//id, feature (iso, net, boot, guest), label, value public async Task <Vm> ReconfigureVm(string id, string feature, string label, string newvalue) { await Connect(); int index = 0; if (int.TryParse(label, out index)) { label = ""; } Vm vm = _vmCache[id]; RetrievePropertiesResponse response = await _vim.RetrievePropertiesAsync( _props, FilterFactory.VmFilter(vm.AsVim(), "config")); ObjectContent[] oc = response.returnval; VirtualMachineConfigInfo config = (VirtualMachineConfigInfo)oc[0].GetProperty("config"); VirtualMachineConfigSpec vmcs = new VirtualMachineConfigSpec(); switch (feature) { case "iso": VirtualCdrom cdrom = (VirtualCdrom)((label.HasValue()) ? config.hardware.device.Where(o => o.deviceInfo.label == label).SingleOrDefault() : config.hardware.device.OfType <VirtualCdrom>().ToArray()[index]); if (cdrom != null) { if (cdrom.backing.GetType() != typeof(VirtualCdromIsoBackingInfo)) { cdrom.backing = new VirtualCdromIsoBackingInfo(); } ((VirtualCdromIsoBackingInfo)cdrom.backing).fileName = newvalue; cdrom.connectable = new VirtualDeviceConnectInfo { connected = true, startConnected = true }; vmcs.deviceChange = new VirtualDeviceConfigSpec[] { new VirtualDeviceConfigSpec { device = cdrom, operation = VirtualDeviceConfigSpecOperation.edit, operationSpecified = true } }; } break; case "net": case "eth": VirtualEthernetCard card = (VirtualEthernetCard)((label.HasValue()) ? config.hardware.device.Where(o => o.deviceInfo.label == label).SingleOrDefault() : config.hardware.device.OfType <VirtualEthernetCard>().ToArray()[index]); if (card != null) { if (newvalue.StartsWith("_none_")) { card.connectable = new VirtualDeviceConnectInfo() { connected = false, startConnected = false, }; } else { _netman.UpdateEthernetCardBacking(card, newvalue); card.connectable.connected = true; } vmcs.deviceChange = new VirtualDeviceConfigSpec[] { new VirtualDeviceConfigSpec { device = card, operation = VirtualDeviceConfigSpecOperation.edit, operationSpecified = true } }; } break; case "boot": int delay = 0; if (Int32.TryParse(newvalue, out delay)) { vmcs.AddBootOption(delay); } break; case "guest": if (newvalue.HasValue() && !newvalue.EndsWith("\n")) { newvalue += "\n"; } vmcs.annotation = config.annotation + newvalue; if (vm.State == VmPowerState.Running && vmcs.annotation.HasValue()) { vmcs.AddGuestInfo(Regex.Split(vmcs.annotation, "\r\n|\r|\n")); } break; default: throw new Exception("Invalid change request."); //break; } ManagedObjectReference task = await _vim.ReconfigVM_TaskAsync(vm.AsVim(), vmcs); TaskInfo info = await WaitForVimTask(task); if (info.state == TaskInfoState.error) { throw new Exception(info.error.localizedMessage); } return(await GetVirtualMachine(vm.AsVim())); }
public static VirtualMachineConfigSpec TemplateToVmSpec(VmTemplate template, string datastore, string dvsuuid) { int key = -101, idekey = 200; VirtualMachineConfigSpec vmcs = new VirtualMachineConfigSpec(); List <VirtualDeviceConfigSpec> devices = new List <VirtualDeviceConfigSpec>(); vmcs.name = template.Name; vmcs.extraConfig = GetExtraConfig(template); vmcs.AddRam(template.Ram); vmcs.AddCpu(template.Cpu); vmcs.AddBootOption(Math.Max(template.Delay, 10)); vmcs.version = (template.Version.HasValue()) ? template.Version : null; vmcs.guestId = (template.Guest.HasValue() ? template.Guest : "other"); if (!vmcs.guestId.EndsWith("Guest")) { vmcs.guestId += "Guest"; } if (datastore.HasValue()) { vmcs.files = new VirtualMachineFileInfo { vmPathName = $"{datastore}/{template.Name}/{template.Name}.vmx" }; } //can't actually be applied via ExtraConfig if (template.GuestSettings.Length > 0 && template.GuestSettings.Any(s => s.Key == "vhv.enable" && s.Value == "true")) { vmcs.nestedHVEnabled = true; vmcs.nestedHVEnabledSpecified = true; } //video card devices.Add(GetVideoController(ref key, template.VideoRam)); //floppy disk if (template.Floppy.HasValue()) { devices.Add(GetFloppy(ref key, template.Floppy)); } //nics foreach (VmNet nic in template.Eth) { devices.Add(GetEthernetAdapter(ref key, nic, dvsuuid)); } // //network serial port // if (!String.IsNullOrEmpty(template.FindOne("nsp").Value())) // devices.Add(GetNetworkSerialPort(ref key, template.FindOne("nsp").Value())); //controller int controllerKey = 0, count = 0; foreach (VmDisk disk in template.Disks) { if (controllerKey == 0) { if (disk.Controller == "ide") { controllerKey = idekey; } else { VirtualDeviceConfigSpec controller = GetSCSIController(ref key, disk.Controller); controllerKey = controller.device.key; devices.Add(controller); } } devices.Add(GetDisk(ref key, disk.Path, controllerKey, count++)); } //iso devices.Add(GetCdrom(ref key, idekey, (template.Iso.HasValue() ? template.Iso : "[iso] null.iso"))); //add all devices to spec vmcs.deviceChange = devices.ToArray(); return(vmcs); }
public async Task <TaskInfo> ReconfigureVm(Guid id, Feature feature, string label, string newvalue) { VirtualMachine machine = await GetMachineById(id); ManagedObjectReference vmReference = machine.Reference; VirtualDevice[] devices = machine.Devices; VirtualMachineConfigSpec vmcs = new VirtualMachineConfigSpec(); switch (feature) { case Feature.iso: VirtualCdrom cdrom = (VirtualCdrom)((label.HasValue()) ? devices.Where(o => o.deviceInfo.label == label).SingleOrDefault() : devices.OfType <VirtualCdrom>().FirstOrDefault()); if (cdrom != null) { if (cdrom.backing.GetType() != typeof(VirtualCdromIsoBackingInfo)) { cdrom.backing = new VirtualCdromIsoBackingInfo(); } ((VirtualCdromIsoBackingInfo)cdrom.backing).datastore = (await GetDatastoreByName(_options.DsName)).Reference; ((VirtualCdromIsoBackingInfo)cdrom.backing).fileName = newvalue; cdrom.connectable = new VirtualDeviceConnectInfo { connected = true, startConnected = true }; vmcs.deviceChange = new VirtualDeviceConfigSpec[] { new VirtualDeviceConfigSpec { device = cdrom, operation = VirtualDeviceConfigSpecOperation.edit, operationSpecified = true } }; } break; case Feature.net: case Feature.eth: VirtualEthernetCard card = (VirtualEthernetCard)((label.HasValue()) ? devices.Where(o => o.deviceInfo.label == label).SingleOrDefault() : devices.OfType <VirtualEthernetCard>().FirstOrDefault()); if (card != null) { Network network = _connectionService.GetNetworkByName(newvalue); if (network.IsDistributed) { card.backing = new VirtualEthernetCardDistributedVirtualPortBackingInfo { port = new DistributedVirtualSwitchPortConnection { portgroupKey = network.Reference, switchUuid = network.SwitchId } }; } else { card.backing = new VirtualEthernetCardNetworkBackingInfo { deviceName = newvalue }; } //if (card.backing is VirtualEthernetCardNetworkBackingInfo) // ((VirtualEthernetCardNetworkBackingInfo)card.backing).deviceName = newvalue; //if (card.backing is VirtualEthernetCardDistributedVirtualPortBackingInfo) // ((VirtualEthernetCardDistributedVirtualPortBackingInfo)card.backing).port.portgroupKey = newvalue; card.connectable = new VirtualDeviceConnectInfo() { connected = true, startConnected = true, }; vmcs.deviceChange = new VirtualDeviceConfigSpec[] { new VirtualDeviceConfigSpec { device = card, operation = VirtualDeviceConfigSpecOperation.edit, operationSpecified = true } }; } break; case Feature.boot: int delay = 0; if (Int32.TryParse(newvalue, out delay)) { vmcs.AddBootOption(delay); } break; //case Feature.guest: // if (newvalue.HasValue() && !newvalue.EndsWith("\n")) // newvalue += "\n"; // vmcs.annotation = config.annotation + newvalue; // if (vm.State == VmPowerState.running && vmcs.annotation.HasValue()) // vmcs.AddGuestInfo(Regex.Split(vmcs.annotation, "\r\n|\r|\n")); // break; default: throw new Exception("Invalid change request."); //break; } ManagedObjectReference task = await _client.ReconfigVM_TaskAsync(vmReference, vmcs); TaskInfo info = await WaitForVimTask(task); if (info.state == TaskInfoState.error) { throw new Exception(info.error.localizedMessage); } return(info); }