Skip to content

Commit 0c87788

Browse files
committed
feat: #16 install caddy as a part of the initialization process
1 parent 193c8ce commit 0c87788

File tree

12 files changed

+144
-23
lines changed

12 files changed

+144
-23
lines changed

app/Http/Controllers/SwarmTaskController.php

+66-7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace App\Http\Controllers;
44

55
use App\Http\Requests\NodeTask\InitClusterFormRequest;
6+
use App\Models\DeploymentData;
67
use App\Models\Network;
78
use App\Models\Node;
89
use App\Models\NodeTaskGroup;
@@ -26,7 +27,7 @@ public function initCluster(InitClusterFormRequest $request)
2627

2728
$network = Network::create([
2829
'swarm_id' => $swarm->id,
29-
'name' => 'ptah-net',
30+
'name' => dockerize_name('ptah-net'),
3031
]);
3132

3233
$taskGroup = NodeTaskGroup::create([
@@ -36,7 +37,7 @@ public function initCluster(InitClusterFormRequest $request)
3637
'invoker_id' => auth()->user()->id,
3738
]);
3839

39-
$taskGroup->tasks()->createMany([
40+
$tasks = [
4041
[
4142
'type' => NodeTaskType::InitSwarm,
4243
'meta' => InitSwarmMeta::from([
@@ -64,7 +65,7 @@ public function initCluster(InitClusterFormRequest $request)
6465
'type' => NodeTaskType::CreateNetwork,
6566
'meta' => CreateNetworkMeta::from(['networkId' => $network->id, 'name' => $network->name]),
6667
'payload' => [
67-
'NetworkName' => $network->name,
68+
'NetworkName' => $network->docker_name,
6869
'NetworkCreateOptions' => [
6970
'Driver' => 'overlay',
7071
'Labels' => dockerize_labels([
@@ -73,10 +74,68 @@ public function initCluster(InitClusterFormRequest $request)
7374
],
7475
],
7576
],
76-
// TODO: create bare-bones Caddy
77-
// [
78-
// 'type' => NodeTaskType::CreateService,
79-
// ]
77+
];
78+
79+
$caddyService = $swarm->services()->create([
80+
'name' => 'caddy',
81+
]);
82+
83+
$deployment = $caddyService->deployments()->create([
84+
'task_group_id' => $taskGroup->id,
85+
'data' => DeploymentData::from([
86+
'dockerRegistryId' => null,
87+
'dockerImage' => 'caddy:2.8-alpine',
88+
'envVars' => [
89+
[
90+
'name' => 'CADDY_ADMIN',
91+
'value' => '0.0.0.0:2019',
92+
]
93+
],
94+
'secretVars' => [],
95+
'configFiles' => [
96+
[
97+
'path' => '/ptah/caddy/tls/.keep',
98+
'content' => '# Keep this file',
99+
]
100+
],
101+
'secretFiles' => [],
102+
'volumes' => [
103+
[
104+
'name' => 'data',
105+
'path' => '/data',
106+
],
107+
[
108+
'name' => 'config',
109+
'path' => '/config',
110+
]
111+
],
112+
'networkName' => $network->docker_name,
113+
'internalDomain' => 'caddy.ptah.local',
114+
'ports' => [
115+
[
116+
'targetPort' => '80',
117+
'publishedPort' => '80',
118+
],
119+
[
120+
'targetPort' => '443',
121+
'publishedPort' => '443',
122+
],
123+
[
124+
'targetPort' => '2019',
125+
'publishedPort' => '2019',
126+
],
127+
],
128+
'replicas' => 1,
129+
'placementNodeId' => null,
130+
'caddy' => [],
131+
'fastcgiVars' => [],
132+
]),
80133
]);
134+
135+
foreach ($deployment->asNodeTasks() as $task) {
136+
$tasks[] = $task;
137+
}
138+
139+
$taskGroup->tasks()->createMany($tasks);
81140
}
82141
}

app/Models/Deployment.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ public function asNodeTasks(): array
179179
],
180180
'Networks' => [
181181
[
182-
'Target' => Network::find($data->networkId)->docker_id,
182+
'Target' => $data->networkName,
183183
'Aliases' => [$data->internalDomain],
184184
]
185185
],
@@ -203,6 +203,7 @@ public function asNodeTasks(): array
203203
];
204204
}
205205

206+
// TODO: update node labels and select by the labels instead of the id
206207
protected function getNodeDockerId($nodeId)
207208
{
208209
return Node::find($nodeId)->docker_id;

app/Models/DeploymentData.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function __construct(
3535
#[DataCollectionOf(Volume::class)]
3636
/* @var Volume[] */
3737
public array $volumes,
38-
public int $networkId,
38+
public string $networkName,
3939
public string $internalDomain,
4040
#[DataCollectionOf(NodePort::class)]
4141
/* @var NodePort[] */

app/Models/Network.php

+7
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,11 @@ class Network extends Model
1515
'swarm_id',
1616
'name',
1717
];
18+
19+
protected static function booted(): void
20+
{
21+
self::creating(function (Network $network) {
22+
$network->docker_name = dockerize_name($network->name);
23+
});
24+
}
1825
}

app/Models/NodeTasks/AbstractTaskResult.php

+3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
namespace App\Models\NodeTasks;
44

5+
use Illuminate\Database\Eloquent\Concerns\HasEvents;
56
use Spatie\LaravelData\Data;
67

78
abstract class AbstractTaskResult extends Data
89
{
10+
11+
912
abstract public function formattedHtml();
1013
}

app/Models/Service.php

+1-9
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,7 @@ public function deployments(): HasMany
3232

3333
public function makeResourceName($name): string
3434
{
35-
$name = "svc_" . $this->id . '_'. $name;
36-
37-
$name = Str::snake($name);
38-
$name = Str::replaceMatches('/\W/', '_', $name);
39-
$name = Str::replaceMatches('/_+/', '_', $name);
40-
41-
if (Str::length($name) > 63) {
42-
$name = Str::substr($name, 0, 57) . '_' . Str::random(5);
43-
}
35+
$name = dockerize_name("svc_" . $this->id . '_'. $name);
4436

4537
return $name;
4638
}

app/Models/Swarm.php

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use App\Traits\HasOwningTeam;
66
use Illuminate\Database\Eloquent\Factories\HasFactory;
77
use Illuminate\Database\Eloquent\Model;
8+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
89
use Illuminate\Database\Eloquent\Relations\HasMany;
910

1011
class Swarm extends Model
@@ -25,4 +26,9 @@ public function nodes(): HasMany
2526
{
2627
return $this->hasMany(Node::class);
2728
}
29+
30+
public function services(): HasMany
31+
{
32+
return $this->hasMany(Service::class);
33+
}
2834
}

bootstrap/helpers.php

+17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
use Illuminate\Support\Str;
4+
35
if (!function_exists('dockerize_labels')) {
46
function dockerize_labels(array $labels): array
57
{
@@ -14,3 +16,18 @@ function dockerize_labels(array $labels): array
1416
return $result;
1517
}
1618
}
19+
20+
if (!function_exists('dockerize_name')) {
21+
function dockerize_name(string $name): string
22+
{
23+
$name = Str::snake($name);
24+
$name = Str::replaceMatches('/\W/', '_', $name);
25+
$name = Str::replaceMatches('/_+/', '_', $name);
26+
27+
if (Str::length($name) > 63) {
28+
$name = Str::substr($name, 0, 57) . '_' . Str::random(5);
29+
}
30+
31+
return $name;
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*/
12+
public function up(): void
13+
{
14+
Schema::table('networks', function (Blueprint $table) {
15+
$table->string('docker_name');
16+
});
17+
}
18+
19+
/**
20+
* Reverse the migrations.
21+
*/
22+
public function down(): void
23+
{
24+
Schema::table('networks', function (Blueprint $table) {
25+
$table->dropColumn('docker_name');
26+
});
27+
}
28+
};

resources/js/Pages/Nodes/Partials/AgentInstall.vue

+9-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import {onMounted, ref, reactive} from "vue";
33
import {CopyClipboard} from 'flowbite';
44
import InputLabel from "@/Components/InputLabel.vue";
55
6+
defineProps({
7+
'node': Object,
8+
})
9+
610
const trigger = ref(null);
711
const copyToClipboardRef = ref(null);
812
@@ -42,9 +46,13 @@ onMounted(() => {
4246
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 17.345a4.76 4.76 0 0 0 2.558 1.618c2.274.589 4.512-.446 4.999-2.31.487-1.866-1.273-3.9-3.546-4.49-2.273-.59-4.034-2.623-3.547-4.488.486-1.865 2.724-2.899 4.998-2.31.982.236 1.87.793 2.538 1.592m-3.879 12.171V21m0-18v2.2"/>
4347
</svg>
4448
</div>
49+
<!-- TODO: correct script -->
50+
<!-- <input id="agent-install-cli" ref="copyToClipboardRef" type="text"-->
51+
<!-- class="ps-10 p-2.5 col-span-6 bg-gray-50 border border-gray-300 text-gray-500 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full px-2.5 py-4 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500"-->
52+
<!-- value="script cli goes here" disabled readonly>-->
4553
<input id="agent-install-cli" ref="copyToClipboardRef" type="text"
4654
class="ps-10 p-2.5 col-span-6 bg-gray-50 border border-gray-300 text-gray-500 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full px-2.5 py-4 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500"
47-
value="script cli goes here" disabled readonly>
55+
:value="$props.node.agent_token" disabled readonly>
4856
</div>
4957
<button ref="trigger"
5058
class="absolute end-2.5 w-24 top-1/2 -translate-y-1/2 text-gray-900 dark:text-gray-400 hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-600 dark:hover:bg-gray-700 rounded-lg py-2 px-2.5 inline-flex items-center justify-center bg-white border-gray-200 border">

resources/js/Pages/Nodes/Partials/AgentStatus.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ defineProps([
2626
</div>
2727
</div>
2828
<div v-else class="col-span-10">
29-
<AgentInstall />
29+
<AgentInstall :node="$props.node" />
3030
</div>
3131
</template>
3232

resources/js/Pages/Services/Create.vue

+3-3
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const form = useForm({
3434
secretFiles: [],
3535
placementNodeId: '',
3636
volumes: [],
37-
networkId: props.networks[0]?.id,
37+
networkName: props.networks[0]?.docker_name,
3838
internalDomain: '',
3939
ports: [],
4040
replicas: 1,
@@ -435,10 +435,10 @@ const createService = () => {
435435
</template>
436436

437437
<template #content>
438-
<FormField :error="form.errors.networkId">
438+
<FormField :error="form.errors.networkName">
439439
<template #label>Attach to Network</template>
440440

441-
<Select v-model="form.networkId">
441+
<Select v-model="form.networkName">
442442
<option v-for="network in $page.props.networks" :value="network.id">{{ network.name }}</option>
443443
</Select>
444444
</FormField>

0 commit comments

Comments
 (0)