summaryrefslogtreecommitdiffstats
path: root/recipes-containers/vcontainer/vcontainer-initramfs-create.inc
diff options
context:
space:
mode:
authorBruce Ashfield <bruce.ashfield@gmail.com>2026-01-06 20:41:53 +0000
committerBruce Ashfield <bruce.ashfield@gmail.com>2026-02-09 03:32:52 +0000
commitc32db56912b06a89490fda5d554468dbc12a39a2 (patch)
tree8084bd9c1b56b13354cddf99b39356967f0142ea /recipes-containers/vcontainer/vcontainer-initramfs-create.inc
parent4baa3503321fb2ad9edfebc5e89bcd37115e626e (diff)
downloadmeta-virtualization-c32db56912b06a89490fda5d554468dbc12a39a2.tar.gz
vcontainer: add shared infrastructure and runner
Add core vcontainer infrastructure shared by vdkr and vpdmn: Scripts: - vrunner.sh: QEMU runner supporting both Docker and Podman runtimes - vcontainer-common.sh: Shared CLI functions and command handling - vcontainer-init-common.sh: Shared init script functions for QEMU guest - vdkr-preinit.sh: Initramfs preinit for switch_root to squashfs overlay Recipes: - vcontainer-native: Installs vrunner.sh and shared scripts - vcontainer-initramfs-create.inc: Shared initramfs build logic Features: - Docker/Podman-compatible commands: images, pull, load, save, run, exec - Memory resident mode for fast command execution - KVM acceleration when host matches target - Interactive mode with volume mounts - Squashfs rootfs with tmpfs overlay Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
Diffstat (limited to 'recipes-containers/vcontainer/vcontainer-initramfs-create.inc')
-rw-r--r--recipes-containers/vcontainer/vcontainer-initramfs-create.inc237
1 files changed, 237 insertions, 0 deletions
diff --git a/recipes-containers/vcontainer/vcontainer-initramfs-create.inc b/recipes-containers/vcontainer/vcontainer-initramfs-create.inc
new file mode 100644
index 00000000..a0930a68
--- /dev/null
+++ b/recipes-containers/vcontainer/vcontainer-initramfs-create.inc
@@ -0,0 +1,237 @@
1# SPDX-FileCopyrightText: Copyright (C) 2025 Bruce Ashfield
2#
3# SPDX-License-Identifier: MIT
4#
5# vcontainer-initramfs-create.inc
6# ===========================================================================
7# Shared code for building QEMU boot blobs (vdkr/vpdmn)
8# ===========================================================================
9#
10# This .inc file contains common code for building boot blobs.
11# Individual recipes (vdkr-initramfs-create, vpdmn-initramfs-create)
12# set VCONTAINER_RUNTIME and include this file.
13#
14# Required variables from including recipe:
15# VCONTAINER_RUNTIME - "vdkr" or "vpdmn"
16#
17# Boot flow:
18# QEMU boots kernel + tiny initramfs
19# -> preinit mounts rootfs.img from /dev/vda
20# -> switch_root into rootfs.img
21# -> ${VCONTAINER_RUNTIME}-init.sh runs
22#
23# ===========================================================================
24
25HOMEPAGE = "https://git.yoctoproject.org/meta-virtualization/"
26LICENSE = "MIT"
27LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
28
29inherit deploy
30
31# Not built by default - user must explicitly request via bitbake or vcontainer-native
32EXCLUDE_FROM_WORLD = "1"
33
34# Need squashfs-tools-native for unsquashfs to extract files from rootfs.img
35DEPENDS = "squashfs-tools-native"
36
37# Always rebuild - no sstate caching for this recipe
38# This ensures source file changes (like init scripts in the rootfs) are picked up
39SSTATE_SKIP_CREATION = "1"
40do_compile[nostamp] = "1"
41do_deploy[nostamp] = "1"
42
43# Only populate native sysroot, skip target sysroot to avoid libgcc conflicts
44INHIBIT_DEFAULT_DEPS = "1"
45
46# Dependencies:
47# 1. The multiconfig rootfs image from same vruntime-* multiconfig
48# 2. The kernel from main build (not multiconfig)
49#
50# Use regular depends for rootfs-image since both recipes are in the same multiconfig
51# Use mcdepends for kernel since it's from the main (default) config
52do_compile[depends] = "${VCONTAINER_RUNTIME}-rootfs-image:do_image_complete"
53do_compile[mcdepends] = "mc:${VCONTAINER_MULTICONFIG}::virtual/kernel:do_deploy"
54
55# Preinit is shared between vdkr and vpdmn
56SRC_URI = "file://vdkr-preinit.sh"
57
58S = "${UNPACKDIR}"
59B = "${WORKDIR}/build"
60
61def get_kernel_image_name(d):
62 arch = d.getVar('TARGET_ARCH')
63 if arch == 'aarch64':
64 return 'Image'
65 elif arch in ['x86_64', 'i686', 'i586']:
66 return 'bzImage'
67 elif arch == 'arm':
68 return 'zImage'
69 return 'Image'
70
71def get_multiconfig_name(d):
72 arch = d.getVar('TARGET_ARCH')
73 if arch == 'aarch64':
74 return 'vruntime-aarch64'
75 elif arch in ['x86_64', 'i686', 'i586']:
76 return 'vruntime-x86-64'
77 return 'vruntime-aarch64'
78
79def get_blob_arch(d):
80 """Map TARGET_ARCH to vrunner blob architecture (aarch64 or x86_64)"""
81 arch = d.getVar('TARGET_ARCH')
82 if arch == 'aarch64':
83 return 'aarch64'
84 elif arch in ['x86_64', 'i686', 'i586']:
85 return 'x86_64'
86 return 'aarch64'
87
88KERNEL_IMAGETYPE_INITRAMFS = "${@get_kernel_image_name(d)}"
89VCONTAINER_MULTICONFIG = "${@get_multiconfig_name(d)}"
90BLOB_ARCH = "${@get_blob_arch(d)}"
91
92# Path to the multiconfig build output
93VCONTAINER_MC_DEPLOY = "${TOPDIR}/tmp-${VCONTAINER_MULTICONFIG}/deploy/images/${MACHINE}"
94
95do_compile() {
96 mkdir -p ${B}
97
98 # =========================================================================
99 # PART 1: BUILD TINY INITRAMFS (just for switch_root)
100 # =========================================================================
101 INITRAMFS_DIR="${B}/initramfs"
102 rm -rf ${INITRAMFS_DIR}
103 mkdir -p ${INITRAMFS_DIR}/bin
104 mkdir -p ${INITRAMFS_DIR}/proc
105 mkdir -p ${INITRAMFS_DIR}/sys
106 mkdir -p ${INITRAMFS_DIR}/dev
107 mkdir -p ${INITRAMFS_DIR}/mnt/root
108
109 bbnote "Building tiny initramfs for switch_root..."
110
111 # Extract busybox from the multiconfig rootfs image (squashfs)
112 MC_TMPDIR="${TOPDIR}/tmp-${VCONTAINER_MULTICONFIG}"
113 ROOTFS_SRC="${MC_TMPDIR}/deploy/images/${MACHINE}/${VCONTAINER_RUNTIME}-rootfs-image-${MACHINE}.rootfs.squashfs"
114
115 if [ ! -f "${ROOTFS_SRC}" ]; then
116 bbfatal "Rootfs image not found at ${ROOTFS_SRC}. Build it first with: bitbake mc:${VCONTAINER_MULTICONFIG}:${VCONTAINER_RUNTIME}-rootfs-image"
117 fi
118
119 # Extract busybox from rootfs using unsquashfs
120 # In usrmerge layouts, busybox is at usr/bin/busybox
121 BUSYBOX_PATH="usr/bin/busybox"
122 EXTRACT_DIR="${B}/squashfs-extract"
123
124 bbnote "Extracting busybox from $BUSYBOX_PATH"
125 # Try native sysroot first, fall back to system unsquashfs
126 UNSQUASHFS="${WORKDIR}/recipe-sysroot-native/usr/bin/unsquashfs"
127 if [ ! -x "$UNSQUASHFS" ]; then
128 UNSQUASHFS="/usr/bin/unsquashfs"
129 fi
130 if [ ! -x "$UNSQUASHFS" ]; then
131 bbfatal "unsquashfs not found in native sysroot or at /usr/bin/unsquashfs"
132 fi
133 bbnote "Using unsquashfs: $UNSQUASHFS"
134
135 rm -rf "${EXTRACT_DIR}"
136 $UNSQUASHFS -d "${EXTRACT_DIR}" "${ROOTFS_SRC}" "$BUSYBOX_PATH"
137
138 if [ ! -f "${EXTRACT_DIR}/${BUSYBOX_PATH}" ]; then
139 bbfatal "Failed to extract busybox from rootfs image"
140 fi
141 cp "${EXTRACT_DIR}/${BUSYBOX_PATH}" "${INITRAMFS_DIR}/bin/busybox"
142 chmod +x ${INITRAMFS_DIR}/bin/busybox
143
144 # Create minimal symlinks
145 cd ${INITRAMFS_DIR}/bin
146 for cmd in sh mount umount mkdir ls cat echo sleep switch_root reboot; do
147 ln -sf busybox $cmd 2>/dev/null || true
148 done
149 cd -
150
151 # Install preinit script as /init
152 cp ${S}/vdkr-preinit.sh ${INITRAMFS_DIR}/init
153 chmod +x ${INITRAMFS_DIR}/init
154
155 # Create tiny initramfs cpio
156 bbnote "Creating tiny initramfs cpio archive..."
157 cd ${INITRAMFS_DIR}
158 find . | cpio -o -H newc 2>/dev/null | gzip -9 > ${B}/initramfs.cpio.gz
159 cd -
160
161 INITRAMFS_SIZE=$(stat -c%s ${B}/initramfs.cpio.gz)
162 bbnote "Tiny initramfs created: ${INITRAMFS_SIZE} bytes ($(expr ${INITRAMFS_SIZE} / 1024)KB)"
163
164 # =========================================================================
165 # PART 2: COPY ROOTFS FROM MULTICONFIG BUILD
166 # =========================================================================
167 bbnote "Looking for multiconfig rootfs at: ${MC_TMPDIR}/deploy/images/${MACHINE}"
168
169 # ROOTFS_SRC already set above when extracting busybox
170 cp "${ROOTFS_SRC}" ${B}/rootfs.img
171 ROOTFS_SIZE=$(stat -c%s ${B}/rootfs.img)
172 bbnote "Rootfs image copied: ${ROOTFS_SIZE} bytes ($(expr ${ROOTFS_SIZE} / 1024 / 1024)MB)"
173
174 # =========================================================================
175 # PART 3: COPY KERNEL
176 # =========================================================================
177 bbnote "Copying kernel image..."
178 KERNEL_FILE="${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE_INITRAMFS}"
179 if [ -f "${KERNEL_FILE}" ]; then
180 cp "${KERNEL_FILE}" ${B}/kernel
181 KERNEL_SIZE=$(stat -c%s ${B}/kernel)
182 bbnote "Kernel copied: ${KERNEL_SIZE} bytes ($(expr ${KERNEL_SIZE} / 1024 / 1024)MB)"
183 else
184 bbwarn "Kernel not found at ${KERNEL_FILE}"
185 fi
186}
187
188do_install[noexec] = "1"
189do_package[noexec] = "1"
190do_packagedata[noexec] = "1"
191do_package_write_rpm[noexec] = "1"
192do_package_write_ipk[noexec] = "1"
193do_package_write_deb[noexec] = "1"
194do_populate_sysroot[noexec] = "1"
195
196do_deploy() {
197 # Deploy to ${VCONTAINER_RUNTIME}/<arch> subdirectory
198 install -d ${DEPLOYDIR}/${VCONTAINER_RUNTIME}/${BLOB_ARCH}
199
200 if [ -f ${B}/initramfs.cpio.gz ]; then
201 install -m 0644 ${B}/initramfs.cpio.gz ${DEPLOYDIR}/${VCONTAINER_RUNTIME}/${BLOB_ARCH}/
202 bbnote "Deployed initramfs.cpio.gz to ${VCONTAINER_RUNTIME}/${BLOB_ARCH}/"
203 fi
204
205 if [ -f ${B}/rootfs.img ]; then
206 install -m 0644 ${B}/rootfs.img ${DEPLOYDIR}/${VCONTAINER_RUNTIME}/${BLOB_ARCH}/
207 bbnote "Deployed rootfs.img to ${VCONTAINER_RUNTIME}/${BLOB_ARCH}/"
208 fi
209
210 if [ -f ${B}/kernel ]; then
211 install -m 0644 ${B}/kernel ${DEPLOYDIR}/${VCONTAINER_RUNTIME}/${BLOB_ARCH}/${KERNEL_IMAGETYPE_INITRAMFS}
212 bbnote "Deployed kernel as ${VCONTAINER_RUNTIME}/${BLOB_ARCH}/${KERNEL_IMAGETYPE_INITRAMFS}"
213 fi
214
215 cat > ${DEPLOYDIR}/${VCONTAINER_RUNTIME}/${BLOB_ARCH}/README << EOF
216${VCONTAINER_RUNTIME} Boot Blobs
217==================
218
219Built for: ${TARGET_ARCH}
220Machine: ${MACHINE}
221Multiconfig: ${VCONTAINER_MULTICONFIG}
222Date: $(date)
223
224Files:
225 ${KERNEL_IMAGETYPE_INITRAMFS} - Kernel image for QEMU
226 initramfs.cpio.gz - Tiny initramfs (switch_root only)
227 rootfs.img - Root filesystem with container tools
228
229Boot flow:
230 QEMU boots kernel + initramfs
231 -> preinit mounts rootfs.img from /dev/vda
232 -> switch_root into rootfs.img
233 -> ${VCONTAINER_RUNTIME}-init.sh runs container commands
234EOF
235}
236
237addtask deploy after do_compile before do_build