//id, feature (iso, net, boot, guest), label, value public async Task <Vm> ReconfigureVm(string id, string feature, string label, string newvalue) { await Connect(); 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>().FirstOrDefault()); 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>().FirstOrDefault()); if (card != null) { _netman.UpdateEthernetCardBacking(card, newvalue); 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 async Task <string[]> GetFiles(string path, bool recursive) { await Connect(); List <string> list = new List <string>(); DatastorePath dsPath = new DatastorePath(path); RetrievePropertiesResponse response = await _vim.RetrievePropertiesAsync( _props, FilterFactory.DatastoreFilter(_res)); ObjectContent[] oc = response.returnval; foreach (ObjectContent obj in oc) { ManagedObjectReference dsBrowser = (ManagedObjectReference)obj.propSet[0].val; string dsName = ((DatastoreSummary)obj.propSet[1].val).name; if (dsName == dsPath.Datastore) { ManagedObjectReference task = null; TaskInfo info = null; HostDatastoreBrowserSearchSpec spec = new HostDatastoreBrowserSearchSpec { matchPattern = new string[] { dsPath.File } }; List <HostDatastoreBrowserSearchResults> results = new List <HostDatastoreBrowserSearchResults>(); if (recursive) { task = await _vim.SearchDatastoreSubFolders_TaskAsync( dsBrowser, dsPath.FolderPath, spec); info = await WaitForVimTask(task); if (info.result != null) { results.AddRange((HostDatastoreBrowserSearchResults[])info.result); } } else { task = await _vim.SearchDatastore_TaskAsync( dsBrowser, dsPath.FolderPath, spec); info = await WaitForVimTask(task); if (info.result != null) { results.Add((HostDatastoreBrowserSearchResults)info.result); } } foreach (HostDatastoreBrowserSearchResults result in results) { if (result != null && result.file != null && result.file.Length > 0) { string fp = result.folderPath; if (!fp.EndsWith("/")) { fp += "/"; } list.AddRange(result.file.Select(o => fp + o.path)); } } } } return(list.ToArray()); }
public async Task <Vm> Save(string id) { await Connect(); Vm vm = _vmCache[id]; //protect stock disks; only save a disk if it is local to the workspace //i.e. the disk folder matches the workspaceId if (vm.Name.Tag().HasValue() && !vm.DiskPath.Contains(vm.Name.Tag())) { throw new InvalidOperationException("External templates must be cloned into local templates in order to be saved."); } _logger.LogDebug($"Save: get current snap for vm {vm.Name}"); //Get the current snapshot mor ManagedObjectReference mor = null; RetrievePropertiesResponse response = await _vim.RetrievePropertiesAsync( _props, FilterFactory.VmFilter(vm.AsVim(), "snapshot")); ObjectContent[] oc = response.returnval; mor = ((VirtualMachineSnapshotInfo)oc.First().GetProperty("snapshot")).currentSnapshot as ManagedObjectReference; // if (oc.Length > 0 && oc[0].propSet.Length > 0 && oc[0].propSet[0].val != null) // mor = ((VirtualMachineSnapshotInfo)oc[0].propSet[0].val).currentSnapshot; //add new snapshot _logger.LogDebug($"Save: add new snap for vm {vm.Name}"); ManagedObjectReference task = await _vim.CreateSnapshot_TaskAsync( vm.AsVim(), "Root Snap", "Created by TopoMojo Save at " + DateTime.UtcNow.ToString("s") + "Z", false, false); TaskInfo info = await WaitForVimTask(task); //remove previous snapshot if (mor != null) { _logger.LogDebug($"Save: remove previous snap for vm {vm.Name}"); task = await _vim.RemoveSnapshot_TaskAsync(mor, false, true); info = await GetVimTaskInfo(task); if (info.state == TaskInfoState.error) { throw new Exception(info.error.localizedMessage); } if (info.progress < 100) { var t = new VimHostTask { Task = task, Action = "saving", WhenCreated = DateTime.UtcNow }; vm.Task = new VmTask { Name = t.Action, WhenCreated = t.WhenCreated, Progress = t.Progress }; _tasks.Add(vm.Id, t); } } _vmCache.TryUpdate(vm.Id, vm, vm); return(vm); }