public Task <HypervVolumeDetail> CreateVolumeAsync(HypervCreateVolumeRequest request, CancellationToken cancellationToken = default)
 {
     return(GetHost(_options.HostName).CreateVolumeAsync(request, cancellationToken));
 }
Esempio n. 2
0
        public async Task <HypervVolumeDetail> CreateVolumeAsync(HypervCreateVolumeRequest request, CancellationToken cancellationToken = default)
        {
            if (string.IsNullOrEmpty(request.Name))
            {
                throw new ArgumentNullException(nameof(request.Name));
            }

            //todo VHDSet switch
            if (request.Shared)
            {
                throw new NotImplementedException("shared disk not implemented");
            }

            //the smallest valid size for a virtual hard disk is 3MB.
            var sizeBytes = Math.Max(request.SizeBytes, 3 * 1024 * 1024);

            //align size to 4096
            sizeBytes = sizeBytes % 4096 > 0 ? sizeBytes + 4096 - (sizeBytes % 4096) : sizeBytes;

            var name    = request.Name;
            var storage = !string.IsNullOrEmpty(request.Storage)
                    ? request.Storage
                    : await FindFreeStoragesAsync(sizeBytes)
                          .FirstOrDefaultAsync(cancellationToken);

            //use default storage
            if (string.IsNullOrEmpty(storage))
            {
                storage = !string.IsNullOrEmpty(DefaultStorage)
                    ? DefaultStorage
                    : throw new InvalidOperationException("no storage found or specified");
            }

            //todo check storage free space

            //handle windows Path under linux
            storage = storage.ToLower();

            var path = $@"{HypervDefaults.ClusterStoragePath}\{storage}\Volumes\{name}.vhdx";

            Command cmd;
            var     commands = new List <Command>(2);

            cmd = new Command("New-VHD");
            cmd.Parameters.Add("Path", path);
            cmd.Parameters.Add("SizeBytes", sizeBytes);
            cmd.Parameters.Add("Dynamic", request.Dynamic);
            cmd.Parameters.Add("BlockSizeBytes", request.BlockSizeBytes);
            cmd.Parameters.Add("LogicalSectorSizeBytes", 4096);
            cmd.Parameters.Add("PhysicalSectorSizeBytes", 4096);
            commands.Add(cmd);

            cmd = new Command("Select-Object");
            cmd.Parameters.Add("Property", new[] { "DiskIdentifier", "Path", "FileSize", "Size", "BlockSize", "VhdType", "Attached" });
            //todo ParentPath, FragmentationPercentage, VHDFormat
            commands.Add(cmd);

            dynamic item = await _power.InvokeAsync(commands).ThrowOnError().FirstAsync(cancellationToken);

            return(new HypervVolumeDetail
            {
                Id = Guid.Parse((string)item.DiskIdentifier),
                //Name = Path.GetFileNameWithoutExtension((string)item.Path),
                Name = name,
                Path = item.Path,
                FileSizeBytes = item.FileSize,
                SizeBytes = item.Size,
                Attached = item.Attached,
                BlockSizeBytes = item.BlockSize,
                Dynamic = item.VhdType switch
                {
                    "Dynamic" => true,
                    _ => false
                },