public Task <HypervVolumeDetail> CreateVolumeAsync(HypervCreateVolumeRequest request, CancellationToken cancellationToken = default) { return(GetHost(_options.HostName).CreateVolumeAsync(request, cancellationToken)); }
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 },