[RFC PATCH 3/4] vcontainer-initramfs-create.inc: depend on virtual/kernel:do_deploy

Tim Orling <[email protected]> Mon, 27 Apr 2026 18:13:13 -0700
Newsgroups org.yoctoproject.lists.meta-virtualization
Message-ID <f654e57a131e4e6ef29ba6b8159a77bd1f65f388.1777337030.git.tim.orling@konsulko.com>
vcontainer-tarball fails on sstate-accelerated builds with errors
similar to:

  vdkr blob not found: .../tmp-vruntime-x86-64/deploy/images/\
  qemux86-64/vdkr/x86_64/bzImage

do_compile in vcontainer-initramfs-create.inc copies the kernel out
of the multiconfig deploy dir:

    KERNEL_FILE="${MC_DEPLOY}/${KERNEL_IMAGETYPE_INITRAMFS}"

but only declares build-time deps on the two image recipes:

    do_compile[depends]  = "${VCONTAINER_RUNTIME}-tiny-initramfs-image:do_image_complete"
    do_compile[depends] += "${VCONTAINER_RUNTIME}-rootfs-image:do_image_complete"

The existing comment argued that the kernel is "built as a dependency
of the rootfs image" so no explicit kernel dep was needed. That
conflates building with deploying: a core-image rootfs needs the
kernel via virtual/kernel:do_shared_workdir / do_packagedata, but it
does not force virtual/kernel:do_deploy. The bare bzImage / Image
symlink only lands in DEPLOY_DIR_IMAGE when something explicitly
pulls in virtual/kernel:do_deploy (typically qemuboot.bbclass or an
IMAGE_CLASSES inherit), which the vruntime-* multiconfigs do not do.

Why sstate exposes it so reliably:

  - On a clean from-source build the kernel ends up deployed
    transitively through other mechanisms and do_compile finds it by
    accident.
  - On an sstate-accelerated build, <runtime>-rootfs-image:do_image_complete
    is restored straight from cache, virtual/kernel:do_deploy is
    never invoked, MC_DEPLOY/bzImage doesn't exist, do_compile only
    emits a bbwarn, and do_deploy silently skips the kernel install
    because of its `if [ -f ${B}/kernel ]` guard. vcontainer-tarball
    is then the one that finally fatals with "vdkr blob not found".
  - Because the kernel wasn't in do_compile's signature, the
    do_deploy sstate key didn't reflect it either, so a cached
    kernel-less deploy could be reused indefinitely.

Fix: declare an explicit intra-multiconfig dep on
virtual/kernel:do_deploy. The recipe runs inside the mc (it is pulled
in as `mc::<mc>:vdkr-initramfs-create:do_deploy` from
vcontainer-tarball.bb), so a plain `depends` — not `mcdepends` — is
correct. Also promote the missing-kernel bbwarn to bbfatal so a
future regression fails loudly at the producing recipe instead of
downstream in vcontainer-tarball.

AI-Generated: Claude Cowork Opus 4.7
Signed-off-by: Tim Orling <[email protected]>
---
 .../vcontainer-initramfs-create.inc           | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/recipes-containers/vcontainer/vcontainer-initramfs-create.inc b/recipes-containers/vcontainer/vcontainer-initramfs-create.inc
index 1a22c3d4..29b14e20 100644
--- a/recipes-containers/vcontainer/vcontainer-initramfs-create.inc
+++ b/recipes-containers/vcontainer/vcontainer-initramfs-create.inc
@@ -58,12 +58,18 @@ INHIBIT_DEFAULT_DEPS = "1"
 # Dependencies:
 # 1. The tiny initramfs image (produces cpio.gz)
 # 2. The multiconfig rootfs image (produces squashfs)
-# 3. The kernel from main build
-#
-# Both initramfs and rootfs images are in the same multiconfig
+# 3. The kernel's do_deploy (so ${MC_DEPLOY}/${KERNEL_IMAGETYPE_INITRAMFS}
+#    — e.g. bzImage/Image — actually exists before do_compile reads it).
+#    Being a build-time dep of the rootfs image is not enough: image
+#    recipes don't imply virtual/kernel:do_deploy, so on an sstate-
+#    accelerated build the kernel binary never lands in MC_DEPLOY and
+#    this recipe silently deploys a kernel-less blob set, which later
+#    fatals in vcontainer-tarball as "vdkr blob not found: .../bzImage".
+#    The dep is intra-multiconfig (this recipe runs inside the mc), so
+#    a plain depends — not mcdepends — is correct.
 do_compile[depends] = "${VCONTAINER_RUNTIME}-tiny-initramfs-image:do_image_complete"
 do_compile[depends] += "${VCONTAINER_RUNTIME}-rootfs-image:do_image_complete"
-# mcdepends set conditionally in anonymous python below
+do_compile[depends] += "virtual/kernel:do_deploy"
 
 S = "${UNPACKDIR}"
 B = "${WORKDIR}/build"
@@ -152,7 +158,10 @@ do_compile() {
         KERNEL_SIZE=$(stat -c%s ${B}/kernel)
         bbnote "Kernel copied: ${KERNEL_SIZE} bytes ($(expr ${KERNEL_SIZE} / 1024 / 1024)MB)"
     else
-        bbwarn "Kernel not found at ${KERNEL_FILE} — check that the vruntime multiconfig kernel is built"
+        # Fatal rather than warn: silently shipping a kernel-less blob set
+        # lets vcontainer-tarball get much further before failing with a
+        # confusing "vdkr blob not found" and produces stale sstate.
+        bbfatal "Kernel not found at ${KERNEL_FILE}. This usually means virtual/kernel:do_deploy was not pulled into the multiconfig build graph; ensure do_compile[depends] includes virtual/kernel:do_deploy."
     fi
 }
 
-- 
2.50.1 (Apple Git-155)