Agent host: SilverBullet boots into accounts and the vault, not a bare space
SB_NAME alone put SilverBullet 2.11 in single-space mode: no accounts, no setup wizard, and its /data folder served instead of the vault. The compose file sets only PUID and PGID now, a test holds it to that, and the host check fails on a single-space boot. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
This commit is contained in:
1 parent
e287eea2d3
commit
1d33d50907
3 files changed
+24
-2
No files matched your search
@@ -10,6 +10,11 @@ bad() { echo "FAIL: $1"; fail=1; }
|
||||
cd "$stack" || { echo "FAIL: no $stack"; exit 1; }
|
||||
[ "$(sudo docker compose ps --status running -q | wc -l)" -ge 1 ] \
|
||||
&& ok "SilverBullet is running" || bad "SilverBullet isn't running"
|
||||
if sudo docker compose logs --no-color silverbullet 2>/dev/null | grep -q 'boot mode: single-space'; then
|
||||
bad "it booted a single space with no accounts (an SB_* setting?)"
|
||||
else
|
||||
ok "it keeps accounts (no single-space boot)"
|
||||
fi
|
||||
code=$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3000/)
|
||||
case $code in 2??|3??) ok "it answers locally ($code)" ;; *) bad "it answers $code" ;; esac
|
||||
probe=.nisse-probe-$$
|
||||
|
||||
@@ -8,9 +8,10 @@ services:
|
||||
image: ghcr.io/silverbulletmd/silverbullet:2.11.1-slim
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
# Only these. Any SB_* setting (even SB_NAME) boots a single space with
|
||||
# no accounts, serving /data instead of the vault.
|
||||
PUID: "1000"
|
||||
PGID: "1000"
|
||||
SB_NAME: Nisse vault
|
||||
ports:
|
||||
# IPv4 only; setup.sh's firewall lets only the operator's Caddy in.
|
||||
- "0.0.0.0:3000:3000"
|
||||
|
||||
@@ -67,6 +67,12 @@ def test_no_secrets_in_the_compose_file() -> None:
|
||||
assert not [k for k in environment if re.search(r"USER|TOKEN|PASS|SECRET|KEY", k)]
|
||||
|
||||
|
||||
def test_it_boots_into_accounts_and_the_vault_not_a_bare_space() -> None:
|
||||
# SB_NAME alone switched 2.11 to single-space mode: no accounts, no setup
|
||||
# wizard, and /data served in place of the vault.
|
||||
assert set(silverbullet()["environment"]) == {"PUID", "PGID"}
|
||||
|
||||
|
||||
def test_its_port_caddys_and_the_firewalls_agree() -> None:
|
||||
port = setting("SB_PORT")
|
||||
assert silverbullet()["ports"] == [f"0.0.0.0:{port}:3000"] # IPv4 only
|
||||
@@ -120,7 +126,9 @@ def test_the_firewall_lets_only_one_address_in_and_replaces_its_own_rule() -> No
|
||||
SCRIPT = HOST.parents[1] / "scripts" / "agent-host.sh"
|
||||
|
||||
|
||||
def _fake_host(tmp_path: Path, *, memory_writable: bool) -> dict[str, str]:
|
||||
def _fake_host(
|
||||
tmp_path: Path, *, memory_writable: bool, boot: str = "multi-space"
|
||||
) -> dict[str, str]:
|
||||
"""Commands standing in for the host's: ssh runs the command here, sudo
|
||||
just runs it, and docker reads all of stdin, as docker compose exec does."""
|
||||
bin_ = tmp_path / "bin"
|
||||
@@ -134,6 +142,7 @@ def _fake_host(tmp_path: Path, *, memory_writable: bool) -> dict[str, str]:
|
||||
"cat > /dev/null\n"
|
||||
'case "$*" in\n'
|
||||
' *"ps --status running"*) echo abc123 ;;\n'
|
||||
f' *" logs "*) echo "boot mode: {boot}" ;;\n'
|
||||
f' *"/vault/memory/"*) exit {0 if memory_writable else 1} ;;\n'
|
||||
"esac"
|
||||
),
|
||||
@@ -167,6 +176,7 @@ def test_the_check_runs_every_step_even_though_docker_reads_stdin(
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
assert result.stdout.splitlines() == [
|
||||
"ok: SilverBullet is running",
|
||||
"ok: it keeps accounts (no single-space boot)",
|
||||
"ok: it answers locally (200)",
|
||||
"ok: the operator's folders are writable",
|
||||
"ok: memory/ is read-only to SilverBullet",
|
||||
@@ -184,3 +194,9 @@ def test_a_writable_memory_folder_fails_the_check(tmp_path: Path) -> None:
|
||||
)
|
||||
assert "ok: the firewall rule is in place" in result.stdout # still checked
|
||||
assert "all checks passed" not in result.stdout
|
||||
|
||||
|
||||
def test_a_single_space_boot_fails_the_check(tmp_path: Path) -> None:
|
||||
result = _check(_fake_host(tmp_path, memory_writable=False, boot="single-space"))
|
||||
assert result.returncode == 1
|
||||
assert "FAIL: it booted a single space with no accounts" in result.stdout
|
||||
Reference in new issue
Block a user