Beispiel #1
0
        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}");
        }
Beispiel #2
0
        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());
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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.");
        }
Beispiel #6
0
        public async Task <Vm> Revert(string id)
        {
            _logger.LogDebug("reverting " + id);
            VimClient host = FindHostByVm(id);

            return(await host.Revert(id));
        }
Beispiel #7
0
        public async Task <Vm> Save(string id)
        {
            _logger.LogDebug("saving " + id);
            VimClient host = FindHostByVm(id);

            return(await host.Save(id));
        }
Beispiel #8
0
        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));
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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());
            }
        }
Beispiel #12
0
        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));
        }
Beispiel #13
0
        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));
        }
Beispiel #14
0
        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()
            });
        }
Beispiel #15
0
        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);
        }
Beispiel #16
0
        public async Task <Vm> Answer(string id, VmAnswer answer)
        {
            VimClient host = FindHostByVm(id);

            return(await host.AnswerVmQuestion(id, answer.QuestionId, answer.ChoiceKey));
        }