summaryrefslogtreecommitdiffstats
path: root/recipes-containers
diff options
context:
space:
mode:
authorBruce Ashfield <bruce.ashfield@gmail.com>2026-01-15 21:50:27 +0000
committerBruce Ashfield <bruce.ashfield@gmail.com>2026-02-09 03:32:52 +0000
commit1c902059df8215731e9ee7210f6bbc4e19593761 (patch)
tree2bec4fc2d24b3eb273b450016021e98d7f89a7af /recipes-containers
parent1008fa9b63f5123989e9f82cd50d51b60bfee2ee (diff)
downloadmeta-virtualization-1c902059df8215731e9ee7210f6bbc4e19593761.tar.gz
container-registry: abstract config and add multi-directory push
Abstract registry configuration for Docker/Podman compatibility and add multi-directory scanning for easy multi-arch manifest list creation. - Support both DOCKER_REGISTRY_INSECURE and CONTAINER_REGISTRY_INSECURE - Add DEPLOY_DIR_IMAGES to scan all machine directories - Support push by path (single OCI) and push by name (all archs) - Add environment variable overrides for flexibility - Single 'push' command now creates multi-arch manifest lists Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
Diffstat (limited to 'recipes-containers')
-rw-r--r--recipes-containers/container-registry/container-registry-index.bb373
-rw-r--r--recipes-containers/container-registry/docker-registry-config.bb24
2 files changed, 352 insertions, 45 deletions
diff --git a/recipes-containers/container-registry/container-registry-index.bb b/recipes-containers/container-registry/container-registry-index.bb
index 75090faa..29125eee 100644
--- a/recipes-containers/container-registry/container-registry-index.bb
+++ b/recipes-containers/container-registry/container-registry-index.bb
@@ -98,6 +98,8 @@ python do_generate_registry_script() {
98 script_path = d.getVar('CONTAINER_REGISTRY_SCRIPT') 98 script_path = d.getVar('CONTAINER_REGISTRY_SCRIPT')
99 deploy_dir = d.getVar('DEPLOY_DIR') 99 deploy_dir = d.getVar('DEPLOY_DIR')
100 deploy_dir_image = d.getVar('DEPLOY_DIR_IMAGE') 100 deploy_dir_image = d.getVar('DEPLOY_DIR_IMAGE')
101 # Parent of DEPLOY_DIR_IMAGE (e.g., tmp/deploy/images/) for multi-arch discovery
102 deploy_dir_images = os.path.dirname(deploy_dir_image)
101 103
102 # Find registry binary path 104 # Find registry binary path
103 native_sysroot = d.getVar('STAGING_DIR_NATIVE') or '' 105 native_sysroot = d.getVar('STAGING_DIR_NATIVE') or ''
@@ -160,7 +162,12 @@ REGISTRY_CONFIG="{config_file}"
160REGISTRY_STORAGE="{registry_storage}" 162REGISTRY_STORAGE="{registry_storage}"
161REGISTRY_URL="{registry_url}" 163REGISTRY_URL="{registry_url}"
162REGISTRY_NAMESPACE="{registry_namespace}" 164REGISTRY_NAMESPACE="{registry_namespace}"
163DEPLOY_DIR_IMAGE="{deploy_dir_image}" 165
166# Deploy directories - can be overridden via environment
167# DEPLOY_DIR_IMAGES: parent directory containing per-machine deploy dirs
168# DEPLOY_DIR_IMAGE: single machine deploy dir (legacy, still supported)
169DEPLOY_DIR_IMAGES="${{DEPLOY_DIR_IMAGES:-{deploy_dir_images}}}"
170DEPLOY_DIR_IMAGE="${{DEPLOY_DIR_IMAGE:-{deploy_dir_image}}}"
164 171
165# Baked-in defaults from bitbake (can be overridden by CLI or env vars) 172# Baked-in defaults from bitbake (can be overridden by CLI or env vars)
166DEFAULT_TAG_STRATEGY="{tag_strategy}" 173DEFAULT_TAG_STRATEGY="{tag_strategy}"
@@ -299,6 +306,189 @@ cmd_status() {{
299 fi 306 fi
300}} 307}}
301 308
309# ============================================================================
310# Multi-Architecture Manifest List Support
311# ============================================================================
312# Always creates/updates manifest lists for tags, enabling multi-arch images.
313# When pushing the same image name from different architectures, each push
314# adds to the manifest list instead of overwriting.
315# ============================================================================
316
317# Get architecture from OCI image config
318# Usage: get_oci_arch <oci_dir>
319get_oci_arch() {{
320 local oci_dir="$1"
321 [ -f "$oci_dir/index.json" ] || return 1
322
323 # Get manifest digest from index.json
324 local manifest_digest=$(grep -o '"digest"[[:space:]]*:[[:space:]]*"sha256:[a-f0-9]*"' "$oci_dir/index.json" | head -1 | sed 's/.*sha256:\\([a-f0-9]*\\)".*/\\1/')
325 [ -z "$manifest_digest" ] && return 1
326
327 # Get config digest from manifest
328 local manifest_file="$oci_dir/blobs/sha256/$manifest_digest"
329 [ -f "$manifest_file" ] || return 1
330 local config_digest=$(grep -o '"config"[^}}]*"digest"[[:space:]]*:[[:space:]]*"sha256:[a-f0-9]*"' "$manifest_file" | sed 's/.*sha256:\\([a-f0-9]*\\)".*/\\1/')
331 [ -z "$config_digest" ] && return 1
332
333 # Get architecture from config
334 local config_file="$oci_dir/blobs/sha256/$config_digest"
335 [ -f "$config_file" ] || return 1
336 grep -o '"architecture"[[:space:]]*:[[:space:]]*"[^"]*"' "$config_file" | head -1 | sed 's/.*"\\([^"]*\\)"$/\\1/'
337}}
338
339# Check if a tag points to a manifest list (vs single manifest)
340# Usage: is_manifest_list <image_ref>
341# Returns: 0 if manifest list, 1 if single manifest or not found
342is_manifest_list() {{
343 local image="$1"
344 local tag="$2"
345
346 local content_type=$(curl -s -I -H "Accept: application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.list.v2+json" \\
347 "http://$REGISTRY_URL/v2/$image/manifests/$tag" 2>/dev/null | grep -i "content-type" | head -1)
348
349 echo "$content_type" | grep -qE "manifest.list|image.index"
350}}
351
352# Get existing manifest list for a tag (if any)
353# Usage: get_manifest_list <image> <tag>
354# Returns: JSON manifest list or empty string
355get_manifest_list() {{
356 local image="$1"
357 local tag="$2"
358
359 curl -s -H "Accept: application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.list.v2+json" \\
360 "http://$REGISTRY_URL/v2/$image/manifests/$tag" 2>/dev/null
361}}
362
363# Get manifest digest and size for an image by tag
364# Usage: get_manifest_info <image> <tag>
365# Returns: digest:size or empty
366get_manifest_info() {{
367 local image="$1"
368 local tag="$2"
369
370 local headers=$(curl -s -I -H "Accept: application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.v2+json" \\
371 "http://$REGISTRY_URL/v2/$image/manifests/$tag" 2>/dev/null)
372
373 local digest=$(echo "$headers" | grep -i "docker-content-digest" | awk '{{print $2}}' | tr -d '\\r\\n')
374 local size=$(echo "$headers" | grep -i "content-length" | awk '{{print $2}}' | tr -d '\\r\\n')
375
376 [ -n "$digest" ] && [ -n "$size" ] && echo "$digest:$size"
377}}
378
379# Push image by digest (returns the digest)
380# Usage: push_by_digest <oci_dir> <image_name>
381push_by_digest() {{
382 local oci_dir="$1"
383 local image_name="$2"
384 local temp_tag="temp-${{RANDOM}}-$(date +%s)"
385
386 # Push with temporary tag
387 "$SKOPEO_BIN" copy --dest-tls-verify=false \\
388 "oci:$oci_dir" \\
389 "docker://$REGISTRY_URL/$REGISTRY_NAMESPACE/$image_name:$temp_tag" >/dev/null 2>&1
390
391 # Get digest for the pushed image
392 local info=$(get_manifest_info "$REGISTRY_NAMESPACE/$image_name" "$temp_tag")
393 local digest=$(echo "$info" | cut -d: -f1-2) # sha256:xxx
394 local size=$(echo "$info" | cut -d: -f3)
395
396 # Delete the temp tag (leave the blobs)
397 curl -s -X DELETE "http://$REGISTRY_URL/v2/$REGISTRY_NAMESPACE/$image_name/manifests/$temp_tag" >/dev/null 2>&1 || true
398
399 echo "$digest:$size"
400}}
401
402# Create or update manifest list for a tag
403# Usage: update_manifest_list <image> <tag> <new_digest> <new_size> <new_arch>
404update_manifest_list() {{
405 local image="$1"
406 local tag="$2"
407 local new_digest="$3"
408 local new_size="$4"
409 local new_arch="$5"
410 local new_os="${{6:-linux}}"
411
412 # Normalize architecture for OCI
413 case "$new_arch" in
414 aarch64) new_arch="arm64" ;;
415 x86_64) new_arch="amd64" ;;
416 esac
417
418 local manifests=""
419
420 # Check for existing manifest list or single manifest
421 if is_manifest_list "$image" "$tag"; then
422 # Get existing manifest list and extract manifests (excluding our arch)
423 local existing=$(get_manifest_list "$image" "$tag")
424 manifests=$(echo "$existing" | python3 -c "
425import sys, json
426try:
427 data = json.load(sys.stdin)
428 for m in data.get('manifests', []):
429 p = m.get('platform', {{}})
430 if p.get('architecture') != '$new_arch':
431 print(json.dumps(m))
432except: pass
433" 2>/dev/null)
434 else
435 # Check if there's a single manifest at this tag
436 local existing_info=$(get_manifest_info "$image" "$tag")
437 if [ -n "$existing_info" ]; then
438 # Get architecture of existing single manifest
439 local existing_digest=$(echo "$existing_info" | cut -d: -f1-2)
440 local existing_size=$(echo "$existing_info" | cut -d: -f3)
441
442 # Inspect to get architecture
443 local existing_arch=$("$SKOPEO_BIN" inspect --tls-verify=false \\
444 "docker://$REGISTRY_URL/$image:$tag" 2>/dev/null | \\
445 python3 -c "import sys,json; print(json.load(sys.stdin).get('Architecture',''))" 2>/dev/null)
446
447 if [ -n "$existing_arch" ] && [ "$existing_arch" != "$new_arch" ]; then
448 # Different arch - include it in manifest list
449 manifests=$(cat <<MANIFEST
450{{"mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "$existing_digest", "size": $existing_size, "platform": {{"architecture": "$existing_arch", "os": "linux"}}}}
451MANIFEST
452)
453 fi
454 fi
455 fi
456
457 # Add our new manifest
458 local new_manifest='{{"mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "'$new_digest'", "size": '$new_size', "platform": {{"architecture": "'$new_arch'", "os": "'$new_os'"}}}}'
459
460 if [ -n "$manifests" ]; then
461 manifests="$manifests
462$new_manifest"
463 else
464 manifests="$new_manifest"
465 fi
466
467 # Create manifest list JSON
468 local manifest_list=$(python3 -c "
469import sys, json
470manifests = []
471for line in sys.stdin:
472 line = line.strip()
473 if line:
474 manifests.append(json.loads(line))
475result = {{
476 'schemaVersion': 2,
477 'mediaType': 'application/vnd.oci.image.index.v1+json',
478 'manifests': manifests
479}}
480print(json.dumps(result, indent=2))
481" <<< "$manifests")
482
483 # Push manifest list
484 local status=$(curl -s -o /dev/null -w "%{{http_code}}" -X PUT \\
485 -H "Content-Type: application/vnd.oci.image.index.v1+json" \\
486 -d "$manifest_list" \\
487 "http://$REGISTRY_URL/v2/$image/manifests/$tag")
488
489 [ "$status" = "201" ] || [ "$status" = "200" ]
490}}
491
302cmd_push() {{ 492cmd_push() {{
303 shift # Remove 'push' from args 493 shift # Remove 'push' from args
304 494
@@ -367,59 +557,146 @@ cmd_push() {{
367 tags=$(generate_tags "$strategy") 557 tags=$(generate_tags "$strategy")
368 fi 558 fi
369 559
560 # Check if argument is a path to an OCI directory (contains / or ends with -oci)
561 if [ -n "$image_filter" ] && [ -d "$image_filter" ] && [ -f "$image_filter/index.json" ]; then
562 # Direct path mode: push single OCI directory
563 local oci_dir="$image_filter"
564 local name=$(basename "$oci_dir" | sed 's/-latest-oci$//' | sed 's/-oci$//')
565 name=$(echo "$name" | sed 's/-qemux86-64//' | sed 's/-qemuarm64//')
566 name=$(echo "$name" | sed 's/\\.rootfs-[0-9]*//')
567
568 local arch=$(get_oci_arch "$oci_dir")
569 [ -z "$arch" ] && arch="unknown"
570
571 echo "Pushing OCI directory: $oci_dir"
572 echo " Image name: $name ($arch)"
573 echo " To registry: $REGISTRY_URL/$REGISTRY_NAMESPACE/"
574 echo " Tags: $tags"
575 echo ""
576
577 echo " Uploading image blobs..."
578 local digest_info=$(push_by_digest "$oci_dir" "$name")
579 local digest=$(echo "$digest_info" | cut -d: -f1-2)
580 local size=$(echo "$digest_info" | cut -d: -f3)
581
582 if [ -z "$digest" ]; then
583 echo " ERROR: Failed to push image"
584 return 1
585 fi
586
587 echo " Image digest: $digest"
588
589 for tag in $tags; do
590 echo " Creating/updating manifest list: $tag"
591 if update_manifest_list "$REGISTRY_NAMESPACE/$name" "$tag" "$digest" "$size" "$arch"; then
592 echo " -> $REGISTRY_URL/$REGISTRY_NAMESPACE/$name:$tag (manifest list)"
593 else
594 echo " WARNING: Failed to update manifest list, falling back to direct push"
595 "$SKOPEO_BIN" copy --dest-tls-verify=false \\
596 "oci:$oci_dir" \\
597 "docker://$REGISTRY_URL/$REGISTRY_NAMESPACE/$name:$tag"
598 fi
599 done
600
601 echo ""
602 echo "Done."
603 return 0
604 fi
605
606 # Name filter mode or push all: scan machine directories
370 if [ -n "$image_filter" ]; then 607 if [ -n "$image_filter" ]; then
371 echo "Pushing image: $image_filter" 608 echo "Pushing image: $image_filter (all architectures)"
372 else 609 else
373 echo "Pushing all OCI images from $DEPLOY_DIR_IMAGE" 610 echo "Pushing all OCI images"
374 fi 611 fi
612 echo "Scanning: $DEPLOY_DIR_IMAGES/*/"
375 echo "To registry: $REGISTRY_URL/$REGISTRY_NAMESPACE/" 613 echo "To registry: $REGISTRY_URL/$REGISTRY_NAMESPACE/"
376 echo "Tags: $tags" 614 echo "Tags: $tags"
615 echo "(Multi-arch manifest lists enabled)"
377 echo "" 616 echo ""
378 617
379 local found=0 618 local found=0
380 for oci_dir in "$DEPLOY_DIR_IMAGE"/*-oci; do
381 [ -d "$oci_dir" ] || continue
382 [ -f "$oci_dir/index.json" ] || continue
383 619
384 name=$(basename "$oci_dir" | sed 's/-latest-oci$//' | sed 's/-oci$//') 620 # Iterate over all machine directories (e.g., qemuarm64, qemux86-64)
385 # Remove machine suffix 621 for machine_dir in "$DEPLOY_DIR_IMAGES"/*/; do
386 name=$(echo "$name" | sed 's/-qemux86-64//' | sed 's/-qemuarm64//') 622 [ -d "$machine_dir" ] || continue
387 # Remove rootfs timestamp
388 name=$(echo "$name" | sed 's/\\.rootfs-[0-9]*//')
389 623
390 # Filter by image name if specified 624 local machine_name=$(basename "$machine_dir")
391 if [ -n "$image_filter" ]; then
392 # Match exact name or name.rootfs variant
393 case "$name" in
394 "$image_filter"|"$image_filter.rootfs")
395 : # match
396 ;;
397 *)
398 continue
399 ;;
400 esac
401 fi
402 625
403 found=1 626 # Find OCI directories in this machine's deploy dir
404 echo "Pushing: $name" 627 for oci_dir in "$machine_dir"*-oci; do
405 for tag in $tags; do 628 [ -d "$oci_dir" ] || continue
406 echo " -> $REGISTRY_URL/$REGISTRY_NAMESPACE/$name:$tag" 629 [ -f "$oci_dir/index.json" ] || continue
407 "$SKOPEO_BIN" copy --dest-tls-verify=false \\ 630
408 "oci:$oci_dir" \\ 631 name=$(basename "$oci_dir" | sed 's/-latest-oci$//' | sed 's/-oci$//')
409 "docker://$REGISTRY_URL/$REGISTRY_NAMESPACE/$name:$tag" 632 # Remove machine suffix
633 name=$(echo "$name" | sed 's/-qemux86-64//' | sed 's/-qemuarm64//')
634 # Remove rootfs timestamp
635 name=$(echo "$name" | sed 's/\\.rootfs-[0-9]*//')
636
637 # Filter by image name if specified
638 if [ -n "$image_filter" ]; then
639 # Match exact name or name.rootfs variant
640 case "$name" in
641 "$image_filter"|"$image_filter.rootfs")
642 : # match
643 ;;
644 *)
645 continue
646 ;;
647 esac
648 fi
649
650 found=1
651
652 # Get architecture from OCI image
653 local arch=$(get_oci_arch "$oci_dir")
654 [ -z "$arch" ] && arch="unknown"
655 echo "Pushing: $name ($arch) [from $machine_name]"
656
657 # Push image by digest first
658 echo " Uploading image blobs..."
659 local digest_info=$(push_by_digest "$oci_dir" "$name")
660 local digest=$(echo "$digest_info" | cut -d: -f1-2)
661 local size=$(echo "$digest_info" | cut -d: -f3)
662
663 if [ -z "$digest" ]; then
664 echo " ERROR: Failed to push image"
665 continue
666 fi
667
668 echo " Image digest: $digest"
669
670 # Update manifest list for each tag
671 for tag in $tags; do
672 echo " Creating/updating manifest list: $tag"
673 if update_manifest_list "$REGISTRY_NAMESPACE/$name" "$tag" "$digest" "$size" "$arch"; then
674 echo " -> $REGISTRY_URL/$REGISTRY_NAMESPACE/$name:$tag (manifest list)"
675 else
676 echo " WARNING: Failed to update manifest list, falling back to direct push"
677 "$SKOPEO_BIN" copy --dest-tls-verify=false \\
678 "oci:$oci_dir" \\
679 "docker://$REGISTRY_URL/$REGISTRY_NAMESPACE/$name:$tag"
680 fi
681 done
682 echo ""
410 done 683 done
411 done 684 done
412 685
413 if [ -n "$image_filter" ] && [ "$found" = "0" ]; then 686 if [ -n "$image_filter" ] && [ "$found" = "0" ]; then
414 echo "Error: Image '$image_filter' not found in $DEPLOY_DIR_IMAGE" 687 echo "Error: Image '$image_filter' not found in $DEPLOY_DIR_IMAGES"
415 echo "" 688 echo ""
416 echo "Available images:" 689 echo "Available images:"
417 for oci_dir in "$DEPLOY_DIR_IMAGE"/*-oci; do 690 for machine_dir in "$DEPLOY_DIR_IMAGES"/*/; do
418 [ -d "$oci_dir" ] || continue 691 [ -d "$machine_dir" ] || continue
419 [ -f "$oci_dir/index.json" ] || continue 692 for oci_dir in "$machine_dir"*-oci; do
420 n=$(basename "$oci_dir" | sed 's/-latest-oci$//' | sed 's/-oci$//' | sed 's/-qemux86-64//' | sed 's/-qemuarm64//' | sed 's/\\.rootfs-[0-9]*//') 693 [ -d "$oci_dir" ] || continue
421 echo " $n" 694 [ -f "$oci_dir/index.json" ] || continue
422 done 695 local arch=$(get_oci_arch "$oci_dir")
696 n=$(basename "$oci_dir" | sed 's/-latest-oci$//' | sed 's/-oci$//' | sed 's/-qemux86-64//' | sed 's/-qemuarm64//' | sed 's/\\.rootfs-[0-9]*//')
697 echo " $n ($arch)"
698 done
699 done | sort -u
423 return 1 700 return 1
424 fi 701 fi
425 702
@@ -697,11 +974,23 @@ cmd_help() {{
697 echo " latest The 'latest' tag" 974 echo " latest The 'latest' tag"
698 echo " arch Append architecture suffix to other tags" 975 echo " arch Append architecture suffix to other tags"
699 echo "" 976 echo ""
977 echo "Multi-architecture support:"
978 echo " Push scans all machine directories under DEPLOY_DIR_IMAGES and creates"
979 echo " manifest lists containing all architectures found for each container."
980 echo ""
981 echo " Workflow:"
982 echo " MACHINE=qemuarm64 bitbake myapp"
983 echo " MACHINE=qemux86-64 bitbake myapp"
984 echo " $0 push # Scans all machines, creates manifest lists"
985 echo ""
986 echo " Result: myapp:latest is a manifest list with both arm64 and amd64"
987 echo ""
700 echo "Examples:" 988 echo "Examples:"
701 echo " $0 start" 989 echo " $0 start"
702 echo " $0 push # Push all, default strategy" 990 echo " $0 push # Push all from all machines"
703 echo " $0 push container-base # Push one, default strategy" 991 echo " $0 push container-base # Push by name (all archs found)"
704 echo " $0 push container-base --tag v1.0.0 # Explicit tag (one image)" 992 echo " $0 push /path/to/container-base-latest-oci # Push by path (single OCI dir)"
993 echo " $0 push container-base --tag v1.0.0 # Explicit tag"
705 echo " $0 push container-base -t latest -t v1.0.0 # Multiple explicit tags" 994 echo " $0 push container-base -t latest -t v1.0.0 # Multiple explicit tags"
706 echo " $0 push --strategy 'sha branch latest' # All images, strategy" 995 echo " $0 push --strategy 'sha branch latest' # All images, strategy"
707 echo " $0 push --strategy semver --version 1.2.3 # All images, SemVer" 996 echo " $0 push --strategy semver --version 1.2.3 # All images, SemVer"
@@ -712,6 +1001,8 @@ cmd_help() {{
712 echo " $0 tags container-base" 1001 echo " $0 tags container-base"
713 echo "" 1002 echo ""
714 echo "Environment variables:" 1003 echo "Environment variables:"
1004 echo " DEPLOY_DIR_IMAGES Override parent of deploy dirs (scans */)"
1005 echo " DEPLOY_DIR_IMAGE Override single machine deploy dir"
715 echo " CONTAINER_REGISTRY_TAG_STRATEGY Override default tag strategy" 1006 echo " CONTAINER_REGISTRY_TAG_STRATEGY Override default tag strategy"
716 echo " IMAGE_VERSION Version for semver/version strategies" 1007 echo " IMAGE_VERSION Version for semver/version strategies"
717 echo " TARGET_ARCH Architecture for arch strategy" 1008 echo " TARGET_ARCH Architecture for arch strategy"
@@ -722,7 +1013,7 @@ cmd_help() {{
722 echo " Tag strategy: $DEFAULT_TAG_STRATEGY" 1013 echo " Tag strategy: $DEFAULT_TAG_STRATEGY"
723 echo " Target arch: $DEFAULT_TARGET_ARCH" 1014 echo " Target arch: $DEFAULT_TARGET_ARCH"
724 echo " Storage: $REGISTRY_STORAGE" 1015 echo " Storage: $REGISTRY_STORAGE"
725 echo " Deploy images: $DEPLOY_DIR_IMAGE" 1016 echo " Deploy dirs: $DEPLOY_DIR_IMAGES/*/"
726}} 1017}}
727 1018
728case "${{1:-help}}" in 1019case "${{1:-help}}" in
diff --git a/recipes-containers/container-registry/docker-registry-config.bb b/recipes-containers/container-registry/docker-registry-config.bb
index cbe2e13f..e03cd3eb 100644
--- a/recipes-containers/container-registry/docker-registry-config.bb
+++ b/recipes-containers/container-registry/docker-registry-config.bb
@@ -46,22 +46,38 @@ LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda
46 46
47# Space-separated list of insecure registries 47# Space-separated list of insecure registries
48# Example: "10.0.2.2:5000 myregistry.local:5000" 48# Example: "10.0.2.2:5000 myregistry.local:5000"
49# Can also use runtime-agnostic CONTAINER_REGISTRY_URL + CONTAINER_REGISTRY_INSECURE
49DOCKER_REGISTRY_INSECURE ?= "" 50DOCKER_REGISTRY_INSECURE ?= ""
51CONTAINER_REGISTRY_URL ?= ""
52CONTAINER_REGISTRY_INSECURE ?= ""
53
54def get_insecure_registries(d):
55 """Get insecure registries from either Docker-specific or generic config"""
56 # Prefer explicit DOCKER_REGISTRY_INSECURE if set
57 docker_insecure = d.getVar('DOCKER_REGISTRY_INSECURE') or ""
58 if docker_insecure.strip():
59 return docker_insecure.strip()
60 # Fall back to CONTAINER_REGISTRY_URL if marked insecure
61 registry_url = d.getVar('CONTAINER_REGISTRY_URL') or ""
62 is_insecure = d.getVar('CONTAINER_REGISTRY_INSECURE') or ""
63 if registry_url.strip() and is_insecure in ['1', 'true', 'yes']:
64 return registry_url.strip()
65 return ""
50 66
51inherit allarch 67inherit allarch
52 68
53# Skip recipe entirely if not configured 69# Skip recipe entirely if not configured
54python() { 70python() {
55 registries = d.getVar('DOCKER_REGISTRY_INSECURE') 71 registries = get_insecure_registries(d)
56 if not registries or not registries.strip(): 72 if not registries:
57 raise bb.parse.SkipRecipe("DOCKER_REGISTRY_INSECURE not set - recipe is opt-in only") 73 raise bb.parse.SkipRecipe("No insecure registry configured - recipe is opt-in only")
58} 74}
59 75
60python do_install() { 76python do_install() {
61 import os 77 import os
62 import json 78 import json
63 79
64 registries = d.getVar('DOCKER_REGISTRY_INSECURE').split() 80 registries = get_insecure_registries(d).split()
65 81
66 dest = d.getVar('D') 82 dest = d.getVar('D')
67 confdir = os.path.join(dest, d.getVar('sysconfdir').lstrip('/'), 'docker') 83 confdir = os.path.join(dest, d.getVar('sysconfdir').lstrip('/'), 'docker')