Beispiel #1
0
 public static Task <Either <PowershellFailure, Seq <VMDriveStorageSettings> > > PlanDriveStorageSettings(
     MachineConfig config, VMStorageSettings storageSettings, HostSettings hostSettings, IPowershellEngine engine)
 {
     return(config.VM.Drives
            .ToSeq().MapToEitherAsync((index, c) =>
                                      DriveConfigToDriveStorageSettings(index, c, storageSettings, hostSettings)));
 }
Beispiel #2
0
        private static Task <Either <PowershellFailure, VMStorageSettings> > EnsureStorageId(VMStorageSettings first, VMStorageSettings second, Func <Task <Either <PowershellFailure, string> > > idGeneratorFunc)
        {
            if (second.Frozen)
            {
                return(Prelude.RightAsync <PowershellFailure, VMStorageSettings>(second).ToEither());
            }


            return(first.StorageIdentifier.MatchAsync(
                       None:
                       () => second.StorageIdentifier.MatchAsync(
                           None: idGeneratorFunc,
                           Some: s => Prelude.RightAsync <PowershellFailure, string>(s).ToEither()),
                       Some: s => Prelude.RightAsync <PowershellFailure, string>(s).ToEither()
                       ).MapAsync(storageIdentifier =>

                                  new VMStorageSettings
            {
                StorageNames = first.StorageNames,
                StorageIdentifier = storageIdentifier,
                VMPath = first.VMPath
            }));
        }
Beispiel #3
0
 private static Task <Either <PowershellFailure, VMStorageSettings> > EnsureStorageId(VMStorageSettings settings, Func <Task <Either <PowershellFailure, string> > > idGeneratorFunc)
 {
     return(EnsureStorageId(settings, new VMStorageSettings(), idGeneratorFunc));
 }
Beispiel #4
0
        private static Task <Either <PowershellFailure, VMDriveStorageSettings> > DriveConfigToDriveStorageSettings(int index,
                                                                                                                    VirtualMachineDriveConfig driveConfig, VMStorageSettings storageSettings, HostSettings hostSettings)
        {
            const int controllerNumber   = 0;     //currently this will not be configurable, but keep it here at least as constant
            var       controllerLocation = index; //later, when adding controller config support, we will have to add a logic to

            //set location relative to the free slots for each controller


            //if it is not a vhd, we only need controller settings
            if (driveConfig.Type != VirtualMachineDriveType.VHD)
            {
                VMDriveStorageSettings result;
                if (driveConfig.Type == VirtualMachineDriveType.DVD)
                {
                    result = new VMDVdStorageSettings
                    {
                        ControllerNumber   = controllerNumber,
                        ControllerLocation = controllerLocation,
                        Type = VirtualMachineDriveType.DVD
                    };
                }
                else
                {
                    result = new VMDriveStorageSettings
                    {
                        ControllerNumber   = controllerNumber,
                        ControllerLocation = controllerLocation,
                        Type = driveConfig.Type.GetValueOrDefault(VirtualMachineDriveType.PHD)
                    };
                }

                return(Prelude.RightAsync <PowershellFailure, VMDriveStorageSettings>(result).ToEither());
            }

            //so far for the simple part, now the complicated case - a vhd disk...

            var projectName       = Prelude.Some("default");
            var environmentName   = Prelude.Some("default");
            var dataStoreName     = Prelude.Some("default");
            var storageIdentifier = Option <string> .None;

            var names = new StorageNames()
            {
                ProjectName     = projectName,
                EnvironmentName = environmentName,
                DataStoreName   = dataStoreName,
            };



            if (storageIdentifier.IsNone)
            {
                storageIdentifier = storageSettings.StorageIdentifier;
            }


            return
                ((from resolvedPath in ResolveStorageBasePath(names, hostSettings.DefaultVirtualHardDiskPath).ToAsync()
                  from identifier in storageIdentifier.ToEither(new PowershellFailure
            {
                Message = $"Unexpected missing storage identifier for disk '{driveConfig.Name}'."
            })
                  .ToAsync()
                  .ToEither().ToAsync()

                  let planned = new VMDiskStorageSettings
            {
                Type = driveConfig.Type.Value,
                StorageNames = names,
                StorageIdentifier = storageIdentifier,
                ParentPath = driveConfig.Template,
                Path = Path.Combine(resolvedPath, identifier),
                AttachPath = Path.Combine(Path.Combine(resolvedPath, identifier), $"{driveConfig.Name}.vhdx"),
                // ReSharper disable once StringLiteralTypo
                Name = driveConfig.Name,
                SizeBytes = driveConfig.Size.ToOption().Match(None: () => 1 * 1024L * 1024 * 1024,
                                                              Some: s => s * 1024L * 1024 * 1024),
                ControllerNumber = controllerNumber,
                ControllerLocation = controllerLocation
            }
                  select planned as VMDriveStorageSettings).ToEither());
        }
Beispiel #5
0
        public static async Task <Either <PowershellFailure, TypedPsObject <VirtualMachineInfo> > > Drives(TypedPsObject <VirtualMachineInfo> vmInfo,
                                                                                                           MachineConfig vmConfig,
                                                                                                           VMStorageSettings storageSettings,
                                                                                                           HostSettings hostSettings, IPowershellEngine engine, Func <string, Task> reportProgress)
        {
            if (storageSettings.Frozen)
            {
                return(Right <PowershellFailure, TypedPsObject <VirtualMachineInfo> >(vmInfo));
            }

            var currentCheckpointType = vmInfo.Value.CheckpointType;

            try
            {
                await(
                    //prevent snapshots creating during running disk converge
                    from _ in SetVMCheckpointType(vmInfo, CheckpointType.Disabled, engine).ToAsync()
                    //make a plan
                    from plannedDriveStorageSettings in Storage.PlanDriveStorageSettings(vmConfig, storageSettings, hostSettings, engine).ToAsync()
                    //ensure that the changes reflect the current VM settings
                    from infoReloaded in vmInfo.Reload(engine).ToAsync()
                    //detach removed disks
                    from __ in DetachUndefinedDrives(engine, infoReloaded, plannedDriveStorageSettings, hostSettings, reportProgress).ToAsync()
                    from infoRecreated in vmInfo.RecreateOrReload(engine).ToAsync()
                    from ___ in VirtualDisks(infoRecreated, plannedDriveStorageSettings, hostSettings, engine, reportProgress).ToAsync()

                    select Unit.Default).ToEither().ConfigureAwait(false);
            }
            finally
            {
                await SetVMCheckpointType(vmInfo, currentCheckpointType, engine).ConfigureAwait(false);
            }

            return(await vmInfo.Reload(engine).ConfigureAwait(false));
        }