[meta-virtualization][PATCH] image-oci: don't preserve ownership in directories/files/host layer copies
[email protected] Sat, 2 May 2026 14:01:40 -0700
| Newsgroups | org.yoctoproject.lists.meta-virtualization |
|---|---|
| Message-ID | <[email protected]> |
From: Tim Orling <[email protected]> The multi-layer 'directories', 'files', and 'host' branches in IMAGE_CMD:oci copy delta content into the OCI bundle rootfs with 'cp -a'. 'cp -a' implies '--preserve=all', which calls lchown() on the destination to copy ownership from the source. When a directories/files layer copies a symbolic link whose target does not exist at build time (for example, the '/dev/stdout' and '/dev/stderr' log forwarding symlinks used by the official nginx Docker image), lchown() can return EINVAL under pseudo and 'cp' aborts with: cp: failed to preserve ownership for .../var/log/nginx/access.log: Invalid argument failing the whole do_image_oci task. The single-layer rootfs copy already handles this correctly: cp -r -a --no-preserve=ownership ${IMAGE_ROOTFS}/* $image_bundle_name/rootfs and the multi-layer 'packages' branch uses 'rsync -a --no-owner --no-group' for the same reason. Bring the three remaining cp -a sites in line by adding '--no-preserve=ownership'. Ownership inside an OCI image is set by umoci based on the image config and source ownership has no meaning for symlinks to runtime device nodes anyway, so dropping preservation is the correct behaviour. Reproduce: declare a directories: layer that copies a path containing a symlink to '/dev/stdout' or '/dev/stderr' (e.g. a postprocess that creates /var/log/nginx/{access,error}.log -> /dev/{stdout,stderr} to mirror the upstream nginx Docker image). Signed-off-by: Tim Orling <[email protected]> --- classes/image-oci-umoci.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/classes/image-oci-umoci.inc b/classes/image-oci-umoci.inc index bad6c5d0..a033d73a 100644 --- a/classes/image-oci-umoci.inc +++ b/classes/image-oci-umoci.inc @@ -611,7 +611,7 @@ IMAGE_CMD:oci() { oci_dst_file="$image_bundle_name/rootfs$oci_rel_path" if [ ! -e "$oci_dst_file" ]; then mkdir -p "$(dirname "$oci_dst_file")" - cp -a "$oci_src_file" "$oci_dst_file" + cp -a --no-preserve=ownership "$oci_src_file" "$oci_dst_file" oci_delta_copied=$(expr $oci_delta_copied + 1) else oci_delta_skipped=$(expr $oci_delta_skipped + 1) @@ -638,7 +638,7 @@ IMAGE_CMD:oci() { oci_dst_file="$image_bundle_name/rootfs$oci_file" if [ ! -e "$oci_dst_file" ]; then mkdir -p "$(dirname "$oci_dst_file")" - cp -a "${IMAGE_ROOTFS}$oci_file" "$oci_dst_file" + cp -a --no-preserve=ownership "${IMAGE_ROOTFS}$oci_file" "$oci_dst_file" bbnote "OCI: Added file $oci_file" else bbnote "OCI: Skipped file $oci_file (already in bundle)" @@ -657,7 +657,7 @@ IMAGE_CMD:oci() { oci_host_dst="${oci_host_pair##*:}" if [ -e "$oci_host_src" ]; then mkdir -p "$image_bundle_name/rootfs$(dirname $oci_host_dst)" - cp -a "$oci_host_src" "$image_bundle_name/rootfs$oci_host_dst" + cp -a --no-preserve=ownership "$oci_host_src" "$image_bundle_name/rootfs$oci_host_dst" bbnote "OCI: Added from host: $oci_host_src -> $oci_host_dst" else bbfatal "OCI: Host path not found: $oci_host_src" -- 2.47.3