Skip to content

Commit

Permalink
sdk/instancesdk: optionally delete instance's data volumes during ins…
Browse files Browse the repository at this point in the history
…tance Delete()

and update gRPC API to migrate this feature.

resolves #1069.
  • Loading branch information
ilgooz committed Jun 21, 2019
1 parent 200d7e3 commit 1cb7180
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 36 deletions.
76 changes: 43 additions & 33 deletions protobuf/api/instance.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions protobuf/api/instance.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ message CreateInstanceResponse {

message DeleteInstanceRequest {
string hash = 1; // Instance hash
bool deleteData = 2; // if enabled, any persistent data (volumes) that belongs to instance and its dependencies will also be deleted.
}

message DeleteInstanceResponse {
Expand Down
14 changes: 12 additions & 2 deletions sdk/instance/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,24 @@ func (i *Instance) GetAllByService(serviceHash string) ([]*instance.Instance, er
return i.instanceDB.GetAllByService(serviceHash)
}

// Delete an instance
func (i *Instance) Delete(hash string) error {
// Delete deletes an instance.
// if deleteData is enabled, any persistent data that belongs to
// the instance and to its dependencies will also be deleted.
func (i *Instance) Delete(hash string, deleteData bool) error {
inst, err := i.instanceDB.Get(hash)
if err != nil {
return err
}
if err := i.stop(inst); err != nil {
return err
}
// delete volumes first before the instance. this way if
// deleting volumes fails, process can be retried by the user again
// because instance still will be in the db.
if deleteData {
if err := i.deleteData(inst); err != nil {
return err
}
}
return i.instanceDB.Delete(hash)
}
43 changes: 43 additions & 0 deletions sdk/instance/volume.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package instancesdk

import (
"sync"

"github.com/docker/docker/client"
"github.com/mesg-foundation/core/instance"
"github.com/mesg-foundation/core/x/xerrors"
)

// deleteData deletes the data volumes of instance and its dependencies.
// TODO: right now deleteData() is not compatible to work with multiple instances of same
// service since extractVolumes() accepts service, not instance. same applies in the start
// api as well. make it work with multiple instances.
func (i *Instance) deleteData(inst *instance.Instance) error {
s, err := i.serviceDB.Get(inst.ServiceHash)
if err != nil {
return err
}
var (
wg sync.WaitGroup
errs xerrors.SyncErrors
)
for _, d := range append(s.Dependencies, s.Configuration) {
// Service.Configuration can be nil so, here is a check for it.
if d == nil {
continue
}
for _, volume := range extractVolumes(s, d) {
wg.Add(1)
go func(source string) {
defer wg.Done()
// if service is never started before, data volume won't be created and Docker Engine
// will return with the not found error. therefore, we can safely ignore it.
if err := i.container.DeleteVolume(source); err != nil && !client.IsErrNotFound(err) {
errs.Append(err)
}
}(volume.Source)
}
}
wg.Wait()
return errs.ErrorOrNil()
}
2 changes: 1 addition & 1 deletion server/grpc/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (s *InstanceServer) Get(ctx context.Context, request *protobuf_api.GetInsta

// Delete an instance
func (s *InstanceServer) Delete(ctx context.Context, request *protobuf_api.DeleteInstanceRequest) (*protobuf_api.DeleteInstanceResponse, error) {
err := s.sdk.Instance.Delete(request.Hash)
err := s.sdk.Instance.Delete(request.Hash, request.DeleteData)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 1cb7180

Please sign in to comment.