122 lines
3.6 KiB
PHP
122 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Modals;
|
|
|
|
use App\Models\AuditEvent;
|
|
use App\Models\Server;
|
|
use App\Services\MaintenanceService;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use LivewireUI\Modal\ModalComponent;
|
|
use Throwable;
|
|
|
|
/**
|
|
* Apply pending package updates across apt/dnf/zypper (resolved per OS). mount()
|
|
* reads whether updates are supported on this host + the pending count; the body
|
|
* explains in GERMAN what happens — never a shell command. „Jetzt aktualisieren"
|
|
* runs the upgrade, AUDITs, notifies, and keeps the modal open showing a clean
|
|
* German result. Unsupported hosts (e.g. Arch/Alpine) get a German reason instead.
|
|
*/
|
|
class SystemUpdate extends ModalComponent
|
|
{
|
|
public int $serverId;
|
|
|
|
public string $serverName = '';
|
|
|
|
/** True when Clusev can manage package updates on this host. */
|
|
public bool $supported = false;
|
|
|
|
/** German reason shown when updates are not supported on this OS. */
|
|
public ?string $unsupportedReason = null;
|
|
|
|
/** Pending upgrade count, or null when it could not be determined ("unbekannt"). */
|
|
public ?int $pending = null;
|
|
|
|
public bool $done = false;
|
|
|
|
public bool $ok = false;
|
|
|
|
/** Trimmed package-manager output, only shown when the upgrade failed. */
|
|
public string $output = '';
|
|
|
|
public ?string $error = null;
|
|
|
|
public function mount(int $serverId, MaintenanceService $maintenance): void
|
|
{
|
|
$this->serverId = $serverId;
|
|
|
|
$server = Server::find($serverId);
|
|
if (! $server) {
|
|
$this->error = 'Server nicht gefunden.';
|
|
|
|
return;
|
|
}
|
|
|
|
$this->serverName = $server->name;
|
|
|
|
try {
|
|
$this->unsupportedReason = $maintenance->updateSupport($server);
|
|
$this->supported = $this->unsupportedReason === null;
|
|
$this->pending = $this->supported ? $maintenance->pendingUpdates($server) : null;
|
|
} catch (Throwable $e) {
|
|
$this->error = $e->getMessage();
|
|
}
|
|
}
|
|
|
|
public static function modalMaxWidth(): string
|
|
{
|
|
return 'lg';
|
|
}
|
|
|
|
public function upgrade(MaintenanceService $maintenance): void
|
|
{
|
|
if ($this->error !== null || $this->done || ! $this->supported) {
|
|
return;
|
|
}
|
|
|
|
$server = Server::find($this->serverId);
|
|
if (! $server) {
|
|
$this->error = 'Server nicht gefunden.';
|
|
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$result = $maintenance->applyUpgrades($server);
|
|
} catch (Throwable $e) {
|
|
$this->done = true;
|
|
$this->ok = false;
|
|
$this->output = $e->getMessage();
|
|
$this->dispatch('notify', message: 'Aktualisierung fehlgeschlagen.');
|
|
|
|
return;
|
|
}
|
|
|
|
$this->done = true;
|
|
$this->ok = $result['ok'];
|
|
// On success we surface a clean German line, not the raw apt log; on failure
|
|
// the trimmed error tail helps the operator diagnose.
|
|
$this->output = $this->ok ? '' : $result['output'];
|
|
|
|
AuditEvent::create([
|
|
'user_id' => Auth::id(),
|
|
'server_id' => $server->id,
|
|
'actor' => Auth::user()?->name ?? 'system',
|
|
'action' => 'system.package_upgrade',
|
|
'target' => $server->name.($this->ok ? '' : ' (fehlgeschlagen)'),
|
|
'ip' => request()->ip(),
|
|
]);
|
|
|
|
if ($this->ok) {
|
|
$this->pending = 0;
|
|
$this->dispatch('notify', message: 'System aktualisiert.');
|
|
} else {
|
|
$this->dispatch('notify', message: 'Aktualisierung fehlgeschlagen.');
|
|
}
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('livewire.modals.system-update');
|
|
}
|
|
}
|