refactor(models): extract defaultStandaloneDockerAttributes method on Server
Extract duplicated inline StandaloneDocker attribute arrays in the Server boot lifecycle into a dedicated method, eliminating repetition between the root-server (id=0) and normal-server paths. Also harden the shared_environment_variables migration by wrapping DDL statements in DB::transaction() and using DROP CONSTRAINT IF EXISTS to make the migration safely re-runnable. Add unit test covering the extracted method to verify uuid is always present in bootstrap attributes.
This commit is contained in:
parent
4f6e1f7e42
commit
466eb8504e
3 changed files with 61 additions and 24 deletions
|
|
@ -155,12 +155,7 @@ protected static function booted()
|
|||
'server_id' => $server->id,
|
||||
])->save();
|
||||
} else {
|
||||
(new StandaloneDocker)->forceFill([
|
||||
'id' => 0,
|
||||
'name' => 'coolify',
|
||||
'network' => 'coolify',
|
||||
'server_id' => $server->id,
|
||||
])->saveQuietly();
|
||||
(new StandaloneDocker)->forceFill($server->defaultStandaloneDockerAttributes(id: 0))->saveQuietly();
|
||||
}
|
||||
} else {
|
||||
if ($server->isSwarm()) {
|
||||
|
|
@ -171,12 +166,7 @@ protected static function booted()
|
|||
]);
|
||||
} else {
|
||||
$standaloneDocker = new StandaloneDocker;
|
||||
$standaloneDocker->forceFill([
|
||||
'name' => 'coolify',
|
||||
'uuid' => (string) new Cuid2,
|
||||
'network' => 'coolify',
|
||||
'server_id' => $server->id,
|
||||
]);
|
||||
$standaloneDocker->forceFill($server->defaultStandaloneDockerAttributes());
|
||||
$standaloneDocker->saveQuietly();
|
||||
}
|
||||
}
|
||||
|
|
@ -1043,6 +1033,25 @@ public function team()
|
|||
return $this->belongsTo(Team::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{id?: int, name: string, uuid: string, network: string, server_id: int}
|
||||
*/
|
||||
public function defaultStandaloneDockerAttributes(?int $id = null): array
|
||||
{
|
||||
$attributes = [
|
||||
'name' => 'coolify',
|
||||
'uuid' => (string) new Cuid2,
|
||||
'network' => 'coolify',
|
||||
'server_id' => $this->id,
|
||||
];
|
||||
|
||||
if (! is_null($id)) {
|
||||
$attributes['id'] = $id;
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
public function environment_variables()
|
||||
{
|
||||
return $this->hasMany(SharedEnvironmentVariable::class)->where('type', 'server');
|
||||
|
|
|
|||
|
|
@ -5,17 +5,23 @@
|
|||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration {
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
DB::statement("ALTER TABLE shared_environment_variables DROP CONSTRAINT shared_environment_variables_type_check");
|
||||
DB::statement("ALTER TABLE shared_environment_variables ADD CONSTRAINT shared_environment_variables_type_check CHECK (type IN ('team', 'project', 'environment', 'server'))");
|
||||
Schema::table('shared_environment_variables', function (Blueprint $table) {
|
||||
$table->foreignId('server_id')->nullable()->constrained()->onDelete('cascade');
|
||||
$table->unique(['key', 'server_id', 'team_id']);
|
||||
DB::transaction(function () {
|
||||
DB::statement('ALTER TABLE shared_environment_variables DROP CONSTRAINT IF EXISTS shared_environment_variables_type_check');
|
||||
DB::statement("ALTER TABLE shared_environment_variables ADD CONSTRAINT shared_environment_variables_type_check CHECK (type IN ('team', 'project', 'environment', 'server'))");
|
||||
Schema::table('shared_environment_variables', function (Blueprint $table) {
|
||||
$table->foreignId('server_id')->nullable()->constrained()->onDelete('cascade');
|
||||
// NULL != NULL in PostgreSQL unique indexes, so this only enforces uniqueness
|
||||
// for server-scoped rows (where server_id is non-null). Other scopes are covered
|
||||
// by existing unique constraints on ['key', 'project_id', 'team_id'] and ['key', 'environment_id', 'team_id'].
|
||||
$table->unique(['key', 'server_id', 'team_id']);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -24,12 +30,14 @@ public function up(): void
|
|||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('shared_environment_variables', function (Blueprint $table) {
|
||||
$table->dropUnique(['key', 'server_id', 'team_id']);
|
||||
$table->dropForeign(['server_id']);
|
||||
$table->dropColumn('server_id');
|
||||
DB::transaction(function () {
|
||||
Schema::table('shared_environment_variables', function (Blueprint $table) {
|
||||
$table->dropUnique(['key', 'server_id', 'team_id']);
|
||||
$table->dropForeign(['server_id']);
|
||||
$table->dropColumn('server_id');
|
||||
});
|
||||
DB::statement('ALTER TABLE shared_environment_variables DROP CONSTRAINT IF EXISTS shared_environment_variables_type_check');
|
||||
DB::statement("ALTER TABLE shared_environment_variables ADD CONSTRAINT shared_environment_variables_type_check CHECK (type IN ('team', 'project', 'environment'))");
|
||||
});
|
||||
DB::statement("ALTER TABLE shared_environment_variables DROP CONSTRAINT shared_environment_variables_type_check");
|
||||
DB::statement("ALTER TABLE shared_environment_variables ADD CONSTRAINT shared_environment_variables_type_check CHECK (type IN ('team', 'project', 'environment'))");
|
||||
}
|
||||
};
|
||||
|
|
|
|||
20
tests/Unit/ServerBootstrapDestinationAttributesTest.php
Normal file
20
tests/Unit/ServerBootstrapDestinationAttributesTest.php
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Server;
|
||||
|
||||
it('includes a uuid in standalone docker bootstrap attributes for the root server path', function () {
|
||||
$server = new Server;
|
||||
$server->id = 0;
|
||||
|
||||
$attributes = $server->defaultStandaloneDockerAttributes(id: 0);
|
||||
|
||||
expect($attributes)
|
||||
->toMatchArray([
|
||||
'id' => 0,
|
||||
'name' => 'coolify',
|
||||
'network' => 'coolify',
|
||||
'server_id' => 0,
|
||||
])
|
||||
->and($attributes['uuid'])->toBeString()
|
||||
->and($attributes['uuid'])->not->toBe('');
|
||||
});
|
||||
Loading…
Reference in a new issue