From b03709620201b44f6464a7df804e2003c9751a30 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Tue, 7 Jun 2022 17:47:32 +0400 Subject: [PATCH] feat: build Talos images with system extensions included This allows to build a custom Talos image which comes with some system extension bundled in. Sometimes we might need to have an extension in the initial image, e.g. `vmtoolsd` for VMWare Talos image. Syntax: ``` make image-aws \ IMAGER_SYSTEM_EXTENSIONS="ghcr.io/siderolabs/amd-ucode:..." ``` System extensions are not supported for now for ISO images, as they don't go through the common installer flow (#5725). Also it might be nice to add a simple way to generate just `initramfs.xz` with system extensions bundled in (e.g. for PXE booting). (#5726) Signed-off-by: Andrey Smirnov --- Makefile | 15 +++++++++++---- hack/imager.sh | 19 +++++++++++++++++++ .../configuration/system-extensions.md | 11 +++++++++-- 3 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 hack/imager.sh diff --git a/Makefile b/Makefile index 78153653e..5e4db3335 100644 --- a/Makefile +++ b/Makefile @@ -40,6 +40,7 @@ SHORT_INTEGRATION_TEST ?= CUSTOM_CNI_URL ?= INSTALLER_ARCH ?= all IMAGER_ARGS ?= +IMAGER_SYSTEM_EXTENSIONS ?= CGO_ENABLED ?= 0 GO_BUILDFLAGS ?= @@ -232,9 +233,12 @@ talosctl: $(TALOSCTL_DEFAULT_TARGET) ## Builds the talosctl binary for the local image-%: ## Builds the specified image. Valid options are aws, azure, digital-ocean, gcp, and vmware (e.g. image-aws) @docker pull $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) - @for platform in $(subst $(,),$(space),$(PLATFORM)); do \ - arch=`basename "$${platform}"` ; \ - docker run --rm -v /dev:/dev --privileged $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) image --platform $* --arch $$arch --tar-to-stdout $(IMAGER_ARGS) | tar xz -C $(ARTIFACTS) ; \ + @ . ./hack/imager.sh && \ + for platform in $(subst $(,),$(space),$(PLATFORM)); do \ + arch=$$(basename "$${platform}") && \ + tmpdir=$$(prepare_extension_images "$${platform}" $(IMAGER_SYSTEM_EXTENSIONS)) && \ + docker run --rm -v /dev:/dev -v "$${tmpdir}:/system/extensions" --privileged $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) image --platform $* --arch $$arch --tar-to-stdout $(IMAGER_ARGS) | tar xz -C $(ARTIFACTS) ; \ + rm -rf "$${tmpdir}"; \ done images-essential: image-aws image-gcp image-metal ## Builds only essential images used in the CI (AWS, GCP, and Metal). @@ -243,7 +247,10 @@ images: image-aws image-azure image-digital-ocean image-gcp image-hcloud image-m sbc-%: ## Builds the specified SBC image. Valid options are rpi_4, rock64, bananapi_m64, libretech_all_h3_cc_h5, rockpi_4, rockpi_4c, pine64 and jetson_nano (e.g. sbc-rpi_4) @docker pull $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) - @docker run --rm -v /dev:/dev --privileged $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) image --platform metal --arch arm64 --board $* --tar-to-stdout $(IMAGER_ARGS) | tar xz -C $(ARTIFACTS) + @ . ./hack/imager.sh && \ + tmpdir=$$(prepare_extension_images linux/arm64 $(IMAGER_SYSTEM_EXTENSIONS)) && \ + docker run --rm -v /dev:/dev -v "$${tmpdir}:/system/extensions" --privileged $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) image --platform metal --arch arm64 --board $* --tar-to-stdout $(IMAGER_ARGS) | tar xz -C $(ARTIFACTS) ; \ + rm -rf "$${tmpdir}" sbcs: sbc-rpi_4 sbc-rock64 sbc-bananapi_m64 sbc-libretech_all_h3_cc_h5 sbc-rockpi_4 sbc-rockpi_4c sbc-pine64 sbc-jetson_nano ## Builds all known SBC images (Raspberry Pi 4 Model B, Rock64, Banana Pi M64, Radxa ROCK Pi 4, Radxa ROCK Pi 4c, pine64, Libre Computer Board ALL-H3-CC and Jetson Nano). diff --git a/hack/imager.sh b/hack/imager.sh new file mode 100644 index 000000000..170dc07bf --- /dev/null +++ b/hack/imager.sh @@ -0,0 +1,19 @@ +# helper scripts for running imager functions + +prepare_extension_images() { + # first argument - image platform, e.g. linux/amd64 + # other arguments - list of system extension images + local platform="$1" + shift + + local extensions_dir=$(mktemp -d) + + for ext_image in "$@"; do + echo "Extracting ${ext_image}..." >&2 + local ext_dir="${extensions_dir}/$(basename `mktemp -u`)" + mkdir -p "${ext_dir}" && \ + crane export --platform="${platform}" "${ext_image}" - | tar x -C "${ext_dir}" + done + + echo "${extensions_dir}" +} diff --git a/website/content/v1.1/talos-guides/configuration/system-extensions.md b/website/content/v1.1/talos-guides/configuration/system-extensions.md index c924803bb..452908dd8 100644 --- a/website/content/v1.1/talos-guides/configuration/system-extensions.md +++ b/website/content/v1.1/talos-guides/configuration/system-extensions.md @@ -29,9 +29,16 @@ System extensions will be activated on boot and overlaid on top of the Talos roo In order to update the system extensions for a running instance, update `.machine.install.extensions` and upgrade Talos. (Note: upgrading to the same version of Talos is fine). -> Note: in the next releases of Talos there will be a way to build a Talos image with system extensions included. +## Building a Talos Image with System Extensions -## Creating System Extensions +System extensions can be installed into the Talos disk image (e.g. AWS AMI or VMWare OVF) by running the following command to generate the image +from the Talos source tree: + +```sh +make image-metal IMAGER_SYSTEM_EXTENSIONS="ghcr.io/siderolabs/amd-ucode:20220411 ghcr.io/siderolabs/gvisor:20220405.0-v1.0.0-10-g82b41ad" +``` + +## Authoring System Extensions A Talos system extension is a container image with the [specific folder structure](https://github.com/siderolabs/extensions#readme). System extensions can be built and managed using any tool that produces container images, e.g. `docker build`.