示例#1
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);
        }