diff --git a/AGENTS.md b/AGENTS.md index 036e48c..b81aaec 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,7 +36,7 @@ - Manual verification for VM lifecycle changes: `./banger vm create`, confirm SSH access, then stop/delete the VM. - For host-integration changes, run `./banger doctor` as a quick readiness check before the live VM smoke. - Rebuilt images now include `mise`, `opencode`, `tmux-resurrect`/`tmux-continuum` defaults for `root`, and the `banger-vsock-agent` service used by the SSH reminder and guest health-check path; if you change guest provisioning, document whether users need to rebuild `./runtime/rootfs-docker.ext4` or another base image to pick it up. -- The experimental Void rootfs path now includes the repo's basic dev baseline plus Docker and Compose, alongside boot, SSH, the vsock HTTP health agent, a `bash` root shell while leaving `/bin/sh` alone, and the `/root` work-seed. Keep further baked-in tooling deliberate and user-driven. +- The experimental Void rootfs path now includes the repo's basic dev baseline plus Docker and Compose, alongside boot, SSH, the vsock HTTP health agent, pinned `mise` plus `opencode` for `root`, a `bash` root shell while leaving `/bin/sh` alone, and the `/root` work-seed. Keep further baked-in tooling deliberate and user-driven. - Rebuilt images also emit a `work-seed.ext4` sidecar used to speed up future VM creates. If you touch `/root` provisioning, verify both the rootfs and the work-seed output. - The daemon may keep idle TAP devices in a pool for faster creates. Smoke tests should treat `tap-pool-*` devices as reusable capacity, not cleanup leaks. - If you add a new operational workflow, document how to exercise it in `README.md`. diff --git a/README.md b/README.md index dc2fd32..e4a33de 100644 --- a/README.md +++ b/README.md @@ -325,6 +325,8 @@ This path is intentionally local-only and does not change the default Debian image flow. It reuses the current runtime bundle kernel, initrd, and modules, but builds a lean `x86_64-glibc` Void userspace with: - `bash` installed for interactive/admin use +- pinned `mise` installed at `/usr/local/bin/mise`, activated for `root` bash shells +- `opencode` installed through `mise`, with `/usr/local/bin/opencode` available by default - `docker` plus `docker-compose` installed from Void packages - the `docker` runit service enabled, with Docker netfilter/forwarding kernel prep - `openssh` enabled under runit @@ -332,9 +334,7 @@ but builds a lean `x86_64-glibc` Void userspace with: - `root` normalized to `/bin/bash` while keeping `/bin/sh` as the distro's system shell - a generated `/root` work-seed for fast creates -It does not install the Debian-oriented extras from rebuilt default images: -- no `mise` -- no `opencode` +It still keeps some Debian-oriented extras out for now: - no tmux plugin defaults The builder fetches official static XBPS tools and packages from the Void diff --git a/make-rootfs-void.sh b/make-rootfs-void.sh index 0056313..fb21397 100755 --- a/make-rootfs-void.sh +++ b/make-rootfs-void.sh @@ -260,6 +260,11 @@ case "$-" in *) return ;; esac +if [ -z "${BANGER_MISE_ACTIVATED:-}" ] && [ -x '/usr/local/bin/mise' ]; then + export BANGER_MISE_ACTIVATED=1 + eval "$(/usr/local/bin/mise activate bash)" +fi + PS1='\u@\h:\w\$ ' EOF cat <<'EOF' | sudo tee "$bash_profile" >/dev/null @@ -280,6 +285,38 @@ EOF sudo chmod 0644 "$bashrc" "$bash_profile" "$profile_prompt" } +install_mise_and_opencode() { + local profile_mise="$ROOT_MOUNT/etc/profile.d/mise.sh" + + sudo mkdir -p "$ROOT_MOUNT/etc/profile.d" + if [[ -r /etc/resolv.conf ]]; then + sudo install -m 0644 /etc/resolv.conf "$ROOT_MOUNT/etc/resolv.conf" + fi + + sudo env \ + HOME=/root \ + PATH=/usr/local/bin:/usr/bin:/bin \ + chroot "$ROOT_MOUNT" /bin/bash -se <&2 + exit 1 +fi +ln -snf /root/.local/share/mise/shims/opencode /usr/local/bin/opencode +EOF + + cat <<'EOF' | sudo tee "$profile_mise" >/dev/null +if [ -n "${BASH_VERSION:-}" ] && [ -z "${BANGER_MISE_ACTIVATED:-}" ] && [ -x '/usr/local/bin/mise' ]; then + export BANGER_MISE_ACTIVATED=1 + eval "$(/usr/local/bin/mise activate bash)" +fi +EOF + sudo chmod 0644 "$profile_mise" +} + cleanup() { if [[ -n "${ROOT_MOUNT:-}" ]] && command -v mountpoint >/dev/null 2>&1 && mountpoint -q "$ROOT_MOUNT"; then sudo umount "$ROOT_MOUNT" || true @@ -313,6 +350,9 @@ OUT_ROOTFS="$RUNTIME_DIR/rootfs-void.ext4" SIZE_SPEC="2G" MIRROR="https://repo-default.voidlinux.org" ARCH="x86_64" +MISE_VERSION="v2025.12.0" +MISE_INSTALL_PATH="/usr/local/bin/mise" +OPENCODE_TOOL="github:anomalyco/opencode" MODULES_DIR="$(bundle_path default_modules_dir "$RUNTIME_DIR/wtf/root/lib/modules/6.8.0-94-generic")" VSOCK_AGENT="$(bundle_path vsock_agent_path "$RUNTIME_DIR/banger-vsock-agent")" if [[ "$VSOCK_AGENT" == "$RUNTIME_DIR/banger-vsock-agent" && ! -x "$VSOCK_AGENT" ]]; then @@ -474,6 +514,8 @@ configure_docker_bootstrap enable_docker_service normalize_root_shell configure_root_bash_prompt +log "installing mise and opencode" +install_mise_and_opencode sudo mkdir -p "$ROOT_MOUNT/root/.ssh" sudo touch "$ROOT_MOUNT/etc/fstab" "$ROOT_MOUNT/etc/hostname" sudo chroot "$ROOT_MOUNT" /usr/bin/ssh-keygen -A @@ -487,8 +529,13 @@ sudo rm -rf \ sudo rm -f \ "$ROOT_MOUNT/root/get-docker" \ "$ROOT_MOUNT/root/get-docker.sh" \ + "$ROOT_MOUNT/root/.cache/opencode" \ "$ROOT_MOUNT/tmp/get-docker" \ "$ROOT_MOUNT/tmp/get-docker.sh" +sudo rm -rf \ + "$ROOT_MOUNT/root/.cache/mise" \ + "$ROOT_MOUNT/root/.local/share/mise/downloads" \ + "$ROOT_MOUNT/root/.local/share/mise/tmp" sudo umount "$ROOT_MOUNT" diff --git a/verify.sh b/verify.sh index 4e5e652..8c0af2d 100755 --- a/verify.sh +++ b/verify.sh @@ -240,6 +240,11 @@ if ! wait_for_ssh "$GUEST_IP" "$BOOT_DEADLINE"; then fi ssh "${SSH_COMMON_ARGS[@]}" "root@${GUEST_IP}" "uname -a" >/dev/null +if [[ "$IMAGE_NAME" == "void-exp" ]]; then + log "asserting mise and opencode are available in the Void guest" + ssh "${SSH_COMMON_ARGS[@]}" "root@${GUEST_IP}" "command -v mise >/dev/null 2>&1 && command -v opencode >/dev/null 2>&1 && mise --version >/dev/null 2>&1 && opencode --version >/dev/null 2>&1" >/dev/null +fi + if (( NAT_ENABLED )); then log "asserting VM has outbound network access" ssh "${SSH_COMMON_ARGS[@]}" "root@${GUEST_IP}" "curl -fsS https://example.com >/dev/null" >/dev/null