Gate guest/boot SSH bring-up behind a nosshd build tag (opt-out)#86
Merged
Conversation
Split guest/boot/boot.go so the SSH-specific portion lives in two build-tag-gated files: guest/boot/ssh_enabled.go //go:build linux && !nosshd guest/boot/ssh_disabled.go //go:build linux && nosshd The default build keeps SSH on — current behavior is preserved and no consumer changes are required. Pass -tags=nosshd at build time to swap in the stub, which strips golang.org/x/crypto/ssh and guest/sshd from the link-time graph entirely. Semantics: - Default build (no tag): SSH compiled in, runtime behavior identical to before this change. - -tags=nosshd: SSH stripped. Callers MUST opt out at runtime via WithoutSSH; otherwise boot.Run returns the new sentinel ErrSSHNotBuilt and fails loud rather than silently boot without SSH. The orchestrator in boot.go no longer imports golang.org/x/crypto/ssh or guest/sshd directly. It calls a single bringUpSSH(logger, cfg, envVars) provided by whichever of the two gated files is compiled in. ParseAuthorizedKeys moves into ssh_enabled.go (its return type references ssh.PublicKey). Tests split by the same tag: - boot_test.go (both builds): option / config tests with no SSH types. - ssh_enabled_test.go (//go:build !nosshd): ParseAuthorizedKeys tests plus the generateTestKey helper that depends on x/crypto/ssh. - ssh_disabled_test.go (//go:build nosshd): verifies the stub's two documented behaviors — no-op when WithoutSSH is set, ErrSSHNotBuilt when it is not. Taskfile: the test, test-nocgo, and build-nocgo targets now run both the default and -tags=nosshd variants so CI exercises both code paths. The host-side microvm.WithoutSSH doc and the guest/boot package doc both mention ErrSSHNotBuilt so callers know what to expect when they forget to either drop the tag or set WithoutSSH. Verification: go list -deps ./guest/boot/ -> includes crypto/ssh go list -tags=nosshd -deps ./guest/boot/ -> no crypto/ssh Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
910724e to
c80ca7a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Splits
guest/bootso the SSH-specific code lives behind a//go:build nosshdopt-out tag. The default build keeps SSH on(current behavior, no consumer changes required); passing
-tags=nosshdswaps in a stub that dropsgolang.org/x/crypto/sshand
guest/sshdfrom the link-time graph.This is the link-time follow-up to #85 (WP-3.1 vsock + runtime
WithoutSSH). That PR gave callers a runtime knob to skip the SSHlistener; this one lets opt-out callers also strip the SSH code from
the binary at build time.
Why opt-out (not opt-in)
The first revision of this PR made SSH opt-in via
-tags=sshd,which would have required brood-box to update its build before being
able to bump go-microvm. Reviewer feedback (rightly) flagged that as
gratuitously disruptive — there's no reason to flip the default for
the existing consumer. Inverted to opt-out: brood-box needs no
changes, and bbox-k8s adds
-tags=nosshdto itsbbox-agentbuildwhen it wants the link-time elimination.
What's in the PR (one commit)
guest/boot/boot.gono longer importsgolang.org/x/crypto/sshorguest/sshd. The orchestrator now calls a singlebringUpSSH(logger, cfg, envVars)provided by one of two new files.guest/boot/ssh_enabled.go(//go:build linux && !nosshd) — thereal impl. Owns
ParseAuthorizedKeys, host-key load, listener start.This is what the default build links.
guest/boot/ssh_disabled.go(//go:build linux && nosshd) — stub.No-op when
cfg.disableSSHis true; returns the new sentinelErrSSHNotBuiltwhen it is false (loud-fail on misconfig).boot_test.go— option/config tests (default + nosshd, no SSH types).ssh_enabled_test.go(!nosshd) —ParseAuthorizedKeys+ thegenerateTestKeyhelper that depends onx/crypto/ssh.ssh_disabled_test.go(nosshd) — verifies both stub paths(no-op vs
ErrSSHNotBuilt).Taskfile.yaml—test,test-nocgo, andbuild-nocgonow runboth the default and
-tags=nosshdvariants so CI exercises bothcode paths.
microvm.WithoutSSHdoc and theguest/bootpackage docboth mention
ErrSSHNotBuilt.Verification
A small
boot.Run-importing test binary built two ways:crypto/ssh+guest/sshdsymbols (go tool nm)-tags=nosshdConsumer impact
cmd/bbox-initbuildcontinues to work without any tag.
cmd/bbox-agentalreadycalls
boot.WithoutSSH()). After bumping to the release containingthis change, add
-tags=nosshdto thebbox-agentbuild to actuallystrip the SSH code from the binary. Without that tag, the binary
works correctly (
WithoutSSHstill suppresses the listener atruntime) but still links the SSH code — same as today.
Test plan
task fmt— cleantask lint— 0 issuestask test-nocgo— all packages pass under both default and-tags=nosshdgo list -depsconfirmscrypto/sshpresent by default,absent with
-tags=nosshdgo tool nm: 0 SSH symbols with-tags=nosshd,518 in the default build
🤖 Generated with Claude Code