yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/esxi/devtools.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 esxi
    16  
    17  import (
    18  	"fmt"
    19  	"reflect"
    20  
    21  	"github.com/vmware/govmomi/vim25/types"
    22  
    23  	"yunion.io/x/log"
    24  	"yunion.io/x/pkg/errors"
    25  )
    26  
    27  type SDiskConfig struct {
    28  	SizeMb        int64
    29  	Uuid          string
    30  	ControllerKey int32
    31  	UnitNumber    int32
    32  	Key           int32
    33  	ImagePath     string
    34  	IsRoot        bool
    35  	Datastore     *SDatastore
    36  }
    37  
    38  // In fact, it is the default lable of first one disk
    39  const rootDiskMark = "Hard disk 1"
    40  
    41  func NewDiskDev(sizeMb int64, config SDiskConfig) *types.VirtualDisk {
    42  	device := types.VirtualDisk{}
    43  	diskFile := types.VirtualDiskFlatVer2BackingInfo{}
    44  	diskFile.DiskMode = "persistent"
    45  	thinProvisioned := true
    46  	diskFile.ThinProvisioned = &thinProvisioned
    47  	diskFile.Uuid = config.Uuid
    48  	if len(config.ImagePath) > 0 {
    49  		diskFile.FileName = config.ImagePath
    50  	}
    51  	if config.Datastore != nil {
    52  		ref := config.Datastore.getDatastoreObj().Reference()
    53  		diskFile.Datastore = &ref
    54  	}
    55  	device.Backing = &diskFile
    56  
    57  	if sizeMb > 0 {
    58  		device.CapacityInKB = sizeMb * 1024
    59  	}
    60  
    61  	device.ControllerKey = config.ControllerKey
    62  	device.Key = config.Key
    63  	device.UnitNumber = &config.UnitNumber
    64  
    65  	var label string
    66  	if config.IsRoot {
    67  		label = rootDiskMark
    68  		device.DeviceInfo = &types.Description{Label: label}
    69  	}
    70  
    71  	return &device
    72  }
    73  
    74  func addDevSpec(device types.BaseVirtualDevice) *types.VirtualDeviceConfigSpec {
    75  	spec := types.VirtualDeviceConfigSpec{}
    76  	spec.Operation = types.VirtualDeviceConfigSpecOperationAdd
    77  	spec.Device = device
    78  	return &spec
    79  }
    80  
    81  func NewSCSIDev(key, ctlKey int32, driver string) types.BaseVirtualDevice {
    82  	desc := types.Description{Label: "SCSI controller 0", Summary: "VMware virtual SCSI"}
    83  
    84  	if driver == "pvscsi" {
    85  		device := types.ParaVirtualSCSIController{}
    86  		device.DeviceInfo = &desc
    87  		device.Key = key
    88  		device.ControllerKey = ctlKey
    89  		device.SharedBus = "noSharing"
    90  		return &device
    91  	}
    92  	device := types.VirtualLsiLogicController{}
    93  	device.DeviceInfo = &desc
    94  	device.Key = key
    95  	device.ControllerKey = ctlKey
    96  	device.SharedBus = "noSharing"
    97  	return &device
    98  }
    99  
   100  func NewAHCIDev(key, ctlKey int32) types.BaseVirtualDevice {
   101  	device := types.VirtualAHCIController{}
   102  	device.DeviceInfo = &types.Description{Label: "SATA controller 0", Summary: "AHCI"}
   103  	device.ControllerKey = ctlKey
   104  	device.Key = key
   105  	return &device
   106  }
   107  
   108  func NewSVGADev(key, ctlKey int32) types.BaseVirtualDevice {
   109  	device := types.VirtualMachineVideoCard{}
   110  	device.DeviceInfo = &types.Description{Label: "Video card", Summary: "Video card"}
   111  	device.ControllerKey = ctlKey
   112  	device.Key = key
   113  	device.VideoRamSizeInKB = 16 * 1024
   114  	return &device
   115  }
   116  
   117  func NewIDEDev(key, index int32) types.BaseVirtualDevice {
   118  	device := types.VirtualIDEController{}
   119  	s := fmt.Sprintf("IDE %d", index)
   120  	device.DeviceInfo = &types.Description{Label: s, Summary: s}
   121  	device.Key = key + index
   122  	device.BusNumber = index
   123  	return &device
   124  }
   125  
   126  func NewCDROMDev(path string, key, ctlKey int32) types.BaseVirtualDevice {
   127  	device := types.VirtualCdrom{}
   128  	device.DeviceInfo = &types.Description{Label: "CD/DVD drive 1", Summary: "Local ISO Emulated CD-ROM"}
   129  	device.ControllerKey = ctlKey
   130  	device.Key = key
   131  
   132  	connectable := types.VirtualDeviceConnectInfo{AllowGuestControl: true, Status: "untried"}
   133  	if len(path) != 0 {
   134  		device.Backing = &types.VirtualCdromIsoBackingInfo{
   135  			VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{
   136  				FileName: path,
   137  			},
   138  		}
   139  		connectable.StartConnected = true
   140  	} else {
   141  		device.Backing = &types.VirtualCdromRemoteAtapiBackingInfo{}
   142  		connectable.StartConnected = false
   143  	}
   144  
   145  	device.Connectable = &connectable
   146  	return &device
   147  }
   148  
   149  func NewUSBController(key *int32) types.BaseVirtualDevice {
   150  	device := types.VirtualUSBController{}
   151  	device.DeviceInfo = &types.Description{
   152  		Label: "USB controller",
   153  	}
   154  	if key != nil {
   155  		device.Key = *key
   156  	}
   157  	return &device
   158  }
   159  
   160  var getNetwork func(bridge, vlanId string) (IVMNetwork, error)
   161  
   162  func NewVNICDev(host *SHost, mac, driver string, bridge string, vlanId int32, key, ctlKey, index int32) (types.BaseVirtualDevice, error) {
   163  	desc := types.Description{Label: fmt.Sprintf("Network adapter %d", index+1), Summary: "VM Network"}
   164  
   165  	newGetNetwork := func(bridge string, vlanId int32) (IVMNetwork, error) {
   166  		if len(bridge) == 0 {
   167  			log.Warningf("empty bridge for host %s, vlanId %d, mac %s", host.GetGlobalId(), vlanId, mac)
   168  			return nil, nil
   169  		}
   170  		vs, err := findVirtualSwitch(host, bridge)
   171  		if err != nil {
   172  			return nil, errors.Wrapf(err, "findVirtualSwitch for host %s bridge %s", host.GetGlobalId(), bridge)
   173  		}
   174  		if vs == nil {
   175  			log.Infof("can't find vs via host %s, bridge %s", host.GetId(), bridge)
   176  			return nil, nil
   177  		}
   178  		network, err := vs.FindNetworkByVlanID(vlanId)
   179  		if err != nil {
   180  			return nil, errors.Wrapf(err, "FindNetworkByVlanID for vlanId %q", vlanId)
   181  		}
   182  		return network, nil
   183  	}
   184  
   185  	oldGetNework := func(bridge string, vlanId int32) (IVMNetwork, error) {
   186  		var inet IVMNetwork
   187  		var err error
   188  		if (vlanId == 0 || vlanId == 1) && len(bridge) > 0 {
   189  			inet, err = host.findDVPGById(bridge)
   190  			if err != nil {
   191  				log.Errorf("fail to find dvportgroup by name %s: %s", bridge, err)
   192  			}
   193  		}
   194  		if inet == nil || reflect.ValueOf(inet).IsNil() {
   195  			inet, err = host.FindNetworkByVlanID(vlanId)
   196  			if err != nil {
   197  				log.Errorf("fail to find network by vlanid %d: %s", vlanId, err)
   198  			}
   199  		}
   200  		if inet == nil || reflect.ValueOf(inet).IsNil() {
   201  			return nil, nil
   202  		}
   203  		return inet, nil
   204  	}
   205  
   206  	inet, err := newGetNetwork(bridge, vlanId)
   207  	if err != nil {
   208  		return nil, err
   209  	}
   210  	if inet == nil {
   211  		log.Infof("no find network via new method")
   212  		inet, err = oldGetNework(bridge, vlanId)
   213  		if err != nil {
   214  			return nil, err
   215  		}
   216  	}
   217  
   218  	if inet == nil {
   219  		return nil, errors.Error(fmt.Sprintf("Brige %s VLAN %d not found", bridge, vlanId))
   220  	}
   221  
   222  	var (
   223  		False = false
   224  		True  = true
   225  	)
   226  	var backing types.BaseVirtualDeviceBackingInfo
   227  	switch inet.(type) {
   228  	case *SDistributedVirtualPortgroup:
   229  		net := inet.(*SDistributedVirtualPortgroup)
   230  		dvpg := net.getMODVPortgroup()
   231  		uuid, err := net.GetDVSUuid()
   232  		if err != nil {
   233  			return nil, errors.Wrap(err, "GetDVSUuid")
   234  		}
   235  		portCon := types.DistributedVirtualSwitchPortConnection{
   236  			PortgroupKey: dvpg.Key,
   237  			SwitchUuid:   uuid,
   238  		}
   239  		backing = &types.VirtualEthernetCardDistributedVirtualPortBackingInfo{Port: portCon}
   240  	case *SNetwork:
   241  		monet := inet.(*SNetwork).getMONetwork()
   242  		backing = &types.VirtualEthernetCardNetworkBackingInfo{
   243  			VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{
   244  				DeviceName:    monet.Name,
   245  				UseAutoDetect: &False,
   246  			},
   247  			Network: &monet.Self,
   248  		}
   249  	default:
   250  		return nil, errors.Error(fmt.Sprintf("Unsuppport network type %s", reflect.TypeOf(inet).Name()))
   251  	}
   252  
   253  	connectable := types.VirtualDeviceConnectInfo{
   254  		StartConnected:    true,
   255  		AllowGuestControl: true,
   256  		Connected:         false,
   257  		Status:            "untried",
   258  	}
   259  
   260  	nic := types.VirtualEthernetCard{
   261  		VirtualDevice: types.VirtualDevice{
   262  			DeviceInfo: &desc,
   263  			Backing:    backing,
   264  		},
   265  		WakeOnLanEnabled: &True,
   266  	}
   267  	nic.Connectable = &connectable
   268  	nic.ControllerKey = ctlKey
   269  	nic.Key = key + index
   270  	if len(mac) != 0 {
   271  		nic.AddressType = "Manual"
   272  		nic.MacAddress = mac
   273  	} else {
   274  		nic.AddressType = "Generated"
   275  	}
   276  	if driver == "e1000" {
   277  		return &types.VirtualE1000{
   278  			VirtualEthernetCard: nic,
   279  		}, nil
   280  	}
   281  
   282  	return &types.VirtualVmxnet3{
   283  		VirtualVmxnet: types.VirtualVmxnet{
   284  			VirtualEthernetCard: nic,
   285  		},
   286  	}, nil
   287  }