diff --git a/Module/PSProxmox.psd1 b/Module/PSProxmox.psd1 index fadc0f2..f694cdb 100644 --- a/Module/PSProxmox.psd1 +++ b/Module/PSProxmox.psd1 @@ -1,5 +1,5 @@ @{ - ModuleVersion = '2025.05.11.0935' + ModuleVersion = '2025.05.11.1030' GUID = 'd24f0894-3d0c-4ef1-a41e-b273c3db86ad' Author = 'PSProxmox Team' CompanyName = 'PSProxmox' @@ -106,7 +106,7 @@ Tags = @('Proxmox', 'VirtualMachine', 'Cluster', 'Management') LicenseUri = 'https://github.com/Grace-Solutions/PSProxmox/blob/main/LICENSE' ProjectUri = 'https://github.com/Grace-Solutions/PSProxmox' - ReleaseNotes = 'Added LXC container and TurnKey template support. See https://github.com/Grace-Solutions/PSProxmox/releases/tag/v2025.05.11.0935' + ReleaseNotes = 'Added LXC container and TurnKey template support. Fixed cloud image functionality and added pipeline support. See https://github.com/Grace-Solutions/PSProxmox/releases/tag/v2025.05.11.1030' } } } diff --git a/PSProxmox/CloudImages/CloudImageRepository.cs b/PSProxmox/CloudImages/CloudImageRepository.cs index 5cea2ec..06413bc 100644 --- a/PSProxmox/CloudImages/CloudImageRepository.cs +++ b/PSProxmox/CloudImages/CloudImageRepository.cs @@ -68,14 +68,14 @@ namespace PSProxmox.CloudImages (string.IsNullOrEmpty(variant) || i.Variant == variant)); } - private static async Task>> GetMetadataAsync() + private static Task>> GetMetadataAsync() { if (File.Exists(_metadataFile)) { try { var json = File.ReadAllText(_metadataFile); - return JsonConvert.DeserializeObject>>(json); + return Task.FromResult(JsonConvert.DeserializeObject>>(json)); } catch { @@ -83,13 +83,14 @@ namespace PSProxmox.CloudImages } } - return new Dictionary>(StringComparer.OrdinalIgnoreCase); + return Task.FromResult(new Dictionary>(StringComparer.OrdinalIgnoreCase)); } - private static async Task SaveMetadataAsync(Dictionary> metadata) + private static Task SaveMetadataAsync(Dictionary> metadata) { var json = JsonConvert.SerializeObject(metadata, Formatting.Indented); File.WriteAllText(_metadataFile, json); + return Task.CompletedTask; } private static async Task> FetchDistributionMetadataAsync(string distribution) diff --git a/PSProxmox/Cmdlets/GetProxmoxCloudImageCmdlet.cs b/PSProxmox/Cmdlets/GetProxmoxCloudImageCmdlet.cs index 64f2da5..a805cb6 100644 --- a/PSProxmox/Cmdlets/GetProxmoxCloudImageCmdlet.cs +++ b/PSProxmox/Cmdlets/GetProxmoxCloudImageCmdlet.cs @@ -25,6 +25,10 @@ namespace PSProxmox.Cmdlets /// Get Ubuntu 22.04 cloud images /// Get-ProxmoxCloudImage -Distribution "ubuntu" -Release "22.04" /// + /// + /// Get Ubuntu 22.04 server cloud image and download it + /// Get-ProxmoxCloudImage -Distribution "ubuntu" -Release "22.04" -Variant "server" | Save-ProxmoxCloudImage + /// [Cmdlet(VerbsCommon.Get, "ProxmoxCloudImage")] [OutputType(typeof(CloudImage))] public class GetProxmoxCloudImageCmdlet : PSCmdlet diff --git a/PSProxmox/Cmdlets/SaveProxmoxCloudImageCmdlet.cs b/PSProxmox/Cmdlets/SaveProxmoxCloudImageCmdlet.cs index 92c8290..137cb42 100644 --- a/PSProxmox/Cmdlets/SaveProxmoxCloudImageCmdlet.cs +++ b/PSProxmox/Cmdlets/SaveProxmoxCloudImageCmdlet.cs @@ -20,6 +20,14 @@ namespace PSProxmox.Cmdlets /// Download a Debian 11 generic cloud image /// Save-ProxmoxCloudImage -Distribution "debian" -Release "11" -Variant "generic" /// + /// + /// Get Ubuntu 22.04 server cloud image and download it + /// Get-ProxmoxCloudImage -Distribution "ubuntu" -Release "22.04" -Variant "server" | Save-ProxmoxCloudImage + /// + /// + /// Download an Ubuntu 22.04 server cloud image to a specific location + /// Save-ProxmoxCloudImage -Distribution "ubuntu" -Release "22.04" -Variant "server" -OutputPath "C:\Images\ubuntu-22.04-server.img" + /// [Cmdlet(VerbsData.Save, "ProxmoxCloudImage")] [OutputType(typeof(string))] public class SaveProxmoxCloudImageCmdlet : PSCmdlet @@ -27,32 +35,40 @@ namespace PSProxmox.Cmdlets /// /// The distribution to download (e.g., "ubuntu", "debian"). /// - [Parameter(Mandatory = true, Position = 0)] + [Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true, ParameterSetName = "ByProperties")] [ValidateSet("ubuntu", "debian")] public string Distribution { get; set; } /// /// The release version to download (e.g., "22.04", "11"). /// - [Parameter(Mandatory = true, Position = 1)] + [Parameter(Mandatory = true, Position = 1, ValueFromPipelineByPropertyName = true, ParameterSetName = "ByProperties")] public string Release { get; set; } /// /// The image variant to download (e.g., "server", "minimal"). /// - [Parameter(Mandatory = false, Position = 2)] + [Parameter(Mandatory = false, Position = 2, ValueFromPipelineByPropertyName = true, ParameterSetName = "ByProperties")] public string Variant { get; set; } + /// + /// The cloud image object to download. + /// + [Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = "ByCloudImage")] + public CloudImage CloudImage { get; set; } + /// /// The output path where the image will be saved. If not specified, the image will be saved to the default download directory. /// - [Parameter(Mandatory = false)] + [Parameter(Mandatory = false, ParameterSetName = "ByProperties")] + [Parameter(Mandatory = false, ParameterSetName = "ByCloudImage")] public string OutputPath { get; set; } /// /// Force download even if the image already exists. /// - [Parameter(Mandatory = false)] + [Parameter(Mandatory = false, ParameterSetName = "ByProperties")] + [Parameter(Mandatory = false, ParameterSetName = "ByCloudImage")] public SwitchParameter Force { get; set; } /// @@ -65,10 +81,21 @@ namespace PSProxmox.Cmdlets var task = Task.Run(async () => { // Get the cloud image - var image = await CloudImageRepository.GetImageAsync(Distribution, Release, Variant); - if (image == null) + CloudImage image; + + if (ParameterSetName == "ByCloudImage") { - throw new Exception($"Cloud image not found for {Distribution} {Release} {Variant}"); + // Use the provided CloudImage object + image = CloudImage; + } + else + { + // Get the cloud image from the repository + image = await CloudImageRepository.GetImageAsync(Distribution, Release, Variant); + if (image == null) + { + throw new Exception($"Cloud image not found for {Distribution} {Release} {Variant}"); + } } // Create a cancellation token source