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>
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user