CluPilotCloud/app/Provisioning/Steps/Customer/DeployApplicationStack.php

54 lines
1.7 KiB
PHP

<?php
namespace App\Provisioning\Steps\Customer;
use App\Models\ProvisioningRun;
use App\Provisioning\StepResult;
use App\Services\Proxmox\ProxmoxClient;
use Illuminate\Support\Str;
class DeployApplicationStack extends CustomerStep
{
public function __construct(private ProxmoxClient $pve) {}
public function key(): string
{
return 'deploy_application_stack';
}
public function maxDuration(): int
{
return 1200;
}
public function execute(ProvisioningRun $run): StepResult
{
$instance = $this->instance($run);
$node = (string) $run->context('node');
$vmid = (int) $run->context('vmid');
$pve = $this->pve->forHost($instance->host);
// Deploy once (guarded). The generated DB password is written straight
// into the guest's .env and never persisted in the run context.
if (! $run->context('stack_deployed')) {
$dbPassword = Str::random(28);
$this->guest($pve, $run,
'install -d /opt/nextcloud && printf %s '.escapeshellarg('MYSQL_PASSWORD='.$dbPassword."\n").
' > /opt/nextcloud/.env');
$this->guest($pve, $run, 'cd /opt/nextcloud && docker compose up -d');
$run->mergeContext(['stack_deployed' => true]);
}
// Poll until Nextcloud answers (poll doesn't consume the retry budget).
$health = $pve->guestExec($node, $vmid,
'curl -sf http://localhost/status.php >/dev/null 2>&1 && echo ok || echo wait');
if (trim($health['out-data'] ?? '') !== 'ok') {
return StepResult::poll(15, 'waiting for application stack');
}
return StepResult::advance();
}
}