Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tinkerbell/charts: introduce showcase chart #89

Open
wants to merge 60 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
81a1f38
stack: introduce hook.downloadEnabled boolean to include/exclude hook…
rpardini Mar 23, 2024
75ea24c
tinkerbell/charts: introduce `showcase` chart
rpardini Mar 16, 2024
97aa178
showcase: add README
rpardini Mar 31, 2024
5e4fba0
showcase: 0.0.2: disable kexec on arm64, it doesn't really work (yet)
rpardini Mar 31, 2024
06f9e04
showcase: validate hookRef not unset
rpardini Apr 4, 2024
b66ed28
showcase: add R58X 3588 example & UEFI cloud image
rpardini Apr 4, 2024
f223138
showcase: VM examples
rpardini Apr 4, 2024
e571625
showcase: bump hook to rpardini's 20240404-2216; add `armbian-rk3588-…
rpardini Apr 4, 2024
5fb3b1c
showcase: add armbian cloud-k8s images for uefi arm64 and amd64
rpardini Apr 5, 2024
a1378dc
showcase: add `rock-5b-edge-trixie-uefi-dtb` image for Rock-5b
rpardini Apr 5, 2024
86cc121
showcase: default netplan to device `e*` (not `en*`) so it matches `e…
rpardini Apr 5, 2024
beaa1bb
showcase: install pkgs with DEBIAN_FRONTEND=noniteractive, no suggest…
rpardini Apr 8, 2024
b211b36
showcase: introduce doFixResolvConf at image level
rpardini Apr 10, 2024
b3acba5
showcase: reduce WAIT_SECONDS to zero
rpardini Apr 10, 2024
deecf4d
showcase: introduce 'download-only' and 'local' non-conversions
rpardini Apr 10, 2024
d9f4d7e
showcase: bump orangepi3b image
rpardini Apr 10, 2024
3d6904f
showcase: example 'fatso' baremetal images with download-only and loc…
rpardini Apr 10, 2024
f8b5621
showcase: HACK: change default Hook amd64 bootMode to reboot (this ne…
rpardini Apr 10, 2024
4c56722
showcase: bump fatso images version to 1001; add local variant examples
rpardini Apr 10, 2024
db59b3d
showcase: devices: show `imgstat` before `boot`
rpardini Apr 13, 2024
0610810
showcase: hook: allow skipping hook download via `skipDownload`
rpardini Apr 13, 2024
b3b98eb
showcase: bump hook versions; add examples for peg/pegk and skipDownload
rpardini Apr 13, 2024
6143325
showcase: bump hook versions; fix example
rpardini Apr 14, 2024
49fb1d1
showcase: allow to override hook's defaults via `hookOverride: {}` on…
rpardini Apr 14, 2024
a4a64fe
showcase: bump fatso images
rpardini Apr 14, 2024
e7f2f20
showcase: bump Hook version; add `latest-lts-xxx` Hooks; add more exa…
rpardini Apr 21, 2024
59e5231
showcase: add image's 'doInjectHegelCloudInit'; set device's `userDat…
rpardini Apr 21, 2024
0450340
showcase: bump images, reorg
rpardini Apr 21, 2024
7948551
showcase: add ntp stuff
rpardini Apr 22, 2024
2047515
showcase: bump images
rpardini Apr 22, 2024
7701e91
showcase: bump fatso
rpardini May 19, 2024
a8d6a01
showcase: add demo t95z (meson64)
rpardini May 19, 2024
0918819
showcase: switch to 20240519-1405 Hook, with new (old?) naming conven…
rpardini May 19, 2024
8f35c41
showcase: bump Hook to 20240519-1935 (new scheme)
rpardini May 19, 2024
244a56a
showcase: bump Hook to 20240520-0729
rpardini May 20, 2024
7484af4
showcase: bump Hook to 20240520-0941 (finally working armbian's again!)
rpardini May 20, 2024
5bb46da
showcase: add support for `xz-qcow2-to-img-gz` image conversion
rpardini May 20, 2024
740f784
showcase: bump all armsurvivors Armbian images to 24.05.20-armsurvivo…
rpardini May 20, 2024
fa5b565
showcase: fix default userdata script
rpardini May 22, 2024
2bc2a93
showcase: bump Hooks; bump images; add rpi4b armbian cloud image; add…
rpardini May 22, 2024
d50e310
showcase: bump Hook to 20240603-0515 (mdev by-id fixes); bump fatso i…
rpardini Jun 1, 2024
d746479
showcase: bump Hook to 20240604-0609 (further mdev by-id fixes)
rpardini Jun 4, 2024
17424c2
showcase: use rpardini's fork of waitdaemon at quay.io
rpardini Jun 4, 2024
fa111e5
showcase: WiP: nanopct6 (ipxe won't load, even with DTB)
rpardini Jun 9, 2024
b9705d2
showcase: introduce image.doAddEFIBootEntry for efibootmgr juggling a…
rpardini Jun 9, 2024
2ccea7b
showcase: introduce image.doRestoreGRUBNormalcy for GRUB+EFI entry ju…
rpardini Jun 9, 2024
13fb7c7
--> introduce 'suite' chart
rpardini Mar 31, 2024
2bfe7fe
suite: copy some settings from showcase for easy custom; disable all …
rpardini Mar 31, 2024
8231198
suite: bump showcase to 0.0.2 for kexec disablement
rpardini Mar 31, 2024
000fbc2
suite: deploy Smee using "Recreate" strategy, lest it conflicts with …
rpardini Apr 8, 2024
c5bb19f
suite: add a NodePort service for Hegel, on 32061
rpardini Apr 21, 2024
8ef8f33
suite: make all NodePorts externalTrafficSource: Local
rpardini Apr 21, 2024
33b2826
suite: set default hegelURL using Hegel's NodePort
rpardini Apr 21, 2024
23f9f6f
suite: experiments
rpardini Apr 14, 2024
02c63b6
suite: config ntp & bump smee for ntp fix
rpardini Apr 22, 2024
339a0b3
suite: add t95z, enable qemu's
rpardini May 20, 2024
40b958d
suite: update smee reference; add more examples
rpardini May 22, 2024
6868a32
suite: use Smee chart 0.3.3 version
rpardini Mar 23, 2024
12afb6d
suite: bump dependencies after upstream/main rebase
rpardini Jun 8, 2024
b7d362c
suite: bump to quay.io/tinkerbellrpardini/smee:latest-rpardini10 with…
rpardini Jun 8, 2024
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
6 changes: 6 additions & 0 deletions tinkerbell/showcase/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v2
name: showcase
description: Generates Tinkerbell CR's for a plethora of standard and exotic hardware; downloads & prepares Hook and OS images for provisioning
type: application
version: "0.0.2"

31 changes: 31 additions & 0 deletions tinkerbell/showcase/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#### tinkerbell/charts: introduce `showcase` chart

- `showcase` is a chart that, based on values.yaml dictionaries:
- generates Tinkerbell CRs (Hardware/Template/Workflow) for both standard (UEFI) & exotic (supported by Armbian) devices
- generates download/process jobs for multiple Hook flavors (see https://github.com/tinkerbell/hook/pull/205)
- generates download/process jobs for a few OS images (Ubuntu Cloud Images, Armbian, etc)
- should be independent of how one deployed Tinkerbell itself (stack chart, individual components, etc)
- A few features:
- validates values.yaml for common mistakes; arch must match, etc.
- validates & handles rootDisk differences (re-invents "formatPartition()" a bit)
- avoids re-downloading Hooks and Images that are already on disk, even if Job re-runs
- allows easy way to use
- custom Hooks
- custom Kernel cmdline parameters at both the Hook & device level
- for example `acpi=off` at Hook level and `console=ttyS0` at board level
- custom OS images for deployment
- reboot or kexec to finish deployment
- different partition numbers for OS image's rootfs (some images have ESP, some have a separate `/boot`, etc)
- control if growpart and/or ssh/user setup is done during provisioning or not
- conversion of OS images (`qemu-to-raw-gzip` and `xz-to-gz`)
- has a "merge" mechanism with a common way to set parameters like net gateway, UEFI, etc (also easy to override per-device)
- default values have everything `enabled: false` thus showcase should produce nothing by default.
- Hooks & Images can be forced `enabled: true` in values.yaml, or
- `enabled: true` Devices automatically enable their Hook & Image
- Probably missing:
- More validations
- Currently pointing to my Tinkerbell Actions, which I haven't PR'ed yet
- How to use:
- Clone it, edit the values.yaml to your liking, and deploy.

Signed-off-by: Ricardo Pardini <[email protected]>
345 changes: 345 additions & 0 deletions tinkerbell/showcase/templates/devices.yaml

Large diffs are not rendered by default.

103 changes: 103 additions & 0 deletions tinkerbell/showcase/templates/hooks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
{{- range $hookId, $hook := .Values.provision.hook }}
{{- $common := $.Values.provision.common -}}
{{- $hook = merge $hook $common }}
---
# --> HookId: {{$hookId}}
# downloadId: {{ $hook.hookDownloadId }}
# downloadFile: {{ $hook.downloadFile }}
# hookDownloadBaseUrl: {{ $hook.hookDownloadBaseUrl }}
{{- $hash := trunc 8 (sha1sum (printf "%s-%s-%s" $hook.hookDownloadId $hook.hookDownloadBaseUrl $hook.downloadFile)) }}
# Loop over $.Values.hardware.devices (a dictionary) and for each value, check if it's hookRef matches this $hookId - if so, enable this hook.
{{- $enabledByDeviceUsage := false }}
{{- range $device := $.Values.hardware.devices }}
# Testing {{$device.hookRef}} against {{$hookId}}...
{{- if and $device.enabled (eq $device.hookRef $hookId) -}}
# YES!
{{- $enabledByDeviceUsage = true -}}
{{- else -}}
# NO!
{{- end -}}
{{- end }}

{{- if or $enabledByDeviceUsage $hook.enabled }}
# Enabled hook: {{$hookId}} - force enabled? {{$hook.enabled}} -- enabled by device usage? {{$enabledByDeviceUsage}}
apiVersion: v1
kind: ConfigMap
metadata:
name: "download-hook-{{$hookId}}-{{$hash}}"
namespace: "{{ $.Release.Namespace }}"
labels:
"app.kubernetes.io/instance": "{{ $.Release.Name }}"
"app.kubernetes.io/part-of": "tinkerbell-showcase"
data:
entrypoint.sh: |
#!/usr/bin/env bash
# This script is designed to download the Hook artifacts.
set -euxo pipefail
if [[ -f "/output/download_hook_{{$hookId}}_{{$hash}}.done" ]]; then
echo "Hook already downloaded ({{$hookId}} - hash: {{$hash}}), skipping."
exit 0
fi

{{
if $hook.skipDownload
}}
echo "Skipping download for hook {{$hookId}}."
ls -lah "/output/{{$hook.kernel}}"
ls -lah "/output/{{$hook.initrd}}"
touch "/output/download_hook_{{$hookId}}_{{$hash}}.done"
{{ else }}
mkdir -p "/output/download_hook_{{$hookId}}"
cd "/output/download_hook_{{$hookId}}"
declare down_url="{{ $hook.hookDownloadBaseURL }}{{$hook.downloadFile}}"
declare down_file="/output/download_hook_{{$hookId}}/{{$hook.downloadFile}}"
wget -O "${down_file}.tmp" "${down_url}"
mv -v "${down_file}.tmp" "${down_file}"
mkdir -p "/output/download_hook_{{$hookId}}/extract"
cd "/output/download_hook_{{$hookId}}/extract"
tar -xvzf "${down_file}"
mv -v "/output/download_hook_{{$hookId}}/extract/"* /output/
rm -rf "/output/download_hook_{{$hookId}}"
ls -lah "/output/{{$hook.kernel}}"
ls -lah "/output/{{$hook.initrd}}"
touch "/output/download_hook_{{$hookId}}_{{$hash}}.done" {{ end }}

---
apiVersion: batch/v1
kind: Job
metadata:
name: "download-hook-{{$hookId}}-{{$hash}}"
namespace: {{ $.Release.Namespace }}
labels:
"app.kubernetes.io/instance": "{{ $.Release.Name }}"
"app.kubernetes.io/part-of": "tinkerbell-showcase"
spec:
backoffLimit: 50
template:
metadata:
labels:
app: download-hook
spec:
containers:
- name: download-hook-{{$hookId}}
image: bash:5
command: [ "/script/entrypoint.sh" ]
volumeMounts:
- mountPath: /output
name: hook-artifacts
- mountPath: /script
name: configmap-volume
restartPolicy: OnFailure
volumes:
- name: hook-artifacts
hostPath:
path: {{ $.Values.tinkerbell.hostDirectory | quote }}
type: DirectoryOrCreate
- name: configmap-volume
configMap:
defaultMode: 0700
name: "download-hook-{{$hookId}}-{{$hash}}"
{{- else }}
# Disabled Hook: {{$hookId}}
{{- end }}
{{- end }}
182 changes: 182 additions & 0 deletions tinkerbell/showcase/templates/images.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
{{- range $imageId, $image := .Values.provision.images }}
---
# --> ImageId: {{ $imageId }}
# downloadUrl: "{{ $image.downloadURL }}"
# image: "{{ $image.image }}"
# conversion: "{{ $image.conversion }}"
{{- $hash := trunc 8 (sha1sum (printf "%s-%s-%s" $image.downloadURL $image.image $image.conversion )) }}
# Loop over $.Values.hardware.devices (a dictionary) and for each value, check if it's imageRef matches this $imageId - if so, enable this image.
{{- $enabledByDeviceUsage := false }}
{{- range $device := $.Values.hardware.devices }}
# Testing {{$device.imageRef}} against {{$imageId}}...
{{- if and $device.enabled (eq $device.imageRef $imageId) -}}
# YES!
{{- $enabledByDeviceUsage = true -}}
{{- else -}}
# NO!
{{- end -}}
{{- end }}
{{- if or $enabledByDeviceUsage $image.enabled }}
# ImageId: {{ $imageId }} - force enabled? {{ $image.enabled }} -- enabled by device usage? {{ $enabledByDeviceUsage }}
apiVersion: v1
kind: ConfigMap
metadata:
name: "download-image-{{$imageId}}-{{$hash}}"
labels:
"app.kubernetes.io/instance": "{{ $.Release.Name }}"
"app.kubernetes.io/part-of": "tinkerbell-showcase"
data:
entrypoint.sh: |-
#!/usr/bin/env bash
set -euxo pipefail
cat > /etc/apk/repositories << EOF; $(echo)
https://dl-cdn.alpinelinux.org/alpine/v$(cut -d'.' -f1,2 /etc/alpine-release)/main/
https://dl-cdn.alpinelinux.org/alpine/v$(cut -d'.' -f1,2 /etc/alpine-release)/community/
https://dl-cdn.alpinelinux.org/alpine/edge/community/
EOF
{{- if eq "qemu-to-raw-gzip" $image.conversion }}
# This script is designed to download a cloud image file (.img) and then convert it to a .raw.gz file.
# This is purpose built so non-raw cloud image files can be used with the "image2disk" action.
# See https://artifacthub.io/packages/tbaction/tinkerbell-community/image2disk.
image_url=$1
file=$2/${image_url##*/}
file=${file%.*}.raw.gz
if [[ ! -f "$file" ]]; then
echo "Image file $file does not exist. Downloading...."
apk add --update pigz qemu-img
wget "$image_url" -O image.img
qemu-img convert -O raw image.img image.raw
pigz < image.raw > "$file"
rm -f image.img image.raw
else
echo "File $file already exists, skipping download and conversion."
fi
{{- end }}

{{- if eq "none" $image.conversion }}
# No conversion, just a simple download; image must be in raw format, possibly compressed.
image_url="{{ $image.downloadURL }}"
file="/output/{{ $image.image }}"
if [[ ! -f "$file" ]]; then
echo "Image file $file does not exist. Downloading...."
wget "$image_url" -O "${file}.tmp"
mv -v "${file}.tmp" "$file"
echo "Done downloading image."
else
echo "Image file $file already exists. Skipping download."
fi
{{- end }}

{{- if eq "xz-to-gz" $image.conversion }}
# Download, then produce a .gz file from a .xz file, using pigz and pixz, and using a pipe.
image_url="{{ $image.downloadURL }}"
file="/output/{{ $image.image }}"
if [[ ! -f "$file" ]]; then
echo "Image file $file does not exist. Downloading...."
apk add --update pigz pixz
wget "$image_url" -O "${file}.tmp.xz"
echo "Done downloading image. Converting from xz to gz..."
pixz -d < "${file}.tmp.xz" | pigz > "${file}.tmp"
mv -v "${file}.tmp" "$file"
echo "Done converting image."
rm -f "${file}.tmp.xz"
else
echo "Image file $file already exists. Skipping download."
fi
{{- end }}

{{- if eq "xz-qcow2-to-img-gz" $image.conversion }}
# Download, decompress xz, convert qcow2 to img, compress img to gz.
image_url="{{ $image.downloadURL }}"
file="/output/{{ $image.image }}"
if [[ ! -f "$file" ]]; then
echo "Image file $file does not exist. Downloading...."
apk add --update pigz pixz qemu-img
wget "$image_url" -O "${file}.tmp.xz"
echo "Done downloading image. Decompressing xz..."
pixz -d < "${file}.tmp.xz" > "${file}.tmp.unxz"
rm -v "${file}.tmp.xz"
echo "Done decompressing xz, converting qcow2 to img..."
qemu-img convert -O raw "${file}.tmp.unxz" "${file}.tmp.raw"
rm -v "${file}.tmp.unxz"
echo "Done converting qcow2 to img, compressing img to gz..."
pigz < "${file}.tmp.raw" > "${file}"
rm -v "${file}.tmp.raw"
echo "Done converting image."
else
echo "Image file $file already exists. Skipping download."
fi
{{- end }}

{{- if eq "download-only" $image.conversion }}
# Download only. Image is already in format necessary.
image_url="{{ $image.downloadURL }}"
file="/output/{{ $image.image }}"
if [[ ! -f "$file" ]]; then
echo "Download-only Image file $file does not exist. Downloading...."
wget "$image_url" -O "${file}.tmp"
echo "Done downloading image. Moving..."
mv -v "${file}.tmp" "$file"
echo "Done moving image."
rm -f "${file}.tmp.xz"
else
echo "Download-only image file $file already exists. Skipping download."
fi
{{- end }}

{{- if eq "local" $image.conversion }}
# Not even download anything. Image should be in there already somehow.
image_url="{{ $image.downloadURL }}"
file="/output/{{ $image.image }}"
if [[ ! -f "$file" ]]; then
echo "Image file $file does not exist. Please deploy image file manually, or use a different conversion than none. Sleeping 10s and exiting with error 66."
sleep 10
exit 66
else
echo "No-conversion image file $file already exists. Ready to use."
fi
{{- end }}

---
apiVersion: batch/v1
kind: Job
metadata:
name: "download-image-{{$imageId}}-{{$hash}}"
labels:
"app.kubernetes.io/instance": "{{ $.Release.Name }}"
"app.kubernetes.io/part-of": "tinkerbell-showcase"
spec:
template:
metadata:
labels:
"app.kubernetes.io/instance": "{{ $.Release.Name }}"
"app.kubernetes.io/part-of": "tinkerbell-showcase"
spec:
containers:
- name: download-{{$imageId}}
image: bash:5
command: [ "/script/entrypoint.sh" ]
args:
[
"{{$image.downloadURL}}",
"/output",
]
volumeMounts:
- mountPath: /output
name: image-artifacts
- mountPath: /script
name: configmap-volume
restartPolicy: OnFailure
volumes:
- name: image-artifacts
hostPath:
path: {{ $.Values.tinkerbell.hostDirectory }}
type: DirectoryOrCreate
- name: configmap-volume
configMap:
defaultMode: 0700
name: "download-image-{{$imageId}}-{{$hash}}"
{{- else }}
# ImageId: {{ $imageId }} DISABLED - force enabled? {{ $image.enabled }} -- enabled by device usage? {{ $enabledByDeviceUsage }}
{{- end }}
{{- end }}
Loading
Loading