diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index 2ca24c78db..e347a23555 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -1587,7 +1587,9 @@ func (self *SGuest) PerformDetachIsolatedDevice(ctx context.Context, userCred mc return nil, httperrors.NewBadRequestError(msg) } err = self.startDetachIsolateDevice(ctx, userCred, device) - return nil, err + if err != nil { + return nil, err + } } else { devs := self.GetIsolatedDevices() host := self.GetHost() @@ -1599,8 +1601,11 @@ func (self *SGuest) PerformDetachIsolatedDevice(ctx context.Context, userCred mc return nil, err } } - return nil, nil } + if jsonutils.QueryBoolean(data, "auto_start", false) { + return self.PerformStart(ctx, userCred, query, data) + } + return nil, nil } func (self *SGuest) startDetachIsolateDevice(ctx context.Context, userCred mcclient.TokenCredential, device string) error { @@ -1648,10 +1653,10 @@ func (self *SGuest) PerformAttachIsolatedDevice(ctx context.Context, userCred mc logclient.AddActionLogWithContext(ctx, self, logclient.ACT_GUEST_ATTACH_ISOLATED_DEVICE, msg, userCred, false) return nil, httperrors.NewInvalidStatusError(msg) } + var err error if data.Contains("device") { device, _ := data.GetString("device") - err := self.startAttachIsolatedDevice(ctx, userCred, device) - return nil, err + err = self.startAttachIsolatedDevice(ctx, userCred, device) } else if data.Contains("model") { vmodel, _ := data.GetString("model") var count int64 = 1 @@ -1661,10 +1666,18 @@ func (self *SGuest) PerformAttachIsolatedDevice(ctx context.Context, userCred mc if count < 1 { return nil, httperrors.NewBadRequestError("guest attach gpu count must > 0") } - err := self.startAttachIsolatedDevices(ctx, userCred, vmodel, int(count)) + err = self.startAttachIsolatedDevices(ctx, userCred, vmodel, int(count)) + } else { + return nil, httperrors.NewMissingParameterError("device||model") + } + + if err != nil { return nil, err } - return nil, httperrors.NewMissingParameterError("device||model") + if jsonutils.QueryBoolean(data, "auto_start", false) { + return self.PerformStart(ctx, userCred, query, data) + } + return nil, nil } func (self *SGuest) startAttachIsolatedDevices(ctx context.Context, userCred mcclient.TokenCredential, gpuModel string, count int) error { @@ -1778,6 +1791,9 @@ func (self *SGuest) PerformSetIsolatedDevice(ctx context.Context, userCred mccli return nil, err } } + if jsonutils.QueryBoolean(data, "auto_start", false) { + return self.PerformStart(ctx, userCred, query, data) + } return nil, nil } @@ -3933,12 +3949,20 @@ func (self *SGuest) validateCreateInstanceSnapshot( return nil, httperrors.NewInvalidStatusError("guest can't do snapshot in status %s", self.Status) } + var name string ownerId := self.GetOwnerId() dataDict := data.(*jsonutils.JSONDict) - name, err := dataDict.GetString("name") - if err != nil || len(name) == 0 { + nameHint, err := dataDict.GetString("generate_name") + if err == nil { + name, err = db.GenerateName(InstanceSnapshotManager, ownerId, nameHint) + if err != nil { + return nil, err + } + dataDict.Set("name", jsonutils.NewString(name)) + } else if name, err = dataDict.GetString("name"); err != nil { return nil, httperrors.NewMissingParameterError("name") } + err = db.NewNameValidator(InstanceSnapshotManager, ownerId, name, "") if err != nil { return nil, err @@ -3971,12 +3995,14 @@ func (self *SGuest) validateCreateInstanceSnapshot( func (self *SGuest) PerformInstanceSnapshot( ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject, ) (jsonutils.JSONObject, error) { + ownerId := self.GetOwnerId() + lockman.LockClass(ctx, InstanceSnapshotManager, ownerId.GetProjectId()) + defer lockman.ReleaseClass(ctx, InstanceSnapshotManager, ownerId.GetProjectId()) pendingUsage, err := self.validateCreateInstanceSnapshot(ctx, userCred, query, data) if err != nil { return nil, err } name, _ := data.GetString("name") - ownerId := self.GetOwnerId() instanceSnapshot, err := InstanceSnapshotManager.CreateInstanceSnapshot(ctx, ownerId, self, name) if err != nil { QuotaManager.CancelPendingUsage( @@ -4079,7 +4105,7 @@ func (self *SGuest) PerformSnapshotAndClone( self.GetQuotaPlatformID(), pendingUsage, pendingUsage) return nil, httperrors.NewInternalServerError("Generate snapshot name failed %s", err) } - instanceSnapshot, err := InstanceSnapshotManager.CreateInstancSnapshot(ctx, self.GetOwnerId(), self, instanceSnapshotName) + instanceSnapshot, err := InstanceSnapshotManager.CreateInstanceSnapshot(ctx, self.GetOwnerId(), self, instanceSnapshotName) if err != nil { QuotaManager.CancelPendingUsage( ctx, userCred, rbacutils.ScopeProject, self.GetOwnerId(),