Implement Keystone environment deployments

This commit is contained in:
2026-05-13 16:11:23 +01:00
parent 65d3142d03
commit aa680b25fd
175 changed files with 10258 additions and 740 deletions

View File

@@ -0,0 +1,154 @@
<?php
namespace App\Drivers\Valkey;
use App\Data\Operations\Plan;
use App\Data\Operations\PlannedStep;
use App\Drivers\Concerns\RendersCompose;
use App\Drivers\Concerns\SupportsSlices;
use App\Drivers\Driver;
use App\Enums\EnvironmentAttachmentRole;
use App\Enums\ServiceType;
use App\Models\Service;
use App\Models\ServiceSlice;
class Valkey8Driver extends Driver implements RendersCompose, SupportsSlices
{
public function __construct(
public ?string $containerName = null,
public ?string $containerId = null,
public ?Service $service = null,
) {
//
}
public function getOperationPlan(string $operationHash): Plan
{
return new Plan(steps: [
new PlannedStep(
name: 'Render Compose file',
script: "mkdir -p /home/keystone/services/{$this->service?->id}",
),
new PlannedStep(
name: 'Start Valkey service',
script: "docker compose -f /home/keystone/services/{$this->service?->id}/compose.yml up -d",
),
]);
}
public function serviceType(): ServiceType
{
return ServiceType::VALKEY;
}
public function versionTrack(): string
{
return '8';
}
public function defaultImage(): string
{
return 'valkey/valkey:8';
}
public function defaultPorts(): array
{
return [6379];
}
public function firewallRules(): array
{
return ['6379/tcp'];
}
public function environmentSchema(): array
{
return [];
}
public function resourceDefaults(): array
{
return [];
}
public function updateBehavior(): string
{
return 'stateful_downtime';
}
public function supportedSliceTypes(): array
{
return ['logical_database'];
}
public function environmentExportsForSlice(ServiceSlice $slice, ?EnvironmentAttachmentRole $role = null): array
{
$exports = [
'REDIS_HOST' => $slice->config['host'] ?? "keystone-service-{$slice->service_id}",
'REDIS_PORT' => (string) ($slice->config['port'] ?? 6379),
'REDIS_DB' => (string) ($slice->config['database'] ?? 0),
];
return match ($role) {
EnvironmentAttachmentRole::CACHE => [
...$exports,
'CACHE_STORE' => 'redis',
],
EnvironmentAttachmentRole::QUEUE => [
...$exports,
'QUEUE_CONNECTION' => 'redis',
],
EnvironmentAttachmentRole::CUSTOM,
EnvironmentAttachmentRole::DATABASE,
EnvironmentAttachmentRole::GATEWAY,
EnvironmentAttachmentRole::STORAGE,
null => $exports,
};
}
public function provisionSliceScript(ServiceSlice $slice): string
{
$serviceKey = str($slice->service->name)->slug('_')->value() ?: 'valkey';
return 'docker compose -f /home/keystone/services/'.$slice->service_id.'/compose.yml exec -T '.$serviceKey.' valkey-cli -n '.escapeshellarg((string) ($slice->config['database'] ?? 0)).' PING';
}
public function composeService(): array
{
$service = [
'image' => $this->service?->available_image_digest
?: $this->service?->current_image_digest
?: $this->defaultImage(),
'restart' => 'unless-stopped',
'healthcheck' => [
'test' => ['CMD', 'valkey-cli', 'ping'],
'interval' => '10s',
'timeout' => '5s',
'retries' => 5,
],
];
if ($this->service?->config['persistence'] ?? false) {
$service['volumes'] = ["keystone_service_{$this->service->id}_valkey_data:/data"];
$service['command'] = ['valkey-server', '--appendonly', 'yes'];
}
return $service;
}
public function composeVolumes(): array
{
if (! ($this->service?->config['persistence'] ?? false)) {
return [];
}
return [
"keystone_service_{$this->service->id}_valkey_data" => null,
];
}
public function environmentExports(): array
{
return [];
}
}