Merge pull request 'install-apt: fail fast when the registry has no Release file' (#18) from fix/install-apt-fail-fast into main
Some checks are pending
ci / test (push) Waiting to run
Some checks are pending
ci / test (push) Waiting to run
This commit is contained in:
commit
907917a870
2 changed files with 39 additions and 2 deletions
|
|
@ -88,6 +88,19 @@ echo "deb [signed-by=$KEYRING] $FORGE_URL/api/packages/$OWNER/debian $DISTRIBUTI
|
||||||
# read these.
|
# read these.
|
||||||
$SUDO chmod 0644 "$KEYRING" "$LIST"
|
$SUDO chmod 0644 "$KEYRING" "$LIST"
|
||||||
|
|
||||||
|
# Fail fast with a clear message when the registry has no package published
|
||||||
|
# yet: without a Release file, `apt-get update` would only fail with a
|
||||||
|
# generic "repository does not have a Release file" error. A definitive 404
|
||||||
|
# is fatal; any other curl outcome (e.g. a network hiccup) is left for
|
||||||
|
# apt-get update to report.
|
||||||
|
RELEASE_URL="$FORGE_URL/api/packages/$OWNER/debian/dists/$DISTRIBUTION/Release"
|
||||||
|
if [ "$(curl -sSL -o /dev/null -w '%{http_code}' "$RELEASE_URL" || true)" = "404" ]; then
|
||||||
|
echo "error: no stoke package has been published to the $OWNER Debian registry yet" >&2
|
||||||
|
echo "($RELEASE_URL returned 404)." >&2
|
||||||
|
echo "Install stoke via npm or manually instead — see the README." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Newer apt verifies with sqv (Sequoia), which rejects the signature Forgejo
|
# Newer apt verifies with sqv (Sequoia), which rejects the signature Forgejo
|
||||||
# currently produces for its Debian registry (malformed Ed25519 MPI encoding
|
# currently produces for its Debian registry (malformed Ed25519 MPI encoding
|
||||||
# in the upstream signing library). Try the properly signed source first so
|
# in the upstream signing library). Try the properly signed source first so
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,13 @@ const SCRIPT = path.join(__dirname, '..', 'scripts', 'install-apt.sh');
|
||||||
// candInitial `apt-cache policy` Candidate before any update
|
// candInitial `apt-cache policy` Candidate before any update
|
||||||
// candAfterUpdate Candidate after any `apt-get update`
|
// candAfterUpdate Candidate after any `apt-get update`
|
||||||
// candAfterNodesource Candidate after an update once nodesource.list exists
|
// candAfterNodesource Candidate after an update once nodesource.list exists
|
||||||
|
// releaseStatus HTTP status curl reports for the registry Release file
|
||||||
// The apt-cache stub localizes the "Candidate:" label unless LC_ALL=C is set,
|
// The apt-cache stub localizes the "Candidate:" label unless LC_ALL=C is set,
|
||||||
// so every scenario doubles as a regression test for locale-safe parsing.
|
// so every scenario doubles as a regression test for locale-safe parsing.
|
||||||
const cleanups = [];
|
const cleanups = [];
|
||||||
process.on('exit', () => { for (const dir of cleanups) fs.rmSync(dir, { recursive: true, force: true }); });
|
process.on('exit', () => { for (const dir of cleanups) fs.rmSync(dir, { recursive: true, force: true }); });
|
||||||
|
|
||||||
function runScenario({ candInitial, candAfterUpdate, candAfterNodesource, preexistingNodesourceList }) {
|
function runScenario({ candInitial, candAfterUpdate, candAfterNodesource, preexistingNodesourceList, releaseStatus }) {
|
||||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'stoke-apt-test-'));
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'stoke-apt-test-'));
|
||||||
cleanups.push(root);
|
cleanups.push(root);
|
||||||
const bin = path.join(root, 'bin');
|
const bin = path.join(root, 'bin');
|
||||||
|
|
@ -39,7 +40,14 @@ function runScenario({ candInitial, candAfterUpdate, candAfterNodesource, preexi
|
||||||
// Force the non-root path so every mutation goes through the sudo stub.
|
// Force the non-root path so every mutation goes through the sudo stub.
|
||||||
stub('id', 'echo 1000');
|
stub('id', 'echo 1000');
|
||||||
stub('sudo', 'exec "$@"');
|
stub('sudo', 'exec "$@"');
|
||||||
stub('curl', 'echo "FAKE-KEY"');
|
// Registry Release-file probes (URLs under /dists/) answer with the
|
||||||
|
// scenario's HTTP status; everything else is a key fetch.
|
||||||
|
stub('curl', [
|
||||||
|
'for a in "$@"; do',
|
||||||
|
' case "$a" in */dists/*) echo "${RELEASE_STATUS:-200}"; exit 0;; esac',
|
||||||
|
'done',
|
||||||
|
'echo "FAKE-KEY"',
|
||||||
|
].join('\n'));
|
||||||
stub('stoke', 'echo 1.2.0');
|
stub('stoke', 'echo 1.2.0');
|
||||||
stub('apt-cache', [
|
stub('apt-cache', [
|
||||||
'cand="$(cat "$STATE_DIR/candidate")"',
|
'cand="$(cat "$STATE_DIR/candidate")"',
|
||||||
|
|
@ -73,6 +81,7 @@ function runScenario({ candInitial, candAfterUpdate, candAfterNodesource, preexi
|
||||||
STATE_DIR: state,
|
STATE_DIR: state,
|
||||||
CAND_AFTER_UPDATE: candAfterUpdate || '',
|
CAND_AFTER_UPDATE: candAfterUpdate || '',
|
||||||
CAND_AFTER_NODESOURCE: candAfterNodesource || '',
|
CAND_AFTER_NODESOURCE: candAfterNodesource || '',
|
||||||
|
RELEASE_STATUS: releaseStatus || '',
|
||||||
LC_ALL: 'es_ES.UTF-8', // localized environment; the script must force C
|
LC_ALL: 'es_ES.UTF-8', // localized environment; the script must force C
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -147,3 +156,18 @@ test('pre-existing user-managed nodesource.list is never overwritten', () => {
|
||||||
assert.equal(s.nodesourceList, marker);
|
assert.equal(s.nodesourceList, marker);
|
||||||
assert.doesNotMatch(s.aptGetLog, /install -y stoke/);
|
assert.doesNotMatch(s.aptGetLog, /install -y stoke/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('registry Release file 404s: fails fast with a clear message before apt runs', () => {
|
||||||
|
const s = runScenario({ candInitial: '22.23.1-1nodesource1', releaseStatus: '404' });
|
||||||
|
assert.notEqual(s.res.status, 0);
|
||||||
|
assert.match(s.res.stderr, /no stoke package has been published/);
|
||||||
|
assert.match(s.res.stderr, /npm/);
|
||||||
|
assert.match(s.res.stderr, /dists\/stable\/Release returned 404/);
|
||||||
|
assert.equal(s.aptGetLog, '', 'must abort before any apt-get invocation');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('registry Release file present: proceeds with the install', () => {
|
||||||
|
const s = runScenario({ candInitial: '22.23.1-1nodesource1', releaseStatus: '200' });
|
||||||
|
assert.equal(s.res.status, 0, s.res.stderr);
|
||||||
|
assert.match(s.aptGetLog, /install -y stoke/);
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue