diff --git a/pkg/scheduler/api/sched.go b/pkg/scheduler/api/sched.go index 7c481a0d1c..0245b1ce77 100644 --- a/pkg/scheduler/api/sched.go +++ b/pkg/scheduler/api/sched.go @@ -107,7 +107,9 @@ type SchedData struct { // vm backup schedule // Schedule server with backup server Backup bool `json:"backup"` - // Backup server should be scheduled + // Backup master host + PreferHostId string `json:"prefer_host_id"` + // Backup host should be scheduled BackupHostID string `json:"backup_host_id"` } @@ -138,41 +140,51 @@ func NewSchedData(sjson *simplejson.Json, count int64, byTest bool) (*SchedData, candidates := make([]string, 0) - if hostID, ok := sjson.CheckGet("prefer_host_id"); ok { - if str, err := hostID.String(); err == nil { - candidates = append(candidates, str) - } - } else if hostID, ok := sjson.CheckGet("prefer_host"); ok { - if str, err := hostID.String(); err == nil { - candidates = append(candidates, str) - } - } - - if baremetalID, ok := sjson.CheckGet("prefer_baremetal_id"); ok { - if str, err := baremetalID.String(); err == nil { - candidates = append(candidates, str) - } - } else if baremetalID, ok := sjson.CheckGet("prefer_baremetal"); ok { - if str, err := baremetalID.String(); err == nil { - candidates = append(candidates, str) - } - } - if backupObj, ok := sjson.CheckGet("backup"); ok { if backup, err := backupObj.Bool(); err == nil && backup { data.Backup = true } } + if hostID, ok := sjson.CheckGet("prefer_host_id"); ok { + if str, err := hostID.String(); err == nil { + if !data.Backup { + candidates = append(candidates, str) + } else { + data.PreferHostId = str + } + } + } else if hostID, ok := sjson.CheckGet("prefer_host"); ok { + if str, err := hostID.String(); err == nil { + if !data.Backup { + candidates = append(candidates, str) + } else { + data.PreferHostId = str + } + } + } + + if baremetalID, ok := sjson.CheckGet("prefer_baremetal_id"); ok { + if str, err := baremetalID.String(); err == nil { + if !data.Backup { + candidates = append(candidates, str) + } + } + } else if baremetalID, ok := sjson.CheckGet("prefer_baremetal"); ok { + if str, err := baremetalID.String(); err == nil { + if !data.Backup { + candidates = append(candidates, str) + } + } + } + if backupHostID, ok := sjson.CheckGet("prefer_backup_host_id"); ok { if backHost, err := backupHostID.String(); err == nil { data.BackupHostID = backHost - candidates = append(candidates, backHost) } } else if backupHostID, ok := sjson.CheckGet("prefer_backup_host"); ok { if backHost, err := backupHostID.String(); err == nil { data.BackupHostID = backHost - candidates = append(candidates, backHost) } } diff --git a/pkg/scheduler/handler/backup_helper.go b/pkg/scheduler/handler/backup_helper.go index 483259f6db..da5012df92 100644 --- a/pkg/scheduler/handler/backup_helper.go +++ b/pkg/scheduler/handler/backup_helper.go @@ -11,21 +11,21 @@ import ( schedman "yunion.io/x/onecloud/pkg/scheduler/manager" ) -func transToBackupSchedResult(result *core.SchedResultItemList, preferBackupHost string, count int64) interface{} { +func transToBackupSchedResult(result *core.SchedResultItemList, preferMasterHost, preferBackupHost string, count int64) interface{} { // clean each result sched result item's count for _, item := range result.Data { item.Count = 0 } - apiResults := newBackupSchedResult(result, preferBackupHost, count) + apiResults := newBackupSchedResult(result, preferMasterHost, preferBackupHost, count) return regionResponse(apiResults) } -func newBackupSchedResult(result *core.SchedResultItemList, preferBackupHost string, count int64) []api.SchedResultItem { +func newBackupSchedResult(result *core.SchedResultItemList, preferMasterHost, preferBackupHost string, count int64) []api.SchedResultItem { apiResults := make([]api.SchedResultItem, 0) for i := 0; i < int(count); i++ { log.V(10).Debugf("Select backup host from result: %s", result) - target, err := getSchedBackupResult(result, preferBackupHost) + target, err := getSchedBackupResult(result, preferMasterHost, preferBackupHost) if err != nil { apiResults = append(apiResults, api.SchedErrItem{Error: err.Error()}) continue @@ -35,8 +35,8 @@ func newBackupSchedResult(result *core.SchedResultItemList, preferBackupHost str return apiResults } -func getSchedBackupResult(result *core.SchedResultItemList, preferBackupHost string) (*api.SchedBackupResultItem, error) { - masterHost := selectMasterHost(result.Data, preferBackupHost) +func getSchedBackupResult(result *core.SchedResultItemList, preferMasterHost, preferBackupHost string) (*api.SchedBackupResultItem, error) { + masterHost := selectMasterHost(result.Data, preferMasterHost, preferBackupHost) if masterHost == nil { return nil, fmt.Errorf("Can't find master host") } @@ -64,19 +64,26 @@ func markHostUsed(host *core.SchedResultItem) { // selectMasterID find master host id run VM // return nil if not found -func selectMasterHost(result []*core.SchedResultItem, preferBackupHost string) *core.SchedResultItem { +func selectMasterHost(result []*core.SchedResultItem, preferMasterHost, preferBackupHost string) *core.SchedResultItem { if len(result) == 0 { return nil } host := result[0] if host.Capacity >= 1 && host.ID != preferBackupHost { - return host + if len(preferMasterHost) == 0 { + return host + } + if len(result) == 1 { + return nil + } + restHosts := result[1:] + return selectMasterHost(restHosts, preferMasterHost, preferBackupHost) } if len(result) == 1 { return nil } restHosts := result[1:] - return selectMasterHost(restHosts, preferBackupHost) + return selectMasterHost(restHosts, preferMasterHost, preferBackupHost) } func selectBackupHost(masterID, preferBackupHost string, result []*core.SchedResultItem) *core.SchedResultItem { diff --git a/pkg/scheduler/handler/handler.go b/pkg/scheduler/handler/handler.go index 89ef8bcdc6..4cd1ce390c 100644 --- a/pkg/scheduler/handler/handler.go +++ b/pkg/scheduler/handler/handler.go @@ -261,7 +261,7 @@ func doSyncSchedule(c *gin.Context) { count := schedInfo.Data.Count var resp interface{} if schedInfo.Data.Backup { - resp = transToBackupSchedResult(result, schedInfo.Data.BackupHostID, count) + resp = transToBackupSchedResult(result, schedInfo.Data.HostID, schedInfo.Data.BackupHostID, count) } else { resp = transToRegionSchedResult(result.Data, count) }