Moves the stateless helpers of the image subsystem into internal/daemon/imagemgr: paths.go — path validators (ValidateRegisterPaths, ValidatePromotePaths), artifact staging (StageBootArtifacts, StageOptionalArtifactPath), metadata (BuildMetadataPackages, WritePackagesMetadata). build.go — ResizeRootfs, WriteBuildLog, and the full guest provisioning script generator (BuildProvisionScript, BuildModulesCommand and all private script-append helpers) along with the mise/tmux/opencode version constants. The orchestrator methods (BuildImage, RegisterImage, PromoteImage, DeleteImage, runImageBuildNative) stay on *Daemon: they still touch d.store, d.imageOpsMu, d.beginOperation, capability hooks, and fcproc-wrapped Daemon helpers — extracting them needs prerequisite phases (operation protocol, workdisk helpers, tap pool). This commit is strictly the pure-helper extraction that can land cleanly today. imagebuild.go shrinks from 453 -> 225 LOC (half gone). images.go shrinks from 450 -> 374 LOC. imagebuild_test.go updated to call the exported imagemgr.BuildProvisionScript. Zero behavior change; all tests green. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
67 lines
3.5 KiB
Go
67 lines
3.5 KiB
Go
package daemon
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"banger/internal/daemon/imagemgr"
|
|
)
|
|
|
|
func TestBuildProvisionScriptInstallsDefaultTools(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
script := imagemgr.BuildProvisionScript("devbox", "1.1.1.1", "ssh-ed25519 AAAATESTKEY banger", []string{"git", "curl"}, false)
|
|
for _, snippet := range []string{
|
|
"mkdir -p /root/.ssh",
|
|
"cat > /root/.ssh/authorized_keys <<'EOF'",
|
|
"ssh-ed25519 AAAATESTKEY banger",
|
|
"cat > /usr/local/libexec/banger-network-bootstrap <<'EOF'",
|
|
"ip addr replace \"$guest_ip/$prefix\" dev \"$iface\"",
|
|
"cat > /etc/systemd/system/banger-network.service <<'EOF'",
|
|
"systemctl enable --now banger-network.service || true",
|
|
"curl -fsSL https://mise.run | MISE_INSTALL_PATH='/usr/local/bin/mise' MISE_VERSION='v2025.12.0' sh",
|
|
"'/usr/local/bin/mise' use -g 'node@22'",
|
|
"'/usr/local/bin/mise' use -g 'github:anomalyco/opencode'",
|
|
"'/usr/local/bin/mise' use -g 'npm:@anthropic-ai/claude-code'",
|
|
"'/usr/local/bin/mise' use -g 'npm:@mariozechner/pi-coding-agent'",
|
|
"'/usr/local/bin/mise' reshim",
|
|
"if [[ ! -e '/root/.local/share/mise/shims/node' ]]; then echo 'node shim not found after mise install' >&2; exit 1; fi",
|
|
"if [[ ! -e '/root/.local/share/mise/shims/npm' ]]; then echo 'npm shim not found after mise install' >&2; exit 1; fi",
|
|
"if [[ ! -e '/root/.local/share/mise/shims/opencode' ]]; then echo 'opencode shim not found after mise install' >&2; exit 1; fi",
|
|
"if [[ ! -e '/root/.local/share/mise/shims/claude' ]]; then echo 'claude shim not found after mise install' >&2; exit 1; fi",
|
|
"if [[ ! -e '/root/.local/share/mise/shims/pi' ]]; then echo 'pi shim not found after mise install' >&2; exit 1; fi",
|
|
"ln -snf '/root/.local/share/mise/shims/node' '/usr/local/bin/node'",
|
|
"ln -snf '/root/.local/share/mise/shims/npm' '/usr/local/bin/npm'",
|
|
"ln -snf '/root/.local/share/mise/shims/opencode' '/usr/local/bin/opencode'",
|
|
"ln -snf '/root/.local/share/mise/shims/claude' '/usr/local/bin/claude'",
|
|
"ln -snf '/root/.local/share/mise/shims/pi' '/usr/local/bin/pi'",
|
|
"cat > /etc/profile.d/mise.sh <<'EOF'",
|
|
"if [ -n \"${BASH_VERSION:-}\" ] && [ -x '/usr/local/bin/mise' ]; then",
|
|
`eval "$(/usr/local/bin/mise activate bash)"`,
|
|
`if ! grep -Fqx 'eval "$(/usr/local/bin/mise activate bash)"' '/etc/bash.bashrc'; then`,
|
|
"cat > /etc/systemd/system/banger-opencode.service <<'EOF'",
|
|
"RequiresMountsFor=/root",
|
|
"ExecStart=/usr/local/bin/opencode serve --hostname 0.0.0.0 --port 4096",
|
|
"systemctl enable --now banger-opencode.service || true",
|
|
`git clone --depth 1 'https://github.com/tmux-plugins/tpm' "$TMUX_PLUGIN_DIR/tpm"`,
|
|
`git clone --depth 1 'https://github.com/tmux-plugins/tmux-resurrect' "$TMUX_PLUGIN_DIR/tmux-resurrect"`,
|
|
`git clone --depth 1 'https://github.com/tmux-plugins/tmux-continuum' "$TMUX_PLUGIN_DIR/tmux-continuum"`,
|
|
"# >>> banger tmux plugins >>>",
|
|
"set -g @plugin 'tmux-plugins/tmux-resurrect'",
|
|
"set -g @plugin 'tmux-plugins/tmux-continuum'",
|
|
"set -g @continuum-save-interval '15'",
|
|
"set -g @continuum-restore 'off'",
|
|
"set -g @resurrect-dir '/root/.tmux/resurrect'",
|
|
"run '~/.tmux/plugins/tpm/tpm'",
|
|
"cat > /etc/modules-load.d/banger-vsock.conf <<'EOF'",
|
|
"vmw_vsock_virtio_transport",
|
|
"cat > /etc/systemd/system/banger-vsock-agent.service <<'EOF'",
|
|
"ExecStart=/usr/local/bin/banger-vsock-agent",
|
|
"systemctl enable --now banger-vsock-agent.service || true",
|
|
"rm -f /root/get-docker /root/get-docker.sh /tmp/get-docker /tmp/get-docker.sh",
|
|
} {
|
|
if !strings.Contains(script, snippet) {
|
|
t.Fatalf("BuildProvisionScript missing snippet %q\nscript:\n%s", snippet, script)
|
|
}
|
|
}
|
|
}
|