find($this->accountId); if (! $account) { Log::warning('ProvisionHostingAccountJob: Account not found', ['account_id' => $this->accountId]); return; } // Skip if already provisioned or not in pending status if ($account->status !== 'pending' && $account->provisioned_at !== null) { Log::info('ProvisionHostingAccountJob: Already provisioned', ['account_id' => $this->accountId, 'status' => $account->status]); return; } $node = $account->node; if (! $node) { Log::error('ProvisionHostingAccountJob: No node assigned', ['account_id' => $this->accountId]); $account->update(['status' => 'failed', 'notes' => 'No hosting node assigned']); return; } $product = $account->product; if (! $product) { Log::error('ProvisionHostingAccountJob: No product found', ['account_id' => $this->accountId]); $account->update(['status' => 'failed', 'notes' => 'No hosting product found']); return; } // Mark as provisioning $account->update(['status' => 'provisioning']); try { $password = \Illuminate\Support\Str::password(16, true, true, false, false); $domain = $account->primary_domain ?? $account->username . '.ladill.com'; $result = $provider->createAccountOnNode($node, [ 'username' => $account->username, 'password' => $password, 'domain' => $domain, 'php_version' => '8.4', 'disk_quota_mb' => max((int) ($product->disk_gb ?? 0), 1) * 1024, ]); $docRoot = $result['document_root'] ?? "/home/{$account->username}/public_html"; $account->update([ 'status' => 'active', 'home_directory' => $result['home_directory'] ?? "/home/{$account->username}", 'provisioned_at' => now(), 'metadata' => array_merge((array) $account->metadata, [ 'provisioned_password' => $password, // Store temporarily for admin reference 'provisioned_at' => now()->toISOString(), ]), ]); // Apply resource limits $provider->applyAccountResourceProfile($account->fresh(), false); // Install WordPress if it's a WordPress hosting product if ($product->type === 'wordpress') { $wpResult = $provider->installWordPress($node, $account->username, $domain, [ 'document_root' => $docRoot, 'admin_email' => $account->user?->email ?? 'admin@' . $domain, 'site_title' => $domain, ]); // Store WordPress credentials in account metadata $account->update([ 'metadata' => array_merge((array) $account->metadata, [ 'wp_admin_user' => $wpResult['admin_user'] ?? 'admin', 'wp_admin_password' => $wpResult['admin_password'] ?? null, 'wp_db_name' => $wpResult['db_name'] ?? null, 'wp_db_user' => $wpResult['db_user'] ?? null, 'wp_db_password' => $wpResult['db_password'] ?? null, ]), ]); Log::info('ProvisionHostingAccountJob: WordPress installed', [ 'account_id' => $this->accountId, 'domain' => $domain, ]); } // Refresh node capacity $capacityService->refreshNodeResourceTotals($node); Log::info('ProvisionHostingAccountJob: Successfully provisioned', [ 'account_id' => $this->accountId, 'username' => $account->username, 'node_id' => $node->id, ]); } catch (\Throwable $exception) { Log::error('ProvisionHostingAccountJob: Failed to provision', [ 'account_id' => $this->accountId, 'username' => $account->username, 'error' => $exception->getMessage(), 'trace' => $exception->getTraceAsString(), ]); $account->update([ 'status' => 'failed', 'notes' => 'Provisioning failed: ' . $exception->getMessage(), ]); // Re-throw to trigger retry throw $exception; } } public function failed(\Throwable $exception): void { Log::error('ProvisionHostingAccountJob: Job failed after all retries', [ 'account_id' => $this->accountId, 'error' => $exception->getMessage(), ]); $account = HostingAccount::find($this->accountId); if ($account) { $account->update([ 'status' => 'failed', 'notes' => 'Provisioning failed after retries: ' . $exception->getMessage(), ]); } } }