fix: 梳理磁盘reset条件

This commit is contained in:
Qu Xuan
2019-11-01 17:08:16 +08:00
parent e9156bea4a
commit cd32e03add
13 changed files with 107 additions and 75 deletions
+15
View File
@@ -15,10 +15,16 @@
package hostdrivers
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SAliyunHostDriver struct {
@@ -62,3 +68,12 @@ func (self *SAliyunHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb
}
return nil
}
func (self *SAliyunHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
for _, guest := range guests {
if !utils.IsInStringArray(guest.Status, []string{api.VM_RUNNING, api.VM_READY}) {
return nil, httperrors.NewBadGatewayError("Aliyun reset disk required guest status is running or read")
}
}
return data, nil
}
+8
View File
@@ -15,12 +15,16 @@
package hostdrivers
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SAwsHostDriver struct {
@@ -62,3 +66,7 @@ func (self *SAwsHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb in
}
return nil
}
func (self *SAwsHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return nil, httperrors.NewBadRequestError("Aws not support reset disk, you can create new disk with snapshot")
}
+4
View File
@@ -52,6 +52,10 @@ func (self *SAzureHostDriver) ValidateUpdateDisk(ctx context.Context, userCred m
return data, nil
}
func (self *SAzureHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return nil, httperrors.NewBadRequestError("Azure not support reset disk, you can create new disk with snapshot")
}
func (self *SAzureHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb int) error {
if utils.IsInStringArray(storage.StorageType, []string{api.STORAGE_STANDARD_LRS, api.STORAGE_STANDARDSSD_LRS, api.STORAGE_PREMIUM_LRS}) {
if sizeGb < 1 || sizeGb > 4095 {
+2 -2
View File
@@ -38,8 +38,8 @@ func (self *SBaseHostDriver) ValidateUpdateDisk(ctx context.Context, userCred mc
return data, nil
}
func (self *SBaseHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return data, nil
func (self *SBaseHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return nil, httperrors.NewNotImplementedError("Not Implement ValidateResetDisk")
}
func (self *SBaseHostDriver) ValidateAttachStorage(ctx context.Context, userCred mcclient.TokenCredential, host *models.SHost, storage *models.SStorage, data *jsonutils.JSONDict) error {
+1 -21
View File
@@ -57,29 +57,9 @@ func (self *SHuaweiHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb
return nil
}
func (self *SHuaweiHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
if disk.Status != api.DISK_READY {
return nil, httperrors.NewInvalidStatusError("Cannot reset disk in status %s", disk.Status)
}
snapshotId, err := data.GetString("snapshot_id")
if err != nil {
return nil, httperrors.NewMissingParameterError("snapshot_id")
}
guests := disk.GetGuests()
func (self *SHuaweiHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
if len(guests) >= 1 {
return nil, httperrors.NewBadRequestError("Disk must be dettached")
}
iSnapshot, err := models.SnapshotManager.FetchById(snapshotId)
if err != nil {
return nil, httperrors.NewNotFoundError("Snapshot %s not found", snapshotId)
}
snapshot := iSnapshot.(*models.SSnapshot)
if snapshot.Status != api.SNAPSHOT_READY {
return nil, httperrors.NewBadRequestError("Cannot reset disk with snapshot in status %s", snapshot.Status)
} else if snapshot.DiskId != disk.Id {
return nil, httperrors.NewBadRequestError("Cannot reset disk %s,Snapshot is belong to disk %s", disk.Id, snapshot.DiskId)
}
return data, nil
}
+1 -18
View File
@@ -352,15 +352,7 @@ func (self *SKVMHostDriver) RequestDeleteSnapshotsWithStorage(ctx context.Contex
return err
}
func (self *SKVMHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
if disk.Status != api.DISK_READY {
return nil, httperrors.NewInvalidStatusError("Cannot reset disk in status %s", disk.Status)
}
snapshotId, err := data.GetString("snapshot_id")
if err != nil {
return nil, httperrors.NewMissingParameterError("snapshot_id")
}
guests := disk.GetGuests()
func (self *SKVMHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
if len(guests) > 1 {
return nil, httperrors.NewBadRequestError("Disk attach muti guests")
} else if len(guests) == 1 {
@@ -371,15 +363,6 @@ func (self *SKVMHostDriver) ValidateResetDisk(ctx context.Context, userCred mccl
return nil, httperrors.NewBadRequestError("Disk dosen't attach guest")
}
iSnapshot, err := models.SnapshotManager.FetchById(snapshotId)
if err != nil {
return nil, httperrors.NewNotFoundError("Snapshot %s not found", snapshotId)
}
snapshot := iSnapshot.(*models.SSnapshot)
if snapshot.Status != api.SNAPSHOT_READY {
return nil, httperrors.NewBadRequestError("Cannot reset disk with snapshot in status %s", snapshot.Status)
}
return data, nil
}
+1 -29
View File
@@ -33,7 +33,6 @@ import (
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
@@ -301,34 +300,7 @@ func (self *SManagedVirtualizationHostDriver) RequestDeallocateDiskOnHost(ctx co
return nil
}
func (self *SManagedVirtualizationHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
if disk.Status != api.DISK_READY {
return nil, httperrors.NewInvalidStatusError("Cannot reset disk in status %s", disk.Status)
}
snapshotId, err := data.GetString("snapshot_id")
if err != nil {
return nil, httperrors.NewMissingParameterError("snapshot_id")
}
guests := disk.GetGuests()
if len(guests) > 1 {
return nil, httperrors.NewBadRequestError("Disk attach muti guests")
} else if len(guests) == 1 {
if guests[0].Status != api.VM_READY {
return nil, httperrors.NewServerStatusError("Disk attached guest status must be ready")
}
} else {
return nil, httperrors.NewBadRequestError("Disk dosen't attach guest")
}
iSnapshot, err := models.SnapshotManager.FetchById(snapshotId)
if err != nil {
return nil, httperrors.NewNotFoundError("Snapshot %s not found", snapshotId)
}
snapshot := iSnapshot.(*models.SSnapshot)
if snapshot.Status != api.SNAPSHOT_READY {
return nil, httperrors.NewBadRequestError("Cannot reset disk with snapshot in status %s", snapshot.Status)
}
func (self *SManagedVirtualizationHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return data, nil
}
+10
View File
@@ -15,8 +15,14 @@
package hostdrivers
import (
"context"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SOpenStackHostDriver struct {
@@ -43,3 +49,7 @@ func (self *SOpenStackHostDriver) ValidateDiskSize(storage *models.SStorage, siz
func (driver *SOpenStackHostDriver) GetStoragecacheQuota(host *models.SHost) int {
return 100
}
func (self *SOpenStackHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return nil, httperrors.NewBadRequestError("OpenStack not support reset disk, you can create new disk with snapshot")
}
+13
View File
@@ -18,10 +18,14 @@ import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SQcloudHostDriver struct {
@@ -63,6 +67,15 @@ func (self *SQcloudHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb
return nil
}
func (self *SQcloudHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
for _, guest := range guests {
if !utils.IsInStringArray(guest.Status, []string{api.VM_RUNNING, api.VM_READY}) {
return nil, httperrors.NewBadGatewayError("Qcloud reset disk required guest status is running or read")
}
}
return data, nil
}
func (self *SQcloudHostDriver) RequestDeleteSnapshotWithStorage(ctx context.Context, host *models.SHost, snapshot *models.SSnapshot, task taskman.ITask) error {
return httperrors.NewNotImplementedError("not implement")
}
+15
View File
@@ -15,10 +15,15 @@
package hostdrivers
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SUCloudHostDriver struct {
@@ -65,3 +70,13 @@ func (self *SUCloudHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb
return nil
}
func (self *SUCloudHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
if len(guests) > 0 {
return nil, httperrors.NewInputParameterError("Ucloud reset disk operation required disk not be attached")
}
if disk.DiskType != api.DISK_TYPE_DATA {
return nil, httperrors.NewInputParameterError("Ucloud only support data disk reset operation")
}
return data, nil
}
+15
View File
@@ -15,8 +15,14 @@
package hostdrivers
import (
"context"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SZStackHostDriver struct {
@@ -39,3 +45,12 @@ func (self *SZStackHostDriver) GetHypervisor() string {
func (self *SZStackHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb int) error {
return nil
}
func (self *SZStackHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
for _, guest := range guests {
if guest.Status != api.VM_READY {
return nil, httperrors.NewBadRequestError("ZStack reset disk operation requried guest status is ready")
}
}
return data, nil
}
+21 -4
View File
@@ -41,6 +41,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
@@ -702,6 +703,9 @@ func (self *SDisk) AllowPerformDiskReset(ctx context.Context, userCred mcclient.
}
func (self *SDisk) PerformDiskReset(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if !utils.IsInStringArray(self.Status, []string{api.DISK_READY}) {
return nil, httperrors.NewInputParameterError("Cannot reset disk in status %s", self.Status)
}
storage := self.GetStorage()
if storage == nil {
return nil, httperrors.NewNotFoundError("failed to find storage for disk %s", self.Name)
@@ -712,15 +716,28 @@ func (self *SDisk) PerformDiskReset(ctx context.Context, userCred mcclient.Token
return nil, httperrors.NewNotFoundError("failed to find host for storage %s with disk %s", storage.Name, self.Name)
}
data, err := host.GetHostDriver().ValidateResetDisk(ctx, userCred, self, data.(*jsonutils.JSONDict))
snapshotV := validators.NewModelIdOrNameValidator("snapshot", "snapshot", userCred)
err := snapshotV.Validate(data.(*jsonutils.JSONDict))
if err != nil {
return nil, err
}
snapshot := snapshotV.Model.(*SSnapshot)
if snapshot.Status != api.SNAPSHOT_READY {
return nil, httperrors.NewBadRequestError("Cannot reset disk with snapshot in status %s", snapshot.Status)
}
if snapshot.DiskId != self.Id {
return nil, httperrors.NewBadRequestError("Cannot reset disk %s(%s),Snapshot is belong to disk %s", self.Name, self.Id, snapshot.DiskId)
}
guests := self.GetGuests()
data, err = host.GetHostDriver().ValidateResetDisk(ctx, userCred, self, snapshot, guests, data.(*jsonutils.JSONDict))
if err != nil {
return nil, err
}
autoStart := jsonutils.QueryBoolean(data, "auto_start", false)
snapshotId, _ := data.GetString("snapshot_id")
guests := self.GetGuests()
return nil, self.StartResetDisk(ctx, userCred, snapshotId, autoStart, &guests[0], "")
return nil, self.StartResetDisk(ctx, userCred, snapshot.Id, autoStart, &guests[0], "")
}
func (self *SDisk) StartResetDisk(
+1 -1
View File
@@ -33,7 +33,7 @@ type IHostDriver interface {
RequestUncacheImage(ctx context.Context, host *SHost, storageCache *SStoragecache, task taskman.ITask) error
ValidateUpdateDisk(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, snapshot *SSnapshot, guests []SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
ValidateDiskSize(storage *SStorage, sizeGb int) error
RequestPrepareSaveDiskOnHost(ctx context.Context, host *SHost, disk *SDisk, imageId string, task taskman.ITask) error
RequestSaveUploadImageOnHost(ctx context.Context, host *SHost, disk *SDisk, imageId string, task taskman.ITask, data jsonutils.JSONObject) error