-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add build-push VM image build automation
Signed-off-by: Chris Evich <[email protected]>
- Loading branch information
Showing
9 changed files
with
392 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#!/bin/bash | ||
|
||
# This script allows stuffing a dnf cache directory with both | ||
# metadata and packages, for a list of architectures. It assumes | ||
# the same Fedora release version as the executing platform unless | ||
# $RELEASE is overriden. It requires the containers/automation | ||
# common libraries are installed and the following env. vars. are | ||
# non-empty: | ||
# | ||
# CACHEDIR - Directory path under which both metadata & packages will | ||
# be stored (under platform specific subdirectory tree). | ||
# ARCHES - Whitespace separated list of architecture names | ||
# PACKAGES - Whitespace separated list of packages to seed in cache | ||
|
||
set -ea | ||
[[ -n "$AUTOMATION_LIB_PATH" ]] || source /etc/automation_environment | ||
source $AUTOMATION_LIB_PATH/common_lib.sh | ||
set +a | ||
|
||
req_env_vars ARCHES PACKAGES CACHEDIR OS_RELEASE_VER SCRIPT_FILENAME DEBUG | ||
|
||
declare -a _ARCHES | ||
# We want to do word-splitting | ||
# shellcheck disable=SC2206 | ||
_ARCHES=( $ARCHES ) | ||
declare -a _PACKAGES | ||
# shellcheck disable=SC2206 | ||
_PACKAGES=( $PACKAGES ) | ||
|
||
RELEASE="${RELEASE:-$OS_RELEASE_VER}" | ||
|
||
# First arg must be name of architecture | ||
# Second arg must be either 'makecache' or 'download' | ||
dnfarch(){ | ||
local arch | ||
arch="$1" | ||
shift | ||
local cmd | ||
cmd=$1 | ||
[[ -n "$arch" ]] || die "Missing arch arument to dnfarch()" | ||
|
||
# Don't download into $PWD | ||
local ddarg | ||
if [[ "$cmd" == "download" ]]; then | ||
# Already checked by req_env_vars() | ||
# shellcheck disable=SC2154 | ||
ddarg="--downloaddir=$CACHEDIR" | ||
fi | ||
|
||
local mq="-q" | ||
local _showrun | ||
# Vars. already checked by req_env_vars() | ||
# shellcheck disable=SC2154 | ||
if ((DEBUG)); then | ||
_showrun="showrun" | ||
mq="" | ||
fi | ||
# Have to put --cachedir option path under here too, otherwise | ||
# metadata gets downloaded every run. | ||
$_showrun dnf --setopt=ignorearch=true --releasever="$RELEASE" \ | ||
--setopt=keepcache=true --setopt=cachedir="$CACHEDIR" \ | ||
$mq -y --setopt=arch=$arch $ddarg "$@" | ||
} | ||
|
||
wait_jobs() { | ||
local job | ||
dbg "Waiting for background jobs to complete." | ||
for job in "$@"; do | ||
dbg "Waiting on job '$job'" | ||
# This isn't perfect, it will miss special-case exit 127 but | ||
# this should be unlikely given the usage of this function. | ||
if ! wait -n $job; then | ||
dbg "Background job $job non-zero exit status" | ||
# This could be hard to debug, but being more verbose | ||
# about the failing command would unacceptably increasse | ||
# the scripts complexity. Rely on dnf's error messages | ||
# being useful. | ||
die "At least one operation failed, bailing out." | ||
fi | ||
dbg "Job '$job' complete" | ||
done | ||
jobs=() | ||
} | ||
|
||
for_each_arch() { | ||
local cmd | ||
local arch | ||
local -a jobs | ||
for arch in "${_ARCHES[@]}"; do | ||
# For display, command needs both whitespace and special quote handling. | ||
cmd=$(printf "%q " "dnfarch" "$arch" "$@") | ||
$cmd & | ||
jobs+=($!) | ||
dbg "New job $!: $cmd" | ||
done | ||
wait_jobs "${jobs[@]}" | ||
} | ||
|
||
mkdir -p "$CACHEDIR" | ||
|
||
msg "Downloading Fedora $RELEASE metadata in parallel" | ||
for_each_arch makecache | ||
|
||
msg "Downloading Fedora $RELEASE packages in parallel" | ||
for_each_arch download "${_PACKAGES[@]}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/* |
Oops, something went wrong.