From 1da88bf5c32c906563db95520aec5a685c31c6aa Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Sun, 28 Dec 2025 22:08:05 -0800 Subject: [PATCH 1/4] feat: upgrade Talos to v1.12.0 and use --embedded-config-path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Upgrade Talos version from v1.9.1 to v1.12.0 - Use --embedded-config-path flag (available in v1.12+) instead of --meta workaround - Update ISO checksums for v1.12.0 - Temporarily enable full transform hook testing on PRs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .github/workflows/images-sync.yml | 21 +++++++++------------ images/hooks/talos-embed-config.sh | 9 ++++----- images/images.yaml | 12 ++++++------ infrastructure/compute/talos/talconfig.yaml | 2 +- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/.github/workflows/images-sync.yml b/.github/workflows/images-sync.yml index f824f53..2861e59 100644 --- a/.github/workflows/images-sync.yml +++ b/.github/workflows/images-sync.yml @@ -98,25 +98,14 @@ jobs: restore-keys: | labctl-images- - # PR: run full sync without upload (tests hooks, no credentials needed) - # Skip transform hooks in PR - they require specialized tools (talhelper, sops, docker) - # that are only available in the full sync environment - - name: Sync Images (PR - no upload) - if: github.event_name == 'pull_request' - run: | - ./labctl images sync --no-upload --skip-transform-hooks --cache-dir ~/.cache/labctl - - # Push/dispatch: full sync with credentials # Install tools needed for transform hooks (talhelper, sops) - name: Install SOPS - if: github.event_name != 'pull_request' run: | curl -LO https://github.com/getsops/sops/releases/download/v3.9.4/sops-v3.9.4.linux.amd64 chmod +x sops-v3.9.4.linux.amd64 sudo mv sops-v3.9.4.linux.amd64 /usr/local/bin/sops - name: Install talhelper - if: github.event_name != 'pull_request' run: | curl -LO https://github.com/budimanjojo/talhelper/releases/download/v3.0.13/talhelper_linux_amd64.tar.gz tar -xzf talhelper_linux_amd64.tar.gz @@ -125,11 +114,19 @@ jobs: talhelper --version - name: Write SOPS age key - if: github.event_name != 'pull_request' run: | echo "${{ secrets.SOPS_AGE_KEY }}" > /tmp/age-key.txt chmod 600 /tmp/age-key.txt + # PR: run full sync without upload (tests hooks including transform) + - name: Sync Images (PR - no upload) + if: github.event_name == 'pull_request' + env: + SOPS_AGE_KEY_FILE: /tmp/age-key.txt + run: | + ./labctl images sync --no-upload --cache-dir ~/.cache/labctl + + # Push/dispatch: full sync with credentials - name: Sync Images if: github.event_name != 'pull_request' id: sync diff --git a/images/hooks/talos-embed-config.sh b/images/hooks/talos-embed-config.sh index 606c0aa..a4aab58 100755 --- a/images/hooks/talos-embed-config.sh +++ b/images/hooks/talos-embed-config.sh @@ -133,14 +133,13 @@ embed_config() { # Run the imager to create a new ISO with embedded config # The imager creates a fresh ISO from scratch - it doesn't modify the downloaded ISO - # Use --meta 0x0a to embed the machine configuration (0x0a = META_MACHINE_CONFIG) # Mount work dir to /out (imager's default output directory) - # Note: Using bash -c to read the file inside the container avoids shell escaping issues - docker run --rm \ + docker run --rm -t \ -v "${WORK_DIR}:/out" \ - --entrypoint /bin/sh \ "ghcr.io/siderolabs/imager:${talos_version}" \ - -c 'imager iso --arch amd64 --meta "0x0a=$(cat /out/machine.yaml)"' + iso \ + --arch amd64 \ + --embedded-config-path=/out/machine.yaml # Find the generated ISO (imager outputs to /out/metal-amd64.iso) local output_iso="${WORK_DIR}/metal-amd64.iso" diff --git a/images/images.yaml b/images/images.yaml index 2edf485..289a463 100644 --- a/images/images.yaml +++ b/images/images.yaml @@ -19,9 +19,9 @@ spec: # Base ISO: Vanilla Talos for general use (VMs, other nodes) - name: talos-base source: - url: https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.9.1/metal-amd64.iso - checksum: sha256:a9c5f4bcb634c5af5e78780d71317197407673db76dcc34d809adc0042a818e2 - destination: talos/talos-1.9.1-metal-amd64.iso + url: https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.12.0/metal-amd64.iso + checksum: sha256:862d7afc6b9f9c27033f5addf05f699b48be83aea81768349ae9a07b9e8eb8b5 + destination: talos/talos-1.12.0-metal-amd64.iso # UM760 ISO: Talos with embedded machine configuration for CP-1 # The transform hook generates machine config via talhelper and embeds it @@ -32,9 +32,9 @@ spec: # Note: The downloaded ISO is replaced entirely by the imager output. # We use the same base URL for consistency, but only the Talos version # from talconfig.yaml matters for the final ISO. - url: https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.9.1/metal-amd64.iso - checksum: sha256:a9c5f4bcb634c5af5e78780d71317197407673db76dcc34d809adc0042a818e2 - destination: talos/talos-1.9.1-um760.iso + url: https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.12.0/metal-amd64.iso + checksum: sha256:862d7afc6b9f9c27033f5addf05f699b48be83aea81768349ae9a07b9e8eb8b5 + destination: talos/talos-1.12.0-um760.iso hooks: transform: - name: embed-um760-config diff --git a/infrastructure/compute/talos/talconfig.yaml b/infrastructure/compute/talos/talconfig.yaml index 07defcc..b4bc297 100644 --- a/infrastructure/compute/talos/talconfig.yaml +++ b/infrastructure/compute/talos/talconfig.yaml @@ -3,7 +3,7 @@ # Run `talhelper genconfig` to regenerate --- clusterName: platform -talosVersion: v1.9.1 +talosVersion: v1.12.0 kubernetesVersion: v1.32.0 endpoint: https://10.10.30.10:6443 From 14679168d877102ce125270f3236b810dfd3affc Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Sun, 28 Dec 2025 22:14:28 -0800 Subject: [PATCH 2/4] fix(ci): update talhelper to v3.0.43 for Talos v1.12 support --- .github/workflows/images-sync.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/images-sync.yml b/.github/workflows/images-sync.yml index 2861e59..fe60b41 100644 --- a/.github/workflows/images-sync.yml +++ b/.github/workflows/images-sync.yml @@ -107,7 +107,7 @@ jobs: - name: Install talhelper run: | - curl -LO https://github.com/budimanjojo/talhelper/releases/download/v3.0.13/talhelper_linux_amd64.tar.gz + curl -LO https://github.com/budimanjojo/talhelper/releases/download/v3.0.43/talhelper_linux_amd64.tar.gz tar -xzf talhelper_linux_amd64.tar.gz chmod +x talhelper sudo mv talhelper /usr/local/bin/talhelper From 863924a482b6e960e43ab80a485ad77ddef95abb Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Sun, 28 Dec 2025 22:19:44 -0800 Subject: [PATCH 3/4] fix(hooks): add --privileged flag for SELinux xattr on CI runners --- images/hooks/talos-embed-config.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/images/hooks/talos-embed-config.sh b/images/hooks/talos-embed-config.sh index a4aab58..625833e 100755 --- a/images/hooks/talos-embed-config.sh +++ b/images/hooks/talos-embed-config.sh @@ -134,7 +134,8 @@ embed_config() { # Run the imager to create a new ISO with embedded config # The imager creates a fresh ISO from scratch - it doesn't modify the downloaded ISO # Mount work dir to /out (imager's default output directory) - docker run --rm -t \ + # Note: --privileged is required for SELinux xattr operations on CI runners + docker run --rm -t --privileged \ -v "${WORK_DIR}:/out" \ "ghcr.io/siderolabs/imager:${talos_version}" \ iso \ From b5de092fabb92fc5a233fe069e4bbc9a6f0b7f09 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Sun, 28 Dec 2025 22:25:25 -0800 Subject: [PATCH 4/4] refactor(ci): restore skip-transform-hooks for PR validation Transform hooks require Docker with privileged mode and were tested successfully. For normal PR validation, we skip them to reduce CI time. --- .github/workflows/images-sync.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/images-sync.yml b/.github/workflows/images-sync.yml index fe60b41..d5bd918 100644 --- a/.github/workflows/images-sync.yml +++ b/.github/workflows/images-sync.yml @@ -118,13 +118,13 @@ jobs: echo "${{ secrets.SOPS_AGE_KEY }}" > /tmp/age-key.txt chmod 600 /tmp/age-key.txt - # PR: run full sync without upload (tests hooks including transform) + # PR: run sync without upload, skipping transform hooks (they require docker) - name: Sync Images (PR - no upload) if: github.event_name == 'pull_request' env: SOPS_AGE_KEY_FILE: /tmp/age-key.txt run: | - ./labctl images sync --no-upload --cache-dir ~/.cache/labctl + ./labctl images sync --no-upload --skip-transform-hooks --cache-dir ~/.cache/labctl # Push/dispatch: full sync with credentials - name: Sync Images