Merge pull request #525 from swordqiu/hotfix/qj-recode-support-query-count-error-handling

fix: clearn up codes that impacted by query.Count return value changes
This commit is contained in:
yunion-ci-robot
2019-04-23 12:43:11 +08:00
committed by GitHub
78 changed files with 1382 additions and 1726 deletions
Generated
+4 -4
View File
@@ -1724,7 +1724,7 @@
[[projects]]
branch = "master"
digest = "1:30ca06466aebad8751130956f96267bc520af0991990522109d4250086e3ae83"
digest = "1:6f329a9c0743517bcdaa329db7524fbd93145b18c87e9bb3b55f80ad92907086"
name = "yunion.io/x/pkg"
packages = [
"gotypes",
@@ -1758,15 +1758,15 @@
"utils",
]
pruneopts = "UT"
revision = "fa6430d86cfb0b2b3cc6ea20bab3b4618186234b"
revision = "43cfeb36a15e9c34652df507d1218409cff2472a"
[[projects]]
branch = "master"
digest = "1:29f0a99ba079309ef8c82def5b9c452d0871837780ee702d7ae7c1ebe47478b0"
digest = "1:cfdd1588eb169908b7d54bfe48338139647512617598b9ffae958e2013b168a0"
name = "yunion.io/x/sqlchemy"
packages = ["."]
pruneopts = "UT"
revision = "5e43c9cfbb8eb2870882b87d3ab429062d69be2b"
revision = "25c2afeeda322a9ddd6047d7e5ba19800e07f9bd"
[[projects]]
branch = "master"
+1
View File
@@ -12,6 +12,7 @@ const (
CLOUD_PROVIDER_SYNC_STATUS_QUEUED = "queued"
CLOUD_PROVIDER_SYNC_STATUS_SYNCING = "syncing"
CLOUD_PROVIDER_SYNC_STATUS_IDLE = "idle"
CLOUD_PROVIDER_SYNC_STATUS_ERROR = "error"
CLOUD_PROVIDER_ONECLOUD = "OneCloud"
CLOUD_PROVIDER_VMWARE = "VMware"
+1
View File
@@ -0,0 +1 @@
package image // import "yunion.io/x/onecloud/pkg/apis/image"
+30
View File
@@ -0,0 +1,30 @@
package db
import (
"reflect"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/utils"
)
func FetchModelExtraCountProperties(model IModel, extra *jsonutils.JSONDict) *jsonutils.JSONDict {
selfValue := reflect.ValueOf(model)
for i := 0; i < selfValue.NumMethod(); i += 1 {
methodValue := selfValue.Method(i)
methodType := methodValue.Type()
if methodType.NumIn() != 0 || methodType.NumOut() != 2 {
continue
}
tokens := utils.CamelSplitTokens(methodValue.Type().Name())
if len(tokens) < 3 {
continue
}
if strings.EqualFold(tokens[0], "get") && strings.EqualFold(tokens[len(tokens)-1], "count") {
resName := strings.ToLower(strings.Join(tokens[1:], "_"))
outs := methodValue.Call([]reflect.Value{})
extra.Add(jsonutils.NewInt(outs[0].Int()), resName)
}
}
return extra
}
+12 -5
View File
@@ -466,13 +466,16 @@ func ListItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
if err != nil {
return nil, err
}
totalCnt := int64(q.Count())
totalCnt, err := q.CountWithError()
if err != nil {
return nil, err
}
// log.Debugf("total count %d", totalCnt)
if totalCnt == 0 {
emptyList := modules.ListResult{Data: []jsonutils.JSONObject{}}
return &emptyList, nil
}
if totalCnt > maxLimit && (limit <= 0 || limit > maxLimit) {
if int64(totalCnt) > maxLimit && (limit <= 0 || limit > maxLimit) {
limit = maxLimit
}
orderBy := jsonutils.GetQueryStringArray(queryDict, "order_by")
@@ -524,14 +527,14 @@ func ListItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
return nil, httperrors.NewGeneralError(err)
}
if len(retList) != retCount {
totalCnt = int64(len(retList))
totalCnt = len(retList)
}
paginate := false
if !customizeFilters.IsEmpty() {
// query not use Limit and Offset, do manual pagination
paginate = true
}
return calculateListResult(retList, totalCnt, limit, offset, paginate), nil
return calculateListResult(retList, int64(totalCnt), limit, offset, paginate), nil
}
func calculateListResult(data []jsonutils.JSONObject, total, limit, offset int64, paginate bool) *modules.ListResult {
@@ -883,7 +886,11 @@ func doCreateItem(manager IModelManager, ctx context.Context, userCred mcclient.
generateName, _ := dataDict.GetString("generate_name")
if len(generateName) > 0 {
dataDict.Remove("generate_name")
dataDict.Add(jsonutils.NewString(GenerateName(manager, ownerProjId, generateName)), "name")
newName, err := GenerateName(manager, ownerProjId, generateName)
if err != nil {
return nil, err
}
dataDict.Add(jsonutils.NewString(newName), "name")
} else {
name, _ := data.GetString("name")
if len(name) > 0 {
+28 -7
View File
@@ -46,7 +46,10 @@ func FetchJointByIds(manager IJointModelManager, masterId, slaveId string, query
cond := sqlchemy.AND(sqlchemy.Equals(masterField, masterId), sqlchemy.Equals(slaveField, slaveId))
q = q.Filter(cond)
q = manager.FilterByParams(q, query)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count > 1 {
return nil, sqlchemy.ErrDuplicateEntry
} else if count == 0 {
@@ -62,7 +65,10 @@ func FetchJointByIds(manager IJointModelManager, masterId, slaveId string, query
func FetchById(manager IModelManager, idStr string) (IModel, error) {
q := manager.Query()
q = manager.FilterById(q, idStr)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count == 1 {
obj, err := NewModelObject(manager)
if err != nil {
@@ -88,10 +94,16 @@ func FetchByName(manager IModelManager, userCred mcclient.IIdentityProvider, idS
}
q := manager.Query()
q = manager.FilterByName(q, idStr)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count > 1 {
q = manager.FilterByOwner(q, owner)
count = q.Count()
count, err = q.CountWithError()
if err != nil {
return nil, err
}
}
if count == 1 {
obj, err := NewModelObject(manager)
@@ -133,7 +145,10 @@ func fetchItemById(manager IModelManager, ctx context.Context, userCred mcclient
}
}
q = manager.FilterById(q, idStr)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count == 1 {
item, err := NewModelObject(manager)
if err != nil {
@@ -161,10 +176,16 @@ func fetchItemByName(manager IModelManager, ctx context.Context, userCred mcclie
}
}
q = manager.FilterByName(q, idStr)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count > 1 {
q = manager.FilterByOwner(q, manager.GetOwnerId(userCred))
count = q.Count()
count, err = q.CountWithError()
if err != nil {
return nil, err
}
}
if count == 1 {
item, err := NewModelObject(manager)
+34 -9
View File
@@ -17,19 +17,24 @@ package db
import (
"fmt"
"yunion.io/x/log"
"yunion.io/x/pkg/util/stringutils"
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
"yunion.io/x/onecloud/pkg/httperrors"
)
func isNameUnique(manager IModelManager, owner string, name string) bool {
func isNameUnique(manager IModelManager, owner string, name string) (bool, error) {
q := manager.Query()
q = manager.FilterByName(q, name)
if !consts.IsGlobalVirtualResourceNamespace() {
q = manager.FilterByOwner(q, owner)
}
return q.Count() == 0
cnt, err := q.CountWithError()
if err != nil {
return false, err
}
return cnt == 0, nil
}
func NewNameValidator(manager IModelManager, ownerProjId string, name string) error {
@@ -37,13 +42,17 @@ func NewNameValidator(manager IModelManager, ownerProjId string, name string) er
if err != nil {
return err
}
if !isNameUnique(manager, ownerProjId, name) {
uniq, err := isNameUnique(manager, ownerProjId, name)
if err != nil {
return err
}
if !uniq {
return httperrors.NewDuplicateNameError("name", name)
}
return nil
}
func isAlterNameUnique(model IModel, name string) bool {
func isAlterNameUnique(model IModel, name string) (bool, error) {
manager := model.GetModelManager()
q := manager.Query()
q = manager.FilterByName(q, name)
@@ -51,7 +60,11 @@ func isAlterNameUnique(model IModel, name string) bool {
q = manager.FilterByOwner(q, model.GetOwnerProjectId())
}
q = manager.FilterByNotId(q, model.GetId())
return q.Count() == 0
cnt, err := q.CountWithError()
if err != nil {
return false, err
}
return cnt == 0, nil
}
func alterNameValidator(model IModel, name string) error {
@@ -59,13 +72,17 @@ func alterNameValidator(model IModel, name string) error {
if err != nil {
return err
}
if !isAlterNameUnique(model, name) {
uniq, err := isAlterNameUnique(model, name)
if err != nil {
return err
}
if !uniq {
return httperrors.NewDuplicateNameError("name", name)
}
return nil
}
func GenerateName(manager IModelManager, ownerProjId string, hint string) string {
func GenerateName(manager IModelManager, ownerProjId string, hint string) (string, error) {
_, pattern, patternLen := stringutils.ParseNamePattern(hint)
var name string
idx := 1
@@ -75,9 +92,17 @@ func GenerateName(manager IModelManager, ownerProjId string, hint string) string
name = fmt.Sprintf(pattern, idx)
idx += 1
}
for !isNameUnique(manager, ownerProjId, name) {
for {
uniq, err := isNameUnique(manager, ownerProjId, name)
if err != nil {
return "", err
}
if uniq {
return name, nil
}
name = fmt.Sprintf(pattern, idx)
idx += 1
}
return name
log.Fatalln("here is not reachable!!!")
return "", nil
}
+4 -1
View File
@@ -99,7 +99,10 @@ func (manager *SStandaloneResourceBaseManager) FetchByIdOrName(userCred mcclient
func (manager *SStandaloneResourceBaseManager) FetchByExternalId(idStr string) (IStandaloneModel, error) {
q := manager.Query().Equals("external_id", idStr)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count == 1 {
obj, err := NewModelObject(manager)
if err != nil {
+11 -3
View File
@@ -251,7 +251,11 @@ func (model *SVirtualResourceBase) PerformChangeOwner(ctx context.Context, userC
q := model.GetModelManager().Query().Equals("name", model.GetName())
q = q.Equals("tenant_id", tobj.GetId())
q = q.NotEquals("id", model.GetId())
if q.Count() > 0 {
cnt, err := q.CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("check name duplication error: %s", err)
}
if cnt > 0 {
return nil, httperrors.NewDuplicateNameError("name", model.GetName())
}
former, _ := TenantCacheManager.FetchTenantById(ctx, model.ProjectId)
@@ -260,7 +264,7 @@ func (model *SVirtualResourceBase) PerformChangeOwner(ctx context.Context, userC
formerObj := NewTenant(model.ProjectId, "unknown")
former = &formerObj
}
_, err := Update(model, func() error {
_, err = Update(model, func() error {
model.ProjectId = tobj.GetId()
model.ProjectSrc = string(PROJECT_SOURCE_LOCAL)
return nil
@@ -353,8 +357,12 @@ func (model *SVirtualResourceBase) MarkCancelPendingDelete(ctx context.Context,
lockman.LockClass(ctx, model.GetModelManager(), ownerProjId)
defer lockman.ReleaseClass(ctx, model.GetModelManager(), ownerProjId)
newName, err := GenerateName(model.GetModelManager(), ownerProjId, model.Name)
if err != nil {
return err
}
diff, err := Update(model, func() error {
model.Name = GenerateName(model.GetModelManager(), ownerProjId, model.Name)
model.Name = newName
model.PendingDeleted = false
model.PendingDeletedAt = time.Time{}
return nil
-154
View File
@@ -147,160 +147,6 @@ func (self *SAliyunGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManag
return userName
}
/* func (self *SAliyunGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams())
if err != nil {
log.Errorf("GetDeployConfigOnHost error: %v", err)
return err
}
log.Debugf("RequestDeployGuestOnHost: %s", config)
desc := cloudprovider.SManagedVMCreateConfig{}
if err := desc.GetConfig(config); err != nil {
return err
}
userName := "root"
if desc.ImageType == "system" && desc.OsType == "Windows" {
userName = "Administrator"
}
action, err := config.GetString("action")
if err != nil {
return err
}
ihost, err := host.GetIHost()
if err != nil {
return err
}
if action == "create" {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iVM, createErr := ihost.CreateVM(&desc)
if createErr != nil {
return nil, createErr
}
guest.SetExternalId(task.GetUserCred(), iVM.GetGlobalId())
log.Debugf("VMcreated %s, wait status ready ...", iVM.GetGlobalId())
err = cloudprovider.WaitStatus(iVM, models.VM_READY, time.Second*5, time.Second*1800)
if err != nil {
return nil, err
}
log.Debugf("VMcreated %s, and status is ready", iVM.GetGlobalId())
iVM, err = ihost.GetIVMById(iVM.GetGlobalId())
if err != nil {
log.Errorf("cannot find vm %s", err)
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action)
return data, nil
})
} else if action == "deploy" {
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
params := task.GetParams()
log.Debugf("Deploy VM params %s", params.String())
deleteKeypair := jsonutils.QueryBoolean(params, "__delete_keypair__", false)
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
if len(desc.UserData) > 0 {
err := iVM.UpdateUserData(desc.UserData)
if err != nil {
log.Errorf("update userdata fail %s", err)
}
}
err := iVM.DeployVM(ctx, desc.Name, desc.Password, desc.PublicKey, deleteKeypair, desc.Description)
if err != nil {
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action)
return data, nil
})
} else if action == "rebuild" {
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
if len(desc.UserData) > 0 {
err := iVM.UpdateUserData(desc.UserData)
if err != nil {
log.Errorf("update userdata fail %s", err)
}
}
diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, desc.Password, desc.PublicKey, desc.SysDisk.SizeGB)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s new diskID %s, wait status ready ...", iVM.GetGlobalId(), diskId)
err = cloudprovider.WaitStatus(iVM, models.VM_READY, time.Second*5, time.Second*1800)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s, and status is ready", iVM.GetGlobalId())
maxWaitSecs := 300
waited := 0
for {
// hack, wait disk number consistent
idisks, err := iVM.GetIDisks()
if err != nil {
log.Errorf("fail to find VM idisks %s", err)
return nil, err
}
if len(idisks) < len(desc.DataDisks)+1 || idisks[0].GetGlobalId() != diskId {
if waited > maxWaitSecs {
log.Errorf("inconsistent disk number, wait timeout, must be something wrong on remote")
return nil, cloudprovider.ErrTimeout
}
if len(idisks) < len(desc.DataDisks)+1 {
log.Debugf("inconsistent disk number???? %d != %d", len(idisks), len(desc.DataDisks)+1)
}
if len(idisks) > 0 && idisks[0].GetGlobalId() != diskId {
log.Errorf("system disk id inconsistent %s != %s", idisks[0].GetGlobalId(), diskId)
}
time.Sleep(time.Second * 5)
waited += 5
} else {
break
}
}
data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action)
return data, nil
})
} else {
log.Errorf("RequestDeployGuestOnHost: Action %s not supported", action)
return fmt.Errorf("Action %s not supported", action)
}
return nil
} */
func (self *SAliyunGuestDriver) AllowReconfigGuest() bool {
return true
}
-131
View File
@@ -148,137 +148,6 @@ func (self *SAwsGuestDriver) GetGuestInitialStateAfterRebuild() string {
return api.VM_READY
}
/*func (self *SAwsGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams())
if err != nil {
log.Errorf("GetDeployConfigOnHost error: %v", err)
return err
}
log.Debugf("RequestDeployGuestOnHost: %s", config)
desc := cloudprovider.SManagedVMCreateConfig{}
if err := desc.GetConfig(config); err != nil {
return err
}
action, err := config.GetString("action")
if err != nil {
return err
}
ihost, err := host.GetIHost()
if err != nil {
return err
}
username := fetchAwsUserName(desc)
switch action {
case "create":
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iVM, createErr := ihost.CreateVM(&desc)
if createErr != nil {
return nil, createErr
}
guest.SetExternalId(task.GetUserCred(), iVM.GetGlobalId())
log.Debugf("VMcreated %s, wait status running ...", iVM.GetGlobalId())
err = cloudprovider.WaitStatus(iVM, models.VM_RUNNING, time.Second*5, time.Second*1800)
if err != nil {
return nil, err
}
log.Debugf("VMcreated %s, and status is ready", iVM.GetGlobalId())
iVM, err = ihost.GetIVMById(iVM.GetGlobalId())
if err != nil {
log.Errorf("cannot find vm %s", err)
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, username, desc.Password, action)
return data, nil
})
case "deploy":
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
params := task.GetParams()
log.Debugf("Deploy VM params %s", params.String())
deleteKeypair := jsonutils.QueryBoolean(params, "__delete_keypair__", false)
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
err := iVM.DeployVM(ctx, desc.Name, desc.Password, desc.PublicKey, deleteKeypair, desc.Description)
if err != nil {
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, username, desc.Password, action)
return data, nil
})
case "rebuild":
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, desc.Password, desc.PublicKey, desc.SysDisk.SizeGB)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s new diskID %s, wait status ready ...", iVM.GetGlobalId(), diskId)
err = cloudprovider.WaitStatus(iVM, models.VM_READY, time.Second*5, time.Second*1800)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s, and status is ready", iVM.GetGlobalId())
maxWaitSecs := 300
waited := 0
for {
// hack, wait disk number consistent
idisks, err := iVM.GetIDisks()
if err != nil {
log.Errorf("fail to find VM idisks %s", err)
return nil, err
}
if len(idisks) < len(desc.DataDisks)+1 {
if waited > maxWaitSecs {
log.Errorf("inconsistent disk number, wait timeout, must be something wrong on remote")
return nil, cloudprovider.ErrTimeout
}
log.Debugf("inconsistent disk number???? %d != %d", len(idisks), len(desc.DataDisks)+1)
time.Sleep(time.Second * 5)
waited += 5
} else {
if idisks[0].GetGlobalId() != diskId {
log.Errorf("system disk id inconsistent %s != %s", idisks[0].GetGlobalId(), diskId)
return nil, fmt.Errorf("inconsistent sys disk id after rebuild root")
}
break
}
}
data := fetchIVMinfo(desc, iVM, guest.Id, username, desc.Password, action)
return data, nil
})
default:
log.Errorf("RequestDeployGuestOnHost: Action %s not supported", action)
return fmt.Errorf("Action %s not supported", action)
}
return nil
}*/
func (self *SAwsGuestDriver) IsSupportedBillingCycle(bc billing.SBillingCycle) bool {
return false
}
+5 -158
View File
@@ -20,12 +20,10 @@ import (
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/cmdline"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
@@ -147,163 +145,12 @@ func (self *SAzureGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManage
return ansible.PUBLIC_CLOUD_ANSIBLE_USER
}
/* func (self *SAzureGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams())
if err != nil {
log.Errorf("GetDeployConfigOnHost error: %v", err)
return err
func (self *SAzureGuestDriver) GetGuestSecgroupVpcid(guest *models.SGuest) (string, error) {
host := guest.GetHost()
if host != nil && strings.HasSuffix(host.Name, "-classic") {
return "classic", nil
}
desc := cloudprovider.SManagedVMCreateConfig{}
if err := desc.GetConfig(config); err != nil {
return err
}
action, err := config.GetString("action")
if err != nil {
return err
}
ihost, err := host.GetIHost()
if err != nil {
return err
}
if action == "create" {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
if len(desc.Password) == 0 {
//Azure创建必须要设置密码
desc.Password = seclib2.RandomPassword2(12)
}
iVM, createErr := ihost.CreateVM(&desc)
if createErr != nil {
return nil, createErr
}
guest.SetExternalId(task.GetUserCred(), iVM.GetGlobalId())
log.Debugf("VMcreated %s, wait status running ...", iVM.GetGlobalId())
if err = cloudprovider.WaitStatus(iVM, models.VM_RUNNING, time.Second*5, time.Second*1800); err != nil {
return nil, err
}
if iVM, err = ihost.GetIVMById(iVM.GetGlobalId()); err != nil {
log.Errorf("cannot find vm %s", err)
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, desc.Password, action)
return data, nil
})
} else if action == "deploy" {
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
params := task.GetParams()
log.Debugf("Deploy VM params %s", params.String())
deleteKeypair := jsonutils.QueryBoolean(params, "__delete_keypair__", false)
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
err := iVM.DeployVM(ctx, desc.Name, desc.Password, desc.PublicKey, deleteKeypair, desc.Description)
if err != nil {
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, desc.Password, action)
return data, nil
})
} else if action == "rebuild" {
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
_, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, desc.Password, desc.PublicKey, desc.SysDisk.SizeGB)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s, and status is ready", iVM.GetGlobalId())
data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, desc.Password, action)
return data, nil
})
} else {
return fmt.Errorf("Action %s not supported", action)
}
return nil
} */
func (self *SAzureGuestDriver) RequestSyncConfigOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
ihost, err := host.GetIHost()
if err != nil {
return nil, err
}
iVM, err := ihost.GetIVMById(guest.ExternalId)
if err != nil {
return nil, err
}
if fwOnly, _ := task.GetParams().Bool("fw_only"); fwOnly {
vpcID := "normal"
if strings.HasSuffix(host.Name, "-classic") {
vpcID = "classic"
}
iregion, err := host.GetIRegion()
if err != nil {
return nil, err
}
lockman.LockRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-%s", guest.SecgrpId, vpcID))
defer lockman.ReleaseRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-%s", guest.SecgrpId, vpcID))
secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), guest.SecgrpId, vpcID, host.GetRegion().Id, host.ManagerId)
if secgroupCache == nil {
return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s vpc: %s", guest.SecgrpId, vpcID)
}
extID, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, vpcID, guest.GetSecgroupName(), "", guest.GetSecRules())
if err != nil {
return nil, err
}
if err = secgroupCache.SetExternalId(task.GetUserCred(), extID); err != nil {
return nil, err
}
return nil, iVM.AssignSecurityGroup(extID)
}
iDisks, err := iVM.GetIDisks()
if err != nil {
return nil, err
}
disks := make([]models.SDisk, 0)
for _, guestdisk := range guest.GetDisks() {
disk := guestdisk.GetDisk()
disks = append(disks, *disk)
}
added := make([]models.SDisk, 0)
commondb := make([]models.SDisk, 0)
commonext := make([]cloudprovider.ICloudDisk, 0)
removed := make([]cloudprovider.ICloudDisk, 0)
if err := compare.CompareSets(disks, iDisks, &added, &commondb, &commonext, &removed); err != nil {
return nil, err
}
for _, disk := range removed {
if err := iVM.DetachDisk(ctx, disk.GetId()); err != nil {
return nil, err
}
}
for _, disk := range added {
if err := iVM.AttachDisk(ctx, disk.ExternalId); err != nil {
return nil, err
}
}
return nil, nil
})
return nil
return api.NORMAL_VPC_ID, nil
}
func (self *SAzureGuestDriver) IsSupportedBillingCycle(bc billing.SBillingCycle) bool {
+19
View File
@@ -262,3 +262,22 @@ func (self *SBaseGuestDriver) RequestSyncConfigOnHost(ctx context.Context, guest
func (self *SBaseGuestDriver) IsSupportGuestClone() bool {
return true
}
func (self *SBaseGuestDriver) RequestSyncSecgroupsOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
return nil // do nothing
}
func (self *SBaseGuestDriver) GetGuestSecgroupVpcid(guest *models.SGuest) (string, error) {
vpcId := ""
guestnets, err := guest.GetNetworks("")
if err != nil {
return "", err
}
for _, network := range guestnets {
if vpc := network.GetNetwork().GetVpc(); vpc != nil {
vpcId = vpc.ExternalId
break
}
}
return vpcId, nil
}
+3 -4
View File
@@ -53,10 +53,9 @@ func (self *SESXiGuestDriver) GetMinimalSysDiskSizeGb() int {
return options.Options.DefaultDiskSizeMB / 1024
}
// func (self *SESXiGuestDriver) RequestSyncConfigOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
// task.ScheduleRun(nil)
// return nil
// }
func (self *SESXiGuestDriver) RequestSyncSecgroupsOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
return nil // do nothing, not support securitygroup
}
func (self *SESXiGuestDriver) GetMaxSecurityGroupCount() int {
//暂不支持绑定安全组
-159
View File
@@ -112,165 +112,6 @@ func (self *SHuaweiGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManag
return userName
}
/*
func (self *SHuaweiGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams())
if err != nil {
log.Errorf("GetDeployConfigOnHost error: %v", err)
return err
}
log.Debugf("RequestDeployGuestOnHost: %s", config)
desc := cloudprovider.SManagedVMCreateConfig{}
if err := desc.GetConfig(config); err != nil {
return err
}
userName := "root"
if desc.ImageType == "system" {
if desc.OsDistribution == "Ubuntu" {
userName = "ubuntu"
}
if desc.OsType == "Windows" {
userName = "Administrator"
}
}
action, err := config.GetString("action")
if err != nil {
return err
}
ihost, err := host.GetIHost()
if err != nil {
return err
}
if action == "create" {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iVM, createErr := ihost.CreateVM(&desc)
if createErr != nil {
return nil, createErr
}
guest.SetExternalId(task.GetUserCred(), iVM.GetGlobalId())
log.Debugf("VMcreated %s, wait status ready ...", iVM.GetGlobalId())
err = cloudprovider.WaitStatus(iVM, models.VM_RUNNING, time.Second*5, time.Second*1800)
if err != nil {
return nil, err
}
log.Debugf("VMcreated %s, and status is ready", iVM.GetGlobalId())
iVM, err = ihost.GetIVMById(iVM.GetGlobalId())
if err != nil {
log.Errorf("cannot find vm %s", err)
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action)
return data, nil
})
} else if action == "deploy" {
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
params := task.GetParams()
log.Debugf("Deploy VM params %s", params.String())
deleteKeypair := jsonutils.QueryBoolean(params, "__delete_keypair__", false)
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
if len(desc.UserData) > 0 {
err := iVM.UpdateUserData(desc.UserData)
if err != nil {
log.Errorf("update userdata fail %s", err)
}
}
err := iVM.DeployVM(ctx, desc.Name, desc.Password, desc.PublicKey, deleteKeypair, desc.Description)
if err != nil {
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action)
return data, nil
})
} else if action == "rebuild" {
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
if len(desc.UserData) > 0 {
err := iVM.UpdateUserData(desc.UserData)
if err != nil {
log.Errorf("update userdata fail %s", err)
}
}
diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, desc.Password, desc.PublicKey, desc.SysDisk.SizeGB)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s new diskID %s, wait status ready ...", iVM.GetGlobalId(), diskId)
err = cloudprovider.WaitStatus(iVM, models.VM_RUNNING, time.Second*5, time.Second*1800)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s, and status is %s", iVM.GetGlobalId(), iVM.GetStatus())
maxWaitSecs := 300
waited := 0
for {
// hack, wait disk number consistent
idisks, err := iVM.GetIDisks()
if err != nil {
log.Errorf("fail to find VM idisks %s", err)
return nil, err
}
if len(idisks) < len(desc.DataDisks)+1 || idisks[0].GetGlobalId() != diskId {
if waited > maxWaitSecs {
log.Errorf("inconsistent disk number, wait timeout, must be something wrong on remote")
return nil, cloudprovider.ErrTimeout
}
if len(idisks) < len(desc.DataDisks)+1 {
log.Debugf("inconsistent disk number???? %d != %d", len(idisks), len(desc.DataDisks)+1)
}
if len(idisks) > 0 && idisks[0].GetGlobalId() != diskId {
log.Errorf("system disk id inconsistent %s != %s", idisks[0].GetGlobalId(), diskId)
}
time.Sleep(time.Second * 5)
waited += 5
} else {
break
}
}
data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action)
return data, nil
})
} else {
log.Errorf("RequestDeployGuestOnHost: Action %s not supported", action)
return fmt.Errorf("Action %s not supported", action)
}
return nil
}*/
func (self *SHuaweiGuestDriver) IsSupportedBillingCycle(bc billing.SBillingCycle) bool {
months := bc.GetMonths()
if (months >= 1 && months <= 9) || (months == 12) || (months == 24) || (months == 36) {
+37 -33
View File
@@ -671,6 +671,41 @@ func (self *SManagedVirtualizedGuestDriver) OnGuestDeployTaskDataReceived(ctx co
return nil
}
func (self *SManagedVirtualizedGuestDriver) RequestSyncSecgroupsOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
iVM, err := guest.GetIVM()
if err != nil {
return err
}
vpcId, err := guest.GetDriver().GetGuestSecgroupVpcid(guest)
if err != nil {
return err
}
iregion, err := host.GetIRegion()
if err != nil {
return err
}
secgroups := guest.GetSecgroups()
externalIds := []string{}
for _, secgroup := range secgroups {
lockman.LockRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-%s", guest.SecgrpId, vpcId))
defer lockman.ReleaseRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-%s", guest.SecgrpId, vpcId))
secgroupCache, err := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), secgroup.Id, vpcId, host.GetRegion().Id, host.ManagerId)
if err != nil {
return fmt.Errorf("failed to registor secgroupCache for secgroup: %s vpc: %s: %s", secgroup.Id, vpcId, err)
}
extID, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, vpcId, secgroup.Name, secgroup.Description, secgroup.GetSecRules(""))
if err != nil {
return err
}
if err = secgroupCache.SetExternalId(task.GetUserCred(), extID); err != nil {
return err
}
externalIds = append(externalIds, extID)
}
return iVM.SetSecurityGroups(externalIds)
}
func (self *SManagedVirtualizedGuestDriver) RequestSyncConfigOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
ihost, err := host.GetIHost()
@@ -682,42 +717,11 @@ func (self *SManagedVirtualizedGuestDriver) RequestSyncConfigOnHost(ctx context.
return nil, err
}
if fwOnly, _ := task.GetParams().Bool("fw_only"); fwOnly {
vpcId := ""
guestnets, err := guest.GetNetworks("")
if jsonutils.QueryBoolean(task.GetParams(), "fw_only", false) {
err = guest.GetDriver().RequestSyncSecgroupsOnHost(ctx, guest, host, task)
if err != nil {
return nil, err
}
for _, network := range guestnets {
if vpc := network.GetNetwork().GetVpc(); vpc != nil {
vpcId = vpc.ExternalId
break
}
}
iregion, err := host.GetIRegion()
if err != nil {
return nil, err
}
secgroups := guest.GetSecgroups()
externalIds := []string{}
for _, secgroup := range secgroups {
lockman.LockRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-%s", guest.SecgrpId, vpcId))
defer lockman.ReleaseRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-%s", guest.SecgrpId, vpcId))
secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), secgroup.Id, vpcId, host.GetRegion().Id, host.ManagerId)
if secgroupCache == nil {
return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s vpc: %s", secgroup.Id, vpcId)
}
extID, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, vpcId, secgroup.Name, secgroup.Description, secgroup.GetSecRules(""))
if err != nil {
return nil, err
}
if err = secgroupCache.SetExternalId(task.GetUserCred(), extID); err != nil {
return nil, err
}
externalIds = append(externalIds, extID)
}
return nil, iVM.SetSecurityGroups(externalIds)
}
iDisks, err := iVM.GetIDisks()
+2 -228
View File
@@ -16,15 +16,8 @@ package guestdrivers
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/compare"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
@@ -109,227 +102,8 @@ func (self *SOpenStackGuestDriver) GetGuestInitialStateAfterRebuild() string {
return api.VM_READY
}
/*func (self *SOpenStackGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams())
if err != nil {
log.Errorf("GetDeployConfigOnHost error: %v", err)
return err
}
log.Debugf("RequestDeployGuestOnHost: %s", config)
desc := cloudprovider.SManagedVMCreateConfig{}
if err := desc.GetConfig(config); err != nil {
return err
}
action, err := config.GetString("action")
if err != nil {
return err
}
ihost, err := host.GetIHost()
if err != nil {
return err
}
if action == "create" {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iVM, createErr := ihost.CreateVM(&desc)
if createErr != nil {
return nil, createErr
}
// 避免部署失败后,不能删除openstack平台机器
guest.SetExternalId(task.GetUserCred(), iVM.GetGlobalId())
log.Debugf("VMcreated %s, wait status running ...", iVM.GetGlobalId())
err = cloudprovider.WaitStatus(iVM, models.VM_RUNNING, time.Second*5, time.Second*1800)
if err != nil {
return nil, err
}
log.Debugf("VMcreated %s, and status is running", iVM.GetGlobalId())
iVM, err = ihost.GetIVMById(iVM.GetGlobalId())
if err != nil {
log.Errorf("cannot find vm %s", err)
return nil, err
}
err = cloudprovider.RetryUntil(func() (bool, error) {
idisks, err := iVM.GetIDisks()
if err != nil {
log.Errorf("cannot find vm disks %s", err)
return false, err
}
if len(idisks) == len(desc.DataDisks)+1 {
return true, nil
} else {
return false, nil
}
}, 10)
if err != nil {
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action)
return data, nil
})
} else if action == "deploy" {
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
params := task.GetParams()
log.Debugf("Deploy VM params %s", params.String())
deleteKeypair := jsonutils.QueryBoolean(params, "__delete_keypair__", false)
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
err := iVM.DeployVM(ctx, desc.Name, desc.Password, desc.PublicKey, deleteKeypair, desc.Description)
if err != nil {
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action)
return data, nil
})
} else if action == "rebuild" {
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, desc.Password, desc.PublicKey, desc.SysDisk.SizeGB)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s new diskID %s, wait status ready ...", iVM.GetGlobalId(), diskId)
err = cloudprovider.WaitStatus(iVM, models.VM_READY, time.Second*5, time.Second*1800)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s, and status is ready", iVM.GetGlobalId())
maxWaitSecs := 300
waited := 0
for {
// hack, wait disk number consistent
idisks, err := iVM.GetIDisks()
if err != nil {
log.Errorf("fail to find VM idisks %s", err)
return nil, err
}
if len(idisks) < len(desc.DataDisks)+1 {
if waited > maxWaitSecs {
log.Errorf("inconsistent disk number, wait timeout, must be something wrong on remote")
return nil, cloudprovider.ErrTimeout
}
log.Debugf("inconsistent disk number???? %d != %d", len(idisks), len(desc.DataDisks)+1)
time.Sleep(time.Second * 5)
waited += 5
} else {
if idisks[0].GetGlobalId() != diskId {
log.Errorf("system disk id inconsistent %s != %s", idisks[0].GetGlobalId(), diskId)
return nil, fmt.Errorf("inconsistent sys disk id after rebuild root")
}
break
}
}
data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action)
return data, nil
})
} else {
log.Errorf("RequestDeployGuestOnHost: Action %s not supported", action)
return fmt.Errorf("Action %s not supported", action)
}
return nil
}*/
func (self *SOpenStackGuestDriver) RequestSyncConfigOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
ihost, err := host.GetIHost()
if err != nil {
return nil, err
}
iVM, err := ihost.GetIVMById(guest.ExternalId)
if err != nil {
return nil, err
}
if fwOnly, _ := task.GetParams().Bool("fw_only"); fwOnly {
iregion, err := host.GetIRegion()
if err != nil {
return nil, err
}
secgroups := guest.GetSecgroups()
externalIds := []string{}
for _, secgroup := range secgroups {
lockman.LockRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-normal", guest.SecgrpId))
defer lockman.ReleaseRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-normal", guest.SecgrpId))
secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), secgroup.Id, "normal", host.GetRegion().Id, host.ManagerId)
if secgroupCache == nil {
return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s", secgroup.Id)
}
extID, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, "", secgroup.Name, secgroup.Description, secgroup.GetSecRules(""))
if err != nil {
return nil, err
}
if err = secgroupCache.SetExternalId(task.GetUserCred(), extID); err != nil {
return nil, err
}
externalIds = append(externalIds, extID)
}
return nil, iVM.SetSecurityGroups(externalIds)
}
iDisks, err := iVM.GetIDisks()
if err != nil {
return nil, err
}
disks := make([]models.SDisk, 0)
for _, guestdisk := range guest.GetDisks() {
disk := guestdisk.GetDisk()
disks = append(disks, *disk)
}
added := make([]models.SDisk, 0)
commondb := make([]models.SDisk, 0)
commonext := make([]cloudprovider.ICloudDisk, 0)
removed := make([]cloudprovider.ICloudDisk, 0)
if err := compare.CompareSets(disks, iDisks, &added, &commondb, &commonext, &removed); err != nil {
return nil, err
}
for _, disk := range removed {
if err := iVM.DetachDisk(ctx, disk.GetId()); err != nil {
return nil, err
}
}
for _, disk := range added {
if err := iVM.AttachDisk(ctx, disk.ExternalId); err != nil {
return nil, err
}
}
return nil, nil
})
return nil
func (self *SOpenStackGuestDriver) GetGuestSecgroupVpcid(guest *models.SGuest) (string, error) {
return api.NORMAL_VPC_ID, nil
}
func (self *SOpenStackGuestDriver) AllowReconfigGuest() bool {
+2 -247
View File
@@ -18,12 +18,9 @@ import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
@@ -167,250 +164,8 @@ func (self *SQcloudGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManag
return userName
}
/* func (self *SQcloudGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams())
if err != nil {
log.Errorf("GetDeployConfigOnHost error: %v", err)
return err
}
log.Debugf("RequestDeployGuestOnHost: %s", config)
desc := cloudprovider.SManagedVMCreateConfig{}
if err := desc.GetConfig(config); err != nil {
return err
}
userName := "root"
if desc.ImageType == "system" {
if desc.OsDistribution == "Ubuntu" {
userName = "ubuntu"
}
if desc.OsType == "Windows" {
userName = "Administrator"
}
}
action, err := config.GetString("action")
if err != nil {
return err
}
ihost, err := host.GetIHost()
if err != nil {
return err
}
if action == "create" {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iVM, createErr := ihost.CreateVM(&desc)
if createErr != nil {
return nil, createErr
}
guest.SetExternalId(task.GetUserCred(), iVM.GetGlobalId())
log.Debugf("VMcreated %s, wait status running ...", iVM.GetGlobalId())
err = cloudprovider.WaitStatus(iVM, models.VM_RUNNING, time.Second*5, time.Second*1800)
if err != nil {
return nil, err
}
log.Debugf("VMcreated %s, and status is running", iVM.GetGlobalId())
iVM, err = ihost.GetIVMById(iVM.GetGlobalId())
if err != nil {
log.Errorf("cannot find vm %s", err)
return nil, err
}
err = cloudprovider.RetryUntil(func() (bool, error) {
idisks, err := iVM.GetIDisks()
if err != nil {
log.Errorf("cannot find vm disks %s", err)
return false, err
}
if len(idisks) == len(desc.DataDisks)+1 {
return true, nil
} else {
return false, nil
}
}, 10)
if err != nil {
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action)
return data, nil
})
} else if action == "deploy" {
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
params := task.GetParams()
log.Debugf("Deploy VM params %s", params.String())
deleteKeypair := jsonutils.QueryBoolean(params, "__delete_keypair__", false)
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
//腾讯云暂不支持更新自定义用户数据
// if len(userData) > 0 {
// err := iVM.UpdateUserData(userData)
// if err != nil {
// log.Errorf("update userdata fail %s", err)
// }
// }
err := iVM.DeployVM(ctx, desc.Name, desc.Password, desc.PublicKey, deleteKeypair, desc.Description)
if err != nil {
return nil, err
}
data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action)
return data, nil
})
} else if action == "rebuild" {
iVM, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil || iVM == nil {
log.Errorf("cannot find vm %s", err)
return fmt.Errorf("cannot find vm")
}
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
//腾讯云暂不支持更新自定义用户数据
// if len(userData) > 0 {
// err := iVM.UpdateUserData(userData)
// if err != nil {
// log.Errorf("update userdata fail %s", err)
// }
// }
diskId, err := iVM.RebuildRoot(ctx, desc.ExternalImageId, desc.Password, desc.PublicKey, desc.SysDisk.SizeGB)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s new diskID %s, wait status ready ...", iVM.GetGlobalId(), diskId)
err = cloudprovider.WaitStatus(iVM, models.VM_READY, time.Second*5, time.Second*1800)
if err != nil {
return nil, err
}
log.Debugf("VMrebuildRoot %s, and status is ready", iVM.GetGlobalId())
maxWaitSecs := 300
waited := 0
for {
// hack, wait disk number consistent
idisks, err := iVM.GetIDisks()
if err != nil {
log.Errorf("fail to find VM idisks %s", err)
return nil, err
}
if len(idisks) < len(desc.DataDisks)+1 {
if waited > maxWaitSecs {
log.Errorf("inconsistent disk number, wait timeout, must be something wrong on remote")
return nil, cloudprovider.ErrTimeout
}
log.Debugf("inconsistent disk number???? %d != %d", len(idisks), len(desc.DataDisks)+1)
time.Sleep(time.Second * 5)
waited += 5
} else {
if idisks[0].GetGlobalId() != diskId {
log.Errorf("system disk id inconsistent %s != %s", idisks[0].GetGlobalId(), diskId)
return nil, fmt.Errorf("inconsistent sys disk id after rebuild root")
}
break
}
}
data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action)
return data, nil
})
} else {
log.Errorf("RequestDeployGuestOnHost: Action %s not supported", action)
return fmt.Errorf("Action %s not supported", action)
}
return nil
} */
func (self *SQcloudGuestDriver) RequestSyncConfigOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
ihost, err := host.GetIHost()
if err != nil {
return nil, err
}
iVM, err := ihost.GetIVMById(guest.ExternalId)
if err != nil {
return nil, err
}
if fwOnly, _ := task.GetParams().Bool("fw_only"); fwOnly {
iregion, err := host.GetIRegion()
if err != nil {
return nil, err
}
secgroups := guest.GetSecgroups()
externalIds := []string{}
for _, secgroup := range secgroups {
lockman.LockRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-normal", guest.SecgrpId))
defer lockman.ReleaseRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-normal", guest.SecgrpId))
secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), secgroup.Id, "normal", host.GetRegion().Id, host.ManagerId)
if secgroupCache == nil {
return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s", secgroup.Id)
}
extID, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, "", secgroup.Name, secgroup.Description, secgroup.GetSecRules(""))
if err != nil {
return nil, err
}
if err = secgroupCache.SetExternalId(task.GetUserCred(), extID); err != nil {
return nil, err
}
externalIds = append(externalIds, extID)
}
return nil, iVM.SetSecurityGroups(externalIds)
}
iDisks, err := iVM.GetIDisks()
if err != nil {
return nil, err
}
disks := make([]models.SDisk, 0)
for _, guestdisk := range guest.GetDisks() {
disk := guestdisk.GetDisk()
disks = append(disks, *disk)
}
added := make([]models.SDisk, 0)
commondb := make([]models.SDisk, 0)
commonext := make([]cloudprovider.ICloudDisk, 0)
removed := make([]cloudprovider.ICloudDisk, 0)
if err := compare.CompareSets(disks, iDisks, &added, &commondb, &commonext, &removed); err != nil {
return nil, err
}
for _, disk := range removed {
if err := iVM.DetachDisk(ctx, disk.GetId()); err != nil {
return nil, err
}
}
for _, disk := range added {
if err := iVM.AttachDisk(ctx, disk.ExternalId); err != nil {
return nil, err
}
}
return nil, nil
})
return nil
func (self *SQcloudGuestDriver) GetGuestSecgroupVpcid(guest *models.SGuest) (string, error) {
return api.NORMAL_VPC_ID, nil
}
func (self *SQcloudGuestDriver) AllowReconfigGuest() bool {
+5 -1
View File
@@ -218,7 +218,11 @@ func (self *SVirtualizedGuestDriver) ValidateCreateDataOnHost(ctx context.Contex
input.VmemSize = host.MemSize
input.VcpuCount = int(host.CpuCount)
if host.GetGuestCount() >= 1 {
cnt, err := host.GetGuestCount()
if err != nil {
return nil, httperrors.NewInternalServerError("GetGuestCount fail %s", err)
}
if cnt >= 1 {
return nil, httperrors.NewInsufficientResourceError("host has been occupied")
}
}
+8 -2
View File
@@ -448,8 +448,14 @@ func (self *SKVMHostDriver) PrepareUnconvert(host *models.SHost) error {
}
for i := 0; i < len(hoststorages); i++ {
storage := hoststorages[i].GetStorage()
if storage.IsLocal() && storage.StorageType != api.STORAGE_BAREMETAL && storage.GetDiskCount() > 0 {
return fmt.Errorf("Local host storage is not empty??? %s", storage.GetName())
if storage.IsLocal() && storage.StorageType != api.STORAGE_BAREMETAL {
cnt, err := storage.GetDiskCount()
if err != nil {
return err
}
if cnt > 0 {
return fmt.Errorf("Local host storage is not empty??? %s", storage.GetName())
}
}
}
return self.SBaseHostDriver.PrepareUnconvert(host)
+9 -3
View File
@@ -85,8 +85,11 @@ func (self *SBaremetalagent) ValidateDeleteCondition(ctx context.Context) error
func (self *SBaremetalagent) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
mangerUri, err := data.GetString("manager_uri")
if err == nil {
count := BaremetalagentManager.Query().Equals("manager_uri", mangerUri).
NotEquals("id", self.Id).Count()
count, err := BaremetalagentManager.Query().Equals("manager_uri", mangerUri).
NotEquals("id", self.Id).CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("check agent uniqness fail %s", err)
}
if count > 0 {
return nil, httperrors.NewConflictError("Conflict manager_uri %s", mangerUri)
}
@@ -96,7 +99,10 @@ func (self *SBaremetalagent) ValidateUpdateData(ctx context.Context, userCred mc
func (manager *SBaremetalagentManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
mangerUri, _ := data.GetString("manager_uri")
count := manager.Query().Equals("manager_uri", mangerUri).Count()
count, err := manager.Query().Equals("manager_uri", mangerUri).CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("check agent uniqness fail %s", err)
}
if count > 0 {
return nil, httperrors.NewDuplicateResourceError("Duplicate manager_uri %s", mangerUri)
}
+27 -9
View File
@@ -90,7 +90,11 @@ func (self *SCachedimage) AllowDeleteItem(ctx context.Context, userCred mcclient
}
func (self *SCachedimage) ValidateDeleteCondition(ctx context.Context) error {
if self.getStoragecacheCount() > 0 {
cnt, err := self.getStoragecacheCount()
if err != nil {
return httperrors.NewInternalServerError("ValidateDeleteCondition error %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("The image has been cached on storages")
}
if self.GetStatus() == "active" && !self.isReferenceSessionExpire() {
@@ -148,8 +152,8 @@ func (self *SCachedimage) getStoragecacheQuery() *sqlchemy.SQuery {
return q
}
func (self *SCachedimage) getStoragecacheCount() int {
return self.getStoragecacheQuery().Count()
func (self *SCachedimage) getStoragecacheCount() (int, error) {
return self.getStoragecacheQuery().CountWithError()
}
func (self *SCachedimage) GetImage() (*cloudprovider.SImage, error) {
@@ -183,9 +187,12 @@ func (manager *SCachedimageManager) cacheGlanceImageInfo(ctx context.Context, us
name = imgId
}
name = db.GenerateName(manager, "", name)
name, err := db.GenerateName(manager, "", name)
if err != nil {
return nil, err
}
err := manager.RawQuery().Equals("id", imgId).First(&imageCache)
err = manager.RawQuery().Equals("id", imgId).First(&imageCache)
if err != nil {
if err == sql.ErrNoRows { // insert
imageCache.Id = imgId
@@ -308,7 +315,8 @@ func (self *SCachedimage) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.J
extra.Add(jsonutils.NewString(val), k)
}
}
extra.Add(jsonutils.NewInt(int64(self.getStoragecacheCount())), "cached_count")
cachedCnt, _ := self.getStoragecacheCount()
extra.Add(jsonutils.NewInt(int64(cachedCnt)), "cached_count")
return extra
}
@@ -395,7 +403,12 @@ func (manager *SCachedimageManager) ImageAddRefCount(imageId string) {
}
func (self *SCachedimage) canDeleteLastCache() bool {
if self.getStoragecacheCount() != 1 {
cnt, err := self.getStoragecacheCount()
if err != nil {
// database error
return false
}
if cnt != 1 {
return true
}
if self.isReferenceSessionExpire() {
@@ -426,7 +439,12 @@ func (manager *SCachedimageManager) newFromCloudImage(ctx context.Context, userC
cachedImage := SCachedimage{}
cachedImage.SetModelManager(manager)
cachedImage.Name = db.GenerateName(manager, "", image.GetName())
newName, err := db.GenerateName(manager, "", image.GetName())
if err != nil {
return nil, err
}
cachedImage.Name = newName
cachedImage.Size = image.GetSize()
sImage := cloudprovider.CloudImage2Image(image)
cachedImage.Info = jsonutils.Marshal(&sImage)
@@ -434,7 +452,7 @@ func (manager *SCachedimageManager) newFromCloudImage(ctx context.Context, userC
cachedImage.ImageType = image.GetImageType()
cachedImage.ExternalId = image.GetGlobalId()
err := manager.TableSpec().Insert(&cachedImage)
err = manager.TableSpec().Insert(&cachedImage)
if err != nil {
return nil, err
}
+7 -3
View File
@@ -218,7 +218,7 @@ func getGPUs(region *SCloudregion, zone *SZone) []string {
return gpus
}
func getNetworkCount(region *SCloudregion, zone *SZone) int {
func getNetworkCount(region *SCloudregion, zone *SZone) (int, error) {
wires := WireManager.Query().SubQuery()
networks := NetworkManager.Query().SubQuery()
@@ -234,7 +234,7 @@ func getNetworkCount(region *SCloudregion, zone *SZone) int {
}
q = q.Filter(sqlchemy.Equals(networks.Field("status"), api.NETWORK_STATUS_AVAILABLE))
return q.Count()
return q.CountWithError()
}
func isSchedPolicySupported(region *SCloudregion, zone *SZone) bool {
@@ -282,7 +282,11 @@ func getMaxDataDiskCount(region *SCloudregion, zone *SZone) int {
}
func isUsable(region *SCloudregion, zone *SZone) bool {
if getNetworkCount(region, zone) > 0 {
cnt, err := getNetworkCount(region, zone)
if err != nil {
return false
}
if cnt > 0 {
return true
} else {
return false
+49 -31
View File
@@ -262,11 +262,15 @@ func (manager *SCloudaccountManager) ValidateCreateData(ctx context.Context, use
q = q.Equals("access_url", url)
}
if q.Count() > 0 {
cnt, err := q.CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("check uniqness fail %s", err)
}
if cnt > 0 {
return nil, httperrors.NewConflictError("The account has been registered")
}
err := cloudprovider.IsValidCloudAccount(url, account, secret, provider)
err = cloudprovider.IsValidCloudAccount(url, account, secret, provider)
if err != nil {
if err == cloudprovider.ErrNoSuchProvder {
return nil, httperrors.NewResourceNotFoundError("no such provider %s", provider)
@@ -365,7 +369,11 @@ func (self *SCloudaccount) PerformUpdateCredential(ctx context.Context, userCred
q = q.Equals("account", account.Account)
q = q.Equals("access_url", self.AccessUrl)
q = q.NotEquals("id", self.Id)
if q.Count() > 0 {
cnt, err := q.CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("check uniqueness fail %s", err)
}
if cnt > 0 {
return nil, httperrors.NewConflictError("account %s conflict", account.Account)
}
}
@@ -519,9 +527,9 @@ func (self *SCloudaccount) GetSubAccounts() ([]cloudprovider.SSubAccount, error)
func (self *SCloudaccount) importSubAccount(ctx context.Context, userCred mcclient.TokenCredential, subAccount cloudprovider.SSubAccount) (*SCloudprovider, bool, error) {
isNew := false
q := CloudproviderManager.Query().Equals("cloudaccount_id", self.Id).Equals("account", subAccount.Account)
providerCount := q.Count()
if providerCount < 0 {
return nil, false, fmt.Errorf("fail to query subaccount")
providerCount, err := q.CountWithError()
if err != nil {
return nil, false, err
}
if providerCount > 1 {
log.Errorf("cloudaccount %s has duplicate subaccount with name %s", self.Name, subAccount.Account)
@@ -547,6 +555,10 @@ func (self *SCloudaccount) importSubAccount(ctx context.Context, userCred mcclie
lockman.LockClass(ctx, CloudproviderManager, "")
defer lockman.ReleaseClass(ctx, CloudproviderManager, "")
newName, err := db.GenerateName(CloudproviderManager, "", subAccount.Name)
if err != nil {
return nil, err
}
newCloudprovider := SCloudprovider{}
newCloudprovider.Account = subAccount.Account
newCloudprovider.Secret = self.Secret
@@ -556,14 +568,14 @@ func (self *SCloudaccount) importSubAccount(ctx context.Context, userCred mcclie
newCloudprovider.Enabled = true
newCloudprovider.Status = api.CLOUD_PROVIDER_CONNECTED
newCloudprovider.HealthStatus = self.HealthStatus
newCloudprovider.Name = db.GenerateName(CloudproviderManager, "", subAccount.Name)
newCloudprovider.Name = newName
if !self.AutoCreateProject {
newCloudprovider.ProjectId = auth.AdminCredential().GetProjectId()
}
newCloudprovider.SetModelManager(CloudproviderManager)
err := CloudproviderManager.TableSpec().Insert(&newCloudprovider)
err = CloudproviderManager.TableSpec().Insert(&newCloudprovider)
if err != nil {
return nil, err
} else {
@@ -627,59 +639,59 @@ func (manager *SCloudaccountManager) FetchCloudaccountByIdOrName(accountId strin
return providerObj.(*SCloudaccount)
}
func (self *SCloudaccount) getProviderCount() int {
func (self *SCloudaccount) getProviderCount() (int, error) {
q := CloudproviderManager.Query().Equals("cloudaccount_id", self.Id)
return q.Count()
return q.CountWithError()
}
func (self *SCloudaccount) getHostCount() int {
func (self *SCloudaccount) getHostCount() (int, error) {
subq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
q := HostManager.Query().In("manager_id", subq)
return q.Count()
return q.CountWithError()
}
func (self *SCloudaccount) getVpcCount() int {
func (self *SCloudaccount) getVpcCount() (int, error) {
subq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
q := VpcManager.Query().In("manager_id", subq)
return q.Count()
return q.CountWithError()
}
func (self *SCloudaccount) getStorageCount() int {
func (self *SCloudaccount) getStorageCount() (int, error) {
subq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
q := StorageManager.Query().In("manager_id", subq)
return q.Count()
return q.CountWithError()
}
func (self *SCloudaccount) getStoragecacheCount() int {
func (self *SCloudaccount) getStoragecacheCount() (int, error) {
subq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
q := StoragecacheManager.Query().In("manager_id", subq)
return q.Count()
return q.CountWithError()
}
func (self *SCloudaccount) getEipCount() int {
func (self *SCloudaccount) getEipCount() (int, error) {
subq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
q := ElasticipManager.Query().In("manager_id", subq)
return q.Count()
return q.CountWithError()
}
func (self *SCloudaccount) getRoutetableCount() int {
func (self *SCloudaccount) getRoutetableCount() (int, error) {
subq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
q := RouteTableManager.Query().In("manager_id", subq)
return q.Count()
return q.CountWithError()
}
func (self *SCloudaccount) getGuestCount() int {
func (self *SCloudaccount) getGuestCount() (int, error) {
subsubq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
subq := HostManager.Query("id").In("manager_id", subsubq).SubQuery()
q := GuestManager.Query().In("host_id", subq)
return q.Count()
return q.CountWithError()
}
func (self *SCloudaccount) getDiskCount() int {
func (self *SCloudaccount) getDiskCount() (int, error) {
subsubq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
subq := StorageManager.Query("id").In("manager_id", subsubq).SubQuery()
q := DiskManager.Query().In("storage_id", subq)
return q.Count()
return q.CountWithError()
}
func (self *SCloudaccount) getProjectIds() []string {
@@ -702,10 +714,12 @@ func (self *SCloudaccount) getProjectIds() []string {
}
func (self *SCloudaccount) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict {
extra.Add(jsonutils.NewInt(int64(self.getProviderCount())), "provider_count")
extra.Add(jsonutils.NewInt(int64(self.getHostCount())), "host_count")
extra.Add(jsonutils.NewInt(int64(self.getGuestCount())), "guest_count")
extra.Add(jsonutils.NewInt(int64(self.getDiskCount())), "disk_count")
extra = db.FetchModelExtraCountProperties(self, extra)
// cnt, _ := self.getProviderCount()
// int64(cnt)), "provider_count")
// extra.Add(jsonutils.NewInt(int64(self.getHostCount())), "host_count")
// extra.Add(jsonutils.NewInt(int64(self.getGuestCount())), "guest_count")
// extra.Add(jsonutils.NewInt(int64(self.getDiskCount())), "disk_count")
// extra.Add(jsonutils.NewString(self.getVersion()), "version")
projects := jsonutils.NewArray()
for _, projectId := range self.getProjectIds() {
@@ -1284,7 +1298,11 @@ func (self *SCloudaccount) getSyncStatus() string {
q = q.Filter(sqlchemy.Equals(providers.Field("cloudaccount_id"), self.Id))
q = q.Filter(sqlchemy.NotEquals(cprs.Field("sync_status"), api.CLOUD_PROVIDER_SYNC_STATUS_IDLE))
if q.Count() > 0 {
cnt, err := q.CountWithError()
if err != nil {
return api.CLOUD_PROVIDER_SYNC_STATUS_ERROR
}
if cnt > 0 {
return api.CLOUD_PROVIDER_SYNC_STATUS_SYNCING
} else {
return api.CLOUD_PROVIDER_SYNC_STATUS_IDLE
+35 -31
View File
@@ -171,45 +171,45 @@ func (self *SCloudprovider) CleanSchedCache() {
}
}
func (self *SCloudprovider) GetGuestCount() int {
func (self *SCloudprovider) GetGuestCount() (int, error) {
sq := HostManager.Query("id").Equals("manager_id", self.Id)
return GuestManager.Query().In("host_id", sq).Count()
return GuestManager.Query().In("host_id", sq).CountWithError()
}
func (self *SCloudprovider) GetHostCount() int {
return HostManager.Query().Equals("manager_id", self.Id).Count()
func (self *SCloudprovider) GetHostCount() (int, error) {
return HostManager.Query().Equals("manager_id", self.Id).CountWithError()
}
func (self *SCloudprovider) getVpcCount() int {
return VpcManager.Query().Equals("manager_id", self.Id).Count()
func (self *SCloudprovider) getVpcCount() (int, error) {
return VpcManager.Query().Equals("manager_id", self.Id).CountWithError()
}
func (self *SCloudprovider) getStorageCount() int {
return StorageManager.Query().Equals("manager_id", self.Id).Count()
func (self *SCloudprovider) getStorageCount() (int, error) {
return StorageManager.Query().Equals("manager_id", self.Id).CountWithError()
}
func (self *SCloudprovider) getStoragecacheCount() int {
return StoragecacheManager.Query().Equals("manager_id", self.Id).Count()
func (self *SCloudprovider) getStoragecacheCount() (int, error) {
return StoragecacheManager.Query().Equals("manager_id", self.Id).CountWithError()
}
func (self *SCloudprovider) getEipCount() int {
return ElasticipManager.Query().Equals("manager_id", self.Id).Count()
func (self *SCloudprovider) getEipCount() (int, error) {
return ElasticipManager.Query().Equals("manager_id", self.Id).CountWithError()
}
func (self *SCloudprovider) getSnapshotCount() int {
return SnapshotManager.Query().Equals("manager_id", self.Id).Count()
func (self *SCloudprovider) getSnapshotCount() (int, error) {
return SnapshotManager.Query().Equals("manager_id", self.Id).CountWithError()
}
func (self *SCloudprovider) getLoadbalancerCount() int {
return LoadbalancerManager.Query().Equals("manager_id", self.Id).Count()
func (self *SCloudprovider) getLoadbalancerCount() (int, error) {
return LoadbalancerManager.Query().Equals("manager_id", self.Id).CountWithError()
}
func (self *SCloudprovider) getExternalProjectCount() int {
return ExternalProjectManager.Query().Equals("manager_id", self.Id).Count()
func (self *SCloudprovider) getExternalProjectCount() (int, error) {
return ExternalProjectManager.Query().Equals("manager_id", self.Id).CountWithError()
}
func (self *SCloudprovider) getSyncRegionCount() int {
return CloudproviderRegionManager.Query().Equals("cloudprovider_id", self.Id).Count()
func (self *SCloudprovider) getSyncRegionCount() (int, error) {
return CloudproviderRegionManager.Query().Equals("cloudprovider_id", self.Id).CountWithError()
}
func (self *SCloudprovider) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
@@ -691,16 +691,16 @@ func (usage *SCloudproviderUsage) isEmpty() bool {
func (self *SCloudprovider) getUsage() *SCloudproviderUsage {
usage := SCloudproviderUsage{}
usage.GuestCount = self.GetGuestCount()
usage.HostCount = self.GetHostCount()
usage.VpcCount = self.getVpcCount()
usage.StorageCount = self.getStorageCount()
usage.StorageCacheCount = self.getStoragecacheCount()
usage.EipCount = self.getEipCount()
usage.SnapshotCount = self.getSnapshotCount()
usage.LoadbalancerCount = self.getLoadbalancerCount()
usage.ProjectCount = self.getExternalProjectCount()
usage.SyncRegionCount = self.getSyncRegionCount()
usage.GuestCount, _ = self.GetGuestCount()
usage.HostCount, _ = self.GetHostCount()
usage.VpcCount, _ = self.getVpcCount()
usage.StorageCount, _ = self.getStorageCount()
usage.StorageCacheCount, _ = self.getStoragecacheCount()
usage.EipCount, _ = self.getEipCount()
usage.SnapshotCount, _ = self.getSnapshotCount()
usage.LoadbalancerCount, _ = self.getLoadbalancerCount()
usage.ProjectCount, _ = self.getExternalProjectCount()
usage.SyncRegionCount, _ = self.getSyncRegionCount()
return &usage
}
@@ -796,8 +796,12 @@ func (manager *SCloudproviderManager) migrateVCenterInfo(vc *SVCenter) error {
cp := SCloudprovider{}
cp.SetModelManager(manager)
newName, err := db.GenerateName(manager, "", vc.Name)
if err != nil {
return err
}
cp.Id = vc.Id
cp.Name = db.GenerateName(manager, "", vc.Name)
cp.Name = newName
cp.Status = vc.Status
cp.AccessUrl = fmt.Sprintf("https://%s:%d", vc.Hostname, vc.Port)
cp.Account = vc.Account
+33 -17
View File
@@ -87,7 +87,15 @@ func (self *SCloudregion) CustomizeCreate(ctx context.Context, userCred mcclient
}
func (self *SCloudregion) ValidateDeleteCondition(ctx context.Context) error {
if self.GetZoneCount() > 0 || self.GetVpcCount() > 0 {
zoneCnt, err := self.GetZoneCount()
if err != nil {
return httperrors.NewInternalServerError("GetZoneCount fail %s", err)
}
vpcCnt, err := self.GetVpcCount()
if err != nil {
return httperrors.NewInternalServerError("GetVpcCount fail %s", err)
}
if zoneCnt > 0 || vpcCnt > 0 {
return httperrors.NewNotEmptyError("not empty cloud region")
}
if self.Id == api.DEFAULT_REGION_ID {
@@ -96,18 +104,26 @@ func (self *SCloudregion) ValidateDeleteCondition(ctx context.Context) error {
return self.SEnabledStatusStandaloneResourceBase.ValidateDeleteCondition(ctx)
}
func (self *SCloudregion) GetZoneCount() int {
func (self *SCloudregion) GetZoneCount() (int, error) {
zones := ZoneManager.Query()
if self.Id == api.DEFAULT_REGION_ID {
return zones.Filter(sqlchemy.OR(sqlchemy.IsNull(zones.Field("cloudregion_id")),
sqlchemy.IsEmpty(zones.Field("cloudregion_id")),
sqlchemy.Equals(zones.Field("cloudregion_id"), self.Id))).Count()
sqlchemy.Equals(zones.Field("cloudregion_id"), self.Id))).CountWithError()
} else {
return zones.Equals("cloudregion_id", self.Id).Count()
return zones.Equals("cloudregion_id", self.Id).CountWithError()
}
}
func (self *SCloudregion) GetGuestCount(increment bool) int {
func (self *SCloudregion) GetGuestCount() (int, error) {
return self.getGuestCountInternal(false)
}
func (self *SCloudregion) GetGuestIncrementCount() (int, error) {
return self.getGuestCountInternal(true)
}
func (self *SCloudregion) getGuestCountInternal(increment bool) (int, error) {
zoneTable := ZoneManager.Query("id")
if self.Id == api.DEFAULT_REGION_ID {
zoneTable = zoneTable.Filter(sqlchemy.OR(sqlchemy.IsNull(zoneTable.Field("cloudregion_id")),
@@ -123,17 +139,17 @@ func (self *SCloudregion) GetGuestCount(increment bool) int {
startOfMonth := time.Date(year, month, 1, 0, 0, 0, 0, time.UTC)
query.GE("created_at", startOfMonth)
}
return query.Count()
return query.CountWithError()
}
func (self *SCloudregion) GetVpcCount() int {
func (self *SCloudregion) GetVpcCount() (int, error) {
vpcs := VpcManager.Query()
if self.Id == api.DEFAULT_REGION_ID {
return vpcs.Filter(sqlchemy.OR(sqlchemy.IsNull(vpcs.Field("cloudregion_id")),
sqlchemy.IsEmpty(vpcs.Field("cloudregion_id")),
sqlchemy.Equals(vpcs.Field("cloudregion_id"), self.Id))).Count()
sqlchemy.Equals(vpcs.Field("cloudregion_id"), self.Id))).CountWithError()
} else {
return vpcs.Equals("cloudregion_id", self.Id).Count()
return vpcs.Equals("cloudregion_id", self.Id).CountWithError()
}
}
@@ -149,11 +165,7 @@ func (self *SCloudregion) GetDriver() IRegionDriver {
}
func (self *SCloudregion) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict {
extra.Add(jsonutils.NewInt(int64(self.GetVpcCount())), "vpc_count")
extra.Add(jsonutils.NewInt(int64(self.GetZoneCount())), "zone_count")
extra.Add(jsonutils.NewInt(int64(self.GetGuestCount(false))), "guest_count")
extra.Add(jsonutils.NewInt(int64(self.GetGuestCount(true))), "guest_increment_count")
return extra
return db.FetchModelExtraCountProperties(self, extra)
}
func (self *SCloudregion) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
@@ -311,8 +323,12 @@ func (manager *SCloudregionManager) newFromCloudRegion(ctx context.Context, user
region := SCloudregion{}
region.SetModelManager(manager)
newName, err := db.GenerateName(manager, "", cloudRegion.GetName())
if err != nil {
return nil, err
}
region.ExternalId = cloudRegion.GetGlobalId()
region.Name = db.GenerateName(manager, "", cloudRegion.GetName())
region.Name = newName
region.SGeographicInfo = cloudRegion.GetGeographicInfo()
region.Status = cloudRegion.GetStatus()
region.Enabled = true
@@ -320,7 +336,7 @@ func (manager *SCloudregionManager) newFromCloudRegion(ctx context.Context, user
region.IsEmulated = cloudRegion.IsEmulated()
err := manager.TableSpec().Insert(&region)
err = manager.TableSpec().Insert(&region)
if err != nil {
log.Errorf("newFromCloudRegion fail %s", err)
return nil, err
@@ -527,7 +543,7 @@ func (self *SCloudregion) GetDetailsCapability(ctx context.Context, userCred mcc
return jsonutils.Marshal(&capa), nil
}
func (self *SCloudregion) getNetworkCount() int {
func (self *SCloudregion) getNetworkCount() (int, error) {
return getNetworkCount(self, nil)
}
+25 -14
View File
@@ -93,25 +93,36 @@ func syncRegionZones(ctx context.Context, userCred mcclient.TokenCredential, syn
func syncRegionSkus(ctx context.Context, localRegion *SCloudregion) {
if localRegion == nil {
log.Debugf("local region is nil skipped.")
log.Debugf("local region is nil, skipp...")
return
}
regionId := localRegion.GetId()
if len(regionId) > 0 && ServerSkuManager.GetSkuCountByRegion(regionId) == 0 {
// 提前同步instance type.如果同步失败可能导致vm 内存显示为0
if err := syncSkusByRegion(localRegion); err != nil {
msg := fmt.Sprintf("Get Skus for region %s failed %s", localRegion.GetName(), err)
log.Errorf(msg)
// 暂时不终止同步
// logSyncFailed(provider, task, msg)
return
}
if len(regionId) == 0 {
log.Debugf("local region Id is empty, skip...")
return
}
_, err := modules.SchedManager.SyncSku(auth.GetAdminSession(ctx, options.Options.Region, ""), false)
if err != nil {
log.Errorf("SchedManager SyncSku %s", err)
}
cnt, err := ServerSkuManager.GetSkuCountByRegion(regionId)
if err != nil {
log.Errorf("GetSkuCountByRegion fail %s", err)
return
}
if cnt > 0 {
return
}
// 提前同步instance type.如果同步失败可能导致vm 内存显示为0
if err = syncSkusByRegion(localRegion); err != nil {
msg := fmt.Sprintf("Get Skus for region %s failed %s", localRegion.GetName(), err)
log.Errorln(msg)
// 暂时不终止同步
// logSyncFailed(provider, task, msg)
return
}
_, err = modules.SchedManager.SyncSku(auth.GetAdminSession(ctx, options.Options.Region, ""), false)
if err != nil {
log.Errorf("SchedManager SyncSku %s", err)
}
}
+52 -21
View File
@@ -269,13 +269,17 @@ func (manager *SDiskManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQu
return q, nil
}
func (self *SDisk) GetGuestDiskCount() int {
func (self *SDisk) GetGuestDiskCount() (int, error) {
guestdisks := GuestdiskManager.Query()
return guestdisks.Equals("disk_id", self.Id).Count()
return guestdisks.Equals("disk_id", self.Id).CountWithError()
}
func (self *SDisk) isAttached() bool {
return GuestdiskManager.Query().Equals("disk_id", self.Id).Count() > 0
func (self *SDisk) isAttached() (bool, error) {
cnt, err := self.GetGuestDiskCount()
if err != nil {
return false, err
}
return cnt > 0, nil
}
func (self *SDisk) GetGuestdisks() []SGuestdisk {
@@ -304,21 +308,21 @@ func (self *SDisk) GetGuests() []SGuest {
return result
}
func (self *SDisk) GetGuestsCount() int {
func (self *SDisk) GetGuestsCount() (int, error) {
guests := GuestManager.Query().SubQuery()
guestdisks := GuestdiskManager.Query().SubQuery()
return guests.Query().Join(guestdisks, sqlchemy.AND(
sqlchemy.Equals(guestdisks.Field("guest_id"), guests.Field("id")))).
Filter(sqlchemy.Equals(guestdisks.Field("disk_id"), self.Id)).Count()
Filter(sqlchemy.Equals(guestdisks.Field("disk_id"), self.Id)).CountWithError()
}
func (self *SDisk) GetRuningGuestCount() int {
func (self *SDisk) GetRuningGuestCount() (int, error) {
guests := GuestManager.Query().SubQuery()
guestdisks := GuestdiskManager.Query().SubQuery()
return guests.Query().Join(guestdisks, sqlchemy.AND(
sqlchemy.Equals(guestdisks.Field("guest_id"), guests.Field("id")))).
Filter(sqlchemy.Equals(guestdisks.Field("disk_id"), self.Id)).
Filter(sqlchemy.Equals(guests.Field("status"), api.VM_RUNNING)).Count()
Filter(sqlchemy.Equals(guests.Field("status"), api.VM_RUNNING)).CountWithError()
}
func (self *SDisk) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
@@ -522,11 +526,10 @@ func (self *SDisk) StartDiskCreateTask(ctx context.Context, userCred mcclient.To
return nil
}
func (self *SDisk) GetSnapshotCount() int {
func (self *SDisk) GetSnapshotCount() (int, error) {
q := SnapshotManager.Query()
count := q.Filter(sqlchemy.AND(sqlchemy.Equals(q.Field("disk_id"), self.Id),
sqlchemy.Equals(q.Field("fake_deleted"), false))).Count()
return count
return q.Filter(sqlchemy.AND(sqlchemy.Equals(q.Field("disk_id"), self.Id),
sqlchemy.Equals(q.Field("fake_deleted"), false))).CountWithError()
}
func (self *SDisk) StartAllocate(ctx context.Context, host *SHost, storage *SStorage, taskId string, userCred mcclient.TokenCredential, rebuild bool, snapshot string, task taskman.ITask) error {
@@ -800,7 +803,11 @@ func (self *SDisk) PerformSave(ctx context.Context, userCred mcclient.TokenCrede
return nil, httperrors.NewResourceNotReadyError("Save disk when disk is READY")
}
if self.GetRuningGuestCount() > 0 {
cnt, err := self.GetRuningGuestCount()
if err != nil {
return nil, httperrors.NewInternalServerError("GetRuningGuestCount fail %s", err)
}
if cnt > 0 {
return nil, httperrors.NewResourceNotReadyError("Save disk when not being USED")
}
@@ -836,7 +843,11 @@ func (self *SDisk) ValidatePurgeCondition(ctx context.Context) error {
}
func (self *SDisk) validateDeleteCondition(ctx context.Context, isPurge bool) error {
if self.GetGuestDiskCount() > 0 {
cnt, err := self.GetGuestDiskCount()
if err != nil {
return httperrors.NewInternalServerError("GetGuestDiskCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("Virtual disk used by virtual servers")
}
if !isPurge && self.IsValidPrePaid() {
@@ -1076,7 +1087,11 @@ func (manager *SDiskManager) newFromCloudDisk(ctx context.Context, userCred mccl
disk := SDisk{}
disk.SetModelManager(manager)
disk.Name = db.GenerateName(manager, projectId, extDisk.GetName())
newName, err := db.GenerateName(manager, projectId, extDisk.GetName())
if err != nil {
return nil, err
}
disk.Name = newName
disk.Status = extDisk.GetStatus()
disk.ExternalId = extDisk.GetGlobalId()
disk.StorageId = storage.Id
@@ -1097,7 +1112,7 @@ func (manager *SDiskManager) newFromCloudDisk(ctx context.Context, userCred mccl
disk.ExpiredAt = extDisk.GetExpiredAt()
}
err := manager.TableSpec().Insert(&disk)
err = manager.TableSpec().Insert(&disk)
if err != nil {
log.Errorf("newFromCloudZone fail %s", err)
return nil, err
@@ -1345,8 +1360,14 @@ func (self *SDisk) PerformPurge(ctx context.Context, userCred mcclient.TokenCred
}
provider := self.GetCloudprovider()
if provider != nil && provider.Provider == api.CLOUD_PROVIDER_HUAWEI && self.GetSnapshotCount() > 0 {
return nil, httperrors.NewForbiddenError("not allow to purge. Virtual disk must not have snapshots")
if provider != nil && provider.Provider == api.CLOUD_PROVIDER_HUAWEI {
cnt, err := self.GetSnapshotCount()
if err != nil {
return nil, httperrors.NewInternalServerError("GetSnapshotCount fail %s", err)
}
if cnt > 0 {
return nil, httperrors.NewForbiddenError("not allow to purge. Virtual disk must not have snapshots")
}
}
return nil, self.StartDiskDeleteTask(ctx, userCred, "", true, false)
@@ -1354,8 +1375,14 @@ func (self *SDisk) PerformPurge(ctx context.Context, userCred mcclient.TokenCred
func (self *SDisk) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
provider := self.GetCloudprovider()
if provider != nil && provider.Provider == api.CLOUD_PROVIDER_HUAWEI && self.GetSnapshotCount() > 0 {
return httperrors.NewForbiddenError("not allow to delete. Virtual disk must not have snapshots")
if provider != nil && provider.Provider == api.CLOUD_PROVIDER_HUAWEI {
cnt, err := self.GetSnapshotCount()
if err != nil {
return httperrors.NewInternalServerError("GetSnapshotCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewForbiddenError("not allow to delete. Virtual disk must not have snapshots")
}
}
return self.StartDiskDeleteTask(ctx, userCred, "", false,
@@ -1613,7 +1640,11 @@ func (manager *SDiskManager) AutoDiskSnapshot(ctx context.Context, userCred mccl
return
}
for _, disk := range disks {
snapCount := disk.GetSnapshotCount()
snapCount, err := disk.GetSnapshotCount()
if err != nil {
log.Errorf("GetSnapshotCount fail %s", err)
continue
}
if snapCount >= options.Options.DefaultMaxSnapshotCount {
continue
}
+9 -5
View File
@@ -346,7 +346,11 @@ func (manager *SElasticipManager) newFromCloudEip(ctx context.Context, userCred
eip := SElasticip{}
eip.SetModelManager(manager)
eip.Name = db.GenerateName(manager, projectId, extEip.GetName())
newName, err := db.GenerateName(manager, projectId, extEip.GetName())
if err != nil {
return nil, err
}
eip.Name = newName
eip.Status = extEip.GetStatus()
eip.ExternalId = extEip.GetGlobalId()
eip.IpAddr = extEip.GetIpAddr()
@@ -356,7 +360,7 @@ func (manager *SElasticipManager) newFromCloudEip(ctx context.Context, userCred
eip.CloudregionId = region.Id
eip.ChargeType = extEip.GetInternetChargeType()
err := manager.TableSpec().Insert(&eip)
err = manager.TableSpec().Insert(&eip)
if err != nil {
log.Errorf("newFromCloudEip fail %s", err)
return nil, err
@@ -973,9 +977,9 @@ func (manager *SElasticipManager) TotalCount(projectId string, rangeObj db.IStan
q2 = q2.Equals("tenant_id", projectId)
q3 = q3.Equals("tenant_id", projectId)
}
usage.PublicIPCount = q1.Count()
usage.EIPCount = q2.Count()
usage.EIPUsedCount = q3.Count()
usage.PublicIPCount, _ = q1.CountWithError()
usage.EIPCount, _ = q2.CountWithError()
usage.EIPUsedCount, _ = q3.CountWithError()
return usage
}
+10 -3
View File
@@ -120,7 +120,10 @@ func (manager *SExternalProjectManager) GetProject(externalId string, providerId
project := &SExternalProject{}
project.SetModelManager(manager)
q := manager.Query().Equals("external_id", externalId).Equals("manager_id", providerId)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count == 0 {
return nil, fmt.Errorf("no external project record %s for provider %s", externalId, providerId)
}
@@ -205,13 +208,17 @@ func (manager *SExternalProjectManager) newFromCloudProject(ctx context.Context,
project := SExternalProject{}
project.SetModelManager(manager)
project.Name = db.GenerateName(manager, manager.GetOwnerId(userCred), extProject.GetName())
newName, err := db.GenerateName(manager, manager.GetOwnerId(userCred), extProject.GetName())
if err != nil {
return nil, err
}
project.Name = newName
project.ExternalId = extProject.GetGlobalId()
project.IsEmulated = extProject.IsEmulated()
project.ManagerId = provider.Id
project.ProjectId = provider.ProjectId
err := manager.TableSpec().Insert(&project)
err = manager.TableSpec().Insert(&project)
if err != nil {
log.Errorf("newFromCloudProject fail %s", err)
return nil, err
+26 -7
View File
@@ -499,7 +499,11 @@ func (self *SGuest) ValidateAttachDisk(ctx context.Context, disk *SDisk) error {
}
}
if disk.isAttached() {
attached, err := disk.isAttached()
if err != nil {
return httperrors.NewInternalServerError("isAttached check failed %s", err)
}
if attached {
return httperrors.NewInputParameterError("Disk %s has been attached", disk.Name)
}
if len(disk.GetPathAtHost(self.GetHost())) == 0 {
@@ -1309,7 +1313,11 @@ func (self *SGuest) PerformDetachdisk(ctx context.Context, userCred mcclient.Tok
}
disk := iDisk.(*SDisk)
if disk != nil {
if self.isAttach2Disk(disk) {
attached, err := self.isAttach2Disk(disk)
if err != nil {
return nil, httperrors.NewInternalServerError("check isAttach2Disk fail %s", err)
}
if attached {
if disk.DiskType == api.DISK_TYPE_SYS {
return nil, httperrors.NewUnsupportOperationError("Cannot detach sys disk")
}
@@ -1519,7 +1527,11 @@ func (self *SGuest) PerformChangeIpaddr(ctx context.Context, userCred mcclient.T
return nil, httperrors.NewInvalidStatusError("cannot change mac when guest is running")
}
// check mac duplication
if GuestnetworkManager.Query().Equals("mac_addr", conf.Mac).Count() > 0 {
cnt, err := GuestnetworkManager.Query().Equals("mac_addr", conf.Mac).CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("check mac uniqueness fail %s", err)
}
if cnt > 0 {
return nil, httperrors.NewConflictError("mac addr %s has been occupied", conf.Mac)
}
} else {
@@ -2073,9 +2085,12 @@ func (self *SGuest) PerformDiskSnapshot(ctx context.Context, userCred mcclient.T
}
if self.GetHypervisor() == api.HYPERVISOR_KVM {
q := SnapshotManager.Query()
cnt := q.Filter(sqlchemy.AND(sqlchemy.Equals(q.Field("disk_id"), diskId),
cnt, err := q.Filter(sqlchemy.AND(sqlchemy.Equals(q.Field("disk_id"), diskId),
sqlchemy.Equals(q.Field("created_by"), api.SNAPSHOT_MANUAL),
sqlchemy.Equals(q.Field("fake_deleted"), false))).Count()
sqlchemy.Equals(q.Field("fake_deleted"), false))).CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("check disk snapshot count fail %s", err)
}
if cnt >= options.Options.DefaultMaxManualSnapshotCount {
return nil, httperrors.NewBadRequestError("Disk %s snapshot full, cannot take any more", diskId)
}
@@ -2566,12 +2581,16 @@ func (self *SGuest) PerformCreateBackup(ctx context.Context, userCred mcclient.T
if len(self.GetIsolatedDevices()) > 0 {
return nil, httperrors.NewBadRequestError("Cannot create backup with isolated devices")
}
if self.GuestDisksHasSnapshot() {
hasSnapshot, err := self.GuestDisksHasSnapshot()
if err != nil {
return nil, httperrors.NewInternalServerError("GuestDisksHasSnapshot fail %s", err)
}
if hasSnapshot {
return nil, httperrors.NewBadRequestError("Cannot create backup with snapshot")
}
req := self.getGuestBackupResourceRequirements(ctx, userCred)
err := QuotaManager.CheckSetPendingQuota(ctx, userCred, self.GetOwnerProjectId(), &req)
err = QuotaManager.CheckSetPendingQuota(ctx, userCred, self.GetOwnerProjectId(), &req)
if err != nil {
return nil, httperrors.NewOutOfQuotaError(err.Error())
}
+5 -2
View File
@@ -80,9 +80,12 @@ func (self *SGuestdisk) ValidateUpdateData(ctx context.Context, userCred mcclien
return nil, err
} else {
guestdisk := GuestdiskManager.Query().SubQuery()
count := guestdisk.Query().Filter(sqlchemy.Equals(guestdisk.Field("guest_id"), self.GuestId)).
count, err := guestdisk.Query().Filter(sqlchemy.Equals(guestdisk.Field("guest_id"), self.GuestId)).
Filter(sqlchemy.NotEquals(guestdisk.Field("disk_id"), self.DiskId)).
Filter(sqlchemy.Equals(guestdisk.Field("index"), index)).Count()
Filter(sqlchemy.Equals(guestdisk.Field("index"), index)).CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("check disk index uniqueness fail %s", err)
}
if count > 0 {
return nil, httperrors.NewInputParameterError("DISK Index %d has been occupied", index)
}
+2
View File
@@ -90,6 +90,8 @@ type IGuestDriver interface {
StartGuestSyncstatusTask(guest *SGuest, ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error
RequestSyncConfigOnHost(ctx context.Context, guest *SGuest, host *SHost, task taskman.ITask) error
RequestSyncSecgroupsOnHost(ctx context.Context, guest *SGuest, host *SHost, task taskman.ITask) error
GetGuestSecgroupVpcid(guest *SGuest) (string, error)
RequestSyncstatusOnHost(ctx context.Context, guest *SGuest, host *SHost, userCred mcclient.TokenCredential) (jsonutils.JSONObject, error)
+21 -10
View File
@@ -34,6 +34,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
@@ -111,7 +112,7 @@ func (gn *SGuestnetwork) AllowDeleteItem(ctx context.Context, userCred mcclient.
const MAX_TRIES = 10
func (manager *SGuestnetworkManager) GenerateMac(netId string, suggestion string) string {
func (manager *SGuestnetworkManager) GenerateMac(netId string, suggestion string) (string, error) {
for tried := 0; tried < MAX_TRIES; tried += 1 {
var mac string
if len(suggestion) > 0 && regutils.MatchMacAddr(suggestion) {
@@ -130,11 +131,15 @@ func (manager *SGuestnetworkManager) GenerateMac(netId string, suggestion string
if len(netId) > 0 {
q = q.Equals("network_id", netId)
}
if q.Count() == 0 {
return mac
cnt, err := q.CountWithError()
if err != nil {
return "", err
}
if cnt == 0 {
return mac, nil
}
}
return ""
return "", fmt.Errorf("maximal retry reached")
}
func (manager *SGuestnetworkManager) newGuestNetwork(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, network *SNetwork,
@@ -159,7 +164,10 @@ func (manager *SGuestnetworkManager) newGuestNetwork(ctx context.Context, userCr
lockman.LockObject(ctx, network)
defer lockman.ReleaseObject(ctx, network)
macAddr := manager.GenerateMac(network.Id, mac)
macAddr, err := manager.GenerateMac(network.Id, mac)
if err != nil {
return nil, err
}
if len(macAddr) == 0 {
log.Errorf("Mac address generate fails")
return nil, fmt.Errorf("mac address generate fails")
@@ -189,7 +197,7 @@ func (manager *SGuestnetworkManager) newGuestNetwork(ctx context.Context, userCr
}
gn.Ifname = ifName
gn.TeamWith = teamWithMac
err := manager.TableSpec().Insert(&gn)
err = manager.TableSpec().Insert(&gn)
if err != nil {
return nil, err
}
@@ -382,14 +390,17 @@ func (self *SGuestnetwork) ValidateUpdateData(ctx context.Context, userCred mccl
if data.Contains("index") {
index, err := data.Int("index")
if err != nil {
return nil, fmt.Errorf("fail to fetch index %s", err)
return nil, httperrors.NewInternalServerError("fail to fetch index %s", err)
}
q := GuestnetworkManager.Query().SubQuery()
count := q.Query().Filter(sqlchemy.Equals(q.Field("guest_id"), self.GuestId)).
count, err := q.Query().Filter(sqlchemy.Equals(q.Field("guest_id"), self.GuestId)).
Filter(sqlchemy.NotEquals(q.Field("network_id"), self.NetworkId)).
Filter(sqlchemy.Equals(q.Field("index"), index)).Count()
Filter(sqlchemy.Equals(q.Field("index"), index)).CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("checkout nic index uniqueness fail %s", err)
}
if count > 0 {
return nil, fmt.Errorf("NIC Index %d has been occupied", index)
return nil, httperrors.NewDuplicateResourceError("NIC Index %d has been occupied", index)
}
}
return self.SJointResourceBase.ValidateUpdateData(ctx, userCred, query, data)
+42 -20
View File
@@ -436,7 +436,10 @@ func (manager *SGuestManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQ
}
disk := diskI.(*SDisk)
guestdisks := GuestdiskManager.Query().SubQuery()
count := guestdisks.Query().Equals("disk_id", disk.Id).Count()
count, err := guestdisks.Query().Equals("disk_id", disk.Id).CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("checkout guestdisk count fail %s", err)
}
if count > 0 {
sgq := guestdisks.Query(guestdisks.Field("guest_id")).Equals("disk_id", disk.Id).SubQuery()
q = q.Filter(sqlchemy.In(q.Field("id"), sgq))
@@ -585,8 +588,8 @@ func (guest *SGuest) GetDisksQuery() *sqlchemy.SQuery {
return GuestdiskManager.Query().Equals("guest_id", guest.Id)
}
func (guest *SGuest) DiskCount() int {
return guest.GetDisksQuery().Count()
func (guest *SGuest) DiskCount() (int, error) {
return guest.GetDisksQuery().CountWithError()
}
func (guest *SGuest) GetDisks() []SGuestdisk {
@@ -622,8 +625,8 @@ func (guest *SGuest) GetNetworksQuery(netId string) *sqlchemy.SQuery {
return q
}
func (guest *SGuest) NetworkCount() int {
return guest.GetNetworksQuery("").Count()
func (guest *SGuest) NetworkCount() (int, error) {
return guest.GetNetworksQuery("").CountWithError()
}
func (guest *SGuest) GetNetworks(netId string) ([]SGuestnetwork, error) {
@@ -1943,7 +1946,11 @@ func (manager *SGuestManager) newCloudVM(ctx context.Context, userCred mcclient.
if options.NameSyncResources.Contains(manager.Keyword()) {
guest.Name = extVM.GetName()
} else {
guest.Name = db.GenerateName(manager, projectId, extVM.GetName())
newName, err := db.GenerateName(manager, projectId, extVM.GetName())
if err != nil {
return nil, err
}
guest.Name = newName
}
guest.VcpuCount = extVM.GetVcpuCount()
guest.BootOrder = extVM.GetBootOrder()
@@ -2033,10 +2040,10 @@ func (self *SGuest) detachNetworks(ctx context.Context, userCred mcclient.TokenC
return nil
}
func (self *SGuest) getAttach2NetworkCount(net *SNetwork) int {
func (self *SGuest) getAttach2NetworkCount(net *SNetwork) (int, error) {
q := GuestnetworkManager.Query()
q = q.Equals("guest_id", self.Id).Equals("network_id", net.Id)
return q.Count()
return q.CountWithError()
}
func (self *SGuest) getMaxNicIndex() int8 {
@@ -2279,9 +2286,13 @@ func (self *SGuest) SyncVMNics(ctx context.Context, userCred mcclient.TokenCrede
return result
}
func (self *SGuest) isAttach2Disk(disk *SDisk) bool {
func (self *SGuest) isAttach2Disk(disk *SDisk) (bool, error) {
q := GuestdiskManager.Query().Equals("disk_id", disk.Id).Equals("guest_id", self.Id)
return q.Count() > 0
cnt, err := q.CountWithError()
if err != nil {
return false, err
}
return cnt > 0, nil
}
func (self *SGuest) getMaxDiskIndex() int8 {
@@ -2294,7 +2305,11 @@ func (self *SGuest) AttachDisk(ctx context.Context, disk *SDisk, userCred mcclie
}
func (self *SGuest) attach2Disk(ctx context.Context, disk *SDisk, userCred mcclient.TokenCredential, driver string, cache string, mountpoint string) error {
if self.isAttach2Disk(disk) {
attached, err := self.isAttach2Disk(disk)
if err != nil {
return err
}
if attached {
return fmt.Errorf("Guest has been attached to disk")
}
index := self.getMaxDiskIndex()
@@ -2308,7 +2323,7 @@ func (self *SGuest) attach2Disk(ctx context.Context, disk *SDisk, userCred mccli
guestdisk.DiskId = disk.Id
guestdisk.GuestId = self.Id
guestdisk.Index = index
err := guestdisk.DoSave(driver, cache, mountpoint)
err = guestdisk.DoSave(driver, cache, mountpoint)
if err == nil {
db.OpsLog.LogAttachEvent(ctx, self, disk, userCred, nil)
}
@@ -3036,9 +3051,9 @@ func (self *SGuest) GetDeployConfigOnHost(ctx context.Context, userCred mcclient
secgroupIds := jsonutils.NewArray()
secgroups := self.GetSecgroups()
for i, secgroup := range secgroups {
secgroupCache := SecurityGroupCacheManager.Register(ctx, userCred, secgroup.Id, registerVpcId, vpc.CloudregionId, vpc.ManagerId)
if secgroupCache == nil {
return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s(%s), vpc: %s", secgroup.Name, secgroup.Id, vpc.Name)
secgroupCache, err := SecurityGroupCacheManager.Register(ctx, userCred, secgroup.Id, registerVpcId, vpc.CloudregionId, vpc.ManagerId)
if err != nil {
return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s(%s), vpc: %s: %s", secgroup.Name, secgroup.Id, vpc.Name, err)
}
externalSecgroupId, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, externalVpcId, secgroup.Name, secgroup.Description, secgroup.GetSecRules(""))
@@ -3871,7 +3886,10 @@ func (self *SGuest) getSecgroupByCache(provider *SCloudprovider, externalId stri
q := SecurityGroupCacheManager.Query().Equals("manager_id", provider.Id).Equals("external_id", externalId)
cache := SSecurityGroupCache{}
cache.SetModelManager(SecurityGroupCacheManager)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, fmt.Errorf("getSecgroupByCache fail %s", err)
}
if count == 0 {
return nil, fmt.Errorf("failed find secgroup cache from provider %s externalId %s", provider.Name, externalId)
}
@@ -4083,14 +4101,18 @@ func (self *SGuest) FillNetSchedDesc(desc *api.ServerConfigs) {
}
}
func (self *SGuest) GuestDisksHasSnapshot() bool {
func (self *SGuest) GuestDisksHasSnapshot() (bool, error) {
guestDisks := self.GetDisks()
for i := 0; i < len(guestDisks); i++ {
if SnapshotManager.GetDiskSnapshotCount(guestDisks[i].DiskId) > 0 {
return true
cnt, err := SnapshotManager.GetDiskSnapshotCount(guestDisks[i].DiskId)
if err != nil {
return false, err
}
if cnt > 0 {
return true, nil
}
}
return false
return false, nil
}
func (self *SGuest) OnScheduleToHost(ctx context.Context, userCred mcclient.TokenCredential, hostId string) error {
+5 -1
View File
@@ -65,7 +65,11 @@ func (self *SGuestsecgroup) getSecgroup() *SSecurityGroup {
func (manager *SGuestsecgroupManager) newGuestSecgroup(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, secgroup *SSecurityGroup) (*SGuestsecgroup, error) {
q := manager.Query()
q = q.Equals("guest_id", guest.Id).Equals("secgroup_id", secgroup.Id)
if count := q.Count(); count > 0 {
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count > 0 {
return nil, fmt.Errorf("security group %s has already been assigned to guest %s", secgroup.Name, guest.Name)
}
+6 -2
View File
@@ -413,7 +413,11 @@ func doUndoPrepaidRecycleNoLock(ctx context.Context, userCred mcclient.TokenCred
sqlchemy.Equals(q.Field("resource_type"), api.HostResourceTypeShared),
))
oHostCnt := q.Count()
oHostCnt, err := q.CountWithError()
if err != nil {
return err
}
if oHostCnt == 0 {
msg := "orthordox host not found???"
@@ -429,7 +433,7 @@ func doUndoPrepaidRecycleNoLock(ctx context.Context, userCred mcclient.TokenCred
oHost := SHost{}
oHost.SetModelManager(HostManager)
err := q.First(&oHost)
err = q.First(&oHost)
if err != nil {
msg := fmt.Sprintf("fail to query orthordox host %s", err)
log.Errorf(msg)
+162 -86
View File
@@ -475,14 +475,25 @@ func (self *SHost) validateDeleteCondition(ctx context.Context, purge bool) erro
if self.Enabled {
return httperrors.NewInvalidStatusError("Host is not disabled")
}
if self.GetGuestCount() > 0 {
cnt, err := self.GetGuestCount()
if err != nil {
return httperrors.NewInternalServerError("getGuestCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("Not an empty host")
}
for _, hoststorage := range self.GetHoststorages() {
storage := hoststorage.GetStorage()
if storage != nil && storage.IsLocal() && storage.GetDiskCount() > 0 {
return httperrors.NewNotEmptyError("Local host storage is not empty???")
if storage != nil && storage.IsLocal() {
cnt, err := storage.GetDiskCount()
if err != nil {
return httperrors.NewInternalServerError("GetDiskCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("Local host storage is not empty???")
}
}
}
return self.SEnabledStatusStandaloneResourceBase.ValidateDeleteCondition(ctx)
}
@@ -516,8 +527,14 @@ func (self *SHost) RealDelete(ctx context.Context, userCred mcclient.TokenCreden
for _, hoststorage := range self.GetHoststorages() {
storage := hoststorage.GetStorage()
if storage != nil && storage.IsLocal() && storage.GetDiskCount() > 0 {
return httperrors.NewNotEmptyError("Inconsistent: local storage is not empty???")
if storage != nil && storage.IsLocal() {
cnt, err := storage.GetDiskCount()
if err != nil {
return err
}
if cnt > 0 {
return httperrors.NewNotEmptyError("Inconsistent: local storage is not empty???")
}
}
}
for _, hoststorage := range self.GetHoststorages() {
@@ -552,8 +569,8 @@ func (self *SHost) GetHoststoragesQuery() *sqlchemy.SQuery {
return HoststorageManager.Query().Equals("host_id", self.Id)
}
func (self *SHost) GetStorageCount() int {
return self.GetHoststoragesQuery().Count()
func (self *SHost) GetStorageCount() (int, error) {
return self.GetHoststoragesQuery().CountWithError()
}
func (self *SHost) GetHoststorages() []SHoststorage {
@@ -622,7 +639,11 @@ func (self *SHost) GetBaremetalstorage() *SHoststorage {
sqlchemy.IsFalse(storages.Field("deleted"))))
q = q.Filter(sqlchemy.Equals(storages.Field("storage_type"), api.STORAGE_BAREMETAL))
q = q.Filter(sqlchemy.Equals(hoststorages.Field("host_id"), self.Id))
if q.Count() == 1 {
cnt, err := q.CountWithError()
if err != nil {
return nil
}
if cnt == 1 {
hs := SHoststorage{}
hs.SetModelManager(HoststorageManager)
err := q.First(&hs)
@@ -632,7 +653,7 @@ func (self *SHost) GetBaremetalstorage() *SHoststorage {
}
return &hs
}
log.Errorf("Cannof find baremetalstorage??")
log.Errorf("Cannot find baremetalstorage??")
return nil
}
@@ -778,13 +799,17 @@ func (self *SHost) SyncAttachedStorageStatus() {
}
}
func (self *SHostManager) IsNewNameUnique(name string, userCred mcclient.TokenCredential, kwargs *jsonutils.JSONDict) bool {
func (self *SHostManager) IsNewNameUnique(name string, userCred mcclient.TokenCredential, kwargs *jsonutils.JSONDict) (bool, error) {
q := self.Query().Equals("name", name)
if kwargs != nil && kwargs.Contains("zone_id") {
zoneId, _ := kwargs.GetString("zone_id")
q.Equals("zone_id", zoneId)
}
return q.Count() == 0
cnt, err := q.CountWithError()
if err != nil {
return false, err
}
return cnt == 0, nil
}
func (self *SHostManager) AllowGetPropertyBmStartRegisterScript(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
@@ -851,8 +876,15 @@ func (self *SHost) GetSpec(statusCheck bool) *jsonutils.JSONDict {
if self.MemSize == 0 || self.CpuCount == 0 {
return nil
}
if self.ResourceType == api.HostResourceTypePrepaidRecycle && self.GetGuestCount() > 0 {
return nil
if self.ResourceType == api.HostResourceTypePrepaidRecycle {
cnt, err := self.GetGuestCount()
if err != nil {
return nil
}
if cnt > 0 {
// occupied
return nil
}
}
if len(self.ManagerId) > 0 {
@@ -1053,8 +1085,8 @@ func (self *SHost) GetWiresQuery() *sqlchemy.SQuery {
return HostwireManager.Query().Equals("host_id", self.Id)
}
func (self *SHost) GetWireCount() int {
return self.GetWiresQuery().Count()
func (self *SHost) GetWireCount() (int, error) {
return self.GetWiresQuery().CountWithError()
}
func (self *SHost) GetHostwires() []SHostwire {
@@ -1157,30 +1189,30 @@ func (self *SHost) GetGuests() []SGuest {
return guests
}
func (self *SHost) GetGuestCount() int {
func (self *SHost) GetGuestCount() (int, error) {
q := self.GetGuestsQuery()
return q.Count()
return q.CountWithError()
}
func (self *SHost) GetContainerCount(status []string) int {
func (self *SHost) GetContainerCount(status []string) (int, error) {
q := self.GetGuestsQuery()
q = q.Filter(sqlchemy.Equals(q.Field("hypervisor"), api.HYPERVISOR_CONTAINER))
if len(status) > 0 {
q = q.In("status", status)
}
return q.Count()
return q.CountWithError()
}
func (self *SHost) GetNonsystemGuestCount() int {
func (self *SHost) GetNonsystemGuestCount() (int, error) {
q := self.GetGuestsQuery()
q = q.Filter(sqlchemy.OR(sqlchemy.IsNull(q.Field("is_system")), sqlchemy.IsFalse(q.Field("is_system"))))
return q.Count()
return q.CountWithError()
}
func (self *SHost) GetRunningGuestCount() int {
func (self *SHost) GetRunningGuestCount() (int, error) {
q := self.GetGuestsQuery()
q = q.In("status", api.VM_RUNNING_STATUS)
return q.Count()
return q.CountWithError()
}
func (self *SHost) GetBaremetalnetworksQuery() *sqlchemy.SQuery {
@@ -1441,7 +1473,11 @@ func (manager *SHostManager) newFromCloudHost(ctx context.Context, userCred mccl
izone = wire.GetZone()
}
host.Name = db.GenerateName(manager, manager.GetOwnerId(userCred), extHost.GetName())
newName, err := db.GenerateName(manager, manager.GetOwnerId(userCred), extHost.GetName())
if err != nil {
return nil, fmt.Errorf("generate name fail %s", err)
}
host.Name = newName
host.ExternalId = extHost.GetGlobalId()
host.ZoneId = izone.Id
@@ -1471,7 +1507,7 @@ func (manager *SHostManager) newFromCloudHost(ctx context.Context, userCred mccl
host.IsMaintenance = extHost.GetIsMaintenance()
host.Version = extHost.GetVersion()
err := manager.TableSpec().Insert(&host)
err = manager.TableSpec().Insert(&host)
if err != nil {
log.Errorf("newFromCloudHost fail %s", err)
return nil, err
@@ -1837,7 +1873,11 @@ func (self *SHost) GetNetinterfacesWithIdAndCredential(netId string, userCred mc
return nil, nil
}
net := netObj.(*SNetwork)
if net.getFreeAddressCount() == 0 && !reserved {
used, err := net.getFreeAddressCount()
if err != nil {
return nil, nil
}
if used == 0 && !reserved {
return nil, nil
}
matchNetIfs := make([]SNetInterface, 0)
@@ -1874,7 +1914,14 @@ func (self *SHost) GetNetworkWithIdAndCredential(netId string, userCred mcclient
if err != nil {
return nil, err
}
if reserved || net.getFreeAddressCount() > 0 {
if reserved {
return &net, nil
}
freeCnt, err := net.getFreeAddressCount()
if err != nil {
return nil, err
}
if freeCnt > 0 {
return &net, nil
}
return nil, fmt.Errorf("No IP address")
@@ -2195,11 +2242,14 @@ func (self *SHost) getMoreDetails(ctx context.Context, extra *jsonutils.JSONDict
extra.Add(jsonutils.NewInt(int64(usage.GuestVcpuCount)), "cpu_commit")
extra.Add(jsonutils.NewInt(int64(usage.GuestVmemSize)), "mem_commit")
}
containerCount := self.GetContainerCount(nil)
runningContainerCount := self.GetContainerCount(api.VM_RUNNING_STATUS)
extra.Add(jsonutils.NewInt(int64(self.GetGuestCount()-containerCount)), "guests")
extra.Add(jsonutils.NewInt(int64(self.GetNonsystemGuestCount()-containerCount)), "nonsystem_guests")
extra.Add(jsonutils.NewInt(int64(self.GetRunningGuestCount()-runningContainerCount)), "running_guests")
containerCount, _ := self.GetContainerCount(nil)
runningContainerCount, _ := self.GetContainerCount(api.VM_RUNNING_STATUS)
guestCount, _ := self.GetGuestCount()
nonesysGuestCnt, _ := self.GetNonsystemGuestCount()
runningGuestCnt, _ := self.GetRunningGuestCount()
extra.Add(jsonutils.NewInt(int64(guestCount-containerCount)), "guests")
extra.Add(jsonutils.NewInt(int64(nonesysGuestCnt-containerCount)), "nonsystem_guests")
extra.Add(jsonutils.NewInt(int64(runningGuestCnt-runningContainerCount)), "running_guests")
totalCpu := self.GetCpuCount()
cpuCommitRate := 0.0
if totalCpu > 0 && usage.GuestVcpuCount > 0 {
@@ -2366,32 +2416,74 @@ func (manager *SHostManager) ValidateSizeParams(data *jsonutils.JSONDict) (*json
return data, nil
}
func inputUniquenessCheck(data *jsonutils.JSONDict, zoneId string, hostId string) (*jsonutils.JSONDict, error) {
for _, key := range []string{
"manager_uri",
"access_ip",
} {
val, _ := data.GetString(key)
if len(val) > 0 {
q := HostManager.Query().Equals(key, val)
if len(zoneId) > 0 {
q = q.Equals("zone_id", zoneId)
} else {
q = q.IsNullOrEmpty("zone_id")
}
if len(hostId) > 0 {
q = q.NotEquals("id", hostId)
}
cnt, err := q.CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("check %s duplication fail %s", key, err)
}
if cnt > 0 {
return nil, httperrors.NewConflictError("duplicate %s %s", key, val)
}
}
}
accessMac, _ := data.GetString("access_mac")
if len(accessMac) > 0 {
accessMac2 := netutils.FormatMacAddr(accessMac)
if len(accessMac2) == 0 {
return nil, httperrors.NewInputParameterError("invalid macAddr %s", accessMac)
}
q := HostManager.Query().Equals("access_mac", accessMac2)
if len(hostId) > 0 {
q = q.NotEquals("host_id", hostId)
}
cnt, err := q.CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("check access_mac duplication fail %s", err)
}
if cnt > 0 {
return nil, httperrors.NewConflictError("duplicate access_mac %s", accessMac)
}
data.Set("access_mac", jsonutils.NewString(accessMac2))
}
return data, nil
}
func (manager *SHostManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
zoneId, _ := data.GetString("zone_id")
if len(zoneId) > 0 && ZoneManager.Query().Equals("id", zoneId).Count() == 0 {
return nil, httperrors.NewInputParameterError("Zone id %s not found", zoneId)
}
mangerUri, err := data.GetString("manager_uri")
if err == nil {
count := manager.Query().Equals("manager_uri", mangerUri).Count()
if count > 0 {
return nil, httperrors.NewConflictError("Conflict manager_uri %s", mangerUri)
zoneId := jsonutils.GetAnyString(data, []string{"zone_id", "zone"})
if len(zoneId) > 0 {
zoneObj, err := ZoneManager.FetchByIdOrName(userCred, zoneId)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2(ZoneManager.Keyword(), zoneId)
} else {
return nil, httperrors.NewGeneralError(err)
}
}
zoneId = zoneObj.GetId()
data.Set("zone_id", jsonutils.NewString(zoneObj.GetId()))
}
accessIp, err := data.GetString("access_ip")
if err == nil {
count := manager.Query().Equals("access_ip", accessIp).Count()
if count > 0 {
return nil, httperrors.NewDuplicateResourceError("Duplicate access_ip %s", accessIp)
}
}
accessMac, err := data.GetString("access_mac")
if err == nil {
count := HostManager.Query().Equals("access_mac", accessMac).Count()
if count > 0 {
return nil, httperrors.NewDuplicateResourceError("Duplicate access_mac %s", accessMac)
}
data, err := inputUniquenessCheck(data, zoneId, "")
if err != nil {
return nil, err
}
data, err = manager.ValidateSizeParams(data)
if err != nil {
return nil, httperrors.NewInputParameterError(err.Error())
@@ -2423,33 +2515,11 @@ func (manager *SHostManager) ValidateCreateData(ctx context.Context, userCred mc
}
func (self *SHost) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
mangerUri, err := data.GetString("manager_uri")
if err == nil {
count := HostManager.Query().Equals("manager_uri", mangerUri).
NotEquals("id", self.Id).Equals("zone_id", self.ZoneId).Count()
if count > 0 {
return nil, httperrors.NewConflictError("Conflict manager_uri %s", mangerUri)
}
}
accessIp, err := data.GetString("access_ip")
if err == nil {
count := HostManager.Query().Equals("access_ip", accessIp).
NotEquals("id", self.Id).Equals("zone_id", self.ZoneId).Count()
if count > 0 {
return nil, httperrors.NewDuplicateResourceError("Duplicate access_ip %s", accessIp)
}
}
accessMac, err := data.GetString("access_mac")
if err == nil {
accessMac = netutils.FormatMacAddr(accessMac)
if len(accessMac) == 0 {
return nil, httperrors.NewInputParameterError("invalid access_mac address")
}
q := HostManager.Query().Equals("access_mac", accessMac).NotEquals("id", self.Id)
if q.Count() > 0 {
return nil, httperrors.NewDuplicateResourceError("Duplicate access_mac %s", accessMac)
}
data, err := inputUniquenessCheck(data, self.ZoneId, self.Id)
if err != nil {
return nil, err
}
data, err = HostManager.ValidateSizeParams(data)
if err != nil {
return nil, httperrors.NewInputParameterError(err.Error())
@@ -3361,11 +3431,13 @@ func (self *SHost) AllowPerformConvertHypervisor(ctx context.Context,
return db.IsAdminAllowPerform(userCred, self, "convert-hypervisor")
}
func (self *SHost) isAlterNameUnique(name string) bool {
if self.GetModelManager().Query().Equals("name", name).NotEquals("id", self.Id).Equals("zone_id", self.ZoneId).Count() == 0 {
return true
func (self *SHost) isAlterNameUnique(name string) (bool, error) {
q := HostManager.Query().Equals("name", name).NotEquals("id", self.Id).Equals("zone_id", self.ZoneId)
cnt, err := q.CountWithError()
if err != nil {
return false, err
}
return false
return cnt == 0, nil
}
func (self *SHost) PerformConvertHypervisor(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
@@ -3392,8 +3464,12 @@ func (self *SHost) PerformConvertHypervisor(ctx context.Context, userCred mcclie
if err != nil {
return nil, err
}
if !self.isAlterNameUnique(name) {
return nil, httperrors.NewInputParameterError("Invalid name %s", name)
uniq, err := self.isAlterNameUnique(name)
if err != nil {
return nil, httperrors.NewInternalServerError("isAlterNameUnique fail %s", err)
}
if !uniq {
return nil, httperrors.NewDuplicateNameError(name, self.Id)
}
}
image, _ := data.GetString("image")
+12 -4
View File
@@ -200,7 +200,11 @@ func (self *SHoststorage) getExtraDetails(extra *jsonutils.JSONDict) *jsonutils.
extra.Add(jsonutils.NewString(storage.MediumType), "medium_type")
extra.Add(jsonutils.NewBool(storage.Enabled), "enabled")
extra.Add(jsonutils.NewFloat(float64(storage.GetOvercommitBound())), "cmtbound")
extra.Add(jsonutils.NewInt(int64(self.GetGuestDiskCount())), "guest_disk_count")
//extra.Add(jsonutils.NewInt(int64(self.GetGuestDiskCount())), "guest_disk_count")
extra = db.FetchModelExtraCountProperties(self, extra)
if len(storage.StoragecacheId) > 0 {
storagecache := StoragecacheManager.FetchStoragecacheById(storage.StoragecacheId)
if storagecache != nil {
@@ -211,7 +215,7 @@ func (self *SHoststorage) getExtraDetails(extra *jsonutils.JSONDict) *jsonutils.
return extra
}
func (self *SHoststorage) GetGuestDiskCount() int {
func (self *SHoststorage) GetGuestDiskCount() (int, error) {
guestdisks := GuestdiskManager.Query().SubQuery()
guests := GuestManager.Query().SubQuery()
disks := DiskManager.Query().SubQuery()
@@ -224,11 +228,15 @@ func (self *SHoststorage) GetGuestDiskCount() int {
sqlchemy.Equals(disks.Field("id"), guestdisks.Field("disk_id")),
sqlchemy.Equals(disks.Field("storage_id"), self.StorageId)))
return q.Count()
return q.CountWithError()
}
func (self *SHoststorage) ValidateDeleteCondition(ctx context.Context) error {
if self.GetGuestDiskCount() > 0 {
cnt, err := self.GetGuestDiskCount()
if err != nil {
return httperrors.NewInternalServerError("GetGuestDiskCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("guest on the host are using disks on this storage")
}
return self.SHostJointsBase.ValidateDeleteCondition(ctx)
+7 -3
View File
@@ -104,7 +104,7 @@ func (hw *SHostwire) getExtraDetails(extra *jsonutils.JSONDict) *jsonutils.JSOND
return extra
}
func (self *SHostwire) GetGuestnicsCount() int {
func (self *SHostwire) GetGuestnicsCount() (int, error) {
guestnics := GuestnetworkManager.Query().SubQuery()
guests := GuestManager.Query().SubQuery()
nets := NetworkManager.Query().SubQuery()
@@ -117,11 +117,15 @@ func (self *SHostwire) GetGuestnicsCount() int {
sqlchemy.Equals(nets.Field("id"), guestnics.Field("network_id")),
sqlchemy.Equals(nets.Field("wire_id"), self.WireId)))
return q.Count()
return q.CountWithError()
}
func (self *SHostwire) ValidateDeleteCondition(ctx context.Context) error {
if self.GetGuestnicsCount() > 0 {
cnt, err := self.GetGuestnicsCount()
if err != nil {
return httperrors.NewInternalServerError("GetGuestnicsCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("guest on the host are using networks on this wire")
}
return self.SHostJointsBase.ValidateDeleteCondition(ctx)
+14 -6
View File
@@ -417,15 +417,23 @@ type IsolatedDeviceCountStat struct {
Gpus int
}
func (manager *SIsolatedDeviceManager) totalCount(devType, hostTypes []string, resourceTypes []string, providers []string, rangeObj db.IStandaloneModel) int {
return manager.totalCountQ(devType, hostTypes, resourceTypes, providers, rangeObj).Count()
func (manager *SIsolatedDeviceManager) totalCount(devType, hostTypes []string, resourceTypes []string, providers []string, rangeObj db.IStandaloneModel) (int, error) {
return manager.totalCountQ(devType, hostTypes, resourceTypes, providers, rangeObj).CountWithError()
}
func (manager *SIsolatedDeviceManager) TotalCount(hostType []string, resourceTypes []string, providers []string, rangeObj db.IStandaloneModel) IsolatedDeviceCountStat {
return IsolatedDeviceCountStat{
Devices: manager.totalCount(nil, hostType, resourceTypes, providers, rangeObj),
Gpus: manager.totalCount(VALID_GPU_TYPES, hostType, resourceTypes, providers, rangeObj),
func (manager *SIsolatedDeviceManager) TotalCount(hostType []string, resourceTypes []string, providers []string, rangeObj db.IStandaloneModel) (IsolatedDeviceCountStat, error) {
stat := IsolatedDeviceCountStat{}
devCnt, err := manager.totalCount(nil, hostType, resourceTypes, providers, rangeObj)
if err != nil {
return stat, err
}
gpuCnt, err := manager.totalCount(VALID_GPU_TYPES, hostType, resourceTypes, providers, rangeObj)
if err != nil {
return stat, err
}
stat.Devices = devCnt
stat.Gpus = gpuCnt
return stat, nil
}
func (self *SIsolatedDevice) getDesc() *jsonutils.JSONDict {
+22 -7
View File
@@ -93,7 +93,12 @@ func (self *SKeypair) AllowGetDetails(ctx context.Context, userCred mcclient.Tok
func (self *SKeypair) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
extra := self.SStandaloneResourceBase.GetCustomizeColumns(ctx, userCred, query)
extra.Add(jsonutils.NewInt(int64(len(self.PrivateKey))), "private_key_len")
extra.Add(jsonutils.NewInt(int64(self.GetLinkedGuestsCount())), "linked_guest_count")
guestCnt, err := self.GetLinkedGuestsCount()
if err == nil {
extra.Add(jsonutils.NewInt(int64(guestCnt)), "linked_guest_count")
}
return extra
}
@@ -103,7 +108,13 @@ func (self *SKeypair) GetExtraDetails(ctx context.Context, userCred mcclient.Tok
return nil, err
}
extra.Add(jsonutils.NewInt(int64(len(self.PrivateKey))), "private_key_len")
extra.Add(jsonutils.NewInt(int64(self.GetLinkedGuestsCount())), "linked_guest_count")
guestCnt, err := self.GetLinkedGuestsCount()
if err != nil {
return nil, httperrors.NewInternalServerError("GetLinkedGuestsCount fail %s", err)
}
extra.Add(jsonutils.NewInt(int64(guestCnt)), "linked_guest_count")
if db.IsAdminAllowGet(userCred, self) {
extra.Add(jsonutils.NewString(self.OwnerId), "owner_id")
uc, _ := db.UserCacheManager.FetchUserById(self.OwnerId)
@@ -126,8 +137,8 @@ func (self *SKeypair) AllowDeleteItem(ctx context.Context, userCred mcclient.Tok
return self.IsOwner(userCred) || db.IsAdminAllowDelete(userCred, self)
}
func (self *SKeypair) GetLinkedGuestsCount() int {
return GuestManager.Query().Equals("keypair_id", self.Id).Count()
func (self *SKeypair) GetLinkedGuestsCount() (int, error) {
return GuestManager.Query().Equals("keypair_id", self.Id).CountWithError()
}
func (manager *SKeypairManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
@@ -176,15 +187,19 @@ func (manager *SKeypairManager) ValidateCreateData(ctx context.Context, userCred
}
func (self *SKeypair) ValidateDeleteCondition(ctx context.Context) error {
if self.GetLinkedGuestsCount() > 0 {
guestCnt, err := self.GetLinkedGuestsCount()
if err != nil {
return httperrors.NewInternalServerError("GetLinkedGuestsCount failed %s", err)
}
if guestCnt > 0 {
return httperrors.NewNotEmptyError("Cannot delete keypair used by servers")
}
return self.SStandaloneResourceBase.ValidateDeleteCondition(ctx)
}
func totalKeypairCount(userId string) int {
func totalKeypairCount(userId string) (int, error) {
q := KeypairManager.Query().Equals("owner_id", userId)
return q.Count()
return q.CountWithError()
}
func (manager *SKeypairManager) FilterByOwner(q *sqlchemy.SQuery, owner string) *sqlchemy.SQuery {
+14 -6
View File
@@ -310,13 +310,17 @@ func (lbacl *SLoadbalancerAcl) ValidateDeleteCondition(ctx context.Context) erro
t := man.TableSpec().Instance()
pdF := t.Field("pending_deleted")
lbaclId := lbacl.Id
n := t.Query().
n, err := t.Query().
Filter(sqlchemy.OR(sqlchemy.IsNull(pdF), sqlchemy.IsFalse(pdF))).
Equals("acl_id", lbaclId).
Count()
CountWithError()
if err != nil {
return httperrors.NewInternalServerError("get acl count fail %s", err)
}
if n > 0 {
return fmt.Errorf("acl %s is still referred to by %d %s",
lbaclId, n, man.KeywordPlural())
// return fmt.Errorf("acl %s is still referred to by %d %s",
// lbaclId, n, man.KeywordPlural())
return httperrors.NewResourceBusyError("acl %s is still referred to by %d %s", lbaclId, n, man.KeywordPlural())
}
return nil
}
@@ -430,8 +434,12 @@ func (man *SLoadbalancerAclManager) newFromCloudLoadbalancerAcl(ctx context.Cont
acl := SLoadbalancerAcl{}
acl.SetModelManager(man)
newName, err := db.GenerateName(man, projectId, extAcl.GetName())
if err != nil {
return nil, err
}
acl.ExternalId = extAcl.GetGlobalId()
acl.Name = db.GenerateName(man, projectId, extAcl.GetName())
acl.Name = newName
acl.ManagerId = provider.Id
acl.CloudregionId = region.Id
@@ -439,7 +447,7 @@ func (man *SLoadbalancerAclManager) newFromCloudLoadbalancerAcl(ctx context.Cont
for _, entry := range extAcl.GetAclEntries() {
*acl.AclEntries = append(*acl.AclEntries, &SLoadbalancerAclEntry{Cidr: entry.CIDR, Comment: entry.Comment})
}
err := man.TableSpec().Insert(&acl)
err = man.TableSpec().Insert(&acl)
if err != nil {
log.Errorf("newFromCloudLoadbalancerAcl fail %s", err)
return nil, err
@@ -201,23 +201,27 @@ func (lbbg *SLoadbalancerBackendGroup) GetBackends() ([]SLoadbalancerBackend, er
}
// 返回值 TotalRef
func (lbbg *SLoadbalancerBackendGroup) RefCount() int {
func (lbbg *SLoadbalancerBackendGroup) RefCount() (int, error) {
men := lbbg.getRefManagers()
var count int
for _, m := range men {
count += lbbg.refCount(m)
cnt, err := lbbg.refCount(m)
if err != nil {
return -1, err
}
count += cnt
}
return count
return count, nil
}
func (lbbg *SLoadbalancerBackendGroup) refCount(men db.IModelManager) int {
func (lbbg *SLoadbalancerBackendGroup) refCount(men db.IModelManager) (int, error) {
t := men.TableSpec().Instance()
pdF := t.Field("pending_deleted")
return t.Query().
Equals("backend_group_id", lbbg.Id).
Filter(sqlchemy.OR(sqlchemy.IsNull(pdF), sqlchemy.IsFalse(pdF))).
Count()
CountWithError()
}
func (lbbg *SLoadbalancerBackendGroup) getRefManagers() []db.IModelManager {
@@ -237,9 +241,12 @@ func (lbbg *SLoadbalancerBackendGroup) AllowPerformStatus(ctx context.Context, u
func (lbbg *SLoadbalancerBackendGroup) ValidateDeleteCondition(ctx context.Context) error {
men := lbbg.getRefManagers()
for _, m := range men {
n := lbbg.refCount(m)
n, err := lbbg.refCount(m)
if err != nil {
return httperrors.NewInternalServerError("get refCount fail %s", err.Error())
}
if n > 0 {
return fmt.Errorf("backend group %s is still referred to by %d %s",
return httperrors.NewResourceBusyError("backend group %s is still referred to by %d %s",
lbbg.Id, n, m.KeywordPlural())
}
}
@@ -476,12 +483,17 @@ func (man *SLoadbalancerBackendGroupManager) newFromCloudLoadbalancerBackendgrou
}*/
lbbg.Name = db.GenerateName(man, projectId, extLoadbalancerBackendgroup.GetName())
newName, err := db.GenerateName(man, projectId, extLoadbalancerBackendgroup.GetName())
if err != nil {
return nil, err
}
lbbg.Name = newName
lbbg.Type = extLoadbalancerBackendgroup.GetType()
lbbg.Status = extLoadbalancerBackendgroup.GetStatus()
err := man.TableSpec().Insert(lbbg)
err = man.TableSpec().Insert(lbbg)
if err != nil {
return nil, err
}
+6 -2
View File
@@ -421,13 +421,17 @@ func (man *SLoadbalancerBackendManager) newFromCloudLoadbalancerBackend(ctx cont
lbb.CloudregionId = loadbalancerBackendgroup.CloudregionId
lbb.ManagerId = loadbalancerBackendgroup.ManagerId
lbb.Name = db.GenerateName(man, projectId, extLoadbalancerBackend.GetName())
newName, err := db.GenerateName(man, projectId, extLoadbalancerBackend.GetName())
if err != nil {
return nil, err
}
lbb.Name = newName
if err := lbb.constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend); err != nil {
return nil, err
}
err := man.TableSpec().Insert(lbb)
err = man.TableSpec().Insert(lbb)
if err != nil {
return nil, err
+12 -5
View File
@@ -267,12 +267,15 @@ func (lbcert *SLoadbalancerCertificate) ValidateDeleteCondition(ctx context.Cont
for _, man := range men {
t := man.TableSpec().Instance()
pdF := t.Field("pending_deleted")
n := t.Query().
n, err := t.Query().
Equals("certificate_id", lbcertId).
Filter(sqlchemy.OR(sqlchemy.IsNull(pdF), sqlchemy.IsFalse(pdF))).
Count()
CountWithError()
if err != nil {
return httperrors.NewInternalServerError("get certificate refcount fail %s", err)
}
if n > 0 {
return fmt.Errorf("certificate %s is still referred to by %d %s",
return httperrors.NewResourceBusyError("certificate %s is still referred to by %d %s",
lbcertId, n, man.KeywordPlural())
}
}
@@ -396,7 +399,11 @@ func (man *SLoadbalancerCertificateManager) newFromCloudLoadbalancerCertificate(
lbcert := SLoadbalancerCertificate{}
lbcert.SetModelManager(man)
lbcert.Name = db.GenerateName(man, projectId, extCertificate.GetName())
newName, err := db.GenerateName(man, projectId, extCertificate.GetName())
if err != nil {
return nil, err
}
lbcert.Name = newName
lbcert.ExternalId = extCertificate.GetGlobalId()
lbcert.ManagerId = provider.Id
lbcert.CloudregionId = region.Id
@@ -406,7 +413,7 @@ func (man *SLoadbalancerCertificateManager) newFromCloudLoadbalancerCertificate(
lbcert.Fingerprint = extCertificate.GetFingerprint()
lbcert.NotAfter = extCertificate.GetExpireTime()
err := man.TableSpec().Insert(&lbcert)
err = man.TableSpec().Insert(&lbcert)
if err != nil {
log.Errorf("newFromCloudLoadbalancerCertificate fail %s", err)
return nil, err
@@ -16,7 +16,6 @@ package models
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -131,7 +130,7 @@ func (man *SLoadbalancerListenerRuleManager) ValidateCreateData(ctx context.Cont
data.Set("manager_id", jsonutils.NewString(listener.ManagerId))
listenerType := listener.ListenerType
if listenerType != api.LB_LISTENER_TYPE_HTTP && listenerType != api.LB_LISTENER_TYPE_HTTPS {
return nil, fmt.Errorf("listener type must be http/https, got %s", listenerType)
return nil, httperrors.NewInputParameterError("listener type must be http/https, got %s", listenerType)
}
{
if lbbg, ok := backendGroupV.Model.(*SLoadbalancerBackendGroup); ok && lbbg.LoadbalancerId != listener.LoadbalancerId {
@@ -140,9 +139,12 @@ func (man *SLoadbalancerListenerRuleManager) ValidateCreateData(ctx context.Cont
} else {
// 腾讯云backend group只能1v1关联
if listener.GetProviderName() == api.CLOUD_PROVIDER_QCLOUD {
count := lbbg.RefCount()
count, err := lbbg.RefCount()
if err != nil {
return nil, httperrors.NewInternalServerError("get lbbg RefCount fail %s", err)
}
if count > 0 {
return nil, fmt.Errorf("backendgroup already related with other listener/rule")
return nil, httperrors.NewResourceBusyError("backendgroup already related with other listener/rule")
}
}
}
@@ -388,10 +390,14 @@ func (man *SLoadbalancerListenerRuleManager) newFromCloudLoadbalancerListenerRul
lbr.ListenerId = listener.Id
lbr.ManagerId = listener.ManagerId
lbr.Name = db.GenerateName(man, projectId, extRule.GetName())
newName, err := db.GenerateName(man, projectId, extRule.GetName())
if err != nil {
return nil, err
}
lbr.Name = newName
lbr.constructFieldsFromCloudListenerRule(userCred, extRule)
err := man.TableSpec().Insert(lbr)
err = man.TableSpec().Insert(lbr)
if err != nil {
log.Errorf("newFromCloudLoadbalancerListenerRule fail %s", err)
+11 -4
View File
@@ -249,9 +249,12 @@ func (man *SLoadbalancerListenerManager) ValidateCreateData(ctx context.Context,
} else {
// 腾讯云backend group只能1v1关联
if lb.GetProviderName() == api.CLOUD_PROVIDER_QCLOUD {
count := lbbg.RefCount()
count, err := lbbg.RefCount()
if err != nil {
return nil, httperrors.NewInternalServerError("get lbbg RefCount fail %s", err)
}
if count > 0 {
return nil, fmt.Errorf("backendgroup aready related with other listener/rule")
return nil, httperrors.NewResourceBusyError("backendgroup aready related with other listener/rule")
}
}
}
@@ -860,11 +863,15 @@ func (man *SLoadbalancerListenerManager) newFromCloudLoadbalancerListener(ctx co
lblis.LoadbalancerId = lb.Id
lblis.ExternalId = extListener.GetGlobalId()
lblis.Name = db.GenerateName(man, projectId, extListener.GetName())
newName, err := db.GenerateName(man, projectId, extListener.GetName())
if err != nil {
return nil, err
}
lblis.Name = newName
lblis.constructFieldsFromCloudListener(userCred, lb, extListener)
err := man.TableSpec().Insert(lblis)
err = man.TableSpec().Insert(lblis)
if err != nil {
return nil, err
}
+16 -3
View File
@@ -157,11 +157,19 @@ func (man *SLoadbalancerManager) ValidateCreateData(ctx context.Context, userCre
return nil, httperrors.NewInputParameterError("address %s is not in the range of network %s(%s)",
ipS, network.Name, network.Id)
}
if network.isAddressUsed(ipS) {
used, err := network.isAddressUsed(ipS)
if err != nil {
return nil, httperrors.NewInternalServerError("isAddressUsed fail %s", err)
}
if used {
return nil, httperrors.NewInputParameterError("address %s is already occupied", ipS)
}
}
if network.getFreeAddressCount() <= 0 {
freeCnt, err := network.getFreeAddressCount()
if err != nil {
return nil, httperrors.NewInternalServerError("getFreeAddressCount fail %s", err)
}
if freeCnt <= 0 {
return nil, httperrors.NewNotAcceptableError("network %s(%s) has no free addresses",
network.Name, network.Id)
}
@@ -599,7 +607,12 @@ func (man *SLoadbalancerManager) newFromCloudLoadbalancer(ctx context.Context, u
lb.Address = extLb.GetAddress()
lb.AddressType = extLb.GetAddressType()
lb.NetworkType = extLb.GetNetworkType()
lb.Name = db.GenerateName(man, projectId, extLb.GetName())
newName, err := db.GenerateName(man, projectId, extLb.GetName())
if err != nil {
return nil, err
}
lb.Name = newName
lb.Status = extLb.GetStatus()
lb.LoadbalancerSpec = extLb.GetLoadbalancerSpec()
lb.ChargeType = extLb.GetChargeType()
+99 -56
View File
@@ -132,39 +132,64 @@ func (manager *SNetworkManager) AllowCreateItem(ctx context.Context, userCred mc
}
func (self *SNetwork) ValidateDeleteCondition(ctx context.Context) error {
if self.GetTotalNicCount() > 0 {
cnt, err := self.GetTotalNicCount()
if err != nil {
return httperrors.NewInternalServerError("GetTotalNicCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("not an empty network")
}
return self.SSharableVirtualResourceBase.ValidateDeleteCondition(ctx)
}
func (self *SNetwork) GetTotalNicCount() int {
total := self.GetGuestnicsCount() +
self.GetGroupNicsCount() +
self.GetBaremetalNicsCount() +
self.GetReservedNicsCount() +
self.GetLoadbalancerIpsCount()
return total
func (self *SNetwork) GetTotalNicCount() (int, error) {
total := 0
cnt, err := self.GetGuestnicsCount()
if err != nil {
return -1, err
}
total += cnt
cnt, err = self.GetGroupNicsCount()
if err != nil {
return -1, err
}
total += cnt
cnt, err = self.GetBaremetalNicsCount()
if err != nil {
return -1, err
}
total += cnt
cnt, err = self.GetReservedNicsCount()
if err != nil {
return -1, err
}
total += cnt
cnt, err = self.GetLoadbalancerIpsCount()
if err != nil {
return -1, err
}
total += cnt
return total, nil
}
func (self *SNetwork) GetGuestnicsCount() int {
return GuestnetworkManager.Query().Equals("network_id", self.Id).IsFalse("virtual").Count()
func (self *SNetwork) GetGuestnicsCount() (int, error) {
return GuestnetworkManager.Query().Equals("network_id", self.Id).IsFalse("virtual").CountWithError()
}
func (self *SNetwork) GetGroupNicsCount() int {
return GroupnetworkManager.Query().Equals("network_id", self.Id).Count()
func (self *SNetwork) GetGroupNicsCount() (int, error) {
return GroupnetworkManager.Query().Equals("network_id", self.Id).CountWithError()
}
func (self *SNetwork) GetBaremetalNicsCount() int {
return HostnetworkManager.Query().Equals("network_id", self.Id).Count()
func (self *SNetwork) GetBaremetalNicsCount() (int, error) {
return HostnetworkManager.Query().Equals("network_id", self.Id).CountWithError()
}
func (self *SNetwork) GetReservedNicsCount() int {
return ReservedipManager.Query().Equals("network_id", self.Id).Count()
func (self *SNetwork) GetReservedNicsCount() (int, error) {
return ReservedipManager.Query().Equals("network_id", self.Id).CountWithError()
}
func (self *SNetwork) GetLoadbalancerIpsCount() int {
return LoadbalancernetworkManager.Query().Equals("network_id", self.Id).Count()
func (self *SNetwork) GetLoadbalancerIpsCount() (int, error) {
return LoadbalancernetworkManager.Query().Equals("network_id", self.Id).CountWithError()
}
func (self *SNetwork) GetUsedAddresses() map[string]bool {
@@ -552,7 +577,11 @@ func (manager *SNetworkManager) newFromCloudNetwork(ctx context.Context, userCre
net := SNetwork{}
net.SetModelManager(manager)
net.Name = db.GenerateName(manager, projectId, extNet.GetName())
newName, err := db.GenerateName(manager, projectId, extNet.GetName())
if err != nil {
return nil, err
}
net.Name = newName
net.Status = extNet.GetStatus()
net.ExternalId = extNet.GetGlobalId()
net.WireId = wire.Id
@@ -565,7 +594,7 @@ func (manager *SNetworkManager) newFromCloudNetwork(ctx context.Context, userCre
net.AllocTimoutSeconds = extNet.GetAllocTimeoutSeconds()
err := manager.TableSpec().Insert(&net)
err = manager.TableSpec().Insert(&net)
if err != nil {
log.Errorf("newFromCloudZone fail %s", err)
return nil, err
@@ -583,7 +612,7 @@ func (self *SNetwork) isAddressInRange(address netutils.IPV4Addr) bool {
return self.getIPRange().Contains(address)
}
func (self *SNetwork) isAddressUsed(address string) bool {
func (self *SNetwork) isAddressUsed(address string) (bool, error) {
managers := []db.IModelManager{
GuestnetworkManager,
GroupnetworkManager,
@@ -593,11 +622,15 @@ func (self *SNetwork) isAddressUsed(address string) bool {
}
for _, manager := range managers {
q := manager.Query().Equals("ip_addr", address).Equals("network_id", self.Id)
if q.Count() > 0 {
return true
cnt, err := q.CountWithError()
if err != nil {
return false, err
}
if cnt > 0 {
return true, nil
}
}
return false
return false, nil
}
func (manager *SNetworkManager) GetOnPremiseNetworkOfIP(ipAddr string, serverType string, isPublic tristate.TriState) (*SNetwork, error) {
@@ -715,12 +748,16 @@ func parseNetworkInfo(userCred mcclient.TokenCredential, info *api.NetworkConfig
return info, nil
}
func (self *SNetwork) GetFreeAddressCount() int {
func (self *SNetwork) GetFreeAddressCount() (int, error) {
return self.getFreeAddressCount()
}
func (self *SNetwork) getFreeAddressCount() int {
return self.getIPRange().AddressCount() - self.GetTotalNicCount()
func (self *SNetwork) getFreeAddressCount() (int, error) {
used, err := self.GetTotalNicCount()
if err != nil {
return -1, err
}
return self.getIPRange().AddressCount() - used, nil
}
func isValidNetworkInfo(userCred mcclient.TokenCredential, netConfig *api.NetworkConfig) error {
@@ -751,14 +788,24 @@ func isValidNetworkInfo(userCred mcclient.TokenCredential, netConfig *api.Networ
if ReservedipManager.GetReservedIP(net, netConfig.Address) == nil {
return httperrors.NewInputParameterError("Address %s not reserved", netConfig.Address)
}
} else if net.isAddressUsed(netConfig.Address) {
return httperrors.NewInputParameterError("Address %s has been used", netConfig.Address)
} else {
used, err := net.isAddressUsed(netConfig.Address)
if err != nil {
return httperrors.NewInternalServerError("isAddressUsed fail %s", err)
}
if used {
return httperrors.NewInputParameterError("Address %s has been used", netConfig.Address)
}
}
}
if netConfig.BwLimit > api.MAX_BANDWIDTH {
return httperrors.NewInputParameterError("Bandwidth limit cannot exceed %dMbps", api.MAX_BANDWIDTH)
}
if net.getFreeAddressCount() < 1 {
freeCnt, err := net.getFreeAddressCount()
if err != nil {
return httperrors.NewInternalServerError("getFreeAddressCount fail %s", err)
}
if freeCnt < 1 {
return httperrors.NewInputParameterError("network %s(%s) has no free addresses", net.Name, net.Id)
}
}
@@ -820,30 +867,18 @@ func (self *SNetwork) getMoreDetails(ctx context.Context, extra *jsonutils.JSOND
extra.Add(jsonutils.JSONFalse, "exit")
}
extra.Add(jsonutils.NewInt(int64(self.GetPorts())), "ports")
extra.Add(jsonutils.NewInt(int64(self.GetTotalNicCount())), "ports_used")
extra.Add(jsonutils.NewInt(int64(self.GetGuestnicsCount())), "vnics")
extra.Add(jsonutils.NewInt(int64(self.GetBaremetalNicsCount())), "bm_vnics")
extra.Add(jsonutils.NewInt(int64(self.GetLoadbalancerIpsCount())), "lb_vnics")
extra.Add(jsonutils.NewInt(int64(self.GetGroupNicsCount())), "group_vnics")
extra.Add(jsonutils.NewInt(int64(self.GetReservedNicsCount())), "reserve_vnics")
/*zone := self.getZone()
if zone != nil {
extra.Add(jsonutils.NewString(zone.GetId()), "zone_id")
extra.Add(jsonutils.NewString(zone.GetName()), "zone")
if len(zone.GetExternalId()) > 0 {
extra.Add(jsonutils.NewString(zone.GetExternalId()), "zone_external_id")
}
}
region := self.getRegion()
if region != nil {
extra.Add(jsonutils.NewString(region.GetId()), "region_id")
extra.Add(jsonutils.NewString(region.GetName()), "region")
if len(region.GetExternalId()) > 0 {
extra.Add(jsonutils.NewString(region.GetExternalId()), "region_external_id")
}
}*/
portsUsed, _ := self.GetTotalNicCount()
extra.Add(jsonutils.NewInt(int64(portsUsed)), "ports_used")
vnics, _ := self.GetGuestnicsCount()
extra.Add(jsonutils.NewInt(int64(vnics)), "vnics")
bmVnics, _ := self.GetBaremetalNicsCount()
extra.Add(jsonutils.NewInt(int64(bmVnics)), "bm_vnics")
lbVnics, _ := self.GetLoadbalancerIpsCount()
extra.Add(jsonutils.NewInt(int64(lbVnics)), "lb_vnics")
groupVnics, _ := self.GetGroupNicsCount()
extra.Add(jsonutils.NewInt(int64(groupVnics)), "group_vnics")
reserveVnics, _ := self.GetReservedNicsCount()
extra.Add(jsonutils.NewInt(int64(reserveVnics)), "reserve_vnics")
vpc := self.getVpc()
if vpc != nil {
@@ -907,7 +942,11 @@ func (self *SNetwork) PerformReserveIp(ctx context.Context, userCred mcclient.To
if !self.isAddressInRange(ipAddr) {
return nil, httperrors.NewInputParameterError("Address %s not in network", ipstr)
}
if self.isAddressUsed(ipstr) {
used, err := self.isAddressUsed(ipstr)
if err != nil {
return nil, httperrors.NewInternalServerError("isAddressUsed fail %s", err)
}
if used {
return nil, httperrors.NewConflictError("Address %s has been used", ipstr)
}
err = ReservedipManager.ReserveIP(userCred, self, ipstr, notes)
@@ -1663,7 +1702,11 @@ func (self *SNetwork) PerformSplit(ctx context.Context, userCred mcclient.TokenC
return nil, httperrors.NewInputParameterError("Duplicate name %s", name)
}
} else {
name = db.GenerateName(NetworkManager, userCred.GetProjectId(), fmt.Sprintf("%s#", self.Name))
newName, err := db.GenerateName(NetworkManager, userCred.GetProjectId(), fmt.Sprintf("%s#", self.Name))
if err != nil {
return nil, httperrors.NewInternalServerError("GenerateName fail %s", err)
}
name = newName
}
network := &SNetwork{}
+2 -2
View File
@@ -90,7 +90,7 @@ func (self *SQuota) FetchUsage(ctx context.Context, projectId string) error {
net := totalGuestNicCount(projectId, nil, false)
guest := totalGuestResourceCount(projectId, nil, nil, nil, false, false, nil, nil, nil)
eipUsage := ElasticipManager.TotalCount(projectId, nil, nil)
snapshotCount := TotalSnapshotCount(projectId, nil, nil)
snapshotCount, _ := TotalSnapshotCount(projectId, nil, nil)
// XXX
// keypair belongs to user
// keypair := totalKeypairCount(projectId)
@@ -105,7 +105,7 @@ func (self *SQuota) FetchUsage(ctx context.Context, projectId string) error {
self.Ebw = net.ExternalBandwidth
self.Keypair = 0 // keypair
self.Group = 0
self.Secgroup = totalSecurityGroupCount(projectId)
self.Secgroup, _ = totalSecurityGroupCount(projectId)
self.IsolatedDevice = guest.TotalIsolatedCount
self.Snapshot = snapshotCount
return nil
+5 -1
View File
@@ -434,7 +434,11 @@ func (man *SRouteTableManager) newRouteTableFromCloud(userCred mcclient.TokenCre
Type: cloudRouteTable.GetType(),
Routes: (*SRoutes)(&routes),
}
routeTable.Name = db.GenerateName(man, userCred.GetProjectId(), cloudRouteTable.GetName())
newName, err := db.GenerateName(man, userCred.GetProjectId(), cloudRouteTable.GetName())
if err != nil {
return nil, err
}
routeTable.Name = newName
routeTable.ManagerId = vpc.ManagerId
routeTable.ExternalId = cloudRouteTable.GetGlobalId()
routeTable.Description = cloudRouteTable.GetDescription()
+27 -12
View File
@@ -227,13 +227,25 @@ func (self *SSchedtag) ValidateUpdateData(ctx context.Context, userCred mcclient
}
func (self *SSchedtag) ValidateDeleteCondition(ctx context.Context) error {
if self.GetObjectCount() > 0 {
cnt, err := self.GetObjectCount()
if err != nil {
return httperrors.NewInternalServerError("GetObjectCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("Tag is associated with %s", self.ResourceType)
}
if self.getDynamicSchedtagCount() > 0 {
cnt, err = self.getDynamicSchedtagCount()
if err != nil {
return httperrors.NewInternalServerError("getDynamicSchedtagCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("tag has dynamic rules")
}
if self.getSchedPoliciesCount() > 0 {
cnt, err = self.getSchedPoliciesCount()
if err != nil {
return httperrors.NewInternalServerError("getSchedPoliciesCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("tag is associate with sched policies")
}
return self.SStandaloneResourceBase.ValidateDeleteCondition(ctx)
@@ -275,22 +287,25 @@ func (self *SSchedtag) GetJointManager() ISchedtagJointManager {
return SchedtagManager.jointsManager[self.ResourceType]
}
func (self *SSchedtag) GetObjectCount() int {
return self.GetJointManager().Query().Equals("schedtag_id", self.Id).Count()
func (self *SSchedtag) GetObjectCount() (int, error) {
return self.GetJointManager().Query().Equals("schedtag_id", self.Id).CountWithError()
}
func (self *SSchedtag) getSchedPoliciesCount() int {
return SchedpolicyManager.Query().Equals("schedtag_id", self.Id).Count()
func (self *SSchedtag) getSchedPoliciesCount() (int, error) {
return SchedpolicyManager.Query().Equals("schedtag_id", self.Id).CountWithError()
}
func (self *SSchedtag) getDynamicSchedtagCount() int {
return DynamicschedtagManager.Query().Equals("schedtag_id", self.Id).Count()
func (self *SSchedtag) getDynamicSchedtagCount() (int, error) {
return DynamicschedtagManager.Query().Equals("schedtag_id", self.Id).CountWithError()
}
func (self *SSchedtag) getMoreColumns(extra *jsonutils.JSONDict) *jsonutils.JSONDict {
extra.Add(jsonutils.NewInt(int64(self.GetObjectCount())), fmt.Sprintf("%s_count", self.GetJointManager().GetMasterManager().Keyword()))
extra.Add(jsonutils.NewInt(int64(self.getDynamicSchedtagCount())), "dynamic_schedtag_count")
extra.Add(jsonutils.NewInt(int64(self.getSchedPoliciesCount())), "schedpolicy_count")
cnt, _ := self.GetObjectCount()
extra.Add(jsonutils.NewInt(int64(cnt)), fmt.Sprintf("%s_count", self.GetJointManager().GetMasterManager().Keyword()))
cnt, _ = self.getDynamicSchedtagCount()
extra.Add(jsonutils.NewInt(int64(cnt)), "dynamic_schedtag_count")
cnt, _ = self.getSchedPoliciesCount()
extra.Add(jsonutils.NewInt(int64(cnt)), "schedpolicy_count")
return extra
}
+22 -15
View File
@@ -127,30 +127,37 @@ func (self *SSecurityGroupCache) Delete(ctx context.Context, userCred mcclient.T
return db.DeleteModel(ctx, userCred, self)
}
func (manager *SSecurityGroupCacheManager) GetSecgroupCache(ctx context.Context, userCred mcclient.TokenCredential, secgroupId, vpcId string, regionId string, providerId string) *SSecurityGroupCache {
func (manager *SSecurityGroupCacheManager) GetSecgroupCache(ctx context.Context, userCred mcclient.TokenCredential, secgroupId, vpcId string, regionId string, providerId string) (*SSecurityGroupCache, error) {
secgroupCache := SSecurityGroupCache{}
query := manager.Query()
cond := sqlchemy.AND(sqlchemy.Equals(query.Field("secgroup_id"), secgroupId), sqlchemy.Equals(query.Field("vpc_id"), vpcId), sqlchemy.Equals(query.Field("cloudregion_id"), regionId), sqlchemy.Equals(query.Field("manager_id"), providerId))
query = query.Filter(cond)
count := query.Count()
count, err := query.CountWithError()
if err != nil {
return nil, err
}
if count > 1 {
log.Errorf("duplicate secgroupcache for secgroup: %s vpcId: %s regionId: %s", secgroupId, vpcId, regionId)
} else if count == 0 {
return nil
return nil, fmt.Errorf("duplicate secgroupcache for secgroup: %s vpcId: %s regionId: %s", secgroupId, vpcId, regionId)
}
if count == 0 {
return nil, nil
}
query.First(&secgroupCache)
secgroupCache.SetModelManager(manager)
return &secgroupCache
return &secgroupCache, nil
}
func (manager *SSecurityGroupCacheManager) Register(ctx context.Context, userCred mcclient.TokenCredential, secgroupId, vpcId, regionId string, providerId string) *SSecurityGroupCache {
func (manager *SSecurityGroupCacheManager) Register(ctx context.Context, userCred mcclient.TokenCredential, secgroupId, vpcId, regionId string, providerId string) (*SSecurityGroupCache, error) {
lockman.LockClass(ctx, manager, userCred.GetProjectId())
defer lockman.ReleaseClass(ctx, manager, userCred.GetProjectId())
secgroupCache := manager.GetSecgroupCache(ctx, userCred, secgroupId, vpcId, regionId, providerId)
secgroupCache, err := manager.GetSecgroupCache(ctx, userCred, secgroupId, vpcId, regionId, providerId)
if err != nil {
return nil, err
}
if secgroupCache != nil {
return secgroupCache
return secgroupCache, nil
}
secgroupCache = &SSecurityGroupCache{
@@ -162,9 +169,9 @@ func (manager *SSecurityGroupCacheManager) Register(ctx context.Context, userCre
secgroupCache.SetModelManager(manager)
if err := manager.TableSpec().Insert(secgroupCache); err != nil {
log.Errorf("insert secgroupcache error: %v", err)
return nil
return nil, err
}
return secgroupCache
return secgroupCache, nil
}
func (manager *SSecurityGroupCacheManager) getSecgroupcachesByProvider(provider *SCloudprovider) ([]SSecurityGroupCache, error) {
@@ -217,12 +224,12 @@ func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(ctx context.C
syncResult.AddError(err)
continue
}
cache := manager.Register(ctx, userCred, secgroup.Id, added[i].GetVpcId(), vpc.CloudregionId, provider.Id)
if cache == nil {
syncResult.AddError(fmt.Errorf("failed to registor secgroup cache for secgroup %s(%s) provider: %s", secgroup.Name, secgroup.Name, provider.Name))
cache, err := manager.Register(ctx, userCred, secgroup.Id, added[i].GetVpcId(), vpc.CloudregionId, provider.Id)
if err != nil {
syncResult.AddError(fmt.Errorf("failed to registor secgroup cache for secgroup %s(%s) provider: %s: %s", secgroup.Name, secgroup.Name, provider.Name, err))
continue
}
if err := cache.SetExternalId(userCred, added[i].GetGlobalId()); err != nil {
if err = cache.SetExternalId(userCred, added[i].GetGlobalId()); err != nil {
syncResult.AddError(err)
continue
}
+37 -18
View File
@@ -35,6 +35,7 @@ import (
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type SSecurityGroupManager struct {
@@ -102,8 +103,8 @@ func (self *SSecurityGroup) GetGuestsQuery() *sqlchemy.SQuery {
).Filter(sqlchemy.NotIn(guests.Field("hypervisor"), []string{api.HYPERVISOR_CONTAINER, api.HYPERVISOR_BAREMETAL, api.HYPERVISOR_ESXI}))
}
func (self *SSecurityGroup) GetGuestsCount() int {
return self.GetGuestsQuery().Count()
func (self *SSecurityGroup) GetGuestsCount() (int, error) {
return self.GetGuestsQuery().CountWithError()
}
func (self *SSecurityGroup) GetGuests() []SGuest {
@@ -121,8 +122,8 @@ func (self *SSecurityGroup) GetSecgroupCacheQuery() *sqlchemy.SQuery {
return SecurityGroupCacheManager.Query().Equals("secgroup_id", self.Id)
}
func (self *SSecurityGroup) GetSecgroupCacheCount() int {
return self.GetSecgroupCacheQuery().Count()
func (self *SSecurityGroup) GetSecgroupCacheCount() (int, error) {
return self.GetSecgroupCacheQuery().CountWithError()
}
func (self *SSecurityGroup) getDesc() jsonutils.JSONObject {
@@ -139,7 +140,8 @@ func (self *SSecurityGroup) GetExtraDetails(ctx context.Context, userCred mcclie
return nil, err
}
extra.Add(jsonutils.NewInt(int64(len(self.GetGuests()))), "guest_cnt")
extra.Add(jsonutils.NewInt(int64(self.GetSecgroupCacheCount())), "cache_cnt")
cnt, _ := self.GetSecgroupCacheCount()
extra.Add(jsonutils.NewInt(int64(cnt)), "cache_cnt")
extra.Add(jsonutils.NewString(self.getSecurityRuleString("")), "rules")
extra.Add(jsonutils.NewString(self.getSecurityRuleString("in")), "in_rules")
extra.Add(jsonutils.NewString(self.getSecurityRuleString("out")), "out_rules")
@@ -148,8 +150,10 @@ func (self *SSecurityGroup) GetExtraDetails(ctx context.Context, userCred mcclie
func (self *SSecurityGroup) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
extra := self.SSharableVirtualResourceBase.GetCustomizeColumns(ctx, userCred, query)
extra.Add(jsonutils.NewInt(int64(len(self.GetGuests()))), "guest_cnt")
extra.Add(jsonutils.NewInt(int64(self.GetSecgroupCacheCount())), "cache_cnt")
cnt, _ := self.GetSecgroupCacheCount()
extra.Add(jsonutils.NewInt(int64(cnt)), "cache_cnt")
extra.Add(jsonutils.NewTimeString(self.CreatedAt), "created_at")
extra.Add(jsonutils.NewString(self.Description), "description")
extra.Add(jsonutils.NewString(self.getSecurityRuleString("in")), "in_rules")
@@ -214,9 +218,9 @@ func (self *SSecurityGroup) getSecurityRuleString(direction string) string {
return strings.Join(rules, SECURITY_GROUP_SEPARATOR)
}
func totalSecurityGroupCount(projectId string) int {
func totalSecurityGroupCount(projectId string) (int, error) {
q := SecurityGroupManager.Query().Equals("tenant_id", projectId)
return q.Count()
return q.CountWithError()
}
func (self *SSecurityGroup) AllowPerformAddRule(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
@@ -263,26 +267,32 @@ func (self *SSecurityGroup) AllowPerformClone(ctx context.Context, userCred mccl
}
func (self *SSecurityGroup) PerformClone(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if name, _ := data.GetString("name"); len(name) == 0 {
name, _ := data.GetString("name")
if len(name) == 0 {
return nil, httperrors.NewMissingParameterError("name")
} else {
sql := SecurityGroupManager.Query()
sql = SecurityGroupManager.FilterByName(sql, name)
if sql.Count() != 0 {
return nil, httperrors.NewDuplicateNameError("name", name)
}
_, err := SecurityGroupManager.FetchByName(userCred, name)
if err != nil {
if err != sql.ErrNoRows {
return nil, httperrors.NewInternalServerError("FetchByName fail %s", err)
}
} else {
return nil, httperrors.NewDuplicateNameError("name", name)
}
secgroup := &SSecurityGroup{}
secgroup.SetModelManager(SecurityGroupManager)
secgroup.Name, _ = data.GetString("name")
secgroup.Name = name
secgroup.Description, _ = data.GetString("description")
secgroup.ProjectId = userCred.GetTenantId()
if err := SecurityGroupManager.TableSpec().Insert(secgroup); err != nil {
err = SecurityGroupManager.TableSpec().Insert(secgroup)
if err != nil {
return nil, err
//db.OpsLog.LogCloneEvent(self, secgroup, userCred, nil)
}
secgrouprules := self.getSecurityRules("")
for _, rule := range secgrouprules {
secgrouprule := &SSecurityGroupRule{}
@@ -300,6 +310,8 @@ func (self *SSecurityGroup) PerformClone(ctx context.Context, userCred mcclient.
return nil, err
}
}
logclient.AddActionLogWithContext(ctx, secgroup, logclient.ACT_CREATE, secgroup.GetShortDesc(ctx), userCred, true)
return nil, nil
}
@@ -447,7 +459,11 @@ func (manager *SSecurityGroupManager) newFromCloudSecgroup(ctx context.Context,
secgroup := SSecurityGroup{}
secgroup.SetModelManager(manager)
secgroup.Name = db.GenerateName(manager, "", extSec.GetName())
newName, err := db.GenerateName(manager, "", extSec.GetName())
if err != nil {
return nil, err
}
secgroup.Name = newName
secgroup.Description = extSec.GetDescription()
secgroup.ProjectId = userCred.GetProjectId()
@@ -555,7 +571,10 @@ func (manager *SSecurityGroupManager) InitializeData() error {
}
func (self *SSecurityGroup) ValidateDeleteCondition(ctx context.Context) error {
cnt := self.GetGuestsCount()
cnt, err := self.GetGuestsCount()
if err != nil {
return httperrors.NewInternalServerError("GetGuestsCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("the security group is in use")
}
+29 -15
View File
@@ -193,7 +193,7 @@ func genInstanceType(family string, cpu, mem_mb int64) (string, error) {
return fmt.Sprintf("ecs.%s.c%dm%d", family, cpu, mem_mb/1024), nil
}
func skuRelatedGuestCount(self *SServerSku) int {
func skuRelatedGuestCount(self *SServerSku) (int, error) {
var q *sqlchemy.SQuery
if len(self.ZoneId) > 0 {
hostTable := HostManager.Query().SubQuery()
@@ -205,7 +205,7 @@ func skuRelatedGuestCount(self *SServerSku) int {
}
q = q.Equals("instance_type", self.GetName())
return q.Count()
return q.CountWithError()
}
func getNameAndExtId(resId string, manager db.IModelManager) (string, string, error) {
@@ -263,12 +263,13 @@ func (self *SServerSku) GetCustomizeColumns(ctx context.Context, userCred mcclie
countKey := self.GetId() + ".total_guest_count"
v := Cache.Get(countKey)
if v == nil {
count = skuRelatedGuestCount(self)
Cache.Set(countKey, count)
} else {
count = v.(int)
}
count, _ = skuRelatedGuestCount(self)
extra.Add(jsonutils.NewInt(int64(count)), "total_guest_count")
// zone
@@ -299,7 +300,7 @@ func (self *SServerSku) GetExtraDetails(ctx context.Context, userCred mcclient.T
if err != nil {
return nil, err
}
count := skuRelatedGuestCount(self)
count, _ := skuRelatedGuestCount(self)
extra.Add(jsonutils.NewInt(int64(count)), "total_guest_count")
return extra, nil
}
@@ -385,7 +386,11 @@ func (self *SServerSkuManager) ValidateCreateData(ctx context.Context,
sqlchemy.IsEmpty(q.Field("provider")),
))
if q.Count() > 0 {
cnt, err := q.CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("check duplication fail %s", err)
}
if cnt > 0 {
return nil, httperrors.NewDuplicateResourceError("Duplicate sku %s", name)
}
@@ -403,7 +408,12 @@ func (self *SServerSkuManager) FetchByZoneExtId(zoneExtId string, name string) (
func (self *SServerSkuManager) FetchByZoneId(zoneId string, name string) (db.IModel, error) {
q := self.Query().Equals("zone_id", zoneId).Equals("name", name)
count := q.Count()
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count == 1 {
obj, err := db.NewModelObject(self)
if err != nil {
@@ -721,18 +731,21 @@ func (self *SServerSku) AllowDeleteItem(ctx context.Context, userCred mcclient.T
}
func (self *SServerSku) ValidateDeleteCondition(ctx context.Context) error {
serverCount := GuestManager.Query().Equals("instance_type", self.Id).Count()
serverCount, err := skuRelatedGuestCount(self)
if err != nil {
return httperrors.NewInternalServerError("check instance")
}
if serverCount > 0 {
return httperrors.NewForbiddenError("now allow to delete inuse instance_type.please remove related servers first: %s", self.Name)
return httperrors.NewNotEmptyError("now allow to delete inuse instance_type.please remove related servers first: %s", self.Name)
}
if !inWhiteList(self.Provider) {
return httperrors.NewForbiddenError("not allow to delete public cloud instance_type: %s", self.Name)
}
count := GuestManager.Query().Equals("instance_type", self.Name).Count()
/*count := GuestManager.Query().Equals("instance_type", self.Id).Count()
if count > 0 {
return httperrors.NewNotEmptyError("instance_type used by servers")
}
}*/
return nil
}
@@ -877,7 +890,7 @@ func (manager *SServerSkuManager) FetchSkuByNameAndHypervisor(name string, hyper
return &skus[0], nil
}
func (manager *SServerSkuManager) GetSkuCountByProvider(provider string) int {
func (manager *SServerSkuManager) GetSkuCountByProvider(provider string) (int, error) {
q := manager.Query()
if len(provider) == 0 {
q = q.IsNotEmpty("provider")
@@ -885,10 +898,10 @@ func (manager *SServerSkuManager) GetSkuCountByProvider(provider string) int {
q = q.Equals("provider", provider)
}
return q.Count()
return q.CountWithError()
}
func (manager *SServerSkuManager) GetSkuCountByRegion(regionId string) int {
func (manager *SServerSkuManager) GetSkuCountByRegion(regionId string) (int, error) {
q := manager.Query()
if len(regionId) == 0 {
q = q.IsNotEmpty("cloudregion_id")
@@ -896,7 +909,7 @@ func (manager *SServerSkuManager) GetSkuCountByRegion(regionId string) int {
q = q.Equals("cloudregion_id", regionId)
}
return q.Count()
return q.CountWithError()
}
func (manager *SServerSkuManager) GetSkuCountByZone(zoneId string) []SServerSku {
@@ -1063,7 +1076,8 @@ func (manager *SServerSkuManager) newFromCloudSku(ctx context.Context, userCred
Provider: provider.Provider,
}
sku.constructSku(extSku)
sku.Name = db.GenerateName(manager, manager.GetOwnerId(userCred), extSku.GetName())
sku.Name = extSku.GetName()
sku.ExternalId = extSku.GetGlobalId()
sku.SetModelManager(manager)
err := manager.TableSpec().Insert(sku)
+7 -1
View File
@@ -341,7 +341,13 @@ func (self *SkusZoneList) SyncToLocalDB() error {
// 全量同步sku列表.
func SyncSkus(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
if isStart {
if ServerSkuManager.GetSkuCountByProvider("") > 0 {
cnt, err := ServerSkuManager.GetSkuCountByProvider("")
if err != nil {
log.Errorf("GetSkuCountByProvider fail %s", err)
return
}
if cnt > 0 {
log.Debugf("GetSkuCountByProvider synced skus, skip...")
return
}
}
+15 -7
View File
@@ -77,7 +77,11 @@ func ValidateSnapshotName(hypervisor, name, owner string) error {
q := SnapshotManager.Query()
q = SnapshotManager.FilterByName(q, name)
q = SnapshotManager.FilterByOwner(q, owner)
if q.Count() != 0 {
cnt, err := q.CountWithError()
if err != nil {
return err
}
if cnt != 0 {
return fmt.Errorf("Name conflict?")
}
if !('A' <= name[0] && name[0] <= 'Z' || 'a' <= name[0] && name[0] <= 'z') {
@@ -339,10 +343,10 @@ func (self *SSnapshotManager) GetDiskFirstSnapshot(diskId string) *SSnapshot {
return dest
}
func (self *SSnapshotManager) GetDiskSnapshotCount(diskId string) int {
func (self *SSnapshotManager) GetDiskSnapshotCount(diskId string) (int, error) {
q := self.Query().SubQuery()
return q.Query().Filter(sqlchemy.AND(sqlchemy.Equals(q.Field("disk_id"), diskId),
sqlchemy.Equals(q.Field("fake_deleted"), false))).Count()
sqlchemy.Equals(q.Field("fake_deleted"), false))).CountWithError()
}
func (self *SSnapshotManager) CreateSnapshot(ctx context.Context, userCred mcclient.TokenCredential, createdBy, diskId, guestId, location, name string) (*SSnapshot, error) {
@@ -509,7 +513,7 @@ func (self *SSnapshot) Delete(ctx context.Context, userCred mcclient.TokenCreden
return nil
}
func TotalSnapshotCount(projectId string, rangeObj db.IStandaloneModel, providers []string) int {
func TotalSnapshotCount(projectId string, rangeObj db.IStandaloneModel, providers []string) (int, error) {
q := SnapshotManager.Query()
if len(projectId) > 0 {
q = q.Equals("tenant_id", projectId)
@@ -533,7 +537,7 @@ func TotalSnapshotCount(projectId string, rangeObj db.IStandaloneModel, provider
q = q.In("manager_id", subq.SubQuery())
}
q = q.Equals("fake_deleted", false)
return q.Count()
return q.CountWithError()
}
func (self *SSnapshot) syncRemoveCloudSnapshot(ctx context.Context, userCred mcclient.TokenCredential) error {
@@ -574,7 +578,11 @@ func (manager *SSnapshotManager) newFromCloudSnapshot(ctx context.Context, userC
snapshot := SSnapshot{}
snapshot.SetModelManager(manager)
snapshot.Name = db.GenerateName(manager, projectId, extSnapshot.GetName())
newName, err := db.GenerateName(manager, projectId, extSnapshot.GetName())
if err != nil {
return nil, err
}
snapshot.Name = newName
snapshot.Status = extSnapshot.GetStatus()
snapshot.ExternalId = extSnapshot.GetGlobalId()
if len(extSnapshot.GetDiskId()) > 0 {
@@ -591,7 +599,7 @@ func (manager *SSnapshotManager) newFromCloudSnapshot(ctx context.Context, userC
snapshot.ManagerId = provider.Id
snapshot.CloudregionId = region.Id
err := manager.TableSpec().Insert(&snapshot)
err = manager.TableSpec().Insert(&snapshot)
if err != nil {
log.Errorf("newFromCloudEip fail %s", err)
return nil, err
+41 -12
View File
@@ -185,16 +185,22 @@ func (self *SStoragecachedimage) getExtraDetails(extra *jsonutils.JSONDict) *jso
extra.Add(jsonutils.NewString(cachedImage.GetName()), "image")
extra.Add(jsonutils.NewInt(cachedImage.Size), "size")
}
extra.Add(jsonutils.NewInt(int64(self.getReferenceCount())), "reference")
cnt, _ := self.getReferenceCount()
extra.Add(jsonutils.NewInt(int64(cnt)), "reference")
return extra
}
func (self *SStoragecachedimage) getCdromReferenceCount() int {
// TODO
return 0
func (self *SStoragecachedimage) getCdromReferenceCount() (int, error) {
cdroms := GuestcdromManager.Query().SubQuery()
guests := GuestManager.Query().SubQuery()
q := cdroms.Query()
q = q.Join(guests, sqlchemy.Equals(cdroms.Field("id"), guests.Field("id")))
q = q.Filter(sqlchemy.Equals(cdroms.Field("image_id"), self.CachedimageId))
return q.CountWithError()
}
func (self *SStoragecachedimage) getDiskReferenceCount() int {
func (self *SStoragecachedimage) getDiskReferenceCount() (int, error) {
guestdisks := GuestdiskManager.Query().SubQuery()
disks := DiskManager.Query().SubQuery()
storages := StorageManager.Query().SubQuery()
@@ -208,11 +214,22 @@ func (self *SStoragecachedimage) getDiskReferenceCount() int {
q = q.Filter(sqlchemy.Equals(disks.Field("template_id"), self.CachedimageId))
q = q.Filter(sqlchemy.NOT(sqlchemy.In(disks.Field("status"), []string{api.DISK_ALLOC_FAILED, api.DISK_INIT})))
return q.Count()
return q.CountWithError()
}
func (self *SStoragecachedimage) getReferenceCount() int {
return self.getCdromReferenceCount() + self.getDiskReferenceCount()
func (self *SStoragecachedimage) getReferenceCount() (int, error) {
totalCnt := 0
cnt, err := self.getCdromReferenceCount()
if err != nil {
return -1, err
}
totalCnt += cnt
cnt, err = self.getDiskReferenceCount()
if err != nil {
return -1, err
}
totalCnt += cnt
return totalCnt, nil
}
func (manager *SStoragecachedimageManager) GetStoragecachedimage(cacheId string, imageId string) *SStoragecachedimage {
@@ -235,7 +252,11 @@ func (self *SStoragecachedimage) Detach(ctx context.Context, userCred mcclient.T
}
func (self *SStoragecachedimage) ValidateDeleteCondition(ctx context.Context) error {
if self.getReferenceCount() > 0 {
cnt, err := self.getReferenceCount()
if err != nil {
return httperrors.NewInternalServerError("getReferenceCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("Image is in use")
}
return self.SJointResourceBase.ValidateDeleteCondition(ctx)
@@ -372,10 +393,18 @@ func (self *SStoragecachedimage) syncRemoveCloudImage(ctx context.Context, userC
if err != nil {
return err
}
if image != nil && image.getStoragecacheCount() == 0 {
err = image.Delete(ctx, userCred)
if image != nil {
cnt, err := image.getStoragecacheCount()
if err != nil {
log.Errorf("image delete error %s", err)
log.Errorf("getStoragecacheCount fail %s", err)
return err
}
if cnt == 0 {
err = image.Delete(ctx, userCred)
if err != nil {
log.Errorf("image delete error %s", err)
return err
}
}
}
return nil
+6 -2
View File
@@ -180,7 +180,11 @@ func (manager *SStoragecacheManager) newFromCloudStoragecache(ctx context.Contex
local := SStoragecache{}
local.SetModelManager(manager)
local.Name = db.GenerateName(manager, manager.GetOwnerId(userCred), cloudCache.GetName())
newName, err := db.GenerateName(manager, manager.GetOwnerId(userCred), cloudCache.GetName())
if err != nil {
return nil, err
}
local.Name = newName
local.ExternalId = cloudCache.GetGlobalId()
local.IsEmulated = cloudCache.IsEmulated()
@@ -188,7 +192,7 @@ func (manager *SStoragecacheManager) newFromCloudStoragecache(ctx context.Contex
local.Path = cloudCache.GetPath()
err := manager.TableSpec().Insert(&local)
err = manager.TableSpec().Insert(&local)
if err != nil {
return nil, err
}
+32 -13
View File
@@ -224,8 +224,26 @@ func (manager *SStorageManager) ValidateCreateData(ctx context.Context, userCred
}
func (self *SStorage) ValidateDeleteCondition(ctx context.Context) error {
if self.GetHostCount() > 0 || self.GetDiskCount() > 0 || self.GetSnapshotCount() > 0 {
return httperrors.NewNotEmptyError("Not an empty storage provider")
cnt, err := self.GetHostCount()
if err != nil {
return httperrors.NewInternalServerError("GetHostCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("storage has associate hosts")
}
cnt, err = self.GetDiskCount()
if err != nil {
return httperrors.NewInternalServerError("GetDiskCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("storage has disks")
}
cnt, err = self.GetSnapshotCount()
if err != nil {
return httperrors.NewInternalServerError("GetSnapshotCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("storage has snapshots")
}
return self.SStandaloneResourceBase.ValidateDeleteCondition(ctx)
}
@@ -332,12 +350,12 @@ func (self *SStorage) PerformOffline(ctx context.Context, userCred mcclient.Toke
return nil, nil
}
func (self *SStorage) GetHostCount() int {
return HoststorageManager.Query().Equals("storage_id", self.Id).Count()
func (self *SStorage) GetHostCount() (int, error) {
return HoststorageManager.Query().Equals("storage_id", self.Id).CountWithError()
}
func (self *SStorage) GetDiskCount() int {
return DiskManager.Query().Equals("storage_id", self.Id).Count()
func (self *SStorage) GetDiskCount() (int, error) {
return DiskManager.Query().Equals("storage_id", self.Id).CountWithError()
}
func (self *SStorage) GetDisks() []SDisk {
@@ -351,8 +369,8 @@ func (self *SStorage) GetDisks() []SDisk {
return disks
}
func (self *SStorage) GetSnapshotCount() int {
return SnapshotManager.Query().Equals("storage_id", self.Id).Count()
func (self *SStorage) GetSnapshotCount() (int, error) {
return SnapshotManager.Query().Equals("storage_id", self.Id).CountWithError()
}
func (self *SStorage) IsLocal() bool {
@@ -413,9 +431,6 @@ func (self *SStorage) GetUsedCapacity(isReady tristate.TriState) int {
case tristate.False:
q = q.NotEquals("status", api.DISK_READY)
}
if q.Count() == 0 {
return 0
}
row := q.Row()
var sum int
err := row.Scan(&sum)
@@ -696,7 +711,11 @@ func (manager *SStorageManager) newFromCloudStorage(ctx context.Context, userCre
storage := SStorage{}
storage.SetModelManager(manager)
storage.Name = db.GenerateName(manager, manager.GetOwnerId(userCred), extStorage.GetName())
newName, err := db.GenerateName(manager, manager.GetOwnerId(userCred), extStorage.GetName())
if err != nil {
return nil, err
}
storage.Name = newName
storage.Status = extStorage.GetStatus()
storage.ExternalId = extStorage.GetGlobalId()
storage.ZoneId = zone.Id
@@ -713,7 +732,7 @@ func (manager *SStorageManager) newFromCloudStorage(ctx context.Context, userCre
storage.IsSysDiskStore = extStorage.IsSysDiskStore()
err := manager.TableSpec().Insert(&storage)
err = manager.TableSpec().Insert(&storage)
if err != nil {
log.Errorf("newFromCloudStorage fail %s", err)
return nil, err
+23 -12
View File
@@ -103,7 +103,11 @@ func (self *SVpc) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCr
}
func (self *SVpc) ValidateDeleteCondition(ctx context.Context) error {
if self.GetNetworkCount() > 0 {
cnt, err := self.GetNetworkCount()
if err != nil {
return httperrors.NewInternalServerError("GetNetworkCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("VPC not empty")
}
if self.Id == api.DEFAULT_VPC_ID {
@@ -123,9 +127,9 @@ func (self *SVpc) getWireQuery() *sqlchemy.SQuery {
}
}
func (self *SVpc) GetWireCount() int {
func (self *SVpc) GetWireCount() (int, error) {
q := self.getWireQuery()
return q.Count()
return q.CountWithError()
}
func (self *SVpc) GetWires() []SWire {
@@ -146,9 +150,9 @@ func (self *SVpc) getNetworkQuery() *sqlchemy.SQuery {
return q
}
func (self *SVpc) GetNetworkCount() int {
func (self *SVpc) GetNetworkCount() (int, error) {
q := self.getNetworkQuery()
return q.Count()
return q.CountWithError()
}
func (self *SVpc) GetRouteTableQuery() *sqlchemy.SQuery {
@@ -162,14 +166,17 @@ func (self *SVpc) GetRouteTables() []SRouteTable {
return routes
}
func (self *SVpc) GetRouteTableCount() int {
return self.GetRouteTableQuery().Count()
func (self *SVpc) GetRouteTableCount() (int, error) {
return self.GetRouteTableQuery().CountWithError()
}
func (self *SVpc) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict {
extra.Add(jsonutils.NewInt(int64(self.GetWireCount())), "wire_count")
extra.Add(jsonutils.NewInt(int64(self.GetNetworkCount())), "network_count")
extra.Add(jsonutils.NewInt(int64(self.GetRouteTableCount())), "routetable_count")
cnt, _ := self.GetWireCount()
extra.Add(jsonutils.NewInt(int64(cnt)), "wire_count")
cnt, _ = self.GetNetworkCount()
extra.Add(jsonutils.NewInt(int64(cnt)), "network_count")
cnt, _ = self.GetRouteTableCount()
extra.Add(jsonutils.NewInt(int64(cnt)), "routetable_count")
/* region, err := self.GetRegion()
if err != nil {
log.Errorf("failed getting region for vpc %s(%s)", self.Name, self.Id)
@@ -344,7 +351,11 @@ func (manager *SVpcManager) newFromCloudVpc(ctx context.Context, userCred mcclie
vpc := SVpc{}
vpc.SetModelManager(manager)
vpc.Name = db.GenerateName(manager, manager.GetOwnerId(userCred), extVPC.GetName())
newName, err := db.GenerateName(manager, manager.GetOwnerId(userCred), extVPC.GetName())
if err != nil {
return nil, err
}
vpc.Name = newName
vpc.Status = extVPC.GetStatus()
vpc.ExternalId = extVPC.GetGlobalId()
vpc.IsDefault = extVPC.GetIsDefault()
@@ -355,7 +366,7 @@ func (manager *SVpcManager) newFromCloudVpc(ctx context.Context, userCred mcclie
vpc.IsEmulated = extVPC.IsEmulated()
err := manager.TableSpec().Insert(&vpc)
err = manager.TableSpec().Insert(&vpc)
if err != nil {
log.Errorf("newFromCloudVpc fail %s", err)
return nil, err
+27 -26
View File
@@ -122,8 +122,19 @@ func (wire *SWire) ValidateUpdateData(ctx context.Context, userCred mcclient.Tok
}
func (wire *SWire) ValidateDeleteCondition(ctx context.Context) error {
if wire.HostCount() > 0 || wire.NetworkCount() > 0 {
return httperrors.NewNotEmptyError("not an empty wire")
cnt, err := wire.HostCount()
if err != nil {
return httperrors.NewInternalServerError("HostCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("wire contains hosts")
}
cnt, err = wire.NetworkCount()
if err != nil {
return httperrors.NewInternalServerError("NetworkCount fail %s", err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("wire contains networks")
}
return wire.SStandaloneResourceBase.ValidateDeleteCondition(ctx)
}
@@ -132,9 +143,9 @@ func (wire *SWire) getHostwireQuery() *sqlchemy.SQuery {
return HostwireManager.Query().Equals("wire_id", wire.Id)
}
func (wire *SWire) HostCount() int {
func (wire *SWire) HostCount() (int, error) {
q := wire.getHostwireQuery()
return q.Count()
return q.CountWithError()
}
func (wire *SWire) GetHostwires() ([]SHostwire, error) {
@@ -147,9 +158,9 @@ func (wire *SWire) GetHostwires() ([]SHostwire, error) {
return hostwires, nil
}
func (wire *SWire) NetworkCount() int {
func (wire *SWire) NetworkCount() (int, error) {
q := NetworkManager.Query().Equals("wire_id", wire.Id)
return q.Count()
return q.CountWithError()
}
func (wire *SWire) GetVpcId() string {
@@ -287,7 +298,11 @@ func (manager *SWireManager) newFromCloudWire(ctx context.Context, userCred mccl
wire := SWire{}
wire.SetModelManager(manager)
wire.Name = db.GenerateName(manager, manager.GetOwnerId(userCred), extWire.GetName())
newName, err := db.GenerateName(manager, manager.GetOwnerId(userCred), extWire.GetName())
if err != nil {
return nil, err
}
wire.Name = newName
wire.ExternalId = extWire.GetGlobalId()
wire.Bandwidth = extWire.GetBandwidth()
wire.VpcId = vpc.Id
@@ -304,7 +319,7 @@ func (manager *SWireManager) newFromCloudWire(ctx context.Context, userCred mccl
wire.IsEmulated = extWire.IsEmulated()
err := manager.TableSpec().Insert(&wire)
err = manager.TableSpec().Insert(&wire)
if err != nil {
log.Errorf("newFromCloudWire fail %s", err)
return nil, err
@@ -498,8 +513,8 @@ func chooseNetworkByAddressCount(nets []*SNetwork) (*SNetwork, *SNetwork) {
var minSel *SNetwork
var maxSel *SNetwork
for _, net := range nets {
cnt := net.getFreeAddressCount()
if cnt <= 0 {
cnt, err := net.getFreeAddressCount()
if err != nil || cnt <= 0 {
continue
}
if minSel == nil || minCnt > cnt {
@@ -770,22 +785,8 @@ func (self *SWire) GetExtraDetails(ctx context.Context, userCred mcclient.TokenC
}
func (self *SWire) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict {
extra.Add(jsonutils.NewInt(int64(self.NetworkCount())), "networks")
/*zone := self.GetZone()
if zone != nil {
extra.Add(jsonutils.NewString(zone.GetName()), "zone")
if len(zone.GetExternalId()) > 0 {
extra.Add(jsonutils.NewString(zone.GetExternalId()), "zone_external_id")
}
}
region := self.getRegion()
if region != nil {
extra.Add(jsonutils.NewString(region.GetId()), "region_id")
extra.Add(jsonutils.NewString(region.GetName()), "region")
if len(region.GetExternalId()) > 0 {
extra.Add(jsonutils.NewString(region.GetExternalId()), "region_external_id")
}
}*/
cnt, _ := self.NetworkCount()
extra.Add(jsonutils.NewInt(int64(cnt)), "networks")
vpc := self.getVpc()
if vpc != nil {
extra.Add(jsonutils.NewString(vpc.GetName()), "vpc")
+22 -18
View File
@@ -135,8 +135,8 @@ on_succ, on_fail, **kwargs)
*/
func (manager *SZoneManager) Count() int {
return manager.Query().Count()
func (manager *SZoneManager) Count() (int, error) {
return manager.Query().CountWithError()
}
type ZoneGeneralUsage struct {
@@ -167,17 +167,17 @@ func (usage *ZoneGeneralUsage) isEmpty() bool {
func (zone *SZone) GeneralUsage() ZoneGeneralUsage {
usage := ZoneGeneralUsage{}
usage.Hosts = zone.HostCount("", "", tristate.None, "", tristate.None)
usage.HostsEnabled = zone.HostCount("", "", tristate.True, "", tristate.None)
usage.Baremetals = zone.HostCount("", "", tristate.None, "", tristate.True)
usage.BaremetalsEnabled = zone.HostCount("", "", tristate.True, "", tristate.True)
usage.Wires = zone.getWireCount()
usage.Networks = zone.getNetworkCount()
usage.Storages = zone.getStorageCount()
usage.Hosts, _ = zone.HostCount("", "", tristate.None, "", tristate.None)
usage.HostsEnabled, _ = zone.HostCount("", "", tristate.True, "", tristate.None)
usage.Baremetals, _ = zone.HostCount("", "", tristate.None, "", tristate.True)
usage.BaremetalsEnabled, _ = zone.HostCount("", "", tristate.True, "", tristate.True)
usage.Wires, _ = zone.getWireCount()
usage.Networks, _ = zone.getNetworkCount()
usage.Storages, _ = zone.getStorageCount()
return usage
}
func (zone *SZone) HostCount(status string, hostStatus string, enabled tristate.TriState, hostType string, isBaremetal tristate.TriState) int {
func (zone *SZone) HostCount(status string, hostStatus string, enabled tristate.TriState, hostType string, isBaremetal tristate.TriState) (int, error) {
q := HostManager.Query().Equals("zone_id", zone.Id)
if len(status) > 0 {
q = q.Equals("status", status)
@@ -198,20 +198,20 @@ func (zone *SZone) HostCount(status string, hostStatus string, enabled tristate.
} else if isBaremetal.IsFalse() {
q = q.IsFalse("is_baremetal")
}
return q.Count()
return q.CountWithError()
}
func (zone *SZone) getWireCount() int {
func (zone *SZone) getWireCount() (int, error) {
q := WireManager.Query().Equals("zone_id", zone.Id)
return q.Count()
return q.CountWithError()
}
func (zone *SZone) getStorageCount() int {
func (zone *SZone) getStorageCount() (int, error) {
q := StorageManager.Query().Equals("zone_id", zone.Id)
return q.Count()
return q.CountWithError()
}
func (zone *SZone) getNetworkCount() int {
func (zone *SZone) getNetworkCount() (int, error) {
return getNetworkCount(nil, zone)
}
@@ -352,7 +352,11 @@ func (manager *SZoneManager) newFromCloudZone(ctx context.Context, userCred mccl
zone := SZone{}
zone.SetModelManager(manager)
zone.Name = db.GenerateName(manager, manager.GetOwnerId(userCred), extZone.GetName())
newName, err := db.GenerateName(manager, manager.GetOwnerId(userCred), extZone.GetName())
if err != nil {
return nil, err
}
zone.Name = newName
zone.Status = extZone.GetStatus()
zone.ExternalId = extZone.GetGlobalId()
@@ -360,7 +364,7 @@ func (manager *SZoneManager) newFromCloudZone(ctx context.Context, userCred mccl
zone.CloudregionId = region.Id
err := manager.TableSpec().Insert(&zone)
err = manager.TableSpec().Insert(&zone)
if err != nil {
log.Errorf("newFromCloudZone fail %s", err)
return nil, err
+12 -3
View File
@@ -104,8 +104,14 @@ func (self *SQcloudRegionDriver) RequestCreateLoadbalancerBackend(ctx context.Co
}
// 兼容腾讯云,在fake的backend group 关联具体的转发策略之前。不需要同步后端服务器
if lbbg.GetProviderName() == api.CLOUD_PROVIDER_QCLOUD && lbbg.RefCount() == 0 {
return nil, nil
if lbbg.GetProviderName() == api.CLOUD_PROVIDER_QCLOUD {
cnt, err := lbbg.RefCount()
if err != nil {
return nil, err
}
if cnt == 0 {
return nil, nil
}
}
lb := lbbg.GetLoadbalancer()
@@ -156,7 +162,10 @@ func (self *SQcloudRegionDriver) RequestDeleteLoadbalancerBackend(ctx context.Co
// ===========兼容腾讯云,未关联具体转发规则时,直接删除本地数据即可===============
if iRegion.GetProvider() == api.CLOUD_PROVIDER_QCLOUD {
count := lbbg.RefCount()
count, err := lbbg.RefCount()
if err != nil {
return nil, err
}
if count == 0 {
return nil, nil
}
@@ -77,12 +77,12 @@ func (self *BaremetalSyncAllGuestsStatusTask) OnInit(ctx context.Context, obj db
bs.SetStatus(self.UserCred, api.STORAGE_OFFLINE, "")
if first && baremetal.Name != guest.Name {
db.Update(baremetal, func() error {
if models.HostManager.IsNewNameUnique(guest.Name, self.UserCred, nil) {
baremetal.Name = guest.Name
} else {
baremetal.Name = db.GenerateName(baremetal.GetModelManager(),
self.UserCred.GetTokenString(), guest.Name)
newName, err := db.GenerateName(baremetal.GetModelManager(),
self.UserCred.GetTokenString(), guest.Name)
if err != nil {
return err
}
baremetal.Name = newName
return nil
})
}
+8 -1
View File
@@ -38,7 +38,14 @@ func init() {
func (self *DiskDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
disk := obj.(*models.SDisk)
if disk.GetGuestDiskCount() > 0 {
cnt, err := disk.GetGuestDiskCount()
if err != nil {
reason := "Disk GetGuestDiskCount fail: " + err.Error()
self.SetStageFailed(ctx, reason)
db.OpsLog.LogEvent(disk, db.ACT_DELOCATE_FAIL, reason, self.UserCred)
return
}
if cnt > 0 {
reason := "Disk has been attached to server"
self.SetStageFailed(ctx, reason)
db.OpsLog.LogEvent(disk, db.ACT_DELOCATE_FAIL, reason, self.UserCred)
@@ -39,7 +39,12 @@ func (self *GuestDetachAllDisksTask) OnInit(ctx context.Context, obj db.IStandal
func (self *GuestDetachAllDisksTask) OnDiskDeleteComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
guest := obj.(*models.SGuest)
if guest.DiskCount() == 0 {
cnt, err := guest.DiskCount()
if err != nil {
self.SetStageFailed(ctx, err.Error())
return
}
if cnt == 0 {
self.SetStageComplete(ctx, nil)
return
}
+12 -9
View File
@@ -97,17 +97,19 @@ func (self *GuestDetachDiskTask) OnSyncConfigComplete(ctx context.Context, guest
if host != nil && host.Status == api.HOST_DISABLED && jsonutils.QueryBoolean(self.Params, "purge", false) {
purge = true
}
if !keepDisk && disk.GetGuestDiskCount() == 0 && disk.AutoDelete {
self.SetStage("OnDiskDeleteComplete", nil)
db.OpsLog.LogEvent(disk, db.ACT_DELETE, "", self.UserCred)
err := guest.GetDriver().RequestDeleteDetachedDisk(ctx, disk, self, purge)
if err != nil {
self.OnTaskFail(ctx, guest, disk, err)
if !keepDisk && disk.AutoDelete {
cnt, _ := disk.GetGuestDiskCount()
if cnt == 0 {
self.SetStage("OnDiskDeleteComplete", nil)
db.OpsLog.LogEvent(disk, db.ACT_DELETE, "", self.UserCred)
err := guest.GetDriver().RequestDeleteDetachedDisk(ctx, disk, self, purge)
if err != nil {
self.OnTaskFail(ctx, guest, disk, err)
}
return
}
} else {
self.SetStageComplete(ctx, nil)
}
logclient.AddActionLogWithStartable(self, guest, logclient.ACT_VM_DETACH_DISK, nil, self.UserCred, true)
self.OnDiskDeleteComplete(ctx, guest, nil)
}
func (self *GuestDetachDiskTask) OnSyncConfigCompleteFailed(ctx context.Context, obj db.IStandaloneModel, reason jsonutils.JSONObject) {
@@ -143,4 +145,5 @@ func (self *GuestDetachDiskTask) OnTaskFail(ctx context.Context, guest *models.S
func (self *GuestDetachDiskTask) OnDiskDeleteComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
self.SetStageComplete(ctx, nil)
logclient.AddActionLogWithStartable(self, obj, logclient.ACT_VM_DETACH_DISK, nil, self.UserCred, true)
}
@@ -76,27 +76,34 @@ func (self *HostImportLibvirtServersTask) StartImportServers(
success bool
)
for i := 0; i < len(guestsDesc); i++ {
self.FillLibvirtGuestDesc(ctx, host, &guestsDesc[i])
guest, err := models.GuestManager.DoImport(ctx, self.UserCred, &guestsDesc[i])
var guest *models.SGuest = nil
err := self.FillLibvirtGuestDesc(ctx, host, &guestsDesc[i])
if err != nil {
note = fmt.Sprintf("Guest %s import failed: %s", guestsDesc[i].Id, err)
note = fmt.Sprintf("Guest %s desc fill failed: %s", guestsDesc[i].Id, err)
success = false
goto end
} else {
guest, err = models.GuestManager.DoImport(ctx, self.UserCred, &guestsDesc[i])
if err != nil {
note = fmt.Sprintf("Guest %s import failed: %s", guestsDesc[i].Id, err)
success = false
} else {
if err := self.CreateImportedLibvirtGuestOnHost(ctx, host, guest, &guestsDesc[i]); err != nil {
note = fmt.Sprintf("Guest %s create on host failed: %s", guestsDesc[i].Id, err)
success = false
} else {
note = fmt.Sprintf("Guest %s import success, started create on host", guestsDesc[i].Id)
success = true
}
}
}
if err := self.CreateImportedLibvirtGuestOnHost(ctx, host, guest, &guestsDesc[i]); err != nil {
note = fmt.Sprintf("Guest %s create on host failed: %s", guestsDesc[i].Id, err)
success = false
goto end
}
note = fmt.Sprintf("Guest %s import success, started create on host", guestsDesc[i].Id)
success = true
end:
if success {
db.OpsLog.LogEvent(host, db.ACT_HOST_IMPORT_LIBVIRT_SERVERS, note, self.UserCred)
} else {
log.Errorln(note)
guest.SetStatus(self.UserCred, compute.VM_IMPORT_FAILED, note)
if guest != nil {
guest.SetStatus(self.UserCred, compute.VM_IMPORT_FAILED, note)
}
db.OpsLog.LogEvent(host, db.ACT_HOST_IMPORT_LIBVIRT_SERVERS_FAIL, note, self.UserCred)
}
logclient.AddActionLogWithContext(ctx, host,
@@ -107,20 +114,22 @@ func (self *HostImportLibvirtServersTask) StartImportServers(
func (self *HostImportLibvirtServersTask) FillLibvirtGuestDesc(
ctx context.Context, host *models.SHost, guestDesc *compute.SImportGuestDesc,
) {
) error {
// Generate new uuid for guest to prevent duplicate
guestDesc.Id = stringutils.UUID4()
guestDesc.HostId = host.Id
g, _ := models.GuestManager.FetchByName(self.UserCred, guestDesc.Name)
if g != nil {
guestDesc.Name = db.GenerateName(models.GuestManager, self.UserCred.GetProjectId(), guestDesc.Name)
newName, err := db.GenerateName(models.GuestManager, self.UserCred.GetProjectId(), guestDesc.Name)
if err != nil {
return err
}
guestDesc.Name = newName
for i := 0; i < len(guestDesc.Disks); i++ {
guestDesc.Disks[i].DiskId = stringutils.UUID4()
if len(guestDesc.Disks[i].Backend) == 0 {
guestDesc.Disks[i].Backend = api.STORAGE_LOCAL
}
}
return nil
}
// Create sub task to create guest on host, and feedback disk real access path
+5 -5
View File
@@ -379,7 +379,7 @@ func RegionUsage(providers []string) Usage {
q = q.In("provider", providers)
}
count := make(map[string]interface{})
count["regions"] = q.Count()
count["regions"], _ = q.CountWithError()
return count
}
@@ -391,7 +391,7 @@ func ZoneUsage(providers []string) Usage {
}
q := models.ZoneManager.Query().In("cloudregion_id", subq.SubQuery())
count := make(map[string]interface{})
count["zones"] = q.Count()
count["zones"], _ = q.CountWithError()
return count
}
@@ -403,7 +403,7 @@ func VpcUsage(providers []string) Usage {
}
q := models.VpcManager.Query().In("cloudregion_id", subq.SubQuery())
count := make(map[string]interface{})
count["vpcs"] = q.Count()
count["vpcs"], _ = q.CountWithError()
return count
}
@@ -566,7 +566,7 @@ func IsolatedDeviceUsage(pref string, rangeObj db.IStandaloneModel, hostType []s
if len(pref) > 0 {
prefix = fmt.Sprintf("%s.%s", prefix, pref)
}
ret := models.IsolatedDeviceManager.TotalCount(hostType, resourceTypes, providers, rangeObj)
ret, _ := models.IsolatedDeviceManager.TotalCount(hostType, resourceTypes, providers, rangeObj)
count := make(map[string]interface{})
count[prefix] = ret.Devices
return count
@@ -591,7 +591,7 @@ func EipUsage(projectId string, rangeObj db.IStandaloneModel, providers []string
}
func SnapshotUsage(projectId string, rangeObj db.IStandaloneModel, providers []string) Usage {
cnt := models.TotalSnapshotCount(projectId, rangeObj, providers)
cnt, _ := models.TotalSnapshotCount(projectId, rangeObj, providers)
count := make(map[string]interface{})
count[getKey(projectId, "snapshot")] = cnt
return count
+2 -1
View File
@@ -730,7 +730,8 @@ func (manager *SImageManager) count(projectId string, status string, isISO trist
ret[u.Format] = SImageUsage{Count: u.Count, Size: u.Size}
totalSize += u.Size
}
ret["total"] = SImageUsage{Count: int64(sq.Count()), Size: totalSize}
cnt, _ := sq.CountWithError()
ret["total"] = SImageUsage{Count: int64(cnt), Size: totalSize}
return ret
}
@@ -98,7 +98,10 @@ func (p *NetworkSchedtagPredicate) IsResourceFitInput(u *core.Unit, res ISchedta
return fmt.Errorf("Address %s not in range", net.Address)
}
}
free := network.GetFreeAddressCount()
free, err := network.GetFreeAddressCount()
if err != nil {
return err
}
req := u.SchedData().Count
if free < req {
return fmt.Errorf("Network %s no free IPs, free %d, require %d", network.Name, free, req)
@@ -127,7 +130,11 @@ func (p *NetworkSchedtagPredicate) OnSelectEnd(u *core.Unit, c core.Candidater,
}
func (p *NetworkSchedtagPredicate) GetCandidateResourceSortScore(selectRes ISchedtagCandidateResource) int {
return selectRes.(*api.CandidateNetwork).GetFreeAddressCount()
cnt, err := selectRes.(*api.CandidateNetwork).GetFreeAddressCount()
if err != nil {
return -1
}
return cnt
}
func (p *NetworkSchedtagPredicate) DoSelect(
+1 -1
View File
@@ -924,7 +924,7 @@ func (self *SRegion) ReplaceSystemDisk(ctx context.Context, instanceId string, i
defer self.DeleteVM(_id)
} else {
log.Debugf("ReplaceSystemDisk create temp server failed. %s", err)
return "",fmt.Errorf("ReplaceSystemDisk create temp server failed.")
return "", fmt.Errorf("ReplaceSystemDisk create temp server failed.")
}
self.ec2Client.WaitUntilInstanceRunning(&ec2.DescribeInstancesInput{InstanceIds: []*string{&_id}})
+5 -1
View File
@@ -137,7 +137,11 @@ func (manager *SParameterManager) ValidateCreateData(ctx context.Context, userCr
// check duplication, 同一个namespace下,name不能 重复
q := manager.Query().Equals("name", name).Equals("namespace_id", namespace_id)
if q.Count() > 0 {
cnt, err := q.CountWithError()
if err != nil {
return nil, httperrors.NewInternalServerError("check name duplication fail %s", err)
}
if cnt > 0 {
return nil, httperrors.NewDuplicateNameError("paramter %s has been created", name)
}
+6 -1
View File
@@ -18,6 +18,11 @@ func isLowerChar(ch byte) bool {
}
func CamelSplit(str string, sep string) string {
tokens := CamelSplitTokens(str)
return strings.Join(tokens, sep)
}
func CamelSplitTokens(str string) []string {
tokens := make([]string, 0)
var buf bytes.Buffer
upperCount := 0
@@ -53,7 +58,7 @@ func CamelSplit(str string, sep string) string {
if buf.Len() > 0 {
tokens = append(tokens, buf.String())
}
return strings.Join(tokens, sep)
return tokens
}
func Capitalize(str string) string {
+6 -1
View File
@@ -41,7 +41,12 @@ func (t *STableSpec) insertSqlPrep(dataFields reflectutils.SStructFieldValueSet)
if ok && (dtc.IsCreatedAt || dtc.IsUpdatedAt) {
createdAtFields = append(createdAtFields, k)
names = append(names, fmt.Sprintf("`%s`", k))
format = append(format, "UTC_TIMESTAMP()")
if c.IsZero(ov) {
format = append(format, "UTC_TIMESTAMP()")
} else {
values = append(values, ov)
format = append(format, "?")
}
} else if c.IsSupportDefault() && len(c.Default()) > 0 && !gotypes.IsNil(ov) && c.IsZero(ov) { // empty text value
val := c.ConvertFromString(c.Default())
values = append(values, val)
+7 -2
View File
@@ -385,6 +385,11 @@ func (tq *SQuery) Rows() (*sql.Rows, error) {
}
func (tq *SQuery) Count() int {
cnt, _ := tq.CountWithError()
return cnt
}
func (tq *SQuery) CountWithError() (int, error) {
cq := SQuery{fields: []IQueryField{COUNT("count")},
from: tq.from,
joins: tq.joins,
@@ -395,9 +400,9 @@ func (tq *SQuery) Count() int {
err := cq.Row().Scan(&count)
if err != nil {
log.Errorf("SQuery count %s failed: %s", cq.String(), err)
return -1
return -1, err
} else {
return count
return count, nil
}
}