mirror of
https://github.com/tiennm99/coolify.git
synced 2026-09-05 08:17:27 +00:00
Merge remote-tracking branch 'origin/next' into audit-policies
This commit is contained in:
@@ -86,7 +86,7 @@ function format_docker_command_output_to_json($rawOutput): Collection
|
||||
return $outputLines
|
||||
->reject(fn ($line) => empty($line))
|
||||
->map(fn ($outputLine) => json_decode($outputLine, true, flags: JSON_THROW_ON_ERROR));
|
||||
} catch (\Throwable) {
|
||||
} catch (Throwable) {
|
||||
return collect([]);
|
||||
}
|
||||
}
|
||||
@@ -123,7 +123,7 @@ function format_docker_envs_to_json($rawOutput)
|
||||
|
||||
return [$env[0] => $env[1]];
|
||||
});
|
||||
} catch (\Throwable) {
|
||||
} catch (Throwable) {
|
||||
return collect([]);
|
||||
}
|
||||
}
|
||||
@@ -255,12 +255,12 @@ function defaultLabels($id, $name, string $projectName, string $resourceName, st
|
||||
|
||||
function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
|
||||
{
|
||||
if ($resource->getMorphClass() === \App\Models\ServiceApplication::class) {
|
||||
if ($resource->getMorphClass() === ServiceApplication::class) {
|
||||
$uuid = data_get($resource, 'uuid');
|
||||
$server = data_get($resource, 'service.server');
|
||||
$environment_variables = data_get($resource, 'service.environment_variables');
|
||||
$type = $resource->serviceType();
|
||||
} elseif ($resource->getMorphClass() === \App\Models\Application::class) {
|
||||
} elseif ($resource->getMorphClass() === Application::class) {
|
||||
$uuid = data_get($resource, 'uuid');
|
||||
$server = data_get($resource, 'destination.server');
|
||||
$environment_variables = data_get($resource, 'environment_variables');
|
||||
@@ -641,7 +641,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\Throwable) {
|
||||
} catch (Throwable) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1000,6 +1000,7 @@ function convertDockerRunToCompose(?string $custom_docker_run_options = null)
|
||||
'--ulimit',
|
||||
'--device',
|
||||
'--shm-size',
|
||||
'--dns',
|
||||
]);
|
||||
$mapping = collect([
|
||||
'--cap-add' => 'cap_add',
|
||||
@@ -1013,6 +1014,7 @@ function convertDockerRunToCompose(?string $custom_docker_run_options = null)
|
||||
'--ip' => 'ip',
|
||||
'--ip6' => 'ip6',
|
||||
'--shm-size' => 'shm_size',
|
||||
'--dns' => 'dns',
|
||||
'--gpus' => 'gpus',
|
||||
'--hostname' => 'hostname',
|
||||
'--entrypoint' => 'entrypoint',
|
||||
@@ -1219,7 +1221,7 @@ function validateComposeFile(string $compose, int $server_id): string|Throwable
|
||||
$server = Server::ownedByCurrentTeam()->find($server_id);
|
||||
try {
|
||||
if (! $server) {
|
||||
throw new \Exception('Server not found');
|
||||
throw new Exception('Server not found');
|
||||
}
|
||||
$yaml_compose = Yaml::parse($compose);
|
||||
|
||||
@@ -1235,7 +1237,7 @@ function validateComposeFile(string $compose, int $server_id): string|Throwable
|
||||
], $server);
|
||||
|
||||
return 'OK';
|
||||
} catch (\Throwable $e) {
|
||||
} catch (Throwable $e) {
|
||||
return $e->getMessage();
|
||||
} finally {
|
||||
if (filled($server)) {
|
||||
@@ -1351,10 +1353,10 @@ function escapeBashDoubleQuoted(?string $value): string
|
||||
* Generate Docker build arguments from environment variables collection
|
||||
* Returns only keys (no values) since values are sourced from environment via export
|
||||
*
|
||||
* @param \Illuminate\Support\Collection|array $variables Collection of variables with 'key', 'value', and optionally 'is_multiline'
|
||||
* @return \Illuminate\Support\Collection Collection of formatted --build-arg strings (keys only)
|
||||
* @param Collection|array $variables Collection of variables with 'key', 'value', and optionally 'is_multiline'
|
||||
* @return Collection Collection of formatted --build-arg strings (keys only)
|
||||
*/
|
||||
function generateDockerBuildArgs($variables): \Illuminate\Support\Collection
|
||||
function generateDockerBuildArgs($variables): Collection
|
||||
{
|
||||
$variables = collect($variables);
|
||||
|
||||
@@ -1369,7 +1371,7 @@ function generateDockerBuildArgs($variables): \Illuminate\Support\Collection
|
||||
/**
|
||||
* Generate Docker environment flags from environment variables collection
|
||||
*
|
||||
* @param \Illuminate\Support\Collection|array $variables Collection of variables with 'key', 'value', and optionally 'is_multiline'
|
||||
* @param Collection|array $variables Collection of variables with 'key', 'value', and optionally 'is_multiline'
|
||||
* @return string Space-separated environment flags
|
||||
*/
|
||||
function generateDockerEnvFlags($variables): string
|
||||
|
||||
@@ -4,6 +4,7 @@ use App\Models\GithubApp;
|
||||
use App\Models\GitlabApp;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonImmutable;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Str;
|
||||
use Lcobucci\JWT\Encoding\ChainedFormatter;
|
||||
@@ -20,7 +21,7 @@ function generateGithubToken(GithubApp $source, string $type)
|
||||
$timeDiff = abs($serverTime->diffInSeconds($githubTime));
|
||||
|
||||
if ($timeDiff > 50) {
|
||||
throw new \Exception(
|
||||
throw new Exception(
|
||||
'System time is out of sync with GitHub API time:<br>'.
|
||||
'- System time: '.$serverTime->format('Y-m-d H:i:s').' UTC<br>'.
|
||||
'- GitHub time: '.$githubTime->format('Y-m-d H:i:s').' UTC<br>'.
|
||||
@@ -60,7 +61,7 @@ function generateGithubToken(GithubApp $source, string $type)
|
||||
|
||||
return $response->json()['token'];
|
||||
})(),
|
||||
default => throw new \InvalidArgumentException("Unsupported token type: {$type}")
|
||||
default => throw new InvalidArgumentException("Unsupported token type: {$type}")
|
||||
};
|
||||
}
|
||||
|
||||
@@ -77,11 +78,11 @@ function generateGithubJwt(GithubApp $source)
|
||||
function githubApi(GithubApp|GitlabApp|null $source, string $endpoint, string $method = 'get', ?array $data = null, bool $throwError = true)
|
||||
{
|
||||
if (is_null($source)) {
|
||||
throw new \Exception('Source is required for API calls');
|
||||
throw new Exception('Source is required for API calls');
|
||||
}
|
||||
|
||||
if ($source->getMorphClass() !== GithubApp::class) {
|
||||
throw new \InvalidArgumentException("Unsupported source type: {$source->getMorphClass()}");
|
||||
throw new InvalidArgumentException("Unsupported source type: {$source->getMorphClass()}");
|
||||
}
|
||||
|
||||
if ($source->is_public) {
|
||||
@@ -100,7 +101,7 @@ function githubApi(GithubApp|GitlabApp|null $source, string $endpoint, string $m
|
||||
$errorMessage = data_get($response->json(), 'message', 'no error message found');
|
||||
$remainingCalls = $response->header('X-RateLimit-Remaining', '0');
|
||||
|
||||
throw new \Exception(
|
||||
throw new Exception(
|
||||
'GitHub API call failed:<br>'.
|
||||
"Error: {$errorMessage}<br>".
|
||||
'Rate Limit Status:<br>'.
|
||||
@@ -116,13 +117,19 @@ function githubApi(GithubApp|GitlabApp|null $source, string $endpoint, string $m
|
||||
];
|
||||
}
|
||||
|
||||
function getInstallationPath(GithubApp $source)
|
||||
function getInstallationPath(GithubApp $source): string
|
||||
{
|
||||
$github = GithubApp::where('uuid', $source->uuid)->first();
|
||||
$name = str(Str::kebab($github->name));
|
||||
$installation_path = $github->html_url === 'https://github.com' ? 'apps' : 'github-apps';
|
||||
$name = str(Str::kebab($source->name));
|
||||
$installation_path = $source->html_url === 'https://github.com' ? 'apps' : 'github-apps';
|
||||
$state = Str::random(64);
|
||||
|
||||
return "$github->html_url/$installation_path/$name/installations/new";
|
||||
Cache::put('github-app-setup-state:'.hash('sha256', $state), [
|
||||
'action' => 'install',
|
||||
'github_app_id' => $source->id,
|
||||
'team_id' => $source->team_id,
|
||||
], now()->addMinutes(60));
|
||||
|
||||
return "$source->html_url/$installation_path/$name/installations/new?".http_build_query(['state' => $state]);
|
||||
}
|
||||
|
||||
function getPermissionsPath(GithubApp $source)
|
||||
|
||||
@@ -4,6 +4,7 @@ use App\Actions\Proxy\SaveProxyConfiguration;
|
||||
use App\Enums\ProxyTypes;
|
||||
use App\Models\Application;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
@@ -137,7 +138,7 @@ function connectProxyToNetworks(Server $server)
|
||||
* This must be called BEFORE docker compose up since the compose file declares networks as external.
|
||||
*
|
||||
* @param Server $server The server to ensure networks on
|
||||
* @return \Illuminate\Support\Collection Commands to create networks if they don't exist
|
||||
* @return Collection Commands to create networks if they don't exist
|
||||
*/
|
||||
function ensureProxyNetworksExist(Server $server)
|
||||
{
|
||||
@@ -215,7 +216,7 @@ function extractCustomProxyCommands(Server $server, string $existing_config): ar
|
||||
$custom_commands[] = $command;
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// If we can't parse the config, return empty array
|
||||
// Silently fail to avoid breaking the proxy regeneration
|
||||
}
|
||||
@@ -436,7 +437,7 @@ function getExactTraefikVersionFromContainer(Server $server): ?string
|
||||
Log::debug("getExactTraefikVersionFromContainer: Server '{$server->name}' (ID: {$server->id}) - Could not detect exact version");
|
||||
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
Log::error("getExactTraefikVersionFromContainer: Server '{$server->name}' (ID: {$server->id}) - Error: ".$e->getMessage());
|
||||
|
||||
return null;
|
||||
@@ -483,7 +484,7 @@ function getTraefikVersionFromDockerCompose(Server $server): ?string
|
||||
Log::debug("getTraefikVersionFromDockerCompose: Server '{$server->name}' (ID: {$server->id}) - Image format doesn't match expected pattern: {$image}");
|
||||
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
Log::error("getTraefikVersionFromDockerCompose: Server '{$server->name}' (ID: {$server->id}) - Error: ".$e->getMessage());
|
||||
|
||||
return null;
|
||||
|
||||
@@ -200,6 +200,7 @@ function decode_remote_command_output(?ApplicationDeploymentQueue $application_d
|
||||
}
|
||||
$application = Application::find(data_get($application_deployment_queue, 'application_id'));
|
||||
$is_debug_enabled = data_get($application, 'settings.is_debug_enabled');
|
||||
$serverTimezone = getServerTimezone(data_get($application, 'destination.server'));
|
||||
|
||||
// Members should never see debug logs, even if an admin enabled debug mode
|
||||
if ($is_debug_enabled && auth()->check() && auth()->user()->isMember()) {
|
||||
@@ -245,8 +246,14 @@ function decode_remote_command_output(?ApplicationDeploymentQueue $application_d
|
||||
|
||||
return $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'));
|
||||
->map(function ($i) use ($serverTimezone) {
|
||||
$timestamp = Carbon::parse(data_get($i, 'timestamp'));
|
||||
try {
|
||||
$timestamp->setTimezone($serverTimezone);
|
||||
} catch (Exception) {
|
||||
$timestamp->setTimezone('UTC');
|
||||
}
|
||||
data_set($i, 'timestamp', $timestamp->format('Y-M-d H:i:s.u'));
|
||||
|
||||
return $i;
|
||||
})
|
||||
|
||||
@@ -1865,15 +1865,15 @@ function isBase64Encoded($strValue)
|
||||
{
|
||||
return base64_encode(base64_decode($strValue, true)) === $strValue;
|
||||
}
|
||||
function customApiValidator(Collection|array $item, array $rules)
|
||||
function customApiValidator(Collection|array $item, array $rules, array $messages = [])
|
||||
{
|
||||
if (is_array($item)) {
|
||||
$item = collect($item);
|
||||
}
|
||||
|
||||
return Validator::make($item->toArray(), $rules, [
|
||||
return Validator::make($item->toArray(), $rules, array_merge([
|
||||
'required' => 'This field is required.',
|
||||
]);
|
||||
], $messages));
|
||||
}
|
||||
function parseDockerComposeFile(Service|Application $resource, bool $isNew = false, int $pull_request_id = 0, ?int $preview_id = null)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user