| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- // 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"
- "net/http"
- "path"
- "yunion.io/x/jsonutils"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/util/httputils"
- "yunion.io/x/onecloud/pkg/apis"
- api "yunion.io/x/onecloud/pkg/apis/compute"
- container_storage "yunion.io/x/onecloud/pkg/hostman/container/storage"
- "yunion.io/x/onecloud/pkg/hostman/guestman/desc"
- deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis"
- "yunion.io/x/onecloud/pkg/hostman/hostdeployer/deployclient"
- "yunion.io/x/onecloud/pkg/mcclient/auth"
- "yunion.io/x/onecloud/pkg/util/qemuimg"
- "yunion.io/x/onecloud/pkg/util/seclib2"
- )
- type IDisk interface {
- GetType() string
- GetId() string
- Probe() error
- GetPath() string
- GetFormat() (string, error)
- GetDiskDesc() jsonutils.JSONObject
- GetDiskSetupScripts(idx int) string
- OnRebuildRoot(ctx context.Context, params api.DiskAllocateInput) error
- GetSnapshotDir() string
- DoDeleteSnapshot(snapshotId string) error
- GetSnapshotLocation() string
- GetSnapshotPath(snapshotId string) string
- RollbackDiskOnSnapshotFail(snapshotId string) error
- GetStorage() IStorage
- DeleteAllSnapshot(skipRecycle bool) error
- DiskSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
- DiskDeleteSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
- Delete(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
- Resize(ctx context.Context, params *SDiskResizeInput) (jsonutils.JSONObject, error)
- PreResize(ctx context.Context, sizeMb int64) error
- PrepareSaveToGlance(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
- ResetFromSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
- CleanupSnapshots(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
- PrepareMigrate(liveMigrate bool) ([]string, string, bool, error)
- RebuildSlaveDisk(diskUri string) error
- CreateFromUrl(ctx context.Context, url string, size int64, callback func(progress, progressMbps float64, totalSizeMb int64)) error
- CreateFromTemplate(context.Context, string, string, int64, *apis.SEncryptInfo) (jsonutils.JSONObject, error)
- CreateFromSnapshotLocation(ctx context.Context, location string, size int64, encryptInfo *apis.SEncryptInfo) (jsonutils.JSONObject, error)
- CreateFromRbdSnapshot(ctx context.Context, snapshotId, srcDiskId, srcPool string) error
- CreateFromRemoteHostImage(ctx context.Context, url string, size int64, encryptInfo *apis.SEncryptInfo) error
- CreateRaw(ctx context.Context, sizeMb int, diskFormat string, fsFormat string, fsFeatures *api.DiskFsFeatures, encryptInfo *apis.SEncryptInfo, diskId string, back string) (jsonutils.JSONObject, error)
- PostCreateFromRemoteHostImage(diskUrl string)
- CreateSnapshot(snapshotId string, encryptKey string, encFormat qemuimg.TEncryptFormat, encAlg seclib2.TSymEncAlg) error
- DeleteSnapshot(snapshotId, convertSnapshot string, blockStream bool, encryptInfo apis.SEncryptInfo) error
- DeployGuestFs(diskInfo *deployapi.DiskInfo, guestDesc *desc.SGuestDesc,
- deployInfo *deployapi.DeployInfo) (jsonutils.JSONObject, error)
- ConvertSnapshotRelyOnReloadDisk(convertSnapshotId string, encryptInfo apis.SEncryptInfo) (func() error, error)
- // GetBackupDir() string
- DiskBackup(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
- IsFile() bool
- GetContainerStorageDriver() (container_storage.IContainerStorage, error)
- }
- type SBaseDisk struct {
- Id string
- Storage IStorage
- }
- func NewBaseDisk(storage IStorage, id string) *SBaseDisk {
- var ret = new(SBaseDisk)
- ret.Storage = storage
- ret.Id = id
- return ret
- }
- func (d *SBaseDisk) GetId() string {
- return d.Id
- }
- func (d *SBaseDisk) GetStorage() IStorage {
- return d.Storage
- }
- func (d *SBaseDisk) GetPath() string {
- return path.Join(d.Storage.GetPath(), d.Id)
- }
- func (d *SBaseDisk) GetFormat() (string, error) {
- return "", nil
- }
- func (d *SBaseDisk) OnRebuildRoot(ctx context.Context, params api.DiskAllocateInput) error {
- return errors.Errorf("unsupported operation")
- }
- func (d *SBaseDisk) CreateFromUrl(ctx context.Context, url string, size int64, callback func(progress, progressMbps float64, totalSizeMb int64)) error {
- return errors.Errorf("unsupported operation")
- }
- func (d *SBaseDisk) CreateFromTemplate(context.Context, string, string, int64, *apis.SEncryptInfo) (jsonutils.JSONObject, error) {
- return nil, errors.Errorf("unsupported operation")
- }
- func (d *SBaseDisk) CreateFromSnapshotLocation(ctx context.Context, location string, size int64, encryptInfo *apis.SEncryptInfo) (jsonutils.JSONObject, error) {
- return nil, errors.Errorf("Not implemented")
- }
- func (d *SBaseDisk) CreateFromRemoteHostImage(ctx context.Context, url string, size int64, encryptInfo *apis.SEncryptInfo) error {
- return errors.Errorf("unsupported operation")
- }
- func (d *SBaseDisk) Resize(context.Context, *SDiskResizeInput) (jsonutils.JSONObject, error) {
- return nil, errors.Errorf("unsupported operation")
- }
- func (d *SBaseDisk) PreResize(ctx context.Context, sizeMb int64) error {
- return nil
- }
- func (d *SBaseDisk) CreateSnapshot(snapshotId string, encryptKey string, encFormat qemuimg.TEncryptFormat, encAlg seclib2.TSymEncAlg) error {
- return errors.Errorf("unsupported operation")
- }
- func (d *SBaseDisk) ConvertSnapshotRelyOnReloadDisk(convertSnapshotId string, encryptInfo apis.SEncryptInfo) (func() error, error) {
- return nil, errors.Errorf("unsupported operation")
- }
- func (d *SBaseDisk) DeleteSnapshot(snapshotId, convertSnapshot string, blockStream bool, encryptInfo apis.SEncryptInfo) error {
- return errors.Errorf("unsupported operation")
- }
- func (d *SBaseDisk) DeleteAllSnapshot(skipRecycle bool) error {
- return errors.Errorf("unsupported operation")
- }
- func (d *SBaseDisk) PrepareSaveToGlance(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
- return nil, errors.Errorf("unsupported operation")
- }
- func (d *SBaseDisk) ResetFromSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
- return nil, errors.Errorf("unsupported operation")
- }
- func (d *SBaseDisk) CleanupSnapshots(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
- return nil, errors.Errorf("unsupported operation")
- }
- func (d *SBaseDisk) PrepareMigrate(liveMigrate bool) ([]string, string, bool, error) {
- return nil, "", false, errors.Errorf("unsupported operation")
- }
- func (d *SBaseDisk) RebuildSlaveDisk(diskUri string) error {
- return nil
- }
- func (d *SBaseDisk) PostCreateFromRemoteHostImage(string) {
- }
- func (d *SBaseDisk) GetZoneId() string {
- return d.Storage.GetZoneId()
- }
- func (d *SBaseDisk) DeployGuestFs(diskInfo *deployapi.DiskInfo, guestDesc *desc.SGuestDesc,
- deployInfo *deployapi.DeployInfo) (jsonutils.JSONObject, error) {
- deployGuestDesc := deployapi.GuestStructDescToDeployDesc(guestDesc)
- deployGuestDesc.Hypervisor = api.HYPERVISOR_KVM
- ret, err := deployclient.GetDeployClient().DeployGuestFs(
- context.Background(), &deployapi.DeployParams{
- DiskInfo: diskInfo,
- GuestDesc: deployGuestDesc,
- DeployInfo: deployInfo,
- },
- )
- if err != nil {
- return nil, errors.Wrap(err, "request deploy guest fs")
- }
- return jsonutils.Marshal(ret), nil
- }
- func (d *SBaseDisk) ResizeFs(resizeDiskInput *deployapi.DiskInfo, guestDesc *deployapi.GuestDesc) error {
- _, err := deployclient.GetDeployClient().ResizeFs(
- context.Background(), &deployapi.ResizeFsParams{
- DiskInfo: resizeDiskInput,
- GuestDesc: guestDesc,
- })
- return err
- }
- func (d *SBaseDisk) GetDiskSetupScripts(diskIndex int) string {
- return ""
- }
- func (d *SBaseDisk) GetSnapshotLocation() string {
- return ""
- }
- func (d *SBaseDisk) GetSnapshotPath(snapshotId string) string {
- return ""
- }
- func ConvertDiskFsFeaturesToDeploy(fsFeatures *api.DiskFsFeatures) *deployapi.FsFeatures {
- if fsFeatures == nil {
- return nil
- }
- ret := &deployapi.FsFeatures{}
- if fsFeatures.Ext4 != nil {
- ret.Ext4 = &deployapi.FsExt4Features{
- CaseInsensitive: fsFeatures.Ext4.CaseInsensitive,
- ReservedBlocksPercentage: int32(fsFeatures.Ext4.ReservedBlocksPercentage),
- }
- }
- if fsFeatures.F2fs != nil {
- ret.F2Fs = &deployapi.FsF2FsFeatures{
- CaseInsensitive: fsFeatures.F2fs.CaseInsensitive,
- OverprovisionRatioPercentage: int32((fsFeatures.F2fs.OverprovisionRatioPercentage)),
- }
- }
- return ret
- }
- func (d *SBaseDisk) FormatFs(fsFormat string, fsFeatures *api.DiskFsFeatures, uuid string, diskInfo *deployapi.DiskInfo) error {
- log.Infof("Make disk %s fs %s, features: %s", uuid, fsFormat, jsonutils.Marshal(fsFeatures))
- _, err := deployclient.GetDeployClient().FormatFs(
- context.Background(),
- &deployapi.FormatFsParams{
- DiskInfo: diskInfo,
- FsFormat: fsFormat,
- FsFeatures: ConvertDiskFsFeaturesToDeploy(fsFeatures),
- Uuid: uuid,
- },
- )
- if err != nil {
- log.Errorf("Format fs error : %s", err)
- return err
- }
- return nil
- }
- func (d *SBaseDisk) DiskSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
- return nil, fmt.Errorf("Not implement disk.DiskSnapshot")
- }
- func (d *SBaseDisk) DiskDeleteSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
- return nil, fmt.Errorf("Not implement disk.DiskDeleteSnapshot")
- }
- func (d *SBaseDisk) CreateFromRbdSnapshot(ctx context.Context, napshotUrl, srcDiskId, srcPool string) error {
- return fmt.Errorf("Not implement disk.CreateFromRbdSnapshot")
- }
- func (d *SBaseDisk) DoDeleteSnapshot(snapshotId string) error {
- return fmt.Errorf("Not implement disk.DoDeleteSnapshot")
- }
- func (d *SBaseDisk) RollbackDiskOnSnapshotFail(snapshotId string) error {
- return errors.Errorf("Not implement disk.DoDeleteSnapshot")
- }
- func (d *SBaseDisk) GetBackupDir() string {
- return ""
- }
- func (d *SBaseDisk) GetContainerStorageDriver() (container_storage.IContainerStorage, error) {
- return nil, errors.Wrap(errors.ErrNotImplemented, "GetContainerStorageDriver")
- }
- func (d *SBaseDisk) RequestExportNbdImage(ctx context.Context, url string, encryptInfo *apis.SEncryptInfo) (int64, error) {
- body := jsonutils.NewDict()
- body.Set("disk_id", jsonutils.NewString(d.GetId()))
- header := http.Header{}
- userCred := auth.AdminCredential()
- header.Set("X-Auth-Token", userCred.GetTokenString())
- if encryptInfo != nil {
- header.Set("X-Encrypt-Key", encryptInfo.Key)
- header.Set("X-Encrypt-Alg", string(encryptInfo.Alg))
- }
- url = fmt.Sprintf("%s/%s", url, "nbd-export")
- httpClient := httputils.GetDefaultClient()
- _, respBody, err := httputils.JSONRequest(httpClient, ctx, "POST", url, header, body, false)
- if err != nil {
- return -1, errors.Wrap(err, "request export image")
- }
- nbdPort, err := respBody.Int("nbd_port")
- if err != nil {
- return -1, errors.Wrapf(err, "failed get nbd port from %s", url)
- }
- return nbdPort, nil
- }
- func (d *SBaseDisk) RequestCloseNbdImage(ctx context.Context, url string) error {
- body := jsonutils.NewDict()
- body.Set("disk_id", jsonutils.NewString(d.GetId()))
- header := http.Header{}
- userCred := auth.AdminCredential()
- header.Set("X-Auth-Token", userCred.GetTokenString())
- url = fmt.Sprintf("%s/%s", url, "nbd-close")
- httpClient := httputils.GetDefaultClient()
- _, _, err := httputils.JSONRequest(httpClient, ctx, "POST", url, header, body, false)
- if err != nil {
- return errors.Wrap(err, "request close image")
- }
- return nil
- }
|