private async Task AddHost(string url) { string hostname = new Uri(url).Host; _logger.LogDebug($"Adding host {hostname}"); if (_hostCache.ContainsKey(hostname)) { await _hostCache[hostname].Disconnect(); _hostCache.TryRemove(hostname, out VimClient discard); await Task.Delay(100); } HypervisorServiceConfiguration hostOptions = _options.Clone <HypervisorServiceConfiguration>(); if (!url.EndsWith("/sdk")) { url += "/sdk"; } hostOptions.Url = url; hostOptions.Host = hostname; var vHost = new VimClient( hostOptions, _vmCache, _vlanman, _mill.CreateLogger <VimClient>() ); _hostCache.AddOrUpdate(hostname, vHost, (k, v) => (v = vHost)); _logger.LogDebug($"Added host {hostname}; cache: {_hostCache.Values.Count}"); }
public async Task <ConsoleSummary> Display(string id) { ConsoleSummary info = null; Vm vm = await Load(id); if (vm != null) { VimClient host = _hostCache[vm.Host]; string ticket = ""; try { ticket = await host.GetTicket(vm.Id); } catch {} info = new ConsoleSummary { Id = vm.Id, Name = vm.Name.Untagged(), IsolationId = vm.Name.Tag(), Url = ticket, IsRunning = vm.State == VmPowerState.Running }; } return(info ?? new ConsoleSummary()); }
private VimClient FindHostByAffinity(string tag) { VimClient host = null; lock (_affinityMap) { if (_affinityMap.ContainsKey(tag)) { host = _affinityMap[tag]; } else { Vm vm = _vmCache.Values.Where(o => o.Name.EndsWith(tag)).FirstOrDefault(); if (vm != null) { host = _hostCache[vm.Host]; } else { host = FindHostByFewestVms(); } _affinityMap.Add(tag, host); } } return(host); }
public async Task <int> CreateDisks(VmTemplate template) { if (template.Disks.Length == 0) { return(-1); } int progress = await VerifyDisks(template); if (progress < 0) { VimClient host = FindHostByRandom(); if (template.Disks[0].Source.HasValue()) { Task cloneTask = host.CloneDisk(template.Id, template.Disks[0].Source, template.Disks[0].Path); progress = 0; } else { await host.CreateDisk(template.Disks[0]); progress = 100; } } return(progress); }
public async Task <int> DeleteDisks(VmTemplate template) { if (template.Disks.Length == 0) { return(-1); } int progress = await VerifyDisks(template); if (progress < 0) { return(-1); } if (progress == 100) { VimClient host = FindHostByRandom(); foreach (VmDisk disk in template.Disks) { //protect stock disks; only delete a disk if it is local to the workspace //i.e. the disk folder matches the workspaceId if (template.IsolationTag.HasValue() && disk.Path.Contains(template.IsolationTag)) { Task deleteTask = host.DeleteDisk(disk.Path); } } return(-1); } throw new Exception("Cannot delete disk that isn't fully created."); }
public async Task <Vm> Revert(string id) { _logger.LogDebug("reverting " + id); VimClient host = FindHostByVm(id); return(await host.Revert(id)); }
public async Task <Vm> Save(string id) { _logger.LogDebug("saving " + id); VimClient host = FindHostByVm(id); return(await host.Save(id)); }
public async Task <Vm> Deploy(VmTemplate template) { var vm = await Load(template.Name + "#" + template.IsolationTag); if (vm != null) { return(vm); } VimClient host = FindHostByAffinity(template.IsolationTag); _logger.LogDebug("deploy: host " + host.Name); NormalizeTemplate(template, host.Options); _logger.LogDebug("deploy: normalized " + template.Name); if (!template.Disks.IsEmpty()) { bool found = await host.FileExists(template.Disks[0].Path); if (!found) { throw new Exception("Template disks have not been prepared."); } } if (!host.Options.Uplink.StartsWith("nsx.")) { _logger.LogDebug("deploy: reserve vlans "); _vlanman.ReserveVlans(template, host.Options.IsVCenter); } _logger.LogDebug("deploy: " + template.Name + " " + host.Name); return(await host.Deploy(template)); }
public async Task SetAffinity(string isolationTag, Vm[] vms, bool start) { _logger.LogDebug("setaffinity: find host "); VimClient host = FindHostByAffinity(isolationTag); _logger.LogDebug("setaffinity: setting affinity "); await host.SetAffinity(isolationTag, vms, start); }
public async Task <Vm> Delete(string id) { _logger.LogDebug("deleting " + id); VimClient host = FindHostByVm(id); Vm vm = await host.Delete(id); RefreshAffinity(); //TODO: fix race condition here return(vm); }
public async Task DeleteAll(string target) { _logger.LogDebug("deleting all matching " + target); var tasks = new List <Task>(); foreach (var vm in await Find(target)) { VimClient host = FindHostByVm(vm.Id); tasks.Add(host.Delete(vm.Id)); } if (tasks.Count > 0) { await Task.WhenAll(tasks.ToArray()); } }
public async Task <Vm> ChangeConfiguration(string id, VmKeyValue change) { _logger.LogDebug("changing " + id + " " + change.Key + "=" + change.Value); Vm vm = await Load(id); if (vm == null) { throw new InvalidOperationException(); } VimClient host = FindHostByVm(id); VmOptions vmo = null; var segments = change.Value.Split(':'); string val = segments.First(); string tag = segments.Length > 1 ? $":{segments.Last()}" : ""; //sanitize inputs if (change.Key == "iso") { // vmo = await GetVmIsoOptions(vm.Name.Tag()); // if (!vmo.Iso.Contains(change.Value)) // throw new InvalidOperationException(); var isopath = new DatastorePath(val); isopath.Merge(host.Options.IsoStore); change = new VmKeyValue { Key = "iso", Value = isopath.ToString() + tag }; } if (change.Key == "net" && !change.Value.StartsWith("_none_")) { vmo = await GetVmNetOptions(vm.Name.Tag()); if (!vmo.Net.Contains(val)) { throw new InvalidOperationException(); } } return(await host.Change(id, change)); }
public async Task <Vm> ChangeConfiguration(string id, VmKeyValue change) { _logger.LogDebug("changing " + id + " " + change.Key + "=" + change.Value); Vm vm = await Load(id); if (vm == null) { throw new InvalidOperationException(); } VimClient host = FindHostByVm(id); VmOptions vmo = null; //sanitize inputs if (change.Key == "iso") { // vmo = await GetVmIsoOptions(vm.Name.Tag()); // if (!vmo.Iso.Contains(change.Value)) // throw new InvalidOperationException(); var isopath = new DatastorePath(change.Value); isopath.Merge(host.Options.IsoStore); change = new VmKeyValue { Key = "iso", Value = isopath.ToString() }; } if (change.Key == "net") { vmo = await GetVmNetOptions(vm.Name.Tag()); if (!vmo.Net.Contains(change.Value)) { throw new InvalidOperationException(); } } return(await host.Change(id, change)); }
public async Task <VmOptions> GetVmIsoOptions(string id) { VimClient host = FindHostByRandom(); List <string> isos = new List <string>(); string publicFolder = Guid.Empty.ToString(); isos.AddRange( (await host.GetFiles(host.Options.IsoStore + id + "/*.iso", false)) ); isos.AddRange( (await host.GetFiles(host.Options.IsoStore + publicFolder + "/*.iso", false)) ); //translate actual path to display path isos = isos.Select(x => x.Replace(host.Options.IsoStore, "").Trim()).ToList(); return(new VmOptions { Iso = isos.ToArray() }); }
public async Task <int> VerifyDisks(VmTemplate template) { if (template.Disks.Length == 0) { return(100); //show good if no disks to verify } foreach (VimClient vhost in _hostCache.Values) { int progress = await vhost.TaskProgress(template.Id); if (progress >= 0) { return(progress); } } // string pattern = @"blank-(\d+)([^\.]+)"; // Match match = Regex.Match(template.Disks[0].Path, pattern); // if (match.Success) // { // return 100; //show blank disk as created // } VimClient host = FindHostByRandom(); NormalizeTemplate(template, host.Options); // if (template.Disks.Length > 0) // { _logger.LogDebug(template.Source + " " + template.Disks[0].Path); if (await host.FileExists(template.Disks[0].Path)) { return(100); } // } return(-1); }
public async Task <Vm> Answer(string id, VmAnswer answer) { VimClient host = FindHostByVm(id); return(await host.AnswerVmQuestion(id, answer.QuestionId, answer.ChoiceKey)); }