Skip to content

Commit

Permalink
Merge pull request #97 from cevich/build_push
Browse files Browse the repository at this point in the history
Build push
  • Loading branch information
cevich authored Mar 24, 2022
2 parents 752b774 + fb9e50b commit 1501326
Show file tree
Hide file tree
Showing 10 changed files with 398 additions and 11 deletions.
20 changes: 20 additions & 0 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ cache_images_task:
- <<: *cache_image
env:
PACKER_BUILDS: "ubuntu"
- <<: *cache_image
env:
PACKER_BUILDS: "build-push"
env:
GAC_JSON: ENCRYPTED[7fba7fb26ab568ae39f799ab58a476123206576b0135b3d1019117c6d682391370c801e149f29324ff4b50133012aed9]
script: "ci/make_cache_images.sh"
Expand Down Expand Up @@ -238,6 +241,7 @@ imgts_task:
fedora-netavark-c${IMG_SFX}
fedora-podman-py-c${IMG_SFX}
ubuntu-c${IMG_SFX}
build-push-c${IMG_SFX}
clone_script: &noop mkdir -p "${CIRRUS_WORKING_DIR}" # source is not needed
script: "/usr/local/bin/entrypoint.sh"

Expand Down Expand Up @@ -311,6 +315,21 @@ test_get_ci_vm_task:
test_script: "get_ci_vm/test.sh"


test_build-push_task:
name: "Test build-push VM functions"
alias: test_build-push
depends_on:
- cache_images
gce_instance:
image_project: "libpod-218412"
image_name: "build-push-c${IMG_SFX}"
zone: "us-central1-a"
disk: 200
# More muscle to emulate multi-arch
type: "n2-standard-4"
script: bash ./build-push/test.sh


# N/B: "latest" image produced after PR-merge (branch-push)
cron_imgobsolete_task: &lifecycle_cron
name: "Periodicly mark old images obsolete"
Expand Down Expand Up @@ -353,6 +372,7 @@ success_task:
- cron_imgprune
- test_gcsupld
- test_get_ci_vm
- test_build-push
container:
<<: *ci_container
clone_script: *noop
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ see step 4 below.
* The bulk of the packaging work occurs next, from the `cache_images/*_packaging.sh`
scripts. **This is most likely what you want to modify.**

* Unlike the Fedora and Ubuntu scripts, the `build-push` VM image is not
for general-purpose use. It's intended to be used by it's embedded
`main.sh` script, in downstream repositories for building container images.
The image and `main.sh` are both tightly coupled with `build-push` tool
in the
[containers/automation repository](https://github.com/containers/automation).

* Some non-packaged/source-based tooling is installed using the
`cache_images/podman_tooling.sh` script. These are slightly fragile, as
they always come from upstream (master) podman. Avoid adding/changing
Expand Down
5 changes: 5 additions & 0 deletions build-push/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# DO NOT USE

This directory contains scripts/data used by the Cirrus-CI
`test_build-push` task. It is not intended to be used otherwise
and may cause harm.
139 changes: 139 additions & 0 deletions build-push/bin/main.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#!/bin/bash

# This script is not intended for humans. It should be run by automation
# at the branch-level in automation for the skopeo, buildah, and podman
# repositories. It's purpose is to produce a multi-arch container image
# based on the contents of context subdirectory. At runtime, $PWD is assumed
# to be the root of the cloned git repository.
#
# The first argument to the script, should be the URL of the git repository
# in question. Though at this time, this is only used for labeling the
# resulting image.
#
# The second argument to this script is the relative path to the build context
# subdirectory. The basename of this subdirectory indicates the
# type of image being built (i.e. `upstream`, `testing`, or `stable`).
# Depending on this value, the image may be pushed to multiple container
# registries.

set -eo pipefail

if [[ -r "/etc/automation_environment" ]]; then
source /etc/automation_environment # defines AUTOMATION_LIB_PATH
#shellcheck disable=SC1090,SC2154
source "$AUTOMATION_LIB_PATH/common_lib.sh"
else
echo "Expecting to find automation common library installed."
exit 1
fi

if [[ -z $(type -P build-push.sh) ]]; then
die "It does not appear that build-push.sh is installed properly"
fi

if ! [[ -d "$PWD/.git" ]]; then
die "The current directory ($PWD) does not appear to be the root of a git repo."
fi

# Assume transitive debugging state for build-push.sh if set
export DEBUG

# Arches to build by default - may be overridden for testing
ARCHES="${ARCHES:-amd64,ppc64le,s390x,arm64}"

# First arg (REPO_URL) is the clone URL for repository for informational purposes
REPO_URL="$1"
REPO_NAME=$(basename "${REPO_URL%.git}")
# Second arg (CTX_SUB) is the context subdirectory relative to the clone path
CTX_SUB="$2"
# Basename of second arg names the image contents
CTX_NAME=$(basename "$CTX_SUB")
_REG="quay.io"
if [[ "$REPO_NAME" =~ testing ]]; then
_REG="example.com"
fi
REPO_FQIN="$_REG/$REPO_NAME/$CTX_NAME"
req_env_vars REPO_URL REPO_NAME CTX_SUB CTX_NAME

# Common library defines SCRIPT_FILENAME
# shellcheck disable=SC2154
dbg "$SCRIPT_FILENAME operating constants:
REPO_URL=$REPO_URL
REPO_NAME=$REPO_NAME
CTX_SUB=$CTX_SUB
CTX_NAME=$CTX_NAME
REPO_FQIN=$REPO_FQIN
"

# Set non-zero to avoid actually executing build-push, simply print
# the command-line that would have been executed
DRYRUN=${DRYRUN:-0}
_DRNOPUSH=""
if ((DRYRUN)); then
_DRNOPUSH="--nopush"
warn "Operating in dry-run mode with $_DRNOPUSH"
fi

### MAIN

head_sha=$(git rev-parse HEAD)
dbg "HEAD is $head_sha"
# Labels to add to all images
# N/B: These won't show up in the manifest-list itself, only it's constituents.
lblargs="\
--label=org.opencontainers.image.source=$REPO_URL \
--label=org.opencontainers.image.revision=$head_sha \
--label=org.opencontainers.image.created=$(date -u --iso-8601=seconds)"
dbg "lblargs=$lblargs"

# tag_version.sh is sensitive to this value if set
export img_cmd_version=""

# For stable images, the version number of the command is needed for tagging.
if [[ "$CTX_NAME" == "stable" ]]; then
# only native arch is needed to extract the version
dbg "Building local-arch image to extract stable version number"
podman build -t $REPO_FQIN ./$CTX_SUB

case "$REPO_NAME" in
skopeo) version_cmd="--version" ;;
buildah) version_cmd="buildah --version" ;;
podman) version_cmd="podman --version" ;;
testing) version_cmd="cat FAKE_VERSION" ;;
*) die "Unknown/unsupported repo '$REPO_NAME'" ;;
esac

pvcmd="podman run -i --rm $REPO_FQIN $version_cmd"
dbg "Extracting version with command: $pvcmd"
version_output=$($pvcmd)
dbg "version output:
$version_output
"
img_cmd_version=$(awk -r -e '/^.+ version /{print $3}' <<<"$version_output")
dbg "parsed version: $img_cmd_version"
test -n "$img_cmd_version"
lblargs="$lblargs --label=org.opencontainers.image.version=$img_cmd_version"
# Prevent temporary build colliding with multi-arch manifest list (built next)
# but preserve image (by ID) for use as cache.
dbg "Un-tagging $REPO_FQIN"
podman untag $REPO_FQIN

# Stable images get pushed to 'containers' namespace as latest & version-tagged
build-push.sh \
$_DRNOPUSH \
--arches=$ARCHES \
--modcmd=tag_version.sh \
$_REG/containers/$REPO_NAME \
./$CTX_SUB \
$lblargs
fi

# All images are pushed to quay.io/<reponame>, both
# latest and version-tagged (if available).
build-push.sh \
$_DRNOPUSH \
--arches=$ARCHES \
--modcmd=tag_version.sh \
$REPO_FQIN \
./$CTX_SUB \
$lblargs
43 changes: 43 additions & 0 deletions build-push/bin/tag_version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/bash

# This script is not intended for humans. It should only be referenced
# as an argument to the build-push.sh `--modcmd` option. It's purpose
# is to ensure stable images are re-tagged with a verison-number
# cooresponding to the included tool's version.

set -eo pipefail

if [[ -r "/etc/automation_environment" ]]; then
source /etc/automation_environment # defines AUTOMATION_LIB_PATH
#shellcheck disable=SC1090,SC2154
source "$AUTOMATION_LIB_PATH/common_lib.sh"
else
echo "Unexpected operating environment"
exit 1
fi

# Vars defined by build-push.sh spec. for mod scripts
req_env_vars SCRIPT_FILEPATH RUNTIME PLATFORMOS FQIN CONTEXT \
PUSH ARCHES REGSERVER NAMESPACE IMGNAME MODCMD

# As in main.sh, the context name comes from subdir basename
# shellcheck disable=SC2154
CTX_NAME=$(basename "$CONTEXT") # upstream, testing, or stable

# shellcheck disable=SC2154
dbg "Mod-command operating on $FQIN in $CTX_NAME context"

if [[ "$CTX_NAME" == "stable" ]]; then
# Stable images must all be tagged with a version number.
# Confirm this value is passed in by shell env. var. since
# retrieving it from the image content is beyond the scope
# of this script.
req_env_vars img_cmd_version
# shellcheck disable=SC2154
msg "Found image command version '$img_cmd_version'"
# shellcheck disable=SC2154
$RUNTIME tag $FQIN:latest $FQIN:$img_cmd_version
msg "Successfully tagged $FQIN:$img_cmd_version"
else
warn "Not tagging '$CTX_NAME' context of '$FQIN'"
fi
88 changes: 88 additions & 0 deletions build-push/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@


# DO NOT USE - This script is intended to be called by the Cirrus-CI
# `test_build-push` task. It is not intended to be used otherwise
# and may cause harm. It's purpose is to confirm the 'main.sh' script
# behaves in an expected way, given a local test repository as input.

set -e
SCRIPT_DIRPATH=$(dirname $(realpath "${BASH_SOURCE[0]}"))
source $SCRIPT_DIRPATH/../lib.sh

req_env_vars CIRRUS_CI

# Architectures to test with (golang standard names)
TESTARCHES="amd64 arm64"
# main.sh is sensitive to this value
ARCHES=$(tr " " ","<<<"$TESTARCHES")
export ARCHES
# Contrived "version" for testing purposes
FAKE_VERSION=$RANDOM
# Contrived source repository for testing
SRC_TMP=$(mktemp -p '' -d tmp-build-push-test-XXXX)
# Do not change, main.sh is sensitive to the 'testing' name
TEST_FQIN=example.com/testing/stable
# Stable build should result in manifest list tagged this
TEST_FQIN2=example.com/containers/testing

trap "rm -rf $SRC_TMP" EXIT

# main.sh expects $PWD to be a git repository.
msg "Constructing local test repository"
cd $SRC_TMP
showrun git init -b main testing
cd testing
git config --local user.name "Testy McTestface"
git config --local user.email "[email protected]"
git config --local advice.detachedHead "false"
git config --local commit.gpgsign "false"
# The following paths match the style of sub-dir in the actual
# skopeo/buildah/podman repositories. Only the 'stable' flavor
# is tested here, since it involves the most complex workflow.
mkdir -vp "contrib/testimage/stable"
cd "contrib/testimage/stable"
echo "build-push-test version $FAKE_VERSION" | tee "FAKE_VERSION"
cat <<EOF | tee "Containerfile"
FROM registry.fedoraproject.org/fedora:latest
ADD /FAKE_VERSION /
RUN dnf install -y iputils
EOF
cd $SRC_TMP/testing
git add --all
git commit -m 'test repo initial commit'

msg "Building test image '$TEST_FQIN' (in debug/dry-run mode)"
buildah --version
export DRYRUN=1 # Force main.sh not to push anything
req_env_vars ARCHES DRYRUN
# main.sh is sensitive to 'testing' value.
# also confirms main.sh is on $PATH
env DEBUG=1 main.sh git://testing contrib/testimage/stable

# Because this is a 'stable' image, verify that main.sh will properly
# version-tagged both FQINs. No need to check 'latest'.
msg "Testing 'stable' images tagged '$FAKE_VERSION' for arches $TESTARCHES"
podman --version
req_env_vars TESTARCHES FAKE_VERSION TEST_FQIN TEST_FQIN2
for _fqin in $TEST_FQIN $TEST_FQIN2; do
for _arch in $TESTARCHES; do
# As of podman 3.4.4, the --arch=$arch argument will cause failures
# looking up the image in local storage. This bug is fixed in later
# versions. For now, query the manifest directly for the image sha256.
_q='.manifests[] | select(.platform.architecture == "'"$_arch"'") | .digest'
_s=$(podman manifest inspect $_fqin:$FAKE_VERSION | jq -r "$_q")
msg "Found '$_arch' in manifest-list $_fqin:$FAKE_VERSION as digest $_s"
if [[ -z "$_s" ]]; then
die "Failed to get sha256 for FQIN '$_fqin:$FAKE_VERSION' ($_arch)"
fi
msg "Testing container can ping localhost"
showrun podman run -i --rm "$_fqin@$_s" ping -q -c 1 127.0.0.1

#TODO: Test org.opencontainers.image.source value
#TODO: fails, returns null for some reason
#msg "Confirming version-label matches tag"
#_q='.[0].Labels."org.opencontainers.image.version"'
#_v=$(podman image inspect "$_fqin@$_s" | jq -r "$_q")
#showrun test $_v -eq $FAKE_VERSION
done
done
45 changes: 45 additions & 0 deletions cache_images/build-push_packaging.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/bash

# This script is called from build-push_setup.sh by packer. It's not intended
# to be used outside of those contexts. It assumes the lib.sh library has
# already been sourced, and that all "ground-up" package-related activity
# needs to be done, including repository setup and initial update.

set -e

SCRIPT_FILEPATH=$(realpath "$0")
SCRIPT_DIRPATH=$(dirname "$SCRIPT_FILEPATH")
REPO_DIRPATH=$(realpath "$SCRIPT_DIRPATH/../")

# shellcheck source=./lib.sh
source "$REPO_DIRPATH/lib.sh"

# packer and/or a --build-arg define this envar value uniformly
# for both VM and container image build workflows.
req_env_vars PACKER_BUILD_NAME

msg "Updating/Installing repos and packages for $OS_REL_VER"

bigto ooe.sh $SUDO dnf update -y

INSTALL_PACKAGES=(\
buildah
jq
podman
qemu-user-static
skopeo
)

echo "Installing general build/test dependencies"
bigto $SUDO dnf install -y "${INSTALL_PACKAGES[@]}"

# It was observed in F33, dnf install doesn't always get you the latest/greatest
lilto $SUDO dnf update -y

# Re-install with the 'build-push' component
install_automation_tooling build-push

# Install main scripts into directory on $PATH
set -x
$SUDO cp $REPO_DIRPATH/build-push/bin/* $AUTOMATION_LIB_PATH/../bin/
$SUDO chmod +x $AUTOMATION_LIB_PATH/../bin/*
Loading

0 comments on commit 1501326

Please sign in to comment.