yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/incloudsphere/host.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 incloudsphere 16 17 import ( 18 "fmt" 19 "net" 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 SHost struct { 32 multicloud.SHostBase 33 InCloudSphereTags 34 zone *SZone 35 36 Id string `json:"id"` 37 IP string `json:"ip"` 38 SwitchUplinkPortDto string `json:"switchUplinkPortDto"` 39 UplinkTopoDto string `json:"uplinkTopoDto"` 40 Pnics string `json:"pnics"` 41 Disks string `json:"disks"` 42 Name string `json:"name"` 43 HostName string `json:"hostName"` 44 NodeVersion string `json:"nodeVersion"` 45 Password string `json:"password"` 46 DataCenterId string `json:"dataCenterId"` 47 DataCenterName string `json:"dataCenterName"` 48 ClusterName string `json:"clusterName"` 49 ClusterId string `json:"clusterId"` 50 Status string `json:"status"` 51 CPUSocket int64 `json:"cpuSocket"` 52 CPUCorePerSocket int64 `json:"cpuCorePerSocket"` 53 CPUThreadPerCore int64 `json:"cpuThreadPerCore"` 54 LogicCPUNum int64 `json:"logicCpuNum"` 55 LogicalProcessor int64 `json:"logicalProcessor"` 56 CPUFrequency float64 `json:"cpuFrequency"` 57 CPUUsage float64 `json:"cpuUsage"` 58 CPUTotalHz int64 `json:"cpuTotalHz"` 59 FreeCPU int64 `json:"freeCpu"` 60 UsedCPU int64 `json:"usedCpu"` 61 TotalMem float64 `json:"totalMem"` 62 LogicTotalMem int64 `json:"logicTotalMem"` 63 MemoryUsage float64 `json:"memoryUsage"` 64 FreeMemory int64 `json:"freeMemory"` 65 UsedMemory int64 `json:"usedMemory"` 66 LogicUsedMemory int64 `json:"logicUsedMemory"` 67 LogicFreeMemory int64 `json:"logicFreeMemory"` 68 PnicNum int64 `json:"pnicNum"` 69 NormalRunTime int64 `json:"normalRunTime"` 70 Model string `json:"model"` 71 CPUType string `json:"cpuType"` 72 VTDegree int64 `json:"vtDegree"` 73 Powerstate string `json:"powerstate"` 74 HostBmcDto string `json:"hostBmcDto"` 75 MountPath string `json:"mountPath"` 76 MonMountState string `json:"monMountState"` 77 CPUModel string `json:"cpuModel"` 78 NetworkDtos string `json:"networkDtos"` 79 PortIP string `json:"portIp"` 80 Monstatus bool `json:"monstatus"` 81 HostIqn string `json:"hostIqn"` 82 VxlanPortDto string `json:"vxlanPortDto"` 83 SDNUpLinks string `json:"sdnUpLinks"` 84 AllPNicsCount int64 `json:"allPNicsCount"` 85 AvailablePNicsCount int64 `json:"availablePNicsCount"` 86 CfsDomainStatus string `json:"cfsDomainStatus"` 87 SerialNumber string `json:"serialNumber"` 88 Manufacturer string `json:"manufacturer"` 89 IndicatorStatus string `json:"indicatorStatus"` 90 EntryTemperature string `json:"entryTemperature"` 91 MulticastEnabled bool `json:"multicastEnabled"` 92 BroadcastLimitEnabled bool `json:"broadcastLimitEnabled"` 93 Pcies string `json:"pcies"` 94 VgpuEnable bool `json:"vgpuEnable"` 95 SSHEnable bool `json:"sshEnable"` 96 SpecialFailover bool `json:"specialFailover"` 97 VswitchDtos string `json:"vswitchDtos"` 98 HotfixVersion string `json:"hotfixVersion"` 99 VMMigBandWidth string `json:"vmMigBandWidth"` 100 VMMigBandWidthFlag bool `json:"vmMigBandWidthFlag"` 101 DpdkEnabled bool `json:"dpdkEnabled"` 102 HugePageTotal int64 `json:"hugePageTotal"` 103 HugePageUsed int64 `json:"hugePageUsed"` 104 HugePageFree int64 `json:"hugePageFree"` 105 StorageUsage int64 `json:"storageUsage"` 106 NodeForm string `json:"nodeForm"` 107 CPUArchType string `json:"cpuArchType"` 108 LogPartitionSize int64 `json:"logPartitionSize"` 109 RootPartitionSize int64 `json:"rootPartitionSize"` 110 Cpuflags string `json:"cpuflags"` 111 } 112 113 func (self *SHost) GetId() string { 114 return self.Id 115 } 116 117 func (self *SHost) GetGlobalId() string { 118 return self.Id 119 } 120 121 func (self *SHost) GetName() string { 122 return self.HostName 123 } 124 125 func (self *SHost) GetEnabled() bool { 126 return true 127 } 128 129 func (self *SHost) GetHostStatus() string { 130 return api.HOST_ONLINE 131 } 132 133 func (self *SHost) GetStatus() string { 134 return api.HOST_STATUS_RUNNING 135 } 136 137 func (self *SHost) GetAccessIp() string { 138 return self.Name 139 } 140 141 func (self *SHost) GetAccessMac() string { 142 return "" 143 } 144 145 func (self *SHost) GetSysInfo() jsonutils.JSONObject { 146 return jsonutils.NewDict() 147 } 148 149 func (self *SHost) GetSN() string { 150 return self.SerialNumber 151 } 152 153 func (self *SHost) GetCpuCount() int { 154 return int(self.CPUCorePerSocket) 155 } 156 157 func (self *SHost) GetNodeCount() int8 { 158 return int8(self.CPUSocket) 159 } 160 161 func (self *SHost) GetCpuDesc() string { 162 return self.CPUType 163 } 164 165 func (self *SHost) GetCpuMhz() int { 166 return int(self.CPUFrequency * 1024) 167 } 168 169 func (self *SHost) GetCpuCmtbound() float32 { 170 return 1 171 } 172 173 func (self *SHost) GetMemSizeMB() int { 174 return int(self.TotalMem) 175 } 176 177 func (self *SHost) GetMemCmtbound() float32 { 178 return 1 179 } 180 181 func (self *SHost) GetReservedMemoryMb() int { 182 return 0 183 } 184 185 func (self *SHost) GetStorageSizeMB() int { 186 return 0 187 } 188 189 func (self *SHost) GetStorageType() string { 190 return api.STORAGE_LOCAL 191 } 192 193 func (self *SHost) GetHostType() string { 194 return api.HOST_TYPE_INCLOUD_SPHERE 195 } 196 197 func (self *SHost) GetIsMaintenance() bool { 198 return false 199 } 200 201 func (self *SHost) GetVersion() string { 202 return self.NodeVersion 203 } 204 205 func (self *SHost) CreateVM(opts *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { 206 storages, err := self.zone.region.GetImageStorages(self.zone.Id) 207 if err != nil { 208 return nil, errors.Wrapf(err, "GetImageStorages") 209 } 210 var image *SImage = nil 211 storageCache := &SStoragecache{zone: self.zone} 212 for i := range storages { 213 images, err := self.zone.region.GetImageList(storages[i].Id) 214 if err != nil { 215 return nil, err 216 } 217 for j := range images { 218 images[j].cache = storageCache 219 if images[j].GetGlobalId() == opts.ExternalImageId { 220 image = &images[j] 221 break 222 } 223 } 224 } 225 if image == nil { 226 return nil, errors.Wrapf(cloudprovider.ErrNotFound, opts.ExternalImageId) 227 } 228 format := "RAW" 229 if strings.HasSuffix(opts.ExternalImageId, "qcow2") { 230 format = "QCOW2" 231 } 232 sizeGb := float64((image.GetSizeByte() + 1024/2) / 1024 / 1024 / 1024) 233 disks := []Disks{} 234 disks = append(disks, Disks{ 235 BusModel: "IDE", 236 ReadWriteModel: "NONE", 237 QueueNum: 1, 238 Volume: Volume{ 239 Bootable: true, 240 DataStoreId: opts.SysDisk.StorageExternalId, 241 Format: format, 242 Size: sizeGb, 243 VolumePolicy: "THIN", 244 VvSourceDto: VvSourceDto{ 245 FilePath: fmt.Sprintf("%s/%s", image.Path, image.Name), 246 SourceType: "IMAGE_STORAGE", 247 FtpServerHost: FtpServerHost{ 248 Id: image.ServerID, 249 Ip: image.FTPServer, 250 }, 251 }, 252 }, 253 }) 254 for i := range opts.DataDisks { 255 disks = append(disks, Disks{ 256 BusModel: "IDE", 257 ReadWriteModel: "NONE", 258 QueueNum: 1, 259 Volume: Volume{ 260 Bootable: false, 261 DataStoreId: opts.DataDisks[i].StorageExternalId, 262 Format: "RAW", 263 Size: float64(opts.DataDisks[i].SizeGB), 264 VolumePolicy: "THIN", 265 }, 266 }) 267 } 268 imageTree, err := self.zone.region.GetImageTrees() 269 if err != nil { 270 return nil, errors.Wrapf(err, "GetImageTrees") 271 } 272 guestLabel, guestosType := "CentOS 7.9(2009) 64bit", "CentOS" 273 for i := range imageTree { 274 images := imageTree[i].ToList() 275 for j := range images { 276 if images[j].IsEquals(image.Name) { 277 guestLabel = images[j].Model 278 guestosType = images[j].OsDist 279 break 280 } 281 } 282 } 283 nic := SInstanceNic{ 284 AutoGenerated: true, 285 DeviceId: opts.ExternalNetworkId, 286 DeviceType: "NETWORK", 287 Model: "E1000", 288 Queues: 1, 289 } 290 network, err := self.zone.region.GetNetwork(opts.ExternalNetworkId) 291 if err != nil { 292 return nil, errors.Wrapf(err, "GetNetwork") 293 } 294 if network.DhcpEnabled { 295 nic.Dhcp = true 296 nic.DhcpEnabled = true 297 nic.DhcpIP = opts.IpAddr 298 } else if len(opts.IpAddr) > 0 { 299 nic.IP = opts.IpAddr 300 mask := net.CIDRMask(int(network.GetIpMask()), 32) 301 nic.Netmask = fmt.Sprintf("%d.%d.%d.%d", mask[0], mask[1], mask[2], mask[3]) 302 nic.Gateway = network.GetGateway() 303 if len(nic.Gateway) == 0 { 304 info := strings.Split(opts.IpAddr, ".") 305 if len(info) == 4 { 306 info[3] = "1" 307 nic.Gateway = strings.Join(info, ".") 308 } 309 } 310 } 311 body := map[string]interface{}{ 312 "boot": "HD", 313 "bootMode": "BIOS", 314 "clockModel": "LOCALTIME", 315 "cpuBindType": "NOBIND", 316 "cpuCore": opts.Cpu, 317 "cpuHotplugEnabled": false, 318 "cpuLimit": -1, 319 "cpuModelType": "SELF_ADAPTING", 320 "cpuNum": opts.Cpu, 321 "cpuReservation": 0, 322 "cpuShares": 1024, 323 "cpuSocket": 1, 324 "dataCenterId": self.zone.Id, 325 "dataStoreId": opts.SysDisk.StorageExternalId, 326 "deacription": opts.Description, 327 "disks": disks, 328 "enableHugeMemPage": false, 329 "enableReplicate": false, 330 "graphicsCardMemory": 16384, 331 "graphicsCardModel": "VGA", 332 "guestosLabel": guestLabel, 333 "guestosType": guestosType, 334 "hostBinded": false, 335 "hostId": self.Id, 336 "maxCpuNum": 128, 337 "maxMemory": 4194304, 338 "memory": opts.MemoryMB, 339 "memoryShow": 4, 340 "memoryUnit": "GB", 341 "name": opts.Name, 342 "nics": []SInstanceNic{ 343 nic, 344 }, 345 "panickPolicy": "NO_ACTION", 346 "replicate": 1, 347 "socketLimit": 24, 348 "startPriority": "DEFAULT", 349 "supportCpuHotPlug": true, 350 "supportMemHotPlug": true, 351 "supportUefiBootMode": true, 352 "vcpuPin": "all", 353 "version": "V2", 354 } 355 resp, err := self.zone.region.post("/vms", jsonutils.Marshal(body)) 356 if err != nil { 357 return nil, err 358 } 359 taskId, err := resp.GetString("taskId") 360 if err != nil { 361 return nil, errors.Wrapf(err, "taskId") 362 } 363 vmId, err := self.zone.region.client.waitTask(taskId) 364 if err != nil { 365 return nil, err 366 } 367 vm, err := self.zone.region.GetInstance(vmId) 368 if err != nil { 369 return nil, err 370 } 371 vm.host = self 372 return vm, nil 373 } 374 375 func (self *SHost) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error) { 376 return nil, cloudprovider.ErrNotImplemented 377 } 378 379 func (self *SHost) GetIVMs() ([]cloudprovider.ICloudVM, error) { 380 vms, err := self.zone.region.GetInstances(self.Id) 381 if err != nil { 382 return nil, errors.Wrapf(err, "GetInstances") 383 } 384 ret := []cloudprovider.ICloudVM{} 385 for i := range vms { 386 vms[i].host = self 387 ret = append(ret, &vms[i]) 388 } 389 return ret, nil 390 } 391 392 func (self *SHost) GetIVMById(id string) (cloudprovider.ICloudVM, error) { 393 vm, err := self.zone.region.GetInstance(id) 394 if err != nil { 395 return nil, err 396 } 397 if vm.HostId != self.Id { 398 return nil, cloudprovider.ErrNotFound 399 } 400 vm.host = self 401 return vm, nil 402 } 403 404 func (self *SHost) GetIWires() ([]cloudprovider.ICloudWire, error) { 405 wires, err := self.zone.region.GetWiresByDs(self.DataCenterId) 406 if err != nil { 407 return nil, err 408 } 409 ret := []cloudprovider.ICloudWire{} 410 for i := range wires { 411 wires[i].region = self.zone.region 412 ret = append(ret, &wires[i]) 413 } 414 return ret, nil 415 } 416 417 func (self *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) { 418 storages, err := self.zone.region.GetStoragesByHost(self.Id) 419 if err != nil { 420 return nil, err 421 } 422 ret := []cloudprovider.ICloudStorage{} 423 for i := range storages { 424 storages[i].zone = self.zone 425 ret = append(ret, &storages[i]) 426 } 427 return ret, nil 428 } 429 430 func (self *SHost) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) { 431 storage, err := self.zone.region.GetStorage(id) 432 if err != nil { 433 return nil, err 434 } 435 storage.zone = self.zone 436 if storage.HostId != self.Id { 437 return nil, cloudprovider.ErrNotFound 438 } 439 return storage, nil 440 } 441 442 func (self *SRegion) GetHosts(dcId string) ([]SHost, error) { 443 hosts := []SHost{} 444 res := fmt.Sprintf("/datacenters/%s/hosts", dcId) 445 return hosts, self.list(res, url.Values{}, &hosts) 446 } 447 448 func (self *SRegion) GetHost(id string) (*SHost, error) { 449 ret := &SHost{} 450 res := fmt.Sprintf("/hosts/%s", id) 451 return ret, self.get(res, url.Values{}, ret) 452 }