Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled
94 lines
2.6 KiB
Bash
94 lines
2.6 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Multi-arch buildx helper for DEVOPS-CONTAINERS-44-001
|
|
# Requirements: docker CLI with buildx, optional syft (for SBOM) and cosign (for signing).
|
|
|
|
usage() {
|
|
echo "Usage: $0 <image-tag> <context-dir> [--platform linux/amd64,linux/arm64] [--push] [--sbom syft|none] [--sign <cosign-key>]" >&2
|
|
exit 64
|
|
}
|
|
|
|
if [[ $# -lt 2 ]]; then
|
|
usage
|
|
fi
|
|
|
|
IMAGE_TAG=$1; shift
|
|
CONTEXT_DIR=$1; shift
|
|
|
|
PLATFORMS="linux/amd64,linux/arm64"
|
|
PUSH=false
|
|
SBOM_TOOL="syft"
|
|
COSIGN_KEY=""
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--platform) PLATFORMS="$2"; shift 2;;
|
|
--push) PUSH=true; shift;;
|
|
--sbom) SBOM_TOOL="$2"; shift 2;;
|
|
--sign) COSIGN_KEY="$2"; shift 2;;
|
|
*) echo "Unknown option: $1" >&2; usage;;
|
|
esac
|
|
done
|
|
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
echo "[buildx] docker CLI not found" >&2
|
|
exit 69
|
|
fi
|
|
|
|
OUT_ROOT="out/buildx/$(echo "$IMAGE_TAG" | tr '/:' '__')"
|
|
mkdir -p "$OUT_ROOT"
|
|
|
|
BUILDER_NAME="stellaops-multiarch"
|
|
if ! docker buildx inspect "$BUILDER_NAME" >/dev/null 2>&1; then
|
|
docker buildx create --name "$BUILDER_NAME" --driver docker-container --use >/dev/null
|
|
else
|
|
docker buildx use "$BUILDER_NAME" >/dev/null
|
|
fi
|
|
|
|
BUILD_OPTS=(
|
|
--platform "$PLATFORMS"
|
|
-t "$IMAGE_TAG"
|
|
--provenance=false
|
|
--sbom=false
|
|
--output "type=oci,dest=${OUT_ROOT}/image.oci"
|
|
)
|
|
|
|
if $PUSH; then
|
|
BUILD_OPTS+=("--push")
|
|
fi
|
|
|
|
echo "[buildx] building $IMAGE_TAG for $PLATFORMS"
|
|
docker buildx build "${BUILD_OPTS[@]}" "$CONTEXT_DIR"
|
|
|
|
echo "[buildx] computing digest"
|
|
IMAGE_DIGEST=$(sha256sum "${OUT_ROOT}/image.oci" | awk '{print $1}')
|
|
echo "$IMAGE_DIGEST image.oci" > "${OUT_ROOT}/image.sha256"
|
|
|
|
if [[ "$SBOM_TOOL" == "syft" ]] && command -v syft >/dev/null 2>&1; then
|
|
echo "[buildx] generating SBOM via syft"
|
|
syft "oci-archive:${OUT_ROOT}/image.oci" -o json > "${OUT_ROOT}/sbom.syft.json"
|
|
else
|
|
echo "[buildx] skipping SBOM (tool=$SBOM_TOOL, syft available? $(command -v syft >/dev/null && echo yes || echo no))"
|
|
fi
|
|
|
|
if [[ -n "$COSIGN_KEY" ]] && command -v cosign >/dev/null 2>&1; then
|
|
echo "[buildx] signing digest with cosign key"
|
|
COSIGN_EXPERIMENTAL=1 cosign sign-blob --key "$COSIGN_KEY" --output-signature "${OUT_ROOT}/image.sig" --output-certificate "${OUT_ROOT}/image.cert" "${OUT_ROOT}/image.oci"
|
|
else
|
|
echo "[buildx] signature skipped (no key provided or cosign missing)"
|
|
fi
|
|
|
|
cat > "${OUT_ROOT}/build-metadata.json" <<EOF
|
|
{
|
|
"image": "${IMAGE_TAG}",
|
|
"platforms": "${PLATFORMS}",
|
|
"pushed": ${PUSH},
|
|
"digest_sha256": "${IMAGE_DIGEST}",
|
|
"generated_at": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
|
|
"sbom": "$( [[ -f ${OUT_ROOT}/sbom.syft.json ]] && echo sbom.syft.json || echo null )"
|
|
}
|
|
EOF
|
|
|
|
echo "[buildx] artifacts written to ${OUT_ROOT}"
|