diff --git a/pkg/compute/hostdrivers/aws.go b/pkg/compute/hostdrivers/aws.go index b4022ab211..255282bcc7 100644 --- a/pkg/compute/hostdrivers/aws.go +++ b/pkg/compute/hostdrivers/aws.go @@ -188,6 +188,22 @@ func (self *SAwsHostDriver) RequestResizeDiskOnHost(host *models.SHost, storage return nil } +func (self *SAwsHostDriver) RequestResetDisk(ctx context.Context, host *models.SHost, disk *models.SDisk, params *jsonutils.JSONDict, task taskman.ITask) error { + iDisk, err := disk.GetIDisk() + if err != nil { + return err + } + snapshotId, err := params.GetString("snapshot_id") + if err != nil { + return err + } + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + err := iDisk.Reset(snapshotId) + return nil, err + }) + return nil +} + func init() { driver := SAwsHostDriver{} models.RegisterHostDriver(&driver) diff --git a/pkg/util/aws/disk.go b/pkg/util/aws/disk.go index a1a304162c..02e5c23ae5 100644 --- a/pkg/util/aws/disk.go +++ b/pkg/util/aws/disk.go @@ -27,7 +27,7 @@ type SDisk struct { DiskId string // VolumeId DiskName string // Tag Name - Size int // Size + Size int // Size GB Category string // VolumeType Type string // system | data Status string // State @@ -366,8 +366,49 @@ func (self *SRegion) resizeDisk(diskId string, size int64) error { } func (self *SRegion) resetDisk(diskId, snapshotId string) error { - // aws貌似不支持直接重置 - return cloudprovider.ErrNotImplemented + // 这里实际是回滚快照 + disk, err := self.GetDisk(diskId) + if err != nil { + log.Debugf("resetDisk %s:%s",diskId, err.Error()) + return err + } + + params := &ec2.CreateVolumeInput{} + params.SetSnapshotId(snapshotId) + params.SetSize(int64(disk.Size)) + params.SetVolumeType(disk.Category) + params.SetAvailabilityZone(disk.ZoneId) + tags,_ := disk.Tags.GetTagSpecifications() + params.SetTagSpecifications([]*ec2.TagSpecification{tags}) + ret, err := self.ec2Client.CreateVolume(params) + if err != nil { + log.Debugf("resetDisk %s: %s",params.String(), err.Error()) + return err + } + + // detach disk + if disk.Status == ec2.VolumeStateInUse { + err := self.DetachDisk(disk.InstanceId, diskId) + if err != nil { + log.Debugf("resetDisk %s %s: %s", disk.InstanceId, diskId, err.Error()) + return err + } + + err = self.ec2Client.WaitUntilVolumeAvailable(&ec2.DescribeVolumesInput{VolumeIds:[]*string{&diskId}}) + if err != nil { + log.Debugf("resetDisk :%s", err.Error()) + return err + } + } + + err = self.AttachDisk(disk.InstanceId, *ret.VolumeId, disk.Device) + if err != nil { + log.Debugf("resetDisk %s %s %s: %s",disk.InstanceId, *ret.VolumeId, disk.Device, err.Error()) + return err + } + + // 绑定成功后删除原磁盘 + return self.DeleteDisk(diskId) } func (self *SRegion) CreateDisk(zoneId string, category string, name string, sizeGb int, snapshotId string, desc string) (string, error) { diff --git a/pkg/util/aws/snapshot.go b/pkg/util/aws/snapshot.go index c1a13fc38d..506044282b 100644 --- a/pkg/util/aws/snapshot.go +++ b/pkg/util/aws/snapshot.go @@ -3,6 +3,7 @@ package aws import ( "fmt" "github.com/aws/aws-sdk-go/service/ec2" + "strings" "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/onecloud/pkg/cloudprovider" @@ -90,7 +91,7 @@ func (self *SSnapshot) GetDiskId() string { } func (self *SSnapshot) Delete() error { - panic("implement me") + return self.region.DeleteSnapshot(self.SnapshotId) } func (self *SSnapshot) GetRegionId() string { @@ -125,6 +126,10 @@ func (self *SRegion) GetSnapshots(instanceId string, diskId string, snapshotName ret, err := self.ec2Client.DescribeSnapshots(params) if err != nil { + if strings.Contains(err.Error(), "InvalidSnapshot.NotFound") { + return nil, 0, cloudprovider.ErrNotFound + } + return nil, 0, err }