Uh oh!
There was an error while loading. Please reload this page.
feat(cli): tracebloc prepare-host wrapper (#1178, cli) - #394
Conversation
…0001 #1178) Adds `tracebloc prepare-host`: a thin, discoverable wrapper that re-runs the official installer's verified prepare-host step (curl … | bash -s -- prepare-host), exactly like `tracebloc upgrade` delegates to the installer rather than re-implementing privileged host prep in the CLI. Registered in root; copy catalog gains 11-prepare-host.golden + the strings flow into zz-all-strings. build/vet/ staticcheck/deadcode clean; catalog no-drift; gofmt clean. Pairs with the client installer prepare-host step (tracebloc/client#377). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 22, 2026
bugbot run |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…allowed (Bugbot #394) Without pipefail, `curl … | bash -s -- prepare-host` under `bash -c` exits 0 when curl fails (bash reads empty stdin), so the command reported success while prepare-host never ran. Prepend `set -o pipefail;` so curl's non-zero propagates and c.Run() surfaces the failure. Regression guard added. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 23, 2026
bugbot run |
divyasinghds
left a comment
There was a problem hiding this comment.
Approve. Thin wrapper delegating to the cosign-verified installer, keeping the privileged surface in one place. The 'set -o pipefail' fix is correct and essential (a failed curl would otherwise report success), with a guard test. Natural home for the --user affordance if you address the prepare-host targeting note I left on client#377.
Cancelling the context (Ctrl-C / parent shutdown) previously killed only the top-level `bash -c`, leaving the `curl` and the `bash -s` prepare-host child -- which performs privileged host prep -- running detached after the CLI had already reported failure and exited (Bugbot #394). Extract prepareHostCmd(ctx): set SysProcAttr.Setpgid so the pipeline gets its own process group, and a Cancel that group-signals (kill -PGID SIGINT) so the whole pipeline stops when the user aborts. Add a test asserting Setpgid + Cancel are wired. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 23, 2026
bugbot run |
Uh oh!
There was an error while loading. Please reload this page.
…on TTY) `curl | bash -s -- prepare-host` makes the inner bash read its *program* from the pipe, so the installer's stdin is no longer the terminal — any interactive prompt in prepare-host (e.g. which non-admin user gets runtime access) gets EOF (Bugbot #394, second finding). Switching to `bash <(curl …)` would fix stdin but reopen the FIRST #394 finding: process-substitution exit codes bypass pipefail, so a failed curl would silently run nothing. Instead download to a temp file under `set -e` (so a failed `curl -o` aborts) and run the file (stdin stays on the TTY). Best of both: fail-closed on download error AND interactive-capable. The manual-run hint shown on failure uses `bash <(curl …)` — the repo's recommended idiom — since a human re-running it keeps their own TTY. Add tests: fail-closed on download error (set -e + curl -o), and never pipe the script into bash. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 23, 2026
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
2 issues from previous reviews remain unresolved.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit e9a4f67. Configure here.
LukasWodka
commented
Jul 23, 2026
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
2 issues from previous reviews remain unresolved.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit e9a4f67. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
LukasWodka
commented
Jul 23, 2026
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
3 issues from previous reviews remain unresolved.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 7b599be. Configure here.
…nd build tags The process-group cancel added for Bugbot #394 used syscall.SysProcAttr.Setpgid and syscall.Kill(-pid, …), which are POSIX-only — the Windows build failed to compile (unknown field Setpgid; undefined syscall.Kill). Extract configureProcessGroup into build-tagged files: - prepare_host_unix.go (//go:build !windows): sets Setpgid + the group-killing Cancel (unchanged behavior on linux/darwin). - prepare_host_windows.go (//go:build windows): no-op — POSIX process groups don't exist there, and exec.CommandContext still kills the top-level process; prepare-host is a Linux host op regardless. Move the Setpgid assertion test into prepare_host_unix_test.go (also !windows-tagged) so `go test`/`go vet` compile on Windows too. Verified: `GOOS=windows go build/vet ./...` now pass for amd64 + arm64, and the native build/test/staticcheck stay green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 23, 2026
bugbot run |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…(Bugbot #394) The process-group approach was wrong for an interactive command and Bugbot flagged five follow-ups: - Setpgid put the installer in its own (background) process group while stdin was the TTY, so any prepare-host prompt got SIGTTIN and hung (High). - the SIGINT-only Cancel with no WaitDelay could hang Wait forever if a privileged child ignored the signal, re-opening the orphaned-work risk. - a user Ctrl-C was wrapped as "prepare-host didn't complete — retry" instead of a quiet interrupt. Drop Setpgid and the custom Cancel entirely: keep the installer in the CLI's foreground process group so prompts work and a terminal Ctrl-C signals the whole pipeline (bash + curl + child) at once. Add WaitDelay=5s so a programmatic cancel can't hang Wait. Treat ctx cancel as exitInterrupted (130), matching the other cancellable paths. This also removes all syscall usage, so the Windows build no longer needs the build-tagged split (files deleted). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 23, 2026
bugbot run |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…ion (Bugbot #394) - prepareHostManualHint duplicated the bootstrap idiom owned by installCmd (doctor.go), so a URL/idiom change could leave the prepare-host fallback stale. Build it from installCmd + " prepare-host" (same value, one source). - Interrupt detection only checked ctx.Err() after c.Run(); on a terminal Ctrl-C the child dies (bash exits 130) and Run can return before NotifyContext flips ctx.Err(), so an abort was mis-reported as a failed install. Add prepareHostInterrupted(ctx, err): interrupt if ctx cancelled OR the run exited 130 (128+SIGINT). Unit-tested (cancelled ctx, exit 130, exit 1). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 23, 2026
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 447cadc. Configure here.
…ss (Divya #377) prepare-host was cobra.NoArgs with no flag and no mention of TB_PREPARE_USER, so an admin had no discoverable way to name the researcher — the installer's docker-group grant (which reads TB_PREPARE_USER) was always skipped and the feature couldn't deliver Tier-0 access end-to-end. Add an optional positional arg: `tracebloc prepare-host <researcher-username>` (MaximumNArgs(1)). The username is validated (Linux-username shape) and passed to the installer via the TB_PREPARE_USER environment variable (not the command string, so it can't be shell-interpreted; the installer quotes it for usermod). Help text explains the arg and stresses it's the researcher, not the admin. Without it, prepare-host installs prereqs only and prints how to grant access. The client installer already grants ONLY TB_PREPARE_USER (never $SUDO_USER), so this closes the loop. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 23, 2026
bugbot run |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
divyasinghds
left a comment
There was a problem hiding this comment.
Approve. This now implements the researcher-username affordance I asked for on client#377, and does it securely:
prepare-host [researcher-username](MaximumNArgs(1)), passed to the installer via the ENVIRONMENT (TB_PREPARE_USER=<user>), not the command string — so it can't be shell-interpreted — and validated by a conservative regex that rejects shell metacharacters, spaces, empty, leading-/., and overlong input. Help text is explicit that the username is the researcher, not the admin.- Temp-file-not-pipe (
set -e; curl -o "$tmp"; bash "$tmp" prepare-host): fails closed on a download error AND keeps stdin on the TTY — important because prepare-host runs preflight_sudo, whosesudo -vpassword prompt would hang if stdin were the pipe. - Foreground process group (no SysProcAttr) with a clear rationale (a backgrounded interactive child gets SIGTTIN; Ctrl-C reaches the whole pipeline), positive WaitDelay, default-SIGKILL teardown.
- Interrupt detection handles the ctx.Err()-vs-exit-130 race so a Ctrl-C exits quietly (130) rather than as a scary failure.
Thorough test coverage (fail-closed, no-pipe, foreground-group, interrupt, username validation, arg count) + golden files updated. CI green. LGTM.
Resolves the develop conflict (prepare-host vs the merged `upgrade` command): - root.go: register both prepare-host and upgrade - copy_catalog_test.go / 00-home.golden: keep both commands; renumber the prepare-host catalog entry to 12-prepare-host.golden (11 is now upgrade) - regenerate goldens Fixes 3 Bugbot findings on prepare-host: 1. Ambient TB_PREPARE_USER not cleared (prepare_host.go): the no-username path left c.Env unset, so the child inherited any ambient TB_PREPARE_USER and could grant access the command says it won't. New prepareHostEnv() strips it and sets it only when a username is given. 2. Failure hint dropped the grant (prepare_host.go): the manual retry hint had no TB_PREPARE_USER, so copy-pasting it after `prepare-host <user>` failed silently did less than asked. prepareHostManualHint(user) now prefixes TB_PREPARE_USER=<user>. 3. Installer URL duplicated (doctor.go/prepare_host.go): extracted a shared installerURL const so the automated download can't drift from the hint. Adds regression tests for the env stripping and the username-carrying hint. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
shujaatTracebloc
commented
Jul 23, 2026
Pushed
Conflict resolution: registered both |
Uh oh!
There was an error while loading. Please reload this page.
prepare-host shells out to bash/curl/mktemp and readies a Linux server / HPC login node (container runtime, docker group) — a Unix-only concept. On Windows it appeared in --help then failed with a cryptic missing-bash error and a Unix-only retry hint. It now stops early with a clear explanation (a no-op-with-message), mirroring upgrade's Windows handling. Adds a regression test for the OS guard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
shujaatTracebloc
commented
Jul 23, 2026
Pushed |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4d9833f. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Resolves the develop conflict (branched before the upgrade #390 and prepare-host #394 commands merged): copy_catalog_test.go auto-merged to keep all three commands' catalog entries; regenerated goldens (zz-all-strings + 00-home + 08-client) so the harvested strings and command lists include upgrade, prepare-host, and the seal-check screens together. No code conflicts; the seal logic is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… not failed (backend#2255) (#586) helm.Upgrade wrapped every Runner error as "helm upgrade failed", so a Ctrl-C / cancelled context mid-`helm upgrade` — after helm may have already applied the values — was reported as a flat failure with no progress, telling the user nothing changed when the change could be live. - helm.Upgrade now distinguishes an interrupt (ctx cancelled, or the helm child exiting 130 before NotifyContext flips ctx.Err()) from a genuine failure, returning the new helm.ErrInterrupted sentinel plus the resolved Plan so the caller can surface what was in flight. Mirrors the cli package's installerRunInterrupted (Bugbot #394/#397). - resources set shows a live wait line during the apply (progress), and on an interrupt mid-upgrade reports "may already have applied — re-run to confirm" (via launcher()) and exits 130, never "helm upgrade failed". A Ctrl-C before the upgrade runs (probe / repo add-update) also exits a quiet 130 via installerRunInterrupted, but without the "may have applied" note. - Tests for both halves at the helm and cli layers: cancelled-context and exit-130 interrupts, a pre-upgrade interrupt, a genuine failure, and the progress wait-line on a real apply. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

What (#1178, cli half)
Adds
tracebloc prepare-host— a discoverable command for the one-time administrator step that readies a shared / HPC host so a non-admin user can then install tracebloc with no root.It's a thin wrapper: it re-runs the official installer's verified
prepare-hoststep (curl -fsSL https://tracebloc.io/i.sh | bash -s -- prepare-host), exactly astracebloc upgradedelegates to the installer rather than re-implementing any privileged host prep in the CLI — the privileged surface stays in one cosign-verified place.Tests
root; copy catalog gains11-prepare-host.goldenand the strings flow intozz-all-strings.golden.go build/go vet/staticcheck (all,-ST1005)/ deadcode gate clean; catalog no-drift; gofmt clean.Pairing
The installer side (the actual
prepare-hoststep this wraps) is tracebloc/client#377. This command is only useful once that lands + ships ini.sh; until then it wraps a step the released installer doesn't yet have (like the B2 cli half, they release together).Part of the least-privilege install epic — tracebloc/backend#1168, ticket tracebloc/backend#1178 (cli half).
🤖 Generated with Claude Code
Note
Medium Risk
The command runs privileged installer work via bash/curl as root on Unix hosts; env/username handling is carefully guarded but misconfiguration could still affect host prep. Depends on the installer shipping the prepare-host subcommand.
Overview
Adds
tracebloc prepare-hostas a top-level command for the one-time admin step on shared/HPC hosts so a non-admin can install tracebloc without root. It delegates to the official installer'sprepare-hoststep (same pattern asupgrade), with an optional researcher username to passTB_PREPARE_USERfor docker-group access.Installer execution downloads
i.shto a temp file (set -e,curl -o) instead ofcurl | bash, preserving TTY stdin for interactive prompts and failing closed on download errors. Child env strips ambientTB_PREPARE_USERunless a username arg is given; usernames are validated before use. Ctrl-C maps to exit 130; failures surface a manual retry hint that preservesTB_PREPARE_USERwhen applicable. Windows gets an explanatory no-op instead of invoking bash.Refactor:
installerURLis centralized indoctor.gosoinstallCmdand the prepare-host download share one URL.Copy catalog gains
12-prepare-host.golden; home help lists the new command; unit tests cover the shell script shape, env handling, and OS guard.Reviewed by Cursor Bugbot for commit 4d9833f. Bugbot is set up for automated code reviews on this repo. Configure here.