Skip to content

Commit

Permalink
Provide, and use, a buildah script to construct zbm-builder images
Browse files Browse the repository at this point in the history
Using buildah directly provides flexibility that can not be achieved
with a Dockerfile. It also prevents the layer problem that bloats image
sizes, avoiding the need to squash the image.

Closes #230.
  • Loading branch information
ahesford committed Nov 17, 2021
1 parent fdb22b3 commit 6789ee2
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 14 deletions.
32 changes: 26 additions & 6 deletions releng/docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,28 @@ the commands should work just as well by substituting `docker` for `podman`.

# Creating a ZFSBootMenu Builder Image

The provided `Dockerfile` automates creation of the ZFSBootMenu builder image.
From this directory, simply run
The script `image-build.sh` uses `buildah` to construct a ZBM builder image.
This is the preferred way to construct the image and may, in the future,
provide features not available with a `podman build` workflow. The script
requires a single argument, the tag to use when naming the image.

An optional second argument is a Git commit-like reference (a hash or tag) that
will be recorded as `/etc/zbm-commit-hash` in the image. The contents of this
file are used to checkout a specific state of the ZFSBootMenu repository. If
the tag is unspecified on the command line, the build script will attempt to
capture a reference to the current HEAD commit if the image is built in an
active git repository. If a commit-like name is not provided and cannot be
discovered, no default will be recorded and containers will attempt to build
from the current `master`.

The `image-build.sh` script expects to be run from the root of the ZFSBootMenu
tree by default. From there, the path `releng/docker/zbm-build.sh` defines the
entrypoint for build containers. To run the `image-build.sh` script from
another directory, simply set the `ZBM_BUILDER` environment variable to the
location of the `zbm-build.sh` script to use.

For those without access to `buildah`, the `Dockerfile` will also create of a
ZFSBootMenu builder image. From this directory, simply run

```sh
podman build --squash -t zbm .
Expand All @@ -34,10 +54,10 @@ the latest release version packaged for Void; manually editing the `Dockerfile`
to add new dependencies may be necessary until a new release is packaged.

The builder image does **not** contain a ZFSBootMenu installation or a copy of
the upstream git repository. Instead, the image contains a build script,
installed as `/zbm-build.sh`, that runs by default. The script ensures that a
ZFSBootMenu repository is available in a running container and invokes
`generate-zbm` to build images.
the upstream git repository. Instead, the entrypoint `/zbm-build.sh` will fetch
a ZFSBootMenu archive when the container is instantiated (or allow a local copy
to be bind-mounted) and, as noted above, attempt to check out a specific commit
based on the contents of `/etc/zbm-commit-hash`.

# Running a ZFSBootMenu Builder Container

Expand Down
73 changes: 73 additions & 0 deletions releng/docker/image-build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/bin/sh
# vim: softtabstop=2 shiftwidth=2 expandtab

set -o errexit

# A tag for the image is required
tag="${1}"
if [ -z "${tag}" ]; then
echo "USAGE: $0 <tag> [zbm-commit-like]"
exit 1
fi

# If a commit hash is unspecified, try to pull HEAD from git
zbm_commit_hash="$2"
if [ -z "${zbm_commit_hash}" ]; then
if ! zbm_commit_hash="$(git rev-parse HEAD 2>/dev/null)"; then
unset zbm_commit_hash
fi
fi

if [ -z "${ZBM_BUILDER}" ]; then
ZBM_BUILDER="./releng/docker/zbm-build.sh"
fi

if [ ! -r "${ZBM_BUILDER}" ]; then
echo "ERROR: cannot find build script at ${ZBM_BUILDER}"
echo "Run from ZFSBootMenu root or override \$ZBM_BUILDER"
exit 1
fi

maintainer="ZFSBootMenu Team, https://zfsbootmenu.org"
container="$(buildah from voidlinux/voidlinux:latest)"

buildah config --label author="${maintainer}" "${container}"

# Make sure image is up to date
buildah run "${container}" xbps-install -Syu xbps
buildah run "${container}" xbps-install -yu

# Prefer an LTS version over whatever Void thinks is current
buildah run "${container}" sh -c "cat > /etc/xbps.d/10-nolinux.conf" <<-EOF
ignorepkg=linux
ignorepkg=linux-headers
EOF

# Install ZFSBootMenu dependencies and components necessary to build images
buildah run "${container}" \
sh -c 'xbps-query -Rp run_depends zfsbootmenu | xargs xbps-install -y'
buildah run "${container}" xbps-install -y \
linux5.10 linux5.10-headers gummiboot-efistub curl yq-go bash kbd terminus-font

# Remove headers and development toolchain, but keep binutils for objcopy
buildah run "${container}" sh -c 'echo "ignorepkg=dkms" > /etc/xbps.d/10-nodkms.conf'
buildah run "${container}" xbps-pkgdb -m manual binutils
buildah run "${container}" xbps-remove -Roy linux5.10-headers dkms
buildah run "${container}" sh -c 'rm -f /var/cache/xbps/*'

# Record a commit hash if one is available
if [ -n "${zbm_commit_hash}" ]; then
echo "${zbm_commit_hash}" | \
buildah run "${container}" sh -c 'cat > /etc/zbm-commit-hash'
fi

buildah copy "${container}" "${ZBM_BUILDER}" /zbm-build.sh
buildah run "${container}" chmod 755 /zbm-build.sh

buildah config \
--workingdir / \
--entrypoint '[ "/zbm-build.sh" ]' \
--cmd '[ ]' \
"${container}"

buildah commit --rm "${container}" "${tag}"
12 changes: 4 additions & 8 deletions releng/make-binary.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,13 @@ esac

buildtag="${2:-localhost/zbm-builder:$(date '+%Y%m%d')}"
if ! podman inspect "${buildtag}" >/dev/null 2>&1; then
if ! bldctx="$( realpath -e releng/docker )"; then
error "missing releng/docker, cannot create image ${buildtag}"
fi

build_args=( "--squash" )
build_args=( "${buildtag}" )

if ZBM_COMMIT_HASH="$(git rev-parse HEAD)" && [ -n "${ZBM_COMMIT_HASH}" ]; then
build_args+=( "--build-arg=ZBM_COMMIT_HASH=${ZBM_COMMIT_HASH}" )
if [ -n "${ZBM_COMMIT_HASH}" ]; then
build_args+=( "${ZBM_COMMIT_HASH}" )
fi

if ! podman build -t "${buildtag}" "${build_args[@]}" "${bldctx}"; then
if ! ./releng/docker/image-build.sh "${build_args[@]}"; then
error "failed to create builder image"
fi
fi
Expand Down

0 comments on commit 6789ee2

Please sign in to comment.