mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-21 14:19:49 +08:00
@@ -438,3 +438,12 @@ type ServerResetInput struct {
|
||||
// 自动启动
|
||||
AutoStart *bool `json:"auto_start"`
|
||||
}
|
||||
|
||||
type ServerStopInput struct {
|
||||
// 是否强制关机
|
||||
IsForce bool `json:"is_force"`
|
||||
|
||||
// 是否关机停止计费, 若平台不支持停止计费,此参数无作用
|
||||
// 目前仅阿里云,腾讯云此参数生效
|
||||
StopCharging bool `json:"stop_charging"`
|
||||
}
|
||||
|
||||
@@ -46,6 +46,11 @@ type SPublicIpInfo struct {
|
||||
PublicIpChargeType TElasticipChargeType
|
||||
}
|
||||
|
||||
type ServerStopOptions struct {
|
||||
IsForce bool
|
||||
StopCharging bool
|
||||
}
|
||||
|
||||
type SManagedVMCreateConfig struct {
|
||||
Name string
|
||||
ExternalImageId string
|
||||
|
||||
@@ -294,7 +294,7 @@ type ICloudVM interface {
|
||||
// GetSecurityGroup() ICloudSecurityGroup
|
||||
|
||||
StartVM(ctx context.Context) error
|
||||
StopVM(ctx context.Context, isForce bool) error
|
||||
StopVM(ctx context.Context, opts *ServerStopOptions) error
|
||||
DeleteVM(ctx context.Context) error
|
||||
|
||||
UpdateVM(ctx context.Context, name string) error
|
||||
|
||||
@@ -322,7 +322,7 @@ func (self *SBaremetalGuestDriver) RequestStopGuestForDelete(ctx context.Context
|
||||
!guest.PendingDeleted &&
|
||||
!overridePendingDelete &&
|
||||
!purge {
|
||||
return guest.StartGuestStopTask(ctx, task.GetUserCred(), true, task.GetTaskId())
|
||||
return guest.StartGuestStopTask(ctx, task.GetUserCred(), true, false, task.GetTaskId())
|
||||
}
|
||||
if host != nil && !host.GetEnabled() && !purge {
|
||||
return fmt.Errorf("fail to contact baremetal")
|
||||
|
||||
@@ -706,13 +706,16 @@ func (self *SManagedVirtualizedGuestDriver) RequestStopOnHost(ctx context.Contex
|
||||
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
|
||||
ihost, err := host.GetIHost()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrapf(err, "host.GetIHost")
|
||||
}
|
||||
ivm, err := ihost.GetIVMById(guest.ExternalId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrapf(err, "ihost.GetIVMById")
|
||||
}
|
||||
err = ivm.StopVM(ctx, true)
|
||||
opts := &cloudprovider.ServerStopOptions{}
|
||||
task.GetParams().Unmarshal(&opts)
|
||||
|
||||
err = ivm.StopVM(ctx, opts)
|
||||
return nil, err
|
||||
})
|
||||
return nil
|
||||
|
||||
@@ -268,7 +268,10 @@ func (self *SOpenStackGuestDriver) RemoteDeployGuestForRebuildRoot(ctx context.C
|
||||
log.Debugf("VMrebuildRoot %s new instance, wait status %s ...", iVM.GetGlobalId(), initialState)
|
||||
cloudprovider.WaitStatus(iVM, initialState, time.Second*5, time.Second*1800)
|
||||
|
||||
iVM.StopVM(ctx, true)
|
||||
opts := &cloudprovider.ServerStopOptions{
|
||||
IsForce: true,
|
||||
}
|
||||
iVM.StopVM(ctx, opts)
|
||||
|
||||
iDisks, err = iVM.GetIDisks()
|
||||
if err != nil {
|
||||
|
||||
@@ -226,7 +226,7 @@ func (self *SVirtualizedGuestDriver) RequestStopGuestForDelete(ctx context.Conte
|
||||
host = guest.GetHost()
|
||||
}
|
||||
if host != nil && host.GetEnabled() && host.HostStatus == api.HOST_ONLINE {
|
||||
return guest.StartGuestStopTask(ctx, task.GetUserCred(), true, task.GetTaskId())
|
||||
return guest.StartGuestStopTask(ctx, task.GetUserCred(), true, false, task.GetTaskId())
|
||||
}
|
||||
if host != nil && !jsonutils.QueryBoolean(task.GetParams(), "purge", false) {
|
||||
return fmt.Errorf("fail to contact host")
|
||||
|
||||
@@ -902,14 +902,13 @@ func (self *SGuest) NotifyAdminServerEvent(ctx context.Context, event string, pr
|
||||
notifyclient.SystemNotifyWithCtx(ctx, priority, event, kwargs)
|
||||
}
|
||||
|
||||
func (self *SGuest) StartGuestStopTask(ctx context.Context, userCred mcclient.TokenCredential, isForce bool, parentTaskId string) error {
|
||||
func (self *SGuest) StartGuestStopTask(ctx context.Context, userCred mcclient.TokenCredential, isForce, stopCharging bool, parentTaskId string) error {
|
||||
if len(parentTaskId) == 0 {
|
||||
self.SetStatus(userCred, api.VM_START_STOP, "")
|
||||
}
|
||||
params := jsonutils.NewDict()
|
||||
if isForce {
|
||||
params.Add(jsonutils.JSONTrue, "is_force")
|
||||
}
|
||||
params.Add(jsonutils.NewBool(isForce), "is_force")
|
||||
params.Add(jsonutils.NewBool(stopCharging), "stop_charging")
|
||||
if len(parentTaskId) > 0 {
|
||||
params.Add(jsonutils.JSONTrue, "subtask")
|
||||
}
|
||||
@@ -2786,14 +2785,12 @@ func (self *SGuest) AllowPerformStop(ctx context.Context,
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformStop(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
input api.ServerStopInput) (jsonutils.JSONObject, error) {
|
||||
// XXX if is force, force stop guest
|
||||
var isForce = jsonutils.QueryBoolean(data, "is_force", false)
|
||||
if isForce || utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_STOP_FAILED}) {
|
||||
return nil, self.StartGuestStopTask(ctx, userCred, isForce, "")
|
||||
} else {
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot stop server in status %s", self.Status)
|
||||
if input.IsForce || utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_STOP_FAILED}) {
|
||||
return nil, self.StartGuestStopTask(ctx, userCred, input.IsForce, input.StopCharging, "")
|
||||
}
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot stop server in status %s", self.Status)
|
||||
}
|
||||
|
||||
func (self *SGuest) AllowPerformRestart(ctx context.Context,
|
||||
|
||||
@@ -3594,7 +3594,9 @@ func (self *SHost) PerformStop(ctx context.Context, userCred mcclient.TokenCrede
|
||||
return nil, self.InitializedGuestStop(ctx, userCred, guest)
|
||||
}
|
||||
self.SetStatus(userCred, api.BAREMETAL_START_MAINTAIN, "")
|
||||
return guest.PerformStop(ctx, userCred, query, data)
|
||||
input := api.ServerStopInput{}
|
||||
data.Unmarshal(&input)
|
||||
return guest.PerformStop(ctx, userCred, query, input)
|
||||
}
|
||||
}
|
||||
return nil, self.StartBaremetalUnmaintenanceTask(ctx, userCred, false, "stop")
|
||||
|
||||
@@ -44,7 +44,7 @@ func (self *GuestDeployTask) OnInit(ctx context.Context, obj db.IStandaloneModel
|
||||
func (self *GuestDeployTask) OnGuestNetworkReady(ctx context.Context, guest *models.SGuest) {
|
||||
self.SetStage("OnDeployWaitServerStop", nil)
|
||||
if jsonutils.QueryBoolean(self.Params, "restart", false) {
|
||||
guest.StartGuestStopTask(ctx, self.UserCred, false, self.GetTaskId())
|
||||
guest.StartGuestStopTask(ctx, self.UserCred, false, false, self.GetTaskId())
|
||||
} else {
|
||||
// Note: have to use LocalTaskRun, run to another place implement OnDeployWaitServerStop
|
||||
taskman.LocalTaskRun(self, func() (jsonutils.JSONObject, error) {
|
||||
|
||||
@@ -45,7 +45,7 @@ func (self *GuestRebuildRootTask) OnInit(ctx context.Context, obj db.IStandalone
|
||||
guest := obj.(*models.SGuest)
|
||||
if jsonutils.QueryBoolean(self.Params, "need_stop", false) {
|
||||
self.SetStage("OnStopServerComplete", nil)
|
||||
guest.StartGuestStopTask(ctx, self.UserCred, false, self.GetTaskId())
|
||||
guest.StartGuestStopTask(ctx, self.UserCred, false, false, self.GetTaskId())
|
||||
} else {
|
||||
self.StartRebuildRootDisk(ctx, guest)
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ func (self *GuestHardResetTask) OnInit(ctx context.Context, obj db.IStandaloneMo
|
||||
func (self *GuestHardResetTask) StopServer(ctx context.Context, guest *models.SGuest) {
|
||||
guest.SetStatus(self.UserCred, api.VM_STOPPING, "")
|
||||
self.SetStage("OnServerStopComplete", nil)
|
||||
guest.StartGuestStopTask(ctx, self.UserCred, false, self.GetTaskId())
|
||||
guest.StartGuestStopTask(ctx, self.UserCred, false, false, self.GetTaskId())
|
||||
// logclient.AddActionLogWith(guest, logclient.ACT_VM_RESTART, `{"is_force": true}`, self.UserCred, true)
|
||||
}
|
||||
|
||||
@@ -81,6 +81,6 @@ type GuestRestartTask struct {
|
||||
func (self *GuestRestartTask) StopServer(ctx context.Context, guest *models.SGuest) {
|
||||
self.SetStage("OnServerStopComplete", nil)
|
||||
isForce := jsonutils.QueryBoolean(self.Params, "is_force", false)
|
||||
guest.StartGuestStopTask(ctx, self.UserCred, isForce, self.GetTaskId())
|
||||
guest.StartGuestStopTask(ctx, self.UserCred, isForce, false, self.GetTaskId())
|
||||
// logclient.AddActionLog(guest, logclient.ACT_VM_RESTART, `{"is_force": false}`, self.UserCred, true)
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ func (self *GuestSaveImageTask) OnInit(ctx context.Context, obj db.IStandaloneMo
|
||||
log.Infof("Saving server image: %s", guest.Name)
|
||||
if restart, _ := self.GetParams().Bool("restart"); restart {
|
||||
self.SetStage("OnStopServerComplete", nil)
|
||||
guest.StartGuestStopTask(ctx, self.GetUserCred(), false, self.GetTaskId())
|
||||
guest.StartGuestStopTask(ctx, self.GetUserCred(), false, false, self.GetTaskId())
|
||||
} else {
|
||||
self.OnStopServerComplete(ctx, guest, nil)
|
||||
}
|
||||
|
||||
@@ -358,7 +358,10 @@ func (as *SAgentStorage) waitVmToolsVersion(ctx context.Context, vm *esxi.SVirtu
|
||||
}
|
||||
timeUpper = time.Now().Add(timeout)
|
||||
for vm.GetStatus() == api.VM_RUNNING && time.Now().Before(timeUpper) {
|
||||
vm.StopVM(ctx, true)
|
||||
opts := &cloudprovider.ServerStopOptions{
|
||||
IsForce: true,
|
||||
}
|
||||
vm.StopVM(ctx, opts)
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
return
|
||||
|
||||
@@ -552,8 +552,9 @@ func (opts *ServerCreateOptions) Params() (*computeapi.ServerCreateInput, error)
|
||||
}
|
||||
|
||||
type ServerStopOptions struct {
|
||||
ID []string `help:"ID or Name of server" json:"-"`
|
||||
Force *bool `help:"Stop server forcefully" json:"is_force"`
|
||||
ID []string `help:"ID or Name of server" json:"-"`
|
||||
Force *bool `help:"Stop server forcefully" json:"is_force"`
|
||||
StopCharging *bool `help:"Stop charging when server stop"`
|
||||
}
|
||||
|
||||
func (o *ServerStopOptions) GetIds() []string {
|
||||
|
||||
@@ -454,8 +454,8 @@ func (self *SInstance) StartVM(ctx context.Context) error {
|
||||
return cloudprovider.ErrTimeout
|
||||
}
|
||||
|
||||
func (self *SInstance) StopVM(ctx context.Context, isForce bool) error {
|
||||
err := self.host.zone.region.StopVM(self.InstanceId, isForce)
|
||||
func (self *SInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerStopOptions) error {
|
||||
err := self.host.zone.region.StopVM(self.InstanceId, opts.IsForce, opts.StopCharging)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -657,7 +657,7 @@ func (self *SRegion) doStartVM(instanceId string) error {
|
||||
return self.instanceOperation(instanceId, "StartInstance", nil)
|
||||
}
|
||||
|
||||
func (self *SRegion) doStopVM(instanceId string, isForce bool) error {
|
||||
func (self *SRegion) doStopVM(instanceId string, isForce, stopCharging bool) error {
|
||||
params := make(map[string]string)
|
||||
if isForce {
|
||||
params["ForceStop"] = "true"
|
||||
@@ -665,6 +665,9 @@ func (self *SRegion) doStopVM(instanceId string, isForce bool) error {
|
||||
params["ForceStop"] = "false"
|
||||
}
|
||||
params["StoppedMode"] = "KeepCharging"
|
||||
if stopCharging {
|
||||
params["StoppedMode"] = "StopCharging"
|
||||
}
|
||||
return self.instanceOperation(instanceId, "StopInstance", params)
|
||||
}
|
||||
|
||||
@@ -711,7 +714,7 @@ func (self *SRegion) StartVM(instanceId string) error {
|
||||
// return self.waitInstanceStatus(instanceId, InstanceStatusRunning, time.Second*5, time.Second*180) // 3 minutes to timeout
|
||||
}
|
||||
|
||||
func (self *SRegion) StopVM(instanceId string, isForce bool) error {
|
||||
func (self *SRegion) StopVM(instanceId string, isForce, stopCharging bool) error {
|
||||
status, err := self.GetInstanceStatus(instanceId)
|
||||
if err != nil {
|
||||
log.Errorf("Fail to get instance status on StopVM: %s", err)
|
||||
@@ -724,7 +727,7 @@ func (self *SRegion) StopVM(instanceId string, isForce bool) error {
|
||||
log.Errorf("StopVM: vm status is %s expect %s", status, InstanceStatusRunning)
|
||||
return cloudprovider.ErrInvalidStatus
|
||||
}
|
||||
return self.doStopVM(instanceId, isForce)
|
||||
return self.doStopVM(instanceId, isForce, stopCharging)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
@@ -116,11 +116,12 @@ func init() {
|
||||
})
|
||||
|
||||
type InstanceStopOptions struct {
|
||||
ID string `help:"instance ID"`
|
||||
Force bool `help:"Force stop instance"`
|
||||
ID string `help:"instance ID"`
|
||||
Force bool `help:"Force stop instance"`
|
||||
StopCharging bool `help:"Stop Charging"`
|
||||
}
|
||||
shellutils.R(&InstanceStopOptions{}, "instance-stop", "Stop a instance", func(cli *aliyun.SRegion, args *InstanceStopOptions) error {
|
||||
err := cli.StopVM(args.ID, args.Force)
|
||||
err := cli.StopVM(args.ID, args.Force, args.StopCharging)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -378,8 +378,8 @@ func (self *SInstance) StartVM(ctx context.Context) error {
|
||||
return cloudprovider.ErrTimeout
|
||||
}
|
||||
|
||||
func (self *SInstance) StopVM(ctx context.Context, isForce bool) error {
|
||||
err := self.host.zone.region.StopVM(self.InstanceId, isForce)
|
||||
func (self *SInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerStopOptions) error {
|
||||
err := self.host.zone.region.StopVM(self.InstanceId, opts.IsForce)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -448,8 +448,8 @@ func (self *SClassicInstance) StartVM(ctx context.Context) error {
|
||||
return cloudprovider.WaitStatus(self, api.VM_RUNNING, 10*time.Second, 300*time.Second)
|
||||
}
|
||||
|
||||
func (self *SClassicInstance) StopVM(ctx context.Context, isForce bool) error {
|
||||
err := self.host.zone.region.StopClassicVM(self.ID, isForce)
|
||||
func (self *SClassicInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerStopOptions) error {
|
||||
err := self.host.zone.region.StopClassicVM(self.ID, opts.IsForce)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -781,7 +781,10 @@ func (region *SRegion) DeployVM(ctx context.Context, instanceId, name, password,
|
||||
func (self *SInstance) RebuildRoot(ctx context.Context, desc *cloudprovider.SManagedVMRebuildRootConfig) (string, error) {
|
||||
cpu := self.GetVcpuCount()
|
||||
memoryMb := self.GetVmemSizeMB()
|
||||
self.StopVM(ctx, true)
|
||||
opts := &cloudprovider.ServerStopOptions{
|
||||
IsForce: true,
|
||||
}
|
||||
self.StopVM(ctx, opts)
|
||||
return self.host.zone.region.ReplaceSystemDisk(self, cpu, memoryMb, desc.ImageId, desc.Password, desc.PublicKey, desc.SysSizeGB)
|
||||
}
|
||||
|
||||
@@ -832,7 +835,10 @@ func (region *SRegion) ReplaceSystemDisk(instance *SInstance, cpu int, memoryMb
|
||||
return "", err
|
||||
}
|
||||
|
||||
newInstance.StopVM(context.Background(), true)
|
||||
opts := &cloudprovider.ServerStopOptions{
|
||||
IsForce: true,
|
||||
}
|
||||
newInstance.StopVM(context.Background(), opts)
|
||||
cloudprovider.WaitStatus(newInstance, api.VM_READY, time.Second*5, time.Minute*5)
|
||||
|
||||
newInstance.deleteVM(context.Background(), true)
|
||||
@@ -1064,8 +1070,8 @@ func (self *SInstance) StartVM(ctx context.Context) error {
|
||||
return cloudprovider.WaitStatus(self, api.VM_RUNNING, 10*time.Second, 300*time.Second)
|
||||
}
|
||||
|
||||
func (self *SInstance) StopVM(ctx context.Context, isForce bool) error {
|
||||
err := self.host.zone.region.StopVM(self.ID, isForce)
|
||||
func (self *SInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerStopOptions) error {
|
||||
err := self.host.zone.region.StopVM(self.ID, opts.IsForce)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -476,7 +476,7 @@ func (self *SInstance) StartVM(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SInstance) StopVM(ctx context.Context, isForce bool) error {
|
||||
func (self *SInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerStopOptions) error {
|
||||
err := self.host.zone.region.StopVM(self.GetId())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Instance.StopVM")
|
||||
|
||||
@@ -456,11 +456,11 @@ func makeNicStartConnected(nic *SVirtualNIC) *types.VirtualDeviceConfigSpec {
|
||||
return &editSpec
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) StopVM(ctx context.Context, isForce bool) error {
|
||||
func (self *SVirtualMachine) StopVM(ctx context.Context, opts *cloudprovider.ServerStopOptions) error {
|
||||
if self.GetStatus() == api.VM_READY {
|
||||
return nil
|
||||
}
|
||||
if !isForce && self.isToolsOk() {
|
||||
if !opts.IsForce && self.isToolsOk() {
|
||||
return self.shutdownVM(ctx)
|
||||
} else {
|
||||
return self.poweroffVM(ctx)
|
||||
|
||||
@@ -430,7 +430,7 @@ func (instance *SInstance) StartVM(ctx context.Context) error {
|
||||
return instance.host.zone.region.StartInstance(instance.SelfLink)
|
||||
}
|
||||
|
||||
func (instance *SInstance) StopVM(ctx context.Context, isForce bool) error {
|
||||
func (instance *SInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerStopOptions) error {
|
||||
return instance.host.zone.region.StopInstance(instance.SelfLink)
|
||||
}
|
||||
|
||||
|
||||
@@ -470,7 +470,7 @@ func (self *SInstance) StartVM(ctx context.Context) error {
|
||||
return cloudprovider.ErrTimeout
|
||||
}
|
||||
|
||||
func (self *SInstance) StopVM(ctx context.Context, isForce bool) error {
|
||||
func (self *SInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerStopOptions) error {
|
||||
if self.Status == InstanceStatusStopped {
|
||||
return nil
|
||||
}
|
||||
@@ -480,7 +480,7 @@ func (self *SInstance) StopVM(ctx context.Context, isForce bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := self.host.zone.region.StopVM(self.GetId(), isForce)
|
||||
err := self.host.zone.region.StopVM(self.GetId(), opts.IsForce)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -406,8 +406,8 @@ func (instance *SInstance) StartVM(ctx context.Context) error {
|
||||
return cloudprovider.WaitStatus(instance, api.VM_RUNNING, 10*time.Second, 8*time.Minute)
|
||||
}
|
||||
|
||||
func (instance *SInstance) StopVM(ctx context.Context, isForce bool) error {
|
||||
err := instance.host.zone.region.StopVM(instance.Id, isForce)
|
||||
func (instance *SInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerStopOptions) error {
|
||||
err := instance.host.zone.region.StopVM(instance.Id, opts.IsForce)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "StopVM(%s)", instance.Id)
|
||||
}
|
||||
|
||||
@@ -417,8 +417,8 @@ func (self *SInstance) StartVM(ctx context.Context) error {
|
||||
return cloudprovider.ErrTimeout
|
||||
}
|
||||
|
||||
func (self *SInstance) StopVM(ctx context.Context, isForce bool) error {
|
||||
err := self.host.zone.region.StopVM(self.InstanceId, isForce)
|
||||
func (self *SInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerStopOptions) error {
|
||||
err := self.host.zone.region.StopVM(self.InstanceId, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -467,7 +467,10 @@ func (self *SInstance) RebuildRoot(ctx context.Context, desc *cloudprovider.SMan
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
self.StopVM(ctx, true)
|
||||
opts := &cloudprovider.ServerStopOptions{
|
||||
IsForce: true,
|
||||
}
|
||||
self.StopVM(ctx, opts)
|
||||
instance, err := self.host.zone.region.GetInstance(self.InstanceId)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -638,15 +641,18 @@ func (self *SRegion) doStartVM(instanceId string) error {
|
||||
return self.instanceOperation(instanceId, "StartInstances", nil, true)
|
||||
}
|
||||
|
||||
func (self *SRegion) doStopVM(instanceId string, isForce bool) error {
|
||||
func (self *SRegion) doStopVM(instanceId string, opts *cloudprovider.ServerStopOptions) error {
|
||||
params := make(map[string]string)
|
||||
if isForce {
|
||||
if opts.IsForce {
|
||||
// params["ForceStop"] = "FALSE"
|
||||
params["StopType"] = "HARD"
|
||||
} else {
|
||||
// params["ForceStop"] = "FALSE"
|
||||
params["StopType"] = "SOFT"
|
||||
}
|
||||
if opts.StopCharging {
|
||||
params["StoppedMode"] = "STOP_CHARGING"
|
||||
}
|
||||
return self.instanceOperation(instanceId, "StopInstances", params, true)
|
||||
}
|
||||
|
||||
@@ -672,7 +678,7 @@ func (self *SRegion) StartVM(instanceId string) error {
|
||||
return self.doStartVM(instanceId)
|
||||
}
|
||||
|
||||
func (self *SRegion) StopVM(instanceId string, isForce bool) error {
|
||||
func (self *SRegion) StopVM(instanceId string, opts *cloudprovider.ServerStopOptions) error {
|
||||
status, err := self.GetInstanceStatus(instanceId)
|
||||
if err != nil {
|
||||
log.Errorf("Fail to get instance status on StopVM: %s", err)
|
||||
@@ -681,7 +687,7 @@ func (self *SRegion) StopVM(instanceId string, isForce bool) error {
|
||||
if status == InstanceStatusStopped {
|
||||
return nil
|
||||
}
|
||||
return self.doStopVM(instanceId, isForce)
|
||||
return self.doStopVM(instanceId, opts)
|
||||
}
|
||||
|
||||
func (self *SRegion) DeleteVM(instanceId string) error {
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/qcloud"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
@@ -122,11 +123,16 @@ func init() {
|
||||
})
|
||||
|
||||
type InstanceStopOptions struct {
|
||||
ID string `help:"instance ID"`
|
||||
Force bool `help:"Force stop instance"`
|
||||
ID string `help:"instance ID"`
|
||||
Force bool `help:"Force stop instance"`
|
||||
StopCharging bool `help:"Stop charging"`
|
||||
}
|
||||
shellutils.R(&InstanceStopOptions{}, "instance-stop", "Stop a instance", func(cli *qcloud.SRegion, args *InstanceStopOptions) error {
|
||||
err := cli.StopVM(args.ID, args.Force)
|
||||
opts := &cloudprovider.ServerStopOptions{
|
||||
IsForce: args.Force,
|
||||
StopCharging: args.StopCharging,
|
||||
}
|
||||
err := cli.StopVM(args.ID, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -400,7 +400,7 @@ func (self *SInstance) StartVM(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SInstance) StopVM(ctx context.Context, isForce bool) error {
|
||||
func (self *SInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerStopOptions) error {
|
||||
err := self.host.zone.region.StopVM(self.GetId())
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -279,8 +279,8 @@ func (region *SRegion) StartVM(instanceId string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (instance *SInstance) StopVM(ctx context.Context, isForce bool) error {
|
||||
err := instance.host.zone.region.StopVM(instance.UUID, isForce)
|
||||
func (instance *SInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerStopOptions) error {
|
||||
err := instance.host.zone.region.StopVM(instance.UUID, opts.IsForce)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user