dynamic schedule support resource type

This commit is contained in:
Zexi Li
2019-03-23 16:49:04 +08:00
parent 7c8ea8fae9
commit 3ba6d4186c
18 changed files with 265 additions and 137 deletions
+9 -5
View File
@@ -114,14 +114,18 @@ func init() {
})
type DynamicSchedtagEvaluateOptions struct {
ID string `help:"ID or name of the sched policy"`
HOST string `help:"ID or name of the host"`
SERVER string `help:"ID or name of the server"`
ID string `help:"ID or name of the sched policy"`
ResourceType string `help:"Standalone resource type" choices:"host|storage" default:"host"`
VirtaulResourceType string `help:"Virtual resource type" choices:"server|disk" default:"server"`
STANDALONERES string `help:"ID or name of the standalone resource, e.g. host, storage"`
VIRTUALRES string `help:"ID or name of the virtual resource, e.g. server, disk"`
}
R(&DynamicSchedtagEvaluateOptions{}, "dynamic-schedtag-evaluate", "Evaluate dynamic schedtag condition", func(s *mcclient.ClientSession, args *DynamicSchedtagEvaluateOptions) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(args.HOST), "host")
params.Add(jsonutils.NewString(args.SERVER), "server")
params.Add(jsonutils.NewString(args.ResourceType), "resource_type")
params.Add(jsonutils.NewString(args.VirtaulResourceType), "virtual_resource_type")
params.Add(jsonutils.NewString(args.STANDALONERES), "object_id")
params.Add(jsonutils.NewString(args.VIRTUALRES), "virtual_object_id")
result, err := modules.Dynamicschedtags.PerformAction(s, args.ID, "evaluate", params)
if err != nil {
return err
+5 -3
View File
@@ -124,12 +124,14 @@ func init() {
})
type SchedpoliciesEvaluateOptions struct {
ID string `help:"ID or name of the sched policy"`
SERVER string `help:"ID or name of the server"`
ID string `help:"ID or name of the sched policy"`
OBJECT string `help:"ID or name of the object"`
ResourceType string `help:"Resource type of the object" default:"server" choices:"server|disk" short-token:"t"`
}
R(&SchedpoliciesEvaluateOptions{}, "sched-policy-evaluate", "Evaluate sched policy", func(s *mcclient.ClientSession, args *SchedpoliciesEvaluateOptions) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(args.SERVER), "server")
params.Add(jsonutils.NewString(args.OBJECT), "object")
params.Add(jsonutils.NewString(args.ResourceType), "resource_type")
result, err := modules.Schedpolicies.PerformAction(s, args.ID, "evaluate", params)
if err != nil {
return err
+2 -2
View File
@@ -36,7 +36,7 @@ type NetworkConfig struct {
StandbyPortCount int `json:"standby_port_count"`
StandbyAddrCount int `json:"standby_addr_count"`
Project string `json:"project"`
Project string `json:"project_id"`
Ifname string `json:"ifname"`
}
@@ -102,7 +102,7 @@ type ServerConfigs struct {
// ResourceType "shared|prepaid|dedicated"`
ResourceType string `json:"resource_type"`
InstanceType string `json:"instance_type"`
Project string `json:"project"`
Project string `json:"project_id"`
Backup bool `json:"backup"`
Count int `json:"count"`
+9
View File
@@ -1,6 +1,8 @@
package scheduler
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/apis/compute"
)
@@ -56,6 +58,13 @@ type ScheduleInput struct {
ServerConfig
}
func (input ScheduleInput) ToConditionInput() *jsonutils.JSONDict {
ret := input.JSON(input)
// old condition compatible
ret.Add(jsonutils.NewString(input.Project), "owner_tenant_id")
return ret
}
type CandidateDisk struct {
Index int `json:"index"`
StorageId string `json:"storage_id"`
+2
View File
@@ -883,6 +883,8 @@ func doCreateItem(manager IModelManager, ctx context.Context, userCred mcclient.
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
// HACK: set data same as dataDict
data.(*jsonutils.JSONDict).Update(dataDict)
return model, nil
}
+5
View File
@@ -1702,3 +1702,8 @@ func (self *SDisk) IsDetachable() bool {
}
return true
}
func (self *SDisk) GetDynamicConditionInput() *jsonutils.JSONDict {
conf := self.ToDiskConfig()
return conf.JSON(conf)
}
+96 -32
View File
@@ -3,9 +3,11 @@ package models
import (
"context"
"database/sql"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
@@ -13,8 +15,20 @@ import (
"yunion.io/x/onecloud/pkg/util/conditionparser"
)
type IDynamicResourceManager interface {
db.IModelManager
}
type IDynamicResource interface {
db.IModel
GetDynamicConditionInput() *jsonutils.JSONDict
}
type SDynamicschedtagManager struct {
db.SStandaloneResourceBaseManager
StandaloneResourcesManager map[string]IDynamicResourceManager
VirtualResourcesManager map[string]IDynamicResourceManager
}
var DynamicschedtagManager *SDynamicschedtagManager
@@ -27,9 +41,39 @@ func init() {
"dynamicschedtag",
"dynamicschedtags",
),
StandaloneResourcesManager: make(map[string]IDynamicResourceManager),
VirtualResourcesManager: make(map[string]IDynamicResourceManager),
}
}
func (man *SDynamicschedtagManager) bindDynamicResourceManager(
store map[string]IDynamicResourceManager,
ms ...IDynamicResourceManager) {
for _, m := range ms {
store[m.Keyword()] = m
}
}
func (man *SDynamicschedtagManager) BindStandaloneResourceManager(ms ...IDynamicResourceManager) {
man.bindDynamicResourceManager(man.StandaloneResourcesManager, ms...)
}
func (man *SDynamicschedtagManager) BindVirtualResourceManager(ms ...IDynamicResourceManager) {
man.bindDynamicResourceManager(man.VirtualResourcesManager, ms...)
}
func (man *SDynamicschedtagManager) InitializeData() error {
man.BindStandaloneResourceManager(
HostManager,
StorageManager,
)
man.BindVirtualResourceManager(
GuestManager,
DiskManager,
)
return nil
}
// dynamic schedtag is called before scan host candidates, dynamically adding additional schedtag to hosts
// condition examples:
// host.sys_load > 1.5 || host.mem_used_percent > 0.7 => "high_load"
@@ -86,7 +130,8 @@ func validateDynamicSchedtagInputData(data *jsonutils.JSONDict, create bool) err
return httperrors.NewGeneralError(err)
}
}
data.Set("schedtag_id", jsonutils.NewString(schedObj.GetId()))
schedtag := schedObj.(*SSchedtag)
data.Set("schedtag_id", jsonutils.NewString(schedtag.GetId()))
}
return nil
@@ -126,6 +171,7 @@ func (self *SDynamicschedtag) getMoreColumns(extra *jsonutils.JSONDict) *jsonuti
schedtag := self.getSchedtag()
if schedtag != nil {
extra.Add(jsonutils.NewString(schedtag.GetName()), "schedtag")
extra.Add(jsonutils.NewString(schedtag.ResourceType), "resource_type")
}
return extra
}
@@ -143,17 +189,17 @@ func (self *SDynamicschedtag) GetExtraDetails(ctx context.Context, userCred mccl
return self.getMoreColumns(extra), nil
}
func (manager *SDynamicschedtagManager) GetAllEnabledDynamicSchedtags() []SDynamicschedtag {
return manager.getAllEnabledDynamicSchedtags()
}
func (manager *SDynamicschedtagManager) getAllEnabledDynamicSchedtags() []SDynamicschedtag {
func (manager *SDynamicschedtagManager) GetEnabledDynamicSchedtagsByResource(resType string) []SDynamicschedtag {
rules := make([]SDynamicschedtag, 0)
q := DynamicschedtagManager.Query().IsTrue("enabled")
schedtags := SchedtagManager.Query().SubQuery()
q = q.Join(schedtags, sqlchemy.AND(
sqlchemy.Equals(q.Field("schedtag_id"), schedtags.Field("id")),
sqlchemy.Equals(schedtags.Field("resource_type"), resType)))
err := db.FetchModelObjects(manager, q, &rules)
if err != nil {
log.Errorf("getAllEnabledDynamicSchedtags fail %s", err)
log.Errorf("GetEnabledDynamicSchedtagsByResource %s fail %s", resType, err)
return nil
}
@@ -165,44 +211,46 @@ func (self *SDynamicschedtag) AllowPerformEvaluate(ctx context.Context, userCred
}
func (self *SDynamicschedtag) PerformEvaluate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
serverStr := jsonutils.GetAnyString(data, []string{"server", "server_id", "guest", "guest_id"})
serverObj, err := GuestManager.FetchByIdOrName(userCred, serverStr)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError("server %s not found", serverStr)
} else {
return nil, httperrors.NewGeneralError(err)
}
objectId := jsonutils.GetAnyString(data, []string{"object", "object_id"})
resType := jsonutils.GetAnyString(data, []string{"resource_type"})
virtObjId := jsonutils.GetAnyString(data, []string{"virtual_object", "virtual_object_id"})
virtType := jsonutils.GetAnyString(data, []string{"virtual_resource_type"})
objectMan := DynamicschedtagManager.StandaloneResourcesManager[resType]
if objectMan == nil {
return nil, httperrors.NewResourceNotFoundError("Resource type %s not support", resType)
}
virtObjectMan := DynamicschedtagManager.VirtualResourcesManager[virtType]
if virtObjectMan == nil {
return nil, httperrors.NewResourceNotFoundError("Virtual resource type %s not support", virtType)
}
server := serverObj.(*SGuest)
srvDesc := server.getSchedDesc()
hostStr := jsonutils.GetAnyString(data, []string{"host", "host_id"})
hostObj, err := HostManager.FetchByIdOrName(userCred, hostStr)
object, err := FetchDynamicResourceObject(objectMan, userCred, objectId)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError("host %s not found", serverStr)
} else {
return nil, httperrors.NewGeneralError(err)
}
return nil, err
}
virtObject, err := FetchDynamicResourceObject(virtObjectMan, userCred, virtObjId)
if err != nil {
return nil, err
}
host := hostObj.(*SHost)
// TODO: to fill host scheduling information
hostDesc := jsonutils.Marshal(host)
// TODO: to fill standalone resource scheduling information
standaloneDesc := object.GetDynamicConditionInput()
virtDesc := virtObject.GetDynamicConditionInput()
params := jsonutils.NewDict()
params.Add(srvDesc.JSON(srvDesc), "server")
params.Add(hostDesc, "host")
params.Add(standaloneDesc, object.Keyword())
params.Add(virtDesc, virtObject.Keyword())
log.V(10).Debugf("Dynamicschedtag evaluate input: %s", params.PrettyString())
meet, err := conditionparser.Eval(self.Condition, params)
if err != nil {
return nil, err
}
result := jsonutils.NewDict()
result.Add(srvDesc.JSON(srvDesc), "server")
result.Add(hostDesc, "host")
result.Add(standaloneDesc, object.Keyword())
result.Add(virtDesc, virtObject.Keyword())
if meet {
result.Add(jsonutils.JSONTrue, "result")
@@ -211,3 +259,19 @@ func (self *SDynamicschedtag) PerformEvaluate(ctx context.Context, userCred mccl
}
return result, nil
}
func FetchDynamicResourceObject(man IDynamicResourceManager, userCred mcclient.TokenCredential, idOrName string) (IDynamicResource, error) {
obj, err := man.FetchByIdOrName(userCred, idOrName)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError("%s %s not found", man.Keyword(), idOrName)
} else {
return nil, httperrors.NewGeneralError(err)
}
}
res, ok := obj.(IDynamicResource)
if !ok {
return nil, httperrors.NewGeneralError(fmt.Errorf("%s %s not implement IDynamicResource", obj.Keyword(), obj.GetName()))
}
return res, nil
}
+16 -44
View File
@@ -3888,43 +3888,6 @@ func (self *SGuest) getDefaultStorageType() string {
return STORAGE_LOCAL
}
func (self *SGuest) getSchedDesc() *schedapi.ScheduleInput {
desc := new(schedapi.ScheduleInput)
desc.Id = self.Id
desc.Name = self.Name
desc.Memory = self.VmemSize
desc.Ncpu = int(self.VcpuCount)
gds := self.GetDisks()
if gds != nil {
for i := 0; i < len(gds); i += 1 {
conf := new(api.DiskConfig)
jsonutils.Marshal(gds[i].ToDiskInfo()).Unmarshal(conf)
desc.Disks = append(desc.Disks, conf)
}
}
gns, _ := self.GetNetworks("")
if gns != nil {
for i := 0; i < len(gns); i += 1 {
desc.Networks = append(desc.Networks, &api.NetworkConfig{
Network: gns[i].NetworkId,
Address: gns[i].IpAddr,
})
}
}
if len(self.HostId) > 0 && regutils.MatchUUID(self.HostId) {
desc.HostId = self.HostId
}
desc.Project = self.ProjectId
desc.Hypervisor = self.GetHypervisor()
return desc
}
func (self *SGuest) GetApptags() []string {
tagsStr := self.GetMetadata("app_tags", nil)
if len(tagsStr) > 0 {
@@ -3936,13 +3899,15 @@ func (self *SGuest) GetApptags() []string {
func (self *SGuest) ToSchedDesc() *schedapi.ScheduleInput {
desc := new(schedapi.ScheduleInput)
config := &schedapi.ServerConfig{
Name: self.Name,
Memory: self.VmemSize,
Ncpu: int(self.VcpuCount),
Name: self.Name,
Memory: self.VmemSize,
Ncpu: int(self.VcpuCount),
ServerConfigs: new(api.ServerConfigs),
}
desc.Id = self.Id
//self.FillGroupSchedDesc(desc)
self.FillDiskSchedDesc(config)
self.FillNetSchedDesc(config)
self.FillDiskSchedDesc(config.ServerConfigs)
self.FillNetSchedDesc(config.ServerConfigs)
if len(self.HostId) > 0 && regutils.MatchUUID(self.HostId) {
config.HostId = self.HostId
}
@@ -3970,7 +3935,7 @@ func (self *SGuest) ToSchedDesc() *schedapi.ScheduleInput {
}
}*/
func (self *SGuest) FillDiskSchedDesc(desc *schedapi.ServerConfig) {
func (self *SGuest) FillDiskSchedDesc(desc *api.ServerConfigs) {
guestDisks := make([]SGuestdisk, 0)
err := GuestdiskManager.Query().Equals("guest_id", self.Id).All(&guestDisks)
if err != nil {
@@ -3982,13 +3947,16 @@ func (self *SGuest) FillDiskSchedDesc(desc *schedapi.ServerConfig) {
}
}
func (self *SGuest) FillNetSchedDesc(desc *schedapi.ServerConfig) {
func (self *SGuest) FillNetSchedDesc(desc *api.ServerConfigs) {
guestNetworks := make([]SGuestnetwork, 0)
err := GuestnetworkManager.Query().Equals("guest_id", self.Id).All(&guestNetworks)
if err != nil {
log.Errorln("FillNetSchedDesc: %v", err)
return
}
if desc.Networks == nil {
desc.Networks = make([]*api.NetworkConfig, 0)
}
for i := 0; i < len(guestNetworks); i++ {
desc.Networks = append(desc.Networks, guestNetworks[i].ToNetworkConfig())
}
@@ -4040,3 +4008,7 @@ func (guest *SGuest) GetDetailsTasks(ctx context.Context, userCred mcclient.Toke
ret.Add(jsonutils.NewArray(objs...), "tasks")
return ret, nil
}
func (guest *SGuest) GetDynamicConditionInput() *jsonutils.JSONDict {
return guest.ToSchedDesc().ToConditionInput()
}
+4
View File
@@ -3814,3 +3814,7 @@ func (host *SHost) PerformSetSchedtag(ctx context.Context, userCred mcclient.Tok
host.ClearSchedDescCache()
return nil, nil
}
func (host *SHost) GetDynamicConditionInput() *jsonutils.JSONDict {
return jsonutils.Marshal(host).(*jsonutils.JSONDict)
}
+1
View File
@@ -28,6 +28,7 @@ func InitDB() error {
LoadbalancerBackendGroupManager,
LoadbalancerBackendManager,
SchedtagManager,
DynamicschedtagManager,
} {
err := manager.InitializeData()
if err != nil {
+92 -39
View File
@@ -2,11 +2,11 @@ package models
import (
"context"
"database/sql"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
schedapi "yunion.io/x/onecloud/pkg/apis/scheduler"
@@ -113,6 +113,7 @@ func (self *SSchedpolicy) getMoreColumns(extra *jsonutils.JSONDict) *jsonutils.J
schedtag := self.getSchedtag()
if schedtag != nil {
extra.Add(jsonutils.NewString(schedtag.GetName()), "schedtag")
extra.Add(jsonutils.NewString(schedtag.ResourceType), "resource_type")
}
return extra
}
@@ -130,46 +131,58 @@ func (self *SSchedpolicy) GetExtraDetails(ctx context.Context, userCred mcclient
return self.getMoreColumns(extra), nil
}
func (manager *SSchedpolicyManager) getAllEnabledPolicies() []SSchedpolicy {
func (manager *SSchedpolicyManager) getAllEnabledPoliciesByResource(resType string) []SSchedpolicy {
policies := make([]SSchedpolicy, 0)
q := SchedpolicyManager.Query().IsTrue("enabled")
schedtags := SchedtagManager.Query().SubQuery()
q = q.Join(schedtags, sqlchemy.AND(
sqlchemy.Equals(q.Field("schedtag_id"), schedtags.Field("id")),
sqlchemy.Equals(schedtags.Field("resource_type"), resType)))
err := db.FetchModelObjects(manager, q, &policies)
if err != nil {
log.Errorf("getAllEnabledPolicies fail %s", err)
return nil
}
return policies
}
func (manager *SSchedpolicyManager) getHostEnabledPolicies() []SSchedpolicy {
return manager.getAllEnabledPoliciesByResource(HostManager.KeywordPlural())
}
func (manager *SSchedpolicyManager) getStorageEnabledPolicies() []SSchedpolicy {
return manager.getAllEnabledPoliciesByResource(StorageManager.KeywordPlural())
}
func (self *SSchedpolicy) AllowPerformEvaluate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowPerform(userCred, self, "evaluate")
}
func (self *SSchedpolicy) PerformEvaluate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
serverStr := jsonutils.GetAnyString(data, []string{"server", "server_id", "guest", "guest_id"})
serverObj, err := GuestManager.FetchByIdOrName(userCred, serverStr)
objectId := jsonutils.GetAnyString(data, []string{"object", "object_id"})
resType := jsonutils.GetAnyString(data, []string{"resource_type"})
resMan := DynamicschedtagManager.VirtualResourcesManager[resType]
if resMan == nil {
return nil, httperrors.NewNotAcceptableError("ResourceType %q not support", resType)
}
obj, err := FetchDynamicResourceObject(resMan, userCred, objectId)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError("server %s not found", serverStr)
} else {
return nil, httperrors.NewGeneralError(err)
}
return nil, err
}
server := serverObj.(*SGuest)
desc := server.getSchedDesc()
desc := obj.GetDynamicConditionInput()
params := jsonutils.NewDict()
params.Add(desc.JSON(desc), "server")
params.Add(desc, obj.Keyword())
log.V(10).Debugf("Schedpolicy evaluate input: %s", params.PrettyString())
meet, err := conditionparser.Eval(self.Condition, params)
if err != nil {
return nil, err
}
result := jsonutils.NewDict()
result.Add(desc.JSON(desc), "server")
result.Add(desc, obj.Keyword())
if meet {
result.Add(jsonutils.JSONTrue, "result")
} else {
@@ -178,45 +191,85 @@ func (self *SSchedpolicy) PerformEvaluate(ctx context.Context, userCred mcclient
return result, nil
}
func ApplySchedPolicies(params *schedapi.ScheduleInput) *schedapi.ScheduleInput {
policies := SchedpolicyManager.getAllEnabledPolicies()
if policies == nil {
log.Errorf("getAllEnabledPolicies fail")
//return jsonutils.Marshal(params).(*jsonutils.JSONDict)
return params
func matchResourceSchedPolicy(
policy SSchedpolicy,
input *jsonutils.JSONDict,
) bool {
meet, err := conditionparser.Eval(policy.Condition, input)
if err != nil {
log.Errorf("Eval Condition %s error: %v", policy.Condition, err)
return false
}
return meet
}
func applyResourceSchedPolicy(
policies []SSchedpolicy,
oldTags []*api.SchedtagConfig,
input *jsonutils.JSONDict,
setTags func([]*api.SchedtagConfig),
) {
schedtags := make(map[string]string)
if len(params.ServerConfig.Schedtags) != 0 {
for _, tag := range params.ServerConfig.Schedtags {
schedtags[tag.Id] = tag.Strategy
}
log.Infof("original sched tag %#v", schedtags)
for _, tag := range oldTags {
schedtags[tag.Id] = tag.Strategy
}
input := jsonutils.NewDict()
input.Add(jsonutils.Marshal(params), "server")
log.Infof("original schedtag %#v", schedtags)
for i := 0; i < len(policies); i += 1 {
meet, err := conditionparser.Eval(policies[i].Condition, input)
if err == nil && meet {
st := policies[i].getSchedtag()
if st != nil {
schedtags[st.Name] = policies[i].Strategy
}
policy := policies[i]
st := policy.getSchedtag()
if matchResourceSchedPolicy(policy, input) {
schedtags[st.Name] = policy.Strategy
}
}
log.Infof("updated sched tag %s", schedtags)
params.ServerConfig.Schedtags = make([]*api.SchedtagConfig, 0)
newSchedtags := make([]*api.SchedtagConfig, 0)
for name, strategy := range schedtags {
params.ServerConfig.Schedtags = append(params.ServerConfig.Schedtags, &api.SchedtagConfig{
newSchedtags = append(newSchedtags, &api.SchedtagConfig{
Id: name,
Strategy: strategy,
})
}
return params
setTags(newSchedtags)
}
func GetDynamicConditionInput(man IDynamicResourceManager, input *jsonutils.JSONDict) *jsonutils.JSONDict {
ret := jsonutils.NewDict()
ret.Add(input, man.Keyword())
return ret
}
func applyServerSchedtags(policies []SSchedpolicy, input *schedapi.ScheduleInput) {
inputCond := GetDynamicConditionInput(GuestManager, input.ToConditionInput())
setFunc := func(tags []*api.SchedtagConfig) {
input.Schedtags = tags
}
applyResourceSchedPolicy(policies, input.Schedtags, inputCond, setFunc)
}
func applyDiskSchedtags(policies []SSchedpolicy, input *api.DiskConfig) {
inputCond := GetDynamicConditionInput(DiskManager, jsonutils.Marshal(input).(*jsonutils.JSONDict))
setFunc := func(tags []*api.SchedtagConfig) {
input.Schedtags = tags
}
applyResourceSchedPolicy(policies, input.Schedtags, inputCond, setFunc)
}
func ApplySchedPolicies(input *schedapi.ScheduleInput) *schedapi.ScheduleInput {
hostPolicies := SchedpolicyManager.getHostEnabledPolicies()
storagePolicies := SchedpolicyManager.getStorageEnabledPolicies()
config := input.ServerConfigs
applyServerSchedtags(hostPolicies, input)
for _, disk := range config.Disks {
applyDiskSchedtags(storagePolicies, disk)
}
input.ServerConfig.ServerConfigs = config
return input
}
+4
View File
@@ -1151,3 +1151,7 @@ func (self *SStorage) IsPrepaidRecycleResource() bool {
func (self *SStorage) GetSchedtags() []SSchedtag {
return GetSchedtags(StorageschedtagManager, self.Id)
}
func (self *SStorage) GetDynamicConditionInput() *jsonutils.JSONDict {
return jsonutils.Marshal(self).(*jsonutils.JSONDict)
}
+3 -2
View File
@@ -6,8 +6,9 @@ var (
func init() {
Dynamicschedtags = NewComputeManager("dynamicschedtag", "dynamicschedtags",
[]string{"ID", "Name", "Description",
"Condition", "Schedtag", "Schedtag_Id", "Enabled"},
[]string{
"ID", "Name", "Description", "Condition", "Schedtag",
"Schedtag_Id", "Resource_Type", "Enabled"},
[]string{})
registerComputeV2(&Dynamicschedtags)
+4 -2
View File
@@ -6,8 +6,10 @@ var (
func init() {
Schedpolicies = NewComputeManager("schedpolicy", "schedpolicies",
[]string{"ID", "Name", "Description",
"Condition", "Schedtag", "Schedtag_Id", "Strategy", "Enabled"},
[]string{
"ID", "Name", "Description", "Condition", "Schedtag",
"Resource_Type", "Schedtag_Id", "Strategy", "Enabled",
},
[]string{})
registerComputeV2(&Schedpolicies)
+1 -1
View File
@@ -178,7 +178,7 @@ type BaseListOptions struct {
JointFilter []string `help:"Filters with joint table col; joint_tbl.related_key(origin_key).filter_col.filter_cond(filters)"`
FilterAny *bool `help:"If true, match if any of the filters matches; otherwise, match if all of the filters match"`
Admin *bool `help:"Is an admin call?"`
Tenant string `help:"Tenant ID or Name"`
Tenant string `help:"Tenant ID or Name" alias:"project"`
User string `help:"User ID or Name"`
System *bool `help:"Show system resource"`
PendingDelete *bool `help:"Show only pending deleted resource"`
@@ -69,9 +69,9 @@ type schedtagCandidateW struct {
func (w schedtagCandidateW) GetDynamicSchedDesc() *jsonutils.JSONDict {
ret := jsonutils.NewDict()
hostSchedDesc := w.GetSchedDesc()
srvSchedDesc := jsonutils.Marshal(w.schedData)
ret.Add(hostSchedDesc, "host")
ret.Add(srvSchedDesc, "server")
srvSchedDesc := w.schedData.ToConditionInput()
ret.Add(hostSchedDesc, computemodels.HostManager.Keyword())
ret.Add(srvSchedDesc, computemodels.GuestManager.Keyword())
return ret
}
@@ -127,7 +127,12 @@ func (w schedtagStorageW) IndexKey() string {
}
func (w schedtagStorageW) GetDynamicSchedDesc() *jsonutils.JSONDict {
return nil
ret := jsonutils.NewDict()
storageSchedDesc := w.candidater.GetDynamicConditionInput()
diskSchedDesc := w.disk.JSON(w.disk)
ret.Add(storageSchedDesc, models.StorageManager.Keyword())
ret.Add(diskSchedDesc, models.DiskManager.Keyword())
return ret
}
func (w schedtagStorageW) GetSchedtags() []models.SSchedtag {
@@ -187,11 +187,11 @@ func (c *SchedtagChecker) Contains(objectTags []models.SSchedtag, tags []compute
return true, nil
}
func (p *SchedtagChecker) getDynamicSchedtags(schedDesc *jsonutils.JSONDict) ([]models.SSchedtag, error) {
func (p *SchedtagChecker) getDynamicSchedtags(resType string, schedDesc *jsonutils.JSONDict) ([]models.SSchedtag, error) {
if schedDesc == nil {
return []models.SSchedtag{}, nil
}
dynamicTags := models.DynamicschedtagManager.GetAllEnabledDynamicSchedtags()
dynamicTags := models.DynamicschedtagManager.GetEnabledDynamicSchedtagsByResource(resType)
tags := []models.SSchedtag{}
for _, tag := range dynamicTags {
@@ -233,7 +233,7 @@ func (c *SchedtagChecker) mergeSchedtags(candiate ISchedtagCandidate, staticTags
func (c *SchedtagChecker) GetCandidateSchedtags(candidate ISchedtagCandidate) ([]models.SSchedtag, error) {
staticTags := candidate.GetSchedtags()
dynamicTags, err := c.getDynamicSchedtags(candidate.GetDynamicSchedDesc())
dynamicTags, err := c.getDynamicSchedtags(candidate.ResourceType(), candidate.GetDynamicSchedDesc())
if err != nil {
return nil, err
}