Build HotStack Controller Image #9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| 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 }} |