Skip to content

Commit

Permalink
Merge pull request #28 from cevich/simplify_immutable
Browse files Browse the repository at this point in the history
Simplify immutable image tagging
  • Loading branch information
cevich authored Apr 30, 2024
2 parents 1f8ea2a + 5c14eec commit c95cda1
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 60 deletions.
3 changes: 0 additions & 3 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,6 @@ test_image_build_task:
- env:
FLAVOR_NAME: stable
matrix: *pbs_images
- env:
FLAVOR_NAME: immutable
matrix: *pbs_images
script: &pbs_script |
source /etc/automation_environment
./ci/containers_build_push.sh ${CIRRUS_REPO_CLONE_URL} ${CTX_SUB} ${FLAVOR_NAME}
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ or `skopeo`:
`vX.Y`, and `vX.Y.Z`) the image contents will be updated daily to incorporate
(especially) security updates.
* `quay.io/containers/*:<version>-immutable` - Uses the same source as the 'stable'
images, is built daily, but version-tags are never overwritten once pushed. This is
intended for users that value an unchanging image tag and digest over having daily
security updates. All three `<version>` values are available, `vX-immutable`,
images, built daily, but version-tags are never overwritten once pushed. Tags
will only be removed in case of an extreme security problem. Otherwise, these
images are intended for users that value an unchanging image tag and digest over
daily security updates. All three `<version>` values are available, `vX-immutable`,
`vX.Y-immutable` and `vX.Y.Z-immutable`.
* `quay.io/containers/*:latest` and `quay.io/*/stable:latest` -
Built daily using the same `Containerfile` as above. The tool versions
Expand Down
21 changes: 6 additions & 15 deletions ci/containers_build_push.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#
# The third argument indicates the image "FLAVOR", which will be passed into
# the build as a `--build-arg`. This is used by the `Containerfile` to alter
# the build to produce a 'stable', 'immutable', 'testing', or 'upstream' image.
# the build to produce a 'stable' (with 'immutable'), 'testing', or 'upstream' image.
# Importantly, this value also determines where the image is pushed, see the
# top-level README.md for more details.
#
Expand Down Expand Up @@ -87,10 +87,6 @@ if [[ "$CTX_SUB" =~ testing ]]; then
fi

REPO_FQIN="$_REG/$CTX_SUB/$FLAVOR_NAME"
if [[ "$FLAVOR_NAME" == "immutable" ]]; then
# Only the image version-tag varies
REPO_FQIN="$_REG/$CTX_SUB/stable"
fi
req_env_vars REPO_URL CTX_SUB FLAVOR_NAME

# Common library defines SCRIPT_FILENAME
Expand All @@ -115,11 +111,7 @@ fi
### MAIN

declare -a build_args
if [[ "$FLAVOR_NAME" == "immutable" ]]; then
build_args=("--build-arg=FLAVOR=stable")
else
build_args=("--build-arg=FLAVOR=$FLAVOR_NAME")
fi
build_args=("--build-arg=FLAVOR=$FLAVOR_NAME")

head_sha=$(git rev-parse HEAD)
dbg "HEAD is $head_sha"
Expand Down Expand Up @@ -172,7 +164,7 @@ done
modcmdarg="$SCRIPT_PATH/tag_version.sh $FLAVOR_NAME"

# For stable images, the version number of the command is needed for tagging and labeling.
if [[ "$FLAVOR_NAME" == "stable" || "$FLAVOR_NAME" == "immutable" ]]; then
if [[ "$FLAVOR_NAME" == "stable" ]]; then
# only native arch is needed to extract the version
dbg "Building temporary local-arch image to extract $FLAVOR_NAME version number"
fqin_tmp="$CTX_SUB:temp"
Expand Down Expand Up @@ -206,9 +198,8 @@ if [[ "$FLAVOR_NAME" == "stable" || "$FLAVOR_NAME" == "immutable" ]]; then
label_args+=("$arg=org.opencontainers.image.url=https://$_REG/containers/$CTX_SUB")
done

# Stable images get pushed to 'containers' namespace as latest & version-tagged.
# Immutable images are only version-tagged, and are never pushed if they already
# exist.
# Stable (with immutable) images get pushed to 'containers' namespace as latest & version-tagged.
# Immutable images are never pushed if they already exist.
showrun build-push.sh \
$_DRNOPUSH \
--arches="$ARCHES" \
Expand All @@ -232,7 +223,7 @@ for arg in "--label" "--annotation"; do
done

# All flavors are pushed to quay.io/<reponame>/<flavor>, both
# latest and version-tagged (if available). Stable + Immutable
# latest and version-tagged (if available). Immutable
# images are only version-tagged, and are never pushed if they
# already exist.
showrun build-push.sh \
Expand Down
34 changes: 16 additions & 18 deletions ci/tag_version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ fi
# Given the image tag as an argument, apply the tag as appropriate given $FLAVOR_NAME
# N/B: For the "immutable" flavor, the tag will have `-immutable` appended to it.
handle_tagging() {
local existing
local tag
local existing tag imtag
tag="$1"

[[ -n "$tag" ]] || \
Expand All @@ -60,32 +59,37 @@ handle_tagging() {
[[ "$tag" != "latest" ]] || \
die "handle_tagging() must never be run with tag argument 'latest'."

if [[ "$FLAVOR_NAME" == "immutable" ]]; then
tag="${tag}-immutable"

# Stable images get <version>-immutable tags only if they don't already exist
if [[ "$FLAVOR_NAME" == "stable" ]]; then
imtag="${tag}-immutable"
# ci/test.sh tests never push, there's never any remote image to check.
existing=""

# The FQIN envar is defined by the build-push.sh caller
# shellcheck disable=SC2154
if [[ ! "$FQIN" =~ testing ]]; then
existing=$(skopeo list-tags docker://$FQIN | jq -e -r '.Tags[]')
if grep -F -x -q "$tag" <<<"$existing"; then
msg "Skipping; $FQIN:$tag already exists in registry."
return 0
fi
fi

if grep -F -x -q "$imtag" <<<"$existing"; then
msg "Skipping; $FQIN:$imtag already exists in registry."
else
msg "Tagging new $FQIN:${tag}-immutable"
# The RUNTIME envar is defined by the build-push.sh caller
# shellcheck disable=SC2154
$RUNTIME tag $FQIN:latest $FQIN:$imtag
fi
fi

dbg "Tagging $FQIN:latest $FQIN:$tag"
# The RUNTIME envar is defined by the build-push.sh caller
# shellcheck disable=SC2154
$RUNTIME tag $FQIN:latest $FQIN:$tag
msg "Successfully tagged $FQIN:$tag"
}

# shellcheck disable=SC2154
dbg "$SCRIPT_FILENAME operating on '$FLAVOR_NAME' flavor of '$FQIN' with tool version '$VERSION' (optional)"

if [[ "$FLAVOR_NAME" == "stable" || "$FLAVOR_NAME" == "immutable" ]]; then
if [[ "$FLAVOR_NAME" == "stable" ]]; then
# Stable images must all be tagged with a version number.
# Confirm this value is passed in by caller.
if grep -E -q '^v[0-9]+\.[0-9]+\.[0-9]+'<<<"$VERSION"; then
Expand All @@ -103,12 +107,6 @@ if [[ "$FLAVOR_NAME" == "stable" || "$FLAVOR_NAME" == "immutable" ]]; then
# Tag as x to provide consistent tag even for a future y+1
x_ver=$(awk -F '.' '{print $1}'<<<"$xy_ver")
handle_tagging $x_ver

# handle_tagging() uses $FQIN:latest as the source, but there can never be an immutable 'latest'.
if [[ "$FLAVOR_NAME" == "immutable" ]]; then
$RUNTIME manifest rm $FQIN:latest || $RUNTIME rm $FQIN:latest
msg "Successfully removed non-immutable $FQIN:latest"
fi
elif [[ "$FLAVOR_NAME" == "aio" ]]; then
# Not a real flavor, see aio_build_push.sh
handle_tagging $VERSION
Expand Down
48 changes: 27 additions & 21 deletions ci/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,22 @@ TEST_REVISION=$(git rev-parse HEAD)

TEST_REPO_URL="file://$SRC_TMP"

# Print an error message and exit non-zero if the FQIN:TAG indicated
# by the first argument does not exist.
manifest_exists() {
msg "Confirming existence of manifest list '$1'"
if ! showrun podman manifest exists "$1"; then
die "Failed to find expected manifest-list '$1'"
fi
}

# Given the flavor-name as the first argument, verify built image
# expectations. For 'stable' image, verify that containers_build_push.sh will properly
# version-tagged both FQINs. For 'immutable' verify version tags only for TEST_FQIN2.
# For other flavors, verify expected labels on the `latest` tagged FQINs.
verify_built_images() {
local _fqin _arch xy_ver x_ver img_ver img_src img_rev _fltr
local _test_tag expected_flavor _test_fqins img_docs
local test_tag expected_flavor _test_fqins img_docs
expected_flavor="$1"
msg "
##### Testing execution of '$expected_flavor' images for arches $TESTARCHES #####"
Expand All @@ -82,38 +91,35 @@ verify_built_images() {
test_tag="v$FAKE_VERSION"
xy_ver="v$FAKE_VER_X.$FAKE_VER_Y"
x_ver="v$FAKE_VER_X"
elif [[ "$expected_flavor" == "immutable" ]]; then
expected_flavor="stable" # Only the tags are different
_test_fqins=("$TEST_FQIN" "$TEST_FQIN2")
test_tag="v$FAKE_VERSION-immutable"
xy_ver="v$FAKE_VER_X.$FAKE_VER_Y-immutable"
x_ver="v$FAKE_VER_X-immutable"
else
test_tag="latest"
xy_ver="latest"
x_ver="latest"
fi

for _fqin in "${_test_fqins[@]}"; do
manifest_exists $_fqin:$test_tag

if [[ "$expected_flavor" == "stable" ]]; then
manifest_exists $_fqin:$xy_ver
manifest_exists $_fqin:$x_ver
manifest_exists $_fqin:${test_tag}-immutable
manifest_exists $_fqin:${xy_ver}-immutable
manifest_exists $_fqin:${x_ver}-immutable

msg "Confirming there is no 'latest-immutable' tag"
if showrun podman manifest exists $_fqin:latest-immutable; then
die "The latest tag must never ever have an immutable suffix"
fi
fi

for _arch in $TESTARCHES; do
msg "Testing container can execute '/bin/true'"
showrun podman run -i --arch=$_arch --rm "$_fqin:$test_tag" /bin/true

msg "Testing container FLAVOR build-arg passed correctly"
showrun podman run -i --arch=$_arch --rm "$_fqin:$test_tag" \
cat /FLAVOUR | tee /dev/stderr | grep -Fxq "FLAVOUR=$expected_flavor"

if [[ "$expected_flavor" == "stable" ]]; then
msg "Testing tag '$xy_ver'"
if ! showrun podman manifest exists $_fqin:$xy_ver; then
die "Failed to find manifest-list tagged '$xy_ver'"
fi

msg "Testing tag '$x_ver'"
if ! showrun podman manifest exists $_fqin:$x_ver; then
die "Failed to find manifest-list tagged '$x_ver'"
fi
fi
done

if [[ "$expected_flavor" == "stable" ]]; then
Expand Down Expand Up @@ -175,7 +181,7 @@ remove_built_images() {
for fqin in $TEST_FQIN $TEST_FQIN2; do
for tag in "${tags[@]}"; do
# Not all tests produce every possible tag
podman manifest rm $fqin:$tag || true
podman manifest rm $fqin:$tag &> /dev/null || true
done
done
}
Expand All @@ -186,7 +192,7 @@ _cbp=$CIRRUS_WORKING_DIR/ci/containers_build_push.sh

cd $SRC_TMP

for flavor_arg in stable foobarbaz immutable; do
for flavor_arg in stable foobarbaz; do
msg "
##### Testing build-push $flavor_arg flavor run of '$TEST_FQIN' & '$TEST_FQIN2' #####"
remove_built_images
Expand Down

0 comments on commit c95cda1

Please sign in to comment.