Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,48 @@ When running RKE2 you will also need to install these packages:
make
```

## Local Docker Image Build

### Image Targets
- `build-env`: toolchain/build container (not runnable as an rke2 server)
- `runtime`: runtime bundle image (`rke2-runtime`)
- `test`: runnable local image that includes `/bin/rke2` and local airgap artifacts

### Changes Required For Local `test` Image Builds
- Fixed Dockerfile line continuation parse error in the `gh` install step.
- Converted legacy `ENV key value` syntax to `ENV key=value`.
- Updated the `test` stage airgap artifact path to use architecture-aware output:
- `dist/artifacts/rke2-images.linux-${TARGETARCH}.tar.zst`
- Added compatibility handling in `scripts/build-local-test-image` so older refs that still
expect `build/images/rke2-images.linux-amd64.tar.zst` can be built from non-amd64 hosts.

### One-Command Build (Recommended)
Build a runnable local image with versioned tags:

```shell
make build-local-test-image
```

By default this now tags:
- `rancher/rke2-test:<resolved-version>-<goos>-<arch>`
- `rancher/rke2-test:<resolved-version>`

Optional overrides:

```shell
IMAGE_TAG=my-rke2:test make build-local-test-image
TARGETARCH=amd64 make build-local-test-image
RKE2_REF=v1.34.4+rke2r1 make build-local-test-image
```

`RKE2_REF` builds from a git tag/branch in an isolated local clone, so older versions can be built without changing your current checkout.

### What The One-Command Build Does
1. Builds `bin/rke2` in Dockerized build env.
2. Builds runtime/images metadata in Dockerized build env.
3. Creates `dist/artifacts/rke2-images.linux-<arch>.tar.zst` from `build/images.txt`.
4. Builds Docker `--target test` and tags the result with versioned test image tags.

## Running

### rke2 (dev-shell)
Expand Down
8 changes: 4 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ ARG KUBERNETES_VERSION=dev
# Base image for common build tools
FROM rancher/hardened-build-base:v1.25.6b1 AS base
ARG BUILDARCH
ENV ARCH $BUILDARCH
ENV ARCH=$BUILDARCH
RUN set -x && \
apk --no-cache add \
bash \
Expand Down Expand Up @@ -31,14 +31,14 @@ RUN zypper install -y systemd-rpm-macros
# Build environment
FROM base AS build-env
ARG BUILDARCH
ENV ARCH $BUILDARCH
ENV ARCH=$BUILDARCH
RUN if [ "${ARCH}" = "amd64" ] || [ "${ARCH}" = "arm64" ]; then \
VERSION=0.56.10 OS=linux && \
curl -sL "https://github.com/vmware-tanzu/sonobuoy/releases/download/v${VERSION}/sonobuoy_${VERSION}_${OS}_${ARCH}.tar.gz" | \
tar -xzf - -C /usr/local/bin; \
fi

RUN curl -sL "https://github.com/cli/cli/releases/download/v2.53.0/gh_2.53.0_linux_${ARCH}.tar.gz" | \
RUN curl -sL "https://github.com/cli/cli/releases/download/v2.53.0/gh_2.53.0_linux_${ARCH}.tar.gz" | \
tar --strip-components=2 -xzvf - -C /usr/local/bin gh_2.53.0_linux_${ARCH}/bin/gh;

COPY channels.yaml /tmp/channels.yaml
Expand Down Expand Up @@ -148,7 +148,7 @@ VOLUME /var/lib/cni
VOLUME /var/log
COPY bin/rke2 /bin/
# use built air-gap images
COPY build/images/rke2-images.linux-amd64.tar.zst /var/lib/rancher/rke2/agent/images/
COPY dist/artifacts/rke2-images.linux-${TARGETARCH}.tar.zst /var/lib/rancher/rke2/agent/images/
COPY build/images.txt /images.txt

# use rke2 bundled binaries
Expand Down
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ build-windows-images: ## Build only the Windows images and t
build-image-runtime: ## Build the runtime image
./scripts/build-image-runtime

.PHONY: build-local-test-image
build-local-test-image: ## Build a local runnable rke2 test image (default: rancher/rke2-test:<version>)
./scripts/build-local-test-image

.PHONY: publish-image-runtime
publish-image-runtime:
./scripts/publish-image-runtime
Expand Down Expand Up @@ -163,4 +167,4 @@ in-docker-%: ## Advanced: wraps any target in Docker environment, for example: i

.PHONY: help
help: ## this help
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
105 changes: 105 additions & 0 deletions scripts/build-local-test-image
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/usr/bin/env bash
set -euo pipefail

SCRIPT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"
DEFAULT_REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BUILD_ROOT="${BUILD_ROOT:-${DEFAULT_REPO_ROOT}}"
REQUESTED_REF="${RKE2_REF:-}"
TEMP_BUILD_ROOT=""

if [ "${BUILD_LOCAL_FROM_WORKTREE:-0}" != "1" ] && [ -n "${RKE2_REF:-}" ]; then
TEMP_BUILD_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/rke2-build-ref.XXXXXX")"
trap 'rm -rf "${TEMP_BUILD_ROOT}"' EXIT

git clone --local --no-hardlinks "${DEFAULT_REPO_ROOT}" "${TEMP_BUILD_ROOT}" >/dev/null 2>&1
(
cd "${TEMP_BUILD_ROOT}"
git checkout --detach "${RKE2_REF}" >/dev/null
)
BUILD_ROOT="${TEMP_BUILD_ROOT}"
unset RKE2_REF
fi

cd "${BUILD_ROOT}"

TARGETARCH="${TARGETARCH:-}"
if [ -z "${TARGETARCH}" ]; then
case "$(uname -m)" in
x86_64|amd64)
TARGETARCH="amd64"
;;
arm64|aarch64)
TARGETARCH="arm64"
;;
s390x)
TARGETARCH="s390x"
;;
*)
echo "Unsupported architecture: $(uname -m)" >&2
exit 1
;;
esac
fi

BUNDLE_TAR="dist/artifacts/rke2-images.linux-${TARGETARCH}.tar"
BUNDLE_ZST="${BUNDLE_TAR}.zst"
BRANCH_TAG="$(git rev-parse --abbrev-ref HEAD | sed 's/\//-/g')"
TOOLING_IMAGE="rke2:${BRANCH_TAG}"

make in-docker-build-binary
make in-docker-build-images || true
if [ ! -f build/images.txt ]; then
if [ -f build/images-core.txt ]; then
if [ ! -f build/images-canal.txt ]; then
: > build/images-canal.txt
fi
cat build/images-core.txt build/images-canal.txt > build/images.txt
else
echo "Unable to recover: build/images-core.txt was not generated" >&2
exit 1
fi
fi

RAW_VERSION=""
if [ -n "${REQUESTED_REF}" ]; then
RAW_VERSION="${REQUESTED_REF}"
else
RAW_VERSION="$(git tag -l --contains HEAD | head -n 1 || true)"
fi
if [ -n "${RAW_VERSION}" ]; then
DOCKERIZED_VERSION="${RAW_VERSION//+/-}"
else
DOCKERIZED_VERSION="dev-$(git rev-parse --short HEAD)"
fi
REPO="rancher"
PROG="rke2"
GOOS="linux"

DEFAULT_IMAGE_TAG="${REPO}/${PROG}-test:${DOCKERIZED_VERSION}-${GOOS}-${TARGETARCH}"
SECONDARY_IMAGE_TAG="${REPO}/${PROG}-test:${DOCKERIZED_VERSION}"
IMAGE_TAG="${IMAGE_TAG:-${DEFAULT_IMAGE_TAG}}"

mkdir -p dist/artifacts
xargs docker image save --output "${BUNDLE_TAR}" < build/images.txt

docker run --rm -v "${PWD}:/work" "${TOOLING_IMAGE}" sh -lc \
"zstd -T0 -16 -f --long=25 --no-progress /work/${BUNDLE_TAR} -o /work/${BUNDLE_ZST}"

mkdir -p build/images
cp -f "${BUNDLE_ZST}" "build/images/rke2-images.linux-${TARGETARCH}.tar.zst"
if [ "${TARGETARCH}" != "amd64" ]; then
cp -f "${BUNDLE_ZST}" "build/images/rke2-images.linux-amd64.tar.zst"
fi

docker build \
--build-arg TARGETARCH="${TARGETARCH}" \
--target test \
--file Dockerfile \
--tag "${IMAGE_TAG}" \
$( [ "${IMAGE_TAG}" = "${DEFAULT_IMAGE_TAG}" ] && printf -- '--tag %s' "${SECONDARY_IMAGE_TAG}" ) \
.

echo "Built ${IMAGE_TAG}"
if [ "${IMAGE_TAG}" = "${DEFAULT_IMAGE_TAG}" ]; then
echo "Built ${SECONDARY_IMAGE_TAG}"
fi