Add managed registry provisioning, pruning, and readiness tracking
This commit is contained in:
49
app/Console/Commands/CheckManagedRegistry.php
Normal file
49
app/Console/Commands/CheckManagedRegistry.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Actions\Registries\CreateManagedRegistrySmokeCheckOperation;
|
||||
use App\Enums\RegistryType;
|
||||
use App\Models\Registry;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class CheckManagedRegistry extends Command
|
||||
{
|
||||
protected $signature = 'keystone:managed-registry:check
|
||||
{registry : Managed registry id}
|
||||
{--build-server= : Build server id, defaults to the registry control server}
|
||||
{--runtime-server=* : Runtime server id to pull the smoke image}
|
||||
{--dispatch : Dispatch the first operation step immediately}';
|
||||
|
||||
protected $description = 'Create managed registry HTTPS/auth/push/pull smoke-check operations.';
|
||||
|
||||
public function handle(CreateManagedRegistrySmokeCheckOperation $operations): int
|
||||
{
|
||||
$registry = Registry::query()
|
||||
->where('type', RegistryType::MANAGED->value)
|
||||
->findOrFail((int) $this->argument('registry'));
|
||||
|
||||
$buildServer = $this->option('build-server')
|
||||
? Server::query()
|
||||
->where('organisation_id', $registry->organisation_id)
|
||||
->findOrFail((int) $this->option('build-server'))
|
||||
: null;
|
||||
|
||||
$runtimeServers = collect($this->option('runtime-server'))
|
||||
->map(fn (string $serverId): Server => Server::query()
|
||||
->where('organisation_id', $registry->organisation_id)
|
||||
->findOrFail((int) $serverId));
|
||||
|
||||
$operation = $operations->execute($registry, $buildServer, $runtimeServers);
|
||||
|
||||
$this->info("Created registry smoke-check operation {$operation->id}.");
|
||||
|
||||
if ($this->option('dispatch')) {
|
||||
$operation->steps()->orderBy('order')->first()?->dispatchJob();
|
||||
$this->info('Dispatched registry smoke-check operation.');
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
87
app/Console/Commands/ProvisionManagedRegistry.php
Normal file
87
app/Console/Commands/ProvisionManagedRegistry.php
Normal 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;
|
||||
}
|
||||
}
|
||||
40
app/Console/Commands/PruneManagedRegistry.php
Normal file
40
app/Console/Commands/PruneManagedRegistry.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Actions\Registries\CreateManagedRegistryMaintenanceOperation;
|
||||
use App\Enums\RegistryType;
|
||||
use App\Models\Registry;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class PruneManagedRegistry extends Command
|
||||
{
|
||||
protected $signature = 'keystone:managed-registry:prune
|
||||
{registry? : Managed registry id}
|
||||
{--dispatch : Dispatch the first operation step immediately}';
|
||||
|
||||
protected $description = 'Create managed registry manifest deletion and garbage-collection operations.';
|
||||
|
||||
public function handle(CreateManagedRegistryMaintenanceOperation $operations): int
|
||||
{
|
||||
$registries = Registry::query()
|
||||
->where('type', RegistryType::MANAGED->value)
|
||||
->when($this->argument('registry'), fn ($query) => $query->whereKey((int) $this->argument('registry')))
|
||||
->get();
|
||||
|
||||
$count = 0;
|
||||
|
||||
foreach ($registries as $registry) {
|
||||
$operation = $operations->execute($registry);
|
||||
$count++;
|
||||
|
||||
if ($this->option('dispatch')) {
|
||||
$operation->steps()->orderBy('order')->first()?->dispatchJob();
|
||||
}
|
||||
}
|
||||
|
||||
$this->info("Created {$count} managed registry maintenance operation(s).");
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user