diff options
| author | Bruce Ashfield <bruce.ashfield@gmail.com> | 2026-01-06 20:45:13 +0000 |
|---|---|---|
| committer | Bruce Ashfield <bruce.ashfield@gmail.com> | 2026-02-09 03:32:52 +0000 |
| commit | 8f6f746bb6075157fa175a2081e6b3dcd833a8a2 (patch) | |
| tree | cc0ed3530abeda331b74af3325e85542edabd703 /recipes-containers/vcontainer/vpdmn-rootfs-image.bb | |
| parent | 18074e0efe255a43ab9155171d08aa6e0d736b5f (diff) | |
| download | meta-virtualization-8f6f746bb6075157fa175a2081e6b3dcd833a8a2.tar.gz | |
vcontainer: add vpdmn Podman support
Add vpdmn - Podman CLI wrapper for cross-architecture container operations:
Scripts:
- vpdmn.sh: Podman CLI entry point (vpdmn-x86_64, vpdmn-aarch64)
- vpdmn-init.sh: Podman init script for QEMU guest
Recipes:
- vpdmn-native: Installs vpdmn CLI wrappers
- vpdmn-rootfs-image: Builds Podman rootfs with crun, netavark, skopeo
- vpdmn-initramfs-create: Creates bootable initramfs blob
The vpdmn CLI provides Podman-compatible commands executed inside a
QEMU-emulated environment. Unlike vdkr, Podman is daemonless which
simplifies the guest init process.
Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
Diffstat (limited to 'recipes-containers/vcontainer/vpdmn-rootfs-image.bb')
| -rw-r--r-- | recipes-containers/vcontainer/vpdmn-rootfs-image.bb | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/recipes-containers/vcontainer/vpdmn-rootfs-image.bb b/recipes-containers/vcontainer/vpdmn-rootfs-image.bb new file mode 100644 index 00000000..33647202 --- /dev/null +++ b/recipes-containers/vcontainer/vpdmn-rootfs-image.bb | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | # SPDX-FileCopyrightText: Copyright (C) 2025 Bruce Ashfield | ||
| 2 | # | ||
| 3 | # SPDX-License-Identifier: MIT | ||
| 4 | # | ||
| 5 | # vpdmn-rootfs-image.bb | ||
| 6 | # Minimal Podman-capable image for vpdmn QEMU environment | ||
| 7 | # | ||
| 8 | # This image is built via multiconfig and used by vpdmn-initramfs-create | ||
| 9 | # to provide a proper rootfs for running Podman in QEMU. | ||
| 10 | # | ||
| 11 | # Build with: | ||
| 12 | # bitbake mc:vpdmn-aarch64:vpdmn-rootfs-image | ||
| 13 | # bitbake mc:vpdmn-x86-64:vpdmn-rootfs-image | ||
| 14 | |||
| 15 | SUMMARY = "Minimal Podman rootfs for vpdmn" | ||
| 16 | DESCRIPTION = "A minimal image containing Podman tools for use with vpdmn. \ | ||
| 17 | This image runs inside QEMU to provide Podman command execution." | ||
| 18 | |||
| 19 | LICENSE = "MIT" | ||
| 20 | LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" | ||
| 21 | |||
| 22 | # Track init script changes via file-checksums | ||
| 23 | # This adds the file content hash to the task signature | ||
| 24 | do_rootfs[file-checksums] += "${THISDIR}/files/vpdmn-init.sh:True" | ||
| 25 | do_rootfs[file-checksums] += "${THISDIR}/files/vcontainer-init-common.sh:True" | ||
| 26 | |||
| 27 | # Force do_rootfs to always run (no stamp caching) | ||
| 28 | # Combined with file-checksums, this ensures init script changes are picked up | ||
| 29 | do_rootfs[nostamp] = "1" | ||
| 30 | |||
| 31 | # Inherit from core-image-minimal for a minimal base | ||
| 32 | inherit core-image | ||
| 33 | |||
| 34 | # Use crun as the OCI runtime (not runc) - this prevents the conflict where | ||
| 35 | # both crun (which creates /usr/bin/runc symlink) and runc package are installed | ||
| 36 | VIRTUAL-RUNTIME_container_runtime = "crun" | ||
| 37 | |||
| 38 | # Use netavark for container networking (pulled in via podman's RDEPENDS) | ||
| 39 | VIRTUAL-RUNTIME_container_networking = "netavark" | ||
| 40 | |||
| 41 | # Use aardvark-dns for container DNS | ||
| 42 | VIRTUAL-RUNTIME_container_dns = "aardvark-dns" | ||
| 43 | |||
| 44 | # We need Podman and container tools | ||
| 45 | # Podman is daemonless - no containerd required! | ||
| 46 | IMAGE_INSTALL = " \ | ||
| 47 | packagegroup-core-boot \ | ||
| 48 | podman \ | ||
| 49 | skopeo \ | ||
| 50 | conmon \ | ||
| 51 | netavark \ | ||
| 52 | aardvark-dns \ | ||
| 53 | busybox \ | ||
| 54 | iproute2 \ | ||
| 55 | iptables \ | ||
| 56 | util-linux \ | ||
| 57 | ca-certificates \ | ||
| 58 | " | ||
| 59 | |||
| 60 | # No extra features needed | ||
| 61 | IMAGE_FEATURES = "" | ||
| 62 | |||
| 63 | # Keep the image small | ||
| 64 | IMAGE_ROOTFS_SIZE = "524288" | ||
| 65 | IMAGE_ROOTFS_EXTRA_SPACE = "0" | ||
| 66 | |||
| 67 | # Use squashfs for smaller size (~3x compression) | ||
| 68 | # The preinit mounts squashfs read-only with tmpfs overlay for writes | ||
| 69 | IMAGE_FSTYPES = "squashfs" | ||
| 70 | |||
| 71 | # Install our init script | ||
| 72 | ROOTFS_POSTPROCESS_COMMAND += "install_vpdmn_init;" | ||
| 73 | |||
| 74 | install_vpdmn_init() { | ||
| 75 | # Install vpdmn-init.sh as /init and vcontainer-init-common.sh alongside it | ||
| 76 | install -m 0755 ${THISDIR}/files/vpdmn-init.sh ${IMAGE_ROOTFS}/init | ||
| 77 | install -m 0755 ${THISDIR}/files/vcontainer-init-common.sh ${IMAGE_ROOTFS}/vcontainer-init-common.sh | ||
| 78 | |||
| 79 | # Create required directories | ||
| 80 | install -d ${IMAGE_ROOTFS}/mnt/input | ||
| 81 | install -d ${IMAGE_ROOTFS}/mnt/state | ||
| 82 | install -d ${IMAGE_ROOTFS}/var/lib/containers | ||
| 83 | install -d ${IMAGE_ROOTFS}/run/containers | ||
| 84 | |||
| 85 | # Create skopeo/podman policy | ||
| 86 | install -d ${IMAGE_ROOTFS}/etc/containers | ||
| 87 | echo '{"default":[{"type":"insecureAcceptAnything"}]}' > ${IMAGE_ROOTFS}/etc/containers/policy.json | ||
| 88 | |||
| 89 | # Create registries.conf for podman | ||
| 90 | cat > ${IMAGE_ROOTFS}/etc/containers/registries.conf << 'EOF' | ||
| 91 | # Search registries | ||
| 92 | unqualified-search-registries = ["docker.io", "quay.io"] | ||
| 93 | |||
| 94 | # Short name aliases | ||
| 95 | [aliases] | ||
| 96 | "alpine" = "docker.io/library/alpine" | ||
| 97 | "busybox" = "docker.io/library/busybox" | ||
| 98 | "nginx" = "docker.io/library/nginx" | ||
| 99 | "ubuntu" = "docker.io/library/ubuntu" | ||
| 100 | "debian" = "docker.io/library/debian" | ||
| 101 | EOF | ||
| 102 | |||
| 103 | # Create storage.conf for podman | ||
| 104 | # IMPORTANT: Must use VFS driver, not overlay, because: | ||
| 105 | # - The storage tar is extracted into Yocto rootfs under pseudo (fakeroot) | ||
| 106 | # - Overlay storage has special files/symlinks that fail under pseudo | ||
| 107 | # - VFS extracts cleanly (simpler structure, no special filesystem features) | ||
| 108 | install -d ${IMAGE_ROOTFS}/etc/containers/storage.conf.d | ||
| 109 | cat > ${IMAGE_ROOTFS}/etc/containers/storage.conf << 'EOF' | ||
| 110 | [storage] | ||
| 111 | driver = "vfs" | ||
| 112 | runroot = "/run/containers/storage" | ||
| 113 | graphroot = "/var/lib/containers/storage" | ||
| 114 | |||
| 115 | [storage.options] | ||
| 116 | additionalimagestores = [] | ||
| 117 | EOF | ||
| 118 | |||
| 119 | # Create containers.conf for podman engine settings | ||
| 120 | cat > ${IMAGE_ROOTFS}/etc/containers/containers.conf << 'EOF' | ||
| 121 | [engine] | ||
| 122 | # Location of helper binaries (netavark, aardvark-dns) | ||
| 123 | helper_binaries_dir = ["/usr/libexec/podman"] | ||
| 124 | |||
| 125 | [network] | ||
| 126 | # Use netavark as the network backend | ||
| 127 | network_backend = "netavark" | ||
| 128 | EOF | ||
| 129 | } | ||
