Build both RPi 5 and RPi 4/CM4 from single tag

- Make TALOS_VERSION overridable (?=) and extract from git tag
- Workflow builds Pi5 then Pi4 (clean re-checkout for different kernel config)
- Separate installer images: <tag>-rpi5 and <tag>-rpi4
- Separate metal images: metal-arm64-rpi5.raw.zst and metal-arm64-rpi4.raw.zst
- Release includes both platforms with updated notes
- README updated for dual-platform support
This commit is contained in:
Stephen Wheet
2026-03-10 21:20:47 -07:00
parent 3319e2db58
commit c62a8373a2
3 changed files with 149 additions and 62 deletions
+111 -44
View File
@@ -4,7 +4,6 @@ on:
- 'v*.*.*' - 'v*.*.*'
env: env:
RPI_MODEL: rpi5
REGISTRY: ghcr.io REGISTRY: ghcr.io
REGISTRY_USERNAME: ${{ github.repository_owner }} REGISTRY_USERNAME: ${{ github.repository_owner }}
# Extensions to bake into the installer image. # Extensions to bake into the installer image.
@@ -36,6 +35,16 @@ jobs:
git config --global user.name "github-actions[bot]" git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com" git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: Extract Talos version from tag
id: talos-version
run: |
# Tag format: v1.11.6-rpi5, v1.11.5-cm5, etc.
# Extract the upstream Talos version (vMAJOR.MINOR.PATCH) from the tag.
TAG="${{ github.ref_name }}"
TALOS_VERSION=$(echo "$TAG" | grep -oE '^v[0-9]+\.[0-9]+\.[0-9]+')
echo "TALOS_VERSION=${TALOS_VERSION}" >> $GITHUB_ENV
echo "Resolved TALOS_VERSION=${TALOS_VERSION} from tag ${TAG}"
- name: Resolve extension image digests - name: Resolve extension image digests
run: | run: |
EXTENSIONS="" EXTENSIONS=""
@@ -46,84 +55,142 @@ jobs:
done < <(env | grep '^EXTENSION_') done < <(env | grep '^EXTENSION_')
echo "EXTENSIONS=${EXTENSIONS# }" >> $GITHUB_ENV echo "EXTENSIONS=${EXTENSIONS# }" >> $GITHUB_ENV
- name: Prepare (checkouts & patches) # ──────────────────────────────────────────────
run: make RPI_MODEL=${{ env.RPI_MODEL }} checkouts patches-pi5 # Raspberry Pi 5
# ──────────────────────────────────────────────
- name: Kernel - name: "Pi5 — Prepare (checkouts & patches)"
run: make RPI_MODEL=${{ env.RPI_MODEL }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} kernel run: make TALOS_VERSION=${{ env.TALOS_VERSION }} checkouts patches-pi5
- name: Kernel initramfs - name: "Pi5 — Kernel"
run: make RPI_MODEL=${{ env.RPI_MODEL }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} kern_initramfs run: make TALOS_VERSION=${{ env.TALOS_VERSION }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} kernel
- name: Installer base - name: "Pi5 — Kernel initramfs"
run: make RPI_MODEL=${{ env.RPI_MODEL }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} installer-base run: make TALOS_VERSION=${{ env.TALOS_VERSION }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} kern_initramfs
- name: Imager - name: "Pi5 — Installer base"
run: make RPI_MODEL=${{ env.RPI_MODEL }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} imager run: make TALOS_VERSION=${{ env.TALOS_VERSION }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} installer-base
- name: Overlay - name: "Pi5 — Imager"
run: make RPI_MODEL=${{ env.RPI_MODEL }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} overlay run: make TALOS_VERSION=${{ env.TALOS_VERSION }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} imager
- name: Build installer image (with extensions) - name: "Pi5 — Overlay"
run: make TALOS_VERSION=${{ env.TALOS_VERSION }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} overlay
- name: "Pi5 — Build installer image (with extensions)"
run: | run: |
make RPI_MODEL=${{ env.RPI_MODEL }} \ make TALOS_VERSION=${{ env.TALOS_VERSION }} \
REGISTRY=${{ env.REGISTRY }} \ REGISTRY=${{ env.REGISTRY }} \
REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} \ REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} \
ASSET_TYPE=installer \ ASSET_TYPE=installer \
EXTENSIONS="${{ env.EXTENSIONS }}" \ EXTENSIONS="${{ env.EXTENSIONS }}" \
installer-pi5 installer-pi5
# Push the installer OCI tarball so it can be used for upgrades
crane push \ crane push \
./checkouts/talos/_out/installer-arm64.tar \ ./checkouts/talos/_out/installer-arm64.tar \
${{ env.REGISTRY }}/${{ env.REGISTRY_USERNAME }}/installer:$(cd checkouts/talos && git describe --tag --always --dirty --match v[0-9]*) ${{ env.REGISTRY }}/${{ env.REGISTRY_USERNAME }}/installer:${{ github.ref_name }}-rpi5
- name: Build metal disk image (for fresh installs) - name: "Pi5 — Build metal disk image"
run: | run: |
make RPI_MODEL=${{ env.RPI_MODEL }} \ make TALOS_VERSION=${{ env.TALOS_VERSION }} \
REGISTRY=${{ env.REGISTRY }} \ REGISTRY=${{ env.REGISTRY }} \
REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} \ REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} \
ASSET_TYPE=metal \ ASSET_TYPE=metal \
EXTENSIONS="${{ env.EXTENSIONS }}" \ EXTENSIONS="${{ env.EXTENSIONS }}" \
installer-pi5 installer-pi5
mv ./checkouts/talos/_out/metal-arm64.raw.zst ./metal-arm64-rpi5.raw.zst
- name: Release (tag installer image with git tag) # ──────────────────────────────────────────────
if: startsWith(github.ref, 'refs/tags/v') # Raspberry Pi 4 / CM4
run: make RPI_MODEL=${{ env.RPI_MODEL }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} release # ──────────────────────────────────────────────
- name: "Pi4 — Prepare (clean, re-checkout & patches)"
run: make TALOS_VERSION=${{ env.TALOS_VERSION }} checkouts-clean checkouts patches-pi4
- name: "Pi4 — Kernel"
run: make TALOS_VERSION=${{ env.TALOS_VERSION }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} kernel
- name: "Pi4 — Kernel initramfs"
run: make TALOS_VERSION=${{ env.TALOS_VERSION }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} kern_initramfs
- name: "Pi4 — Installer base"
run: make TALOS_VERSION=${{ env.TALOS_VERSION }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} installer-base
- name: "Pi4 — Imager"
run: make TALOS_VERSION=${{ env.TALOS_VERSION }} REGISTRY=${{ env.REGISTRY }} REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} imager
- name: "Pi4 — Build installer image (with extensions)"
run: |
make TALOS_VERSION=${{ env.TALOS_VERSION }} \
REGISTRY=${{ env.REGISTRY }} \
REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} \
ASSET_TYPE=installer \
EXTENSIONS="${{ env.EXTENSIONS }}" \
installer-pi4
crane push \
./checkouts/talos/_out/installer-arm64.tar \
${{ env.REGISTRY }}/${{ env.REGISTRY_USERNAME }}/installer:${{ github.ref_name }}-rpi4
- name: "Pi4 — Build metal disk image"
run: |
make TALOS_VERSION=${{ env.TALOS_VERSION }} \
REGISTRY=${{ env.REGISTRY }} \
REGISTRY_USERNAME=${{ env.REGISTRY_USERNAME }} \
ASSET_TYPE=metal \
EXTENSIONS="${{ env.EXTENSIONS }}" \
installer-pi4
mv ./checkouts/talos/_out/metal-arm64.raw.zst ./metal-arm64-rpi4.raw.zst
# ──────────────────────────────────────────────
# Release
# ──────────────────────────────────────────────
- name: Create GitHub Release - name: Create GitHub Release
if: startsWith(github.ref, 'refs/tags/v')
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | run: |
INSTALLER_PI5="${{ env.REGISTRY }}/${{ env.REGISTRY_USERNAME }}/installer:${{ github.ref_name }}-rpi5"
INSTALLER_PI4="${{ env.REGISTRY }}/${{ env.REGISTRY_USERNAME }}/installer:${{ github.ref_name }}-rpi4"
NOTES=$(cat <<EOF NOTES=$(cat <<EOF
> ⚠️ Experimental build, use at your own risk. > ⚠️ Experimental build, use at your own risk.
This is a patched version of Talos tailored for the Raspberry Pi 5, including NVMe, NIC and USB support. Patched Talos Linux for **Raspberry Pi 5** and **Raspberry Pi 4 / CM4**, including NVMe, NIC and USB support.
### Extensions included ### Extensions included
- \`iscsi-tools\` ${{ env.EXTENSION_ISCSI_IMAGE }} - \`iscsi-tools\` ${{ env.EXTENSION_ISCSI_IMAGE }}
- \`util-linux-tools\` ${{ env.EXTENSION_UTIL_LINUX_IMAGE }} - \`util-linux-tools\` ${{ env.EXTENSION_UTIL_LINUX_IMAGE }}
### What's available ### Artifacts
- 📦 **Raw disk image** (\`metal-arm64.raw.zst\`) for fresh installs | Platform | Disk image | Installer image |
- ⚙️ **Installer image** (\`${{ env.REGISTRY }}/${{ env.REGISTRY_USERNAME }}/installer:${{ github.ref_name }}\`) for upgrades |----------|-----------|----------------|
| **RPi 5 / CM5** | \`metal-arm64-rpi5.raw.zst\` | \`${INSTALLER_PI5}\` |
### Install | **RPi 4 / CM4** | \`metal-arm64-rpi4.raw.zst\` | \`${INSTALLER_PI4}\` |
- **Fresh install** ### Fresh install
- Download the raw disk image from this release
- Flash with \`dd\` or your favorite tool Download the disk image for your board and flash it:
\`\`\`bash
- **Upgrade existing node** unzstd metal-arm64-rpi5.raw.zst # or metal-arm64-rpi4.raw.zst
\`\`\`bash dd if=metal-arm64-rpi5.raw of=<disk> bs=4M status=progress
talosctl upgrade --nodes <NODE_IP> --image ${{ env.REGISTRY }}/${{ env.REGISTRY_USERNAME }}/installer:${{ github.ref_name }} \`\`\`
\`\`\`
### Upgrade
\`\`\`bash
# Raspberry Pi 5
talosctl upgrade --nodes <NODE_IP> --image ${INSTALLER_PI5}
# Raspberry Pi 4 / CM4
talosctl upgrade --nodes <NODE_IP> --image ${INSTALLER_PI4}
\`\`\`
EOF EOF
) )
gh release create \ gh release create \
${{ github.ref_name }} \ ${{ github.ref_name }} \
./checkouts/talos/_out/metal-arm64.raw.zst \ metal-arm64-rpi5.raw.zst \
metal-arm64-rpi4.raw.zst \
--title "${{ github.ref_name }}" \ --title "${{ github.ref_name }}" \
--notes "$NOTES" --notes "$NOTES"
+1 -1
View File
@@ -1,5 +1,5 @@
PKG_VERSION = v1.11.0 PKG_VERSION = v1.11.0
TALOS_VERSION = v1.11.5 TALOS_VERSION ?= v1.11.5
SBCOVERLAY_VERSION = main SBCOVERLAY_VERSION = main
PUSH ?= true PUSH ?= true
+37 -17
View File
@@ -1,6 +1,6 @@
# Raspberry Pi 5 Talos Builder # Raspberry Pi 5 & Pi 4 Talos Builder
This repository serves as the glue to build custom Talos images for the Raspberry Pi 5. It patches the Kernel and Talos build process to use the Linux Kernel source provided by [raspberrypi/linux](https://github.com/raspberrypi/linux). This repository builds custom Talos Linux images for the **Raspberry Pi 5** and **Raspberry Pi 4 / CM4**. It patches the Kernel and Talos build process to use the Linux Kernel source provided by [raspberrypi/linux](https://github.com/raspberrypi/linux).
## Tested on ## Tested on
@@ -18,24 +18,34 @@ So far, this release has been verified on:
## How to use? ## How to use?
The releases on this repository align with the corresponding Talos version. There is a raw disk image (initial setup) and an installer image (upgrades) provided. Each release contains disk images and installer images for both Raspberry Pi 5 and Raspberry Pi 4 / CM4 platforms.
### Examples ### Examples
Initial: Initial:
```bash ```bash
unzstd metal-arm64-rpi.raw.zst # Raspberry Pi 5 / CM5
dd if=metal-arm64-rpi.raw of=<disk> bs=4M status=progress unzstd metal-arm64-rpi5.raw.zst
sync dd if=metal-arm64-rpi5.raw of=<disk> bs=4M status=progress
# Raspberry Pi 4 / CM4
unzstd metal-arm64-rpi4.raw.zst
dd if=metal-arm64-rpi4.raw of=<disk> bs=4M status=progress
``` ```
Upgrade: Upgrade:
```bash ```bash
# Raspberry Pi 5 / CM5
talosctl upgrade \ talosctl upgrade \
--nodes <node IP> \ --nodes <node IP> \
--image ghcr.io/talos-rpi5/installer:<version> --image ghcr.io/talos-rpi5/installer:<version>-rpi5
# Raspberry Pi 4 / CM4
talosctl upgrade \
--nodes <node IP> \
--image ghcr.io/talos-rpi5/installer:<version>-rpi4
``` ```
## Building ## Building
@@ -44,28 +54,38 @@ talosctl upgrade \
The CI workflow builds and publishes images automatically. It is triggered when you push a version tag: The CI workflow builds and publishes images automatically. It is triggered when you push a version tag:
- **Push a tag** matching `v*.*.*` — this triggers the full build and creates a GitHub Release: - **Push a tag** matching `v*.*.*` — this builds both Raspberry Pi 5 and Pi 4 / CM4 images and creates a GitHub Release:
```bash ```bash
git tag v1.11.5-cm5 git tag v1.11.6
git push origin v1.11.5-cm5 git push origin v1.11.6
``` ```
### Local build ### Local build
If you'd like to make modifications, it is possible to create your own build. Bellow is an example of the standard build. If you'd like to make modifications, it is possible to create your own build.
```bash ```bash
# Clones all dependencies and applies the necessary patches # Full pipeline for Raspberry Pi 5
make checkouts patches make REGISTRY=ghcr.io REGISTRY_USERNAME=<username> pi5
# Builds the Linux Kernel (can take a while) # Full pipeline for Raspberry Pi 4 / CM4
make REGISTRY=ghcr.io REGISTRY_USERNAME=<username> pi4
```
Or step by step:
```bash
# Clone dependencies and apply patches
make checkouts patches-pi5 # or patches-pi4
# Build the Linux Kernel (can take a while)
make REGISTRY=ghcr.io REGISTRY_USERNAME=<username> kernel make REGISTRY=ghcr.io REGISTRY_USERNAME=<username> kernel
# Builds the overlay (U-Boot, dtoverlays ...) # Build the overlay (Pi5 only — Pi4 uses the stock siderolabs overlay)
make REGISTRY=ghcr.io REGISTRY_USERNAME=<username> overlay make REGISTRY=ghcr.io REGISTRY_USERNAME=<username> overlay
# Final step to build the installer and disk image # Build the installer and disk image
make REGISTRY=ghcr.io REGISTRY_USERNAME=<username> installer make REGISTRY=ghcr.io REGISTRY_USERNAME=<username> installer-pi5 # or installer-pi4
``` ```
### Extensions support ### Extensions support