diff --git a/.github/workflows/image-build.yml b/.github/workflows/image-build.yml index fbae383..b0069ff 100644 --- a/.github/workflows/image-build.yml +++ b/.github/workflows/image-build.yml @@ -1,22 +1,26 @@ name: image-build + # Controls when the workflow will run on: - # Triggers the workflow on push or pull request events but only for the "main" branch + # Trigger on push or pull request to main branch push: branches: ["main"] pull_request: branches: ["main"] - # Allows you to run this workflow manually from the Actions tab + # Allow manual run from Actions tab workflow_dispatch: + # Scheduled run every Wednesday at 11:11 UTC schedule: - cron: "11 11 * * WED" + jobs: - # save minicc and minirouter as artifacts to inject in image later + # Job: Save minicc and minirouter as artifacts for later use in image builds get-miniccc: runs-on: ubuntu-latest container: image: ghcr.io/sandialabs/sceptre-phenix/minimega:main steps: + # Upload binaries as artifact named 'miniexes' - name: upload miniccc and minirouter uses: actions/upload-artifact@v4 with: @@ -24,7 +28,8 @@ jobs: path: | /opt/minimega/bin/miniccc /opt/minimega/bin/minirouter - # build using phenix image builder + + # Job: Build the bennu image using the phenix image builder build-bennu: needs: get-miniccc runs-on: ubuntu-latest @@ -33,22 +38,26 @@ jobs: options: --privileged # needed for kernel device-mapper permissions steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + # Install oras CLI for pushing images to OCI registries + - name: oras install + uses: oras-project/setup-oras@v1 + # Checkout repository code - uses: actions/checkout@v4 - # Runs a set of commands using the runners shell + # Download miniexes artifact (miniccc and minirouter) - name: get miniexes uses: actions/download-artifact@v4.1.8 with: name: miniexes - # add the miniccc binary - # the phenix base scripts already include the systemd service + # Add the miniccc binary to the overlay for image build + # The systemd service is already included in base scripts - name: add miniccc run: | mkdir -p ./overlays/miniccc/opt/minimega/bin cp ./miniccc ./overlays/miniccc/opt/minimega/bin chmod +x ./overlays/miniccc/opt/minimega/bin/miniccc + # Build the bennu image using phenix - name: bennu image build run: | phenix version @@ -56,12 +65,23 @@ jobs: phenix image create -O ./overlays/bennu,./overlays/brash,./overlays/miniccc -T ./scripts/aptly,./scripts/bennu --format qcow2 --release jammy -c bennu --size 10G phenix image build bennu -o ./out -x - # upload bennu qc2 as artifact - - name: upload qc2 - uses: actions/upload-artifact@v4 - with: - name: bennu.qc2 - path: ./out/bennu.qc2 + # Optionally upload bennu.qc2 as artifact (currently commented out) + # - name: upload qc2 + # uses: actions/upload-artifact@v4 + # with: + # name: bennu.qc2 + # path: ./out/bennu.qc2 + + # Publish the built image to GitHub Container Registry using oras + - name: publish package with oras + # Only push package if on the default branch (e.g., main) + if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) + run: | + cd ./out + oras login -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} ghcr.io + oras push "ghcr.io/${{ github.repository }}/bennu.qc2:${GITHUB_SHA:0:7}" bennu.qc2 + + # Job: Build the ubuntu image using the phenix image builder build-ubuntu: needs: get-miniccc runs-on: ubuntu-latest @@ -70,22 +90,25 @@ jobs: options: --privileged # needed for kernel device-mapper permissions steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + # Install oras CLI + - name: oras install + uses: oras-project/setup-oras@v1 + # Checkout repository code - uses: actions/checkout@v4 - # Runs a set of commands using the runners shell + # Download miniexes artifact - name: get miniexes uses: actions/download-artifact@v4.1.8 with: name: miniexes - # add the miniccc binary - # the phenix base scripts already include the systemd service + # Add the miniccc binary to the overlay for image build - name: add miniccc run: | mkdir -p ./overlays/miniccc/opt/minimega/bin cp ./miniccc ./overlays/miniccc/opt/minimega/bin chmod +x ./overlays/miniccc/opt/minimega/bin/miniccc + # Build the ubuntu image using phenix - name: ubuntu image build run: | phenix version @@ -93,23 +116,37 @@ jobs: phenix image create -O ./overlays/miniccc -T ./scripts/ubuntu,./scripts/ubuntu-user --format qcow2 --release noble -c ubuntu --size 10G phenix image build ubuntu -o ./out -x - # upload bennu qc2 as artifact - - name: upload qc2 - uses: actions/upload-artifact@v4 - with: - name: ubuntu.qc2 - path: ./out/ubuntu.qc2 - # upload to github release + # Optionally upload ubuntu.qc2 as artifact (currently commented out) + # - name: upload qc2 + # uses: actions/upload-artifact@v4 + # with: + # name: ubuntu.qc2 + # path: ./out/ubuntu.qc2 + + # Publish the built image to GitHub Container Registry using oras + - name: publish package with oras + # Only push package if on the default branch (e.g., main) + if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) + run: | + cd ./out + oras login -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} ghcr.io + oras push "ghcr.io/${{ github.repository }}/ubuntu.qc2:${GITHUB_SHA:0:7}" ubuntu.qc2 + + # Job: Tag and release images after successful builds release: - if: github.ref == 'refs/heads/main' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') + # Only run on main branch for scheduled or manual workflow_dispatch events + if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') needs: - build-bennu - build-ubuntu runs-on: ubuntu-latest steps: + # Get current date for tagging - name: Get current date id: date run: echo "date=$(date +'%Y%m%d')" >> $GITHUB_OUTPUT + # Download built images from artifacts (if uploaded) + # Not needed with oras push, but kept for reference # - name: get images from artifacts # uses: actions/download-artifact@v4.1.8 # with: @@ -117,14 +154,31 @@ jobs: # path: ./images # merge-multiple: true + # Install oras CLI + - name: oras install + uses: oras-project/setup-oras@v1 + + # Tag images in the registry with 'latest' and date-based tags + - name: tag images with date and latest + run: | + oras version + oras login -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} ghcr.io + oras tag ghcr.io/${{ github.repository }}/bennu.qc2:${GITHUB_SHA:0:7} latest ${{ steps.date.outputs.date }} + oras tag ghcr.io/${{ github.repository }}/ubuntu.qc2:${GITHUB_SHA:0:7} latest ${{ steps.date.outputs.date }} + + # Create a GitHub release with notes and usage instructions - name: create release uses: ncipollo/release-action@v1.15.0 with: name: release-${{ steps.date.outputs.date }} body: | - Images are too large to be attached to the release directly. - For the full set of downloadable images, visit the [artifacts page](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}). - # artifacts: "./images/*.qc2" + Images can be downloaded from the registry using the oras client: https://oras.land/docs/installation + e.g.: + ``` + oras pull ghcr.io/${{ github.repository }}/bennu.qc2:latest + ``` + You can view the available image builds from the [Package List](https://github.com/orgs/${{ github.repository_owner }}/packages?repo_name=${{ github.event.repository.name }}) + tag: release-${{ steps.date.outputs.date }} commit: main generateReleaseNotes: true diff --git a/.github/workflows/release-cleanup.yml b/.github/workflows/release-cleanup.yml index 307a187..4149a7b 100644 --- a/.github/workflows/release-cleanup.yml +++ b/.github/workflows/release-cleanup.yml @@ -16,3 +16,16 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} delete_tags: true keep_latest_days: 90 + + cleanup-old-images: + name: Delete Untagged Images + runs-on: ubuntu-latest + permissions: + packages: write + steps: + - uses: dataaxiom/ghcr-cleanup-action@v1 + with: + older-than: 90 day + packages: sceptre-phenix-images/bennu.qc2,sceptre-phenix-images/ubuntu.qc2 + keep-n-tagged: 5 + exclude-tags: latest \ No newline at end of file diff --git a/README.md b/README.md index 009fcd1..e815331 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,16 @@ 1. Create an image configuration by specifying things like release code, packages, scripts to run after building, and filesystem overlays. 2. Build the image. +## Pre-built Images +Pre-built qcow2 images are available as [Packages](https://github.com/orgs/sandialabs/packages?repo_name=sceptre-phenix-images). They are stored in OCI registry format (due to size constraints) and require the [oras](https://oras.land/docs/installation) client to download. Once you have the oras client installed you can download with a command like: + +``` +oras pull ghcr.io/sandialabs/sceptre-phenix-images/bennu.qc2:latest +``` +_This example will download the latest version of bennu.qc2 to your current working directory._ + +Images are built weekly and saved for 90 days. View the [Github workflow](./.github/workflows/image-build.yml) for the details on how images are built. + ## How it works In step 1, the tool compiles command line arguments, scripts, and filesystem overlay paths on disk into an `Image` vmdb configuration file in the phenix datastore. The scripts and overlays are specified on the command line by path. diff --git a/scripts/ubuntu b/scripts/ubuntu index a4cedf2..280f5bf 100755 --- a/scripts/ubuntu +++ b/scripts/ubuntu @@ -39,8 +39,8 @@ systemctl enable ssh # apt cleanup rm -rf /var/cache/apt/archives -apt clean -apt autoremove +apt clean -y +apt autoremove -y # add phenix hostname echo '127.0.1.1 phenix' > /etc/hosts