diff --git a/pkg/multicloud/aliyun/instance.go b/pkg/multicloud/aliyun/instance.go index 3b981eae92..288ba2d34a 100644 --- a/pkg/multicloud/aliyun/instance.go +++ b/pkg/multicloud/aliyun/instance.go @@ -550,20 +550,24 @@ func (self *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.S var err error for _, instanceType := range instanceTypes { if isPrepaid { - err = self.host.zone.region.ChangePrepaidVMConfig(self.ZoneId, self.InstanceId, instanceType, isDowngrade) + err = self.host.zone.region.ChangePrepaidVMConfig(self.InstanceId, instanceType, isDowngrade) if err != nil { log.Errorf("ChangePrepaidVMConfig %s error: %v", instanceType, err) + continue } } else { - err = self.host.zone.region.ChangeVMConfig(self.ZoneId, self.InstanceId, instanceType) + err = self.host.zone.region.ChangeVMConfig(self.InstanceId, instanceType) if err != nil { log.Errorf("ChangeVMConfig %s error: %v", instanceType, err) + continue } } + return nil } if err != nil { return errors.Wrapf(err, "ChangeVMConfig") } + return fmt.Errorf("Failed to change vm config, specification not supported") } @@ -927,7 +931,7 @@ func (self *SRegion) ReplaceSystemDisk(instanceId string, imageId string, passwd return body.GetString("DiskId") } -func (self *SRegion) ChangePrepaidVMConfig(zoneId string, instanceId string, instanceType string, isDowngrade bool) error { +func (self *SRegion) ChangePrepaidVMConfig(instanceId string, instanceType string, isDowngrade bool) error { // todo: support change disk config? params := make(map[string]string) params["InstanceType"] = instanceType @@ -942,7 +946,7 @@ func (self *SRegion) ChangePrepaidVMConfig(zoneId string, instanceId string, ins return nil } -func (self *SRegion) ChangeVMConfig(zoneId string, instanceId string, instanceType string) error { +func (self *SRegion) ChangeVMConfig(instanceId string, instanceType string) error { // todo: support change disk config? params := make(map[string]string) params["InstanceType"] = instanceType diff --git a/pkg/multicloud/aliyun/shell/instance.go b/pkg/multicloud/aliyun/shell/instance.go index bd781ae787..5448e35254 100644 --- a/pkg/multicloud/aliyun/shell/instance.go +++ b/pkg/multicloud/aliyun/shell/instance.go @@ -177,18 +177,12 @@ func init() { }) type InstanceChangeConfigOptions struct { - ID string `help:"instance ID"` - InstanceTypeId string `help:"instance type"` - Disk []int `help:"Data disk sizes int GB"` + ID string `help:"instance ID"` + InstanceType string `help:"instance type"` } shellutils.R(&InstanceChangeConfigOptions{}, "instance-change-config", "Deploy keypair/password to a stopped virtual server", func(cli *aliyun.SRegion, args *InstanceChangeConfigOptions) error { - instance, e := cli.GetInstance(args.ID) - if e != nil { - return e - } - - err := cli.ChangeVMConfig2(instance.ZoneId, args.ID, args.InstanceTypeId, nil) + err := cli.ChangeVMConfig(args.ID, args.InstanceType) if err != nil { return err } diff --git a/pkg/multicloud/huawei/instance.go b/pkg/multicloud/huawei/instance.go index 966c6ffa57..16396f621d 100644 --- a/pkg/multicloud/huawei/instance.go +++ b/pkg/multicloud/huawei/instance.go @@ -692,29 +692,31 @@ func (self *SInstance) DeployVM(ctx context.Context, name string, username strin } func (self *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.SManagedVMChangeConfig) error { + instanceTypes := []string{} if len(config.InstanceType) > 0 { - return self.ChangeConfig2(ctx, config.InstanceType) + instanceTypes = []string{config.InstanceType} + } else { + flavors, err := self.host.zone.region.GetMatchInstanceTypes(config.Cpu, config.MemoryMB, self.OSEXTAZAvailabilityZone) + if err != nil { + return errors.Wrapf(err, "GetMatchInstanceTypes") + } + for _, flavor := range flavors { + instanceTypes = append(instanceTypes, flavor.ID) + } + } + var err error + for _, instanceType := range instanceTypes { + err = self.host.zone.region.ChangeVMConfig(self.GetId(), instanceType) + if err != nil { + log.Warningf("ChangeVMConfig %s for %s error: %v", self.GetId(), instanceType, err) + } else { + return cloudprovider.WaitStatusWithDelay(self, api.VM_READY, 15*time.Second, 15*time.Second, 180*time.Second) + } } - err := self.host.zone.region.ChangeVMConfig(self.OSEXTAZAvailabilityZone, self.GetId(), config.Cpu, config.MemoryMB, nil) if err != nil { - return err + return errors.Wrapf(err, "ChangeVMConfig") } - - return cloudprovider.WaitStatusWithDelay(self, api.VM_READY, 15*time.Second, 15*time.Second, 180*time.Second) -} - -func (self *SInstance) ChangeConfig2(ctx context.Context, instanceType string) error { - err := self.host.zone.region.ChangeVMConfig2(self.OSEXTAZAvailabilityZone, self.GetId(), instanceType, nil) - if err != nil { - return errors.Wrap(err, "Instance.ChangeConfig2.ChangeVMConfig2") - } - - err = cloudprovider.WaitStatusWithDelay(self, api.VM_READY, 15*time.Second, 15*time.Second, 180*time.Second) - if err != nil { - return errors.Wrap(err, "Instance.ChangeConfig2.WaitStatusWithDelay") - } - - return nil + return fmt.Errorf("Failed to change vm config, specification not supported") } // todo:// 返回jsonobject感觉很诡异。不能直接知道内部细节 @@ -1290,42 +1292,16 @@ func (self *SRegion) DeployVM(instanceId string, name string, password string, k } // https://support.huaweicloud.com/api-ecs/zh-cn_topic_0020212653.html -func (self *SRegion) ChangeVMConfig(zoneId string, instanceId string, ncpu int, vmem int, disks []*SDisk) error { - instanceTypes, err := self.GetMatchInstanceTypes(ncpu, vmem, zoneId) - if err != nil { - return err - } - +func (self *SRegion) ChangeVMConfig(instanceId string, instanceType string) error { self.ecsClient.Servers.SetVersion("v1.1") defer self.ecsClient.Servers.SetVersion("v1") - for _, t := range instanceTypes { - params := jsonutils.NewDict() - resizeObj := jsonutils.NewDict() - resizeObj.Add(jsonutils.NewString(t.ID), "flavorRef") - params.Add(resizeObj, "resize") - _, err := self.ecsClient.Servers.PerformAction2("resize", instanceId, params, "") - if err != nil { - log.Errorf("Failed for %s: %s", t.ID, err) - } else { - return nil - } - } - - return fmt.Errorf("Failed to change vm config, specification not supported") -} - -func (self *SRegion) ChangeVMConfig2(zoneId string, instanceId string, instanceType string, disks []*SDisk) error { params := jsonutils.NewDict() resizeObj := jsonutils.NewDict() resizeObj.Add(jsonutils.NewString(instanceType), "flavorRef") params.Add(resizeObj, "resize") - - self.ecsClient.Servers.SetVersion("v1.1") - defer self.ecsClient.Servers.SetVersion("v1") - _, err := self.ecsClient.Servers.PerformAction2("resize", instanceId, params, "") - return err + return errors.Wrapf(err, "PerformAction2(resize)") } // https://support.huaweicloud.com/api-ecs/zh-cn_topic_0142763126.html 微版本2.6及以上? diff --git a/pkg/multicloud/huawei/shell/instance.go b/pkg/multicloud/huawei/shell/instance.go index 95818a8525..d46f364462 100644 --- a/pkg/multicloud/huawei/shell/instance.go +++ b/pkg/multicloud/huawei/shell/instance.go @@ -136,19 +136,12 @@ func init() { }) type InstanceChangeConfigOptions struct { - ID string `help:"instance ID"` - InstanceTypeId string `help:"instance type"` - Disk []int `help:"Data disk sizes int GB"` + ID string `help:"instance ID"` + InstanceType string `help:"instance type"` } shellutils.R(&InstanceChangeConfigOptions{}, "instance-change-config", "Deploy keypair/password to a stopped virtual server", func(cli *huawei.SRegion, args *InstanceChangeConfigOptions) error { - instance, e := cli.GetInstanceByID(args.ID) - if e != nil { - return e - } - - // todo : add create disks - err := cli.ChangeVMConfig2(instance.GetId(), args.ID, args.InstanceTypeId, nil) + err := cli.ChangeVMConfig(args.ID, args.InstanceType) if err != nil { return err } diff --git a/pkg/multicloud/qcloud/instance.go b/pkg/multicloud/qcloud/instance.go index 3c1a86fe9b..ce1f653ee3 100644 --- a/pkg/multicloud/qcloud/instance.go +++ b/pkg/multicloud/qcloud/instance.go @@ -535,14 +535,33 @@ func (self *SInstance) RebuildRoot(ctx context.Context, desc *cloudprovider.SMan } func (self *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.SManagedVMChangeConfig) error { + instanceTypes := []string{} if len(config.InstanceType) > 0 { - return self.ChangeConfig2(ctx, config.InstanceType) + instanceTypes = []string{config.InstanceType} + } else { + specs, err := self.host.zone.region.GetMatchInstanceTypes(config.Cpu, config.MemoryMB, 0, self.Placement.Zone) + if err != nil { + return errors.Wrapf(err, "GetMatchInstanceTypes") + } + for _, spec := range specs { + instanceTypes = append(instanceTypes, spec.InstanceType) + } } - return self.host.zone.region.ChangeVMConfig(self.Placement.Zone, self.InstanceId, config.Cpu, config.MemoryMB, nil) -} -func (self *SInstance) ChangeConfig2(ctx context.Context, instanceType string) error { - return self.host.zone.region.ChangeVMConfig2(self.Placement.Zone, self.InstanceId, instanceType, nil) + var err error + for _, instanceType := range instanceTypes { + err = self.host.zone.region.ChangeVMConfig(self.InstanceId, instanceType) + if err != nil { + log.Errorf("ChangeConfig for %s with %s error: %v", self.InstanceId, instanceType, err) + continue + } + return nil + } + if err != nil { + return err + } + + return fmt.Errorf("Failed to change vm config, specification not supported") } func (self *SInstance) AttachDisk(ctx context.Context, diskId string) error { @@ -863,39 +882,12 @@ func (self *SRegion) ReplaceSystemDisk(instanceId string, imageId string, passwd return err } -func (self *SRegion) ChangeVMConfig(zoneId string, instanceId string, ncpu int, vmem int, disks []*SDisk) error { - // todo: support change disk config? - params := make(map[string]string) - instanceTypes, e := self.GetMatchInstanceTypes(ncpu, vmem, 0, zoneId) - if e != nil { - return e - } - - for _, instancetype := range instanceTypes { - params["InstanceType"] = instancetype.InstanceType - err := self.instanceOperation(instanceId, "ResetInstancesType", params, true) - if err != nil { - log.Errorf("Failed for %s: %s", instancetype.InstanceType, err) - } else { - return nil - } - } - - return fmt.Errorf("Failed to change vm config, specification not supported") -} - -func (self *SRegion) ChangeVMConfig2(zoneId string, instanceId string, instanceType string, disks []*SDisk) error { - // todo: support change disk config? +func (self *SRegion) ChangeVMConfig(instanceId string, instanceType string) error { params := make(map[string]string) params["InstanceType"] = instanceType err := self.instanceOperation(instanceId, "ResetInstancesType", params, true) - if err != nil { - log.Errorf("Failed for %s: %s", instanceType, err) - return fmt.Errorf("Failed to change vm config, specification not supported") - } - - return nil + return errors.Wrapf(err, "ResetInstancesType %s", instanceType) } func (self *SRegion) DetachDisk(instanceId string, diskId string) error { diff --git a/pkg/multicloud/qcloud/shell/instance.go b/pkg/multicloud/qcloud/shell/instance.go index 9b11ce854e..daa68a35b6 100644 --- a/pkg/multicloud/qcloud/shell/instance.go +++ b/pkg/multicloud/qcloud/shell/instance.go @@ -186,20 +186,12 @@ func init() { }) type InstanceChangeConfigOptions struct { - ID string `help:"instance ID"` - InstanceTypeId string `help:"instance type"` - Vmem int `help:"MiB of memory"` - Disk []int `help:"Data disk sizes int GB"` + ID string `help:"instance ID"` + InstanceType string `help:"instance type"` } shellutils.R(&InstanceChangeConfigOptions{}, "instance-change-config", "Deploy keypair/password to a stopped virtual server", func(cli *qcloud.SRegion, args *InstanceChangeConfigOptions) error { - instance, e := cli.GetInstance(args.ID) - if e != nil { - return e - } - - // todo : add create disks - err := cli.ChangeVMConfig2(instance.Placement.Zone, args.ID, args.InstanceTypeId, nil) + err := cli.ChangeVMConfig(args.ID, args.InstanceType) if err != nil { return err }