| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package storageman
- import (
- "context"
- "fmt"
- "os"
- "path"
- "path/filepath"
- "yunion.io/x/jsonutils"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/gotypes"
- "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"
- "yunion.io/x/onecloud/pkg/hostman/hostdeployer/deployclient"
- "yunion.io/x/onecloud/pkg/hostman/hostutils"
- "yunion.io/x/onecloud/pkg/hostman/options"
- modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
- "yunion.io/x/onecloud/pkg/mcclient/modules/image"
- "yunion.io/x/onecloud/pkg/util/cephutils"
- "yunion.io/x/onecloud/pkg/util/procutils"
- "yunion.io/x/onecloud/pkg/util/qemuimg"
- )
- const (
- RBD_FEATURE = 3
- RBD_ORDER = 22 //为rbd对应到rados中每个对象的大小,默认为4MB
- )
- type sStorageConf struct {
- MonHost string
- Key string
- Pool string
- // https://docs.ceph.com/en/latest/rados/configuration/msgr2/
- // The messenger v2 protocol, or msgr2, is the second major
- // revision on Ceph’s on-wire protocol.
- EnableMessengerV2 bool
- RadosMonOpTimeout int
- RadosOsdOpTimeout int
- ClientMountTimeout int
- }
- type SRbdStorage struct {
- SBaseStorage
- sStorageConf
- }
- func NewRBDStorage(manager *SStorageManager, path string) *SRbdStorage {
- var ret = new(SRbdStorage)
- ret.SBaseStorage = *NewBaseStorage(manager, path)
- ret.sStorageConf = sStorageConf{}
- return ret
- }
- type SRbdStorageFactory struct {
- }
- func (factory *SRbdStorageFactory) NewStorage(manager *SStorageManager, mountPoint string) IStorage {
- return NewRBDStorage(manager, mountPoint)
- }
- func (factory *SRbdStorageFactory) StorageType() string {
- return api.STORAGE_RBD
- }
- func init() {
- registerStorageFactory(&SRbdStorageFactory{})
- }
- func (s *SRbdStorage) StorageType() string {
- return api.STORAGE_RBD
- }
- func (s *SRbdStorage) IsLocal() bool {
- return false
- }
- func (s *SRbdStorage) GetSnapshotPathByIds(diskId, snapshotId string) string {
- return ""
- }
- func (s *SRbdStorage) getCephClient(pool string) (*cephutils.CephClient, error) {
- if pool == "" {
- pool = s.Pool
- }
- return cephutils.NewClient(s.MonHost, s.Key, pool, s.EnableMessengerV2, s.RadosMonOpTimeout, s.RadosOsdOpTimeout, s.ClientMountTimeout)
- }
- func (s *SRbdStorage) getClient() (*cephutils.CephClient, error) {
- return s.getCephClient("")
- }
- func (s *SRbdStorage) IsSnapshotExist(diskId, snapshotId string) (bool, error) {
- client, err := s.getClient()
- if err != nil {
- return false, errors.Wrapf(err, "GetClient")
- }
- defer client.Close()
- img, err := client.GetImage(diskId)
- if err != nil {
- return false, errors.Wrapf(err, "GetImage")
- }
- return img.IsSnapshotExist(snapshotId)
- }
- func (s *SRbdStorage) GetSnapshotDir() string {
- return ""
- }
- func (s *SRbdStorage) GetFuseTmpPath() string {
- return ""
- }
- func (s *SRbdStorage) GetFuseMountPath() string {
- return ""
- }
- func (s *SRbdStorage) GetImgsaveBackupPath() string {
- return ""
- }
- func (s *SRbdStorage) getStorageConfDir() string {
- workspacePath := filepath.Dir(options.HostOptions.ServersPath)
- cephConfDir := path.Join(workspacePath, "ceph_config", s.StorageId)
- return cephConfDir
- }
- // Tip Configuration values containing :, @, or = can be escaped with a leading \ character.
- func (s *SRbdStorage) getStorageConfString() string {
- cephConfDir := s.getStorageConfDir()
- cephConfPath := path.Join(cephConfDir, "ceph.conf")
- return ":" + fmt.Sprintf("conf=%s", cephConfPath)
- }
- func (s *SRbdStorage) listImages() ([]string, error) {
- client, err := s.getClient()
- if err != nil {
- return nil, errors.Wrapf(err, "GetClient")
- }
- defer client.Close()
- return client.ListImages()
- }
- func (s *SRbdStorage) IsImageExist(name string) (bool, error) {
- images, err := s.listImages()
- if err != nil {
- return false, errors.Wrapf(err, "listImages")
- }
- if utils.IsInStringArray(name, images) {
- return true, nil
- }
- return false, nil
- }
- func (s *SRbdStorage) getImageSizeMb(name string) (uint64, error) {
- client, err := s.getClient()
- if err != nil {
- return 0, errors.Wrapf(err, "GetClient")
- }
- defer client.Close()
- img, err := client.GetImage(name)
- if err != nil {
- return 0, errors.Wrapf(err, "GetImage")
- }
- info, err := img.GetInfo()
- if err != nil {
- return 0, errors.Wrapf(err, "GetInfo")
- }
- return uint64(info.SizeByte) / 1024 / 1024, nil
- }
- func (s *SRbdStorage) resizeImage(name string, sizeMb uint64) error {
- client, err := s.getClient()
- if err != nil {
- return errors.Wrapf(err, "GetClient")
- }
- defer client.Close()
- img, err := client.GetImage(name)
- if err != nil {
- return errors.Wrapf(err, "GetImage")
- }
- info, err := img.GetInfo()
- if err != nil {
- return errors.Wrapf(err, "img.GetInfo")
- }
- if uint64(info.SizeByte/1024/1024) >= sizeMb {
- return nil
- }
- return img.Resize(int64(sizeMb))
- }
- func (s *SRbdStorage) deleteImage(name string, skipRecycle bool) error {
- client, err := s.getClient()
- if err != nil {
- return errors.Wrapf(err, "GetClient")
- }
- defer client.Close()
- img, err := client.GetImage(name)
- if err != nil {
- if errors.Cause(err) == errors.ErrNotFound {
- return nil
- }
- return errors.Wrapf(err, "GetImage")
- }
- return img.Delete()
- }
- func (s *SRbdStorage) cloneImage(ctx context.Context, srcPool string, srcImage string, destPool string, destImage string) error {
- cli, err := s.getClient()
- if err != nil {
- return errors.Wrapf(err, "GetClient")
- }
- defer cli.Close()
- srcCli := cli.Child(srcPool)
- img, err := srcCli.GetImage(srcImage)
- if err != nil {
- return errors.Wrapf(err, "GetImage")
- }
- _, err = img.Clone(ctx, destPool, destImage)
- if err != nil {
- return errors.Wrap(err, "Clone")
- }
- return nil
- }
- func (s *SRbdStorage) cloneFromSnapshot(srcImage, srcPool, srcSnapshot, newImage, pool string) error {
- cli, err := s.getClient()
- if err != nil {
- return errors.Wrapf(err, "GetClient")
- }
- defer cli.Close()
- srcCli := cli.Child(srcPool)
- img, err := srcCli.GetImage(srcImage)
- if err != nil {
- return errors.Wrapf(err, "GetImage(%s/%s)", srcPool, srcImage)
- }
- snap, err := img.GetSnapshot(srcSnapshot)
- if err != nil {
- return errors.Wrapf(err, "GetSnapshot(%s)", srcSnapshot)
- }
- _, err = snap.Clone(pool, newImage, true)
- if err != nil {
- return errors.Wrap(err, "Clone")
- }
- return nil
- }
- func (s *SRbdStorage) createImage(name string, sizeMb uint64) error {
- client, err := s.getClient()
- if err != nil {
- return errors.Wrapf(err, "GetClient")
- }
- defer client.Close()
- _, err = client.CreateImage(name, int64(sizeMb))
- return err
- }
- func (s *SRbdStorage) renameImage(pool string, src string, dest string) error {
- cli, err := s.getClient()
- if err != nil {
- return errors.Wrapf(err, "GetClient")
- }
- defer cli.Close()
- srcCli := cli.Child(pool)
- img, err := srcCli.GetImage(src)
- if err != nil {
- return errors.Wrapf(err, "GetImage")
- }
- return img.Rename(dest)
- }
- func (s *SRbdStorage) resetDisk(diskId string, snapshotId string) error {
- client, err := s.getClient()
- if err != nil {
- return errors.Wrapf(err, "GetClient")
- }
- defer client.Close()
- img, err := client.GetImage(diskId)
- if err != nil {
- return errors.Wrapf(err, "GetImage")
- }
- snap, err := img.GetSnapshot(snapshotId)
- if err != nil {
- return errors.Wrapf(err, "GetSnapshot")
- }
- return snap.Rollback()
- }
- func (s *SRbdStorage) createBackup(ctx context.Context, diskId string, diskBackup *SDiskBackup) (int, error) {
- client, err := s.getClient()
- if err != nil {
- return 0, errors.Wrapf(err, "GetClient")
- }
- defer client.Close()
- img, err := client.GetImage(diskId)
- if err != nil {
- return 0, errors.Wrapf(err, "GetImage")
- }
- snap, err := img.GetSnapshot(diskBackup.SnapshotId)
- if err != nil {
- return 0, errors.Wrapf(err, "unable to GetSnapshot %s of Image %s", diskBackup.SnapshotId, diskId)
- }
- backupName := fmt.Sprintf("backup_%s", diskBackup.BackupId)
- // no need to flattern, as image will be delete right after backup
- backupImg, err := snap.Clone(s.sStorageConf.Pool, backupName, false)
- if err != nil {
- return 0, errors.Wrapf(err, "unable to Clone snap %s", fmt.Sprintf("%s@%s", diskId, diskBackup.SnapshotId))
- }
- defer backupImg.Delete()
- srcPath := fmt.Sprintf("rbd:%s%s", backupImg.GetName(), s.getStorageConfString())
- size, err := doBackupDisk(ctx, srcPath, diskBackup)
- if err != nil {
- return 0, errors.Wrap(err, "doBackupDisk")
- }
- return size, nil
- }
- func (s *SRbdStorage) createSnapshot(diskId string, snapshotId string) error {
- client, err := s.getClient()
- if err != nil {
- return errors.Wrapf(err, "GetClient")
- }
- defer client.Close()
- img, err := client.GetImage(diskId)
- if err != nil {
- return errors.Wrapf(err, "GetImage")
- }
- _, err = img.CreateSnapshot(snapshotId)
- return err
- }
- func (s *SRbdStorage) deleteSnapshot(diskId string, snapshotId string) error {
- client, err := s.getClient()
- if err != nil {
- return errors.Wrapf(err, "GetClient")
- }
- defer client.Close()
- img, err := client.GetImage(diskId)
- if err != nil {
- return errors.Wrapf(err, "GetImage")
- }
- snap, err := img.GetSnapshot(snapshotId)
- if err != nil {
- return errors.Wrapf(err, "GetSnapshot")
- }
- return snap.Delete()
- }
- func (s *SRbdStorage) getSnapshotSize(diskId string, snapshotId string) (int64, error) {
- client, err := s.getClient()
- if err != nil {
- return -1, errors.Wrapf(err, "GetClient")
- }
- defer client.Close()
- img, err := client.GetImage(diskId)
- if err != nil {
- return -1, errors.Wrapf(err, "GetImage")
- }
- snapSize, err := img.GetSnapshotUsedSize(diskId, snapshotId)
- if err != nil {
- return -1, errors.Wrapf(err, "GetSnapshot")
- }
- return snapSize, nil
- }
- func (s *SRbdStorage) SyncStorageSize() (api.SHostStorageStat, error) {
- stat := api.SHostStorageStat{
- StorageId: s.StorageId,
- }
- client, err := s.getClient()
- if err != nil {
- return stat, errors.Wrapf(err, "GetClient")
- }
- defer client.Close()
- capacity, err := client.GetCapacity()
- if err != nil {
- return stat, errors.Wrapf(err, "GetCapacity")
- }
- stat.CapacityMb = capacity.CapacitySizeKb / 1024
- stat.ActualCapacityUsedMb = capacity.UsedCapacitySizeKb / 1024
- return stat, nil
- }
- func (s *SRbdStorage) GetCapacityMb() int {
- capa, err := s.getRbdCapacity()
- if err != nil {
- return -1
- }
- return int(capa.CapacitySizeKb) / 1024
- }
- func (s *SRbdStorage) getRbdCapacity() (*cephutils.SCapacity, error) {
- client, err := s.getClient()
- if err != nil {
- return nil, errors.Wrap(err, "getClient")
- }
- defer client.Close()
- capacity, err := client.GetCapacity()
- if err != nil {
- return nil, errors.Wrap(err, "GetCapacity")
- }
- return capacity, nil
- }
- func (s *SRbdStorage) SyncStorageInfo() (jsonutils.JSONObject, error) {
- content := map[string]interface{}{}
- if len(s.StorageId) > 0 {
- capacity, err := s.getRbdCapacity()
- if err != nil {
- reason := jsonutils.Marshal(map[string]string{"reason": errors.Wrapf(err, "GetCapacity").Error()})
- return modules.Storages.PerformAction(hostutils.GetComputeSession(context.Background()), s.StorageId, api.STORAGE_OFFLINE, reason)
- }
- content = map[string]interface{}{
- "name": s.StorageName,
- "capacity": capacity.CapacitySizeKb / 1024,
- "actual_capacity_used": capacity.UsedCapacitySizeKb / 1024,
- "status": api.STORAGE_ONLINE,
- "zone": s.GetZoneId(),
- }
- return modules.Storages.Put(hostutils.GetComputeSession(context.Background()), s.StorageId, jsonutils.Marshal(content))
- }
- return modules.Storages.Get(hostutils.GetComputeSession(context.Background()), s.StorageName, jsonutils.Marshal(content))
- }
- func (s *SRbdStorage) GetDiskById(diskId string) (IDisk, error) {
- s.DiskLock.Lock()
- defer s.DiskLock.Unlock()
- for i := 0; i < len(s.Disks); i++ {
- if s.Disks[i].GetId() == diskId {
- err := s.Disks[i].Probe()
- if err != nil {
- return nil, errors.Wrapf(err, "disk.Prob")
- }
- return s.Disks[i], nil
- }
- }
- var disk = NewRBDDisk(s, diskId)
- if disk.Probe() == nil {
- s.Disks = append(s.Disks, disk)
- return disk, nil
- }
- return nil, errors.ErrNotFound
- }
- func (s *SRbdStorage) CreateDisk(diskId string) IDisk {
- s.DiskLock.Lock()
- defer s.DiskLock.Unlock()
- disk := NewRBDDisk(s, diskId)
- s.Disks = append(s.Disks, disk)
- return disk
- }
- func (s *SRbdStorage) Accessible() error {
- client, err := s.getClient()
- if err != nil {
- return errors.Wrapf(err, "GetClient")
- }
- defer client.Close()
- _, err = client.GetCapacity()
- return err
- }
- func (s *SRbdStorage) Detach() error {
- return nil
- }
- func (s *SRbdStorage) SaveToGlance(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
- info, ok := params.(SStorageSaveToGlanceInfo)
- if !ok {
- return nil, hostutils.ParamsError
- }
- data := info.DiskInfo
- rbdImageCache := storageManager.GetStoragecacheById(s.GetStoragecacheId())
- if rbdImageCache == nil {
- return nil, fmt.Errorf("failed to find storage image cache for storage %s", s.GetStorageName())
- }
- imagePath, _ := data.GetString("image_path")
- compress := jsonutils.QueryBoolean(data, "compress", true)
- format, _ := data.GetString("format")
- imageId, _ := data.GetString("image_id")
- imageName := "image_cache_" + imageId
- if err := s.renameImage(rbdImageCache.GetPath(), imagePath, imageName); err != nil {
- return nil, err
- }
- imagePath = fmt.Sprintf("rbd:%s/%s%s", rbdImageCache.GetPath(), imageName, s.getStorageConfString())
- if err := s.saveToGlance(ctx, imageId, imagePath, compress, format); err != nil {
- log.Errorf("Save to glance failed: %s", err)
- s.onSaveToGlanceFailed(ctx, imageId, err.Error())
- }
- rbdImageCache.LoadImageCache(imageId)
- _, err := hostutils.RemoteStoragecacheCacheImage(ctx, rbdImageCache.GetId(), imageId, "active", imagePath)
- if err != nil {
- log.Errorf("Fail to remote cache image: %v", err)
- }
- return nil, nil
- }
- func (s *SRbdStorage) saveToGlance(ctx context.Context, imageId, imagePath string, compress bool, format string) error {
- diskInfo := &deployapi.DiskInfo{
- Path: imagePath,
- }
- ret, err := deployclient.GetDeployClient().SaveToGlance(context.Background(),
- &deployapi.SaveToGlanceParams{DiskInfo: diskInfo, Compress: compress})
- if err != nil {
- return err
- }
- tmpPath := "/opt/cloud/tmp"
- err = os.MkdirAll(tmpPath, 0755)
- if err != nil {
- log.Errorf("failed mkdir %s", tmpPath)
- return errors.Wrap(err, "os.MkdirAll")
- }
- tmpFileDir, err := os.MkdirTemp(tmpPath, "ceph_save_images")
- if err != nil {
- log.Errorf("fail to obtain tempFile for ceph save glance image: %s", err)
- return errors.Wrap(err, "os.MkdirTemp")
- }
- defer func() {
- log.Debugf("clean up temp dir for glance image save %s", tmpFileDir)
- output, err := procutils.NewRemoteCommandAsFarAsPossible("rm", "-fr", tmpFileDir).Output()
- if err != nil {
- log.Errorf("rm %s fail %s %s", tmpFileDir, output, err)
- }
- }()
- tmpImageFile := filepath.Join(tmpFileDir, imageId)
- if len(format) == 0 {
- format = options.HostOptions.DefaultImageSaveFormat
- }
- img, err := qemuimg.NewQemuImage(imagePath)
- if err != nil {
- return errors.Wrapf(err, "NewQemuImage %s", imagePath)
- }
- _, err = img.Clone(tmpImageFile, qemuimgfmt.String2ImageFormat(format), compress)
- if err != nil {
- return errors.Wrapf(err, "Clone %s", tmpImageFile)
- }
- f, err := os.Open(tmpImageFile)
- if err != nil {
- return err
- }
- defer os.Remove(tmpImageFile)
- defer f.Close()
- finfo, err := f.Stat()
- if err != nil {
- return err
- }
- size := finfo.Size()
- var params = jsonutils.NewDict()
- if len(ret.OsInfo) > 0 {
- params.Set("os_type", jsonutils.NewString(ret.OsInfo))
- }
- releaseInfoToParams(ret.ReleaseInfo, params)
- params.Set("image_id", jsonutils.NewString(imageId))
- _, err = image.Images.Upload(hostutils.GetImageSession(ctx), params, f, size)
- return err
- }
- func (s *SRbdStorage) CreateSnapshotFormUrl(ctx context.Context, snapshotUrl, diskId, snapshotPath string) error {
- return fmt.Errorf("Not support")
- }
- func (s *SRbdStorage) DeleteSnapshots(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
- return nil, fmt.Errorf("Not support delete snapshots")
- }
- func (s *SRbdStorage) DeleteSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
- return nil, fmt.Errorf("Not support delete snapshot")
- }
- func (s *SRbdStorage) CreateDiskFromSnapshot(ctx context.Context, disk IDisk, input *SDiskCreateByDiskinfo) (jsonutils.JSONObject, error) {
- info := input.DiskInfo
- err := disk.CreateFromRbdSnapshot(ctx, info.SnapshotUrl, info.SrcDiskId, info.SrcPool)
- if err != nil {
- return nil, err
- }
- return disk.GetDiskDesc(), nil
- }
- 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 {
- pool, _ := s.StorageConf.GetString("pool")
- destPath := fmt.Sprintf("rbd:%s/%s%s", pool, disk.GetId(), s.getStorageConfString())
- err := doRestoreDisk(ctx, s, input, disk, destPath)
- if err != nil {
- return errors.Wrap(err, "doRestore")
- }
- /*backup := input.DiskInfo.Backup
- backupStorage, err := backupstorage.GetBackupStorage(backup.BackupStorageId, backup.BackupStorageAccessInfo)
- if err != nil {
- return errors.Wrap(err, "unable to GetBackupStorage")
- }
- err = backupStorage.ConvertTo(destPath, qemuimgfmt.RAW, backup.BackupId)
- if err != nil {
- return errors.Wrapf(err, "unable to Convert to with destPath %s and format %s", destPath, qemuimgfmt.RAW.String())
- }*/
- return nil
- }
- func (s *SRbdStorage) getDiskPath(diskId string) string {
- storageConf := s.GetStorageConf()
- pool, _ := storageConf.GetString("pool")
- return fmt.Sprintf("rbd:%s/%s", pool, diskId)
- }
- func (s *SRbdStorage) GetDiskPath(diskId string) string {
- return fmt.Sprintf("%s%s", s.getDiskPath(diskId), s.getStorageConfString())
- }
- func (s *SRbdStorage) GetCloneTargetDiskPath(ctx context.Context, targetDiskId string) string {
- return s.GetDiskPath(targetDiskId)
- }
- 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 {
- return nil, errors.Wrapf(err, "Get source image %q info", srcDiskPath)
- }
- accessPath := s.GetCloneTargetDiskPath(ctx, targetDiskId)
- if fullCopy {
- _, err = srcImg.Clone(accessPath, qemuimgfmt.RAW, false)
- if err != nil {
- return nil, errors.Wrap(err, "Clone source disk to target rbd storage")
- }
- } else {
- err = s.createImage(targetDiskId, uint64(srcImg.GetSizeMB()))
- if err != nil {
- return nil, errors.Wrap(err, "Create rbd image")
- }
- }
- return &hostapi.ServerCloneDiskFromStorageResponse{
- TargetAccessPath: accessPath,
- TargetFormat: qemuimgfmt.RAW.String(),
- }, nil
- }
- func (s *SRbdStorage) SetStorageInfo(storageId, storageName string, conf jsonutils.JSONObject) error {
- s.StorageId = storageId
- s.StorageName = storageName
- if gotypes.IsNil(conf) {
- return fmt.Errorf("empty storage conf for storage %s(%s)", storageName, storageId)
- }
- if dconf, ok := conf.(*jsonutils.JSONDict); ok {
- s.StorageConf = dconf
- }
- conf.Unmarshal(&s.sStorageConf)
- if s.RadosMonOpTimeout == 0 {
- s.RadosMonOpTimeout = api.RBD_DEFAULT_MON_TIMEOUT
- }
- if s.RadosOsdOpTimeout == 0 {
- s.RadosOsdOpTimeout = api.RBD_DEFAULT_OSD_TIMEOUT
- }
- if s.ClientMountTimeout == 0 {
- s.ClientMountTimeout = api.RBD_DEFAULT_MOUNT_TIMEOUT
- }
- confDir := s.getStorageConfDir()
- if err := os.MkdirAll(confDir, os.ModePerm); err != nil {
- return errors.Wrapf(err, "mkdir all %s", confDir)
- }
- confPath := path.Join(confDir, "ceph.conf")
- keyringPath := path.Join(confDir, "ceph.keyring")
- cli, err := cephutils.NewClientAndPersistentConf(
- s.MonHost, s.Key, s.Pool,
- s.EnableMessengerV2, s.RadosMonOpTimeout,
- s.RadosOsdOpTimeout, s.ClientMountTimeout,
- confPath, keyringPath,
- )
- if err != nil {
- log.Errorf("failed get ceph client %s:", err)
- return errors.Wrap(err, "getClient")
- }
- defer cli.Close()
- return nil
- }
- func (s *SRbdStorage) CleanRecycleDiskfiles(ctx context.Context) {
- log.Infof("SRbdStorage CleanRecycleDiskfiles do nothing!")
- }
|