Fix styling
This commit is contained in:

committed by
github-actions[bot]
![github-actions[bot]](/assets/img/avatar_default.png)
parent
41fb6a1fc9
commit
d86274cc37
@@ -1,3 +1,4 @@
|
||||
<?php
|
||||
|
||||
$version = include 'config/version.php';
|
||||
echo $version;
|
||||
|
@@ -3,6 +3,7 @@
|
||||
function get_team_id_from_token()
|
||||
{
|
||||
$token = auth()->user()->currentAccessToken();
|
||||
|
||||
return data_get($token, 'team_id');
|
||||
}
|
||||
function invalid_token()
|
||||
|
@@ -8,10 +8,10 @@ use App\Models\Server;
|
||||
use App\Models\StandaloneDocker;
|
||||
use Spatie\Url\Url;
|
||||
|
||||
function queue_application_deployment(Application $application, string $deployment_uuid, int | null $pull_request_id = 0, string $commit = 'HEAD', bool $force_rebuild = false, bool $is_webhook = false, bool $restart_only = false, ?string $git_type = null, bool $no_questions_asked = false, Server $server = null, StandaloneDocker $destination = null, bool $only_this_server = false, bool $rollback = false)
|
||||
function queue_application_deployment(Application $application, string $deployment_uuid, ?int $pull_request_id = 0, string $commit = 'HEAD', bool $force_rebuild = false, bool $is_webhook = false, bool $restart_only = false, ?string $git_type = null, bool $no_questions_asked = false, ?Server $server = null, ?StandaloneDocker $destination = null, bool $only_this_server = false, bool $rollback = false)
|
||||
{
|
||||
$application_id = $application->id;
|
||||
$deployment_link = Url::fromString($application->link() . "/deployment/{$deployment_uuid}");
|
||||
$deployment_link = Url::fromString($application->link()."/deployment/{$deployment_uuid}");
|
||||
$deployment_url = $deployment_link->getPath();
|
||||
$server_id = $application->destination->server->id;
|
||||
$server_name = $application->destination->server->name;
|
||||
@@ -39,14 +39,14 @@ function queue_application_deployment(Application $application, string $deployme
|
||||
'commit' => $commit,
|
||||
'rollback' => $rollback,
|
||||
'git_type' => $git_type,
|
||||
'only_this_server' => $only_this_server
|
||||
'only_this_server' => $only_this_server,
|
||||
]);
|
||||
|
||||
if ($no_questions_asked) {
|
||||
dispatch(new ApplicationDeploymentJob(
|
||||
application_deployment_queue_id: $deployment->id,
|
||||
));
|
||||
} else if (next_queuable($server_id, $application_id)) {
|
||||
} elseif (next_queuable($server_id, $application_id)) {
|
||||
dispatch(new ApplicationDeploymentJob(
|
||||
application_deployment_queue_id: $deployment->id,
|
||||
));
|
||||
@@ -95,5 +95,6 @@ function next_queuable(string $server_id, string $application_id): bool
|
||||
if ($deployments->count() > $concurrent_builds) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -28,18 +28,18 @@ const DATABASE_DOCKER_IMAGES = [
|
||||
'neo4j',
|
||||
'influxdb',
|
||||
'clickhouse/clickhouse-server',
|
||||
'supabase/postgres'
|
||||
'supabase/postgres',
|
||||
];
|
||||
const SPECIFIC_SERVICES = [
|
||||
'quay.io/minio/minio',
|
||||
'svhd/logto'
|
||||
'svhd/logto',
|
||||
];
|
||||
|
||||
// Based on /etc/os-release
|
||||
const SUPPORTED_OS = [
|
||||
'ubuntu debian raspbian',
|
||||
'centos fedora rhel ol rocky amzn almalinux',
|
||||
'sles opensuse-leap opensuse-tumbleweed'
|
||||
'sles opensuse-leap opensuse-tumbleweed',
|
||||
];
|
||||
|
||||
const SHARED_VARIABLE_TYPES = ['team', 'project', 'environment'];
|
||||
|
@@ -15,16 +15,18 @@ use Visus\Cuid2\Cuid2;
|
||||
function generate_database_name(string $type): string
|
||||
{
|
||||
$cuid = new Cuid2(7);
|
||||
return $type . '-database-' . $cuid;
|
||||
|
||||
return $type.'-database-'.$cuid;
|
||||
}
|
||||
|
||||
function create_standalone_postgresql($environment_id, $destination_uuid): StandalonePostgresql
|
||||
{
|
||||
// TODO: If another type of destination is added, this will need to be updated.
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (!$destination) {
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
|
||||
return StandalonePostgresql::create([
|
||||
'name' => generate_database_name('postgresql'),
|
||||
'postgres_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
@@ -37,9 +39,10 @@ function create_standalone_postgresql($environment_id, $destination_uuid): Stand
|
||||
function create_standalone_redis($environment_id, $destination_uuid): StandaloneRedis
|
||||
{
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (!$destination) {
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
|
||||
return StandaloneRedis::create([
|
||||
'name' => generate_database_name('redis'),
|
||||
'redis_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
@@ -52,9 +55,10 @@ function create_standalone_redis($environment_id, $destination_uuid): Standalone
|
||||
function create_standalone_mongodb($environment_id, $destination_uuid): StandaloneMongodb
|
||||
{
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (!$destination) {
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
|
||||
return StandaloneMongodb::create([
|
||||
'name' => generate_database_name('mongodb'),
|
||||
'mongo_initdb_root_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
@@ -66,9 +70,10 @@ function create_standalone_mongodb($environment_id, $destination_uuid): Standalo
|
||||
function create_standalone_mysql($environment_id, $destination_uuid): StandaloneMysql
|
||||
{
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (!$destination) {
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
|
||||
return StandaloneMysql::create([
|
||||
'name' => generate_database_name('mysql'),
|
||||
'mysql_root_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
@@ -81,9 +86,10 @@ function create_standalone_mysql($environment_id, $destination_uuid): Standalone
|
||||
function create_standalone_mariadb($environment_id, $destination_uuid): StandaloneMariadb
|
||||
{
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (!$destination) {
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
|
||||
return StandaloneMariadb::create([
|
||||
'name' => generate_database_name('mariadb'),
|
||||
'mariadb_root_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
@@ -96,9 +102,10 @@ function create_standalone_mariadb($environment_id, $destination_uuid): Standalo
|
||||
function create_standalone_keydb($environment_id, $destination_uuid): StandaloneKeydb
|
||||
{
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (!$destination) {
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
|
||||
return StandaloneKeydb::create([
|
||||
'name' => generate_database_name('keydb'),
|
||||
'keydb_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
@@ -111,9 +118,10 @@ function create_standalone_keydb($environment_id, $destination_uuid): Standalone
|
||||
function create_standalone_dragonfly($environment_id, $destination_uuid): StandaloneDragonfly
|
||||
{
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (!$destination) {
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
|
||||
return StandaloneDragonfly::create([
|
||||
'name' => generate_database_name('dragonfly'),
|
||||
'dragonfly_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
@@ -125,9 +133,10 @@ function create_standalone_dragonfly($environment_id, $destination_uuid): Standa
|
||||
function create_standalone_clickhouse($environment_id, $destination_uuid): StandaloneClickhouse
|
||||
{
|
||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||
if (!$destination) {
|
||||
if (! $destination) {
|
||||
throw new Exception('Destination not found');
|
||||
}
|
||||
|
||||
return StandaloneClickhouse::create([
|
||||
'name' => generate_database_name('clickhouse'),
|
||||
'clickhouse_admin_password' => \Illuminate\Support\Str::password(length: 64, symbols: false),
|
||||
@@ -139,11 +148,8 @@ function create_standalone_clickhouse($environment_id, $destination_uuid): Stand
|
||||
|
||||
/**
|
||||
* Delete file locally on the filesystem.
|
||||
* @param string $filename
|
||||
* @param Server $server
|
||||
* @return void
|
||||
*/
|
||||
function delete_backup_locally(string | null $filename, Server $server): void
|
||||
function delete_backup_locally(?string $filename, Server $server): void
|
||||
{
|
||||
if (empty($filename)) {
|
||||
return;
|
||||
|
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
use App\Enums\ProxyTypes;
|
||||
use App\Models\Application;
|
||||
use App\Models\ApplicationPreview;
|
||||
use App\Models\Server;
|
||||
@@ -13,13 +12,14 @@ use Visus\Cuid2\Cuid2;
|
||||
function getCurrentApplicationContainerStatus(Server $server, int $id, ?int $pullRequestId = null, ?bool $includePullrequests = false): Collection
|
||||
{
|
||||
$containers = collect([]);
|
||||
if (!$server->isSwarm()) {
|
||||
if (! $server->isSwarm()) {
|
||||
$containers = instant_remote_process(["docker ps -a --filter='label=coolify.applicationId={$id}' --format '{{json .}}' "], $server);
|
||||
$containers = format_docker_command_output_to_json($containers);
|
||||
$containers = $containers->map(function ($container) use ($pullRequestId, $includePullrequests) {
|
||||
$labels = data_get($container, 'Labels');
|
||||
if (!str($labels)->contains("coolify.pullRequestId=")) {
|
||||
data_set($container, 'Labels', $labels . ",coolify.pullRequestId={$pullRequestId}");
|
||||
if (! str($labels)->contains('coolify.pullRequestId=')) {
|
||||
data_set($container, 'Labels', $labels.",coolify.pullRequestId={$pullRequestId}");
|
||||
|
||||
return $container;
|
||||
}
|
||||
if ($includePullrequests) {
|
||||
@@ -28,11 +28,14 @@ function getCurrentApplicationContainerStatus(Server $server, int $id, ?int $pul
|
||||
if (str($labels)->contains("coolify.pullRequestId=$pullRequestId")) {
|
||||
return $container;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
$containers = $containers->filter();
|
||||
|
||||
return $containers;
|
||||
}
|
||||
|
||||
return $containers;
|
||||
}
|
||||
|
||||
@@ -44,6 +47,7 @@ function format_docker_command_output_to_json($rawOutput): Collection
|
||||
} else {
|
||||
$outputLines = collect($outputLines);
|
||||
}
|
||||
|
||||
return $outputLines
|
||||
->reject(fn ($line) => empty($line))
|
||||
->map(fn ($outputLine) => json_decode($outputLine, true, flags: JSON_THROW_ON_ERROR));
|
||||
@@ -60,6 +64,7 @@ function format_docker_labels_to_json(string|array $rawOutput): Collection
|
||||
->reject(fn ($line) => empty($line))
|
||||
->map(function ($outputLine) {
|
||||
$outputArray = explode(',', $outputLine);
|
||||
|
||||
return collect($outputArray)
|
||||
->map(function ($outputLine) {
|
||||
return explode('=', $outputLine);
|
||||
@@ -74,8 +79,10 @@ function format_docker_envs_to_json($rawOutput)
|
||||
{
|
||||
try {
|
||||
$outputLines = json_decode($rawOutput, true, flags: JSON_THROW_ON_ERROR);
|
||||
|
||||
return collect(data_get($outputLines[0], 'Config.Env', []))->mapWithKeys(function ($env) {
|
||||
$env = explode('=', $env);
|
||||
|
||||
return [$env[0] => $env[1]];
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
@@ -88,6 +95,7 @@ function checkMinimumDockerEngineVersion($dockerVersion)
|
||||
if ($majorDockerVersion <= 22) {
|
||||
$dockerVersion = null;
|
||||
}
|
||||
|
||||
return $dockerVersion;
|
||||
}
|
||||
function executeInDocker(string $containerId, string $command)
|
||||
@@ -103,7 +111,7 @@ function getContainerStatus(Server $server, string $container_id, bool $all_data
|
||||
} else {
|
||||
$container = instant_remote_process(["docker inspect --format '{{json .}}' {$container_id}"], $server, $throwError);
|
||||
}
|
||||
if (!$container) {
|
||||
if (! $container) {
|
||||
return 'exited';
|
||||
}
|
||||
$container = format_docker_command_output_to_json($container);
|
||||
@@ -113,8 +121,8 @@ function getContainerStatus(Server $server, string $container_id, bool $all_data
|
||||
if ($server->isSwarm()) {
|
||||
$replicas = data_get($container[0], 'Replicas');
|
||||
$replicas = explode('/', $replicas);
|
||||
$active = (int)$replicas[0];
|
||||
$total = (int)$replicas[1];
|
||||
$active = (int) $replicas[0];
|
||||
$total = (int) $replicas[1];
|
||||
if ($active === $total) {
|
||||
return 'running';
|
||||
} else {
|
||||
@@ -130,15 +138,16 @@ function generateApplicationContainerName(Application $application, $pull_reques
|
||||
$consistent_container_name = $application->settings->is_consistent_container_name_enabled;
|
||||
$now = now()->format('Hisu');
|
||||
if ($pull_request_id !== 0 && $pull_request_id !== null) {
|
||||
return $application->uuid . '-pr-' . $pull_request_id;
|
||||
return $application->uuid.'-pr-'.$pull_request_id;
|
||||
} else {
|
||||
if ($consistent_container_name) {
|
||||
return $application->uuid;
|
||||
}
|
||||
return $application->uuid . '-' . $now;
|
||||
|
||||
return $application->uuid.'-'.$now;
|
||||
}
|
||||
}
|
||||
function get_port_from_dockerfile($dockerfile): int|null
|
||||
function get_port_from_dockerfile($dockerfile): ?int
|
||||
{
|
||||
$dockerfile_array = explode("\n", $dockerfile);
|
||||
$found_exposed_port = null;
|
||||
@@ -150,8 +159,9 @@ function get_port_from_dockerfile($dockerfile): int|null
|
||||
}
|
||||
}
|
||||
if ($found_exposed_port) {
|
||||
return (int)$found_exposed_port->value();
|
||||
return (int) $found_exposed_port->value();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -159,15 +169,16 @@ function defaultLabels($id, $name, $pull_request_id = 0, string $type = 'applica
|
||||
{
|
||||
$labels = collect([]);
|
||||
$labels->push('coolify.managed=true');
|
||||
$labels->push('coolify.version=' . config('version'));
|
||||
$labels->push("coolify." . $type . "Id=" . $id);
|
||||
$labels->push('coolify.version='.config('version'));
|
||||
$labels->push('coolify.'.$type.'Id='.$id);
|
||||
$labels->push("coolify.type=$type");
|
||||
$labels->push('coolify.name=' . $name);
|
||||
$labels->push('coolify.pullRequestId=' . $pull_request_id);
|
||||
$labels->push('coolify.name='.$name);
|
||||
$labels->push('coolify.pullRequestId='.$pull_request_id);
|
||||
if ($type === 'service') {
|
||||
$subId && $labels->push('coolify.service.subId=' . $subId);
|
||||
$subType && $labels->push('coolify.service.subType=' . $subType);
|
||||
$subId && $labels->push('coolify.service.subId='.$subId);
|
||||
$subType && $labels->push('coolify.service.subType='.$subType);
|
||||
}
|
||||
|
||||
return $labels;
|
||||
}
|
||||
function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
|
||||
@@ -177,7 +188,7 @@ function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
|
||||
$server = data_get($resource, 'service.server');
|
||||
$environment_variables = data_get($resource, 'service.environment_variables');
|
||||
$type = $resource->serviceType();
|
||||
} else if ($resource->getMorphClass() === 'App\Models\Application') {
|
||||
} elseif ($resource->getMorphClass() === 'App\Models\Application') {
|
||||
$uuid = data_get($resource, 'uuid');
|
||||
$server = data_get($resource, 'destination.server');
|
||||
$environment_variables = data_get($resource, 'environment_variables');
|
||||
@@ -197,17 +208,17 @@ function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
|
||||
}
|
||||
if (is_null($MINIO_BROWSER_REDIRECT_URL?->value)) {
|
||||
$MINIO_BROWSER_REDIRECT_URL?->update([
|
||||
"value" => generateFqdn($server, 'console-' . $uuid)
|
||||
'value' => generateFqdn($server, 'console-'.$uuid),
|
||||
]);
|
||||
}
|
||||
if (is_null($MINIO_SERVER_URL?->value)) {
|
||||
$MINIO_SERVER_URL?->update([
|
||||
"value" => generateFqdn($server, 'minio-' . $uuid)
|
||||
'value' => generateFqdn($server, 'minio-'.$uuid),
|
||||
]);
|
||||
}
|
||||
$payload = collect([
|
||||
$MINIO_BROWSER_REDIRECT_URL->value . ':9001',
|
||||
$MINIO_SERVER_URL->value . ':9000',
|
||||
$MINIO_BROWSER_REDIRECT_URL->value.':9001',
|
||||
$MINIO_SERVER_URL->value.':9000',
|
||||
]);
|
||||
break;
|
||||
case $type?->contains('logto'):
|
||||
@@ -218,20 +229,21 @@ function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
|
||||
}
|
||||
if (is_null($LOGTO_ENDPOINT?->value)) {
|
||||
$LOGTO_ENDPOINT?->update([
|
||||
"value" => generateFqdn($server, 'logto-' . $uuid)
|
||||
'value' => generateFqdn($server, 'logto-'.$uuid),
|
||||
]);
|
||||
}
|
||||
if (is_null($LOGTO_ADMIN_ENDPOINT?->value)) {
|
||||
$LOGTO_ADMIN_ENDPOINT?->update([
|
||||
"value" => generateFqdn($server, 'logto-admin-' . $uuid)
|
||||
'value' => generateFqdn($server, 'logto-admin-'.$uuid),
|
||||
]);
|
||||
}
|
||||
$payload = collect([
|
||||
$LOGTO_ENDPOINT->value . ':3001',
|
||||
$LOGTO_ADMIN_ENDPOINT->value . ':3002',
|
||||
$LOGTO_ENDPOINT->value.':3001',
|
||||
$LOGTO_ADMIN_ENDPOINT->value.':3002',
|
||||
]);
|
||||
break;
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
function fqdnLabelsForCaddy(string $network, string $uuid, Collection $domains, bool $is_force_https_enabled = false, $onlyPort = null, ?Collection $serviceLabels = null, ?bool $is_gzip_enabled = true, ?bool $is_stripprefix_enabled = true, ?string $service_name = null, ?string $image = null)
|
||||
@@ -250,7 +262,7 @@ function fqdnLabelsForCaddy(string $network, string $uuid, Collection $domains,
|
||||
|
||||
$schema = $url->getScheme();
|
||||
$port = $url->getPort();
|
||||
if (is_null($port) && !is_null($onlyPort)) {
|
||||
if (is_null($port) && ! is_null($onlyPort)) {
|
||||
$port = $onlyPort;
|
||||
}
|
||||
$labels->push("caddy_{$loop}={$schema}://{$host}");
|
||||
@@ -270,14 +282,15 @@ function fqdnLabelsForCaddy(string $network, string $uuid, Collection $domains,
|
||||
// $labels->push("caddy_{$loop}.tls=internal");
|
||||
}
|
||||
}
|
||||
|
||||
return $labels->sort();
|
||||
}
|
||||
function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_https_enabled = false, $onlyPort = null, ?Collection $serviceLabels = null, ?bool $is_gzip_enabled = true, ?bool $is_stripprefix_enabled = true, ?string $service_name = null, bool $generate_unique_uuid = false, ?string $image = null)
|
||||
{
|
||||
$labels = collect([]);
|
||||
$labels->push('traefik.enable=true');
|
||||
$labels->push("traefik.http.middlewares.gzip.compress=true");
|
||||
$labels->push("traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https");
|
||||
$labels->push('traefik.http.middlewares.gzip.compress=true');
|
||||
$labels->push('traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https');
|
||||
|
||||
$basic_auth = false;
|
||||
$basic_auth_middleware = null;
|
||||
@@ -321,7 +334,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$path = $url->getPath();
|
||||
$schema = $url->getScheme();
|
||||
$port = $url->getPort();
|
||||
if (is_null($port) && !is_null($onlyPort)) {
|
||||
if (is_null($port) && ! is_null($onlyPort)) {
|
||||
$port = $onlyPort;
|
||||
}
|
||||
$http_label = "http-{$loop}-{$uuid}";
|
||||
@@ -332,7 +345,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$labels->push("traefik.http.middlewares.redir-ghost.redirectregex.regex=^{$path}/(.*)");
|
||||
$labels->push("traefik.http.middlewares.redir-ghost.redirectregex.replacement=/$1");
|
||||
$labels->push('traefik.http.middlewares.redir-ghost.redirectregex.replacement=/$1');
|
||||
}
|
||||
if ($schema === 'https') {
|
||||
// Set labels for https
|
||||
@@ -344,7 +357,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
}
|
||||
if ($path !== '/') {
|
||||
$middlewares = collect([]);
|
||||
if ($is_stripprefix_enabled && !str($image)->contains('ghost')) {
|
||||
if ($is_stripprefix_enabled && ! str($image)->contains('ghost')) {
|
||||
$labels->push("traefik.http.middlewares.{$https_label}-stripprefix.stripprefix.prefixes={$path}");
|
||||
$middlewares->push("{$https_label}-stripprefix");
|
||||
}
|
||||
@@ -406,7 +419,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
}
|
||||
if ($path !== '/') {
|
||||
$middlewares = collect([]);
|
||||
if ($is_stripprefix_enabled && !str($image)->contains('ghost')) {
|
||||
if ($is_stripprefix_enabled && ! str($image)->contains('ghost')) {
|
||||
$labels->push("traefik.http.middlewares.{$http_label}-stripprefix.stripprefix.prefixes={$path}");
|
||||
$middlewares->push("{$https_label}-stripprefix");
|
||||
}
|
||||
@@ -450,6 +463,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return $labels->sort();
|
||||
}
|
||||
function generateLabelsApplication(Application $application, ?ApplicationPreview $preview = null): array
|
||||
@@ -462,7 +476,7 @@ function generateLabelsApplication(Application $application, ?ApplicationPreview
|
||||
$pull_request_id = data_get($preview, 'pull_request_id', 0);
|
||||
$appUuid = $application->uuid;
|
||||
if ($pull_request_id !== 0) {
|
||||
$appUuid = $appUuid . '-pr-' . $pull_request_id;
|
||||
$appUuid = $appUuid.'-pr-'.$pull_request_id;
|
||||
}
|
||||
$labels = collect([]);
|
||||
if ($pull_request_id === 0) {
|
||||
@@ -488,7 +502,7 @@ function generateLabelsApplication(Application $application, ?ApplicationPreview
|
||||
));
|
||||
}
|
||||
} else {
|
||||
if (data_get($preview,'fqdn')) {
|
||||
if (data_get($preview, 'fqdn')) {
|
||||
$domains = Str::of(data_get($preview, 'fqdn'))->explode(',');
|
||||
} else {
|
||||
$domains = collect([]);
|
||||
@@ -513,6 +527,7 @@ function generateLabelsApplication(Application $application, ?ApplicationPreview
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
return $labels->all();
|
||||
}
|
||||
|
||||
@@ -531,6 +546,7 @@ function isDatabaseImage(?string $image = null)
|
||||
if (collect(DATABASE_DOCKER_IMAGES)->contains($imageName)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -573,7 +589,7 @@ function convert_docker_run_to_compose(?string $custom_docker_run_options = null
|
||||
$options = collect($options);
|
||||
// Easily get mappings from https://github.com/composerize/composerize/blob/master/packages/composerize/src/mappings.js
|
||||
foreach ($options as $option => $value) {
|
||||
if (!data_get($mapping, $option)) {
|
||||
if (! data_get($mapping, $option)) {
|
||||
continue;
|
||||
}
|
||||
if ($option === '--ulimit') {
|
||||
@@ -587,7 +603,7 @@ function convert_docker_run_to_compose(?string $custom_docker_run_options = null
|
||||
$hard_limit = $limits[1];
|
||||
$ulimits->put($type, [
|
||||
'soft' => $soft_limit,
|
||||
'hard' => $hard_limit
|
||||
'hard' => $hard_limit,
|
||||
]);
|
||||
} else {
|
||||
$soft_limit = $ulimit[1];
|
||||
@@ -600,18 +616,21 @@ function convert_docker_run_to_compose(?string $custom_docker_run_options = null
|
||||
} else {
|
||||
if ($list_options->contains($option)) {
|
||||
if ($compose_options->has($mapping[$option])) {
|
||||
$compose_options->put($mapping[$option], $options->get($mapping[$option]) . ',' . $value);
|
||||
$compose_options->put($mapping[$option], $options->get($mapping[$option]).','.$value);
|
||||
} else {
|
||||
$compose_options->put($mapping[$option], $value);
|
||||
}
|
||||
|
||||
continue;
|
||||
} else {
|
||||
$compose_options->put($mapping[$option], $value);
|
||||
|
||||
continue;
|
||||
}
|
||||
$compose_options->forget($option);
|
||||
}
|
||||
}
|
||||
|
||||
return $compose_options->toArray();
|
||||
}
|
||||
|
||||
@@ -627,9 +646,11 @@ function validateComposeFile(string $compose, int $server_id): string|Throwable
|
||||
"docker compose -f /tmp/{$uuid}.yml config",
|
||||
], $server);
|
||||
ray($output);
|
||||
|
||||
return 'OK';
|
||||
} catch (\Throwable $e) {
|
||||
ray($e);
|
||||
|
||||
return $e->getMessage();
|
||||
} finally {
|
||||
instant_remote_process([
|
||||
@@ -640,13 +661,15 @@ function validateComposeFile(string $compose, int $server_id): string|Throwable
|
||||
|
||||
function escapeEnvVariables($value)
|
||||
{
|
||||
$search = array("\\", "\r", "\t", "\x0", '"', "'");
|
||||
$replace = array("\\\\", "\\r", "\\t", "\\0", '\"', "\'");
|
||||
$search = ['\\', "\r", "\t", "\x0", '"', "'"];
|
||||
$replace = ['\\\\', '\\r', '\\t', '\\0', '\"', "\'"];
|
||||
|
||||
return str_replace($search, $replace, $value);
|
||||
}
|
||||
function escapeDollarSign($value)
|
||||
{
|
||||
$search = array('$');
|
||||
$replace = array('$$');
|
||||
$search = ['$'];
|
||||
$replace = ['$$'];
|
||||
|
||||
return str_replace($search, $replace, $value);
|
||||
}
|
||||
|
@@ -26,11 +26,12 @@ function generate_github_installation_token(GithubApp $source)
|
||||
->toString();
|
||||
$token = Http::withHeaders([
|
||||
'Authorization' => "Bearer $issuedToken",
|
||||
'Accept' => 'application/vnd.github.machine-man-preview+json'
|
||||
'Accept' => 'application/vnd.github.machine-man-preview+json',
|
||||
])->post("{$source->api_url}/app/installations/{$source->installation_id}/access_tokens");
|
||||
if ($token->failed()) {
|
||||
throw new RuntimeException("Failed to get access token for " . $source->name . " with error: " . data_get($token->json(),'message','no error message found'));
|
||||
throw new RuntimeException('Failed to get access token for '.$source->name.' with error: '.data_get($token->json(), 'message', 'no error message found'));
|
||||
}
|
||||
|
||||
return $token->json()['token'];
|
||||
}
|
||||
|
||||
@@ -47,10 +48,11 @@ function generate_github_jwt_token(GithubApp $source)
|
||||
->expiresAt($now->modify('+10 minutes'))
|
||||
->getToken($algorithm, $signingKey)
|
||||
->toString();
|
||||
|
||||
return $issuedToken;
|
||||
}
|
||||
|
||||
function githubApi(GithubApp|GitlabApp|null $source, string $endpoint, string $method = 'get', array|null $data = null, bool $throwError = true)
|
||||
function githubApi(GithubApp|GitlabApp|null $source, string $endpoint, string $method = 'get', ?array $data = null, bool $throwError = true)
|
||||
{
|
||||
if (is_null($source)) {
|
||||
throw new \Exception('Not implemented yet.');
|
||||
@@ -70,12 +72,13 @@ function githubApi(GithubApp|GitlabApp|null $source, string $endpoint, string $m
|
||||
$json = $response->json();
|
||||
if ($response->failed() && $throwError) {
|
||||
ray($json);
|
||||
throw new \Exception("Failed to get data from {$source->name} with error:<br><br>" . $json['message'] . "<br><br>Rate Limit resets at: " . Carbon::parse((int)$response->header('X-RateLimit-Reset'))->format('Y-m-d H:i:s') . 'UTC');
|
||||
throw new \Exception("Failed to get data from {$source->name} with error:<br><br>".$json['message'].'<br><br>Rate Limit resets at: '.Carbon::parse((int) $response->header('X-RateLimit-Reset'))->format('Y-m-d H:i:s').'UTC');
|
||||
}
|
||||
|
||||
return [
|
||||
'rate_limit_remaining' => $response->header('X-RateLimit-Remaining'),
|
||||
'rate_limit_reset' => $response->header('X-RateLimit-Reset'),
|
||||
'data' => collect($json)
|
||||
'data' => collect($json),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -84,10 +87,13 @@ function get_installation_path(GithubApp $source)
|
||||
$github = GithubApp::where('uuid', $source->uuid)->first();
|
||||
$name = Str::of(Str::kebab($github->name));
|
||||
$installation_path = $github->html_url === 'https://github.com' ? 'apps' : 'github-apps';
|
||||
|
||||
return "$github->html_url/$installation_path/$name/installations/new";
|
||||
}
|
||||
function get_permissions_path(GithubApp $source) {
|
||||
function get_permissions_path(GithubApp $source)
|
||||
{
|
||||
$github = GithubApp::where('uuid', $source->uuid)->first();
|
||||
$name = Str::of(Str::kebab($github->name));
|
||||
|
||||
return "$github->html_url/settings/apps/$name/permissions";
|
||||
}
|
||||
|
@@ -2,12 +2,9 @@
|
||||
|
||||
use App\Actions\Proxy\SaveConfiguration;
|
||||
use App\Models\Application;
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\Server;
|
||||
use Spatie\Url\Url;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
|
||||
function connectProxyToNetworks(Server $server)
|
||||
{
|
||||
if ($server->isSwarm()) {
|
||||
@@ -35,7 +32,7 @@ function connectProxyToNetworks(Server $server)
|
||||
$pullRequestId = $preview->pull_request_id;
|
||||
$applicationId = $preview->application_id;
|
||||
$application = Application::find($applicationId);
|
||||
if (!$application) {
|
||||
if (! $application) {
|
||||
continue;
|
||||
}
|
||||
$network = "{$application->uuid}-{$pullRequestId}";
|
||||
@@ -92,108 +89,108 @@ function generate_default_proxy_configuration(Server $server)
|
||||
$array_of_networks = collect([]);
|
||||
$networks->map(function ($network) use ($array_of_networks) {
|
||||
$array_of_networks[$network] = [
|
||||
"external" => true,
|
||||
'external' => true,
|
||||
];
|
||||
});
|
||||
if ($proxy_type === 'TRAEFIK_V2') {
|
||||
$labels = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.traefik.entrypoints=http",
|
||||
"traefik.http.routers.traefik.service=api@internal",
|
||||
"traefik.http.services.traefik.loadbalancer.server.port=8080",
|
||||
"coolify.managed=true",
|
||||
'traefik.enable=true',
|
||||
'traefik.http.routers.traefik.entrypoints=http',
|
||||
'traefik.http.routers.traefik.service=api@internal',
|
||||
'traefik.http.services.traefik.loadbalancer.server.port=8080',
|
||||
'coolify.managed=true',
|
||||
];
|
||||
$config = [
|
||||
"version" => "3.8",
|
||||
"networks" => $array_of_networks->toArray(),
|
||||
"services" => [
|
||||
"traefik" => [
|
||||
"container_name" => "coolify-proxy",
|
||||
"image" => "traefik:v2.10",
|
||||
"restart" => RESTART_MODE,
|
||||
"extra_hosts" => [
|
||||
"host.docker.internal:host-gateway",
|
||||
'version' => '3.8',
|
||||
'networks' => $array_of_networks->toArray(),
|
||||
'services' => [
|
||||
'traefik' => [
|
||||
'container_name' => 'coolify-proxy',
|
||||
'image' => 'traefik:v2.10',
|
||||
'restart' => RESTART_MODE,
|
||||
'extra_hosts' => [
|
||||
'host.docker.internal:host-gateway',
|
||||
],
|
||||
"networks" => $networks->toArray(),
|
||||
"ports" => [
|
||||
"80:80",
|
||||
"443:443",
|
||||
"8080:8080",
|
||||
'networks' => $networks->toArray(),
|
||||
'ports' => [
|
||||
'80:80',
|
||||
'443:443',
|
||||
'8080:8080',
|
||||
],
|
||||
"healthcheck" => [
|
||||
"test" => "wget -qO- http://localhost:80/ping || exit 1",
|
||||
"interval" => "4s",
|
||||
"timeout" => "2s",
|
||||
"retries" => 5,
|
||||
'healthcheck' => [
|
||||
'test' => 'wget -qO- http://localhost:80/ping || exit 1',
|
||||
'interval' => '4s',
|
||||
'timeout' => '2s',
|
||||
'retries' => 5,
|
||||
],
|
||||
"volumes" => [
|
||||
"/var/run/docker.sock:/var/run/docker.sock:ro",
|
||||
'volumes' => [
|
||||
'/var/run/docker.sock:/var/run/docker.sock:ro',
|
||||
"{$proxy_path}:/traefik",
|
||||
],
|
||||
"command" => [
|
||||
"--ping=true",
|
||||
"--ping.entrypoint=http",
|
||||
"--api.dashboard=true",
|
||||
"--api.insecure=false",
|
||||
"--entrypoints.http.address=:80",
|
||||
"--entrypoints.https.address=:443",
|
||||
"--entrypoints.http.http.encodequerysemicolons=true",
|
||||
"--entryPoints.http.http2.maxConcurrentStreams=50",
|
||||
"--entrypoints.https.http.encodequerysemicolons=true",
|
||||
"--entryPoints.https.http2.maxConcurrentStreams=50",
|
||||
"--providers.docker.exposedbydefault=false",
|
||||
"--providers.file.directory=/traefik/dynamic/",
|
||||
"--providers.file.watch=true",
|
||||
"--certificatesresolvers.letsencrypt.acme.httpchallenge=true",
|
||||
"--certificatesresolvers.letsencrypt.acme.storage=/traefik/acme.json",
|
||||
"--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http",
|
||||
'command' => [
|
||||
'--ping=true',
|
||||
'--ping.entrypoint=http',
|
||||
'--api.dashboard=true',
|
||||
'--api.insecure=false',
|
||||
'--entrypoints.http.address=:80',
|
||||
'--entrypoints.https.address=:443',
|
||||
'--entrypoints.http.http.encodequerysemicolons=true',
|
||||
'--entryPoints.http.http2.maxConcurrentStreams=50',
|
||||
'--entrypoints.https.http.encodequerysemicolons=true',
|
||||
'--entryPoints.https.http2.maxConcurrentStreams=50',
|
||||
'--providers.docker.exposedbydefault=false',
|
||||
'--providers.file.directory=/traefik/dynamic/',
|
||||
'--providers.file.watch=true',
|
||||
'--certificatesresolvers.letsencrypt.acme.httpchallenge=true',
|
||||
'--certificatesresolvers.letsencrypt.acme.storage=/traefik/acme.json',
|
||||
'--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http',
|
||||
],
|
||||
"labels" => $labels,
|
||||
'labels' => $labels,
|
||||
],
|
||||
],
|
||||
];
|
||||
if (isDev()) {
|
||||
// $config['services']['traefik']['command'][] = "--log.level=debug";
|
||||
$config['services']['traefik']['command'][] = "--accesslog.filepath=/traefik/access.log";
|
||||
$config['services']['traefik']['command'][] = "--accesslog.bufferingsize=100";
|
||||
$config['services']['traefik']['command'][] = '--accesslog.filepath=/traefik/access.log';
|
||||
$config['services']['traefik']['command'][] = '--accesslog.bufferingsize=100';
|
||||
}
|
||||
if ($server->isSwarm()) {
|
||||
data_forget($config, 'services.traefik.container_name');
|
||||
data_forget($config, 'services.traefik.restart');
|
||||
data_forget($config, 'services.traefik.labels');
|
||||
|
||||
$config['services']['traefik']['command'][] = "--providers.docker.swarmMode=true";
|
||||
$config['services']['traefik']['command'][] = '--providers.docker.swarmMode=true';
|
||||
$config['services']['traefik']['deploy'] = [
|
||||
"labels" => $labels,
|
||||
"placement" => [
|
||||
"constraints" => [
|
||||
"node.role==manager",
|
||||
'labels' => $labels,
|
||||
'placement' => [
|
||||
'constraints' => [
|
||||
'node.role==manager',
|
||||
],
|
||||
],
|
||||
];
|
||||
} else {
|
||||
$config['services']['traefik']['command'][] = "--providers.docker=true";
|
||||
$config['services']['traefik']['command'][] = '--providers.docker=true';
|
||||
}
|
||||
} else if ($proxy_type === 'CADDY') {
|
||||
} elseif ($proxy_type === 'CADDY') {
|
||||
$config = [
|
||||
"version" => "3.8",
|
||||
"networks" => $array_of_networks->toArray(),
|
||||
"services" => [
|
||||
"caddy" => [
|
||||
"container_name" => "coolify-proxy",
|
||||
"image" => "lucaslorentz/caddy-docker-proxy:2.8-alpine",
|
||||
"restart" => RESTART_MODE,
|
||||
"extra_hosts" => [
|
||||
"host.docker.internal:host-gateway",
|
||||
'version' => '3.8',
|
||||
'networks' => $array_of_networks->toArray(),
|
||||
'services' => [
|
||||
'caddy' => [
|
||||
'container_name' => 'coolify-proxy',
|
||||
'image' => 'lucaslorentz/caddy-docker-proxy:2.8-alpine',
|
||||
'restart' => RESTART_MODE,
|
||||
'extra_hosts' => [
|
||||
'host.docker.internal:host-gateway',
|
||||
],
|
||||
"environment" => [
|
||||
"CADDY_DOCKER_POLLING_INTERVAL=5s",
|
||||
"CADDY_DOCKER_CADDYFILE_PATH=/dynamic/Caddyfile",
|
||||
'environment' => [
|
||||
'CADDY_DOCKER_POLLING_INTERVAL=5s',
|
||||
'CADDY_DOCKER_CADDYFILE_PATH=/dynamic/Caddyfile',
|
||||
],
|
||||
"networks" => $networks->toArray(),
|
||||
"ports" => [
|
||||
"80:80",
|
||||
"443:443",
|
||||
'networks' => $networks->toArray(),
|
||||
'ports' => [
|
||||
'80:80',
|
||||
'443:443',
|
||||
],
|
||||
// "healthcheck" => [
|
||||
// "test" => "wget -qO- http://localhost:80|| exit 1",
|
||||
@@ -201,8 +198,8 @@ function generate_default_proxy_configuration(Server $server)
|
||||
// "timeout" => "2s",
|
||||
// "retries" => 5,
|
||||
// ],
|
||||
"volumes" => [
|
||||
"/var/run/docker.sock:/var/run/docker.sock:ro",
|
||||
'volumes' => [
|
||||
'/var/run/docker.sock:/var/run/docker.sock:ro',
|
||||
"{$proxy_path}/dynamic:/dynamic",
|
||||
"{$proxy_path}/config:/config",
|
||||
"{$proxy_path}/data:/data",
|
||||
@@ -216,5 +213,6 @@ function generate_default_proxy_configuration(Server $server)
|
||||
|
||||
$config = Yaml::dump($config, 12, 2);
|
||||
SaveConfiguration::run($server, $config);
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
@@ -17,12 +17,12 @@ use Illuminate\Support\Str;
|
||||
use Spatie\Activitylog\Contracts\Activity;
|
||||
|
||||
function remote_process(
|
||||
Collection|array $command,
|
||||
Server $server,
|
||||
?string $type = null,
|
||||
Collection|array $command,
|
||||
Server $server,
|
||||
?string $type = null,
|
||||
?string $type_uuid = null,
|
||||
?Model $model = null,
|
||||
bool $ignore_errors = false,
|
||||
?Model $model = null,
|
||||
bool $ignore_errors = false,
|
||||
$callEventOnFinish = null,
|
||||
$callEventData = null
|
||||
): Activity {
|
||||
@@ -38,10 +38,11 @@ function remote_process(
|
||||
$command_string = implode("\n", $command);
|
||||
if (auth()->user()) {
|
||||
$teams = auth()->user()->teams->pluck('id');
|
||||
if (!$teams->contains($server->team_id) && !$teams->contains(0)) {
|
||||
throw new \Exception("User is not part of the team that owns this server");
|
||||
if (! $teams->contains($server->team_id) && ! $teams->contains(0)) {
|
||||
throw new \Exception('User is not part of the team that owns this server');
|
||||
}
|
||||
}
|
||||
|
||||
return resolve(PrepareCoolifyTask::class, [
|
||||
'remoteProcessArgs' => new CoolifyTaskArgs(
|
||||
server_uuid: $server->uuid,
|
||||
@@ -61,15 +62,16 @@ function server_ssh_configuration(Server $server)
|
||||
{
|
||||
$uuid = data_get($server, 'uuid');
|
||||
if (is_null($uuid)) {
|
||||
throw new \Exception("Server does not have a uuid");
|
||||
throw new \Exception('Server does not have a uuid');
|
||||
}
|
||||
$private_key_filename = "id.root@{$server->uuid}";
|
||||
$location = '/var/www/html/storage/app/ssh/keys/' . $private_key_filename;
|
||||
$mux_filename = '/var/www/html/storage/app/ssh/mux/' . $server->muxFilename();
|
||||
$location = '/var/www/html/storage/app/ssh/keys/'.$private_key_filename;
|
||||
$mux_filename = '/var/www/html/storage/app/ssh/mux/'.$server->muxFilename();
|
||||
|
||||
return [
|
||||
'location' => $location,
|
||||
'mux_filename' => $mux_filename,
|
||||
'private_key_filename' => $private_key_filename
|
||||
'private_key_filename' => $private_key_filename,
|
||||
];
|
||||
}
|
||||
function savePrivateKeyToFs(Server $server)
|
||||
@@ -77,10 +79,11 @@ function savePrivateKeyToFs(Server $server)
|
||||
if (data_get($server, 'privateKey.private_key') === null) {
|
||||
throw new \Exception("Server {$server->name} does not have a private key");
|
||||
}
|
||||
['location' => $location, 'private_key_filename' => $private_key_filename] = server_ssh_configuration($server);
|
||||
['location' => $location, 'private_key_filename' => $private_key_filename] = server_ssh_configuration($server);
|
||||
Storage::disk('ssh-keys')->makeDirectory('.');
|
||||
Storage::disk('ssh-mux')->makeDirectory('.');
|
||||
Storage::disk('ssh-keys')->put($private_key_filename, $server->privateKey->private_key);
|
||||
|
||||
return $location;
|
||||
}
|
||||
|
||||
@@ -95,15 +98,15 @@ function generateScpCommand(Server $server, string $source, string $dest)
|
||||
|
||||
$scp_command = "timeout $timeout scp ";
|
||||
$scp_command .= "-i {$privateKeyLocation} "
|
||||
. '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '
|
||||
. '-o PasswordAuthentication=no '
|
||||
. "-o ConnectTimeout=$connectionTimeout "
|
||||
. "-o ServerAliveInterval=$serverInterval "
|
||||
. '-o RequestTTY=no '
|
||||
. '-o LogLevel=ERROR '
|
||||
. "-P {$port} "
|
||||
. "{$source} "
|
||||
. "{$user}@{$server->ip}:{$dest}";
|
||||
.'-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '
|
||||
.'-o PasswordAuthentication=no '
|
||||
."-o ConnectTimeout=$connectionTimeout "
|
||||
."-o ServerAliveInterval=$serverInterval "
|
||||
.'-o RequestTTY=no '
|
||||
.'-o LogLevel=ERROR '
|
||||
."-P {$port} "
|
||||
."{$source} "
|
||||
."{$user}@{$server->ip}:{$dest}";
|
||||
|
||||
return $scp_command;
|
||||
}
|
||||
@@ -115,14 +118,16 @@ function instant_scp(string $source, string $dest, Server $server, $throwError =
|
||||
$output = trim($process->output());
|
||||
$exitCode = $process->exitCode();
|
||||
if ($exitCode !== 0) {
|
||||
if (!$throwError) {
|
||||
if (! $throwError) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return excludeCertainErrors($process->errorOutput(), $exitCode);
|
||||
}
|
||||
if ($output === 'null') {
|
||||
$output = null;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
function generateSshCommand(Server $server, string $command)
|
||||
@@ -150,17 +155,18 @@ function generateSshCommand(Server $server, string $command)
|
||||
$delimiter = Hash::make($command);
|
||||
$command = str_replace($delimiter, '', $command);
|
||||
$ssh_command .= "-i {$privateKeyLocation} "
|
||||
. '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '
|
||||
. '-o PasswordAuthentication=no '
|
||||
. "-o ConnectTimeout=$connectionTimeout "
|
||||
. "-o ServerAliveInterval=$serverInterval "
|
||||
. '-o RequestTTY=no '
|
||||
. '-o LogLevel=ERROR '
|
||||
. "-p {$port} "
|
||||
. "{$user}@{$server->ip} "
|
||||
. " 'bash -se' << \\$delimiter" . PHP_EOL
|
||||
. $command . PHP_EOL
|
||||
. $delimiter;
|
||||
.'-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '
|
||||
.'-o PasswordAuthentication=no '
|
||||
."-o ConnectTimeout=$connectionTimeout "
|
||||
."-o ServerAliveInterval=$serverInterval "
|
||||
.'-o RequestTTY=no '
|
||||
.'-o LogLevel=ERROR '
|
||||
."-p {$port} "
|
||||
."{$user}@{$server->ip} "
|
||||
." 'bash -se' << \\$delimiter".PHP_EOL
|
||||
.$command.PHP_EOL
|
||||
.$delimiter;
|
||||
|
||||
// ray($ssh_command);
|
||||
return $ssh_command;
|
||||
}
|
||||
@@ -170,7 +176,7 @@ function instant_remote_process(Collection|array $command, Server $server, bool
|
||||
if ($command instanceof Collection) {
|
||||
$command = $command->toArray();
|
||||
}
|
||||
if ($server->isNonRoot() && !$no_sudo) {
|
||||
if ($server->isNonRoot() && ! $no_sudo) {
|
||||
$command = parseCommandsByLineForSudo(collect($command), $server);
|
||||
}
|
||||
$command_string = implode("\n", $command);
|
||||
@@ -179,14 +185,16 @@ function instant_remote_process(Collection|array $command, Server $server, bool
|
||||
$output = trim($process->output());
|
||||
$exitCode = $process->exitCode();
|
||||
if ($exitCode !== 0) {
|
||||
if (!$throwError) {
|
||||
if (! $throwError) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return excludeCertainErrors($process->errorOutput(), $exitCode);
|
||||
}
|
||||
if ($output === 'null') {
|
||||
$output = null;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
function excludeCertainErrors(string $errorOutput, ?int $exitCode = null)
|
||||
@@ -227,20 +235,23 @@ function decode_remote_command_output(?ApplicationDeploymentQueue $application_d
|
||||
}
|
||||
// ray($decoded );
|
||||
$formatted = collect($decoded);
|
||||
if (!$is_debug_enabled) {
|
||||
if (! $is_debug_enabled) {
|
||||
$formatted = $formatted->filter(fn ($i) => $i['hidden'] === false ?? false);
|
||||
}
|
||||
$formatted = $formatted
|
||||
->sortBy(fn ($i) => data_get($i, 'order'))
|
||||
->map(function ($i) {
|
||||
data_set($i, 'timestamp', Carbon::parse(data_get($i, 'timestamp'))->format('Y-M-d H:i:s.u'));
|
||||
|
||||
return $i;
|
||||
});
|
||||
|
||||
return $formatted;
|
||||
}
|
||||
function remove_iip($text)
|
||||
{
|
||||
$text = preg_replace('/x-access-token:.*?(?=@)/', "x-access-token:" . REDACTED, $text);
|
||||
$text = preg_replace('/x-access-token:.*?(?=@)/', 'x-access-token:'.REDACTED, $text);
|
||||
|
||||
return preg_replace('/\x1b\[[0-9;]*m/', '', $text);
|
||||
}
|
||||
function remove_mux_and_private_key(Server $server)
|
||||
@@ -262,26 +273,28 @@ function refresh_server_connection(?PrivateKey $private_key = null)
|
||||
|
||||
function checkRequiredCommands(Server $server)
|
||||
{
|
||||
$commands = collect(["jq", "jc"]);
|
||||
$commands = collect(['jq', 'jc']);
|
||||
foreach ($commands as $command) {
|
||||
$commandFound = instant_remote_process(["docker run --rm --privileged --net=host --pid=host --ipc=host --volume /:/host busybox chroot /host bash -c 'command -v {$command}'"], $server, false);
|
||||
if ($commandFound) {
|
||||
ray($command . ' found');
|
||||
ray($command.' found');
|
||||
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
instant_remote_process(["docker run --rm --privileged --net=host --pid=host --ipc=host --volume /:/host busybox chroot /host bash -c 'apt update && apt install -y {$command}'"], $server);
|
||||
} catch (\Throwable $e) {
|
||||
ray('could not install ' . $command);
|
||||
ray('could not install '.$command);
|
||||
ray($e);
|
||||
break;
|
||||
}
|
||||
$commandFound = instant_remote_process(["docker run --rm --privileged --net=host --pid=host --ipc=host --volume /:/host busybox chroot /host bash -c 'command -v {$command}'"], $server, false);
|
||||
if ($commandFound) {
|
||||
ray($command . ' found');
|
||||
ray($command.' found');
|
||||
|
||||
continue;
|
||||
}
|
||||
ray('could not install ' . $command);
|
||||
ray('could not install '.$command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -34,7 +34,7 @@ function getFilesystemVolumesFromServer(ServiceApplication|ServiceDatabase|Appli
|
||||
$fileVolumes = $oneService->fileStorages()->get();
|
||||
$commands = collect([
|
||||
"mkdir -p $workdir > /dev/null 2>&1 || true",
|
||||
"cd $workdir"
|
||||
"cd $workdir",
|
||||
]);
|
||||
instant_remote_process($commands, $server);
|
||||
foreach ($fileVolumes as $fileVolume) {
|
||||
@@ -42,7 +42,7 @@ function getFilesystemVolumesFromServer(ServiceApplication|ServiceDatabase|Appli
|
||||
$content = data_get($fileVolume, 'content');
|
||||
if ($path->startsWith('.')) {
|
||||
$path = $path->after('.');
|
||||
$fileLocation = $workdir . $path;
|
||||
$fileLocation = $workdir.$path;
|
||||
} else {
|
||||
$fileLocation = $path;
|
||||
}
|
||||
@@ -57,12 +57,12 @@ function getFilesystemVolumesFromServer(ServiceApplication|ServiceDatabase|Appli
|
||||
$fileVolume->content = $filesystemContent;
|
||||
$fileVolume->is_directory = false;
|
||||
$fileVolume->save();
|
||||
} else if ($isDir == 'OK') {
|
||||
} elseif ($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) {
|
||||
} elseif ($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;
|
||||
@@ -71,9 +71,9 @@ function getFilesystemVolumesFromServer(ServiceApplication|ServiceDatabase|Appli
|
||||
$dir = Str::of($fileLocation)->dirname();
|
||||
instant_remote_process([
|
||||
"mkdir -p $dir",
|
||||
"echo '$content' | base64 -d | tee $fileLocation"
|
||||
"echo '$content' | base64 -d | tee $fileLocation",
|
||||
], $server);
|
||||
} else if ($isFile == 'NOK' && $isDir == 'NOK' && $fileVolume->is_directory && $isInit) {
|
||||
} elseif ($isFile == 'NOK' && $isDir == 'NOK' && $fileVolume->is_directory && $isInit) {
|
||||
$fileVolume->content = null;
|
||||
$fileVolume->is_directory = true;
|
||||
$fileVolume->save();
|
||||
@@ -106,26 +106,26 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
||||
$resourceFqdns = str($resource->fqdn)->explode(',');
|
||||
if ($resourceFqdns->count() === 1) {
|
||||
$resourceFqdns = $resourceFqdns->first();
|
||||
$variableName = "SERVICE_FQDN_" . Str::of($resource->name)->upper()->replace('-', '');
|
||||
$variableName = 'SERVICE_FQDN_'.Str::of($resource->name)->upper()->replace('-', '');
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
$fqdn = Url::fromString($resourceFqdns);
|
||||
$port = $fqdn->getPort();
|
||||
$path = $fqdn->getPath();
|
||||
$fqdn = $fqdn->getScheme() . '://' . $fqdn->getHost();
|
||||
$fqdn = $fqdn->getScheme().'://'.$fqdn->getHost();
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $fqdn . $path;
|
||||
$generatedEnv->value = $fqdn.$path;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
if ($port) {
|
||||
$variableName = $variableName . "_$port";
|
||||
$variableName = $variableName."_$port";
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
// ray($generatedEnv);
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $fqdn . $path;
|
||||
$generatedEnv->value = $fqdn.$path;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
}
|
||||
$variableName = "SERVICE_URL_" . Str::of($resource->name)->upper()->replace('-', '');
|
||||
$variableName = 'SERVICE_URL_'.Str::of($resource->name)->upper()->replace('-', '');
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
$url = Url::fromString($fqdn);
|
||||
$port = $url->getPort();
|
||||
@@ -133,60 +133,60 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
||||
$url = $url->getHost();
|
||||
if ($generatedEnv) {
|
||||
$url = Str::of($fqdn)->after('://');
|
||||
$generatedEnv->value = $url . $path;
|
||||
$generatedEnv->value = $url.$path;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
if ($port) {
|
||||
$variableName = $variableName . "_$port";
|
||||
$variableName = $variableName."_$port";
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $url . $path;
|
||||
$generatedEnv->value = $url.$path;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
}
|
||||
} else if ($resourceFqdns->count() > 1) {
|
||||
} elseif ($resourceFqdns->count() > 1) {
|
||||
foreach ($resourceFqdns as $fqdn) {
|
||||
$host = Url::fromString($fqdn);
|
||||
$port = $host->getPort();
|
||||
$url = $host->getHost();
|
||||
$path = $host->getPath();
|
||||
$host = $host->getScheme() . '://' . $host->getHost();
|
||||
$host = $host->getScheme().'://'.$host->getHost();
|
||||
if ($port) {
|
||||
$port_envs = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'like', "SERVICE_FQDN_%_$port")->get();
|
||||
foreach ($port_envs as $port_env) {
|
||||
$service_fqdn = str($port_env->key)->beforeLast('_')->after('SERVICE_FQDN_');
|
||||
$env = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'SERVICE_FQDN_' . $service_fqdn)->first();
|
||||
$env = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'SERVICE_FQDN_'.$service_fqdn)->first();
|
||||
if ($env) {
|
||||
$env->value = $host . $path;
|
||||
$env->value = $host.$path;
|
||||
$env->save();
|
||||
}
|
||||
$port_env->value = $host . $path;
|
||||
$port_env->value = $host.$path;
|
||||
$port_env->save();
|
||||
}
|
||||
$port_envs_url = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'like', "SERVICE_URL_%_$port")->get();
|
||||
foreach ($port_envs_url as $port_env_url) {
|
||||
$service_url = str($port_env_url->key)->beforeLast('_')->after('SERVICE_URL_');
|
||||
$env = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'SERVICE_URL_' . $service_url)->first();
|
||||
$env = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'SERVICE_URL_'.$service_url)->first();
|
||||
if ($env) {
|
||||
$env->value = $url . $path;
|
||||
$env->value = $url.$path;
|
||||
$env->save();
|
||||
}
|
||||
$port_env_url->value = $url . $path;
|
||||
$port_env_url->value = $url.$path;
|
||||
$port_env_url->save();
|
||||
}
|
||||
} else {
|
||||
$variableName = "SERVICE_FQDN_" . Str::of($resource->name)->upper()->replace('-', '');
|
||||
$variableName = 'SERVICE_FQDN_'.Str::of($resource->name)->upper()->replace('-', '');
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
$fqdn = Url::fromString($fqdn);
|
||||
$fqdn = $fqdn->getScheme() . '://' . $fqdn->getHost() . $fqdn->getPath();
|
||||
$fqdn = $fqdn->getScheme().'://'.$fqdn->getHost().$fqdn->getPath();
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $fqdn;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
$variableName = "SERVICE_URL_" . Str::of($resource->name)->upper()->replace('-', '');
|
||||
$variableName = 'SERVICE_URL_'.Str::of($resource->name)->upper()->replace('-', '');
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
$url = Url::fromString($fqdn);
|
||||
$url = $url->getHost() . $url->getPath();
|
||||
$url = $url->getHost().$url->getPath();
|
||||
if ($generatedEnv) {
|
||||
$url = Str::of($fqdn)->after('://');
|
||||
$generatedEnv->value = $url;
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,8 @@ function get_socialite_provider(string $provider)
|
||||
$oauth_setting->client_secret,
|
||||
$oauth_setting->redirect_uri,
|
||||
['tenant' => $oauth_setting->tenant],
|
||||
);
|
||||
);
|
||||
|
||||
return Socialite::driver('azure')->setConfig($azure_config);
|
||||
}
|
||||
|
||||
|
@@ -7,7 +7,7 @@ use Stripe\Stripe;
|
||||
function getSubscriptionLink($type)
|
||||
{
|
||||
$checkout_id = config("subscription.lemon_squeezy_checkout_id_$type");
|
||||
if (!$checkout_id) {
|
||||
if (! $checkout_id) {
|
||||
return null;
|
||||
}
|
||||
$user_id = auth()->user()->id;
|
||||
@@ -27,6 +27,7 @@ function getSubscriptionLink($type)
|
||||
if ($name) {
|
||||
$url .= "&checkout[name]={$name}";
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
@@ -47,11 +48,11 @@ function getEndDate()
|
||||
|
||||
function isSubscriptionActive()
|
||||
{
|
||||
if (!isCloud()) {
|
||||
if (! isCloud()) {
|
||||
return false;
|
||||
}
|
||||
$team = currentTeam();
|
||||
if (!$team) {
|
||||
if (! $team) {
|
||||
return false;
|
||||
}
|
||||
$subscription = $team?->subscription;
|
||||
@@ -68,26 +69,29 @@ function isSubscriptionActive()
|
||||
if (isStripe()) {
|
||||
return $subscription->stripe_invoice_paid === true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
function isSubscriptionOnGracePeriod()
|
||||
{
|
||||
$team = currentTeam();
|
||||
if (!$team) {
|
||||
if (! $team) {
|
||||
return false;
|
||||
}
|
||||
$subscription = $team?->subscription;
|
||||
if (!$subscription) {
|
||||
if (! $subscription) {
|
||||
return false;
|
||||
}
|
||||
if (isLemon()) {
|
||||
$is_still_grace_period = $subscription->lemon_ends_at &&
|
||||
Carbon::parse($subscription->lemon_ends_at) > Carbon::now();
|
||||
|
||||
return $is_still_grace_period;
|
||||
}
|
||||
if (isStripe()) {
|
||||
return $subscription->stripe_cancel_at_period_end;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
function subscriptionProvider()
|
||||
@@ -110,14 +114,15 @@ function getStripeCustomerPortalSession(Team $team)
|
||||
{
|
||||
Stripe::setApiKey(config('subscription.stripe_api_key'));
|
||||
$return_url = route('subscription.show');
|
||||
$stripe_customer_id = data_get($team,'subscription.stripe_customer_id');
|
||||
if (!$stripe_customer_id) {
|
||||
$stripe_customer_id = data_get($team, 'subscription.stripe_customer_id');
|
||||
if (! $stripe_customer_id) {
|
||||
return null;
|
||||
}
|
||||
$session = \Stripe\BillingPortal\Session::create([
|
||||
'customer' => $stripe_customer_id,
|
||||
'return_url' => $return_url,
|
||||
]);
|
||||
|
||||
return $session;
|
||||
}
|
||||
function allowedPathsForUnsubscribedAccounts()
|
||||
@@ -128,7 +133,7 @@ function allowedPathsForUnsubscribedAccounts()
|
||||
'logout',
|
||||
'waitlist',
|
||||
'force-password-reset',
|
||||
'livewire/update'
|
||||
'livewire/update',
|
||||
];
|
||||
}
|
||||
function allowedPathsForBoardingAccounts()
|
||||
@@ -136,14 +141,15 @@ function allowedPathsForBoardingAccounts()
|
||||
return [
|
||||
...allowedPathsForUnsubscribedAccounts(),
|
||||
'onboarding',
|
||||
'livewire/update'
|
||||
'livewire/update',
|
||||
];
|
||||
}
|
||||
function allowedPathsForInvalidAccounts() {
|
||||
function allowedPathsForInvalidAccounts()
|
||||
{
|
||||
return [
|
||||
'logout',
|
||||
'verify',
|
||||
'force-password-reset',
|
||||
'livewire/update'
|
||||
'livewire/update',
|
||||
];
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
$files = glob(__DIR__ . '/helpers/*.php');
|
||||
|
||||
$files = glob(__DIR__.'/helpers/*.php');
|
||||
foreach ($files as $file) {
|
||||
require($file);
|
||||
require $file;
|
||||
}
|
||||
|
Reference in New Issue
Block a user