Files
ladill-servers/app/Console/Commands/AuditHostingPhpFpmPoolsCommand.php
T
isaaccladandCursor b6c8ac343f Extract Ladill Servers as standalone app at servers.ladill.com.
VPS and dedicated server ordering, managed panels, SSO, billing, and launcher integration — forked from hosting infrastructure with server-focused routes and dashboard.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 19:18:30 +00:00

108 lines
3.3 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\HostingAccount;
use App\Services\Hosting\Providers\SharedNodeProvider;
use Illuminate\Console\Command;
class AuditHostingPhpFpmPoolsCommand extends Command
{
protected $signature = 'hosting:audit-php-fpm-pools
{--account= : Limit to one hosting account id}
{--repair : Remove duplicate pools and keep the account PHP version}';
protected $description = 'Scan shared hosting accounts for duplicate PHP-FPM pool configs across PHP versions.';
public function handle(SharedNodeProvider $provider): int
{
$accounts = HostingAccount::query()
->with('node')
->where('type', HostingAccount::TYPE_SHARED)
->when($this->option('account'), fn ($query, $accountId) => $query->whereKey($accountId))
->orderBy('id')
->get();
if ($accounts->isEmpty()) {
$this->info('No hosting accounts matched.');
return self::SUCCESS;
}
$issues = 0;
$repaired = 0;
$failures = 0;
foreach ($accounts as $account) {
if (! $account->node) {
$this->warn("[{$account->id}] {$account->username}: no node assigned");
continue;
}
try {
$versions = $provider->findPhpFpmPoolVersions($account);
} catch (\Throwable $e) {
$failures++;
$this->error("[{$account->id}] {$account->username}: {$e->getMessage()}");
continue;
}
if ($versions === []) {
$this->line("[{$account->id}] {$account->username}: no pool configs found");
continue;
}
$targetVersion = $account->php_version ?? '8.4';
$status = count($versions) === 1 && $versions[0] === $targetVersion
? 'ok'
: 'duplicate';
$this->line(sprintf(
'[%d] %s: pools=%s target=%s (%s)',
$account->id,
$account->username,
implode(', ', $versions),
$targetVersion,
$status,
));
if ($status === 'ok') {
continue;
}
$issues++;
if (! $this->option('repair')) {
continue;
}
try {
if ($provider->changeAccountPhpVersion($account, $targetVersion)) {
$repaired++;
$this->info(" repaired {$account->username}");
} else {
$failures++;
$this->error(" failed to repair {$account->username}");
}
} catch (\Throwable $e) {
$failures++;
$this->error(" failed to repair {$account->username}: {$e->getMessage()}");
}
}
$this->newLine();
$this->info("Accounts scanned: {$accounts->count()}");
$this->info("Issues found: {$issues}");
if ($this->option('repair')) {
$this->info("Repaired: {$repaired}");
$this->info("Failures: {$failures}");
}
return $failures > 0 ? self::FAILURE : ($issues > 0 && ! $this->option('repair') ? self::FAILURE : self::SUCCESS);
}
}