summaryrefslogtreecommitdiffstats
path: root/recipes-containers/container-registry
diff options
context:
space:
mode:
authorBruce Ashfield <bruce.ashfield@gmail.com>2026-05-10 13:58:45 +0000
committerBruce Ashfield <bruce.ashfield@gmail.com>2026-05-10 13:58:45 +0000
commitcbe004439cae170ad5455fbb881495795e42bf5a (patch)
tree540a4ef020ede79fa8b4d22e5ce3091fc4ceba92 /recipes-containers/container-registry
parentaf92db59a7d2367528bc86cb37d969e87ef36659 (diff)
downloadmeta-virtualization-cbe004439cae170ad5455fbb881495795e42bf5a.tar.gz
container-registry: add multi-arch OCI push support and tests
The registry push script (container-registry-index.bb) treated all OCI directories as single-arch, calling 'skopeo copy oci:<dir>' which fails with "more than one image in oci, choose an image" when the directory contains a multi-arch image index. The original push implementation predated multi-arch OCI support and only handled the single-manifest case. Detect multi-arch OCI Image Index directories (both flat and nested layouts) in the direct-path push mode and use 'skopeo copy --all' to push the entire manifest list to the registry in one operation. This preserves the multi-platform structure so that clients pulling from the registry automatically get the correct architecture. Also strip the '-multiarch' suffix from directory names when deriving the registry image name, so container-base-multiarch-multiarch-oci pushes as 'container-base' rather than 'container-base-multiarch'. Add build-profiles.md documentation for the vcontainer distro, container multiconfigs, and multi-arch container build workflow. Add test_vcontainer_distro.py with 54 tests across three tiers: - Tier 1: Static file assertions (vruntime-base.inc, vcontainer.conf, multiconfigs, bbclass defaults, recipe structure) - Tier 2: Cross-file consistency (shared base, distro-MC alignment, bbclass-to-multiconfig file matching) - Tier 3: Build output verification (OCI index structure, platform entries, blob integrity, manifest validation) Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
Diffstat (limited to 'recipes-containers/container-registry')
-rw-r--r--recipes-containers/container-registry/container-registry-index.bb54
1 files changed, 54 insertions, 0 deletions
diff --git a/recipes-containers/container-registry/container-registry-index.bb b/recipes-containers/container-registry/container-registry-index.bb
index 7d53e28e..1b977ea5 100644
--- a/recipes-containers/container-registry/container-registry-index.bb
+++ b/recipes-containers/container-registry/container-registry-index.bb
@@ -1223,7 +1223,61 @@ cmd_push() {{
1223 local name=$(basename "$oci_dir" | sed 's/-latest-oci$//' | sed 's/-oci$//') 1223 local name=$(basename "$oci_dir" | sed 's/-latest-oci$//' | sed 's/-oci$//')
1224 name=$(echo "$name" | sed 's/-qemux86-64//' | sed 's/-qemuarm64//') 1224 name=$(echo "$name" | sed 's/-qemux86-64//' | sed 's/-qemuarm64//')
1225 name=$(echo "$name" | sed 's/\\.rootfs-[0-9]*//') 1225 name=$(echo "$name" | sed 's/\\.rootfs-[0-9]*//')
1226 # Strip -multiarch suffix for cleaner registry names
1227 name=$(echo "$name" | sed 's/-multiarch$//')
1228
1229 # Detect multi-arch OCI Image Index
1230 # Flat layout: index.json has multiple manifests with platform info
1231 # Nested layout: index.json → single image index blob → platform manifests
1232 local is_multiarch=0
1233 local platform_file="$oci_dir/index.json"
1234 local manifest_count=$(grep -c '"digest"' "$platform_file" 2>/dev/null || echo "0")
1235 local has_platform=$(grep -c '"platform"' "$platform_file" 2>/dev/null || echo "0")
1236
1237 if [ "$manifest_count" -gt 1 ] && [ "$has_platform" -gt 0 ]; then
1238 is_multiarch=1
1239 elif grep -q 'image\\.index' "$platform_file" 2>/dev/null; then
1240 # Nested layout: follow digest to blob
1241 local idx_digest=$(grep -o '"sha256:[a-f0-9]*"' "$platform_file" 2>/dev/null | head -1 | tr -d '"' | sed 's/sha256://')
1242 if [ -n "$idx_digest" ] && [ -f "$oci_dir/blobs/sha256/$idx_digest" ]; then
1243 if grep -q '"platform"' "$oci_dir/blobs/sha256/$idx_digest" 2>/dev/null; then
1244 platform_file="$oci_dir/blobs/sha256/$idx_digest"
1245 is_multiarch=1
1246 fi
1247 fi
1248 fi
1249
1250 if [ "$is_multiarch" = "1" ]; then
1251 # Multi-arch OCI Image Index: push with --all to preserve manifest list
1252 local platforms=$(grep -o '"architecture"[[:space:]]*:[[:space:]]*"[^"]*"' "$platform_file" | \\
1253 sed 's/.*"\\([^"]*\\)"$/\\1/' | tr '\\n' ' ')
1254
1255 echo "Pushing multi-arch OCI Image Index: $oci_dir"
1256 echo " Image name: $name"
1257 echo " Platforms: $platforms"
1258 echo " To registry: $REGISTRY_URL/$REGISTRY_NAMESPACE/"
1259 echo " Tags: $tags"
1260 echo ""
1261
1262 local tls_args=$(get_tls_args dest)
1263 for tag in $tags; do
1264 echo " Pushing manifest list: $name:$tag"
1265 if "$SKOPEO_BIN" copy --all $tls_args $auth_args \\
1266 "oci:$oci_dir" \\
1267 "docker://$REGISTRY_URL/$REGISTRY_NAMESPACE/$name:$tag" 2>&1; then
1268 echo " -> $REGISTRY_URL/$REGISTRY_NAMESPACE/$name:$tag (manifest list: $platforms)"
1269 else
1270 echo " ERROR: Failed to push multi-arch image"
1271 return 1
1272 fi
1273 done
1274
1275 echo ""
1276 echo "Done."
1277 return 0
1278 fi
1226 1279
1280 # Single-arch OCI: push normally
1227 local arch=$(get_oci_arch "$oci_dir") 1281 local arch=$(get_oci_arch "$oci_dir")
1228 [ -z "$arch" ] && arch="unknown" 1282 [ -z "$arch" ] && arch="unknown"
1229 1283