Compare commits

...

17 Commits

Author SHA1 Message Date
Zexi Li
caa530bd60 Merge pull request #9789 from yousong/automated-cherry-pick-of-#9785-upstream-release-3.4
Automated cherry pick of #9785: guest_deploy_task: log other deploy details with i18n
2021-01-07 21:16:57 +08:00
Yousong Zhou
559d30afa8 guest_deploy_task: log other deploy details with i18n
Fixes 9f350392 ("add service tag for actionlog")
2021-01-07 11:47:12 +08:00
Zexi Li
b8c10b8e7c Merge pull request #9766 from wanyaoqi/automated-cherry-pick-of-#9762-upstream-release-3.4
Automated cherry pick of #9762: feat(region): stop guest before freeze
2021-01-05 18:33:42 +08:00
wanyaoqi
b3285aebce feat(region): stop guest before freeze 2021-01-05 15:49:25 +08:00
Zexi Li
ad01c895cf Merge pull request #9739 from wanyaoqi/automated-cherry-pick-of-#9731-upstream-release-3.4
Automated cherry pick of #9731: fix(region): server start check host memory is enough
2020-12-30 21:40:07 +08:00
Zexi Li
b2aa6dd321 Merge pull request #9748 from rainzm/automated-cherry-pick-of-#9744-upstream-release-3.4
Automated cherry pick of #9744: fix(esxiagent): nicIndex should be incremented
2020-12-30 21:36:07 +08:00
rainzm
a4dcc91d0d fix(esxiagent): nicIndex should be incremented 2020-12-30 19:04:00 +08:00
wanyaoqi
18a751548c fix(region): server start check host memory is enough 2020-12-30 15:59:07 +08:00
Zexi Li
b53b09ebb5 Merge pull request #9718 from wanyaoqi/automated-cherry-pick-of-#9711-upstream-release-3.4
Automated cherry pick of #9711: fix(region,host,host-deployer): sync status chekc block jobs
2020-12-29 20:43:49 +08:00
Zexi Li
c6941536b7 Merge pull request #9714 from rainzm/automated-cherry-pick-of-#9693-upstream-release-3.4
Automated cherry pick of #9693: Solve the permission problem of notify to create receiver
2020-12-29 20:41:56 +08:00
wanyaoqi
edba3c3dfc fix(region,host): sync status check block jobs 2020-12-29 15:39:34 +08:00
wanyaoqi
a66c1aa1ba fix(host-deployer): add log line on blkid failed 2020-12-29 15:38:59 +08:00
wanyaoqi
c5dd4389d3 fix(climc): host add netif add params bridge/interface 2020-12-29 15:38:59 +08:00
rainzm
0e4ea782e1 feat(db): progressive inspection when determining the required scope 2020-12-29 15:14:28 +08:00
rainzm
9b993f1a99 fix(notify): inject domain info in ReceiverManager.FetchOwnerId 2020-12-29 15:14:28 +08:00
Zexi Li
8a62c46a92 Merge pull request #9704 from swordqiu/automated-cherry-pick-of-#9701-upstream-release-3.4
Automated cherry pick of #9701: fix(region): omit vpc quota check if vpc created by owner
2020-12-29 09:36:04 +08:00
Qiu Jian
d3ad4967a9 fix(region): omit vpc quota check if vpc created by owner
Vpc quota check is omitted if vpc is create by owner user
2020-12-29 01:21:47 +08:00
16 changed files with 150 additions and 22 deletions

View File

@@ -407,12 +407,14 @@ func init() {
})
type HostAddNetIfOptions struct {
ID string `help:"ID or Name of host"`
WIRE string `help:"ID or Name of wire to attach"`
MAC string `help:"Mac address of NIC"`
INDEX int64 `help:"nic index"`
Type string `help:"Nic type" choices:"admin|ipmi"`
IpAddr string `help:"IP address"`
ID string `help:"ID or Name of host"`
WIRE string `help:"ID or Name of wire to attach"`
MAC string `help:"Mac address of NIC"`
INDEX int64 `help:"nic index"`
Type string `help:"Nic type" choices:"admin|ipmi"`
IpAddr string `help:"IP address"`
Bridge string `help:"Bridge of hostwire"`
Interface string `help:"Interface name, eg:eth0, en0"`
}
R(&HostAddNetIfOptions{}, "host-add-netif", "Host add a NIC", func(s *mcclient.ClientSession, args *HostAddNetIfOptions) error {
params := jsonutils.NewDict()
@@ -426,6 +428,12 @@ func init() {
if len(args.IpAddr) > 0 {
params.Add(jsonutils.NewString(args.IpAddr), "ip_addr")
}
if len(args.Bridge) > 0 {
params.Add(jsonutils.NewString(args.Bridge), "bridge")
}
if len(args.Interface) > 0 {
params.Add(jsonutils.NewString(args.Interface), "interface")
}
result, err := modules.Hosts.PerformAction(s, args.ID, "add-netif", params)
if err != nil {
return err

View File

@@ -201,6 +201,8 @@ type PerformStatusInput struct {
// 更改的目标状态值
// required:true
Status string `json:"status"`
// swagger:ignore
BlockJobsCount int `json:"block_jobs_count"`
// 更改状态的原因描述
// required:false

View File

@@ -47,8 +47,9 @@ const (
ACT_BACKUP_START = "backup_start"
ACT_BACKUP_START_FAILED = "backup_start_fail"
ACT_FREEZE = "freeze"
ACT_UNFREEZE = "unfreeze"
ACT_FREEZE = "freeze"
ACT_FREEZE_FAIL = "freeze_fail"
ACT_UNFREEZE = "unfreeze"
ACT_RESTARING = "restarting"
ACT_RESTART_FAIL = "restart_fail"

View File

@@ -51,6 +51,8 @@ func isObjectRbacAllowed(model IModel, userCred mcclient.TokenCredential, action
case rbacutils.ScopeUser:
if ownerId != nil && objOwnerId != nil && (ownerId.GetUserId() == objOwnerId.GetUserId() || objOwnerId.GetUserId() == "" || (model.IsSharable(ownerId) && action == policy.PolicyActionGet)) {
requireScope = rbacutils.ScopeUser
} else if ownerId != nil && objOwnerId != nil && ownerId.GetProjectDomainId() == objOwnerId.GetProjectDomainId() {
requireScope = rbacutils.ScopeDomain
} else {
requireScope = rbacutils.ScopeSystem
}
@@ -103,6 +105,8 @@ func isClassRbacAllowed(manager IModelManager, userCred mcclient.TokenCredential
case rbacutils.ScopeUser:
if ownerId != nil && ownerId.GetUserId() == objOwnerId.GetUserId() {
requireScope = rbacutils.ScopeUser
} else if ownerId != nil && ownerId.GetProjectDomainId() == objOwnerId.GetProjectDomainId() {
requireScope = rbacutils.ScopeDomain
} else {
requireScope = rbacutils.ScopeSystem
}

View File

@@ -788,6 +788,16 @@ func (self *SGuest) AllowPerformStart(ctx context.Context,
func (self *SGuest) PerformStart(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject,
data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if utils.IsInStringArray(self.Status, []string{api.VM_READY, api.VM_START_FAILED, api.VM_SAVE_DISK_FAILED, api.VM_SUSPEND}) {
if !self.guestDisksStorageTypeIsShared() {
host := self.GetHost()
guestsMem, err := host.GetNotReadyGuestsMemorySize()
if err != nil {
return nil, err
}
if float32(guestsMem+self.VmemSize) > host.GetVirtualMemorySize() {
return nil, httperrors.NewInsufficientResourceError("host virtual memory not enough")
}
}
if self.isAllDisksReady() {
var kwargs *jsonutils.JSONDict
if data != nil {
@@ -2745,7 +2755,7 @@ func (self *SGuest) PerformStatus(ctx context.Context, userCred mcclient.TokenCr
}
status := input.Status
if len(self.BackupHostId) > 0 && status == api.VM_RUNNING {
if len(self.BackupHostId) > 0 && status == api.VM_RUNNING && input.BlockJobsCount > 0 {
if len(self.GetMetadata("__mirror_job_status", userCred)) == 0 {
self.SetMetadata(ctx, "__mirror_job_status", "ready", userCred)
}
@@ -2786,6 +2796,27 @@ func (self *SGuest) PerformStop(ctx context.Context, userCred mcclient.TokenCred
}
}
func (self *SGuest) PerformFreeze(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformFreezeInput) (jsonutils.JSONObject, error) {
if self.Freezed {
return nil, httperrors.NewBadRequestError("virtual resource already freezed")
}
if utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_STOP_FAILED}) {
return nil, self.StartGuestStopAndFreezeTask(ctx, userCred)
} else {
return self.SVirtualResourceBase.PerformFreeze(ctx, userCred, query, input)
}
}
func (self *SGuest) StartGuestStopAndFreezeTask(ctx context.Context, userCred mcclient.TokenCredential) error {
self.SetStatus(userCred, api.VM_START_STOP, "")
task, err := taskman.TaskManager.NewTask(ctx, "GuestStopAndFreezeTask", self, userCred, nil, "", "", nil)
if err != nil {
return err
}
task.ScheduleRun(nil)
return nil
}
func (self *SGuest) AllowPerformRestart(ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,

View File

@@ -4654,7 +4654,7 @@ func (self *SGuestManager) switchBackupGuests(ctx context.Context, userCred mccl
log.Errorf("ReconcileBackupGuests failed fetch guests %s", err)
return
}
log.Infof("Guests count %d need reconcile with switch bakcup", len(guests))
log.Debugf("Guests count %d need reconcile with switch backup", len(guests))
for i := 0; i < len(guests); i++ {
val := guests[i].GetMetadataJson("switch_backup", userCred)
t, err := val.GetTime()

View File

@@ -1490,6 +1490,23 @@ func (self *SHost) GetRunningGuestCount() (int, error) {
return q.CountWithError()
}
func (self *SHost) GetNotReadyGuestsMemorySize() (int, error) {
guests := GuestManager.Query().SubQuery()
q := guests.Query(sqlchemy.COUNT("guest_count"),
sqlchemy.SUM("guest_vcpu_count", guests.Field("vcpu_count")),
sqlchemy.SUM("guest_vmem_size", guests.Field("vmem_size")))
cond := sqlchemy.OR(sqlchemy.Equals(q.Field("host_id"), self.Id),
sqlchemy.Equals(q.Field("backup_host_id"), self.Id))
q = q.Filter(cond)
q = q.NotEquals("status", api.VM_READY)
stat := SHostGuestResourceUsage{}
err := q.First(&stat)
if err != nil {
return -1, err
}
return stat.GuestVmemSize, nil
}
func (self *SHost) GetRunningGuestMemorySize() int {
res := self.getGuestsResource(api.VM_RUNNING)
if res != nil {
@@ -3085,7 +3102,7 @@ func (self *SHost) PostCreate(
}
}
keys := GetHostQuotaKeysFromCreateInput(input)
keys := GetHostQuotaKeysFromCreateInput(ownerId, input)
quota := SInfrasQuota{Host: 1}
quota.SetKeys(keys)
err = quotas.CancelPendingUsage(ctx, userCred, &quota, &quota, true)
@@ -3379,7 +3396,7 @@ func (manager *SHostManager) ValidateCreateData(
return input, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ValidateCreateData")
}
keys := GetHostQuotaKeysFromCreateInput(input)
keys := GetHostQuotaKeysFromCreateInput(ownerId, input)
quota := SInfrasQuota{Host: 1}
quota.SetKeys(keys)
err = quotas.CheckSetPendingQuota(ctx, userCred, &quota)
@@ -5612,8 +5629,8 @@ func (host *SHost) GetChangeOwnerRequiredDomainIds() []string {
return requires
}
func GetHostQuotaKeysFromCreateInput(input api.HostCreateInput) quotas.SDomainRegionalCloudResourceKeys {
ownerId := &db.SOwnerId{DomainId: input.ProjectDomainId}
func GetHostQuotaKeysFromCreateInput(owner mcclient.IIdentityProvider, input api.HostCreateInput) quotas.SDomainRegionalCloudResourceKeys {
ownerId := &db.SOwnerId{DomainId: owner.GetProjectDomainId()}
var zone *SZone
if len(input.ZoneId) > 0 {
zone = ZoneManager.FetchZoneById(input.ZoneId)

View File

@@ -774,7 +774,7 @@ func (manager *SVpcManager) ValidateCreateData(
return input, httperrors.NewMissingParameterError("cidr")
}
keys := GetVpcQuotaKeysFromCreateInput(input)
keys := GetVpcQuotaKeysFromCreateInput(ownerId, input)
quota := &SInfrasQuota{Vpc: 1}
quota.SetKeys(keys)
err = quotas.CheckSetPendingQuota(ctx, userCred, quota)
@@ -792,7 +792,7 @@ func (self *SVpc) PostCreate(ctx context.Context, userCred mcclient.TokenCredent
log.Errorf("input unmarshal error %s", err)
} else {
pendingUsage := &SInfrasQuota{Vpc: 1}
keys := GetVpcQuotaKeysFromCreateInput(input)
keys := GetVpcQuotaKeysFromCreateInput(ownerId, input)
pendingUsage.SetKeys(keys)
quotas.CancelPendingUsage(ctx, userCred, pendingUsage, pendingUsage, true)
}
@@ -1171,8 +1171,8 @@ func (self *SVpc) initWire(ctx context.Context, zone *SZone) (*SWire, error) {
return wire, nil
}
func GetVpcQuotaKeysFromCreateInput(input api.VpcCreateInput) quotas.SDomainRegionalCloudResourceKeys {
ownerId := &db.SOwnerId{DomainId: input.ProjectDomainId}
func GetVpcQuotaKeysFromCreateInput(owner mcclient.IIdentityProvider, input api.VpcCreateInput) quotas.SDomainRegionalCloudResourceKeys {
ownerId := &db.SOwnerId{DomainId: owner.GetProjectDomainId()}
var region *SCloudregion
if len(input.CloudregionId) > 0 {
region = CloudregionManager.FetchRegionById(input.CloudregionId)

View File

@@ -106,7 +106,7 @@ func (self *GuestDeployTask) OnDeployGuestComplete(ctx context.Context, obj db.I
}
if !_log {
// 如果 deploy 有其他事件,统一记在这里。
logclient.AddActionLogWithStartable(self, guest, "misc部署", "", self.UserCred, true)
logclient.AddActionLogWithStartable(self, guest, logclient.ACT_VM_DEPLOY, action, self.UserCred, true)
}
if self.HasParentTask() {

View File

@@ -20,6 +20,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/apis"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
@@ -33,6 +34,7 @@ type GuestStopTask struct {
func init() {
taskman.RegisterTask(GuestStopTask{})
taskman.RegisterTask(GuestStopAndFreezeTask{})
}
func (self *GuestStopTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
@@ -80,3 +82,40 @@ func (self *GuestStopTask) OnGuestStopTaskCompleteFailed(ctx context.Context, gu
self.SetStageFailed(ctx, reason)
logclient.AddActionLogWithStartable(self, guest, logclient.ACT_VM_STOP, reason.String(), self.UserCred, false)
}
type GuestStopAndFreezeTask struct {
SGuestBaseTask
}
func (self *GuestStopAndFreezeTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
guest := obj.(*models.SGuest)
self.SetStage("OnStopGuest", nil)
err := guest.StartGuestStopTask(ctx, self.UserCred, false, self.GetTaskId())
if err != nil {
self.OnStopGuestFailed(ctx, guest, jsonutils.NewString(err.Error()))
}
}
func (self *GuestStopAndFreezeTask) OnStopGuestFailed(ctx context.Context, guest *models.SGuest, reason jsonutils.JSONObject) {
db.OpsLog.LogEvent(guest, db.ACT_FREEZE_FAIL, reason.String(), self.UserCred)
self.SetStageFailed(ctx, reason)
}
func (self *GuestStopAndFreezeTask) OnStopGuest(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
self.SetStage("OnSyncStatus", nil)
guest.StartSyncstatus(ctx, self.UserCred, self.GetTaskId())
}
func (self *GuestStopAndFreezeTask) OnSyncStatus(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
_, err := guest.SVirtualResourceBase.PerformFreeze(ctx, self.UserCred, nil, apis.PerformFreezeInput{})
if err != nil {
self.OnStopGuestFailed(ctx, guest, jsonutils.NewString(err.Error()))
return
}
self.SetStageComplete(ctx, nil)
}
func (self *GuestStopAndFreezeTask) OnSyncStatusFailed(ctx context.Context, guest *models.SGuest, reason jsonutils.JSONObject) {
db.OpsLog.LogEvent(guest, db.ACT_FREEZE_FAIL, reason.String(), self.UserCred)
self.SetStageFailed(ctx, reason)
}

View File

@@ -68,8 +68,13 @@ func (self *GuestSyncstatusTask) OnGetStatusSucc(ctx context.Context, guest *mod
default:
statusStr = api.VM_UNKNOWN
}
blockJobsCount, err := body.Int("block_jobs_count")
if err != nil {
blockJobsCount = -1
}
input := apis.PerformStatusInput{
Status: statusStr,
Status: statusStr,
BlockJobsCount: int(blockJobsCount),
}
guest.PerformStatus(ctx, self.UserCred, nil, input)
self.SetStageComplete(ctx, nil)

View File

@@ -106,8 +106,12 @@ func guestActions(f actionFunc) appsrv.FilterHandler {
func getStatus(ctx context.Context, w http.ResponseWriter, r *http.Request) {
params, _, _ := appsrv.FetchEnv(ctx, w, r)
var status = guestman.GetGuestManager().Status(params["<sid>"])
appsrv.SendStruct(w, strDict{"status": status})
var status, blockJobsCount = guestman.GetGuestManager().StatusWithBlockJobsCount(params["<sid>"])
res := map[string]interface{}{
"status": status,
"block_jobs_count": blockJobsCount,
}
appsrv.SendStruct(w, res)
}
func cpusetBalance(ctx context.Context, w http.ResponseWriter, r *http.Request) {

View File

@@ -475,6 +475,19 @@ func (m *SGuestManager) Status(sid string) string {
return status
}
func (m *SGuestManager) StatusWithBlockJobsCount(sid string) (string, int) {
status := m.GetStatus(sid)
blockJobsCount := 0
if status == GUEST_RUNNING {
guest, _ := m.GetServer(sid)
if guest.Monitor == nil && !guest.IsStopping() {
guest.StartMonitor(context.Background())
}
blockJobsCount = guest.BlockJobsCount()
}
return status, blockJobsCount
}
func (m *SGuestManager) GetStatus(sid string) string {
if guest, ok := m.GetServer(sid); ok {
if guest.IsRunning() && guest.Monitor != nil && guest.IsMaster() {

View File

@@ -969,6 +969,7 @@ func (host *SHost) CloneVM(ctx context.Context, from *SVirtualMachine, ds *SData
Device: dev,
})
}
nicIndex += 1
}
}

View File

@@ -531,6 +531,8 @@ func (rm *SReceiverManager) FetchOwnerId(ctx context.Context, data jsonutils.JSO
return nil, errors.Wrap(err, "UserCacheManager.FetchUserByIdOrName")
}
ownerId := db.SOwnerId{
DomainId: u.DomainId,
Domain: u.Domain,
UserDomain: u.Domain,
UserDomainId: u.DomainId,
UserId: u.Id,

View File

@@ -178,6 +178,7 @@ func FileGetContents(file string) (string, error) {
func GetFsFormat(diskPath string) string {
ret, err := procutils.NewCommand("blkid", "-o", "value", "-s", "TYPE", diskPath).Output()
if err != nil {
log.Errorf("failed exec blkid of dev %s: %s, %s", diskPath, err, ret)
return ""
}
var res string