Skip to content

Build Cloud and Vagrant Images #159

Build Cloud and Vagrant Images

Build Cloud and Vagrant Images #159

Workflow file for this run

name: Build Cloud and Vagrant Images
on:
workflow_dispatch:
inputs:
date_time_stamp:
description: 'Custom date+time stamp, YYYYMMDDhhmmss'
required: false
default: ''
version_major:
description: 'AlmaLinux major version'
required: true
default: '10'
type: choice
options:
- 10-kitten
- 10
- 9
- 8
image_type:
description: 'Cloud image type'
required: true
default: 'NONE'
type: choice
options:
- NONE
- ALL
- azure
# - digitalocean # TODO: require data to work with the cloud, such as: bucket, access key, secret key, etc.
- gcp
- gencloud
- oci
- opennebula
vagrant_type:
description: 'Vagrant image type'
required: true
default: 'NONE'
type: choice
options:
- NONE
- ALL
- vagrant_libvirt
- vagrant_virtualbox
- vagrant_vmware
self-hosted:
description: "Allow self-hosted runner (aarch64 or vagrant_vmware only)"
required: true
type: boolean
default: true
self_hosted_runner:
description: 'self-hosted runner'
required: true
default: 'aws-ec2'
type: choice
options:
- self-hosted
- aws-ec2
run_test:
description: "Do image simple testing and generate installed packages list (vagrant_* only)"
required: true
type: boolean
default: true
store_as_artifact:
description: "Store images to the workflow Artifacts"
required: true
type: boolean
default: false
upload_to_s3:
description: "Upload to S3 Bucket"
required: true
type: boolean
default: true
notify_mattermost:
description: "Send notification to Mattermost"
required: true
type: boolean
default: false
env:
PACKER_GITHUB_API_TOKEN: ${{ secrets.GIT_HUB_TOKEN }}
jobs:
init-data:
name: Initialize common data
runs-on: ubuntu-24.04
outputs:
time_stamp: ${{ steps.date-time-stamp.outputs.time_stamp }}
date_stamp: ${{ steps.date-time-stamp.outputs.date_stamp }}
matrix_gh: ${{ steps.set-matrix.outputs.matrix_gh }}
matrix_sh: ${{ steps.set-matrix.outputs.matrix_sh }}
steps:
- name: Set matrix
id: set-matrix
run: |
# Build matrix is json array of string elements like:
matrix_gh= # ["azure-x86_64", "gencloud-x86_64", ...]
matrix_sh= # ["azure-aarch64", "gencloud-aarch64", ... , "vagrant_vmware-x86_64"]
# Cloud Images
if [ "${{ inputs.image_type }}" = "azure" -o "${{ inputs.image_type }}" = "ALL" ]; then
VARIANTS_GH+=("azure-x86_64")
VARIANTS_SH+=("azure-aarch64")
fi
if [ "${{ inputs.image_type }}" = "gcp" -o "${{ inputs.image_type }}" = "ALL" ]; then
VARIANTS_GH+=("gcp-x86_64")
VARIANTS_SH+=("gcp-aarch64")
fi
# TODO: require data to work with the cloud, such as: bucket, access key, secret key, etc.
# if [ "${{ inputs.image_type }}" = "digitalocean" -o "${{ inputs.image_type }}" = "ALL" ]; then
# if [[ "${{ inputs.version_major }}" != *"kitten"* ]] && [[ "${{ inputs.version_major }}" != *"10" ]]; then
# VARIANTS_GH+=("digitalocean-x86_64")
# fi
# fi
if [ "${{ inputs.image_type }}" = "gencloud" -o "${{ inputs.image_type }}" = "ALL" ]; then
VARIANTS_GH+=("gencloud-x86_64")
VARIANTS_SH+=("gencloud-aarch64")
fi
if [ "${{ inputs.image_type }}" = "oci" -o "${{ inputs.image_type }}" = "ALL" ]; then
if [[ "${{ inputs.version_major }}" != *"kitten"* ]]; then
VARIANTS_GH+=("oci-x86_64")
VARIANTS_SH+=("oci-aarch64")
fi
fi
if [ "${{ inputs.image_type }}" = "opennebula" -o "${{ inputs.image_type }}" = "ALL" ]; then
VARIANTS_GH+=("opennebula-x86_64")
VARIANTS_SH+=("opennebula-aarch64")
fi
# Vagrant Images
if [ "${{ inputs.vagrant_type }}" = "vagrant_libvirt" -o "${{ inputs.vagrant_type }}" = "ALL" ]; then
VARIANTS_GH+=("vagrant_libvirt-x86_64")
fi
if [ "${{ inputs.vagrant_type }}" = "vagrant_virtualbox" -o "${{ inputs.vagrant_type }}" = "ALL" ]; then
VARIANTS_GH+=("vagrant_virtualbox-x86_64") # tests aren't work on GitHub runners, use self-hosted to run tests
fi
if [ "${{ inputs.vagrant_type }}" = "vagrant_vmware" -o "${{ inputs.vagrant_type }}" = "ALL" ]; then
VARIANTS_SH+=("vagrant_vmware-x86_64") # VMware has networking issues on GitHub runners, so we use self-hosted runner
fi
# Add SH values to matrix_gh if using runs-on
if [ "${{ github.repository_owner }}" == 'AlmaLinux' ]; then
for sh in "${VARIANTS_SH[@]}"; do
VARIANTS_GH+=("$sh")
done
unset VARIANTS_SH
fi
[ ${#VARIANTS_GH[@]} -ne 0 ] && matrix_gh=$(printf '"%s",' "${VARIANTS_GH[@]}")
matrix_gh=${matrix_gh%,} # Remove the trailing comma
echo matrix_gh=$(jq -c <<< [${matrix_gh}]) >> $GITHUB_OUTPUT
echo "[Debug] on GitHub Hosted [${matrix_gh}]"
[ ${#VARIANTS_SH[@]} -ne 0 ] && matrix_sh=$(printf '"%s",' "${VARIANTS_SH[@]}")
matrix_sh=${matrix_sh%,} # Remove the trailing comma
echo matrix_sh=$(jq -c <<< [${matrix_sh}]) >> $GITHUB_OUTPUT
echo "[Debug] on Self Hosted [${matrix_sh}]"
- name: Date+time stamp
id: date-time-stamp
run: |
# date+time stamp, YYYYMMDDhhmmss
if [ "${{ inputs.date_time_stamp }}" != "" ]; then
date_time_stamp="${{ inputs.date_time_stamp }}"
else
date_time_stamp=$(date -u '+%Y%m%d%H%M%S')
fi
echo "time_stamp=${date_time_stamp}" >> $GITHUB_OUTPUT
# date stamp, YYYYMMDD
date_stamp=${date_time_stamp:0:-6}
echo "date_stamp=${date_stamp}" >> "$GITHUB_OUTPUT"
build-gh-hosted:
name: ${{ matrix.variant }} ${{ matrix.matrix_gh }} image
permissions:
id-token: write
contents: read
needs: [init-data]
if: ${{ needs.init-data.outputs.matrix_gh != '[]' }}
# use runs-on runners if within the almalinux org, otherwise GH runners"
runs-on: "${{ github.repository_owner == 'AlmaLinux' && format('runs-on={0}/family=c7i.metal-24xl+c7a.metal-48xl+*8gd.metal*/image=ubuntu24-full-{2}', github.run_id, matrix.variant, contains(matrix.matrix_gh, 'aarch64') && 'arm64' || 'x64') || 'ubuntu-24.04' }}"
strategy:
fail-fast: false
matrix:
variant: ${{ fromJSON(format('["{0}"]', ( (inputs.version_major == '10-kitten' || inputs.version_major == '10') && !(contains(needs.init-data.outputs.matrix_gh, 'aarch64') ) ) && format('{0}", "{0}-v2', inputs.version_major) || inputs.version_major )) }}
matrix_gh: ${{ fromJSON(needs.init-data.outputs.matrix_gh) }}
exclude:
- matrix_gh: 'azure-x86_64'
variant: '10-kitten-v2'
- matrix_gh: 'oci-x86_64'
variant: '10-kitten-v2'
- matrix_gh: 'gcp-x86_64'
variant: '10-kitten-v2'
# Kitten x86_64_v2 Vagrant for VirtualBox stuck on "Waiting for SSH to become available"
- matrix_gh: 'vagrant_virtualbox-x86_64'
variant: '10-kitten-v2'
- matrix_gh: 'digitalocean-x86_64'
variant: '10-kitten-v2'
- matrix_gh: 'azure-x86_64'
variant: '10-v2'
- matrix_gh: 'gcp-x86_64'
variant: '10-v2'
- matrix_gh: 'oci-x86_64'
variant: '10-v2'
- matrix_gh: 'digitalocean-x86_64'
variant: '10-v2'
env:
TIME_STAMP: ${{ needs.init-data.outputs.time_stamp }}
DATE_STAMP: ${{ needs.init-data.outputs.date_stamp }}
steps:
- name: Prepare some environment variables
run: |
# Read image type
IFS=- read -r type arch <<< "${{ matrix.matrix_gh }}"
echo "type=$type" >> $GITHUB_ENV
echo "ARCH=$arch" >> $GITHUB_ENV
- name: Checkout ${{ github.action_repository }}
uses: actions/checkout@v5
- uses: ./.github/actions/shared-steps
name: ${{ matrix.variant }} ${{ matrix.matrix_gh }} image
with:
type: ${{ env.type }}
variant: ${{ matrix.variant }}
arch: ${{ env.ARCH }}
S3_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
S3_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ vars.AWS_REGION }}
AWS_S3_BUCKET: ${{ vars.AWS_S3_BUCKET }}
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK_URL }}
MATTERMOST_CHANNEL: ${{ vars.MATTERMOST_CHANNEL }}
store_as_artifact: ${{ inputs.store_as_artifact }}
upload_to_s3: ${{ inputs.upload_to_s3 }}
notify_mattermost: ${{ inputs.notify_mattermost }}
run_test: true # Do image simple testing and generate installed packages list (vagrant_* and GCP only)
# runner: ${{ github.repository_owner == 'AlmaLinux' && 'aws-ec2' || 'gh_hosted' }}
runner: gh_hosted
env:
PACKER_GITHUB_API_TOKEN: ${{ secrets.GIT_HUB_TOKEN }}
### Everything below is for self-hosted runners only ###
start-self-hosted-runner:
name: ${{ matrix.variant }} ${{ matrix.matrix_sh }} runner
# If we're in the almalinux org we use runs-on for self-hosted
if: ${{ github.repository_owner != 'AlmaLinux' && inputs.self-hosted && needs.init-data.outputs.matrix_sh != '[]' }}
runs-on: ubuntu-24.04
needs: [init-data]
strategy:
fail-fast: false
matrix:
variant: ${{ fromJSON(format('["{0}"]', ( (contains(needs.init-data.outputs.matrix_sh, 'azure-aarch64') && ( inputs.version_major == '9' || inputs.version_major == '10' || inputs.version_major == '10-kitten' ) ) && format('{0}", "{0}-64k', inputs.version_major) || ( ( (inputs.vagrant_type == 'vagrant_vmware' || inputs.vagrant_type == 'ALL') && ( inputs.version_major == '10' || inputs.version_major == '10-kitten' ) ) && format('{0}", "{0}-v2', inputs.version_major) || inputs.version_major ) ) )) }}
matrix_sh: ${{ fromJSON(needs.init-data.outputs.matrix_sh) }}
exclude:
- matrix_sh: 'oci-aarch64'
variant: '10-kitten'
- matrix_sh: 'oci-aarch64'
variant: '9-64k'
- matrix_sh: 'oci-aarch64'
variant: '10-kitten-64k'
- matrix_sh: 'oci-aarch64'
variant: '10-64k'
- matrix_sh: 'gencloud-aarch64'
variant: '9-64k'
- matrix_sh: 'gencloud-aarch64'
variant: '10-kitten-64k'
- matrix_sh: 'gencloud-aarch64'
variant: '10-64k'
- matrix_sh: 'opennebula-aarch64'
variant: '9-64k'
- matrix_sh: 'opennebula-aarch64'
variant: '10-kitten-64k'
- matrix_sh: 'opennebula-aarch64'
variant: '10-64k'
steps:
- name: Setup and start runner
if: inputs.self_hosted_runner == 'aws-ec2' && github.repository_owner != 'AlmaLinux'
uses: NextChapterSoftware/[email protected]
with:
github_token: ${{ secrets.GIT_HUB_TOKEN }}
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws_region: ${{ vars.AWS_REGION }}
ec2_ami_id: ${{ secrets[format('EC2_AMI_ID_AL9_{0}', ( contains(matrix.matrix_sh, 'x86_64') && 'X86_64' || 'AARCH64' ))] }}
ec2_subnet_id: ${{ secrets.EC2_SUBNET_ID}} # Subnet and Security Group should match
ec2_security_group_id: ${{ secrets.EC2_SECURITY_GROUP_ID }} # Availability Zones list for 'a1.metal' Instance Type
ec2_instance_type: ${{ contains(matrix.matrix_sh, 'x86_64') && 'c5n.metal' || 'a1.metal' }}
# aarch64 - t4g.medium a1.metal
# x86_64 - t3.medium c5n.metal
ec2_root_disk_size_gb: "16" # override default size which is too small for actions and tests stuff
ec2_root_disk_ebs_class: "gp3" # use faster and cheeper storage instead of default 'gp2'
ec2_instance_ttl: 30 # Optional (default is 60 minutes)
ec2_spot_instance_strategy: None # Other options are: SpotOnly, BestEffort, MaxPerformance
ec2_instance_tags: > # Required for IAM role resource permission scoping
[
{"Key": "Project", "Value": "GitHub Actions Self-hosted Runners"}
]
build-self-hosted:
name: ${{ matrix.variant }} ${{ matrix.matrix_sh }} image
if: ${{ inputs.self-hosted && needs.init-data.outputs.matrix_sh != '[]' }}
needs: [init-data, start-self-hosted-runner]
runs-on: ${{ github.repository_owner == 'AlmaLinux' && ( contains(matrix.matrix_sh, 'x86_64') && format('runs-on={0}/family=c5n.metal/ami={1}', github.run_id, vars.EC2_AMI_ID_AL9_X86_64 ) || format('runs-on={0}/family=a1.metal/image=almalinux-9-aarch64', github.run_id) ) || ( inputs.self_hosted_runner == 'aws-ec2' && github.run_id || matrix.matrix_sh ) }}
strategy:
fail-fast: false
matrix:
variant: ${{ fromJSON(format('["{0}"]', ( (contains(needs.init-data.outputs.matrix_sh, 'azure-aarch64') && ( inputs.version_major == '9' || inputs.version_major == '10' || inputs.version_major == '10-kitten' ) ) && format('{0}", "{0}-64k', inputs.version_major) || ( ( (inputs.vagrant_type == 'vagrant_vmware' || inputs.vagrant_type == 'ALL') && ( inputs.version_major == '10' || inputs.version_major == '10-kitten' ) ) && format('{0}", "{0}-v2', inputs.version_major) || inputs.version_major ) ) )) }}
matrix_sh: ${{ fromJSON(needs.init-data.outputs.matrix_sh) }}
exclude:
- matrix_sh: 'oci-aarch64'
variant: '10-kitten'
- matrix_sh: 'oci-aarch64'
variant: '10'
- matrix_sh: 'oci-aarch64'
variant: '9-64k'
- matrix_sh: 'oci-aarch64'
variant: '10-kitten-64k'
- matrix_sh: 'oci-aarch64'
variant: '10-64k'
- matrix_sh: 'gencloud-aarch64'
variant: '9-64k'
- matrix_sh: 'gencloud-aarch64'
variant: '10-kitten-64k'
- matrix_sh: 'gencloud-aarch64'
variant: '10-64k'
- matrix_sh: 'opennebula-aarch64'
variant: '9-64k'
- matrix_sh: 'opennebula-aarch64'
variant: '10-kitten-64k'
- matrix_sh: 'opennebula-aarch64'
variant: '10-64k'
env:
TIME_STAMP: ${{ needs.init-data.outputs.time_stamp }}
DATE_STAMP: ${{ needs.init-data.outputs.date_stamp }}
steps:
- name: Prepare some environment variables
run: |
# Read image type
IFS=- read -r type arch <<< "${{ matrix.matrix_sh }}"
echo "type=$type" >> $GITHUB_ENV
echo "ARCH=$arch" >> $GITHUB_ENV
- name: Clean up runner
if: inputs.self_hosted_runner != 'aws-ec2'
run: sudo rm -rf ansible .vagrant output-*
- name: Checkout ${{ github.action_repository }}
uses: actions/checkout@v4
- uses: ./.github/actions/shared-steps
name: ${{ matrix.variant }} ${{ matrix.matrix_sh }} image
with:
type: ${{ env.type }}
variant: ${{ matrix.variant }}
arch: ${{ env.ARCH }}
S3_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
S3_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ vars.AWS_REGION }}
AWS_S3_BUCKET: ${{ vars.AWS_S3_BUCKET }}
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK_URL }}
MATTERMOST_CHANNEL: ${{ vars.MATTERMOST_CHANNEL }}
store_as_artifact: ${{ inputs.store_as_artifact }}
upload_to_s3: ${{ inputs.upload_to_s3 }}
notify_mattermost: ${{ inputs.notify_mattermost }}
run_test: ${{ contains(env.type, 'vagrant') && inputs.run_test && 'true' || 'false' }} # Do image simple testing and generate installed packages list (vagrant_* only)
runner: ${{ github.repository_owner == 'AlmaLinux' && 'aws-ec2' || 'self_hosted' }}
env:
PACKER_GITHUB_API_TOKEN: ${{ secrets.GIT_HUB_TOKEN }}