diff --git a/pkg/apis/compute/host.go b/pkg/apis/compute/host.go index 937e87bb23..c1b7049fd1 100644 --- a/pkg/apis/compute/host.go +++ b/pkg/apis/compute/host.go @@ -431,3 +431,8 @@ type HostUpdateInput struct { // 主机启动模式, 可能值位PXE和ISO BootMode string `json:"boot_mode"` } + +type HostOfflineInput struct { + UpdateHealthStatus *bool `json:"update_health_status"` + Reason string +} diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index 687f90b271..3e5e0ece3d 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -2399,6 +2399,11 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T var cpuChanged, memChanged bool confs := jsonutils.NewDict() + confs.Add(jsonutils.Marshal(map[string]interface{}{ + "instance_type": self.InstanceType, + "vcpu_count": self.VcpuCount, + "vmem_size": self.VmemSize, + }), "old") if len(input.InstanceType) > 0 { sku, err := ServerSkuManager.FetchSkuByNameAndProvider(input.InstanceType, self.GetDriver().GetProvider(), true) if err != nil { @@ -2563,6 +2568,7 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T if len(newDisks) > 0 { confs.Add(jsonutils.Marshal(newDisks), "create") } + logclient.AddActionLogWithContext(ctx, self, logclient.ACT_CHANGE_CONFIG, confs, userCred, true) self.StartChangeConfigTask(ctx, userCred, confs, "", pendingUsage) return nil, nil } diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index 2a36769c86..4fe13c93bf 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -3750,11 +3750,11 @@ func (self *SHost) StartSyncstatus(ctx context.Context, userCred mcclient.TokenC return nil } -func (self *SHost) PerformOffline(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { +func (self *SHost) PerformOffline(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.HostOfflineInput) (jsonutils.JSONObject, error) { if self.HostStatus != api.HOST_OFFLINE { _, err := self.SaveUpdates(func() error { self.HostStatus = api.HOST_OFFLINE - if jsonutils.QueryBoolean(data, "update_health_status", false) { + if input.UpdateHealthStatus != nil && *input.UpdateHealthStatus { self.EnableHealthCheck = false } // Note: update host status to unknown on host offline @@ -3768,8 +3768,8 @@ func (self *SHost) PerformOffline(ctx context.Context, userCred mcclient.TokenCr if hostHealthChecker != nil { hostHealthChecker.UnwatchHost(context.Background(), self.Id) } - db.OpsLog.LogEvent(self, db.ACT_OFFLINE, "", userCred) - logclient.AddActionLogWithContext(ctx, self, logclient.ACT_OFFLINE, nil, userCred, true) + db.OpsLog.LogEvent(self, db.ACT_OFFLINE, input.Reason, userCred) + logclient.AddActionLogWithContext(ctx, self, logclient.ACT_OFFLINE, map[string]string{"reason": input.Reason}, userCred, false) self.SyncAttachedStorageStatus() } return nil, nil @@ -5122,24 +5122,19 @@ func (manager *SHostManager) PingDetectionTask(ctx context.Context, userCred mcc q = q.Filter(sqlchemy.OR(sqlchemy.IsNull(q.Field("last_ping_at")), sqlchemy.LT(q.Field("last_ping_at"), deadline))) - rows, err := q.Rows() + hosts := []SHost{} + err := db.FetchModelObjects(manager, q, &hosts) if err != nil { - log.Errorln(err) return } - defer rows.Close() - data := jsonutils.NewDict() - data.Set("update_health_status", jsonutils.JSONFalse) - for rows.Next() { - var host = new(SHost) - q.Row2Struct(rows, host) - host.SetModelManager(manager, host) + updateHealthStatus := false + for i := range hosts { func() { - lockman.LockObject(ctx, host) - defer lockman.ReleaseObject(ctx, host) - host.PerformOffline(ctx, userCred, nil, data) - host.MarkGuestUnknown(userCred) + lockman.LockObject(ctx, &hosts[i]) + defer lockman.ReleaseObject(ctx, &hosts[i]) + hosts[i].PerformOffline(ctx, userCred, nil, &api.HostOfflineInput{UpdateHealthStatus: &updateHealthStatus, Reason: fmt.Sprintf("last ping detection at %s", deadline)}) + hosts[i].MarkGuestUnknown(userCred) }() } } @@ -5246,6 +5241,8 @@ func (host *SHost) OnHostDown(ctx context.Context, userCred mcclient.TokenCreden }); err != nil { log.Errorf("update host %s failed %s", host.Id, err) } + + logclient.AddActionLogWithContext(ctx, host, logclient.ACT_OFFLINE, map[string]string{"reason": "host down"}, userCred, false) host.SyncCleanSchedDescCache() host.switchWithBackup(ctx, userCred) host.migrateOnHostDown(ctx, userCred) diff --git a/pkg/hostman/hostinfo/hostinfo.go b/pkg/hostman/hostinfo/hostinfo.go index 624769266f..61152c8726 100644 --- a/pkg/hostman/hostinfo/hostinfo.go +++ b/pkg/hostman/hostinfo/hostinfo.go @@ -1186,7 +1186,7 @@ func (h *SHostInfo) onUpdateHostInfoSucc(hostbody jsonutils.JSONObject) { if memReserved, _ := hostbody.Int("mem_reserved"); memReserved == 0 { h.updateHostReservedMem() } else { - h.PutHostOffline() + h.PutHostOffline("") } } @@ -1214,11 +1214,14 @@ func (h *SHostInfo) getReservedMem() int { return reserved } -func (h *SHostInfo) PutHostOffline() { +func (h *SHostInfo) PutHostOffline(reason string) { data := jsonutils.NewDict() if options.HostOptions.EnableHealthChecker { data.Set("update_health_status", jsonutils.JSONTrue) } + if len(reason) > 0 { + data.Set("reason", jsonutils.NewString(reason)) + } _, err := modules.Hosts.PerformAction( h.GetSession(), h.HostId, "offline", data) if err != nil {