Skip to content

Build & Push Slurmd Warewulf Image #34

Build & Push Slurmd Warewulf Image

Build & Push Slurmd Warewulf Image #34

name: Build & Push Slurmd Warewulf Image
on:
push:
branches:
- latest
workflow_dispatch:
inputs:
SLURM_VERSION_OVERRIDE:
description: 'Specific Slurm version (e.g., 24-11-5-1). Use "0" for latest.'
required: false
default: '0'
KERNEL_VERSION_OVERRIDE:
description: 'Specific kernel version (e.g., 7.0). Use "0" for default kernel, "none" for no kernel installation.'
required: false
default: '7.0'
DISABLE_AUTOLOGIN:
description: 'Disable console autologin (1=Yes, 0=No).'
required: true
type: choice
options:
- '1' # True
- '0' # False
default: '0'
NVIDIA_INSTALL_ENABLED:
description: 'Enable NVIDIA driver installation (1=Yes, 0=No).'
required: true
type: choice
options:
- '1' # True
- '0' # False
default: '1'
NVIDIA_DRIVER_VERSION_OVERRIDE:
description: 'Specific NVIDIA driver version (e.g., 550.90.07). Use "0" for latest.'
required: false
default: '0'
FIRSTBOOT_ENABLED:
description: 'Enable firstboot Ansible service (1=Yes, 0=No).'
required: true
type: choice
options:
- '1' # True
- '0' # False
default: '1'
schedule:
- cron: '0 3 * * 1' # Every Monday at 3:00 AM UTC
env:
TAG_NAME: ${{ github.ref_name }}
jobs:
build-and-push:
name: Build & Push SlurmD WareWulf Image
runs-on: ubuntu-24.04
steps:
- name: 🛠️ Checkout Repository
uses: actions/checkout@v6
- name: 🔧 Configure Build & Verify Dependencies
id: config
env:
# Pass ALL potential inputs and variables into the script's environment
INPUT_SLURM_VERSION: ${{ github.event.inputs.SLURM_VERSION_OVERRIDE }}
VAR_SLURM_VERSION: ${{ vars.SLURM_VERSION_OVERRIDE }}
INPUT_KERNEL_VERSION: ${{ github.event.inputs.KERNEL_VERSION_OVERRIDE }}
VAR_KERNEL_VERSION: ${{ vars.KERNEL_VERSION_OVERRIDE }}
INPUT_DISABLE_AUTOLOGIN: ${{ github.event.inputs.DISABLE_AUTOLOGIN }}
VAR_DISABLE_AUTOLOGIN: ${{ vars.DISABLE_AUTOLOGIN }}
INPUT_NVIDIA_ENABLED: ${{ github.event.inputs.NVIDIA_INSTALL_ENABLED }}
VAR_NVIDIA_ENABLED: ${{ vars.NVIDIA_INSTALL_ENABLED }}
INPUT_NVIDIA_VERSION: ${{ github.event.inputs.NVIDIA_DRIVER_VERSION_OVERRIDE }}
VAR_NVIDIA_VERSION: ${{ vars.NVIDIA_DRIVER_VERSION_OVERRIDE }}
INPUT_FIRSTBOOT_ENABLED: ${{ github.event.inputs.FIRSTBOOT_ENABLED }}
VAR_FIRSTBOOT_ENABLED: ${{ vars.FIRSTBOOT_ENABLED }}
run: |
set -e # Exit on any error
echo "--- Debugging Raw Input/Variable Values ---"
echo "INPUT_KERNEL_VERSION: '$INPUT_KERNEL_VERSION'"
echo "VAR_KERNEL_VERSION: '$VAR_KERNEL_VERSION'"
echo "INPUT_FIRSTBOOT_ENABLED: '$INPUT_FIRSTBOOT_ENABLED'"
echo "VAR_FIRSTBOOT_ENABLED: '$VAR_FIRSTBOOT_ENABLED'"
echo "-------------------------------------------"
lower() { echo "$1" | tr '[:upper:]' '[:lower:]'; }
echo "## 1. Normalizing Autologin Option ##"
AUTOLOGIN_VAL="0"
if [ -n "$INPUT_DISABLE_AUTOLOGIN" ]; then AUTOLOGIN_VAL="$INPUT_DISABLE_AUTOLOGIN";
elif [ -n "$VAR_DISABLE_AUTOLOGIN" ]; then AUTOLOGIN_VAL="$VAR_DISABLE_AUTOLOGIN"; fi
if [ "$(lower "$AUTOLOGIN_VAL")" = "1" ] || [ "$(lower "$AUTOLOGIN_VAL")" = "true" ]; then
echo "DISABLE_AUTOLOGIN=true" >> $GITHUB_OUTPUT
else
echo "DISABLE_AUTOLOGIN=false" >> $GITHUB_OUTPUT
fi
echo "## 2. Normalizing Firstboot Option ##"
FIRSTBOOT_VAL="1"
if [ -n "$INPUT_FIRSTBOOT_ENABLED" ]; then FIRSTBOOT_VAL="$INPUT_FIRSTBOOT_ENABLED";
elif [ -n "$VAR_FIRSTBOOT_ENABLED" ]; then FIRSTBOOT_VAL="$VAR_FIRSTBOOT_ENABLED"; fi
if [ "$(lower "$FIRSTBOOT_VAL")" = "1" ] || [ "$(lower "$FIRSTBOOT_VAL")" = "true" ]; then
echo "FIRSTBOOT_ENABLED=true" >> $GITHUB_OUTPUT
else
echo "FIRSTBOOT_ENABLED=false" >> $GITHUB_OUTPUT
fi
echo -e "\n## 3. Processing Kernel Configuration & Verifying Packages ##"
# Normalize Kernel Version Override
KERNEL_VERSION_OVERRIDE="7.0"
if [ -n "$INPUT_KERNEL_VERSION" ]; then
KERNEL_VERSION_OVERRIDE="$INPUT_KERNEL_VERSION"
elif [ -n "$VAR_KERNEL_VERSION" ]; then
KERNEL_VERSION_OVERRIDE="$VAR_KERNEL_VERSION"
fi
# Check if kernel installation should be enabled
if [ "$KERNEL_VERSION_OVERRIDE" = "none" ]; then
echo "🎯 Kernel installation DISABLED (no kernel option selected)"
echo "KERNEL_INSTALL_ENABLED=false" >> $GITHUB_OUTPUT
echo "KERNEL_VERSION=none" >> $GITHUB_OUTPUT
else
echo "🎯 Resolving best matching kernel version from ubuntu:26.04 apt repositories..."
if [ "$KERNEL_VERSION_OVERRIDE" = "0" ]; then
RESOLVED_KERNEL_VERSION=$(docker run --rm ubuntu:26.04 bash -c 'apt-get update -qq >/dev/null 2>&1 && GENERIC_VERSION=$(apt-cache policy linux-image-generic | grep Candidate | awk "{print \$2}") && apt-cache show "linux-image-generic=${GENERIC_VERSION}" | grep -E "^Depends:" | sed -E "s/.*linux-image-([0-9]+\.[0-9]+\.[0-9]+-[0-9]+-generic).*/\1/" | head -n1')
else
RESOLVED_KERNEL_VERSION=$(docker run --rm ubuntu:26.04 bash -c "apt-get update -qq >/dev/null 2>&1 && apt-cache search \"^linux-image-${KERNEL_VERSION_OVERRIDE}\" | awk -v prefix=\"linux-image-${KERNEL_VERSION_OVERRIDE}\" 'index(\$1, prefix) == 1 && \$1 ~ /-generic\$/ { sub(/^linux-image-/, \"\", \$1); print \$1 }' | sort -V | tail -n1")
fi
if [ -z "$RESOLVED_KERNEL_VERSION" ]; then
echo "❌ ERROR: Failed to resolve kernel version inside ubuntu:26.04 container for override '$KERNEL_VERSION_OVERRIDE'."
exit 1
fi
echo "✅ Resolved kernel version: $RESOLVED_KERNEL_VERSION"
KERNEL_VERSION_STRIPPED="${RESOLVED_KERNEL_VERSION%-generic}"
echo "✅ Kernel version for tag (stripped '-generic'): $KERNEL_VERSION_STRIPPED"
echo "KERNEL_INSTALL_ENABLED=true" >> $GITHUB_OUTPUT
echo "KERNEL_VERSION=$KERNEL_VERSION_STRIPPED" >> $GITHUB_OUTPUT
fi
echo -e "\n## 4. Processing Slurm Configuration & Verifying DEBs ##"
SLURM_VERSION_OVERRIDE="0"
if [ -n "$INPUT_SLURM_VERSION" ] && [ "$INPUT_SLURM_VERSION" != "0" ]; then SLURM_VERSION_OVERRIDE="$INPUT_SLURM_VERSION";
elif [ -n "$VAR_SLURM_VERSION" ] && [ "$VAR_SLURM_VERSION" != "0" ]; then SLURM_VERSION_OVERRIDE="$VAR_SLURM_VERSION"; fi
if [ "$SLURM_VERSION_OVERRIDE" != "0" ]; then
TARGET_SLURM_VERSION="$SLURM_VERSION_OVERRIDE"
else
echo "🔍 No valid override. Detecting latest stable version..."
LATEST_TAG=$(curl -s https://api.github.com/repos/SchedMD/slurm/tags | jq -r '.[].name' | grep -E '^slurm-[0-9]+-[0-9]+-[0-9]+-[0-9]+$' | sort -V | tail -n1)
[ -z "$LATEST_TAG" ] && { echo "❌ ERROR: Could not determine latest Slurm tag."; exit 1; }
TARGET_SLURM_VERSION="${LATEST_TAG#slurm-}"
fi
echo "🎯 Target Slurm Version: $TARGET_SLURM_VERSION"
debver="$(echo "$TARGET_SLURM_VERSION" | sed 's/^\([0-9]*\)-\([0-9]*\)-\([0-9]*\)-\([0-9]*\)$/\1.\2.\3-\4/')"
count=$(find "$GITHUB_WORKSPACE/slurm-debs" -type f -name "*_${debver}_*_u2604.deb" 2>/dev/null | wc -l)
[ "$count" -eq 0 ] && { echo "❌ ERROR: Slurm DEB packages for version $TARGET_SLURM_VERSION not found!"; exit 1; }
echo "✅ Found $count matching DEB packages."
echo -e "\n## 5. Processing NVIDIA Configuration ##"
IS_NVIDIA_ENABLED=false
ENABLED_VAL="0"
if [ -n "$INPUT_NVIDIA_ENABLED" ]; then ENABLED_VAL="$INPUT_NVIDIA_ENABLED";
elif [ -n "$VAR_NVIDIA_ENABLED" ]; then ENABLED_VAL="$VAR_NVIDIA_ENABLED"; fi
if [ "$(lower "$ENABLED_VAL")" = "1" ] || [ "$(lower "$ENABLED_VAL")" = "true" ]; then IS_NVIDIA_ENABLED=true; fi
# Check if kernel installation is enabled (NVIDIA requires kernel headers)
KERNEL_INSTALL_ENABLED_VAL="$(grep '^KERNEL_INSTALL_ENABLED=' $GITHUB_OUTPUT | cut -d'=' -f2)"
if [ "$IS_NVIDIA_ENABLED" = "true" ] && [ "$KERNEL_INSTALL_ENABLED_VAL" != "true" ]; then
echo "⚠️ WARNING: NVIDIA installation requested but kernel installation is disabled. Disabling NVIDIA installation."
IS_NVIDIA_ENABLED=false
fi
NVIDIA_DRIVER_URL="0"
if [ "$IS_NVIDIA_ENABLED" = "true" ]; then
echo "NVIDIA Install is ENABLED."
NVIDIA_VERSION_OVERRIDE="0"
if [ -n "$INPUT_NVIDIA_VERSION" ] && [ "$INPUT_NVIDIA_VERSION" != "0" ]; then NVIDIA_VERSION_OVERRIDE="$INPUT_NVIDIA_VERSION";
elif [ -n "$VAR_NVIDIA_VERSION" ] && [ "$VAR_NVIDIA_VERSION" != "0" ]; then NVIDIA_VERSION_OVERRIDE="$VAR_NVIDIA_VERSION"; fi
ARCH="x86_64"
echo "Effective NVIDIA_VERSION_OVERRIDE: '$NVIDIA_VERSION_OVERRIDE', Arch: '$ARCH'"
RELEASES_JSON=$(curl -sL "https://docs.nvidia.com/datacenter/tesla/drivers/releases.json")
[ -z "$RELEASES_JSON" ] && { echo "❌ ERROR: Failed to download NVIDIA release data."; exit 1; }
if [ "$NVIDIA_VERSION_OVERRIDE" != "0" ]; then
DRIVER_URL=$(echo "$RELEASES_JSON" | jq -r --arg ver "$NVIDIA_VERSION_OVERRIDE" --arg arch "$ARCH" '.[] | .driver_info[] | select(.release_version == $ver) | .runfile_url[$arch]' | head -n1)
else
DRIVER_URL=$(echo "$RELEASES_JSON" | jq -r --arg arch "$ARCH" 'first(.[] | select(.type == "production branch")) | .driver_info[0].runfile_url[$arch]')
fi
[ -z "$DRIVER_URL" ] || [ "$DRIVER_URL" = "null" ] && { echo "❌ ERROR: Could not determine a valid NVIDIA driver URL for version '$NVIDIA_VERSION_OVERRIDE' and arch '$ARCH'."; exit 1; }
NVIDIA_DRIVER_URL="$DRIVER_URL"
echo "✅ Success! NVIDIA Driver URL found: $NVIDIA_DRIVER_URL"
else
echo "NVIDIA Install is DISABLED."
fi
echo -e "\n## 6. Final Build Configuration ##"
echo "SLURM_VERSION=${TARGET_SLURM_VERSION}" >> $GITHUB_OUTPUT
echo "NVIDIA_INSTALL_ENABLED=${IS_NVIDIA_ENABLED}" >> $GITHUB_OUTPUT
echo "NVIDIA_DRIVER_URL=${NVIDIA_DRIVER_URL}" >> $GITHUB_OUTPUT
echo -e "\n📋 Final Configuration Summary:"
echo " SLURM_VERSION: ${TARGET_SLURM_VERSION}"
echo " KERNEL_INSTALL_ENABLED: $(grep '^KERNEL_INSTALL_ENABLED=' $GITHUB_OUTPUT | cut -d'=' -f2)"
echo " KERNEL_VERSION: $(grep '^KERNEL_VERSION=' $GITHUB_OUTPUT | cut -d'=' -f2)"
echo " NVIDIA_INSTALL_ENABLED: ${IS_NVIDIA_ENABLED}"
echo " DISABLE_AUTOLOGIN: $(grep '^DISABLE_AUTOLOGIN=' $GITHUB_OUTPUT | cut -d'=' -f2)"
echo " FIRSTBOOT_ENABLED: $(grep '^FIRSTBOOT_ENABLED=' $GITHUB_OUTPUT | cut -d'=' -f2)"
cat $GITHUB_OUTPUT
- name: 🏷️ Generate Docker Tag Name
id: taggen
run: |
SLURM_VER="${{ steps.config.outputs.SLURM_VERSION }}"
KERNEL_VER_RAW="${{ steps.config.outputs.KERNEL_VERSION }}"
KERNEL_INSTALL_ENABLED="${{ steps.config.outputs.KERNEL_INSTALL_ENABLED }}"
NVIDIA_ENABLED="${{ steps.config.outputs.NVIDIA_INSTALL_ENABLED }}"
NVIDIA_URL="${{ steps.config.outputs.NVIDIA_DRIVER_URL }}"
# Slugify Slurm version
SLURM_VER=$(echo "$SLURM_VER" | tr '.' '-' | tr '[:upper:]' '[:lower:]')
# If kernel installation is disabled, skip kernel/NVIDIA parts
if [ "$KERNEL_INSTALL_ENABLED" = "false" ]; then
TAG_NAME="slurm-${SLURM_VER}-no-kernel"
echo "🔖 Kernel installation disabled; using 'no-kernel' tag."
else
KERNEL_VER=$(echo "U26.04-$KERNEL_VER_RAW" | tr '.' '-' | tr '[:upper:]' '[:lower:]')
TAG_NAME="${KERNEL_VER}-slurm-${SLURM_VER}"
if [ "$NVIDIA_ENABLED" = "true" ]; then
# Extract version from URL: NVIDIA-Linux-x86_64-570.148.08.run
NVIDIA_VER=$(basename "$NVIDIA_URL" | grep -oP '[0-9]+\.[0-9]+\.[0-9]+')
NVIDIA_VER=$(echo "$NVIDIA_VER" | tr '.' '-') # slugify
TAG_NAME="${TAG_NAME}-${NVIDIA_VER}"
fi
fi
echo "Generated TAG_NAME: $TAG_NAME"
echo "TAG_NAME=$TAG_NAME" >> $GITHUB_OUTPUT
- name: 🐳 Build Docker Image
run: |
docker build \
--build-arg SLURM_VERSION=${{ steps.config.outputs.SLURM_VERSION }} \
--build-arg KERNEL_VERSION=${{ steps.config.outputs.KERNEL_VERSION }} \
--build-arg DISABLE_AUTOLOGIN=${{ steps.config.outputs.DISABLE_AUTOLOGIN }} \
--build-arg NVIDIA_INSTALL_ENABLED=${{ steps.config.outputs.NVIDIA_INSTALL_ENABLED }} \
--build-arg NVIDIA_DRIVER_URL=${{ steps.config.outputs.NVIDIA_DRIVER_URL }} \
--build-arg FIRSTBOOT_ENABLED=${{ steps.config.outputs.FIRSTBOOT_ENABLED }} \
--build-arg KERNEL_INSTALL_ENABLED=${{ steps.config.outputs.KERNEL_INSTALL_ENABLED }} \
-t ${{ secrets.DOCKER_HUB_REPO }}:${{ steps.taggen.outputs.TAG_NAME }} .
- name: 🚀 Login to DockerHub
run: |
echo "${{ secrets.DOCKER_HUB_TOKEN }}" | docker login -u "${{ secrets.DOCKER_HUB_USER }}" --password-stdin
- name: 🚀 Push Image to DockerHub
run: |
docker push ${{ secrets.DOCKER_HUB_REPO }}:${{ steps.taggen.outputs.TAG_NAME }}