region: storage support set schedtags (#223)

This commit is contained in:
Zexi Li
2019-04-08 10:25:31 +08:00
committed by yunion-ci-robot
parent bf0274779b
commit 599aa4a6f6
8 changed files with 191 additions and 99 deletions
-17
View File
@@ -518,21 +518,4 @@ func init() {
printObject(result)
return nil
})
type HostSetSchedtagOptions struct {
ID string `help:"ID or Name of host"`
Schedtag []string `help:"Ids of schedtag"`
}
R(&HostSetSchedtagOptions{}, "host-set-schedtag", "Set schedtags to a host", func(s *mcclient.ClientSession, args *HostSetSchedtagOptions) error {
params := jsonutils.NewDict()
for idx, tag := range args.Schedtag {
params.Add(jsonutils.NewString(tag), fmt.Sprintf("schedtag.%d", idx))
}
result, err := modules.Hosts.PerformAction(s, args.ID, "set-schedtag", params)
if err != nil {
return err
}
printObject(result)
return nil
})
}
+20
View File
@@ -35,6 +35,7 @@ func (h *schedtagModelHelper) register() {
h.list(man.Slave, man.Slave.GetKeyword())
h.add(man, man.Slave.GetKeyword())
h.remove(man, man.Slave.GetKeyword())
h.setTags(man, man.Slave.GetKeyword())
}
}
@@ -97,6 +98,25 @@ func (h *schedtagModelHelper) remove(man modules.JointResourceManager, kw string
})
}
func (h *schedtagModelHelper) setTags(man modules.JointResourceManager, kw string) {
R(
&options.SchedtagSetOptions{},
fmt.Sprintf("%s-set-schedtag", kw),
fmt.Sprintf("Set schedtags to %v", kw),
func(s *mcclient.ClientSession, args *options.SchedtagSetOptions) error {
params, err := args.Params()
if err != nil {
return err
}
ret, err := man.Slave.PerformAction(s, args.ID, "set-schedtag", params)
if err != nil {
return err
}
printObject(ret)
return nil
})
}
func init() {
newSchedtagModelHelper(
modules.Schedtaghosts,
-1
View File
@@ -228,5 +228,4 @@ func init() {
printObject(storage)
return nil
})
}
+8 -76
View File
@@ -515,9 +515,7 @@ func (self *SHost) StartDeleteBaremetalTask(ctx context.Context, userCred mcclie
}
func (self *SHost) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
for _, hostschedtag := range self.GetHostschedtags() {
hostschedtag.Delete(ctx, userCred)
}
DeleteResourceJointSchedtags(self, ctx, userCred)
IsolatedDeviceManager.DeleteDevicesByHost(ctx, userCred, self)
@@ -555,17 +553,6 @@ func (self *SHost) RealDelete(ctx context.Context, userCred mcclient.TokenCreden
return self.SEnabledStatusStandaloneResourceBase.Delete(ctx, userCred)
}
func (self *SHost) GetHostschedtags() []SHostschedtag {
q := HostschedtagManager.Query().Equals("host_id", self.Id)
hostschedtags := make([]SHostschedtag, 0)
err := db.FetchModelObjects(HostschedtagManager, q, &hostschedtags)
if err != nil {
log.Errorf("GetHostschedtags error %s", err)
return nil
}
return hostschedtags
}
func (self *SHost) GetHoststoragesQuery() *sqlchemy.SQuery {
return HoststorageManager.Query().Equals("host_id", self.Id)
}
@@ -2193,14 +2180,7 @@ func (self *SHost) getMoreDetails(ctx context.Context, extra *jsonutils.JSONDict
extra.Add(jsonutils.NewInt(int64(len(nicInfos))), "nic_count")
extra.Add(jsonutils.NewArray(nicInfos...), "nic_info")
}
schedtags := self.GetSchedtags()
if schedtags != nil && len(schedtags) > 0 {
info := make([]jsonutils.JSONObject, len(schedtags))
for i := 0; i < len(schedtags); i += 1 {
info[i] = schedtags[i].GetShortDesc(ctx)
}
extra.Add(jsonutils.NewArray(info...), "schedtags")
}
extra = GetSchedtagsDetailsToResource(self, ctx, extra)
var usage *SHostGuestResourceUsage
if options.Options.IgnoreNonrunningGuests {
usage = self.getGuestsResource(VM_RUNNING)
@@ -3802,63 +3782,11 @@ func (self *SHost) IsPrepaidRecycleResource() bool {
}
func (host *SHost) AllowPerformSetSchedtag(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowPerform(userCred, host, "set-schedtag")
}
func (host *SHost) getHostschedtags() []SHostschedtag {
tags := make([]SHostschedtag, 0)
hostschedtags := HostschedtagManager.Query().SubQuery()
q := hostschedtags.Query().Equals("host_id", host.Id)
err := db.FetchModelObjects(HostschedtagManager, q, &tags)
if err != nil {
log.Errorf("Get hostschedtags: %v", err)
return nil
}
return tags
return AllowPerformSetResourceSchedtag(host, ctx, userCred, query, data)
}
func (host *SHost) PerformSetSchedtag(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
schedtags := jsonutils.GetArrayOfPrefix(data, "schedtag")
setTagsId := []string{}
for idx := 0; idx < len(schedtags); idx++ {
schedtagIdent, _ := schedtags[idx].GetString()
tag, err := SchedtagManager.FetchByIdOrName(userCred, schedtagIdent)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewNotFoundError("Schedtag %s not found", schedtagIdent)
}
return nil, httperrors.NewGeneralError(err)
}
setTagsId = append(setTagsId, tag.GetId())
}
oldTags := host.getHostschedtags()
for _, oldTag := range oldTags {
if !utils.IsInStringArray(oldTag.SchedtagId, setTagsId) {
if err := oldTag.Detach(ctx, userCred); err != nil {
return nil, httperrors.NewGeneralError(err)
}
}
}
var oldTagIds []string
for _, tag := range oldTags {
oldTagIds = append(oldTagIds, tag.SchedtagId)
}
for _, setTagId := range setTagsId {
if !utils.IsInStringArray(setTagId, oldTagIds) {
if newTagObj, err := db.NewModelObject(HostschedtagManager); err != nil {
return nil, httperrors.NewGeneralError(err)
} else {
newTag := newTagObj.(*SHostschedtag)
newTag.HostId = host.Id
newTag.SchedtagId = setTagId
if err := newTag.GetModelManager().TableSpec().Insert(newTag); err != nil {
return nil, httperrors.NewGeneralError(err)
}
}
}
}
host.ClearSchedDescCache()
return nil, nil
return PerformSetResourceSchedtag(host, ctx, userCred, query, data)
}
func (host *SHost) GetDynamicConditionInput() *jsonutils.JSONDict {
@@ -3873,3 +3801,7 @@ func (host *SHost) PerformStatus(ctx context.Context, userCred mcclient.TokenCre
host.ClearSchedDescCache()
return ret, nil
}
func (host *SHost) GetSchedtagJointManager() ISchedtagJointManager {
return HostschedtagManager
}
+6 -2
View File
@@ -115,6 +115,10 @@ func (self *SSchedtagJointsBase) AllowDeleteItem(ctx context.Context, userCred m
return db.IsAdminAllowDelete(userCred, self)
}
func (joint *SSchedtagJointsBase) GetSchedtagId() string {
return joint.SchedtagId
}
func (joint *SSchedtagJointsBase) master(obj db.IJointModel) db.IStandaloneModel {
return db.JointMaster(obj)
}
@@ -145,7 +149,7 @@ func (joint *SSchedtagJointsBase) Delete(ctx context.Context, userCred mcclient.
}
func (joint *SSchedtagJointsBase) delete(obj db.IJointModel, ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DeleteModel(ctx, userCred, joint)
return db.DeleteModel(ctx, userCred, obj)
}
func (joint *SSchedtagJointsBase) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
@@ -153,5 +157,5 @@ func (joint *SSchedtagJointsBase) Detach(ctx context.Context, userCred mcclient.
}
func (joint *SSchedtagJointsBase) detach(obj db.IJointModel, ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DetachJoint(ctx, userCred, joint)
return db.DetachJoint(ctx, userCred, obj)
}
+121
View File
@@ -50,6 +50,17 @@ type ISchedtagJointManager interface {
GetMasterIdKey(db.IJointModelManager) string
}
type ISchedtagJointModel interface {
db.IJointModel
GetSchedtagId() string
}
type IModelWithSchedtag interface {
db.IModel
GetSchedtagJointManager() ISchedtagJointManager
ClearSchedDescCache() error
}
type SSchedtagManager struct {
db.SStandaloneResourceBaseManager
@@ -305,6 +316,33 @@ func (self *SSchedtag) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
return desc
}
func GetResourceJointSchedtags(obj IModelWithSchedtag) ([]ISchedtagJointModel, error) {
jointMan := obj.GetSchedtagJointManager()
q := jointMan.Query().Equals(jointMan.GetMasterIdKey(jointMan), obj.GetId())
jointTags := make([]ISchedtagJointModel, 0)
rows, err := q.Rows()
if err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return nil, err
}
defer rows.Close()
for rows.Next() {
item, err := db.NewModelObject(jointMan)
if err != nil {
return nil, err
}
err = q.Row2Struct(rows, item)
if err != nil {
return nil, err
}
jointTags = append(jointTags, item.(ISchedtagJointModel))
}
return jointTags, nil
}
func GetSchedtags(jointMan ISchedtagJointManager, masterId string) []SSchedtag {
tags := make([]SSchedtag, 0)
schedtags := SchedtagManager.Query().SubQuery()
@@ -320,3 +358,86 @@ func GetSchedtags(jointMan ISchedtagJointManager, masterId string) []SSchedtag {
}
return tags
}
func AllowPerformSetResourceSchedtag(obj db.IModel, ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowPerform(userCred, obj, "set-schedtag")
}
func PerformSetResourceSchedtag(obj IModelWithSchedtag, ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
schedtags := jsonutils.GetArrayOfPrefix(data, "schedtag")
setTagsId := []string{}
for idx := 0; idx < len(schedtags); idx++ {
schedtagIdent, _ := schedtags[idx].GetString()
tag, err := SchedtagManager.FetchByIdOrName(userCred, schedtagIdent)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewNotFoundError("Schedtag %s not found", schedtagIdent)
}
return nil, httperrors.NewGeneralError(err)
}
schedtag := tag.(*SSchedtag)
if schedtag.ResourceType != obj.KeywordPlural() {
return nil, httperrors.NewInputParameterError("Schedtag %s ResourceType is %s, not match %s", schedtag.GetName(), schedtag.ResourceType, obj.KeywordPlural())
}
setTagsId = append(setTagsId, schedtag.GetId())
}
oldTags, err := GetResourceJointSchedtags(obj)
if err != nil {
return nil, httperrors.NewGeneralError(fmt.Errorf("Get old joint schedtags: %v", err))
}
for _, oldTag := range oldTags {
if !utils.IsInStringArray(oldTag.GetId(), setTagsId) {
if err := oldTag.Detach(ctx, userCred); err != nil {
return nil, httperrors.NewGeneralError(err)
}
}
}
var oldTagIds []string
for _, tag := range oldTags {
oldTagIds = append(oldTagIds, tag.GetSchedtagId())
}
jointMan := obj.GetSchedtagJointManager()
for _, setTagId := range setTagsId {
if !utils.IsInStringArray(setTagId, oldTagIds) {
if newTagObj, err := db.NewModelObject(jointMan); err != nil {
return nil, httperrors.NewGeneralError(err)
} else {
objectKey := jointMan.GetMasterIdKey(jointMan)
createData := jsonutils.NewDict()
createData.Add(jsonutils.NewString(setTagId), "schedtag_id")
createData.Add(jsonutils.NewString(obj.GetId()), objectKey)
if err := createData.Unmarshal(newTagObj); err != nil {
return nil, httperrors.NewGeneralError(fmt.Errorf("Create %s joint schedtag error: %v", jointMan.Keyword(), err))
}
if err := newTagObj.GetModelManager().TableSpec().Insert(newTagObj); err != nil {
return nil, httperrors.NewGeneralError(err)
}
}
}
}
obj.ClearSchedDescCache()
return nil, nil
}
func DeleteResourceJointSchedtags(obj IModelWithSchedtag, ctx context.Context, userCred mcclient.TokenCredential) error {
jointTags, err := GetResourceJointSchedtags(obj)
if err != nil {
return fmt.Errorf("Get %s schedtags error: %v", obj.Keyword(), err)
}
for _, tag := range jointTags {
tag.Delete(ctx, userCred)
}
return nil
}
func GetSchedtagsDetailsToResource(obj IModelWithSchedtag, ctx context.Context, extra *jsonutils.JSONDict) *jsonutils.JSONDict {
schedtags := GetSchedtags(obj.GetSchedtagJointManager(), obj.GetId())
if schedtags != nil && len(schedtags) > 0 {
info := make([]jsonutils.JSONObject, len(schedtags))
for i := 0; i < len(schedtags); i += 1 {
info[i] = schedtags[i].GetShortDesc(ctx)
}
extra.Add(jsonutils.NewArray(info...), "schedtags")
}
return extra
}
+21 -3
View File
@@ -183,6 +183,11 @@ func (self *SStorage) AllowDeleteItem(ctx context.Context, userCred mcclient.Tok
return db.IsAdminAllowDelete(userCred, self)
}
func (self *SStorage) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
DeleteResourceJointSchedtags(self, ctx, userCred)
return self.SStandaloneResourceBase.Delete(ctx, userCred)
}
func (manager *SStorageManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
storageType, _ := data.GetString("storage_type")
mediumType, _ := data.GetString("medium_type")
@@ -360,7 +365,7 @@ func (self *SStorage) getStorageCapacity() SStorageCapacity {
return capa
}
func (self *SStorage) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict {
func (self *SStorage) getMoreDetails(ctx context.Context, extra *jsonutils.JSONDict) *jsonutils.JSONDict {
capa := self.getStorageCapacity()
extra.Update(capa.ToJson())
@@ -368,13 +373,14 @@ func (self *SStorage) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSOND
info := self.getCloudProviderInfo()
extra.Update(jsonutils.Marshal(&info))
extra = GetSchedtagsDetailsToResource(self, ctx, extra)
return extra
}
func (self *SStorage) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
extra := self.SStandaloneResourceBase.GetCustomizeColumns(ctx, userCred, query)
return self.getMoreDetails(extra)
return self.getMoreDetails(ctx, extra)
}
func (self *SStorage) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*jsonutils.JSONDict, error) {
@@ -382,7 +388,7 @@ func (self *SStorage) GetExtraDetails(ctx context.Context, userCred mcclient.Tok
if err != nil {
return nil, err
}
return self.getMoreDetails(extra), nil
return self.getMoreDetails(ctx, extra), nil
}
func (self *SStorage) GetUsedCapacity(isReady tristate.TriState) int {
@@ -1176,3 +1182,15 @@ func (self *SStorage) GetSchedtags() []SSchedtag {
func (self *SStorage) GetDynamicConditionInput() *jsonutils.JSONDict {
return jsonutils.Marshal(self).(*jsonutils.JSONDict)
}
func (self *SStorage) AllowPerformSetSchedtag(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return AllowPerformSetResourceSchedtag(self, ctx, userCred, query, data)
}
func (self *SStorage) PerformSetSchedtag(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return PerformSetResourceSchedtag(self, ctx, userCred, query, data)
}
func (self *SStorage) GetSchedtagJointManager() ISchedtagJointManager {
return StorageschedtagManager
}
+15
View File
@@ -15,6 +15,8 @@
package options
import (
"fmt"
"yunion.io/x/jsonutils"
)
@@ -35,3 +37,16 @@ type SchedtagModelPairOptions struct {
SCHEDTAG string `help:"Scheduler tag"`
OBJECT string `help:"Object id"`
}
type SchedtagSetOptions struct {
ID string `help:"Id or name of resource"`
Schedtag []string `help:"Ids of schedtag"`
}
func (o SchedtagSetOptions) Params() (*jsonutils.JSONDict, error) {
params := jsonutils.NewDict()
for idx, tag := range o.Schedtag {
params.Add(jsonutils.NewString(tag), fmt.Sprintf("schedtag.%d", idx))
}
return params, nil
}