From 66838bb1358daeda004ded2f8ea91a24fcc1b23b Mon Sep 17 00:00:00 2001 From: Thales Maciel Date: Sat, 18 Apr 2026 14:58:42 -0300 Subject: [PATCH] make-bundle: strip /.dockerenv so systemd doesn't misdetect virt `docker create` drops /.dockerenv into the container's writable layer, and `docker export` includes it in the tar. When systemd later boots that rootfs it finds /.dockerenv and flags virtualization=docker, which disables a bunch of udev device-unit behaviour (device units never become active, mount units waiting on them hang forever). Strip /.dockerenv (and /run/.containerenv for podman symmetry) from the staging tree after FlattenTar and before BuildExt4 so systemd correctly detects virtualization=kvm. Co-Authored-By: Claude Opus 4.7 (1M context) --- internal/cli/banger.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/internal/cli/banger.go b/internal/cli/banger.go index 606a773..dccda53 100644 --- a/internal/cli/banger.go +++ b/internal/cli/banger.go @@ -421,6 +421,21 @@ func runInternalMakeBundle(cmd *cobra.Command, opts internalMakeBundleOpts) erro return fmt.Errorf("flatten rootfs: %w", err) } + // docker create drops /.dockerenv (and containerd drops + // /run/.containerenv) into the container's writable layer, so + // `docker export` includes them in the tar. systemd-detect-virt + // reads those files and flags the boot as virtualization=docker, + // which disables udev device-unit activation (including the work- + // disk dev-vdb.device) and leaves systemd waiting forever. Strip + // them before building the ext4. + for _, marker := range []string{".dockerenv", "run/.containerenv"} { + path := filepath.Join(rootfsTree, marker) + if err := os.Remove(path); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("strip %s: %w", marker, err) + } + delete(meta.Entries, marker) + } + if sizeBytes <= 0 { treeSize, err := dirSize(rootfsTree) if err != nil {