Add managed registry provisioning, pruning, and readiness tracking

This commit is contained in:
2026-06-08 20:44:16 +01:00
parent 5b977c1f41
commit 3a851db08f
52 changed files with 2706 additions and 116 deletions

View File

@@ -0,0 +1,87 @@
<?php
namespace App\Console\Commands;
use App\Actions\Registries\CreateManagedRegistryProvisionOperation;
use App\Models\Organisation;
use App\Models\Server;
use App\Services\Registries\ManagedRegistryHealth;
use App\Services\Registries\ManagedRegistryProvisioner;
use Illuminate\Console\Command;
class ProvisionManagedRegistry extends Command
{
protected $signature = 'keystone:managed-registry:provision
{organisation : Organisation id or slug}
{--url= : HTTPS registry hostname}
{--control-server= : Control/build server id}
{--storage-path= : Registry storage path}
{--retention= : Successful artifacts to retain per environment}
{--create-operation : Create the remote registry install/proxy operation}
{--dispatch : Dispatch the first operation step immediately}
{--mark-healthy : Mark the persisted registry ready after configuration validation}';
protected $description = 'Persist and optionally install a first-party managed Docker registry.';
public function handle(ManagedRegistryProvisioner $provisioner, ManagedRegistryHealth $health, CreateManagedRegistryProvisionOperation $operations): int
{
$organisationKey = (string) $this->argument('organisation');
$organisation = Organisation::query()
->where('id', $organisationKey)
->orWhere('slug', $organisationKey)
->firstOrFail();
$url = (string) ($this->option('url') ?: config('keystone.managed_registry.url'));
if ($url === '') {
$this->error('Provide --url or KEYSTONE_MANAGED_REGISTRY_URL.');
return self::FAILURE;
}
$controlServer = $this->option('control-server')
? Server::query()
->where('organisation_id', $organisation->id)
->findOrFail((int) $this->option('control-server'))
: null;
$registry = $provisioner->provision(
organisation: $organisation,
url: $url,
controlServer: $controlServer,
storagePath: $this->option('storage-path') ? (string) $this->option('storage-path') : null,
retention: $this->option('retention') ? (int) $this->option('retention') : null,
);
$blocker = $health->readinessBlocker($registry);
if ($this->option('mark-healthy') && $blocker !== null && $blocker !== 'Managed registry has not passed readiness checks.') {
$this->error($blocker);
return self::FAILURE;
}
if ($this->option('mark-healthy')) {
$registry->markHealthy('Marked ready by provisioning command.');
$blocker = null;
}
$this->info("Managed registry {$registry->url} persisted for {$organisation->name}.");
if ($blocker !== null) {
$this->warn($blocker);
}
if ($this->option('create-operation')) {
$operation = $operations->execute($registry);
$this->info("Created registry provision operation {$operation->id}.");
if ($this->option('dispatch')) {
$operation->steps()->orderBy('order')->first()?->dispatchJob();
$this->info('Dispatched registry provision operation.');
}
}
return self::SUCCESS;
}
}