Merge pull request #1115 in YUNIONIO/onecloud from ~WANYAOQI/onecloud:bugfix/wyq/minor-20190223 to release/2.6.0

* commit '7425e13bc692f2f42d74be60e68a3b5d23649705':
  set http idle conn timeout
  add delete backup on switch
  add verify dirty servers
  minor fix
This commit is contained in:
邱剑
2019-02-25 17:12:06 +08:00
8 changed files with 101 additions and 19 deletions
+10 -3
View File
@@ -154,9 +154,16 @@ func init() {
return nil
})
R(&options.ServerIdsOptions{}, "server-switch-to-backup", "Switch geust master to backup host", func(s *mcclient.ClientSession, opts *options.ServerIdsOptions) error {
ret := modules.Servers.BatchPerformAction(s, opts.ID, "switch-to-backup", nil)
printBatchResults(ret, modules.Servers.GetColumns(s))
R(&options.ServerSwitchToBackupOptions{}, "server-switch-to-backup", "Switch geust master to backup host", func(s *mcclient.ClientSession, opts *options.ServerSwitchToBackupOptions) error {
params, err := options.StructToParams(opts)
if err != nil {
return err
}
ret, err := modules.Servers.PerformAction(s, opts.ID, "switch-to-backup", params)
if err != nil {
return err
}
printObject(ret)
return nil
})
+48 -6
View File
@@ -2270,8 +2270,16 @@ func (self *SGuest) PerformSwitchToBackup(ctx context.Context, userCred mcclient
if len(self.BackupHostId) == 0 {
return nil, httperrors.NewBadRequestError("Guest no backup host")
}
oldStatus := self.Status
self.SetStatus(userCred, VM_SWITCH_TO_BACKUP, "Switch to backup")
if task, err := taskman.TaskManager.NewTask(ctx, "GuestSwitchToBackupTask", self, userCred, nil, "", "", nil); err != nil {
deleteBackup := jsonutils.QueryBoolean(data, "delete_backup", false)
purgeBackup := jsonutils.QueryBoolean(data, "purge_backup", false)
taskData := jsonutils.NewDict()
taskData.Set("old_status", jsonutils.NewString(oldStatus))
taskData.Set("delete_backup", jsonutils.NewBool(deleteBackup))
taskData.Set("purge_backup", jsonutils.NewBool(purgeBackup))
if task, err := taskman.TaskManager.NewTask(ctx, "GuestSwitchToBackupTask", self, userCred, taskData, "", "", nil); err != nil {
log.Errorf(err.Error())
return nil, err
} else {
@@ -2295,7 +2303,7 @@ func (manager *SGuestManager) PerformDirtyServerStart(ctx context.Context, userC
}
hostId, _ := data.GetString("host_id")
if len(hostId) == 0 {
return nil, httperrors.NewBadGatewayError("Missing host_id or host id is nil?")
return nil, httperrors.NewBadRequestError("Missing host_id or host id is nil?")
}
if guest.HostId == hostId {
@@ -2307,13 +2315,47 @@ func (manager *SGuestManager) PerformDirtyServerStart(ctx context.Context, userC
err := guest.GuestStartAndSyncToBackup(ctx, userCred, nil, "")
return nil, err
}
// else { // 这里是清除这台机器最后的机会
// err := guest.StartUndeployGuestTask(ctx, userCred, "", hostId)
// return nil, err
// }
return nil, nil
}
func (manager *SGuestManager) AllowPerformDirtyServerVerify(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowClassPerform(userCred, manager, "dirty-server-verify")
}
func (manager *SGuestManager) PerformDirtyServerVerify(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
guestId, err := data.GetString("guest_id")
if err != nil {
return nil, httperrors.NewBadRequestError("Missing guest_id")
}
guest := manager.FetchGuestById(guestId)
if guest == nil {
return nil, httperrors.NewNotFoundError("Guest %s not found", guestId)
}
hostId, _ := data.GetString("host_id")
if len(hostId) == 0 {
return nil, httperrors.NewBadRequestError("Missing host_id or host id is nil?")
}
if guest.HostId != hostId && guest.BackupHostId != hostId {
return nil, guest.StartGuestDeleteOnHostTask(ctx, userCred, hostId, false, "")
}
return nil, nil
}
func (self *SGuest) StartGuestDeleteOnHostTask(ctx context.Context, userCred mcclient.TokenCredential, hostId string, purge bool, parentTaskId string) error {
taskData := jsonutils.NewDict()
taskData.Set("host_id", jsonutils.NewString(hostId))
taskData.Set("purge", jsonutils.NewBool(purge))
if task, err := taskman.TaskManager.NewTask(
ctx, "GuestDeleteOnHostTask", self, userCred, taskData, parentTaskId, "", nil); err != nil {
log.Errorf(err.Error())
return err
} else {
task.ScheduleRun(nil)
}
return nil
}
func (guest *SGuest) GuestStartAndSyncToBackup(ctx context.Context, userCred mcclient.TokenCredential,
data *jsonutils.JSONDict, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "GuestStartAndSyncToBackupTask", guest, userCred, data, parentTaskId, "", nil)
+1
View File
@@ -1336,6 +1336,7 @@ func (self *SGuest) moreExtraInfo(extra *jsonutils.JSONDict) *jsonutils.JSONDict
if len(self.BackupHostId) > 0 {
backupHost := HostManager.FetchHostById(self.BackupHostId)
extra.Set("backup_host_name", jsonutils.NewString(backupHost.Name))
extra.Set("backup_host_status", jsonutils.NewString(backupHost.HostStatus))
}
host := self.GetHost()
+23 -2
View File
@@ -67,8 +67,15 @@ func (self *GuestSwitchToBackupTask) OnBackupGuestStoped(ctx context.Context, gu
}
db.OpsLog.LogEvent(guest, db.ACT_SWITCHED, "Switch to backup", self.UserCred)
logclient.AddActionLogWithContext(ctx, guest, logclient.ACT_SWITCH_TO_BACKUP, "Switch to backup", self.UserCred, true)
self.SetStage("OnNewMasterStarted", nil)
guest.StartGueststartTask(ctx, self.UserCred, nil, self.GetTaskId())
self.SetStage("OnSwitched", nil)
if jsonutils.QueryBoolean(self.Params, "purge_backup", false) {
guest.StartGuestDeleteOnHostTask(ctx, self.UserCred, guest.BackupHostId, true, self.GetTaskId())
} else if jsonutils.QueryBoolean(self.Params, "delete_backup", false) {
guest.StartGuestDeleteOnHostTask(ctx, self.UserCred, guest.BackupHostId, false, self.GetTaskId())
} else {
self.OnSwitched(ctx, guest, nil)
}
}
func (self *GuestSwitchToBackupTask) OnNewMasterStarted(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
@@ -82,6 +89,20 @@ func (self *GuestSwitchToBackupTask) OnFail(ctx context.Context, guest *models.S
self.SetStageFailed(ctx, reason)
}
func (self *GuestSwitchToBackupTask) OnSwitched(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
oldStatus, _ := self.Params.GetString("old_status")
if utils.IsInStringArray(oldStatus, models.VM_RUNNING_STATUS) {
self.SetStage("OnNewMasterStarted", nil)
guest.StartGueststartTask(ctx, self.UserCred, nil, self.GetTaskId())
} else {
self.SetStageComplete(ctx, nil)
}
}
func (self *GuestSwitchToBackupTask) OnSwitchedFailed(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
self.OnFail(ctx, guest, data.String())
}
/********************* GuestStartAndSyncToBackupTask *********************/
type GuestStartAndSyncToBackupTask struct {
+11 -8
View File
@@ -49,20 +49,23 @@ func (self *GuestDeleteOnHostTask) OnStopGuest(ctx context.Context, guest *model
for _, guestDiks := range disks {
disk := guestDiks.GetDisk()
storage := models.StorageManager.FetchStorageById(disk.BackupStorageId)
storage := host.GetStorageByFilePath(disk.AccessPath)
// storage := models.StorageManager.FetchStorageById(disk.BackupStorageId)
if storage != nil && !isPurge {
if err := host.GetHostDriver().RequestDeallocateBackupDiskOnHost(ctx, host, storage, disk, self); err != nil {
self.OnFail(ctx, guest, err.Error())
return
}
}
_, err := models.DiskManager.TableSpec().Update(disk, func() error {
disk.BackupStorageId = ""
return nil
})
if err != nil {
self.OnFail(ctx, guest, err.Error())
return
if disk.BackupStorageId == storage.Id {
_, err := models.DiskManager.TableSpec().Update(disk, func() error {
disk.BackupStorageId = ""
return nil
})
if err != nil {
self.OnFail(ctx, guest, err.Error())
return
}
}
}
if !isPurge {
+1
View File
@@ -47,6 +47,7 @@ func NewClient(authUrl string, timeout int, debug bool, insecure bool, certFile,
DialContext: (&net.Dialer{
Timeout: 5 * time.Second,
}).DialContext,
IdleConnTimeout: 5 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
}
+6
View File
@@ -50,6 +50,12 @@ type ServerDeleteBackupOptions struct {
Purge *bool `help:"Purge Guest Backup" json:"purge"`
}
type ServerSwitchToBackupOptions struct {
ID string `help:"ID of the server" json:"-"`
PurgeBackup *bool `help:"Purge Guest Backup" json:"purge_backup"`
DeleteBackup *bool `help:"Delete Guest Backup" json:"delete_backup"`
}
type ServerShowOptions struct {
ID string `help:"ID or name of the server" json:"-"`
WithMeta *bool `help:"With meta data"`
+1
View File
@@ -107,6 +107,7 @@ func GetClient(insecure bool) *http.Client {
DialContext: (&net.Dialer{
Timeout: 5 * time.Second,
}).DialContext,
IdleConnTimeout: 5 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
TLSClientConfig: &tls.Config{InsecureSkipVerify: insecure},
}