summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrenner <80410025+renner0e@users.noreply.github.com>2026-06-17 16:16:34 +0200
committerGitHub <noreply@github.com>2026-06-17 16:16:34 +0200
commit7f9dd326ec891735fa8e7c482ae88ac178f89219 (patch)
treec43390563ea091322338d9c0c8bf8038a58b6160
parent5c9c70b4cc96c21c658e160753cefd554b41e23a (diff)
downloadAeroCore-OS-7f9dd326ec891735fa8e7c482ae88ac178f89219.tar.gz
AeroCore-OS-7f9dd326ec891735fa8e7c482ae88ac178f89219.zip
refactor: rewrite in just, saner defaults (#218)
* refactor: rewrite in just, saner defaults I think it makes sense to do this as it is longterm easier to maintain, locally iterate and extend. Documents how to rebase to a local image, it pains me greatly when people iterate on github and wait forever for things to build and then to download the image for trivial things they could also quickly do locally. Rpm-ostree rechunker by default instead of opt-in legacy-rechunker, chunkah is also available if people want to use it already, if we deem it ready then we can enable it later on. They can all be opted-out of. Have a way to copy files to /{usr,etc} by default. We should sign the digest of the image instead of the tag. Co-Authored-by: a lot of sugar and bad music * docs: bump fedora-bootc version Co-authored-by: Jill Fiore <contact@lumaeris.com> * fix: formatting inconsistency Co-authored-by: Jill Fiore <contact@lumaeris.com> * docs: remove variable mentions from workflows These are now defined in the image-template.env file * fix: small nits in labels Co-authored-by: Adam Fidel <ledif@users.noreply.github.com> --------- Co-authored-by: Jill Fiore <contact@lumaeris.com> Co-authored-by: Adam Fidel <ledif@users.noreply.github.com>
-rw-r--r--.github/workflows/build.yml193
-rw-r--r--Containerfile11
-rw-r--r--Justfile154
-rw-r--r--README.md50
-rwxr-xr-xbuild_files/build.sh5
-rw-r--r--image-template.env15
-rw-r--r--system_files/etc/.gitkeep0
-rw-r--r--system_files/usr/.gitkeep0
8 files changed, 302 insertions, 126 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 85a8c97..e355434 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -14,12 +14,7 @@ on:
workflow_dispatch:
env:
- IMAGE_DESC: "My Customized Universal Blue Image"
- IMAGE_KEYWORDS: "bootc,ublue,universal-blue"
- IMAGE_LOGO_URL: "https://avatars.githubusercontent.com/u/120078124?s=200&v=4" # Put your own image here for a fancy profile on https://artifacthub.io/!
- IMAGE_NAME: "${{ github.event.repository.name }}" # output image name, usually same as repo name
IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit
- DEFAULT_TAG: "latest"
concurrency:
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}-${{ inputs.brand_name}}-${{ inputs.stream_name }}
@@ -36,98 +31,87 @@ jobs:
id-token: write
steps:
- - name: Prepare environment
- run: |
- # Lowercase the image uri
- echo "IMAGE_REGISTRY=${IMAGE_REGISTRY,,}" >> ${GITHUB_ENV}
- echo "IMAGE_NAME=${IMAGE_NAME,,}" >> ${GITHUB_ENV}
-
# These stage versions are pinned by https://github.com/renovatebot/renovate
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- # This is optional, but if you see that your builds are way too big for the runners, you can enable this by uncommenting the following lines:
- name: Maximize build space
uses: ublue-os/remove-unwanted-software@695eb75bc387dbcd9685a8e72d23439d8686cba6
- - name: Get current date
- id: date
+ - name: Install just
+ uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 #v4.0.0
+
+ - name: Check Just Syntax
+ shell: bash
run: |
- # This generates a timestamp like what is defined on the ArtifactHub documentation
- # E.G: 2022-02-08T15:38:15Z'
- # https://artifacthub.io/docs/topics/repositories/container-images/
- # https://linux.die.net/man/1/date
- echo "date=$(date -u +%Y\-%m\-%d\T%H\:%M\:%S\Z)" >> $GITHUB_OUTPUT
-
- # Image metadata for https://artifacthub.io/ - This is optional but is highly recommended so we all can get a index of all the custom images
- # The metadata by itself is not going to do anything, you choose if you want your image to be on ArtifactHub or not.
- - name: Image Metadata
- uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
- id: metadata
- with:
- # This generates all the tags for your image, you can add custom tags here too!
- # Default tags are "$DEFAULT_TAG" and "$DEFAULT_TAG.$date".
- tags: |
- type=raw,value=${{ env.DEFAULT_TAG }}
- type=raw,value=${{ env.DEFAULT_TAG }}.{{date 'YYYYMMDD'}}
- type=raw,value={{date 'YYYYMMDD'}}
- type=sha,enable=${{ github.event_name == 'pull_request' }}
- type=ref,event=pr
- labels: |
- io.artifacthub.package.readme-url=https://raw.githubusercontent.com/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}/${{ github.sha }}/README.md
- org.opencontainers.image.created=${{ steps.date.outputs.date }}
- org.opencontainers.image.description=${{ env.IMAGE_DESC }}
- org.opencontainers.image.documentation=https://raw.githubusercontent.com/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}/${{ github.sha }}/README.md
- org.opencontainers.image.source=https://github.com/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}/blob/${{ github.sha }}/Containerfile
- org.opencontainers.image.title=${{ env.IMAGE_NAME }}
- org.opencontainers.image.url=https://github.com/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}/tree/${{ github.sha }}
- org.opencontainers.image.vendor=${{ github.repository_owner }}
- org.opencontainers.image.version=${{ env.DEFAULT_TAG }}.{{date 'YYYYMMDD'}}
- io.artifacthub.package.deprecated=false
- io.artifacthub.package.keywords=${{ env.IMAGE_KEYWORDS }}
- io.artifacthub.package.license=Apache-2.0
- io.artifacthub.package.logo-url=${{ env.IMAGE_LOGO_URL }}
- io.artifacthub.package.prerelease=false
- containers.bootc=1
- sep-tags: " "
- sep-annotations: " "
+ just check
+
+ - name: Image Name
+ id: image-name
+ run: |
+ IMAGE_NAME=$(just image_name)
+
+ echo "IMAGE_NAME=${IMAGE_NAME}" >> $GITHUB_ENV
+
+ - name: Default Tag
+ id: gen-default-tag
+ run: |
+ DEFAULT_TAG=$(just generate-default-tag)
+
+ echo "DEFAULT_TAG=${DEFAULT_TAG}" >> $GITHUB_ENV
+
+ - name: Prepare environment
+ run: |
+ # Lowercase the image uri https://github.com/macbre/push-to-ghcr/issues/12
+ echo "IMAGE_REGISTRY=${IMAGE_REGISTRY,,}" >> ${GITHUB_ENV}
+ echo "IMAGE_NAME=${IMAGE_NAME,,}" >> ${GITHUB_ENV}
+ # This actually builds the container image
- name: Build Image
- id: build_image
- uses: redhat-actions/buildah-build@7a95fa7ee0f02d552a32753e7414641a04307056 # v2
- with:
- containerfiles: |
- ./Containerfile
- # Postfix image name with -custom to make it a little more descriptive
- # Syntax: https://docs.github.com/en/actions/learn-github-actions/expressions#format
- image: ${{ env.IMAGE_NAME }}
- tags: ${{ steps.metadata.outputs.tags }}
- labels: ${{ steps.metadata.outputs.labels }}
- oci: false
-
- # Rechunk is a script that we use on Universal Blue to make sure there isnt a single huge layer when your image gets published.
- # This does not make your image faster to download, just provides better resumability and fixes a few errors.
- # Documentation for Rechunk is provided on their github repository at https://github.com/hhd-dev/rechunk
- # You can enable it by uncommenting the following lines:
- # - name: Run Rechunker
- # id: rechunk
- # uses: ublue-os/legacy-rechunk@a925083d9af7cb04b3e2a6e8c01bfa495f38b710 # v1.0.0
- # with:
- # rechunk: 'ghcr.io/ublue-os/legacy-rechunk:v1.0.0-x86_64'
- # ref: "localhost/${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }}"
- # prev-ref: "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }}"
- # skip_compression: true
- # version: ${{ env.CENTOS_VERSION }}
- # labels: ${{ steps.metadata.outputs.labels }} # Rechunk strips out all the labels during build, this needs to be reapplied here with newline separator
-
- # This is necessary so that the podman socket can find the rechunked image on its storage
- # - name: Load in podman and tag
- # run: |
- # IMAGE=$(podman pull ${{ steps.rechunk.outputs.ref }})
- # sudo rm -rf ${{ steps.rechunk.outputs.output }}
- # for tag in ${{ steps.metadata.outputs.tags }}; do
- # podman tag $IMAGE ${{ env.IMAGE_NAME }}:$tag
- # done
+ id: build-image
+ run: |
+ sudo -E $(command -v just) build \
+ ${IMAGE_NAME} \
+ ${DEFAULT_TAG}
+
+ # This is optional, this provides smaller delta updates
+ - name: Rechunk with rpm-ostree
+ id: rechunk
+ run: |
+ sudo -E $(command -v just) ostree-rechunk \
+ ${IMAGE_NAME} \
+ ${DEFAULT_TAG}
+
+ # If you are feeling adventurous, use the new distro agnostic rechunker
+ # https://github.com/coreos/chunkah
+ # You can delete the Rechunk with rpm-ostree portion then if you use this
+ #- name: Rechunk with Chunkah
+ # id: rechunk
+ # run: |
+ # sudo -E $(command -v just) rechunk \
+ # ${IMAGE_NAME} \
+ # ${DEFAULT_TAG}
+
+ - name: Generate Build Tags
+ id: gen-build-tags
+ run: |
+ alias_tags="$(just generate-build-tags \
+ ${IMAGE_NAME} \
+ ${DEFAULT_TAG})"
+
+ echo "Tags for this Action..."
+ echo "${alias_tags}"
+ echo "alias_tags=${alias_tags}" >> $GITHUB_OUTPUT
+
+ - name: Tag Image
+ id: tag-images
+ env:
+ ALIAS_TAGS: ${{ steps.gen-build-tags.outputs.alias_tags }}
+ run: |
+ sudo -E $(command -v just) tag-images \
+ "${IMAGE_NAME}" \
+ "${DEFAULT_TAG}" \
+ "${ALIAS_TAGS}"
# These `if` statements are so that pull requests for your custom images do not make it publish any packages under your name without you knowing
# They also check if the runner is on the default branch so that things like the merge queue (if you enable it), are going to work
@@ -140,37 +124,38 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
- name: Push To GHCR
- uses: redhat-actions/push-to-registry@5ed88d269cf581ea9ef6dd6806d01562096bee9c # v2
if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
- id: push
+ id: push-image
env:
- REGISTRY_USER: ${{ github.actor }}
- REGISTRY_PASSWORD: ${{ github.token }}
- with:
- registry: ${{ env.IMAGE_REGISTRY }}
- image: ${{ env.IMAGE_NAME }}
- tags: ${{ steps.metadata.outputs.tags }}
- username: ${{ env.REGISTRY_USER }}
- password: ${{ env.REGISTRY_PASSWORD }}
+ ALIAS_TAGS: ${{ steps.gen-build-tags.outputs.alias_tags }}
+ run: |
+ set -euox pipefail
+ for tag in ${ALIAS_TAGS}; do
+ sudo -E podman push --digestfile=/tmp/digestfile ${IMAGE_NAME}:${tag} ${IMAGE_REGISTRY}/${IMAGE_NAME}:${tag}
+ done
+
+ digest=$(< /tmp/digestfile)
+
+ echo "digest=${digest}" >> $GITHUB_OUTPUT
# This section is optional and only needs to be enabled if you plan on distributing
# your project for others to consume. You will need to create a public and private key
# using Cosign and save the private key as a repository secret in Github for this workflow
# to consume. For more details, review the image signing section of the README.
- name: Install Cosign
- uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 # v4.1.0
+ uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
+ # https://github.com/containers/container-libs/issues/388
with:
cosign-release: 'v2.6.3'
- name: Sign container image
+ id: sign-image
if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
- run: |
- IMAGE_FULL="${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}"
- for tag in ${{ steps.metadata.outputs.tags }}; do
- cosign sign -y --key env://COSIGN_PRIVATE_KEY $IMAGE_FULL:$tag
- done
env:
- TAGS: ${{ steps.push.outputs.digest }}
COSIGN_EXPERIMENTAL: false
COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }}
+ DIGEST: ${{ steps.push-image.outputs.digest }}
+ run: |
+ cosign sign -y --key env://COSIGN_PRIVATE_KEY ${IMAGE_REGISTRY}/${IMAGE_NAME}@${DIGEST}
+
diff --git a/Containerfile b/Containerfile
index 4cab82b..f3bbf77 100644
--- a/Containerfile
+++ b/Containerfile
@@ -1,17 +1,18 @@
# Allow build scripts to be referenced without being copied into the final image
FROM scratch AS ctx
COPY build_files /
+COPY system_files /system_files
# Base Image
FROM ghcr.io/ublue-os/bazzite:stable
-
## Other possible base images include:
-# FROM ghcr.io/ublue-os/bazzite:latest
-# FROM ghcr.io/ublue-os/bluefin-nvidia:stable
+# FROM ghcr.io/ublue-os/bazzite:testing
+# FROM ghcr.io/ublue-os/aurora:stable
+# FROM ghcr.io/ublue-os/bluefin-nvidia-open:stable
#
# ... and so on, here are more base images
# Universal Blue Images: https://github.com/orgs/ublue-os/packages
-# Fedora base image: quay.io/fedora/fedora-bootc:41
+# Fedora base image: quay.io/fedora/fedora-bootc:44
# CentOS base images: quay.io/centos-bootc/centos-bootc:stream10
### [IM]MUTABLE /opt
@@ -34,7 +35,7 @@ RUN --mount=type=bind,from=ctx,source=/,target=/ctx \
--mount=type=cache,dst=/var/log \
--mount=type=tmpfs,dst=/tmp \
/ctx/build.sh
-
+
### LINTING
## Verify final image and contents are correct.
RUN bootc container lint
diff --git a/Justfile b/Justfile
index 555cca8..150c89c 100644
--- a/Justfile
+++ b/Justfile
@@ -1,6 +1,13 @@
-export image_name := env("IMAGE_NAME", "image-template") # output image name, usually same as repo name, change as needed
-export default_tag := env("DEFAULT_TAG", "latest")
-export bib_image := env("BIB_IMAGE", "quay.io/centos-bootc/bootc-image-builder:latest")
+set dotenv-filename := "image-template.env"
+set dotenv-load
+
+export image_name := env_var("IMAGE_NAME")
+export repo_organization := env_var("REPO_ORGANIZATION")
+export image_desc := env_var("IMAGE_DESC")
+export image_keywords := env_var("IMAGE_KEYWORDS")
+export image_logo_url := env_var("IMAGE_LOGO_URL")
+export default_tag := env_var("DEFAULT_TAG")
+export bib_image := env_var("BIB_IMAGE")
alias build-vm := build-qcow2
alias rebuild-vm := rebuild-qcow2
@@ -80,25 +87,149 @@ sudoif command *args:
# just build $target_image $tag
#
# Example usage:
-# just build aurora lts
+# just build myimage mytag
#
-# This will build an image 'aurora:lts' with DX and GDX enabled.
+# This will build an image 'myimage:mytag'
#
# Build the image using the specified parameters
build $target_image=image_name $tag=default_tag:
#!/usr/bin/env bash
+ set -euox pipefail
+
BUILD_ARGS=()
+ LABELS=()
+ if [[ -z "$(git status -s)" ]]; then
+ GIT_SHA=$(git rev-parse --short HEAD)
+ LABELS+=("--label" "io.artifacthub.package.readme-url=https://raw.githubusercontent.com/{{ repo_organization }}/{{ image_name }}/${GIT_SHA}/README.md")
+ LABELS+=("--label" "org.opencontainers.image.documentation=https://raw.githubusercontent.com/{{ repo_organization }}/{{ image_name }}/${GIT_SHA}/README.md")
+ LABELS+=("--label" "org.opencontainers.image.source=https://github.com/{{ repo_organization }}/{{ image_name }}/blob/${GIT_SHA}/Containerfile")
+ LABELS+=("--label" "org.opencontainers.image.url=https://github.com/{{ repo_organization }}/{{ image_name }}/tree/${GIT_SHA}")
+ LABELS+=("--label" "org.opencontainers.image.version={{ default_tag }}.$(date +%Y%m%d)-${GIT_SHA}")
+ fi
+
+ # Image metadata for https://artifacthub.io/ - This is optional but is highly recommended so we all can get a index of all the custom images
+ # The metadata by itself is not going to do anything, you choose if you want your image to be on ArtifactHub or not.
+ LABELS+=("--label" "io.artifacthub.package.deprecated=false")
+ LABELS+=("--label" "io.artifacthub.package.keywords={{ image_keywords }}")
+ LABELS+=("--label" "io.artifacthub.package.license=Apache-2.0")
+ LABELS+=("--label" "io.artifacthub.package.logo-url={{ image_logo_url }}")
+ LABELS+=("--label" "io.artifacthub.package.prerelease=false")
+ LABELS+=("--label" "org.opencontainers.image.created=$(date -u +%Y\-%m\-%d\T%H\:%M\:%S\Z)")
+ LABELS+=("--label" "org.opencontainers.image.description={{ image_desc }}")
+ LABELS+=("--label" "org.opencontainers.image.title={{ image_name }}")
+ LABELS+=("--label" "org.opencontainers.image.vendor={{ repo_organization }}")
+
+ # This actually builds the image!
+ PODMAN_BUILD_ARGS=("${BUILD_ARGS[@]}" "${LABELS[@]}" --pull=newer --tag "${target_image}:${tag}" --file Containerfile)
+
+ podman build "${PODMAN_BUILD_ARGS[@]}" .
+
+# Split the image for smaller updates (New)!
+rechunk $target_image=image_name $tag=default_tag:
+ #!/usr/bin/env bash
+
+ set -xeuo pipefail
+
+ # TODO: pin chunkah image to hash once mature enough
+ # You may run into space issues on github runenrs as we are making a
+ # complete copy of the image
+ export CHUNKAH_CONFIG_STR=$(podman inspect "${target_image}")
+ podman run --rm --mount=type=image,src="${target_image}",target=/chunkah \
+ -e CHUNKAH_CONFIG_STR quay.io/coreos/chunkah:latest \
+ build \
+ --verbose \
+ --compressed \
+ --max-layers 128 \
+ --prune /sysroot/ \
+ --label ostree.commit- --label ostree.final-diffid- \
+ --tag "${target_image}:${tag}" | podman load
+
+# Split the image for smaller updates (Classical)!
+ostree-rechunk $target_image=image_name $tag=default_tag:
+ #!/usr/bin/env bash
+
+ set -xeuo pipefail
+
+ # TODO: This is the only blocker for rootless CI
+ # https://github.com/coreos/rpm-ostree/issues/5346
+ if [[ ! "${UID}" -eq "0" ]]; then
+ echo "This needs to run as root."
+ exit 1
+ fi
+
+ # You can use your own base image here to avoid pulling fedora-bootc
+ RPM_OSTREE_CHUNKER_IMAGE="quay.io/fedora/fedora-bootc:latest"
+
+ podman run --rm \
+ --pull=newer \
+ --privileged \
+ -v "/var/lib/containers:/var/lib/containers" \
+ --entrypoint /usr/bin/rpm-ostree \
+ "${RPM_OSTREE_CHUNKER_IMAGE}" \
+ compose build-chunked-oci \
+ --max-layers 127 \
+ --format-version=2 \
+ --bootc \
+ --from "localhost/${target_image}:${tag}" \
+ --output containers-storage:"localhost/${target_image}:${tag}"
+
+# Generate Default Tag
+[group('Utility')]
+generate-default-tag $tag=default_tag:
+ #!/usr/bin/env bash
+ set -eoux pipefail
+
+ echo "${tag}"
+
+# Generate Tags
+[group('Utility')]
+generate-build-tags $target_image=image_name $tag=default_tag:
+ #!/usr/bin/bash
+ set -eoux pipefail
+
+ DATE=$(date +%Y%m%d)
+ BUILD_TAGS=()
if [[ -z "$(git status -s)" ]]; then
- BUILD_ARGS+=("--build-arg" "SHA_HEAD_SHORT=$(git rev-parse --short HEAD)")
+ GIT_SHA=$(git rev-parse --short HEAD)
+ BUILD_TAGS+=("${tag}-${GIT_SHA}")
+ BUILD_TAGS+=("${tag}-${DATE}-${GIT_SHA}")
+ BUILD_TAGS+=("${DATE}-${GIT_SHA}")
fi
- podman build \
- "${BUILD_ARGS[@]}" \
- --pull=newer \
- --tag "${target_image}:${tag}" \
- .
+ BUILD_TAGS+=("${DATE}")
+ BUILD_TAGS+=("${tag}")
+ BUILD_TAGS+=("${tag}-${DATE}")
+
+ echo "${BUILD_TAGS[@]}"
+
+# Tag Images
+[group('Utility')]
+tag-images $target_image=image_name $tag=default_tag tags="":
+ #!/usr/bin/env bash
+ set -eoux pipefail
+
+ # Get Image, and untag
+ IMAGE=$(podman inspect ${target_image}:${tag} | jq -r .[].Id)
+ podman untag ${IMAGE}
+
+ # Tag Image
+ for tag in {{ tags }}; do
+ podman tag $IMAGE "${target_image}:${tag}"
+ done
+
+ # Show Images
+ podman images
+
+# Image Name
+[group('Utility')]
+[private]
+image_name $target_image=image_name:
+ #!/usr/bin/env bash
+ set -eoux pipefail
+
+ echo "${image_name}"
# Command: _rootful_load_image
# Description: This script checks if the current user is root or running under sudo. If not, it attempts to resolve the image tag using podman inspect.
@@ -293,7 +424,6 @@ spawn-vm rebuild="0" type="qcow2" ram="6G":
--vsock=false --pass-ssh-key=false \
-i ./output/**/*.{{ type }}
-
# Runs shell check on all Bash scripts
lint:
#!/usr/bin/env bash
diff --git a/README.md b/README.md
index ba52ebf..64250be 100644
--- a/README.md
+++ b/README.md
@@ -89,7 +89,7 @@ For a base image, you can choose any of the Universal Blue images or start from
- Aurora: `ghcr.io/ublue-os/aurora:stable`
- Bluefin: `ghcr.io/ublue-os/bluefin:stable`
- Universal Blue Base: `ghcr.io/ublue-os/base-main:latest`
-- Fedora: `quay.io/fedora/fedora-bootc:42`
+- Fedora: `quay.io/fedora/fedora-bootc:44`
You can find more Universal Blue images on the [packages page](https://github.com/orgs/ublue-os/packages).
</details>
@@ -102,11 +102,11 @@ This will show you all the info you need to know about your current image. The i
### Step 2c: Changing Names
-Change the first line in the [Justfile](./Justfile) to your image's name.
+Change the `IMAGE_NAME` and `REPO_ORGANIZATION` variable inside the `image-template.env`
To commit and push all the files changed and added in step 2 into your Github repository:
```bash
-git add Containerfile Justfile cosign.pub
+git add Containerfile image-template.env cosign.pub
git commit -m "Initial Setup"
git push
```
@@ -132,7 +132,7 @@ The [build.sh](./build_files/build.sh) file is called from your Containerfile. I
## build.yml
-The [build.yml](./.github/workflows/build.yml) Github Actions workflow creates your custom OCI image and publishes it to the Github Container Registry (GHCR). By default, the image name will match the Github repository name. There are several environment variables at the start of the workflow which may be of interest to change.
+The [build.yml](./.github/workflows/build.yml) Github Actions workflow creates your custom OCI image and publishes it to the Github Container Registry (GHCR). By default, the image name will match the Github repository name.
# Building Disk Images
@@ -173,12 +173,16 @@ To use it, you must have installed [just](https://just.systems/man/en/introducti
## Environment Variables
+These are all sourced from the `image-template.env` file.
+
- `image_name`: The name of the image (default: "image-template").
- `default_tag`: The default tag for the image (default: "latest").
- `bib_image`: The Bootc Image Builder (BIB) image (default: "quay.io/centos-bootc/bootc-image-builder:latest").
## Building The Image
+All these recipes will work (with default values) without supplying any arguments to them, e.g. `just build`
+
### `just build`
Builds a container image using Podman.
@@ -191,6 +195,44 @@ Arguments:
- `$target_image`: The tag you want to apply to the image (default: `$image_name`).
- `$tag`: The tag for the image (default: `$default_tag`).
+### Rechunking
+We can flatten the layers of container images to make sure there isn't a single huge layer when your image gets published.
+This does not make your image faster to download, just provides better resumability.
+
+#### `just ostree-rechunk`
+Rechunks the existing Image with [rpm-ostree](https://coreos.github.io/rpm-ostree/build-chunked-oci/)
+
+```bash
+just ostree-rechunk $target_image $tag
+```
+
+#### `just rechunk`
+Rechunks the existing Image with [chunkah](https://github.com/coreos/chunkah), this is probably gonna be the default here at some point, try it out, it's cool.
+
+```bash
+just rechunk $target_image $tag
+```
+
+### Switching to the locally built image for testing
+
+The image has to be in the containers-storage owned by root, to be able to rebase to it, see the `_rootful_load_image` recipe.
+
+`sudo just build` and `sudo just ostree-rechunk` builds directly as root and allows you to skip the transfer to the root containers-storage.
+
+You can rebase to all the images that are in your containers-storage:
+
+```
+sudo podman image list --filter=label=containers.bootc=1
+```
+
+See [man bootc switch](https://bootc.dev/bootc/man/bootc-switch.8.html) for more info.
+
+```
+sudo bootc switch --transport containers-storage localhost/myimage:latest
+```
+
+and reboot your system!
+
## Building and Running Virtual Machines and ISOs
The below commands all build QCOW2 images. To produce or use a different type of image, substitute in the command with that type in the place of `qcow2`. The available types are `qcow2`, `iso`, and `raw`.
diff --git a/build_files/build.sh b/build_files/build.sh
index ebffafc..0bb290c 100755
--- a/build_files/build.sh
+++ b/build_files/build.sh
@@ -2,6 +2,9 @@
set -ouex pipefail
+# Copy the contents of system_files/ of the git repo to /
+cp -avf "/ctx/system_files"/. /
+
### Install packages
# Packages can be installed from any enabled yum repo on the image.
@@ -10,7 +13,7 @@ set -ouex pipefail
# https://mirrors.rpmfusion.org/mirrorlist?path=free/fedora/updates/43/x86_64/repoview/index.html&protocol=https&redirect=1
# this installs a package from fedora repos
-dnf5 install -y tmux
+dnf5 install -y tmux
# Use a COPR Example:
#
diff --git a/image-template.env b/image-template.env
new file mode 100644
index 0000000..c0707c5
--- /dev/null
+++ b/image-template.env
@@ -0,0 +1,15 @@
+# Here we set a bunch of parameters for your image build
+
+# output image name, usually same as repo name, change as needed
+IMAGE_NAME=image-template
+
+# Make this the same as your github username/organisation
+REPO_ORGANIZATION="alice-and-bob"
+
+IMAGE_DESC="My Customized Bootc Image"
+IMAGE_KEYWORDS="bootc,oci,linux"
+
+# Put your own image here for a fancy profile on https://artifacthub.io/!
+IMAGE_LOGO_URL="https://avatars.githubusercontent.com/u/120078124?s=200&v=4"
+DEFAULT_TAG="latest"
+BIB_IMAGE="quay.io/centos-bootc/bootc-image-builder:latest"
diff --git a/system_files/etc/.gitkeep b/system_files/etc/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/system_files/etc/.gitkeep
diff --git a/system_files/usr/.gitkeep b/system_files/usr/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/system_files/usr/.gitkeep