Merge pull request #2162 from wanyaoqi/feature/wyq/support-migrate-with-different-mountpoint

feature: server migrate to different mountpoint storage
This commit is contained in:
yunion-ci-robot
2019-08-08 16:05:58 +08:00
committed by GitHub
7 changed files with 57 additions and 12 deletions
+2 -3
View File
@@ -285,9 +285,8 @@ func (self *GuestMigrateTask) localStorageMigrateConf(ctx context.Context,
targetStorage := targetHost.GetHoststorageOfId(targetStorageId)
sourceStorage := sourceHost.GetHoststorageOfId(disks[0].GetDisk().StorageId)
if sourceStorage.MountPoint != targetStorage.MountPoint {
self.TaskFailed(ctx, guest, fmt.Sprintf("target host %s storage"+
"mount point is different with source storage", targetHost.Id))
return nil, true
// rebase disks backing file
body.Set("rebase_disks", jsonutils.JSONTrue)
}
body.Set("desc", targetDesc)
body.Set("is_local_storage", jsonutils.JSONTrue)
@@ -70,7 +70,6 @@ func (self *StorageCacheImageTask) OnRelinquishLeastUsedCachedImageComplete(ctx
errData := taskman.Error2TaskData(err)
self.OnImageCacheCompleteFailed(ctx, storageCache, errData)
}
}
func (self *StorageCacheImageTask) OnImageCacheComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
@@ -317,6 +317,7 @@ func guestDestPrepareMigrate(ctx context.Context, sid string, body jsonutils.JSO
}
params.TargetStorageId = targetStorageId
}
params.RebaseDisks = jsonutils.QueryBoolean(body, "rebase_disks", false)
}
hostutils.DelayTask(ctx, guestman.GetGuestManager().DestPrepareMigrate, params)
return nil, nil
+1
View File
@@ -44,6 +44,7 @@ type SDestPrepareMigrate struct {
DisksUri string
TargetStorageId string
LiveMigrate bool
RebaseDisks bool
Desc jsonutils.JSONObject
DisksBackingFile jsonutils.JSONObject
+1 -1
View File
@@ -491,7 +491,7 @@ func (m *SGuestManager) DestPrepareMigrate(ctx context.Context, params interface
err := iStorage.DestinationPrepareMigrate(
ctx, migParams.LiveMigrate, migParams.DisksUri, migParams.SnapshotsUri,
migParams.Desc, migParams.DisksBackingFile, migParams.SrcSnapshots)
migParams.Desc, migParams.DisksBackingFile, migParams.SrcSnapshots, migParams.RebaseDisks)
if err != nil {
return nil, fmt.Errorf("dest prepare migrate failed %s", err)
}
+6 -2
View File
@@ -112,7 +112,8 @@ type IStorage interface {
GetFuseMountPath() string
GetImgsaveBackupPath() string
DestinationPrepareMigrate(ctx context.Context, liveMigrate bool, disksUri string, snapshotsUri string, desc, disksBackingFile, srcSnapshots jsonutils.JSONObject) error
DestinationPrepareMigrate(ctx context.Context, liveMigrate bool, disksUri string, snapshotsUri string,
desc, disksBackingFile, srcSnapshots jsonutils.JSONObject, rebaseDisks bool) error
}
type SBaseStorage struct {
@@ -320,7 +321,10 @@ func (s *SBaseStorage) CreateDiskFromSnpashot(ctx context.Context, disk IDisk, c
return disk.GetDiskDesc(), nil
}
func (s *SBaseStorage) DestinationPrepareMigrate(ctx context.Context, liveMigrate bool, disksUri string, snapshotsUri string, desc, disksBackingFile, srcSnapshots jsonutils.JSONObject) error {
func (s *SBaseStorage) DestinationPrepareMigrate(
ctx context.Context, liveMigrate bool, disksUri string, snapshotsUri string,
desc, disksBackingFile, srcSnapshots jsonutils.JSONObject, rebaseDisks bool,
) error {
return nil
}
+46 -5
View File
@@ -21,6 +21,7 @@ import (
"path"
"time"
"github.com/pkg/errors"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/util/timeutils"
@@ -322,7 +323,9 @@ func (s *SLocalStorage) DeleteSnapshots(ctx context.Context, params interface{})
return nil, nil
}
func (s *SLocalStorage) DestinationPrepareMigrate(ctx context.Context, liveMigrate bool, disksUri string, snapshotsUri string, desc, disksBackingFile, srcSnapshots jsonutils.JSONObject) error {
func (s *SLocalStorage) DestinationPrepareMigrate(
ctx context.Context, liveMigrate bool, disksUri string, snapshotsUri string,
desc, disksBackingFile, srcSnapshots jsonutils.JSONObject, rebaseDisks bool) error {
disks, _ := desc.GetArray("disks")
for i, diskinfo := range disks {
var (
@@ -336,6 +339,7 @@ func (s *SLocalStorage) DestinationPrepareMigrate(ctx context.Context, liveMigra
"Storage %s create disk %s failed", s.GetId(), diskId)
}
templateId, _ := diskinfo.GetString("template_id")
// prepare disk snapshot dir
if len(snapshots) > 0 && !fileutils2.Exists(disk.GetSnapshotDir()) {
_, err := procutils.NewCommand("mkdir", "-p", disk.GetSnapshotDir()).Run()
@@ -345,15 +349,30 @@ func (s *SLocalStorage) DestinationPrepareMigrate(ctx context.Context, liveMigra
}
// create snapshots form remote url
diskStorageId, _ := diskinfo.GetString("storage_id")
for _, snapshotId := range snapshots {
var (
diskStorageId, _ = diskinfo.GetString("storage_id")
baseImagePath string
)
for i, snapshotId := range snapshots {
snapId, _ := snapshotId.GetString()
snapshotUrl := fmt.Sprintf("%s/%s/%s/%s",
snapshotsUri, diskStorageId, diskId, snapId)
snapshotPath := path.Join(disk.GetSnapshotDir(), snapId)
log.Infof("Disk %s snapshot %s url: %s", diskId, snapId, snapshotUrl)
s.CreateSnapshotFormUrl(ctx, snapshotUrl, diskId, snapshotPath)
if err := s.CreateSnapshotFormUrl(ctx, snapshotUrl, diskId, snapshotPath); err != nil {
return errors.Wrap(err, "create from snapshot url failed")
}
baseImagePath = snapshotPath
if i == 0 && len(templateId) > 0 {
templatePath := path.Join(storageManager.LocalStorageImagecacheManager.GetPath(), templateId)
if err := doRebaseDisk(snapshotPath, templatePath); err != nil {
return err
}
} else if rebaseDisks {
if err := doRebaseDisk(snapshotPath, baseImagePath); err != nil {
return err
}
}
}
if liveMigrate {
@@ -373,8 +392,30 @@ func (s *SLocalStorage) DestinationPrepareMigrate(ctx context.Context, liveMigra
return err
}
}
if rebaseDisks && len(templateId) > 0 && len(baseImagePath) == 0 {
templatePath := path.Join(storageManager.LocalStorageImagecacheManager.GetPath(), templateId)
if err := doRebaseDisk(disk.GetPath(), templatePath); err != nil {
return err
}
} else if rebaseDisks && len(baseImagePath) > 0 {
if err := doRebaseDisk(disk.GetPath(), baseImagePath); err != nil {
return err
}
}
diskDesc, _ := disks[i].(*jsonutils.JSONDict)
diskDesc.Set("path", jsonutils.NewString(disk.GetPath()))
}
return nil
}
func doRebaseDisk(diskPath, newBasePath string) error {
img, err := qemuimg.NewQemuImage(diskPath)
if err != nil {
return errors.Wrap(err, "failed open disk as qemu image")
}
if err = img.Rebase(newBasePath, true); err != nil {
return errors.Wrap(err, "failed rebase disk backing file")
}
log.Infof("rebase disk %s backing file to %s ", diskPath, newBasePath)
return nil
}