lasthourcloud/bootstrap/helpers/services.php

161 lines
5.9 KiB
PHP
Raw Normal View History

2023-09-19 13:51:13 +00:00
<?php
2023-09-27 10:45:53 +00:00
use App\Models\EnvironmentVariable;
2023-09-20 13:42:41 +00:00
use App\Models\Service;
use App\Models\ServiceApplication;
use App\Models\ServiceDatabase;
2023-09-26 12:45:52 +00:00
use Illuminate\Support\Facades\Storage;
2023-09-22 13:29:19 +00:00
use Illuminate\Support\Str;
2023-09-26 12:45:52 +00:00
use Symfony\Component\Yaml\Yaml;
2023-09-19 13:51:13 +00:00
function replaceRegex(?string $name = null)
{
return "/\\\${?{$name}[^}]*}?|\\\${$name}\w+/";
}
function collectRegex(string $name)
{
return "/{$name}\w+/";
}
function replaceVariables($variable)
{
return $variable->replaceFirst('$', '')->replaceFirst('{', '')->replaceLast('}', '');
}
2023-09-21 19:30:13 +00:00
function serviceStatus(Service $service)
{
$foundRunning = false;
$isDegraded = false;
2023-09-26 12:45:52 +00:00
$foundRestaring = false;
2023-09-21 19:30:13 +00:00
$applications = $service->applications;
$databases = $service->databases;
foreach ($applications as $application) {
2023-09-26 12:45:52 +00:00
if ($application->exclude_from_status) {
2023-09-25 13:48:43 +00:00
continue;
}
2023-09-22 13:29:19 +00:00
if (Str::of($application->status)->startsWith('running')) {
2023-09-21 19:30:13 +00:00
$foundRunning = true;
2023-09-26 12:45:52 +00:00
} else if (Str::of($application->status)->startsWith('restarting')) {
$foundRestaring = true;
2023-09-21 19:30:13 +00:00
} else {
$isDegraded = true;
}
}
foreach ($databases as $database) {
2023-09-26 12:45:52 +00:00
if ($database->exclude_from_status) {
2023-09-25 13:48:43 +00:00
continue;
}
2023-09-22 13:29:19 +00:00
if (Str::of($database->status)->startsWith('running')) {
2023-09-21 19:30:13 +00:00
$foundRunning = true;
2023-09-26 12:45:52 +00:00
} else if (Str::of($database->status)->startsWith('restarting')) {
$foundRestaring = true;
2023-09-21 19:30:13 +00:00
} else {
$isDegraded = true;
}
}
2023-09-26 12:45:52 +00:00
if ($foundRestaring) {
return 'degraded';
}
2023-09-21 19:30:13 +00:00
if ($foundRunning && !$isDegraded) {
return 'running';
} else if ($foundRunning && $isDegraded) {
return 'degraded';
2023-09-26 12:45:52 +00:00
} else if (!$foundRunning && !$isDegraded) {
2023-09-21 19:30:13 +00:00
return 'exited';
}
return 'exited';
}
2023-10-02 16:02:32 +00:00
function getFilesystemVolumesFromServer(ServiceApplication|ServiceDatabase $oneService, bool $isInit = false)
{
// TODO: make this async
try {
$workdir = $oneService->service->workdir();
$server = $oneService->service->server;
$fileVolumes = $oneService->fileStorages()->get();
$commands = collect([
2023-09-26 12:45:52 +00:00
"mkdir -p $workdir > /dev/null 2>&1 || true",
"cd "
]);
instant_remote_process($commands, $server);
foreach ($fileVolumes as $fileVolume) {
$path = Str::of(data_get($fileVolume, 'fs_path'));
$content = data_get($fileVolume, 'content');
if ($path->startsWith('.')) {
$path = $path->after('.');
$fileLocation = $workdir . $path;
} else {
$fileLocation = $path;
}
// Exists and is a file
$isFile = instant_remote_process(["test -f $fileLocation && echo OK || echo NOK"], $server);
// Exists and is a directory
$isDir = instant_remote_process(["test -d $fileLocation && echo OK || echo NOK"], $server);
if ($isFile == 'OK') {
// If its a file & exists
$filesystemContent = instant_remote_process(["cat $fileLocation"], $server);
$fileVolume->content = $filesystemContent;
$fileVolume->is_directory = false;
$fileVolume->save();
} else if ($isDir == 'OK') {
// If its a directory & exists
$fileVolume->content = null;
$fileVolume->is_directory = true;
$fileVolume->save();
} else if ($isFile == 'NOK' && $isDir == 'NOK' && !$fileVolume->is_directory && $isInit && $content) {
// Does not exists (no dir or file), not flagged as directory, is init, has content
$fileVolume->content = $content;
$fileVolume->is_directory = false;
$fileVolume->save();
$content = base64_encode($content);
$dir = Str::of($fileLocation)->dirname();
instant_remote_process([
"mkdir -p $dir",
"echo '$content' | base64 -d > $fileLocation"
], $server);
} else if ($isFile == 'NOK' && $isDir == 'NOK' && $fileVolume->is_directory && $isInit) {
$fileVolume->content = null;
$fileVolume->is_directory = true;
$fileVolume->save();
instant_remote_process(["mkdir -p $fileLocation"], $server);
}
}
} catch (\Throwable $e) {
return handleError($e);
}
2023-09-21 19:30:13 +00:00
}
function updateCompose($resource)
{
2023-09-26 12:45:52 +00:00
try {
$name = data_get($resource, 'name');
$dockerComposeRaw = data_get($resource, 'service.docker_compose_raw');
$dockerCompose = Yaml::parse($dockerComposeRaw);
2023-09-27 10:45:53 +00:00
// Switch Image
$image = data_get($resource, 'image');
2023-09-26 12:45:52 +00:00
data_set($dockerCompose, "services.{$name}.image", $image);
2023-09-27 10:45:53 +00:00
2023-11-11 20:32:41 +00:00
if (!str($resource->fqdn)->contains(',')) {
// Update FQDN
$variableName = "SERVICE_FQDN_" . Str::of($resource->name)->upper();
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
if ($generatedEnv) {
$generatedEnv->value = $resource->fqdn;
$generatedEnv->save();
}
$variableName = "SERVICE_URL_" . Str::of($resource->name)->upper();
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
if ($generatedEnv) {
$url = Str::of($resource->fqdn)->after('://');
$generatedEnv->value = $url;
$generatedEnv->save();
}
2023-10-04 12:40:26 +00:00
}
2023-09-27 10:45:53 +00:00
2023-09-26 12:45:52 +00:00
$dockerComposeRaw = Yaml::dump($dockerCompose, 10, 2);
$resource->service->docker_compose_raw = $dockerComposeRaw;
$resource->service->save();
} catch (\Throwable $e) {
return handleError($e);
}
}