Beispiel #1
0
        public async Task <Vm> Delete(string id)
        {
            //Implemented by stopping vm (if necessary), unregistering vm, and deleting vm folder
            //This protects the base disk from deletion.  When we get vvols, and a data provider
            //with instance-clone of vvols, every vm will have its own disk, and we can just
            //delete the vm.
            await Connect();

            Vm     vm  = _vmCache[id];
            string tag = vm.Name.Tag();

            _logger.LogDebug($"Delete: stopping vm {vm.Name}");
            await Stop(id);

            vm.State = VmPowerState.Off;

            _logger.LogDebug($"Delete: unregistering vm {vm.Name}");
            await _netman.Unprovision(vm.AsVim());

            await _vim.UnregisterVMAsync(vm.AsVim());

            string folder = vm.Path.Substring(0, vm.Path.LastIndexOf('/'));

            _logger.LogDebug($"Delete: deleting vm folder {folder}");
            await _vim.DeleteDatastoreFile_TaskAsync(_sic.fileManager, folder, _datacenter);

            _vmCache.TryRemove(vm.Id, out vm);

            await _netman.Clean(tag);

            vm.Status = "initialized";
            return(vm);
        }
Beispiel #2
0
        public async Task <Vm> Start(string id)
        {
            await Connect();

            Vm vm = _vmCache[id];

            _logger.LogDebug($"Starting vm {vm.Name}");
            if (vm.State != VmPowerState.Running)
            {
                ManagedObjectReference task = await _vim.PowerOnVM_TaskAsync(vm.AsVim(), null);

                TaskInfo info = await WaitForVimTask(task);

                vm.State = (info.state == TaskInfoState.success)
                    ? VmPowerState.Running
                    : vm.State;
                if (vm.State != VmPowerState.Running)
                {
                    throw new Exception(info.error.localizedMessage);
                }

                //apply guestinfo for annotations
                await ReconfigureVm(id, "guest", "", "");
            }

            _vmCache.TryUpdate(vm.Id, vm, vm);
            return(vm);
        }
Beispiel #3
0
        public async Task <Vm> AnswerVmQuestion(string id, string question, string answer)
        {
            await Connect();

            Vm vm = _vmCache[id];
            await _vim.AnswerVMAsync(vm.AsVim(), question, answer);

            vm.Question = null;
            return(vm);
        }
Beispiel #4
0
        public async Task <string> GetTicket(string id)
        {
            await Connect();

            Vm vm = _vmCache[id];

            _logger.LogDebug($"Aquiring mks ticket for vm {vm.Name}");
            var ticket = await _vim.AcquireTicketAsync(vm.AsVim(), "webmks");

            string port = (ticket.portSpecified && ticket.port != 443) ? $":{ticket.port}" : "";

            return($"wss://{ticket.host ?? _config.Host}{port}/ticket/{ticket.ticket}");
        }
Beispiel #5
0
        public async Task <Vm> Deploy(VmTemplate template)
        {
            Vm vm = null;

            await Connect();

            _logger.LogDebug("deploy: validate portgroups...");
            await _netman.Provision(template);

            _logger.LogDebug("deploy: transform template...");
            //var transformer = new VCenterTransformer { DVSuuid = _dvsuuid };
            VirtualMachineConfigSpec vmcs = Transform.TemplateToVmSpec(
                template,
                _config.VmStore.Replace("{host}", _hostPrefix),
                _dvsuuid
                );

            _logger.LogDebug("deploy: create vm...");
            ManagedObjectReference task = await _vim.CreateVM_TaskAsync(_vms, vmcs, _pool, null);

            TaskInfo info = await WaitForVimTask(task);

            if (info.state == TaskInfoState.success)
            {
                _logger.LogDebug("deploy: load vm...");
                await Task.Delay(200);

                vm = await GetVirtualMachine((ManagedObjectReference)info.result);

                _logger.LogDebug("deploy: create snapshot...");
                task = await _vim.CreateSnapshot_TaskAsync(
                    vm.AsVim(),
                    "Root Snap",
                    "Created by TopoMojo Deploy at " + DateTime.UtcNow.ToString("s") + "Z",
                    false, false);

                info = await WaitForVimTask(task);

                if (template.AutoStart && info.state == TaskInfoState.success)
                {
                    _logger.LogDebug("deploy: start vm...");
                    vm = await Start(vm.Id);
                }
            }
            else
            {
                throw new Exception(info.error.localizedMessage);
            }
            return(vm);
        }
Beispiel #6
0
        public async Task <Vm> Revert(string id)
        {
            await Connect();

            Vm vm = _vmCache[id];

            _logger.LogDebug($"Stopping vm {vm.Name}");
            ManagedObjectReference task = await _vim.RevertToCurrentSnapshot_TaskAsync(
                vm.AsVim(), null, false);

            TaskInfo info = await WaitForVimTask(task);

            if (vm.State == VmPowerState.Running)
            {
                await Start(id);
            }
            _vmCache.TryUpdate(vm.Id, vm, vm);
            return(vm);
        }
Beispiel #7
0
        public async Task <Vm> Stop(string id)
        {
            await Connect();

            Vm vm = _vmCache[id];

            _logger.LogDebug($"Stopping vm {vm.Name}");
            if (vm.State == VmPowerState.Running)
            {
                ManagedObjectReference task = await _vim.PowerOffVM_TaskAsync(vm.AsVim());

                TaskInfo info = await WaitForVimTask(task);

                vm.State = (info.state == TaskInfoState.success)
                    ? VmPowerState.Off
                    : vm.State;
                if (vm.State == VmPowerState.Running)
                {
                    throw new Exception(info.error.localizedMessage);
                }
            }
            _vmCache.TryUpdate(vm.Id, vm, vm);
            return(vm);
        }
Beispiel #8
0
        //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()));
        }
Beispiel #9
0
        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);

                await Task.Delay(500);

                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);
        }