Deploy Ladill Hosting / deploy (push) Failing after 17s
Shared web hosting extracted from the platform monolith, with CI deploy to /var/www/ladill-hosting matching Bird/Domains/Email. Co-authored-by: Cursor <cursoragent@cursor.com>
141 lines
4.8 KiB
PHP
141 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Hosting\PanelRuntimes;
|
|
|
|
use App\Models\CustomerHostingOrder;
|
|
use App\Models\ServerAgent;
|
|
use App\Models\ServerTask;
|
|
use App\Services\Hosting\ServerAgentBootstrapService;
|
|
use Illuminate\Support\Str;
|
|
use RuntimeException;
|
|
|
|
class ServerAgentPanelRuntime
|
|
{
|
|
public function __construct(
|
|
private ServerAgentBootstrapService $bootstrap,
|
|
) {}
|
|
|
|
public function label(): string
|
|
{
|
|
return 'Ladill Hosting Panel';
|
|
}
|
|
|
|
public function supports(CustomerHostingOrder $order): bool
|
|
{
|
|
return (bool) data_get($order->meta, 'server_panel_runtime.managed_stack_candidate', false);
|
|
}
|
|
|
|
public function ensureAgent(CustomerHostingOrder $order): ServerAgent
|
|
{
|
|
if (! $this->supports($order)) {
|
|
throw new RuntimeException('This server image is not enabled for agent-backed Ladill hosting tasks.');
|
|
}
|
|
|
|
return $this->bootstrap->ensureBootstrap($order)['agent'];
|
|
}
|
|
|
|
public function queueDomainTask(CustomerHostingOrder $order, string $domain, ?string $documentRoot = null, ?string $phpVersion = null): ServerTask
|
|
{
|
|
return $this->queueTask($order, ServerTask::TYPE_DOMAIN_ADD, array_filter([
|
|
'domain' => strtolower($domain),
|
|
'document_root' => $documentRoot,
|
|
'php_version' => $phpVersion,
|
|
], static fn ($value): bool => $value !== null && $value !== ''));
|
|
}
|
|
|
|
public function queueSslTask(CustomerHostingOrder $order, string $domain): ServerTask
|
|
{
|
|
return $this->queueTask($order, ServerTask::TYPE_SSL_REQUEST, [
|
|
'domain' => strtolower($domain),
|
|
]);
|
|
}
|
|
|
|
public function queueDatabaseTask(CustomerHostingOrder $order, string $name): ServerTask
|
|
{
|
|
return $this->queueTask($order, ServerTask::TYPE_DATABASE_CREATE, [
|
|
'name' => Str::lower($name),
|
|
]);
|
|
}
|
|
|
|
public function queueSiteDeleteTask(CustomerHostingOrder $order, string $domain): ServerTask
|
|
{
|
|
return $this->queueTask($order, ServerTask::TYPE_SITE_DELETE, [
|
|
'domain' => strtolower($domain),
|
|
]);
|
|
}
|
|
|
|
public function queuePhpTask(CustomerHostingOrder $order, string $domain, string $phpVersion): ServerTask
|
|
{
|
|
return $this->queueTask($order, ServerTask::TYPE_PHP_CONFIGURE, [
|
|
'domain' => strtolower($domain),
|
|
'php_version' => $phpVersion,
|
|
]);
|
|
}
|
|
|
|
public function queueCronTask(
|
|
CustomerHostingOrder $order,
|
|
string $operation,
|
|
?string $name = null,
|
|
?string $expression = null,
|
|
?string $command = null,
|
|
?string $user = null,
|
|
): ServerTask {
|
|
$taskType = match ($operation) {
|
|
'list' => ServerTask::TYPE_CRON_LIST,
|
|
'upsert' => ServerTask::TYPE_CRON_UPSERT,
|
|
'remove' => ServerTask::TYPE_CRON_REMOVE,
|
|
default => throw new RuntimeException('Unsupported cron operation.'),
|
|
};
|
|
|
|
return $this->queueTask($order, $taskType, array_filter([
|
|
'name' => $name,
|
|
'expression' => $expression,
|
|
'command' => $command,
|
|
'user' => $user,
|
|
], static fn ($value): bool => $value !== null && $value !== ''));
|
|
}
|
|
|
|
public function queueLogTask(CustomerHostingOrder $order, string $target, ?string $domain = null, int $lines = 120): ServerTask
|
|
{
|
|
return $this->queueTask($order, ServerTask::TYPE_LOG_READ, [
|
|
'target' => $target,
|
|
'domain' => $domain ? strtolower($domain) : null,
|
|
'lines' => max(20, min(500, $lines)),
|
|
]);
|
|
}
|
|
|
|
public function queueFileTask(CustomerHostingOrder $order, string $operation, string $path, ?string $content = null): ServerTask
|
|
{
|
|
$taskType = match ($operation) {
|
|
'list' => ServerTask::TYPE_FILE_LIST,
|
|
'read' => ServerTask::TYPE_FILE_READ,
|
|
'write' => ServerTask::TYPE_FILE_WRITE,
|
|
default => throw new RuntimeException('Unsupported file operation.'),
|
|
};
|
|
|
|
return $this->queueTask($order, $taskType, array_filter([
|
|
'path' => $path,
|
|
'content' => $content,
|
|
], static fn ($value): bool => $value !== null));
|
|
}
|
|
|
|
private function queueTask(CustomerHostingOrder $order, string $type, array $payload): ServerTask
|
|
{
|
|
$agent = $this->ensureAgent($order);
|
|
|
|
return ServerTask::create([
|
|
'customer_hosting_order_id' => $order->id,
|
|
'server_agent_id' => $agent->id,
|
|
'type' => $type,
|
|
'status' => ServerTask::STATUS_QUEUED,
|
|
'payload' => $payload,
|
|
'progress' => 0,
|
|
'max_attempts' => 3,
|
|
'retry_backoff_seconds' => 60,
|
|
'stale_after_seconds' => 120,
|
|
'queued_at' => now(),
|
|
'available_at' => now(),
|
|
]);
|
|
}
|
|
}
|