Seed bootapi-images: AlmaLinux node rootfs build
Builds the AlmaLinux 9 node rootfs tarball bootapi's image-based provisioning (liveimg) unpacks, and on a v* tag publishes almalinux9-node-<ver>.tar.zst to the artifactapi rootfs-images repo. Moved out of bootapi-templates (which stays templates-only) per review on bootapi-templates#3. - packages.txt (bake list) + scripts/build-rootfs.sh (dnf --installroot -> tar.zst). - .woodpecker: pre-commit + shellcheck (PR); build+upload on v* tag. - Makefile (build/lint/patch|minor|major). Claude-Session: https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
/rootfs/
|
||||
/dist/
|
||||
@@ -0,0 +1,20 @@
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
- id: check-merge-conflict
|
||||
|
||||
- repo: https://github.com/adrienverge/yamllint
|
||||
rev: v1.35.1
|
||||
hooks:
|
||||
- id: yamllint
|
||||
args: [-c, .yamllint.yaml]
|
||||
|
||||
- repo: https://github.com/shellcheck-py/shellcheck-py
|
||||
rev: v0.10.0.1
|
||||
hooks:
|
||||
- id: shellcheck
|
||||
@@ -0,0 +1,18 @@
|
||||
when:
|
||||
- event: [pull_request, push]
|
||||
|
||||
steps:
|
||||
- name: lint
|
||||
image: koalaman/shellcheck-alpine:stable
|
||||
commands:
|
||||
- shellcheck scripts/*.sh
|
||||
backend_options:
|
||||
kubernetes:
|
||||
serviceAccountName: default
|
||||
resources:
|
||||
requests:
|
||||
memory: 128Mi
|
||||
cpu: 100m
|
||||
limits:
|
||||
memory: 512Mi
|
||||
cpu: 500m
|
||||
@@ -0,0 +1,18 @@
|
||||
when:
|
||||
- event: [pull_request, push]
|
||||
|
||||
steps:
|
||||
- name: pre-commit
|
||||
image: git.unkin.net/unkin/almalinux9-gobuilder:20260606
|
||||
commands:
|
||||
- uvx pre-commit run --all-files
|
||||
backend_options:
|
||||
kubernetes:
|
||||
serviceAccountName: default
|
||||
resources:
|
||||
requests:
|
||||
memory: 512Mi
|
||||
cpu: 1
|
||||
limits:
|
||||
memory: 2Gi
|
||||
cpu: 2
|
||||
@@ -0,0 +1,57 @@
|
||||
when:
|
||||
- event: tag
|
||||
ref: refs/tags/v*
|
||||
|
||||
# On a v* tag: build the AlmaLinux 9 node rootfs and publish
|
||||
# almalinux9-node-<tag-without-v>.tar.zst to the artifactapi rootfs-images local
|
||||
# repo, where the bootapi-templates almalinux9-image catalog entry's liveimg
|
||||
# points. Bump the image with `make patch|minor|major`.
|
||||
steps:
|
||||
- name: build-rootfs
|
||||
image: git.unkin.net/unkin/almalinux9-base:20260606
|
||||
commands:
|
||||
- dnf -y install tar zstd
|
||||
- ./scripts/build-rootfs.sh ${CI_COMMIT_TAG}
|
||||
backend_options:
|
||||
kubernetes:
|
||||
serviceAccountName: default
|
||||
resources:
|
||||
requests:
|
||||
memory: 2Gi
|
||||
cpu: 2
|
||||
ephemeral-storage: 8Gi
|
||||
limits:
|
||||
memory: 4Gi
|
||||
cpu: 4
|
||||
ephemeral-storage: 16Gi
|
||||
|
||||
- name: upload
|
||||
image: git.unkin.net/unkin/almalinux9-base:20260606
|
||||
commands:
|
||||
- |
|
||||
VER="${CI_COMMIT_TAG#v}"
|
||||
HOST="https://artifactapi.k8s.syd1.au.unkin.net"
|
||||
REPO="rootfs-images"
|
||||
FILE="almalinux9-node-$${VER}.tar.zst"
|
||||
# Immutable, versioned artifact; skip if this version already exists.
|
||||
code=$$(curl -s -o /dev/null -w '%{http_code}' "$$HOST/api/v2/remotes/$$REPO/files/$$FILE" || true)
|
||||
if [ "$$code" = "200" ]; then
|
||||
echo "$$FILE already exists (HTTP $$code); skipping upload"
|
||||
exit 0
|
||||
fi
|
||||
curl -f -X PUT "$$HOST/api/v2/remotes/$$REPO/files/$$FILE" \
|
||||
-H "Content-Type: application/zstd" \
|
||||
--data-binary @"dist/$$FILE"
|
||||
depends_on: [build-rootfs]
|
||||
backend_options:
|
||||
kubernetes:
|
||||
serviceAccountName: default
|
||||
resources:
|
||||
requests:
|
||||
memory: 512Mi
|
||||
cpu: 500m
|
||||
ephemeral-storage: 8Gi
|
||||
limits:
|
||||
memory: 1Gi
|
||||
cpu: 1
|
||||
ephemeral-storage: 16Gi
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
extends: relaxed
|
||||
|
||||
rules:
|
||||
line-length: disable
|
||||
document-start: disable
|
||||
comments:
|
||||
min-spaces-from-content: 1
|
||||
@@ -0,0 +1,32 @@
|
||||
.PHONY: build lint clean patch minor major
|
||||
|
||||
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "0.0.0-dev")
|
||||
|
||||
# Build the rootfs tarball locally (needs dnf + tar + zstd; run as root).
|
||||
build:
|
||||
./scripts/build-rootfs.sh $(VERSION)
|
||||
|
||||
lint:
|
||||
shellcheck scripts/*.sh
|
||||
|
||||
clean:
|
||||
rm -rf rootfs/ dist/
|
||||
|
||||
# --- version bump: tag + push triggers the release pipeline (build + upload) ---
|
||||
_LATEST := $(shell git tag --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$$' | head -1)
|
||||
_BASE := $(if $(_LATEST),$(_LATEST),v0.0.0)
|
||||
_MAJ := $(shell echo $(_BASE) | sed 's/^v//' | cut -d. -f1)
|
||||
_MIN := $(shell echo $(_BASE) | sed 's/^v//' | cut -d. -f2)
|
||||
_PAT := $(shell echo $(_BASE) | sed 's/^v//' | cut -d. -f3)
|
||||
|
||||
patch:
|
||||
@NEW=v$(_MAJ).$(_MIN).$(shell expr $(_PAT) + 1); \
|
||||
git tag $$NEW && echo "Tagged $$NEW" && git push origin $$NEW
|
||||
|
||||
minor:
|
||||
@NEW=v$(_MAJ).$(shell expr $(_MIN) + 1).0; \
|
||||
git tag $$NEW && echo "Tagged $$NEW" && git push origin $$NEW
|
||||
|
||||
major:
|
||||
@NEW=v$(shell expr $(_MAJ) + 1).0.0; \
|
||||
git tag $$NEW && echo "Tagged $$NEW" && git push origin $$NEW
|
||||
@@ -1,3 +1,41 @@
|
||||
# bootapi-images
|
||||
|
||||
Builds AlmaLinux node rootfs tarballs for bootapi image-based provisioning; on v* tag publishes almalinux9-node-<ver>.tar.zst to the artifactapi rootfs-images repo.
|
||||
Builds the AlmaLinux 9 **node rootfs** tarball that
|
||||
[bootapi](https://git.unkin.net/unkin/bootapi)'s image-based provisioning unpacks
|
||||
with Anaconda `liveimg`. On a `v*` tag it publishes
|
||||
`almalinux9-node-<ver>.tar.zst` to the artifactapi `rootfs-images` local repo,
|
||||
where the [bootapi-templates](https://git.unkin.net/unkin/bootapi-templates)
|
||||
`almalinux9-image` catalog entry's `rootfs_tarball` points.
|
||||
|
||||
This is the build half; the kickstart/catalog that *consumes* the tarball live in
|
||||
bootapi-templates. Kept separate so that repo stays templates-only.
|
||||
|
||||
## What's baked in
|
||||
|
||||
`packages.txt` is the package set installed into the rootfs — everything the
|
||||
`image.ks.tmpl` `%post` assumes is already present (kernel, grub2 BIOS+UEFI,
|
||||
dracut, NetworkManager, openssh, chrony, kexec-tools, curl, …). `puppet-agent` is
|
||||
added from the puppet platform repo in `scripts/build-rootfs.sh`. Per-host config
|
||||
(networking, hostname, puppet server, callback) stays in the kickstart `%post`.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
packages.txt # bake list (one package per line)
|
||||
scripts/build-rootfs.sh # dnf --installroot -> tar.zst
|
||||
.woodpecker/ # pre-commit + lint (PR); release build+upload (v* tag)
|
||||
Makefile # build / lint / patch|minor|major
|
||||
```
|
||||
|
||||
## Releasing an image
|
||||
|
||||
`make patch|minor|major` tags `v<x.y.z>` and pushes; CI builds the rootfs and
|
||||
uploads `almalinux9-node-<x.y.z>.tar.zst`. Then bump `rootfs_tarball` in the
|
||||
bootapi-templates `almalinux9-image` catalog entry to the new version (immutable;
|
||||
overwrites are 409-rejected).
|
||||
|
||||
Build locally (needs `dnf`, `tar`, `zstd`, root):
|
||||
|
||||
```bash
|
||||
make build VERSION=v0.0.0-dev
|
||||
```
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# Package set baked into the AlmaLinux 9 node rootfs image.
|
||||
# Everything image.ks.tmpl's %post assumes is already installed (puppet-agent is
|
||||
# added separately in build-rootfs.sh from the puppet platform repo). One package
|
||||
# per line; blank lines and # comments ignored.
|
||||
|
||||
# base system + kernel
|
||||
@core
|
||||
kernel
|
||||
|
||||
# boot chain: BIOS + UEFI (fleet firmware is not standardized yet)
|
||||
grub2-pc
|
||||
grub2-efi-x64
|
||||
shim-x64
|
||||
grub2-tools
|
||||
grub2-tools-efi
|
||||
efibootmgr
|
||||
dracut
|
||||
dracut-config-generic
|
||||
|
||||
# storage
|
||||
lvm2
|
||||
xfsprogs
|
||||
e2fsprogs
|
||||
dosfstools
|
||||
|
||||
# networking + selinux
|
||||
NetworkManager
|
||||
selinux-policy-targeted
|
||||
policycoreutils
|
||||
|
||||
# node tooling (matches the classic package install)
|
||||
openssh-server
|
||||
chrony
|
||||
kexec-tools
|
||||
bind-utils
|
||||
vim-minimal
|
||||
tmux
|
||||
git
|
||||
curl
|
||||
glibc-langpack-en
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build the AlmaLinux 9 node rootfs and tar it as almalinux9-node-<ver>.tar.zst
|
||||
# for bootapi image-based provisioning (liveimg). Usage:
|
||||
# scripts/build-rootfs.sh [version] (version defaults to ${CI_COMMIT_TAG#v})
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${ROOT_DIR}"
|
||||
|
||||
VER="${1:-${CI_COMMIT_TAG:-0.0.0-dev}}"
|
||||
VER="${VER#v}"
|
||||
RELEASEVER="${RELEASEVER:-9}"
|
||||
ROOTFS="${ROOTFS:-${ROOT_DIR}/rootfs}"
|
||||
DIST="${DIST:-${ROOT_DIR}/dist}"
|
||||
OUT="${DIST}/almalinux9-node-${VER}.tar.zst"
|
||||
|
||||
# Read the bake list (skip comments / blank lines).
|
||||
mapfile -t PKGS < <(grep -vE '^[[:space:]]*(#|$)' packages.txt)
|
||||
if [ "${#PKGS[@]}" -eq 0 ]; then
|
||||
echo "ERROR: packages.txt is empty" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf "${ROOTFS}"
|
||||
mkdir -p "${ROOTFS}" "${DIST}"
|
||||
|
||||
dnf -y --installroot="${ROOTFS}" --releasever="${RELEASEVER}" \
|
||||
--setopt=install_weak_deps=False install "${PKGS[@]}"
|
||||
|
||||
# Puppet agent from the puppet platform repo (baked; image.ks.tmpl %post only
|
||||
# configures it).
|
||||
dnf -y --installroot="${ROOTFS}" install https://yum.puppet.com/puppet8-release-el-9.noarch.rpm
|
||||
dnf -y --installroot="${ROOTFS}" install puppet-agent
|
||||
|
||||
dnf -y --installroot="${ROOTFS}" clean all
|
||||
rm -rf "${ROOTFS}"/var/cache/dnf/* "${ROOTFS}"/var/log/dnf* "${ROOTFS}"/etc/machine-id
|
||||
|
||||
# Reproducible, ownership/xattr/SELinux-preserving tarball.
|
||||
tar --numeric-owner --acls --xattrs --selinux -C "${ROOTFS}" -caf "${OUT}" .
|
||||
|
||||
echo "Built: ${OUT}"
|
||||
ls -lh "${OUT}"
|
||||
Reference in New Issue
Block a user