Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
117 changes: 117 additions & 0 deletions packer/gcp/rocky/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Rocky Linux Packer Template

This directory contains the Packer template and scripts to build optimized Rocky Linux 8 base images for GitHub Actions self-hosted runners on GCP.

## 📊 Performance

- **Standard spawn time:** 4min37s (277s)
- **With Packer image:** 2min21s (141s)
- **Improvement:** 49% faster ⚡
- **Time saved per instance:** 136 seconds (2min16s)

## 📦 What's Pre-installed

- Docker CE + containerd.io
- EPEL repository (Extra Packages for Enterprise Linux)
- System updates (yum update)
- Base development tools (bind-utils, yum-utils)
- Docker service enabled
- Optimized for GitHub Actions runner deployment

## 🚀 Quick Start

### Build Locally

```bash
./build.sh
```

The script will interactively prompt you for:

- GCP Project ID
- GCP Zone
- Disk size (default: 80 GB)
- Image name (auto-generated with timestamp)

### Manual Build

```bash
# Initialize Packer
packer init template.pkr.hcl

# Validate
packer validate \
-var="project_id=YOUR_PROJECT" \
-var="zone=europe-west1-b" \
-var="disk_size=80" \
-var="image_name=github-runner-base-rocky-8-$(date +%Y%m%d-%H%M%S)" \
template.pkr.hcl

# Build
packer build \
-var="project_id=YOUR_PROJECT" \
-var="zone=europe-west1-b" \
-var="disk_size=80" \
-var="image_name=github-runner-base-rocky-8-$(date +%Y%m%d-%H%M%S)" \
template.pkr.hcl
```

## 📋 Files

- **template.pkr.hcl** - Packer template definition
- **build.sh** - Interactive build script
- **provision.sh** - Shell provisioning script (if used)
- **variables.pkrvars.hcl.example** - Example variables file
- **config-example.yaml** - Runner-manager configuration example

## 🛠️ Customization

To customize the image, edit:

1. **template.pkr.hcl** - Modify build configuration, machine type, disk size
2. **provisioners** - Add/remove provisioning steps

Example: Add additional packages

```hcl
provisioner "shell" {
inline = [
"sudo yum install -y your-package",
]
}
```

## 💡 Why EPEL?

EPEL (Extra Packages for Enterprise Linux) provides most GitHub Actions runner dependencies:

- `lttng-ust`
- `openssl-libs`
- `krb5-libs`
- `zlib`
- `libicu`

By pre-installing EPEL in the Packer image, the runner's `installdependencies.sh` script finds these packages already available, significantly reducing startup time.

## 📝 Notes

- Build machine: e2-standard-2 (2 vCPU, 8 GB RAM)
- Build time: ~10-15 minutes
- Disk size: 80 GB SSD
- Image family: `github-runner-base-rocky-8`
- Source image: `rocky-linux-8` from `rocky-linux-cloud`

## ⚠️ Important

Rocky Linux 8 runners show the **best performance improvement** (49% vs 35% for Ubuntu) because:

1. Standard Rocky VMs take much longer to provision (4min37s vs 2min09s)
2. EPEL installation eliminates most dependency installation time
3. Docker pre-installation is more impactful on Rocky

## 🔗 See Also

- [Main Packer README](../README.md)
- [Runner Manager Documentation](../../README.md)
- [Rocky Linux Documentation](https://docs.rockylinux.org/)
- [Packer GCP Builder Documentation](https://developer.hashicorp.com/packer/integrations/hashicorp/googlecompute)
154 changes: 154 additions & 0 deletions packer/gcp/rocky/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#!/bin/bash
# Interactive script to build Rocky Linux 8 GitHub Runner base image with Packer

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

echo "=========================================="
echo " Rocky Linux 8 Runner Image Builder"
echo "=========================================="
echo

# Check prerequisites
echo "Checking prerequisites..."

# Check if packer is installed
if ! command -v packer &>/dev/null; then
echo "❌ Error: Packer is not installed"
echo " Install from: https://www.packer.io/downloads"
exit 1
fi
echo "✅ Packer found: $(packer version)"

# Check if gcloud is installed
if ! command -v gcloud &>/dev/null; then
echo "❌ Error: gcloud CLI is not installed"
echo " Install from: https://cloud.google.com/sdk/docs/install"
exit 1
fi
echo "✅ gcloud CLI found"

# Check gcloud authentication
if ! gcloud auth list --filter=status:ACTIVE --format="value(account)" &>/dev/null; then
echo "❌ Error: No active gcloud authentication"
echo " Run: gcloud auth login"
exit 1
fi
ACTIVE_ACCOUNT=$(gcloud auth list --filter=status:ACTIVE --format="value(account)")
# trunk-ignore-all(shellcheck)
echo "✅ Authenticated as: ${ACTIVE_ACCOUNT}"

echo
echo "Prerequisites check passed!"
echo

# Get configuration
read -p "Enter GCP Project ID [scality-prod-ga-runners]: " PROJECT_ID
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
read -p "Enter GCP Project ID [scality-prod-ga-runners]: " PROJECT_ID
read -p "Enter GCP Project ID [my-gcp-project]: " PROJECT_ID

PROJECT_ID=${PROJECT_ID:-scality-prod-ga-runners}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
PROJECT_ID=${PROJECT_ID:-scality-prod-ga-runners}
PROJECT_ID=${PROJECT_ID:-my-gcp-project}


read -p "Enter GCP Zone [europe-west1-b]: " ZONE
ZONE=${ZONE:-europe-west1-b}

# Choose Rocky Linux version
echo
echo "Available Rocky Linux versions:"
echo " 1) Rocky Linux 8 (recommended)"
echo " 2) Rocky Linux 9"
echo " 3) Custom version"
read -p "Select Rocky Linux version (1/2/3): " VERSION_CHOICE

case ${VERSION_CHOICE} in
1)
ROCKY_VERSION="8"
echo "✅ Selected: Rocky Linux 8"
;;
2)
ROCKY_VERSION="9"
echo "✅ Selected: Rocky Linux 9"
;;
3)
read -p "Enter Rocky Linux version (e.g., 8 or 9): " ROCKY_VERSION
echo "✅ Selected: Rocky Linux ${ROCKY_VERSION}"
;;
*)
ROCKY_VERSION="8"
echo "⚠️ Invalid choice, defaulting to Rocky Linux 8"
;;
esac

read -p "Enter disk size in GB [80]: " DISK_SIZE
DISK_SIZE=${DISK_SIZE:-80}

# Generate image name with timestamp
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
IMAGE_NAME="github-runner-base-rocky-${ROCKY_VERSION}-${TIMESTAMP}"

echo
echo "=========================================="
echo "Build Configuration:"
echo "=========================================="
echo "Project ID: ${PROJECT_ID}"
echo "Zone: ${ZONE}"
echo "Rocky Version: ${ROCKY_VERSION}"
echo "Disk Size: ${DISK_SIZE}GB"
echo "Image Name: ${IMAGE_NAME}"
echo "Image Family: github-runner-base-rocky-${ROCKY_VERSION}"
echo "=========================================="
echo

read -p "Proceed with build? (yes/no): " CONFIRM
if [[ ${CONFIRM} != "yes" ]]; then
echo "Build cancelled."
exit 0
fi

echo
echo "Starting Packer build..."
echo "This will take approximately 10-15 minutes."
echo

# Initialize Packer
echo "Initializing Packer plugins..."
packer init template.pkr.hcl

# Validate template
echo "Validating Packer template..."
packer validate \
-var="project_id=${PROJECT_ID}" \
-var="zone=${ZONE}" \
-var="image_name=${IMAGE_NAME}" \
-var="rocky_version=${ROCKY_VERSION}" \
-var="disk_size=${DISK_SIZE}" \
template.pkr.hcl

# Build image
echo
echo "Building image (this will take several minutes)..."
packer build \
-var="project_id=${PROJECT_ID}" \
-var="zone=${ZONE}" \
-var="image_name=${IMAGE_NAME}" \
-var="rocky_version=${ROCKY_VERSION}" \
-var="disk_size=${DISK_SIZE}" \
template.pkr.hcl | tee "packer-build-rocky-${TIMESTAMP}.log"

echo
echo "=========================================="
echo "✅ Build completed successfully!"
echo "=========================================="
echo
echo "Image Details:"
echo " Name: ${IMAGE_NAME}"
echo " Family: github-runner-base-rocky-${ROCKY_VERSION}"
echo
echo "To use this image in runner-manager, update your config.yaml:"
echo " runner_groups:"
echo " - name: rocky-${ROCKY_VERSION}-packer-gcloud"
echo " cloud_provider: gcloud"
echo " image_family: github-runner-base-rocky-${ROCKY_VERSION}"
echo " image_project: ${PROJECT_ID}"
echo
echo "Build log saved to: packer-build-rocky-${TIMESTAMP}.log"
echo "Manifest saved to: manifest-rocky.json"
echo
37 changes: 37 additions & 0 deletions packer/gcp/rocky/provision.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash
# Rocky Linux provisioning script for GitHub Actions runner base image
# This script is called by Packer to configure the image

set -e

echo "=========================================="
echo "Rocky Linux Provisioning Starting"
echo "=========================================="

# Update system packages
echo "Step 1/4: Updating system packages..."
yum update -y

# Install base dependencies
echo "Step 2/4: Installing base dependencies..."
yum install -y bind-utils yum-utils

# Install Docker CE
echo "Step 3/4: Installing Docker CE..."
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y epel-release docker-ce docker-ce-cli containerd.io

# Configure Docker
systemctl enable docker
groupadd -f docker

# Clean up
echo "Step 4/4: Cleaning up..."
yum clean all
rm -rf /var/cache/yum
rm -rf /tmp/*
rm -f ~/.bash_history

echo "=========================================="
echo "Rocky Linux Provisioning Completed"
echo "=========================================="
Loading