mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-30 18:23:35 +08:00
feat(region,host): create disk from existing path (#14677)
Server create disk from existing path. Usage: climc server-create --disk storage=<storage>:existing_path=<path> ... climc disk-create storage=<storage>:existing_path=<path> DISKNAME Signed-off-by: wanyaoqi <d3lx.yq@gmail.com>
This commit is contained in:
@@ -212,6 +212,9 @@ type DiskConfig struct {
|
||||
|
||||
//swagger:ignore
|
||||
DiskId string `json:"disk_id"`
|
||||
|
||||
//swagger:ignore
|
||||
ExistingPath string `json:"existing_path"`
|
||||
}
|
||||
|
||||
type IsolatedDeviceConfig struct {
|
||||
|
||||
@@ -296,6 +296,7 @@ type DiskAllocateInput struct {
|
||||
Protocol string
|
||||
SrcDiskId string
|
||||
SrcPool string
|
||||
ExistingPath string
|
||||
|
||||
// vmware
|
||||
HostIp string
|
||||
|
||||
@@ -63,3 +63,5 @@ const (
|
||||
DISK_NOT_EXIST = "not_exist"
|
||||
DISK_EXIST = "exist"
|
||||
)
|
||||
|
||||
const DISK_META_EXISTING_PATH = "disk_existing_path"
|
||||
|
||||
@@ -185,6 +185,8 @@ func ParseDiskConfig(diskStr string, idx int) (*compute.DiskConfig, error) {
|
||||
diskConfig.Storage = str
|
||||
case "image", "image_id":
|
||||
diskConfig.ImageId = str
|
||||
case "existing_path":
|
||||
diskConfig.ExistingPath = str
|
||||
default:
|
||||
return nil, errors.Errorf("invalid disk description %s", p)
|
||||
}
|
||||
|
||||
@@ -461,12 +461,17 @@ func (manager *SDiskManager) ValidateCreateData(ctx context.Context, userCred mc
|
||||
if err != nil {
|
||||
return input, err
|
||||
}
|
||||
if input.ExistingPath != "" && input.Storage == "" {
|
||||
return input, httperrors.NewInputParameterError("disk create from existing disk must give storage")
|
||||
}
|
||||
|
||||
input.ProjectId = ownerId.GetProjectId()
|
||||
input.ProjectDomainId = ownerId.GetProjectDomainId()
|
||||
|
||||
var quotaKey quotas.IQuotaKeys
|
||||
|
||||
storageID := input.Storage
|
||||
|
||||
if storageID != "" {
|
||||
storageObj, err := StorageManager.FetchByIdOrName(nil, storageID)
|
||||
if err != nil {
|
||||
@@ -558,6 +563,13 @@ func (manager *SDiskManager) validateDiskOnStorage(diskConfig *api.DiskConfig, s
|
||||
if storage.StorageType != diskConfig.Backend {
|
||||
return httperrors.NewInputParameterError("Storage type[%s] not match backend %s", storage.StorageType, diskConfig.Backend)
|
||||
}
|
||||
if diskConfig.ExistingPath != "" {
|
||||
if !utils.IsInStringArray(storage.StorageType, api.FIEL_STORAGE) {
|
||||
return httperrors.NewInputParameterError(
|
||||
"Disk create from existing path, unsupport storage type %s", storage.StorageType)
|
||||
}
|
||||
}
|
||||
|
||||
if host, _ := storage.GetMasterHost(); host != nil {
|
||||
//公有云磁盘大小检查。
|
||||
if err := host.GetHostDriver().ValidateDiskSize(storage, diskConfig.SizeMb>>10); err != nil {
|
||||
@@ -663,12 +675,24 @@ func getDiskResourceRequirements(ctx context.Context, userCred mcclient.TokenCre
|
||||
return newData
|
||||
}*/
|
||||
|
||||
func (disk *SDisk) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
input := api.DiskCreateInput{}
|
||||
err := data.Unmarshal(&input)
|
||||
if err != nil {
|
||||
log.Errorf("!!!data.Unmarshal api.DiskCreateInput fail %s", err)
|
||||
}
|
||||
if input.ExistingPath != "" {
|
||||
disk.SetMetadata(ctx, api.DISK_META_EXISTING_PATH, input.ExistingPath, userCred)
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SDiskManager) OnCreateComplete(ctx context.Context, items []db.IModel, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
input := api.DiskCreateInput{}
|
||||
err := data.Unmarshal(&input)
|
||||
if err != nil {
|
||||
log.Errorf("!!!data.Unmarshal api.DiskCreateInput fail %s", err)
|
||||
}
|
||||
|
||||
pendingUsage := getDiskResourceRequirements(ctx, userCred, ownerId, input, len(items))
|
||||
parentTaskId, _ := data.GetString("parent_task_id")
|
||||
RunBatchCreateTask(ctx, items, userCred, data, pendingUsage, SRegionQuota{}, "DiskBatchCreateTask", parentTaskId)
|
||||
@@ -761,6 +785,10 @@ func (self *SDisk) StartAllocate(ctx context.Context, host *SHost, storage *SSto
|
||||
return errors.Wrap(err, "GetEncryptInfo")
|
||||
}
|
||||
}
|
||||
if ePath := self.GetMetadata(ctx, api.DISK_META_EXISTING_PATH, userCred); ePath != "" {
|
||||
input.ExistingPath = ePath
|
||||
}
|
||||
|
||||
if rebuild {
|
||||
return host.GetHostDriver().RequestRebuildDiskOnStorage(ctx, host, storage, self, task, input)
|
||||
} else {
|
||||
|
||||
@@ -3902,6 +3902,10 @@ func (self *SGuest) createDiskOnHost(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if diskConfig.ExistingPath != "" {
|
||||
disk.SetMetadata(ctx, api.DISK_META_EXISTING_PATH, diskConfig.ExistingPath, userCred)
|
||||
}
|
||||
|
||||
if len(self.BackupHostId) > 0 {
|
||||
backupHost := HostManager.FetchHostById(self.BackupHostId)
|
||||
backupStorage, err := self.ChooseHostStorage(backupHost, diskConfig, backupCandidate)
|
||||
|
||||
@@ -123,7 +123,7 @@ type IStorage interface {
|
||||
CreateDiskByDiskinfo(context.Context, interface{}) (jsonutils.JSONObject, error)
|
||||
SaveToGlance(context.Context, interface{}) (jsonutils.JSONObject, error)
|
||||
CreateDiskFromSnapshot(context.Context, IDisk, *SDiskCreateByDiskinfo) error
|
||||
|
||||
CreateDiskFromExistingPath(context.Context, IDisk, *SDiskCreateByDiskinfo) error
|
||||
CreateDiskFromBackup(context.Context, IDisk, *SDiskCreateByDiskinfo) error
|
||||
|
||||
// GetCloneTargetDiskPath generate target disk path by target disk id
|
||||
@@ -354,6 +354,8 @@ func (s *SBaseStorage) CreateDiskByDiskinfo(ctx context.Context, params interfac
|
||||
case createParams.DiskInfo.Backup != nil:
|
||||
log.Infof("CreateDiskFromBackup %s", createParams)
|
||||
return s.createDiskFromBackup(ctx, disk, createParams)
|
||||
case len(createParams.DiskInfo.ExistingPath) > 0:
|
||||
return s.createDiskFromExistingPath(ctx, disk, createParams)
|
||||
case createParams.DiskInfo.DiskSizeMb > 0:
|
||||
log.Infof("CreateRawDisk %s", createParams)
|
||||
return s.CreateRawDisk(ctx, disk, createParams)
|
||||
@@ -397,6 +399,22 @@ func (s *SBaseStorage) CreateDiskFromSnpashot(ctx context.Context, disk IDisk, i
|
||||
return disk.GetDiskDesc(), nil
|
||||
}
|
||||
|
||||
func (s *SBaseStorage) createDiskFromExistingPath(ctx context.Context, disk IDisk, input *SDiskCreateByDiskinfo) (jsonutils.JSONObject, error) {
|
||||
var storage = input.Storage
|
||||
if len(input.DiskInfo.ExistingPath) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("existing_path")
|
||||
}
|
||||
if !strings.HasPrefix(input.DiskInfo.ExistingPath, storage.GetPath()) {
|
||||
return nil, errors.Errorf("disk %s not in storage %s", input.DiskInfo.ExistingPath, storage.GetPath())
|
||||
}
|
||||
err := storage.CreateDiskFromExistingPath(ctx, disk, input)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "CreateDiskFromExistingPath")
|
||||
}
|
||||
|
||||
return disk.GetDiskDesc(), nil
|
||||
}
|
||||
|
||||
func (s *SBaseStorage) createDiskFromBackup(ctx context.Context, disk IDisk, input *SDiskCreateByDiskinfo) (jsonutils.JSONObject, error) {
|
||||
var storage = input.Storage
|
||||
if input.DiskInfo.Backup == nil {
|
||||
|
||||
@@ -664,6 +664,16 @@ func (s *SLocalStorage) CreateDiskFromSnapshot(
|
||||
return httperrors.NewUnsupportOperationError("Unsupport protocol %s for Local storage", info.Protocol)
|
||||
}
|
||||
|
||||
func (s *SLocalStorage) CreateDiskFromExistingPath(
|
||||
ctx context.Context, disk IDisk, input *SDiskCreateByDiskinfo,
|
||||
) error {
|
||||
err := os.Link(input.DiskInfo.ExistingPath, disk.GetPath())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "os.link")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SLocalStorage) GetCloneTargetDiskPath(ctx context.Context, targetDiskId string) string {
|
||||
return path.Join(s.GetPath(), targetDiskId)
|
||||
}
|
||||
|
||||
@@ -577,6 +577,10 @@ func (s *SRbdStorage) GetBackupDir() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *SRbdStorage) CreateDiskFromExistingPath(context.Context, IDisk, *SDiskCreateByDiskinfo) error {
|
||||
return fmt.Errorf("Not support")
|
||||
}
|
||||
|
||||
func (s *SRbdStorage) CreateDiskFromBackup(ctx context.Context, disk IDisk, input *SDiskCreateByDiskinfo) error {
|
||||
backup := input.DiskInfo.Backup
|
||||
pool, _ := s.StorageConf.GetString("pool")
|
||||
|
||||
Reference in New Issue
Block a user