mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
fix: 避免创建vmware磁盘快照
This commit is contained in:
@@ -19,9 +19,8 @@ import "yunion.io/x/onecloud/pkg/apis"
|
||||
type SSnapshotCreateInput struct {
|
||||
apis.Meta
|
||||
|
||||
Name string `json:"name"`
|
||||
ProjectId string `json:"project_id"`
|
||||
DomainId string `json:"domain_id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
|
||||
DiskId string `json:"disk_id"`
|
||||
StorageId string `json:"storage_id"`
|
||||
|
||||
@@ -978,6 +978,14 @@ func (self *SDisk) GetStorage() *SStorage {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SDisk) GetRegionDriver() (IRegionDriver, error) {
|
||||
storage := self.GetStorage()
|
||||
if storage == nil {
|
||||
return nil, fmt.Errorf("failed to found storage for disk %s(%s)", self.Name, self.Id)
|
||||
}
|
||||
return storage.GetRegionDriver()
|
||||
}
|
||||
|
||||
func (self *SDisk) GetBackupStorage() *SStorage {
|
||||
if len(self.BackupStorageId) == 0 {
|
||||
return nil
|
||||
|
||||
@@ -51,6 +51,19 @@ func (self *SManagedResourceBase) GetCloudaccount() *SCloudaccount {
|
||||
return cp.GetCloudaccount()
|
||||
}
|
||||
|
||||
func (self *SManagedResourceBase) GetRegionDriver() (IRegionDriver, error) {
|
||||
cloudprovider := self.GetCloudprovider()
|
||||
provider := api.CLOUD_PROVIDER_ONECLOUD
|
||||
if cloudprovider != nil {
|
||||
provider = cloudprovider.Provider
|
||||
}
|
||||
driver := GetRegionDriver(provider)
|
||||
if driver == nil {
|
||||
return nil, fmt.Errorf("failed to get %s region drivder", provider)
|
||||
}
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
func (self *SManagedResourceBase) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
provider := self.GetCloudprovider()
|
||||
if provider == nil {
|
||||
|
||||
@@ -97,7 +97,7 @@ type IRegionDriver interface {
|
||||
|
||||
// Region Driver Snapshot Apis
|
||||
ValidateSnapshotDelete(ctx context.Context, snapshot *SSnapshot) error
|
||||
ValidateSnapshotCreate(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, data *jsonutils.JSONDict) error
|
||||
ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, storage *SStorage, input *api.SSnapshotCreateInput) error
|
||||
RequestCreateSnapshot(ctx context.Context, snapshot *SSnapshot, task taskman.ITask) error
|
||||
RequestDeleteSnapshot(ctx context.Context, snapshot *SSnapshot, task taskman.ITask) error
|
||||
SnapshotIsOutOfChain(disk *SDisk) bool
|
||||
|
||||
@@ -84,27 +84,6 @@ func init() {
|
||||
SnapshotManager.SetVirtualObject(SnapshotManager)
|
||||
}
|
||||
|
||||
func ValidateSnapshotName(name string, owner mcclient.IIdentityProvider) error {
|
||||
q := SnapshotManager.Query()
|
||||
q = SnapshotManager.FilterByName(q, name)
|
||||
q = SnapshotManager.FilterByOwner(q, owner, SnapshotManager.NamespaceScope())
|
||||
q = SnapshotManager.FilterBySystemAttributes(q, nil, nil, SnapshotManager.ResourceScope())
|
||||
cnt, err := q.CountWithError()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cnt != 0 {
|
||||
return httperrors.NewConflictError("Name %s conflict", name)
|
||||
}
|
||||
if !('A' <= name[0] && name[0] <= 'Z' || 'a' <= name[0] && name[0] <= 'z') {
|
||||
return httperrors.NewBadRequestError("Name must start with letter")
|
||||
}
|
||||
if len(name) < 2 || len(name) > 128 {
|
||||
return httperrors.NewBadRequestError("Snapshot name length must within 2~128")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SSnapshotManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return true
|
||||
}
|
||||
@@ -236,21 +215,40 @@ func (self *SSnapshot) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
|
||||
|
||||
func (manager *SSnapshotManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
diskV := validators.NewModelIdOrNameValidator("disk", "disk", ownerId)
|
||||
if err := diskV.Validate(data); err != nil {
|
||||
err := diskV.Validate(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
disk := diskV.Model.(*SDisk)
|
||||
|
||||
snapshotName, err := data.GetString("name")
|
||||
if err != nil {
|
||||
return nil, httperrors.NewMissingParameterError("name")
|
||||
input := &api.SSnapshotCreateInput{
|
||||
DiskType: disk.DiskType,
|
||||
Size: disk.DiskSize,
|
||||
}
|
||||
err = ValidateSnapshotName(snapshotName, ownerId)
|
||||
|
||||
err = data.Unmarshal(input)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("failed to unmarshal input params: %v", err)
|
||||
}
|
||||
|
||||
storage := disk.GetStorage()
|
||||
if len(disk.ExternalId) == 0 {
|
||||
input.StorageId = disk.StorageId
|
||||
}
|
||||
input.ManagerId = storage.ManagerId
|
||||
region := storage.GetRegion()
|
||||
if region == nil {
|
||||
return nil, httperrors.NewInputParameterError("failed to found region for disk's storage %s(%s)", storage.Name, storage.Id)
|
||||
}
|
||||
input.CloudregionId = region.Id
|
||||
|
||||
driver, err := storage.GetRegionDriver()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
input.OutOfChain = driver.SnapshotIsOutOfChain(disk)
|
||||
|
||||
err = disk.GetStorage().GetRegion().GetDriver().ValidateSnapshotCreate(ctx, userCred, disk, data)
|
||||
err = driver.ValidateCreateSnapshotData(ctx, userCred, disk, storage, input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -262,26 +260,6 @@ func (manager *SSnapshotManager) ValidateCreateData(ctx context.Context, userCre
|
||||
return nil, httperrors.NewOutOfQuotaError("Check set pending quota error %s", err)
|
||||
}
|
||||
|
||||
input := &api.SSnapshotCreateInput{}
|
||||
input.Name = snapshotName
|
||||
input.ProjectId = ownerId.GetProjectId()
|
||||
input.DomainId = ownerId.GetProjectDomainId()
|
||||
input.DiskId = disk.Id
|
||||
input.CreatedBy = api.SNAPSHOT_MANUAL
|
||||
input.Size = disk.DiskSize
|
||||
input.DiskType = disk.DiskType
|
||||
input.OutOfChain = disk.GetStorage().GetRegion().GetDriver().SnapshotIsOutOfChain(disk)
|
||||
storage := disk.GetStorage()
|
||||
if len(disk.ExternalId) == 0 {
|
||||
input.StorageId = disk.StorageId
|
||||
}
|
||||
if cloudregion := storage.GetRegion(); cloudregion != nil {
|
||||
input.CloudregionId = cloudregion.GetId()
|
||||
}
|
||||
provider := disk.GetCloudprovider()
|
||||
if provider != nil {
|
||||
input.ManagerId = provider.Id
|
||||
}
|
||||
return input.JSON(input), nil
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
@@ -34,7 +35,7 @@ type IStorageDriver interface {
|
||||
PostCreate(ctx context.Context, userCred mcclient.TokenCredential, storage *SStorage, data jsonutils.JSONObject)
|
||||
|
||||
ValidateSnapshotDelete(ctx context.Context, snapshot *SSnapshot) error
|
||||
ValidateSnapshotCreate(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, data *jsonutils.JSONDict) error
|
||||
ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, input *api.SSnapshotCreateInput) error
|
||||
RequestCreateSnapshot(ctx context.Context, snapshot *SSnapshot, task taskman.ITask) error
|
||||
RequestDeleteSnapshot(ctx context.Context, snapshot *SSnapshot, task taskman.ITask) error
|
||||
SnapshotIsOutOfChain(disk *SDisk) bool
|
||||
|
||||
@@ -845,9 +845,8 @@ func (self *SAliyunRegionDriver) ValidateCreateSnapshopolicyDiskData(ctx context
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAliyunRegionDriver) ValidateSnapshotCreate(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) error {
|
||||
name, _ := data.GetString("name")
|
||||
if strings.HasPrefix(name, "auto") || strings.HasPrefix(name, "http://") || strings.HasPrefix(name, "https://") {
|
||||
func (self *SAliyunRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SSnapshotCreateInput) error {
|
||||
if strings.HasPrefix(input.Name, "auto") || strings.HasPrefix(input.Name, "http://") || strings.HasPrefix(input.Name, "https://") {
|
||||
return httperrors.NewBadRequestError(
|
||||
"Snapshot for %s name can't start with auto, http:// or https://", self.GetProvider())
|
||||
}
|
||||
|
||||
@@ -149,8 +149,8 @@ func (self *SBaseRegionDriver) RequestDeleteSnapshot(ctx context.Context, snapsh
|
||||
return fmt.Errorf("Not Implement RequestDeleteSnapshot")
|
||||
}
|
||||
|
||||
func (self *SBaseRegionDriver) ValidateSnapshotCreate(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) error {
|
||||
return fmt.Errorf("Not Implement ValidateSnapshotCreate")
|
||||
func (self *SBaseRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SSnapshotCreateInput) error {
|
||||
return fmt.Errorf("Not Implement ValidateCreateSnapshotData")
|
||||
}
|
||||
|
||||
func (self *SBaseRegionDriver) RequestCreateSnapshot(ctx context.Context, snapshot *models.SSnapshot, task taskman.ITask) error {
|
||||
|
||||
@@ -51,6 +51,6 @@ func (self *SEsxiRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx con
|
||||
return nil, httperrors.NewNotImplementedError("%s does not support creating loadbalancer certificate", self.GetProvider())
|
||||
}
|
||||
|
||||
func (self *SEsxiRegionDriver) ValidateSnapshotCreate(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) error {
|
||||
func (self *SEsxiRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SSnapshotCreateInput) error {
|
||||
return fmt.Errorf("%s does not support creating snapshot", self.GetProvider())
|
||||
}
|
||||
|
||||
@@ -732,9 +732,12 @@ func (self *SKVMRegionDriver) RequestDeleteSnapshot(ctx context.Context, snapsho
|
||||
return models.GetStorageDriver(storage.StorageType).RequestDeleteSnapshot(ctx, snapshot, task)
|
||||
}
|
||||
|
||||
func (self *SKVMRegionDriver) ValidateSnapshotCreate(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) error {
|
||||
storage := disk.GetStorage()
|
||||
return models.GetStorageDriver(storage.StorageType).ValidateSnapshotCreate(ctx, userCred, disk, data)
|
||||
func (self *SKVMRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SSnapshotCreateInput) error {
|
||||
host := storage.GetMasterHost()
|
||||
if host == nil {
|
||||
return fmt.Errorf("failed to get master host, maybe the host is offline")
|
||||
}
|
||||
return models.GetStorageDriver(storage.StorageType).ValidateCreateSnapshotData(ctx, userCred, disk, input)
|
||||
}
|
||||
|
||||
func (self *SKVMRegionDriver) RequestCreateSnapshot(ctx context.Context, snapshot *models.SSnapshot, task taskman.ITask) error {
|
||||
|
||||
@@ -1193,7 +1193,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestDeleteSnapshot(ctx contex
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SManagedVirtualizationRegionDriver) ValidateSnapshotCreate(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) error {
|
||||
func (self *SManagedVirtualizationRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SSnapshotCreateInput) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ func (self *SBaseStorageDriver) ValidateSnapshotDelete(ctx context.Context, snap
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaseStorageDriver) ValidateSnapshotCreate(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) error {
|
||||
func (self *SBaseStorageDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, input *api.SSnapshotCreateInput) error {
|
||||
guests := disk.GetGuests()
|
||||
if len(guests) != 1 {
|
||||
return httperrors.NewBadRequestError("Disk %s dosen't attach guest ?", disk.Id)
|
||||
|
||||
@@ -179,7 +179,7 @@ func (self *SRbdStorageDriver) ValidateSnapshotDelete(ctx context.Context, snaps
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRbdStorageDriver) ValidateSnapshotCreate(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) error {
|
||||
func (self *SRbdStorageDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, input *api.SSnapshotCreateInput) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
|
||||
type SnapshotCreateTask struct {
|
||||
@@ -41,12 +42,14 @@ func (self *SnapshotCreateTask) OnInit(ctx context.Context, obj db.IStandaloneMo
|
||||
func (self *SnapshotCreateTask) TaskFailed(ctx context.Context, snapshot *models.SSnapshot, reason string) {
|
||||
snapshot.SetStatus(self.UserCred, api.SNAPSHOT_FAILED, reason)
|
||||
db.OpsLog.LogEvent(snapshot, db.ACT_SNAPSHOT_FAIL, reason, self.UserCred)
|
||||
logclient.AddActionLogWithStartable(self, snapshot, logclient.ACT_CREATE, reason, self.UserCred, false)
|
||||
self.SetStageFailed(ctx, reason)
|
||||
}
|
||||
|
||||
func (self *SnapshotCreateTask) TaskComplete(ctx context.Context, snapshot *models.SSnapshot, data jsonutils.JSONObject) {
|
||||
snapshot.SetStatus(self.UserCred, api.SNAPSHOT_READY, "")
|
||||
db.OpsLog.LogEvent(snapshot, db.ACT_SNAPSHOT_DONE, "", self.UserCred)
|
||||
logclient.AddActionLogWithStartable(self, snapshot, logclient.ACT_CREATE, "", self.UserCred, true)
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user