Skip to content

Commit 576322b

Browse files
ralyodioclaude
andauthored
root-w3bs-os: package it for w3bs.org/packages (version, pinned installer) (#203)
root-w3bs-os.sh gets ROOT_W3BS_OS_VERSION=0.1.0 and --version (w3bs tracks updates with it). install-root-w3bs-os.sh fetches the script from the tag root-w3bs-os-v<version> and checks it against the pinned sha256, so the signed w3bs release installs exactly what was reviewed; root installs to /usr/local/sbin, others to ~/.local/bin. A test keeps the installer's version and sha in step with the script. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 5176228 commit 576322b

3 files changed

Lines changed: 53 additions & 0 deletions

File tree

‎install-root-w3bs-os.sh‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/sh
2+
# Installs root-w3bs-os, the W3BS OS box setup and maintenance script (users, ssh, Caddy,
3+
# firewall, confinement), as the package profullstack.com/root-w3bs-os on w3bs.org/packages:
4+
#
5+
# w3bs install profullstack.com/root-w3bs-os # or: w3bs os setup
6+
#
7+
# The script is fetched from this release's git tag and must match the sha256 below, so
8+
# the signed release installs exactly what was reviewed. Re-run to update.
9+
set -eu
10+
VERSION=0.1.0
11+
SHA256=de06d5cf0fd62d8f9a9d867a1e2a4eb753601ad7eaa2600a5ad7cf8788e54a76
12+
URL="https://raw.githubusercontent.com/profullstack/cli-tools/root-w3bs-os-v$VERSION/root-w3bs-os.sh"
13+
fail() { printf 'root-w3bs-os: %s\n' "$*" >&2; exit 1; }
14+
command -v curl >/dev/null 2>&1 || fail 'curl is required'
15+
if [ "$(id -u)" = 0 ]; then bin=/usr/local/sbin; else bin=${HOME:?HOME must be set}/.local/bin; fi
16+
mkdir -p "$bin"
17+
tmp=$(mktemp "$bin/.root-w3bs-os.XXXXXX")
18+
trap 'rm -f "$tmp"' EXIT INT TERM
19+
curl -fsSL "$URL" -o "$tmp" || fail "could not download $URL"
20+
if command -v sha256sum >/dev/null 2>&1; then got=$(sha256sum "$tmp" | cut -d' ' -f1)
21+
else got=$(shasum -a 256 "$tmp" | cut -d' ' -f1); fi
22+
[ "$got" = "$SHA256" ] || fail "downloaded script does not match this installer (got $got)"
23+
chmod 0755 "$tmp" && mv "$tmp" "$bin/root-w3bs-os"
24+
trap - EXIT INT TERM
25+
printf 'root-w3bs-os %s installed in %s\n' "$VERSION" "$bin"
26+
printf 'Run it as root: doas %s/root-w3bs-os anthony --groups wheel (or: w3bs os setup)\n' "$bin"

‎root-w3bs-os.sh‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,13 @@ fi
184184

185185
set -uo pipefail
186186

187+
# The packaged release (w3bs install profullstack.com/root-w3bs-os). Bump with every
188+
# change that ships, and tag the commit root-w3bs-os-v<version>.
189+
ROOT_W3BS_OS_VERSION=0.1.0
190+
case "${1:-}" in
191+
--version|-V) printf 'root-w3bs-os %s\n' "$ROOT_W3BS_OS_VERSION"; exit 0 ;;
192+
esac
193+
187194
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)" || SCRIPT_DIR=""
188195

189196
# ------------------------------------------------------------------ config ---

‎test/root-w3bs-os.test.ts‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { execFileSync, spawnSync } from 'node:child_process';
2+
import { createHash } from 'node:crypto';
23
import { chmodSync, mkdtempSync, readFileSync, writeFileSync } from 'node:fs';
34
import { tmpdir } from 'node:os';
45
import { dirname, join, resolve } from 'node:path';
@@ -521,3 +522,22 @@ describe('the unprivileged subcommands', () => {
521522
expect(out).toContain('/mnt/sshfs.files.example.com/data');
522523
});
523524
});
525+
526+
describe('the w3bs package (profullstack.com/root-w3bs-os)', () => {
527+
it('pins the script it installs: same version, same sha256', () => {
528+
const installer = readFileSync(join(dirname(SCRIPT), 'install-root-w3bs-os.sh'), 'utf8');
529+
const version = /^ROOT_W3BS_OS_VERSION=(\S+)$/m.exec(SOURCE)?.[1];
530+
expect(version).toBeTruthy();
531+
expect(installer).toContain(`VERSION=${version}\n`);
532+
const sha = createHash('sha256').update(readFileSync(SCRIPT)).digest('hex');
533+
// Edit root-w3bs-os.sh => bump ROOT_W3BS_OS_VERSION, update the installer's
534+
// VERSION and SHA256, tag root-w3bs-os-v<version>, publish the release.
535+
expect(installer).toContain(`SHA256=${sha}\n`);
536+
});
537+
538+
it('answers --version without root', () => {
539+
expect(execFileSync('bash', [SCRIPT, '--version'], { encoding: 'utf8' }).trim()).toMatch(
540+
/^root-w3bs-os \d+\.\d+\.\d+$/,
541+
);
542+
});
543+
});

0 commit comments

Comments
 (0)