diff --git a/pkg/apis/compute/guests.go b/pkg/apis/compute/guests.go index 92e83d9b58..fe19660a84 100644 --- a/pkg/apis/compute/guests.go +++ b/pkg/apis/compute/guests.go @@ -763,3 +763,21 @@ func (o ServerDelExtraOptionInput) Validate() error { } return nil } + +type ServerSnapshotAndCloneInput struct { + Name string + GenerateName string + Count int + AutoStart bool + AutoDeleteInstanceSnapshot bool +} + +func (o *ServerSnapshotAndCloneInput) Validate() error { + if len(o.Name) == 0 { + return httperrors.NewMissingParameterError("name") + } + if o.Count <= 1 { + o.Count = 1 + } + return nil +} diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index a739cda0cd..738f7fa39a 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -4790,29 +4790,23 @@ func (self *SGuest) StartSnapshotResetTask(ctx context.Context, userCred mcclien } func (self *SGuest) PerformSnapshotAndClone( - ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject, + ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.ServerSnapshotAndCloneInput, ) (jsonutils.JSONObject, error) { - newlyGuestName, err := data.GetString("name") + err := input.Validate() if err != nil { - return nil, httperrors.NewMissingParameterError("name") - } - count, err := data.Int("count") - if err != nil { - count = 1 - } else if count <= 0 { - return nil, httperrors.NewInputParameterError("count must > 0") + return nil, err } lockman.LockRawObject(ctx, InstanceSnapshotManager.Keyword(), "name") defer lockman.ReleaseRawObject(ctx, InstanceSnapshotManager.Keyword(), "name") // validate create instance snapshot and set snapshot pending usage - snapshotUsage, err := self.validateCreateInstanceSnapshot(ctx, userCred, query, data) + snapshotUsage, err := self.validateCreateInstanceSnapshot(ctx, userCred, query, jsonutils.Marshal(input)) if err != nil { return nil, err } // set guest pending usage - pendingUsage, pendingRegionUsage, err := self.getGuestUsage(int(count)) + pendingUsage, pendingRegionUsage, err := self.getGuestUsage(input.Count) keys, err := self.GetQuotaKeys() if err != nil { quotas.CancelPendingUsage(ctx, userCred, snapshotUsage, snapshotUsage, false) @@ -4841,7 +4835,7 @@ func (self *SGuest) PerformSnapshotAndClone( pendingRegionUsage.Snapshot = snapshotUsage.Snapshot instanceSnapshotName, err := db.GenerateName(ctx, InstanceSnapshotManager, self.GetOwnerId(), - fmt.Sprintf("%s-%s", newlyGuestName, rand.String(8))) + fmt.Sprintf("%s-%s", input.Name, rand.String(8))) if err != nil { quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage, false) quotas.CancelPendingUsage(ctx, userCred, &pendingRegionUsage, &pendingRegionUsage, false) @@ -4849,7 +4843,7 @@ func (self *SGuest) PerformSnapshotAndClone( } instanceSnapshot, err := InstanceSnapshotManager.CreateInstanceSnapshot( ctx, userCred, self, instanceSnapshotName, - jsonutils.QueryBoolean(data, "auto_delete_instance_snapshot", false)) + input.AutoDeleteInstanceSnapshot) if err != nil { quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage, false) quotas.CancelPendingUsage(ctx, userCred, &pendingRegionUsage, &pendingRegionUsage, false) @@ -4860,7 +4854,7 @@ func (self *SGuest) PerformSnapshotAndClone( } err = self.StartInstanceSnapshotAndCloneTask( - ctx, userCred, newlyGuestName, &pendingUsage, &pendingRegionUsage, instanceSnapshot, data.(*jsonutils.JSONDict)) + ctx, userCred, input.Name, &pendingUsage, &pendingRegionUsage, instanceSnapshot, jsonutils.Marshal(input).(*jsonutils.JSONDict)) if err != nil { quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage, false) quotas.CancelPendingUsage(ctx, userCred, &pendingRegionUsage, &pendingRegionUsage, false) @@ -4906,6 +4900,12 @@ func (manager *SGuestManager) CreateGuestFromInstanceSnapshot( return nil, nil, err } guest := iGuest.(*SGuest) + notes := map[string]string{ + "instance_snapshot_id": isp.Id, + "guest_id": isp.GuestId, + } + + logclient.AddActionLogWithContext(ctx, guest, logclient.ACT_VM_SNAPSHOT_AND_CLONE, notes, userCred, true) func() { lockman.LockObject(ctx, guest) defer lockman.ReleaseObject(ctx, guest) diff --git a/pkg/compute/tasks/guest_rebuild_root_task.go b/pkg/compute/tasks/guest_rebuild_root_task.go index 0397af3790..4f46210105 100644 --- a/pkg/compute/tasks/guest_rebuild_root_task.go +++ b/pkg/compute/tasks/guest_rebuild_root_task.go @@ -194,7 +194,14 @@ func (self *GuestRebuildRootTask) OnSyncStatusComplete(ctx context.Context, gues } else { self.SetStageComplete(ctx, nil) } - logclient.AddActionLogWithStartable(self, guest, logclient.ACT_VM_REBUILD, "", self.UserCred, true) + + oldImageId, _ := self.GetParams().GetString("origin_image_id") + imgId, _ := self.Params.GetString("image_id") + notes := map[string]interface{}{} + if oldImageId != imgId && len(oldImageId) > 0 { + notes["old image id"] = oldImageId + } + logclient.AddActionLogWithStartable(self, guest, logclient.ACT_VM_REBUILD, notes, self.UserCred, true) } func (self *GuestRebuildRootTask) OnGuestStartComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {