From 015ffbf4173e3d0288baf5399817b17691413d3c Mon Sep 17 00:00:00 2001 From: Bruce Ashfield Date: Mon, 12 Jan 2026 20:15:39 +0000 Subject: image-oci: add build-time metadata labels for traceability Automatically embed source and build information into OCI images using standard OCI annotations (opencontainers.org image-spec): - org.opencontainers.image.revision: git commit SHA - org.opencontainers.image.ref.name: git branch name - org.opencontainers.image.created: ISO 8601 build timestamp - org.opencontainers.image.version: PV (if meaningful) New variables: - OCI_IMAGE_REVISION: explicit SHA override (auto-detects from TOPDIR) - OCI_IMAGE_BRANCH: explicit branch override (auto-detects from TOPDIR) - OCI_IMAGE_BUILD_DATE: explicit timestamp override (auto-generated) - OCI_IMAGE_APP_RECIPE: hook for future cross-recipe extraction Set any variable to "none" to disable that specific label. This enables 1:1 traceability between container images and source code, following industry best practices for CI/CD and release management. Signed-off-by: Bruce Ashfield --- classes/image-oci-umoci.inc | 38 ++++++++++++++++++++++++++++++++++++++ classes/image-oci.bbclass | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/classes/image-oci-umoci.inc b/classes/image-oci-umoci.inc index 1d4863b3..0dba347c 100644 --- a/classes/image-oci-umoci.inc +++ b/classes/image-oci-umoci.inc @@ -15,6 +15,37 @@ IMAGE_CMD:oci() { bbdebug 1 " env vars: ${OCI_IMAGE_ENV_VARS}" bbdebug 1 " ports: ${OCI_IMAGE_PORTS}" + # Auto-generate OCI standard labels at task time (not parse time) + OCI_AUTO_LABELS="" + if [ "${OCI_IMAGE_AUTO_LABELS}" = "1" ]; then + # Git revision + if [ -n "${OCI_IMAGE_REVISION}" ] && [ "${OCI_IMAGE_REVISION}" != "none" ]; then + OCI_AUTO_LABELS="$OCI_AUTO_LABELS org.opencontainers.image.revision=${OCI_IMAGE_REVISION}" + elif [ "${OCI_IMAGE_REVISION}" != "none" ]; then + _rev=$(cd ${TOPDIR} && git rev-parse --short HEAD 2>/dev/null || true) + [ -n "$_rev" ] && OCI_AUTO_LABELS="$OCI_AUTO_LABELS org.opencontainers.image.revision=$_rev" + fi + + # Git branch + if [ -n "${OCI_IMAGE_BRANCH}" ] && [ "${OCI_IMAGE_BRANCH}" != "none" ]; then + OCI_AUTO_LABELS="$OCI_AUTO_LABELS org.opencontainers.image.ref.name=${OCI_IMAGE_BRANCH}" + elif [ "${OCI_IMAGE_BRANCH}" != "none" ]; then + _branch=$(cd ${TOPDIR} && git rev-parse --abbrev-ref HEAD 2>/dev/null || true) + [ -n "$_branch" ] && [ "$_branch" != "HEAD" ] && \ + OCI_AUTO_LABELS="$OCI_AUTO_LABELS org.opencontainers.image.ref.name=$_branch" + fi + + # Build date (ISO 8601) + if [ -n "${OCI_IMAGE_BUILD_DATE}" ] && [ "${OCI_IMAGE_BUILD_DATE}" != "none" ]; then + OCI_AUTO_LABELS="$OCI_AUTO_LABELS org.opencontainers.image.created=${OCI_IMAGE_BUILD_DATE}" + elif [ "${OCI_IMAGE_BUILD_DATE}" != "none" ]; then + _date=$(date -u +%Y-%m-%dT%H:%M:%SZ) + OCI_AUTO_LABELS="$OCI_AUTO_LABELS org.opencontainers.image.created=$_date" + fi + + bbdebug 1 " auto-labels: $OCI_AUTO_LABELS" + fi + OCI_REUSE_IMAGE="" # Change into the image deploy dir to avoid having any output operations capture @@ -62,6 +93,13 @@ IMAGE_CMD:oci() { umoci config --image $image_name:${OCI_IMAGE_TAG} --config.label "$l" done fi + # Apply auto-generated OCI standard labels + if [ -n "$OCI_AUTO_LABELS" ]; then + for l in $OCI_AUTO_LABELS; do + bbdebug 1 "OCI: umoci config --image $image_name:${OCI_IMAGE_TAG} --config.label \"$l\"" + umoci config --image $image_name:${OCI_IMAGE_TAG} --config.label "$l" + done + fi if [ -n "${OCI_IMAGE_ENV_VARS}" ]; then for l in ${OCI_IMAGE_ENV_VARS}; do bbdebug 1 "umoci config --image $image_name:${OCI_IMAGE_TAG} --config.env \"$l\"" diff --git a/classes/image-oci.bbclass b/classes/image-oci.bbclass index 0ec5c487..70f32bf1 100644 --- a/classes/image-oci.bbclass +++ b/classes/image-oci.bbclass @@ -65,11 +65,53 @@ OCI_IMAGE_STOPSIGNAL ?= "" # format: /tcp, /udp, or (same as /tcp). OCI_IMAGE_PORTS ?= "" -# key=value list of labels +# key=value list of labels (user-defined) OCI_IMAGE_LABELS ?= "" # key=value list of environment variables OCI_IMAGE_ENV_VARS ?= "" +# ============================================================================= +# Build-time metadata for traceability +# ============================================================================= +# +# These variables embed source info into OCI image labels for traceability. +# Standard OCI annotations are used: https://github.com/opencontainers/image-spec/blob/main/annotations.md +# +# OCI_IMAGE_APP_RECIPE: Recipe name for the "main application" in the container. +# If set, future versions may auto-extract SRCREV/branch from this recipe. +# For now, it's documentation and a hook point. +# +# OCI_IMAGE_REVISION: Git commit SHA (short or full). +# - If set: uses this value +# - If empty: auto-detects from TOPDIR git repo +# - Set to "none" to disable +# +# OCI_IMAGE_BRANCH: Git branch name. +# - If set: uses this value +# - If empty: auto-detects from TOPDIR git repo +# - Set to "none" to disable +# +# OCI_IMAGE_BUILD_DATE: ISO 8601 timestamp. +# - Auto-generated at build time +# +# These become standard OCI labels: +# org.opencontainers.image.revision = OCI_IMAGE_REVISION +# org.opencontainers.image.ref.name = OCI_IMAGE_BRANCH +# org.opencontainers.image.created = OCI_IMAGE_BUILD_DATE +# org.opencontainers.image.version = PV (if meaningful) + +# Application recipe for traceability (documentation/future use) +OCI_IMAGE_APP_RECIPE ?= "" + +# Explicit overrides - if set, these are used instead of auto-detection +# Set to "none" to disable a specific label +OCI_IMAGE_REVISION ?= "" +OCI_IMAGE_BRANCH ?= "" +OCI_IMAGE_BUILD_DATE ?= "" + +# Enable/disable auto-detection of git metadata (set to "0" to disable) +OCI_IMAGE_AUTO_LABELS ?= "1" + # whether the oci image dir should be left as a directory, or # bundled into a tarball. OCI_IMAGE_TAR_OUTPUT ?= "true" -- cgit v1.2.3-54-g00ecf