api.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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 scheduler
  15. import (
  16. "yunion.io/x/jsonutils"
  17. "yunion.io/x/onecloud/pkg/apis"
  18. "yunion.io/x/onecloud/pkg/apis/compute"
  19. )
  20. type ScheduleBaseConfig struct {
  21. BestEffort bool `json:"best_effort"`
  22. SuggestionLimit int64 `json:"suggestion_limit"`
  23. SuggestionAll bool `json:"suggestion_all"`
  24. IgnoreFilters []string `json:"ignore_filters"`
  25. SessionId string `json:"session_id"`
  26. // usedby test api
  27. RecordLog bool `json:"record_to_history"`
  28. Details bool `json:"details"`
  29. }
  30. type ForGuest struct {
  31. Id string `json:"id"`
  32. Name string `json:"name"`
  33. }
  34. type GroupRelation struct {
  35. GroupId string `json:"group_id"`
  36. Strategy string `json:"strategy"`
  37. Scope string `json:"scope"`
  38. }
  39. type ServerConfig struct {
  40. *compute.ServerConfigs
  41. Memory int `json:"vmem_size"`
  42. Ncpu int `json:"vcpu_count"`
  43. Name string `json:"name"`
  44. GuestStatus string `json:"guest_status"`
  45. Cdrom string `json:"cdrom"`
  46. Bios string `json:"bios"`
  47. // owner project id
  48. Project string `json:"project_id"`
  49. // owner domain id
  50. Domain string `json:"domain_id"`
  51. // Deprecated
  52. Metadata map[string]string `json:"__meta__"`
  53. ForGuests []*ForGuest `json:"for_guests"`
  54. GroupRelations []*GroupRelation `json:"group_releations"`
  55. Groups interface{} `json:"groups"`
  56. Id string `json:"id"`
  57. InstanceSnapshotId string `json:"instance_snapshot_id"`
  58. InstanceBackupId string `json:"instance_backup_id"`
  59. }
  60. // ScheduleInput used by scheduler sync-schedule/test/forecast api
  61. type ScheduleInput struct {
  62. apis.Meta
  63. ScheduleBaseConfig
  64. ServerConfig
  65. // HostId used by migrate
  66. HostId string `json:"host_id"`
  67. LiveMigrate bool `json:"live_migrate"`
  68. SkipCpuCheck *bool `json:"skip_cpu_check"`
  69. CpuDesc string `json:"cpu_desc"`
  70. CpuMicrocode string `json:"cpu_microcode"`
  71. CpuMode string `json:"cpu_mode"`
  72. OsArch string `json:"os_arch"`
  73. ResetCpuNumaPin bool `json:"reset_cpu_numa_pin"`
  74. ExtraCpuCount int `json:"extra_cpu_count"`
  75. CpuNumaPin []SCpuNumaPin `json:"cpu_numa_pin"`
  76. PreferNumaNodes []int `json:"prefer_numa_nodes"`
  77. // GuestIds
  78. GuestIds []string `json:"guest_ids"`
  79. HostMemPageSizeKB int `json:"host_mem_page_size"`
  80. SkipKernelCheck *bool `json:"skip_kernel_check"`
  81. TargetHostKernel string `json:"target_host_kernel"`
  82. // In the migrate and create backup cases
  83. // we don't need reallocate network
  84. ReuseNetwork bool `json:"reuse_network"`
  85. // Change config
  86. ChangeConfig bool `json:"change_config"`
  87. // guest who change config has isolated device
  88. HasIsolatedDevice bool `json:"has_isolated_device"`
  89. PendingUsages []jsonutils.JSONObject `json:"pending_usages"`
  90. }
  91. func (input ScheduleInput) ToConditionInput() *jsonutils.JSONDict {
  92. ret := input.JSON(input)
  93. // old condition compatible
  94. ret.Add(jsonutils.NewString(input.Project), "owner_tenant_id")
  95. return ret
  96. }
  97. type CandidateDisk struct {
  98. Index int `json:"index"`
  99. StorageIds []string `json:"storage_ids"`
  100. }
  101. type CandidateDiskV2 struct {
  102. Index int `json:"index"`
  103. Storages []*CandidateStorage `json:"storages"`
  104. }
  105. type CandidateStorage struct {
  106. Id string `json:"id"`
  107. Name string `json:"name"`
  108. FreeCapacity int64 `json:"free_capacity"`
  109. }
  110. type CandidateNet struct {
  111. Index int `json:"index"`
  112. NetworkIds []string `json:"network_ids"`
  113. }
  114. type SFreeNumaCpuMem struct {
  115. FreeCpuCount int `json:"free_cpu_count"`
  116. MemSize int `json:"mem_size"`
  117. EnableNumaAllocate bool `json:"enable_numa_allocate"`
  118. CpuCount int `json:"cpu_count"`
  119. NodeId int `json:"node_id"`
  120. }
  121. type SortedFreeNumaCpuMam []*SFreeNumaCpuMem
  122. func (pq SortedFreeNumaCpuMam) Len() int { return len(pq) }
  123. func (pq SortedFreeNumaCpuMam) Less(i, j int) bool {
  124. if pq[i].EnableNumaAllocate {
  125. return pq[i].MemSize > pq[j].MemSize
  126. } else {
  127. return pq[i].FreeCpuCount > pq[j].FreeCpuCount
  128. }
  129. }
  130. func (pq SortedFreeNumaCpuMam) Swap(i, j int) {
  131. pq[i], pq[j] = pq[j], pq[i]
  132. }
  133. func NodesFreeMemSizeEnough(nodeCount, memSize int, cpuNumaFree []*SFreeNumaCpuMem) bool {
  134. if !cpuNumaFree[0].EnableNumaAllocate {
  135. return true
  136. }
  137. var freeMem = 0
  138. var leastFree = memSize / nodeCount
  139. for i := 0; i < nodeCount; i++ {
  140. if cpuNumaFree[i].MemSize < leastFree {
  141. return false
  142. }
  143. freeMem += cpuNumaFree[i].MemSize
  144. }
  145. return freeMem >= memSize
  146. }
  147. func NodesFreeCpuEnough(nodeCount, vcpuCount int, cpuNumaFree []*SFreeNumaCpuMem) bool {
  148. var freeCpu = 0
  149. var leaseCpu = vcpuCount / nodeCount
  150. //if vcpuCount > nodeCount*cpuNumaFree[0].CpuCount {
  151. // return false
  152. //}
  153. for i := 0; i < nodeCount; i++ {
  154. if cpuNumaFree[i].FreeCpuCount < leaseCpu {
  155. return false
  156. }
  157. freeCpu += cpuNumaFree[i].FreeCpuCount
  158. }
  159. return freeCpu >= vcpuCount
  160. }
  161. type SCpuPin struct {
  162. Vcpu int `json:"vcpu"`
  163. Pcpu int `json:"pcpu"`
  164. }
  165. type SCpuNumaPin struct {
  166. CpuPin []int `json:"cpu_pin"`
  167. NodeId int `json:"node_id"`
  168. MemSizeMB *int `json:"mem_size_mb"`
  169. ExtraCpuCount int `json:"extra_cpu_count"`
  170. }
  171. type CandidateResource struct {
  172. SessionId string `json:"session_id"`
  173. HostId string `json:"host_id"`
  174. Name string `json:"name"`
  175. CpuNumaPin []SCpuNumaPin `json:"cpu_numa_pin"`
  176. Disks []*CandidateDisk `json:"disks"`
  177. Nets []*CandidateNet `json:"nets"`
  178. // used by backup schedule
  179. BackupCandidate *CandidateResource `json:"backup_candidate"`
  180. // Error means no candidate found, include reasons
  181. Error string `json:"error"`
  182. }
  183. type ScheduleOutput struct {
  184. apis.Meta
  185. Candidates []*CandidateResource `json:"candidates"`
  186. }