yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/hcs/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 hcs 16 17 import ( 18 "fmt" 19 "strings" 20 21 "yunion.io/x/jsonutils" 22 "yunion.io/x/log" 23 "yunion.io/x/pkg/errors" 24 "yunion.io/x/pkg/util/osprofile" 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 "yunion.io/x/onecloud/pkg/util/billing" 30 ) 31 32 type SHost struct { 33 multicloud.SHostBase 34 zone *SZone 35 } 36 37 func (self *SHost) GetId() string { 38 return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId()) 39 } 40 41 func (self *SHost) GetName() string { 42 return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Name, self.zone.GetId()) 43 } 44 45 func (self *SHost) GetGlobalId() string { 46 return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId()) 47 } 48 49 func (self *SHost) IsEmulated() bool { 50 return true 51 } 52 53 func (self *SHost) GetStatus() string { 54 return api.HOST_STATUS_RUNNING 55 } 56 57 func (self *SHost) GetIVMs() ([]cloudprovider.ICloudVM, error) { 58 vms, err := self.zone.region.GetInstances("") 59 if err != nil { 60 return nil, err 61 } 62 63 ret := []cloudprovider.ICloudVM{} 64 for i := range vms { 65 if vms[i].OSEXTAZAvailabilityZone == self.zone.GetId() { 66 vms[i].host = self 67 ret = append(ret, &vms[i]) 68 } 69 } 70 return ret, nil 71 } 72 73 func (self *SHost) GetIVMById(id string) (cloudprovider.ICloudVM, error) { 74 vm, err := self.zone.region.GetInstance(id) 75 if err != nil { 76 return nil, err 77 } 78 vm.host = self 79 return vm, nil 80 } 81 82 func (self *SHost) GetIWires() ([]cloudprovider.ICloudWire, error) { 83 return self.zone.GetIWires() 84 } 85 86 func (self *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) { 87 return self.zone.GetIStorages() 88 } 89 90 func (self *SHost) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) { 91 return self.zone.GetIStorageById(id) 92 } 93 94 func (self *SHost) GetEnabled() bool { 95 return true 96 } 97 98 func (self *SHost) GetHostStatus() string { 99 return api.HOST_ONLINE 100 } 101 102 func (self *SHost) GetAccessIp() string { 103 return "" 104 } 105 106 func (self *SHost) GetAccessMac() string { 107 return "" 108 } 109 110 func (self *SHost) GetSysInfo() jsonutils.JSONObject { 111 info := jsonutils.NewDict() 112 info.Add(jsonutils.NewString(CLOUD_PROVIDER_HCS), "manufacture") 113 return info 114 } 115 116 func (self *SHost) GetSN() string { 117 return "" 118 } 119 120 func (self *SHost) GetCpuCount() int { 121 return 0 122 } 123 124 func (self *SHost) GetNodeCount() int8 { 125 return 0 126 } 127 128 func (self *SHost) GetCpuDesc() string { 129 return "" 130 } 131 132 func (self *SHost) GetCpuMhz() int { 133 return 0 134 } 135 136 func (self *SHost) GetMemSizeMB() int { 137 return 0 138 } 139 140 func (self *SHost) GetStorageSizeMB() int { 141 return 0 142 } 143 144 func (self *SHost) GetStorageType() string { 145 return api.DISK_TYPE_HYBRID 146 } 147 148 func (self *SHost) GetHostType() string { 149 return api.HOST_TYPE_HCS 150 } 151 152 func (self *SHost) GetIsMaintenance() bool { 153 return false 154 } 155 156 func (self *SHost) GetVersion() string { 157 return HCS_API_VERSION 158 } 159 160 func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { 161 vm, err := self._createVM( 162 desc.Name, desc.ExternalImageId, desc.SysDisk, 163 desc.Cpu, desc.MemoryMB, desc.InstanceType, 164 desc.ExternalNetworkId, desc.IpAddr, 165 desc.Description, desc.Account, 166 desc.Password, desc.DataDisks, 167 desc.PublicKey, desc.ExternalSecgroupId, 168 desc.UserData, desc.BillingCycle, desc.ProjectId, desc.Tags) 169 if err != nil { 170 return nil, err 171 } 172 return vm, err 173 } 174 175 func (self *SHost) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error) { 176 return nil, cloudprovider.ErrNotSupported 177 } 178 179 func (self *SHost) _createVM(name string, imgId string, sysDisk cloudprovider.SDiskInfo, cpu int, memMB int, instanceType string, 180 networkId string, ipAddr string, desc string, account string, passwd string, 181 diskSizes []cloudprovider.SDiskInfo, publicKey string, secgroupId string, 182 userData string, bc *billing.SBillingCycle, projectId string, tags map[string]string) (*SInstance, error) { 183 net, err := self.zone.region.GetNetwork(networkId) 184 if err != nil { 185 return nil, errors.Wrapf(err, "GetNetwork(%s)", networkId) 186 } 187 188 keypair := "" 189 if len(publicKey) > 0 { 190 keypair, err = self.zone.region.syncKeypair(publicKey) 191 if err != nil { 192 return nil, err 193 } 194 } 195 196 // 镜像及硬盘配置 197 img, err := self.zone.region.GetImage(imgId) 198 if err != nil { 199 return nil, errors.Wrapf(err, "GetImage(%s)", imgId) 200 } 201 // passwd, windows机型直接使用密码比较方便 202 if strings.ToLower(img.Platform) == strings.ToLower(osprofile.OS_TYPE_WINDOWS) && len(passwd) > 0 { 203 keypair = "" 204 } 205 206 if strings.ToLower(img.Platform) == strings.ToLower(osprofile.OS_TYPE_WINDOWS) { 207 if u, err := updateWindowsUserData(userData, img.OSVersion, account, passwd); err == nil { 208 userData = u 209 } else { 210 return nil, errors.Wrap(err, "SHost.CreateVM.updateWindowsUserData") 211 } 212 } 213 214 if sysDisk.SizeGB > 0 && sysDisk.SizeGB < img.SizeGB { 215 sysDisk.SizeGB = img.SizeGB 216 } 217 218 // 创建实例 219 if len(instanceType) > 0 { 220 log.Debugf("Try instancetype : %s", instanceType) 221 vm, err := self.zone.region.CreateInstance(name, imgId, instanceType, networkId, secgroupId, 222 net.VpcId, self.zone.GetId(), desc, sysDisk, diskSizes, ipAddr, keypair, 223 passwd, userData, bc, projectId, tags) 224 if err != nil { 225 return nil, fmt.Errorf("create %s failed:%v", instanceType, err) 226 } 227 return vm, nil 228 } 229 230 // 匹配实例类型 231 instanceTypes, err := self.zone.region.GetMatchInstanceTypes(cpu, memMB, self.zone.GetId()) 232 if err != nil { 233 return nil, err 234 } 235 if len(instanceTypes) == 0 { 236 return nil, fmt.Errorf("instance type %dC%dMB not avaiable", cpu, memMB) 237 } 238 239 var vm *SInstance 240 for _, instType := range instanceTypes { 241 instanceTypeId := instType.Name 242 log.Debugf("Try instancetype : %s", instanceTypeId) 243 vm, err = self.zone.region.CreateInstance(name, imgId, instanceTypeId, networkId, secgroupId, 244 net.VpcId, self.zone.GetId(), desc, sysDisk, diskSizes, ipAddr, keypair, 245 passwd, userData, bc, projectId, tags) 246 if err != nil { 247 log.Errorf("Failed for %s: %s", instanceTypeId, err) 248 } else { 249 return vm, nil 250 } 251 } 252 253 return nil, fmt.Errorf("create failed: %v", err) 254 }