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 }