using System; using System.Collections.Generic; using System.Management.Automation; using PSProxmox.Client; using PSProxmox.Models; using PSProxmox.Session; namespace PSProxmox.Cmdlets { /// /// Restores a cluster backup in Proxmox VE. /// The Restore-ProxmoxClusterBackup cmdlet restores a cluster backup in Proxmox VE. /// /// Restore a cluster backup /// Restore-ProxmoxClusterBackup -Connection $connection -BackupID "vzdump-cluster-2023_04_28-12_00_00.vma.lzo" -Force /// /// /// Restore a cluster backup using pipeline input /// Get-ProxmoxClusterBackup -Connection $connection | Select-Object -First 1 | Restore-ProxmoxClusterBackup -Connection $connection -Force /// /// [Cmdlet(VerbsData.Restore, "ProxmoxClusterBackup", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)] public class RestoreProxmoxClusterBackupCmdlet : PSCmdlet { /// /// The connection to the Proxmox VE server. /// [Parameter(Mandatory = true, Position = 0)] public ProxmoxConnection Connection { get; set; } /// /// The ID of the backup to restore. /// [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)] public string BackupID { get; set; } /// /// Whether to force the restore operation. /// [Parameter(Mandatory = false)] public SwitchParameter Force { get; set; } /// /// Whether to wait for the restore to complete. /// [Parameter(Mandatory = false)] public SwitchParameter Wait { get; set; } /// /// The timeout in seconds to wait for the restore to complete. /// [Parameter(Mandatory = false)] public int Timeout { get; set; } = 600; /// /// Processes the cmdlet. /// protected override void ProcessRecord() { try { var client = new ProxmoxApiClient(Connection, this); // Confirm restore if (!ShouldProcess($"Cluster backup {BackupID}", "Restore")) { return; } // Restore the backup var parameters = new Dictionary { ["backup-id"] = BackupID }; if (Force.IsPresent) { parameters["force"] = "1"; } WriteVerbose($"Restoring cluster backup {BackupID}"); string response = client.Post("cluster/backup/restore", parameters); var taskData = PSProxmox.Utilities.JsonUtility.DeserializeResponse(response); string taskId = taskData.data; if (Wait.IsPresent && !string.IsNullOrEmpty(taskId)) { WriteVerbose($"Waiting for restore task {taskId} to complete"); int attempts = 0; int maxAttempts = Timeout / 5; bool completed = false; while (attempts < maxAttempts) { string taskResponse = client.Get($"nodes/{Connection.Server}/tasks/{taskId}/status"); var taskStatus = PSProxmox.Utilities.JsonUtility.DeserializeResponse(taskResponse); string status = taskStatus.data.status; if (status == "stopped") { completed = true; break; } System.Threading.Thread.Sleep(5000); attempts++; } if (!completed) { WriteWarning($"Timeout waiting for restore task {taskId} to complete"); } else { WriteVerbose($"Restore task {taskId} completed successfully"); } } WriteVerbose($"Cluster backup {BackupID} restored"); } catch (Exception ex) { WriteError(new ErrorRecord(ex, "RestoreProxmoxClusterBackupError", ErrorCategory.OperationStopped, BackupID)); } } } }