mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Merge pull request #919 in YUNIONIO/onecloud from ~QIUJIAN/onecloud:hotfix/qj-restrict-recycle-in-running-ready-status to release/2.5.0
* commit 'caa7b8f25ad2c21afeaa4bcdebc875bad593e534': user-create default-project-id 修正:1. 包年包月资源池添加和减少操作需要做状态检查 2. 同步时候忽略包年包月资源次的host和storage
This commit is contained in:
+15
-24
@@ -85,39 +85,30 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&HostDetailOptions{}, "host-enable", "Enable a host", func(s *mcclient.ClientSession, args *HostDetailOptions) error {
|
||||
result, err := modules.Hosts.PerformAction(s, args.ID, "enable", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
type HostOpsOptions struct {
|
||||
ID []string `help:"ID or name of hosts"`
|
||||
}
|
||||
R(&HostOpsOptions{}, "host-enable", "Enable a host", func(s *mcclient.ClientSession, args *HostOpsOptions) error {
|
||||
results := modules.Hosts.BatchPerformAction(s, args.ID, "enable", nil)
|
||||
printBatchResults(results, modules.Hosts.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&HostDetailOptions{}, "host-disable", "Disable a host", func(s *mcclient.ClientSession, args *HostDetailOptions) error {
|
||||
result, err := modules.Hosts.PerformAction(s, args.ID, "disable", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
R(&HostOpsOptions{}, "host-disable", "Disable a host", func(s *mcclient.ClientSession, args *HostOpsOptions) error {
|
||||
results := modules.Hosts.BatchPerformAction(s, args.ID, "disable", nil)
|
||||
printBatchResults(results, modules.Hosts.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&HostDetailOptions{}, "host-syncstatus", "Synchronize status of a host", func(s *mcclient.ClientSession, args *HostDetailOptions) error {
|
||||
result, err := modules.Hosts.PerformAction(s, args.ID, "syncstatus", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
R(&HostOpsOptions{}, "host-syncstatus", "Synchronize status of a host", func(s *mcclient.ClientSession, args *HostOpsOptions) error {
|
||||
results := modules.Hosts.BatchPerformAction(s, args.ID, "syncstatus", nil)
|
||||
printBatchResults(results, modules.Hosts.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&HostDetailOptions{}, "host-prepare", "Prepare a host for installation", func(s *mcclient.ClientSession, args *HostDetailOptions) error {
|
||||
result, err := modules.Hosts.PerformAction(s, args.ID, "prepare", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
R(&HostOpsOptions{}, "host-prepare", "Prepare a host for installation", func(s *mcclient.ClientSession, args *HostOpsOptions) error {
|
||||
results := modules.Hosts.BatchPerformAction(s, args.ID, "prepare", nil)
|
||||
printBatchResults(results, modules.Hosts.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
|
||||
@@ -176,6 +176,8 @@ func init() {
|
||||
Mobile string `help:"Mobile"`
|
||||
Enabled bool `help:"Enabled"`
|
||||
Disabled bool `help:"Disabled"`
|
||||
|
||||
DefaultProject string `help:"Default project"`
|
||||
}
|
||||
R(&UserCreateOptions{}, "user-create", "Create a user", func(s *mcclient.ClientSession, args *UserCreateOptions) error {
|
||||
mod, err := modules.GetModule(s, "users")
|
||||
@@ -211,6 +213,15 @@ func init() {
|
||||
} else if !args.Enabled && args.Disabled {
|
||||
params.Add(jsonutils.JSONFalse, "enabled")
|
||||
}
|
||||
|
||||
if len(args.DefaultProject) > 0 {
|
||||
projId, err := modules.Projects.GetId(s, args.DefaultProject, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
params.Add(jsonutils.NewString(projId), "default_project_id")
|
||||
}
|
||||
|
||||
user, err := mod.Create(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
@@ -62,3 +64,7 @@ func (model *SStatusStandaloneResourceBase) PerformStatus(ctx context.Context, u
|
||||
err = model.SetStatus(userCred, status, reason)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (model *SStatusStandaloneResourceBase) IsInStatus(status ...string) bool {
|
||||
return utils.IsInStringArray(model.Status, status)
|
||||
}
|
||||
|
||||
@@ -1061,9 +1061,9 @@ func totalDiskSize(projectId string, active tristate.TriState, ready tristate.Tr
|
||||
q = q.Join(storages, sqlchemy.AND(sqlchemy.IsFalse(storages.Field("deleted")),
|
||||
sqlchemy.Equals(storages.Field("id"), disks.Field("storage_id"))))
|
||||
if active.IsTrue() {
|
||||
q = q.Filter(sqlchemy.Equals(storages.Field("status"), STORAGE_ENABLED))
|
||||
q = q.Filter(sqlchemy.In(storages.Field("status"), []string{STORAGE_ENABLED, STORAGE_ONLINE}))
|
||||
} else {
|
||||
q = q.Filter(sqlchemy.NotEquals(storages.Field("status"), STORAGE_ENABLED))
|
||||
q = q.Filter(sqlchemy.NotIn(storages.Field("status"), []string{STORAGE_ENABLED, STORAGE_ONLINE}))
|
||||
}
|
||||
}
|
||||
if len(projectId) > 0 {
|
||||
|
||||
@@ -53,6 +53,9 @@ func (self *SGuest) CanPerformPrepaidRecycle() error {
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformPrepaidRecycle(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
if !self.IsInStatus(VM_READY, VM_RUNNING) {
|
||||
return nil, httperrors.NewInvalidStatusError("cannot recycle in status %s", self.Status)
|
||||
}
|
||||
err := self.CanPerformPrepaidRecycle()
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInvalidStatusError(err.Error())
|
||||
@@ -282,6 +285,10 @@ func (self *SGuest) AllowPerformUndoPrepaidRecycle(ctx context.Context, userCred
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformUndoPrepaidRecycle(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
if !self.IsInStatus(VM_READY, VM_RUNNING) {
|
||||
return nil, httperrors.NewInvalidStatusError("cannot undo recycle in status %s", self.Status)
|
||||
}
|
||||
|
||||
host := self.GetHost()
|
||||
|
||||
if host == nil {
|
||||
@@ -296,7 +303,7 @@ func (self *SGuest) PerformUndoPrepaidRecycle(ctx context.Context, userCred mccl
|
||||
return nil, httperrors.NewInvalidStatusError("host is not a prepaid recycle host")
|
||||
}
|
||||
|
||||
err := doUndoPrepaidRecycle(ctx, userCred, host, self)
|
||||
err := doUndoPrepaidRecycleLockHost(ctx, userCred, host, self)
|
||||
if err != nil {
|
||||
logclient.AddActionLog(self, logclient.ACT_UNDO_RECYCLE_PREPAID, self.GetShortDesc(ctx), userCred, false)
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
@@ -331,11 +338,15 @@ func (self *SHost) PerformUndoPrepaidRecycle(ctx context.Context, userCred mccli
|
||||
return nil, httperrors.NewInvalidStatusError("a recycle host shoud not allocate more than 1 guest")
|
||||
}
|
||||
|
||||
if !guests[0].IsInStatus(VM_READY, VM_RUNNING) {
|
||||
return nil, httperrors.NewInvalidStatusError("cannot undo recycle in status %s", self.Status)
|
||||
}
|
||||
|
||||
if guests[0].PendingDeleted {
|
||||
return nil, httperrors.NewInvalidStatusError("cannot undo a recycle host with pending_deleted guest")
|
||||
}
|
||||
|
||||
err := doUndoPrepaidRecycle(ctx, userCred, self, &guests[0])
|
||||
err := doUndoPrepaidRecycleLockGuest(ctx, userCred, self, &guests[0])
|
||||
if err != nil {
|
||||
logclient.AddActionLog(self, logclient.ACT_UNDO_RECYCLE_PREPAID, self.GetShortDesc(ctx), userCred, false)
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
@@ -356,7 +367,21 @@ func findIdiskById(idisks []cloudprovider.ICloudDisk, uuid string) cloudprovider
|
||||
return nil
|
||||
}
|
||||
|
||||
func doUndoPrepaidRecycle(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, server *SGuest) error {
|
||||
func doUndoPrepaidRecycleLockGuest(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, server *SGuest) error {
|
||||
lockman.LockObject(ctx, server)
|
||||
defer lockman.ReleaseObject(ctx, server)
|
||||
|
||||
return doUndoPrepaidRecycleNoLock(ctx, userCred, host, server)
|
||||
}
|
||||
|
||||
func doUndoPrepaidRecycleLockHost(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, server *SGuest) error {
|
||||
lockman.LockObject(ctx, host)
|
||||
defer lockman.ReleaseObject(ctx, host)
|
||||
|
||||
return doUndoPrepaidRecycleNoLock(ctx, userCred, host, server)
|
||||
}
|
||||
|
||||
func doUndoPrepaidRecycleNoLock(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, server *SGuest) error {
|
||||
if host.RealExternalId != server.ExternalId {
|
||||
msg := "host and server external id not match!!!!"
|
||||
log.Errorf(msg)
|
||||
|
||||
@@ -1217,6 +1217,9 @@ func (manager *SHostManager) SyncHosts(ctx context.Context, userCred mcclient.To
|
||||
}
|
||||
|
||||
for i := 0; i < len(removed); i += 1 {
|
||||
if removed[i].IsPrepaidRecycleResource() {
|
||||
continue
|
||||
}
|
||||
err = removed[i].ValidateDeleteCondition(ctx)
|
||||
if err != nil { // cannot delete
|
||||
err = removed[i].SetStatus(userCred, HOST_OFFLINE, "sync to delete")
|
||||
@@ -3636,3 +3639,7 @@ func (manager *SHostManager) PingDetectionTask(ctx context.Context, userCred mcc
|
||||
host.MarkGuestUnknown(userCred)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SHost) IsPrepaidRecycleResource() bool {
|
||||
return self.ResourceType == HostResourceTypePrepaidRecycle
|
||||
}
|
||||
|
||||
@@ -65,10 +65,10 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
STORAGE_ENABLED = "enabled"
|
||||
STORAGE_DISABLED = "disabled"
|
||||
STORAGE_OFFLINE = "offline"
|
||||
STORAGE_ONLINE = "online"
|
||||
STORAGE_ENABLED = "enabled"
|
||||
// STORAGE_DISABLED = "disabled"
|
||||
STORAGE_OFFLINE = "offline"
|
||||
STORAGE_ONLINE = "online"
|
||||
|
||||
DISK_TYPE_ROTATE = "rotate"
|
||||
DISK_TYPE_SSD = "ssd"
|
||||
@@ -679,9 +679,13 @@ func (manager *SStorageManager) SyncStorages(ctx context.Context, userCred mccli
|
||||
}
|
||||
|
||||
for i := 0; i < len(removed); i += 1 {
|
||||
// may be a fake storage for prepaid recycle host
|
||||
if removed[i].IsPrepaidRecycleResource() {
|
||||
continue
|
||||
}
|
||||
err = removed[i].ValidateDeleteCondition(ctx)
|
||||
if err != nil { // cannot delete
|
||||
err = removed[i].SetStatus(userCred, STORAGE_DISABLED, "sync to delete")
|
||||
err = removed[i].SetStatus(userCred, STORAGE_OFFLINE, "sync to delete")
|
||||
if err == nil {
|
||||
_, err = removed[i].PerformDisable(ctx, userCred, nil, nil)
|
||||
}
|
||||
@@ -1201,3 +1205,14 @@ func (self *SStorage) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
|
||||
desc.Update(jsonutils.Marshal(&info))
|
||||
return desc
|
||||
}
|
||||
|
||||
func (self *SStorage) IsPrepaidRecycleResource() bool {
|
||||
if !self.IsLocal() {
|
||||
return false
|
||||
}
|
||||
hosts := self.GetAttachedHosts()
|
||||
if len(hosts) != 1 {
|
||||
return false
|
||||
}
|
||||
return hosts[0].IsPrepaidRecycleResource()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user