diff --git a/pkg/hostman/guestman/guesttasks.go b/pkg/hostman/guestman/guesttasks.go index 7d922c4d63a..af6faaf2cf1 100644 --- a/pkg/hostman/guestman/guesttasks.go +++ b/pkg/hostman/guestman/guesttasks.go @@ -43,6 +43,7 @@ import ( "yunion.io/x/onecloud/pkg/hostman/monitor" "yunion.io/x/onecloud/pkg/hostman/options" "yunion.io/x/onecloud/pkg/hostman/storageman" + "yunion.io/x/onecloud/pkg/mcclient/auth" "yunion.io/x/onecloud/pkg/util/cgrouputils/cpuset" "yunion.io/x/onecloud/pkg/util/procutils" "yunion.io/x/onecloud/pkg/util/qemuimg" @@ -2935,8 +2936,15 @@ func (t *SGuestStorageCloneDiskTask) Start(guestRunning bool) { return } - resp, err := t.params.TargetStorage.CloneDiskFromStorage( - t.ctx, t.params.SourceStorage, t.params.SourceDisk, t.params.TargetDiskId, !guestRunning) + encryptInfo, err := t.getEncryptKey(t.ctx, auth.AdminCredential()) + if err != nil { + hostutils.TaskFailed( + t.ctx, fmt.Sprintf("failed get guest encrypt info %s", t.params.SourceDisk.GetId()), + ) + return + } + + resp, err := t.params.TargetStorage.CloneDiskFromStorage(t.ctx, t.params.SourceStorage, t.params.SourceDisk, t.params.TargetDiskId, !guestRunning, encryptInfo) if err != nil { hostutils.TaskFailed( t.ctx, fmt.Sprintf("Clone disk %s to storage %s failed %s", diff --git a/pkg/hostman/storageman/storage_base.go b/pkg/hostman/storageman/storage_base.go index 75aaa6016b0..041d655bfd5 100644 --- a/pkg/hostman/storageman/storage_base.go +++ b/pkg/hostman/storageman/storage_base.go @@ -133,7 +133,7 @@ type IStorage interface { // GetCloneTargetDiskPath generate target disk path by target disk id GetCloneTargetDiskPath(ctx context.Context, targetDiskId string) string // CloneDiskFromStorage clone disk from other storage - CloneDiskFromStorage(ctx context.Context, srcStorage IStorage, srcDisk IDisk, targetDiskId string, fullCopy bool) (*hostapi.ServerCloneDiskFromStorageResponse, error) + CloneDiskFromStorage(ctx context.Context, srcStorage IStorage, srcDisk IDisk, targetDiskId string, fullCopy bool, encInfo apis.SEncryptInfo) (*hostapi.ServerCloneDiskFromStorageResponse, error) CreateSnapshotFormUrl(ctx context.Context, snapshotUrl, diskId, snapshotPath string) error diff --git a/pkg/hostman/storageman/storage_local.go b/pkg/hostman/storageman/storage_local.go index b502c0efbdd..640a32ea172 100644 --- a/pkg/hostman/storageman/storage_local.go +++ b/pkg/hostman/storageman/storage_local.go @@ -984,14 +984,15 @@ func (s *SLocalStorage) GetCloneTargetDiskPath(ctx context.Context, targetDiskId return path.Join(s.GetPath(), targetDiskId) } -func (s *SLocalStorage) CloneDiskFromStorage( - ctx context.Context, srcStorage IStorage, srcDisk IDisk, targetDiskId string, fullCopy bool, -) (*hostapi.ServerCloneDiskFromStorageResponse, error) { +func (s *SLocalStorage) CloneDiskFromStorage(ctx context.Context, srcStorage IStorage, srcDisk IDisk, targetDiskId string, fullCopy bool, encInfo apis.SEncryptInfo) (*hostapi.ServerCloneDiskFromStorageResponse, error) { srcDiskPath := srcDisk.GetPath() srcImg, err := qemuimg.NewQemuImage(srcDiskPath) if err != nil { return nil, errors.Wrapf(err, "Get source image %q info", srcDiskPath) } + if encInfo.Id != "" { + srcImg.SetPassword(encInfo.Key) + } // start create target disk. if full copy is false, just create // empty target disk with same size and format @@ -1004,7 +1005,7 @@ func (s *SLocalStorage) CloneDiskFromStorage( return nil, errors.Wrap(err, "failed new qemu image") } - err = newImg.CreateQcow2(srcImg.GetSizeMB(), false, "", "", "", "") + err = newImg.CreateQcow2(srcImg.GetSizeMB(), false, "", encInfo.Key, qemuimg.EncryptFormatLuks, encInfo.Alg) } if err != nil { return nil, errors.Wrap(err, "Clone source disk to target local storage") diff --git a/pkg/hostman/storageman/storage_lvm.go b/pkg/hostman/storageman/storage_lvm.go index 56867b6a1f5..7913931fb2d 100644 --- a/pkg/hostman/storageman/storage_lvm.go +++ b/pkg/hostman/storageman/storage_lvm.go @@ -594,14 +594,15 @@ func (s *SLVMStorage) StorageBackup(ctx context.Context, params *SStorageBackup) return nil, nil } -func (s *SLVMStorage) CloneDiskFromStorage( - ctx context.Context, srcStorage IStorage, srcDisk IDisk, targetDiskId string, fullCopy bool, -) (*hostapi.ServerCloneDiskFromStorageResponse, error) { +func (s *SLVMStorage) CloneDiskFromStorage(ctx context.Context, srcStorage IStorage, srcDisk IDisk, targetDiskId string, fullCopy bool, encInfo apis.SEncryptInfo) (*hostapi.ServerCloneDiskFromStorageResponse, error) { srcDiskPath := srcDisk.GetPath() srcImg, err := qemuimg.NewQemuImage(srcDiskPath) if err != nil { return nil, errors.Wrapf(err, "Get source image %q info", srcDiskPath) } + if encInfo.Id != "" { + srcImg.SetPassword(encInfo.Key) + } // create target disk lv lvSize := lvmutils.GetQcow2LvSize(srcImg.SizeBytes/1024/1024) * 1024 * 1024 @@ -620,7 +621,7 @@ func (s *SLVMStorage) CloneDiskFromStorage( return nil, errors.Wrap(err, "failed new qemu image") } - err = newImg.CreateQcow2(srcImg.GetSizeMB(), false, "", "", "", "") + err = newImg.CreateQcow2(srcImg.GetSizeMB(), false, "", encInfo.Key, qemuimg.EncryptFormatLuks, encInfo.Alg) } if err != nil { return nil, errors.Wrap(err, "Clone source disk to target local storage") diff --git a/pkg/hostman/storageman/storage_rbd.go b/pkg/hostman/storageman/storage_rbd.go index 1e9d4172aa2..950052f4cf3 100644 --- a/pkg/hostman/storageman/storage_rbd.go +++ b/pkg/hostman/storageman/storage_rbd.go @@ -28,6 +28,7 @@ import ( "yunion.io/x/pkg/util/qemuimgfmt" "yunion.io/x/pkg/utils" + apis2 "yunion.io/x/onecloud/pkg/apis" api "yunion.io/x/onecloud/pkg/apis/compute" hostapi "yunion.io/x/onecloud/pkg/apis/host" deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" @@ -669,9 +670,7 @@ func (s *SRbdStorage) GetCloneTargetDiskPath(ctx context.Context, targetDiskId s return s.GetDiskPath(targetDiskId) } -func (s *SRbdStorage) CloneDiskFromStorage( - ctx context.Context, srcStorage IStorage, srcDisk IDisk, targetDiskId string, fullCopy bool, -) (*hostapi.ServerCloneDiskFromStorageResponse, error) { +func (s *SRbdStorage) CloneDiskFromStorage(ctx context.Context, srcStorage IStorage, srcDisk IDisk, targetDiskId string, fullCopy bool, encInfo apis2.SEncryptInfo) (*hostapi.ServerCloneDiskFromStorageResponse, error) { srcDiskPath := srcDisk.GetPath() srcImg, err := qemuimg.NewQemuImage(srcDiskPath) if err != nil {