base.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955
  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. package candidate
  15. import (
  16. "fmt"
  17. "strings"
  18. "sync"
  19. "yunion.io/x/jsonutils"
  20. "yunion.io/x/log"
  21. "yunion.io/x/pkg/errors"
  22. "yunion.io/x/pkg/util/sets"
  23. "yunion.io/x/pkg/utils"
  24. "yunion.io/x/sqlchemy"
  25. computeapi "yunion.io/x/onecloud/pkg/apis/compute"
  26. "yunion.io/x/onecloud/pkg/cloudcommon/types"
  27. computemodels "yunion.io/x/onecloud/pkg/compute/models"
  28. "yunion.io/x/onecloud/pkg/scheduler/api"
  29. "yunion.io/x/onecloud/pkg/scheduler/core"
  30. "yunion.io/x/onecloud/pkg/scheduler/data_manager/cloudregion"
  31. "yunion.io/x/onecloud/pkg/scheduler/data_manager/netinterface"
  32. "yunion.io/x/onecloud/pkg/scheduler/data_manager/network"
  33. "yunion.io/x/onecloud/pkg/scheduler/data_manager/network_additional_wire"
  34. "yunion.io/x/onecloud/pkg/scheduler/data_manager/sku"
  35. "yunion.io/x/onecloud/pkg/scheduler/data_manager/zone"
  36. schedmodels "yunion.io/x/onecloud/pkg/scheduler/models"
  37. )
  38. type BaseHostDesc struct {
  39. *computemodels.SHost
  40. Region *computemodels.SCloudregion `json:"region"`
  41. Zone *computemodels.SZone `json:"zone"`
  42. Cloudprovider *computemodels.SCloudprovider `json:"cloudprovider"`
  43. Cloudaccount *computemodels.SCloudaccount `json:"cloudaccount"`
  44. Networks []*api.CandidateNetwork `json:"networks"`
  45. NetInterfaces map[string][]computemodels.SNetInterface `json:"net_interfaces"`
  46. Storages []*api.CandidateStorage `json:"storages"`
  47. IsolatedDevices []*core.IsolatedDeviceDesc `json:"isolated_devices"`
  48. Tenants map[string]int64 `json:"tenants"`
  49. InstanceGroups map[string]*api.CandidateGroup `json:"instance_groups"`
  50. IpmiInfo types.SIPMIInfo `json:"ipmi_info"`
  51. Nics []*types.SNic `json:"nics"`
  52. SharedDomains []string `json:"shared_domains"`
  53. PendingUsage map[string]interface{} `json:"pending_usage"`
  54. ClassMetadata map[string]string `json:"class_metadata"`
  55. }
  56. type baseHostGetter struct {
  57. h *BaseHostDesc
  58. }
  59. func newBaseHostGetter(h *BaseHostDesc) *baseHostGetter {
  60. return &baseHostGetter{h}
  61. }
  62. func (b baseHostGetter) Id() string {
  63. return b.h.GetId()
  64. }
  65. func (b baseHostGetter) Name() string {
  66. return b.h.GetName()
  67. }
  68. func (b baseHostGetter) Zone() *computemodels.SZone {
  69. return b.h.Zone
  70. }
  71. func (b baseHostGetter) Host() *computemodels.SHost {
  72. return b.h.SHost
  73. }
  74. func (b baseHostGetter) IsArmHost() bool {
  75. return b.h.IsArmHost()
  76. }
  77. func (b baseHostGetter) IsRISCVHost() bool {
  78. return b.h.IsRISCVHost()
  79. }
  80. func (b baseHostGetter) CPUArch() string {
  81. return b.h.CpuArchitecture
  82. }
  83. func (b baseHostGetter) KvmCapMaxVcpuCount() int64 {
  84. return int64(b.h.KvmCapMaxVcpu)
  85. }
  86. func (b baseHostGetter) Cloudprovider() *computemodels.SCloudprovider {
  87. return b.h.Cloudprovider
  88. }
  89. func (b baseHostGetter) IsPublic() bool {
  90. return b.h.IsPublic
  91. /*provider := b.Cloudprovider()
  92. if provider == nil {
  93. return false
  94. }
  95. account := provider.GetCloudaccount()
  96. if account == nil {
  97. return false
  98. }
  99. return account.ShareMode == computeapi.CLOUD_ACCOUNT_SHARE_MODE_SYSTEM*/
  100. }
  101. func (b baseHostGetter) KeywordPlural() string {
  102. return b.h.KeywordPlural()
  103. }
  104. func (b baseHostGetter) DomainId() string {
  105. return b.h.DomainId
  106. }
  107. func (b baseHostGetter) PublicScope() string {
  108. return b.h.PublicScope
  109. }
  110. func (b baseHostGetter) SharedDomains() []string {
  111. return b.h.SharedDomains
  112. }
  113. func (b baseHostGetter) Region() *computemodels.SCloudregion {
  114. return b.h.Region
  115. }
  116. func (b baseHostGetter) HostType() string {
  117. return b.h.HostType
  118. }
  119. func (b baseHostGetter) Sku(instanceType string) *sku.ServerSku {
  120. zone := b.Zone()
  121. return sku.GetByZone(instanceType, zone.CloudregionId, zone.GetId())
  122. }
  123. func (b baseHostGetter) Storages() []*api.CandidateStorage {
  124. return b.h.Storages
  125. }
  126. func (b baseHostGetter) InstanceGroups() map[string]*api.CandidateGroup {
  127. return b.h.InstanceGroups
  128. }
  129. func (b baseHostGetter) GetAllClassMetadata() (map[string]string, error) {
  130. return b.h.ClassMetadata, nil
  131. }
  132. func (b baseHostGetter) GetFreeGroupCount(groupId string) (int, error) {
  133. // Must Be
  134. scg, ok := b.h.InstanceGroups[groupId]
  135. if !ok {
  136. return 0, errors.Wrap(core.ErrInstanceGroupNotFound, groupId)
  137. }
  138. free := scg.Granularity - scg.ReferCount
  139. if free < 1 {
  140. return 0, nil
  141. }
  142. pendingScg, ok := b.h.GetPendingUsage().InstanceGroupUsage[groupId]
  143. if ok {
  144. free -= pendingScg.ReferCount
  145. }
  146. return free, nil
  147. }
  148. func (b baseHostGetter) Networks() []*api.CandidateNetwork {
  149. return b.h.Networks
  150. }
  151. func (b baseHostGetter) OvnCapable() bool {
  152. return false
  153. }
  154. func (b baseHostGetter) ResourceType() string {
  155. return reviseResourceType(b.h.ResourceType)
  156. }
  157. func (b baseHostGetter) NetInterfaces() map[string][]computemodels.SNetInterface {
  158. return b.h.NetInterfaces
  159. }
  160. func (b baseHostGetter) Status() string {
  161. return b.h.Status
  162. }
  163. func (b baseHostGetter) HostStatus() string {
  164. return b.h.HostStatus
  165. }
  166. func (b baseHostGetter) Enabled() bool {
  167. return b.h.GetEnabled()
  168. }
  169. func (b baseHostGetter) ProjectGuests() map[string]int64 {
  170. return b.h.Tenants
  171. }
  172. func (b baseHostGetter) CreatingGuestCount() int {
  173. return 0
  174. }
  175. func (b baseHostGetter) RunningCPUCount() int64 {
  176. return 0
  177. }
  178. func (b baseHostGetter) TotalCPUCount(_ bool) int64 {
  179. return int64(b.h.CpuCount)
  180. }
  181. func (b baseHostGetter) RunningMemorySize() int64 {
  182. return 0
  183. }
  184. func (b baseHostGetter) TotalMemorySize(_ bool) int64 {
  185. return int64(b.h.MemSize)
  186. }
  187. func checkStorageSize(s *api.CandidateStorage, reqMaxSize int64, useRsvd bool) error {
  188. storageSize := s.FreeCapacity
  189. if useRsvd {
  190. storageSize += s.GetReserved()
  191. }
  192. minSize := utils.Min(storageSize, s.ActualFreeCapacity)
  193. if minSize >= reqMaxSize {
  194. return nil
  195. }
  196. return errors.Errorf("storage %q free size %d less than max request %d, use reserverd %v, free_capacity(%d), actual_free_capacity(%d)", s.GetName(), minSize, reqMaxSize, useRsvd, storageSize, s.ActualFreeCapacity)
  197. }
  198. func IsStorageBackendMediumMatch(s *api.CandidateStorage, backend string, mediumType string) bool {
  199. if s.StorageType != backend {
  200. return false
  201. }
  202. if mediumType == "" {
  203. return true
  204. }
  205. return s.MediumType == mediumType
  206. }
  207. func (b baseHostGetter) GetFreeStorageSizeOfType(storageType string, mediumType string, useRsvd bool, reqMaxSize int64) (int64, int64, error) {
  208. var size int64
  209. var actualSize int64
  210. foundLEReqStore := false
  211. errs := make([]error, 0)
  212. for _, s := range b.Storages() {
  213. if IsStorageBackendMediumMatch(s, storageType, mediumType) {
  214. size += s.FreeCapacity
  215. actualSize += s.ActualFreeCapacity
  216. if err := checkStorageSize(s, reqMaxSize, false); err != nil {
  217. errs = append(errs, err)
  218. } else {
  219. foundLEReqStore = true
  220. }
  221. }
  222. }
  223. if foundLEReqStore {
  224. return size, actualSize, nil
  225. }
  226. return size, actualSize, errors.NewAggregate(errs)
  227. }
  228. func (b baseHostGetter) GetFreePort(netId string) int {
  229. return b.h.GetFreePort(netId)
  230. }
  231. func (b baseHostGetter) GetIpmiInfo() types.SIPMIInfo {
  232. return b.h.IpmiInfo
  233. }
  234. func (b baseHostGetter) GetNics() []*types.SNic {
  235. return b.h.Nics
  236. }
  237. func (b baseHostGetter) GetQuotaKeys(s *api.SchedInfo) computemodels.SComputeResourceKeys {
  238. return b.h.getQuotaKeys(s)
  239. }
  240. func (b baseHostGetter) GetPendingUsage() *schedmodels.SPendingUsage {
  241. return b.h.GetPendingUsage()
  242. }
  243. func (b baseHostGetter) UnusedIsolatedDevices() []*core.IsolatedDeviceDesc {
  244. return b.h.UnusedIsolatedDevices()
  245. }
  246. func (b baseHostGetter) UnusedIsolatedDevicesByType(devType string) []*core.IsolatedDeviceDesc {
  247. return b.h.UnusedIsolatedDevicesByType(devType)
  248. }
  249. func (b baseHostGetter) UnusedIsolatedDevicesByVendorModel(vendorModel string) []*core.IsolatedDeviceDesc {
  250. return b.h.UnusedIsolatedDevicesByVendorModel(vendorModel)
  251. }
  252. func (b baseHostGetter) UnusedIsolatedDevicesByDevicePath(devPath string) []*core.IsolatedDeviceDesc {
  253. return b.h.UnusedIsolatedDevicesByDevicePath(devPath)
  254. }
  255. func (b baseHostGetter) UnusedIsolatedDevicesByModel(model string) []*core.IsolatedDeviceDesc {
  256. return b.h.UnusedIsolatedDevicesByModel(model)
  257. }
  258. func (b baseHostGetter) UnusedIsolatedDevicesByModelAndWire(model, wire string) []*core.IsolatedDeviceDesc {
  259. return b.h.UnusedIsolatedDevicesByModelAndWire(model, wire)
  260. }
  261. func (b baseHostGetter) GetIsolatedDevice(devID string) *core.IsolatedDeviceDesc {
  262. return b.h.GetIsolatedDevice(devID)
  263. }
  264. func (b baseHostGetter) UnusedGpuDevices() []*core.IsolatedDeviceDesc {
  265. return b.h.UnusedGpuDevices()
  266. }
  267. func (b baseHostGetter) GetIsolatedDevices() []*core.IsolatedDeviceDesc {
  268. return b.h.GetIsolatedDevices()
  269. }
  270. func reviseResourceType(resType string) string {
  271. if resType == "" {
  272. return computeapi.HostResourceTypeDefault
  273. }
  274. return resType
  275. }
  276. type networkGetter struct {
  277. netFreeMap *sync.Map
  278. }
  279. func newNetworkGetter() *networkGetter {
  280. return &networkGetter{
  281. netFreeMap: new(sync.Map),
  282. }
  283. }
  284. func shouldSkipLoadNetFromCache(host *computemodels.SHost) bool {
  285. if host.IsEmulated || host.HostType == computeapi.HOST_TYPE_ESXI {
  286. return true
  287. }
  288. return false
  289. }
  290. func (g *networkGetter) GetFreePort(host *computemodels.SHost, n *computemodels.SNetwork) (int, error) {
  291. if shouldSkipLoadNetFromCache(host) {
  292. // not calculate emulated host's network free address
  293. return -1, nil
  294. }
  295. if val, ok := g.netFreeMap.Load(n.GetId()); ok {
  296. return val.(int), nil
  297. }
  298. freePort, err := n.GetFreeAddressCount()
  299. if err != nil {
  300. return -1, errors.Wrapf(err, "GetFreeAddressCount for network %s(%s)", n.GetName(), n.GetId())
  301. }
  302. g.netFreeMap.Store(n.GetId(), freePort)
  303. return freePort, nil
  304. }
  305. func newBaseHostDesc(b *baseBuilder, host *computemodels.SHost, netGetter *networkGetter) (*BaseHostDesc, error) {
  306. host.ResourceType = reviseResourceType(host.ResourceType)
  307. desc := &BaseHostDesc{
  308. SHost: host,
  309. }
  310. if err := desc.fillCloudProvider(b, host); err != nil {
  311. return nil, fmt.Errorf("Fill cloudprovider info error: %v", err)
  312. }
  313. if err := desc.fillNetworks(host, netGetter); err != nil {
  314. return nil, fmt.Errorf("Fill networks error: %v", err)
  315. }
  316. // only onecloud host should fill onecloud vpc networks
  317. if sets.NewString(computeapi.HOST_TYPE_HYPERVISOR, computeapi.HOST_TYPE_CONTAINER).Has(host.HostType) && len(host.ManagerId) == 0 {
  318. if err := desc.fillOnecloudVpcNetworks(netGetter); err != nil {
  319. return nil, fmt.Errorf("Fill onecloud vpc networks error: %v", err)
  320. }
  321. if err := desc.fillOneCloudHostLocalNetworks(netGetter); err != nil {
  322. return nil, fmt.Errorf("Fill onecloud host local networks error: %v", err)
  323. }
  324. }
  325. if sets.NewString(computeapi.HOST_TYPE_HYPERVISOR, computeapi.HOST_TYPE_BAREMETAL, computeapi.HOST_TYPE_CONTAINER).Has(host.HostType) && len(host.ManagerId) > 0 {
  326. if err := desc.fillCloudpodsVpcNetworks(netGetter); err != nil {
  327. return nil, fmt.Errorf("Fill cloudpods vpc networks error: %v", err)
  328. }
  329. if err := desc.fillCloudpodsHostLocalNetworks(netGetter); err != nil {
  330. return nil, fmt.Errorf("Fill cloudpods host local networks error: %v", err)
  331. }
  332. }
  333. if err := desc.fillZone(host); err != nil {
  334. return nil, fmt.Errorf("Fill zone error: %v", err)
  335. }
  336. if err := desc.fillRegion(host); err != nil {
  337. return nil, fmt.Errorf("Fill region error: %v", err)
  338. }
  339. if err := desc.fillStorages(host); err != nil {
  340. return nil, fmt.Errorf("Fill storage error: %v", err)
  341. }
  342. if err := desc.fillInstanceGroups(host); err != nil {
  343. return nil, fmt.Errorf("Fill instance group error: %v", err)
  344. }
  345. if err := desc.fillClassMetadata(host); err != nil {
  346. return nil, fmt.Errorf("Fill class metadata error: %v", err)
  347. }
  348. if err := desc.fillIpmiInfo(host); err != nil {
  349. return nil, fmt.Errorf("Fill ipmi info error: %v", err)
  350. }
  351. if err := desc.fillNics(host); err != nil {
  352. return nil, fmt.Errorf("Fill nics info error: %v", err)
  353. }
  354. if err := desc.fillIsolatedDevices(b, host); err != nil {
  355. return nil, fmt.Errorf("Fill isolated devices error: %v", err)
  356. }
  357. desc.fillSharedDomains()
  358. desc.PendingUsage = desc.GetPendingUsage().ToMap()
  359. return desc, nil
  360. }
  361. func (b BaseHostDesc) GetSchedDesc() *jsonutils.JSONDict {
  362. desc := jsonutils.Marshal(b.SHost).(*jsonutils.JSONDict)
  363. if b.Cloudprovider != nil {
  364. p := b.Cloudprovider
  365. cloudproviderDesc := jsonutils.NewDict()
  366. cloudproviderDesc.Add(jsonutils.NewString(p.ProjectId), "tenant_id")
  367. cloudproviderDesc.Add(jsonutils.NewString(p.Provider), "provider")
  368. desc.Add(cloudproviderDesc, "cloudprovider")
  369. }
  370. return desc
  371. }
  372. func (b *BaseHostDesc) GetPendingUsage() *schedmodels.SPendingUsage {
  373. usage, err := schedmodels.HostPendingUsageManager.GetPendingUsage(b.GetId())
  374. if err != nil {
  375. return schedmodels.NewPendingUsageBySchedInfo(b.GetId(), nil, nil)
  376. }
  377. return usage
  378. }
  379. func (b *BaseHostDesc) GetFreePort(netId string) int {
  380. var selNet *api.CandidateNetwork = nil
  381. for _, n := range b.Networks {
  382. if n.GetId() == netId {
  383. selNet = n
  384. break
  385. }
  386. }
  387. if selNet == nil {
  388. return 0
  389. }
  390. if shouldSkipLoadNetFromCache(b.SHost) {
  391. freeCount, _ := selNet.GetFreeAddressCount()
  392. return freeCount
  393. }
  394. return selNet.FreePort
  395. }
  396. func (b BaseHostDesc) GetResourceType() string {
  397. return b.ResourceType
  398. }
  399. func (h *BaseHostDesc) UnusedIsolatedDevices() []*core.IsolatedDeviceDesc {
  400. ret := make([]*core.IsolatedDeviceDesc, 0)
  401. for _, dev := range h.IsolatedDevices {
  402. if len(dev.GuestID) == 0 {
  403. ret = append(ret, dev)
  404. }
  405. }
  406. return ret
  407. }
  408. func (h *BaseHostDesc) UnusedIsolatedDevicesByType(devType string) []*core.IsolatedDeviceDesc {
  409. ret := make([]*core.IsolatedDeviceDesc, 0)
  410. for _, dev := range h.UnusedIsolatedDevices() {
  411. if dev.DevType == devType {
  412. ret = append(ret, dev)
  413. }
  414. }
  415. return ret
  416. }
  417. func (h *BaseHostDesc) UnusedIsolatedDevicesByVendorModel(vendorModel string) []*core.IsolatedDeviceDesc {
  418. ret := make([]*core.IsolatedDeviceDesc, 0)
  419. vm := core.NewVendorModelByStr(vendorModel)
  420. for _, dev := range h.UnusedIsolatedDevices() {
  421. if dev.GetVendorModel().IsMatch(vm) {
  422. ret = append(ret, dev)
  423. }
  424. }
  425. return ret
  426. }
  427. func (h *BaseHostDesc) UnusedIsolatedDevicesByModel(model string) []*core.IsolatedDeviceDesc {
  428. ret := make([]*core.IsolatedDeviceDesc, 0)
  429. for _, dev := range h.UnusedIsolatedDevices() {
  430. if strings.Contains(dev.Model, model) {
  431. ret = append(ret, dev)
  432. }
  433. }
  434. return ret
  435. }
  436. func (h *BaseHostDesc) UnusedIsolatedDevicesByDevicePath(devPath string) []*core.IsolatedDeviceDesc {
  437. ret := make([]*core.IsolatedDeviceDesc, 0)
  438. for _, dev := range h.UnusedIsolatedDevices() {
  439. if devPath == dev.DevicePath {
  440. ret = append(ret, dev)
  441. }
  442. }
  443. return ret
  444. }
  445. func (h *BaseHostDesc) UnusedIsolatedDevicesByModelAndWire(model, wire string) []*core.IsolatedDeviceDesc {
  446. ret := make([]*core.IsolatedDeviceDesc, 0)
  447. for _, dev := range h.UnusedIsolatedDevices() {
  448. log.Errorf("dev wire is %s, dev model is %s, request model is %s, request wire is %s", dev.Model, dev.WireId, model, wire)
  449. if strings.Contains(dev.Model, model) && dev.WireId == wire {
  450. ret = append(ret, dev)
  451. }
  452. }
  453. return ret
  454. }
  455. func (h *BaseHostDesc) GetIsolatedDevice(devID string) *core.IsolatedDeviceDesc {
  456. for _, dev := range h.IsolatedDevices {
  457. if dev.ID == devID {
  458. return dev
  459. }
  460. }
  461. return nil
  462. }
  463. func (h *BaseHostDesc) GetIsolatedDevices() []*core.IsolatedDeviceDesc {
  464. return h.IsolatedDevices
  465. }
  466. func (h *BaseHostDesc) UnusedGpuDevices() []*core.IsolatedDeviceDesc {
  467. ret := make([]*core.IsolatedDeviceDesc, 0)
  468. for _, dev := range h.UnusedIsolatedDevices() {
  469. if strings.HasPrefix(dev.DevType, "GPU") {
  470. ret = append(ret, dev)
  471. }
  472. }
  473. return ret
  474. }
  475. func (h *BaseHostDesc) fillIsolatedDevices(b *baseBuilder, host *computemodels.SHost) error {
  476. allDevs := b.getIsolatedDevices(host.Id)
  477. if len(allDevs) == 0 {
  478. return nil
  479. }
  480. devs := make([]*core.IsolatedDeviceDesc, len(allDevs))
  481. for index, devModel := range allDevs {
  482. dev := &core.IsolatedDeviceDesc{
  483. ID: devModel.Id,
  484. GuestID: devModel.GuestId,
  485. HostID: devModel.HostId,
  486. DevType: devModel.DevType,
  487. Model: devModel.Model,
  488. Addr: devModel.Addr,
  489. VendorDeviceID: devModel.VendorDeviceId,
  490. WireId: devModel.WireId,
  491. DevicePath: devModel.DevicePath,
  492. }
  493. devs[index] = dev
  494. }
  495. h.IsolatedDevices = devs
  496. return nil
  497. }
  498. func (b *BaseHostDesc) fillCloudProvider(builder *baseBuilder, host *computemodels.SHost) error {
  499. provider, ok := builder.hostCloudproviers[host.GetId()]
  500. if !ok {
  501. return nil
  502. }
  503. b.Cloudprovider = provider
  504. account, ok := builder.hostCloudaccounts[host.GetId()]
  505. if !ok {
  506. return nil
  507. }
  508. b.Cloudaccount = account
  509. return nil
  510. }
  511. func (b *BaseHostDesc) fillRegion(host *computemodels.SHost) error {
  512. regionId := b.Zone.GetCloudRegionId()
  513. obj, ok := cloudregion.Manager.GetResource(regionId)
  514. if !ok {
  515. return errors.Errorf("Not found cloudregion by host %q with id %q", host.GetName(), regionId)
  516. }
  517. b.Region = &obj
  518. return nil
  519. }
  520. func (b *BaseHostDesc) fillZone(host *computemodels.SHost) error {
  521. obj, ok := zone.Manager.GetResource(host.ZoneId)
  522. if !ok {
  523. return errors.Errorf("Not found zone by host %q with id %q", host.GetName(), host.ZoneId)
  524. }
  525. b.Zone = &obj
  526. b.ZoneId = host.ZoneId
  527. return nil
  528. }
  529. // func (b *BaseHostDesc) fillResidentTenants(host *computemodels.SHost) error {
  530. // rets, err := HostResidentTenantCount(host.Id)
  531. // if err != nil {
  532. // return err
  533. // }
  534. //
  535. // b.Tenants = rets
  536. //
  537. // return nil
  538. // }
  539. func (b *BaseHostDesc) fillSharedDomains() error {
  540. b.SharedDomains = b.SHost.GetSharedDomains()
  541. return nil
  542. }
  543. func (b *BaseHostDesc) fillNetworks(host *computemodels.SHost, netGetter *networkGetter) error {
  544. hostId := host.Id
  545. netifs := netinterface.GetByHost(hostId)
  546. wireIds := sets.NewString()
  547. for _, netif := range netifs {
  548. if netif.NicType != computeapi.NIC_TYPE_IPMI && len(netif.WireId) > 0 {
  549. wireIds.Insert(netif.WireId)
  550. }
  551. }
  552. nets := make([]computemodels.SNetwork, 0)
  553. allNets := network.Manager.GetStore().GetAll()
  554. for _, net := range allNets {
  555. netAdditionalWireIds := network_additional_wire.FetchNetworkAdditionalWireIds(net.Id)
  556. if wireIds.Has(net.WireId) || wireIds.HasAny(netAdditionalWireIds...) {
  557. nets = append(nets, net)
  558. }
  559. }
  560. b.Networks = make([]*api.CandidateNetwork, len(nets))
  561. for idx, n := range nets {
  562. freePort, err := netGetter.GetFreePort(host, &n)
  563. if err != nil {
  564. return errors.Wrapf(err, "GetFreePort for network %s(%s)", n.GetName(), n.GetId())
  565. }
  566. b.Networks[idx] = &api.CandidateNetwork{
  567. SNetwork: &nets[idx],
  568. FreePort: freePort,
  569. }
  570. }
  571. // netifs := host.GetNetInterfaces()
  572. // netifs := netinterface.GetByHost(hostId)
  573. netifIndexs := make(map[string][]computemodels.SNetInterface, 0)
  574. for _, netif := range netifs {
  575. if !netif.IsUsableServernic() {
  576. continue
  577. }
  578. wireId := netif.WireId
  579. if _, exist := netifIndexs[wireId]; !exist {
  580. netifIndexs[wireId] = make([]computemodels.SNetInterface, 0)
  581. }
  582. netifIndexs[wireId] = append(netifIndexs[wireId], netif)
  583. }
  584. b.NetInterfaces = netifIndexs
  585. return nil
  586. }
  587. func (b *BaseHostDesc) fillCloudpodsVpcNetworks(netGetter *networkGetter) error {
  588. nets := computemodels.NetworkManager.Query()
  589. wires := computemodels.WireManager.Query().SubQuery()
  590. vpcs := computemodels.VpcManager.Query().SubQuery()
  591. regions := computemodels.CloudregionManager.Query().Equals("provider", computeapi.CLOUD_PROVIDER_CLOUDPODS).SubQuery()
  592. q := nets.AppendField(nets.QueryFields()...)
  593. q = q.AppendField(
  594. vpcs.Field("id", "vpc_id"),
  595. regions.Field("provider"),
  596. )
  597. q = q.Join(wires, sqlchemy.Equals(wires.Field("id"), nets.Field("wire_id")))
  598. q = q.Join(vpcs, sqlchemy.Equals(vpcs.Field("id"), wires.Field("vpc_id")))
  599. q = q.Join(regions, sqlchemy.Equals(regions.Field("id"), vpcs.Field("cloudregion_id")))
  600. q = q.Filter(
  601. sqlchemy.NOT(sqlchemy.Equals(vpcs.Field("external_id"), computeapi.DEFAULT_VPC_ID)),
  602. )
  603. return b.fillNetworksByQuery(netGetter, q)
  604. }
  605. func (b *BaseHostDesc) fillOnecloudVpcNetworks(netGetter *networkGetter) error {
  606. nets := computemodels.NetworkManager.Query()
  607. wires := computemodels.WireManager.Query().SubQuery()
  608. vpcs := computemodels.VpcManager.Query().SubQuery()
  609. regions := computemodels.CloudregionManager.Query().Equals("provider", computeapi.CLOUD_PROVIDER_ONECLOUD).SubQuery()
  610. q := nets.AppendField(nets.QueryFields()...)
  611. q = q.AppendField(
  612. vpcs.Field("id", "vpc_id"),
  613. regions.Field("provider"),
  614. )
  615. q = q.Join(wires, sqlchemy.Equals(wires.Field("id"), nets.Field("wire_id")))
  616. q = q.Join(vpcs, sqlchemy.Equals(vpcs.Field("id"), wires.Field("vpc_id")))
  617. q = q.Join(regions, sqlchemy.Equals(regions.Field("id"), vpcs.Field("cloudregion_id")))
  618. q = q.Filter(
  619. sqlchemy.NOT(sqlchemy.Equals(vpcs.Field("id"), computeapi.DEFAULT_VPC_ID)),
  620. )
  621. return b.fillNetworksByQuery(netGetter, q)
  622. }
  623. func (b *BaseHostDesc) fillOneCloudHostLocalNetworks(netGetter *networkGetter) error {
  624. nets := computemodels.NetworkManager.Query()
  625. wires := computemodels.WireManager.Query().Equals("id", computeapi.DEFAULT_HOST_LOCAL_WIRE_ID).SubQuery()
  626. vpcs := computemodels.VpcManager.Query().Equals("id", computeapi.DEFAULT_VPC_ID).SubQuery()
  627. regions := computemodels.CloudregionManager.Query().Equals("provider", computeapi.CLOUD_PROVIDER_ONECLOUD).SubQuery()
  628. q := nets.AppendField(nets.QueryFields()...)
  629. q = q.AppendField(
  630. vpcs.Field("id", "vpc_id"),
  631. regions.Field("provider"),
  632. )
  633. q = q.Join(wires, sqlchemy.Equals(wires.Field("id"), nets.Field("wire_id")))
  634. q = q.Join(vpcs, sqlchemy.Equals(vpcs.Field("id"), wires.Field("vpc_id")))
  635. q = q.Join(regions, sqlchemy.Equals(regions.Field("id"), vpcs.Field("cloudregion_id")))
  636. return b.fillNetworksByQuery(netGetter, q)
  637. }
  638. func (b *BaseHostDesc) fillCloudpodsHostLocalNetworks(netGetter *networkGetter) error {
  639. nets := computemodels.NetworkManager.Query()
  640. wires := computemodels.WireManager.Query().Equals("external_id", computeapi.DEFAULT_HOST_LOCAL_WIRE_ID).SubQuery()
  641. vpcs := computemodels.VpcManager.Query().Equals("external_id", computeapi.DEFAULT_VPC_ID).SubQuery()
  642. regions := computemodels.CloudregionManager.Query().Equals("provider", computeapi.CLOUD_PROVIDER_CLOUDPODS).SubQuery()
  643. q := nets.AppendField(nets.QueryFields()...)
  644. q = q.AppendField(
  645. vpcs.Field("id", "vpc_id"),
  646. regions.Field("provider"),
  647. )
  648. q = q.Join(wires, sqlchemy.Equals(wires.Field("id"), nets.Field("wire_id")))
  649. q = q.Join(vpcs, sqlchemy.Equals(vpcs.Field("id"), wires.Field("vpc_id")))
  650. q = q.Join(regions, sqlchemy.Equals(regions.Field("id"), vpcs.Field("cloudregion_id")))
  651. return b.fillNetworksByQuery(netGetter, q)
  652. }
  653. func (b *BaseHostDesc) fillNetworksByQuery(netGetter *networkGetter, q *sqlchemy.SQuery) error {
  654. type Row struct {
  655. computemodels.SNetwork
  656. VpcId string
  657. Provider string
  658. }
  659. rows := []Row{}
  660. if err := q.All(&rows); err != nil {
  661. return errors.Wrap(err, "query onecloud vpc networks")
  662. }
  663. for i := range rows {
  664. row := &rows[i]
  665. net := &row.SNetwork
  666. net.SetModelManager(computemodels.NetworkManager, net)
  667. freePort, err := netGetter.GetFreePort(b.SHost, net)
  668. if err != nil {
  669. return errors.Wrapf(err, "GetFreeAddressCount for network %s(%s)", net.GetName(), net.GetId())
  670. }
  671. candidateNet := &api.CandidateNetwork{
  672. SNetwork: net,
  673. FreePort: freePort,
  674. VpcId: row.VpcId,
  675. Provider: row.Provider,
  676. }
  677. b.Networks = append(b.Networks, candidateNet)
  678. }
  679. return nil
  680. }
  681. func (b *BaseHostDesc) GetHypervisorDriver() computemodels.IGuestDriver {
  682. if b.Region == nil {
  683. return nil
  684. }
  685. hostDriver, _ := computemodels.GetHostDriver(b.HostType, b.Region.Provider)
  686. if hostDriver == nil {
  687. return nil
  688. }
  689. driver, _ := computemodels.GetDriver(hostDriver.GetHypervisor(), b.Region.Provider)
  690. return driver
  691. }
  692. func (b *BaseHostDesc) fillStorages(host *computemodels.SHost) error {
  693. ss := make([]*api.CandidateStorage, 0)
  694. storages, err := host.GetStorages()
  695. if err != nil {
  696. return errors.Wrapf(err, "host %s/%s get storages", b.Name, b.Id)
  697. }
  698. for _, tmpS := range storages {
  699. storage := tmpS
  700. cs := &api.CandidateStorage{
  701. SStorage: &storage,
  702. ActualFreeCapacity: storage.Capacity - storage.ActualCapacityUsed,
  703. }
  704. driver := b.GetHypervisorDriver()
  705. if driver == nil || driver.DoScheduleStorageFilter() {
  706. cs.FreeCapacity = storage.GetFreeCapacity()
  707. }
  708. ss = append(ss, cs)
  709. }
  710. b.Storages = ss
  711. return nil
  712. }
  713. func (b *BaseHostDesc) fillInstanceGroups(host *computemodels.SHost) error {
  714. candidateSet := make(map[string]*api.CandidateGroup)
  715. groups, groupSet, err := host.InstanceGroups()
  716. if err != nil {
  717. b.InstanceGroups = candidateSet
  718. return err
  719. }
  720. for i := range groups {
  721. id := groups[i].GetId()
  722. candidateSet[id] = &api.CandidateGroup{
  723. SGroup: &groups[i],
  724. ReferCount: groupSet[id],
  725. }
  726. }
  727. b.InstanceGroups = candidateSet
  728. return nil
  729. }
  730. func (b *BaseHostDesc) fillClassMetadata(host *computemodels.SHost) error {
  731. cm, err := host.GetAllClassMetadata()
  732. if err != nil {
  733. return err
  734. }
  735. b.ClassMetadata = cm
  736. return nil
  737. }
  738. func (b *BaseHostDesc) fillIpmiInfo(host *computemodels.SHost) error {
  739. info, err := host.GetIpmiInfo()
  740. if err != nil {
  741. return err
  742. }
  743. b.IpmiInfo = info
  744. return nil
  745. }
  746. func (b *BaseHostDesc) fillNics(host *computemodels.SHost) error {
  747. b.Nics = host.GetNics()
  748. return nil
  749. }
  750. func (h *BaseHostDesc) GetEnableStatus() string {
  751. if h.GetEnabled() {
  752. return "enable"
  753. }
  754. return "disable"
  755. }
  756. func (h *BaseHostDesc) GetHostType() string {
  757. if h.HostType == api.HostTypeBaremetal && h.IsBaremetal {
  758. return api.HostTypeBaremetal
  759. }
  760. return h.HostType
  761. }
  762. func (h *BaseHostDesc) getQuotaKeys(s *api.SchedInfo) computemodels.SComputeResourceKeys {
  763. computeKeys := computemodels.SComputeResourceKeys{}
  764. computeKeys.DomainId = s.Domain
  765. computeKeys.ProjectId = s.Project
  766. if h.Cloudprovider != nil {
  767. computeKeys.Provider = h.Cloudaccount.Provider
  768. computeKeys.Brand = h.Cloudaccount.Brand
  769. computeKeys.CloudEnv = h.Cloudaccount.GetCloudEnv()
  770. computeKeys.AccountId = h.Cloudaccount.Id
  771. computeKeys.ManagerId = h.Cloudprovider.Id
  772. } else {
  773. computeKeys.Provider = computeapi.CLOUD_PROVIDER_ONECLOUD
  774. computeKeys.Brand = computeapi.ONECLOUD_BRAND_ONECLOUD
  775. computeKeys.CloudEnv = computeapi.CLOUD_ENV_ON_PREMISE
  776. computeKeys.AccountId = ""
  777. computeKeys.ManagerId = ""
  778. }
  779. computeKeys.RegionId = h.Region.Id
  780. computeKeys.ZoneId = h.Zone.Id
  781. driver, _ := computemodels.GetHostDriver(h.HostType, computeKeys.Provider)
  782. if driver != nil {
  783. computeKeys.Hypervisor = driver.GetHypervisor()
  784. }
  785. return computeKeys
  786. }
  787. func HostsResidentTenantStats(hostIDs []string) (map[string]map[string]interface{}, error) {
  788. residentTenantStats, err := FetchHostsResidentTenants(hostIDs)
  789. if err != nil {
  790. return nil, err
  791. }
  792. stat3 := make([]utils.StatItem3, len(residentTenantStats))
  793. for i, item := range residentTenantStats {
  794. stat3[i] = item
  795. }
  796. return utils.ToStatDict3(stat3)
  797. }
  798. func HostResidentTenantCount(id string) (map[string]int64, error) {
  799. residentTenantDict, err := HostsResidentTenantStats([]string{id})
  800. if err != nil {
  801. return nil, err
  802. }
  803. tenantMap, ok := residentTenantDict[id]
  804. if !ok {
  805. log.V(10).Infof("Not found host ID: %s when fill resident tenants, may be no guests on it.", id)
  806. return nil, nil
  807. }
  808. rets := make(map[string]int64, len(tenantMap))
  809. for tenantID, countObj := range tenantMap {
  810. rets[tenantID] = countObj.(int64)
  811. }
  812. return rets, nil
  813. }
  814. type DescBuilder struct {
  815. actor BuildActor
  816. isolatedDevicesDict map[string][]interface{}
  817. }
  818. func NewDescBuilder(act BuildActor) *DescBuilder {
  819. return &DescBuilder{
  820. actor: act,
  821. }
  822. }
  823. func (d *DescBuilder) Build(ids []string) ([]interface{}, error) {
  824. return d.actor.Do(ids)
  825. }