169 lines
5.2 KiB
PHP
169 lines
5.2 KiB
PHP
<?php
|
|
|
|
namespace Paymenter\Extensions\Servers\Proxmox\Livewire\Backups;
|
|
|
|
use Livewire\Attributes\Locked;
|
|
use Paymenter\Extensions\Servers\Proxmox\Livewire\Component;
|
|
use Paymenter\Extensions\Servers\Proxmox\Models\Server;
|
|
use Paymenter\Extensions\Servers\Proxmox\Proxmox;
|
|
|
|
class Index extends Component
|
|
{
|
|
#[Locked]
|
|
public $backups = [];
|
|
|
|
public $showRestore = false;
|
|
|
|
public $confirmRestore = false;
|
|
|
|
public bool $showDelete = false;
|
|
|
|
public bool $confirmDelete = false;
|
|
|
|
public $volid;
|
|
|
|
public function mount(Server $server): void
|
|
{
|
|
parent::mount($server);
|
|
|
|
$proxmox = new Proxmox;
|
|
$settings = $this->server->service->product->settings()->where('key', 'backups')->first();
|
|
if ($settings?->value <= 0) {
|
|
$this->redirect(route('proxmox.server.overview', $this->server->id), true);
|
|
|
|
return;
|
|
}
|
|
|
|
// Check if backup_location is configured
|
|
if (empty($this->server->node->backup_location)) {
|
|
$this->backups = [];
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$response = $proxmox->request('/nodes/' . $this->server->node->name . '/storage/' . $this->server->node->backup_location . '/content', data: [
|
|
'content' => 'backup',
|
|
'vmid' => $this->server->vm_id,
|
|
]);
|
|
|
|
$this->backups = $response->json()['data'] ?? [];
|
|
} catch (\Exception $e) {
|
|
$this->backups = [];
|
|
// Log the error for debugging
|
|
\Illuminate\Support\Facades\Log::error('Failed to fetch backups: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
public function restoreBackup()
|
|
{
|
|
$this->validate([
|
|
'volid' => 'required',
|
|
]);
|
|
|
|
if (!$this->confirmRestore) {
|
|
$this->notify('Please confirm the restore action', 'error');
|
|
|
|
return;
|
|
}
|
|
|
|
// Check if backup exists
|
|
$backup = collect($this->backups)->firstWhere('volid', $this->volid);
|
|
if (!$backup) {
|
|
$this->notify('Backup not found', 'error');
|
|
|
|
return;
|
|
}
|
|
|
|
$proxmox = new Proxmox;
|
|
|
|
// Stop the VM before restoring — Proxmox requires it
|
|
try {
|
|
$proxmox->requestAndWait('/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/status/stop', 'post', [
|
|
'vmid' => $this->server->vm_id,
|
|
], $this->server->node->name);
|
|
} catch (\Exception $e) {
|
|
$msg = strtolower($e->getMessage());
|
|
// If VM is already stopped, continue with restore; otherwise abort
|
|
if (!str_contains($msg, 'not running')
|
|
&& !str_contains($msg, 'already stopped')
|
|
&& !str_contains($msg, 'is not running')) {
|
|
$this->notify('Failed to stop VM before restore: ' . $e->getMessage(), 'error');
|
|
return;
|
|
}
|
|
}
|
|
|
|
try {
|
|
$proxmox->request('/nodes/' . $this->server->node->name . '/qemu', 'post', data: [
|
|
'vmid' => $this->server->vm_id,
|
|
'force' => true,
|
|
'archive' => $this->volid,
|
|
]);
|
|
} catch (\Throwable $e) {
|
|
$this->notify('Backup restore failed: ' . $e->getMessage(), 'error');
|
|
return;
|
|
}
|
|
|
|
$this->notify('Backup restoration in progress', 'success');
|
|
|
|
$this->showRestore = false;
|
|
|
|
// Redirect to the server overview page
|
|
$this->redirect(route('proxmox.server.overview', $this->server->id), true);
|
|
}
|
|
|
|
public function promptDelete(string $volid): void
|
|
{
|
|
$this->volid = $volid;
|
|
$this->confirmDelete = false;
|
|
$this->showDelete = true;
|
|
}
|
|
|
|
public function deleteBackup(?string $volid = null)
|
|
{
|
|
$volid = $volid ?? $this->volid;
|
|
|
|
if (!$volid) {
|
|
$this->notify('Select a backup to delete.', 'error');
|
|
|
|
return;
|
|
}
|
|
|
|
if (!$this->confirmDelete) {
|
|
$this->notify('Please confirm the delete action', 'error');
|
|
|
|
return;
|
|
}
|
|
|
|
// Check if backup exists
|
|
$backup = collect($this->backups)->firstWhere('volid', $volid);
|
|
if (!$backup) {
|
|
$this->notify('Backup not found', 'error');
|
|
|
|
return;
|
|
}
|
|
|
|
$proxmox = new Proxmox;
|
|
|
|
try {
|
|
$response = $proxmox->request('/nodes/' . $this->server->node->name . '/storage/' . $this->server->node->backup_location . '/content/' . $volid, 'delete');
|
|
|
|
$this->notify('Backup deleted successfully', 'success');
|
|
$this->backups = array_values(array_filter($this->backups, fn ($backup) => $backup['volid'] !== $volid));
|
|
$this->showDelete = false;
|
|
$this->confirmDelete = false;
|
|
$this->volid = null;
|
|
} catch (\Illuminate\Http\Client\RequestException $e) {
|
|
$errors = $e->response?->json()['errors'] ?? null;
|
|
$message = is_array($errors) ? implode(', ', array_values($errors)) : 'Unknown error';
|
|
$this->notify('Failed to delete backup: ' . $message, 'error');
|
|
}
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('proxmox::backups')->layoutData([
|
|
'sidebar' => true,
|
|
]);
|
|
}
|
|
}
|