diff --git a/src/PSProxmoxVE.Core/Services/ContainerService.cs b/src/PSProxmoxVE.Core/Services/ContainerService.cs index c4cd6f7..341f1f0 100644 --- a/src/PSProxmoxVE.Core/Services/ContainerService.cs +++ b/src/PSProxmoxVE.Core/Services/ContainerService.cs @@ -362,7 +362,8 @@ namespace PSProxmoxVE.Core.Services int newid, string? hostname = null, string? targetNode = null, - bool full = true) + bool full = true, + string? storage = null) { if (session == null) throw new ArgumentNullException(nameof(session)); if (string.IsNullOrWhiteSpace(node)) throw new ArgumentNullException(nameof(node)); @@ -374,6 +375,7 @@ namespace PSProxmoxVE.Core.Services }; if (!string.IsNullOrEmpty(hostname)) formData["hostname"] = hostname!; if (!string.IsNullOrEmpty(targetNode)) formData["target"] = targetNode!; + if (!string.IsNullOrEmpty(storage)) formData["storage"] = storage!; IPveHttpClient client = _injectedClient ?? new PveHttpClient(session); try diff --git a/src/PSProxmoxVE/Cmdlets/Containers/CopyPveContainerCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Containers/CopyPveContainerCmdlet.cs index fdc0a17..4d66f4c 100644 --- a/src/PSProxmoxVE/Cmdlets/Containers/CopyPveContainerCmdlet.cs +++ b/src/PSProxmoxVE/Cmdlets/Containers/CopyPveContainerCmdlet.cs @@ -72,6 +72,13 @@ namespace PSProxmoxVE.Cmdlets.Containers protected override void ProcessRecord() { + if (!string.IsNullOrEmpty(Storage) && !Full.IsPresent) + ThrowTerminatingError(new ErrorRecord( + new PSArgumentException("-Storage is only valid together with -Full; PVE rejects a target storage on a linked clone.", nameof(Storage)), + "StorageRequiresFullClone", + ErrorCategory.InvalidArgument, + Storage)); + var target = TargetNode ?? SourceNode; if (!ShouldProcess($"Container {VmId} on node '{SourceNode}' to new container on node '{target}'", "Copy-PveContainer")) return; @@ -80,14 +87,18 @@ namespace PSProxmoxVE.Cmdlets.Containers var containerService = new ContainerService(); WriteVerbose($"Cloning container {VmId}..."); + var newid = NewVmId ?? new ClusterConfigService().GetNextId(session); + if (!NewVmId.HasValue) + WriteVerbose($"Auto-assigned container ID: {newid}"); var task = containerService.CloneContainer( session, SourceNode, VmId, - NewVmId ?? 0, + newid, NewName, TargetNode, - Full.IsPresent); + Full.IsPresent, + Storage); if (Wait.IsPresent) { diff --git a/src/PSProxmoxVE/Cmdlets/Vms/CopyPveVmCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/CopyPveVmCmdlet.cs index f25f679..9151ecc 100644 --- a/src/PSProxmoxVE/Cmdlets/Vms/CopyPveVmCmdlet.cs +++ b/src/PSProxmoxVE/Cmdlets/Vms/CopyPveVmCmdlet.cs @@ -72,6 +72,13 @@ namespace PSProxmoxVE.Cmdlets.Vms protected override void ProcessRecord() { + if (!string.IsNullOrEmpty(Storage) && !Full.IsPresent) + ThrowTerminatingError(new ErrorRecord( + new PSArgumentException("-Storage is only valid together with -Full; PVE rejects a target storage on a linked clone.", nameof(Storage)), + "StorageRequiresFullClone", + ErrorCategory.InvalidArgument, + Storage)); + var target = TargetNode ?? SourceNode; if (!ShouldProcess($"VM {VmId} on node '{SourceNode}' to new VM on node '{target}'", "Copy-PveVm")) return; @@ -80,8 +87,10 @@ namespace PSProxmoxVE.Cmdlets.Vms var vmService = new VmService(); WriteVerbose($"Cloning VM {VmId}..."); - var newid = NewVmId ?? 0; - PveTask Issue() => vmService.CloneVm(session, SourceNode, VmId, newid, NewName, TargetNode, Full.IsPresent); + var newid = NewVmId ?? new ClusterConfigService().GetNextId(session); + if (!NewVmId.HasValue) + WriteVerbose($"Auto-assigned VM ID: {newid}"); + PveTask Issue() => vmService.CloneVm(session, SourceNode, VmId, newid, NewName, TargetNode, Full.IsPresent, Storage); var task = Wait.IsPresent ? InvokeGuestTask(session, SourceNode, Issue) diff --git a/src/PSProxmoxVE/Cmdlets/Vms/ImportPveOvaCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/ImportPveOvaCmdlet.cs index 32a124e..5b89ef8 100644 --- a/src/PSProxmoxVE/Cmdlets/Vms/ImportPveOvaCmdlet.cs +++ b/src/PSProxmoxVE/Cmdlets/Vms/ImportPveOvaCmdlet.cs @@ -3,8 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Management.Automation; using System.Net; -using Newtonsoft.Json.Linq; -using PSProxmoxVE.Core.Client; using PSProxmoxVE.Core.Exceptions; using PSProxmoxVE.Core.Models.Vms; using PSProxmoxVE.Core.Services; @@ -151,10 +149,7 @@ namespace PSProxmoxVE.Cmdlets.Vms } else { - using var allocClient = new PveHttpClient(session); - var nextIdJson = allocClient.GetAsync("cluster/nextid").GetAwaiter().GetResult(); - var nextIdData = JObject.Parse(nextIdJson)["data"]; - vmId = int.Parse(nextIdData!.ToString()); + vmId = new ClusterConfigService().GetNextId(session); WriteVerbose($"Auto-assigned VM ID: {vmId}"); } diff --git a/src/PSProxmoxVE/Cmdlets/Vms/NewPveVmCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/NewPveVmCmdlet.cs index ae48844..f3d4fb3 100644 --- a/src/PSProxmoxVE/Cmdlets/Vms/NewPveVmCmdlet.cs +++ b/src/PSProxmoxVE/Cmdlets/Vms/NewPveVmCmdlet.cs @@ -1,7 +1,5 @@ using System.Collections.Generic; using System.Management.Automation; -using Newtonsoft.Json.Linq; -using PSProxmoxVE.Core.Client; using PSProxmoxVE.Core.Models.Vms; using PSProxmoxVE.Core.Services; using PSProxmoxVE.Core.Utilities; @@ -214,11 +212,7 @@ namespace PSProxmoxVE.Cmdlets.Vms } else { - // Auto-allocate the next available VM ID from the cluster. - using var allocClient = new PveHttpClient(session); - var nextIdJson = allocClient.GetAsync("cluster/nextid").GetAwaiter().GetResult(); - var nextIdData = JObject.Parse(nextIdJson)["data"]; - config["vmid"] = int.Parse(nextIdData!.ToString()); + config["vmid"] = new ClusterConfigService().GetNextId(session); } if (!string.IsNullOrEmpty(Name)) config["name"] = Name!;