Re: [meta-virtualization][PATCH 1/7] classes: add container-nonroot-user.bbclass
Bruce Ashfield <[email protected]> Fri, 12 Jun 2026 09:54:17 -0700 (PDT)
| Newsgroups | org.yoctoproject.lists.meta-virtualization |
|---|---|
| Message-ID | <[email protected]> |
Hi Tim, A few things on this one — none of them blocking the intent, but worth a small follow-up either as a fixup in this series or a v2. On Fri, May 29, 2026 at 18:31 -0700, Tim Orling wrote: > For secure and production environments, we want to run containers as a > non-root user. Some applications, such as Python, require a $HOME > directory with proper permissions. Because OCI_LAYERS :directories: > copies with 'cp -a --no-preserve=ownership', we need a fixup function > to create the proper permissions and ownership in a new raw layer. > > The behavior here is inspired by dhi.io/python:3 (Docker Hardened Image) > > Signed-off-by: Tim Orling <[email protected]> The non-root + DHI-style image is a real gap in what we ship today; glad to see it filled. > +inherit extrausers > + > +NONROOT_USER ?= "nonroot" > +NONROOT_UID ?= "65532" > +NONROOT_GID ?= "65532" > + > +# --------------------------------------------------------------------------- > +# Create the unprivileged "nonroot" user (uid 65532, group 65532) > +# --------------------------------------------------------------------------- > +EXTRA_USERS_PARAMS = "\ > + groupadd -g ${NONROOT_GID} ${NONROOT_USER}; \ > + useradd -m -u ${NONROOT_UID} -g ${NONROOT_GID} -d /home/${NONROOT_USER} ${NONROOT_USER}; \ > +" This hard-assigns EXTRA_USERS_PARAMS rather than appending. Any image that inherits container-nonroot-user AND wants its own extrausers (e.g. a recipe that needs an additional service account) loses whatever else was set, and the order of inheritance silently determines who wins. Suggest: EXTRA_USERS_PARAMS += " \ groupadd -g ${NONROOT_GID} ${NONROOT_USER}; \ useradd -m -u ${NONROOT_UID} -g ${NONROOT_GID} \ -d /home/${NONROOT_USER} ${NONROOT_USER}; \ " That way the class composes cleanly with anyone else who sets EXTRA_USERS_PARAMS earlier. > +# Make sure we can write to e.g. /home/nonroot/.python_history > +# using :directories: in OCI_LAYERS does not preserve permissions > +fakeroot fix_oci_home_perms() { > + cd ${IMGDEPLOYDIR} > + image_name="${IMAGE_NAME}${IMAGE_NAME_SUFFIX}-oci" > + layer_tar="${WORKDIR}/oci-home-fix-layer.tar" > + > + rm -f "$layer_tar" > + > + python3 - "$layer_tar" <<'PYEOF' > +import sys, tarfile, time > + > +layer_tar = sys.argv[1] > +mtime = int(time.time()) > + > +# (path, mode, uid, gid) > +entries = [ > + ("home", 0o755, 0, 0), > + ("home/${NONROOT_USER}", 0o700, ${NONROOT_UID}, ${NONROOT_GID}), > +] Two things about the Python heredoc: 1. The 'PYEOF' delimiter uses single quotes, which would normally suppress shell expansion inside the heredoc — but bitbake expands ${NONROOT_USER} etc. at parse time *before* the shell ever sees the body, so the expansion does happen, just via a different path than the reader expects. Worth a one-line comment so the next person doesn't try to "fix" it. 2. While the values are simple here (alphanumeric user, integer uid/gid) it's fine, but if someone ever sets NONROOT_USER to something with a quote or backslash, the Python source is no longer well-formed. Since this is a meta-virt-internal class, low risk — but a comment ("NONROOT_USER must be a bare identifier") would protect it. > + umoci raw add-layer --image "$image_name:${OCI_IMAGE_TAG}" "$layer_tar" > + rm -f "$layer_tar" > + > + rm -f "$image_name.tar" "$image_name-dir.tar" > + ( cd "$image_name" && tar -cf "../$image_name.tar" "." ) > + tar -cf "$image_name-dir.tar" "$image_name" > +} > +do_image_oci[postfuncs] += "fix_oci_home_perms" The repackaging step at the bottom assumes do_image_oci's output layout (image_name.tar / image_name-dir.tar) is stable. If image-oci.bbclass ever changes its packaging naming, this silently produces a broken tarball — there's no error checking against the assumption. A defensive option: stat the expected files before rm -f / tar -cf, and bbwarn if either is missing rather than recreating from a possibly-empty directory. Or, if there's a helper in image-oci.bbclass that already does the repackaging, call that instead of rebuilding by hand. Otherwise the series looks good — I'll keep going through 2/7..7/7 and respond per-patch as I have specific notes. Bruce