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(), ]); } }