Merge pull request #132 in YUNIONIO/onecloud from ~QUXUAN/onecloud:feature/server-disk to release/2.1.0

* commit '5ad60302560eb5aeb540c1540902c43769e83dc2':
  补全aliyun driver信息
  添加aliyuncli操作
  添加GetDetachDiskStatus内容
  添加公有云云硬盘同步操作
This commit is contained in:
邱剑
2018-08-29 18:39:27 +08:00
7 changed files with 116 additions and 18 deletions
+1
View File
@@ -160,6 +160,7 @@ type ICloudVM interface {
ChangeConfig(instanceId string, ncpu int, vmem int) error
GetVNCInfo() (jsonutils.JSONObject, error)
AttachDisk(diskId string) error
DetachDisk(diskId string) error
}
type ICloudNic interface {
+47 -7
View File
@@ -9,6 +9,7 @@ import (
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
@@ -48,6 +49,14 @@ func (self *SAliyunGuestDriver) ChooseHostStorage(host *models.SHost, backend st
return nil
}
func (self *SAliyunGuestDriver) GetDetachDiskStatus() ([]string, error) {
return []string{models.VM_READY, models.VM_RUNNING}, nil
}
func (self *SAliyunGuestDriver) RequestDetachDisk(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
return guest.StartSyncTask(ctx, task.GetUserCred(), false, task.GetTaskId())
}
func (self *SAliyunGuestDriver) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
data, err := self.SManagedVirtualizedGuestDriver.ValidateCreateData(ctx, userCred, data)
if err != nil {
@@ -335,13 +344,44 @@ func (self *SAliyunGuestDriver) OnGuestDeployTaskDataReceived(ctx context.Contex
func (self *SAliyunGuestDriver) RequestSyncConfigOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
if fw_only, _ := task.GetParams().Bool("fw_only"); fw_only {
if ihost, err := host.GetIHost(); err != nil {
return nil, err
} else if iVM, err := ihost.GetIVMById(guest.ExternalId); err != nil {
return nil, err
} else if err := iVM.SyncSecurityGroup(guest.SecgrpId, guest.GetSecgroupName(), guest.GetSecRules()); err != nil {
return nil, err
if ihost, err := host.GetIHost(); err != nil {
return nil, err
} else if iVM, err := ihost.GetIVMById(guest.ExternalId); err != nil {
return nil, err
} else {
if fw_only, _ := task.GetParams().Bool("fw_only"); fw_only {
if err := iVM.SyncSecurityGroup(guest.SecgrpId, guest.GetSecgroupName(), guest.GetSecRules()); err != nil {
return nil, err
}
} else {
if iDisks, err := iVM.GetIDisks(); err != nil {
return nil, err
} else {
disks := make([]models.SDisk, 0)
for _, guestdisk := range guest.GetDisks() {
disk := guestdisk.GetDisk()
disks = append(disks, *disk)
}
added := make([]models.SDisk, 0)
commondb := make([]models.SDisk, 0)
commonext := make([]cloudprovider.ICloudDisk, 0)
removed := make([]cloudprovider.ICloudDisk, 0)
if err := compare.CompareSets(disks, iDisks, &added, &commondb, &commonext, &removed); err != nil {
return nil, err
}
for _, disk := range removed {
if err := iVM.DetachDisk(disk.GetId()); err != nil {
return nil, err
}
}
for _, disk := range added {
if err := iVM.AttachDisk(disk.ExternalId); err != nil {
return nil, err
}
}
}
}
}
return nil, nil
+14 -11
View File
@@ -224,18 +224,21 @@ func (self *SKVMGuestDriver) RequestDeleteDetachedDisk(ctx context.Context, disk
}
func (self *SKVMGuestDriver) RequestSyncConfigOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
desc := guest.GetDriver().GetJsonDescAtHost(ctx, guest, host)
body := jsonutils.NewDict()
body.Add(desc, "desc")
if fw_only, _ := task.GetParams().Bool("fw_only"); fw_only {
body.Add(jsonutils.JSONTrue, "fw_only")
if guest.Status == models.VM_RUNNING {
desc := guest.GetDriver().GetJsonDescAtHost(ctx, guest, host)
body := jsonutils.NewDict()
body.Add(desc, "desc")
if fw_only, _ := task.GetParams().Bool("fw_only"); fw_only {
body.Add(jsonutils.JSONTrue, "fw_only")
}
url := fmt.Sprintf("/servers/%s/sync", guest.Id)
header := http.Header{}
header.Add("X-Task-Id", task.GetTaskId())
header.Add("X-Region-Version", "v2")
_, err := host.Request(task.GetUserCred(), "POST", url, header, body)
return err
}
url := fmt.Sprintf("/servers/%s/sync", guest.Id)
header := http.Header{}
header.Add("X-Task-Id", task.GetTaskId())
header.Add("X-Region-Version", "v2")
_, err := host.Request(task.GetUserCred(), "POST", url, header, body)
return err
return nil
}
func (self *SKVMGuestDriver) RqeuestSuspendOnHost(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
+11
View File
@@ -1625,6 +1625,17 @@ func (self *SGuest) AllowPerformAttachdisk(ctx context.Context, userCred mcclien
}
func (self *SGuest) ValidateAttachDisk(ctx context.Context, disk *SDisk) error {
storage := disk.GetStorage()
if provider := storage.GetCloudprovider(); provider != nil {
host := self.GetHost()
if provider.Id != host.ManagerId {
return httperrors.NewInputParameterError("Disk %s and guest not belong to the same account", disk.Name)
} else if storage.ZoneId != host.ZoneId {
return httperrors.NewInputParameterError("Disk %s and guest not belong to the same zone", disk.Name)
}
return nil
}
if disk.isAttached() {
return httperrors.NewInputParameterError("Disk %s has been attached", disk.Name)
} else if len(disk.GetPathAtHost(self.GetHost())) == 0 {
+18
View File
@@ -406,6 +406,10 @@ func (self *SInstance) AttachDisk(diskId string) error {
return self.host.zone.region.AttachDisk(self.InstanceId, diskId)
}
func (self *SInstance) DetachDisk(diskId string) error {
return self.host.zone.region.DetachDisk(self.InstanceId, diskId)
}
func (self *SRegion) GetInstance(instanceId string) (*SInstance, error) {
instances, _, err := self.GetInstances("", []string{instanceId}, 0, 1)
if err != nil {
@@ -667,6 +671,20 @@ func (self *SRegion) ChangeVMConfig(zoneId string, instanceId string, ncpu int,
return fmt.Errorf("Failed to change vm config, specification not supported")
}
func (self *SRegion) DetachDisk(instanceId string, diskId string) error {
params := make(map[string]string)
params["InstanceId"] = instanceId
params["DiskId"] = diskId
log.Infof("Detach instance %s disk %s", instanceId, diskId)
_, err := self.ecsRequest("DetachDisk", params)
if err != nil {
log.Errorf("DetachDisk %s to %s fail %s", diskId, instanceId, err)
return err
}
return nil
}
func (self *SRegion) AttachDisk(instanceId string, diskId string) error {
params := make(map[string]string)
params["InstanceId"] = instanceId
+21
View File
@@ -43,6 +43,27 @@ func init() {
return nil
})
type InstanceDiskOperationOptions struct {
ID string `help:"instance ID"`
DISK string `help:"disk ID"`
}
shellutils.R(&InstanceDiskOperationOptions{}, "instance-attach-disk", "Attach a disk to instance", func(cli *aliyun.SRegion, args *InstanceDiskOperationOptions) error {
err := cli.AttachDisk(args.ID, args.DISK)
if err != nil {
return err
}
return nil
})
shellutils.R(&InstanceDiskOperationOptions{}, "instance-detach-disk", "Detach a disk to instance", func(cli *aliyun.SRegion, args *InstanceDiskOperationOptions) error {
err := cli.DetachDisk(args.ID, args.DISK)
if err != nil {
return err
}
return nil
})
type InstanceOperationOptions struct {
ID string `help:"instance ID"`
}
+4
View File
@@ -81,6 +81,10 @@ func (self *SVirtualMachine) UpdateVM(name string) error {
return cloudprovider.ErrNotImplemented
}
func (self *SVirtualMachine) DetachDisk(diskId string) error {
return cloudprovider.ErrNotImplemented
}
func (self *SVirtualMachine) AttachDisk(diskId string) error {
return cloudprovider.ErrNotImplemented
}