yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/proxmox/disk.go (about)

     1  // Copyright 2019 Yunion
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package proxmox
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"net/url"
    21  	"strings"
    22  
    23  	"yunion.io/x/jsonutils"
    24  	"yunion.io/x/pkg/errors"
    25  
    26  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    27  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    28  	"yunion.io/x/cloudmux/pkg/multicloud"
    29  )
    30  
    31  type SDisk struct {
    32  	multicloud.SDisk
    33  	ProxmoxTags
    34  
    35  	region *SRegion
    36  
    37  	Storage    string
    38  	Node       string
    39  	DiskDriver string
    40  	DriverIdx  int
    41  	VmId       int
    42  	CacheMode  string
    43  
    44  	Format  string `json:"format"`
    45  	Size    int64  `json:"size"`
    46  	VolId   string `json:"volid"`
    47  	Name    string `json:"name"`
    48  	Parent  string `json:"parent"`
    49  	Content string `json:"content"`
    50  }
    51  
    52  func (self *SDisk) GetName() string {
    53  	return self.Name
    54  }
    55  
    56  func (self *SDisk) GetId() string {
    57  	return self.VolId
    58  }
    59  
    60  func (self *SDisk) GetGlobalId() string {
    61  	return self.GetId()
    62  }
    63  
    64  func (self *SDisk) CreateISnapshot(ctx context.Context, name, desc string) (cloudprovider.ICloudSnapshot, error) {
    65  	return nil, cloudprovider.ErrNotSupported
    66  }
    67  
    68  func (self *SDisk) Delete(ctx context.Context) error {
    69  	return cloudprovider.ErrNotImplemented
    70  }
    71  
    72  func (self *SDisk) GetCacheMode() string {
    73  	return self.CacheMode
    74  }
    75  
    76  func (self *SDisk) GetFsFormat() string {
    77  	return ""
    78  }
    79  
    80  func (self *SDisk) GetIsNonPersistent() bool {
    81  	return false
    82  }
    83  
    84  func (self *SDisk) GetDriver() string {
    85  	return self.DiskDriver
    86  }
    87  
    88  func (self *SDisk) GetDiskType() string {
    89  	return api.DISK_TYPE_DATA
    90  }
    91  
    92  func (self *SDisk) GetDiskFormat() string {
    93  	return strings.ToLower(self.Format)
    94  }
    95  
    96  func (self *SDisk) GetDiskSizeMB() int {
    97  	return int(self.Size / 1024 / 1024)
    98  }
    99  
   100  func (self *SDisk) GetIsAutoDelete() bool {
   101  	return true
   102  }
   103  
   104  func (self *SDisk) GetMountpoint() string {
   105  	return ""
   106  }
   107  
   108  func (self *SDisk) GetStatus() string {
   109  	return api.DISK_READY
   110  }
   111  
   112  func (self *SDisk) Rebuild(ctx context.Context) error {
   113  	return cloudprovider.ErrNotSupported
   114  }
   115  
   116  func (self *SDisk) Reset(ctx context.Context, snapshotId string) (string, error) {
   117  	return "", cloudprovider.ErrNotSupported
   118  }
   119  
   120  func (self *SDisk) Resize(ctx context.Context, sizeMb int64) error {
   121  	return self.region.ResizeDisk(self.VolId, int(sizeMb/1024))
   122  }
   123  
   124  func (self *SDisk) GetTemplateId() string {
   125  	return ""
   126  }
   127  
   128  func (self *SDisk) GetAccessPath() string {
   129  	return ""
   130  }
   131  
   132  func (self *SDisk) GetIStorage() (cloudprovider.ICloudStorage, error) {
   133  	DataStoreId := fmt.Sprintf("storage/%s/%s", self.Node, self.Storage)
   134  	return self.region.GetStorage(DataStoreId)
   135  }
   136  
   137  func (self *SDisk) GetISnapshot(snapshotId string) (cloudprovider.ICloudSnapshot, error) {
   138  	return nil, cloudprovider.ErrNotSupported
   139  }
   140  
   141  func (self *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
   142  	return []cloudprovider.ICloudSnapshot{}, nil
   143  }
   144  
   145  func (self *SRegion) GetDisks(storageId string) ([]SDisk, error) {
   146  	vols := []SDisk{}
   147  	disks := []SDisk{}
   148  
   149  	splited := strings.Split(storageId, "/")
   150  	nodeName := ""
   151  	storageName := ""
   152  
   153  	if len(splited) == 3 {
   154  		nodeName, storageName = splited[1], splited[2]
   155  	}
   156  
   157  	res := fmt.Sprintf("/nodes/%s/storage/%s/content", nodeName, storageName)
   158  	err := self.get(res, url.Values{}, &vols)
   159  	if err != nil {
   160  		return nil, err
   161  	}
   162  	for i := range vols {
   163  		_, diskName := ParseSubConf(vols[i].VolId, ":")
   164  		if err != nil {
   165  			continue
   166  		}
   167  		vols[i].Storage = storageName
   168  		vols[i].Node = nodeName
   169  		vols[i].Name = diskName.(string)
   170  
   171  		disks = append(disks, vols[i])
   172  	}
   173  
   174  	return disks, nil
   175  }
   176  
   177  func (self *SRegion) GetDisk(Id string) (*SDisk, error) {
   178  
   179  	vols := []SDisk{}
   180  	nodeName := ""
   181  	storageName, diskName := ParseSubConf(Id, ":")
   182  	resources, err := self.GetClusterStoragesResources()
   183  	if err != nil {
   184  		return nil, err
   185  	}
   186  
   187  	if res, ok := resources[storageName]; !ok {
   188  		return nil, errors.Errorf("self.GetDisk")
   189  	} else {
   190  		nodeName = res.Node
   191  	}
   192  
   193  	res := fmt.Sprintf("/nodes/%s/storage/%s/content", nodeName, storageName)
   194  	err = self.get(res, url.Values{}, &vols)
   195  	if err != nil {
   196  		return nil, errors.Wrapf(err, "self.GetDisk")
   197  	}
   198  
   199  	for _, vol := range vols {
   200  		if vol.VolId == Id {
   201  			ret := &SDisk{
   202  				region:  self,
   203  				Storage: storageName,
   204  				Node:    nodeName,
   205  				Format:  vol.Format,
   206  				Size:    vol.Size,
   207  				VolId:   vol.VolId,
   208  				Name:    diskName.(string),
   209  				Parent:  vol.Parent,
   210  				VmId:    vol.VmId,
   211  				Content: vol.Content,
   212  			}
   213  			return ret, nil
   214  		}
   215  	}
   216  
   217  	return nil, errors.Errorf("self.GetDisk failed to get disk by %s", Id)
   218  }
   219  
   220  func (self *SRegion) ResizeDisk(id string, sizeGb int) error {
   221  	disk, err := self.GetDisk(id)
   222  	if err != nil {
   223  		return errors.Wrapf(err, "GetDisk(%s)", id)
   224  	}
   225  	// not support unmount disk
   226  	if disk.VmId < 1 {
   227  		return nil
   228  	}
   229  	body := map[string]interface{}{
   230  		"disk": fmt.Sprintf("%s%d", disk.DiskDriver, disk.DriverIdx),
   231  		"size": sizeGb,
   232  	}
   233  
   234  	res := fmt.Sprintf("/nodes/%s/qemu/%d/resize", disk.Node, disk.VmId)
   235  	return self.put(res, nil, jsonutils.Marshal(body), nil)
   236  }