mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-01-31 17:23:34 +00:00
k3s: add airgap images to passthru attributes
The k3s update script filters the assets of a corresponding release for airgap images archives and provides these as passthru attributes of the k3s derivation. We use zstd archives, as these offer the best compression ratios and decompression speed. Furthermore, the `airgapImages` passthru provides the images archive that matches the host platform architecture, however, this only works for aarch64 and x86_64. In addition, a txt file listing all container images of a release is made available via a passthru attribute. The airgap images archives can be combined nicely with the `services.k3s.images` option, e.g. to pre-provision k3s nodes for environments without Internet connectivity.
This commit is contained in:
parent
c38f9ee113
commit
eeacf85fb9
44
nixos/tests/k3s/airgap-images.nix
Normal file
44
nixos/tests/k3s/airgap-images.nix
Normal file
@ -0,0 +1,44 @@
|
||||
# A test that imports k3s airgapped images and verifies that all expected images are present
|
||||
import ../make-test-python.nix (
|
||||
{ lib, k3s, ... }:
|
||||
{
|
||||
name = "${k3s.name}-airgap-images";
|
||||
meta.maintainers = lib.teams.k3s.members;
|
||||
|
||||
nodes.machine =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
# k3s uses enough resources the default vm fails.
|
||||
virtualisation.memorySize = 1536;
|
||||
virtualisation.diskSize = 4096;
|
||||
|
||||
services.k3s = {
|
||||
enable = true;
|
||||
role = "server";
|
||||
package = k3s;
|
||||
# Slightly reduce resource usage
|
||||
extraFlags = [
|
||||
"--disable coredns"
|
||||
"--disable local-storage"
|
||||
"--disable metrics-server"
|
||||
"--disable servicelb"
|
||||
"--disable traefik"
|
||||
];
|
||||
images = [ k3s.airgapImages ];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
import json
|
||||
|
||||
start_all()
|
||||
machine.wait_for_unit("k3s")
|
||||
machine.wait_until_succeeds("journalctl -r --no-pager -u k3s | grep \"Imported images from /var/lib/rancher/k3s/agent/images/\"", timeout=60)
|
||||
images = json.loads(machine.succeed("crictl img -o json"))
|
||||
image_names = [i["repoTags"][0] for i in images["images"]]
|
||||
with open("${k3s.imagesList}") as expected_images:
|
||||
for line in expected_images:
|
||||
assert line.rstrip() in image_names, f"The image {line.rstrip()} is not present in the airgap images archive"
|
||||
'';
|
||||
}
|
||||
)
|
@ -0,0 +1,18 @@
|
||||
{
|
||||
"airgap-images-amd64": {
|
||||
"url": "https://github.com/k3s-io/k3s/releases/download/v1.28.11%2Bk3s2/k3s-airgap-images-amd64.tar.zst",
|
||||
"sha256": "199nxfxwr52cddk2ljchhxaigyi0al3lzyc0jy2am4aljlm0jivy"
|
||||
},
|
||||
"airgap-images-arm": {
|
||||
"url": "https://github.com/k3s-io/k3s/releases/download/v1.28.11%2Bk3s2/k3s-airgap-images-arm.tar.zst",
|
||||
"sha256": "02riiiwwr0h3zhlxxmjn5p8ws354rr2gk44x3kz9d7sxqn17sz4w"
|
||||
},
|
||||
"airgap-images-arm64": {
|
||||
"url": "https://github.com/k3s-io/k3s/releases/download/v1.28.11%2Bk3s2/k3s-airgap-images-arm64.tar.zst",
|
||||
"sha256": "0bs9wj33appb9xpsb2v1xz4xck4qq6g74flnc0mxf9warwr4988r"
|
||||
},
|
||||
"images-list": {
|
||||
"url": "https://github.com/k3s-io/k3s/releases/download/v1.28.11%2Bk3s2/k3s-images.txt",
|
||||
"sha256": "0245zra2h8756kq2v8nwl6gji749xlvy1y1bkab8vz5b0vpqhfxy"
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
k3sRepoSha256 = "1k1k3qmxc7n2h2i0g52ad4gnpq0qrvxnl7p2y0g9dss1ancgqwsd";
|
||||
k3sVendorHash = "sha256-tzcMcsTmY8lG+9EyYkzYJm1YU/8tGpxpH7oZ4Jl/yNU=";
|
||||
chartVersions = import ./chart-versions.nix;
|
||||
imagesVersions = builtins.fromJSON (builtins.readFile ./images-versions.json);
|
||||
k3sRootVersion = "0.12.2";
|
||||
k3sRootSha256 = "1gjynvr350qni5mskgm7pcc7alss4gms4jmkiv453vs8mmma9c9k";
|
||||
k3sCNIVersion = "1.4.0-k3s2";
|
||||
|
@ -0,0 +1,18 @@
|
||||
{
|
||||
"airgap-images-amd64": {
|
||||
"url": "https://github.com/k3s-io/k3s/releases/download/v1.29.6%2Bk3s2/k3s-airgap-images-amd64.tar.zst",
|
||||
"sha256": "1d1adpjxxgkflm4xqzynsib67pga85r1qmhkhh540nl0rppbq7gr"
|
||||
},
|
||||
"airgap-images-arm": {
|
||||
"url": "https://github.com/k3s-io/k3s/releases/download/v1.29.6%2Bk3s2/k3s-airgap-images-arm.tar.zst",
|
||||
"sha256": "07c085y5qy8h5ja2ms3np61d7wkp6gic82snx70qlsm5fm3ak3z7"
|
||||
},
|
||||
"airgap-images-arm64": {
|
||||
"url": "https://github.com/k3s-io/k3s/releases/download/v1.29.6%2Bk3s2/k3s-airgap-images-arm64.tar.zst",
|
||||
"sha256": "0ljajvz0n0mmwkdl1rwpwqmhgxqivakdpfyaqsascdzfk0qpv5gp"
|
||||
},
|
||||
"images-list": {
|
||||
"url": "https://github.com/k3s-io/k3s/releases/download/v1.29.6%2Bk3s2/k3s-images.txt",
|
||||
"sha256": "0245zra2h8756kq2v8nwl6gji749xlvy1y1bkab8vz5b0vpqhfxy"
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
k3sRepoSha256 = "0wagfh4vbvyi62np6zx7b4p6myn0xavw691y78rnbl32jckiy14f";
|
||||
k3sVendorHash = "sha256-o36gf3q7Vv+RoY681cL44rU2QFrdFW3EbRpw3dLcVTI=";
|
||||
chartVersions = import ./chart-versions.nix;
|
||||
imagesVersions = builtins.fromJSON (builtins.readFile ./images-versions.json);
|
||||
k3sRootVersion = "0.13.0";
|
||||
k3sRootSha256 = "1jq5f0lm08abx5ikarf92z56fvx4kjpy2nmzaazblb34lajw87vj";
|
||||
k3sCNIVersion = "1.4.0-k3s2";
|
||||
|
@ -0,0 +1,18 @@
|
||||
{
|
||||
"airgap-images-amd64": {
|
||||
"url": "https://github.com/k3s-io/k3s/releases/download/v1.30.2%2Bk3s2/k3s-airgap-images-amd64.tar.zst",
|
||||
"sha256": "1d1adpjxxgkflm4xqzynsib67pga85r1qmhkhh540nl0rppbq7gr"
|
||||
},
|
||||
"airgap-images-arm": {
|
||||
"url": "https://github.com/k3s-io/k3s/releases/download/v1.30.2%2Bk3s2/k3s-airgap-images-arm.tar.zst",
|
||||
"sha256": "1hjhlj4b5ddaqhpmqbbvhvgzryi5j84i8bmpl3yij87yjkz3kld7"
|
||||
},
|
||||
"airgap-images-arm64": {
|
||||
"url": "https://github.com/k3s-io/k3s/releases/download/v1.30.2%2Bk3s2/k3s-airgap-images-arm64.tar.zst",
|
||||
"sha256": "1r9rd70qp8x57j3hdpgwgkzchykphw0x4yd8c1jwjfaqm5df1w0d"
|
||||
},
|
||||
"images-list": {
|
||||
"url": "https://github.com/k3s-io/k3s/releases/download/v1.30.2%2Bk3s2/k3s-images.txt",
|
||||
"sha256": "0245zra2h8756kq2v8nwl6gji749xlvy1y1bkab8vz5b0vpqhfxy"
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
k3sRepoSha256 = "0hy0f44hj5n5nscr0p52dbklvj2ki2vs7k0cgh1r8xlg4p6fn1b0";
|
||||
k3sVendorHash = "sha256-Mj9Q3TgqZoJluG4/nyuw2WHnB3OJ+/mlV7duzWt1B1A=";
|
||||
chartVersions = import ./chart-versions.nix;
|
||||
imagesVersions = builtins.fromJSON (builtins.readFile ./images-versions.json);
|
||||
k3sRootVersion = "0.13.0";
|
||||
k3sRootSha256 = "1jq5f0lm08abx5ikarf92z56fvx4kjpy2nmzaazblb34lajw87vj";
|
||||
k3sCNIVersion = "1.4.0-k3s2";
|
||||
|
@ -12,6 +12,8 @@ lib:
|
||||
# Based on the traefik charts here: https://github.com/k3s-io/k3s/blob/d71ab6317e22dd34673faa307a412a37a16767f6/scripts/download#L29-L32
|
||||
# see also https://github.com/k3s-io/k3s/blob/d71ab6317e22dd34673faa307a412a37a16767f6/manifests/traefik.yaml#L8
|
||||
chartVersions,
|
||||
# Air gap container images that are released as assets with every k3s release
|
||||
imagesVersions,
|
||||
# taken from ./scripts/version.sh VERSION_CNIPLUGINS https://github.com/k3s-io/k3s/blob/v1.23.3%2Bk3s1/scripts/version.sh#L45
|
||||
k3sCNIVersion,
|
||||
k3sCNISha256 ? lib.fakeHash,
|
||||
@ -30,41 +32,42 @@ lib:
|
||||
# It is likely we will have to split out additional builders for additional
|
||||
# versions in the future, or customize this one further.
|
||||
{
|
||||
lib,
|
||||
makeWrapper,
|
||||
socat,
|
||||
iptables,
|
||||
iproute2,
|
||||
ipset,
|
||||
bash,
|
||||
bridge-utils,
|
||||
btrfs-progs,
|
||||
conntrack-tools,
|
||||
buildGoModule,
|
||||
runc,
|
||||
rsync,
|
||||
kmod,
|
||||
libseccomp,
|
||||
pkg-config,
|
||||
conntrack-tools,
|
||||
coreutils,
|
||||
ethtool,
|
||||
util-linux,
|
||||
fetchFromGitHub,
|
||||
fetchgit,
|
||||
fetchurl,
|
||||
fetchzip,
|
||||
fetchgit,
|
||||
zstd,
|
||||
yq-go,
|
||||
sqlite,
|
||||
nixosTests,
|
||||
pkgsBuildBuild,
|
||||
go,
|
||||
runCommand,
|
||||
bash,
|
||||
procps,
|
||||
coreutils,
|
||||
gnugrep,
|
||||
findutils,
|
||||
gnugrep,
|
||||
gnused,
|
||||
go,
|
||||
iproute2,
|
||||
ipset,
|
||||
iptables,
|
||||
kmod,
|
||||
lib,
|
||||
libseccomp,
|
||||
makeWrapper,
|
||||
nixosTests,
|
||||
pkg-config,
|
||||
pkgsBuildBuild,
|
||||
procps,
|
||||
rsync,
|
||||
runc,
|
||||
runCommand,
|
||||
socat,
|
||||
sqlite,
|
||||
stdenv,
|
||||
systemd,
|
||||
util-linux,
|
||||
yq-go,
|
||||
zstd,
|
||||
}:
|
||||
|
||||
# k3s is a kinda weird derivation. One of the main points of k3s is the
|
||||
@ -122,6 +125,39 @@ let
|
||||
traefikChart = fetchurl chartVersions.traefik;
|
||||
traefik-crdChart = fetchurl chartVersions.traefik-crd;
|
||||
|
||||
mutFirstChar =
|
||||
f: s:
|
||||
let
|
||||
firstChar = f (lib.substring 0 1 s);
|
||||
rest = lib.substring 1 (-1) s;
|
||||
in
|
||||
firstChar + rest;
|
||||
|
||||
kebabToCamel =
|
||||
s:
|
||||
mutFirstChar lib.toLower (lib.concatMapStrings (mutFirstChar lib.toUpper) (lib.splitString "-" s));
|
||||
|
||||
# finds the images archive for the desired architecture, aborts in case no suitable archive is found
|
||||
findImagesArchive =
|
||||
arch:
|
||||
let
|
||||
imagesVersionsNames = builtins.attrNames imagesVersions;
|
||||
in
|
||||
lib.findFirst (
|
||||
n: lib.hasInfix arch n
|
||||
) (abort "k3s: no airgap images for ${arch} available") imagesVersionsNames;
|
||||
|
||||
# a shortcut that provides the images archive for the host platform. Currently only supports
|
||||
# aarch64 (arm64) and x86_64 (amd64), aborts on other architectures.
|
||||
airgapImages = fetchurl (
|
||||
if stdenv.isAarch64 then
|
||||
imagesVersions.${findImagesArchive "arm64"}
|
||||
else if stdenv.isx86_64 then
|
||||
imagesVersions.${findImagesArchive "amd64"}
|
||||
else
|
||||
abort "k3s: airgap images cannot be found automatically for architecture ${stdenv.hostPlatform.linuxArch}, consider using an image archive with an explicit architecture."
|
||||
);
|
||||
|
||||
# so, k3s is a complicated thing to package
|
||||
# This derivation attempts to avoid including any random binaries from the
|
||||
# internet. k3s-root is _mostly_ binaries built to be bundled in k3s (which
|
||||
@ -417,21 +453,26 @@ buildGoModule rec {
|
||||
runHook postInstallCheck
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
k3sCNIPlugins = k3sCNIPlugins;
|
||||
k3sContainerd = k3sContainerd;
|
||||
k3sRepo = k3sRepo;
|
||||
k3sRoot = k3sRoot;
|
||||
k3sServer = k3sServer;
|
||||
mkTests =
|
||||
version:
|
||||
let
|
||||
k3s_version = "k3s_" + lib.replaceStrings [ "." ] [ "_" ] (lib.versions.majorMinor version);
|
||||
in
|
||||
lib.mapAttrs (name: value: nixosTests.k3s.${name}.${k3s_version}) nixosTests.k3s;
|
||||
tests = passthru.mkTests k3sVersion;
|
||||
updateScript = updateScript;
|
||||
};
|
||||
passthru =
|
||||
{
|
||||
inherit airgapImages;
|
||||
k3sCNIPlugins = k3sCNIPlugins;
|
||||
k3sContainerd = k3sContainerd;
|
||||
k3sRepo = k3sRepo;
|
||||
k3sRoot = k3sRoot;
|
||||
k3sServer = k3sServer;
|
||||
mkTests =
|
||||
version:
|
||||
let
|
||||
k3s_version = "k3s_" + lib.replaceStrings [ "." ] [ "_" ] (lib.versions.majorMinor version);
|
||||
in
|
||||
lib.mapAttrs (name: value: nixosTests.k3s.${name}.${k3s_version}) nixosTests.k3s;
|
||||
tests = passthru.mkTests k3sVersion;
|
||||
updateScript = updateScript;
|
||||
}
|
||||
// (lib.mapAttrs' (
|
||||
name: _: lib.nameValuePair (kebabToCamel name) (fetchurl imagesVersions.${name})
|
||||
) imagesVersions);
|
||||
|
||||
meta = baseMeta;
|
||||
}
|
||||
|
@ -69,6 +69,24 @@ cat > chart-versions.nix.update <<EOF
|
||||
EOF
|
||||
mv chart-versions.nix.update chart-versions.nix
|
||||
|
||||
# Get all airgap images files associated with this release
|
||||
IMAGES_ARCHIVES=$(curl "https://api.github.com/repos/k3s-io/k3s/releases/tags/v${K3S_VERSION}" | \
|
||||
# Filter the assets so that only zstd archives and text files that have "images" in their name remain
|
||||
# Modify the name and write the modified name and download URL to a string
|
||||
jq -r '.assets[] | select(.name | contains("images")) |
|
||||
select(.content_type == "application/zstd" or .content_type == "text/plain; charset=utf-8") |
|
||||
.name = (.name | sub("k3s-"; "") | sub(".tar.zst"; "") | sub(".txt"; "-list")) |
|
||||
"\(.name) \(.browser_download_url)"')
|
||||
|
||||
# Create a JSON object for each airgap images file and prefetch all download URLs in the process
|
||||
# Combine all JSON objects and write the result to images-versions.json
|
||||
while read -r name url; do
|
||||
jq --null-input --arg name "$name" \
|
||||
--arg url "$url" \
|
||||
--arg sha256 "$(nix-prefetch-url --quiet "${url}")" \
|
||||
'{$name: {"url": $url, "sha256": $sha256}}'
|
||||
done <<<"${IMAGES_ARCHIVES}" | jq --slurp 'reduce .[] as $item ({}; . * $item)' > images-versions.json
|
||||
|
||||
FILE_GO_MOD=${WORKDIR}/go.mod
|
||||
curl --silent https://raw.githubusercontent.com/k3s-io/k3s/${K3S_COMMIT}/go.mod > $FILE_GO_MOD
|
||||
|
||||
@ -105,6 +123,7 @@ cat >versions.nix <<EOF
|
||||
k3sRepoSha256 = "${K3S_REPO_SHA256}";
|
||||
k3sVendorHash = "${FAKE_HASH}";
|
||||
chartVersions = import ./chart-versions.nix;
|
||||
imagesVersions = builtins.fromJSON (builtins.readFile ./images-versions.json);
|
||||
k3sRootVersion = "${K3S_ROOT_VERSION}";
|
||||
k3sRootSha256 = "${K3S_ROOT_SHA256}";
|
||||
k3sCNIVersion = "${CNIPLUGINS_VERSION}";
|
||||
|
Loading…
Reference in New Issue
Block a user