devtools.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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 esxi
  15. import (
  16. "context"
  17. "fmt"
  18. "reflect"
  19. "github.com/vmware/govmomi/vim25/types"
  20. api "yunion.io/x/cloudmux/pkg/apis/compute"
  21. "yunion.io/x/pkg/errors"
  22. )
  23. type SDiskConfig struct {
  24. Uefi bool
  25. SizeMb int64
  26. Uuid string
  27. ControllerKey int32
  28. UnitNumber int32
  29. Key int32
  30. ImagePath string
  31. IsRoot bool
  32. Datastore *SDatastore
  33. Preallocation string
  34. }
  35. // In fact, it is the default lable of first one disk
  36. const rootDiskMark = "Hard disk 1"
  37. func NewDiskDev(ctx context.Context, sizeMb int64, config SDiskConfig) (*types.VirtualDisk, error) {
  38. device := types.VirtualDisk{}
  39. diskFile := types.VirtualDiskFlatVer2BackingInfo{}
  40. diskFile.DiskMode = "persistent"
  41. thinProvisioned := true
  42. if config.Preallocation == api.DISK_PREALLOCATION_FALLOC || config.Preallocation == api.DISK_PREALLOCATION_FULL {
  43. thinProvisioned = false
  44. if config.Preallocation == api.DISK_PREALLOCATION_FULL {
  45. diskFile.EagerlyScrub = types.NewBool(true)
  46. }
  47. }
  48. diskFile.ThinProvisioned = &thinProvisioned
  49. diskFile.Uuid = config.Uuid
  50. if len(config.ImagePath) > 0 {
  51. diskFile.FileName = config.ImagePath
  52. }
  53. if config.Datastore != nil {
  54. ds, err := config.Datastore.getDatastoreObj(ctx)
  55. if err != nil {
  56. return nil, errors.Wrapf(err, "getDatastoreObj")
  57. }
  58. ref := ds.Reference()
  59. diskFile.Datastore = &ref
  60. }
  61. device.Backing = &diskFile
  62. if sizeMb > 0 {
  63. device.CapacityInKB = sizeMb * 1024
  64. }
  65. device.ControllerKey = config.ControllerKey
  66. device.Key = config.Key
  67. device.UnitNumber = &config.UnitNumber
  68. var label string
  69. if config.IsRoot {
  70. label = rootDiskMark
  71. device.DeviceInfo = &types.Description{Label: label}
  72. }
  73. return &device, nil
  74. }
  75. func addDevSpec(device types.BaseVirtualDevice) *types.VirtualDeviceConfigSpec {
  76. spec := types.VirtualDeviceConfigSpec{}
  77. spec.Operation = types.VirtualDeviceConfigSpecOperationAdd
  78. spec.Device = device
  79. return &spec
  80. }
  81. func NewSCSIDev(key, ctlKey int32, driver string) types.BaseVirtualDevice {
  82. desc := types.Description{Label: "SCSI controller 0", Summary: "VMware virtual SCSI"}
  83. if driver == "pvscsi" {
  84. device := types.ParaVirtualSCSIController{}
  85. device.DeviceInfo = &desc
  86. device.Key = key
  87. device.ControllerKey = ctlKey
  88. device.SharedBus = "noSharing"
  89. return &device
  90. }
  91. device := types.VirtualLsiLogicController{}
  92. device.DeviceInfo = &desc
  93. device.Key = key
  94. device.ControllerKey = ctlKey
  95. device.SharedBus = "noSharing"
  96. return &device
  97. }
  98. func NewAHCIDev(key, ctlKey int32) types.BaseVirtualDevice {
  99. device := types.VirtualAHCIController{}
  100. device.DeviceInfo = &types.Description{Label: "SATA controller 0", Summary: "AHCI"}
  101. device.ControllerKey = ctlKey
  102. device.Key = key
  103. return &device
  104. }
  105. func NewSVGADev(key, ctlKey int32) types.BaseVirtualDevice {
  106. device := types.VirtualMachineVideoCard{}
  107. device.DeviceInfo = &types.Description{Label: "Video card", Summary: "Video card"}
  108. device.ControllerKey = ctlKey
  109. device.Key = key
  110. device.VideoRamSizeInKB = 16 * 1024
  111. return &device
  112. }
  113. func NewIDEDev(key, index int32) types.BaseVirtualDevice {
  114. device := types.VirtualIDEController{}
  115. s := fmt.Sprintf("IDE %d", index)
  116. device.DeviceInfo = &types.Description{Label: s, Summary: s}
  117. device.Key = key + index
  118. device.BusNumber = index
  119. return &device
  120. }
  121. func NewCDROMDev(path string, key, ctlKey int32) types.BaseVirtualDevice {
  122. device := types.VirtualCdrom{}
  123. device.DeviceInfo = &types.Description{Label: "CD/DVD drive 1", Summary: "Local ISO Emulated CD-ROM"}
  124. device.ControllerKey = ctlKey
  125. device.Key = key
  126. connectable := types.VirtualDeviceConnectInfo{AllowGuestControl: true, Status: "untried"}
  127. if len(path) != 0 {
  128. device.Backing = &types.VirtualCdromIsoBackingInfo{
  129. VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{
  130. FileName: path,
  131. },
  132. }
  133. connectable.StartConnected = true
  134. } else {
  135. device.Backing = &types.VirtualCdromRemoteAtapiBackingInfo{}
  136. connectable.StartConnected = false
  137. }
  138. device.Connectable = &connectable
  139. return &device
  140. }
  141. func NewUSBController(key *int32) types.BaseVirtualDevice {
  142. device := types.VirtualUSBController{}
  143. device.DeviceInfo = &types.Description{
  144. Label: "USB controller",
  145. }
  146. if key != nil {
  147. device.Key = *key
  148. }
  149. return &device
  150. }
  151. var getNetwork func(bridge, vlanId string) (IVMNetwork, error)
  152. func NewVNICDev(host *SHost, mac, driver string, bridge string, vlanId int32, key, ctlKey, index int32) (types.BaseVirtualDevice, error) {
  153. desc := types.Description{Label: fmt.Sprintf("Network adapter %d", index+1), Summary: "VM Network"}
  154. inet, err := host.getNetworkById(bridge)
  155. if err != nil {
  156. return nil, errors.Wrapf(err, "GetNetworkById %s on host %s", bridge, host.GetName())
  157. }
  158. if inet == nil {
  159. return nil, errors.Wrapf(errors.ErrNotFound, "Bridge %s not found on host %s", bridge, host.GetName())
  160. }
  161. var backing types.BaseVirtualDeviceBackingInfo
  162. switch inet.(type) {
  163. case *SDistributedVirtualPortgroup:
  164. net := inet.(*SDistributedVirtualPortgroup)
  165. dvpg := net.getMODVPortgroup()
  166. uuid, err := net.GetDVSUuid()
  167. if err != nil {
  168. return nil, errors.Wrap(err, "GetDVSUuid")
  169. }
  170. portCon := types.DistributedVirtualSwitchPortConnection{
  171. PortgroupKey: dvpg.Key,
  172. SwitchUuid: uuid,
  173. }
  174. backing = &types.VirtualEthernetCardDistributedVirtualPortBackingInfo{Port: portCon}
  175. case *SNetwork:
  176. monet := inet.(*SNetwork).getMONetwork()
  177. backing = &types.VirtualEthernetCardNetworkBackingInfo{
  178. VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{
  179. DeviceName: monet.Name,
  180. UseAutoDetect: &False,
  181. },
  182. Network: &monet.Self,
  183. }
  184. default:
  185. return nil, errors.Error(fmt.Sprintf("Unsuppport network type %s", reflect.TypeOf(inet).Name()))
  186. }
  187. connectable := types.VirtualDeviceConnectInfo{
  188. StartConnected: true,
  189. AllowGuestControl: true,
  190. Connected: false,
  191. Status: "untried",
  192. }
  193. nic := types.VirtualEthernetCard{
  194. VirtualDevice: types.VirtualDevice{
  195. DeviceInfo: &desc,
  196. Backing: backing,
  197. },
  198. WakeOnLanEnabled: &True,
  199. }
  200. nic.Connectable = &connectable
  201. nic.ControllerKey = ctlKey
  202. nic.Key = key + index
  203. if len(mac) != 0 {
  204. nic.AddressType = "Manual"
  205. nic.MacAddress = mac
  206. } else {
  207. nic.AddressType = "Generated"
  208. }
  209. if driver == "e1000" {
  210. return &types.VirtualE1000{
  211. VirtualEthernetCard: nic,
  212. }, nil
  213. }
  214. return &types.VirtualVmxnet3{
  215. VirtualVmxnet: types.VirtualVmxnet{
  216. VirtualEthernetCard: nic,
  217. },
  218. }, nil
  219. }