33# Sourced by build_guest_image.sh — not meant to be run directly.
44# Expects: guest_common.sh already sourced, OUT_DIR / ARCH / ROOT_DIR set.
55
6- # ── Shared libraries for claude-code (via ldd) ───────────────────────────────
6+ # ── Shared libraries for claude-code (via ldd) ───────────────────────────
77
88install_claude_code_libs_linux () {
99 local bin=" ${CLAUDE_CODE_BIN:- } "
@@ -14,7 +14,7 @@ install_claude_code_libs_linux() {
1414 fi
1515}
1616
17- # ── Host binary installation ─────────────────────────────────────────────────
17+ # ── Host binary installation ─────────────────────────────────────────────
1818
1919install_host_binary () {
2020 local bin_name=" $1 "
@@ -65,14 +65,113 @@ install_host_binaries() {
6565 fi
6666}
6767
68- # ── Kernel modules (from host /lib/modules) ──────────────────────────────────
68+ # ── Kernel modules (from host or downloaded from Ubuntu package) ─────────
69+
70+ # Download kernel modules from Ubuntu package matching the target kernel.
71+ # Used in CI or when host kernel doesn't match the VM kernel.
72+ #
73+ # Env vars:
74+ # VOID_BOX_KMOD_VERSION — Target kernel version (e.g. "6.8.0-51")
75+ # VOID_BOX_KMOD_UPLOAD — Upload number (e.g. "52"), defaults to KERNEL_UPLOAD
76+ install_kernel_modules_from_deb () {
77+ local dest=" $1 "
78+ local kmod_version=" ${VOID_BOX_KMOD_VERSION:- ${KERNEL_VER:- } } "
79+ local kmod_upload=" ${VOID_BOX_KMOD_UPLOAD:- ${KERNEL_UPLOAD:- } } "
80+
81+ if [[ -z " $kmod_version " || -z " $kmod_upload " ]]; then
82+ echo " [void-box] WARNING: VOID_BOX_KMOD_VERSION not set — cannot download modules"
83+ return 1
84+ fi
85+
86+ local kmod_deb_version=" ${kmod_version} .${kmod_upload} "
87+ local deb_arch url_base
88+ case " $ARCH " in
89+ x86_64) deb_arch=" amd64" ; url_base=" https://archive.ubuntu.com/ubuntu/pool/main/l/linux" ;;
90+ aarch64) deb_arch=" arm64" ; url_base=" https://ports.ubuntu.com/pool/main/l/linux" ;;
91+ * ) echo " [void-box] ERROR: unsupported arch for module download: $ARCH " ; return 1 ;;
92+ esac
93+
94+ local deb_name=" linux-modules-${kmod_version} -generic_${kmod_deb_version} _${deb_arch} .deb"
95+ local kmod_url=" ${url_base} /${deb_name} "
96+ local tmp
97+ tmp=$( mktemp -d)
98+
99+ echo " [void-box] Downloading kernel modules (${kmod_version} -generic, ${deb_arch} )..."
100+ echo " [void-box] URL: ${kmod_url} "
101+ if ! curl -fsSL " $kmod_url " -o " $tmp /modules.deb" ; then
102+ echo " [void-box] WARNING: failed to download kernel modules"
103+ rm -rf " $tmp "
104+ return 1
105+ fi
106+
107+ (cd " $tmp " && ar x modules.deb)
108+
109+ local mod_paths=(
110+ " lib/modules/${kmod_version} -generic/kernel/drivers/virtio/virtio_mmio.ko"
111+ " lib/modules/${kmod_version} -generic/kernel/net/vmw_vsock/vsock.ko"
112+ " lib/modules/${kmod_version} -generic/kernel/net/vmw_vsock/vmw_vsock_virtio_transport_common.ko"
113+ " lib/modules/${kmod_version} -generic/kernel/net/vmw_vsock/vmw_vsock_virtio_transport.ko"
114+ " lib/modules/${kmod_version} -generic/kernel/net/core/failover.ko"
115+ " lib/modules/${kmod_version} -generic/kernel/drivers/net/net_failover.ko"
116+ " lib/modules/${kmod_version} -generic/kernel/drivers/net/virtio_net.ko"
117+ )
118+
119+ # Data tarball may be compressed as .zst, .xz, or .gz
120+ local data_tar
121+ data_tar=$( find " $tmp " -maxdepth 1 -name ' data.tar*' -print | head -1)
122+ if [[ -z " $data_tar " ]]; then
123+ echo " [void-box] WARNING: no data.tar found in modules package"
124+ rm -rf " $tmp "
125+ return 1
126+ fi
127+
128+ for mod_path in " ${mod_paths[@]} " ; do
129+ local mod_name
130+ mod_name=$( basename " $mod_path " )
131+ local found=false
132+ for suffix in " .zst" " .xz" " " ; do
133+ tar xf " $data_tar " -C " $tmp " " ./${mod_path}${suffix} " 2> /dev/null || continue
134+ if [[ -f " $tmp /${mod_path}${suffix} " ]]; then
135+ case " $suffix " in
136+ .zst) zstd -d " $tmp /${mod_path}${suffix} " -o " $dest /$mod_name " --force -q ;;
137+ .xz) xz -d " $tmp /${mod_path}${suffix} " -c > " $dest /$mod_name " ;;
138+ " " ) cp " $tmp /${mod_path} " " $dest /$mod_name " ;;
139+ esac
140+ echo " -> $mod_name (downloaded${suffix: +, $suffix } )"
141+ found=true
142+ break
143+ fi
144+ done
145+ if [[ " $found " == " false" ]]; then
146+ echo " WARNING: $mod_name not found in modules package"
147+ fi
148+ done
149+
150+ rm -rf " $tmp "
151+ }
69152
70153install_kernel_modules_linux () {
154+ local dest=" $OUT_DIR /lib/modules"
155+ mkdir -p " $dest "
156+
157+ # If VOID_BOX_MODULES_DIR is set, use pre-extracted modules.
158+ if [[ -n " ${VOID_BOX_MODULES_DIR:- } " && -d " $VOID_BOX_MODULES_DIR " ]]; then
159+ echo " [void-box] Installing kernel modules from VOID_BOX_MODULES_DIR=$VOID_BOX_MODULES_DIR "
160+ cp " $VOID_BOX_MODULES_DIR " /* .ko " $dest /" 2> /dev/null || true
161+ return
162+ fi
163+
164+ # If VOID_BOX_KMOD_VERSION is set, download modules for that kernel (CI / cross-build).
165+ if [[ -n " ${VOID_BOX_KMOD_VERSION:- } " ]]; then
166+ echo " [void-box] Target kernel differs from host — downloading matching modules..."
167+ install_kernel_modules_from_deb " $dest "
168+ return
169+ fi
170+
171+ # Default: copy from host /lib/modules (works when host kernel == VM kernel).
71172 local kver
72173 kver=$( uname -r)
73174 local moddir=" /lib/modules/$kver /kernel"
74- local dest=" $OUT_DIR /lib/modules"
75- mkdir -p " $dest "
76175
77176 _install_kmod () {
78177 local mod_base=" $1 "
0 commit comments