diff --git a/app/Http/Controllers/SwarmTaskController.php b/app/Http/Controllers/SwarmTaskController.php index b13f200..a1fcfeb 100644 --- a/app/Http/Controllers/SwarmTaskController.php +++ b/app/Http/Controllers/SwarmTaskController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Http\Requests\NodeTask\InitClusterFormRequest; +use App\Models\DeploymentData; use App\Models\Network; use App\Models\Node; use App\Models\NodeTaskGroup; @@ -26,7 +27,7 @@ public function initCluster(InitClusterFormRequest $request) $network = Network::create([ 'swarm_id' => $swarm->id, - 'name' => 'ptah-net', + 'name' => dockerize_name('ptah-net'), ]); $taskGroup = NodeTaskGroup::create([ @@ -36,7 +37,7 @@ public function initCluster(InitClusterFormRequest $request) 'invoker_id' => auth()->user()->id, ]); - $taskGroup->tasks()->createMany([ + $tasks = [ [ 'type' => NodeTaskType::InitSwarm, 'meta' => InitSwarmMeta::from([ @@ -64,7 +65,7 @@ public function initCluster(InitClusterFormRequest $request) 'type' => NodeTaskType::CreateNetwork, 'meta' => CreateNetworkMeta::from(['networkId' => $network->id, 'name' => $network->name]), 'payload' => [ - 'NetworkName' => $network->name, + 'NetworkName' => $network->docker_name, 'NetworkCreateOptions' => [ 'Driver' => 'overlay', 'Labels' => dockerize_labels([ @@ -73,10 +74,68 @@ public function initCluster(InitClusterFormRequest $request) ], ], ], - // TODO: create bare-bones Caddy -// [ -// 'type' => NodeTaskType::CreateService, -// ] + ]; + + $caddyService = $swarm->services()->create([ + 'name' => 'caddy', + ]); + + $deployment = $caddyService->deployments()->create([ + 'task_group_id' => $taskGroup->id, + 'data' => DeploymentData::from([ + 'dockerRegistryId' => null, + 'dockerImage' => 'caddy:2.8-alpine', + 'envVars' => [ + [ + 'name' => 'CADDY_ADMIN', + 'value' => '0.0.0.0:2019', + ] + ], + 'secretVars' => [], + 'configFiles' => [ + [ + 'path' => '/ptah/caddy/tls/.keep', + 'content' => '# Keep this file', + ] + ], + 'secretFiles' => [], + 'volumes' => [ + [ + 'name' => 'data', + 'path' => '/data', + ], + [ + 'name' => 'config', + 'path' => '/config', + ] + ], + 'networkName' => $network->docker_name, + 'internalDomain' => 'caddy.ptah.local', + 'ports' => [ + [ + 'targetPort' => '80', + 'publishedPort' => '80', + ], + [ + 'targetPort' => '443', + 'publishedPort' => '443', + ], + [ + 'targetPort' => '2019', + 'publishedPort' => '2019', + ], + ], + 'replicas' => 1, + 'placementNodeId' => null, + 'caddy' => [], + 'fastcgiVars' => [], + ]), ]); + + foreach ($deployment->asNodeTasks() as $task) { + $tasks[] = $task; + } + + $taskGroup->tasks()->createMany($tasks); } } diff --git a/app/Models/Deployment.php b/app/Models/Deployment.php index fa94a5c..8a1528c 100644 --- a/app/Models/Deployment.php +++ b/app/Models/Deployment.php @@ -179,7 +179,7 @@ public function asNodeTasks(): array ], 'Networks' => [ [ - 'Target' => Network::find($data->networkId)->docker_id, + 'Target' => $data->networkName, 'Aliases' => [$data->internalDomain], ] ], @@ -203,6 +203,7 @@ public function asNodeTasks(): array ]; } + // TODO: update node labels and select by the labels instead of the id protected function getNodeDockerId($nodeId) { return Node::find($nodeId)->docker_id; diff --git a/app/Models/DeploymentData.php b/app/Models/DeploymentData.php index 5b07cbd..9ede342 100644 --- a/app/Models/DeploymentData.php +++ b/app/Models/DeploymentData.php @@ -35,7 +35,7 @@ public function __construct( #[DataCollectionOf(Volume::class)] /* @var Volume[] */ public array $volumes, - public int $networkId, + public string $networkName, public string $internalDomain, #[DataCollectionOf(NodePort::class)] /* @var NodePort[] */ diff --git a/app/Models/Network.php b/app/Models/Network.php index 375ef32..8c7eec7 100644 --- a/app/Models/Network.php +++ b/app/Models/Network.php @@ -15,4 +15,11 @@ class Network extends Model 'swarm_id', 'name', ]; + + protected static function booted(): void + { + self::creating(function (Network $network) { + $network->docker_name = dockerize_name($network->name); + }); + } } diff --git a/app/Models/NodeTasks/AbstractTaskResult.php b/app/Models/NodeTasks/AbstractTaskResult.php index ae192a6..d52cd7d 100644 --- a/app/Models/NodeTasks/AbstractTaskResult.php +++ b/app/Models/NodeTasks/AbstractTaskResult.php @@ -2,9 +2,12 @@ namespace App\Models\NodeTasks; +use Illuminate\Database\Eloquent\Concerns\HasEvents; use Spatie\LaravelData\Data; abstract class AbstractTaskResult extends Data { + + abstract public function formattedHtml(); } \ No newline at end of file diff --git a/app/Models/Service.php b/app/Models/Service.php index 58600f1..3b92120 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -32,15 +32,7 @@ public function deployments(): HasMany public function makeResourceName($name): string { - $name = "svc_" . $this->id . '_'. $name; - - $name = Str::snake($name); - $name = Str::replaceMatches('/\W/', '_', $name); - $name = Str::replaceMatches('/_+/', '_', $name); - - if (Str::length($name) > 63) { - $name = Str::substr($name, 0, 57) . '_' . Str::random(5); - } + $name = dockerize_name("svc_" . $this->id . '_'. $name); return $name; } diff --git a/app/Models/Swarm.php b/app/Models/Swarm.php index 29321b6..624346c 100644 --- a/app/Models/Swarm.php +++ b/app/Models/Swarm.php @@ -5,6 +5,7 @@ use App\Traits\HasOwningTeam; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; class Swarm extends Model @@ -25,4 +26,9 @@ public function nodes(): HasMany { return $this->hasMany(Node::class); } + + public function services(): HasMany + { + return $this->hasMany(Service::class); + } } diff --git a/bootstrap/helpers.php b/bootstrap/helpers.php index 86de1f7..1dcdb0f 100644 --- a/bootstrap/helpers.php +++ b/bootstrap/helpers.php @@ -1,5 +1,7 @@ 63) { + $name = Str::substr($name, 0, 57) . '_' . Str::random(5); + } + + return $name; + } +} \ No newline at end of file diff --git a/database/migrations/2024_06_23_164312_alter_networks_add_docker_name_column.php b/database/migrations/2024_06_23_164312_alter_networks_add_docker_name_column.php new file mode 100644 index 0000000..35b4abb --- /dev/null +++ b/database/migrations/2024_06_23_164312_alter_networks_add_docker_name_column.php @@ -0,0 +1,28 @@ +string('docker_name'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('networks', function (Blueprint $table) { + $table->dropColumn('docker_name'); + }); + } +}; diff --git a/resources/js/Pages/Nodes/Partials/AgentInstall.vue b/resources/js/Pages/Nodes/Partials/AgentInstall.vue index fdd94c8..23fbd71 100644 --- a/resources/js/Pages/Nodes/Partials/AgentInstall.vue +++ b/resources/js/Pages/Nodes/Partials/AgentInstall.vue @@ -3,6 +3,10 @@ import {onMounted, ref, reactive} from "vue"; import {CopyClipboard} from 'flowbite'; import InputLabel from "@/Components/InputLabel.vue"; +defineProps({ + 'node': Object, +}) + const trigger = ref(null); const copyToClipboardRef = ref(null); @@ -42,9 +46,13 @@ onMounted(() => { + + + + + :value="$props.node.agent_token" disabled readonly>