Zoo

← back to the zoo

8. A bad manifest is shown, not applied

A mistake in an app's settings file (ratcloud.conf) leaves the old settings running and says what was wrong.

ratcloud.conf is checked before anything is applied. A bad one refuses the push, in the pusher's terminal and in RC_FACTS/manifest.json; the site keeps running.

This is the code serving the zoo right now: read from disk for this request, from commit 0c1c124a02 (live). The zoo's own self-check fetches this page and compares it byte for byte with the file it runs.

exhibits/08-bad-manifest.php sha256 521428ea5169 · raw

1<?php
2// Exhibit 8. A push whose ratcloud.conf is wrong is refused whole: the old code and settings keep
3// running and the error lands in the app's RC_FACTS/manifest.json. The sample app `zoo-broken` has a
4// deliberate typo pushed to it. The zoo reads only its own facts, so zoo-broken publishes its own
5// manifest fact at /manifest.json, from its last good version, and the zoo fetches that over HTTPS.
6// (The dashboard will show the same error to zoo-broken's creator.)
7return [
8    "n" => 8, "wing" => "Deploy",
9    "title" => "A bad manifest is shown, not applied",
10    "promise" => "A mistake in an app's settings file (ratcloud.conf) leaves the old settings running and says what was wrong.",
11    "block" => "ratcloud.conf is checked before anything is applied. A bad one refuses the push, in the pusher's terminal and in RC_FACTS/manifest.json; the site keeps running.",
12    "show" => function (?array $me): string {
13        $s = stored(8)["data"] ?? null;
14        $url = rc_app_url("zoo-broken");
15        if (!$s) return '<p>The sample app <a href="' . h($url) . '/">zoo-broken</a> has not been checked yet.</p>';
16        return '<p>The sample app <a href="' . h($url) . '/">' . h(parse_url($url, PHP_URL_HOST)) . '</a> is up, and its last push was refused:</p>'
17             . '<pre class="log">' . h($s["error"] ?? "") . "</pre>"
18             . '<p class="muted">Refused ' . ago(strtotime($s["at"] ?? "now")) . ", commit " . h(substr($s["commit"] ?? "", 0, 7)) . ". It still serves its last good version.</p>";
19    },
20    "check" => function (): array {
21        $url = rc_app_url("zoo-broken");
22        [$code] = (new Browser())->get("$url/");
23        if ($code !== 200) return [false, "the sample app is down ($code): a bad manifest must not take it down"];
24        [$code, , $m] = (new Browser())->get("$url/manifest.json");
25        if ($code !== 200 || !is_array($m)) return [false, "the sample app's manifest fact did not load ($code)"];
26        if (($m["ok"] ?? null) !== false) return [false, "the sample app's typo was accepted, or is gone: no error to show"];
27        if (trim((string)($m["error"] ?? "")) === "") return [false, "the push was refused but no error was recorded"];
28        return [true, "zoo-broken is up on its last good version; its typo was refused with: " . $m["error"], $m];
29    },
30];