mirror of
https://github.com/tiennm99/coolify.git
synced 2026-10-14 06:17:36 +00:00
feat(v5): add mesh app canvas
This commit is contained in:
1 parent
155b07378c
commit
86156b6f7a
53 files changed
+6037
-113
No files matched your search
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('v5_applications', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('team_id')->constrained('teams')->cascadeOnDelete();
|
||||
$table->foreignId('project_id')->constrained('projects')->cascadeOnDelete();
|
||||
$table->foreignId('environment_id')->constrained('environments')->cascadeOnDelete();
|
||||
$table->foreignId('server_id')->nullable()->constrained('v5_servers')->nullOnDelete();
|
||||
$table->foreignId('created_by_user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->string('name');
|
||||
$table->string('image');
|
||||
$table->string('container_name')->unique();
|
||||
$table->string('status')->default('creating');
|
||||
$table->text('status_message')->nullable();
|
||||
$table->string('runtime_container_id')->nullable();
|
||||
$table->string('mesh_namespace')->default('default');
|
||||
$table->integer('canvas_x')->default(0);
|
||||
$table->integer('canvas_y')->default(0);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['team_id', 'status']);
|
||||
$table->index(['team_id', 'project_id', 'environment_id']);
|
||||
$table->index(['team_id', 'server_id']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('v5_applications');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('v5_servers', function (Blueprint $table) {
|
||||
$table->integer('canvas_x')->nullable()->after('container_subnets');
|
||||
$table->integer('canvas_y')->nullable()->after('canvas_x');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('v5_servers', function (Blueprint $table) {
|
||||
$table->dropColumn(['canvas_x', 'canvas_y']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('v5_resource_connections', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('team_id')->constrained('teams')->cascadeOnDelete();
|
||||
$table->foreignId('project_id')->constrained('projects')->cascadeOnDelete();
|
||||
$table->foreignId('environment_id')->constrained('environments')->cascadeOnDelete();
|
||||
$table->morphs('resource_one');
|
||||
$table->morphs('resource_two');
|
||||
$table->string('resource_pair_key');
|
||||
$table->foreignId('created_by_user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['team_id', 'resource_pair_key']);
|
||||
$table->index(['team_id', 'project_id', 'environment_id']);
|
||||
});
|
||||
|
||||
Schema::create('v5_resource_connection_rules', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('connection_id')->constrained('v5_resource_connections')->cascadeOnDelete();
|
||||
$table->morphs('source_resource');
|
||||
$table->morphs('target_resource');
|
||||
$table->string('protocol')->default('tcp');
|
||||
$table->unsignedSmallInteger('port');
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique([
|
||||
'connection_id',
|
||||
'source_resource_type',
|
||||
'source_resource_id',
|
||||
'target_resource_type',
|
||||
'target_resource_id',
|
||||
'protocol',
|
||||
'port',
|
||||
], 'v5_resource_connection_rules_unique_direction_port');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('v5_resource_connection_rules');
|
||||
Schema::dropIfExists('v5_resource_connections');
|
||||
}
|
||||
};
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('v5_servers', function (Blueprint $table) {
|
||||
$table->string('caddy_ingress_status')->nullable()->after('status');
|
||||
});
|
||||
|
||||
DB::table('v5_servers')
|
||||
->where('status', 'installed')
|
||||
->where(function ($query) {
|
||||
$query
|
||||
->where('capabilities', 'like', '%"ingress"%')
|
||||
->orWhere('capabilities', 'like', '%ingress%');
|
||||
})
|
||||
->update(['caddy_ingress_status' => 'running']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('v5_servers', function (Blueprint $table) {
|
||||
$table->dropColumn('caddy_ingress_status');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('v5_container_statuses', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('team_id')->constrained('teams')->cascadeOnDelete();
|
||||
$table->foreignId('server_id')->constrained('v5_servers')->cascadeOnDelete();
|
||||
$table->string('container_id');
|
||||
$table->string('container_name')->nullable();
|
||||
$table->string('image')->nullable();
|
||||
$table->string('status')->default('unknown');
|
||||
$table->text('status_message')->nullable();
|
||||
$table->timestamp('last_seen_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['server_id', 'container_id']);
|
||||
$table->index(['team_id', 'server_id']);
|
||||
$table->index(['team_id', 'status']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('v5_container_statuses');
|
||||
}
|
||||
};
|
||||
@@ -1363,6 +1363,7 @@ CREATE TABLE IF NOT EXISTS "v5_servers" (
|
||||
"ssh_user" TEXT NOT NULL,
|
||||
"ssh_port" INTEGER DEFAULT '22' NOT NULL,
|
||||
"status" TEXT DEFAULT 'installed' NOT NULL,
|
||||
"caddy_ingress_status" TEXT,
|
||||
"capabilities" TEXT,
|
||||
"builder_enabled" INTEGER DEFAULT false NOT NULL,
|
||||
"builder_capacity" INTEGER DEFAULT '0' NOT NULL,
|
||||
@@ -1373,6 +1374,8 @@ CREATE TABLE IF NOT EXISTS "v5_servers" (
|
||||
"wireguard_management_ip" TEXT,
|
||||
"wireguard_public_key" TEXT,
|
||||
"container_subnets" JSON,
|
||||
"canvas_x" INTEGER,
|
||||
"canvas_y" INTEGER,
|
||||
"last_bootstrapped_at" TEXT,
|
||||
"last_bootstrap_action" TEXT,
|
||||
"last_bootstrap_status" TEXT,
|
||||
@@ -1385,6 +1388,40 @@ CREATE TABLE IF NOT EXISTS "v5_servers" (
|
||||
"updated_at" TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "v5_container_statuses" (
|
||||
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"team_id" INTEGER NOT NULL,
|
||||
"server_id" INTEGER NOT NULL,
|
||||
"container_id" TEXT NOT NULL,
|
||||
"container_name" TEXT,
|
||||
"image" TEXT,
|
||||
"status" TEXT DEFAULT 'unknown' NOT NULL,
|
||||
"status_message" TEXT,
|
||||
"last_seen_at" TEXT,
|
||||
"created_at" TEXT,
|
||||
"updated_at" TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "v5_applications" (
|
||||
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"team_id" INTEGER NOT NULL,
|
||||
"project_id" INTEGER NOT NULL,
|
||||
"environment_id" INTEGER NOT NULL,
|
||||
"server_id" INTEGER,
|
||||
"created_by_user_id" INTEGER NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"image" TEXT NOT NULL,
|
||||
"container_name" TEXT NOT NULL,
|
||||
"status" TEXT DEFAULT 'creating' NOT NULL,
|
||||
"status_message" TEXT,
|
||||
"runtime_container_id" TEXT,
|
||||
"mesh_namespace" TEXT DEFAULT 'default' NOT NULL,
|
||||
"canvas_x" INTEGER DEFAULT '0' NOT NULL,
|
||||
"canvas_y" INTEGER DEFAULT '0' NOT NULL,
|
||||
"created_at" TEXT,
|
||||
"updated_at" TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "webhook_notification_settings" (
|
||||
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"team_id" INTEGER NOT NULL,
|
||||
@@ -1499,6 +1536,7 @@ CREATE INDEX IF NOT EXISTS "user_changelog_reads_release_tag_index" ON "user_cha
|
||||
CREATE INDEX IF NOT EXISTS "user_changelog_reads_user_id_index" ON "user_changelog_reads" (user_id);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "user_changelog_reads_user_id_release_tag_unique" ON "user_changelog_reads" (user_id, release_tag);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "users_email_unique" ON "users" (email);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "v5_applications_container_name_unique" ON "v5_applications" (container_name);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "v5_servers_uuid_unique" ON "v5_servers" (uuid);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "webhook_notification_settings_team_id_unique" ON "webhook_notification_settings" (team_id);
|
||||
|
||||
@@ -1819,3 +1857,7 @@ INSERT INTO "migrations" ("id", "migration", "batch") VALUES (313, '2025_12_17_0
|
||||
INSERT INTO "migrations" ("id", "migration", "batch") VALUES (314, '2025_12_17_000002_add_restart_tracking_to_standalone_databases', 314);
|
||||
INSERT INTO "migrations" ("id", "migration", "batch") VALUES (316, '2026_06_16_130649_v5_create_clusters_table', 316);
|
||||
INSERT INTO "migrations" ("id", "migration", "batch") VALUES (317, '2026_06_16_130650_v5_create_servers_table', 317);
|
||||
INSERT INTO "migrations" ("id", "migration", "batch") VALUES (318, '2026_06_19_140000_v5_create_applications_table', 318);
|
||||
INSERT INTO "migrations" ("id", "migration", "batch") VALUES (319, '2026_06_19_141231_add_canvas_position_to_v5_servers_table', 319);
|
||||
INSERT INTO "migrations" ("id", "migration", "batch") VALUES (320, '2026_06_19_173933_add_caddy_ingress_status_to_v5_servers_table', 320);
|
||||
INSERT INTO "migrations" ("id", "migration", "batch") VALUES (321, '2026_06_19_182231_create_container_statuses_table', 321);
|
||||
@@ -2,11 +2,10 @@
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Actions\V5\Server\SyncDevLimaServers;
|
||||
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
|
||||
@@ -25,14 +24,6 @@ class V5DevLimaSeeder extends Seeder
|
||||
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)
|
||||
@@ -40,34 +31,26 @@ class V5DevLimaSeeder extends Seeder
|
||||
->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'],
|
||||
$servers = collect($this->servers())
|
||||
->map(fn (array $server): array => [
|
||||
...$server,
|
||||
'ssh_user' => $sshUser,
|
||||
'status' => 'installed',
|
||||
'capabilities' => $capabilities,
|
||||
'builder_enabled' => $builderEnabled,
|
||||
'builder_capacity' => $builderCapacity,
|
||||
'wireguard_listen_port_override' => $server['wireguard_listen_port_override'],
|
||||
'wireguard_endpoint_override' => $server['wireguard_endpoint_override'],
|
||||
'last_bootstrapped_at' => now(),
|
||||
]);
|
||||
}
|
||||
])
|
||||
->all();
|
||||
|
||||
SyncDevLimaServers::run(
|
||||
team: $team,
|
||||
user: $user,
|
||||
privateKey: $privateKey,
|
||||
clusterName: self::CLUSTER_NAME,
|
||||
builderCapacity: $builderCapacity,
|
||||
servers: $servers,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array{name: string, host: string, ssh_port: int, wireguard_listen_port_override: int, wireguard_endpoint_override: string}>
|
||||
* @return array<int, array{name: string, host: string, ssh_port: int, wireguard_management_ip: string, wireguard_listen_port_override: int, wireguard_endpoint_override: string}>
|
||||
*/
|
||||
private function servers(): array
|
||||
{
|
||||
@@ -76,6 +59,7 @@ class V5DevLimaSeeder extends Seeder
|
||||
'name' => 'coold-dev',
|
||||
'host' => 'host.docker.internal',
|
||||
'ssh_port' => 60001,
|
||||
'wireguard_management_ip' => '100.64.0.1',
|
||||
'wireguard_listen_port_override' => 51821,
|
||||
'wireguard_endpoint_override' => 'host.lima.internal:51821',
|
||||
],
|
||||
@@ -83,6 +67,7 @@ class V5DevLimaSeeder extends Seeder
|
||||
'name' => 'coold-dev-2',
|
||||
'host' => 'host.docker.internal',
|
||||
'ssh_port' => 60002,
|
||||
'wireguard_management_ip' => '100.64.0.2',
|
||||
'wireguard_listen_port_override' => 51822,
|
||||
'wireguard_endpoint_override' => 'host.lima.internal:51822',
|
||||
],
|
||||
|
||||
Reference in new issue
Block a user