mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-04 10:42:23 +00:00
fix(templates): keep local service templates when the CDN bundle is unusable
A 200 response with an empty body or an error page replaced the local templates and the shared cache, so the service list became empty. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
69eeb2f628
commit
1e66c9f9bd
3 files changed
+41
-2
No files matched your search
@@ -34,7 +34,11 @@ class PullTemplatesFromCDN implements ShouldBeEncrypted, ShouldQueue
|
||||
->get(config('constants.services.official'));
|
||||
if ($response->successful()) {
|
||||
// Shared cache so Cloud HTTP nodes see the same bundle Horizon pulled.
|
||||
store_service_templates_bundle($response->body());
|
||||
if (! store_service_templates_bundle($response->body())) {
|
||||
Log::error('PullTemplatesFromCDN received an invalid bundle', [
|
||||
'body' => str($response->body())->limit(500)->toString(),
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
Log::error('PullTemplatesFromCDN failed', [
|
||||
'status' => $response->status(),
|
||||
|
||||
@@ -1484,6 +1484,12 @@ function service_templates_path(): string
|
||||
*/
|
||||
function store_service_templates_bundle(string $json, ?string $fetchedAt = null): bool
|
||||
{
|
||||
// A 200 response can still be an empty body or an error page; keep the current templates then.
|
||||
$templates = json_decode($json, true);
|
||||
if (! is_array($templates) || $templates === [] || array_is_list($templates)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$fetchedAt ??= now()->toIso8601String();
|
||||
$path = service_templates_path();
|
||||
|
||||
@@ -1530,7 +1536,9 @@ function get_service_templates(bool $force = false): Collection
|
||||
if ($response->failed()) {
|
||||
return collect([]);
|
||||
}
|
||||
store_service_templates_bundle($response->body());
|
||||
if (! store_service_templates_bundle($response->body())) {
|
||||
return get_service_templates();
|
||||
}
|
||||
|
||||
return collect(json_decode($response->body()))->sortKeys();
|
||||
} catch (Throwable) {
|
||||
|
||||
@@ -119,6 +119,33 @@ it('skips pulling templates in local development', function () {
|
||||
expect(Cache::get(service_templates_cache_key()))->toBeNull();
|
||||
});
|
||||
|
||||
it('keeps the local templates when the CDN returns an unusable bundle', function (string $body) {
|
||||
Http::fake([
|
||||
config('constants.services.official') => Http::response($body, 200),
|
||||
]);
|
||||
|
||||
$path = service_templates_path();
|
||||
$original = File::get($path);
|
||||
|
||||
try {
|
||||
config(['app.env' => 'production']);
|
||||
|
||||
(new PullTemplatesFromCDN)->handle();
|
||||
|
||||
expect(md5(File::get($path)))->toBe(md5($original))
|
||||
->and(Cache::get(service_templates_cache_key()))->toBeNull()
|
||||
->and(get_service_templates())->not->toBeEmpty();
|
||||
} finally {
|
||||
File::put($path, $original);
|
||||
Cache::forget(service_templates_cache_key());
|
||||
}
|
||||
})->with([
|
||||
'empty body' => '',
|
||||
'html error page' => '<html>Bad gateway</html>',
|
||||
'empty object' => '{}',
|
||||
'json list' => '[1, 2]',
|
||||
]);
|
||||
|
||||
it('logs when the CDN responds with a non-success status', function () {
|
||||
Http::fake([
|
||||
'cdn.coollabs.io/*' => Http::response('nope', 503),
|
||||
|
||||
Reference in new issue
Block a user