Skip to content

Build HotStack Controller Image #7

Build HotStack Controller Image

Build HotStack Controller Image #7

---
name: Build HotStack Controller Image
"on":
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Run weekly on Mondays at 00:00 UTC
schedule:
- cron: '0 0 * * 1'
jobs:
build-image:
runs-on: ubuntu-22.04
# Permission needed to create a release and upload assets
permissions:
contents: write
steps:
- name: 1. Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: 2. Install System Dependencies
run: |
echo "Installing system dependencies for diskimage-builder..."
sudo apt-get update
sudo apt-get install -y \
python3-pip \
python3-venv \
qemu-utils \
dosfstools \
xfsprogs \
kpartx \
debootstrap \
gdisk \
git \
make
echo "System dependencies installed"
- name: 3. Build Controller Image Using Makefile (DIB)
run: |
echo "Building controller image using diskimage-builder..."
cd images
make controller CONTROLLER_IMAGE_FORMAT=qcow2
echo "Controller image built successfully"
ls -lh controller.qcow2
qemu-img info controller.qcow2
cd ..
- name: 5. Rename Image with Release Tag
id: release_tag
run: |
if [ "${{ github.event_name }}" == "schedule" ] || [ -z "${{ inputs.release_tag }}" ]; then
# Scheduled run or no tag provided: generate timestamp-based tag
RELEASE_TAG="build-$(date +%Y%m%d-%H%M%S)"
else
# Manual run with tag provided: use provided tag
RELEASE_TAG="${{ inputs.release_tag }}"
fi
echo "release_tag=$RELEASE_TAG" >> $GITHUB_OUTPUT
echo "Release tag: $RELEASE_TAG"
# Rename image to include the release tag
TAGGED_IMAGE="controller-${RELEASE_TAG}.qcow2"
cp images/controller.qcow2 ${TAGGED_IMAGE}
echo "tagged_image=$TAGGED_IMAGE" >> $GITHUB_OUTPUT
echo "Image renamed to: $TAGGED_IMAGE"
ls -lh ${TAGGED_IMAGE}
# yamllint disable rule:line-length
- name: 6. Create Versioned GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.release_tag.outputs.release_tag }}
name: "Controller Image ${{ steps.release_tag.outputs.release_tag }}"
body: |
HotStack Controller image built by GitHub Actions.
## Image Details
- **Base**: CentOS Stream 9
- **Build Tool**: diskimage-builder (DIB)
- **Format**: qcow2
- **Build type**: ${{ github.event_name == 'schedule' && 'Scheduled (weekly)' || (inputs.release_tag == '' && 'Manual (auto-versioned)' || 'Manual (versioned)') }}
- **Packages**: bash-completion, bind-utils, butane, dnsmasq, git,
haproxy, httpd, httpd-tools, make, nfs-utils, nmstate, podman,
tcpdump, tmux, vim-enhanced
- **Timezone**: UTC
- **Partitioning**: EFI boot support with GPT
## Usage
```bash
# Download the image
curl -L -O https://github.com/${{ github.repository }}/releases/download/${{ steps.release_tag.outputs.release_tag }}/${{ steps.release_tag.outputs.tagged_image }}
# Upload to OpenStack Glance (qcow2 works for most deployments)
openstack image create hotstack-controller \
--disk-format qcow2 \
--container-format bare \
--file ${{ steps.release_tag.outputs.tagged_image }}
# If you need raw format (required for some Ceph RBD backends):
qemu-img convert -f qcow2 -O raw \
${{ steps.release_tag.outputs.tagged_image }} controller.raw
openstack image create hotstack-controller \
--disk-format raw \
--container-format bare \
--file controller.raw
```
files: ${{ steps.release_tag.outputs.tagged_image }}
# yamllint enable rule:line-length
- name: 7. Update 'latest-controller' Release Tag
uses: softprops/action-gh-release@v2
with:
tag_name: latest-controller
name: "Controller Image (Latest)"
prerelease: true
body: |
This is the latest Controller image build. This release is automatically updated.
**Latest Build**: ${{ steps.release_tag.outputs.release_tag }}
## Download
Use the static URL for the latest build:
```bash
curl -L -O https://github.com/${{ github.repository }}/releases/download/latest-controller/controller-latest.qcow2
```
Or download a specific version from the [releases page](https://github.com/${{ github.repository }}/releases)
to pin your setup to a known-good build.
## Usage
```bash
# Upload to OpenStack Glance (qcow2 works for most deployments)
openstack image create hotstack-controller \
--disk-format qcow2 \
--container-format bare \
--file controller-latest.qcow2
# If you need raw format (required for some Ceph RBD backends):
qemu-img convert -f qcow2 -O raw controller-latest.qcow2 controller.raw
openstack image create hotstack-controller \
--disk-format raw \
--container-format bare \
--file controller.raw
```
files: ${{ steps.release_tag.outputs.tagged_image }}
- name: 8. Upload Image with Static Filename to Latest Release
run: |
echo "Creating static filename copy for easy downloading..."
# Copy the image with a static name
cp ${{ steps.release_tag.outputs.tagged_image }} controller-latest.qcow2
echo "Uploading to latest-controller release with static filename..."
# Upload to latest-controller release, replacing any existing file with the same name
gh release upload latest-controller controller-latest.qcow2 --clobber --repo ${{ github.repository }}
echo "Static URL available at:"
echo "https://github.com/${{ github.repository }}/releases/download/latest-controller/controller-latest.qcow2"
env:
GH_TOKEN: ${{ github.token }}
- name: 9. Cleanup Old Releases (Keep Last 4)
run: |
echo "Cleaning up old builds, keeping last 4..."
# Get all releases with 'build-' prefix, sort by creation date (newest first)
# Skip the first 4 (keep them), delete the rest
OLD_RELEASES=$(gh release list --limit 100 --json tagName,createdAt --repo ${{ github.repository }} \
| jq -r '.[] | select(.tagName | startswith("build-")) | .tagName' \
| sort -r \
| tail -n +5)
if [ -n "$OLD_RELEASES" ]; then
echo "Deleting old releases:"
echo "$OLD_RELEASES"
echo "$OLD_RELEASES" | xargs -I {} gh release delete {} --yes --cleanup-tag --repo ${{ github.repository }}
echo "Cleanup complete"
else
echo "No old releases to delete (fewer than 5 total)"
fi
env:
GH_TOKEN: ${{ github.token }}