Add managed registry provisioning, pruning, and readiness tracking
This commit is contained in:
128
app/Services/Registries/ManagedRegistryHealth.php
Normal file
128
app/Services/Registries/ManagedRegistryHealth.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Registries;
|
||||
|
||||
use App\Enums\RegistryType;
|
||||
use App\Models\Registry;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class ManagedRegistryHealth
|
||||
{
|
||||
public function check(Registry $registry): bool
|
||||
{
|
||||
if ($registry->type !== RegistryType::MANAGED) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$message = $this->configurationBlocker($registry);
|
||||
|
||||
if ($message !== null) {
|
||||
$registry->markUnhealthy($message);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::timeout(5)->get('https://'.$registry->url.'/v2/');
|
||||
} catch (\Throwable $exception) {
|
||||
$registry->markUnhealthy('Registry URL is not reachable over HTTPS: '.$exception->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! in_array($response->status(), [200, 401], true)) {
|
||||
$registry->markUnhealthy('Registry HTTPS check returned HTTP '.$response->status().'.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$checks = $registry->readiness_checks ?? [];
|
||||
$checks['control_https'] = 'passed';
|
||||
|
||||
$registry->forceFill([
|
||||
'readiness_checks' => $checks,
|
||||
])->save();
|
||||
|
||||
if ($this->readinessChecksPassed($registry->refresh())) {
|
||||
$registry->markHealthy('Registry HTTPS endpoint and smoke checks passed.');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$registry->markUnhealthy('Registry HTTPS endpoint is reachable, but smoke checks have not all passed.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function readinessBlocker(Registry $registry): ?string
|
||||
{
|
||||
if ($registry->type !== RegistryType::MANAGED) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$message = $this->configurationBlocker($registry);
|
||||
|
||||
if ($message !== null) {
|
||||
return $message;
|
||||
}
|
||||
|
||||
if ($registry->ready_at === null || $registry->health_status !== 'healthy') {
|
||||
return 'Managed registry has not passed readiness checks.';
|
||||
}
|
||||
|
||||
if (! $this->readinessChecksPassed($registry)) {
|
||||
return 'Managed registry smoke checks have not all passed.';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function configurationBlocker(Registry $registry): ?string
|
||||
{
|
||||
if (! $registry->url) {
|
||||
return 'Managed registry URL is not configured.';
|
||||
}
|
||||
|
||||
if (! str_contains((string) $registry->url, '.')) {
|
||||
return 'Managed registry must use a resolvable HTTPS hostname.';
|
||||
}
|
||||
|
||||
$credentials = $registry->credentials ?? [];
|
||||
|
||||
foreach (['build_username', 'build_password', 'runtime_username', 'runtime_password'] as $key) {
|
||||
if (blank($credentials[$key] ?? null)) {
|
||||
return 'Managed registry credentials are incomplete.';
|
||||
}
|
||||
}
|
||||
|
||||
$controlServer = $registry->controlServer;
|
||||
|
||||
if (! $controlServer instanceof Server) {
|
||||
return 'A control/build server is required for managed registry builds.';
|
||||
}
|
||||
|
||||
if (! $controlServer->build_enabled) {
|
||||
return 'The managed registry control server is not build-enabled.';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function readinessChecksPassed(Registry $registry): bool
|
||||
{
|
||||
$checks = $registry->readiness_checks ?? [];
|
||||
|
||||
if ($checks === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (['control_https', 'build_push'] as $requiredCheck) {
|
||||
if (! array_key_exists($requiredCheck, $checks)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return collect($checks)->every(fn (mixed $status): bool => $status === 'passed');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user