diff options
| author | Bruce Ashfield <bruce.ashfield@gmail.com> | 2026-01-12 20:15:39 +0000 |
|---|---|---|
| committer | Bruce Ashfield <bruce.ashfield@gmail.com> | 2026-01-21 18:00:26 -0500 |
| commit | 015ffbf4173e3d0288baf5399817b17691413d3c (patch) | |
| tree | 7af4bc18360f563ee029399281c78bcd52614284 | |
| parent | 767a90842721b8a1ca5eb73a893910e80245f920 (diff) | |
| download | meta-virtualization-015ffbf4173e3d0288baf5399817b17691413d3c.tar.gz | |
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 <bruce.ashfield@gmail.com>
| -rw-r--r-- | classes/image-oci-umoci.inc | 38 | ||||
| -rw-r--r-- | classes/image-oci.bbclass | 44 |
2 files changed, 81 insertions, 1 deletions
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() { | |||
| 15 | bbdebug 1 " env vars: ${OCI_IMAGE_ENV_VARS}" | 15 | bbdebug 1 " env vars: ${OCI_IMAGE_ENV_VARS}" |
| 16 | bbdebug 1 " ports: ${OCI_IMAGE_PORTS}" | 16 | bbdebug 1 " ports: ${OCI_IMAGE_PORTS}" |
| 17 | 17 | ||
| 18 | # Auto-generate OCI standard labels at task time (not parse time) | ||
| 19 | OCI_AUTO_LABELS="" | ||
| 20 | if [ "${OCI_IMAGE_AUTO_LABELS}" = "1" ]; then | ||
| 21 | # Git revision | ||
| 22 | if [ -n "${OCI_IMAGE_REVISION}" ] && [ "${OCI_IMAGE_REVISION}" != "none" ]; then | ||
| 23 | OCI_AUTO_LABELS="$OCI_AUTO_LABELS org.opencontainers.image.revision=${OCI_IMAGE_REVISION}" | ||
| 24 | elif [ "${OCI_IMAGE_REVISION}" != "none" ]; then | ||
| 25 | _rev=$(cd ${TOPDIR} && git rev-parse --short HEAD 2>/dev/null || true) | ||
| 26 | [ -n "$_rev" ] && OCI_AUTO_LABELS="$OCI_AUTO_LABELS org.opencontainers.image.revision=$_rev" | ||
| 27 | fi | ||
| 28 | |||
| 29 | # Git branch | ||
| 30 | if [ -n "${OCI_IMAGE_BRANCH}" ] && [ "${OCI_IMAGE_BRANCH}" != "none" ]; then | ||
| 31 | OCI_AUTO_LABELS="$OCI_AUTO_LABELS org.opencontainers.image.ref.name=${OCI_IMAGE_BRANCH}" | ||
| 32 | elif [ "${OCI_IMAGE_BRANCH}" != "none" ]; then | ||
| 33 | _branch=$(cd ${TOPDIR} && git rev-parse --abbrev-ref HEAD 2>/dev/null || true) | ||
| 34 | [ -n "$_branch" ] && [ "$_branch" != "HEAD" ] && \ | ||
| 35 | OCI_AUTO_LABELS="$OCI_AUTO_LABELS org.opencontainers.image.ref.name=$_branch" | ||
| 36 | fi | ||
| 37 | |||
| 38 | # Build date (ISO 8601) | ||
| 39 | if [ -n "${OCI_IMAGE_BUILD_DATE}" ] && [ "${OCI_IMAGE_BUILD_DATE}" != "none" ]; then | ||
| 40 | OCI_AUTO_LABELS="$OCI_AUTO_LABELS org.opencontainers.image.created=${OCI_IMAGE_BUILD_DATE}" | ||
| 41 | elif [ "${OCI_IMAGE_BUILD_DATE}" != "none" ]; then | ||
| 42 | _date=$(date -u +%Y-%m-%dT%H:%M:%SZ) | ||
| 43 | OCI_AUTO_LABELS="$OCI_AUTO_LABELS org.opencontainers.image.created=$_date" | ||
| 44 | fi | ||
| 45 | |||
| 46 | bbdebug 1 " auto-labels: $OCI_AUTO_LABELS" | ||
| 47 | fi | ||
| 48 | |||
| 18 | OCI_REUSE_IMAGE="" | 49 | OCI_REUSE_IMAGE="" |
| 19 | 50 | ||
| 20 | # Change into the image deploy dir to avoid having any output operations capture | 51 | # Change into the image deploy dir to avoid having any output operations capture |
| @@ -62,6 +93,13 @@ IMAGE_CMD:oci() { | |||
| 62 | umoci config --image $image_name:${OCI_IMAGE_TAG} --config.label "$l" | 93 | umoci config --image $image_name:${OCI_IMAGE_TAG} --config.label "$l" |
| 63 | done | 94 | done |
| 64 | fi | 95 | fi |
| 96 | # Apply auto-generated OCI standard labels | ||
| 97 | if [ -n "$OCI_AUTO_LABELS" ]; then | ||
| 98 | for l in $OCI_AUTO_LABELS; do | ||
| 99 | bbdebug 1 "OCI: umoci config --image $image_name:${OCI_IMAGE_TAG} --config.label \"$l\"" | ||
| 100 | umoci config --image $image_name:${OCI_IMAGE_TAG} --config.label "$l" | ||
| 101 | done | ||
| 102 | fi | ||
| 65 | if [ -n "${OCI_IMAGE_ENV_VARS}" ]; then | 103 | if [ -n "${OCI_IMAGE_ENV_VARS}" ]; then |
| 66 | for l in ${OCI_IMAGE_ENV_VARS}; do | 104 | for l in ${OCI_IMAGE_ENV_VARS}; do |
| 67 | bbdebug 1 "umoci config --image $image_name:${OCI_IMAGE_TAG} --config.env \"$l\"" | 105 | 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 ?= "" | |||
| 65 | # format: <port>/tcp, <port>/udp, or <port> (same as <port>/tcp). | 65 | # format: <port>/tcp, <port>/udp, or <port> (same as <port>/tcp). |
| 66 | OCI_IMAGE_PORTS ?= "" | 66 | OCI_IMAGE_PORTS ?= "" |
| 67 | 67 | ||
| 68 | # key=value list of labels | 68 | # key=value list of labels (user-defined) |
| 69 | OCI_IMAGE_LABELS ?= "" | 69 | OCI_IMAGE_LABELS ?= "" |
| 70 | # key=value list of environment variables | 70 | # key=value list of environment variables |
| 71 | OCI_IMAGE_ENV_VARS ?= "" | 71 | OCI_IMAGE_ENV_VARS ?= "" |
| 72 | 72 | ||
| 73 | # ============================================================================= | ||
| 74 | # Build-time metadata for traceability | ||
| 75 | # ============================================================================= | ||
| 76 | # | ||
| 77 | # These variables embed source info into OCI image labels for traceability. | ||
| 78 | # Standard OCI annotations are used: https://github.com/opencontainers/image-spec/blob/main/annotations.md | ||
| 79 | # | ||
| 80 | # OCI_IMAGE_APP_RECIPE: Recipe name for the "main application" in the container. | ||
| 81 | # If set, future versions may auto-extract SRCREV/branch from this recipe. | ||
| 82 | # For now, it's documentation and a hook point. | ||
| 83 | # | ||
| 84 | # OCI_IMAGE_REVISION: Git commit SHA (short or full). | ||
| 85 | # - If set: uses this value | ||
| 86 | # - If empty: auto-detects from TOPDIR git repo | ||
| 87 | # - Set to "none" to disable | ||
| 88 | # | ||
| 89 | # OCI_IMAGE_BRANCH: Git branch name. | ||
| 90 | # - If set: uses this value | ||
| 91 | # - If empty: auto-detects from TOPDIR git repo | ||
| 92 | # - Set to "none" to disable | ||
| 93 | # | ||
| 94 | # OCI_IMAGE_BUILD_DATE: ISO 8601 timestamp. | ||
| 95 | # - Auto-generated at build time | ||
| 96 | # | ||
| 97 | # These become standard OCI labels: | ||
| 98 | # org.opencontainers.image.revision = OCI_IMAGE_REVISION | ||
| 99 | # org.opencontainers.image.ref.name = OCI_IMAGE_BRANCH | ||
| 100 | # org.opencontainers.image.created = OCI_IMAGE_BUILD_DATE | ||
| 101 | # org.opencontainers.image.version = PV (if meaningful) | ||
| 102 | |||
| 103 | # Application recipe for traceability (documentation/future use) | ||
| 104 | OCI_IMAGE_APP_RECIPE ?= "" | ||
| 105 | |||
| 106 | # Explicit overrides - if set, these are used instead of auto-detection | ||
| 107 | # Set to "none" to disable a specific label | ||
| 108 | OCI_IMAGE_REVISION ?= "" | ||
| 109 | OCI_IMAGE_BRANCH ?= "" | ||
| 110 | OCI_IMAGE_BUILD_DATE ?= "" | ||
| 111 | |||
| 112 | # Enable/disable auto-detection of git metadata (set to "0" to disable) | ||
| 113 | OCI_IMAGE_AUTO_LABELS ?= "1" | ||
| 114 | |||
| 73 | # whether the oci image dir should be left as a directory, or | 115 | # whether the oci image dir should be left as a directory, or |
| 74 | # bundled into a tarball. | 116 | # bundled into a tarball. |
| 75 | OCI_IMAGE_TAR_OUTPUT ?= "true" | 117 | OCI_IMAGE_TAR_OUTPUT ?= "true" |
