refactor(dev): replace v5:sync-dev-lima-servers with V5DevLimaSeeder

Switch Lima VM dev-environment sync from a custom Artisan command to a
database seeder. The seeder creates/updates the Development-Lima cluster
and its two servers idempotently, reading ssh_user from the
COOLIFY_CLI_SSH_USER env var (exposed via config('coold.dev_ssh_user')).

dev.sh now passes COOLIFY_CLI_SSH_USER and runs db:seed instead of
building per-server --server flag arrays.
This commit is contained in:
Andras Bacsai
2026-06-16 17:10:40 +02:00
parent 9566b259b2
commit 295addb6b0
7 changed files with 129 additions and 22 deletions
+1
View File
@@ -6,4 +6,5 @@ return [
'corrosion_version' => env('COOLIFY_CORROSION_VERSION', 'v1.0.0'),
'dev_builder_capacity' => (int) env('COOLIFY_COOLD_VM_BUILDER_CAPACITY', 2),
'dev_builder_enabled' => (int) env('COOLIFY_COOLD_VM_BUILDER_CAPACITY', 2) > 0,
'dev_ssh_user' => env('COOLIFY_CLI_SSH_USER', get_current_user()),
];
+1
View File
@@ -35,6 +35,7 @@ class DatabaseSeeder extends Seeder
if (in_array(config('app.env'), ['local', 'development', 'dev'], true)) {
$this->call([
DevelopmentRailpackExamplesSeeder::class,
V5DevLimaSeeder::class,
]);
}
}
+85
View File
@@ -0,0 +1,85 @@
<?php
namespace Database\Seeders;
use App\Models\PrivateKey;
use App\Models\Team;
use App\Models\User;
use App\Models\V5\Cluster;
use App\Models\V5\Server;
use Illuminate\Database\Seeder;
class V5DevLimaSeeder extends Seeder
{
private const CLUSTER_NAME = 'Development-Lima';
/**
* Run the database seeds.
*/
public function run(): void
{
$team = Team::query()->find(0) ?? Team::query()->orderBy('id')->first();
$user = User::query()->find(0) ?? User::query()->orderBy('id')->first();
if (! $team instanceof Team || ! $user instanceof User) {
return;
}
$cluster = Cluster::query()->updateOrCreate([
'team_id' => $team->id,
'name' => self::CLUSTER_NAME,
], [
'created_by_user_id' => $user->id,
'description' => 'Local Lima development cluster managed by scripts/dev.sh.',
]);
$privateKey = PrivateKey::query()
->where('team_id', $team->id)
->where('is_git_related', false)
->orderBy('id')
->first();
$builderCapacity = max(0, (int) config('coold.dev_builder_capacity', 2));
$builderEnabled = $builderCapacity > 0;
$capabilities = $builderEnabled ? ['coold', 'builder'] : ['coold'];
$sshUser = (string) config('coold.dev_ssh_user', get_current_user());
foreach ($this->servers() as $server) {
Server::query()->updateOrCreate([
'team_id' => $team->id,
'host' => $server['host'],
'ssh_port' => $server['ssh_port'],
], [
'cluster_id' => $cluster->id,
'created_by_user_id' => $user->id,
'private_key_id' => $privateKey?->id,
'name' => $server['name'],
'ssh_user' => $sshUser,
'status' => 'installed',
'capabilities' => $capabilities,
'builder_enabled' => $builderEnabled,
'builder_capacity' => $builderCapacity,
'last_bootstrapped_at' => now(),
]);
}
}
/**
* @return array<int, array{name: string, host: string, ssh_port: int}>
*/
private function servers(): array
{
return [
[
'name' => 'coold-dev',
'host' => 'lima-coold-dev',
'ssh_port' => 22,
],
[
'name' => 'coold-dev-2',
'host' => 'lima-coold-dev-2',
'ssh_port' => 22,
],
];
}
}
+6 -18
View File
@@ -417,29 +417,17 @@ follow_logs() {
}
sync_v5_dev_lima_servers() {
local count
local builder_capacity
local args=()
local instance
local node
local ssh_user
count="$(coold_vm_count)"
builder_capacity="$(read_coolify_env COOLIFY_COOLD_VM_BUILDER_CAPACITY 2)"
for index in $(seq 1 "$count"); do
instance="$(coold_vm_instance "$index")"
node="$(lima_ssh_target "$index")"
args+=(--server "${instance}|${node}|$(coolify_ssh_user)|22")
done
ssh_user="$(coolify_ssh_user)"
echo "==> Running pending migrations before syncing v5 dev Lima state..."
spin exec -T coolify php artisan migrate --force
echo "==> Syncing dev Lima VM(s) into v5 clusters/servers..."
spin exec -T coolify php artisan v5:sync-dev-lima-servers \
--cluster="Development-Lima" \
--builder-capacity="$builder_capacity" \
"${args[@]}"
echo "==> Seeding dev Lima VM(s) into v5 clusters/servers..."
spin exec -T \
-e COOLIFY_CLI_SSH_USER="$ssh_user" \
coolify php artisan db:seed --class=V5DevLimaSeeder --force
}
configure_flux_dev_for_vm() {
@@ -29,3 +29,11 @@ it('defaults coold dev VM settings in Laravel config', function () {
->and(config('coold.dev_builder_capacity'))->toBe(2)
->and(config('coold.dev_builder_enabled'))->toBeTrue();
});
it('runs the v5 dev Lima seeder with the normal development database seeder', function () {
$databaseSeeder = file_get_contents(database_path('seeders/DatabaseSeeder.php'));
$developmentSeederBlock = str($databaseSeeder)->after("if (in_array(config('app.env'), ['local', 'development', 'dev'], true)) {")->before(' }')->toString();
expect($developmentSeederBlock)->toContain('DevelopmentRailpackExamplesSeeder::class')
->and($developmentSeederBlock)->toContain('V5DevLimaSeeder::class');
});
@@ -59,13 +59,14 @@ it('retries dev coolify bootstrap because fresh Lima setup can complete across p
->and($script)->toContain('fresh Lima hosts can finish setup after partial bootstrap phases');
});
it('syncs bootstrapped Lima VMs into v5 development server state', function () {
it('seeds bootstrapped Lima VMs into v5 development server state', function () {
$script = file_get_contents(base_path('scripts/dev.sh'));
expect($script)->toContain('sync_v5_dev_lima_servers()')
->and($script)->toContain('v5:sync-dev-lima-servers')
->and($script)->toContain('--cluster="Development-Lima"')
->and($script)->toContain('--server "${instance}|${node}|$(coolify_ssh_user)|22"');
->and($script)->toContain('COOLIFY_CLI_SSH_USER="$ssh_user"')
->and($script)->toContain('db:seed --class=V5DevLimaSeeder --force')
->and($script)->not->toContain('v5:sync-dev-lima-servers')
->and($script)->not->toContain('--server "${instance}|${node}|$(coolify_ssh_user)|22"');
});
it('supports down cleanup as the preferred VM cleanup command', function () {
+23
View File
@@ -11,6 +11,7 @@ use App\Models\User;
use App\Models\V5\Cluster;
use App\Models\V5\Server as V5Server;
use App\Services\Flux\FluxHealth;
use Database\Seeders\V5DevLimaSeeder;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Process;
@@ -465,6 +466,28 @@ it('syncs dev Lima VMs into v5 clusters and servers', function () {
->and(V5Server::query()->where('name', 'coold-dev-2')->where('host', 'lima-coold-dev-2')->exists())->toBeTrue();
});
it('seeds dev Lima VMs into v5 clusters and servers idempotently', function () {
createSharedUserAndTeamTables();
[$user, $team] = createV5UserWithTeam();
createV5PrivateKey($team, 'Dev Lima Key');
config()->set('coold.dev_builder_capacity', 2);
(new V5DevLimaSeeder)->run();
(new V5DevLimaSeeder)->run();
$cluster = Cluster::query()->where('name', 'Development-Lima')->sole();
expect($cluster->team_id)->toBe($team->id)
->and($cluster->created_by_user_id)->toBe($user->id)
->and($cluster->description)->toBe('Local Lima development cluster managed by scripts/dev.sh.')
->and(V5Server::query()->count())->toBe(2)
->and(V5Server::query()->where('name', 'coold-dev')->where('host', 'lima-coold-dev')->where('ssh_user', get_current_user())->where('ssh_port', 22)->exists())->toBeTrue()
->and(V5Server::query()->where('name', 'coold-dev-2')->where('host', 'lima-coold-dev-2')->where('ssh_user', get_current_user())->where('ssh_port', 22)->exists())->toBeTrue()
->and(V5Server::query()->where('status', 'installed')->count())->toBe(2)
->and(V5Server::query()->where('builder_enabled', true)->where('builder_capacity', 2)->count())->toBe(2)
->and(V5Server::query()->where('cluster_id', $cluster->id)->count())->toBe(2);
});
function fakeFluxHealth(bool $available = true, string $message = 'Flux is running.'): void
{
app()->instance(FluxHealth::class, Mockery::mock(FluxHealth::class, function (MockInterface $mock) use ($available, $message) {