From 3403039ae5f9454ced428a2eb29b477b1ca92ac5 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Sat, 26 Aug 2023 10:48:11 -0500 Subject: first commit --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..329bb47 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# ublue-clean-start -- cgit v1.2.3 From 12af8be21e6cf643ed746f0aafa0359a1288d3e9 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Sat, 26 Aug 2023 10:49:08 -0500 Subject: chore: add license --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -- cgit v1.2.3 From 0c9be97ab878b2ed98850b5ba44725c8e40cfb17 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Sat, 26 Aug 2023 11:13:59 -0500 Subject: feat: first pass at a simple downstream build --- Containerfile | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Containerfile diff --git a/Containerfile b/Containerfile new file mode 100644 index 0000000..6ffa096 --- /dev/null +++ b/Containerfile @@ -0,0 +1,46 @@ +### 1. BUILD ARGS +## IMAGE_NAME arg can be anything from ublue upstream: silverblue, kinoite, sericea, vauxite, mate, lxqt, base +ARG IMAGE_NAME="silverblue" +## IMAGE_SUFFIX arg should be "main", nvidia users should use "nvidia" +ARG IMAGE_SUFFIX="main" +## FEDORA_MAJOR_VERSION arg must be a version built by ublue: 37 or 38 as of today +ARG FEDORA_MAJOR_VERSION="38" +## NVIDIA_MAJOR_VERSION should only be changed if the user needs a specific nvidia driver version +## if needing driver 535, this should be set to "-535". It is important to include the hyphen +ARG NVIDIA_MAJOR_VERSION="" + + +### 2. SOURCE IMAGE +## this is a standard Containerfile FROM using the build ARGs above to select the right upstream image +FROM ghcr.io/ublue-os/${IMAGE_NAME}-${IMAGE_SUFFIX}:${FEDORA_MAJOR_VERSION}${NVIDIA_MAJOR_VERSION} + + +### 3. PRE-MODIFICATIONS +## this directory is needed to prevent failure with some RPM installs +RUN mkdir -p /var/lib/alternatives + + +### 4. MODIFICATIONS +## make modifications desired in your image and install packages here, a few examples follow + +# install a package from standard fedora repo +RUN rpm-ostree install screen + +# install a package from rpmfusion repo +RUN rpm-ostree install vlc + +# static binaries can sometimes by added using a COPY directive like these below. +COPY --from=cgr.dev/chainguard/kubectl:latest /usr/bin/kubectl /usr/bin/kubectl +#COPY --from=docker.io/docker/compose-bin:latest /docker-compose /usr/bin/docker-compose + +# modify default timeouts on system to prevent slow reboots from services that won't stop +RUN sed -i 's/#DefaultTimeoutStopSec.*/DefaultTimeoutStopSec=15s/' /etc/systemd/user.conf && \ + sed -i 's/#DefaultTimeoutStopSec.*/DefaultTimeoutStopSec=15s/' /etc/systemd/system.conf + + +### 5. POST-MODIFICATIONS +## these commands leave the image in a clean state after local modifications +RUN rm -rf /tmp/* /var/* && \ + ostree container commit && \ + mkdir -p /tmp /var/tmp && \ + chmod 1777 /tmp /var/tmp -- cgit v1.2.3 From 2a26bae17c13890a2cf4417830abaa409f227379 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Sat, 26 Aug 2023 19:55:59 -0500 Subject: feat: add github actions build workflow --- .github/workflows/build.yml | 158 ++++++++++++++++++++++++++++++++++++++++++++ Containerfile | 5 ++ 2 files changed, 163 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..381ec83 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,158 @@ +--- +name: build-ublue-custom +on: + pull_request: + branches: + - main + schedule: + - cron: '05 10 * * *' # 10:05am UTC everyday + push: + branches: + - main + paths-ignore: + - '**/README.md' + workflow_dispatch: + +# The env variables starting with "ARG_" are described in the Containerfile of this repo. +# Look there for options and explanations for their usage. +# The values here are defaults and should be modified if using a different image, needing +# nvidia, a specific nvidia driver, or a different Fedora version. +env: + ARG_IMAGE_NAME: "silverblue" + ARG_IMAGE_SUFFIX: "main" + ARG_FEDORA_MAJOR_VERSION: "38" + ARG_NVIDIA_MAJOR_VERSION: "" + IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} + +jobs: + push-ghcr: + name: Build and push image + runs-on: ubuntu-22.04 + + permissions: + contents: read + packages: write + id-token: write + + steps: + # Checkout push-to-registry action GitHub repository + - name: Checkout Push to Registry action + uses: actions/checkout@v3 + + - name: Generate tags + id: generate-tags + shell: bash + run: | + # Generate a timestamp for creating an image version history + TIMESTAMP="$(date +%Y%m%d)" + VARIANT="${{ env.ARG_FEDORA_MAJOR_VERSION }}" + + COMMIT_TAGS=() + BUILD_TAGS=() + + # Have tags for tracking builds during pull request + SHA_SHORT="${GITHUB_SHA::7}" + COMMIT_TAGS+=("pr-${{ github.event.number }}-${VARIANT}") + COMMIT_TAGS+=("${SHA_SHORT}-${VARIANT}") + + COMMIT_TAGS+=("pr-${{ github.event.number }}") + COMMIT_TAGS+=("${SHA_SHORT}") + + BUILD_TAGS=("${VARIANT}") + + # Append matching timestamp tags to keep a version history + for TAG in "${BUILD_TAGS[@]}"; do + BUILD_TAGS+=("${TAG}-${TIMESTAMP}") + done + + BUILD_TAGS+=("${TIMESTAMP}") + BUILD_TAGS+=("latest") + + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + echo "Generated the following commit tags: " + for TAG in "${COMMIT_TAGS[@]}"; do + echo "${TAG}" + done + + alias_tags=("${COMMIT_TAGS[@]}") + else + alias_tags=("${BUILD_TAGS[@]}") + fi + + echo "Generated the following build tags: " + for TAG in "${BUILD_TAGS[@]}"; do + echo "${TAG}" + done + + echo "alias_tags=${alias_tags[*]}" >> $GITHUB_OUTPUT + + - name: Get current version + id: labels + run: | + ver=$(skopeo inspect docker://ghcr.io/ublue-os/${{ env.ARG_IMAGE_NAME }}-${{ env.ARG_IMAGE_SUFFIX }}:${{ env.FEDORA_MAJOR_VERSION}}${{ env.NVIDIA_MAJOR_VERSION}} | jq -r '.Labels["org.opencontainers.image.version"]') + echo "VERSION=$ver" >> $GITHUB_OUTPUT + + # Build metadata + - name: Image Metadata + uses: docker/metadata-action@v4 + id: meta + with: + images: | + ${{ env.ARG_IMAGE_NAME }}-${{ env.ARG_IMAGE_SUFFIX }}-custom + + labels: | + io.artifacthub.package.readme-url=https://raw.githubusercontent.com/${{ github.repository_owner }}/${{ github.repository_name }}/main/README.md + org.opencontainers.image.description=Customized ${{ env.ARG_IMAGE_NAME }}-${{ env.ARG_IMAGE_SUFFIX }} image. + org.opencontainers.image.title=${{ env.ARG_IMAGE_NAME }}-${{ env.ARG_IMAGE_SUFFIX }} + org.opencontainers.image.version=${{ steps.labels.outputs.VERSION }} + + # Build image using Buildah action + - name: Build Image + id: build_image + uses: redhat-actions/buildah-build@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.ARG_IMAGE_NAME }}-${{ env.ARG_IMAGE_SUFFIX }}-custom + tags: | + ${{ steps.generate-tags.outputs.alias_tags }} + build-args: | + IMAGE_NAME=${{ env.ARG_IMAGE_NAME }} + IMAGE_SUFFIX=${{ env.ARG_IMAGE_SUFFIX }} + FEDORA_MAJOR_VERSION=${{ env.ARG_FEDORA_MAJOR_VERSION }} + NVIDIA_MAJOR_VERSION=${{ env.ARG_NVIDIA_MAJOR_VERSION }} + labels: ${{ steps.meta.outputs.labels }} + oci: false + + # Workaround bug where capital letters in your GitHub username make it impossible to push to GHCR. + # https://github.com/macbre/push-to-ghcr/issues/12 + - name: Lowercase Registry + id: registry_case + uses: ASzc/change-string-case-action@v5 + with: + string: ${{ env.IMAGE_REGISTRY }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Push the image to GHCR (Image Registry) + - name: Push To GHCR + uses: redhat-actions/push-to-registry@v2 + id: push + env: + REGISTRY_USER: ${{ github.actor }} + REGISTRY_PASSWORD: ${{ github.token }} + with: + image: ${{ steps.build_image.outputs.image }} + tags: ${{ steps.build_image.outputs.tags }} + registry: ${{ steps.registry_case.outputs.lowercase }} + username: ${{ env.REGISTRY_USER }} + password: ${{ env.REGISTRY_PASSWORD }} + extra-args: | + --disable-content-trust diff --git a/Containerfile b/Containerfile index 6ffa096..e51bd8e 100644 --- a/Containerfile +++ b/Containerfile @@ -1,4 +1,9 @@ ### 1. BUILD ARGS +## These enable the produced image to be different by passing different build args. +## They are provided on the commandline when building in a terminal, but the github +## workflow provides them when building in Github Actions. Changes to the workflow +## build.xml will override changes here. + ## IMAGE_NAME arg can be anything from ublue upstream: silverblue, kinoite, sericea, vauxite, mate, lxqt, base ARG IMAGE_NAME="silverblue" ## IMAGE_SUFFIX arg should be "main", nvidia users should use "nvidia" -- cgit v1.2.3 From 0752d0772f610d771cb464fa6fa55ce4f4260cad Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Sat, 26 Aug 2023 20:09:48 -0500 Subject: refactor: simplify some variable names --- .github/workflows/build.yml | 31 ++++++++++++++++--------------- Containerfile | 18 +++++++++--------- README.md | 2 +- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 381ec83..ced7a05 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,11 +18,12 @@ on: # The values here are defaults and should be modified if using a different image, needing # nvidia, a specific nvidia driver, or a different Fedora version. env: - ARG_IMAGE_NAME: "silverblue" - ARG_IMAGE_SUFFIX: "main" - ARG_FEDORA_MAJOR_VERSION: "38" - ARG_NVIDIA_MAJOR_VERSION: "" - IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} + ARG_SOURCE_IMAGE: "silverblue" + ARG_SOURCE_SUFFIX: "main" + ARG_FEDORA_VERSION: "38" + ARG_NVIDIA_VERSION: "" + IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" + MY_IMAGE_NAME: "customzed-ublue" jobs: push-ghcr: @@ -45,7 +46,7 @@ jobs: run: | # Generate a timestamp for creating an image version history TIMESTAMP="$(date +%Y%m%d)" - VARIANT="${{ env.ARG_FEDORA_MAJOR_VERSION }}" + VARIANT="${{ env.ARG_FEDORA_VERSION }}" COMMIT_TAGS=() BUILD_TAGS=() @@ -89,7 +90,7 @@ jobs: - name: Get current version id: labels run: | - ver=$(skopeo inspect docker://ghcr.io/ublue-os/${{ env.ARG_IMAGE_NAME }}-${{ env.ARG_IMAGE_SUFFIX }}:${{ env.FEDORA_MAJOR_VERSION}}${{ env.NVIDIA_MAJOR_VERSION}} | jq -r '.Labels["org.opencontainers.image.version"]') + ver=$(skopeo inspect docker://ghcr.io/ublue-os/${{ env.ARG_SOURCE_IMAGE }}-${{ env.ARG_SOURCE_SUFFIX }}:${{ env.FEDORA_VERSION}}${{ env.NVIDIA_VERSION}} | jq -r '.Labels["org.opencontainers.image.version"]') echo "VERSION=$ver" >> $GITHUB_OUTPUT # Build metadata @@ -98,12 +99,12 @@ jobs: id: meta with: images: | - ${{ env.ARG_IMAGE_NAME }}-${{ env.ARG_IMAGE_SUFFIX }}-custom + ${{ env.MY_IMAGE_NAME }} labels: | io.artifacthub.package.readme-url=https://raw.githubusercontent.com/${{ github.repository_owner }}/${{ github.repository_name }}/main/README.md - org.opencontainers.image.description=Customized ${{ env.ARG_IMAGE_NAME }}-${{ env.ARG_IMAGE_SUFFIX }} image. - org.opencontainers.image.title=${{ env.ARG_IMAGE_NAME }}-${{ env.ARG_IMAGE_SUFFIX }} + org.opencontainers.image.description=Customized ${{ env.ARG_SOURCE_IMAGE }}-${{ env.ARG_SOURCE_SUFFIX }} image. + org.opencontainers.image.title=${{ env.MY_IMAGE_NAME }} org.opencontainers.image.version=${{ steps.labels.outputs.VERSION }} # Build image using Buildah action @@ -115,14 +116,14 @@ jobs: ./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.ARG_IMAGE_NAME }}-${{ env.ARG_IMAGE_SUFFIX }}-custom + image: ${{ env.MY_IMAGE_NAME }} tags: | ${{ steps.generate-tags.outputs.alias_tags }} build-args: | - IMAGE_NAME=${{ env.ARG_IMAGE_NAME }} - IMAGE_SUFFIX=${{ env.ARG_IMAGE_SUFFIX }} - FEDORA_MAJOR_VERSION=${{ env.ARG_FEDORA_MAJOR_VERSION }} - NVIDIA_MAJOR_VERSION=${{ env.ARG_NVIDIA_MAJOR_VERSION }} + SOURCE_IMAGE=${{ env.ARG_SOURCE_IMAGE }} + SOURCE_SUFFIX=${{ env.ARG_SOURCE_SUFFIX }} + FEDORA_VERSION=${{ env.ARG_FEDORA_VERSION }} + NVIDIA_VERSION=${{ env.ARG_NVIDIA_VERSION }} labels: ${{ steps.meta.outputs.labels }} oci: false diff --git a/Containerfile b/Containerfile index e51bd8e..caa8a00 100644 --- a/Containerfile +++ b/Containerfile @@ -4,20 +4,20 @@ ## workflow provides them when building in Github Actions. Changes to the workflow ## build.xml will override changes here. -## IMAGE_NAME arg can be anything from ublue upstream: silverblue, kinoite, sericea, vauxite, mate, lxqt, base -ARG IMAGE_NAME="silverblue" -## IMAGE_SUFFIX arg should be "main", nvidia users should use "nvidia" -ARG IMAGE_SUFFIX="main" -## FEDORA_MAJOR_VERSION arg must be a version built by ublue: 37 or 38 as of today -ARG FEDORA_MAJOR_VERSION="38" -## NVIDIA_MAJOR_VERSION should only be changed if the user needs a specific nvidia driver version +## SOURCE_IMAGE arg can be anything from ublue upstream: silverblue, kinoite, sericea, vauxite, mate, lxqt, base +ARG SOURCE_IMAGE="silverblue" +## SOURCE_SUFFIX arg should be "main", nvidia users should use "nvidia" +ARG SOURCE_SUFFIX="main" +## FEDORA_VERSION arg must be a version built by ublue: 37 or 38 as of today +ARG FEDORA_VERSION="38" +## NVIDIA_VERSION should only be changed if the user needs a specific nvidia driver version ## if needing driver 535, this should be set to "-535". It is important to include the hyphen -ARG NVIDIA_MAJOR_VERSION="" +ARG NVIDIA_VERSION="" ### 2. SOURCE IMAGE ## this is a standard Containerfile FROM using the build ARGs above to select the right upstream image -FROM ghcr.io/ublue-os/${IMAGE_NAME}-${IMAGE_SUFFIX}:${FEDORA_MAJOR_VERSION}${NVIDIA_MAJOR_VERSION} +FROM ghcr.io/ublue-os/${SOURCE_IMAGE}-${SOURCE_SUFFIX}:${FEDORA_VERSION}${NVIDIA_VERSION} ### 3. PRE-MODIFICATIONS diff --git a/README.md b/README.md index 329bb47..04a0213 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# ublue-clean-start +# ublue-custom-start -- cgit v1.2.3 From 3ad6d864605c9e56bd2809efd6bd3f5b0997d5c8 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Sat, 26 Aug 2023 20:16:41 -0500 Subject: refactor: fixing typo and cleanup comments --- .github/workflows/build.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ced7a05..7811bf7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,16 +14,15 @@ on: workflow_dispatch: # The env variables starting with "ARG_" are described in the Containerfile of this repo. -# Look there for options and explanations for their usage. # The values here are defaults and should be modified if using a different image, needing # nvidia, a specific nvidia driver, or a different Fedora version. env: - ARG_SOURCE_IMAGE: "silverblue" - ARG_SOURCE_SUFFIX: "main" - ARG_FEDORA_VERSION: "38" - ARG_NVIDIA_VERSION: "" - IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" - MY_IMAGE_NAME: "customzed-ublue" + MY_IMAGE_NAME: "custom-silverblue" # the name of the image produced by this build + ARG_SOURCE_IMAGE: "silverblue" # see Containerfile for list of possible upstream images + ARG_SOURCE_SUFFIX: "main" # see Containerfile + ARG_FEDORA_VERSION: "38" # see Containerfile + ARG_NVIDIA_VERSION: "" # see Containerfile + IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit jobs: push-ghcr: @@ -102,7 +101,7 @@ jobs: ${{ env.MY_IMAGE_NAME }} labels: | - io.artifacthub.package.readme-url=https://raw.githubusercontent.com/${{ github.repository_owner }}/${{ github.repository_name }}/main/README.md + io.artifacthub.package.readme-url=https://raw.githubusercontent.com/${{ github.repository_owner }}/${{ github.repository }}/main/README.md org.opencontainers.image.description=Customized ${{ env.ARG_SOURCE_IMAGE }}-${{ env.ARG_SOURCE_SUFFIX }} image. org.opencontainers.image.title=${{ env.MY_IMAGE_NAME }} org.opencontainers.image.version=${{ steps.labels.outputs.VERSION }} -- cgit v1.2.3 From 0d0ca0f7f525ee414fae25ac93c8becd2b8fd1ee Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Sat, 26 Aug 2023 20:26:38 -0500 Subject: chore(ci): fixing urls in build --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7811bf7..480ae9d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -89,7 +89,7 @@ jobs: - name: Get current version id: labels run: | - ver=$(skopeo inspect docker://ghcr.io/ublue-os/${{ env.ARG_SOURCE_IMAGE }}-${{ env.ARG_SOURCE_SUFFIX }}:${{ env.FEDORA_VERSION}}${{ env.NVIDIA_VERSION}} | jq -r '.Labels["org.opencontainers.image.version"]') + ver=$(skopeo inspect docker://ghcr.io/ublue-os/${{ env.ARG_SOURCE_IMAGE }}-${{ env.ARG_SOURCE_SUFFIX }}:${{ env.FEDORA_VERSION}}${{ env.NVIDIA_VERSION }} | jq -r '.Labels["org.opencontainers.image.version"]') echo "VERSION=$ver" >> $GITHUB_OUTPUT # Build metadata @@ -101,8 +101,8 @@ jobs: ${{ env.MY_IMAGE_NAME }} labels: | - io.artifacthub.package.readme-url=https://raw.githubusercontent.com/${{ github.repository_owner }}/${{ github.repository }}/main/README.md - org.opencontainers.image.description=Customized ${{ env.ARG_SOURCE_IMAGE }}-${{ env.ARG_SOURCE_SUFFIX }} image. + io.artifacthub.package.readme-url=https://raw.githubusercontent.com/${{ github.repository }}/main/README.md + org.opencontainers.image.description=Customized ${{ env.ARG_SOURCE_IMAGE }}-${{ env.ARG_SOURCE_SUFFIX }} org.opencontainers.image.title=${{ env.MY_IMAGE_NAME }} org.opencontainers.image.version=${{ steps.labels.outputs.VERSION }} -- cgit v1.2.3 From 87fe7febb68b1d5d3035e0f6d9db1435ca442599 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Sat, 26 Aug 2023 20:30:49 -0500 Subject: chore(ci): fix version query --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 480ae9d..745b0c2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -89,7 +89,7 @@ jobs: - name: Get current version id: labels run: | - ver=$(skopeo inspect docker://ghcr.io/ublue-os/${{ env.ARG_SOURCE_IMAGE }}-${{ env.ARG_SOURCE_SUFFIX }}:${{ env.FEDORA_VERSION}}${{ env.NVIDIA_VERSION }} | jq -r '.Labels["org.opencontainers.image.version"]') + ver=$(skopeo inspect docker://ghcr.io/ublue-os/${{ env.ARG_SOURCE_IMAGE }}-${{ env.ARG_SOURCE_SUFFIX }}:${{ env.FEDORA_VERSION}} | jq -r '.Labels["org.opencontainers.image.version"]') echo "VERSION=$ver" >> $GITHUB_OUTPUT # Build metadata -- cgit v1.2.3 From c0f2a66ffcf5191e87167c8831d07629c5aa0b8f Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Sat, 26 Aug 2023 20:32:04 -0500 Subject: chore(ci): the ARG_ was missing from the env var in version lookup --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 745b0c2..fdd54f0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -89,7 +89,7 @@ jobs: - name: Get current version id: labels run: | - ver=$(skopeo inspect docker://ghcr.io/ublue-os/${{ env.ARG_SOURCE_IMAGE }}-${{ env.ARG_SOURCE_SUFFIX }}:${{ env.FEDORA_VERSION}} | jq -r '.Labels["org.opencontainers.image.version"]') + ver=$(skopeo inspect docker://ghcr.io/ublue-os/${{ env.ARG_SOURCE_IMAGE }}-${{ env.ARG_SOURCE_SUFFIX }}:${{ env.ARG_FEDORA_VERSION }}${{ env.ARG_NVIDIA_VERSION }} | jq -r '.Labels["org.opencontainers.image.version"]') echo "VERSION=$ver" >> $GITHUB_OUTPUT # Build metadata -- cgit v1.2.3 From 695cbe518a3c44662f91ccda0892174f6a4a018a Mon Sep 17 00:00:00 2001 From: Noel Miller Date: Sun, 3 Mar 2024 11:39:58 -0600 Subject: feat: Updated build.yml to include container signing section --- .github/workflows/build.yml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fdd54f0..96547dc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,7 +20,7 @@ env: MY_IMAGE_NAME: "custom-silverblue" # the name of the image produced by this build ARG_SOURCE_IMAGE: "silverblue" # see Containerfile for list of possible upstream images ARG_SOURCE_SUFFIX: "main" # see Containerfile - ARG_FEDORA_VERSION: "38" # see Containerfile + ARG_FEDORA_VERSION: "39" # see Containerfile ARG_NVIDIA_VERSION: "" # see Containerfile IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit @@ -156,3 +156,22 @@ jobs: password: ${{ env.REGISTRY_PASSWORD }} extra-args: | --disable-content-trust + + # This section is optional and only needs to be enabled in you plan on distributing + # your project to 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. + + # Sign container + + #- uses: sigstore/cosign-installer@v3.4.0 + # if: github.event_name != 'pull_request' + + #- name: Sign container image + # if: github.event_name != 'pull_request' + # run: | + # cosign sign -y --key env://COSIGN_PRIVATE_KEY ${{ steps.registry_case.outputs.lowercase }}/${{ steps.build_image.outputs.image }}@${TAGS} + # env: + # TAGS: ${{ steps.push.outputs.digest }} + # COSIGN_EXPERIMENTAL: false + # COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} -- cgit v1.2.3 From 70cb151691908d500f70829389de78c0cacc6f80 Mon Sep 17 00:00:00 2001 From: Noel Miller Date: Sun, 3 Mar 2024 11:40:37 -0600 Subject: feat: Added additional information in base containerfile --- Containerfile | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/Containerfile b/Containerfile index caa8a00..6e4bc6e 100644 --- a/Containerfile +++ b/Containerfile @@ -2,16 +2,21 @@ ## These enable the produced image to be different by passing different build args. ## They are provided on the commandline when building in a terminal, but the github ## workflow provides them when building in Github Actions. Changes to the workflow -## build.xml will override changes here. +## build.yml will override changes here. -## SOURCE_IMAGE arg can be anything from ublue upstream: silverblue, kinoite, sericea, vauxite, mate, lxqt, base +## SOURCE_IMAGE arg can be anything from ublue upstream: silverblue, kinoite, sericea, base +## See list here: https://github.com/orgs/ublue-os/packages?repo_name=main ARG SOURCE_IMAGE="silverblue" + ## SOURCE_SUFFIX arg should be "main", nvidia users should use "nvidia" ARG SOURCE_SUFFIX="main" + ## FEDORA_VERSION arg must be a version built by ublue: 37 or 38 as of today -ARG FEDORA_VERSION="38" +ARG FEDORA_VERSION="39" + ## NVIDIA_VERSION should only be changed if the user needs a specific nvidia driver version -## if needing driver 535, this should be set to "-535". It is important to include the hyphen +## This will depend on your hardware and the version of the driver that supports it. +## if needing driver 470, this should be set to "-470". It is important to include the hyphen ARG NVIDIA_VERSION="" @@ -21,6 +26,8 @@ FROM ghcr.io/ublue-os/${SOURCE_IMAGE}-${SOURCE_SUFFIX}:${FEDORA_VERSION}${NVIDIA ### 3. PRE-MODIFICATIONS +## This section is meant for any modifications to the image before the main modifications are made. + ## this directory is needed to prevent failure with some RPM installs RUN mkdir -p /var/lib/alternatives @@ -28,24 +35,32 @@ RUN mkdir -p /var/lib/alternatives ### 4. MODIFICATIONS ## make modifications desired in your image and install packages here, a few examples follow -# install a package from standard fedora repo -RUN rpm-ostree install screen +#### Install packages -# install a package from rpmfusion repo +# install a package from standard fedora repo or rpmfusion repo +# RPMfusion packages are available by default in ublue main images +# List of rpmfusion packages can be found here: +# https://mirrors.rpmfusion.org/mirrorlist?path=free/fedora/updates/39/x86_64/repoview/index.html&protocol=https&redirect=1 +RUN rpm-ostree install screen +# exmaple package from rpmfusion RUN rpm-ostree install vlc +#### Installation of static binaries + # static binaries can sometimes by added using a COPY directive like these below. COPY --from=cgr.dev/chainguard/kubectl:latest /usr/bin/kubectl /usr/bin/kubectl -#COPY --from=docker.io/docker/compose-bin:latest /docker-compose /usr/bin/docker-compose +# COPY --from=docker.io/docker/compose-bin:latest /docker-compose /usr/bin/docker-compose + +#### Change to System Configuration Files # modify default timeouts on system to prevent slow reboots from services that won't stop RUN sed -i 's/#DefaultTimeoutStopSec.*/DefaultTimeoutStopSec=15s/' /etc/systemd/user.conf && \ - sed -i 's/#DefaultTimeoutStopSec.*/DefaultTimeoutStopSec=15s/' /etc/systemd/system.conf + sed -i 's/#DefaultTimeoutStopSec.*/DefaultTimeoutStopSec=15s/' /etc/systemd/system.conf ### 5. POST-MODIFICATIONS ## these commands leave the image in a clean state after local modifications RUN rm -rf /tmp/* /var/* && \ - ostree container commit && \ - mkdir -p /tmp /var/tmp && \ - chmod 1777 /tmp /var/tmp + ostree container commit && \ + mkdir -p /tmp /var/tmp && \ + chmod 1777 /tmp /var/tmp -- cgit v1.2.3 From 340e8ba38bb092d5f71255c1a343718eaa4e24ff Mon Sep 17 00:00:00 2001 From: Noel Miller Date: Sun, 3 Mar 2024 19:00:00 -0600 Subject: feat: initial update of readme --- README.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/README.md b/README.md index 04a0213..dd8f82f 100644 --- a/README.md +++ b/README.md @@ -1 +1,36 @@ # ublue-custom-start + +# Purpose + +This repository is meant to be used as a template to build your own custom Universal Blue Image. This base template is what the Universal Blue Project uses for all of our new and existing downstream projects (Bazzite, Bluefin, and Ucore). Each project has edited from this template to suit their own individual needs for more advanced build requirements. This template includes a Containerfile and 2 Github workflows (one for building the container and one for building an installation ISO from the container file) that will work immediately out of the box as soon as you enable the workflow in your repository. + +# Prerequisites + +Working knowledge in the following topics: + +- Containers + - Resources: + - https://www.youtube.com/watch?v=SnSH8Ht3MIc + - https://www.mankier.com/5/Containerfile +- rpm-ostree + - Resources: + - https://coreos.github.io/rpm-ostree/ +- Fedora Silverblue (and other Fedora Atomic variants) + - Resources: + - https://docs.fedoraproject.org/en-US/fedora-silverblue/ +- Github Workflows + - Resources: + - https://docs.github.com/en/actions/using-workflows + +# How to Use + +## Template + +Since this is a template repository, you can select `Use this Template` and create a new repository from it. To enable the workflows, you will need to go the actions tab of the new repository and enable the workflows. + +## Containerfile + +This is the main file used to customize the base image you are using. There are several examples of how to add layered rpm-ostree packages + +## Workflows +The `build.yml` workflow creates your OCI container -- cgit v1.2.3 From e91798658878a8ea7a10b01c4c4add12246e1df6 Mon Sep 17 00:00:00 2001 From: Noel Miller Date: Fri, 12 Apr 2024 11:28:03 -0500 Subject: chore: update readme --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dd8f82f..7beae58 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Purpose -This repository is meant to be used as a template to build your own custom Universal Blue Image. This base template is what the Universal Blue Project uses for all of our new and existing downstream projects (Bazzite, Bluefin, and Ucore). Each project has edited from this template to suit their own individual needs for more advanced build requirements. This template includes a Containerfile and 2 Github workflows (one for building the container and one for building an installation ISO from the container file) that will work immediately out of the box as soon as you enable the workflow in your repository. +This repository is meant to be used as a template to build your own custom Universal Blue Image. This example base template is what the Universal Blue Project uses for all of our new and existing downstream projects (Bazzite, Bluefin, and Ucore). This template includes a Containerfile and 2 Github workflows (one for building the container and one for building an installation ISO from the container file) that will work immediately out of the box as soon as you enable the workflow in your repository. # Prerequisites @@ -33,4 +33,11 @@ Since this is a template repository, you can select `Use this Template` and crea This is the main file used to customize the base image you are using. There are several examples of how to add layered rpm-ostree packages ## Workflows -The `build.yml` workflow creates your OCI container + +### build.yml + +This workflow creates your custom OCI container and publishes it to Github Container Registry. + +### build_iso.yml + +This workflow creates an ISO and uploads it as a Github Artifact. (For examples on how to upload to a cloud registry, feel free to review Bazzite or Bluefin's workflow for uploading to R2.) -- cgit v1.2.3 From 7fb4265c3ba9d5ff464de1dc070843cdeaf0fd80 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Fri, 12 Apr 2024 15:20:45 -0500 Subject: chore: simplify workflow even more --- .github/workflows/build.yml | 41 ++++++++--------------------------------- 1 file changed, 8 insertions(+), 33 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 96547dc..9154ca4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,21 +13,15 @@ on: - '**/README.md' workflow_dispatch: -# The env variables starting with "ARG_" are described in the Containerfile of this repo. -# The values here are defaults and should be modified if using a different image, needing -# nvidia, a specific nvidia driver, or a different Fedora version. env: - MY_IMAGE_NAME: "custom-silverblue" # the name of the image produced by this build - ARG_SOURCE_IMAGE: "silverblue" # see Containerfile for list of possible upstream images - ARG_SOURCE_SUFFIX: "main" # see Containerfile - ARG_FEDORA_VERSION: "39" # see Containerfile - ARG_NVIDIA_VERSION: "" # see Containerfile + MY_IMAGE_NAME: "ublue-custom" # the name of the image produced by this build + MY_IMAGE_DESC: "My Customized Universal Blue System Image" IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit jobs: - push-ghcr: + build_push: name: Build and push image - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest permissions: contents: read @@ -45,21 +39,14 @@ jobs: run: | # Generate a timestamp for creating an image version history TIMESTAMP="$(date +%Y%m%d)" - VARIANT="${{ env.ARG_FEDORA_VERSION }}" - COMMIT_TAGS=() BUILD_TAGS=() # Have tags for tracking builds during pull request SHA_SHORT="${GITHUB_SHA::7}" - COMMIT_TAGS+=("pr-${{ github.event.number }}-${VARIANT}") - COMMIT_TAGS+=("${SHA_SHORT}-${VARIANT}") - COMMIT_TAGS+=("pr-${{ github.event.number }}") COMMIT_TAGS+=("${SHA_SHORT}") - BUILD_TAGS=("${VARIANT}") - # Append matching timestamp tags to keep a version history for TAG in "${BUILD_TAGS[@]}"; do BUILD_TAGS+=("${TAG}-${TIMESTAMP}") @@ -86,12 +73,6 @@ jobs: echo "alias_tags=${alias_tags[*]}" >> $GITHUB_OUTPUT - - name: Get current version - id: labels - run: | - ver=$(skopeo inspect docker://ghcr.io/ublue-os/${{ env.ARG_SOURCE_IMAGE }}-${{ env.ARG_SOURCE_SUFFIX }}:${{ env.ARG_FEDORA_VERSION }}${{ env.ARG_NVIDIA_VERSION }} | jq -r '.Labels["org.opencontainers.image.version"]') - echo "VERSION=$ver" >> $GITHUB_OUTPUT - # Build metadata - name: Image Metadata uses: docker/metadata-action@v4 @@ -102,9 +83,8 @@ jobs: labels: | io.artifacthub.package.readme-url=https://raw.githubusercontent.com/${{ github.repository }}/main/README.md - org.opencontainers.image.description=Customized ${{ env.ARG_SOURCE_IMAGE }}-${{ env.ARG_SOURCE_SUFFIX }} + org.opencontainers.image.description=${{ env.MY_IMAGE_DESC }} org.opencontainers.image.title=${{ env.MY_IMAGE_NAME }} - org.opencontainers.image.version=${{ steps.labels.outputs.VERSION }} # Build image using Buildah action - name: Build Image @@ -118,11 +98,6 @@ jobs: image: ${{ env.MY_IMAGE_NAME }} tags: | ${{ steps.generate-tags.outputs.alias_tags }} - build-args: | - SOURCE_IMAGE=${{ env.ARG_SOURCE_IMAGE }} - SOURCE_SUFFIX=${{ env.ARG_SOURCE_SUFFIX }} - FEDORA_VERSION=${{ env.ARG_FEDORA_VERSION }} - NVIDIA_VERSION=${{ env.ARG_NVIDIA_VERSION }} labels: ${{ steps.meta.outputs.labels }} oci: false @@ -141,8 +116,7 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - # Push the image to GHCR (Image Registry) - - name: Push To GHCR + - name: Push Image to GHCR uses: redhat-actions/push-to-registry@v2 id: push env: @@ -170,7 +144,8 @@ jobs: #- name: Sign container image # if: github.event_name != 'pull_request' # run: | - # cosign sign -y --key env://COSIGN_PRIVATE_KEY ${{ steps.registry_case.outputs.lowercase }}/${{ steps.build_image.outputs.image }}@${TAGS} + # cosign sign -y --key env://COSIGN_PRIVATE_KEY ${{ steps.registry_case.outputs.lowercase }}/$ +{{ steps.build_image.outputs.image }}@${TAGS} # env: # TAGS: ${{ steps.push.outputs.digest }} # COSIGN_EXPERIMENTAL: false -- cgit v1.2.3 From 78a2e68421cb6fc76fd1ceefc29709c821466132 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Fri, 12 Apr 2024 15:34:52 -0500 Subject: chore: cleanup Containerfile args & comments --- Containerfile | 61 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/Containerfile b/Containerfile index 6e4bc6e..da1dad9 100644 --- a/Containerfile +++ b/Containerfile @@ -1,28 +1,47 @@ -### 1. BUILD ARGS -## These enable the produced image to be different by passing different build args. -## They are provided on the commandline when building in a terminal, but the github -## workflow provides them when building in Github Actions. Changes to the workflow -## build.yml will override changes here. - -## SOURCE_IMAGE arg can be anything from ublue upstream: silverblue, kinoite, sericea, base -## See list here: https://github.com/orgs/ublue-os/packages?repo_name=main +## 1. BUILD ARGS +# These allow changing the produced image by passing different build args to adjust +# the source from which your image is built. +# Build args can be provided on the commandline when building locally with: +# podman build -f Containerfile --build-arg FEDORA_VERSION=40 -t local-image + +# SOURCE_IMAGE arg can be anything from ublue upstream which matches your desired version: +# See list here: https://github.com/orgs/ublue-os/packages?repo_name=main +# - "silverblue" +# - "kinoite" +# - "sericea" +# - "onyx" +# - "lazurite" +# - "vauxite" +# - "base" +# +# "aurora", "bazzite", "bluefin" or "ucore" may also be used but have different suffixes. ARG SOURCE_IMAGE="silverblue" -## SOURCE_SUFFIX arg should be "main", nvidia users should use "nvidia" -ARG SOURCE_SUFFIX="main" - -## FEDORA_VERSION arg must be a version built by ublue: 37 or 38 as of today +## SOURCE_SUFFIX arg should include a hyphen and the appropriate suffix name +# These examples all work for silverblue/kinoite/sericea/onyx/lazurite/vauxite/base +# - "-main" +# - "-nvidia" +# - "-asus" +# - "-asus-nvidia" +# - "-surface" +# - "-surface-nvidia" +# +# aurora, bazzite and bluefin each have unique suffixes. Please check the specific image. +# ucore has the following possible suffixes +# - stable +# - stable-nvidia +# - stable-zfs +# - stable-nvidia-zfs +# - (and the above with testing rather than stable) +ARG SOURCE_SUFFIX="-main" + +## FEDORA_VERSION arg must be a version built by ublue: eg, 39 or 40 ARG FEDORA_VERSION="39" -## NVIDIA_VERSION should only be changed if the user needs a specific nvidia driver version -## This will depend on your hardware and the version of the driver that supports it. -## if needing driver 470, this should be set to "-470". It is important to include the hyphen -ARG NVIDIA_VERSION="" - ### 2. SOURCE IMAGE ## this is a standard Containerfile FROM using the build ARGs above to select the right upstream image -FROM ghcr.io/ublue-os/${SOURCE_IMAGE}-${SOURCE_SUFFIX}:${FEDORA_VERSION}${NVIDIA_VERSION} +FROM ghcr.io/ublue-os/${SOURCE_IMAGE}${SOURCE_SUFFIX}:${FEDORA_VERSION} ### 3. PRE-MODIFICATIONS @@ -42,14 +61,14 @@ RUN mkdir -p /var/lib/alternatives # List of rpmfusion packages can be found here: # https://mirrors.rpmfusion.org/mirrorlist?path=free/fedora/updates/39/x86_64/repoview/index.html&protocol=https&redirect=1 RUN rpm-ostree install screen -# exmaple package from rpmfusion -RUN rpm-ostree install vlc +# example package from rpmfusion +#RUN rpm-ostree install vlc #### Installation of static binaries # static binaries can sometimes by added using a COPY directive like these below. COPY --from=cgr.dev/chainguard/kubectl:latest /usr/bin/kubectl /usr/bin/kubectl -# COPY --from=docker.io/docker/compose-bin:latest /docker-compose /usr/bin/docker-compose +#COPY --from=docker.io/docker/compose-bin:latest /docker-compose /usr/bin/docker-compose #### Change to System Configuration Files -- cgit v1.2.3 From efef8cbaa458c28725fdaf9acaf7dc05b0c7e459 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Fri, 12 Apr 2024 15:37:55 -0500 Subject: docs: add cosign and cleanup other info --- .github/workflows/build.yml | 3 +- README.md | 71 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9154ca4..8840974 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -144,8 +144,7 @@ jobs: #- name: Sign container image # if: github.event_name != 'pull_request' # run: | - # cosign sign -y --key env://COSIGN_PRIVATE_KEY ${{ steps.registry_case.outputs.lowercase }}/$ -{{ steps.build_image.outputs.image }}@${TAGS} + # cosign sign -y --key env://COSIGN_PRIVATE_KEY ${{ steps.registry_case.outputs.lowercase }}/${{ steps.build_image.outputs.image }}@${TAGS} # env: # TAGS: ${{ steps.push.outputs.digest }} # COSIGN_EXPERIMENTAL: false diff --git a/README.md b/README.md index 7beae58..095ba49 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,82 @@ -# ublue-custom-start +# ublue-custom-template # Purpose -This repository is meant to be used as a template to build your own custom Universal Blue Image. This example base template is what the Universal Blue Project uses for all of our new and existing downstream projects (Bazzite, Bluefin, and Ucore). This template includes a Containerfile and 2 Github workflows (one for building the container and one for building an installation ISO from the container file) that will work immediately out of the box as soon as you enable the workflow in your repository. +This repository is meant to be a template for building your own custom Universal Blue image. This template is the recommended way to make customizations to any image published by the Universal Blue Project: +- [Aurora](https://getaurora.dev/) +- [Bazzite](https://bazzite.gg/) +- [Bluefin](https://projectbluefin.io/) +- [uCore](https://projectucore.io/) +- [main](https://github.com/ublue-os/main/) +- [hwe](https://github.com/ublue-os/hwe/) + +This template includes a Containerfile and a Github workflow for building the container image. As soon as the workflow is enabled in your repository, it will build the container image and push it to the Github Container Registry. # Prerequisites Working knowledge in the following topics: - Containers - - Resources: - - https://www.youtube.com/watch?v=SnSH8Ht3MIc - - https://www.mankier.com/5/Containerfile + - https://www.youtube.com/watch?v=SnSH8Ht3MIc + - https://www.mankier.com/5/Containerfile - rpm-ostree - - Resources: - - https://coreos.github.io/rpm-ostree/ + - https://coreos.github.io/rpm-ostree/container/ - Fedora Silverblue (and other Fedora Atomic variants) - - Resources: - - https://docs.fedoraproject.org/en-US/fedora-silverblue/ + - https://docs.fedoraproject.org/en-US/fedora-silverblue/ - Github Workflows - - Resources: - - https://docs.github.com/en/actions/using-workflows + - https://docs.github.com/en/actions/using-workflows # How to Use ## Template -Since this is a template repository, you can select `Use this Template` and create a new repository from it. To enable the workflows, you will need to go the actions tab of the new repository and enable the workflows. +Select `Use this Template` and create a new repository from it. To enable the workflows, you will need to go the `Actions` tab of the new repository and click to enable workflows. ## Containerfile -This is the main file used to customize the base image you are using. There are several examples of how to add layered rpm-ostree packages +This file defines the operations used to customize the selected image. It contains examples of possible modifications, including how to: +- change the upstream from which the custom image is derived +- add additional RPM packages +- add binaries as a layer from other images +- modify system files (like /etc/systemd/system.conf) ## Workflows ### build.yml -This workflow creates your custom OCI container and publishes it to Github Container Registry. +This workflow creates your custom OCI image and publishes it to the Github Container Registry (GHCR). + +#### Container Signing + +Container signing is important for end-user security and is enabled on all Universal Blue images. It is recommended you set this up, and by default the image builds *will fail* if you don't. + +This provides users a method of verifying the image. + +1. Install the [cosign CLI tool](https://edu.chainguard.dev/open-source/sigstore/cosign/how-to-install-cosign/#installing-cosign-with-the-cosign-binary) + +2. Run inside your repo folder: + + ```bash + cosign generate-key-pair + ``` + + + - Do NOT put in a password when it asks you to, just press enter. The signing key will be used in GitHub Actions and will not work if it is encrypted. + +> [!WARNING] +> Be careful to *never* accidentally commit `cosign.key` into your git repo. + +3. Add the private key to GitHub + + - This can also be done manually. Go to your repository settings, under Secrets and Variables -> Actions + ![image](https://user-images.githubusercontent.com/1264109/216735595-0ecf1b66-b9ee-439e-87d7-c8cc43c2110a.png) + Add a new secret and name it `SIGNING_SECRET`, then paste the contents of `cosign.key` into the secret and save it. Make sure it's the .key file and not the .pub file. Once done, it should look like this: + ![image](https://user-images.githubusercontent.com/1264109/216735690-2d19271f-cee2-45ac-a039-23e6a4c16b34.png) + + - (CLI instructions) If you have the `github-cli` installed, run: -### build_iso.yml + ```bash + gh secret set SIGNING_SECRET < cosign.key + ``` -This workflow creates an ISO and uploads it as a Github Artifact. (For examples on how to upload to a cloud registry, feel free to review Bazzite or Bluefin's workflow for uploading to R2.) +4. Commit the `cosign.pub` file into your git repository -- cgit v1.2.3 From 9c67a9c024a2bf27e1e18fa24af92ef18b7860e9 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Fri, 12 Apr 2024 17:00:27 -0500 Subject: docs: change header --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 095ba49..3d34e94 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ublue-custom-template +# image-template # Purpose -- cgit v1.2.3 From 53869f2cbfca3551b93b271b67dffdff12697070 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Fri, 12 Apr 2024 17:02:33 -0500 Subject: chore(ci): expect signing by default --- .github/workflows/build.yml | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8840974..d5be3bc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -138,14 +138,12 @@ jobs: # Sign container - #- uses: sigstore/cosign-installer@v3.4.0 - # if: github.event_name != 'pull_request' - - #- name: Sign container image - # if: github.event_name != 'pull_request' - # run: | - # cosign sign -y --key env://COSIGN_PRIVATE_KEY ${{ steps.registry_case.outputs.lowercase }}/${{ steps.build_image.outputs.image }}@${TAGS} - # env: - # TAGS: ${{ steps.push.outputs.digest }} - # COSIGN_EXPERIMENTAL: false - # COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} + - name: Sign container image + uses: sigstore/cosign-installer@v3.4.0 + if: github.event_name != 'pull_request' + run: | + cosign sign -y --key env://COSIGN_PRIVATE_KEY ${{ steps.registry_case.outputs.lowercase }}/${{ steps.build_image.outputs.image }}@${TAGS} + env: + TAGS: ${{ steps.push.outputs.digest }} + COSIGN_EXPERIMENTAL: false + COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} -- cgit v1.2.3 From 44ec67ffc51ccc8d00dfecdcc27436973a149962 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Fri, 12 Apr 2024 17:03:10 -0500 Subject: docs: update may need to --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d34e94..df019a3 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Working knowledge in the following topics: ## Template -Select `Use this Template` and create a new repository from it. To enable the workflows, you will need to go the `Actions` tab of the new repository and click to enable workflows. +Select `Use this Template` and create a new repository from it. To enable the workflows, you may need to go the `Actions` tab of the new repository and click to enable workflows. ## Containerfile -- cgit v1.2.3 From bb583f32d0a4de4b7fb8e4f5d0d5645eca4a6745 Mon Sep 17 00:00:00 2001 From: Kyle Gospodnetich Date: Sun, 14 Apr 2024 22:27:36 -0700 Subject: fix: clarify ostree container commit must be used (#4) * fix: clarify ostree container commit must be used after each RUN * chore: use a bash script and simplify Containerfile --------- Co-authored-by: Benjamin Sherman --- Containerfile | 52 +++++++++++++--------------------------------------- build.sh | 27 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 39 deletions(-) create mode 100755 build.sh diff --git a/Containerfile b/Containerfile index da1dad9..b4cbcce 100644 --- a/Containerfile +++ b/Containerfile @@ -44,42 +44,16 @@ ARG FEDORA_VERSION="39" FROM ghcr.io/ublue-os/${SOURCE_IMAGE}${SOURCE_SUFFIX}:${FEDORA_VERSION} -### 3. PRE-MODIFICATIONS -## This section is meant for any modifications to the image before the main modifications are made. - -## this directory is needed to prevent failure with some RPM installs -RUN mkdir -p /var/lib/alternatives - - -### 4. MODIFICATIONS -## make modifications desired in your image and install packages here, a few examples follow - -#### Install packages - -# install a package from standard fedora repo or rpmfusion repo -# RPMfusion packages are available by default in ublue main images -# List of rpmfusion packages can be found here: -# https://mirrors.rpmfusion.org/mirrorlist?path=free/fedora/updates/39/x86_64/repoview/index.html&protocol=https&redirect=1 -RUN rpm-ostree install screen -# example package from rpmfusion -#RUN rpm-ostree install vlc - -#### Installation of static binaries - -# static binaries can sometimes by added using a COPY directive like these below. -COPY --from=cgr.dev/chainguard/kubectl:latest /usr/bin/kubectl /usr/bin/kubectl -#COPY --from=docker.io/docker/compose-bin:latest /docker-compose /usr/bin/docker-compose - -#### Change to System Configuration Files - -# modify default timeouts on system to prevent slow reboots from services that won't stop -RUN sed -i 's/#DefaultTimeoutStopSec.*/DefaultTimeoutStopSec=15s/' /etc/systemd/user.conf && \ - sed -i 's/#DefaultTimeoutStopSec.*/DefaultTimeoutStopSec=15s/' /etc/systemd/system.conf - - -### 5. POST-MODIFICATIONS -## these commands leave the image in a clean state after local modifications -RUN rm -rf /tmp/* /var/* && \ - ostree container commit && \ - mkdir -p /tmp /var/tmp && \ - chmod 1777 /tmp /var/tmp +### 3. MODIFICATIONS +## make modifications desired in your image and install packages by modifying the build.sh script +## the following RUN directive does all the things required to run "build.sh" as recommended. + +COPY build.sh /tmp/build.sh + +RUN mkdir -p /var/lib/alternatives && \ + /tmp/build.sh && \ + ostree container commit +## NOTES: +# - /var/lib/alternatives is required to prevent failure with some RPM installs +# - All RUN commands must end with ostree container commit +# see: https://coreos.github.io/rpm-ostree/container/#using-ostree-container-commit diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..d5fb95d --- /dev/null +++ b/build.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +set -ouex pipefail + +RELEASE="$(rpm -E %fedora)" + + +### Install packages + +# Packages can be installed from any enabled yum repo on the image. +# RPMfusion repos are available by default in ublue main images +# List of rpmfusion packages can be found here: +# https://mirrors.rpmfusion.org/mirrorlist?path=free/fedora/updates/39/x86_64/repoview/index.html&protocol=https&redirect=1 + +# this installs a package from fedora repos +rpm-ostree install screen + +# this would install a package from rpmfusion +#RUN rpm-ostree install vlc + + + +#### Change to System Configuration Files + +# this example modifies default timeouts to prevent slow reboots from services that won't stop +sed -i 's/#DefaultTimeoutStopSec.*/DefaultTimeoutStopSec=15s/' /etc/systemd/user.conf +sed -i 's/#DefaultTimeoutStopSec.*/DefaultTimeoutStopSec=15s/' /etc/systemd/system.conf -- cgit v1.2.3 From 13e83d301dacbab7d7fef73022b4c20caf7f6335 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Mon, 22 Apr 2024 13:48:20 -0500 Subject: fix(ci): split cosign steps (#6) A step can't have both "uses" and "run" so the cosign step needed to be split. --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d5be3bc..d41d98d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -137,9 +137,10 @@ jobs: # to consume. For more details, review the image signing section of the README. # Sign container + - uses: sigstore/cosign-installer@v3.4.0 + if: github.event_name != 'pull_request' - name: Sign container image - uses: sigstore/cosign-installer@v3.4.0 if: github.event_name != 'pull_request' run: | cosign sign -y --key env://COSIGN_PRIVATE_KEY ${{ steps.registry_case.outputs.lowercase }}/${{ steps.build_image.outputs.image }}@${TAGS} -- cgit v1.2.3 From 7427e32030ddd8edbc336c4b8f251a0de17f3e22 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Mon, 22 Apr 2024 23:05:49 -0500 Subject: refactor: use repo name as default image name (#7) Also makes the source image's tag easier to understand in the Containerfile. --- .github/workflows/build.yml | 4 ++-- Containerfile | 6 +++--- README.md | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d41d98d..f7cc31b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,8 +14,8 @@ on: workflow_dispatch: env: - MY_IMAGE_NAME: "ublue-custom" # the name of the image produced by this build - MY_IMAGE_DESC: "My Customized Universal Blue System Image" + MY_IMAGE_NAME: "${{ github.event.repository.name }}" # the name of the image produced by this build, matches repo names + MY_IMAGE_DESC: "My Customized Universal Blue Image" IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit jobs: diff --git a/Containerfile b/Containerfile index b4cbcce..5d08ad5 100644 --- a/Containerfile +++ b/Containerfile @@ -35,13 +35,13 @@ ARG SOURCE_IMAGE="silverblue" # - (and the above with testing rather than stable) ARG SOURCE_SUFFIX="-main" -## FEDORA_VERSION arg must be a version built by ublue: eg, 39 or 40 -ARG FEDORA_VERSION="39" +## SOURCE_TAG arg must be a version built for the specific image: eg, 39, 40, gts, latest +ARG SOURCE_TAG="latest" ### 2. SOURCE IMAGE ## this is a standard Containerfile FROM using the build ARGs above to select the right upstream image -FROM ghcr.io/ublue-os/${SOURCE_IMAGE}${SOURCE_SUFFIX}:${FEDORA_VERSION} +FROM ghcr.io/ublue-os/${SOURCE_IMAGE}${SOURCE_SUFFIX}:${SOURCE_TAG} ### 3. MODIFICATIONS diff --git a/README.md b/README.md index df019a3..261102c 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ This file defines the operations used to customize the selected image. It contai ### build.yml -This workflow creates your custom OCI image and publishes it to the Github Container Registry (GHCR). +This 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. #### Container Signing -- cgit v1.2.3 From b1e074e9118e268e8c13b6c972159a0313d444d4 Mon Sep 17 00:00:00 2001 From: Noel Miller <4983138+noelmiller@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:52:34 -0500 Subject: fix: use a working example (#13) Fedora 40 broke the example for editing systemd configuration behavior. Decided to use a simpler example. --- build.sh | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/build.sh b/build.sh index d5fb95d..ed25b26 100755 --- a/build.sh +++ b/build.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash set -ouex pipefail @@ -18,10 +18,6 @@ rpm-ostree install screen # this would install a package from rpmfusion #RUN rpm-ostree install vlc +#### Example for enabling a System Unit File - -#### Change to System Configuration Files - -# this example modifies default timeouts to prevent slow reboots from services that won't stop -sed -i 's/#DefaultTimeoutStopSec.*/DefaultTimeoutStopSec=15s/' /etc/systemd/user.conf -sed -i 's/#DefaultTimeoutStopSec.*/DefaultTimeoutStopSec=15s/' /etc/systemd/system.conf +systemctl enable podman.socket -- cgit v1.2.3 From 2cae75d77d678cd5a2c9300347143bcf9fedc1ba Mon Sep 17 00:00:00 2001 From: Daniel Yrovas Date: Wed, 24 Apr 2024 04:54:19 +1000 Subject: feat: ignore cosign.key (#8) --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2f01194 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +cosign.key -- cgit v1.2.3 From b7a13fbbaaaea89248f2819255b9903faf8bd840 Mon Sep 17 00:00:00 2001 From: Marcin Jahn <10273406+marcinjahn@users.noreply.github.com> Date: Tue, 23 Apr 2024 20:56:28 +0200 Subject: style: Remove RUN from commented command (#9) Co-authored-by: Noel Miller <4983138+noelmiller@users.noreply.github.com> --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index ed25b26..0ca1678 100755 --- a/build.sh +++ b/build.sh @@ -16,7 +16,7 @@ RELEASE="$(rpm -E %fedora)" rpm-ostree install screen # this would install a package from rpmfusion -#RUN rpm-ostree install vlc +# rpm-ostree install vlc #### Example for enabling a System Unit File -- cgit v1.2.3 From be9a9d9fd02278726cd43d9ac118ef874df307e9 Mon Sep 17 00:00:00 2001 From: Marcin Jahn <10273406+marcinjahn@users.noreply.github.com> Date: Tue, 23 Apr 2024 20:58:01 +0200 Subject: chore: update Node 16 actions to latest versions (#11) Co-authored-by: Benjamin Sherman Co-authored-by: Noel Miller <4983138+noelmiller@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f7cc31b..5daee78 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,7 +31,7 @@ jobs: steps: # Checkout push-to-registry action GitHub repository - name: Checkout Push to Registry action - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Generate tags id: generate-tags @@ -75,7 +75,7 @@ jobs: # Build metadata - name: Image Metadata - uses: docker/metadata-action@v4 + uses: docker/metadata-action@v5 id: meta with: images: | -- cgit v1.2.3 From e733ce4570a2c64b7b56851d07aec49881f02f14 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Tue, 23 Apr 2024 16:50:38 -0500 Subject: chore: add dependabot (#14) --- .github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..92c44a8 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" -- cgit v1.2.3 From 0c3303ed645339f615b07b48d5ed0cd33fd79543 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:00:30 -0500 Subject: chore(deps): bump ASzc/change-string-case-action from 5 to 6 (#17) Bumps [ASzc/change-string-case-action](https://github.com/aszc/change-string-case-action) from 5 to 6. - [Release notes](https://github.com/aszc/change-string-case-action/releases) - [Commits](https://github.com/aszc/change-string-case-action/compare/v5...v6) --- updated-dependencies: - dependency-name: ASzc/change-string-case-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5daee78..55e56a1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -105,7 +105,7 @@ jobs: # https://github.com/macbre/push-to-ghcr/issues/12 - name: Lowercase Registry id: registry_case - uses: ASzc/change-string-case-action@v5 + uses: ASzc/change-string-case-action@v6 with: string: ${{ env.IMAGE_REGISTRY }} -- cgit v1.2.3 From 856626e92a3d8d5b3974ebcc10e2d44be625d1ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:00:41 -0500 Subject: chore(deps): bump docker/login-action from 2 to 3 (#16) Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 55e56a1..888926c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -110,7 +110,7 @@ jobs: string: ${{ env.IMAGE_REGISTRY }} - name: Login to GitHub Container Registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} -- cgit v1.2.3 From 0fd1b1f35d094a809fd4f73e6dde3cbb53839fcb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:02:52 -0500 Subject: chore(deps): bump sigstore/cosign-installer from 3.4.0 to 3.5.0 (#15) Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 3.4.0 to 3.5.0. - [Release notes](https://github.com/sigstore/cosign-installer/releases) - [Commits](https://github.com/sigstore/cosign-installer/compare/v3.4.0...v3.5.0) --- updated-dependencies: - dependency-name: sigstore/cosign-installer dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 888926c..8ea733a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -137,7 +137,7 @@ jobs: # to consume. For more details, review the image signing section of the README. # Sign container - - uses: sigstore/cosign-installer@v3.4.0 + - uses: sigstore/cosign-installer@v3.5.0 if: github.event_name != 'pull_request' - name: Sign container image -- cgit v1.2.3 From ca0c14e5f2808f5ca93a01c0b62b36b2af4e3a8a Mon Sep 17 00:00:00 2001 From: Noel Miller <4983138+noelmiller@users.noreply.github.com> Date: Tue, 30 Apr 2024 15:45:59 -0500 Subject: chore: Update README.md (#19) Remove example that no longer exists. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 261102c..40fe917 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,6 @@ This file defines the operations used to customize the selected image. It contai - change the upstream from which the custom image is derived - add additional RPM packages - add binaries as a layer from other images -- modify system files (like /etc/systemd/system.conf) ## Workflows -- cgit v1.2.3 From 93a8118920a0e7fb088e2fd07a9cdf370fa9a0e9 Mon Sep 17 00:00:00 2001 From: Kyle Gospodnetich Date: Wed, 26 Jun 2024 19:28:49 -0700 Subject: feat: Maximize build space (#22) Required to build Bazzite images --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8ea733a..4f8e6d5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,6 +33,9 @@ jobs: - name: Checkout Push to Registry action uses: actions/checkout@v4 + - name: Maximize build space + uses: ublue-os/remove-unwanted-software@v7 + - name: Generate tags id: generate-tags shell: bash -- cgit v1.2.3 From 7c5aab2454e3c4f5c24373e352de53f147ba945d Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Mon, 12 Aug 2024 17:29:11 -0400 Subject: chore(ci): explicitly use ubuntu 24.04 (#28) Avoids the tar bug --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4f8e6d5..73acdd1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ env: jobs: build_push: name: Build and push image - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 permissions: contents: read -- cgit v1.2.3 From 6f80cc86137d78c9d231c67c64d856a40526a834 Mon Sep 17 00:00:00 2001 From: Robin Avery Date: Sun, 1 Sep 2024 07:12:39 -0400 Subject: style: fix wording in build.yml comment (#29) --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 73acdd1..3a979f3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -134,8 +134,8 @@ jobs: extra-args: | --disable-content-trust - # This section is optional and only needs to be enabled in you plan on distributing - # your project to others to consume. You will need to create a public and private key + # 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. -- cgit v1.2.3 From 7aa4737dfa685bf300bc9da844929ed045620485 Mon Sep 17 00:00:00 2001 From: m2 <69128853+m2Giles@users.noreply.github.com> Date: Tue, 19 Nov 2024 17:12:06 -0500 Subject: feat: Add examples of image-template to README (#37) * feat: Add examples of image-template to README * include BK's * Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 40fe917..bfb9e86 100644 --- a/README.md +++ b/README.md @@ -79,3 +79,8 @@ This provides users a method of verifying the image. ``` 4. Commit the `cosign.pub` file into your git repository + +### Examples +- [m2os](https://github.com/m2giles/m2os) +- [bos](https://github.com/bsherman/bos) +- [homer](https://github.com/bketelsen/homer/) -- cgit v1.2.3 From 45dad42de4c0fbcf3941bf455dc055427e976053 Mon Sep 17 00:00:00 2001 From: XLion Date: Wed, 27 Nov 2024 03:18:22 +0800 Subject: feat(ci): buildah: del `disable-content-trust`, enable zstd compression; bump sigstore/cosign-installer to 3.7.0 (#39) --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3a979f3..a61ef2d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -132,7 +132,7 @@ jobs: username: ${{ env.REGISTRY_USER }} password: ${{ env.REGISTRY_PASSWORD }} extra-args: | - --disable-content-trust + --compression-format=zstd # 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 @@ -140,7 +140,7 @@ jobs: # to consume. For more details, review the image signing section of the README. # Sign container - - uses: sigstore/cosign-installer@v3.5.0 + - uses: sigstore/cosign-installer@v3.7.0 if: github.event_name != 'pull_request' - name: Sign container image -- cgit v1.2.3 From 90c3f2c60a127e440e94d621e65fb8aee14dcc92 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Mon, 2 Dec 2024 22:52:48 -0500 Subject: feat(ci): add concurrency (#38) This makes it so that inprogress builds are cancelled when you make a new push. Matches the rest of ublue. --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a61ef2d..b6d3598 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,6 +18,10 @@ env: MY_IMAGE_DESC: "My Customized Universal Blue Image" IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }}-${{ inputs.brand_name}}-${{ inputs.stream_name }} + cancel-in-progress: true + jobs: build_push: name: Build and push image -- cgit v1.2.3 From 3822e1626b0995f75a524b2075b700459fa82a9b Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Sun, 29 Dec 2024 12:52:59 -0500 Subject: Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bfb9e86..7c86af5 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ This provides users a method of verifying the image. gh secret set SIGNING_SECRET < cosign.key ``` -4. Commit the `cosign.pub` file into your git repository +4. Commit the `cosign.pub` file to the root of your git repository. ### Examples - [m2os](https://github.com/m2giles/m2os) -- cgit v1.2.3 From 8eabfa6df1ef05ac67f12b22188adcca6ae1fc9d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 4 Jan 2025 16:40:31 -0500 Subject: Add renovate.json (#42) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- renovate.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 renovate.json diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..5db72dd --- /dev/null +++ b/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ] +} -- cgit v1.2.3 From 2c954ab4a89496bde0829000e2041dada4c131a5 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Sat, 4 Jan 2025 16:49:50 -0500 Subject: feat: simplify template (#44) --- Containerfile | 65 ++++++++++++----------------------------------------------- 1 file changed, 13 insertions(+), 52 deletions(-) diff --git a/Containerfile b/Containerfile index 5d08ad5..c30c336 100644 --- a/Containerfile +++ b/Containerfile @@ -1,50 +1,15 @@ -## 1. BUILD ARGS -# These allow changing the produced image by passing different build args to adjust -# the source from which your image is built. -# Build args can be provided on the commandline when building locally with: -# podman build -f Containerfile --build-arg FEDORA_VERSION=40 -t local-image - -# SOURCE_IMAGE arg can be anything from ublue upstream which matches your desired version: -# See list here: https://github.com/orgs/ublue-os/packages?repo_name=main -# - "silverblue" -# - "kinoite" -# - "sericea" -# - "onyx" -# - "lazurite" -# - "vauxite" -# - "base" -# -# "aurora", "bazzite", "bluefin" or "ucore" may also be used but have different suffixes. -ARG SOURCE_IMAGE="silverblue" - -## SOURCE_SUFFIX arg should include a hyphen and the appropriate suffix name -# These examples all work for silverblue/kinoite/sericea/onyx/lazurite/vauxite/base -# - "-main" -# - "-nvidia" -# - "-asus" -# - "-asus-nvidia" -# - "-surface" -# - "-surface-nvidia" -# -# aurora, bazzite and bluefin each have unique suffixes. Please check the specific image. -# ucore has the following possible suffixes -# - stable -# - stable-nvidia -# - stable-zfs -# - stable-nvidia-zfs -# - (and the above with testing rather than stable) -ARG SOURCE_SUFFIX="-main" - -## SOURCE_TAG arg must be a version built for the specific image: eg, 39, 40, gts, latest -ARG SOURCE_TAG="latest" - - -### 2. SOURCE IMAGE -## this is a standard Containerfile FROM using the build ARGs above to select the right upstream image -FROM ghcr.io/ublue-os/${SOURCE_IMAGE}${SOURCE_SUFFIX}:${SOURCE_TAG} - - -### 3. MODIFICATIONS +FROM ghcr.io/ublue-os/ublue-os/silverblue-main:latest + +## Other possible base images include: +# FROM ghcr.io/ublue-os/bazzite:stable +# FROM ghcr.io/ublue-os/bluefin-nvidia: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 +# CentOS base images: quay.io/centos-bootc/centos-bootc:stream10 + +### MODIFICATIONS ## make modifications desired in your image and install packages by modifying the build.sh script ## the following RUN directive does all the things required to run "build.sh" as recommended. @@ -52,8 +17,4 @@ COPY build.sh /tmp/build.sh RUN mkdir -p /var/lib/alternatives && \ /tmp/build.sh && \ - ostree container commit -## NOTES: -# - /var/lib/alternatives is required to prevent failure with some RPM installs -# - All RUN commands must end with ostree container commit -# see: https://coreos.github.io/rpm-ostree/container/#using-ostree-container-commit + ostree container lint -- cgit v1.2.3 From 6f5b0690232644b307538d94fea8fa36d98578f4 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Sat, 4 Jan 2025 16:49:59 -0500 Subject: fix: update installation command (#43) --- build.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/build.sh b/build.sh index 0ca1678..f0a7fce 100755 --- a/build.sh +++ b/build.sh @@ -2,9 +2,6 @@ set -ouex pipefail -RELEASE="$(rpm -E %fedora)" - - ### Install packages # Packages can be installed from any enabled yum repo on the image. @@ -13,7 +10,7 @@ RELEASE="$(rpm -E %fedora)" # https://mirrors.rpmfusion.org/mirrorlist?path=free/fedora/updates/39/x86_64/repoview/index.html&protocol=https&redirect=1 # this installs a package from fedora repos -rpm-ostree install screen +dnf install -y tmux # this would install a package from rpmfusion # rpm-ostree install vlc -- cgit v1.2.3 From 48f1ce23d72dc6d64664ec15d97d66ea6dd23a18 Mon Sep 17 00:00:00 2001 From: Tulip Blossom Date: Sat, 4 Jan 2025 18:54:57 -0300 Subject: chore: add ostree container commit there and fix bootc typo (#45) --- Containerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Containerfile b/Containerfile index c30c336..94354eb 100644 --- a/Containerfile +++ b/Containerfile @@ -17,4 +17,6 @@ COPY build.sh /tmp/build.sh RUN mkdir -p /var/lib/alternatives && \ /tmp/build.sh && \ - ostree container lint + ostree container commit && \ + bootc container lint + -- cgit v1.2.3 From f4dd8cb33d6a7876da2deb9d810ed5febcdb2edc Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Sat, 4 Jan 2025 16:55:09 -0500 Subject: docs: update readme (#46) --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7c86af5..e0a2303 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,9 @@ Working knowledge in the following topics: - Containers - https://www.youtube.com/watch?v=SnSH8Ht3MIc - https://www.mankier.com/5/Containerfile -- rpm-ostree - - https://coreos.github.io/rpm-ostree/container/ +- bootc + - https://containers.github.io/bootc/ + - https://github.com/containers/bootc/discussions - Forum for bootc, this is probably the best place to ask questions! - Fedora Silverblue (and other Fedora Atomic variants) - https://docs.fedoraproject.org/en-US/fedora-silverblue/ - Github Workflows -- cgit v1.2.3 From 301dcd61f6c9b115c53fb937b36b21f28e7f847d Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Sat, 4 Jan 2025 17:12:41 -0500 Subject: Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e0a2303..e5ee449 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ This repository is meant to be a template for building your own custom Universal This template includes a Containerfile and a Github workflow for building the container image. As soon as the workflow is enabled in your repository, it will build the container image and push it to the Github Container Registry. +# Community + +- [**bootc discussion forums**](https://github.com/containers/bootc/discussions) - Nothing in this template is ublue specific, the upstream bootc project has a discussions forum where custom image builders can hang out and ask questions. + # Prerequisites Working knowledge in the following topics: @@ -21,7 +25,6 @@ Working knowledge in the following topics: - https://www.mankier.com/5/Containerfile - bootc - https://containers.github.io/bootc/ - - https://github.com/containers/bootc/discussions - Forum for bootc, this is probably the best place to ask questions! - Fedora Silverblue (and other Fedora Atomic variants) - https://docs.fedoraproject.org/en-US/fedora-silverblue/ - Github Workflows -- cgit v1.2.3 From 3390db95f4c8ac2e4a759a9940c0e372e9ba11d1 Mon Sep 17 00:00:00 2001 From: Tulip Blossom Date: Sun, 5 Jan 2025 12:33:03 -0300 Subject: feat: add artifacthub metadata by default and WIP README (#48) --- .github/renovate.json5 | 6 ++ .github/workflows/build.yml | 152 +++++++++++++++++++------------------------- README.md | 6 ++ artifacthub-repo.yml | 8 +++ renovate.json | 6 -- 5 files changed, 84 insertions(+), 94 deletions(-) create mode 100644 .github/renovate.json5 create mode 100644 artifacthub-repo.yml delete mode 100644 renovate.json diff --git a/.github/renovate.json5 b/.github/renovate.json5 new file mode 100644 index 0000000..5db72dd --- /dev/null +++ b/.github/renovate.json5 @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ] +} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b6d3598..e4c7ea1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,5 @@ --- -name: build-ublue-custom +name: Build Custom Image on: pull_request: branches: @@ -17,6 +17,7 @@ env: MY_IMAGE_NAME: "${{ github.event.repository.name }}" # the name of the image produced by this build, matches repo names MY_IMAGE_DESC: "My Customized Universal Blue Image" IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit + ARTIFACTHUB_LOGO_URL: "https://avatars.githubusercontent.com/u/120078124?s=200&v=4" # You should put your own image here so that you get a fancy profile image on https://artifacthub.io/! concurrency: group: ${{ github.workflow }}-${{ github.ref || github.run_id }}-${{ inputs.brand_name}}-${{ inputs.stream_name }} @@ -33,67 +34,52 @@ jobs: id-token: write steps: - # Checkout push-to-registry action GitHub repository - - name: Checkout Push to Registry action - uses: actions/checkout@v4 - - - name: Maximize build space - uses: ublue-os/remove-unwanted-software@v7 - - - name: Generate tags - id: generate-tags - shell: bash + # These stage versions are pinned by https://github.com/renovatebot/renovate + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Get current date + id: date run: | - # Generate a timestamp for creating an image version history - TIMESTAMP="$(date +%Y%m%d)" - COMMIT_TAGS=() - BUILD_TAGS=() - - # Have tags for tracking builds during pull request - SHA_SHORT="${GITHUB_SHA::7}" - COMMIT_TAGS+=("pr-${{ github.event.number }}") - COMMIT_TAGS+=("${SHA_SHORT}") - - # Append matching timestamp tags to keep a version history - for TAG in "${BUILD_TAGS[@]}"; do - BUILD_TAGS+=("${TAG}-${TIMESTAMP}") - done - - BUILD_TAGS+=("${TIMESTAMP}") - BUILD_TAGS+=("latest") - - if [[ "${{ github.event_name }}" == "pull_request" ]]; then - echo "Generated the following commit tags: " - for TAG in "${COMMIT_TAGS[@]}"; do - echo "${TAG}" - done - - alias_tags=("${COMMIT_TAGS[@]}") - else - alias_tags=("${BUILD_TAGS[@]}") - fi - - echo "Generated the following build tags: " - for TAG in "${BUILD_TAGS[@]}"; do - echo "${TAG}" - done - - echo "alias_tags=${alias_tags[*]}" >> $GITHUB_OUTPUT - - # Build metadata + # 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@v5 - id: meta + uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5 + id: metadata with: - images: | - ${{ env.MY_IMAGE_NAME }} - + # This generates all the tags for your image, you can add custom tags here too! + # By default, it should generate "latest" and "latest.(date here)". + tags: | + type=raw,value=latest + type=raw,value=latest.{{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 }}/main/README.md - org.opencontainers.image.description=${{ env.MY_IMAGE_DESC }} - org.opencontainers.image.title=${{ env.MY_IMAGE_NAME }} + io.artifacthub.package.readme-url=https://raw.githubusercontent.com/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}/refs/heads/main/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 }}/refs/heads/main/README.md + org.opencontainers.image.source=https://github.com/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}/blob/main/Containerfile + org.opencontainers.image.title=${{ env.IMAGE_NAME }} + org.opencontainers.image.url=https://github.com/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} + org.opencontainers.image.vendor=${{ github.repository_owner }} + org.opencontainers.image.version=latest + io.artifacthub.package.deprecated=false + io.artifacthub.package.keywords=bootc,ublue,universal-blue + io.artifacthub.package.license=Apache-2.0 + io.artifacthub.package.logo-url=${{ env.ARTIFACTHUB_LOGO_URL }} + io.artifacthub.package.prerelease=false + containers.bootc=1 + sep-tags: " " + sep-annotations: " " - # Build image using Buildah action - name: Build Image id: build_image uses: redhat-actions/buildah-build@v2 @@ -102,55 +88,45 @@ jobs: ./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.MY_IMAGE_NAME }} - tags: | - ${{ steps.generate-tags.outputs.alias_tags }} - labels: ${{ steps.meta.outputs.labels }} + image: ${{ env.IMAGE_NAME }} + tags: ${{ steps.metadata.outputs.tags }} + labels: ${{ steps.metadata.outputs.labels }} oci: false - # Workaround bug where capital letters in your GitHub username make it impossible to push to GHCR. - # https://github.com/macbre/push-to-ghcr/issues/12 - - name: Lowercase Registry - id: registry_case - uses: ASzc/change-string-case-action@v6 - with: - string: ${{ env.IMAGE_REGISTRY }} - + # 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 - name: Login to GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3 + if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Push Image to GHCR - uses: redhat-actions/push-to-registry@v2 + - 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 - env: - REGISTRY_USER: ${{ github.actor }} - REGISTRY_PASSWORD: ${{ github.token }} with: - image: ${{ steps.build_image.outputs.image }} - tags: ${{ steps.build_image.outputs.tags }} - registry: ${{ steps.registry_case.outputs.lowercase }} - username: ${{ env.REGISTRY_USER }} - password: ${{ env.REGISTRY_PASSWORD }} - extra-args: | - --compression-format=zstd + registry: ${{ env.IMAGE_REGISTRY }} + image: ${{ env.IMAGE_NAME }} + tags: ${{ steps.metadata.outputs.tags }} # 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. - - # Sign container - - uses: sigstore/cosign-installer@v3.7.0 - if: github.event_name != 'pull_request' + - name: Install Cosign + uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 + if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) - name: Sign container image - if: github.event_name != 'pull_request' + if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) run: | - cosign sign -y --key env://COSIGN_PRIVATE_KEY ${{ steps.registry_case.outputs.lowercase }}/${{ steps.build_image.outputs.image }}@${TAGS} + IMAGE_FULL="${{ env.IMAGE_REGISTRY }}/${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 diff --git a/README.md b/README.md index e5ee449..41082bc 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,12 @@ This template includes a Containerfile and a Github workflow for building the co - [**bootc discussion forums**](https://github.com/containers/bootc/discussions) - Nothing in this template is ublue specific, the upstream bootc project has a discussions forum where custom image builders can hang out and ask questions. +## ArtifactHub + +ArtifactHub is - PLACEHOLDER + +- [**artifacthub universal blue index**](https://artifacthub.io/packages/search?ts_query_web=ublue&sort=relevance&page=1) + # Prerequisites Working knowledge in the following topics: diff --git a/artifacthub-repo.yml b/artifacthub-repo.yml new file mode 100644 index 0000000..beb393c --- /dev/null +++ b/artifacthub-repo.yml @@ -0,0 +1,8 @@ +# This file is completely optional, but if you want to index your image on https://artifacthub.io/ you can, by +# adding the Repository ID and your data there on `owners`. This makes it so we can all have a fancy index of all custom +# images. If you dont want to be on that, dont worry, this should not do anything by itself + +repositoryID: my-custom-id-here # Fill in with your own credentials +owners: # (optional, used to claim repository ownership) + - name: My Name + email: my_email@email.com diff --git a/renovate.json b/renovate.json deleted file mode 100644 index 5db72dd..0000000 --- a/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ] -} -- cgit v1.2.3 From b24fee8d379514aa1b78f711f6e538a5edb87966 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Sun, 5 Jan 2025 10:36:12 -0500 Subject: docs: add artifacthub to readme (#49) --- README.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/README.md b/README.md index 41082bc..4dc787e 100644 --- a/README.md +++ b/README.md @@ -15,12 +15,7 @@ This template includes a Containerfile and a Github workflow for building the co # Community - [**bootc discussion forums**](https://github.com/containers/bootc/discussions) - Nothing in this template is ublue specific, the upstream bootc project has a discussions forum where custom image builders can hang out and ask questions. - -## ArtifactHub - -ArtifactHub is - PLACEHOLDER - -- [**artifacthub universal blue index**](https://artifacthub.io/packages/search?ts_query_web=ublue&sort=relevance&page=1) +- Index your image on [artifacthub.io](https://artifacthub.io), use the `artifacthub-repo.yml` file at the root to verify yourself as the publisher. # Prerequisites -- cgit v1.2.3 From da39213f105e03dbe5296490c4b01c625f2d22df Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Sun, 5 Jan 2025 10:37:26 -0500 Subject: Update README.md (#50) --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 4dc787e..507b376 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,6 @@ This repository is meant to be a template for building your own custom Universal This template includes a Containerfile and a Github workflow for building the container image. As soon as the workflow is enabled in your repository, it will build the container image and push it to the Github Container Registry. -# Community - -- [**bootc discussion forums**](https://github.com/containers/bootc/discussions) - Nothing in this template is ublue specific, the upstream bootc project has a discussions forum where custom image builders can hang out and ask questions. -- Index your image on [artifacthub.io](https://artifacthub.io), use the `artifacthub-repo.yml` file at the root to verify yourself as the publisher. - # Prerequisites Working knowledge in the following topics: @@ -85,7 +80,13 @@ This provides users a method of verifying the image. 4. Commit the `cosign.pub` file to the root of your git repository. -### Examples +# Community + +- [**bootc discussion forums**](https://github.com/containers/bootc/discussions) - Nothing in this template is ublue specific, the upstream bootc project has a discussions forum where custom image builders can hang out and ask questions. +- Index your image on [artifacthub.io](https://artifacthub.io), use the `artifacthub-repo.yml` file at the root to verify yourself as the publisher. + +## Community Examples + - [m2os](https://github.com/m2giles/m2os) - [bos](https://github.com/bsherman/bos) - [homer](https://github.com/bketelsen/homer/) -- cgit v1.2.3 From 4fa1d41a49b8eb9e3964a3fb8d17d24c3049312f Mon Sep 17 00:00:00 2001 From: Tulip Blossom Date: Wed, 8 Jan 2025 21:14:57 -0300 Subject: chore: add rechunk and maximize-build-storage examples on the build workflow (#52) I believe these should be enabled by default, since they make builds a lot slower, but it is nice having some docs about it --- .github/workflows/build.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e4c7ea1..c12fb00 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,6 +37,12 @@ jobs: # These stage versions are pinned by https://github.com/renovatebot/renovate - name: Checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + # 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@517622d6452028f266b7ba4cc9a123b5f58a6b53 # v7 + # with: + # remove-codeql: true - name: Get current date id: date @@ -93,6 +99,30 @@ jobs: 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: hhd-dev/rechunk@f153348d8100c1f504dec435460a0d7baf11a9d2 # v1.1.1 + # with: + # rechunk: 'ghcr.io/hhd-dev/rechunk:v1.0.1' + # 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 + # 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 - name: Login to GitHub Container Registry -- cgit v1.2.3 From 93299922c7ff6ad495b9586e2d11499a1d122704 Mon Sep 17 00:00:00 2001 From: Tulip Blossom Date: Wed, 8 Jan 2025 21:15:28 -0300 Subject: fix: use IMAGE_NAME and IMAGE_DESC for variables + fix typo in containerfile (#51) --- .github/workflows/build.yml | 4 ++-- Containerfile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c12fb00..85eaf26 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,8 +14,8 @@ on: workflow_dispatch: env: - MY_IMAGE_NAME: "${{ github.event.repository.name }}" # the name of the image produced by this build, matches repo names - MY_IMAGE_DESC: "My Customized Universal Blue Image" + IMAGE_NAME: "${{ github.event.repository.name }}" # the name of the image produced by this build, matches repo names + IMAGE_DESC: "My Customized Universal Blue Image" IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit ARTIFACTHUB_LOGO_URL: "https://avatars.githubusercontent.com/u/120078124?s=200&v=4" # You should put your own image here so that you get a fancy profile image on https://artifacthub.io/! diff --git a/Containerfile b/Containerfile index 94354eb..fd30687 100644 --- a/Containerfile +++ b/Containerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/ublue-os/ublue-os/silverblue-main:latest +FROM ghcr.io/ublue-os/silverblue-main:latest ## Other possible base images include: # FROM ghcr.io/ublue-os/bazzite:stable -- cgit v1.2.3 From bc92a516af548351c038f10a6a4574740badfcd4 Mon Sep 17 00:00:00 2001 From: Tulip Blossom Date: Wed, 8 Jan 2025 21:15:48 -0300 Subject: feat: (re)add registry login to push to GHCR (#53) --- .github/workflows/build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 85eaf26..1fcf523 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -137,10 +137,15 @@ jobs: 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 + 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 }} # 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 -- cgit v1.2.3 From 8c6b00ffd80bf4542464a2415cce902d685e0fb5 Mon Sep 17 00:00:00 2001 From: Tulip Blossom Date: Wed, 8 Jan 2025 21:26:12 -0300 Subject: feat: add justfile pattern from M2's PRs to bluefin (#54) --- .gitignore | 1 + Justfile | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ image.toml | 3 + iso.toml | 19 ++++++ 4 files changed, 226 insertions(+) create mode 100644 Justfile create mode 100644 image.toml create mode 100644 iso.toml diff --git a/.gitignore b/.gitignore index 2f01194..bbc6166 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ cosign.key +_build_* diff --git a/Justfile b/Justfile new file mode 100644 index 0000000..6608d89 --- /dev/null +++ b/Justfile @@ -0,0 +1,203 @@ +export repo_organization := env("GITHUB_REPOSITORY_OWNER", "yourname") +export image_name := env("IMAGE_NAME", "yourimage") +export default_tag := env("DEFAULT_TAG", "latest") +export bib_image := env("BIB_IMAGE", "ghcr.io/osbuild/bootc-image-builder:latest") + +export SUDO_DISPLAY := if `if [ -n "${DISPLAY:-}" ] || [ -n "${WAYLAND_DISPLAY:-}" ]; then echo true; fi` == "true" { "true" } else { "false" } +export SUDOIF := if `id -u` == "0" { "" } else { if SUDO_DISPLAY == "true" { "sudo --askpass" } else { "sudo" } } +export PODMAN := if path_exists("/usr/bin/podman") == "true" { env("PODMAN", "/usr/bin/podman") } else { if path_exists("/usr/bin/docker") == "true" { env("PODMAN", "docker") } else { env("PODMAN", "exit 1 ; ") } } + +alias build-vm := build-qcow2 +alias rebuild-vm := rebuild-qcow2 +alias run-vm := run-vm-qcow2 + +[private] +default: + @just --list + +# Check Just Syntax +[group('Just')] +check: + #!/usr/bin/bash + find . -type f -name "*.just" | while read -r file; do + echo "Checking syntax: $file" + just --unstable --fmt --check -f $file + done + echo "Checking syntax: Justfile" + just --unstable --fmt --check -f Justfile + +# Fix Just Syntax +[group('Just')] +fix: + #!/usr/bin/bash + find . -type f -name "*.just" | while read -r file; do + echo "Checking syntax: $file" + just --unstable --fmt -f $file + done + echo "Checking syntax: Justfile" + just --unstable --fmt -f Justfile || { exit 1; } + +# Clean Repo +[group('Utility')] +clean: + #!/usr/bin/bash + set -eoux pipefail + touch _build + find *_build* -exec rm -rf {} \; + rm -f previous.manifest.json + rm -f changelog.md + rm -f output.env + +# Sudo Clean Repo +[group('Utility')] +[private] +sudo-clean: + ${SUDOIF} just clean + +build $target_image=image_name $tag=default_tag: + #!/usr/bin/env bash + + # Get Version + ver="${tag}-$(date +%Y%m%d)" + + BUILD_ARGS=() + BUILD_ARGS+=("--build-arg" "IMAGE_NAME=${image_name}") + BUILD_ARGS+=("--build-arg" "IMAGE_VENDOR=${repo_organization}") + if [[ -z "$(git status -s)" ]]; then + BUILD_ARGS+=("--build-arg" "SHA_HEAD_SHORT=$(git rev-parse --short HEAD)") + fi + + ${PODMAN} build \ + "${BUILD_ARGS[@]}" \ + --pull=newer \ + --tag "${image_name}:${tag}" \ + . + +_rootful_load_image $target_image=image_name $tag=default_tag: + #!/usr/bin/bash + set -eoux pipefail + + if [[ -n "${SUDO_USER:-}" || "${UID}" -eq "0" ]]; then + echo "Already root or running under sudo, no need to load image from user ${PODMAN}." + exit 0 + fi + + set +e + resolved_tag=$(${PODMAN} inspect -t image "${target_image}:${tag}" | jq -r '.[].RepoTags.[0]') + return_code=$? + set -e + + if [[ $return_code -eq 0 ]]; then + # Load into Rootful ${PODMAN} + ID=$(${SUDOIF} ${PODMAN} images --filter reference="${target_image}:${tag}" --format "'{{ '{{.ID}}' }}'") + if [[ -z "$ID" ]]; then + COPYTMP=$(mktemp -p "${PWD}" -d -t _build_podman_scp.XXXXXXXXXX) + ${SUDOIF} TMPDIR=${COPYTMP} ${PODMAN} image scp ${UID}@localhost::"${target_image}:${tag}" root@localhost::"${target_image}:${tag}" + rm -rf "${COPYTMP}" + fi + else + # Make sure the image is present and/or up to date + ${SUDOIF} ${PODMAN} pull "${target_image}:${tag}" + fi + +_build-bib $target_image $tag $type $config: (_rootful_load_image target_image tag) + #!/usr/bin/env bash + set -euo pipefail + + mkdir -p "output" + + echo "Cleaning up previous build" + if [[ $type == iso ]]; then + sudo rm -rf "output/bootiso" || true + else + sudo rm -rf "output/${type}" || true + fi + + args="--type ${type}" + + if [[ $target_image == localhost/* ]]; then + args+=" --local" + fi + + sudo ${PODMAN} run \ + --rm \ + -it \ + --privileged \ + --pull=newer \ + --net=host \ + --security-opt label=type:unconfined_t \ + -v $(pwd)/${config}:/config.toml:ro \ + -v $(pwd)/output:/output \ + -v /var/lib/containers/storage:/var/lib/containers/storage \ + "${bib_image}" \ + ${args} \ + "${target_image}" + + sudo chown -R $USER:$USER output + +_rebuild-bib $target_image $tag $type $config: (build target_image tag) && (_build-bib target_image tag type config) + +[group('Build Virtual Machine Image')] +build-qcow2 $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "qcow2" "image.toml") + +[group('Build Virtual Machine Image')] +build-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "raw" "image.toml") + +[group('Build Virtual Machine Image')] +build-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "iso" "iso.toml") + +[group('Build Virtual Machine Image')] +rebuild-qcow2 $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "qcow2" "image.toml") + +[group('Build Virtual Machine Image')] +rebuild-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "raw" "image.toml") + +[group('Build Virtual Machine Image')] +rebuild-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "iso" "iso.toml") + +_run-vm $target_image $tag $type $config: + #!/usr/bin/bash + set -eoux pipefail + + image_file="output/${type}/disk.${type}" + + if [[ $type == iso ]]; then + image_file="output/bootiso/install.iso" + fi + + if [[ ! -f "${image_file}" ]]; then + just "build-${type}" "$target_image" "$tag" + fi + + # Determine which port to use + port=8006; + while grep -q :${port} <<< $(ss -tunalp); do + port=$(( port + 1 )) + done + echo "Using Port: ${port}" + echo "Connect to http://localhost:${port}" + run_args=() + run_args+=(--rm --privileged) + run_args+=(--pull=newer) + run_args+=(--publish "127.0.0.1:${port}:8006") + run_args+=(--env "CPU_CORES=4") + run_args+=(--env "RAM_SIZE=8G") + run_args+=(--env "DISK_SIZE=64G") + # run_args+=(--env "BOOT_MODE=windows_secure") + run_args+=(--env "TPM=Y") + run_args+=(--env "GPU=Y") + run_args+=(--device=/dev/kvm) + run_args+=(--volume "${PWD}/${image_file}":"/boot.${type}") + run_args+=(docker.io/qemux/qemu-docker) + ${PODMAN} run "${run_args[@]}" & + xdg-open http://localhost:${port} + fg "%${PODMAN}" + +[group('Run Virtual Machine')] +run-vm-qcow2 $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "qcow2" "image-builder.config.toml") + +[group('Run Virtual Machine')] +run-vm-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "raw" "image-builder.config.toml") + +[group('Run Virtual Machine')] +run-vm-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "iso" "image-builder-iso.config.toml") diff --git a/image.toml b/image.toml new file mode 100644 index 0000000..7478400 --- /dev/null +++ b/image.toml @@ -0,0 +1,3 @@ +[[customizations.filesystem]] +mountpoint = "/" +minsize = "20 GiB" diff --git a/iso.toml b/iso.toml new file mode 100644 index 0000000..1b3084d --- /dev/null +++ b/iso.toml @@ -0,0 +1,19 @@ +[customizations.installer.kickstart] +contents = """ +%post +bootc switch --mutate-in-place --transport registry ghcr.io/yourname/yourusername:latest +%end +""" + +[customizations.installer.modules] +enable = [ + "org.fedoraproject.Anaconda.Modules.Storage" +] +disable = [ + "org.fedoraproject.Anaconda.Modules.Network", + "org.fedoraproject.Anaconda.Modules.Security", + "org.fedoraproject.Anaconda.Modules.Services", + "org.fedoraproject.Anaconda.Modules.Users", + "org.fedoraproject.Anaconda.Modules.Subscription", + "org.fedoraproject.Anaconda.Modules.Timezone" +] -- cgit v1.2.3 From 51e4719366031bd3457231a65fa227fe62a03a42 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Wed, 8 Jan 2025 19:28:28 -0500 Subject: Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 507b376..bb784aa 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,12 @@ This file defines the operations used to customize the selected image. It contai - add additional RPM packages - add binaries as a layer from other images +## Building an ISO + +Modify `iso.toml` to point to your custom image before generating an ISO. + +- (Steps in progress) + ## Workflows ### build.yml -- cgit v1.2.3 From 8ce1cdb82a13e27e085e08b4c43af60af819b9ff Mon Sep 17 00:00:00 2001 From: Tulip Blossom Date: Wed, 8 Jan 2025 21:56:59 -0300 Subject: fix: incorrect URL for bib image on justfile (#55) --- Justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Justfile b/Justfile index 6608d89..f69b5a7 100644 --- a/Justfile +++ b/Justfile @@ -1,7 +1,7 @@ export repo_organization := env("GITHUB_REPOSITORY_OWNER", "yourname") export image_name := env("IMAGE_NAME", "yourimage") export default_tag := env("DEFAULT_TAG", "latest") -export bib_image := env("BIB_IMAGE", "ghcr.io/osbuild/bootc-image-builder:latest") +export bib_image := env("BIB_IMAGE", "quay.io/centos-bootc/bootc-image-builder:latest") export SUDO_DISPLAY := if `if [ -n "${DISPLAY:-}" ] || [ -n "${WAYLAND_DISPLAY:-}" ]; then echo true; fi` == "true" { "true" } else { "false" } export SUDOIF := if `id -u` == "0" { "" } else { if SUDO_DISPLAY == "true" { "sudo --askpass" } else { "sudo" } } -- cgit v1.2.3 From 45680135b80d1aaec012034a5f825407a05f26b9 Mon Sep 17 00:00:00 2001 From: Tulip Blossom Date: Sat, 11 Jan 2025 17:50:43 -0300 Subject: fix: registry-case action is still necessary (#56) --- .github/workflows/build.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1fcf523..0d2f144 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -133,6 +133,14 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + # Workaround bug where capital letters in your GitHub username make it impossible to push to GHCR. + # https://github.com/macbre/push-to-ghcr/issues/12 + - name: Lowercase Registry + id: registry_case + uses: ASzc/change-string-case-action@v6 + with: + string: ${{ env.IMAGE_REGISTRY }} + - 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) @@ -141,7 +149,7 @@ jobs: REGISTRY_USER: ${{ github.actor }} REGISTRY_PASSWORD: ${{ github.token }} with: - registry: ${{ env.IMAGE_REGISTRY }} + registry: ${{ steps.registry_case.outputs.lowercase }} image: ${{ env.IMAGE_NAME }} tags: ${{ steps.metadata.outputs.tags }} username: ${{ env.REGISTRY_USER }} -- cgit v1.2.3 From 4c20cc7a55e19707af7e9b598004d99f5b0580b7 Mon Sep 17 00:00:00 2001 From: Tulip Blossom Date: Sat, 11 Jan 2025 18:00:36 -0300 Subject: fix: signing also needs to be lowercase :sob: (#57) --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0d2f144..51d396d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -166,7 +166,7 @@ jobs: - name: Sign container image if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) run: | - IMAGE_FULL="${{ env.IMAGE_REGISTRY }}/${IMAGE_NAME}" + IMAGE_FULL="${{ steps.registry_case.outputs.lowercase }}/${IMAGE_NAME}" for tag in ${{ steps.metadata.outputs.tags }}; do cosign sign -y --key env://COSIGN_PRIVATE_KEY $IMAGE_FULL:$tag done -- cgit v1.2.3 From acf114c41649ca45b17b84fe884747c63ba24979 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Sat, 11 Jan 2025 19:25:40 -0500 Subject: feat: add copr example (#58) And remove duplicate rpm-ostree example. --- build.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index f0a7fce..27048e0 100755 --- a/build.sh +++ b/build.sh @@ -12,8 +12,12 @@ set -ouex pipefail # this installs a package from fedora repos dnf install -y tmux -# this would install a package from rpmfusion -# rpm-ostree install vlc +# Use a COPR Example: +# +# dnf5 -y copr enable ublue-os/staging +# dnf5 -y install package +# Disable COPRs so they don't end up enabled on the final image: +# dnf5 -y copr disable ublue-os/staging #### Example for enabling a System Unit File -- cgit v1.2.3 From f00f156e2cfaa45d2243104808edf551705d604c Mon Sep 17 00:00:00 2001 From: Cristian Torres <18661121+PrototypeActual@users.noreply.github.com> Date: Thu, 23 Jan 2025 22:46:11 -0500 Subject: Update build.yml (#61) Added lowering casing of image name should it be uppercased.Switched variables to grab lowercased image name. --- .github/workflows/build.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 51d396d..a8d7325 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -141,6 +141,12 @@ jobs: with: string: ${{ env.IMAGE_REGISTRY }} + - name: Lowercase Image + id: image_case + uses: ASzc/change-string-case-action@v6 + with: + string: ${{ env.IMAGE_NAME }} + - 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) @@ -150,7 +156,7 @@ jobs: REGISTRY_PASSWORD: ${{ github.token }} with: registry: ${{ steps.registry_case.outputs.lowercase }} - image: ${{ env.IMAGE_NAME }} + image: ${{ steps.image_case.outputs.lowercase }} tags: ${{ steps.metadata.outputs.tags }} username: ${{ env.REGISTRY_USER }} password: ${{ env.REGISTRY_PASSWORD }} @@ -166,7 +172,7 @@ jobs: - name: Sign container image if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) run: | - IMAGE_FULL="${{ steps.registry_case.outputs.lowercase }}/${IMAGE_NAME}" + IMAGE_FULL="${{ steps.registry_case.outputs.lowercase }}/${{ steps.image_case.outputs.lowercase }}" for tag in ${{ steps.metadata.outputs.tags }}; do cosign sign -y --key env://COSIGN_PRIVATE_KEY $IMAGE_FULL:$tag done -- cgit v1.2.3 From 14ce7531e76276d93ebaacf4ea0982cf31fe77a4 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Fri, 24 Jan 2025 09:00:35 -0500 Subject: Update artifacthub-repo.yml --- artifacthub-repo.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/artifacthub-repo.yml b/artifacthub-repo.yml index beb393c..c08d0b4 100644 --- a/artifacthub-repo.yml +++ b/artifacthub-repo.yml @@ -1,6 +1,6 @@ -# This file is completely optional, but if you want to index your image on https://artifacthub.io/ you can, by -# adding the Repository ID and your data there on `owners`. This makes it so we can all have a fancy index of all custom -# images. If you dont want to be on that, dont worry, this should not do anything by itself +# This file is completely optional, but if you want to index your image on https://artifacthub.io/ you can +# Sign up and add the Repository ID to the right field. Owners fields are optional. +# Examples: https://artifacthub.io/packages/search?ts_query_web=ublue&sort=relevance&page=1 repositoryID: my-custom-id-here # Fill in with your own credentials owners: # (optional, used to claim repository ownership) -- cgit v1.2.3 From e4f19b28a89d11e1cc794b91455c8d21188e6146 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Fri, 24 Jan 2025 09:04:53 -0500 Subject: docs: update README.md --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bb784aa..bc16c9d 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,15 @@ This repository is meant to be a template for building your own custom Universal - [Bluefin](https://projectbluefin.io/) - [uCore](https://projectucore.io/) - [main](https://github.com/ublue-os/main/) -- [hwe](https://github.com/ublue-os/hwe/) +- [hwe](https://github.com/ublue-os/hwe/) -This template includes a Containerfile and a Github workflow for building the container image. As soon as the workflow is enabled in your repository, it will build the container image and push it to the Github Container Registry. +or any other base image: + +- CentOS Stream 9: `quay.io/centos-bootc/centos-bootc:stream9` +- CentOS Stream 10 (in development): `quay.io/centos-bootc/centos-bootc:stream10` +- Fedora: `quay.io/fedora/fedora-bootc:41` + +This template includes a Containerfile and a Github workflow for building the container image, signing, and proper metadata to be listed on [artifacthub](https://artifacthub.io/). As soon as the workflow is enabled in your repository, it will build the container image and push it to the Github Container Registry. # Prerequisites -- cgit v1.2.3 From 8fbb97f4f73684143cbbb970e465ffef7fd703d4 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Fri, 24 Jan 2025 09:05:36 -0500 Subject: Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bc16c9d..492ee7b 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,11 @@ This repository is meant to be a template for building your own custom Universal - [main](https://github.com/ublue-os/main/) - [hwe](https://github.com/ublue-os/hwe/) -or any other base image: +or any other base image if you want to start from scratch: +- Fedora: `quay.io/fedora/fedora-bootc:41` - CentOS Stream 9: `quay.io/centos-bootc/centos-bootc:stream9` - CentOS Stream 10 (in development): `quay.io/centos-bootc/centos-bootc:stream10` -- Fedora: `quay.io/fedora/fedora-bootc:41` This template includes a Containerfile and a Github workflow for building the container image, signing, and proper metadata to be listed on [artifacthub](https://artifacthub.io/). As soon as the workflow is enabled in your repository, it will build the container image and push it to the Github Container Registry. -- cgit v1.2.3 From 624b60125dff950e2cbbd96cc1cf17b3f4c93a25 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Fri, 24 Jan 2025 09:33:11 -0500 Subject: docs: add discussion links --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 492ee7b..0cd1a5d 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ This provides users a method of verifying the image. # Community - [**bootc discussion forums**](https://github.com/containers/bootc/discussions) - Nothing in this template is ublue specific, the upstream bootc project has a discussions forum where custom image builders can hang out and ask questions. -- Index your image on [artifacthub.io](https://artifacthub.io), use the `artifacthub-repo.yml` file at the root to verify yourself as the publisher. +- Index your image on [artifacthub.io](https://artifacthub.io), use the `artifacthub-repo.yml` file at the root to verify yourself as the publisher. [Discussion thread](https://universal-blue.discourse.group/t/listing-your-custom-image-on-artifacthub/6446) ## Community Examples -- cgit v1.2.3 From e18196e1c914d29615628474aa81fcd0e2625c3e Mon Sep 17 00:00:00 2001 From: Tulip Blossom Date: Sun, 26 Jan 2025 12:44:41 -0300 Subject: fix: default btrfs filesystem for image (#62) * fix: ensure librepo is being used and default btrfs filesystem for image * fix --- Justfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Justfile b/Justfile index f69b5a7..d718b0a 100644 --- a/Justfile +++ b/Justfile @@ -130,6 +130,7 @@ _build-bib $target_image $tag $type $config: (_rootful_load_image target_image t -v $(pwd)/output:/output \ -v /var/lib/containers/storage:/var/lib/containers/storage \ "${bib_image}" \ + --rootfs btrfs \ ${args} \ "${target_image}" -- cgit v1.2.3 From 08ab0e0cd352b89645abf9c3013452c4d7dd8b7c Mon Sep 17 00:00:00 2001 From: Robert Sturla Date: Sun, 26 Jan 2025 16:42:34 +0000 Subject: fix: remove bootc container lint check (#63) This requires Composefs to be used, which we are not yet in a position to enable. --- Containerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Containerfile b/Containerfile index fd30687..67bd49c 100644 --- a/Containerfile +++ b/Containerfile @@ -17,6 +17,5 @@ COPY build.sh /tmp/build.sh RUN mkdir -p /var/lib/alternatives && \ /tmp/build.sh && \ - ostree container commit && \ - bootc container lint + ostree container commit -- cgit v1.2.3 From abd59c19e1fddbf69c8f6cccabc989e96cbe5ba5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 00:16:26 -0500 Subject: chore(deps): update sigstore/cosign-installer action to v3.8.0 (#66) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a8d7325..eea69bc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -166,7 +166,7 @@ jobs: # 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@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 + uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) - name: Sign container image -- cgit v1.2.3 From 099b25406e386cc2c59833fed611be31238e9afd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2025 09:03:51 -0500 Subject: chore(deps): update sigstore/cosign-installer action to v3.8.1 (#69) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eea69bc..591560c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -166,7 +166,7 @@ jobs: # 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@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0 + uses: sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) - name: Sign container image -- cgit v1.2.3 From 32fe0f14d688e3adc26a13da75773dfd8ba90f8b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 16:56:23 -0500 Subject: chore(deps): update docker/metadata-action digest to 902fa8e (#70) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 591560c..2be4bdf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,7 +56,7 @@ jobs: # 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@369eb591f429131d6889c46b94e711f089e6ca96 # v5 + uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5 id: metadata with: # This generates all the tags for your image, you can add custom tags here too! -- cgit v1.2.3 From aeec38abcfa8bdc44d812e7f0ec0cdab629007d5 Mon Sep 17 00:00:00 2001 From: Robert Sturla Date: Sat, 8 Mar 2025 23:36:56 +0000 Subject: fix: install packages via dnf5 (#74) --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 27048e0..f1e659a 100755 --- a/build.sh +++ b/build.sh @@ -10,7 +10,7 @@ set -ouex pipefail # https://mirrors.rpmfusion.org/mirrorlist?path=free/fedora/updates/39/x86_64/repoview/index.html&protocol=https&redirect=1 # this installs a package from fedora repos -dnf install -y tmux +dnf5 install -y tmux # Use a COPR Example: # -- cgit v1.2.3 From a60aca3dc764992cd66b0e8b3f929c32a98f997d Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Wed, 12 Mar 2025 01:32:44 -0400 Subject: Update README.md --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0cd1a5d..f5c2fb1 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,16 @@ This provides users a method of verifying the image. # Community - [**bootc discussion forums**](https://github.com/containers/bootc/discussions) - Nothing in this template is ublue specific, the upstream bootc project has a discussions forum where custom image builders can hang out and ask questions. -- Index your image on [artifacthub.io](https://artifacthub.io), use the `artifacthub-repo.yml` file at the root to verify yourself as the publisher. [Discussion thread](https://universal-blue.discourse.group/t/listing-your-custom-image-on-artifacthub/6446) + +## Artifacthub + +This template comes with the necessary tooling to index your image on [artifacthub.io](https://artifacthub.io), use the `artifacthub-repo.yml` file at the root to verify yourself as the publisher. This is important to you for a few reasons: + +- The value of artifacthub is it's one place for people to index their custom images, and since we depend on each other to learn, it helps grow the community. +- You get to see your pet project listed with the other cool projects in Cloud Native. +- Since the site puts your README front and center, it's a good way to learn how to write a good README, learn some marketing, finding your audience, etc. + +[Discussion thread](https://universal-blue.discourse.group/t/listing-your-custom-image-on-artifacthub/6446) ## Community Examples -- cgit v1.2.3 From f44a904f1d1f5d8a384b7acf0f4ce004e2d751cd Mon Sep 17 00:00:00 2001 From: James Reilly Date: Wed, 12 Mar 2025 22:07:17 +0530 Subject: Fix: Update Justfile (#76) * Fix: Update Justfile Updated to match the Bluefin LTS one. Stripped the iso customizations stuff * fix: update Containerfile ublue-os/silverblue-main:latest shouldn't be the default --- Containerfile | 4 +- Justfile | 205 +++++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 169 insertions(+), 40 deletions(-) diff --git a/Containerfile b/Containerfile index 67bd49c..80b04aa 100644 --- a/Containerfile +++ b/Containerfile @@ -1,7 +1,7 @@ -FROM ghcr.io/ublue-os/silverblue-main:latest +FROM ghcr.io/ublue-os/bazzite:stable ## Other possible base images include: -# FROM ghcr.io/ublue-os/bazzite:stable +# FROM ghcr.io/ublue-os/bazzite:latest # FROM ghcr.io/ublue-os/bluefin-nvidia:stable # # ... and so on, here are more base images diff --git a/Justfile b/Justfile index d718b0a..4315601 100644 --- a/Justfile +++ b/Justfile @@ -1,12 +1,10 @@ export repo_organization := env("GITHUB_REPOSITORY_OWNER", "yourname") export image_name := env("IMAGE_NAME", "yourimage") +export centos_version := env("CENTOS_VERSION", "stream10") +export fedora_version := env("CENTOS_VERSION", "41") export default_tag := env("DEFAULT_TAG", "latest") export bib_image := env("BIB_IMAGE", "quay.io/centos-bootc/bootc-image-builder:latest") -export SUDO_DISPLAY := if `if [ -n "${DISPLAY:-}" ] || [ -n "${WAYLAND_DISPLAY:-}" ]; then echo true; fi` == "true" { "true" } else { "false" } -export SUDOIF := if `id -u` == "0" { "" } else { if SUDO_DISPLAY == "true" { "sudo --askpass" } else { "sudo" } } -export PODMAN := if path_exists("/usr/bin/podman") == "true" { env("PODMAN", "/usr/bin/podman") } else { if path_exists("/usr/bin/docker") == "true" { env("PODMAN", "docker") } else { env("PODMAN", "exit 1 ; ") } } - alias build-vm := build-qcow2 alias rebuild-vm := rebuild-qcow2 alias run-vm := run-vm-qcow2 @@ -52,54 +50,136 @@ clean: [group('Utility')] [private] sudo-clean: - ${SUDOIF} just clean + just sudoif just clean -build $target_image=image_name $tag=default_tag: +# sudoif bash function +[group('Utility')] +[private] +sudoif command *args: + #!/usr/bin/bash + function sudoif(){ + if [[ "${UID}" -eq 0 ]]; then + "$@" + elif [[ "$(command -v sudo)" && -n "${SSH_ASKPASS:-}" ]] && [[ -n "${DISPLAY:-}" || -n "${WAYLAND_DISPLAY:-}" ]]; then + /usr/bin/sudo --askpass "$@" || exit 1 + elif [[ "$(command -v sudo)" ]]; then + /usr/bin/sudo "$@" || exit 1 + else + exit 1 + fi + } + sudoif {{ command }} {{ args }} + +# This Justfile recipe builds a container image using Podman. +# +# Arguments: +# $target_image - The tag you want to apply to the image (default: aurora). +# $tag - The tag for the image (default: lts). +# $dx - Enable DX (default: "0"). +# $hwe - Enable HWE (default: "0"). +# $gdx - Enable GDX (default: "0"). +# +# DX: +# Developer Experience (DX) is a feature that allows you to install the latest developer tools for your system. +# Packages include VScode, Docker, Distrobox, and more. +# HWE: +# Hardware Enablement (HWE) is a feature that allows you to install the latest hardware support for your system. +# Currently this install the Hyperscale SIG kernel which will stay ahead of the CentOS Stream kernel and enables btrfs +# GDX: https://docs.projectaurora.io/gdx/ +# GPU Developer Experience (GDX) creates a base as an AI and Graphics platform. +# Installs Nvidia drivers, CUDA, and other tools. +# +# The script constructs the version string using the tag and the current date. +# If the git working directory is clean, it also includes the short SHA of the current HEAD. +# +# just build $target_image $tag $dx $hwe $gdx +# +# Example usage: +# just build aurora lts 1 0 1 +# +# This will build an image 'aurora:lts' with DX and GDX enabled. +# + +# Build the image using the specified parameters +build $target_image=image_name $tag=default_tag $dx="0" $hwe="0" $gdx="0": #!/usr/bin/env bash # Get Version - ver="${tag}-$(date +%Y%m%d)" + ver="${tag}-${centos_version}.$(date +%Y%m%d)" BUILD_ARGS=() + BUILD_ARGS+=("--build-arg" "MAJOR_VERSION=${centos_version}") BUILD_ARGS+=("--build-arg" "IMAGE_NAME=${image_name}") BUILD_ARGS+=("--build-arg" "IMAGE_VENDOR=${repo_organization}") + BUILD_ARGS+=("--build-arg" "ENABLE_DX=${dx}") + BUILD_ARGS+=("--build-arg" "ENABLE_HWE=${hwe}") + BUILD_ARGS+=("--build-arg" "ENABLE_GDX=${gdx}") if [[ -z "$(git status -s)" ]]; then BUILD_ARGS+=("--build-arg" "SHA_HEAD_SHORT=$(git rev-parse --short HEAD)") fi - ${PODMAN} build \ + podman build \ "${BUILD_ARGS[@]}" \ --pull=newer \ - --tag "${image_name}:${tag}" \ + --tag "${target_image}:${tag}" \ . +# 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. +# If the image is found, it loads it into rootful podman. If the image is not found, it pulls it from the repository. +# +# Parameters: +# $target_image - The name of the target image to be loaded or pulled. +# $tag - The tag of the target image to be loaded or pulled. Default is 'default_tag'. +# +# Example usage: +# _rootful_load_image my_image latest +# +# Steps: +# 1. Check if the script is already running as root or under sudo. +# 2. Check if target image is in the non-root podman container storage) +# 3. If the image is found, load it into rootful podman using podman scp. +# 4. If the image is not found, pull it from the remote repository into reootful podman. + _rootful_load_image $target_image=image_name $tag=default_tag: #!/usr/bin/bash set -eoux pipefail + # Check if already running as root or under sudo if [[ -n "${SUDO_USER:-}" || "${UID}" -eq "0" ]]; then - echo "Already root or running under sudo, no need to load image from user ${PODMAN}." + echo "Already root or running under sudo, no need to load image from user podman." exit 0 fi + # Try to resolve the image tag using podman inspect set +e - resolved_tag=$(${PODMAN} inspect -t image "${target_image}:${tag}" | jq -r '.[].RepoTags.[0]') + resolved_tag=$(podman inspect -t image "${target_image}:${tag}" | jq -r '.[].RepoTags.[0]') return_code=$? set -e if [[ $return_code -eq 0 ]]; then - # Load into Rootful ${PODMAN} - ID=$(${SUDOIF} ${PODMAN} images --filter reference="${target_image}:${tag}" --format "'{{ '{{.ID}}' }}'") + # If the image is found, load it into rootful podman + ID=$(just sudoif podman images --filter reference="${target_image}:${tag}" --format "'{{ '{{.ID}}' }}'") if [[ -z "$ID" ]]; then + # If the image ID is not found, copy the image from user podman to root podman COPYTMP=$(mktemp -p "${PWD}" -d -t _build_podman_scp.XXXXXXXXXX) - ${SUDOIF} TMPDIR=${COPYTMP} ${PODMAN} image scp ${UID}@localhost::"${target_image}:${tag}" root@localhost::"${target_image}:${tag}" + just sudoif TMPDIR=${COPYTMP} podman image scp ${UID}@localhost::"${target_image}:${tag}" root@localhost::"${target_image}:${tag}" rm -rf "${COPYTMP}" fi else - # Make sure the image is present and/or up to date - ${SUDOIF} ${PODMAN} pull "${target_image}:${tag}" + # If the image is not found, pull it from the repository + just sudoif podman pull "${target_image}:${tag}" fi +# Build a bootc bootable image using Bootc Image Builder (BIB) +# Converts a container image to a bootable image +# Parameters: +# target_image: The name of the image to build (ex. localhost/fedora) +# tag: The tag of the image to build (ex. latest) +# type: The type of image to build (ex. qcow2, raw, iso) +# config: The configuration file to use for the build (default: image.toml) + +# Example: just _rebuild-bib localhost/fedora latest qcow2 image.toml _build-bib $target_image $tag $type $config: (_rootful_load_image target_image tag) #!/usr/bin/env bash set -euo pipefail @@ -113,13 +193,14 @@ _build-bib $target_image $tag $type $config: (_rootful_load_image target_image t sudo rm -rf "output/${type}" || true fi - args="--type ${type}" + args="--type ${type} " + args+="--use-librepo=True" if [[ $target_image == localhost/* ]]; then args+=" --local" fi - sudo ${PODMAN} run \ + sudo podman run \ --rm \ -it \ --privileged \ @@ -130,53 +211,70 @@ _build-bib $target_image $tag $type $config: (_rootful_load_image target_image t -v $(pwd)/output:/output \ -v /var/lib/containers/storage:/var/lib/containers/storage \ "${bib_image}" \ - --rootfs btrfs \ ${args} \ - "${target_image}" + "${target_image}:${tag}" sudo chown -R $USER:$USER output +# Podman builds the image from the Containerfile and creates a bootable image +# Parameters: +# target_image: The name of the image to build (ex. localhost/fedora) +# tag: The tag of the image to build (ex. latest) +# type: The type of image to build (ex. qcow2, raw, iso) +# config: The configuration file to use for the build (deafult: image.toml) + +# Example: just _rebuild-bib localhost/fedora latest qcow2 image.toml _rebuild-bib $target_image $tag $type $config: (build target_image tag) && (_build-bib target_image tag type config) -[group('Build Virtual Machine Image')] +# Build a QCOW2 virtual machine image +[group('Build Virtal Machine Image')] build-qcow2 $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "qcow2" "image.toml") -[group('Build Virtual Machine Image')] +# Build a RAW virtual machine image +[group('Build Virtal Machine Image')] build-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "raw" "image.toml") -[group('Build Virtual Machine Image')] +# Build an ISO virtual machine image +[group('Build Virtal Machine Image')] build-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "iso" "iso.toml") -[group('Build Virtual Machine Image')] +# Rebuild a QCOW2 virtual machine image +[group('Build Virtal Machine Image')] rebuild-qcow2 $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "qcow2" "image.toml") -[group('Build Virtual Machine Image')] +# Rebuild a RAW virtual machine image +[group('Build Virtal Machine Image')] rebuild-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "raw" "image.toml") -[group('Build Virtual Machine Image')] +# Rebuild an ISO virtual machine image +[group('Build Virtal Machine Image')] rebuild-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "iso" "iso.toml") +# Run a virtual machine with the specified image type and configuration _run-vm $target_image $tag $type $config: #!/usr/bin/bash set -eoux pipefail + # Determine the image file based on the type image_file="output/${type}/disk.${type}" - if [[ $type == iso ]]; then image_file="output/bootiso/install.iso" fi + # Build the image if it does not exist if [[ ! -f "${image_file}" ]]; then just "build-${type}" "$target_image" "$tag" fi - # Determine which port to use - port=8006; + # Determine an available port to use + port=8006 while grep -q :${port} <<< $(ss -tunalp); do port=$(( port + 1 )) done echo "Using Port: ${port}" echo "Connect to http://localhost:${port}" + + # Set up the arguments for running the VM run_args=() run_args+=(--rm --privileged) run_args+=(--pull=newer) @@ -184,21 +282,52 @@ _run-vm $target_image $tag $type $config: run_args+=(--env "CPU_CORES=4") run_args+=(--env "RAM_SIZE=8G") run_args+=(--env "DISK_SIZE=64G") - # run_args+=(--env "BOOT_MODE=windows_secure") run_args+=(--env "TPM=Y") run_args+=(--env "GPU=Y") run_args+=(--device=/dev/kvm) run_args+=(--volume "${PWD}/${image_file}":"/boot.${type}") run_args+=(docker.io/qemux/qemu-docker) - ${PODMAN} run "${run_args[@]}" & + + # Run the VM and open the browser to connect + podman run "${run_args[@]}" & xdg-open http://localhost:${port} - fg "%${PODMAN}" + fg "%podman" + +# Run a virtual machine from a QCOW2 image +[group('Run Virtal Machine')] +run-vm-qcow2 $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "qcow2" "image.toml") + +# Run a virtual machine from a RAW image +[group('Run Virtal Machine')] +run-vm-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "raw" "image.toml") + +# Run a virtual machine from an ISO +[group('Run Virtal Machine')] +run-vm-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "iso" "iso.toml") + +# Run a virtual machine using systemd-vmspawn +[group('Run Virtal Machine')] +spawn-vm rebuild="0" type="qcow2" ram="6G": + #!/usr/bin/env bash + + set -euo pipefail + + [ "{{ rebuild }}" -eq 1 ] && echo "Rebuilding the ISO" && just build-vm {{ rebuild }} {{ type }} + + systemd-vmspawn \ + -M "bootc-image" \ + --console=gui \ + --cpus=2 \ + --ram=$(echo {{ ram }}| /usr/bin/numfmt --from=iec) \ + --network-user-mode \ + --vsock=false --pass-ssh-key=false \ + -i ./output/**/*.{{ type }} -[group('Run Virtual Machine')] -run-vm-qcow2 $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "qcow2" "image-builder.config.toml") -[group('Run Virtual Machine')] -run-vm-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "raw" "image-builder.config.toml") +# Runs shell check on all Bash scripts +lint: + /usr/bin/find . -iname "*.sh" -type f -exec shellcheck "{}" ';' -[group('Run Virtual Machine')] -run-vm-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "iso" "image-builder-iso.config.toml") +# Runs shfmt on all Bash scripts +format: + /usr/bin/find . -iname "*.sh" -type f -exec shfmt --write "{}" ';' -- cgit v1.2.3 From f39efa0fddeb1849a1ae0fbb4f9b38a344521f15 Mon Sep 17 00:00:00 2001 From: Robert Sturla Date: Thu, 13 Mar 2025 00:20:26 +0000 Subject: fix(docs): update link to bootc docs (#77) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f5c2fb1..c27dbaa 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Working knowledge in the following topics: - https://www.youtube.com/watch?v=SnSH8Ht3MIc - https://www.mankier.com/5/Containerfile - bootc - - https://containers.github.io/bootc/ + - https://bootc-dev.github.io/bootc/ - Fedora Silverblue (and other Fedora Atomic variants) - https://docs.fedoraproject.org/en-US/fedora-silverblue/ - Github Workflows @@ -94,7 +94,7 @@ This provides users a method of verifying the image. # Community -- [**bootc discussion forums**](https://github.com/containers/bootc/discussions) - Nothing in this template is ublue specific, the upstream bootc project has a discussions forum where custom image builders can hang out and ask questions. +- [**bootc discussion forums**](https://github.com/bootc-dev/bootc/discussions) - Nothing in this template is ublue specific, the upstream bootc project has a discussions forum where custom image builders can hang out and ask questions. ## Artifacthub -- cgit v1.2.3 From eb0cc45977b7dc47656c117a9ed34cfd66857912 Mon Sep 17 00:00:00 2001 From: Sean Date: Thu, 13 Mar 2025 19:30:38 -0500 Subject: feat(build-iso): Add ability to generate ISO (#79) * initial commit of s3 upload for iso * Updated Readme. Updated build-iso.yml from testing in test repo * one more note to make it look more balanced * add artifact upload ability and adjust README to detail how to use * One more final note to help be explicit about artifact location. --------- Co-authored-by: Sean Thrailkill --- .github/workflows/build-iso.yml | 103 ++++++++++++++++++++++++++++++++++++++++ README.md | 22 +++++++-- iso.toml | 2 +- 3 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/build-iso.yml diff --git a/.github/workflows/build-iso.yml b/.github/workflows/build-iso.yml new file mode 100644 index 0000000..1083249 --- /dev/null +++ b/.github/workflows/build-iso.yml @@ -0,0 +1,103 @@ +--- +name: Build ISOs + +on: + workflow_dispatch: + inputs: + upload-to-s3: + description: "Upload to S3" + required: false + default: false + type: boolean + platform: + required: true + type: choice + options: + - amd64 + - arm64 + pull_request: + branches: + - main + paths: + - './iso.toml' + - './.github/workflows/build-iso.yml' + - './Justfile' + +env: + IMAGE_REGISTRY: "ghcr.io/${{ github.repository }}" + DEFAULT_TAG: "latest" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + build: + name: Build ISOs + runs-on: ${{ inputs.platform == 'amd64' && 'ubuntu-24.04' || 'ubuntu-24.04-arm' }} + strategy: + fail-fast: false + permissions: + contents: read + packages: read + id-token: write + + steps: + - name: lower case the image registry in case of any capitalization + run: | + echo "IMAGE_REGISTRY=${IMAGE_REGISTRY,,}" >> ${GITHUB_ENV} + + - name: Install dependencies + if: inputs.platform == 'arm64' + run: | + set -x + sudo apt update -y + sudo apt install -y \ + podman + + - name: Maximize build space + if: inputs.platform != 'arm64' + uses: ublue-os/remove-unwanted-software@cc0becac701cf642c8f0a6613bbdaf5dc36b259e # v9 + with: + remove-codeql: true + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Setup Just + uses: extractions/setup-just@dd310ad5a97d8e7b41793f8ef055398d51ad4de6 # v2 + + - name: Build ISO + id: build + uses: ublue-os/bootc-image-builder-action@main + with: + bootc-image-builder-image: ghcr.io/centos-workstation/bootc-image-builder:latest + use-librepo: true + config-file: ./iso.toml + image: ${{ env.IMAGE_REGISTRY }}:${{ env.DEFAULT_TAG }} + + - name: Upload ISOs and Checksum to Job Artifacts + if: inputs.upload-to-s3 != true && github.event_name != 'pull_request' + uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4 + with: + path: ${{ steps.build.outputs.output-directory }} + if-no-files-found: error + retention-days: 0 + compression-level: 0 + overwrite: true + + - name: Upload to S3 + if: inputs.upload-to-s3 == true && github.event_name != 'pull_request' + shell: bash + env: + RCLONE_CONFIG_S3_TYPE: s3 + RCLONE_CONFIG_S3_PROVIDER: ${{ secrets.S3_PROVIDER }} + RCLONE_CONFIG_S3_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }} + RCLONE_CONFIG_S3_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }} + RCLONE_CONFIG_S3_REGION: ${{ secrets.S3_REGION }} + RCLONE_CONFIG_S3_ENDPOINT: ${{ secrets.S3_ENDPOINT }} + SOURCE_DIR: ${{ steps.build.outputs.output-directory }} + run: | + sudo apt-get update + sudo apt-get install -y rclone + rclone copy $SOURCE_DIR S3:${{ secrets.S3_BUCKET_NAME }} \ No newline at end of file diff --git a/README.md b/README.md index c27dbaa..e79c500 100644 --- a/README.md +++ b/README.md @@ -47,9 +47,9 @@ This file defines the operations used to customize the selected image. It contai ## Building an ISO -Modify `iso.toml` to point to your custom image before generating an ISO. +This template provides an out of the box workflow for getting an ISO image for your custom OCI image which can be used to directly install onto your machines. -- (Steps in progress) +This template provides a way to upload the ISO that is generated from the workflow to a S3 bucket or it will be available as an artifact from the job. To upload to S3 we use a tool called [rclone](https://rclone.org/) which is able to use [many S3 providers](https://rclone.org/s3/). For more details on how to configure this see the details [below](#build-isoyml). ## Workflows @@ -57,6 +57,22 @@ Modify `iso.toml` to point to your custom image before generating an ISO. This 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. +### build-iso.yml + +This workflow creates an ISO from your OCI image by utilizing the [bootc-image-builder](https://osbuild.org/docs/bootc/) to generate an ISO. In order to use this workflow you must complete the following steps: + +- Modify `iso.toml` to point to your custom image before generating an ISO. +- If you changed your image name from the default in `build.yml` then in the `build-iso.yml` file edit the `IMAGE_REGISTRY` and `DEFAULT_TAG` environment variables with the correct values. If you did not make changes, skip this step. +- Finally, if you want to upload your ISOs to S3 then you will need to add your S3 configuration to the repository's Action secrets. This can be found by going to your repository settings, under `Secrets and Variables` -> `Actions`. You will need to add the following + - `S3_PROVIDER` - Must match one of the values from the [supported list](https://rclone.org/s3/) + - `S3_BUCKET_NAME` - Your unique bucket name + - `S3_ACCESS_KEY_ID` - It is recommended that you make a separate key just for this workflow + - `S3_SECRET_ACCESS_KEY` - See above. + - `S3_REGION` - The region your bucket lives in. If you do not know then set this value to `auto`. + - `S3_ENDPOINT` - This value will be specific to the bucket as well. + +Once the workflow is done, you'll find it either in your S3 bucket or as part of the summary under `Artifacts` after the workflow is completed. + #### Container Signing Container signing is important for end-user security and is enabled on all Universal Blue images. It is recommended you set this up, and by default the image builds *will fail* if you don't. @@ -79,7 +95,7 @@ This provides users a method of verifying the image. 3. Add the private key to GitHub - - This can also be done manually. Go to your repository settings, under Secrets and Variables -> Actions + - This can also be done manually. Go to your repository settings, under `Secrets and Variables` -> `Actions` ![image](https://user-images.githubusercontent.com/1264109/216735595-0ecf1b66-b9ee-439e-87d7-c8cc43c2110a.png) Add a new secret and name it `SIGNING_SECRET`, then paste the contents of `cosign.key` into the secret and save it. Make sure it's the .key file and not the .pub file. Once done, it should look like this: ![image](https://user-images.githubusercontent.com/1264109/216735690-2d19271f-cee2-45ac-a039-23e6a4c16b34.png) diff --git a/iso.toml b/iso.toml index 1b3084d..21b6913 100644 --- a/iso.toml +++ b/iso.toml @@ -1,7 +1,7 @@ [customizations.installer.kickstart] contents = """ %post -bootc switch --mutate-in-place --transport registry ghcr.io/yourname/yourusername:latest +bootc switch --mutate-in-place --transport registry ghcr.io/yourrepo/yourimage:latest %end """ -- cgit v1.2.3 From 10777e9d49a26239a4f737cb4ccbd27276762ee4 Mon Sep 17 00:00:00 2001 From: Nathan Ellenfield Date: Fri, 14 Mar 2025 17:26:44 -0400 Subject: fix: Justfile variable usage and formatting (#65) Co-authored-by: Tulip Blossom --- .gitignore | 1 + Justfile | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index bbc6166..dcaf584 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ cosign.key _build_* +output \ No newline at end of file diff --git a/Justfile b/Justfile index 4315601..ff51345 100644 --- a/Justfile +++ b/Justfile @@ -109,7 +109,7 @@ build $target_image=image_name $tag=default_tag $dx="0" $hwe="0" $gdx="0": BUILD_ARGS=() BUILD_ARGS+=("--build-arg" "MAJOR_VERSION=${centos_version}") - BUILD_ARGS+=("--build-arg" "IMAGE_NAME=${image_name}") + BUILD_ARGS+=("--build-arg" "IMAGE_NAME=${target_image}") BUILD_ARGS+=("--build-arg" "IMAGE_VENDOR=${repo_organization}") BUILD_ARGS+=("--build-arg" "ENABLE_DX=${dx}") BUILD_ARGS+=("--build-arg" "ENABLE_HWE=${hwe}") @@ -188,16 +188,16 @@ _build-bib $target_image $tag $type $config: (_rootful_load_image target_image t echo "Cleaning up previous build" if [[ $type == iso ]]; then - sudo rm -rf "output/bootiso" || true + sudo rm -rf "output/bootiso" || true else - sudo rm -rf "output/${type}" || true + sudo rm -rf "output/${type}" || true fi args="--type ${type} " args+="--use-librepo=True" if [[ $target_image == localhost/* ]]; then - args+=" --local" + args+=" --local" fi sudo podman run \ -- cgit v1.2.3 From 5aedfd0d83950551d01b09b94adf0b878e1ccfd5 Mon Sep 17 00:00:00 2001 From: Tulip Blossom Date: Sat, 15 Mar 2025 15:31:35 -0300 Subject: ci: make sure renovate uses best-practices preset (#84) Even if they say that its best for people that want the best practices on the docs, we should make people using this template have this safer thing by default https://docs.renovatebot.com/presets-config/#configbest-practices --- .github/renovate.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 5db72dd..48515b9 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,6 +1,6 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ - "config:recommended" + "config:best-practices" ] } -- cgit v1.2.3 From fabcebc232679e28b4d8b3ca69c77730db8dd6f9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 14:32:51 -0400 Subject: chore(deps): pin dependencies (#85) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 6 +++--- Containerfile | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2be4bdf..ac6e188 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -88,7 +88,7 @@ jobs: - name: Build Image id: build_image - uses: redhat-actions/buildah-build@v2 + uses: redhat-actions/buildah-build@7a95fa7ee0f02d552a32753e7414641a04307056 # v2 with: containerfiles: | ./Containerfile @@ -137,13 +137,13 @@ jobs: # https://github.com/macbre/push-to-ghcr/issues/12 - name: Lowercase Registry id: registry_case - uses: ASzc/change-string-case-action@v6 + uses: ASzc/change-string-case-action@d0603cd0a7dd490be678164909f65c7737470a7f # v6 with: string: ${{ env.IMAGE_REGISTRY }} - name: Lowercase Image id: image_case - uses: ASzc/change-string-case-action@v6 + uses: ASzc/change-string-case-action@d0603cd0a7dd490be678164909f65c7737470a7f # v6 with: string: ${{ env.IMAGE_NAME }} diff --git a/Containerfile b/Containerfile index 80b04aa..4c16910 100644 --- a/Containerfile +++ b/Containerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/ublue-os/bazzite:stable +FROM ghcr.io/ublue-os/bazzite:stable@sha256:b0655252e3d7b53d7c3b4469e4d84635341b991c22a11fb0dc85dba802f9cb27 ## Other possible base images include: # FROM ghcr.io/ublue-os/bazzite:latest -- cgit v1.2.3 From 3ccb54056d2131631e9e6710bf7334057096f1f3 Mon Sep 17 00:00:00 2001 From: Tulip Blossom Date: Sat, 15 Mar 2025 16:02:07 -0300 Subject: ci: use the same renovate config as bluefin-lts (#86) * ci: use the same renovate config as bluefin-lts This one makes it so we (and people that use this template) dont need to manually bump the docker images all the time, like we ran into with [bluefin LTS](https://github.com/ublue-os/bluefin-lts/pull/398#issuecomment-2726873005) * fix: also remove the pin on Containerfile --- .github/renovate.json5 | 17 ++++++++++++++++- Containerfile | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 48515b9..5e48a3e 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,6 +1,21 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ - "config:best-practices" + "config:best-practices", + ], + + "rebaseWhen": "never", + + "packageRules": [ + { + "automerge": true, + "matchUpdateTypes": ["pin", "pinDigest"] + }, + { + "enabled": false, + "matchUpdateTypes": ["digest", "pinDigest", "pin"], + "matchDepTypes": ["container"], + "matchFileNames": [".github/workflows/**.yaml", ".github/workflows/**.yml"], + }, ] } diff --git a/Containerfile b/Containerfile index 4c16910..80b04aa 100644 --- a/Containerfile +++ b/Containerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/ublue-os/bazzite:stable@sha256:b0655252e3d7b53d7c3b4469e4d84635341b991c22a11fb0dc85dba802f9cb27 +FROM ghcr.io/ublue-os/bazzite:stable ## Other possible base images include: # FROM ghcr.io/ublue-os/bazzite:latest -- cgit v1.2.3 From bcfe8db8efdd1ea43bfae63e849bc910d85031cc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 15:03:09 -0400 Subject: chore(deps): update docker/login-action digest to 74a5d14 (#80) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ac6e188..8457604 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -126,7 +126,7 @@ jobs: # 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 - name: Login to GitHub Container Registry - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) with: registry: ghcr.io -- cgit v1.2.3 From 346e234f4522274438d9937ed7a98f45fd9f9316 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 15:03:23 -0400 Subject: chore(deps): update extractions/setup-just action to v3 (#83) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build-iso.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-iso.yml b/.github/workflows/build-iso.yml index 1083249..a267c8d 100644 --- a/.github/workflows/build-iso.yml +++ b/.github/workflows/build-iso.yml @@ -65,7 +65,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Setup Just - uses: extractions/setup-just@dd310ad5a97d8e7b41793f8ef055398d51ad4de6 # v2 + uses: extractions/setup-just@e33e0265a09d6d736e2ee1e0eb685ef1de4669ff # v3 - name: Build ISO id: build -- cgit v1.2.3 From f1d14428d11a562a537942bc6e2fed8bcea60a70 Mon Sep 17 00:00:00 2001 From: R0flcopt3r <12752060+R0flcopt3r@users.noreply.github.com> Date: Sun, 16 Mar 2025 18:33:49 +0100 Subject: fix: _rootful_load_image would not copy if the user image was different (#88) Co-authored-by: Eirik O. Lavik --- Justfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Justfile b/Justfile index ff51345..f12166c 100644 --- a/Justfile +++ b/Justfile @@ -157,11 +157,13 @@ _rootful_load_image $target_image=image_name $tag=default_tag: return_code=$? set -e + USER_IMG_ID=$(podman images --filter reference="${target_image}:${tag}" --format "'{{ '{{.ID}}' }}'") + if [[ $return_code -eq 0 ]]; then # If the image is found, load it into rootful podman ID=$(just sudoif podman images --filter reference="${target_image}:${tag}" --format "'{{ '{{.ID}}' }}'") - if [[ -z "$ID" ]]; then - # If the image ID is not found, copy the image from user podman to root podman + if [[ "$ID" != "$USER_IMG_ID" ]]; then + # If the image ID is not found or different from user, copy the image from user podman to root podman COPYTMP=$(mktemp -p "${PWD}" -d -t _build_podman_scp.XXXXXXXXXX) just sudoif TMPDIR=${COPYTMP} podman image scp ${UID}@localhost::"${target_image}:${tag}" root@localhost::"${target_image}:${tag}" rm -rf "${COPYTMP}" -- cgit v1.2.3 From e0e4a78dfbe3a1a054a7e1342eac68430c529d96 Mon Sep 17 00:00:00 2001 From: R0flcopt3r <12752060+R0flcopt3r@users.noreply.github.com> Date: Mon, 17 Mar 2025 01:15:55 +0100 Subject: feat: build in tempdir and move files on success (#82) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: build in tempdir and move files on success Before it would delete your outputs before starting the build. That means miss-typing the command for example could lead to losing data. This also creates separate folders for each type to avoid collision. * fix: tempdir naming this follows the convention set in the `_rootful_load_image` target. * fix: delete output folder in clean target * fix: move contents of temp build directory This ensures a flatter folder structure, bib allready seem to ensure there aren't any file name collisions. output folder would look like this after building a raw and qcow2. output ├── image │   └── disk.raw ├── manifest-qcow2.json ├── manifest-raw.json └── qcow2 └── disk.qcow2 * fix: overwrite previous output directory From conversations in https://github.com/ublue-os/image-template/pull/82 this is the wanted behaviour for this project. * revert: overwrite previous output directory This reverts commit 75448d72fa624cea01524d5651c926ae772460bf. * chore(gitignore): ensure build directories are not showing up on diffs --------- Co-authored-by: Tulip Blossom --- .gitignore | 3 ++- Justfile | 19 ++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index dcaf584..9eee28b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ cosign.key _build_* -output \ No newline at end of file +output +_build-*/** diff --git a/Justfile b/Justfile index f12166c..000a0c6 100644 --- a/Justfile +++ b/Justfile @@ -45,6 +45,7 @@ clean: rm -f previous.manifest.json rm -f changelog.md rm -f output.env + rm -f output/ # Sudo Clean Repo [group('Utility')] @@ -186,15 +187,6 @@ _build-bib $target_image $tag $type $config: (_rootful_load_image target_image t #!/usr/bin/env bash set -euo pipefail - mkdir -p "output" - - echo "Cleaning up previous build" - if [[ $type == iso ]]; then - sudo rm -rf "output/bootiso" || true - else - sudo rm -rf "output/${type}" || true - fi - args="--type ${type} " args+="--use-librepo=True" @@ -202,6 +194,8 @@ _build-bib $target_image $tag $type $config: (_rootful_load_image target_image t args+=" --local" fi + BUILDTMP=$(mktemp -p "${PWD}" -d -t _build-bib.XXXXXXXXXX) + sudo podman run \ --rm \ -it \ @@ -210,13 +204,16 @@ _build-bib $target_image $tag $type $config: (_rootful_load_image target_image t --net=host \ --security-opt label=type:unconfined_t \ -v $(pwd)/${config}:/config.toml:ro \ - -v $(pwd)/output:/output \ + -v $BUILDTMP:/output \ -v /var/lib/containers/storage:/var/lib/containers/storage \ "${bib_image}" \ ${args} \ "${target_image}:${tag}" - sudo chown -R $USER:$USER output + mkdir -p output + sudo mv -f $BUILDTMP/* output/ + sudo rmdir $BUILDTMP + sudo chown -R $USER:$USER output/ # Podman builds the image from the Containerfile and creates a bootable image # Parameters: -- cgit v1.2.3 From 3a6369f36fdde9038d681d588109bebd7f09cfbb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 09:17:26 -0400 Subject: chore(deps): update actions/upload-artifact digest to ea165f8 (#90) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build-iso.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-iso.yml b/.github/workflows/build-iso.yml index a267c8d..b8aa38e 100644 --- a/.github/workflows/build-iso.yml +++ b/.github/workflows/build-iso.yml @@ -78,7 +78,7 @@ jobs: - name: Upload ISOs and Checksum to Job Artifacts if: inputs.upload-to-s3 != true && github.event_name != 'pull_request' - uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: path: ${{ steps.build.outputs.output-directory }} if-no-files-found: error -- cgit v1.2.3 From 6267a70bca612e9a8f3f0c671d4b9b3880f0ee7c Mon Sep 17 00:00:00 2001 From: Kyle Gospodnetich Date: Sat, 22 Mar 2025 15:15:36 -0700 Subject: feat: Use bind mounts to keep final image clean (#92) --- Containerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Containerfile b/Containerfile index 80b04aa..015dfaf 100644 --- a/Containerfile +++ b/Containerfile @@ -15,7 +15,9 @@ FROM ghcr.io/ublue-os/bazzite:stable COPY build.sh /tmp/build.sh -RUN mkdir -p /var/lib/alternatives && \ +RUN --mount=type=cache,dst=/var/cache \ + --mount=type=cache,dst=/var/log \ + --mount=type=tmpfs,dst=/tmp \ /tmp/build.sh && \ ostree container commit -- cgit v1.2.3 From 6382bb38313ca960f51ce6cf24eb5ac75a87d9d6 Mon Sep 17 00:00:00 2001 From: Kyle Gospodnetich Date: Sat, 22 Mar 2025 15:18:22 -0700 Subject: feat: Avoid copying build files into image, add option for linting (#93) --- Containerfile | 16 ++++++++++++---- build.sh | 24 ------------------------ build_files/build.sh | 24 ++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 28 deletions(-) delete mode 100755 build.sh create mode 100755 build_files/build.sh diff --git a/Containerfile b/Containerfile index 015dfaf..69550ff 100644 --- a/Containerfile +++ b/Containerfile @@ -1,3 +1,8 @@ +# Allow build scripts to be referenced without being copied into the final image +FROM scratch AS ctx +COPY build_files / + +# Base Image FROM ghcr.io/ublue-os/bazzite:stable ## Other possible base images include: @@ -13,11 +18,14 @@ FROM ghcr.io/ublue-os/bazzite:stable ## make modifications desired in your image and install packages by modifying the build.sh script ## the following RUN directive does all the things required to run "build.sh" as recommended. -COPY build.sh /tmp/build.sh - -RUN --mount=type=cache,dst=/var/cache \ +RUN --mount=type=bind,from=ctx,source=/,target=/ctx \ + --mount=type=cache,dst=/var/cache \ --mount=type=cache,dst=/var/log \ --mount=type=tmpfs,dst=/tmp \ - /tmp/build.sh && \ + /ctx/build.sh && \ ostree container commit +### LINTING +## Verify final image and contents are correct. +## This can be quite sensitive, so it's disabled by default. +# RUN bootc container lint \ No newline at end of file diff --git a/build.sh b/build.sh deleted file mode 100755 index f1e659a..0000000 --- a/build.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -set -ouex pipefail - -### Install packages - -# Packages can be installed from any enabled yum repo on the image. -# RPMfusion repos are available by default in ublue main images -# List of rpmfusion packages can be found here: -# https://mirrors.rpmfusion.org/mirrorlist?path=free/fedora/updates/39/x86_64/repoview/index.html&protocol=https&redirect=1 - -# this installs a package from fedora repos -dnf5 install -y tmux - -# Use a COPR Example: -# -# dnf5 -y copr enable ublue-os/staging -# dnf5 -y install package -# Disable COPRs so they don't end up enabled on the final image: -# dnf5 -y copr disable ublue-os/staging - -#### Example for enabling a System Unit File - -systemctl enable podman.socket diff --git a/build_files/build.sh b/build_files/build.sh new file mode 100755 index 0000000..f1e659a --- /dev/null +++ b/build_files/build.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -ouex pipefail + +### Install packages + +# Packages can be installed from any enabled yum repo on the image. +# RPMfusion repos are available by default in ublue main images +# List of rpmfusion packages can be found here: +# https://mirrors.rpmfusion.org/mirrorlist?path=free/fedora/updates/39/x86_64/repoview/index.html&protocol=https&redirect=1 + +# this installs a package from fedora repos +dnf5 install -y tmux + +# Use a COPR Example: +# +# dnf5 -y copr enable ublue-os/staging +# dnf5 -y install package +# Disable COPRs so they don't end up enabled on the final image: +# dnf5 -y copr disable ublue-os/staging + +#### Example for enabling a System Unit File + +systemctl enable podman.socket -- cgit v1.2.3 From 949ae66d2a55e708cc72f1b02efb36f243f0dc7e Mon Sep 17 00:00:00 2001 From: Kyle Gospodnetich Date: Tue, 25 Mar 2025 14:23:04 -0700 Subject: feat: Enable linting by default (#95) --- Containerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Containerfile b/Containerfile index 69550ff..d57ee46 100644 --- a/Containerfile +++ b/Containerfile @@ -27,5 +27,4 @@ RUN --mount=type=bind,from=ctx,source=/,target=/ctx \ ### LINTING ## Verify final image and contents are correct. -## This can be quite sensitive, so it's disabled by default. -# RUN bootc container lint \ No newline at end of file +RUN bootc container lint \ No newline at end of file -- cgit v1.2.3 From eac380c0712f35a3b3237b16aad0caa3304af354 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Tue, 25 Mar 2025 17:27:52 -0400 Subject: docs: document the justfile (#91) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: document the justfile Bless you copilot. 🗡️ * Update README.md Co-authored-by: Tulip Blossom --------- Co-authored-by: Tulip Blossom --- README.md | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/README.md b/README.md index e79c500..0f50ffa 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,151 @@ This template provides an out of the box workflow for getting an ISO image for y This template provides a way to upload the ISO that is generated from the workflow to a S3 bucket or it will be available as an artifact from the job. To upload to S3 we use a tool called [rclone](https://rclone.org/) which is able to use [many S3 providers](https://rclone.org/s3/). For more details on how to configure this see the details [below](#build-isoyml). +### Justfile Documentation + +This `Justfile` contains various commands and configurations for building and managing container images and virtual machine images using Podman and other utilities. + +#### Environment Variables + +- `repo_organization`: The GitHub repository owner (default: "yourname"). +- `image_name`: The name of the image (default: "yourimage"). +- `centos_version`: The CentOS version (default: "stream10"). +- `fedora_version`: The Fedora version (default: "41"). +- `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"). + +#### Aliases + +- `build-vm`: Alias for `build-qcow2`. +- `rebuild-vm`: Alias for `rebuild-qcow2`. +- `run-vm`: Alias for `run-vm-qcow2`. + + +#### Commands + +###### `check` + +Checks the syntax of all `.just` files and the `Justfile`. + +###### `fix` + +Fixes the syntax of all `.just` files and the `Justfile`. + +###### `clean` + +Cleans the repository by removing build artifacts. + +##### Build Commands + +###### `build` + +Builds a container image using Podman. + +```bash +just build $target_image $tag $dx $hwe $gdx +``` + +Arguments: +- `$target_image`: The tag you want to apply to the image (default: aurora). +- `$tag`: The tag for the image (default: lts). +- `$dx`: Enable DX (default: "0"). +- `$hwe`: Enable HWE (default: "0"). +- `$gdx`: Enable GDX (default: "0"). + +##### Building Virtual Machines and ISOs + +###### `build-qcow2` + +Builds a QCOW2 virtual machine image. + +```bash +just build-qcow2 $target_image $tag +``` + +###### `build-raw` + +Builds a RAW virtual machine image. + +```bash +just build-raw $target_image $tag +``` + +###### `build-iso` + +Builds an ISO virtual machine image. + +```bash +just build-iso $target_image $tag +``` + +###### `rebuild-qcow2` + +Rebuilds a QCOW2 virtual machine image. + +```bash +just rebuild-qcow2 $target_image $tag +``` + +###### `rebuild-raw` + +Rebuilds a RAW virtual machine image. + +```bash +just rebuild-raw $target_image $tag +``` + +###### `rebuild-iso` + +Rebuilds an ISO virtual machine image. + +```bash +just rebuild-iso $target_image $tag +``` + +##### Run Virtual Machines + +###### `run-vm-qcow2` + +Runs a virtual machine from a QCOW2 image. + +```bash +just run-vm-qcow2 $target_image $tag +``` + +###### `run-vm-raw` + +Runs a virtual machine from a RAW image. + +```bash +just run-vm-raw $target_image $tag +``` + +###### `run-vm-iso` + +Runs a virtual machine from an ISO. + +```bash +just run-vm-iso $target_image $tag +``` + +###### `spawn-vm` + +Runs a virtual machine using systemd-vmspawn. + +```bash +just spawn-vm rebuild="0" type="qcow2" ram="6G" +``` + +##### Lint and Format + +###### `lint` + +Runs shell check on all Bash scripts. + +###### `format` + +Runs shfmt on all Bash scripts. + ## Workflows ### build.yml -- cgit v1.2.3 From 3b91b7d8d9649cc709eea6c1f77ce6d8bffe18aa Mon Sep 17 00:00:00 2001 From: MymeType <109294126+MymeType@users.noreply.github.com> Date: Sun, 13 Apr 2025 21:59:24 +0200 Subject: fix: Add rootfs argument to _build-bib (#96) --- Justfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Justfile b/Justfile index 000a0c6..61e89df 100644 --- a/Justfile +++ b/Justfile @@ -188,7 +188,8 @@ _build-bib $target_image $tag $type $config: (_rootful_load_image target_image t set -euo pipefail args="--type ${type} " - args+="--use-librepo=True" + args+="--use-librepo=True " + args+="--rootfs=btrfs" if [[ $target_image == localhost/* ]]; then args+=" --local" -- cgit v1.2.3 From 3b4e9e6ecc96b6caec4e20f21fa5012ace2cceb1 Mon Sep 17 00:00:00 2001 From: MymeType <109294126+MymeType@users.noreply.github.com> Date: Fri, 18 Apr 2025 14:24:02 +0200 Subject: Update Justfile (#97) --- Justfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Justfile b/Justfile index 61e89df..f9c481c 100644 --- a/Justfile +++ b/Justfile @@ -289,9 +289,8 @@ _run-vm $target_image $tag $type $config: run_args+=(docker.io/qemux/qemu-docker) # Run the VM and open the browser to connect - podman run "${run_args[@]}" & - xdg-open http://localhost:${port} - fg "%podman" + (sleep 30 && xdg-open http://localhost:"$port") & + podman run "${run_args[@]}" # Run a virtual machine from a QCOW2 image [group('Run Virtal Machine')] -- cgit v1.2.3 From 8eb2594b6da704fee53f8fbb40d30454824c426e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 24 Apr 2025 08:42:53 +0100 Subject: chore(deps): update sigstore/cosign-installer action to v3.8.2 (#98) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8457604..ad0d565 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -166,7 +166,7 @@ jobs: # 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@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1 + uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) - name: Sign container image -- cgit v1.2.3 From bc02a2f79b0c1fc6bdd9f1e74fb3ada1d4c840f4 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Sun, 27 Apr 2025 21:27:01 -0400 Subject: Update README.md --- README.md | 143 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 72 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index 0f50ffa..629e3b0 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,78 @@ This template provides an out of the box workflow for getting an ISO image for y This template provides a way to upload the ISO that is generated from the workflow to a S3 bucket or it will be available as an artifact from the job. To upload to S3 we use a tool called [rclone](https://rclone.org/) which is able to use [many S3 providers](https://rclone.org/s3/). For more details on how to configure this see the details [below](#build-isoyml). +## Workflows + +### build.yml + +This 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. + +### build-iso.yml + +This workflow creates an ISO from your OCI image by utilizing the [bootc-image-builder](https://osbuild.org/docs/bootc/) to generate an ISO. In order to use this workflow you must complete the following steps: + +- Modify `iso.toml` to point to your custom image before generating an ISO. +- If you changed your image name from the default in `build.yml` then in the `build-iso.yml` file edit the `IMAGE_REGISTRY` and `DEFAULT_TAG` environment variables with the correct values. If you did not make changes, skip this step. +- Finally, if you want to upload your ISOs to S3 then you will need to add your S3 configuration to the repository's Action secrets. This can be found by going to your repository settings, under `Secrets and Variables` -> `Actions`. You will need to add the following + - `S3_PROVIDER` - Must match one of the values from the [supported list](https://rclone.org/s3/) + - `S3_BUCKET_NAME` - Your unique bucket name + - `S3_ACCESS_KEY_ID` - It is recommended that you make a separate key just for this workflow + - `S3_SECRET_ACCESS_KEY` - See above. + - `S3_REGION` - The region your bucket lives in. If you do not know then set this value to `auto`. + - `S3_ENDPOINT` - This value will be specific to the bucket as well. + +Once the workflow is done, you'll find it either in your S3 bucket or as part of the summary under `Artifacts` after the workflow is completed. + +#### Container Signing + +Container signing is important for end-user security and is enabled on all Universal Blue images. It is recommended you set this up, and by default the image builds *will fail* if you don't. + +This provides users a method of verifying the image. + +1. Install the [cosign CLI tool](https://edu.chainguard.dev/open-source/sigstore/cosign/how-to-install-cosign/#installing-cosign-with-the-cosign-binary) + +2. Run inside your repo folder: + + ```bash + cosign generate-key-pair + ``` + + + - Do NOT put in a password when it asks you to, just press enter. The signing key will be used in GitHub Actions and will not work if it is encrypted. + +> [!WARNING] +> Be careful to *never* accidentally commit `cosign.key` into your git repo. + +3. Add the private key to GitHub + + - This can also be done manually. Go to your repository settings, under `Secrets and Variables` -> `Actions` + ![image](https://user-images.githubusercontent.com/1264109/216735595-0ecf1b66-b9ee-439e-87d7-c8cc43c2110a.png) + Add a new secret and name it `SIGNING_SECRET`, then paste the contents of `cosign.key` into the secret and save it. Make sure it's the .key file and not the .pub file. Once done, it should look like this: + ![image](https://user-images.githubusercontent.com/1264109/216735690-2d19271f-cee2-45ac-a039-23e6a4c16b34.png) + + - (CLI instructions) If you have the `github-cli` installed, run: + + ```bash + gh secret set SIGNING_SECRET < cosign.key + ``` + +4. Commit the `cosign.pub` file to the root of your git repository. + +# Community + +- [**bootc discussion forums**](https://github.com/bootc-dev/bootc/discussions) - Nothing in this template is ublue specific, the upstream bootc project has a discussions forum where custom image builders can hang out and ask questions. + +## Artifacthub + +This template comes with the necessary tooling to index your image on [artifacthub.io](https://artifacthub.io), use the `artifacthub-repo.yml` file at the root to verify yourself as the publisher. This is important to you for a few reasons: + +- The value of artifacthub is it's one place for people to index their custom images, and since we depend on each other to learn, it helps grow the community. +- You get to see your pet project listed with the other cool projects in Cloud Native. +- Since the site puts your README front and center, it's a good way to learn how to write a good README, learn some marketing, finding your audience, etc. + +[Discussion thread](https://universal-blue.discourse.group/t/listing-your-custom-image-on-artifacthub/6446) + + ### Justfile Documentation This `Justfile` contains various commands and configurations for building and managing container images and virtual machine images using Podman and other utilities. @@ -196,77 +268,6 @@ Runs shell check on all Bash scripts. Runs shfmt on all Bash scripts. -## Workflows - -### build.yml - -This 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. - -### build-iso.yml - -This workflow creates an ISO from your OCI image by utilizing the [bootc-image-builder](https://osbuild.org/docs/bootc/) to generate an ISO. In order to use this workflow you must complete the following steps: - -- Modify `iso.toml` to point to your custom image before generating an ISO. -- If you changed your image name from the default in `build.yml` then in the `build-iso.yml` file edit the `IMAGE_REGISTRY` and `DEFAULT_TAG` environment variables with the correct values. If you did not make changes, skip this step. -- Finally, if you want to upload your ISOs to S3 then you will need to add your S3 configuration to the repository's Action secrets. This can be found by going to your repository settings, under `Secrets and Variables` -> `Actions`. You will need to add the following - - `S3_PROVIDER` - Must match one of the values from the [supported list](https://rclone.org/s3/) - - `S3_BUCKET_NAME` - Your unique bucket name - - `S3_ACCESS_KEY_ID` - It is recommended that you make a separate key just for this workflow - - `S3_SECRET_ACCESS_KEY` - See above. - - `S3_REGION` - The region your bucket lives in. If you do not know then set this value to `auto`. - - `S3_ENDPOINT` - This value will be specific to the bucket as well. - -Once the workflow is done, you'll find it either in your S3 bucket or as part of the summary under `Artifacts` after the workflow is completed. - -#### Container Signing - -Container signing is important for end-user security and is enabled on all Universal Blue images. It is recommended you set this up, and by default the image builds *will fail* if you don't. - -This provides users a method of verifying the image. - -1. Install the [cosign CLI tool](https://edu.chainguard.dev/open-source/sigstore/cosign/how-to-install-cosign/#installing-cosign-with-the-cosign-binary) - -2. Run inside your repo folder: - - ```bash - cosign generate-key-pair - ``` - - - - Do NOT put in a password when it asks you to, just press enter. The signing key will be used in GitHub Actions and will not work if it is encrypted. - -> [!WARNING] -> Be careful to *never* accidentally commit `cosign.key` into your git repo. - -3. Add the private key to GitHub - - - This can also be done manually. Go to your repository settings, under `Secrets and Variables` -> `Actions` - ![image](https://user-images.githubusercontent.com/1264109/216735595-0ecf1b66-b9ee-439e-87d7-c8cc43c2110a.png) - Add a new secret and name it `SIGNING_SECRET`, then paste the contents of `cosign.key` into the secret and save it. Make sure it's the .key file and not the .pub file. Once done, it should look like this: - ![image](https://user-images.githubusercontent.com/1264109/216735690-2d19271f-cee2-45ac-a039-23e6a4c16b34.png) - - - (CLI instructions) If you have the `github-cli` installed, run: - - ```bash - gh secret set SIGNING_SECRET < cosign.key - ``` - -4. Commit the `cosign.pub` file to the root of your git repository. - -# Community - -- [**bootc discussion forums**](https://github.com/bootc-dev/bootc/discussions) - Nothing in this template is ublue specific, the upstream bootc project has a discussions forum where custom image builders can hang out and ask questions. - -## Artifacthub - -This template comes with the necessary tooling to index your image on [artifacthub.io](https://artifacthub.io), use the `artifacthub-repo.yml` file at the root to verify yourself as the publisher. This is important to you for a few reasons: - -- The value of artifacthub is it's one place for people to index their custom images, and since we depend on each other to learn, it helps grow the community. -- You get to see your pet project listed with the other cool projects in Cloud Native. -- Since the site puts your README front and center, it's a good way to learn how to write a good README, learn some marketing, finding your audience, etc. - -[Discussion thread](https://universal-blue.discourse.group/t/listing-your-custom-image-on-artifacthub/6446) - ## Community Examples - [m2os](https://github.com/m2giles/m2os) -- cgit v1.2.3 From 3f674c2ed1e4ffabbb4fa1433ef8d54dc4f1da54 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Sun, 27 Apr 2025 21:30:26 -0400 Subject: Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 629e3b0..8828991 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,12 @@ Working knowledge in the following topics: - Github Workflows - https://docs.github.com/en/actions/using-workflows +# Video Tutorial + +TesterTech has made a tutorial video, check it out: + +[![Video Tutorial](https://img.youtube.com/vi/IxBl11Zmq5w/0.jpg)](https://www.youtube.com/watch?v=IxBl11Zmq5wE) + # How to Use ## Template -- cgit v1.2.3 From 5ad844fd7a579bcfc8483068af537aa4bcffed0f Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Mon, 28 Apr 2025 03:32:25 +0200 Subject: Update README.md (#101) --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8828991..b853805 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,8 @@ # Purpose This repository is meant to be a template for building your own custom Universal Blue image. This template is the recommended way to make customizations to any image published by the Universal Blue Project: -- [Aurora](https://getaurora.dev/) -- [Bazzite](https://bazzite.gg/) -- [Bluefin](https://projectbluefin.io/) -- [uCore](https://projectucore.io/) -- [main](https://github.com/ublue-os/main/) -- [hwe](https://github.com/ublue-os/hwe/) +- Products: [Aurora](https://getaurora.dev/), [Bazzite](https://bazzite.gg/), [Bluefin](https://projectbluefin.io/), [uCore](https://projectucore.io/) +- Base images: [main](https://github.com/ublue-os/main/) - the product images build on these and may be a better starting point depending on what you want. or any other base image if you want to start from scratch: -- cgit v1.2.3 From dc8eee6c0937c758ce1e2e4750fa1cfba2db5e10 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Sun, 27 Apr 2025 21:35:49 -0400 Subject: Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index b853805..97f09ac 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,7 @@ This repository is meant to be a template for building your own custom Universal or any other base image if you want to start from scratch: - Fedora: `quay.io/fedora/fedora-bootc:41` -- CentOS Stream 9: `quay.io/centos-bootc/centos-bootc:stream9` -- CentOS Stream 10 (in development): `quay.io/centos-bootc/centos-bootc:stream10` +- CentOS Stream 10: `quay.io/centos-bootc/centos-bootc:stream10` This template includes a Containerfile and a Github workflow for building the container image, signing, and proper metadata to be listed on [artifacthub](https://artifacthub.io/). As soon as the workflow is enabled in your repository, it will build the container image and push it to the Github Container Registry. -- cgit v1.2.3 From c33279cddfcc3bc28d2fcb3ac53ec16c875c3072 Mon Sep 17 00:00:00 2001 From: "Jorge O. Castro" Date: Sun, 27 Apr 2025 22:28:17 -0400 Subject: Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 97f09ac..9ada6bb 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Purpose -This repository is meant to be a template for building your own custom Universal Blue image. This template is the recommended way to make customizations to any image published by the Universal Blue Project: +This repository is meant to be a template for building your own custom [bootc](https://github.com/bootc-dev/bootc) image. This template is the recommended way to make customizations to any image published by the Universal Blue Project: - Products: [Aurora](https://getaurora.dev/), [Bazzite](https://bazzite.gg/), [Bluefin](https://projectbluefin.io/), [uCore](https://projectucore.io/) - Base images: [main](https://github.com/ublue-os/main/) - the product images build on these and may be a better starting point depending on what you want. -- cgit v1.2.3 From f825b61c85447dcba26f01747f9323e754b03eef Mon Sep 17 00:00:00 2001 From: Freya Gustavsson Date: Mon, 5 May 2025 18:21:58 +0200 Subject: feat: Add more community examples (#103) This adds two more example bootc images that are based off of this template. One of which is my own VeneOS and the other being Amy OS. Signed-off-by: Freya Gustavsson --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9ada6bb..609f6c8 100644 --- a/README.md +++ b/README.md @@ -271,6 +271,8 @@ Runs shfmt on all Bash scripts. ## Community Examples -- [m2os](https://github.com/m2giles/m2os) -- [bos](https://github.com/bsherman/bos) -- [homer](https://github.com/bketelsen/homer/) +- [m2Giles' OS](https://github.com/m2giles/m2os) +- [bOS](https://github.com/bsherman/bos) +- [Homer](https://github.com/bketelsen/homer/) +- [Amy OS](https://github.com/astrovm/amyos) +- [VeneOS](https://github.com/Venefilyn/veneos) -- cgit v1.2.3 From b7490fe2c9612f17fa8fc989b947707eee24ba38 Mon Sep 17 00:00:00 2001 From: James Reilly Date: Wed, 14 May 2025 22:13:36 +0530 Subject: fix(justfile): `just lint` and `just format` pass when `shellcheck` and `shfmt` do not exist (#105) --- Justfile | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Justfile b/Justfile index f9c481c..0078339 100644 --- a/Justfile +++ b/Justfile @@ -325,8 +325,24 @@ spawn-vm rebuild="0" type="qcow2" ram="6G": # Runs shell check on all Bash scripts lint: + #!/usr/bin/env bash + set -eoux pipefail + # Check if shellcheck is installed + if ! command -v shellcheck &> /dev/null; then + echo "shellcheck could not be found. Please install it." + exit 1 + fi + # Run shellcheck on all Bash scripts /usr/bin/find . -iname "*.sh" -type f -exec shellcheck "{}" ';' # Runs shfmt on all Bash scripts format: + #!/usr/bin/env bash + set -eoux pipefail + # Check if shfmt is installed + if ! command -v shfmt &> /dev/null; then + echo "shellcheck could not be found. Please install it." + exit 1 + fi + # Run shfmt on all Bash scripts /usr/bin/find . -iname "*.sh" -type f -exec shfmt --write "{}" ';' -- cgit v1.2.3 From 95eb2ba745e416e6db2556fb1de7f7fb1a6a6b9b Mon Sep 17 00:00:00 2001 From: James Reilly Date: Tue, 20 May 2025 05:02:39 +0530 Subject: Fix(justfile): update qemu image name (#107) --- Justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Justfile b/Justfile index 0078339..3fe162f 100644 --- a/Justfile +++ b/Justfile @@ -286,7 +286,7 @@ _run-vm $target_image $tag $type $config: run_args+=(--env "GPU=Y") run_args+=(--device=/dev/kvm) run_args+=(--volume "${PWD}/${image_file}":"/boot.${type}") - run_args+=(docker.io/qemux/qemu-docker) + run_args+=(docker.io/qemux/qemu) # Run the VM and open the browser to connect (sleep 30 && xdg-open http://localhost:"$port") & -- cgit v1.2.3 From 2fa28f0598b94db3b842cc24df1e0d02e8ab43f6 Mon Sep 17 00:00:00 2001 From: renner <80410025+renner0e@users.noreply.github.com> Date: Mon, 26 May 2025 02:34:51 +0200 Subject: fix(just): fix syntax error (#109) --- Justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Justfile b/Justfile index 3fe162f..098ad43 100644 --- a/Justfile +++ b/Justfile @@ -337,7 +337,7 @@ lint: # Runs shfmt on all Bash scripts format: - #!/usr/bin/env bash + #!/usr/bin/env bash set -eoux pipefail # Check if shfmt is installed if ! command -v shfmt &> /dev/null; then -- cgit v1.2.3 From 299c8e0e2f9054c07dfc2d26cadcc3164f7510cb Mon Sep 17 00:00:00 2001 From: Christian Glombek Date: Tue, 10 Jun 2025 02:15:44 +0200 Subject: chore: simplify (#111) --- .github/workflows/build-disk.yml | 115 +++++++++++++++++++++++++++++++++++++++ .github/workflows/build-iso.yml | 103 ----------------------------------- .github/workflows/build.yml | 46 +++++++--------- Justfile | 67 +++++++---------------- README.md | 32 +++++------ disk_config/disk.toml | 3 + disk_config/iso.toml | 19 +++++++ image.toml | 3 - iso.toml | 19 ------- 9 files changed, 189 insertions(+), 218 deletions(-) create mode 100644 .github/workflows/build-disk.yml delete mode 100644 .github/workflows/build-iso.yml create mode 100644 disk_config/disk.toml create mode 100644 disk_config/iso.toml delete mode 100644 image.toml delete mode 100644 iso.toml diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml new file mode 100644 index 0000000..e0d0cac --- /dev/null +++ b/.github/workflows/build-disk.yml @@ -0,0 +1,115 @@ +--- +name: Build disk images + +on: + workflow_dispatch: + inputs: + upload-to-s3: + description: "Upload to S3" + required: false + default: false + type: boolean + platform: + required: true + type: choice + options: + - amd64 + - arm64 + pull_request: + branches: + - main + paths: + - './disk_config/disk.toml' + - './disk_config/iso.toml' + - './.github/workflows/build-disk.yml' + +env: + IMAGE_NAME: ${{ github.event.repository.name }} # output of build.yml, keep in sync + IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit + DEFAULT_TAG: "latest" + BIB_IMAGE: "ghcr.io/lorbuschris/bootc-image-builder:20250608" # "quay.io/centos-bootc/bootc-image-builder:latest" - see https://github.com/osbuild/bootc-image-builder/pull/954 + +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + build: + name: Build disk images + runs-on: ${{ inputs.platform == 'amd64' && 'ubuntu-24.04' || 'ubuntu-24.04-arm' }} + strategy: + fail-fast: false + matrix: + disk-type: ["qcow2", "anaconda-iso"] + permissions: + contents: read + packages: read + id-token: write + + steps: + - name: Prepare environment + run: | + USER_UID=$(id -u) + USER_GID=$(id -g) + # Concatenate the types with a hyphen + DISK_TYPE=$(echo "${{ matrix.disk-type }}" | tr ' ' '-') + # Lowercase the image uri + echo "IMAGE_REGISTRY=${IMAGE_REGISTRY,,}" >> ${GITHUB_ENV} + echo "IMAGE_NAME=${IMAGE_NAME,,}" >> ${GITHUB_ENV} + echo "DISK_TYPE=${DISK_TYPE}" >> ${GITHUB_ENV} + echo "USER_UID=${USER_UID}" >> ${GITHUB_ENV} + echo "USER_GID=${USER_GID}" >> ${GITHUB_ENV} + + - name: Install dependencies + if: inputs.platform == 'arm64' + run: | + set -x + sudo apt update -y + sudo apt install -y \ + podman + + - name: Maximize build space + if: inputs.platform != 'arm64' + uses: ublue-os/remove-unwanted-software@cc0becac701cf642c8f0a6613bbdaf5dc36b259e # v9 + with: + remove-codeql: true + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Build disk images + id: build + uses: osbuild/bootc-image-builder-action@main + with: + builder-image: ${{ env.BIB_IMAGE }} + config-file: ${{ matrix.disk-type == 'anaconda-iso' && './disk_config/iso.toml' || './disk_config/disk.toml' }} + image: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }} + chown: ${{ env.USER_UID }}:${{ env.USER_GID }} + types: ${{ matrix.disk-type }} + additional-args: --use-librepo=True + + - name: Upload disk images and Checksum to Job Artifacts + if: inputs.upload-to-s3 != true && github.event_name != 'pull_request' + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + path: ${{ steps.build.outputs.output-directory }} + if-no-files-found: error + retention-days: 0 + compression-level: 0 + overwrite: true + + - name: Upload to S3 + if: inputs.upload-to-s3 == true && github.event_name != 'pull_request' + shell: bash + env: + RCLONE_CONFIG_S3_TYPE: s3 + RCLONE_CONFIG_S3_PROVIDER: ${{ secrets.S3_PROVIDER }} + RCLONE_CONFIG_S3_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }} + RCLONE_CONFIG_S3_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }} + RCLONE_CONFIG_S3_REGION: ${{ secrets.S3_REGION }} + RCLONE_CONFIG_S3_ENDPOINT: ${{ secrets.S3_ENDPOINT }} + SOURCE_DIR: ${{ steps.build.outputs.output-directory }} + run: | + sudo apt-get update + sudo apt-get install -y rclone + rclone copy $SOURCE_DIR S3:${{ secrets.S3_BUCKET_NAME }} \ No newline at end of file diff --git a/.github/workflows/build-iso.yml b/.github/workflows/build-iso.yml deleted file mode 100644 index b8aa38e..0000000 --- a/.github/workflows/build-iso.yml +++ /dev/null @@ -1,103 +0,0 @@ ---- -name: Build ISOs - -on: - workflow_dispatch: - inputs: - upload-to-s3: - description: "Upload to S3" - required: false - default: false - type: boolean - platform: - required: true - type: choice - options: - - amd64 - - arm64 - pull_request: - branches: - - main - paths: - - './iso.toml' - - './.github/workflows/build-iso.yml' - - './Justfile' - -env: - IMAGE_REGISTRY: "ghcr.io/${{ github.repository }}" - DEFAULT_TAG: "latest" - -concurrency: - group: ${{ github.workflow }}-${{ github.ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - name: Build ISOs - runs-on: ${{ inputs.platform == 'amd64' && 'ubuntu-24.04' || 'ubuntu-24.04-arm' }} - strategy: - fail-fast: false - permissions: - contents: read - packages: read - id-token: write - - steps: - - name: lower case the image registry in case of any capitalization - run: | - echo "IMAGE_REGISTRY=${IMAGE_REGISTRY,,}" >> ${GITHUB_ENV} - - - name: Install dependencies - if: inputs.platform == 'arm64' - run: | - set -x - sudo apt update -y - sudo apt install -y \ - podman - - - name: Maximize build space - if: inputs.platform != 'arm64' - uses: ublue-os/remove-unwanted-software@cc0becac701cf642c8f0a6613bbdaf5dc36b259e # v9 - with: - remove-codeql: true - - - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - - name: Setup Just - uses: extractions/setup-just@e33e0265a09d6d736e2ee1e0eb685ef1de4669ff # v3 - - - name: Build ISO - id: build - uses: ublue-os/bootc-image-builder-action@main - with: - bootc-image-builder-image: ghcr.io/centos-workstation/bootc-image-builder:latest - use-librepo: true - config-file: ./iso.toml - image: ${{ env.IMAGE_REGISTRY }}:${{ env.DEFAULT_TAG }} - - - name: Upload ISOs and Checksum to Job Artifacts - if: inputs.upload-to-s3 != true && github.event_name != 'pull_request' - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 - with: - path: ${{ steps.build.outputs.output-directory }} - if-no-files-found: error - retention-days: 0 - compression-level: 0 - overwrite: true - - - name: Upload to S3 - if: inputs.upload-to-s3 == true && github.event_name != 'pull_request' - shell: bash - env: - RCLONE_CONFIG_S3_TYPE: s3 - RCLONE_CONFIG_S3_PROVIDER: ${{ secrets.S3_PROVIDER }} - RCLONE_CONFIG_S3_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }} - RCLONE_CONFIG_S3_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }} - RCLONE_CONFIG_S3_REGION: ${{ secrets.S3_REGION }} - RCLONE_CONFIG_S3_ENDPOINT: ${{ secrets.S3_ENDPOINT }} - SOURCE_DIR: ${{ steps.build.outputs.output-directory }} - run: | - sudo apt-get update - sudo apt-get install -y rclone - rclone copy $SOURCE_DIR S3:${{ secrets.S3_BUCKET_NAME }} \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ad0d565..8e6e384 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,5 @@ --- -name: Build Custom Image +name: Build container image on: pull_request: branches: @@ -14,10 +14,12 @@ on: workflow_dispatch: env: - IMAGE_NAME: "${{ github.event.repository.name }}" # the name of the image produced by this build, matches repo names 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 - ARTIFACTHUB_LOGO_URL: "https://avatars.githubusercontent.com/u/120078124?s=200&v=4" # You should put your own image here so that you get a fancy profile image on https://artifacthub.io/! + DEFAULT_TAG: "latest" concurrency: group: ${{ github.workflow }}-${{ github.ref || github.run_id }}-${{ inputs.brand_name}}-${{ inputs.stream_name }} @@ -34,6 +36,12 @@ 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 @@ -60,10 +68,10 @@ jobs: id: metadata with: # This generates all the tags for your image, you can add custom tags here too! - # By default, it should generate "latest" and "latest.(date here)". + # Default tags are "$DEFAULT_TAG" and "$DEFAULT_TAG.$date". tags: | - type=raw,value=latest - type=raw,value=latest.{{date 'YYYYMMDD'}} + 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 @@ -76,11 +84,11 @@ jobs: org.opencontainers.image.title=${{ env.IMAGE_NAME }} org.opencontainers.image.url=https://github.com/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} org.opencontainers.image.vendor=${{ github.repository_owner }} - org.opencontainers.image.version=latest + org.opencontainers.image.version=${{ env.DEFAULT_TAG }}.{{date 'YYYYMMDD'}} io.artifacthub.package.deprecated=false - io.artifacthub.package.keywords=bootc,ublue,universal-blue + io.artifacthub.package.keywords=${{ env.IMAGE_KEYWORDS }} io.artifacthub.package.license=Apache-2.0 - io.artifacthub.package.logo-url=${{ env.ARTIFACTHUB_LOGO_URL }} + io.artifacthub.package.logo-url=${{ env.IMAGE_LOGO_URL }} io.artifacthub.package.prerelease=false containers.bootc=1 sep-tags: " " @@ -133,20 +141,6 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - # Workaround bug where capital letters in your GitHub username make it impossible to push to GHCR. - # https://github.com/macbre/push-to-ghcr/issues/12 - - name: Lowercase Registry - id: registry_case - uses: ASzc/change-string-case-action@d0603cd0a7dd490be678164909f65c7737470a7f # v6 - with: - string: ${{ env.IMAGE_REGISTRY }} - - - name: Lowercase Image - id: image_case - uses: ASzc/change-string-case-action@d0603cd0a7dd490be678164909f65c7737470a7f # v6 - with: - string: ${{ env.IMAGE_NAME }} - - 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) @@ -155,8 +149,8 @@ jobs: REGISTRY_USER: ${{ github.actor }} REGISTRY_PASSWORD: ${{ github.token }} with: - registry: ${{ steps.registry_case.outputs.lowercase }} - image: ${{ steps.image_case.outputs.lowercase }} + registry: ${{ env.IMAGE_REGISTRY }} + image: ${{ env.IMAGE_NAME }} tags: ${{ steps.metadata.outputs.tags }} username: ${{ env.REGISTRY_USER }} password: ${{ env.REGISTRY_PASSWORD }} @@ -172,7 +166,7 @@ jobs: - name: Sign container image if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) run: | - IMAGE_FULL="${{ steps.registry_case.outputs.lowercase }}/${{ steps.image_case.outputs.lowercase }}" + 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 diff --git a/Justfile b/Justfile index 098ad43..6ea8bcf 100644 --- a/Justfile +++ b/Justfile @@ -1,7 +1,4 @@ -export repo_organization := env("GITHUB_REPOSITORY_OWNER", "yourname") -export image_name := env("IMAGE_NAME", "yourimage") -export centos_version := env("CENTOS_VERSION", "stream10") -export fedora_version := env("CENTOS_VERSION", "41") +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") @@ -74,47 +71,25 @@ sudoif command *args: # This Justfile recipe builds a container image using Podman. # # Arguments: -# $target_image - The tag you want to apply to the image (default: aurora). -# $tag - The tag for the image (default: lts). -# $dx - Enable DX (default: "0"). -# $hwe - Enable HWE (default: "0"). -# $gdx - Enable GDX (default: "0"). -# -# DX: -# Developer Experience (DX) is a feature that allows you to install the latest developer tools for your system. -# Packages include VScode, Docker, Distrobox, and more. -# HWE: -# Hardware Enablement (HWE) is a feature that allows you to install the latest hardware support for your system. -# Currently this install the Hyperscale SIG kernel which will stay ahead of the CentOS Stream kernel and enables btrfs -# GDX: https://docs.projectaurora.io/gdx/ -# GPU Developer Experience (GDX) creates a base as an AI and Graphics platform. -# Installs Nvidia drivers, CUDA, and other tools. +# $target_image - The tag you want to apply to the image (default: $image_name). +# $tag - The tag for the image (default: $default_tag). # # The script constructs the version string using the tag and the current date. # If the git working directory is clean, it also includes the short SHA of the current HEAD. # -# just build $target_image $tag $dx $hwe $gdx +# just build $target_image $tag # # Example usage: -# just build aurora lts 1 0 1 +# just build aurora lts # # This will build an image 'aurora:lts' with DX and GDX enabled. # # Build the image using the specified parameters -build $target_image=image_name $tag=default_tag $dx="0" $hwe="0" $gdx="0": +build $target_image=image_name $tag=default_tag: #!/usr/bin/env bash - # Get Version - ver="${tag}-${centos_version}.$(date +%Y%m%d)" - BUILD_ARGS=() - BUILD_ARGS+=("--build-arg" "MAJOR_VERSION=${centos_version}") - BUILD_ARGS+=("--build-arg" "IMAGE_NAME=${target_image}") - BUILD_ARGS+=("--build-arg" "IMAGE_VENDOR=${repo_organization}") - BUILD_ARGS+=("--build-arg" "ENABLE_DX=${dx}") - BUILD_ARGS+=("--build-arg" "ENABLE_HWE=${hwe}") - BUILD_ARGS+=("--build-arg" "ENABLE_GDX=${gdx}") if [[ -z "$(git status -s)" ]]; then BUILD_ARGS+=("--build-arg" "SHA_HEAD_SHORT=$(git rev-parse --short HEAD)") fi @@ -180,9 +155,9 @@ _rootful_load_image $target_image=image_name $tag=default_tag: # target_image: The name of the image to build (ex. localhost/fedora) # tag: The tag of the image to build (ex. latest) # type: The type of image to build (ex. qcow2, raw, iso) -# config: The configuration file to use for the build (default: image.toml) +# config: The configuration file to use for the build (default: disk_config/disk.toml) -# Example: just _rebuild-bib localhost/fedora latest qcow2 image.toml +# Example: just _rebuild-bib localhost/fedora latest qcow2 disk_config/disk.toml _build-bib $target_image $tag $type $config: (_rootful_load_image target_image tag) #!/usr/bin/env bash set -euo pipefail @@ -191,10 +166,6 @@ _build-bib $target_image $tag $type $config: (_rootful_load_image target_image t args+="--use-librepo=True " args+="--rootfs=btrfs" - if [[ $target_image == localhost/* ]]; then - args+=" --local" - fi - BUILDTMP=$(mktemp -p "${PWD}" -d -t _build-bib.XXXXXXXXXX) sudo podman run \ @@ -221,34 +192,34 @@ _build-bib $target_image $tag $type $config: (_rootful_load_image target_image t # target_image: The name of the image to build (ex. localhost/fedora) # tag: The tag of the image to build (ex. latest) # type: The type of image to build (ex. qcow2, raw, iso) -# config: The configuration file to use for the build (deafult: image.toml) +# config: The configuration file to use for the build (deafult: disk_config/disk.toml) -# Example: just _rebuild-bib localhost/fedora latest qcow2 image.toml +# Example: just _rebuild-bib localhost/fedora latest qcow2 disk_config/disk.toml _rebuild-bib $target_image $tag $type $config: (build target_image tag) && (_build-bib target_image tag type config) # Build a QCOW2 virtual machine image [group('Build Virtal Machine Image')] -build-qcow2 $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "qcow2" "image.toml") +build-qcow2 $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "qcow2" "disk_config/disk.toml") # Build a RAW virtual machine image [group('Build Virtal Machine Image')] -build-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "raw" "image.toml") +build-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "raw" "disk_config/disk.toml") # Build an ISO virtual machine image [group('Build Virtal Machine Image')] -build-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "iso" "iso.toml") +build-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "iso" "disk_config/iso.toml") # Rebuild a QCOW2 virtual machine image [group('Build Virtal Machine Image')] -rebuild-qcow2 $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "qcow2" "image.toml") +rebuild-qcow2 $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "qcow2" "disk_config/disk.toml") # Rebuild a RAW virtual machine image [group('Build Virtal Machine Image')] -rebuild-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "raw" "image.toml") +rebuild-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "raw" "disk_config/disk.toml") # Rebuild an ISO virtual machine image [group('Build Virtal Machine Image')] -rebuild-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "iso" "iso.toml") +rebuild-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "iso" "disk_config/iso.toml") # Run a virtual machine with the specified image type and configuration _run-vm $target_image $tag $type $config: @@ -294,15 +265,15 @@ _run-vm $target_image $tag $type $config: # Run a virtual machine from a QCOW2 image [group('Run Virtal Machine')] -run-vm-qcow2 $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "qcow2" "image.toml") +run-vm-qcow2 $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "qcow2" "disk_config/disk.toml") # Run a virtual machine from a RAW image [group('Run Virtal Machine')] -run-vm-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "raw" "image.toml") +run-vm-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "raw" "disk_config/disk.toml") # Run a virtual machine from an ISO [group('Run Virtal Machine')] -run-vm-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "iso" "iso.toml") +run-vm-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "iso" "disk_config/iso.toml") # Run a virtual machine using systemd-vmspawn [group('Run Virtal Machine')] diff --git a/README.md b/README.md index 609f6c8..86aaf76 100644 --- a/README.md +++ b/README.md @@ -46,11 +46,11 @@ This file defines the operations used to customize the selected image. It contai - add additional RPM packages - add binaries as a layer from other images -## Building an ISO +## Building disk images -This template provides an out of the box workflow for getting an ISO image for your custom OCI image which can be used to directly install onto your machines. +This template provides an out of the box workflow for creating ISO and other disk images for your custom OCI image which can be used to directly install onto your machines. -This template provides a way to upload the ISO that is generated from the workflow to a S3 bucket or it will be available as an artifact from the job. To upload to S3 we use a tool called [rclone](https://rclone.org/) which is able to use [many S3 providers](https://rclone.org/s3/). For more details on how to configure this see the details [below](#build-isoyml). +This template provides a way to upload the disk images that is generated from the workflow to a S3 bucket or it will be available as an artifact from the job. To upload to S3 we use a tool called [rclone](https://rclone.org/) which is able to use [many S3 providers](https://rclone.org/s3/). For more details on how to configure this see the details [below](#build-isoyml). ## Workflows @@ -58,13 +58,13 @@ This template provides a way to upload the ISO that is generated from the workfl This 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. -### build-iso.yml +### build-disk.yml -This workflow creates an ISO from your OCI image by utilizing the [bootc-image-builder](https://osbuild.org/docs/bootc/) to generate an ISO. In order to use this workflow you must complete the following steps: +This workflow creates a disk images from your OCI image by utilizing the [bootc-image-builder](https://osbuild.org/docs/bootc/). In order to use this workflow you must complete the following steps: -- Modify `iso.toml` to point to your custom image before generating an ISO. -- If you changed your image name from the default in `build.yml` then in the `build-iso.yml` file edit the `IMAGE_REGISTRY` and `DEFAULT_TAG` environment variables with the correct values. If you did not make changes, skip this step. -- Finally, if you want to upload your ISOs to S3 then you will need to add your S3 configuration to the repository's Action secrets. This can be found by going to your repository settings, under `Secrets and Variables` -> `Actions`. You will need to add the following +- Modify `disk_config/iso.toml` to point to your custom container image before generating an ISO image. +- If you changed your image name from the default in `build.yml` then in the `build-disk.yml` file edit the `IMAGE_REGISTRY`, `IMAGE_NAME` and `DEFAULT_TAG` environment variables with the correct values. If you did not make changes, skip this step. +- Finally, if you want to upload your disk images to S3 then you will need to add your S3 configuration to the repository's Action secrets. This can be found by going to your repository settings, under `Secrets and Variables` -> `Actions`. You will need to add the following - `S3_PROVIDER` - Must match one of the values from the [supported list](https://rclone.org/s3/) - `S3_BUCKET_NAME` - Your unique bucket name - `S3_ACCESS_KEY_ID` - It is recommended that you make a separate key just for this workflow @@ -72,7 +72,7 @@ This workflow creates an ISO from your OCI image by utilizing the [bootc-image-b - `S3_REGION` - The region your bucket lives in. If you do not know then set this value to `auto`. - `S3_ENDPOINT` - This value will be specific to the bucket as well. -Once the workflow is done, you'll find it either in your S3 bucket or as part of the summary under `Artifacts` after the workflow is completed. +Once the workflow is done, you'll find the disk images either in your S3 bucket or as part of the summary under `Artifacts` after the workflow is completed. #### Container Signing @@ -130,10 +130,7 @@ This `Justfile` contains various commands and configurations for building and ma #### Environment Variables -- `repo_organization`: The GitHub repository owner (default: "yourname"). -- `image_name`: The name of the image (default: "yourimage"). -- `centos_version`: The CentOS version (default: "stream10"). -- `fedora_version`: The Fedora version (default: "41"). +- `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"). @@ -165,15 +162,12 @@ Cleans the repository by removing build artifacts. Builds a container image using Podman. ```bash -just build $target_image $tag $dx $hwe $gdx +just build $target_image $tag ``` Arguments: -- `$target_image`: The tag you want to apply to the image (default: aurora). -- `$tag`: The tag for the image (default: lts). -- `$dx`: Enable DX (default: "0"). -- `$hwe`: Enable HWE (default: "0"). -- `$gdx`: Enable GDX (default: "0"). +- `$target_image`: The tag you want to apply to the image (default: `$image_name`). +- `$tag`: The tag for the image (default: `$default_tag`). ##### Building Virtual Machines and ISOs diff --git a/disk_config/disk.toml b/disk_config/disk.toml new file mode 100644 index 0000000..7478400 --- /dev/null +++ b/disk_config/disk.toml @@ -0,0 +1,3 @@ +[[customizations.filesystem]] +mountpoint = "/" +minsize = "20 GiB" diff --git a/disk_config/iso.toml b/disk_config/iso.toml new file mode 100644 index 0000000..d4c8f37 --- /dev/null +++ b/disk_config/iso.toml @@ -0,0 +1,19 @@ +[customizations.installer.kickstart] +contents = """ +%post +bootc switch --mutate-in-place --transport registry ghcr.io/ublue-os/image-template:latest +%end +""" + +[customizations.installer.modules] +enable = [ + "org.fedoraproject.Anaconda.Modules.Storage" +] +disable = [ + "org.fedoraproject.Anaconda.Modules.Network", + "org.fedoraproject.Anaconda.Modules.Security", + "org.fedoraproject.Anaconda.Modules.Services", + "org.fedoraproject.Anaconda.Modules.Users", + "org.fedoraproject.Anaconda.Modules.Subscription", + "org.fedoraproject.Anaconda.Modules.Timezone" +] diff --git a/image.toml b/image.toml deleted file mode 100644 index 7478400..0000000 --- a/image.toml +++ /dev/null @@ -1,3 +0,0 @@ -[[customizations.filesystem]] -mountpoint = "/" -minsize = "20 GiB" diff --git a/iso.toml b/iso.toml deleted file mode 100644 index 21b6913..0000000 --- a/iso.toml +++ /dev/null @@ -1,19 +0,0 @@ -[customizations.installer.kickstart] -contents = """ -%post -bootc switch --mutate-in-place --transport registry ghcr.io/yourrepo/yourimage:latest -%end -""" - -[customizations.installer.modules] -enable = [ - "org.fedoraproject.Anaconda.Modules.Storage" -] -disable = [ - "org.fedoraproject.Anaconda.Modules.Network", - "org.fedoraproject.Anaconda.Modules.Security", - "org.fedoraproject.Anaconda.Modules.Services", - "org.fedoraproject.Anaconda.Modules.Users", - "org.fedoraproject.Anaconda.Modules.Subscription", - "org.fedoraproject.Anaconda.Modules.Timezone" -] -- cgit v1.2.3 From fed4ea695d6fb38fd1d8c4306768faa51be99e0a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Jun 2025 13:54:32 +0300 Subject: chore(deps): update sigstore/cosign-installer action to v3.9.0 (#112) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8e6e384..db95edd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -160,7 +160,7 @@ jobs: # 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@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2 + uses: sigstore/cosign-installer@fb28c2b6339dcd94da6e4cbcbc5e888961f6f8c3 # v3.9.0 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) - name: Sign container image -- cgit v1.2.3 From 7cc76c4fd067355c21267e33e9634d72aeb610b8 Mon Sep 17 00:00:00 2001 From: Zeglius <33781398+Zeglius@users.noreply.github.com> Date: Tue, 24 Jun 2025 06:09:43 +0200 Subject: feat: Bind mount podman container storage to btrfs loopback (#115) --- .github/workflows/build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index db95edd..17f3bcd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,7 +51,10 @@ jobs: # uses: ublue-os/remove-unwanted-software@517622d6452028f266b7ba4cc9a123b5f58a6b53 # v7 # with: # remove-codeql: true - + + - name: Mount BTRFS for podman storage + uses: ublue-os/container-storage-action@main + - name: Get current date id: date run: | -- cgit v1.2.3 From df282f92f3537f64f8615f8288aa1b3892a17b8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:53:32 +0300 Subject: chore(deps): bump sigstore/cosign-installer from 3.9.0 to 3.9.1 (#118) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 17f3bcd..9a6b4b1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -163,7 +163,7 @@ jobs: # 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@fb28c2b6339dcd94da6e4cbcbc5e888961f6f8c3 # v3.9.0 + uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3.9.1 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) - name: Sign container image -- cgit v1.2.3 From a509fc8872e395bc9c62e40f2be9ea742bfccec4 Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Thu, 17 Jul 2025 16:45:28 -0400 Subject: chore(deps): update sigstore/cosign-installer action to v3.9.2 (#119) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9a6b4b1..9776ec9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -163,7 +163,7 @@ jobs: # 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@398d4b0eeef1380460a10c8013a76f728fb906ac # v3.9.1 + uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) - name: Sign container image -- cgit v1.2.3 From b1e057c345c9a1c10535262f2de347bec99e9a50 Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Fri, 1 Aug 2025 08:59:22 -0400 Subject: chore(deps): update docker/metadata-action digest to c1e5197 (#122) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9776ec9..02d560f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -67,7 +67,7 @@ jobs: # 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@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5 + uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5 id: metadata with: # This generates all the tags for your image, you can add custom tags here too! -- cgit v1.2.3 From 3fd368770edd19fe3d6b3fe3a660f9c5f64cf7a3 Mon Sep 17 00:00:00 2001 From: Brennen Puth Date: Sat, 2 Aug 2025 09:18:43 -0400 Subject: docs(README): Giving the README a fresh coat of paint (#123) * Full README spruce-up * First glance changes * Bring community section into line * Quick wording fix * Add Fedora Atomic to list of bootc systems * Add to base image instructions and take some content out of first paragraph * Better repository contents section * Remove TODO and reword community section again --- README.md | 292 ++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 140 insertions(+), 152 deletions(-) diff --git a/README.md b/README.md index 86aaf76..490c5e6 100644 --- a/README.md +++ b/README.md @@ -1,163 +1,185 @@ # image-template -# Purpose +This repository is meant to be a template for building your own custom [bootc](https://github.com/bootc-dev/bootc) image. This template is the recommended way to make customizations to any image published by the Universal Blue Project. -This repository is meant to be a template for building your own custom [bootc](https://github.com/bootc-dev/bootc) image. This template is the recommended way to make customizations to any image published by the Universal Blue Project: -- Products: [Aurora](https://getaurora.dev/), [Bazzite](https://bazzite.gg/), [Bluefin](https://projectbluefin.io/), [uCore](https://projectucore.io/) -- Base images: [main](https://github.com/ublue-os/main/) - the product images build on these and may be a better starting point depending on what you want. +# Community -or any other base image if you want to start from scratch: +If you have questions about this template after following the instructions, try the following spaces: +- [Universal Blue Forums](https://universal-blue.discourse.group/) +- [Universal Blue Discord](https://discord.gg/WEu6BdFEtp) +- [bootc discussion forums](https://github.com/bootc-dev/bootc/discussions) - This is not an Universal Blue managed space, but is an excellent resource if you run into issues with building bootc images. -- Fedora: `quay.io/fedora/fedora-bootc:41` -- CentOS Stream 10: `quay.io/centos-bootc/centos-bootc:stream10` +# How to Use -This template includes a Containerfile and a Github workflow for building the container image, signing, and proper metadata to be listed on [artifacthub](https://artifacthub.io/). As soon as the workflow is enabled in your repository, it will build the container image and push it to the Github Container Registry. +To get started on your first bootc image, simply read and follow the steps in the next few headings. +If you prefer instructions in video form, TesterTech created an excellent tutorial, embedded below. -# Prerequisites +[![Video Tutorial](https://img.youtube.com/vi/IxBl11Zmq5w/0.jpg)](https://www.youtube.com/watch?v=IxBl11Zmq5wE) -Working knowledge in the following topics: +## Step 0: Prerequisites -- Containers - - https://www.youtube.com/watch?v=SnSH8Ht3MIc - - https://www.mankier.com/5/Containerfile -- bootc - - https://bootc-dev.github.io/bootc/ -- Fedora Silverblue (and other Fedora Atomic variants) - - https://docs.fedoraproject.org/en-US/fedora-silverblue/ -- Github Workflows - - https://docs.github.com/en/actions/using-workflows +These steps assume you have the following: +- A Github Account +- A machine running a bootc image (e.g. Bazzite, Bluefin, Aurora, or Fedora Atomic) +- Experience installing and using CLI programs -# Video Tutorial +## Step 1: Preparing the Template -TesterTech has made a tutorial video, check it out: +### Step 1a: Copying the Template -[![Video Tutorial](https://img.youtube.com/vi/IxBl11Zmq5w/0.jpg)](https://www.youtube.com/watch?v=IxBl11Zmq5wE) +Select `Use this Template` on this page. You can set the name and description of your repository to whatever you would like, but all other settings should be left untouched. -# How to Use +Once you have finished copying the template, you need to enable the Github Actions workflows for your new repository. +To enable the workflows, go to the `Actions` tab of the new repository and click the button to enable workflows. -## Template +### Step 1b: Cloning the New Repository -Select `Use this Template` and create a new repository from it. To enable the workflows, you may need to go the `Actions` tab of the new repository and click to enable workflows. +Here I will defer to the much superior GitHub documentation on the matter. You can use whichever method is easiest. +[GitHub Documentation](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) -## Containerfile +Once you have the repository on your local drive, proceed to the next step. -This file defines the operations used to customize the selected image. It contains examples of possible modifications, including how to: -- change the upstream from which the custom image is derived -- add additional RPM packages -- add binaries as a layer from other images +## Step 2: Initial Setup -## Building disk images +### Step 2a: Creating a Cosign Key -This template provides an out of the box workflow for creating ISO and other disk images for your custom OCI image which can be used to directly install onto your machines. +Container signing is important for end-user security and is enabled on all Universal Blue images. By default the image builds *will fail* if you don't. -This template provides a way to upload the disk images that is generated from the workflow to a S3 bucket or it will be available as an artifact from the job. To upload to S3 we use a tool called [rclone](https://rclone.org/) which is able to use [many S3 providers](https://rclone.org/s3/). For more details on how to configure this see the details [below](#build-isoyml). +First, install the [cosign CLI tool](https://edu.chainguard.dev/open-source/sigstore/cosign/how-to-install-cosign/#installing-cosign-with-the-cosign-binary) +With the cosign tool installed, run inside your repo folder: -## Workflows +```bash +cosign generate-key-pair +``` -### build.yml +Do NOT put in a password when it asks you to, just press enter. The signing key will be used in GitHub Actions and will not work if it is encrypted. -This 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. +> [!WARNING] +> Be careful to *never* accidentally commit `cosign.key` into your git repo. If this key goes out to the public, the security of your repository is compromised. -### build-disk.yml +Next, you need to add the key to GitHub. This makes use of GitHub's secret signing system. -This workflow creates a disk images from your OCI image by utilizing the [bootc-image-builder](https://osbuild.org/docs/bootc/). In order to use this workflow you must complete the following steps: +
+ Using the Github Web Interface (preferred) -- Modify `disk_config/iso.toml` to point to your custom container image before generating an ISO image. -- If you changed your image name from the default in `build.yml` then in the `build-disk.yml` file edit the `IMAGE_REGISTRY`, `IMAGE_NAME` and `DEFAULT_TAG` environment variables with the correct values. If you did not make changes, skip this step. -- Finally, if you want to upload your disk images to S3 then you will need to add your S3 configuration to the repository's Action secrets. This can be found by going to your repository settings, under `Secrets and Variables` -> `Actions`. You will need to add the following - - `S3_PROVIDER` - Must match one of the values from the [supported list](https://rclone.org/s3/) - - `S3_BUCKET_NAME` - Your unique bucket name - - `S3_ACCESS_KEY_ID` - It is recommended that you make a separate key just for this workflow - - `S3_SECRET_ACCESS_KEY` - See above. - - `S3_REGION` - The region your bucket lives in. If you do not know then set this value to `auto`. - - `S3_ENDPOINT` - This value will be specific to the bucket as well. + Go to your repository settings, under `Secrets and Variables` -> `Actions` + ![image](https://user-images.githubusercontent.com/1264109/216735595-0ecf1b66-b9ee-439e-87d7-c8cc43c2110a.png) + Add a new secret and name it `SIGNING_SECRET`, then paste the contents of `cosign.key` into the secret and save it. Make sure it's the .key file and not the .pub file. Once done, it should look like this: + ![image](https://user-images.githubusercontent.com/1264109/216735690-2d19271f-cee2-45ac-a039-23e6a4c16b34.png) +
+
+Using the Github CLI -Once the workflow is done, you'll find the disk images either in your S3 bucket or as part of the summary under `Artifacts` after the workflow is completed. +If you have the `github-cli` installed, run: -#### Container Signing +```bash +gh secret set SIGNING_SECRET < cosign.key +``` +
-Container signing is important for end-user security and is enabled on all Universal Blue images. It is recommended you set this up, and by default the image builds *will fail* if you don't. +### Step 2b: Choosing Your Base Image -This provides users a method of verifying the image. +To choose a base image, simply modify the line in the container file starting with `FROM`. This will be the image your image derives from, and is your starting point for modifications. +For a base image, you can choose any of the Universal Blue images or start from a Fedora Atomic system. Below this paragraph is a dropdown with a non-exhaustive list of potential base images. -1. Install the [cosign CLI tool](https://edu.chainguard.dev/open-source/sigstore/cosign/how-to-install-cosign/#installing-cosign-with-the-cosign-binary) +
+ Base Images -2. Run inside your repo folder: + - Bazzite: `ghcr.io/ublue-os/bazzite:stable` + - 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` - ```bash - cosign generate-key-pair - ``` + You can find more Universal Blue images on the [packages page](https://github.com/orgs/ublue-os/packages). +
- - - Do NOT put in a password when it asks you to, just press enter. The signing key will be used in GitHub Actions and will not work if it is encrypted. +If you don't know which image to pick, choosing the one your system is currently on is the best bet for a smooth transition. To find out what image your system currently uses, run the following command: +```bash +sudo bootc status +``` +This will show you all the info you need to know about your current image. The image you are currently on is displayed after `Booted image:`. Paste that information after the `FROM` statement in the Containerfile to set it as your base image. -> [!WARNING] -> Be careful to *never* accidentally commit `cosign.key` into your git repo. +### Step 2c: Changing Names -3. Add the private key to GitHub +Change the first line in the [Justfile](./Justfile) to your image's name. - - This can also be done manually. Go to your repository settings, under `Secrets and Variables` -> `Actions` - ![image](https://user-images.githubusercontent.com/1264109/216735595-0ecf1b66-b9ee-439e-87d7-c8cc43c2110a.png) - Add a new secret and name it `SIGNING_SECRET`, then paste the contents of `cosign.key` into the secret and save it. Make sure it's the .key file and not the .pub file. Once done, it should look like this: - ![image](https://user-images.githubusercontent.com/1264109/216735690-2d19271f-cee2-45ac-a039-23e6a4c16b34.png) +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 commit -m "Initial Setup" +git push +``` +Once pushed, go look at the Actions tab on your Github repository's page. The green checkmark should be showing on the top commit, which means your new image is ready! - - (CLI instructions) If you have the `github-cli` installed, run: +## Step 3: Switch to Your Image - ```bash - gh secret set SIGNING_SECRET < cosign.key - ``` +From your bootc system, run the following command substituting in your Github username and image name where noted. +```bash +sudo bootc switch ghcr.io// +``` +This should queue your image for the next reboot, which you can do immediately after the command finishes. You have officially set up your custom image! See the following section for an explanation of the important parts of the template for customization. -4. Commit the `cosign.pub` file to the root of your git repository. +# Repository Contents -# Community +## Containerfile -- [**bootc discussion forums**](https://github.com/bootc-dev/bootc/discussions) - Nothing in this template is ublue specific, the upstream bootc project has a discussions forum where custom image builders can hang out and ask questions. +The [Containerfile](./Containerfile) defines the operations used to customize the selected image.This file is the entrypoint for your image build, and works exactly like a regular podman Containerfile. For reference, please see the [Podman Documentation](https://docs.podman.io/en/latest/Introduction.html). -## Artifacthub +## build.sh -This template comes with the necessary tooling to index your image on [artifacthub.io](https://artifacthub.io), use the `artifacthub-repo.yml` file at the root to verify yourself as the publisher. This is important to you for a few reasons: +The [build.sh](./build_files/build.sh) file is called from your Containerfile. It is the best place to install new packages or make any other customization to your system. There are customization examples contained within it for your perusal. -- The value of artifacthub is it's one place for people to index their custom images, and since we depend on each other to learn, it helps grow the community. -- You get to see your pet project listed with the other cool projects in Cloud Native. -- Since the site puts your README front and center, it's a good way to learn how to write a good README, learn some marketing, finding your audience, etc. +## build.yml -[Discussion thread](https://universal-blue.discourse.group/t/listing-your-custom-image-on-artifacthub/6446) +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. +# Building Disk Images -### Justfile Documentation +This template provides an out of the box workflow for creating disk images (ISO, qcow, raw) for your custom OCI image which can be used to directly install onto your machines. -This `Justfile` contains various commands and configurations for building and managing container images and virtual machine images using Podman and other utilities. +This template provides a way to upload the disk images that is generated from the workflow to a S3 bucket. The disk images will also be available as an artifact from the job, if you wish to use an alternate provider. To upload to S3 we use [rclone](https://rclone.org/) which is able to use [many S3 providers](https://rclone.org/s3/). -#### Environment Variables +## Setting Up ISO Builds -- `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"). +The [build-disk.yml](./.github/workflows/build-disk.yml) Github Actions workflow creates a disk image from your OCI image by utilizing the [bootc-image-builder](https://osbuild.org/docs/bootc/). In order to use this workflow you must complete the following steps: -#### Aliases +1. Modify `disk_config/iso.toml` to point to your custom container image before generating an ISO image. +2. If you changed your image name from the default in `build.yml` then in the `build-disk.yml` file edit the `IMAGE_REGISTRY`, `IMAGE_NAME` and `DEFAULT_TAG` environment variables with the correct values. If you did not make changes, skip this step. +3. Finally, if you want to upload your disk images to S3 then you will need to add your S3 configuration to the repository's Action secrets. This can be found by going to your repository settings, under `Secrets and Variables` -> `Actions`. You will need to add the following + - `S3_PROVIDER` - Must match one of the values from the [supported list](https://rclone.org/s3/) + - `S3_BUCKET_NAME` - Your unique bucket name + - `S3_ACCESS_KEY_ID` - It is recommended that you make a separate key just for this workflow + - `S3_SECRET_ACCESS_KEY` - See above. + - `S3_REGION` - The region your bucket lives in. If you do not know then set this value to `auto`. + - `S3_ENDPOINT` - This value will be specific to the bucket as well. -- `build-vm`: Alias for `build-qcow2`. -- `rebuild-vm`: Alias for `rebuild-qcow2`. -- `run-vm`: Alias for `run-vm-qcow2`. +Once the workflow is done, you'll find the disk images either in your S3 bucket or as part of the summary under `Artifacts` after the workflow is completed. +# Artifacthub -#### Commands +This template comes with the necessary tooling to index your image on [artifacthub.io](https://artifacthub.io). Use the `artifacthub-repo.yml` file at the root to verify yourself as the publisher. This is important to you for a few reasons: -###### `check` +- The value of artifacthub is it's one place for people to index their custom images, and since we depend on each other to learn, it helps grow the community. +- You get to see your pet project listed with the other cool projects in Cloud Native. +- Since the site puts your README front and center, it's a good way to learn how to write a good README, learn some marketing, finding your audience, etc. -Checks the syntax of all `.just` files and the `Justfile`. +[Discussion Thread](https://universal-blue.discourse.group/t/listing-your-custom-image-on-artifacthub/6446) -###### `fix` +# Justfile Documentation -Fixes the syntax of all `.just` files and the `Justfile`. +The `Justfile` contains various commands and configurations for building and managing container images and virtual machine images using Podman and other utilities. +To use it, you must have installed [just](https://just.systems/man/en/introduction.html) from your package manager or manually. It is available by default on all Universal Blue images. -###### `clean` +## Environment Variables -Cleans the repository by removing build artifacts. +- `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"). -##### Build Commands +## Building The Image -###### `build` +### `just build` Builds a container image using Podman. @@ -169,9 +191,11 @@ Arguments: - `$target_image`: The tag you want to apply to the image (default: `$image_name`). - `$tag`: The tag for the image (default: `$default_tag`). -##### Building Virtual Machines and ISOs +## 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`. -###### `build-qcow2` +### `just build-qcow2` Builds a QCOW2 virtual machine image. @@ -179,49 +203,15 @@ Builds a QCOW2 virtual machine image. just build-qcow2 $target_image $tag ``` -###### `build-raw` - -Builds a RAW virtual machine image. - -```bash -just build-raw $target_image $tag -``` - -###### `build-iso` - -Builds an ISO virtual machine image. - -```bash -just build-iso $target_image $tag -``` - -###### `rebuild-qcow2` +### `just rebuild-qcow2` Rebuilds a QCOW2 virtual machine image. ```bash -just rebuild-qcow2 $target_image $tag -``` - -###### `rebuild-raw` - -Rebuilds a RAW virtual machine image. - -```bash -just rebuild-raw $target_image $tag +just rebuild-vm $target_image $tag ``` -###### `rebuild-iso` - -Rebuilds an ISO virtual machine image. - -```bash -just rebuild-iso $target_image $tag -``` - -##### Run Virtual Machines - -###### `run-vm-qcow2` +### `just run-vm-qcow2` Runs a virtual machine from a QCOW2 image. @@ -229,42 +219,40 @@ Runs a virtual machine from a QCOW2 image. just run-vm-qcow2 $target_image $tag ``` -###### `run-vm-raw` +### `just spawn-vm` -Runs a virtual machine from a RAW image. +Runs a virtual machine using systemd-vmspawn. ```bash -just run-vm-raw $target_image $tag +just spawn-vm rebuild="0" type="qcow2" ram="6G" ``` -###### `run-vm-iso` +## File Management -Runs a virtual machine from an ISO. +### `just check` -```bash -just run-vm-iso $target_image $tag -``` +Checks the syntax of all `.just` files and the `Justfile`. -###### `spawn-vm` +### `just fix` -Runs a virtual machine using systemd-vmspawn. +Fixes the syntax of all `.just` files and the `Justfile`. -```bash -just spawn-vm rebuild="0" type="qcow2" ram="6G" -``` +### `just clean` -##### Lint and Format +Cleans the repository by removing build artifacts. -###### `lint` +### `just lint` Runs shell check on all Bash scripts. -###### `format` +### `just format` Runs shfmt on all Bash scripts. ## Community Examples +These are images derived from this template (or similar enough to this template). Reference them when building your image! + - [m2Giles' OS](https://github.com/m2giles/m2os) - [bOS](https://github.com/bsherman/bos) - [Homer](https://github.com/bketelsen/homer/) -- cgit v1.2.3 From 9ac5d95c1a8e6d16c39a43e7c3ff79dc43e7a09f Mon Sep 17 00:00:00 2001 From: Lightprod Date: Wed, 6 Aug 2025 20:15:23 +0200 Subject: Fix Kickstart post installation script not executing (#126) Fixes https://github.com/osbuild/bootc-image-builder/issues/968 --- disk_config/iso.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/disk_config/iso.toml b/disk_config/iso.toml index d4c8f37..0a9c84f 100644 --- a/disk_config/iso.toml +++ b/disk_config/iso.toml @@ -7,7 +7,8 @@ bootc switch --mutate-in-place --transport registry ghcr.io/ublue-os/image-templ [customizations.installer.modules] enable = [ - "org.fedoraproject.Anaconda.Modules.Storage" + "org.fedoraproject.Anaconda.Modules.Storage", + "org.fedoraproject.Anaconda.Modules.Runtime" ] disable = [ "org.fedoraproject.Anaconda.Modules.Network", -- cgit v1.2.3 From 9ad8c318a9f68d57cb25fd047ec617b381ec6624 Mon Sep 17 00:00:00 2001 From: Lightprod Date: Wed, 6 Aug 2025 21:24:59 +0200 Subject: Feat: Change Anaconda settings for non-gnome images (#127) * feat: Add a workable default for KDE images * Rename iso.toml to iso-gnome.toml * Revert "Rename iso.toml to iso-gnome.toml" This reverts commit 02e510f27900439e65ebe8f2153175bb0924d1ad. * Rename default iso.toml to iso-gnome.toml --------- Co-authored-by: Lightprod --- disk_config/iso-gnome.toml | 20 ++++++++++++++++++++ disk_config/iso-kde.toml | 21 +++++++++++++++++++++ disk_config/iso.toml | 20 -------------------- 3 files changed, 41 insertions(+), 20 deletions(-) create mode 100644 disk_config/iso-gnome.toml create mode 100644 disk_config/iso-kde.toml delete mode 100644 disk_config/iso.toml diff --git a/disk_config/iso-gnome.toml b/disk_config/iso-gnome.toml new file mode 100644 index 0000000..0a9c84f --- /dev/null +++ b/disk_config/iso-gnome.toml @@ -0,0 +1,20 @@ +[customizations.installer.kickstart] +contents = """ +%post +bootc switch --mutate-in-place --transport registry ghcr.io/ublue-os/image-template:latest +%end +""" + +[customizations.installer.modules] +enable = [ + "org.fedoraproject.Anaconda.Modules.Storage", + "org.fedoraproject.Anaconda.Modules.Runtime" +] +disable = [ + "org.fedoraproject.Anaconda.Modules.Network", + "org.fedoraproject.Anaconda.Modules.Security", + "org.fedoraproject.Anaconda.Modules.Services", + "org.fedoraproject.Anaconda.Modules.Users", + "org.fedoraproject.Anaconda.Modules.Subscription", + "org.fedoraproject.Anaconda.Modules.Timezone" +] diff --git a/disk_config/iso-kde.toml b/disk_config/iso-kde.toml new file mode 100644 index 0000000..17d2787 --- /dev/null +++ b/disk_config/iso-kde.toml @@ -0,0 +1,21 @@ +[customizations.installer.kickstart] +contents = """ +%post +bootc switch --mutate-in-place --transport registry ghcr.io/ublue-os/image-template:latest +%end +""" + +[customizations.installer.modules] +enable = [ + "org.fedoraproject.Anaconda.Modules.Storage", + "org.fedoraproject.Anaconda.Modules.Runtime", + "org.fedoraproject.Anaconda.Modules.Network", + "org.fedoraproject.Anaconda.Modules.Security", + "org.fedoraproject.Anaconda.Modules.Services", + "org.fedoraproject.Anaconda.Modules.Users", + "org.fedoraproject.Anaconda.Modules.Timezone" +] + +disable = [ + "org.fedoraproject.Anaconda.Modules.Subscription", +] diff --git a/disk_config/iso.toml b/disk_config/iso.toml deleted file mode 100644 index 0a9c84f..0000000 --- a/disk_config/iso.toml +++ /dev/null @@ -1,20 +0,0 @@ -[customizations.installer.kickstart] -contents = """ -%post -bootc switch --mutate-in-place --transport registry ghcr.io/ublue-os/image-template:latest -%end -""" - -[customizations.installer.modules] -enable = [ - "org.fedoraproject.Anaconda.Modules.Storage", - "org.fedoraproject.Anaconda.Modules.Runtime" -] -disable = [ - "org.fedoraproject.Anaconda.Modules.Network", - "org.fedoraproject.Anaconda.Modules.Security", - "org.fedoraproject.Anaconda.Modules.Services", - "org.fedoraproject.Anaconda.Modules.Users", - "org.fedoraproject.Anaconda.Modules.Subscription", - "org.fedoraproject.Anaconda.Modules.Timezone" -] -- cgit v1.2.3 From d6c49785ce8ed3569891bab079eba8e48d435421 Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Fri, 8 Aug 2025 08:43:00 -0400 Subject: chore(deps): update docker/login-action digest to 184bdaa (#124) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 02d560f..8c99d08 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -137,7 +137,7 @@ jobs: # 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 - name: Login to GitHub Container Registry - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) with: registry: ghcr.io -- cgit v1.2.3 From 9888c321d730e745f36a572345c852d66e64e8d9 Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Mon, 11 Aug 2025 14:25:02 +0100 Subject: chore(deps): update actions/checkout action to v5 (#130) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build-disk.yml | 2 +- .github/workflows/build.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index e0d0cac..88756c0 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -75,7 +75,7 @@ jobs: remove-codeql: true - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 - name: Build disk images id: build diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8c99d08..8470597 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,7 @@ jobs: # These stage versions are pinned by https://github.com/renovatebot/renovate - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 # 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 -- cgit v1.2.3 From 7f7f8b13d15283a995d1aa187c37116536b95a8a Mon Sep 17 00:00:00 2001 From: Jordan Petridis <16531710+alatiera@users.noreply.github.com> Date: Fri, 22 Aug 2025 20:47:22 +0300 Subject: docs: Skip password promot during cosign key generation (#131) The key in GH secret requires that its not password protected in order to work. Add COSIGN_PASSWORD="" in the example command so everyone that copy pastes it avoids the prompt they have to manually ignore otherwise. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 490c5e6..e890f6a 100644 --- a/README.md +++ b/README.md @@ -49,10 +49,10 @@ First, install the [cosign CLI tool](https://edu.chainguard.dev/open-source/sigs With the cosign tool installed, run inside your repo folder: ```bash -cosign generate-key-pair +COSIGN_PASSWORD="" cosign generate-key-pair ``` -Do NOT put in a password when it asks you to, just press enter. The signing key will be used in GitHub Actions and will not work if it is encrypted. +The signing key will be used in GitHub Actions and will not work if it is password protected. > [!WARNING] > Be careful to *never* accidentally commit `cosign.key` into your git repo. If this key goes out to the public, the security of your repository is compromised. -- cgit v1.2.3 From 6243fb9fcabeeb68229126549c7cf23486eede78 Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 18:55:45 -0400 Subject: chore(deps): update sigstore/cosign-installer action to v3.10.0 (#135) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8470597..f2d3691 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -163,7 +163,7 @@ jobs: # 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@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 + uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) - name: Sign container image -- cgit v1.2.3 From 5c23f6e840b82480a8301b68f8fed1934d455770 Mon Sep 17 00:00:00 2001 From: Clement Verna <7237866+cverna@users.noreply.github.com> Date: Sun, 28 Sep 2025 00:55:44 +0200 Subject: Containerfile: ostree container commit is not needed (#137) ostree container commit is not needed anymore when using bootc container lint. Signed-off-by: Clement Verna --- Containerfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Containerfile b/Containerfile index d57ee46..8064002 100644 --- a/Containerfile +++ b/Containerfile @@ -22,9 +22,8 @@ RUN --mount=type=bind,from=ctx,source=/,target=/ctx \ --mount=type=cache,dst=/var/cache \ --mount=type=cache,dst=/var/log \ --mount=type=tmpfs,dst=/tmp \ - /ctx/build.sh && \ - ostree container commit + /ctx/build.sh ### LINTING ## Verify final image and contents are correct. -RUN bootc container lint \ No newline at end of file +RUN bootc container lint -- cgit v1.2.3 From c697570bbfa4791e9716fba904984c41bfa06c88 Mon Sep 17 00:00:00 2001 From: renner <80410025+renner0e@users.noreply.github.com> Date: Sun, 28 Sep 2025 14:23:33 +0200 Subject: feat(ci): add fallback condition for btrfs bind mount (#134) --- .github/workflows/build.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f2d3691..4d867be 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,7 +53,15 @@ jobs: # remove-codeql: true - name: Mount BTRFS for podman storage - uses: ublue-os/container-storage-action@main + id: container-storage-action + uses: ublue-os/container-storage-action@911baca08baf30c8654933e9e9723cb399892140 + + # Fallback to the remove-unwanted-software-action if github doesn't allocate enough space + # See: https://github.com/ublue-os/container-storage-action/pull/11 + continue-on-error: true + with: + target-dir: /var/lib/containers + mount-opts: compress-force=zstd:2 - name: Get current date id: date -- cgit v1.2.3 From 2e57cc55652e4ebe2c6a134212f542c74d4ef6c6 Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Tue, 30 Sep 2025 07:04:09 +0300 Subject: chore(deps): update docker/login-action digest to 5e57cd1 (#138) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4d867be..ecd3ffa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -145,7 +145,7 @@ jobs: # 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 - name: Login to GitHub Container Registry - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3 + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) with: registry: ghcr.io -- cgit v1.2.3 From 2e22fda019fc559ac7604c5d5188e74f25d32718 Mon Sep 17 00:00:00 2001 From: Matthias an der Ruhr <135343836+Matthias-adR@users.noreply.github.com> Date: Sun, 19 Oct 2025 17:56:08 +0200 Subject: Update README.md (#145) Fix formatting of text under dropdowns (image previews; hyperlinks) --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index e890f6a..b062592 100644 --- a/README.md +++ b/README.md @@ -62,10 +62,10 @@ Next, you need to add the key to GitHub. This makes use of GitHub's secret signi
Using the Github Web Interface (preferred) - Go to your repository settings, under `Secrets and Variables` -> `Actions` - ![image](https://user-images.githubusercontent.com/1264109/216735595-0ecf1b66-b9ee-439e-87d7-c8cc43c2110a.png) - Add a new secret and name it `SIGNING_SECRET`, then paste the contents of `cosign.key` into the secret and save it. Make sure it's the .key file and not the .pub file. Once done, it should look like this: - ![image](https://user-images.githubusercontent.com/1264109/216735690-2d19271f-cee2-45ac-a039-23e6a4c16b34.png) +Go to your repository settings, under `Secrets and Variables` -> `Actions` +![image](https://user-images.githubusercontent.com/1264109/216735595-0ecf1b66-b9ee-439e-87d7-c8cc43c2110a.png) +Add a new secret and name it `SIGNING_SECRET`, then paste the contents of `cosign.key` into the secret and save it. Make sure it's the .key file and not the .pub file. Once done, it should look like this: +![image](https://user-images.githubusercontent.com/1264109/216735690-2d19271f-cee2-45ac-a039-23e6a4c16b34.png)
Using the Github CLI @@ -85,13 +85,13 @@ For a base image, you can choose any of the Universal Blue images or start from
Base Images - - Bazzite: `ghcr.io/ublue-os/bazzite:stable` - - 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` +- Bazzite: `ghcr.io/ublue-os/bazzite:stable` +- 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` - You can find more Universal Blue images on the [packages page](https://github.com/orgs/ublue-os/packages). +You can find more Universal Blue images on the [packages page](https://github.com/orgs/ublue-os/packages).
If you don't know which image to pick, choosing the one your system is currently on is the best bet for a smooth transition. To find out what image your system currently uses, run the following command: -- cgit v1.2.3 From 5bf7f2ad5140958f00c785a558c2d3f4e9abb2b9 Mon Sep 17 00:00:00 2001 From: Zeglius <33781398+Zeglius@users.noreply.github.com> Date: Tue, 21 Oct 2025 17:38:28 +0200 Subject: feat: allows packages to install in /opt (#150) * feat: allows packages to install in /opt/ * feat: default to mutable opt and add documentation Signed-off-by: Zeglius <33781398+Zeglius@users.noreply.github.com> --------- Signed-off-by: Zeglius <33781398+Zeglius@users.noreply.github.com> Co-authored-by: stevensko <30204691+stevensko@users.noreply.github.com> --- Containerfile | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Containerfile b/Containerfile index 8064002..4cab82b 100644 --- a/Containerfile +++ b/Containerfile @@ -14,6 +14,17 @@ FROM ghcr.io/ublue-os/bazzite:stable # Fedora base image: quay.io/fedora/fedora-bootc:41 # CentOS base images: quay.io/centos-bootc/centos-bootc:stream10 +### [IM]MUTABLE /opt +## Some bootable images, like Fedora, have /opt symlinked to /var/opt, in order to +## make it mutable/writable for users. However, some packages write files to this directory, +## thus its contents might be wiped out when bootc deploys an image, making it troublesome for +## some packages. Eg, google-chrome, docker-desktop. +## +## Uncomment the following line if one desires to make /opt immutable and be able to be used +## by the package manager. + +# RUN rm /opt && mkdir /opt + ### MODIFICATIONS ## make modifications desired in your image and install packages by modifying the build.sh script ## the following RUN directive does all the things required to run "build.sh" as recommended. -- cgit v1.2.3 From 342dae4afc916698c82dc49c5380990c1f19cc68 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 Oct 2025 09:23:39 +0100 Subject: Container image labels point to specific commit (#153) --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ecd3ffa..b7d99af 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -87,13 +87,13 @@ jobs: 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 }}/refs/heads/main/README.md + 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 }}/refs/heads/main/README.md - org.opencontainers.image.source=https://github.com/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}/blob/main/Containerfile + 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 }} + 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 -- cgit v1.2.3 From f2ea9c53e271563bebdbf741c671efb29d60e4bd Mon Sep 17 00:00:00 2001 From: renner <80410025+renner0e@users.noreply.github.com> Date: Tue, 4 Nov 2025 09:35:36 +0100 Subject: docs: clarify usage of space saving actions (#163) --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b7d99af..61e75bb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,9 +46,10 @@ jobs: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + # You only use this action if the container-storage-action proves to be unreliable, you don't need to enable both # 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@517622d6452028f266b7ba4cc9a123b5f58a6b53 # v7 + # uses: ublue-os/remove-unwanted-software@695eb75bc387dbcd9685a8e72d23439d8686cba6 # with: # remove-codeql: true -- cgit v1.2.3 From 2adc810c900be571929503e1906f0fb098ad385d Mon Sep 17 00:00:00 2001 From: DXC-0 Date: Tue, 4 Nov 2025 08:40:01 +0000 Subject: docs: add akmods section (#160) --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index b062592..ba52ebf 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,10 @@ Runs shell check on all Bash scripts. Runs shfmt on all Bash scripts. +## Additional resources + +For additional driver support, ublue maintains a set of scripts and container images available at [ublue-akmod](https://github.com/ublue-os/akmods). These images include the necessary scripts to install multiple kernel drivers within the container (Nvidia, OpenRazer, Framework...). The documentation provides guidance on how to properly integrate these drivers into your container image. + ## Community Examples These are images derived from this template (or similar enough to this template). Reference them when building your image! -- cgit v1.2.3 From 43f801f6547c99878bcfefd7bab566a5fc0fad0d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Nov 2025 10:48:45 +0200 Subject: chore(deps): bump docker/metadata-action from 5.8.0 to 5.9.0 (#167) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 61e75bb..944dbb5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,7 +76,7 @@ jobs: # 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@c1e51972afc2121e065aed6d45c65596fe445f3f # v5 + uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5 id: metadata with: # This generates all the tags for your image, you can add custom tags here too! -- cgit v1.2.3 From 75c48268a1c182fd7af8d3b7c05c5ef7aaf84e2e Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 21:42:35 +0200 Subject: chore(deps): update actions/checkout digest to 93cb6ef (#168) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build-disk.yml | 2 +- .github/workflows/build.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index 88756c0..eee4fa8 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -75,7 +75,7 @@ jobs: remove-codeql: true - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Build disk images id: build diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 944dbb5..66ca0b3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,7 @@ jobs: # These stage versions are pinned by https://github.com/renovatebot/renovate - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 # You only use this action if the container-storage-action proves to be unreliable, you don't need to enable both # 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: -- cgit v1.2.3 From 094c2549529682a176866141750d5052b005ea60 Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 11:17:43 +0200 Subject: chore(deps): update actions/checkout action to v6 (#169) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build-disk.yml | 2 +- .github/workflows/build.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index eee4fa8..e20474c 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -75,7 +75,7 @@ jobs: remove-codeql: true - name: Checkout - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 - name: Build disk images id: build diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 66ca0b3..041f96d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,7 @@ jobs: # These stage versions are pinned by https://github.com/renovatebot/renovate - name: Checkout - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 # You only use this action if the container-storage-action proves to be unreliable, you don't need to enable both # 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: -- cgit v1.2.3 From c396ac73d0c19ba9d95deea5f283cbae4f4e1718 Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Fri, 28 Nov 2025 08:22:30 +0200 Subject: chore(deps): update docker/metadata-action digest to c299e40 (#170) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 041f96d..6b93b96 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,7 +76,7 @@ jobs: # 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@318604b99e75e41977312d83839a89be02ca4893 # v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 id: metadata with: # This generates all the tags for your image, you can add custom tags here too! -- cgit v1.2.3 From c25c32bd66fd7dc81b7c0200718900adf1f08817 Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 19:35:31 +0200 Subject: chore(deps): update actions/checkout digest to 8e8c483 (#171) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build-disk.yml | 2 +- .github/workflows/build.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index e20474c..e1ce80e 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -75,7 +75,7 @@ jobs: remove-codeql: true - name: Checkout - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - name: Build disk images id: build diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6b93b96..543a05d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,7 @@ jobs: # These stage versions are pinned by https://github.com/renovatebot/renovate - name: Checkout - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 # You only use this action if the container-storage-action proves to be unreliable, you don't need to enable both # 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: -- cgit v1.2.3 From bbd1cadd1a9dcb43f5e46b973308853a1a6ed35d Mon Sep 17 00:00:00 2001 From: Kyle Gospodnetich Date: Wed, 17 Dec 2025 12:51:18 -0800 Subject: fix: Maximize build space by default and use legacy rechunker in-org --- .github/workflows/build.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 543a05d..00d23dd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,10 +48,10 @@ jobs: # You only use this action if the container-storage-action proves to be unreliable, you don't need to enable both # 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 - # with: - # remove-codeql: true + - name: Maximize build space + uses: ublue-os/remove-unwanted-software@695eb75bc387dbcd9685a8e72d23439d8686cba6 + with: + remove-codeql: true - name: Mount BTRFS for podman storage id: container-storage-action @@ -125,9 +125,9 @@ jobs: # You can enable it by uncommenting the following lines: # - name: Run Rechunker # id: rechunk - # uses: hhd-dev/rechunk@f153348d8100c1f504dec435460a0d7baf11a9d2 # v1.1.1 + # uses: ublue-os/legacy-rechunk@a925083d9af7cb04b3e2a6e8c01bfa495f38b710 # v1.0.0 # with: - # rechunk: 'ghcr.io/hhd-dev/rechunk:v1.0.1' + # 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 -- cgit v1.2.3 From b0eee2e6d268b49cb679a84140fd112f7a49a549 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 12:53:18 -0800 Subject: chore(deps): bump actions/upload-artifact from 4.6.2 to 6.0.0 (#175) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 6.0.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/ea165f8d65b6e75b540449e92b4886f43607fa02...b7c566a772e6b6bfb58ed0dc250532a479d7789f) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-disk.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index e1ce80e..984b60c 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -90,7 +90,7 @@ jobs: - name: Upload disk images and Checksum to Job Artifacts if: inputs.upload-to-s3 != true && github.event_name != 'pull_request' - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v4 with: path: ${{ steps.build.outputs.output-directory }} if-no-files-found: error -- cgit v1.2.3 From 1b9e1904668fe5c7d4071bc517b05c930461ca9c Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 12:53:43 -0800 Subject: chore(deps): update sigstore/cosign-installer action to v3.10.1 (#146) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 00d23dd..85769c2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -172,7 +172,7 @@ jobs: # 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@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0 + uses: sigstore/cosign-installer@7e8b541eb2e61bf99390e1afd4be13a184e9ebc5 # v3.10.1 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) - name: Sign container image -- cgit v1.2.3 From b1cabd5deb1517772e0056abddcbf14c7088edb6 Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 12:54:23 -0800 Subject: chore(deps): update actions/upload-artifact action to v5 (#152) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> Co-authored-by: Kyle Gospodnetich --- .github/workflows/build-disk.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index 984b60c..f759019 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -90,7 +90,7 @@ jobs: - name: Upload disk images and Checksum to Job Artifacts if: inputs.upload-to-s3 != true && github.event_name != 'pull_request' - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v4 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 with: path: ${{ steps.build.outputs.output-directory }} if-no-files-found: error -- cgit v1.2.3 From f1f35afd308cc410e157b702376fe620f36b27e2 Mon Sep 17 00:00:00 2001 From: Kyle Gospodnetich Date: Wed, 17 Dec 2025 12:55:52 -0800 Subject: fix: Update cosign-installer to v4.0.0 --- .github/workflows/build.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 85769c2..5e18e01 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -172,8 +172,10 @@ jobs: # 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@7e8b541eb2e61bf99390e1afd4be13a184e9ebc5 # v3.10.1 + uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) + with: + cosign-release: 'v2.6.1' - name: Sign container image if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) -- cgit v1.2.3 From 8d5936e6e92f78073ade9bd132cd2403ecc8d1fb Mon Sep 17 00:00:00 2001 From: Kyle Gospodnetich Date: Wed, 17 Dec 2025 12:57:17 -0800 Subject: fix: Drop unneeded remove-codeql flag --- .github/workflows/build.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5e18e01..217689a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,8 +50,6 @@ jobs: # 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 - with: - remove-codeql: true - name: Mount BTRFS for podman storage id: container-storage-action -- cgit v1.2.3 From 9d2b6e562e46a62620f05cc79aa05178cdf80618 Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 23:58:50 +0200 Subject: chore(deps): update actions/upload-artifact action to v6 (#179) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build-disk.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index f759019..3dff937 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -90,7 +90,7 @@ jobs: - name: Upload disk images and Checksum to Job Artifacts if: inputs.upload-to-s3 != true && github.event_name != 'pull_request' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 with: path: ${{ steps.build.outputs.output-directory }} if-no-files-found: error -- cgit v1.2.3 From 713084d7c5dabf26b28ed11ff56d54fcf865a90c Mon Sep 17 00:00:00 2001 From: yodatak Date: Sat, 3 Jan 2026 16:59:50 +0100 Subject: Update build.sh (#182) --- build_files/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_files/build.sh b/build_files/build.sh index f1e659a..ebffafc 100755 --- a/build_files/build.sh +++ b/build_files/build.sh @@ -7,7 +7,7 @@ set -ouex pipefail # Packages can be installed from any enabled yum repo on the image. # RPMfusion repos are available by default in ublue main images # List of rpmfusion packages can be found here: -# https://mirrors.rpmfusion.org/mirrorlist?path=free/fedora/updates/39/x86_64/repoview/index.html&protocol=https&redirect=1 +# 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 -- cgit v1.2.3 From a11adb37a2786b63971b580c622ae0111ed9a10c Mon Sep 17 00:00:00 2001 From: Michael Cuomo <10276078+mykeelium@users.noreply.github.com> Date: Sat, 24 Jan 2026 00:29:44 -0500 Subject: fix: alter BIB_IMAGE to suggested on osbuild/bootc-image-builder (#188) --- .github/workflows/build-disk.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index 3dff937..45aa607 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -27,7 +27,7 @@ env: IMAGE_NAME: ${{ github.event.repository.name }} # output of build.yml, keep in sync IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit DEFAULT_TAG: "latest" - BIB_IMAGE: "ghcr.io/lorbuschris/bootc-image-builder:20250608" # "quay.io/centos-bootc/bootc-image-builder:latest" - see https://github.com/osbuild/bootc-image-builder/pull/954 + BIB_IMAGE: "quay.io/centos-bootc/bootc-image-builder:latest" concurrency: group: ${{ github.workflow }}-${{ github.ref || github.run_id }} @@ -112,4 +112,4 @@ jobs: run: | sudo apt-get update sudo apt-get install -y rclone - rclone copy $SOURCE_DIR S3:${{ secrets.S3_BUCKET_NAME }} \ No newline at end of file + rclone copy $SOURCE_DIR S3:${{ secrets.S3_BUCKET_NAME }} -- cgit v1.2.3 From 852efbe51db0471f82794e4924b5522baa375364 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jan 2026 08:14:58 +0200 Subject: chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#189) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-disk.yml | 2 +- .github/workflows/build.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index 45aa607..a35491c 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -75,7 +75,7 @@ jobs: remove-codeql: true - name: Checkout - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Build disk images id: build diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 217689a..06b483f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,7 @@ jobs: # These stage versions are pinned by https://github.com/renovatebot/renovate - name: Checkout - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 # You only use this action if the container-storage-action proves to be unreliable, you don't need to enable both # 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: -- cgit v1.2.3 From 5ddf1516f3b5b171dd7ec8d4de98b9be8f81b09a Mon Sep 17 00:00:00 2001 From: renner <80410025+renner0e@users.noreply.github.com> Date: Sun, 1 Feb 2026 13:29:49 +0100 Subject: chore: remove btrfs-action (#192) --- .github/workflows/build.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 06b483f..1d2dd90 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,22 +46,10 @@ jobs: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - # You only use this action if the container-storage-action proves to be unreliable, you don't need to enable both # 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: Mount BTRFS for podman storage - id: container-storage-action - uses: ublue-os/container-storage-action@911baca08baf30c8654933e9e9723cb399892140 - - # Fallback to the remove-unwanted-software-action if github doesn't allocate enough space - # See: https://github.com/ublue-os/container-storage-action/pull/11 - continue-on-error: true - with: - target-dir: /var/lib/containers - mount-opts: compress-force=zstd:2 - - name: Get current date id: date run: | -- cgit v1.2.3 From fd08a06d1346d6e85693f3b771c66271e2bb2f97 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 06:49:29 +0200 Subject: chore(deps): bump docker/login-action from 3.6.0 to 3.7.0 (#193) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1d2dd90..6cb85db 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -132,7 +132,7 @@ jobs: # 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 - name: Login to GitHub Container Registry - uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) with: registry: ghcr.io -- cgit v1.2.3 From ec2ccf3b7683d8435a2611eb99d0b702102557b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 06:48:36 +0200 Subject: chore(deps): bump actions/upload-artifact from 6.0.0 to 7.0.0 (#199) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6.0.0 to 7.0.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/b7c566a772e6b6bfb58ed0dc250532a479d7789f...bbbca2ddaa5d8feaa63e36b76fdaad77386f024f) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-disk.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index a35491c..29df29c 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -90,7 +90,7 @@ jobs: - name: Upload disk images and Checksum to Job Artifacts if: inputs.upload-to-s3 != true && github.event_name != 'pull_request' - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: path: ${{ steps.build.outputs.output-directory }} if-no-files-found: error -- cgit v1.2.3 From 5ea9299297b30eca91fc765d5eca2c97947be57c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2026 21:24:59 +0100 Subject: chore(deps): bump docker/metadata-action from 5.10.0 to 6.0.0 (#202) Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.10.0 to 6.0.0. - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/c299e40c65443455700f0fdfc63efafe5b349051...030e881283bb7a6894de51c315a6bfe6a94e05cf) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6cb85db..1a08988 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -62,7 +62,7 @@ jobs: # 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@c299e40c65443455700f0fdfc63efafe5b349051 # v5 + uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 id: metadata with: # This generates all the tags for your image, you can add custom tags here too! -- cgit v1.2.3 From dfc18591ad4fe71b7da8dc3dd04a5b8b7698b23b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 16:59:43 +0100 Subject: chore(deps): bump docker/login-action from 3.7.0 to 4.0.0 (#203) Bumps [docker/login-action](https://github.com/docker/login-action) from 3.7.0 to 4.0.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/c94ce9fb468520275223c153574b00df6fe4bcc9...b45d80f862d83dbcd57f89517bcf500b2ab88fb2) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1a08988..16fbf15 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -132,7 +132,7 @@ jobs: # 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 - name: Login to GitHub Container Registry - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) with: registry: ghcr.io -- cgit v1.2.3 From 1b1784aaf7f128d910c053dffdd5a5884b8b8264 Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2026 22:51:14 +0200 Subject: chore(deps): update docker/login-action action to v4.1.0 (#208) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 16fbf15..85d3532 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -132,7 +132,7 @@ jobs: # 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 - name: Login to GitHub Container Registry - uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) with: registry: ghcr.io -- cgit v1.2.3 From 7c66590555a0165b42580944de619922c971155c Mon Sep 17 00:00:00 2001 From: renner <80410025+renner0e@users.noreply.github.com> Date: Fri, 3 Apr 2026 09:13:07 +0200 Subject: chore(ci): remove remove-unwanted-software-action (#209) --- .github/workflows/build.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 85d3532..fbaf527 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,10 +46,6 @@ jobs: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 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 run: | -- cgit v1.2.3 From 7ecec310266dea738e853ffa7bdf063a3368594a Mon Sep 17 00:00:00 2001 From: renner <80410025+renner0e@users.noreply.github.com> Date: Fri, 3 Apr 2026 21:17:21 +0200 Subject: Revert "chore(ci): remove remove-unwanted-software-action (#209)" (#210) This reverts commit 7c66590555a0165b42580944de619922c971155c. This only got rarer but this is still needed sometimes :( --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fbaf527..85d3532 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,6 +46,10 @@ jobs: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 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 run: | -- cgit v1.2.3 From ea6e7ba9f6d54d35d0f0b05700a0b5c4297a9c20 Mon Sep 17 00:00:00 2001 From: ro62t2 <244381118+ro62t2@users.noreply.github.com> Date: Sat, 2 May 2026 17:35:55 +0100 Subject: added -r flag to rm command for output dir (#216) --- Justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Justfile b/Justfile index 6ea8bcf..9266507 100644 --- a/Justfile +++ b/Justfile @@ -42,7 +42,7 @@ clean: rm -f previous.manifest.json rm -f changelog.md rm -f output.env - rm -f output/ + rm -rf output/ # Sudo Clean Repo [group('Utility')] -- cgit v1.2.3 From 5f2562d812e527ac2d5615c31010d616f1313852 Mon Sep 17 00:00:00 2001 From: renner <80410025+renner0e@users.noreply.github.com> Date: Thu, 7 May 2026 08:39:37 +0200 Subject: fix(just): correct shfmt typo (#217) --- Justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Justfile b/Justfile index 9266507..555cca8 100644 --- a/Justfile +++ b/Justfile @@ -312,7 +312,7 @@ format: set -eoux pipefail # Check if shfmt is installed if ! command -v shfmt &> /dev/null; then - echo "shellcheck could not be found. Please install it." + echo "shfmt could not be found. Please install it." exit 1 fi # Run shfmt on all Bash scripts -- cgit v1.2.3 From 829cb5648a65b825bda8799bb640f97cdfdebbf2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 02:12:45 +0200 Subject: chore(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 (#212) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.0 to 7.0.1. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/bbbca2ddaa5d8feaa63e36b76fdaad77386f024f...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: renner <80410025+renner0e@users.noreply.github.com> --- .github/workflows/build-disk.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index 29df29c..67ee43e 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -90,7 +90,7 @@ jobs: - name: Upload disk images and Checksum to Job Artifacts if: inputs.upload-to-s3 != true && github.event_name != 'pull_request' - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: ${{ steps.build.outputs.output-directory }} if-no-files-found: error -- cgit v1.2.3 From 30dd5f507fdd88236775ccb4e3a7f719c01675b1 Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 02:15:48 +0200 Subject: chore(deps): update sigstore/cosign-installer action to v4.1.0 (#204) * chore(deps): update sigstore/cosign-installer action to v4.1.0 * chore: bump cosign-release to v.2.6.3 --------- Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> Co-authored-by: renner <80410025+renner0e@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 85d3532..d8469ad 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -158,10 +158,10 @@ jobs: # 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@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 + uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 # v4.1.0 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) with: - cosign-release: 'v2.6.1' + cosign-release: 'v2.6.3' - name: Sign container image if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) -- cgit v1.2.3 From 73fcc9a63f81df5c5e52f48d29799d91efb0824e Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Sat, 23 May 2026 12:10:04 +0300 Subject: chore(deps): update docker/metadata-action action to v6.1.0 (#224) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d8469ad..d794606 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -62,7 +62,7 @@ jobs: # 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@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 + 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! -- cgit v1.2.3 From e9611881a7d3b58bcba712d25e0d8331d97cbe2c Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Thu, 4 Jun 2026 06:41:45 +0300 Subject: chore(deps): update actions/checkout digest to df4cb1c (#226) --- .github/workflows/build-disk.yml | 2 +- .github/workflows/build.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index 67ee43e..d8bc599 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -75,7 +75,7 @@ jobs: remove-codeql: true - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - name: Build disk images id: build diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d794606..c1fd45b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,7 @@ jobs: # These stage versions are pinned by https://github.com/renovatebot/renovate - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + 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 -- cgit v1.2.3 From 65d95d25498eb3ed610270882d5b58a47efd51a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jun 2026 06:42:07 +0300 Subject: chore(deps): bump docker/login-action from 4.1.0 to 4.2.0 (#225) Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c1fd45b..85a8c97 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -132,7 +132,7 @@ jobs: # 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 - name: Login to GitHub Container Registry - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) with: registry: ghcr.io -- cgit v1.2.3 -- cgit v1.2.3 From 7f9dd326ec891735fa8e7c482ae88ac178f89219 Mon Sep 17 00:00:00 2001 From: renner <80410025+renner0e@users.noreply.github.com> Date: Wed, 17 Jun 2026 16:16:34 +0200 Subject: 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 * fix: formatting inconsistency Co-authored-by: Jill Fiore * 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 --------- Co-authored-by: Jill Fiore Co-authored-by: Adam Fidel --- .github/workflows/build.yml | 193 ++++++++++++++++++++------------------------ Containerfile | 11 +-- Justfile | 154 ++++++++++++++++++++++++++++++++--- README.md | 50 +++++++++++- build_files/build.sh | 5 +- image-template.env | 15 ++++ system_files/etc/.gitkeep | 0 system_files/usr/.gitkeep | 0 8 files changed, 302 insertions(+), 126 deletions(-) create mode 100644 image-template.env create mode 100644 system_files/etc/.gitkeep create mode 100644 system_files/usr/.gitkeep 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).
@@ -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 diff --git a/system_files/usr/.gitkeep b/system_files/usr/.gitkeep new file mode 100644 index 0000000..e69de29 -- cgit v1.2.3 From 7d886515e999b8c444c6ffc89e9378b16074228c Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 21:40:59 +0200 Subject: chore(deps): update actions/checkout action to v7 (#228) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build-disk.yml | 2 +- .github/workflows/build.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index d8bc599..8f24f42 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -75,7 +75,7 @@ jobs: remove-codeql: true - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Build disk images id: build diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e355434..8278947 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,7 +33,7 @@ jobs: steps: # These stage versions are pinned by https://github.com/renovatebot/renovate - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Maximize build space uses: ublue-os/remove-unwanted-software@695eb75bc387dbcd9685a8e72d23439d8686cba6 -- cgit v1.2.3 From ffec79a89e982ee01a55bbb8ed3fe56f8e3f8534 Mon Sep 17 00:00:00 2001 From: "ubot-7274[bot]" <217212047+ubot-7274[bot]@users.noreply.github.com> Date: Sat, 20 Jun 2026 03:05:27 +0000 Subject: chore(deps): pin dependencies (#230) Co-authored-by: ubot-7274[bot] <217212047+ubot-7274[bot]@users.noreply.github.com> --- .github/workflows/build-disk.yml | 2 +- Containerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index 8f24f42..a24f5a4 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -79,7 +79,7 @@ jobs: - name: Build disk images id: build - uses: osbuild/bootc-image-builder-action@main + uses: osbuild/bootc-image-builder-action@8661cd3832544ad68c12dcde8681b13ab0f56a8d # main with: builder-image: ${{ env.BIB_IMAGE }} config-file: ${{ matrix.disk-type == 'anaconda-iso' && './disk_config/iso.toml' || './disk_config/disk.toml' }} diff --git a/Containerfile b/Containerfile index f3bbf77..6db705a 100644 --- a/Containerfile +++ b/Containerfile @@ -4,7 +4,7 @@ COPY build_files / COPY system_files /system_files # Base Image -FROM ghcr.io/ublue-os/bazzite:stable +FROM ghcr.io/ublue-os/bazzite:stable@sha256:b923f92d5a5b59eb992e269383eba2744601052da9d3d1595f76e79aa6ce2df0 ## Other possible base images include: # FROM ghcr.io/ublue-os/bazzite:testing # FROM ghcr.io/ublue-os/aurora:stable -- cgit v1.2.3 From f9a9e4f843a4f70b421af42964ff5254c0c44e0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 07:24:46 +0200 Subject: chore(deps): bump docker/login-action from 4.2.0 to 4.4.0 (#235) Bumps [docker/login-action](https://github.com/docker/login-action) from 4.2.0 to 4.4.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/650006c6eb7dba73a995cc03b0b2d7f5ca915bee...af1e73f918a031802d376d3c8bbc3fe56130a9b0) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8278947..de2882d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -116,7 +116,7 @@ jobs: # 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 - name: Login to GitHub Container Registry - uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 + uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) with: registry: ghcr.io -- cgit v1.2.3 From 609cd9736f2b0f1f1db01c7fab699197a20f78f9 Mon Sep 17 00:00:00 2001 From: tranch Date: Thu, 9 Jul 2026 16:53:52 +0800 Subject: Configure AeroCore image mirrors Add build-time mirror configuration for Flatpak and Homebrew, expose the related build args, and install an AeroCore-owned profile script to load mirror environment files. Rename the mirror configuration files from the Bazzite-prefixed names to AeroCore-prefixed names while keeping the upstream Bazzite helper reference intact. Verification: bash -n system_files/etc/profile.d/aerocore-mirrors.sh && bash -n build_files/build.sh --- .github/workflows/build.yml | 6 +- Containerfile | 19 +- Justfile | 10 + README.md | 303 ++----------------------- build_files/build.sh | 37 +-- image-template.env | 17 +- system_files/etc/profile.d/aerocore-mirrors.sh | 28 +++ 7 files changed, 105 insertions(+), 315 deletions(-) create mode 100644 system_files/etc/profile.d/aerocore-mirrors.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index de2882d..90371c8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -69,6 +69,11 @@ jobs: # This actually builds the container image - name: Build Image id: build-image + env: + BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable' }} + FLATPAK_REMOTE_URL: ${{ vars.FLATPAK_REMOTE_URL }} + HOMEBREW_BOTTLE_DOMAIN: ${{ vars.HOMEBREW_BOTTLE_DOMAIN }} + HOMEBREW_API_DOMAIN: ${{ vars.HOMEBREW_API_DOMAIN }} run: | sudo -E $(command -v just) build \ ${IMAGE_NAME} \ @@ -158,4 +163,3 @@ jobs: 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 6db705a..976da0c 100644 --- a/Containerfile +++ b/Containerfile @@ -1,19 +1,16 @@ # Allow build scripts to be referenced without being copied into the final image +ARG BASE_IMAGE="ghcr.io/ublue-os/bazzite-deck:stable" + FROM scratch AS ctx COPY build_files / COPY system_files /system_files # Base Image -FROM ghcr.io/ublue-os/bazzite:stable@sha256:b923f92d5a5b59eb992e269383eba2744601052da9d3d1595f76e79aa6ce2df0 +FROM ${BASE_IMAGE} ## Other possible base images include: -# 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:44 -# CentOS base images: quay.io/centos-bootc/centos-bootc:stream10 +# ghcr.io/ublue-os/bazzite-deck:testing +# ghcr.io/ublue-os/bazzite-deck:stable-43.20260420 +# ghcr.io/ublue-os/bazzite:stable ### [IM]MUTABLE /opt ## Some bootable images, like Fedora, have /opt symlinked to /var/opt, in order to @@ -30,6 +27,10 @@ FROM ghcr.io/ublue-os/bazzite:stable@sha256:b923f92d5a5b59eb992e269383eba2744601 ## make modifications desired in your image and install packages by modifying the build.sh script ## the following RUN directive does all the things required to run "build.sh" as recommended. +ARG FLATPAK_REMOTE_URL="" +ARG HOMEBREW_BOTTLE_DOMAIN="" +ARG HOMEBREW_API_DOMAIN="" + RUN --mount=type=bind,from=ctx,source=/,target=/ctx \ --mount=type=cache,dst=/var/cache \ --mount=type=cache,dst=/var/log \ diff --git a/Justfile b/Justfile index 150c89c..e83466d 100644 --- a/Justfile +++ b/Justfile @@ -8,6 +8,10 @@ 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") +export BASE_IMAGE := env_var_or_default("BASE_IMAGE", "ghcr.io/ublue-os/bazzite-deck:stable") +export FLATPAK_REMOTE_URL := env_var_or_default("FLATPAK_REMOTE_URL", "") +export HOMEBREW_BOTTLE_DOMAIN := env_var_or_default("HOMEBREW_BOTTLE_DOMAIN", "") +export HOMEBREW_API_DOMAIN := env_var_or_default("HOMEBREW_API_DOMAIN", "") alias build-vm := build-qcow2 alias rebuild-vm := rebuild-qcow2 @@ -100,6 +104,12 @@ build $target_image=image_name $tag=default_tag: BUILD_ARGS=() LABELS=() + for arg in BASE_IMAGE FLATPAK_REMOTE_URL HOMEBREW_BOTTLE_DOMAIN HOMEBREW_API_DOMAIN; do + if [[ -n "${!arg:-}" ]]; then + BUILD_ARGS+=("--build-arg" "${arg}=${!arg}") + fi + done + 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") diff --git a/README.md b/README.md index 64250be..fdd7c76 100644 --- a/README.md +++ b/README.md @@ -1,306 +1,37 @@ -# image-template +# AeroCore OS -This repository is meant to be a template for building your own custom [bootc](https://github.com/bootc-dev/bootc) image. This template is the recommended way to make customizations to any image published by the Universal Blue Project. +A customized Bazzite-deck image tailored for living-room HTPCs, featuring China-localized updates and an integrated game accelerator. -# Community +AeroCore OS is built on top of the `ublue-os/image-template` ecosystem. Unlike a heavy fork of `ublue-os/bazzite`, AeroCore OS adopts a **layered architecture** that starts directly from a pre-built upstream Bazzite image: -If you have questions about this template after following the instructions, try the following spaces: -- [Universal Blue Forums](https://universal-blue.discourse.group/) -- [Universal Blue Discord](https://discord.gg/WEu6BdFEtp) -- [bootc discussion forums](https://github.com/bootc-dev/bootc/discussions) - This is not an Universal Blue managed space, but is an excellent resource if you run into issues with building bootc images. +```dockerfile +FROM ghcr.io/ublue-os/bazzite-deck:stable -# How to Use - -To get started on your first bootc image, simply read and follow the steps in the next few headings. -If you prefer instructions in video form, TesterTech created an excellent tutorial, embedded below. - -[![Video Tutorial](https://img.youtube.com/vi/IxBl11Zmq5w/0.jpg)](https://www.youtube.com/watch?v=IxBl11Zmq5wE) - -## Step 0: Prerequisites - -These steps assume you have the following: -- A Github Account -- A machine running a bootc image (e.g. Bazzite, Bluefin, Aurora, or Fedora Atomic) -- Experience installing and using CLI programs - -## Step 1: Preparing the Template - -### Step 1a: Copying the Template - -Select `Use this Template` on this page. You can set the name and description of your repository to whatever you would like, but all other settings should be left untouched. - -Once you have finished copying the template, you need to enable the Github Actions workflows for your new repository. -To enable the workflows, go to the `Actions` tab of the new repository and click the button to enable workflows. - -### Step 1b: Cloning the New Repository - -Here I will defer to the much superior GitHub documentation on the matter. You can use whichever method is easiest. -[GitHub Documentation](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) - -Once you have the repository on your local drive, proceed to the next step. - -## Step 2: Initial Setup - -### Step 2a: Creating a Cosign Key - -Container signing is important for end-user security and is enabled on all Universal Blue images. By default the image builds *will fail* if you don't. - -First, install the [cosign CLI tool](https://edu.chainguard.dev/open-source/sigstore/cosign/how-to-install-cosign/#installing-cosign-with-the-cosign-binary) -With the cosign tool installed, run inside your repo folder: - -```bash -COSIGN_PASSWORD="" cosign generate-key-pair -``` - -The signing key will be used in GitHub Actions and will not work if it is password protected. - -> [!WARNING] -> Be careful to *never* accidentally commit `cosign.key` into your git repo. If this key goes out to the public, the security of your repository is compromised. - -Next, you need to add the key to GitHub. This makes use of GitHub's secret signing system. - -
- Using the Github Web Interface (preferred) - -Go to your repository settings, under `Secrets and Variables` -> `Actions` -![image](https://user-images.githubusercontent.com/1264109/216735595-0ecf1b66-b9ee-439e-87d7-c8cc43c2110a.png) -Add a new secret and name it `SIGNING_SECRET`, then paste the contents of `cosign.key` into the secret and save it. Make sure it's the .key file and not the .pub file. Once done, it should look like this: -![image](https://user-images.githubusercontent.com/1264109/216735690-2d19271f-cee2-45ac-a039-23e6a4c16b34.png) -
-
-Using the Github CLI - -If you have the `github-cli` installed, run: - -```bash -gh secret set SIGNING_SECRET < cosign.key -``` -
- -### Step 2b: Choosing Your Base Image - -To choose a base image, simply modify the line in the container file starting with `FROM`. This will be the image your image derives from, and is your starting point for modifications. -For a base image, you can choose any of the Universal Blue images or start from a Fedora Atomic system. Below this paragraph is a dropdown with a non-exhaustive list of potential base images. - -
- Base Images - -- Bazzite: `ghcr.io/ublue-os/bazzite:stable` -- 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:44` - -You can find more Universal Blue images on the [packages page](https://github.com/orgs/ublue-os/packages). -
- -If you don't know which image to pick, choosing the one your system is currently on is the best bet for a smooth transition. To find out what image your system currently uses, run the following command: -```bash -sudo bootc status -``` -This will show you all the info you need to know about your current image. The image you are currently on is displayed after `Booted image:`. Paste that information after the `FROM` statement in the Containerfile to set it as your base image. - -### Step 2c: Changing Names - -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 image-template.env cosign.pub -git commit -m "Initial Setup" -git push -``` -Once pushed, go look at the Actions tab on your Github repository's page. The green checkmark should be showing on the top commit, which means your new image is ready! - -## Step 3: Switch to Your Image - -From your bootc system, run the following command substituting in your Github username and image name where noted. -```bash -sudo bootc switch ghcr.io// -``` -This should queue your image for the next reboot, which you can do immediately after the command finishes. You have officially set up your custom image! See the following section for an explanation of the important parts of the template for customization. - -# Repository Contents - -## Containerfile - -The [Containerfile](./Containerfile) defines the operations used to customize the selected image.This file is the entrypoint for your image build, and works exactly like a regular podman Containerfile. For reference, please see the [Podman Documentation](https://docs.podman.io/en/latest/Introduction.html). - -## build.sh - -The [build.sh](./build_files/build.sh) file is called from your Containerfile. It is the best place to install new packages or make any other customization to your system. There are customization examples contained within it for your perusal. - -## 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. - -# Building Disk Images - -This template provides an out of the box workflow for creating disk images (ISO, qcow, raw) for your custom OCI image which can be used to directly install onto your machines. - -This template provides a way to upload the disk images that is generated from the workflow to a S3 bucket. The disk images will also be available as an artifact from the job, if you wish to use an alternate provider. To upload to S3 we use [rclone](https://rclone.org/) which is able to use [many S3 providers](https://rclone.org/s3/). - -## Setting Up ISO Builds - -The [build-disk.yml](./.github/workflows/build-disk.yml) Github Actions workflow creates a disk image from your OCI image by utilizing the [bootc-image-builder](https://osbuild.org/docs/bootc/). In order to use this workflow you must complete the following steps: - -1. Modify `disk_config/iso.toml` to point to your custom container image before generating an ISO image. -2. If you changed your image name from the default in `build.yml` then in the `build-disk.yml` file edit the `IMAGE_REGISTRY`, `IMAGE_NAME` and `DEFAULT_TAG` environment variables with the correct values. If you did not make changes, skip this step. -3. Finally, if you want to upload your disk images to S3 then you will need to add your S3 configuration to the repository's Action secrets. This can be found by going to your repository settings, under `Secrets and Variables` -> `Actions`. You will need to add the following - - `S3_PROVIDER` - Must match one of the values from the [supported list](https://rclone.org/s3/) - - `S3_BUCKET_NAME` - Your unique bucket name - - `S3_ACCESS_KEY_ID` - It is recommended that you make a separate key just for this workflow - - `S3_SECRET_ACCESS_KEY` - See above. - - `S3_REGION` - The region your bucket lives in. If you do not know then set this value to `auto`. - - `S3_ENDPOINT` - This value will be specific to the bucket as well. - -Once the workflow is done, you'll find the disk images either in your S3 bucket or as part of the summary under `Artifacts` after the workflow is completed. - -# Artifacthub - -This template comes with the necessary tooling to index your image on [artifacthub.io](https://artifacthub.io). Use the `artifacthub-repo.yml` file at the root to verify yourself as the publisher. This is important to you for a few reasons: - -- The value of artifacthub is it's one place for people to index their custom images, and since we depend on each other to learn, it helps grow the community. -- You get to see your pet project listed with the other cool projects in Cloud Native. -- Since the site puts your README front and center, it's a good way to learn how to write a good README, learn some marketing, finding your audience, etc. - -[Discussion Thread](https://universal-blue.discourse.group/t/listing-your-custom-image-on-artifacthub/6446) - -# Justfile Documentation - -The `Justfile` contains various commands and configurations for building and managing container images and virtual machine images using Podman and other utilities. -To use it, you must have installed [just](https://just.systems/man/en/introduction.html) from your package manager or manually. It is available by default on all Universal Blue images. - -## 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. - -```bash -just build $target_image $tag -``` - -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 -``` +By focusing strictly on file overlays and configuration writing, this build intentionally avoids invasive operations like `dnf5 install/remove`, COPR enablement, akmods pulls, or kernel recompilations. This architectural choice keeps AeroCore OS completely immune to Fedora/COPR dependency drift during major upstream transition windows (e.g., Bazzite 43 to 44). -### 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. +## Key Features & Optimizations -`sudo just build` and `sudo just ostree-rechunk` builds directly as root and allows you to skip the transfer to the root containers-storage. +* **Couch-Gaming Tailored:** Optimized settings for a seamless, out-of-the-box living-room console experience. +* **China-Localized Mirrors:** Pre-configured environment setups (e.g., `/etc/environment.d/99-aerocore-mirrors.conf`) utilizing low-latency, mainland China-hosted update streams. +* **Integrated Game Accelerator:** Embedded network booster configuration to ensure low-latency connection for Steam and local gaming services. +* **Maintainable Overlay Structure:** Structured `system_files/` directory for robust, long-term AeroCore core file injection without touching upstream packages. -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 -``` +## Local Build -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`. - -### `just build-qcow2` - -Builds a QCOW2 virtual machine image. +To build AeroCore OS locally, edit `image-template.env` to match your target configurations and then run: ```bash -just build-qcow2 $target_image $tag -``` - -### `just rebuild-qcow2` +just build -Rebuilds a QCOW2 virtual machine image. - -```bash -just rebuild-vm $target_image $tag ``` -### `just run-vm-qcow2` - -Runs a virtual machine from a QCOW2 image. +To test a different upstream base image directly without modifying the environment files: ```bash -just run-vm-qcow2 $target_image $tag -``` - -### `just spawn-vm` - -Runs a virtual machine using systemd-vmspawn. +BASE_IMAGE=ghcr.io/ublue-os/bazzite-deck:testing just build -```bash -just spawn-vm rebuild="0" type="qcow2" ram="6G" ``` - -## File Management - -### `just check` - -Checks the syntax of all `.just` files and the `Justfile`. - -### `just fix` - -Fixes the syntax of all `.just` files and the `Justfile`. - -### `just clean` - -Cleans the repository by removing build artifacts. - -### `just lint` - -Runs shell check on all Bash scripts. - -### `just format` - -Runs shfmt on all Bash scripts. - -## Additional resources - -For additional driver support, ublue maintains a set of scripts and container images available at [ublue-akmod](https://github.com/ublue-os/akmods). These images include the necessary scripts to install multiple kernel drivers within the container (Nvidia, OpenRazer, Framework...). The documentation provides guidance on how to properly integrate these drivers into your container image. - -## Community Examples - -These are images derived from this template (or similar enough to this template). Reference them when building your image! - -- [m2Giles' OS](https://github.com/m2giles/m2os) -- [bOS](https://github.com/bsherman/bos) -- [Homer](https://github.com/bketelsen/homer/) -- [Amy OS](https://github.com/astrovm/amyos) -- [VeneOS](https://github.com/Venefilyn/veneos) diff --git a/build_files/build.sh b/build_files/build.sh index 0bb290c..f1709da 100755 --- a/build_files/build.sh +++ b/build_files/build.sh @@ -5,23 +5,30 @@ set -ouex pipefail # Copy the contents of system_files/ of the git repo to / cp -avf "/ctx/system_files"/. / -### Install packages +mkdir -p /etc/environment.d -# Packages can be installed from any enabled yum repo on the image. -# RPMfusion repos are available by default in ublue main images -# List of rpmfusion packages can be found here: -# https://mirrors.rpmfusion.org/mirrorlist?path=free/fedora/updates/43/x86_64/repoview/index.html&protocol=https&redirect=1 +if [[ -n "${FLATPAK_REMOTE_URL:-}" || -n "${HOMEBREW_BOTTLE_DOMAIN:-}" || -n "${HOMEBREW_API_DOMAIN:-}" ]]; then + : > /etc/environment.d/99-aerocore-mirrors.conf +fi -# this installs a package from fedora repos -dnf5 install -y tmux +if [[ -n "${FLATPAK_REMOTE_URL:-}" ]]; then + printf '%s\n' "FLATPAK_REMOTE_URL=${FLATPAK_REMOTE_URL}" >> /etc/environment.d/99-aerocore-mirrors.conf + if [[ -f /usr/libexec/bazzite-mirror-utils.sh ]]; then + bash /usr/libexec/bazzite-mirror-utils.sh update_flathub_repo_url "${FLATPAK_REMOTE_URL}" + fi +fi -# Use a COPR Example: -# -# dnf5 -y copr enable ublue-os/staging -# dnf5 -y install package -# Disable COPRs so they don't end up enabled on the final image: -# dnf5 -y copr disable ublue-os/staging +if [[ -n "${HOMEBREW_BOTTLE_DOMAIN:-}" || -n "${HOMEBREW_API_DOMAIN:-}" ]]; then + mkdir -p /etc/skel/.config/environment.d + : > /etc/skel/.config/environment.d/99-aerocore-mirrors.conf +fi -#### Example for enabling a System Unit File +if [[ -n "${HOMEBREW_BOTTLE_DOMAIN:-}" ]]; then + printf '%s\n' "HOMEBREW_BOTTLE_DOMAIN=${HOMEBREW_BOTTLE_DOMAIN}" | tee -a /etc/environment.d/99-aerocore-mirrors.conf /etc/skel/.config/environment.d/99-aerocore-mirrors.conf >/dev/null +fi -systemctl enable podman.socket +if [[ -n "${HOMEBREW_API_DOMAIN:-}" ]]; then + printf '%s\n' "HOMEBREW_API_DOMAIN=${HOMEBREW_API_DOMAIN}" | tee -a /etc/environment.d/99-aerocore-mirrors.conf /etc/skel/.config/environment.d/99-aerocore-mirrors.conf >/dev/null +fi + +find /etc/environment.d /etc/skel/.config/environment.d -name 99-aerocore-mirrors.conf -type f -exec chmod 0644 {} + 2>/dev/null || true diff --git a/image-template.env b/image-template.env index c0707c5..bf848fb 100644 --- a/image-template.env +++ b/image-template.env @@ -1,15 +1,24 @@ # 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 +IMAGE_NAME=aerocore-bazzite-image # Make this the same as your github username/organisation -REPO_ORGANIZATION="alice-and-bob" +REPO_ORGANIZATION="AeroCore-IO" -IMAGE_DESC="My Customized Bootc Image" -IMAGE_KEYWORDS="bootc,oci,linux" +IMAGE_DESC="AeroCore customized Bazzite Deck image" +IMAGE_KEYWORDS="bootc,oci,linux,bazzite,steam-deck,aerocore" # 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" + +# Keep this on bazzite-deck for Steam Deck, game mode, and handheld customizations. +# Use a concrete tag during transition windows if stable/testing moves underneath you. +BASE_IMAGE="ghcr.io/ublue-os/bazzite-deck:stable" + +# Optional mirror settings. +FLATPAK_REMOTE_URL="" +HOMEBREW_BOTTLE_DOMAIN="" +HOMEBREW_API_DOMAIN="" diff --git a/system_files/etc/profile.d/aerocore-mirrors.sh b/system_files/etc/profile.d/aerocore-mirrors.sh new file mode 100644 index 0000000..e9b93ab --- /dev/null +++ b/system_files/etc/profile.d/aerocore-mirrors.sh @@ -0,0 +1,28 @@ +#!/usr/bin/bash + +[[ -r /usr/libexec/bazzite-mirror-utils.sh ]] && source /usr/libexec/bazzite-mirror-utils.sh + +if ! declare -F is_valid_mirror_url >/dev/null; then + is_valid_mirror_url() { + [[ "$1" =~ ^https?://[^[:space:]]+$ ]] + } +fi + +load_mirror_file() { + local file="$1" + [[ -r "$file" ]] || return + + while IFS='=' read -r key value; do + [[ -z "$key" || "${key:0:1}" == "#" ]] && continue + case "$key" in + FLATPAK_REMOTE_URL|HOMEBREW_BOTTLE_DOMAIN|HOMEBREW_API_DOMAIN) + if is_valid_mirror_url "$value"; then + export "$key"="$value" + fi + ;; + esac +done <"$file" +} + +load_mirror_file /etc/environment.d/99-aerocore-mirrors.conf +load_mirror_file "$HOME/.config/environment.d/99-aerocore-mirrors.conf" -- cgit v1.2.3 From 85d19ac59f67d0f6ee5beaaa8dbc222954ec6434 Mon Sep 17 00:00:00 2001 From: tranch Date: Thu, 9 Jul 2026 17:21:21 +0800 Subject: Push build images to ACR Add an ACR publish step after the existing GHCR publish and signing flow. The step is gated to non-PR default-branch runs and only executes when ACR_REGISTRY and ACR_NAMESPACE repository variables are set. Verification: ruby YAML parser loaded .github/workflows/build.yml successfully. --- .github/workflows/build.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 90371c8..b822ac6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -163,3 +163,23 @@ jobs: DIGEST: ${{ steps.push-image.outputs.digest }} run: | cosign sign -y --key env://COSIGN_PRIVATE_KEY ${IMAGE_REGISTRY}/${IMAGE_NAME}@${DIGEST} + + - name: Push To ACR + if: | + github.event_name != 'pull_request' && + github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && + vars.ACR_REGISTRY != '' && + vars.ACR_NAMESPACE != '' + env: + ACR_REGISTRY: ${{ vars.ACR_REGISTRY }} + ACR_NAMESPACE: ${{ vars.ACR_NAMESPACE }} + ACR_USERNAME: ${{ secrets.ACR_USERNAME }} + ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }} + ALIAS_TAGS: ${{ steps.gen-build-tags.outputs.alias_tags }} + run: | + set -euo pipefail + echo "$ACR_PASSWORD" | sudo -E podman login "$ACR_REGISTRY" -u "$ACR_USERNAME" --password-stdin + + for tag in ${ALIAS_TAGS}; do + sudo -E podman push "${IMAGE_NAME}:${tag}" "${ACR_REGISTRY}/${ACR_NAMESPACE}/${IMAGE_NAME}:${tag}" + done -- cgit v1.2.3 From a576dcd1d1579aa581f92e91330316248ba19f02 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Jul 2026 09:24:16 +0000 Subject: chore(deps): bump osbuild/bootc-image-builder-action Bumps [osbuild/bootc-image-builder-action](https://github.com/osbuild/bootc-image-builder-action) from 8661cd3832544ad68c12dcde8681b13ab0f56a8d to 30960621b85c9e76c653082f9ef4cab5a10210d5. - [Release notes](https://github.com/osbuild/bootc-image-builder-action/releases) - [Commits](https://github.com/osbuild/bootc-image-builder-action/compare/8661cd3832544ad68c12dcde8681b13ab0f56a8d...30960621b85c9e76c653082f9ef4cab5a10210d5) --- updated-dependencies: - dependency-name: osbuild/bootc-image-builder-action dependency-version: 30960621b85c9e76c653082f9ef4cab5a10210d5 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .github/workflows/build-disk.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index a24f5a4..1de6c6e 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -79,7 +79,7 @@ jobs: - name: Build disk images id: build - uses: osbuild/bootc-image-builder-action@8661cd3832544ad68c12dcde8681b13ab0f56a8d # main + uses: osbuild/bootc-image-builder-action@30960621b85c9e76c653082f9ef4cab5a10210d5 # main with: builder-image: ${{ env.BIB_IMAGE }} config-file: ${{ matrix.disk-type == 'anaconda-iso' && './disk_config/iso.toml' || './disk_config/disk.toml' }} -- cgit v1.2.3 From 39d438730aa65e0e3d5604894d4c41b903e4cae4 Mon Sep 17 00:00:00 2001 From: tranch Date: Thu, 9 Jul 2026 18:21:37 +0800 Subject: Promote ACR images manually Remove push-triggered builds and split ACR publishing out of the build workflow. Add a manual promote-acr workflow that copies an existing GHCR tag to ACR, supports explicit target tags, validates the required ACR configuration, and signs the promoted ACR digest. Verification: parsed both workflow YAML files and checked embedded run blocks with bash -n. --- .github/workflows/build.yml | 25 ------- .github/workflows/promote-acr.yml | 147 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 25 deletions(-) create mode 100644 .github/workflows/promote-acr.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b822ac6..56f8da9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,11 +6,6 @@ on: - main schedule: - cron: '05 10 * * *' # 10:05am UTC everyday - push: - branches: - - main - paths-ignore: - - '**/README.md' workflow_dispatch: env: @@ -163,23 +158,3 @@ jobs: DIGEST: ${{ steps.push-image.outputs.digest }} run: | cosign sign -y --key env://COSIGN_PRIVATE_KEY ${IMAGE_REGISTRY}/${IMAGE_NAME}@${DIGEST} - - - name: Push To ACR - if: | - github.event_name != 'pull_request' && - github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && - vars.ACR_REGISTRY != '' && - vars.ACR_NAMESPACE != '' - env: - ACR_REGISTRY: ${{ vars.ACR_REGISTRY }} - ACR_NAMESPACE: ${{ vars.ACR_NAMESPACE }} - ACR_USERNAME: ${{ secrets.ACR_USERNAME }} - ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }} - ALIAS_TAGS: ${{ steps.gen-build-tags.outputs.alias_tags }} - run: | - set -euo pipefail - echo "$ACR_PASSWORD" | sudo -E podman login "$ACR_REGISTRY" -u "$ACR_USERNAME" --password-stdin - - for tag in ${ALIAS_TAGS}; do - sudo -E podman push "${IMAGE_NAME}:${tag}" "${ACR_REGISTRY}/${ACR_NAMESPACE}/${IMAGE_NAME}:${tag}" - done diff --git a/.github/workflows/promote-acr.yml b/.github/workflows/promote-acr.yml new file mode 100644 index 0000000..99a67f8 --- /dev/null +++ b/.github/workflows/promote-acr.yml @@ -0,0 +1,147 @@ +--- +name: Promote image to ACR + +on: + workflow_dispatch: + inputs: + source_tag: + description: "Existing GHCR tag to promote" + required: true + type: string + target_tags: + description: "Space-separated ACR tags to publish; defaults to source_tag" + required: false + type: string + image_name: + description: "Image name override; defaults to image-template.env" + required: false + type: string + +env: + IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" + +concurrency: + group: ${{ github.workflow }}-${{ inputs.image_name || 'default' }}-${{ inputs.source_tag }} + cancel-in-progress: false + +jobs: + promote_acr: + name: Promote GHCR image to ACR + runs-on: ubuntu-24.04 + + permissions: + contents: read + packages: read + + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + + - name: Install just + uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 #v4.0.0 + + - name: Install skopeo + run: | + sudo apt-get update + sudo apt-get install -y skopeo + + - name: Prepare image variables + env: + IMAGE_NAME_INPUT: ${{ inputs.image_name }} + SOURCE_TAG: ${{ inputs.source_tag }} + TARGET_TAGS_INPUT: ${{ inputs.target_tags }} + run: | + set -euo pipefail + + image_name="${IMAGE_NAME_INPUT:-$(just image_name)}" + target_tags="${TARGET_TAGS_INPUT:-$SOURCE_TAG}" + + echo "IMAGE_REGISTRY=${IMAGE_REGISTRY,,}" >> "$GITHUB_ENV" + echo "IMAGE_NAME=${image_name,,}" >> "$GITHUB_ENV" + echo "SOURCE_TAG=${SOURCE_TAG}" >> "$GITHUB_ENV" + echo "TARGET_TAGS=${target_tags}" >> "$GITHUB_ENV" + + - name: Validate ACR configuration + env: + ACR_REGISTRY: ${{ vars.ACR_REGISTRY }} + ACR_NAMESPACE: ${{ vars.ACR_NAMESPACE }} + ACR_USERNAME: ${{ secrets.ACR_USERNAME }} + ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }} + COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} + run: | + set -euo pipefail + + : "${ACR_REGISTRY:?Repository variable ACR_REGISTRY is required.}" + : "${ACR_NAMESPACE:?Repository variable ACR_NAMESPACE is required.}" + : "${ACR_USERNAME:?Repository secret ACR_USERNAME is required.}" + : "${ACR_PASSWORD:?Repository secret ACR_PASSWORD is required.}" + : "${COSIGN_PRIVATE_KEY:?Repository secret SIGNING_SECRET is required.}" + + - name: Login to GitHub Container Registry + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + echo "$GITHUB_TOKEN" | sudo -E podman login ghcr.io -u "${{ github.actor }}" --password-stdin + + - name: Login to ACR + env: + ACR_REGISTRY: ${{ vars.ACR_REGISTRY }} + ACR_USERNAME: ${{ secrets.ACR_USERNAME }} + ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }} + run: | + set -euo pipefail + echo "$ACR_PASSWORD" | sudo -E podman login "$ACR_REGISTRY" -u "$ACR_USERNAME" --password-stdin + echo "$ACR_PASSWORD" | docker login "$ACR_REGISTRY" -u "$ACR_USERNAME" --password-stdin + + - name: Promote image + id: promote + env: + ACR_REGISTRY: ${{ vars.ACR_REGISTRY }} + ACR_NAMESPACE: ${{ vars.ACR_NAMESPACE }} + run: | + set -euo pipefail + + source_image="docker://${IMAGE_REGISTRY}/${IMAGE_NAME}:${SOURCE_TAG}" + first_target="" + + { + echo "# Promote to ACR result" + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + + for tag in ${TARGET_TAGS}; do + dest_image="${ACR_REGISTRY}/${ACR_NAMESPACE}/${IMAGE_NAME}:${tag}" + sudo -E skopeo copy "$source_image" "docker://$dest_image" + echo "$dest_image" >> "$GITHUB_STEP_SUMMARY" + if [ -z "$first_target" ]; then + first_target="$dest_image" + fi + done + + echo '```' >> "$GITHUB_STEP_SUMMARY" + + digest=$(sudo -E skopeo inspect --format '{{.Digest}}' "docker://$first_target") + if [ -z "$digest" ]; then + echo "Failed to resolve digest for $first_target" >&2 + exit 1 + fi + + echo "digest=${digest}" >> "$GITHUB_OUTPUT" + + - name: Install Cosign + uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 + with: + cosign-release: 'v2.6.3' + + - name: Sign ACR image + env: + ACR_REGISTRY: ${{ vars.ACR_REGISTRY }} + ACR_NAMESPACE: ${{ vars.ACR_NAMESPACE }} + COSIGN_EXPERIMENTAL: false + COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} + DIGEST: ${{ steps.promote.outputs.digest }} + run: | + set -euo pipefail + + cosign sign -y --key env://COSIGN_PRIVATE_KEY "${ACR_REGISTRY}/${ACR_NAMESPACE}/${IMAGE_NAME}@${DIGEST}" -- cgit v1.2.3 From 542f179ec9f26604ae30753ca3271cd1602c917a Mon Sep 17 00:00:00 2001 From: tranch Date: Thu, 9 Jul 2026 18:33:19 +0800 Subject: feat: add cosign public key for image verification --- cosign.pub | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cosign.pub diff --git a/cosign.pub b/cosign.pub new file mode 100644 index 0000000..743ffc6 --- /dev/null +++ b/cosign.pub @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEngDTStJpDStoCngm+s7bPh6jb3HA +lULyuID3xV+K6xc6SmYedXZUtCTZ+VhfuavsmU/j0A/jzypG/0yr/U2nEQ== +-----END PUBLIC KEY----- -- cgit v1.2.3 From 455d63f408c929ad59aab589dda20ba77d769047 Mon Sep 17 00:00:00 2001 From: tranch Date: Fri, 10 Jul 2026 18:59:48 +0800 Subject: Complete OS rename metadata migration Move the image metadata and desktop naming to the new AeroCore OS\nidentity, and wire the build so the generated os-release data is\nwritten during image construction. --- Containerfile | 8 +++- build_files/image-info | 78 +++++++++++++++++++++++++++++++++ system_files/etc/xdg/kcm-about-distrorc | 5 +++ 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100755 build_files/image-info create mode 100644 system_files/etc/xdg/kcm-about-distrorc diff --git a/Containerfile b/Containerfile index 976da0c..7e029a4 100644 --- a/Containerfile +++ b/Containerfile @@ -7,6 +7,11 @@ COPY system_files /system_files # Base Image FROM ${BASE_IMAGE} +ARG IMAGE_NAME="aerocore-bazzite-image" +ARG IMAGE_VENDOR="AeroCore-IO" +ARG IMAGE_BRANCH="stable" +ARG VERSION_TAG="latest" +ARG VERSION_PRETTY="latest" ## Other possible base images include: # ghcr.io/ublue-os/bazzite-deck:testing # ghcr.io/ublue-os/bazzite-deck:stable-43.20260420 @@ -35,7 +40,8 @@ RUN --mount=type=bind,from=ctx,source=/,target=/ctx \ --mount=type=cache,dst=/var/cache \ --mount=type=cache,dst=/var/log \ --mount=type=tmpfs,dst=/tmp \ - /ctx/build.sh + /ctx/build.sh && \ + /ctx/image-info ### LINTING ## Verify final image and contents are correct. diff --git a/build_files/image-info b/build_files/image-info new file mode 100755 index 0000000..d441917 --- /dev/null +++ b/build_files/image-info @@ -0,0 +1,78 @@ +#!/usr/bin/bash + +set -eoux pipefail + +IMAGE_PRETTY_NAME="AeroCore OS" +IMAGE_ID="aerocore" +IMAGE_LIKE="fedora" +HOME_URL="https://os.aerocore.com.cn" +DOCUMENTATION_URL="https://docs.os.aerocore.com.cn" +SUPPORT_URL="https://os.aerocore.com.cn/support" +BUG_SUPPORT_URL="https://github.com/AeroCore-IO/AeroCore-OS/issues/" +LOGO_ICON="distributor-logo" +LOGO_COLOR="0;38;2;12;109;129" + +IMAGE_INFO="/usr/share/ublue-os/image-info.json" +OSTREE_REGISTRY="${OSTREE_REGISTRY:-docker://ghcr.io}" +OSTREE_NAMESPACE="${OSTREE_NAMESPACE:-$IMAGE_VENDOR}" +IMAGE_REF="ostree-image-signed:${OSTREE_REGISTRY%/}/$OSTREE_NAMESPACE/$IMAGE_NAME" +IMAGE_BRANCH_NORMALIZED="$IMAGE_BRANCH" +BASE_IMAGE_NAME="bazzite-deck" + +if [[ $IMAGE_BRANCH_NORMALIZED == "main" ]]; then + IMAGE_BRANCH_NORMALIZED="stable" +fi + +FEDORA_VERSION=$(rpm -E %fedora) + +mkdir -p "$(dirname "$IMAGE_INFO")" +cat > "$IMAGE_INFO" < /etc/system-release + +if grep -q '^BUILD_ID=' /usr/lib/os-release; then + sed -i "s/^BUILD_ID=.*/BUILD_ID=\"$VERSION_PRETTY\"/" /usr/lib/os-release +else + echo "BUILD_ID=\"$VERSION_PRETTY\"" >> /usr/lib/os-release +fi + +if grep -q '^BOOTLOADER_NAME=' /usr/lib/os-release; then + sed -i "s/^BOOTLOADER_NAME=.*/BOOTLOADER_NAME=\"$IMAGE_PRETTY_NAME $VERSION_PRETTY\"/" /usr/lib/os-release +else + echo "BOOTLOADER_NAME=\"$IMAGE_PRETTY_NAME $VERSION_PRETTY\"" >> /usr/lib/os-release +fi + +# Keep hibernation images tied to this exact image version. +if grep -q '^IMAGE_ID=' /usr/lib/os-release; then + sed -i "s/^IMAGE_ID=.*/IMAGE_ID=\"$IMAGE_NAME-$VERSION_TAG\"/" /usr/lib/os-release +else + echo "IMAGE_ID=\"$IMAGE_NAME-$VERSION_TAG\"" >> /usr/lib/os-release +fi diff --git a/system_files/etc/xdg/kcm-about-distrorc b/system_files/etc/xdg/kcm-about-distrorc new file mode 100644 index 0000000..ed2c831 --- /dev/null +++ b/system_files/etc/xdg/kcm-about-distrorc @@ -0,0 +1,5 @@ +[General] +LogoPath=/usr/share/pixmaps/system-logo-white.png +Name=AeroCore OS +Website=https://os.aerocore.com.cn +Variant=Handheld & HTPC Edition -- cgit v1.2.3 From 54a1a1528fca614ec5fcb8a3e55129a5b822a646 Mon Sep 17 00:00:00 2001 From: tranch Date: Sun, 12 Jul 2026 17:47:10 +0800 Subject: Migrate AeroCore logo assets Import AeroCore branding assets from the Bazzite branding commits. --- .../share/plymouth/themes/spinner/watermark.png | Bin 0 -> 4140 bytes .../shared/usr/share/ublue-os/bazzite/docs.svg | 23 +++++++++++++++ .../shared/usr/share/ublue-os/bazzite/logo.svg | 19 +++++++++++++ .../usr/share/ublue-os/bazzite/updatelogo.png | Bin 0 -> 61110 bytes .../icons/hicolor/128x128/bazzite-logo-icon.png | Bin 0 -> 5613 bytes .../icons/hicolor/16x16/bazzite-logo-icon.png | Bin 0 -> 634 bytes .../icons/hicolor/22x22/bazzite-logo-icon.png | Bin 0 -> 837 bytes .../icons/hicolor/24x24/bazzite-logo-icon.png | Bin 0 -> 921 bytes .../icons/hicolor/256x256/bazzite-logo-icon.png | Bin 0 -> 12105 bytes .../icons/hicolor/32x32/bazzite-logo-icon.png | Bin 0 -> 1203 bytes .../icons/hicolor/36x36/bazzite-logo-icon.png | Bin 0 -> 1345 bytes .../icons/hicolor/48x48/bazzite-logo-icon.png | Bin 0 -> 1853 bytes .../icons/hicolor/64x64/bazzite-logo-icon.png | Bin 0 -> 2571 bytes .../icons/hicolor/96x96/bazzite-logo-icon.png | Bin 0 -> 4083 bytes .../hicolor/scalable/places/bazzite-logo-le.svg | 19 +++++++++++++ .../scalable/places/distributor-logo-white.svg | 11 ++++++++ .../hicolor/scalable/places/distributor-logo.svg | 19 +++++++++++++ .../usr/share/pixmaps/bazzite-logo-le.svg | 19 +++++++++++++ .../usr/share/pixmaps/bootloader/fedora.icns | Bin 0 -> 15377 bytes .../usr/share/pixmaps/combination_med.png | Bin 0 -> 76166 bytes .../usr/share/pixmaps/fedora-gdm-logo.png | Bin 0 -> 8908 bytes .../usr/share/pixmaps/fedora-logo-small.png | Bin 0 -> 9520 bytes .../usr/share/pixmaps/fedora-logo-sprite.png | Bin 0 -> 15673 bytes .../usr/share/pixmaps/fedora-logo-sprite.svg | 19 +++++++++++++ .../overrides/usr/share/pixmaps/fedora-logo.png | Bin 0 -> 48311 bytes .../usr/share/pixmaps/fedora_logo_med.png | Bin 0 -> 11667 bytes .../usr/share/pixmaps/fedora_whitelogo.png | Bin 0 -> 71205 bytes .../usr/share/pixmaps/fedora_whitelogo.svg | 31 +++++++++++++++++++++ .../usr/share/pixmaps/fedora_whitelogo_med.png | Bin 0 -> 10651 bytes .../usr/share/pixmaps/system-logo-white.png | Bin 0 -> 53377 bytes 30 files changed, 160 insertions(+) create mode 100644 system_files/desktop/shared/usr/share/plymouth/themes/spinner/watermark.png create mode 100644 system_files/desktop/shared/usr/share/ublue-os/bazzite/docs.svg create mode 100644 system_files/desktop/shared/usr/share/ublue-os/bazzite/logo.svg create mode 100644 system_files/desktop/shared/usr/share/ublue-os/bazzite/updatelogo.png create mode 100644 system_files/overrides/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png create mode 100644 system_files/overrides/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png create mode 100644 system_files/overrides/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png create mode 100644 system_files/overrides/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png create mode 100644 system_files/overrides/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png create mode 100644 system_files/overrides/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png create mode 100644 system_files/overrides/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png create mode 100644 system_files/overrides/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png create mode 100644 system_files/overrides/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png create mode 100644 system_files/overrides/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png create mode 100644 system_files/overrides/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg create mode 100644 system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg create mode 100644 system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo.svg create mode 100644 system_files/overrides/usr/share/pixmaps/bazzite-logo-le.svg create mode 100644 system_files/overrides/usr/share/pixmaps/bootloader/fedora.icns create mode 100644 system_files/overrides/usr/share/pixmaps/combination_med.png create mode 100644 system_files/overrides/usr/share/pixmaps/fedora-gdm-logo.png create mode 100644 system_files/overrides/usr/share/pixmaps/fedora-logo-small.png create mode 100644 system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.png create mode 100644 system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.svg create mode 100644 system_files/overrides/usr/share/pixmaps/fedora-logo.png create mode 100644 system_files/overrides/usr/share/pixmaps/fedora_logo_med.png create mode 100644 system_files/overrides/usr/share/pixmaps/fedora_whitelogo.png create mode 100644 system_files/overrides/usr/share/pixmaps/fedora_whitelogo.svg create mode 100644 system_files/overrides/usr/share/pixmaps/fedora_whitelogo_med.png create mode 100644 system_files/overrides/usr/share/pixmaps/system-logo-white.png diff --git a/system_files/desktop/shared/usr/share/plymouth/themes/spinner/watermark.png b/system_files/desktop/shared/usr/share/plymouth/themes/spinner/watermark.png new file mode 100644 index 0000000..4b53dd2 Binary files /dev/null and b/system_files/desktop/shared/usr/share/plymouth/themes/spinner/watermark.png differ diff --git a/system_files/desktop/shared/usr/share/ublue-os/bazzite/docs.svg b/system_files/desktop/shared/usr/share/ublue-os/bazzite/docs.svg new file mode 100644 index 0000000..a7e16e7 --- /dev/null +++ b/system_files/desktop/shared/usr/share/ublue-os/bazzite/docs.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/system_files/desktop/shared/usr/share/ublue-os/bazzite/logo.svg b/system_files/desktop/shared/usr/share/ublue-os/bazzite/logo.svg new file mode 100644 index 0000000..bd0dae2 --- /dev/null +++ b/system_files/desktop/shared/usr/share/ublue-os/bazzite/logo.svg @@ -0,0 +1,19 @@ + + + AeroCoreIcon + + + + + + + + + + + + + + + + diff --git a/system_files/desktop/shared/usr/share/ublue-os/bazzite/updatelogo.png b/system_files/desktop/shared/usr/share/ublue-os/bazzite/updatelogo.png new file mode 100644 index 0000000..1b3cb8a Binary files /dev/null and b/system_files/desktop/shared/usr/share/ublue-os/bazzite/updatelogo.png differ diff --git a/system_files/overrides/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png new file mode 100644 index 0000000..30cd4aa Binary files /dev/null and b/system_files/overrides/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png differ diff --git a/system_files/overrides/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png new file mode 100644 index 0000000..e7d57f9 Binary files /dev/null and b/system_files/overrides/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png differ diff --git a/system_files/overrides/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png new file mode 100644 index 0000000..f368a0a Binary files /dev/null and b/system_files/overrides/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png differ diff --git a/system_files/overrides/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png new file mode 100644 index 0000000..b722b22 Binary files /dev/null and b/system_files/overrides/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png differ diff --git a/system_files/overrides/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png new file mode 100644 index 0000000..b7acaa2 Binary files /dev/null and b/system_files/overrides/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png differ diff --git a/system_files/overrides/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png new file mode 100644 index 0000000..54e23b2 Binary files /dev/null and b/system_files/overrides/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png differ diff --git a/system_files/overrides/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png new file mode 100644 index 0000000..ff03f27 Binary files /dev/null and b/system_files/overrides/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png differ diff --git a/system_files/overrides/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png new file mode 100644 index 0000000..977f02e Binary files /dev/null and b/system_files/overrides/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png differ diff --git a/system_files/overrides/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png new file mode 100644 index 0000000..74477a7 Binary files /dev/null and b/system_files/overrides/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png differ diff --git a/system_files/overrides/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png new file mode 100644 index 0000000..ea0d730 Binary files /dev/null and b/system_files/overrides/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png differ diff --git a/system_files/overrides/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg b/system_files/overrides/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg new file mode 100644 index 0000000..291b91c --- /dev/null +++ b/system_files/overrides/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg @@ -0,0 +1,19 @@ + + + AeroCoreIcon + + + + + + + + + + + + + + + + diff --git a/system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg b/system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg new file mode 100644 index 0000000..5f58794 --- /dev/null +++ b/system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg @@ -0,0 +1,11 @@ + + + distributor-logo-white + + + + + + + + diff --git a/system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo.svg b/system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo.svg new file mode 100644 index 0000000..291b91c --- /dev/null +++ b/system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo.svg @@ -0,0 +1,19 @@ + + + AeroCoreIcon + + + + + + + + + + + + + + + + diff --git a/system_files/overrides/usr/share/pixmaps/bazzite-logo-le.svg b/system_files/overrides/usr/share/pixmaps/bazzite-logo-le.svg new file mode 100644 index 0000000..bd0dae2 --- /dev/null +++ b/system_files/overrides/usr/share/pixmaps/bazzite-logo-le.svg @@ -0,0 +1,19 @@ + + + AeroCoreIcon + + + + + + + + + + + + + + + + diff --git a/system_files/overrides/usr/share/pixmaps/bootloader/fedora.icns b/system_files/overrides/usr/share/pixmaps/bootloader/fedora.icns new file mode 100644 index 0000000..c16933f Binary files /dev/null and b/system_files/overrides/usr/share/pixmaps/bootloader/fedora.icns differ diff --git a/system_files/overrides/usr/share/pixmaps/combination_med.png b/system_files/overrides/usr/share/pixmaps/combination_med.png new file mode 100644 index 0000000..2f75183 Binary files /dev/null and b/system_files/overrides/usr/share/pixmaps/combination_med.png differ diff --git a/system_files/overrides/usr/share/pixmaps/fedora-gdm-logo.png b/system_files/overrides/usr/share/pixmaps/fedora-gdm-logo.png new file mode 100644 index 0000000..b903599 Binary files /dev/null and b/system_files/overrides/usr/share/pixmaps/fedora-gdm-logo.png differ diff --git a/system_files/overrides/usr/share/pixmaps/fedora-logo-small.png b/system_files/overrides/usr/share/pixmaps/fedora-logo-small.png new file mode 100644 index 0000000..02e6d48 Binary files /dev/null and b/system_files/overrides/usr/share/pixmaps/fedora-logo-small.png differ diff --git a/system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.png b/system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.png new file mode 100644 index 0000000..1f02770 Binary files /dev/null and b/system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.png differ diff --git a/system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.svg b/system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.svg new file mode 100644 index 0000000..bd0dae2 --- /dev/null +++ b/system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.svg @@ -0,0 +1,19 @@ + + + AeroCoreIcon + + + + + + + + + + + + + + + + diff --git a/system_files/overrides/usr/share/pixmaps/fedora-logo.png b/system_files/overrides/usr/share/pixmaps/fedora-logo.png new file mode 100644 index 0000000..55d2a45 Binary files /dev/null and b/system_files/overrides/usr/share/pixmaps/fedora-logo.png differ diff --git a/system_files/overrides/usr/share/pixmaps/fedora_logo_med.png b/system_files/overrides/usr/share/pixmaps/fedora_logo_med.png new file mode 100644 index 0000000..e5b8db5 Binary files /dev/null and b/system_files/overrides/usr/share/pixmaps/fedora_logo_med.png differ diff --git a/system_files/overrides/usr/share/pixmaps/fedora_whitelogo.png b/system_files/overrides/usr/share/pixmaps/fedora_whitelogo.png new file mode 100644 index 0000000..66e2c3e Binary files /dev/null and b/system_files/overrides/usr/share/pixmaps/fedora_whitelogo.png differ diff --git a/system_files/overrides/usr/share/pixmaps/fedora_whitelogo.svg b/system_files/overrides/usr/share/pixmaps/fedora_whitelogo.svg new file mode 100644 index 0000000..372e337 --- /dev/null +++ b/system_files/overrides/usr/share/pixmaps/fedora_whitelogo.svg @@ -0,0 +1,31 @@ + + + AeroCoreLogo_WhiteText + + + + + + + + diff --git a/system_files/overrides/usr/share/pixmaps/fedora_whitelogo_med.png b/system_files/overrides/usr/share/pixmaps/fedora_whitelogo_med.png new file mode 100644 index 0000000..3b12a8c Binary files /dev/null and b/system_files/overrides/usr/share/pixmaps/fedora_whitelogo_med.png differ diff --git a/system_files/overrides/usr/share/pixmaps/system-logo-white.png b/system_files/overrides/usr/share/pixmaps/system-logo-white.png new file mode 100644 index 0000000..60349b2 Binary files /dev/null and b/system_files/overrides/usr/share/pixmaps/system-logo-white.png differ -- cgit v1.2.3 From 664753059edb7b62e829e058f5c7e187b2437cb5 Mon Sep 17 00:00:00 2001 From: tranch Date: Sun, 12 Jul 2026 17:49:39 +0800 Subject: Fix logo overlay paths Place branding assets under the paths copied directly into the image. --- .../share/plymouth/themes/spinner/watermark.png | Bin 4140 -> 0 bytes .../shared/usr/share/ublue-os/bazzite/docs.svg | 23 --------------- .../shared/usr/share/ublue-os/bazzite/logo.svg | 19 ------------- .../usr/share/ublue-os/bazzite/updatelogo.png | Bin 61110 -> 0 bytes .../icons/hicolor/128x128/bazzite-logo-icon.png | Bin 5613 -> 0 bytes .../icons/hicolor/16x16/bazzite-logo-icon.png | Bin 634 -> 0 bytes .../icons/hicolor/22x22/bazzite-logo-icon.png | Bin 837 -> 0 bytes .../icons/hicolor/24x24/bazzite-logo-icon.png | Bin 921 -> 0 bytes .../icons/hicolor/256x256/bazzite-logo-icon.png | Bin 12105 -> 0 bytes .../icons/hicolor/32x32/bazzite-logo-icon.png | Bin 1203 -> 0 bytes .../icons/hicolor/36x36/bazzite-logo-icon.png | Bin 1345 -> 0 bytes .../icons/hicolor/48x48/bazzite-logo-icon.png | Bin 1853 -> 0 bytes .../icons/hicolor/64x64/bazzite-logo-icon.png | Bin 2571 -> 0 bytes .../icons/hicolor/96x96/bazzite-logo-icon.png | Bin 4083 -> 0 bytes .../hicolor/scalable/places/bazzite-logo-le.svg | 19 ------------- .../scalable/places/distributor-logo-white.svg | 11 -------- .../hicolor/scalable/places/distributor-logo.svg | 19 ------------- .../usr/share/pixmaps/bazzite-logo-le.svg | 19 ------------- .../usr/share/pixmaps/bootloader/fedora.icns | Bin 15377 -> 0 bytes .../usr/share/pixmaps/combination_med.png | Bin 76166 -> 0 bytes .../usr/share/pixmaps/fedora-gdm-logo.png | Bin 8908 -> 0 bytes .../usr/share/pixmaps/fedora-logo-small.png | Bin 9520 -> 0 bytes .../usr/share/pixmaps/fedora-logo-sprite.png | Bin 15673 -> 0 bytes .../usr/share/pixmaps/fedora-logo-sprite.svg | 19 ------------- .../overrides/usr/share/pixmaps/fedora-logo.png | Bin 48311 -> 0 bytes .../usr/share/pixmaps/fedora_logo_med.png | Bin 11667 -> 0 bytes .../usr/share/pixmaps/fedora_whitelogo.png | Bin 71205 -> 0 bytes .../usr/share/pixmaps/fedora_whitelogo.svg | 31 --------------------- .../usr/share/pixmaps/fedora_whitelogo_med.png | Bin 10651 -> 0 bytes .../usr/share/pixmaps/system-logo-white.png | Bin 53377 -> 0 bytes .../icons/hicolor/128x128/bazzite-logo-icon.png | Bin 0 -> 5613 bytes .../icons/hicolor/16x16/bazzite-logo-icon.png | Bin 0 -> 634 bytes .../icons/hicolor/22x22/bazzite-logo-icon.png | Bin 0 -> 837 bytes .../icons/hicolor/24x24/bazzite-logo-icon.png | Bin 0 -> 921 bytes .../icons/hicolor/256x256/bazzite-logo-icon.png | Bin 0 -> 12105 bytes .../icons/hicolor/32x32/bazzite-logo-icon.png | Bin 0 -> 1203 bytes .../icons/hicolor/36x36/bazzite-logo-icon.png | Bin 0 -> 1345 bytes .../icons/hicolor/48x48/bazzite-logo-icon.png | Bin 0 -> 1853 bytes .../icons/hicolor/64x64/bazzite-logo-icon.png | Bin 0 -> 2571 bytes .../icons/hicolor/96x96/bazzite-logo-icon.png | Bin 0 -> 4083 bytes .../hicolor/scalable/places/bazzite-logo-le.svg | 19 +++++++++++++ .../scalable/places/distributor-logo-white.svg | 11 ++++++++ .../hicolor/scalable/places/distributor-logo.svg | 19 +++++++++++++ system_files/usr/share/pixmaps/bazzite-logo-le.svg | 19 +++++++++++++ .../usr/share/pixmaps/bootloader/fedora.icns | Bin 0 -> 15377 bytes system_files/usr/share/pixmaps/combination_med.png | Bin 0 -> 76166 bytes system_files/usr/share/pixmaps/fedora-gdm-logo.png | Bin 0 -> 8908 bytes .../usr/share/pixmaps/fedora-logo-small.png | Bin 0 -> 9520 bytes .../usr/share/pixmaps/fedora-logo-sprite.png | Bin 0 -> 15673 bytes .../usr/share/pixmaps/fedora-logo-sprite.svg | 19 +++++++++++++ system_files/usr/share/pixmaps/fedora-logo.png | Bin 0 -> 48311 bytes system_files/usr/share/pixmaps/fedora_logo_med.png | Bin 0 -> 11667 bytes .../usr/share/pixmaps/fedora_whitelogo.png | Bin 0 -> 71205 bytes .../usr/share/pixmaps/fedora_whitelogo.svg | 31 +++++++++++++++++++++ .../usr/share/pixmaps/fedora_whitelogo_med.png | Bin 0 -> 10651 bytes .../usr/share/pixmaps/system-logo-white.png | Bin 0 -> 53377 bytes .../share/plymouth/themes/spinner/watermark.png | Bin 0 -> 4140 bytes system_files/usr/share/ublue-os/bazzite/docs.svg | 23 +++++++++++++++ system_files/usr/share/ublue-os/bazzite/logo.svg | 19 +++++++++++++ .../usr/share/ublue-os/bazzite/updatelogo.png | Bin 0 -> 61110 bytes 60 files changed, 160 insertions(+), 160 deletions(-) delete mode 100644 system_files/desktop/shared/usr/share/plymouth/themes/spinner/watermark.png delete mode 100644 system_files/desktop/shared/usr/share/ublue-os/bazzite/docs.svg delete mode 100644 system_files/desktop/shared/usr/share/ublue-os/bazzite/logo.svg delete mode 100644 system_files/desktop/shared/usr/share/ublue-os/bazzite/updatelogo.png delete mode 100644 system_files/overrides/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png delete mode 100644 system_files/overrides/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png delete mode 100644 system_files/overrides/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png delete mode 100644 system_files/overrides/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png delete mode 100644 system_files/overrides/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png delete mode 100644 system_files/overrides/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png delete mode 100644 system_files/overrides/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png delete mode 100644 system_files/overrides/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png delete mode 100644 system_files/overrides/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png delete mode 100644 system_files/overrides/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png delete mode 100644 system_files/overrides/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg delete mode 100644 system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg delete mode 100644 system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo.svg delete mode 100644 system_files/overrides/usr/share/pixmaps/bazzite-logo-le.svg delete mode 100644 system_files/overrides/usr/share/pixmaps/bootloader/fedora.icns delete mode 100644 system_files/overrides/usr/share/pixmaps/combination_med.png delete mode 100644 system_files/overrides/usr/share/pixmaps/fedora-gdm-logo.png delete mode 100644 system_files/overrides/usr/share/pixmaps/fedora-logo-small.png delete mode 100644 system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.png delete mode 100644 system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.svg delete mode 100644 system_files/overrides/usr/share/pixmaps/fedora-logo.png delete mode 100644 system_files/overrides/usr/share/pixmaps/fedora_logo_med.png delete mode 100644 system_files/overrides/usr/share/pixmaps/fedora_whitelogo.png delete mode 100644 system_files/overrides/usr/share/pixmaps/fedora_whitelogo.svg delete mode 100644 system_files/overrides/usr/share/pixmaps/fedora_whitelogo_med.png delete mode 100644 system_files/overrides/usr/share/pixmaps/system-logo-white.png create mode 100644 system_files/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png create mode 100644 system_files/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png create mode 100644 system_files/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png create mode 100644 system_files/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png create mode 100644 system_files/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png create mode 100644 system_files/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png create mode 100644 system_files/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png create mode 100644 system_files/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png create mode 100644 system_files/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png create mode 100644 system_files/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png create mode 100644 system_files/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg create mode 100644 system_files/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg create mode 100644 system_files/usr/share/icons/hicolor/scalable/places/distributor-logo.svg create mode 100644 system_files/usr/share/pixmaps/bazzite-logo-le.svg create mode 100644 system_files/usr/share/pixmaps/bootloader/fedora.icns create mode 100644 system_files/usr/share/pixmaps/combination_med.png create mode 100644 system_files/usr/share/pixmaps/fedora-gdm-logo.png create mode 100644 system_files/usr/share/pixmaps/fedora-logo-small.png create mode 100644 system_files/usr/share/pixmaps/fedora-logo-sprite.png create mode 100644 system_files/usr/share/pixmaps/fedora-logo-sprite.svg create mode 100644 system_files/usr/share/pixmaps/fedora-logo.png create mode 100644 system_files/usr/share/pixmaps/fedora_logo_med.png create mode 100644 system_files/usr/share/pixmaps/fedora_whitelogo.png create mode 100644 system_files/usr/share/pixmaps/fedora_whitelogo.svg create mode 100644 system_files/usr/share/pixmaps/fedora_whitelogo_med.png create mode 100644 system_files/usr/share/pixmaps/system-logo-white.png create mode 100644 system_files/usr/share/plymouth/themes/spinner/watermark.png create mode 100644 system_files/usr/share/ublue-os/bazzite/docs.svg create mode 100644 system_files/usr/share/ublue-os/bazzite/logo.svg create mode 100644 system_files/usr/share/ublue-os/bazzite/updatelogo.png diff --git a/system_files/desktop/shared/usr/share/plymouth/themes/spinner/watermark.png b/system_files/desktop/shared/usr/share/plymouth/themes/spinner/watermark.png deleted file mode 100644 index 4b53dd2..0000000 Binary files a/system_files/desktop/shared/usr/share/plymouth/themes/spinner/watermark.png and /dev/null differ diff --git a/system_files/desktop/shared/usr/share/ublue-os/bazzite/docs.svg b/system_files/desktop/shared/usr/share/ublue-os/bazzite/docs.svg deleted file mode 100644 index a7e16e7..0000000 --- a/system_files/desktop/shared/usr/share/ublue-os/bazzite/docs.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/system_files/desktop/shared/usr/share/ublue-os/bazzite/logo.svg b/system_files/desktop/shared/usr/share/ublue-os/bazzite/logo.svg deleted file mode 100644 index bd0dae2..0000000 --- a/system_files/desktop/shared/usr/share/ublue-os/bazzite/logo.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - AeroCoreIcon - - - - - - - - - - - - - - - - diff --git a/system_files/desktop/shared/usr/share/ublue-os/bazzite/updatelogo.png b/system_files/desktop/shared/usr/share/ublue-os/bazzite/updatelogo.png deleted file mode 100644 index 1b3cb8a..0000000 Binary files a/system_files/desktop/shared/usr/share/ublue-os/bazzite/updatelogo.png and /dev/null differ diff --git a/system_files/overrides/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png deleted file mode 100644 index 30cd4aa..0000000 Binary files a/system_files/overrides/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png and /dev/null differ diff --git a/system_files/overrides/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png deleted file mode 100644 index e7d57f9..0000000 Binary files a/system_files/overrides/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png and /dev/null differ diff --git a/system_files/overrides/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png deleted file mode 100644 index f368a0a..0000000 Binary files a/system_files/overrides/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png and /dev/null differ diff --git a/system_files/overrides/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png deleted file mode 100644 index b722b22..0000000 Binary files a/system_files/overrides/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png and /dev/null differ diff --git a/system_files/overrides/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png deleted file mode 100644 index b7acaa2..0000000 Binary files a/system_files/overrides/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png and /dev/null differ diff --git a/system_files/overrides/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png deleted file mode 100644 index 54e23b2..0000000 Binary files a/system_files/overrides/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png and /dev/null differ diff --git a/system_files/overrides/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png deleted file mode 100644 index ff03f27..0000000 Binary files a/system_files/overrides/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png and /dev/null differ diff --git a/system_files/overrides/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png deleted file mode 100644 index 977f02e..0000000 Binary files a/system_files/overrides/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png and /dev/null differ diff --git a/system_files/overrides/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png deleted file mode 100644 index 74477a7..0000000 Binary files a/system_files/overrides/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png and /dev/null differ diff --git a/system_files/overrides/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png b/system_files/overrides/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png deleted file mode 100644 index ea0d730..0000000 Binary files a/system_files/overrides/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png and /dev/null differ diff --git a/system_files/overrides/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg b/system_files/overrides/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg deleted file mode 100644 index 291b91c..0000000 --- a/system_files/overrides/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - AeroCoreIcon - - - - - - - - - - - - - - - - diff --git a/system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg b/system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg deleted file mode 100644 index 5f58794..0000000 --- a/system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - distributor-logo-white - - - - - - - - diff --git a/system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo.svg b/system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo.svg deleted file mode 100644 index 291b91c..0000000 --- a/system_files/overrides/usr/share/icons/hicolor/scalable/places/distributor-logo.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - AeroCoreIcon - - - - - - - - - - - - - - - - diff --git a/system_files/overrides/usr/share/pixmaps/bazzite-logo-le.svg b/system_files/overrides/usr/share/pixmaps/bazzite-logo-le.svg deleted file mode 100644 index bd0dae2..0000000 --- a/system_files/overrides/usr/share/pixmaps/bazzite-logo-le.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - AeroCoreIcon - - - - - - - - - - - - - - - - diff --git a/system_files/overrides/usr/share/pixmaps/bootloader/fedora.icns b/system_files/overrides/usr/share/pixmaps/bootloader/fedora.icns deleted file mode 100644 index c16933f..0000000 Binary files a/system_files/overrides/usr/share/pixmaps/bootloader/fedora.icns and /dev/null differ diff --git a/system_files/overrides/usr/share/pixmaps/combination_med.png b/system_files/overrides/usr/share/pixmaps/combination_med.png deleted file mode 100644 index 2f75183..0000000 Binary files a/system_files/overrides/usr/share/pixmaps/combination_med.png and /dev/null differ diff --git a/system_files/overrides/usr/share/pixmaps/fedora-gdm-logo.png b/system_files/overrides/usr/share/pixmaps/fedora-gdm-logo.png deleted file mode 100644 index b903599..0000000 Binary files a/system_files/overrides/usr/share/pixmaps/fedora-gdm-logo.png and /dev/null differ diff --git a/system_files/overrides/usr/share/pixmaps/fedora-logo-small.png b/system_files/overrides/usr/share/pixmaps/fedora-logo-small.png deleted file mode 100644 index 02e6d48..0000000 Binary files a/system_files/overrides/usr/share/pixmaps/fedora-logo-small.png and /dev/null differ diff --git a/system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.png b/system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.png deleted file mode 100644 index 1f02770..0000000 Binary files a/system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.png and /dev/null differ diff --git a/system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.svg b/system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.svg deleted file mode 100644 index bd0dae2..0000000 --- a/system_files/overrides/usr/share/pixmaps/fedora-logo-sprite.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - AeroCoreIcon - - - - - - - - - - - - - - - - diff --git a/system_files/overrides/usr/share/pixmaps/fedora-logo.png b/system_files/overrides/usr/share/pixmaps/fedora-logo.png deleted file mode 100644 index 55d2a45..0000000 Binary files a/system_files/overrides/usr/share/pixmaps/fedora-logo.png and /dev/null differ diff --git a/system_files/overrides/usr/share/pixmaps/fedora_logo_med.png b/system_files/overrides/usr/share/pixmaps/fedora_logo_med.png deleted file mode 100644 index e5b8db5..0000000 Binary files a/system_files/overrides/usr/share/pixmaps/fedora_logo_med.png and /dev/null differ diff --git a/system_files/overrides/usr/share/pixmaps/fedora_whitelogo.png b/system_files/overrides/usr/share/pixmaps/fedora_whitelogo.png deleted file mode 100644 index 66e2c3e..0000000 Binary files a/system_files/overrides/usr/share/pixmaps/fedora_whitelogo.png and /dev/null differ diff --git a/system_files/overrides/usr/share/pixmaps/fedora_whitelogo.svg b/system_files/overrides/usr/share/pixmaps/fedora_whitelogo.svg deleted file mode 100644 index 372e337..0000000 --- a/system_files/overrides/usr/share/pixmaps/fedora_whitelogo.svg +++ /dev/null @@ -1,31 +0,0 @@ - - - AeroCoreLogo_WhiteText - - - - - - - - diff --git a/system_files/overrides/usr/share/pixmaps/fedora_whitelogo_med.png b/system_files/overrides/usr/share/pixmaps/fedora_whitelogo_med.png deleted file mode 100644 index 3b12a8c..0000000 Binary files a/system_files/overrides/usr/share/pixmaps/fedora_whitelogo_med.png and /dev/null differ diff --git a/system_files/overrides/usr/share/pixmaps/system-logo-white.png b/system_files/overrides/usr/share/pixmaps/system-logo-white.png deleted file mode 100644 index 60349b2..0000000 Binary files a/system_files/overrides/usr/share/pixmaps/system-logo-white.png and /dev/null differ diff --git a/system_files/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png new file mode 100644 index 0000000..30cd4aa Binary files /dev/null and b/system_files/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png new file mode 100644 index 0000000..e7d57f9 Binary files /dev/null and b/system_files/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png new file mode 100644 index 0000000..f368a0a Binary files /dev/null and b/system_files/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png new file mode 100644 index 0000000..b722b22 Binary files /dev/null and b/system_files/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png new file mode 100644 index 0000000..b7acaa2 Binary files /dev/null and b/system_files/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png new file mode 100644 index 0000000..54e23b2 Binary files /dev/null and b/system_files/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png new file mode 100644 index 0000000..ff03f27 Binary files /dev/null and b/system_files/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png new file mode 100644 index 0000000..977f02e Binary files /dev/null and b/system_files/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png new file mode 100644 index 0000000..74477a7 Binary files /dev/null and b/system_files/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png new file mode 100644 index 0000000..ea0d730 Binary files /dev/null and b/system_files/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg b/system_files/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg new file mode 100644 index 0000000..291b91c --- /dev/null +++ b/system_files/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg @@ -0,0 +1,19 @@ + + + AeroCoreIcon + + + + + + + + + + + + + + + + diff --git a/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg b/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg new file mode 100644 index 0000000..5f58794 --- /dev/null +++ b/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg @@ -0,0 +1,11 @@ + + + distributor-logo-white + + + + + + + + diff --git a/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo.svg b/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo.svg new file mode 100644 index 0000000..291b91c --- /dev/null +++ b/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo.svg @@ -0,0 +1,19 @@ + + + AeroCoreIcon + + + + + + + + + + + + + + + + diff --git a/system_files/usr/share/pixmaps/bazzite-logo-le.svg b/system_files/usr/share/pixmaps/bazzite-logo-le.svg new file mode 100644 index 0000000..bd0dae2 --- /dev/null +++ b/system_files/usr/share/pixmaps/bazzite-logo-le.svg @@ -0,0 +1,19 @@ + + + AeroCoreIcon + + + + + + + + + + + + + + + + diff --git a/system_files/usr/share/pixmaps/bootloader/fedora.icns b/system_files/usr/share/pixmaps/bootloader/fedora.icns new file mode 100644 index 0000000..c16933f Binary files /dev/null and b/system_files/usr/share/pixmaps/bootloader/fedora.icns differ diff --git a/system_files/usr/share/pixmaps/combination_med.png b/system_files/usr/share/pixmaps/combination_med.png new file mode 100644 index 0000000..2f75183 Binary files /dev/null and b/system_files/usr/share/pixmaps/combination_med.png differ diff --git a/system_files/usr/share/pixmaps/fedora-gdm-logo.png b/system_files/usr/share/pixmaps/fedora-gdm-logo.png new file mode 100644 index 0000000..b903599 Binary files /dev/null and b/system_files/usr/share/pixmaps/fedora-gdm-logo.png differ diff --git a/system_files/usr/share/pixmaps/fedora-logo-small.png b/system_files/usr/share/pixmaps/fedora-logo-small.png new file mode 100644 index 0000000..02e6d48 Binary files /dev/null and b/system_files/usr/share/pixmaps/fedora-logo-small.png differ diff --git a/system_files/usr/share/pixmaps/fedora-logo-sprite.png b/system_files/usr/share/pixmaps/fedora-logo-sprite.png new file mode 100644 index 0000000..1f02770 Binary files /dev/null and b/system_files/usr/share/pixmaps/fedora-logo-sprite.png differ diff --git a/system_files/usr/share/pixmaps/fedora-logo-sprite.svg b/system_files/usr/share/pixmaps/fedora-logo-sprite.svg new file mode 100644 index 0000000..bd0dae2 --- /dev/null +++ b/system_files/usr/share/pixmaps/fedora-logo-sprite.svg @@ -0,0 +1,19 @@ + + + AeroCoreIcon + + + + + + + + + + + + + + + + diff --git a/system_files/usr/share/pixmaps/fedora-logo.png b/system_files/usr/share/pixmaps/fedora-logo.png new file mode 100644 index 0000000..55d2a45 Binary files /dev/null and b/system_files/usr/share/pixmaps/fedora-logo.png differ diff --git a/system_files/usr/share/pixmaps/fedora_logo_med.png b/system_files/usr/share/pixmaps/fedora_logo_med.png new file mode 100644 index 0000000..e5b8db5 Binary files /dev/null and b/system_files/usr/share/pixmaps/fedora_logo_med.png differ diff --git a/system_files/usr/share/pixmaps/fedora_whitelogo.png b/system_files/usr/share/pixmaps/fedora_whitelogo.png new file mode 100644 index 0000000..66e2c3e Binary files /dev/null and b/system_files/usr/share/pixmaps/fedora_whitelogo.png differ diff --git a/system_files/usr/share/pixmaps/fedora_whitelogo.svg b/system_files/usr/share/pixmaps/fedora_whitelogo.svg new file mode 100644 index 0000000..372e337 --- /dev/null +++ b/system_files/usr/share/pixmaps/fedora_whitelogo.svg @@ -0,0 +1,31 @@ + + + AeroCoreLogo_WhiteText + + + + + + + + diff --git a/system_files/usr/share/pixmaps/fedora_whitelogo_med.png b/system_files/usr/share/pixmaps/fedora_whitelogo_med.png new file mode 100644 index 0000000..3b12a8c Binary files /dev/null and b/system_files/usr/share/pixmaps/fedora_whitelogo_med.png differ diff --git a/system_files/usr/share/pixmaps/system-logo-white.png b/system_files/usr/share/pixmaps/system-logo-white.png new file mode 100644 index 0000000..60349b2 Binary files /dev/null and b/system_files/usr/share/pixmaps/system-logo-white.png differ diff --git a/system_files/usr/share/plymouth/themes/spinner/watermark.png b/system_files/usr/share/plymouth/themes/spinner/watermark.png new file mode 100644 index 0000000..4b53dd2 Binary files /dev/null and b/system_files/usr/share/plymouth/themes/spinner/watermark.png differ diff --git a/system_files/usr/share/ublue-os/bazzite/docs.svg b/system_files/usr/share/ublue-os/bazzite/docs.svg new file mode 100644 index 0000000..a7e16e7 --- /dev/null +++ b/system_files/usr/share/ublue-os/bazzite/docs.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/system_files/usr/share/ublue-os/bazzite/logo.svg b/system_files/usr/share/ublue-os/bazzite/logo.svg new file mode 100644 index 0000000..bd0dae2 --- /dev/null +++ b/system_files/usr/share/ublue-os/bazzite/logo.svg @@ -0,0 +1,19 @@ + + + AeroCoreIcon + + + + + + + + + + + + + + + + diff --git a/system_files/usr/share/ublue-os/bazzite/updatelogo.png b/system_files/usr/share/ublue-os/bazzite/updatelogo.png new file mode 100644 index 0000000..1b3cb8a Binary files /dev/null and b/system_files/usr/share/ublue-os/bazzite/updatelogo.png differ -- cgit v1.2.3 From 4f8c98d87405956489a3fd0a816eaa2196e52034 Mon Sep 17 00:00:00 2001 From: tranch Date: Sun, 12 Jul 2026 18:45:16 +0800 Subject: Add AeroCore SteamOS splash assets Add the desktop transition logo and replace the SteamOS update splash. --- .../contents/splash/images/bazzite_logo.svgz | Bin 0 -> 1384 bytes .../contents/splash/images/bazzite_logo.svgz | Bin 0 -> 1384 bytes system_files/usr/share/steamos/steamos.png | Bin 0 -> 20042 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 system_files/usr/share/plasma/look-and-feel/com.valve.vapor.desktop/contents/splash/images/bazzite_logo.svgz create mode 100644 system_files/usr/share/plasma/look-and-feel/com.valve.vgui.desktop/contents/splash/images/bazzite_logo.svgz create mode 100644 system_files/usr/share/steamos/steamos.png diff --git a/system_files/usr/share/plasma/look-and-feel/com.valve.vapor.desktop/contents/splash/images/bazzite_logo.svgz b/system_files/usr/share/plasma/look-and-feel/com.valve.vapor.desktop/contents/splash/images/bazzite_logo.svgz new file mode 100644 index 0000000..0da602b Binary files /dev/null and b/system_files/usr/share/plasma/look-and-feel/com.valve.vapor.desktop/contents/splash/images/bazzite_logo.svgz differ diff --git a/system_files/usr/share/plasma/look-and-feel/com.valve.vgui.desktop/contents/splash/images/bazzite_logo.svgz b/system_files/usr/share/plasma/look-and-feel/com.valve.vgui.desktop/contents/splash/images/bazzite_logo.svgz new file mode 100644 index 0000000..0da602b Binary files /dev/null and b/system_files/usr/share/plasma/look-and-feel/com.valve.vgui.desktop/contents/splash/images/bazzite_logo.svgz differ diff --git a/system_files/usr/share/steamos/steamos.png b/system_files/usr/share/steamos/steamos.png new file mode 100644 index 0000000..3c75128 Binary files /dev/null and b/system_files/usr/share/steamos/steamos.png differ -- cgit v1.2.3 From def4f7576cbe1a3e5120fb552ae7415f4086ab8d Mon Sep 17 00:00:00 2001 From: tranch Date: Sun, 12 Jul 2026 19:52:33 +0800 Subject: chore: rename image name Change IMAGE_NAEME to aerocore-os --- Containerfile | 2 +- image-template.env | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Containerfile b/Containerfile index 7e029a4..cdcd945 100644 --- a/Containerfile +++ b/Containerfile @@ -7,7 +7,7 @@ COPY system_files /system_files # Base Image FROM ${BASE_IMAGE} -ARG IMAGE_NAME="aerocore-bazzite-image" +ARG IMAGE_NAME="aerocore-os" ARG IMAGE_VENDOR="AeroCore-IO" ARG IMAGE_BRANCH="stable" ARG VERSION_TAG="latest" diff --git a/image-template.env b/image-template.env index bf848fb..76fb1cc 100644 --- a/image-template.env +++ b/image-template.env @@ -1,7 +1,7 @@ # Here we set a bunch of parameters for your image build # output image name, usually same as repo name, change as needed -IMAGE_NAME=aerocore-bazzite-image +IMAGE_NAME=aerocore-os # Make this the same as your github username/organisation REPO_ORGANIZATION="AeroCore-IO" -- cgit v1.2.3 From 4824ba779c139ca57105b5306d74570fe1788814 Mon Sep 17 00:00:00 2001 From: tranch Date: Sun, 12 Jul 2026 23:33:44 +0800 Subject: Add live installer build workflow Add a Bazzite-style installer payload, CI workflow, and local\nPodman commands for building and testing the live ISO.\n\nFix stale disk image configuration references and installer targets. --- .github/workflows/build-disk.yml | 7 +- .github/workflows/build-live-installer.yml | 116 +++++++++++++++++++++ Justfile | 16 ++- README.md | 15 ++- disk_config/iso-gnome.toml | 2 +- disk_config/iso-kde.toml | 2 +- installer/Containerfile | 15 +++ installer/build.sh | 60 +++++++++++ installer/iso.yaml | 10 ++ .../remove_root_password_prompt.tmpl | 1 + installer/lorax_templates/set_default_user.tmpl | 1 + just_scripts/build-live-installer.sh | 58 +++++++++++ just_scripts/run-live-installer.sh | 23 ++++ 13 files changed, 317 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/build-live-installer.yml create mode 100644 installer/Containerfile create mode 100755 installer/build.sh create mode 100644 installer/iso.yaml create mode 100644 installer/lorax_templates/remove_root_password_prompt.tmpl create mode 100644 installer/lorax_templates/set_default_user.tmpl create mode 100755 just_scripts/build-live-installer.sh create mode 100755 just_scripts/run-live-installer.sh diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index 1de6c6e..02ef44a 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -20,7 +20,8 @@ on: - main paths: - './disk_config/disk.toml' - - './disk_config/iso.toml' + - './disk_config/iso-kde.toml' + - './disk_config/iso-gnome.toml' - './.github/workflows/build-disk.yml' env: @@ -36,7 +37,7 @@ concurrency: jobs: build: name: Build disk images - runs-on: ${{ inputs.platform == 'amd64' && 'ubuntu-24.04' || 'ubuntu-24.04-arm' }} + runs-on: ${{ inputs.platform == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} strategy: fail-fast: false matrix: @@ -82,7 +83,7 @@ jobs: uses: osbuild/bootc-image-builder-action@30960621b85c9e76c653082f9ef4cab5a10210d5 # main with: builder-image: ${{ env.BIB_IMAGE }} - config-file: ${{ matrix.disk-type == 'anaconda-iso' && './disk_config/iso.toml' || './disk_config/disk.toml' }} + config-file: ${{ matrix.disk-type == 'anaconda-iso' && './disk_config/iso-kde.toml' || './disk_config/disk.toml' }} image: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }} chown: ${{ env.USER_UID }}:${{ env.USER_GID }} types: ${{ matrix.disk-type }} diff --git a/.github/workflows/build-live-installer.yml b/.github/workflows/build-live-installer.yml new file mode 100644 index 0000000..870699e --- /dev/null +++ b/.github/workflows/build-live-installer.yml @@ -0,0 +1,116 @@ +name: Build live installer + +on: + workflow_dispatch: + inputs: + image_tag: + description: "AeroCore image tag to install" + required: false + default: latest + type: string + workflow_call: + push: + branches: + - main + paths: + - "installer/**" + - "just_scripts/build-live-installer.sh" + - ".github/workflows/build-live-installer.yml" + +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + build-live-installer: + name: Build KDE live installer + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: read + + env: + IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} + IMAGE_TAG: ${{ inputs.image_tag || 'latest' }} + BASE_IMAGE: ghcr.io/ublue-os/bazzite:stable + FEDORA_VERSION: "44" + + steps: + - name: Maximize build space + uses: ublue-os/remove-unwanted-software@cc0becac701cf642c8f0a6613bbdaf5dc36b259e # v9 + with: + remove-codeql: true + + - name: Mount container storage BTRFS loopback + run: | + sudo truncate -s 70G /mnt/podman-storage.img + sudo mkfs.btrfs -f /mnt/podman-storage.img + sudo podman system reset --force + sudo systemctl stop podman.service + sudo mount -o compress-force=zstd:2 /mnt/podman-storage.img /var/lib/containers/storage + sudo systemctl start podman.service + + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + + - name: Install just + uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 + + - name: Prepare image references + run: | + image_name="$(just image_name)" + image_registry="${IMAGE_REGISTRY,,}" + echo "IMAGE_NAME=${image_name,,}" >> "$GITHUB_ENV" + echo "IMAGE_REGISTRY=${image_registry}" >> "$GITHUB_ENV" + + - name: Login to GHCR + run: | + echo '${{ secrets.GITHUB_TOKEN }}' | sudo podman login ghcr.io \ + --username '${{ github.actor }}' --password-stdin + + - name: Pull AeroCore install image + run: | + sudo podman pull "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" + + - name: Build live installer payload + run: | + sudo podman build \ + --cap-add sys_admin \ + --security-opt label=disable \ + --build-arg "BASE_IMAGE=${BASE_IMAGE}" \ + --build-arg "INSTALL_IMAGE_PAYLOAD=${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" \ + --tag localhost/aerocore-live-payload:latest \ + --file installer/Containerfile \ + . + + - name: Build ISO + id: build + uses: Zeglius/titanoboa@revamp-pr + with: + arch: x86_64 + image_name: aerocore-live-payload + image_repo: localhost + variant: Kinoite + version: ${{ env.FEDORA_VERSION }} + image_tag: latest + iso_name: aerocore-os-${{ env.IMAGE_TAG }}-amd64.iso + enable_cache_dnf: "false" + enable_cache_skopeo: "false" + enable_flatpak_dependencies: "false" + additional_templates: /github/workspace/installer/lorax_templates/remove_root_password_prompt.tmpl /github/workspace/installer/lorax_templates/set_default_user.tmpl + + - name: Display checksum + run: | + cat "${{ steps.build.outputs.iso_path }}/${{ steps.build.outputs.iso_name }}-CHECKSUM" + + - name: Upload ISO artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: aerocore-os-live-installer-${{ env.IMAGE_TAG }} + path: | + ${{ steps.build.outputs.iso_path }}/${{ steps.build.outputs.iso_name }} + ${{ steps.build.outputs.iso_path }}/${{ steps.build.outputs.iso_name }}-CHECKSUM + if-no-files-found: error + compression-level: 0 diff --git a/Justfile b/Justfile index e83466d..9ec4dd1 100644 --- a/Justfile +++ b/Justfile @@ -16,11 +16,21 @@ export HOMEBREW_API_DOMAIN := env_var_or_default("HOMEBREW_API_DOMAIN", "") alias build-vm := build-qcow2 alias rebuild-vm := rebuild-qcow2 alias run-vm := run-vm-qcow2 +alias build-live-iso := build-live-installer +alias run-live-iso := run-live-installer [private] default: @just --list +# Build a Bazzite-style live installer ISO +build-live-installer: + @./just_scripts/build-live-installer.sh + +# Boot the live installer ISO with QEMU +run-live-installer: + @./just_scripts/run-live-installer.sh + # Check Just Syntax [group('Just')] check: @@ -348,7 +358,7 @@ build-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_build # Build an ISO virtual machine image [group('Build Virtal Machine Image')] -build-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "iso" "disk_config/iso.toml") +build-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "iso" "disk_config/iso-kde.toml") # Rebuild a QCOW2 virtual machine image [group('Build Virtal Machine Image')] @@ -360,7 +370,7 @@ rebuild-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_reb # Rebuild an ISO virtual machine image [group('Build Virtal Machine Image')] -rebuild-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "iso" "disk_config/iso.toml") +rebuild-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "iso" "disk_config/iso-kde.toml") # Run a virtual machine with the specified image type and configuration _run-vm $target_image $tag $type $config: @@ -414,7 +424,7 @@ run-vm-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_run- # Run a virtual machine from an ISO [group('Run Virtal Machine')] -run-vm-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "iso" "disk_config/iso.toml") +run-vm-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_run-vm target_image tag "iso" "disk_config/iso-kde.toml") # Run a virtual machine using systemd-vmspawn [group('Run Virtal Machine')] diff --git a/README.md b/README.md index fdd7c76..0fc3ba4 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ By focusing strictly on file overlays and configuration writing, this build inte To build AeroCore OS locally, edit `image-template.env` to match your target configurations and then run: ```bash -just build +sudo just build ``` @@ -35,3 +35,16 @@ To test a different upstream base image directly without modifying the environme BASE_IMAGE=ghcr.io/ublue-os/bazzite-deck:testing just build ``` + +To build the Bazzite-style live installer locally, first build the AeroCore +image and then run: + +```bash +sudo just build +just build-live-installer +just run-live-installer +``` + +This requires privileged Podman, a rootful Podman API socket, and roughly +70 GiB of free space. The live installer workflow consumes the published +`latest` AeroCore image and uploads the ISO as a GitHub Actions artifact. diff --git a/disk_config/iso-gnome.toml b/disk_config/iso-gnome.toml index 0a9c84f..0fa5652 100644 --- a/disk_config/iso-gnome.toml +++ b/disk_config/iso-gnome.toml @@ -1,7 +1,7 @@ [customizations.installer.kickstart] contents = """ %post -bootc switch --mutate-in-place --transport registry ghcr.io/ublue-os/image-template:latest +bootc switch --mutate-in-place --transport registry ghcr.io/aerocore-io/aerocore-bazzite-image:latest %end """ diff --git a/disk_config/iso-kde.toml b/disk_config/iso-kde.toml index 17d2787..e6e15a0 100644 --- a/disk_config/iso-kde.toml +++ b/disk_config/iso-kde.toml @@ -1,7 +1,7 @@ [customizations.installer.kickstart] contents = """ %post -bootc switch --mutate-in-place --transport registry ghcr.io/ublue-os/image-template:latest +bootc switch --mutate-in-place --transport registry ghcr.io/aerocore-io/aerocore-bazzite-image:latest %end """ diff --git a/installer/Containerfile b/installer/Containerfile new file mode 100644 index 0000000..fa817b6 --- /dev/null +++ b/installer/Containerfile @@ -0,0 +1,15 @@ +# Build the live installer payload from a desktop Bazzite runtime. +# The image installed to disk is supplied separately as INSTALL_IMAGE_PAYLOAD. + +ARG BASE_IMAGE=ghcr.io/ublue-os/bazzite:stable +ARG INSTALL_IMAGE_PAYLOAD=ghcr.io/AeroCore-IO/aerocore-bazzite-image:stable + +FROM ${BASE_IMAGE} + +ARG BASE_IMAGE +ARG INSTALL_IMAGE_PAYLOAD + +RUN --mount=type=bind,source=.,target=/src \ + env BASE_IMAGE="${BASE_IMAGE}" \ + INSTALL_IMAGE_PAYLOAD="${INSTALL_IMAGE_PAYLOAD}" \ + /src/installer/build.sh diff --git a/installer/build.sh b/installer/build.sh new file mode 100755 index 0000000..7532df8 --- /dev/null +++ b/installer/build.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BASE_IMAGE=${BASE_IMAGE:?} +INSTALL_IMAGE_PAYLOAD=${INSTALL_IMAGE_PAYLOAD:?} + +# The installer is a live KDE environment. Keep the installed system payload +# separate: it is the AeroCore image, while BASE_IMAGE provides the live UI. +dnf install -y \ + anaconda-live \ + libblockdev-btrfs \ + libblockdev-dm \ + libblockdev-lvm \ + dracut-live \ + livesys-scripts \ + grub2-efi-x64-cdboot + +# Apply the same AeroCore overlay to the live session where possible. +if [[ -d /src/system_files ]]; then + cp -a /src/system_files/. / +fi + +# Make the install payload available to Anaconda. When the build is running +# with the host container store mounted, this avoids a second registry pull. +if mountpoint -q /usr/lib/containers/storage; then + podman save --format oci-archive "${INSTALL_IMAGE_PAYLOAD}" | \ + podman load --storage-opt additionalimagestore='' +else + podman pull "${INSTALL_IMAGE_PAYLOAD}" +fi + +# Tell Anaconda to install the bootc container that was loaded above. +mkdir -p /var/lib/rpm-state +cat >> /usr/share/anaconda/interactive-defaults.ks </dev/null; then + cp -a /usr/lib/efi/*/*/EFI /boot/efi/ +fi + +systemd-firstboot --timezone UTC +dnf clean all diff --git a/installer/iso.yaml b/installer/iso.yaml new file mode 100644 index 0000000..8e6bd73 --- /dev/null +++ b/installer/iso.yaml @@ -0,0 +1,10 @@ +label: "AeroCore-Live" +grub2: + timeout: 3 + entries: + - name: "Launch AeroCore Installer" + linux: "/images/pxeboot/vmlinuz quiet rhgb root=live:CDLABEL=AeroCore-Live enforcing=0 rd.live.image" + initrd: "/images/pxeboot/initrd.img" + - name: "Launch AeroCore Installer (Basic Graphics Mode)" + linux: "/images/pxeboot/vmlinuz quiet rhgb root=live:CDLABEL=AeroCore-Live enforcing=0 rd.live.image nomodeset" + initrd: "/images/pxeboot/initrd.img" diff --git a/installer/lorax_templates/remove_root_password_prompt.tmpl b/installer/lorax_templates/remove_root_password_prompt.tmpl new file mode 100644 index 0000000..3bd0342 --- /dev/null +++ b/installer/lorax_templates/remove_root_password_prompt.tmpl @@ -0,0 +1 @@ +append etc/anaconda/profile.d/fedora-kinoite.conf "\\n[User Interface]\\nhidden_spokes =\\n PasswordSpoke" diff --git a/installer/lorax_templates/set_default_user.tmpl b/installer/lorax_templates/set_default_user.tmpl new file mode 100644 index 0000000..b4cf2c8 --- /dev/null +++ b/installer/lorax_templates/set_default_user.tmpl @@ -0,0 +1 @@ +append usr/share/anaconda/interactive-defaults.ks "\\nuser --name=aerocore --password=aerocore --plaintext --groups=wheel" diff --git a/just_scripts/build-live-installer.sh b/just_scripts/build-live-installer.sh new file mode 100755 index 0000000..16b371e --- /dev/null +++ b/just_scripts/build-live-installer.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +set -euo pipefail + +project_root="$(git rev-parse --show-toplevel)" +cd "${project_root}" + +image_name="${IMAGE_NAME:-$(just image_name)}" +image_tag="${IMAGE_TAG:-$(just generate-default-tag)}" +base_image="${BASE_IMAGE:-ghcr.io/ublue-os/bazzite:stable}" +payload="localhost/${image_name}:live-payload" +output_dir="${project_root}/output" +api_socket="${PODMAN_SOCKET:-/run/podman/podman.sock}" +if [[ "${EUID}" -eq 0 ]]; then + podman_cmd=(podman) +else + podman_cmd=(sudo podman) +fi + +if [[ ! -S "${api_socket}" ]]; then + echo "Podman API socket not found: ${api_socket}" >&2 + echo "Set PODMAN_SOCKET to the rootful Podman socket and retry." >&2 + exit 1 +fi + +mkdir -p "${output_dir}" +"${podman_cmd[@]}" tag "${image_name}:${image_tag}" "${payload}" + +"${podman_cmd[@]}" build \ + --cap-add sys_admin \ + --security-opt label=disable \ + --build-arg "BASE_IMAGE=${base_image}" \ + --build-arg "INSTALL_IMAGE_PAYLOAD=${payload}" \ + --tag localhost/aerocore-live-payload:latest \ + --file installer/Containerfile \ + . + +"${podman_cmd[@]}" run --rm --privileged \ + --volume "${api_socket}:/var/run/docker.sock" \ + --volume "${project_root}/output:/build-container-installer/build" \ + --volume "${project_root}/installer/lorax_templates:/additional_lorax_templates:ro" \ + docker.io/jasonn3/build-container-installer:latest \ + ADDITIONAL_TEMPLATES="/additional_lorax_templates/remove_root_password_prompt.tmpl /additional_lorax_templates/set_default_user.tmpl" \ + ARCH="x86_64" \ + ENABLE_CACHE_DNF="false" \ + ENABLE_CACHE_SKOPEO="false" \ + ENABLE_FLATPAK_DEPENDENCIES="false" \ + IMAGE_NAME="aerocore-live-payload" \ + IMAGE_REPO="localhost" \ + IMAGE_TAG="latest" \ + ISO_NAME="build/aerocore-os-${image_tag}-amd64.iso" \ + VARIANT="Kinoite" \ + VERSION="${FEDORA_VERSION:-44}" + +iso="${output_dir}/aerocore-os-${image_tag}-amd64.iso" +if [[ -f "${iso}" ]]; then + sha256sum "${iso}" | tee "${iso}-CHECKSUM" +fi diff --git a/just_scripts/run-live-installer.sh b/just_scripts/run-live-installer.sh new file mode 100755 index 0000000..2723aae --- /dev/null +++ b/just_scripts/run-live-installer.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -euo pipefail + +project_root="$(git rev-parse --show-toplevel)" +cd "${project_root}" + +image_tag="${IMAGE_TAG:-$(just generate-default-tag)}" +iso="${project_root}/output/aerocore-os-${image_tag}-amd64.iso" + +if [[ ! -f "${iso}" ]]; then + just build-live-installer +fi + +podman run --rm --cap-add NET_ADMIN \ + --publish 127.0.0.1:8006:8006 \ + --env CPU_CORES=2 \ + --env RAM_SIZE=4G \ + --env DISK_SIZE=64G \ + --env BOOT_MODE=uefi \ + --device /dev/kvm \ + --volume "${iso}:/boot.iso:ro" \ + docker.io/qemux/qemu-docker -- cgit v1.2.3 From 03c4de92818b9f8dd641291928a7c0ceb8590d85 Mon Sep 17 00:00:00 2001 From: tranch Date: Sun, 12 Jul 2026 23:35:37 +0800 Subject: Rebuild initramfs with custom branding Regenerate initramfs after applying AeroCore image metadata and assets. --- Containerfile | 3 ++- build_files/build-initramfs | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100755 build_files/build-initramfs diff --git a/Containerfile b/Containerfile index cdcd945..1f09ba1 100644 --- a/Containerfile +++ b/Containerfile @@ -41,7 +41,8 @@ RUN --mount=type=bind,from=ctx,source=/,target=/ctx \ --mount=type=cache,dst=/var/log \ --mount=type=tmpfs,dst=/tmp \ /ctx/build.sh && \ - /ctx/image-info + /ctx/image-info && \ + /ctx/build-initramfs ### LINTING ## Verify final image and contents are correct. diff --git a/build_files/build-initramfs b/build_files/build-initramfs new file mode 100755 index 0000000..9eec951 --- /dev/null +++ b/build_files/build-initramfs @@ -0,0 +1,17 @@ +#!/usr/bin/bash + +set -eoux pipefail + +echo "::group::Executing build-initramfs" +trap 'echo "::endgroup::"' EXIT + +if [[ "${KERNEL_FLAVOR:-}" == "surface" ]]; then + KERNEL_SUFFIX="surface" +else + KERNEL_SUFFIX="" +fi + +QUALIFIED_KERNEL="$(dnf5 repoquery --installed --queryformat='%{evr}.%{arch}' "kernel${KERNEL_SUFFIX:+-${KERNEL_SUFFIX}}")" +/usr/bin/dracut --no-hostonly --kver "$QUALIFIED_KERNEL" --reproducible --zstd -v --add ostree --add fido2 -f "/usr/lib/modules/$QUALIFIED_KERNEL/initramfs.img" + +chmod 0600 /usr/lib/modules/"$QUALIFIED_KERNEL"/initramfs.img -- cgit v1.2.3 From 0746882128c748280e60f9875e6342a219b077e7 Mon Sep 17 00:00:00 2001 From: tranch Date: Mon, 13 Jul 2026 00:17:46 +0800 Subject: Allow env override for image update ref Pass OSTREE_IMAGE_REF from GitHub repository variables into the image build so image-info.json can point systems at the configured update source. --- .github/workflows/build.yml | 1 + Containerfile | 1 + Justfile | 2 +- build_files/image-info | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 56f8da9..1a7f7d4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -69,6 +69,7 @@ jobs: FLATPAK_REMOTE_URL: ${{ vars.FLATPAK_REMOTE_URL }} HOMEBREW_BOTTLE_DOMAIN: ${{ vars.HOMEBREW_BOTTLE_DOMAIN }} HOMEBREW_API_DOMAIN: ${{ vars.HOMEBREW_API_DOMAIN }} + OSTREE_IMAGE_REF: ${{ vars.OSTREE_IMAGE_REF }} run: | sudo -E $(command -v just) build \ ${IMAGE_NAME} \ diff --git a/Containerfile b/Containerfile index 1f09ba1..90bd7c7 100644 --- a/Containerfile +++ b/Containerfile @@ -12,6 +12,7 @@ ARG IMAGE_VENDOR="AeroCore-IO" ARG IMAGE_BRANCH="stable" ARG VERSION_TAG="latest" ARG VERSION_PRETTY="latest" +ARG OSTREE_IMAGE_REF="" ## Other possible base images include: # ghcr.io/ublue-os/bazzite-deck:testing # ghcr.io/ublue-os/bazzite-deck:stable-43.20260420 diff --git a/Justfile b/Justfile index 9ec4dd1..5b5cc02 100644 --- a/Justfile +++ b/Justfile @@ -114,7 +114,7 @@ build $target_image=image_name $tag=default_tag: BUILD_ARGS=() LABELS=() - for arg in BASE_IMAGE FLATPAK_REMOTE_URL HOMEBREW_BOTTLE_DOMAIN HOMEBREW_API_DOMAIN; do + for arg in BASE_IMAGE FLATPAK_REMOTE_URL HOMEBREW_BOTTLE_DOMAIN HOMEBREW_API_DOMAIN OSTREE_IMAGE_REF; do if [[ -n "${!arg:-}" ]]; then BUILD_ARGS+=("--build-arg" "${arg}=${!arg}") fi diff --git a/build_files/image-info b/build_files/image-info index d441917..6c13612 100755 --- a/build_files/image-info +++ b/build_files/image-info @@ -15,7 +15,7 @@ LOGO_COLOR="0;38;2;12;109;129" IMAGE_INFO="/usr/share/ublue-os/image-info.json" OSTREE_REGISTRY="${OSTREE_REGISTRY:-docker://ghcr.io}" OSTREE_NAMESPACE="${OSTREE_NAMESPACE:-$IMAGE_VENDOR}" -IMAGE_REF="ostree-image-signed:${OSTREE_REGISTRY%/}/$OSTREE_NAMESPACE/$IMAGE_NAME" +IMAGE_REF="${OSTREE_IMAGE_REF:-ostree-image-signed:${OSTREE_REGISTRY%/}/$OSTREE_NAMESPACE/$IMAGE_NAME}" IMAGE_BRANCH_NORMALIZED="$IMAGE_BRANCH" BASE_IMAGE_NAME="bazzite-deck" -- cgit v1.2.3 From 70bb475bc2c1dc520caf61acc7e9f62fc11d5975 Mon Sep 17 00:00:00 2001 From: tranch Date: Mon, 13 Jul 2026 00:26:39 +0800 Subject: Publish manual testing image tags Allow manually dispatched testing branch builds to publish and sign both the moving testing tag and a dated testing tag. --- .github/workflows/build.yml | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1a7f7d4..e542a89 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,7 +51,11 @@ jobs: - name: Default Tag id: gen-default-tag run: | - DEFAULT_TAG=$(just generate-default-tag) + if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" && "${GITHUB_REF_NAME}" == "testing" ]]; then + DEFAULT_TAG="testing-$(date -u +%Y%m%d)" + else + DEFAULT_TAG=$(just generate-default-tag) + fi echo "DEFAULT_TAG=${DEFAULT_TAG}" >> $GITHUB_ENV @@ -96,9 +100,13 @@ jobs: - name: Generate Build Tags id: gen-build-tags run: | - alias_tags="$(just generate-build-tags \ - ${IMAGE_NAME} \ - ${DEFAULT_TAG})" + if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" && "${GITHUB_REF_NAME}" == "testing" ]]; then + alias_tags="testing ${DEFAULT_TAG}" + else + alias_tags="$(just generate-build-tags \ + ${IMAGE_NAME} \ + ${DEFAULT_TAG})" + fi echo "Tags for this Action..." echo "${alias_tags}" @@ -114,18 +122,18 @@ jobs: "${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 + # These `if` statements keep pull requests from publishing packages. + # They publish default-branch builds and manual testing branch builds. - name: Login to GitHub Container Registry uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0 - if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) + if: github.event_name != 'pull_request' && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/testing')) with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Push To GHCR - if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) + if: github.event_name != 'pull_request' && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/testing')) id: push-image env: ALIAS_TAGS: ${{ steps.gen-build-tags.outputs.alias_tags }} @@ -145,14 +153,14 @@ jobs: # to consume. For more details, review the image signing section of the README. - name: Install Cosign 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) + if: github.event_name != 'pull_request' && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/testing')) # 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) + if: github.event_name != 'pull_request' && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/testing')) env: COSIGN_EXPERIMENTAL: false COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} -- cgit v1.2.3 From 006d9630c6b11933943245377379addc4b0410e1 Mon Sep 17 00:00:00 2001 From: tranch Date: Mon, 13 Jul 2026 00:55:21 +0800 Subject: Use BTRFS storage for image builds Mount /var/lib/containers on the larger runner disk before building so rpm-ostree rechunk has enough space for bootc images. --- .github/workflows/build.yml | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e542a89..0b1a54b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,12 +27,31 @@ jobs: steps: # These stage versions are pinned by https://github.com/renovatebot/renovate + - name: Show disk space + run: sudo df -h + + - name: Check if /mnt is there + id: check-mnt + run: | + if sudo mountpoint /mnt; then + echo "mnt_is_there=1" >> "$GITHUB_OUTPUT" + else + echo "mnt_is_there=0" >> "$GITHUB_OUTPUT" + fi + + - name: Free Disk Space + if: ${{ steps.check-mnt.outputs.mnt_is_there == '1' }} + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + + - name: Mount BTRFS for podman storage + if: ${{ steps.check-mnt.outputs.mnt_is_there == '1' }} + uses: ublue-os/container-storage-action@main + with: + target-dir: /var/lib/containers + - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - - name: Maximize build space - uses: ublue-os/remove-unwanted-software@695eb75bc387dbcd9685a8e72d23439d8686cba6 - - name: Install just uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 #v4.0.0 -- cgit v1.2.3 From 4538d902bb97f7f6460b2e50ae838297ae785e87 Mon Sep 17 00:00:00 2001 From: tranch Date: Mon, 13 Jul 2026 01:05:10 +0800 Subject: Free disk space on standard runners --- .github/workflows/build.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0b1a54b..1edbe30 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,6 +30,11 @@ jobs: - name: Show disk space run: sudo df -h + - name: Maximize build space + uses: ublue-os/remove-unwanted-software@695eb75bc387dbcd9685a8e72d23439d8686cba6 + with: + extra-squeeze: true + - name: Check if /mnt is there id: check-mnt run: | @@ -39,16 +44,15 @@ jobs: echo "mnt_is_there=0" >> "$GITHUB_OUTPUT" fi - - name: Free Disk Space - if: ${{ steps.check-mnt.outputs.mnt_is_there == '1' }} - uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 - - name: Mount BTRFS for podman storage if: ${{ steps.check-mnt.outputs.mnt_is_there == '1' }} uses: ublue-os/container-storage-action@main with: target-dir: /var/lib/containers + - name: Show available build space + run: sudo df -h + - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 -- cgit v1.2.3 From a1d3f73a476f9aa1d6458d344c03fa12dd6efd21 Mon Sep 17 00:00:00 2001 From: tranch Date: Mon, 13 Jul 2026 08:25:32 +0800 Subject: Pass Cosign password to signing step --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1edbe30..e72f937 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -187,6 +187,7 @@ jobs: env: COSIGN_EXPERIMENTAL: false COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} + COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} DIGEST: ${{ steps.push-image.outputs.digest }} run: | cosign sign -y --key env://COSIGN_PRIVATE_KEY ${IMAGE_REGISTRY}/${IMAGE_NAME}@${DIGEST} -- cgit v1.2.3 From 44279a34ed21056fda257b9d53a0a24e449c0fe9 Mon Sep 17 00:00:00 2001 From: tranch Date: Tue, 14 Jul 2026 11:37:22 +0800 Subject: feat: add aerocore wallpaper and default background symlinks --- system_files/usr/share/backgrounds/default-dark.jxl | 1 + system_files/usr/share/backgrounds/default.jxl | 1 + .../plasmoidsetupscripts/org.kde.plasma.folder.js | 4 ++++ .../plasmoidsetupscripts/org.kde.plasma.folder.js | 4 ++++ .../usr/share/wallpapers/aerocore-wallpaper.jxl | Bin 0 -> 3395468 bytes 5 files changed, 10 insertions(+) create mode 120000 system_files/usr/share/backgrounds/default-dark.jxl create mode 120000 system_files/usr/share/backgrounds/default.jxl create mode 100644 system_files/usr/share/plasma/look-and-feel/com.valve.vapor.desktop/contents/plasmoidsetupscripts/org.kde.plasma.folder.js create mode 100644 system_files/usr/share/plasma/look-and-feel/com.valve.vgui.desktop/contents/plasmoidsetupscripts/org.kde.plasma.folder.js create mode 100644 system_files/usr/share/wallpapers/aerocore-wallpaper.jxl diff --git a/system_files/usr/share/backgrounds/default-dark.jxl b/system_files/usr/share/backgrounds/default-dark.jxl new file mode 120000 index 0000000..f87d865 --- /dev/null +++ b/system_files/usr/share/backgrounds/default-dark.jxl @@ -0,0 +1 @@ +/usr/share/wallpapers/aerocore-wallpaper.jxl \ No newline at end of file diff --git a/system_files/usr/share/backgrounds/default.jxl b/system_files/usr/share/backgrounds/default.jxl new file mode 120000 index 0000000..f87d865 --- /dev/null +++ b/system_files/usr/share/backgrounds/default.jxl @@ -0,0 +1 @@ +/usr/share/wallpapers/aerocore-wallpaper.jxl \ No newline at end of file diff --git a/system_files/usr/share/plasma/look-and-feel/com.valve.vapor.desktop/contents/plasmoidsetupscripts/org.kde.plasma.folder.js b/system_files/usr/share/plasma/look-and-feel/com.valve.vapor.desktop/contents/plasmoidsetupscripts/org.kde.plasma.folder.js new file mode 100644 index 0000000..b207690 --- /dev/null +++ b/system_files/usr/share/plasma/look-and-feel/com.valve.vapor.desktop/contents/plasmoidsetupscripts/org.kde.plasma.folder.js @@ -0,0 +1,4 @@ +applet.wallpaperPlugin = 'org.kde.image' +applet.currentConfigGroup = ["Wallpaper", "org.kde.image", "General"] +applet.writeConfig("Image", "/usr/share/wallpapers/aerocore-wallpaper.jxl") +applet.reloadConfig() diff --git a/system_files/usr/share/plasma/look-and-feel/com.valve.vgui.desktop/contents/plasmoidsetupscripts/org.kde.plasma.folder.js b/system_files/usr/share/plasma/look-and-feel/com.valve.vgui.desktop/contents/plasmoidsetupscripts/org.kde.plasma.folder.js new file mode 100644 index 0000000..b207690 --- /dev/null +++ b/system_files/usr/share/plasma/look-and-feel/com.valve.vgui.desktop/contents/plasmoidsetupscripts/org.kde.plasma.folder.js @@ -0,0 +1,4 @@ +applet.wallpaperPlugin = 'org.kde.image' +applet.currentConfigGroup = ["Wallpaper", "org.kde.image", "General"] +applet.writeConfig("Image", "/usr/share/wallpapers/aerocore-wallpaper.jxl") +applet.reloadConfig() diff --git a/system_files/usr/share/wallpapers/aerocore-wallpaper.jxl b/system_files/usr/share/wallpapers/aerocore-wallpaper.jxl new file mode 100644 index 0000000..9eca7b7 Binary files /dev/null and b/system_files/usr/share/wallpapers/aerocore-wallpaper.jxl differ -- cgit v1.2.3 From 3590672ec3f45b8df3820d65fc0946dc760292ec Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 15 Jul 2026 14:04:06 +0800 Subject: Integrate Instruments release seed Download and verify the selected release during image builds. Bootstrap it once into the first graphical user's XDG directories. --- .github/workflows/build.yml | 4 + Containerfile | 4 + Justfile | 6 +- README.md | 19 +++ build_files/build.sh | 2 + build_files/install-instruments.sh | 182 +++++++++++++++++++++ image-template.env | 7 + .../system/aerocore-instruments-setup.service | 18 ++ .../usr/libexec/aerocore-instruments-setup | 123 ++++++++++++++ 9 files changed, 364 insertions(+), 1 deletion(-) create mode 100755 build_files/install-instruments.sh create mode 100644 system_files/usr/lib/systemd/system/aerocore-instruments-setup.service create mode 100755 system_files/usr/libexec/aerocore-instruments-setup diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e72f937..49d2f81 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -97,6 +97,10 @@ jobs: HOMEBREW_BOTTLE_DOMAIN: ${{ vars.HOMEBREW_BOTTLE_DOMAIN }} HOMEBREW_API_DOMAIN: ${{ vars.HOMEBREW_API_DOMAIN }} OSTREE_IMAGE_REF: ${{ vars.OSTREE_IMAGE_REF }} + INSTRUMENTS_ENABLED: ${{ vars.INSTRUMENTS_ENABLED || 'true' }} + INSTRUMENTS_RELEASE_REPOSITORY: ${{ vars.INSTRUMENTS_RELEASE_REPOSITORY || 'AeroCore-IO/booster-installer' }} + INSTRUMENTS_VERSION: ${{ vars.INSTRUMENTS_VERSION || 'latest' }} + INSTRUMENTS_RELEASE_API_BASE: ${{ vars.INSTRUMENTS_RELEASE_API_BASE || 'https://api.github.com' }} run: | sudo -E $(command -v just) build \ ${IMAGE_NAME} \ diff --git a/Containerfile b/Containerfile index 90bd7c7..c9377ca 100644 --- a/Containerfile +++ b/Containerfile @@ -36,6 +36,10 @@ ARG OSTREE_IMAGE_REF="" ARG FLATPAK_REMOTE_URL="" ARG HOMEBREW_BOTTLE_DOMAIN="" ARG HOMEBREW_API_DOMAIN="" +ARG INSTRUMENTS_ENABLED="true" +ARG INSTRUMENTS_RELEASE_REPOSITORY="AeroCore-IO/booster-installer" +ARG INSTRUMENTS_VERSION="latest" +ARG INSTRUMENTS_RELEASE_API_BASE="https://api.github.com" RUN --mount=type=bind,from=ctx,source=/,target=/ctx \ --mount=type=cache,dst=/var/cache \ diff --git a/Justfile b/Justfile index 5b5cc02..5e73752 100644 --- a/Justfile +++ b/Justfile @@ -12,6 +12,10 @@ export BASE_IMAGE := env_var_or_default("BASE_IMAGE", "ghcr.io/ublue-os/bazzite- export FLATPAK_REMOTE_URL := env_var_or_default("FLATPAK_REMOTE_URL", "") export HOMEBREW_BOTTLE_DOMAIN := env_var_or_default("HOMEBREW_BOTTLE_DOMAIN", "") export HOMEBREW_API_DOMAIN := env_var_or_default("HOMEBREW_API_DOMAIN", "") +export INSTRUMENTS_ENABLED := env_var_or_default("INSTRUMENTS_ENABLED", "true") +export INSTRUMENTS_RELEASE_REPOSITORY := env_var_or_default("INSTRUMENTS_RELEASE_REPOSITORY", "AeroCore-IO/booster-installer") +export INSTRUMENTS_VERSION := env_var_or_default("INSTRUMENTS_VERSION", "latest") +export INSTRUMENTS_RELEASE_API_BASE := env_var_or_default("INSTRUMENTS_RELEASE_API_BASE", "https://api.github.com") alias build-vm := build-qcow2 alias rebuild-vm := rebuild-qcow2 @@ -114,7 +118,7 @@ build $target_image=image_name $tag=default_tag: BUILD_ARGS=() LABELS=() - for arg in BASE_IMAGE FLATPAK_REMOTE_URL HOMEBREW_BOTTLE_DOMAIN HOMEBREW_API_DOMAIN OSTREE_IMAGE_REF; do + for arg in BASE_IMAGE FLATPAK_REMOTE_URL HOMEBREW_BOTTLE_DOMAIN HOMEBREW_API_DOMAIN OSTREE_IMAGE_REF INSTRUMENTS_ENABLED INSTRUMENTS_RELEASE_REPOSITORY INSTRUMENTS_VERSION INSTRUMENTS_RELEASE_API_BASE; do if [[ -n "${!arg:-}" ]]; then BUILD_ARGS+=("--build-arg" "${arg}=${!arg}") fi diff --git a/README.md b/README.md index 0fc3ba4..3fc11c5 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,25 @@ FROM ghcr.io/ublue-os/bazzite-deck:stable By focusing strictly on file overlays and configuration writing, this build intentionally avoids invasive operations like `dnf5 install/remove`, COPR enablement, akmods pulls, or kernel recompilations. This architectural choice keeps AeroCore OS completely immune to Fedora/COPR dependency drift during major upstream transition windows (e.g., Bazzite 43 to 44). +## AeroCore Booster integration + +Image builds download the selected AeroCore Booster release from +`AeroCore-IO/booster-installer`, verify its published SHA-256 checksum, and +store the complete release seed under `/usr/share/aerocore-booster-release`. +The release installer runs once for the first active graphical user and copies +the application into that user's XDG directories. After bootstrapping, updates +and uninstallation remain owned by the normal Instruments user-space installer. +The bootstrap completion marker is stored at +`/var/lib/aerocore/instruments-bootstrap-complete`, so uninstalling the user +application does not cause the image seed to reinstall it on the next boot. +Remove that marker and enable `aerocore-instruments-setup.service` to explicitly +bootstrap the application again. + +Set `INSTRUMENTS_VERSION` to a release tag for reproducible builds, or leave it +as `latest` for rolling development images. Set `INSTRUMENTS_ENABLED=false` to +build without Booster. The release repository and API base can be overridden +with `INSTRUMENTS_RELEASE_REPOSITORY` and `INSTRUMENTS_RELEASE_API_BASE`. + --- ## Key Features & Optimizations diff --git a/build_files/build.sh b/build_files/build.sh index f1709da..b89907a 100755 --- a/build_files/build.sh +++ b/build_files/build.sh @@ -32,3 +32,5 @@ if [[ -n "${HOMEBREW_API_DOMAIN:-}" ]]; then fi find /etc/environment.d /etc/skel/.config/environment.d -name 99-aerocore-mirrors.conf -type f -exec chmod 0644 {} + 2>/dev/null || true + +/ctx/install-instruments.sh diff --git a/build_files/install-instruments.sh b/build_files/install-instruments.sh new file mode 100755 index 0000000..f85bd3b --- /dev/null +++ b/build_files/install-instruments.sh @@ -0,0 +1,182 @@ +#!/usr/bin/env bash + +set -euo pipefail + +: "${INSTRUMENTS_ENABLED:=true}" +: "${INSTRUMENTS_RELEASE_REPOSITORY:=AeroCore-IO/booster-installer}" +: "${INSTRUMENTS_VERSION:=latest}" +: "${INSTRUMENTS_RELEASE_API_BASE:=https://api.github.com}" +: "${INSTRUMENTS_SEED_ROOT:=/usr/share/aerocore-booster-release}" + +if [[ "${INSTRUMENTS_ENABLED}" != "true" ]]; then + echo "AeroCore Booster image integration is disabled" + exit 0 +fi + +case "$(uname -m)" in + x86_64 | amd64) + asset_suffix="_linux-x86_64.tar.gz" + ;; + *) + echo "Unsupported AeroCore Booster image architecture: $(uname -m)" >&2 + exit 1 + ;; +esac + +for command in curl jq sha256sum tar; do + command -v "$command" >/dev/null 2>&1 || { + echo "Required command is unavailable: $command" >&2 + exit 1 + } +done + +workdir="$(mktemp -d)" +trap 'rm -rf "$workdir"' EXIT + +github_curl() { + local args=( + --fail + --location + --retry 3 + --retry-delay 2 + --retry-max-time 60 + --silent + --show-error + ) + + if [[ -s /run/secrets/GITHUB_TOKEN ]]; then + args+=(--header "Authorization: Bearer $(&2 + exit 1 +fi + +IFS=$'\t' read -r asset_name asset_url <<<"${payload_assets[0]}" +checksum_name="${asset_name}.sha256" +checksum_url="$( + jq -er --arg name "$checksum_name" \ + '.assets[] | select(.name == $name) | .browser_download_url' \ + "$release_json" +)" + +archive="$workdir/$asset_name" +checksum_file="$workdir/$checksum_name" +github_curl "$asset_url" --output "$archive" +github_curl "$checksum_url" --output "$checksum_file" + +expected_checksum="$(awk 'NR == 1 { print $1 }' "$checksum_file")" +actual_checksum="$(sha256sum "$archive" | awk '{ print $1 }')" +if [[ ! "$expected_checksum" =~ ^[[:xdigit:]]{64}$ ]] || + [[ "${actual_checksum,,}" != "${expected_checksum,,}" ]]; then + echo "Checksum verification failed for $asset_name" >&2 + exit 1 +fi + +while IFS= read -r entry; do + case "$entry" in + /* | ../* | */../* | */..) + echo "Unsafe path in release archive: $entry" >&2 + exit 1 + ;; + esac +done < <(tar -tzf "$archive") + +extract_dir="$workdir/extracted" +install -d "$extract_dir" +tar --extract --gzip --file "$archive" --directory "$extract_dir" \ + --no-same-owner + +if [[ -d "$extract_dir/aerocore-booster-release" ]]; then + payload="$extract_dir/aerocore-booster-release" +elif [[ -d "$extract_dir/instruments-ng-release" ]]; then + payload="$extract_dir/instruments-ng-release" +else + echo "Release archive does not contain a supported payload root" >&2 + exit 1 +fi + +required_paths=( + install.sh + appimage/AppRun + appimage/AppRun.wrapped + sidecar/hhd-input-helper.cjs + sidecar/vendor/hhd-input-helper/instruments_hhd_input/__init__.py + runtime/avionics + runtime/cabin + runtime/wing + runtime/node/bin/node + python-wheelhouse + pkg/systemd/ac-avionics.service + pkg/systemd/ac-cabin.service + pkg/systemd/ac-wing.service + pkg/systemd/ac-instruments.service + scripts/check-runtime-health.cjs + manifest.yaml +) + +for path in "${required_paths[@]}"; do + if [[ ! -e "$payload/$path" ]]; then + echo "Required path is missing from Booster release: $path" >&2 + exit 1 + fi +done + +if [[ ! -f "$payload/pkg/aerocore-booster.sh" && + ! -f "$payload/pkg/instruments-ng.sh" ]]; then + echo "Booster launcher is missing from the release payload" >&2 + exit 1 +fi + +# Remove the first implementation's image-owned runtime when upgrading an +# existing AeroCore OS image. The release seed itself remains immutable. +rm -rf /usr/lib/aerocore-booster +rm -f /usr/bin/aerocore-booster +for unit in ac-avionics.service ac-cabin.service ac-wing.service \ + ac-instruments.service; do + rm -f "/usr/lib/systemd/system/$unit" +done + +rm -rf "$INSTRUMENTS_SEED_ROOT" +install -d -m 0755 "$INSTRUMENTS_SEED_ROOT" +cp -a "$payload/." "$INSTRUMENTS_SEED_ROOT/" + +cat >"$INSTRUMENTS_SEED_ROOT/image-release" </dev/null || true)" + if [[ ! "$uid" =~ ^[0-9]+$ ]] || ((uid < 1000)); then + continue + fi + [[ -z "$requested_uid" || "$uid" == "$requested_uid" ]] || continue + + active="$(loginctl show-session "$session" --property=Active --value 2>/dev/null || true)" + state="$(loginctl show-session "$session" --property=State --value 2>/dev/null || true)" + type="$(loginctl show-session "$session" --property=Type --value 2>/dev/null || true)" + seat="$(loginctl show-session "$session" --property=Seat --value 2>/dev/null || true)" + [[ "$active" == "yes" || "$state" == "active" || "$state" == "online" ]] || continue + + user="$(getent passwd "$uid" | cut -d: -f1)" + [[ -n "$user" && "$user" != "root" ]] || continue + if [[ "$type" == "x11" || "$type" == "wayland" ]]; then + printf '%s\n' "$user" + return 0 + fi + if [[ "$seat" == "seat0" ]] && pgrep -u "$uid" -x steam >/dev/null 2>&1; then + printf '%s\n' "$user" + return 0 + fi + done < <(loginctl list-sessions --no-legend --no-pager 2>/dev/null || true) + + return 1 +} + +if [[ -f "$complete_marker" ]]; then + echo "AeroCore Booster user bootstrap is already complete" + exit 0 +fi + +configured_uid="" +if [[ -f "$identity_file" ]]; then + configured_uid="$(awk -F= '$1 == "uid" { print $2; exit }' "$identity_file")" + if [[ ! "$configured_uid" =~ ^[0-9]+$ ]] || + ! getent passwd "$configured_uid" >/dev/null 2>&1; then + configured_uid="" + fi +fi + +deadline=$((SECONDS + AEROCORE_INSTRUMENTS_SETUP_WAIT_SECONDS)) +desktop_user="" +while ((SECONDS < deadline)); do + desktop_user="$(find_graphical_user "$configured_uid" || true)" + [[ -n "$desktop_user" ]] && break + sleep 2 +done + +if [[ -z "$desktop_user" ]]; then + echo "No active graphical user found within ${AEROCORE_INSTRUMENTS_SETUP_WAIT_SECONDS}s" >&2 + exit 1 +fi + +desktop_uid="$(id -u "$desktop_user")" +desktop_group="$(id -gn "$desktop_user")" +desktop_home="$(getent passwd "$desktop_user" | cut -d: -f6)" +if [[ -z "$desktop_home" || ! -d "$desktop_home" ]]; then + echo "Home directory is unavailable for $desktop_user: $desktop_home" >&2 + exit 1 +fi + +install -d -m 0755 "$state_dir" +printf 'user=%s\nuid=%s\n' "$desktop_user" "$desktop_uid" >"$identity_file" +chmod 0644 "$identity_file" + +existing_install=0 +for installed_path in \ + "$desktop_home/.local/share/aerocore-booster/manifest.yaml" \ + "$desktop_home/.local/share/aerocore-booster/appimage/AppRun" \ + "$desktop_home/.local/share/aerocore-booster/aerocore-booster" \ + "$desktop_home/.local/share/instruments-ng/manifest.yaml" \ + "$desktop_home/.local/share/instruments-ng/appimage/AppRun" \ + "$desktop_home/.local/share/instruments-ng/instruments-ng"; do + if [[ -e "$installed_path" ]]; then + existing_install=1 + break + fi +done + +if [[ "$existing_install" == "0" || -f "$attempt_marker" ]]; then + touch "$attempt_marker" + HOME="$desktop_home" \ + AEROCORE_INSTRUMENTS_USER="$desktop_user" \ + AEROCORE_INSTRUMENTS_GROUP="$desktop_group" \ + AEROCORE_INSTRUMENTS_UID="$desktop_uid" \ + AEROCORE_INSTRUMENTS_HOME="$desktop_home" \ + bash "$seed_root/install.sh" install +else + echo "Existing Instruments installation found for $desktop_user; preserving it" +fi + +cat >"$complete_marker" </dev/null 2>&1 || true + +echo "AeroCore Booster user bootstrap completed for $desktop_user (uid $desktop_uid)" -- cgit v1.2.3 From 32f81419098bac6fd02739b18023b921de08bb9b Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 15 Jul 2026 14:39:34 +0800 Subject: Recognize AeroCore as a Deck image Preserve Bazzite's Deck configuration for AeroCore images. Restore SDDM defaults removed by earlier deployments. --- build_files/build.sh | 1 + build_files/image-info | 2 +- build_files/patch-bazzite-deck-identity.sh | 47 ++++++++++++++++++++++ .../usr/lib/tmpfiles.d/aerocore-deck-compat.conf | 2 + 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100755 build_files/patch-bazzite-deck-identity.sh create mode 100644 system_files/usr/lib/tmpfiles.d/aerocore-deck-compat.conf diff --git a/build_files/build.sh b/build_files/build.sh index b89907a..3d37e31 100755 --- a/build_files/build.sh +++ b/build_files/build.sh @@ -34,3 +34,4 @@ fi find /etc/environment.d /etc/skel/.config/environment.d -name 99-aerocore-mirrors.conf -type f -exec chmod 0644 {} + 2>/dev/null || true /ctx/install-instruments.sh +/ctx/patch-bazzite-deck-identity.sh diff --git a/build_files/image-info b/build_files/image-info index 6c13612..84c6495 100755 --- a/build_files/image-info +++ b/build_files/image-info @@ -33,7 +33,7 @@ cat > "$IMAGE_INFO" <&2 + exit 1 +fi + +add_base_image_assignment=0 +if ! grep -Fqx "$base_image_assignment" "$hardware_setup"; then + add_base_image_assignment=1 +fi + +patched_file=$(mktemp) +trap 'rm -f "$patched_file"' EXIT + +awk \ + -v old_condition="$old_condition" \ + -v new_condition="$new_condition" \ + -v base_image_assignment="$base_image_assignment" \ + -v add_base_image_assignment="$add_base_image_assignment" \ + '$0 == old_condition { + if (add_base_image_assignment) { + print base_image_assignment + } + print new_condition + next + } + { print }' "$hardware_setup" > "$patched_file" + +cp "$patched_file" "$hardware_setup" + +grep -Fqx "$new_condition" "$hardware_setup" diff --git a/system_files/usr/lib/tmpfiles.d/aerocore-deck-compat.conf b/system_files/usr/lib/tmpfiles.d/aerocore-deck-compat.conf new file mode 100644 index 0000000..830329f --- /dev/null +++ b/system_files/usr/lib/tmpfiles.d/aerocore-deck-compat.conf @@ -0,0 +1,2 @@ +# Restore the Deck SDDM defaults if an older AeroCore deployment removed them. +C /etc/sddm.conf.d/steamos.conf 0644 root root - /usr/etc/sddm.conf.d/steamos.conf -- cgit v1.2.3 From a1ba0cbb957c2763e43a0bc3b19618ec6059c7e2 Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 15 Jul 2026 15:41:48 +0800 Subject: Preserve upstream desktop metadata Keep the base image's kinoite or silverblue identity intact. Detect AeroCore Deck behavior from its image name instead. --- build_files/image-info | 2 +- build_files/patch-bazzite-deck-identity.sh | 14 +------------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/build_files/image-info b/build_files/image-info index 84c6495..a52d666 100755 --- a/build_files/image-info +++ b/build_files/image-info @@ -17,7 +17,7 @@ OSTREE_REGISTRY="${OSTREE_REGISTRY:-docker://ghcr.io}" OSTREE_NAMESPACE="${OSTREE_NAMESPACE:-$IMAGE_VENDOR}" IMAGE_REF="${OSTREE_IMAGE_REF:-ostree-image-signed:${OSTREE_REGISTRY%/}/$OSTREE_NAMESPACE/$IMAGE_NAME}" IMAGE_BRANCH_NORMALIZED="$IMAGE_BRANCH" -BASE_IMAGE_NAME="bazzite-deck" +BASE_IMAGE_NAME=$(jq -er '."base-image-name"' < "$IMAGE_INFO") if [[ $IMAGE_BRANCH_NORMALIZED == "main" ]]; then IMAGE_BRANCH_NORMALIZED="stable" diff --git a/build_files/patch-bazzite-deck-identity.sh b/build_files/patch-bazzite-deck-identity.sh index 600d97e..078b76c 100755 --- a/build_files/patch-bazzite-deck-identity.sh +++ b/build_files/patch-bazzite-deck-identity.sh @@ -7,9 +7,7 @@ hardware_setup="${1:-/usr/libexec/bazzite-hardware-setup}" # shellcheck disable=SC2016 old_condition='if [[ "$IMAGE_NAME" != *deck* && "$IMAGE_NAME" != *dx* ]]; then' # shellcheck disable=SC2016 -new_condition='if [[ "$IMAGE_NAME" != aerocore-os && "$IMAGE_NAME" != *deck* && "$IMAGE_NAME" != *dx* && "$BASE_IMAGE_NAME" != *deck* && "$BASE_IMAGE_NAME" != *dx* ]]; then' -# shellcheck disable=SC2016 -base_image_assignment='BASE_IMAGE_NAME=$(jq -r '\''."base-image-name"'\'' < $IMAGE_INFO)' +new_condition='if [[ "$IMAGE_NAME" != aerocore-os && "$IMAGE_NAME" != *deck* && "$IMAGE_NAME" != *dx* ]]; then' if grep -Fqx "$new_condition" "$hardware_setup"; then exit 0 @@ -20,23 +18,13 @@ if [[ "$(grep -Fxc "$old_condition" "$hardware_setup")" -ne 1 ]]; then exit 1 fi -add_base_image_assignment=0 -if ! grep -Fqx "$base_image_assignment" "$hardware_setup"; then - add_base_image_assignment=1 -fi - patched_file=$(mktemp) trap 'rm -f "$patched_file"' EXIT awk \ -v old_condition="$old_condition" \ -v new_condition="$new_condition" \ - -v base_image_assignment="$base_image_assignment" \ - -v add_base_image_assignment="$add_base_image_assignment" \ '$0 == old_condition { - if (add_base_image_assignment) { - print base_image_assignment - } print new_condition next } -- cgit v1.2.3 From 392f7d45e3eb7341ba54899a12918743f186bc6c Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 15 Jul 2026 18:43:23 +0800 Subject: Fix ACR promotion environment vars Bind the manual promotion job to the selected GitHub Environment so environment-scoped ACR variables and secrets are available. Resolve the image name from the dispatch override first, then IMAGE_NAME, then image-template.env through just. Pass the Cosign password during signing. --- .github/workflows/promote-acr.yml | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/.github/workflows/promote-acr.yml b/.github/workflows/promote-acr.yml index 99a67f8..890962f 100644 --- a/.github/workflows/promote-acr.yml +++ b/.github/workflows/promote-acr.yml @@ -4,6 +4,11 @@ name: Promote image to ACR on: workflow_dispatch: inputs: + environment: + description: "GitHub Environment containing ACR vars/secrets" + required: true + default: testing + type: environment source_tag: description: "Existing GHCR tag to promote" required: true @@ -13,7 +18,7 @@ on: required: false type: string image_name: - description: "Image name override; defaults to image-template.env" + description: "Image name override; defaults to IMAGE_NAME var, then image-template.env" required: false type: string @@ -21,13 +26,14 @@ env: IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" concurrency: - group: ${{ github.workflow }}-${{ inputs.image_name || 'default' }}-${{ inputs.source_tag }} + group: ${{ github.workflow }}-${{ inputs.environment }}-${{ inputs.image_name || 'default' }}-${{ inputs.source_tag }} cancel-in-progress: false jobs: promote_acr: name: Promote GHCR image to ACR runs-on: ubuntu-24.04 + environment: ${{ inputs.environment }} permissions: contents: read @@ -48,18 +54,21 @@ jobs: - name: Prepare image variables env: IMAGE_NAME_INPUT: ${{ inputs.image_name }} + IMAGE_NAME_VAR: ${{ vars.IMAGE_NAME }} SOURCE_TAG: ${{ inputs.source_tag }} TARGET_TAGS_INPUT: ${{ inputs.target_tags }} run: | set -euo pipefail - image_name="${IMAGE_NAME_INPUT:-$(just image_name)}" + image_name="${IMAGE_NAME_INPUT:-${IMAGE_NAME_VAR:-$(just image_name)}}" target_tags="${TARGET_TAGS_INPUT:-$SOURCE_TAG}" - echo "IMAGE_REGISTRY=${IMAGE_REGISTRY,,}" >> "$GITHUB_ENV" - echo "IMAGE_NAME=${image_name,,}" >> "$GITHUB_ENV" - echo "SOURCE_TAG=${SOURCE_TAG}" >> "$GITHUB_ENV" - echo "TARGET_TAGS=${target_tags}" >> "$GITHUB_ENV" + { + echo "IMAGE_REGISTRY=${IMAGE_REGISTRY,,}" + echo "IMAGE_NAME=${image_name,,}" + echo "SOURCE_TAG=${SOURCE_TAG}" + echo "TARGET_TAGS=${target_tags}" + } >> "$GITHUB_ENV" - name: Validate ACR configuration env: @@ -68,14 +77,16 @@ jobs: ACR_USERNAME: ${{ secrets.ACR_USERNAME }} ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }} COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} + COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} run: | set -euo pipefail - : "${ACR_REGISTRY:?Repository variable ACR_REGISTRY is required.}" - : "${ACR_NAMESPACE:?Repository variable ACR_NAMESPACE is required.}" - : "${ACR_USERNAME:?Repository secret ACR_USERNAME is required.}" - : "${ACR_PASSWORD:?Repository secret ACR_PASSWORD is required.}" - : "${COSIGN_PRIVATE_KEY:?Repository secret SIGNING_SECRET is required.}" + : "${ACR_REGISTRY:?Repository or environment variable ACR_REGISTRY is required.}" + : "${ACR_NAMESPACE:?Repository or environment variable ACR_NAMESPACE is required.}" + : "${ACR_USERNAME:?Repository or environment secret ACR_USERNAME is required.}" + : "${ACR_PASSWORD:?Repository or environment secret ACR_PASSWORD is required.}" + : "${COSIGN_PRIVATE_KEY:?Repository or environment secret SIGNING_SECRET is required.}" + : "${COSIGN_PASSWORD:?Repository or environment secret COSIGN_PASSWORD is required.}" - name: Login to GitHub Container Registry env: @@ -140,6 +151,7 @@ jobs: ACR_NAMESPACE: ${{ vars.ACR_NAMESPACE }} COSIGN_EXPERIMENTAL: false COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} + COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} DIGEST: ${{ steps.promote.outputs.digest }} run: | set -euo pipefail -- cgit v1.2.3 From 04e27e0b977826b475b969f19783c1aad300b560 Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 15 Jul 2026 18:50:32 +0800 Subject: Remove ACR environment input Keep ACR promotion compatible with repositories that do not configure GitHub Environments by using repository-level variables and secrets. --- .github/workflows/promote-acr.yml | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/.github/workflows/promote-acr.yml b/.github/workflows/promote-acr.yml index 890962f..6b00e3b 100644 --- a/.github/workflows/promote-acr.yml +++ b/.github/workflows/promote-acr.yml @@ -4,11 +4,6 @@ name: Promote image to ACR on: workflow_dispatch: inputs: - environment: - description: "GitHub Environment containing ACR vars/secrets" - required: true - default: testing - type: environment source_tag: description: "Existing GHCR tag to promote" required: true @@ -26,14 +21,13 @@ env: IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" concurrency: - group: ${{ github.workflow }}-${{ inputs.environment }}-${{ inputs.image_name || 'default' }}-${{ inputs.source_tag }} + group: ${{ github.workflow }}-${{ inputs.image_name || 'default' }}-${{ inputs.source_tag }} cancel-in-progress: false jobs: promote_acr: name: Promote GHCR image to ACR runs-on: ubuntu-24.04 - environment: ${{ inputs.environment }} permissions: contents: read @@ -81,12 +75,12 @@ jobs: run: | set -euo pipefail - : "${ACR_REGISTRY:?Repository or environment variable ACR_REGISTRY is required.}" - : "${ACR_NAMESPACE:?Repository or environment variable ACR_NAMESPACE is required.}" - : "${ACR_USERNAME:?Repository or environment secret ACR_USERNAME is required.}" - : "${ACR_PASSWORD:?Repository or environment secret ACR_PASSWORD is required.}" - : "${COSIGN_PRIVATE_KEY:?Repository or environment secret SIGNING_SECRET is required.}" - : "${COSIGN_PASSWORD:?Repository or environment secret COSIGN_PASSWORD is required.}" + : "${ACR_REGISTRY:?Repository variable ACR_REGISTRY is required.}" + : "${ACR_NAMESPACE:?Repository variable ACR_NAMESPACE is required.}" + : "${ACR_USERNAME:?Repository secret ACR_USERNAME is required.}" + : "${ACR_PASSWORD:?Repository secret ACR_PASSWORD is required.}" + : "${COSIGN_PRIVATE_KEY:?Repository secret SIGNING_SECRET is required.}" + : "${COSIGN_PASSWORD:?Repository secret COSIGN_PASSWORD is required.}" - name: Login to GitHub Container Registry env: -- cgit v1.2.3 From 4fc0c9bfe42b5d0e543c5ca44c86d25a19f5e1d9 Mon Sep 17 00:00:00 2001 From: tranch Date: Fri, 17 Jul 2026 06:56:56 +0800 Subject: Fix live installer ISO build Build the live installer from the requested local AeroCore image, use a separate Fedora live base, pass the payload through rootful container storage, and write reproducible checksum entries without host paths. --- .github/workflows/build-live-installer.yml | 17 ++++-- Justfile | 6 ++- disk_config/iso-gnome.toml | 7 --- disk_config/iso-kde.toml | 7 --- installer/Containerfile | 4 ++ installer/build.sh | 13 +++-- just_scripts/build-live-installer.sh | 84 ++++++++++++++++++++++++++---- 7 files changed, 105 insertions(+), 33 deletions(-) diff --git a/.github/workflows/build-live-installer.yml b/.github/workflows/build-live-installer.yml index 870699e..b5fedb3 100644 --- a/.github/workflows/build-live-installer.yml +++ b/.github/workflows/build-live-installer.yml @@ -13,6 +13,7 @@ on: branches: - main paths: + - "Justfile" - "installer/**" - "just_scripts/build-live-installer.sh" - ".github/workflows/build-live-installer.yml" @@ -34,7 +35,7 @@ jobs: env: IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} IMAGE_TAG: ${{ inputs.image_tag || 'latest' }} - BASE_IMAGE: ghcr.io/ublue-os/bazzite:stable + LIVE_BASE_IMAGE: quay.io/fedora/fedora-kinoite:43 FEDORA_VERSION: "44" steps: @@ -76,11 +77,21 @@ jobs: - name: Build live installer payload run: | + mkdir -p output + sudo podman tag \ + "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" \ + localhost/aerocore-live-payload:latest + sudo podman save \ + --format oci-archive \ + --output output/install-payload.oci \ + localhost/aerocore-live-payload:latest + sudo podman build \ --cap-add sys_admin \ --security-opt label=disable \ - --build-arg "BASE_IMAGE=${BASE_IMAGE}" \ - --build-arg "INSTALL_IMAGE_PAYLOAD=${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" \ + --build-arg "BASE_IMAGE=${LIVE_BASE_IMAGE}" \ + --build-arg "INSTALL_IMAGE_PAYLOAD=localhost/aerocore-live-payload:latest" \ + --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ --tag localhost/aerocore-live-payload:latest \ --file installer/Containerfile \ . diff --git a/Justfile b/Justfile index 5e73752..b65d2c9 100644 --- a/Justfile +++ b/Justfile @@ -9,6 +9,8 @@ export image_logo_url := env_var("IMAGE_LOGO_URL") export default_tag := env_var("DEFAULT_TAG") export bib_image := env_var("BIB_IMAGE") export BASE_IMAGE := env_var_or_default("BASE_IMAGE", "ghcr.io/ublue-os/bazzite-deck:stable") +export LIVE_BASE_IMAGE := env_var_or_default("LIVE_BASE_IMAGE", "quay.io/fedora/fedora-kinoite:43") +export INSTALLER_BUILDER_IMAGE := env_var_or_default("INSTALLER_BUILDER_IMAGE", "ghcr.io/jasonn3/build-container-installer:v1.5.0") export FLATPAK_REMOTE_URL := env_var_or_default("FLATPAK_REMOTE_URL", "") export HOMEBREW_BOTTLE_DOMAIN := env_var_or_default("HOMEBREW_BOTTLE_DOMAIN", "") export HOMEBREW_API_DOMAIN := env_var_or_default("HOMEBREW_API_DOMAIN", "") @@ -28,8 +30,8 @@ default: @just --list # Build a Bazzite-style live installer ISO -build-live-installer: - @./just_scripts/build-live-installer.sh +build-live-installer $target_image=("localhost/" + image_name) $tag=default_tag: + @IMAGE_NAME="{{ target_image }}" IMAGE_TAG="{{ tag }}" ./just_scripts/build-live-installer.sh # Boot the live installer ISO with QEMU run-live-installer: diff --git a/disk_config/iso-gnome.toml b/disk_config/iso-gnome.toml index 0fa5652..33cf931 100644 --- a/disk_config/iso-gnome.toml +++ b/disk_config/iso-gnome.toml @@ -1,10 +1,3 @@ -[customizations.installer.kickstart] -contents = """ -%post -bootc switch --mutate-in-place --transport registry ghcr.io/aerocore-io/aerocore-bazzite-image:latest -%end -""" - [customizations.installer.modules] enable = [ "org.fedoraproject.Anaconda.Modules.Storage", diff --git a/disk_config/iso-kde.toml b/disk_config/iso-kde.toml index e6e15a0..7f6c80d 100644 --- a/disk_config/iso-kde.toml +++ b/disk_config/iso-kde.toml @@ -1,10 +1,3 @@ -[customizations.installer.kickstart] -contents = """ -%post -bootc switch --mutate-in-place --transport registry ghcr.io/aerocore-io/aerocore-bazzite-image:latest -%end -""" - [customizations.installer.modules] enable = [ "org.fedoraproject.Anaconda.Modules.Storage", diff --git a/installer/Containerfile b/installer/Containerfile index fa817b6..50579e6 100644 --- a/installer/Containerfile +++ b/installer/Containerfile @@ -3,13 +3,17 @@ ARG BASE_IMAGE=ghcr.io/ublue-os/bazzite:stable ARG INSTALL_IMAGE_PAYLOAD=ghcr.io/AeroCore-IO/aerocore-bazzite-image:stable +ARG INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci FROM ${BASE_IMAGE} ARG BASE_IMAGE ARG INSTALL_IMAGE_PAYLOAD +ARG INSTALL_IMAGE_PAYLOAD_ARCHIVE RUN --mount=type=bind,source=.,target=/src \ + --mount=type=bind,source=output/install-payload.oci,target=/install-payload.oci,ro \ env BASE_IMAGE="${BASE_IMAGE}" \ INSTALL_IMAGE_PAYLOAD="${INSTALL_IMAGE_PAYLOAD}" \ + INSTALL_IMAGE_PAYLOAD_ARCHIVE="${INSTALL_IMAGE_PAYLOAD_ARCHIVE}" \ /src/installer/build.sh diff --git a/installer/build.sh b/installer/build.sh index 7532df8..033fe9b 100755 --- a/installer/build.sh +++ b/installer/build.sh @@ -5,10 +5,14 @@ set -euxo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BASE_IMAGE=${BASE_IMAGE:?} INSTALL_IMAGE_PAYLOAD=${INSTALL_IMAGE_PAYLOAD:?} +INSTALL_IMAGE_PAYLOAD_ARCHIVE=${INSTALL_IMAGE_PAYLOAD_ARCHIVE:-} # The installer is a live KDE environment. Keep the installed system payload # separate: it is the AeroCore image, while BASE_IMAGE provides the live UI. -dnf install -y \ +# Bazzite excludes some base packages from normal transactions. The live +# installer needs Anaconda's exact NetworkManager dependencies, so clear the +# excludes only for this dependency install. +dnf --setopt=excludepkgs= install -y \ anaconda-live \ libblockdev-btrfs \ libblockdev-dm \ @@ -22,9 +26,10 @@ if [[ -d /src/system_files ]]; then cp -a /src/system_files/. / fi -# Make the install payload available to Anaconda. When the build is running -# with the host container store mounted, this avoids a second registry pull. -if mountpoint -q /usr/lib/containers/storage; then +# Make the install payload available to Anaconda. +if [[ -n "${INSTALL_IMAGE_PAYLOAD_ARCHIVE}" && -f "${INSTALL_IMAGE_PAYLOAD_ARCHIVE}" ]]; then + podman load --storage-opt additionalimagestore='' < "${INSTALL_IMAGE_PAYLOAD_ARCHIVE}" +elif mountpoint -q /usr/lib/containers/storage; then podman save --format oci-archive "${INSTALL_IMAGE_PAYLOAD}" | \ podman load --storage-opt additionalimagestore='' else diff --git a/just_scripts/build-live-installer.sh b/just_scripts/build-live-installer.sh index 16b371e..45335cb 100755 --- a/just_scripts/build-live-installer.sh +++ b/just_scripts/build-live-installer.sh @@ -5,41 +5,98 @@ set -euo pipefail project_root="$(git rev-parse --show-toplevel)" cd "${project_root}" -image_name="${IMAGE_NAME:-$(just image_name)}" +image_name="${IMAGE_NAME:-localhost/$(just image_name)}" image_tag="${IMAGE_TAG:-$(just generate-default-tag)}" -base_image="${BASE_IMAGE:-ghcr.io/ublue-os/bazzite:stable}" -payload="localhost/${image_name}:live-payload" +live_base_image="${LIVE_BASE_IMAGE:-quay.io/fedora/fedora-kinoite:43}" +installer_builder_image="${INSTALLER_BUILDER_IMAGE:-ghcr.io/jasonn3/build-container-installer:v1.5.0}" +source_image="${image_name}:${image_tag}" +payload="localhost/aerocore-live-payload:latest" output_dir="${project_root}/output" +payload_archive="${output_dir}/install-payload.oci" +iso="${output_dir}/aerocore-os-${image_tag}-amd64.iso" +checksum="${iso}-CHECKSUM" api_socket="${PODMAN_SOCKET:-/run/podman/podman.sock}" if [[ "${EUID}" -eq 0 ]]; then podman_cmd=(podman) + socket_test=(test -S "${api_socket}") else podman_cmd=(sudo podman) + socket_test=(sudo test -S "${api_socket}") fi -if [[ ! -S "${api_socket}" ]]; then +if ! "${socket_test[@]}"; then echo "Podman API socket not found: ${api_socket}" >&2 echo "Set PODMAN_SOCKET to the rootful Podman socket and retry." >&2 exit 1 fi +ensure_rootful_image() { + local root_image_id user_image_id user_name user_uid copy_tmp + + root_image_id="$("${podman_cmd[@]}" images \ + --filter "reference=${source_image}" \ + --format "{{.ID}}" | head -n1)" + + if [[ -n "${root_image_id}" ]]; then + return 0 + fi + + if [[ "${EUID}" -ne 0 ]]; then + just _rootful_load_image "${image_name}" "${image_tag}" + return + fi + + if [[ -z "${SUDO_USER:-}" ]]; then + return + fi + + user_name="${SUDO_USER}" + user_uid="$(id -u "${user_name}")" + user_image_id="$(sudo -u "${user_name}" \ + env XDG_RUNTIME_DIR="/run/user/${user_uid}" \ + podman images \ + --filter "reference=${source_image}" \ + --format "{{.ID}}" | head -n1)" + + if [[ -z "${user_image_id}" ]]; then + return + fi + + copy_tmp="$(mktemp -p "${project_root}" -d -t _build_podman_scp.XXXXXXXXXX)" + TMPDIR="${copy_tmp}" podman image scp \ + "${user_uid}@localhost::${source_image}" \ + "root@localhost::${source_image}" + rm -rf "${copy_tmp}" +} + mkdir -p "${output_dir}" -"${podman_cmd[@]}" tag "${image_name}:${image_tag}" "${payload}" +ensure_rootful_image + +"${podman_cmd[@]}" tag "${source_image}" "${payload}" +"${podman_cmd[@]}" save --format oci-archive --output "${payload_archive}" "${payload}" "${podman_cmd[@]}" build \ --cap-add sys_admin \ --security-opt label=disable \ - --build-arg "BASE_IMAGE=${base_image}" \ + --build-arg "BASE_IMAGE=${live_base_image}" \ --build-arg "INSTALL_IMAGE_PAYLOAD=${payload}" \ - --tag localhost/aerocore-live-payload:latest \ + --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ + --tag "${payload}" \ --file installer/Containerfile \ . +if [[ "${EUID}" -eq 0 ]]; then + rm -f "${iso}" "${checksum}" +else + sudo rm -f "${iso}" "${checksum}" +fi + "${podman_cmd[@]}" run --rm --privileged \ --volume "${api_socket}:/var/run/docker.sock" \ + --volume /var/lib/containers/storage:/var/lib/containers/storage \ --volume "${project_root}/output:/build-container-installer/build" \ --volume "${project_root}/installer/lorax_templates:/additional_lorax_templates:ro" \ - docker.io/jasonn3/build-container-installer:latest \ + "${installer_builder_image}" \ ADDITIONAL_TEMPLATES="/additional_lorax_templates/remove_root_password_prompt.tmpl /additional_lorax_templates/set_default_user.tmpl" \ ARCH="x86_64" \ ENABLE_CACHE_DNF="false" \ @@ -47,12 +104,19 @@ mkdir -p "${output_dir}" ENABLE_FLATPAK_DEPENDENCIES="false" \ IMAGE_NAME="aerocore-live-payload" \ IMAGE_REPO="localhost" \ + IMAGE_SRC="containers-storage:${payload}" \ IMAGE_TAG="latest" \ ISO_NAME="build/aerocore-os-${image_tag}-amd64.iso" \ VARIANT="Kinoite" \ VERSION="${FEDORA_VERSION:-44}" -iso="${output_dir}/aerocore-os-${image_tag}-amd64.iso" if [[ -f "${iso}" ]]; then - sha256sum "${iso}" | tee "${iso}-CHECKSUM" + if [[ "${EUID}" -ne 0 ]]; then + sudo chown "$(id -u):$(id -g)" "${iso}" + sudo rm -f "${checksum}" + (cd "${output_dir}" && sha256sum "$(basename "${iso}")") | sudo tee "${checksum}" + sudo chown "$(id -u):$(id -g)" "${checksum}" + else + (cd "${output_dir}" && sha256sum "$(basename "${iso}")") | tee "${checksum}" + fi fi -- cgit v1.2.3 From bf529f74e0a776518f73852a3a156361051772dc Mon Sep 17 00:00:00 2001 From: Tranch Xiao Date: Wed, 22 Jul 2026 01:15:45 +0800 Subject: ci: Disable daily scheduled build --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 56f8da9..95f2f1c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,8 +4,8 @@ on: pull_request: branches: - main - schedule: - - cron: '05 10 * * *' # 10:05am UTC everyday + #schedule: + # - cron: '05 10 * * *' # 10:05am UTC everyday workflow_dispatch: env: -- cgit v1.2.3 From 0e0290ab60bb89b9ddaedfe3a10127ba999f9383 Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 22 Jul 2026 08:40:43 +0800 Subject: Constrain builds to bazzite-deck Keep the live installer Fedora version aligned with the deck base image and fail early if BASE_IMAGE is overridden to a non-deck variant. --- .github/workflows/build-live-installer.yml | 3 ++- Containerfile | 2 +- build_files/build.sh | 9 +++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-live-installer.yml b/.github/workflows/build-live-installer.yml index b5fedb3..98441df 100644 --- a/.github/workflows/build-live-installer.yml +++ b/.github/workflows/build-live-installer.yml @@ -35,8 +35,9 @@ jobs: env: IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} IMAGE_TAG: ${{ inputs.image_tag || 'latest' }} + # Keep these aligned with the Fedora major used by the target bazzite-deck base image. LIVE_BASE_IMAGE: quay.io/fedora/fedora-kinoite:43 - FEDORA_VERSION: "44" + FEDORA_VERSION: "43" steps: - name: Maximize build space diff --git a/Containerfile b/Containerfile index c9377ca..16e85a2 100644 --- a/Containerfile +++ b/Containerfile @@ -7,6 +7,7 @@ COPY system_files /system_files # Base Image FROM ${BASE_IMAGE} +ARG BASE_IMAGE ARG IMAGE_NAME="aerocore-os" ARG IMAGE_VENDOR="AeroCore-IO" ARG IMAGE_BRANCH="stable" @@ -16,7 +17,6 @@ ARG OSTREE_IMAGE_REF="" ## Other possible base images include: # ghcr.io/ublue-os/bazzite-deck:testing # ghcr.io/ublue-os/bazzite-deck:stable-43.20260420 -# ghcr.io/ublue-os/bazzite:stable ### [IM]MUTABLE /opt ## Some bootable images, like Fedora, have /opt symlinked to /var/opt, in order to diff --git a/build_files/build.sh b/build_files/build.sh index 3d37e31..03adff0 100755 --- a/build_files/build.sh +++ b/build_files/build.sh @@ -2,6 +2,15 @@ set -ouex pipefail +case "${BASE_IMAGE:-}" in + ghcr.io/ublue-os/bazzite-deck:* | ghcr.io/ublue-os/bazzite-deck@*) + ;; + *) + echo "AeroCore OS only supports bazzite-deck BASE_IMAGE values for HTPC game-mode builds: ${BASE_IMAGE:-}" >&2 + exit 1 + ;; +esac + # Copy the contents of system_files/ of the git repo to / cp -avf "/ctx/system_files"/. / -- cgit v1.2.3 From 9a5fc8296062669cd43689727451da6946860b7d Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 22 Jul 2026 16:08:54 +0800 Subject: ci: pin Titanoboa live installer action --- .github/workflows/build-live-installer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-live-installer.yml b/.github/workflows/build-live-installer.yml index 98441df..059c3e9 100644 --- a/.github/workflows/build-live-installer.yml +++ b/.github/workflows/build-live-installer.yml @@ -99,7 +99,7 @@ jobs: - name: Build ISO id: build - uses: Zeglius/titanoboa@revamp-pr + uses: Zeglius/titanoboa@7737f4748458252ac827dca14b3d6dd09298472a # revamp-pr with: arch: x86_64 image_name: aerocore-live-payload -- cgit v1.2.3 From 226cda5808873f213ea858f85404eb8d61d7c82b Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 22 Jul 2026 16:21:37 +0800 Subject: ci: fix workflow inputs and paths --- .github/workflows/build-disk.yml | 7 +++---- .github/workflows/build.yml | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index 02ef44a..869277d 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -19,10 +19,9 @@ on: branches: - main paths: - - './disk_config/disk.toml' - - './disk_config/iso-kde.toml' - - './disk_config/iso-gnome.toml' - - './.github/workflows/build-disk.yml' + - 'disk_config/disk.toml' + - 'disk_config/iso-kde.toml' + - '.github/workflows/build-disk.yml' env: IMAGE_NAME: ${{ github.event.repository.name }} # output of build.yml, keep in sync diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 49d2f81..3182eff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,7 @@ env: IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit concurrency: - group: ${{ github.workflow }}-${{ github.ref || github.run_id }}-${{ inputs.brand_name}}-${{ inputs.stream_name }} + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} cancel-in-progress: true jobs: -- cgit v1.2.3 From 40ee74f08f96c7be7c3356b98152a6a1f1a31f4d Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 22 Jul 2026 16:31:49 +0800 Subject: ci: add live installer PR validation --- .github/workflows/validate-live-installer.yml | 40 +++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/validate-live-installer.yml diff --git a/.github/workflows/validate-live-installer.yml b/.github/workflows/validate-live-installer.yml new file mode 100644 index 0000000..3d35a5d --- /dev/null +++ b/.github/workflows/validate-live-installer.yml @@ -0,0 +1,40 @@ +name: Validate live installer + +on: + pull_request: + paths: + - "Justfile" + - "installer/**" + - "just_scripts/build-live-installer.sh" + - ".github/workflows/build-live-installer.yml" + - ".github/workflows/validate-live-installer.yml" + +permissions: + contents: read + +jobs: + validate-live-installer: + name: Validate live installer inputs + runs-on: ubuntu-24.04 + + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + + - name: Install just + uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 + + - name: Validate workflow YAML + run: | + ruby -e 'require "yaml"; Dir[".github/workflows/*.yml"].each { |file| YAML.load_file(file) }' + + - name: Validate Justfile formatting + run: | + just --unstable --fmt --check -f Justfile + + - name: Validate build scripts + run: | + for script in build_files/*.sh installer/*.sh just_scripts/*.sh; do + bash -n "$script" + done + bash -n system_files/usr/libexec/aerocore-instruments-setup -- cgit v1.2.3 From 54790d45fba14c63544355e4c78247e9e05d6c7d Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 22 Jul 2026 16:40:16 +0800 Subject: ci: quote workflow shell variables --- .github/workflows/build-disk.yml | 14 ++++++++------ .github/workflows/build.yml | 35 ++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build-disk.yml b/.github/workflows/build-disk.yml index 869277d..cef58be 100644 --- a/.github/workflows/build-disk.yml +++ b/.github/workflows/build-disk.yml @@ -54,11 +54,13 @@ jobs: # Concatenate the types with a hyphen DISK_TYPE=$(echo "${{ matrix.disk-type }}" | tr ' ' '-') # Lowercase the image uri - echo "IMAGE_REGISTRY=${IMAGE_REGISTRY,,}" >> ${GITHUB_ENV} - echo "IMAGE_NAME=${IMAGE_NAME,,}" >> ${GITHUB_ENV} - echo "DISK_TYPE=${DISK_TYPE}" >> ${GITHUB_ENV} - echo "USER_UID=${USER_UID}" >> ${GITHUB_ENV} - echo "USER_GID=${USER_GID}" >> ${GITHUB_ENV} + { + echo "IMAGE_REGISTRY=${IMAGE_REGISTRY,,}" + echo "IMAGE_NAME=${IMAGE_NAME,,}" + echo "DISK_TYPE=${DISK_TYPE}" + echo "USER_UID=${USER_UID}" + echo "USER_GID=${USER_GID}" + } >> "$GITHUB_ENV" - name: Install dependencies if: inputs.platform == 'arm64' @@ -112,4 +114,4 @@ jobs: run: | sudo apt-get update sudo apt-get install -y rclone - rclone copy $SOURCE_DIR S3:${{ secrets.S3_BUCKET_NAME }} + rclone copy "$SOURCE_DIR" "S3:${{ secrets.S3_BUCKET_NAME }}" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3182eff..a4661fb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -69,7 +69,7 @@ jobs: run: | IMAGE_NAME=$(just image_name) - echo "IMAGE_NAME=${IMAGE_NAME}" >> $GITHUB_ENV + echo "IMAGE_NAME=${IMAGE_NAME}" >> "$GITHUB_ENV" - name: Default Tag id: gen-default-tag @@ -80,13 +80,13 @@ jobs: DEFAULT_TAG=$(just generate-default-tag) fi - echo "DEFAULT_TAG=${DEFAULT_TAG}" >> $GITHUB_ENV + 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} + echo "IMAGE_REGISTRY=${IMAGE_REGISTRY,,}" >> "$GITHUB_ENV" + echo "IMAGE_NAME=${IMAGE_NAME,,}" >> "$GITHUB_ENV" # This actually builds the container image - name: Build Image @@ -102,17 +102,17 @@ jobs: INSTRUMENTS_VERSION: ${{ vars.INSTRUMENTS_VERSION || 'latest' }} INSTRUMENTS_RELEASE_API_BASE: ${{ vars.INSTRUMENTS_RELEASE_API_BASE || 'https://api.github.com' }} run: | - sudo -E $(command -v just) build \ - ${IMAGE_NAME} \ - ${DEFAULT_TAG} + 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} + 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 @@ -131,20 +131,20 @@ jobs: alias_tags="testing ${DEFAULT_TAG}" else alias_tags="$(just generate-build-tags \ - ${IMAGE_NAME} \ - ${DEFAULT_TAG})" + "${IMAGE_NAME}" \ + "${DEFAULT_TAG}")" fi echo "Tags for this Action..." echo "${alias_tags}" - echo "alias_tags=${alias_tags}" >> $GITHUB_OUTPUT + 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 \ + sudo -E "$(command -v just)" tag-images \ "${IMAGE_NAME}" \ "${DEFAULT_TAG}" \ "${ALIAS_TAGS}" @@ -167,12 +167,13 @@ jobs: 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} + sudo -E podman push --digestfile=/tmp/digestfile \ + "${IMAGE_NAME}:${tag}" "${IMAGE_REGISTRY}/${IMAGE_NAME}:${tag}" done digest=$(< /tmp/digestfile) - echo "digest=${digest}" >> $GITHUB_OUTPUT + 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 @@ -194,4 +195,4 @@ jobs: COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} DIGEST: ${{ steps.push-image.outputs.digest }} run: | - cosign sign -y --key env://COSIGN_PRIVATE_KEY ${IMAGE_REGISTRY}/${IMAGE_NAME}@${DIGEST} + cosign sign -y --key env://COSIGN_PRIVATE_KEY "${IMAGE_REGISTRY}/${IMAGE_NAME}@${DIGEST}" -- cgit v1.2.3 From b60aab650e4af83a0a9e4bae905459833b3f464b Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 22 Jul 2026 17:47:04 +0800 Subject: ci: order image and installer builds --- .github/workflows/build-live-installer.yml | 12 ++++++------ .github/workflows/build.yml | 3 +++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-live-installer.yml b/.github/workflows/build-live-installer.yml index 059c3e9..5993b2f 100644 --- a/.github/workflows/build-live-installer.yml +++ b/.github/workflows/build-live-installer.yml @@ -9,14 +9,13 @@ on: default: latest type: string workflow_call: - push: + workflow_run: + workflows: + - Build container image + types: + - completed branches: - main - paths: - - "Justfile" - - "installer/**" - - "just_scripts/build-live-installer.sh" - - ".github/workflows/build-live-installer.yml" permissions: {} @@ -27,6 +26,7 @@ concurrency: jobs: build-live-installer: name: Build KDE live installer + if: github.event_name != 'workflow_run' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push') runs-on: ubuntu-24.04 permissions: contents: read diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a4661fb..221c735 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,9 @@ --- name: Build container image on: + push: + branches: + - main pull_request: branches: - main -- cgit v1.2.3 From 759583f82c787f06b926c3658662366f75989496 Mon Sep 17 00:00:00 2001 From: tranch Date: Thu, 23 Jul 2026 01:06:50 +0800 Subject: ci: update live installer action inputs --- .github/workflows/build-live-installer.yml | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-live-installer.yml b/.github/workflows/build-live-installer.yml index 5993b2f..c685fd7 100644 --- a/.github/workflows/build-live-installer.yml +++ b/.github/workflows/build-live-installer.yml @@ -101,28 +101,20 @@ jobs: id: build uses: Zeglius/titanoboa@7737f4748458252ac827dca14b3d6dd09298472a # revamp-pr with: - arch: x86_64 - image_name: aerocore-live-payload - image_repo: localhost - variant: Kinoite - version: ${{ env.FEDORA_VERSION }} - image_tag: latest - iso_name: aerocore-os-${{ env.IMAGE_TAG }}-amd64.iso - enable_cache_dnf: "false" - enable_cache_skopeo: "false" - enable_flatpak_dependencies: "false" - additional_templates: /github/workspace/installer/lorax_templates/remove_root_password_prompt.tmpl /github/workspace/installer/lorax_templates/set_default_user.tmpl + image-ref: localhost/aerocore-live-payload:latest + iso-dest: ${{ github.workspace }}/output/aerocore-os-${{ env.IMAGE_TAG }}-amd64.iso - name: Display checksum run: | - cat "${{ steps.build.outputs.iso_path }}/${{ steps.build.outputs.iso_name }}-CHECKSUM" + iso_path="output/aerocore-os-${IMAGE_TAG}-amd64.iso" + sha256sum "${iso_path}" | tee "${iso_path}-CHECKSUM" - name: Upload ISO artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: aerocore-os-live-installer-${{ env.IMAGE_TAG }} path: | - ${{ steps.build.outputs.iso_path }}/${{ steps.build.outputs.iso_name }} - ${{ steps.build.outputs.iso_path }}/${{ steps.build.outputs.iso_name }}-CHECKSUM + output/aerocore-os-${{ env.IMAGE_TAG }}-amd64.iso + output/aerocore-os-${{ env.IMAGE_TAG }}-amd64.iso-CHECKSUM if-no-files-found: error compression-level: 0 -- cgit v1.2.3 From 667f7c530d0c0b1b424b8501d124ec082ce77e7d Mon Sep 17 00:00:00 2001 From: tranch Date: Thu, 23 Jul 2026 14:30:04 +0800 Subject: feat: Adjust live installer build for consistent ISO naming Introduce an `ISO_FILE_TAG` environment variable to ensure consistent ISO filenames. This variable is set to 'testing' when on the testing branch, or uses the provided `image_tag` otherwise. This change affects the ISO destination path, checksum file generation, artifact upload naming, and the R2 upload. Additionally, prepare ISO and checksum files into a dedicated upload directory before uploading artifacts and to R2. This simplifies the artifact handling. --- .github/workflows/build-live-installer.yml | 47 +++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-live-installer.yml b/.github/workflows/build-live-installer.yml index c685fd7..4b8cb62 100644 --- a/.github/workflows/build-live-installer.yml +++ b/.github/workflows/build-live-installer.yml @@ -35,6 +35,7 @@ jobs: env: IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} IMAGE_TAG: ${{ inputs.image_tag || 'latest' }} + ISO_FILE_TAG: ${{ github.ref_name == 'testing' && 'testing' || (inputs.image_tag || 'latest') }} # Keep these aligned with the Fedora major used by the target bazzite-deck base image. LIVE_BASE_IMAGE: quay.io/fedora/fedora-kinoite:43 FEDORA_VERSION: "43" @@ -102,19 +103,51 @@ jobs: uses: Zeglius/titanoboa@7737f4748458252ac827dca14b3d6dd09298472a # revamp-pr with: image-ref: localhost/aerocore-live-payload:latest - iso-dest: ${{ github.workspace }}/output/aerocore-os-${{ env.IMAGE_TAG }}-amd64.iso + iso-dest: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-amd64.iso - name: Display checksum run: | - iso_path="output/aerocore-os-${IMAGE_TAG}-amd64.iso" - sha256sum "${iso_path}" | tee "${iso_path}-CHECKSUM" + iso_path="output/aerocore-os-${ISO_FILE_TAG}-amd64.iso" + checksum_path="${iso_path}-CHECKSUM" + sha256sum "${iso_path}" | tee "${checksum_path}" + { + echo "# ISO Checksum (SHA256)" + echo + echo "ISO: $(basename "${iso_path}")" + echo + echo '```' + cat "${checksum_path}" + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + + - name: Prepare ISO upload files + run: | + iso_path="output/aerocore-os-${ISO_FILE_TAG}-amd64.iso" + upload_dir="output/upload" + mkdir -p "${upload_dir}" + mv "${iso_path}" "${upload_dir}/" + mv "${iso_path}-CHECKSUM" "${upload_dir}/" - name: Upload ISO artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - name: aerocore-os-live-installer-${{ env.IMAGE_TAG }} - path: | - output/aerocore-os-${{ env.IMAGE_TAG }}-amd64.iso - output/aerocore-os-${{ env.IMAGE_TAG }}-amd64.iso-CHECKSUM + name: aerocore-os-live-installer-${{ env.ISO_FILE_TAG }} + path: output/upload if-no-files-found: error compression-level: 0 + + - name: Upload ISO and checksum to R2 + if: github.ref_name == 'testing' || github.ref_name == 'main' + shell: bash + env: + RCLONE_CONFIG_R2_TYPE: s3 + RCLONE_CONFIG_R2_PROVIDER: Cloudflare + RCLONE_CONFIG_R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} + RCLONE_CONFIG_R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} + RCLONE_CONFIG_R2_REGION: auto + RCLONE_CONFIG_R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }} + SOURCE_DIR: ${{ github.workspace }}/output/upload + run: | + sudo apt-get update + sudo apt-get install -y rclone + rclone copy "$SOURCE_DIR" R2:bazzite -- cgit v1.2.3 From 34392b54532ae98e21f983e265525cd637c125fb Mon Sep 17 00:00:00 2001 From: tranch Date: Thu, 23 Jul 2026 16:47:13 +0800 Subject: Fix live installer ISO path Normalize the path reported by Titanoboa before checksum and upload steps so artifacts misplaced under the action directory remain usable. Also enable pipefail so checksum failures are not hidden by tee. Verified with YAML parsing, git diff checks, and local path simulation. --- .github/workflows/build-live-installer.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/build-live-installer.yml b/.github/workflows/build-live-installer.yml index 4b8cb62..1f57edd 100644 --- a/.github/workflows/build-live-installer.yml +++ b/.github/workflows/build-live-installer.yml @@ -105,8 +105,25 @@ jobs: image-ref: localhost/aerocore-live-payload:latest iso-dest: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-amd64.iso + - name: Normalize ISO output path + shell: bash + env: + GENERATED_ISO: ${{ steps.build.outputs.iso-dest }} + EXPECTED_ISO: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-amd64.iso + run: | + if [[ ! -f "${GENERATED_ISO}" ]]; then + echo "::error::Generated ISO does not exist at ${GENERATED_ISO}" + exit 1 + fi + if [[ "${GENERATED_ISO}" != "${EXPECTED_ISO}" ]]; then + mkdir -p "$(dirname "${EXPECTED_ISO}")" + mv "${GENERATED_ISO}" "${EXPECTED_ISO}" + fi + - name: Display checksum + shell: bash run: | + set -o pipefail iso_path="output/aerocore-os-${ISO_FILE_TAG}-amd64.iso" checksum_path="${iso_path}-CHECKSUM" sha256sum "${iso_path}" | tee "${checksum_path}" -- cgit v1.2.3 From aeff85580fae9c6d4dc40ab88c3a89599000de22 Mon Sep 17 00:00:00 2001 From: tranch Date: Thu, 23 Jul 2026 18:11:26 +0800 Subject: test: update build-live-installer.yml to prepare and upload ISO Refactor the ISO upload process in the build workflow. Move the ISO file to a dedicated upload directory and recalculate the checksum there. Upload only the checksum as a job artifact for the 'testing' branch. Adjust the R2 upload condition to trigger only on workflow dispatch for the 'main' branch. Co-authored-by: llm-git --- .github/workflows/build-live-installer.yml | 34 +++++++++++++++++++----------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build-live-installer.yml b/.github/workflows/build-live-installer.yml index 1f57edd..0965c33 100644 --- a/.github/workflows/build-live-installer.yml +++ b/.github/workflows/build-live-installer.yml @@ -137,24 +137,34 @@ jobs: echo '```' } >> "$GITHUB_STEP_SUMMARY" - - name: Prepare ISO upload files + - name: Move ISO to upload directory + id: upload-directory + shell: bash run: | - iso_path="output/aerocore-os-${ISO_FILE_TAG}-amd64.iso" - upload_dir="output/upload" - mkdir -p "${upload_dir}" - mv "${iso_path}" "${upload_dir}/" - mv "${iso_path}-CHECKSUM" "${upload_dir}/" - - - name: Upload ISO artifact + iso_upload_dir="${{ github.workspace }}/output/upload" + iso_path="${{ github.workspace }}/output/aerocore-os-${ISO_FILE_TAG}-amd64.iso" + iso_name="$(basename "${iso_path}")" + + mkdir -p "${iso_upload_dir}" + mv "${iso_path}" "${iso_upload_dir}/" + ( + cd "${iso_upload_dir}" + sha256sum "${iso_name}" | tee "${iso_name}-CHECKSUM" + ) + echo "iso-upload-dir=${iso_upload_dir}" >> "$GITHUB_OUTPUT" + + - name: Upload ISO checksum to Job Artifacts + if: github.ref_name == 'testing' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - name: aerocore-os-live-installer-${{ env.ISO_FILE_TAG }} - path: output/upload + name: aerocore-os-live-installer-${{ env.ISO_FILE_TAG }}-checksum + path: ${{ steps.upload-directory.outputs.iso-upload-dir }}/*-CHECKSUM if-no-files-found: error + retention-days: 1 compression-level: 0 - name: Upload ISO and checksum to R2 - if: github.ref_name == 'testing' || github.ref_name == 'main' + if: github.event_name == 'workflow_dispatch' && github.ref_name == 'main' shell: bash env: RCLONE_CONFIG_R2_TYPE: s3 @@ -163,7 +173,7 @@ jobs: RCLONE_CONFIG_R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} RCLONE_CONFIG_R2_REGION: auto RCLONE_CONFIG_R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }} - SOURCE_DIR: ${{ github.workspace }}/output/upload + SOURCE_DIR: ${{ steps.upload-directory.outputs.iso-upload-dir }} run: | sudo apt-get update sudo apt-get install -y rclone -- cgit v1.2.3 From 471cd249e333446dc73e91adde5d8ea36ca19796 Mon Sep 17 00:00:00 2001 From: tranch Date: Fri, 24 Jul 2026 08:18:08 +0800 Subject: Fix live installer EFI fallback Copy Fedora grubx64.efi to the fallback EFI path expected by bootc-image-builder. --- installer/build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/installer/build.sh b/installer/build.sh index 033fe9b..921e628 100755 --- a/installer/build.sh +++ b/installer/build.sh @@ -61,5 +61,8 @@ if compgen -G '/usr/lib/efi/*/*/EFI' >/dev/null; then cp -a /usr/lib/efi/*/*/EFI /boot/efi/ fi +# bootc-image-builder needs the Fedora live ISO fallback EFI loader. +cp -v /boot/efi/EFI/fedora/grubx64.efi /boot/efi/EFI/BOOT/fbx64.efi + systemd-firstboot --timezone UTC dnf clean all -- cgit v1.2.3 From a7116e218cda6c5db5e7ba57faef638a54c500d6 Mon Sep 17 00:00:00 2001 From: tranch Date: Fri, 24 Jul 2026 09:17:07 +0800 Subject: Fix live installer GRUB EFI fallback Install the full EFI GRUB package and create the fallback directory. --- installer/build.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/installer/build.sh b/installer/build.sh index 921e628..6f1561f 100755 --- a/installer/build.sh +++ b/installer/build.sh @@ -19,6 +19,7 @@ dnf --setopt=excludepkgs= install -y \ libblockdev-lvm \ dracut-live \ livesys-scripts \ + grub2-efi-x64 \ grub2-efi-x64-cdboot # Apply the same AeroCore overlay to the live session where possible. @@ -62,6 +63,7 @@ if compgen -G '/usr/lib/efi/*/*/EFI' >/dev/null; then fi # bootc-image-builder needs the Fedora live ISO fallback EFI loader. +mkdir -p /boot/efi/EFI/BOOT cp -v /boot/efi/EFI/fedora/grubx64.efi /boot/efi/EFI/BOOT/fbx64.efi systemd-firstboot --timezone UTC -- cgit v1.2.3 From a25a2a1b1e7f170226f13656595b9c4db3c3bffd Mon Sep 17 00:00:00 2001 From: tranch Date: Fri, 24 Jul 2026 09:39:33 +0800 Subject: Find live installer EFI files robustly Avoid assuming the Fedora EFI directory layout when creating fbx64.efi. --- installer/build.sh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/installer/build.sh b/installer/build.sh index 6f1561f..2f8a26b 100755 --- a/installer/build.sh +++ b/installer/build.sh @@ -58,13 +58,21 @@ sed -i 's/^livesys_session=.*/livesys_session=kde/' /etc/sysconfig/livesys systemctl enable livesys.service livesys-late.service mkdir -p /boot/efi -if compgen -G '/usr/lib/efi/*/*/EFI' >/dev/null; then - cp -a /usr/lib/efi/*/*/EFI /boot/efi/ +efi_dir="$(find /usr/lib/efi -type d -name EFI -print -quit 2>/dev/null || true)" +if [[ -n "${efi_dir}" ]]; then + cp -a "${efi_dir}" /boot/efi/ fi # bootc-image-builder needs the Fedora live ISO fallback EFI loader. +grubx64="$(find /usr/lib/efi /boot/efi -type f \ + -path '*/EFI/fedora/grubx64.efi' -print -quit 2>/dev/null || true)" +if [[ -z "${grubx64}" ]]; then + echo "grubx64.efi was not found in the installed EFI tree" >&2 + find /usr/lib/efi /boot/efi -type f -path '*/EFI/*' -print >&2 || true + exit 1 +fi mkdir -p /boot/efi/EFI/BOOT -cp -v /boot/efi/EFI/fedora/grubx64.efi /boot/efi/EFI/BOOT/fbx64.efi +cp -v "${grubx64}" /boot/efi/EFI/BOOT/fbx64.efi systemd-firstboot --timezone UTC dnf clean all -- cgit v1.2.3 From 0c4d05acf5e233cd0aa8d8f42560064dde2fc3f6 Mon Sep 17 00:00:00 2001 From: tranch Date: Fri, 24 Jul 2026 09:44:48 +0800 Subject: Restore EFI GRUB files in Kinoite build Reinstall EFI packages so missing payload files are materialized. --- installer/build.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/installer/build.sh b/installer/build.sh index 2f8a26b..efce782 100755 --- a/installer/build.sh +++ b/installer/build.sh @@ -22,6 +22,12 @@ dnf --setopt=excludepkgs= install -y \ grub2-efi-x64 \ grub2-efi-x64-cdboot +# Kinoite can carry the EFI packages in the RPM database without their files +# materialized in the container filesystem. Restore the files for the ISO. +dnf --setopt=excludepkgs= reinstall -y \ + grub2-efi-x64 \ + grub2-efi-x64-cdboot + # Apply the same AeroCore overlay to the live session where possible. if [[ -d /src/system_files ]]; then cp -a /src/system_files/. / -- cgit v1.2.3 From 4301b91f0e54c24b700bf82aac849396441fb692 Mon Sep 17 00:00:00 2001 From: tranch Date: Fri, 24 Jul 2026 13:34:08 +0800 Subject: Add standard UEFI fallback loader Include BOOTX64.EFI alongside the bootc-image-builder fbx64.efi so removable-media UEFI firmware can boot the live installer ISO. --- installer/build.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/installer/build.sh b/installer/build.sh index efce782..3ee1744 100755 --- a/installer/build.sh +++ b/installer/build.sh @@ -78,6 +78,8 @@ if [[ -z "${grubx64}" ]]; then exit 1 fi mkdir -p /boot/efi/EFI/BOOT +# UEFI removable-media fallback; keep fbx64.efi for bootc-image-builder. +cp -v "${grubx64}" /boot/efi/EFI/BOOT/BOOTX64.EFI cp -v "${grubx64}" /boot/efi/EFI/BOOT/fbx64.efi systemd-firstboot --timezone UTC -- cgit v1.2.3 From cb1f8c566bf903d2643c3cc9ad3712c831a90880 Mon Sep 17 00:00:00 2001 From: tranch Date: Fri, 24 Jul 2026 16:58:29 +0800 Subject: Brand live installer sidebar Copy installer branding assets into Anaconda's pixmaps directory after the shared live-session overlay so AeroCore resources take precedence. Ignore local .DS_Store files to keep macOS metadata out of commits. --- .gitignore | 1 + installer/branding/sidebar-bg.png | Bin 0 -> 163156 bytes installer/branding/sidebar-logo.png | Bin 0 -> 4425 bytes installer/build.sh | 6 ++++++ 4 files changed, 7 insertions(+) create mode 100644 installer/branding/sidebar-bg.png create mode 100644 installer/branding/sidebar-logo.png diff --git a/.gitignore b/.gitignore index 9eee28b..d4fa7cf 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ cosign.key _build_* output _build-*/** +.DS_Store diff --git a/installer/branding/sidebar-bg.png b/installer/branding/sidebar-bg.png new file mode 100644 index 0000000..f957fec Binary files /dev/null and b/installer/branding/sidebar-bg.png differ diff --git a/installer/branding/sidebar-logo.png b/installer/branding/sidebar-logo.png new file mode 100644 index 0000000..0f47606 Binary files /dev/null and b/installer/branding/sidebar-logo.png differ diff --git a/installer/build.sh b/installer/build.sh index 3ee1744..f9eb210 100755 --- a/installer/build.sh +++ b/installer/build.sh @@ -33,6 +33,12 @@ if [[ -d /src/system_files ]]; then cp -a /src/system_files/. / fi +BRANDING_DIR="${SCRIPT_DIR}/branding" +if [[ -d "${BRANDING_DIR}" ]]; then + mkdir -p /usr/share/anaconda/pixmaps + cp -a "${BRANDING_DIR}/." /usr/share/anaconda/pixmaps/ +fi + # Make the install payload available to Anaconda. if [[ -n "${INSTALL_IMAGE_PAYLOAD_ARCHIVE}" && -f "${INSTALL_IMAGE_PAYLOAD_ARCHIVE}" ]]; then podman load --storage-opt additionalimagestore='' < "${INSTALL_IMAGE_PAYLOAD_ARCHIVE}" -- cgit v1.2.3 From 41b6840fa4a8a41704a00a115b2338d30673e4ca Mon Sep 17 00:00:00 2001 From: tranch Date: Fri, 24 Jul 2026 17:29:04 +0800 Subject: Rename live installer to installer ISO Use installer ISO terminology across Just, workflows, scripts, docs, and image payloads while preserving compatibility aliases for existing commands. --- .github/workflows/build-installer-iso.yml | 180 ++++++++++++++++++++++++++ .github/workflows/build-live-installer.yml | 180 -------------------------- .github/workflows/validate-installer-iso.yml | 40 ++++++ .github/workflows/validate-live-installer.yml | 40 ------ Justfile | 21 +-- README.md | 8 +- installer/Containerfile | 2 +- installer/iso.yaml | 6 +- just_scripts/build-installer-iso.sh | 122 +++++++++++++++++ just_scripts/build-live-installer.sh | 122 ----------------- just_scripts/run-installer-iso.sh | 23 ++++ just_scripts/run-live-installer.sh | 23 ---- 12 files changed, 386 insertions(+), 381 deletions(-) create mode 100644 .github/workflows/build-installer-iso.yml delete mode 100644 .github/workflows/build-live-installer.yml create mode 100644 .github/workflows/validate-installer-iso.yml delete mode 100644 .github/workflows/validate-live-installer.yml create mode 100755 just_scripts/build-installer-iso.sh delete mode 100755 just_scripts/build-live-installer.sh create mode 100755 just_scripts/run-installer-iso.sh delete mode 100755 just_scripts/run-live-installer.sh diff --git a/.github/workflows/build-installer-iso.yml b/.github/workflows/build-installer-iso.yml new file mode 100644 index 0000000..cfa7b80 --- /dev/null +++ b/.github/workflows/build-installer-iso.yml @@ -0,0 +1,180 @@ +name: Build installer ISO + +on: + workflow_dispatch: + inputs: + image_tag: + description: "AeroCore image tag to install" + required: false + default: latest + type: string + workflow_call: + workflow_run: + workflows: + - Build container image + types: + - completed + branches: + - main + +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + build-installer-iso: + name: Build KDE installer ISO + if: github.event_name != 'workflow_run' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push') + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: read + + env: + IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} + IMAGE_TAG: ${{ inputs.image_tag || 'latest' }} + ISO_FILE_TAG: ${{ github.ref_name == 'testing' && 'testing' || (inputs.image_tag || 'latest') }} + # Keep these aligned with the Fedora major used by the target bazzite-deck base image. + LIVE_BASE_IMAGE: quay.io/fedora/fedora-kinoite:43 + FEDORA_VERSION: "43" + + steps: + - name: Maximize build space + uses: ublue-os/remove-unwanted-software@cc0becac701cf642c8f0a6613bbdaf5dc36b259e # v9 + with: + remove-codeql: true + + - name: Mount container storage BTRFS loopback + run: | + sudo truncate -s 70G /mnt/podman-storage.img + sudo mkfs.btrfs -f /mnt/podman-storage.img + sudo podman system reset --force + sudo systemctl stop podman.service + sudo mount -o compress-force=zstd:2 /mnt/podman-storage.img /var/lib/containers/storage + sudo systemctl start podman.service + + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + + - name: Install just + uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 + + - name: Prepare image references + run: | + image_name="$(just image_name)" + image_registry="${IMAGE_REGISTRY,,}" + echo "IMAGE_NAME=${image_name,,}" >> "$GITHUB_ENV" + echo "IMAGE_REGISTRY=${image_registry}" >> "$GITHUB_ENV" + + - name: Login to GHCR + run: | + echo '${{ secrets.GITHUB_TOKEN }}' | sudo podman login ghcr.io \ + --username '${{ github.actor }}' --password-stdin + + - name: Pull AeroCore install image + run: | + sudo podman pull "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" + + - name: Build installer ISO payload + run: | + mkdir -p output + sudo podman tag \ + "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" \ + localhost/aerocore-installer-payload:latest + sudo podman save \ + --format oci-archive \ + --output output/install-payload.oci \ + localhost/aerocore-installer-payload:latest + + sudo podman build \ + --cap-add sys_admin \ + --security-opt label=disable \ + --build-arg "BASE_IMAGE=${LIVE_BASE_IMAGE}" \ + --build-arg "INSTALL_IMAGE_PAYLOAD=localhost/aerocore-installer-payload:latest" \ + --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ + --tag localhost/aerocore-installer-payload:latest \ + --file installer/Containerfile \ + . + + - name: Build ISO + id: build + uses: Zeglius/titanoboa@7737f4748458252ac827dca14b3d6dd09298472a # revamp-pr + with: + image-ref: localhost/aerocore-installer-payload:latest + iso-dest: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-amd64.iso + + - name: Normalize ISO output path + shell: bash + env: + GENERATED_ISO: ${{ steps.build.outputs.iso-dest }} + EXPECTED_ISO: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-amd64.iso + run: | + if [[ ! -f "${GENERATED_ISO}" ]]; then + echo "::error::Generated ISO does not exist at ${GENERATED_ISO}" + exit 1 + fi + if [[ "${GENERATED_ISO}" != "${EXPECTED_ISO}" ]]; then + mkdir -p "$(dirname "${EXPECTED_ISO}")" + mv "${GENERATED_ISO}" "${EXPECTED_ISO}" + fi + + - name: Display checksum + shell: bash + run: | + set -o pipefail + iso_path="output/aerocore-os-${ISO_FILE_TAG}-amd64.iso" + checksum_path="${iso_path}-CHECKSUM" + sha256sum "${iso_path}" | tee "${checksum_path}" + { + echo "# ISO Checksum (SHA256)" + echo + echo "ISO: $(basename "${iso_path}")" + echo + echo '```' + cat "${checksum_path}" + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + + - name: Move ISO to upload directory + id: upload-directory + shell: bash + run: | + iso_upload_dir="${{ github.workspace }}/output/upload" + iso_path="${{ github.workspace }}/output/aerocore-os-${ISO_FILE_TAG}-amd64.iso" + iso_name="$(basename "${iso_path}")" + + mkdir -p "${iso_upload_dir}" + mv "${iso_path}" "${iso_upload_dir}/" + ( + cd "${iso_upload_dir}" + sha256sum "${iso_name}" | tee "${iso_name}-CHECKSUM" + ) + echo "iso-upload-dir=${iso_upload_dir}" >> "$GITHUB_OUTPUT" + + - name: Upload ISO checksum to Job Artifacts + if: github.ref_name == 'testing' + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: aerocore-os-installer-iso-${{ env.ISO_FILE_TAG }}-checksum + path: ${{ steps.upload-directory.outputs.iso-upload-dir }}/*-CHECKSUM + if-no-files-found: error + retention-days: 1 + compression-level: 0 + + - name: Upload ISO and checksum to R2 + if: github.event_name == 'workflow_dispatch' && github.ref_name == 'main' + shell: bash + env: + RCLONE_CONFIG_R2_TYPE: s3 + RCLONE_CONFIG_R2_PROVIDER: Cloudflare + RCLONE_CONFIG_R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} + RCLONE_CONFIG_R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} + RCLONE_CONFIG_R2_REGION: auto + RCLONE_CONFIG_R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }} + SOURCE_DIR: ${{ steps.upload-directory.outputs.iso-upload-dir }} + run: | + sudo apt-get update + sudo apt-get install -y rclone + rclone copy "$SOURCE_DIR" R2:bazzite diff --git a/.github/workflows/build-live-installer.yml b/.github/workflows/build-live-installer.yml deleted file mode 100644 index 0965c33..0000000 --- a/.github/workflows/build-live-installer.yml +++ /dev/null @@ -1,180 +0,0 @@ -name: Build live installer - -on: - workflow_dispatch: - inputs: - image_tag: - description: "AeroCore image tag to install" - required: false - default: latest - type: string - workflow_call: - workflow_run: - workflows: - - Build container image - types: - - completed - branches: - - main - -permissions: {} - -concurrency: - group: ${{ github.workflow }}-${{ github.ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-live-installer: - name: Build KDE live installer - if: github.event_name != 'workflow_run' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push') - runs-on: ubuntu-24.04 - permissions: - contents: read - packages: read - - env: - IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} - IMAGE_TAG: ${{ inputs.image_tag || 'latest' }} - ISO_FILE_TAG: ${{ github.ref_name == 'testing' && 'testing' || (inputs.image_tag || 'latest') }} - # Keep these aligned with the Fedora major used by the target bazzite-deck base image. - LIVE_BASE_IMAGE: quay.io/fedora/fedora-kinoite:43 - FEDORA_VERSION: "43" - - steps: - - name: Maximize build space - uses: ublue-os/remove-unwanted-software@cc0becac701cf642c8f0a6613bbdaf5dc36b259e # v9 - with: - remove-codeql: true - - - name: Mount container storage BTRFS loopback - run: | - sudo truncate -s 70G /mnt/podman-storage.img - sudo mkfs.btrfs -f /mnt/podman-storage.img - sudo podman system reset --force - sudo systemctl stop podman.service - sudo mount -o compress-force=zstd:2 /mnt/podman-storage.img /var/lib/containers/storage - sudo systemctl start podman.service - - - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - - - name: Install just - uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 - - - name: Prepare image references - run: | - image_name="$(just image_name)" - image_registry="${IMAGE_REGISTRY,,}" - echo "IMAGE_NAME=${image_name,,}" >> "$GITHUB_ENV" - echo "IMAGE_REGISTRY=${image_registry}" >> "$GITHUB_ENV" - - - name: Login to GHCR - run: | - echo '${{ secrets.GITHUB_TOKEN }}' | sudo podman login ghcr.io \ - --username '${{ github.actor }}' --password-stdin - - - name: Pull AeroCore install image - run: | - sudo podman pull "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" - - - name: Build live installer payload - run: | - mkdir -p output - sudo podman tag \ - "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" \ - localhost/aerocore-live-payload:latest - sudo podman save \ - --format oci-archive \ - --output output/install-payload.oci \ - localhost/aerocore-live-payload:latest - - sudo podman build \ - --cap-add sys_admin \ - --security-opt label=disable \ - --build-arg "BASE_IMAGE=${LIVE_BASE_IMAGE}" \ - --build-arg "INSTALL_IMAGE_PAYLOAD=localhost/aerocore-live-payload:latest" \ - --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ - --tag localhost/aerocore-live-payload:latest \ - --file installer/Containerfile \ - . - - - name: Build ISO - id: build - uses: Zeglius/titanoboa@7737f4748458252ac827dca14b3d6dd09298472a # revamp-pr - with: - image-ref: localhost/aerocore-live-payload:latest - iso-dest: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-amd64.iso - - - name: Normalize ISO output path - shell: bash - env: - GENERATED_ISO: ${{ steps.build.outputs.iso-dest }} - EXPECTED_ISO: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-amd64.iso - run: | - if [[ ! -f "${GENERATED_ISO}" ]]; then - echo "::error::Generated ISO does not exist at ${GENERATED_ISO}" - exit 1 - fi - if [[ "${GENERATED_ISO}" != "${EXPECTED_ISO}" ]]; then - mkdir -p "$(dirname "${EXPECTED_ISO}")" - mv "${GENERATED_ISO}" "${EXPECTED_ISO}" - fi - - - name: Display checksum - shell: bash - run: | - set -o pipefail - iso_path="output/aerocore-os-${ISO_FILE_TAG}-amd64.iso" - checksum_path="${iso_path}-CHECKSUM" - sha256sum "${iso_path}" | tee "${checksum_path}" - { - echo "# ISO Checksum (SHA256)" - echo - echo "ISO: $(basename "${iso_path}")" - echo - echo '```' - cat "${checksum_path}" - echo '```' - } >> "$GITHUB_STEP_SUMMARY" - - - name: Move ISO to upload directory - id: upload-directory - shell: bash - run: | - iso_upload_dir="${{ github.workspace }}/output/upload" - iso_path="${{ github.workspace }}/output/aerocore-os-${ISO_FILE_TAG}-amd64.iso" - iso_name="$(basename "${iso_path}")" - - mkdir -p "${iso_upload_dir}" - mv "${iso_path}" "${iso_upload_dir}/" - ( - cd "${iso_upload_dir}" - sha256sum "${iso_name}" | tee "${iso_name}-CHECKSUM" - ) - echo "iso-upload-dir=${iso_upload_dir}" >> "$GITHUB_OUTPUT" - - - name: Upload ISO checksum to Job Artifacts - if: github.ref_name == 'testing' - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 - with: - name: aerocore-os-live-installer-${{ env.ISO_FILE_TAG }}-checksum - path: ${{ steps.upload-directory.outputs.iso-upload-dir }}/*-CHECKSUM - if-no-files-found: error - retention-days: 1 - compression-level: 0 - - - name: Upload ISO and checksum to R2 - if: github.event_name == 'workflow_dispatch' && github.ref_name == 'main' - shell: bash - env: - RCLONE_CONFIG_R2_TYPE: s3 - RCLONE_CONFIG_R2_PROVIDER: Cloudflare - RCLONE_CONFIG_R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} - RCLONE_CONFIG_R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} - RCLONE_CONFIG_R2_REGION: auto - RCLONE_CONFIG_R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }} - SOURCE_DIR: ${{ steps.upload-directory.outputs.iso-upload-dir }} - run: | - sudo apt-get update - sudo apt-get install -y rclone - rclone copy "$SOURCE_DIR" R2:bazzite diff --git a/.github/workflows/validate-installer-iso.yml b/.github/workflows/validate-installer-iso.yml new file mode 100644 index 0000000..37f5496 --- /dev/null +++ b/.github/workflows/validate-installer-iso.yml @@ -0,0 +1,40 @@ +name: Validate installer ISO + +on: + pull_request: + paths: + - "Justfile" + - "installer/**" + - "just_scripts/build-installer-iso.sh" + - ".github/workflows/build-installer-iso.yml" + - ".github/workflows/validate-installer-iso.yml" + +permissions: + contents: read + +jobs: + validate-installer-iso: + name: Validate installer ISO inputs + runs-on: ubuntu-24.04 + + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + + - name: Install just + uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 + + - name: Validate workflow YAML + run: | + ruby -e 'require "yaml"; Dir[".github/workflows/*.yml"].each { |file| YAML.load_file(file) }' + + - name: Validate Justfile formatting + run: | + just --unstable --fmt --check -f Justfile + + - name: Validate build scripts + run: | + for script in build_files/*.sh installer/*.sh just_scripts/*.sh; do + bash -n "$script" + done + bash -n system_files/usr/libexec/aerocore-instruments-setup diff --git a/.github/workflows/validate-live-installer.yml b/.github/workflows/validate-live-installer.yml deleted file mode 100644 index 3d35a5d..0000000 --- a/.github/workflows/validate-live-installer.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Validate live installer - -on: - pull_request: - paths: - - "Justfile" - - "installer/**" - - "just_scripts/build-live-installer.sh" - - ".github/workflows/build-live-installer.yml" - - ".github/workflows/validate-live-installer.yml" - -permissions: - contents: read - -jobs: - validate-live-installer: - name: Validate live installer inputs - runs-on: ubuntu-24.04 - - steps: - - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - - - name: Install just - uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 - - - name: Validate workflow YAML - run: | - ruby -e 'require "yaml"; Dir[".github/workflows/*.yml"].each { |file| YAML.load_file(file) }' - - - name: Validate Justfile formatting - run: | - just --unstable --fmt --check -f Justfile - - - name: Validate build scripts - run: | - for script in build_files/*.sh installer/*.sh just_scripts/*.sh; do - bash -n "$script" - done - bash -n system_files/usr/libexec/aerocore-instruments-setup diff --git a/Justfile b/Justfile index b65d2c9..f77828b 100644 --- a/Justfile +++ b/Justfile @@ -22,20 +22,25 @@ export INSTRUMENTS_RELEASE_API_BASE := env_var_or_default("INSTRUMENTS_RELEASE_A alias build-vm := build-qcow2 alias rebuild-vm := rebuild-qcow2 alias run-vm := run-vm-qcow2 -alias build-live-iso := build-live-installer -alias run-live-iso := run-live-installer +alias build-installer := build-installer-iso +alias run-installer := run-installer-iso +# Backward-compatible aliases; these refer to the installer ISO, not a Live OS. +alias build-live-iso := build-installer-iso +alias run-live-iso := run-installer-iso +alias build-live-installer := build-installer-iso +alias run-live-installer := run-installer-iso [private] default: @just --list -# Build a Bazzite-style live installer ISO -build-live-installer $target_image=("localhost/" + image_name) $tag=default_tag: - @IMAGE_NAME="{{ target_image }}" IMAGE_TAG="{{ tag }}" ./just_scripts/build-live-installer.sh +# Build a Bazzite-style installer ISO +build-installer-iso $target_image=("localhost/" + image_name) $tag=default_tag: + @IMAGE_NAME="{{ target_image }}" IMAGE_TAG="{{ tag }}" ./just_scripts/build-installer-iso.sh -# Boot the live installer ISO with QEMU -run-live-installer: - @./just_scripts/run-live-installer.sh +# Boot the installer ISO with QEMU +run-installer-iso: + @./just_scripts/run-installer-iso.sh # Check Just Syntax [group('Just')] diff --git a/README.md b/README.md index 3fc11c5..de33959 100644 --- a/README.md +++ b/README.md @@ -55,15 +55,15 @@ BASE_IMAGE=ghcr.io/ublue-os/bazzite-deck:testing just build ``` -To build the Bazzite-style live installer locally, first build the AeroCore +To build the Bazzite-style installer ISO locally, first build the AeroCore image and then run: ```bash sudo just build -just build-live-installer -just run-live-installer +just build-installer-iso +just run-installer-iso ``` This requires privileged Podman, a rootful Podman API socket, and roughly -70 GiB of free space. The live installer workflow consumes the published +70 GiB of free space. The installer ISO workflow consumes the published `latest` AeroCore image and uploads the ISO as a GitHub Actions artifact. diff --git a/installer/Containerfile b/installer/Containerfile index 50579e6..34c5e28 100644 --- a/installer/Containerfile +++ b/installer/Containerfile @@ -1,4 +1,4 @@ -# Build the live installer payload from a desktop Bazzite runtime. +# Build the installer ISO payload from a desktop Bazzite runtime. # The image installed to disk is supplied separately as INSTALL_IMAGE_PAYLOAD. ARG BASE_IMAGE=ghcr.io/ublue-os/bazzite:stable diff --git a/installer/iso.yaml b/installer/iso.yaml index 8e6bd73..4b9fd2c 100644 --- a/installer/iso.yaml +++ b/installer/iso.yaml @@ -1,10 +1,10 @@ -label: "AeroCore-Live" +label: "AeroCore-Installer" grub2: timeout: 3 entries: - name: "Launch AeroCore Installer" - linux: "/images/pxeboot/vmlinuz quiet rhgb root=live:CDLABEL=AeroCore-Live enforcing=0 rd.live.image" + linux: "/images/pxeboot/vmlinuz quiet rhgb root=live:CDLABEL=AeroCore-Installer enforcing=0 rd.live.image" initrd: "/images/pxeboot/initrd.img" - name: "Launch AeroCore Installer (Basic Graphics Mode)" - linux: "/images/pxeboot/vmlinuz quiet rhgb root=live:CDLABEL=AeroCore-Live enforcing=0 rd.live.image nomodeset" + linux: "/images/pxeboot/vmlinuz quiet rhgb root=live:CDLABEL=AeroCore-Installer enforcing=0 rd.live.image nomodeset" initrd: "/images/pxeboot/initrd.img" diff --git a/just_scripts/build-installer-iso.sh b/just_scripts/build-installer-iso.sh new file mode 100755 index 0000000..22d14a0 --- /dev/null +++ b/just_scripts/build-installer-iso.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash + +set -euo pipefail + +project_root="$(git rev-parse --show-toplevel)" +cd "${project_root}" + +image_name="${IMAGE_NAME:-localhost/$(just image_name)}" +image_tag="${IMAGE_TAG:-$(just generate-default-tag)}" +live_base_image="${LIVE_BASE_IMAGE:-quay.io/fedora/fedora-kinoite:43}" +installer_builder_image="${INSTALLER_BUILDER_IMAGE:-ghcr.io/jasonn3/build-container-installer:v1.5.0}" +source_image="${image_name}:${image_tag}" +payload="localhost/aerocore-installer-payload:latest" +output_dir="${project_root}/output" +payload_archive="${output_dir}/install-payload.oci" +iso="${output_dir}/aerocore-os-${image_tag}-amd64.iso" +checksum="${iso}-CHECKSUM" +api_socket="${PODMAN_SOCKET:-/run/podman/podman.sock}" +if [[ "${EUID}" -eq 0 ]]; then + podman_cmd=(podman) + socket_test=(test -S "${api_socket}") +else + podman_cmd=(sudo podman) + socket_test=(sudo test -S "${api_socket}") +fi + +if ! "${socket_test[@]}"; then + echo "Podman API socket not found: ${api_socket}" >&2 + echo "Set PODMAN_SOCKET to the rootful Podman socket and retry." >&2 + exit 1 +fi + +ensure_rootful_image() { + local root_image_id user_image_id user_name user_uid copy_tmp + + root_image_id="$("${podman_cmd[@]}" images \ + --filter "reference=${source_image}" \ + --format "{{.ID}}" | head -n1)" + + if [[ -n "${root_image_id}" ]]; then + return 0 + fi + + if [[ "${EUID}" -ne 0 ]]; then + just _rootful_load_image "${image_name}" "${image_tag}" + return + fi + + if [[ -z "${SUDO_USER:-}" ]]; then + return + fi + + user_name="${SUDO_USER}" + user_uid="$(id -u "${user_name}")" + user_image_id="$(sudo -u "${user_name}" \ + env XDG_RUNTIME_DIR="/run/user/${user_uid}" \ + podman images \ + --filter "reference=${source_image}" \ + --format "{{.ID}}" | head -n1)" + + if [[ -z "${user_image_id}" ]]; then + return + fi + + copy_tmp="$(mktemp -p "${project_root}" -d -t _build_podman_scp.XXXXXXXXXX)" + TMPDIR="${copy_tmp}" podman image scp \ + "${user_uid}@localhost::${source_image}" \ + "root@localhost::${source_image}" + rm -rf "${copy_tmp}" +} + +mkdir -p "${output_dir}" +ensure_rootful_image + +"${podman_cmd[@]}" tag "${source_image}" "${payload}" +"${podman_cmd[@]}" save --format oci-archive --output "${payload_archive}" "${payload}" + +"${podman_cmd[@]}" build \ + --cap-add sys_admin \ + --security-opt label=disable \ + --build-arg "BASE_IMAGE=${live_base_image}" \ + --build-arg "INSTALL_IMAGE_PAYLOAD=${payload}" \ + --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ + --tag "${payload}" \ + --file installer/Containerfile \ + . + +if [[ "${EUID}" -eq 0 ]]; then + rm -f "${iso}" "${checksum}" +else + sudo rm -f "${iso}" "${checksum}" +fi + +"${podman_cmd[@]}" run --rm --privileged \ + --volume "${api_socket}:/var/run/docker.sock" \ + --volume /var/lib/containers/storage:/var/lib/containers/storage \ + --volume "${project_root}/output:/build-container-installer/build" \ + --volume "${project_root}/installer/lorax_templates:/additional_lorax_templates:ro" \ + "${installer_builder_image}" \ + ADDITIONAL_TEMPLATES="/additional_lorax_templates/remove_root_password_prompt.tmpl /additional_lorax_templates/set_default_user.tmpl" \ + ARCH="x86_64" \ + ENABLE_CACHE_DNF="false" \ + ENABLE_CACHE_SKOPEO="false" \ + ENABLE_FLATPAK_DEPENDENCIES="false" \ + IMAGE_NAME="aerocore-installer-payload" \ + IMAGE_REPO="localhost" \ + IMAGE_SRC="containers-storage:${payload}" \ + IMAGE_TAG="latest" \ + ISO_NAME="build/aerocore-os-${image_tag}-amd64.iso" \ + VARIANT="Kinoite" \ + VERSION="${FEDORA_VERSION:-44}" + +if [[ -f "${iso}" ]]; then + if [[ "${EUID}" -ne 0 ]]; then + sudo chown "$(id -u):$(id -g)" "${iso}" + sudo rm -f "${checksum}" + (cd "${output_dir}" && sha256sum "$(basename "${iso}")") | sudo tee "${checksum}" + sudo chown "$(id -u):$(id -g)" "${checksum}" + else + (cd "${output_dir}" && sha256sum "$(basename "${iso}")") | tee "${checksum}" + fi +fi diff --git a/just_scripts/build-live-installer.sh b/just_scripts/build-live-installer.sh deleted file mode 100755 index 45335cb..0000000 --- a/just_scripts/build-live-installer.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -project_root="$(git rev-parse --show-toplevel)" -cd "${project_root}" - -image_name="${IMAGE_NAME:-localhost/$(just image_name)}" -image_tag="${IMAGE_TAG:-$(just generate-default-tag)}" -live_base_image="${LIVE_BASE_IMAGE:-quay.io/fedora/fedora-kinoite:43}" -installer_builder_image="${INSTALLER_BUILDER_IMAGE:-ghcr.io/jasonn3/build-container-installer:v1.5.0}" -source_image="${image_name}:${image_tag}" -payload="localhost/aerocore-live-payload:latest" -output_dir="${project_root}/output" -payload_archive="${output_dir}/install-payload.oci" -iso="${output_dir}/aerocore-os-${image_tag}-amd64.iso" -checksum="${iso}-CHECKSUM" -api_socket="${PODMAN_SOCKET:-/run/podman/podman.sock}" -if [[ "${EUID}" -eq 0 ]]; then - podman_cmd=(podman) - socket_test=(test -S "${api_socket}") -else - podman_cmd=(sudo podman) - socket_test=(sudo test -S "${api_socket}") -fi - -if ! "${socket_test[@]}"; then - echo "Podman API socket not found: ${api_socket}" >&2 - echo "Set PODMAN_SOCKET to the rootful Podman socket and retry." >&2 - exit 1 -fi - -ensure_rootful_image() { - local root_image_id user_image_id user_name user_uid copy_tmp - - root_image_id="$("${podman_cmd[@]}" images \ - --filter "reference=${source_image}" \ - --format "{{.ID}}" | head -n1)" - - if [[ -n "${root_image_id}" ]]; then - return 0 - fi - - if [[ "${EUID}" -ne 0 ]]; then - just _rootful_load_image "${image_name}" "${image_tag}" - return - fi - - if [[ -z "${SUDO_USER:-}" ]]; then - return - fi - - user_name="${SUDO_USER}" - user_uid="$(id -u "${user_name}")" - user_image_id="$(sudo -u "${user_name}" \ - env XDG_RUNTIME_DIR="/run/user/${user_uid}" \ - podman images \ - --filter "reference=${source_image}" \ - --format "{{.ID}}" | head -n1)" - - if [[ -z "${user_image_id}" ]]; then - return - fi - - copy_tmp="$(mktemp -p "${project_root}" -d -t _build_podman_scp.XXXXXXXXXX)" - TMPDIR="${copy_tmp}" podman image scp \ - "${user_uid}@localhost::${source_image}" \ - "root@localhost::${source_image}" - rm -rf "${copy_tmp}" -} - -mkdir -p "${output_dir}" -ensure_rootful_image - -"${podman_cmd[@]}" tag "${source_image}" "${payload}" -"${podman_cmd[@]}" save --format oci-archive --output "${payload_archive}" "${payload}" - -"${podman_cmd[@]}" build \ - --cap-add sys_admin \ - --security-opt label=disable \ - --build-arg "BASE_IMAGE=${live_base_image}" \ - --build-arg "INSTALL_IMAGE_PAYLOAD=${payload}" \ - --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ - --tag "${payload}" \ - --file installer/Containerfile \ - . - -if [[ "${EUID}" -eq 0 ]]; then - rm -f "${iso}" "${checksum}" -else - sudo rm -f "${iso}" "${checksum}" -fi - -"${podman_cmd[@]}" run --rm --privileged \ - --volume "${api_socket}:/var/run/docker.sock" \ - --volume /var/lib/containers/storage:/var/lib/containers/storage \ - --volume "${project_root}/output:/build-container-installer/build" \ - --volume "${project_root}/installer/lorax_templates:/additional_lorax_templates:ro" \ - "${installer_builder_image}" \ - ADDITIONAL_TEMPLATES="/additional_lorax_templates/remove_root_password_prompt.tmpl /additional_lorax_templates/set_default_user.tmpl" \ - ARCH="x86_64" \ - ENABLE_CACHE_DNF="false" \ - ENABLE_CACHE_SKOPEO="false" \ - ENABLE_FLATPAK_DEPENDENCIES="false" \ - IMAGE_NAME="aerocore-live-payload" \ - IMAGE_REPO="localhost" \ - IMAGE_SRC="containers-storage:${payload}" \ - IMAGE_TAG="latest" \ - ISO_NAME="build/aerocore-os-${image_tag}-amd64.iso" \ - VARIANT="Kinoite" \ - VERSION="${FEDORA_VERSION:-44}" - -if [[ -f "${iso}" ]]; then - if [[ "${EUID}" -ne 0 ]]; then - sudo chown "$(id -u):$(id -g)" "${iso}" - sudo rm -f "${checksum}" - (cd "${output_dir}" && sha256sum "$(basename "${iso}")") | sudo tee "${checksum}" - sudo chown "$(id -u):$(id -g)" "${checksum}" - else - (cd "${output_dir}" && sha256sum "$(basename "${iso}")") | tee "${checksum}" - fi -fi diff --git a/just_scripts/run-installer-iso.sh b/just_scripts/run-installer-iso.sh new file mode 100755 index 0000000..2c49164 --- /dev/null +++ b/just_scripts/run-installer-iso.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -euo pipefail + +project_root="$(git rev-parse --show-toplevel)" +cd "${project_root}" + +image_tag="${IMAGE_TAG:-$(just generate-default-tag)}" +iso="${project_root}/output/aerocore-os-${image_tag}-amd64.iso" + +if [[ ! -f "${iso}" ]]; then + just build-installer-iso +fi + +podman run --rm --cap-add NET_ADMIN \ + --publish 127.0.0.1:8006:8006 \ + --env CPU_CORES=2 \ + --env RAM_SIZE=4G \ + --env DISK_SIZE=64G \ + --env BOOT_MODE=uefi \ + --device /dev/kvm \ + --volume "${iso}:/boot.iso:ro" \ + docker.io/qemux/qemu-docker diff --git a/just_scripts/run-live-installer.sh b/just_scripts/run-live-installer.sh deleted file mode 100755 index 2723aae..0000000 --- a/just_scripts/run-live-installer.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -project_root="$(git rev-parse --show-toplevel)" -cd "${project_root}" - -image_tag="${IMAGE_TAG:-$(just generate-default-tag)}" -iso="${project_root}/output/aerocore-os-${image_tag}-amd64.iso" - -if [[ ! -f "${iso}" ]]; then - just build-live-installer -fi - -podman run --rm --cap-add NET_ADMIN \ - --publish 127.0.0.1:8006:8006 \ - --env CPU_CORES=2 \ - --env RAM_SIZE=4G \ - --env DISK_SIZE=64G \ - --env BOOT_MODE=uefi \ - --device /dev/kvm \ - --volume "${iso}:/boot.iso:ro" \ - docker.io/qemux/qemu-docker -- cgit v1.2.3 From c6f883fddfb19b906dee32b675bf5af4efd637ba Mon Sep 17 00:00:00 2001 From: tranch Date: Fri, 24 Jul 2026 18:58:16 +0800 Subject: Lock installer default account password --- installer/lorax_templates/set_default_user.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer/lorax_templates/set_default_user.tmpl b/installer/lorax_templates/set_default_user.tmpl index b4cf2c8..c20736f 100644 --- a/installer/lorax_templates/set_default_user.tmpl +++ b/installer/lorax_templates/set_default_user.tmpl @@ -1 +1 @@ -append usr/share/anaconda/interactive-defaults.ks "\\nuser --name=aerocore --password=aerocore --plaintext --groups=wheel" +append usr/share/anaconda/interactive-defaults.ks "\\nuser --name=aerocore --lock --groups=wheel" -- cgit v1.2.3 From 186ad337f32b93bb94676040129e3b8fba0ac879 Mon Sep 17 00:00:00 2001 From: tranch Date: Sat, 25 Jul 2026 04:41:50 +0800 Subject: Use target var tmp during installer deploy Bind the live installer's /var/tmp to the mounted target system in the pre-install phase so ostreecontainer can stage image layers on target disk space instead of the tiny LiveOS rootfs. --- installer/lorax_templates/use_target_var_tmp.tmpl | 1 + just_scripts/build-installer-iso.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 installer/lorax_templates/use_target_var_tmp.tmpl diff --git a/installer/lorax_templates/use_target_var_tmp.tmpl b/installer/lorax_templates/use_target_var_tmp.tmpl new file mode 100644 index 0000000..2d099d1 --- /dev/null +++ b/installer/lorax_templates/use_target_var_tmp.tmpl @@ -0,0 +1 @@ +append usr/share/anaconda/interactive-defaults.ks "\n%pre-install --log=/tmp/aerocore-var-tmp.log\nset -eux\ntarget_tmp=\nfor root in /mnt/sysimage /mnt/sysroot /var/mnt/sysimage; do\n if mountpoint -q ${root}; then\n target_tmp=${root}/var/tmp\n break\n fi\ndone\nif [ x${target_tmp} = x ]; then\n echo No mounted target system found for /var/tmp bind mount >&2\n exit 1\nfi\nmkdir -p ${target_tmp}\nchmod 1777 ${target_tmp}\nmount --bind ${target_tmp} /var/tmp\ndf -h /var/tmp ${target_tmp}\n%end" diff --git a/just_scripts/build-installer-iso.sh b/just_scripts/build-installer-iso.sh index 22d14a0..5c9e9eb 100755 --- a/just_scripts/build-installer-iso.sh +++ b/just_scripts/build-installer-iso.sh @@ -97,7 +97,7 @@ fi --volume "${project_root}/output:/build-container-installer/build" \ --volume "${project_root}/installer/lorax_templates:/additional_lorax_templates:ro" \ "${installer_builder_image}" \ - ADDITIONAL_TEMPLATES="/additional_lorax_templates/remove_root_password_prompt.tmpl /additional_lorax_templates/set_default_user.tmpl" \ + ADDITIONAL_TEMPLATES="/additional_lorax_templates/remove_root_password_prompt.tmpl /additional_lorax_templates/set_default_user.tmpl /additional_lorax_templates/use_target_var_tmp.tmpl" \ ARCH="x86_64" \ ENABLE_CACHE_DNF="false" \ ENABLE_CACHE_SKOPEO="false" \ -- cgit v1.2.3 From b5d70a402fe9ff18aeaa3ba1e213133eef2664d5 Mon Sep 17 00:00:00 2001 From: tranch Date: Sat, 25 Jul 2026 04:55:42 +0800 Subject: Brand installer live session icons Install AeroCore icon aliases for the live KDE launcher and replace Anaconda's installer icon in the hicolor theme. --- installer/build.sh | 39 ++++++++++++++++++++++ .../apps/org.fedoraproject.AnacondaInstaller.svg | 33 ++++++++++++++++++ .../apps/org.fedoraproject.AnacondaInstaller.svg | 33 ++++++++++++++++++ ...rg.fedoraproject.AnacondaInstaller-symbolic.svg | 13 ++++++++ 4 files changed, 118 insertions(+) create mode 100644 installer/system_files/overrides/usr/share/icons/hicolor/48x48/apps/org.fedoraproject.AnacondaInstaller.svg create mode 100644 installer/system_files/overrides/usr/share/icons/hicolor/scalable/apps/org.fedoraproject.AnacondaInstaller.svg create mode 100644 installer/system_files/overrides/usr/share/icons/hicolor/symbolic/apps/org.fedoraproject.AnacondaInstaller-symbolic.svg diff --git a/installer/build.sh b/installer/build.sh index f9eb210..c8ac830 100755 --- a/installer/build.sh +++ b/installer/build.sh @@ -39,6 +39,45 @@ if [[ -d "${BRANDING_DIR}" ]]; then cp -a "${BRANDING_DIR}/." /usr/share/anaconda/pixmaps/ fi +# Installer-only overrides, kept separate from the installed AeroCore payload. +if [[ -d "${SCRIPT_DIR}/system_files/overrides" ]]; then + cp -a "${SCRIPT_DIR}/system_files/overrides/." / +fi + +# Plasma's live-session launcher defaults to start-here, and Fedora keeps +# LOGO=fedora-logo-icon in the base live environment. +for size in 16x16 22x22 24x24 32x32 36x36 48x48 64x64 96x96 128x128 256x256; do + icon_dir="/usr/share/icons/hicolor/${size}" + if [[ -f "${icon_dir}/bazzite-logo-icon.png" ]]; then + mkdir -p "${icon_dir}/apps" "${icon_dir}/places" + cp -f "${icon_dir}/bazzite-logo-icon.png" "${icon_dir}/apps/fedora-logo-icon.png" + cp -f "${icon_dir}/bazzite-logo-icon.png" "${icon_dir}/places/start-here.png" + fi +done + +if [[ -f /usr/share/icons/hicolor/scalable/places/distributor-logo.svg ]]; then + mkdir -p /usr/share/icons/hicolor/scalable/apps /usr/share/icons/hicolor/scalable/places + cp -f /usr/share/icons/hicolor/scalable/places/distributor-logo.svg \ + /usr/share/icons/hicolor/scalable/apps/start-here.svg + cp -f /usr/share/icons/hicolor/scalable/places/distributor-logo.svg \ + /usr/share/icons/hicolor/scalable/places/start-here.svg +fi + +sed -i 's/^LOGO=.*/LOGO=distributor-logo/' /usr/lib/os-release + +for desktop_file in \ + /usr/share/applications/liveinst.desktop \ + /usr/share/applications/org.fedoraproject.AnacondaInstaller.desktop \ + /usr/share/applications/anaconda.desktop; do + if [[ -f "${desktop_file}" ]]; then + sed -i 's/^Icon=.*/Icon=org.fedoraproject.AnacondaInstaller/' "${desktop_file}" + fi +done + +if command -v gtk-update-icon-cache >/dev/null 2>&1; then + gtk-update-icon-cache -f /usr/share/icons/hicolor || true +fi + # Make the install payload available to Anaconda. if [[ -n "${INSTALL_IMAGE_PAYLOAD_ARCHIVE}" && -f "${INSTALL_IMAGE_PAYLOAD_ARCHIVE}" ]]; then podman load --storage-opt additionalimagestore='' < "${INSTALL_IMAGE_PAYLOAD_ARCHIVE}" diff --git a/installer/system_files/overrides/usr/share/icons/hicolor/48x48/apps/org.fedoraproject.AnacondaInstaller.svg b/installer/system_files/overrides/usr/share/icons/hicolor/48x48/apps/org.fedoraproject.AnacondaInstaller.svg new file mode 100644 index 0000000..04454b7 --- /dev/null +++ b/installer/system_files/overrides/usr/share/icons/hicolor/48x48/apps/org.fedoraproject.AnacondaInstaller.svg @@ -0,0 +1,33 @@ + + + aerocore-installer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/installer/system_files/overrides/usr/share/icons/hicolor/scalable/apps/org.fedoraproject.AnacondaInstaller.svg b/installer/system_files/overrides/usr/share/icons/hicolor/scalable/apps/org.fedoraproject.AnacondaInstaller.svg new file mode 100644 index 0000000..04454b7 --- /dev/null +++ b/installer/system_files/overrides/usr/share/icons/hicolor/scalable/apps/org.fedoraproject.AnacondaInstaller.svg @@ -0,0 +1,33 @@ + + + aerocore-installer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/installer/system_files/overrides/usr/share/icons/hicolor/symbolic/apps/org.fedoraproject.AnacondaInstaller-symbolic.svg b/installer/system_files/overrides/usr/share/icons/hicolor/symbolic/apps/org.fedoraproject.AnacondaInstaller-symbolic.svg new file mode 100644 index 0000000..f8dedad --- /dev/null +++ b/installer/system_files/overrides/usr/share/icons/hicolor/symbolic/apps/org.fedoraproject.AnacondaInstaller-symbolic.svg @@ -0,0 +1,13 @@ + + + aerocore-installer-symbolic + + + + + + + + + + -- cgit v1.2.3 From 1861c67458ea2a00ad1937ea43dcdfb87026da55 Mon Sep 17 00:00:00 2001 From: tranch Date: Sat, 25 Jul 2026 07:14:05 +0800 Subject: Apply var tmp fix in installer payload Write the pre-install /var/tmp bind mount hook from installer/build.sh so both Titanoboa CI builds and local ISO builds carry the fix. The previous lorax template path was only wired through the local helper and did not affect GitHub Actions. --- installer/build.sh | 19 +++++++++++++++++++ installer/lorax_templates/use_target_var_tmp.tmpl | 1 - just_scripts/build-installer-iso.sh | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) delete mode 100644 installer/lorax_templates/use_target_var_tmp.tmpl diff --git a/installer/build.sh b/installer/build.sh index c8ac830..aa30f42 100755 --- a/installer/build.sh +++ b/installer/build.sh @@ -91,6 +91,25 @@ fi # Tell Anaconda to install the bootc container that was loaded above. mkdir -p /var/lib/rpm-state cat >> /usr/share/anaconda/interactive-defaults.ks <&2 + exit 1 +fi +mkdir -p \${target_tmp} +chmod 1777 \${target_tmp} +mount --bind \${target_tmp} /var/tmp +df -h /var/tmp \${target_tmp} +%end + ostreecontainer --url=${INSTALL_IMAGE_PAYLOAD} --transport=containers-storage --no-signature-verification EOF diff --git a/installer/lorax_templates/use_target_var_tmp.tmpl b/installer/lorax_templates/use_target_var_tmp.tmpl deleted file mode 100644 index 2d099d1..0000000 --- a/installer/lorax_templates/use_target_var_tmp.tmpl +++ /dev/null @@ -1 +0,0 @@ -append usr/share/anaconda/interactive-defaults.ks "\n%pre-install --log=/tmp/aerocore-var-tmp.log\nset -eux\ntarget_tmp=\nfor root in /mnt/sysimage /mnt/sysroot /var/mnt/sysimage; do\n if mountpoint -q ${root}; then\n target_tmp=${root}/var/tmp\n break\n fi\ndone\nif [ x${target_tmp} = x ]; then\n echo No mounted target system found for /var/tmp bind mount >&2\n exit 1\nfi\nmkdir -p ${target_tmp}\nchmod 1777 ${target_tmp}\nmount --bind ${target_tmp} /var/tmp\ndf -h /var/tmp ${target_tmp}\n%end" diff --git a/just_scripts/build-installer-iso.sh b/just_scripts/build-installer-iso.sh index 5c9e9eb..22d14a0 100755 --- a/just_scripts/build-installer-iso.sh +++ b/just_scripts/build-installer-iso.sh @@ -97,7 +97,7 @@ fi --volume "${project_root}/output:/build-container-installer/build" \ --volume "${project_root}/installer/lorax_templates:/additional_lorax_templates:ro" \ "${installer_builder_image}" \ - ADDITIONAL_TEMPLATES="/additional_lorax_templates/remove_root_password_prompt.tmpl /additional_lorax_templates/set_default_user.tmpl /additional_lorax_templates/use_target_var_tmp.tmpl" \ + ADDITIONAL_TEMPLATES="/additional_lorax_templates/remove_root_password_prompt.tmpl /additional_lorax_templates/set_default_user.tmpl" \ ARCH="x86_64" \ ENABLE_CACHE_DNF="false" \ ENABLE_CACHE_SKOPEO="false" \ -- cgit v1.2.3 From 9bb1a2bb2fdce598e551d1a53c4cb977870f3157 Mon Sep 17 00:00:00 2001 From: tranch Date: Sat, 25 Jul 2026 07:39:18 +0800 Subject: Disable automatic installer ISO builds Remove the workflow_run trigger from the installer ISO workflow while ISO construction is being tested manually. Keep workflow_dispatch and workflow_call available. --- .github/workflows/build-installer-iso.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/build-installer-iso.yml b/.github/workflows/build-installer-iso.yml index cfa7b80..bae0458 100644 --- a/.github/workflows/build-installer-iso.yml +++ b/.github/workflows/build-installer-iso.yml @@ -9,13 +9,6 @@ on: default: latest type: string workflow_call: - workflow_run: - workflows: - - Build container image - types: - - completed - branches: - - main permissions: {} @@ -26,7 +19,6 @@ concurrency: jobs: build-installer-iso: name: Build KDE installer ISO - if: github.event_name != 'workflow_run' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push') runs-on: ubuntu-24.04 permissions: contents: read -- cgit v1.2.3 From 9c32f16d4c982559e1982454d2ee155e0f2efa48 Mon Sep 17 00:00:00 2001 From: tranch Date: Sat, 25 Jul 2026 09:30:11 +0800 Subject: Preserve Deck runtime checks for AeroCore Patch Bazzite Steam and user setup scripts to recognize aerocore-os as a Deck image, keeping Steam bootstrap and gamescope-related initialization active after rebranding. --- build_files/patch-bazzite-deck-identity.sh | 107 ++++++++++++++++++++++------- 1 file changed, 82 insertions(+), 25 deletions(-) diff --git a/build_files/patch-bazzite-deck-identity.sh b/build_files/patch-bazzite-deck-identity.sh index 078b76c..05b6e5f 100755 --- a/build_files/patch-bazzite-deck-identity.sh +++ b/build_files/patch-bazzite-deck-identity.sh @@ -2,34 +2,91 @@ set -euo pipefail -hardware_setup="${1:-/usr/libexec/bazzite-hardware-setup}" -# These are literal source lines; variable expansion must happen at boot time. -# shellcheck disable=SC2016 -old_condition='if [[ "$IMAGE_NAME" != *deck* && "$IMAGE_NAME" != *dx* ]]; then' -# shellcheck disable=SC2016 -new_condition='if [[ "$IMAGE_NAME" != aerocore-os && "$IMAGE_NAME" != *deck* && "$IMAGE_NAME" != *dx* ]]; then' +root="${AEROCORE_DECK_COMPAT_ROOT:-}" +root="${root%/}" + +target_path() { + printf '%s%s\n' "$root" "$1" +} + +patch_condition() { + local file="$1" + local old_condition="$2" + local new_condition="$3" + local expected_count="$4" + local old_count new_count patched_file + + if [[ ! -f "$file" ]]; then + echo "Unable to locate expected Bazzite Deck file: $file" >&2 + exit 1 + fi + + new_count="$(grep -Foc "$new_condition" "$file" || true)" + if [[ "$new_count" -eq "$expected_count" ]]; then + return 0 + fi -if grep -Fqx "$new_condition" "$hardware_setup"; then - exit 0 -fi + old_count="$(grep -Foc "$old_condition" "$file" || true)" + if [[ "$old_count" -ne "$expected_count" ]]; then + echo "Unable to locate the expected Bazzite Deck image check in $file" >&2 + echo "Expected $expected_count occurrence(s), found old=$old_count new=$new_count" >&2 + exit 1 + fi -if [[ "$(grep -Fxc "$old_condition" "$hardware_setup")" -ne 1 ]]; then - echo "Unable to locate the Bazzite Deck image check in $hardware_setup" >&2 - exit 1 -fi + patched_file="$(mktemp)" + awk \ + -v old_condition="$old_condition" \ + -v new_condition="$new_condition" \ + ' { + position = index($0, old_condition) + if (position) { + $0 = substr($0, 1, position - 1) new_condition substr($0, position + length(old_condition)) + } + print + }' "$file" > "$patched_file" -patched_file=$(mktemp) -trap 'rm -f "$patched_file"' EXIT + cp "$patched_file" "$file" + rm -f "$patched_file" -awk \ - -v old_condition="$old_condition" \ - -v new_condition="$new_condition" \ - '$0 == old_condition { - print new_condition - next - } - { print }' "$hardware_setup" > "$patched_file" + new_count="$(grep -Foc "$new_condition" "$file" || true)" + if [[ "$new_count" -ne "$expected_count" ]]; then + echo "Failed to patch the Bazzite Deck image check in $file" >&2 + exit 1 + fi +} -cp "$patched_file" "$hardware_setup" +# Keep AeroCore's public image-name, while restoring the Deck capability checks +# used by Bazzite's runtime scripts. These are literal source lines; variable +# expansion must happen later, when the scripts run on the installed system. +# shellcheck disable=SC2016 +patch_condition \ + "${1:-$(target_path /usr/libexec/bazzite-hardware-setup)}" \ + 'if [[ "$IMAGE_NAME" != *deck* && "$IMAGE_NAME" != *dx* ]]; then' \ + 'if [[ "$IMAGE_NAME" != aerocore-os && "$IMAGE_NAME" != *deck* && "$IMAGE_NAME" != *dx* ]]; then' \ + 1 + +# The hardware setup has a second Deck-only block after the top-level image +# guard. Keep it active for AeroCore as well. +# shellcheck disable=SC2016 +patch_condition \ + "${1:-$(target_path /usr/libexec/bazzite-hardware-setup)}" \ + 'if [[ $IMAGE_NAME =~ "deck" || $IMAGE_NAME =~ "ally" ]]; then' \ + 'if [[ $IMAGE_NAME =~ "deck" || $IMAGE_NAME =~ "ally" || $IMAGE_NAME == aerocore-os ]]; then' \ + 1 -grep -Fqx "$new_condition" "$hardware_setup" +# bazzite-steam gates the Steam bootstrap archive and -steamdeck flag on the +# image name. The user setup script has the same Deck-only gating in three +# places. +# shellcheck disable=SC2016 +patch_condition \ + "$(target_path /usr/bin/bazzite-steam)" \ + 'if [[ $IMAGE_NAME =~ "deck" ]]; then' \ + 'if [[ $IMAGE_NAME =~ "deck" || $IMAGE_NAME == aerocore-os ]]; then' \ + 1 + +# shellcheck disable=SC2016 +patch_condition \ + "$(target_path /usr/libexec/bazzite-user-setup)" \ + 'if [[ $IMAGE_NAME =~ "deck" || $IMAGE_NAME =~ "ally" ]]; then' \ + 'if [[ $IMAGE_NAME =~ "deck" || $IMAGE_NAME =~ "ally" || $IMAGE_NAME == aerocore-os ]]; then' \ + 3 -- cgit v1.2.3 From b4ce9b4030ed04a575466890d5caed9216f166a6 Mon Sep 17 00:00:00 2001 From: tranch Date: Sat, 25 Jul 2026 09:57:45 +0800 Subject: Normalize installer payload and host naming Use a formal local installer image tag and set aerocore-os as the default hostname in both the live image and installed target system. --- .github/workflows/build-installer-iso.yml | 6 +++--- build_files/image-info | 2 +- installer/Containerfile | 2 +- installer/build.sh | 18 +++++++++++++++++- just_scripts/build-installer-iso.sh | 4 ++-- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-installer-iso.yml b/.github/workflows/build-installer-iso.yml index bae0458..7650ebb 100644 --- a/.github/workflows/build-installer-iso.yml +++ b/.github/workflows/build-installer-iso.yml @@ -74,7 +74,7 @@ jobs: mkdir -p output sudo podman tag \ "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" \ - localhost/aerocore-installer-payload:latest + localhost/aerocore-os-installer:latest sudo podman save \ --format oci-archive \ --output output/install-payload.oci \ @@ -86,7 +86,7 @@ jobs: --build-arg "BASE_IMAGE=${LIVE_BASE_IMAGE}" \ --build-arg "INSTALL_IMAGE_PAYLOAD=localhost/aerocore-installer-payload:latest" \ --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ - --tag localhost/aerocore-installer-payload:latest \ + --tag localhost/aerocore-os-installer:latest \ --file installer/Containerfile \ . @@ -94,7 +94,7 @@ jobs: id: build uses: Zeglius/titanoboa@7737f4748458252ac827dca14b3d6dd09298472a # revamp-pr with: - image-ref: localhost/aerocore-installer-payload:latest + image-ref: localhost/aerocore-os-installer:latest iso-dest: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-amd64.iso - name: Normalize ISO output path diff --git a/build_files/image-info b/build_files/image-info index a52d666..bd66383 100755 --- a/build_files/image-info +++ b/build_files/image-info @@ -49,7 +49,7 @@ sed -i "s|^DOCUMENTATION_URL=.*|DOCUMENTATION_URL=\"$DOCUMENTATION_URL\"|" /usr/ sed -i "s|^SUPPORT_URL=.*|SUPPORT_URL=\"$SUPPORT_URL\"|" /usr/lib/os-release sed -i "s|^BUG_REPORT_URL=.*|BUG_REPORT_URL=\"$BUG_SUPPORT_URL\"|" /usr/lib/os-release sed -i "s|^CPE_NAME=.*|CPE_NAME=\"cpe:/o:universal-blue:$IMAGE_ID\"|" /usr/lib/os-release -sed -i "s/^DEFAULT_HOSTNAME=.*/DEFAULT_HOSTNAME=\"$IMAGE_ID\"/" /usr/lib/os-release +sed -i "s/^DEFAULT_HOSTNAME=.*/DEFAULT_HOSTNAME=\"$IMAGE_NAME\"/" /usr/lib/os-release sed -i "s/^ID=fedora/ID=$IMAGE_ID\nID_LIKE=\"$IMAGE_LIKE\"/" /usr/lib/os-release sed -i "s/^LOGO=.*/LOGO=$LOGO_ICON/" /usr/lib/os-release sed -i "s/^ANSI_COLOR=.*/ANSI_COLOR=\"$LOGO_COLOR\"/" /usr/lib/os-release diff --git a/installer/Containerfile b/installer/Containerfile index 34c5e28..fa5d731 100644 --- a/installer/Containerfile +++ b/installer/Containerfile @@ -2,7 +2,7 @@ # The image installed to disk is supplied separately as INSTALL_IMAGE_PAYLOAD. ARG BASE_IMAGE=ghcr.io/ublue-os/bazzite:stable -ARG INSTALL_IMAGE_PAYLOAD=ghcr.io/AeroCore-IO/aerocore-bazzite-image:stable +ARG INSTALL_IMAGE_PAYLOAD=ghcr.io/AeroCore-IO/aerocore-os:stable ARG INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci FROM ${BASE_IMAGE} diff --git a/installer/build.sh b/installer/build.sh index aa30f42..c119dcc 100755 --- a/installer/build.sh +++ b/installer/build.sh @@ -111,6 +111,22 @@ df -h /var/tmp \${target_tmp} %end ostreecontainer --url=${INSTALL_IMAGE_PAYLOAD} --transport=containers-storage --no-signature-verification + +%post --nochroot --log=/tmp/aerocore-hostname.log +set -eux +target_root= +for root in /mnt/sysroot /mnt/sysimage /var/mnt/sysimage; do + if mountpoint -q \${root}; then + target_root=\${root} + break + fi +done +if [ x\${target_root} = x ]; then + echo No mounted target system found for hostname setup >&2 + exit 1 +fi +systemd-firstboot --root=\${target_root} --hostname=aerocore-os +%end EOF mkdir -p /usr/lib/bootc-image-builder @@ -146,5 +162,5 @@ mkdir -p /boot/efi/EFI/BOOT cp -v "${grubx64}" /boot/efi/EFI/BOOT/BOOTX64.EFI cp -v "${grubx64}" /boot/efi/EFI/BOOT/fbx64.efi -systemd-firstboot --timezone UTC +systemd-firstboot --hostname aerocore-os --timezone UTC dnf clean all diff --git a/just_scripts/build-installer-iso.sh b/just_scripts/build-installer-iso.sh index 22d14a0..38e1718 100755 --- a/just_scripts/build-installer-iso.sh +++ b/just_scripts/build-installer-iso.sh @@ -10,7 +10,7 @@ image_tag="${IMAGE_TAG:-$(just generate-default-tag)}" live_base_image="${LIVE_BASE_IMAGE:-quay.io/fedora/fedora-kinoite:43}" installer_builder_image="${INSTALLER_BUILDER_IMAGE:-ghcr.io/jasonn3/build-container-installer:v1.5.0}" source_image="${image_name}:${image_tag}" -payload="localhost/aerocore-installer-payload:latest" +payload="localhost/aerocore-os-installer:latest" output_dir="${project_root}/output" payload_archive="${output_dir}/install-payload.oci" iso="${output_dir}/aerocore-os-${image_tag}-amd64.iso" @@ -102,7 +102,7 @@ fi ENABLE_CACHE_DNF="false" \ ENABLE_CACHE_SKOPEO="false" \ ENABLE_FLATPAK_DEPENDENCIES="false" \ - IMAGE_NAME="aerocore-installer-payload" \ + IMAGE_NAME="aerocore-os-installer" \ IMAGE_REPO="localhost" \ IMAGE_SRC="containers-storage:${payload}" \ IMAGE_TAG="latest" \ -- cgit v1.2.3 From f781cc79dd7ff34a72756b10cc02bd086ac6c734 Mon Sep 17 00:00:00 2001 From: tranch Date: Sat, 25 Jul 2026 10:13:57 +0800 Subject: Fix stale installer payload references --- .github/workflows/build-installer-iso.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-installer-iso.yml b/.github/workflows/build-installer-iso.yml index 7650ebb..f7897b9 100644 --- a/.github/workflows/build-installer-iso.yml +++ b/.github/workflows/build-installer-iso.yml @@ -78,13 +78,13 @@ jobs: sudo podman save \ --format oci-archive \ --output output/install-payload.oci \ - localhost/aerocore-installer-payload:latest + localhost/aerocore-os-installer:latest sudo podman build \ --cap-add sys_admin \ --security-opt label=disable \ --build-arg "BASE_IMAGE=${LIVE_BASE_IMAGE}" \ - --build-arg "INSTALL_IMAGE_PAYLOAD=localhost/aerocore-installer-payload:latest" \ + --build-arg "INSTALL_IMAGE_PAYLOAD=localhost/aerocore-os-installer:latest" \ --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ --tag localhost/aerocore-os-installer:latest \ --file installer/Containerfile \ -- cgit v1.2.3 From 8d0b3dc8a0ccd4509399640bd205c3c611a9d5ed Mon Sep 17 00:00:00 2001 From: tranch Date: Sat, 25 Jul 2026 18:15:12 +0800 Subject: Repair stale Steam user state --- build_files/patch-bazzite-deck-identity.sh | 57 ++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/build_files/patch-bazzite-deck-identity.sh b/build_files/patch-bazzite-deck-identity.sh index 05b6e5f..ea561e4 100755 --- a/build_files/patch-bazzite-deck-identity.sh +++ b/build_files/patch-bazzite-deck-identity.sh @@ -55,6 +55,61 @@ patch_condition() { fi } +patch_steam_state_migration() { + local file="$1" + # shellcheck disable=SC2016 + local condition='if [[ $IMAGE_NAME =~ "deck" || $IMAGE_NAME == aerocore-os ]]; then' + local marker='AeroCore Steam state migration' + local patched_file + + if [[ ! -f "$file" ]]; then + echo "Unable to locate expected Bazzite Deck file: $file" >&2 + exit 1 + fi + + if grep -Fq "$marker" "$file"; then + return 0 + fi + + if [[ "$(grep -Foc "$condition" "$file" || true)" -ne 1 ]]; then + echo "Unable to locate the AeroCore Steam bootstrap condition in $file" >&2 + exit 1 + fi + + patched_file="$(mktemp)" + awk -v condition="$condition" ' + !inserted && $0 == condition { + print + print " # AeroCore Steam state migration" + print " # Older AeroCore images could leave ~/.steam/steam as a directory." + print " # Preserve it before restoring the symlink expected by Steam." + print " STEAM_DATA_HOME=\"$HOME/.local/share/Steam\"" + print " STEAM_DATA_LINK=\"$HOME/.steam/steam\"" + print " if [[ -d \"$STEAM_DATA_LINK\" && ! -L \"$STEAM_DATA_LINK\" && -x \"$STEAM_DATA_HOME/steam.sh\" ]]; then" + print " STEAM_DATA_BACKUP=\"${STEAM_DATA_LINK}.aerocore-backup-$(date +%s)-$$\"" + print " STEAM_DATA_TEMP=\"${STEAM_DATA_LINK}.aerocore-link-$$\"" + print " if ln -s \"$STEAM_DATA_HOME\" \"$STEAM_DATA_TEMP\" && mv -- \"$STEAM_DATA_LINK\" \"$STEAM_DATA_BACKUP\" && mv -- \"$STEAM_DATA_TEMP\" \"$STEAM_DATA_LINK\"; then" + print " :" + print " else" + print " rm -f -- \"$STEAM_DATA_TEMP\"" + print " fi" + print " fi" + inserted=1 + next + } + { print } + END { if (!inserted) exit 1 } + ' "$file" > "$patched_file" + + cp "$patched_file" "$file" + rm -f "$patched_file" + + if ! grep -Fq "$marker" "$file"; then + echo "Failed to add the AeroCore Steam state migration to $file" >&2 + exit 1 + fi +} + # Keep AeroCore's public image-name, while restoring the Deck capability checks # used by Bazzite's runtime scripts. These are literal source lines; variable # expansion must happen later, when the scripts run on the installed system. @@ -84,6 +139,8 @@ patch_condition \ 'if [[ $IMAGE_NAME =~ "deck" || $IMAGE_NAME == aerocore-os ]]; then' \ 1 +patch_steam_state_migration "$(target_path /usr/bin/bazzite-steam)" + # shellcheck disable=SC2016 patch_condition \ "$(target_path /usr/libexec/bazzite-user-setup)" \ -- cgit v1.2.3 From b2e56858143df73d1f659b44a16939c3eb761d22 Mon Sep 17 00:00:00 2001 From: tranch Date: Sat, 25 Jul 2026 22:49:06 +0800 Subject: Route installer updates through OSTREE_IMAGE_REF Use the configured ref for ISO boot origins and derive GHCR fallbacks from the current repository instead of hardcoding the image path. --- .github/workflows/build-installer-iso.yml | 11 ++++++++--- Justfile | 1 + installer/Containerfile | 6 +++++- just_scripts/build-installer-iso.sh | 11 ++++++++++- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-installer-iso.yml b/.github/workflows/build-installer-iso.yml index f7897b9..a6348aa 100644 --- a/.github/workflows/build-installer-iso.yml +++ b/.github/workflows/build-installer-iso.yml @@ -31,6 +31,7 @@ jobs: # Keep these aligned with the Fedora major used by the target bazzite-deck base image. LIVE_BASE_IMAGE: quay.io/fedora/fedora-kinoite:43 FEDORA_VERSION: "43" + OSTREE_IMAGE_REF: ${{ vars.OSTREE_IMAGE_REF }} steps: - name: Maximize build space @@ -72,19 +73,23 @@ jobs: - name: Build installer ISO payload run: | mkdir -p output + ostree_image_ref="${OSTREE_IMAGE_REF:-ostree-image-signed:docker://${IMAGE_REGISTRY}/${IMAGE_NAME}}" + install_image_ref="${ostree_image_ref#ostree-image-signed:docker://}" + install_image_ref="${install_image_ref#ostree-unverified-registry:docker://}" + install_image_ref="${install_image_ref#docker://}" sudo podman tag \ "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" \ - localhost/aerocore-os-installer:latest + "${install_image_ref}:${IMAGE_TAG}" sudo podman save \ --format oci-archive \ --output output/install-payload.oci \ - localhost/aerocore-os-installer:latest + "${install_image_ref}:${IMAGE_TAG}" sudo podman build \ --cap-add sys_admin \ --security-opt label=disable \ --build-arg "BASE_IMAGE=${LIVE_BASE_IMAGE}" \ - --build-arg "INSTALL_IMAGE_PAYLOAD=localhost/aerocore-os-installer:latest" \ + --build-arg "INSTALL_IMAGE_PAYLOAD=${install_image_ref}:${IMAGE_TAG}" \ --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ --tag localhost/aerocore-os-installer:latest \ --file installer/Containerfile \ diff --git a/Justfile b/Justfile index f77828b..257ec46 100644 --- a/Justfile +++ b/Justfile @@ -9,6 +9,7 @@ export image_logo_url := env_var("IMAGE_LOGO_URL") export default_tag := env_var("DEFAULT_TAG") export bib_image := env_var("BIB_IMAGE") export BASE_IMAGE := env_var_or_default("BASE_IMAGE", "ghcr.io/ublue-os/bazzite-deck:stable") +export OSTREE_IMAGE_REF := env_var_or_default("OSTREE_IMAGE_REF", "ostree-image-signed:docker://ghcr.io/" + repo_organization + "/" + image_name) export LIVE_BASE_IMAGE := env_var_or_default("LIVE_BASE_IMAGE", "quay.io/fedora/fedora-kinoite:43") export INSTALLER_BUILDER_IMAGE := env_var_or_default("INSTALLER_BUILDER_IMAGE", "ghcr.io/jasonn3/build-container-installer:v1.5.0") export FLATPAK_REMOTE_URL := env_var_or_default("FLATPAK_REMOTE_URL", "") diff --git a/installer/Containerfile b/installer/Containerfile index fa5d731..cf20e4f 100644 --- a/installer/Containerfile +++ b/installer/Containerfile @@ -2,12 +2,16 @@ # The image installed to disk is supplied separately as INSTALL_IMAGE_PAYLOAD. ARG BASE_IMAGE=ghcr.io/ublue-os/bazzite:stable -ARG INSTALL_IMAGE_PAYLOAD=ghcr.io/AeroCore-IO/aerocore-os:stable +ARG IMAGE_VENDOR=AeroCore-IO +ARG IMAGE_NAME=aerocore-os +ARG INSTALL_IMAGE_PAYLOAD=ghcr.io/${IMAGE_VENDOR}/${IMAGE_NAME}:stable ARG INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci FROM ${BASE_IMAGE} ARG BASE_IMAGE +ARG IMAGE_VENDOR +ARG IMAGE_NAME ARG INSTALL_IMAGE_PAYLOAD ARG INSTALL_IMAGE_PAYLOAD_ARCHIVE diff --git a/just_scripts/build-installer-iso.sh b/just_scripts/build-installer-iso.sh index 38e1718..abd668f 100755 --- a/just_scripts/build-installer-iso.sh +++ b/just_scripts/build-installer-iso.sh @@ -10,7 +10,16 @@ image_tag="${IMAGE_TAG:-$(just generate-default-tag)}" live_base_image="${LIVE_BASE_IMAGE:-quay.io/fedora/fedora-kinoite:43}" installer_builder_image="${INSTALLER_BUILDER_IMAGE:-ghcr.io/jasonn3/build-container-installer:v1.5.0}" source_image="${image_name}:${image_tag}" -payload="localhost/aerocore-os-installer:latest" +# Keep the payload in local container storage, but use the public update +# reference as its local tag so Anaconda writes that reference as the boot +# origin instead of persisting the temporary localhost name. OSTREE_IMAGE_REF +# is intentionally tagless, matching the image-info contract. +image_basename="${image_name##*/}" +ostree_image_ref="${OSTREE_IMAGE_REF:-ostree-image-signed:docker://ghcr.io/${REPO_ORGANIZATION:-AeroCore-IO}/${image_basename}}" +install_image_ref="${ostree_image_ref#ostree-image-signed:docker://}" +install_image_ref="${install_image_ref#ostree-unverified-registry:docker://}" +install_image_ref="${install_image_ref#docker://}" +payload="${install_image_ref}:${image_tag}" output_dir="${project_root}/output" payload_archive="${output_dir}/install-payload.oci" iso="${output_dir}/aerocore-os-${image_tag}-amd64.iso" -- cgit v1.2.3 From d79f4397b9658d66b24e16f6c0bc1e64d45cda76 Mon Sep 17 00:00:00 2001 From: tranch Date: Sat, 25 Jul 2026 23:28:23 +0800 Subject: Add branch-aware versioned image tags Generate Fedora/date version tags and publish stable or testing aliases from the corresponding Git branch. --- .github/workflows/build.yml | 58 ++++++++++++++++++++++++++++----------------- Justfile | 5 +++- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 221c735..6a59b2a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,11 +4,13 @@ on: push: branches: - main + - testing pull_request: branches: - main - schedule: - - cron: '05 10 * * *' # 10:05am UTC everyday + - testing + #schedule: + # - cron: '05 10 * * *' # 10:05am UTC everyday workflow_dispatch: env: @@ -74,16 +76,36 @@ jobs: echo "IMAGE_NAME=${IMAGE_NAME}" >> "$GITHUB_ENV" - - name: Default Tag - id: gen-default-tag + - name: Generate Version and Tags + id: gen-version + env: + BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable' }} run: | - if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" && "${GITHUB_REF_NAME}" == "testing" ]]; then - DEFAULT_TAG="testing-$(date -u +%Y%m%d)" + set -euo pipefail + + sudo podman pull "${BASE_IMAGE}" + FEDORA_VERSION=$(sudo podman run --rm --entrypoint /usr/bin/rpm "${BASE_IMAGE}" -E %fedora) + VERSION_BASE="${FEDORA_VERSION}.$(date -u +%Y%m%d)" + + if [[ "${GITHUB_REF_NAME}" == "testing" ]]; then + VERSION_TAG="testing-${VERSION_BASE}" + VERSION_PRETTY="Testing (F${VERSION_BASE})" + IMAGE_BRANCH="testing" + ALIAS_TAGS="${VERSION_TAG} testing testing-${FEDORA_VERSION}" else - DEFAULT_TAG=$(just generate-default-tag) + VERSION_TAG="${VERSION_BASE}" + VERSION_PRETTY="Stable (F${VERSION_BASE})" + IMAGE_BRANCH="stable" + ALIAS_TAGS="${VERSION_TAG} stable-${VERSION_TAG} latest stable stable-${FEDORA_VERSION}" fi - echo "DEFAULT_TAG=${DEFAULT_TAG}" >> "$GITHUB_ENV" + { + echo "DEFAULT_TAG=${VERSION_TAG}" + echo "IMAGE_BRANCH=${IMAGE_BRANCH}" + echo "VERSION_TAG=${VERSION_TAG}" + echo "VERSION_PRETTY=${VERSION_PRETTY}" + echo "ALIAS_TAGS=${ALIAS_TAGS}" + } >> "$GITHUB_ENV" - name: Prepare environment run: | @@ -130,17 +152,9 @@ jobs: - name: Generate Build Tags id: gen-build-tags run: | - if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" && "${GITHUB_REF_NAME}" == "testing" ]]; then - alias_tags="testing ${DEFAULT_TAG}" - else - alias_tags="$(just generate-build-tags \ - "${IMAGE_NAME}" \ - "${DEFAULT_TAG}")" - fi - echo "Tags for this Action..." - echo "${alias_tags}" - echo "alias_tags=${alias_tags}" >> "$GITHUB_OUTPUT" + echo "${ALIAS_TAGS}" + echo "alias_tags=${ALIAS_TAGS}" >> "$GITHUB_OUTPUT" - name: Tag Image id: tag-images @@ -156,14 +170,14 @@ jobs: # They publish default-branch builds and manual testing branch builds. - name: Login to GitHub Container Registry uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0 - if: github.event_name != 'pull_request' && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/testing')) + if: github.event_name != 'pull_request' && (github.ref_name == github.event.repository.default_branch || github.ref_name == 'testing') with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Push To GHCR - if: github.event_name != 'pull_request' && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/testing')) + if: github.event_name != 'pull_request' && (github.ref_name == github.event.repository.default_branch || github.ref_name == 'testing') id: push-image env: ALIAS_TAGS: ${{ steps.gen-build-tags.outputs.alias_tags }} @@ -184,14 +198,14 @@ jobs: # to consume. For more details, review the image signing section of the README. - name: Install Cosign 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) || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/testing')) + if: github.event_name != 'pull_request' && (github.ref_name == github.event.repository.default_branch || github.ref_name == 'testing') # 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) || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/testing')) + if: github.event_name != 'pull_request' && (github.ref_name == github.event.repository.default_branch || github.ref_name == 'testing') env: COSIGN_EXPERIMENTAL: false COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} diff --git a/Justfile b/Justfile index b65d2c9..6bc9957 100644 --- a/Justfile +++ b/Justfile @@ -8,6 +8,9 @@ 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") +export IMAGE_BRANCH := env_var_or_default("IMAGE_BRANCH", "stable") +export VERSION_TAG := env_var_or_default("VERSION_TAG", default_tag) +export VERSION_PRETTY := env_var_or_default("VERSION_PRETTY", VERSION_TAG) export BASE_IMAGE := env_var_or_default("BASE_IMAGE", "ghcr.io/ublue-os/bazzite-deck:stable") export LIVE_BASE_IMAGE := env_var_or_default("LIVE_BASE_IMAGE", "quay.io/fedora/fedora-kinoite:43") export INSTALLER_BUILDER_IMAGE := env_var_or_default("INSTALLER_BUILDER_IMAGE", "ghcr.io/jasonn3/build-container-installer:v1.5.0") @@ -120,7 +123,7 @@ build $target_image=image_name $tag=default_tag: BUILD_ARGS=() LABELS=() - for arg in BASE_IMAGE FLATPAK_REMOTE_URL HOMEBREW_BOTTLE_DOMAIN HOMEBREW_API_DOMAIN OSTREE_IMAGE_REF INSTRUMENTS_ENABLED INSTRUMENTS_RELEASE_REPOSITORY INSTRUMENTS_VERSION INSTRUMENTS_RELEASE_API_BASE; do + for arg in BASE_IMAGE IMAGE_BRANCH VERSION_TAG VERSION_PRETTY FLATPAK_REMOTE_URL HOMEBREW_BOTTLE_DOMAIN HOMEBREW_API_DOMAIN OSTREE_IMAGE_REF INSTRUMENTS_ENABLED INSTRUMENTS_RELEASE_REPOSITORY INSTRUMENTS_VERSION INSTRUMENTS_RELEASE_API_BASE; do if [[ -n "${!arg:-}" ]]; then BUILD_ARGS+=("--build-arg" "${arg}=${!arg}") fi -- cgit v1.2.3 From a09c6dfd3c294ba2bd4a9df8f9c043b9aefaa0a0 Mon Sep 17 00:00:00 2001 From: tranch Date: Sun, 26 Jul 2026 01:23:31 +0800 Subject: Make stable the default image channel Keep latest as a main-branch alias while using Fedora/date versions for image metadata and release tags. --- .github/workflows/build.yml | 4 +++- Justfile | 2 +- image-template.env | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6a59b2a..97bfd91 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -88,11 +88,13 @@ jobs: VERSION_BASE="${FEDORA_VERSION}.$(date -u +%Y%m%d)" if [[ "${GITHUB_REF_NAME}" == "testing" ]]; then + DEFAULT_TAG="testing" VERSION_TAG="testing-${VERSION_BASE}" VERSION_PRETTY="Testing (F${VERSION_BASE})" IMAGE_BRANCH="testing" ALIAS_TAGS="${VERSION_TAG} testing testing-${FEDORA_VERSION}" else + DEFAULT_TAG="stable" VERSION_TAG="${VERSION_BASE}" VERSION_PRETTY="Stable (F${VERSION_BASE})" IMAGE_BRANCH="stable" @@ -100,7 +102,7 @@ jobs: fi { - echo "DEFAULT_TAG=${VERSION_TAG}" + echo "DEFAULT_TAG=${DEFAULT_TAG}" echo "IMAGE_BRANCH=${IMAGE_BRANCH}" echo "VERSION_TAG=${VERSION_TAG}" echo "VERSION_PRETTY=${VERSION_PRETTY}" diff --git a/Justfile b/Justfile index d3252c6..68939a1 100644 --- a/Justfile +++ b/Justfile @@ -140,7 +140,7 @@ build $target_image=image_name $tag=default_tag: 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}") + LABELS+=("--label" "org.opencontainers.image.version={{ version_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 diff --git a/image-template.env b/image-template.env index 3035db5..22a387b 100644 --- a/image-template.env +++ b/image-template.env @@ -11,7 +11,7 @@ IMAGE_KEYWORDS="bootc,oci,linux,bazzite,steam-deck,aerocore" # 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" +DEFAULT_TAG="stable" BIB_IMAGE="quay.io/centos-bootc/bootc-image-builder:latest" # Keep this on bazzite-deck for Steam Deck, game mode, and handheld customizations. -- cgit v1.2.3 From 5d5d097220c89c4703754583d422a41f37173b97 Mon Sep 17 00:00:00 2001 From: tranch Date: Sun, 26 Jul 2026 01:29:22 +0800 Subject: Fix Justfile version tag variable Use the uppercase VERSION_TAG variable defined by Just. --- Justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Justfile b/Justfile index 68939a1..a8590e2 100644 --- a/Justfile +++ b/Justfile @@ -140,7 +140,7 @@ build $target_image=image_name $tag=default_tag: 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={{ version_tag }}.$(date +%Y%m%d)-${GIT_SHA}") + LABELS+=("--label" "org.opencontainers.image.version={{ VERSION_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 -- cgit v1.2.3 From 030fcab5bb353fdb7d7c18194476af5c6f0aa19c Mon Sep 17 00:00:00 2001 From: tranch Date: Sun, 26 Jul 2026 01:32:34 +0800 Subject: Run lightweight checks for pull requests --- .github/workflows/build.yml | 4 ---- .github/workflows/validate-installer-iso.yml | 18 +++++++++--------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 97bfd91..b9d12cf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,10 +5,6 @@ on: branches: - main - testing - pull_request: - branches: - - main - - testing #schedule: # - cron: '05 10 * * *' # 10:05am UTC everyday workflow_dispatch: diff --git a/.github/workflows/validate-installer-iso.yml b/.github/workflows/validate-installer-iso.yml index 37f5496..131ad5b 100644 --- a/.github/workflows/validate-installer-iso.yml +++ b/.github/workflows/validate-installer-iso.yml @@ -1,20 +1,17 @@ -name: Validate installer ISO +name: Validate pull request on: pull_request: - paths: - - "Justfile" - - "installer/**" - - "just_scripts/build-installer-iso.sh" - - ".github/workflows/build-installer-iso.yml" - - ".github/workflows/validate-installer-iso.yml" + branches: + - main + - testing permissions: contents: read jobs: - validate-installer-iso: - name: Validate installer ISO inputs + validate: + name: Run lightweight checks runs-on: ubuntu-24.04 steps: @@ -28,6 +25,9 @@ jobs: run: | ruby -e 'require "yaml"; Dir[".github/workflows/*.yml"].each { |file| YAML.load_file(file) }' + - name: Validate Just syntax + run: just check + - name: Validate Justfile formatting run: | just --unstable --fmt --check -f Justfile -- cgit v1.2.3 From 5d8a3ae72e2ebad4079feda9ff74ce22b7c549fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Jul 2026 17:58:37 +0000 Subject: chore(deps): bump docker/login-action from 4.4.0 to 4.5.1 Bumps [docker/login-action](https://github.com/docker/login-action) from 4.4.0 to 4.5.1. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/af1e73f918a031802d376d3c8bbc3fe56130a9b0...abd2ef45e78c5afb21d64d4ca52ee8550d9572c7) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b9d12cf..3c8cc06 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -167,7 +167,7 @@ jobs: # These `if` statements keep pull requests from publishing packages. # They publish default-branch builds and manual testing branch builds. - name: Login to GitHub Container Registry - uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0 + uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1 if: github.event_name != 'pull_request' && (github.ref_name == github.event.repository.default_branch || github.ref_name == 'testing') with: registry: ghcr.io -- cgit v1.2.3 From d3279ab8680f9e1d5885442236f3daff420255b3 Mon Sep 17 00:00:00 2001 From: tranch Date: Sun, 26 Jul 2026 10:25:23 +0800 Subject: Add Steam startup and suspend videos --- .../usr/share/ublue-os/bazzite/bazzite-oled.webm | Bin 0 -> 144109 bytes .../share/ublue-os/bazzite/bazzite-suspend-oled.webm | Bin 0 -> 46100 bytes .../usr/share/ublue-os/bazzite/bazzite-suspend.webm | Bin 0 -> 46100 bytes system_files/usr/share/ublue-os/bazzite/bazzite.webm | Bin 0 -> 144109 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 system_files/usr/share/ublue-os/bazzite/bazzite-oled.webm create mode 100644 system_files/usr/share/ublue-os/bazzite/bazzite-suspend-oled.webm create mode 100644 system_files/usr/share/ublue-os/bazzite/bazzite-suspend.webm create mode 100644 system_files/usr/share/ublue-os/bazzite/bazzite.webm diff --git a/system_files/usr/share/ublue-os/bazzite/bazzite-oled.webm b/system_files/usr/share/ublue-os/bazzite/bazzite-oled.webm new file mode 100644 index 0000000..14ba412 Binary files /dev/null and b/system_files/usr/share/ublue-os/bazzite/bazzite-oled.webm differ diff --git a/system_files/usr/share/ublue-os/bazzite/bazzite-suspend-oled.webm b/system_files/usr/share/ublue-os/bazzite/bazzite-suspend-oled.webm new file mode 100644 index 0000000..50f4300 Binary files /dev/null and b/system_files/usr/share/ublue-os/bazzite/bazzite-suspend-oled.webm differ diff --git a/system_files/usr/share/ublue-os/bazzite/bazzite-suspend.webm b/system_files/usr/share/ublue-os/bazzite/bazzite-suspend.webm new file mode 100644 index 0000000..50f4300 Binary files /dev/null and b/system_files/usr/share/ublue-os/bazzite/bazzite-suspend.webm differ diff --git a/system_files/usr/share/ublue-os/bazzite/bazzite.webm b/system_files/usr/share/ublue-os/bazzite/bazzite.webm new file mode 100644 index 0000000..14ba412 Binary files /dev/null and b/system_files/usr/share/ublue-os/bazzite/bazzite.webm differ -- cgit v1.2.3 From 09690831fbab028453dc717b74f89ee48296c846 Mon Sep 17 00:00:00 2001 From: tranch Date: Sun, 26 Jul 2026 11:00:21 +0800 Subject: Hide GRUB menu after installer deployment Configure target GRUB during Anaconda post-install. Preserve Bazzite menu controls and dual-boot recovery. --- installer/build.sh | 23 ++++++++++ installer/configure-target-grub.sh | 89 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100755 installer/configure-target-grub.sh diff --git a/installer/build.sh b/installer/build.sh index c119dcc..a382bcf 100755 --- a/installer/build.sh +++ b/installer/build.sh @@ -44,6 +44,13 @@ if [[ -d "${SCRIPT_DIR}/system_files/overrides" ]]; then cp -a "${SCRIPT_DIR}/system_files/overrides/." / fi +# The target system is an upstream-built bootc image. Keep this installer-only +# helper out of the installed image and invoke it after Anaconda mounts the +# target rootfs. +install -Dm0755 \ + "${SCRIPT_DIR}/configure-target-grub.sh" \ + /usr/libexec/aerocore-configure-target-grub + # Plasma's live-session launcher defaults to start-here, and Fedora keeps # LOGO=fedora-logo-icon in the base live environment. for size in 16x16 22x22 24x24 32x32 36x36 48x48 64x64 96x96 128x128 256x256; do @@ -127,6 +134,22 @@ if [ x\${target_root} = x ]; then fi systemd-firstboot --root=\${target_root} --hostname=aerocore-os %end + +%post --nochroot --log=/tmp/aerocore-grub.log +set -eux +target_root= +for root in /mnt/sysroot /mnt/sysimage /var/mnt/sysimage; do + if mountpoint -q \${root}; then + target_root=\${root} + break + fi +done +if [ x\${target_root} = x ]; then + echo No mounted target system found for GRUB configuration >&2 + exit 1 +fi +/usr/libexec/aerocore-configure-target-grub \${target_root} +%end EOF mkdir -p /usr/lib/bootc-image-builder diff --git a/installer/configure-target-grub.sh b/installer/configure-target-grub.sh new file mode 100755 index 0000000..2f16692 --- /dev/null +++ b/installer/configure-target-grub.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash + +set -euo pipefail + +target_root=${1:?usage: configure-target-grub.sh TARGET_ROOT} + +if [[ ! -d "${target_root}/etc" || ! -d "${target_root}/usr" ]]; then + echo "Invalid target root: ${target_root}" >&2 + exit 1 +fi + +grub_defaults="${target_root}/etc/default/grub" +mkdir -p "$(dirname "${grub_defaults}")" + +if [[ -f "${grub_defaults}" ]] && grep -q '^GRUB_TIMEOUT=' "${grub_defaults}"; then + sed -i 's/^GRUB_TIMEOUT=.*/GRUB_TIMEOUT=0/' "${grub_defaults}" +else + printf 'GRUB_TIMEOUT=0\n' >> "${grub_defaults}" +fi + +grub_editenv="" +for candidate in \ + "${target_root}/usr/bin/grub2-editenv" \ + "${target_root}/usr/sbin/grub2-editenv"; do + if [[ -x "${candidate}" ]]; then + grub_editenv="${candidate#"${target_root}"}" + break + fi +done + +grub_mkconfig="" +for candidate in \ + "${target_root}/usr/bin/grub2-mkconfig" \ + "${target_root}/usr/sbin/grub2-mkconfig"; do + if [[ -x "${candidate}" ]]; then + grub_mkconfig="${candidate#"${target_root}"}" + break + fi +done + +if [[ -z "${grub_editenv}" || -z "${grub_mkconfig}" ]]; then + echo "The target image does not contain the required GRUB tools" >&2 + exit 1 +fi + +mounted_paths=() +cleanup() { + local path + for path in "${mounted_paths[@]}"; do + umount -R "${path}" 2>/dev/null || true + done +} +trap cleanup EXIT + +bind_runtime_tree() { + local source=$1 + local destination="${target_root}/${source#/}" + + mkdir -p "${destination}" + if mountpoint -q "${destination}"; then + return 0 + fi + + mount --rbind "${source}" "${destination}" + mount --make-rslave "${destination}" + mounted_paths+=("${destination}") +} + +# grub2-mkconfig invokes grub-probe and needs the installer's device and EFI +# views while it runs inside the installed image. +bind_runtime_tree /dev +bind_runtime_tree /proc +bind_runtime_tree /sys + +chroot "${target_root}" "${grub_editenv}" - set menu_auto_hide=1 + +if [[ -e "${target_root}/etc/grub2-efi.cfg" || -L "${target_root}/etc/grub2-efi.cfg" ]]; then + grub_config=/etc/grub2-efi.cfg +elif [[ -e "${target_root}/etc/grub2.cfg" || -L "${target_root}/etc/grub2.cfg" ]]; then + grub_config=/etc/grub2.cfg +elif [[ -d /sys/firmware/efi ]]; then + grub_config=/etc/grub2-efi.cfg +else + grub_config=/etc/grub2.cfg +fi + +chroot "${target_root}" "${grub_mkconfig}" -o "${grub_config}" + +echo "Configured target GRUB: GRUB_TIMEOUT=0, menu_auto_hide=1, ${grub_config}" -- cgit v1.2.3 From 4b3aa91a9967c1c38a325415850c2b6754187db4 Mon Sep 17 00:00:00 2001 From: tranch Date: Mon, 27 Jul 2026 23:03:06 +0800 Subject: fix: sync branding and suspend audio --- installer/branding/sidebar-logo.png | Bin 4425 -> 4105 bytes .../apps/org.fedoraproject.AnacondaInstaller.svg | 4 ++-- .../apps/org.fedoraproject.AnacondaInstaller.svg | 4 ++-- ...rg.fedoraproject.AnacondaInstaller-symbolic.svg | 4 ++-- .../icons/hicolor/128x128/bazzite-logo-icon.png | Bin 5613 -> 6400 bytes .../icons/hicolor/16x16/bazzite-logo-icon.png | Bin 634 -> 680 bytes .../icons/hicolor/22x22/bazzite-logo-icon.png | Bin 837 -> 976 bytes .../icons/hicolor/24x24/bazzite-logo-icon.png | Bin 921 -> 1048 bytes .../icons/hicolor/256x256/bazzite-logo-icon.png | Bin 12105 -> 14244 bytes .../icons/hicolor/32x32/bazzite-logo-icon.png | Bin 1203 -> 1483 bytes .../icons/hicolor/36x36/bazzite-logo-icon.png | Bin 1345 -> 1601 bytes .../icons/hicolor/48x48/bazzite-logo-icon.png | Bin 1853 -> 2167 bytes .../icons/hicolor/64x64/bazzite-logo-icon.png | Bin 2571 -> 3052 bytes .../icons/hicolor/96x96/bazzite-logo-icon.png | Bin 4083 -> 4688 bytes .../hicolor/scalable/places/bazzite-logo-le.svg | 4 ++-- .../scalable/places/distributor-logo-white.svg | 4 ++-- .../hicolor/scalable/places/distributor-logo.svg | 4 ++-- system_files/usr/share/pixmaps/bazzite-logo-le.svg | 4 ++-- .../usr/share/pixmaps/fedora-logo-sprite.png | Bin 15673 -> 6400 bytes .../usr/share/pixmaps/fedora-logo-sprite.svg | 4 ++-- .../share/plymouth/themes/spinner/watermark.png | Bin 4140 -> 4999 bytes .../share/ublue-os/bazzite/bazzite-suspend.webm | Bin 46100 -> 47887 bytes .../usr/share/ublue-os/bazzite/bazzite.webm | Bin 144109 -> 191419 bytes system_files/usr/share/ublue-os/bazzite/docs.svg | 4 ++-- system_files/usr/share/ublue-os/bazzite/logo.svg | 4 ++-- .../usr/share/ublue-os/bazzite/updatelogo.png | Bin 61110 -> 58147 bytes .../usr/share/wallpapers/aerocore-wallpaper.jxl | Bin 3395468 -> 3392275 bytes 27 files changed, 20 insertions(+), 20 deletions(-) diff --git a/installer/branding/sidebar-logo.png b/installer/branding/sidebar-logo.png index 0f47606..bd877c4 100644 Binary files a/installer/branding/sidebar-logo.png and b/installer/branding/sidebar-logo.png differ diff --git a/installer/system_files/overrides/usr/share/icons/hicolor/48x48/apps/org.fedoraproject.AnacondaInstaller.svg b/installer/system_files/overrides/usr/share/icons/hicolor/48x48/apps/org.fedoraproject.AnacondaInstaller.svg index 04454b7..c28ad47 100644 --- a/installer/system_files/overrides/usr/share/icons/hicolor/48x48/apps/org.fedoraproject.AnacondaInstaller.svg +++ b/installer/system_files/overrides/usr/share/icons/hicolor/48x48/apps/org.fedoraproject.AnacondaInstaller.svg @@ -26,8 +26,8 @@ - - + + diff --git a/installer/system_files/overrides/usr/share/icons/hicolor/scalable/apps/org.fedoraproject.AnacondaInstaller.svg b/installer/system_files/overrides/usr/share/icons/hicolor/scalable/apps/org.fedoraproject.AnacondaInstaller.svg index 04454b7..c28ad47 100644 --- a/installer/system_files/overrides/usr/share/icons/hicolor/scalable/apps/org.fedoraproject.AnacondaInstaller.svg +++ b/installer/system_files/overrides/usr/share/icons/hicolor/scalable/apps/org.fedoraproject.AnacondaInstaller.svg @@ -26,8 +26,8 @@ - - + + diff --git a/installer/system_files/overrides/usr/share/icons/hicolor/symbolic/apps/org.fedoraproject.AnacondaInstaller-symbolic.svg b/installer/system_files/overrides/usr/share/icons/hicolor/symbolic/apps/org.fedoraproject.AnacondaInstaller-symbolic.svg index f8dedad..f9db423 100644 --- a/installer/system_files/overrides/usr/share/icons/hicolor/symbolic/apps/org.fedoraproject.AnacondaInstaller-symbolic.svg +++ b/installer/system_files/overrides/usr/share/icons/hicolor/symbolic/apps/org.fedoraproject.AnacondaInstaller-symbolic.svg @@ -7,7 +7,7 @@ - - + + diff --git a/system_files/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png index 30cd4aa..b85e00d 100644 Binary files a/system_files/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png and b/system_files/usr/share/icons/hicolor/128x128/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png index e7d57f9..d5671dd 100644 Binary files a/system_files/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png and b/system_files/usr/share/icons/hicolor/16x16/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png index f368a0a..075ca2c 100644 Binary files a/system_files/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png and b/system_files/usr/share/icons/hicolor/22x22/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png index b722b22..47fd41b 100644 Binary files a/system_files/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png and b/system_files/usr/share/icons/hicolor/24x24/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png index b7acaa2..0ff118f 100644 Binary files a/system_files/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png and b/system_files/usr/share/icons/hicolor/256x256/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png index 54e23b2..a84667d 100644 Binary files a/system_files/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png and b/system_files/usr/share/icons/hicolor/32x32/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png index ff03f27..50e56f5 100644 Binary files a/system_files/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png and b/system_files/usr/share/icons/hicolor/36x36/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png index 977f02e..20bb221 100644 Binary files a/system_files/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png and b/system_files/usr/share/icons/hicolor/48x48/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png index 74477a7..b9cfe99 100644 Binary files a/system_files/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png and b/system_files/usr/share/icons/hicolor/64x64/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png b/system_files/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png index ea0d730..a944b51 100644 Binary files a/system_files/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png and b/system_files/usr/share/icons/hicolor/96x96/bazzite-logo-icon.png differ diff --git a/system_files/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg b/system_files/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg index 291b91c..ce7d5b4 100644 --- a/system_files/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg +++ b/system_files/usr/share/icons/hicolor/scalable/places/bazzite-logo-le.svg @@ -12,8 +12,8 @@ - - + + diff --git a/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg b/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg index 5f58794..59150f0 100644 --- a/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg +++ b/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo-white.svg @@ -4,8 +4,8 @@ - - + + diff --git a/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo.svg b/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo.svg index 291b91c..ce7d5b4 100644 --- a/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo.svg +++ b/system_files/usr/share/icons/hicolor/scalable/places/distributor-logo.svg @@ -12,8 +12,8 @@ - - + + diff --git a/system_files/usr/share/pixmaps/bazzite-logo-le.svg b/system_files/usr/share/pixmaps/bazzite-logo-le.svg index bd0dae2..2fe3ccf 100644 --- a/system_files/usr/share/pixmaps/bazzite-logo-le.svg +++ b/system_files/usr/share/pixmaps/bazzite-logo-le.svg @@ -12,8 +12,8 @@ - - + + diff --git a/system_files/usr/share/pixmaps/fedora-logo-sprite.png b/system_files/usr/share/pixmaps/fedora-logo-sprite.png index 1f02770..b85e00d 100644 Binary files a/system_files/usr/share/pixmaps/fedora-logo-sprite.png and b/system_files/usr/share/pixmaps/fedora-logo-sprite.png differ diff --git a/system_files/usr/share/pixmaps/fedora-logo-sprite.svg b/system_files/usr/share/pixmaps/fedora-logo-sprite.svg index bd0dae2..2fe3ccf 100644 --- a/system_files/usr/share/pixmaps/fedora-logo-sprite.svg +++ b/system_files/usr/share/pixmaps/fedora-logo-sprite.svg @@ -12,8 +12,8 @@ - - + + diff --git a/system_files/usr/share/plymouth/themes/spinner/watermark.png b/system_files/usr/share/plymouth/themes/spinner/watermark.png index 4b53dd2..b23f588 100644 Binary files a/system_files/usr/share/plymouth/themes/spinner/watermark.png and b/system_files/usr/share/plymouth/themes/spinner/watermark.png differ diff --git a/system_files/usr/share/ublue-os/bazzite/bazzite-suspend.webm b/system_files/usr/share/ublue-os/bazzite/bazzite-suspend.webm index 50f4300..1c2c6bf 100644 Binary files a/system_files/usr/share/ublue-os/bazzite/bazzite-suspend.webm and b/system_files/usr/share/ublue-os/bazzite/bazzite-suspend.webm differ diff --git a/system_files/usr/share/ublue-os/bazzite/bazzite.webm b/system_files/usr/share/ublue-os/bazzite/bazzite.webm index 14ba412..3c932d8 100644 Binary files a/system_files/usr/share/ublue-os/bazzite/bazzite.webm and b/system_files/usr/share/ublue-os/bazzite/bazzite.webm differ diff --git a/system_files/usr/share/ublue-os/bazzite/docs.svg b/system_files/usr/share/ublue-os/bazzite/docs.svg index a7e16e7..a792c73 100644 --- a/system_files/usr/share/ublue-os/bazzite/docs.svg +++ b/system_files/usr/share/ublue-os/bazzite/docs.svg @@ -17,7 +17,7 @@ - - + + diff --git a/system_files/usr/share/ublue-os/bazzite/logo.svg b/system_files/usr/share/ublue-os/bazzite/logo.svg index bd0dae2..8dbc937 100644 --- a/system_files/usr/share/ublue-os/bazzite/logo.svg +++ b/system_files/usr/share/ublue-os/bazzite/logo.svg @@ -12,8 +12,8 @@ - - + + diff --git a/system_files/usr/share/ublue-os/bazzite/updatelogo.png b/system_files/usr/share/ublue-os/bazzite/updatelogo.png index 1b3cb8a..4ab4da9 100644 Binary files a/system_files/usr/share/ublue-os/bazzite/updatelogo.png and b/system_files/usr/share/ublue-os/bazzite/updatelogo.png differ diff --git a/system_files/usr/share/wallpapers/aerocore-wallpaper.jxl b/system_files/usr/share/wallpapers/aerocore-wallpaper.jxl index 9eca7b7..e09095e 100644 Binary files a/system_files/usr/share/wallpapers/aerocore-wallpaper.jxl and b/system_files/usr/share/wallpapers/aerocore-wallpaper.jxl differ -- cgit v1.2.3 From fbe898492cec0f2601ea0cbff2134380d119a3c1 Mon Sep 17 00:00:00 2001 From: tranch Date: Mon, 27 Jul 2026 23:08:56 +0800 Subject: fix: sync OLED branding video --- .../usr/share/ublue-os/bazzite/bazzite-oled.webm | Bin 144109 -> 191419 bytes .../ublue-os/bazzite/bazzite-suspend-oled.webm | Bin 46100 -> 47887 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/system_files/usr/share/ublue-os/bazzite/bazzite-oled.webm b/system_files/usr/share/ublue-os/bazzite/bazzite-oled.webm index 14ba412..3c932d8 100644 Binary files a/system_files/usr/share/ublue-os/bazzite/bazzite-oled.webm and b/system_files/usr/share/ublue-os/bazzite/bazzite-oled.webm differ diff --git a/system_files/usr/share/ublue-os/bazzite/bazzite-suspend-oled.webm b/system_files/usr/share/ublue-os/bazzite/bazzite-suspend-oled.webm index 50f4300..1c2c6bf 100644 Binary files a/system_files/usr/share/ublue-os/bazzite/bazzite-suspend-oled.webm and b/system_files/usr/share/ublue-os/bazzite/bazzite-suspend-oled.webm differ -- cgit v1.2.3 From 9c04096ab5fd8457e485b3069f0235f0de7ea2b6 Mon Sep 17 00:00:00 2001 From: tranch Date: Mon, 27 Jul 2026 13:34:03 +0800 Subject: Preserve GRUB selection timeout Hide the target GRUB menu through menu_auto_hide while keeping the image-provided timeout. This leaves users time to choose rollback or other boot entries when they explicitly reveal the menu. Verified with bash -n and git diff --check. --- installer/configure-target-grub.sh | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/installer/configure-target-grub.sh b/installer/configure-target-grub.sh index 2f16692..a0aa756 100755 --- a/installer/configure-target-grub.sh +++ b/installer/configure-target-grub.sh @@ -9,15 +9,6 @@ if [[ ! -d "${target_root}/etc" || ! -d "${target_root}/usr" ]]; then exit 1 fi -grub_defaults="${target_root}/etc/default/grub" -mkdir -p "$(dirname "${grub_defaults}")" - -if [[ -f "${grub_defaults}" ]] && grep -q '^GRUB_TIMEOUT=' "${grub_defaults}"; then - sed -i 's/^GRUB_TIMEOUT=.*/GRUB_TIMEOUT=0/' "${grub_defaults}" -else - printf 'GRUB_TIMEOUT=0\n' >> "${grub_defaults}" -fi - grub_editenv="" for candidate in \ "${target_root}/usr/bin/grub2-editenv" \ @@ -86,4 +77,6 @@ fi chroot "${target_root}" "${grub_mkconfig}" -o "${grub_config}" -echo "Configured target GRUB: GRUB_TIMEOUT=0, menu_auto_hide=1, ${grub_config}" +# Preserve the target image's GRUB timeout so users have time to choose an +# entry after explicitly showing the otherwise hidden menu. +echo "Configured target GRUB: menu_auto_hide=1, ${grub_config}" -- cgit v1.2.3 From b8e36fd2f8ecef585f98b1ef10be05a168764704 Mon Sep 17 00:00:00 2001 From: tranch Date: Tue, 28 Jul 2026 01:58:36 +0800 Subject: fix: add omitted branding updates --- .../usr/share/pixmaps/bootloader/fedora.icns | Bin 15377 -> 10302 bytes system_files/usr/share/pixmaps/combination_med.png | Bin 76166 -> 34823 bytes system_files/usr/share/pixmaps/fedora-gdm-logo.png | Bin 8908 -> 8570 bytes .../usr/share/pixmaps/fedora-logo-small.png | Bin 9520 -> 7937 bytes system_files/usr/share/pixmaps/fedora-logo.png | Bin 48311 -> 28847 bytes system_files/usr/share/pixmaps/fedora_logo_med.png | Bin 11667 -> 8937 bytes system_files/usr/share/pixmaps/fedora_whitelogo.png | Bin 71205 -> 30497 bytes system_files/usr/share/pixmaps/fedora_whitelogo.svg | 4 ++-- .../usr/share/pixmaps/fedora_whitelogo_med.png | Bin 10651 -> 7984 bytes .../usr/share/pixmaps/system-logo-white.png | Bin 53377 -> 13778 bytes .../contents/splash/images/bazzite_logo.svgz | Bin 1384 -> 1437 bytes .../contents/splash/images/bazzite_logo.svgz | Bin 1384 -> 1437 bytes 12 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system_files/usr/share/pixmaps/bootloader/fedora.icns b/system_files/usr/share/pixmaps/bootloader/fedora.icns index c16933f..ef7b356 100644 Binary files a/system_files/usr/share/pixmaps/bootloader/fedora.icns and b/system_files/usr/share/pixmaps/bootloader/fedora.icns differ diff --git a/system_files/usr/share/pixmaps/combination_med.png b/system_files/usr/share/pixmaps/combination_med.png index 2f75183..d04fd57 100644 Binary files a/system_files/usr/share/pixmaps/combination_med.png and b/system_files/usr/share/pixmaps/combination_med.png differ diff --git a/system_files/usr/share/pixmaps/fedora-gdm-logo.png b/system_files/usr/share/pixmaps/fedora-gdm-logo.png index b903599..1734d91 100644 Binary files a/system_files/usr/share/pixmaps/fedora-gdm-logo.png and b/system_files/usr/share/pixmaps/fedora-gdm-logo.png differ diff --git a/system_files/usr/share/pixmaps/fedora-logo-small.png b/system_files/usr/share/pixmaps/fedora-logo-small.png index 02e6d48..4ea512c 100644 Binary files a/system_files/usr/share/pixmaps/fedora-logo-small.png and b/system_files/usr/share/pixmaps/fedora-logo-small.png differ diff --git a/system_files/usr/share/pixmaps/fedora-logo.png b/system_files/usr/share/pixmaps/fedora-logo.png index 55d2a45..3f5538b 100644 Binary files a/system_files/usr/share/pixmaps/fedora-logo.png and b/system_files/usr/share/pixmaps/fedora-logo.png differ diff --git a/system_files/usr/share/pixmaps/fedora_logo_med.png b/system_files/usr/share/pixmaps/fedora_logo_med.png index e5b8db5..6b2f870 100644 Binary files a/system_files/usr/share/pixmaps/fedora_logo_med.png and b/system_files/usr/share/pixmaps/fedora_logo_med.png differ diff --git a/system_files/usr/share/pixmaps/fedora_whitelogo.png b/system_files/usr/share/pixmaps/fedora_whitelogo.png index 66e2c3e..968120b 100644 Binary files a/system_files/usr/share/pixmaps/fedora_whitelogo.png and b/system_files/usr/share/pixmaps/fedora_whitelogo.png differ diff --git a/system_files/usr/share/pixmaps/fedora_whitelogo.svg b/system_files/usr/share/pixmaps/fedora_whitelogo.svg index 372e337..e1178e7 100644 --- a/system_files/usr/share/pixmaps/fedora_whitelogo.svg +++ b/system_files/usr/share/pixmaps/fedora_whitelogo.svg @@ -13,8 +13,8 @@ - - + + diff --git a/system_files/usr/share/pixmaps/fedora_whitelogo_med.png b/system_files/usr/share/pixmaps/fedora_whitelogo_med.png index 3b12a8c..60710bf 100644 Binary files a/system_files/usr/share/pixmaps/fedora_whitelogo_med.png and b/system_files/usr/share/pixmaps/fedora_whitelogo_med.png differ diff --git a/system_files/usr/share/pixmaps/system-logo-white.png b/system_files/usr/share/pixmaps/system-logo-white.png index 60349b2..145091c 100644 Binary files a/system_files/usr/share/pixmaps/system-logo-white.png and b/system_files/usr/share/pixmaps/system-logo-white.png differ diff --git a/system_files/usr/share/plasma/look-and-feel/com.valve.vapor.desktop/contents/splash/images/bazzite_logo.svgz b/system_files/usr/share/plasma/look-and-feel/com.valve.vapor.desktop/contents/splash/images/bazzite_logo.svgz index 0da602b..27448ae 100644 Binary files a/system_files/usr/share/plasma/look-and-feel/com.valve.vapor.desktop/contents/splash/images/bazzite_logo.svgz and b/system_files/usr/share/plasma/look-and-feel/com.valve.vapor.desktop/contents/splash/images/bazzite_logo.svgz differ diff --git a/system_files/usr/share/plasma/look-and-feel/com.valve.vgui.desktop/contents/splash/images/bazzite_logo.svgz b/system_files/usr/share/plasma/look-and-feel/com.valve.vgui.desktop/contents/splash/images/bazzite_logo.svgz index 0da602b..27448ae 100644 Binary files a/system_files/usr/share/plasma/look-and-feel/com.valve.vgui.desktop/contents/splash/images/bazzite_logo.svgz and b/system_files/usr/share/plasma/look-and-feel/com.valve.vgui.desktop/contents/splash/images/bazzite_logo.svgz differ -- cgit v1.2.3 From 6aee80a6d0e7a627f7966c8b00fc3acf1264b72b Mon Sep 17 00:00:00 2001 From: tranch Date: Tue, 28 Jul 2026 02:08:21 +0800 Subject: fix: avoid duplicate date in image version label --- Justfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Justfile b/Justfile index af61316..8161c52 100644 --- a/Justfile +++ b/Justfile @@ -110,8 +110,8 @@ sudoif command *args: # $target_image - The tag you want to apply to the image (default: $image_name). # $tag - The tag for the image (default: $default_tag). # -# The script constructs the version string using the tag and the current date. -# If the git working directory is clean, it also includes the short SHA of the current HEAD. +# If the git working directory is clean, it appends the short SHA of the current HEAD +# to the version tag supplied by the build environment. # # just build $target_image $tag # @@ -141,7 +141,7 @@ build $target_image=image_name $tag=default_tag: 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={{ VERSION_TAG }}.$(date +%Y%m%d)-${GIT_SHA}") + LABELS+=("--label" "org.opencontainers.image.version={{ VERSION_TAG }}-${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 -- cgit v1.2.3 From c1f3f42c14e5bbf1c8181d1469ac58f1d9f7ebf3 Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 29 Jul 2026 00:28:49 +0800 Subject: Allow live user to launch installer Authorize only the local active liveuser session for Anaconda's specific polkit action, avoiding the transient password prompt. Validate installer polkit rule syntax in the pull request workflow. --- .github/workflows/validate-installer-iso.yml | 6 ++++++ .../overrides/etc/polkit-1/rules.d/10-aerocore-liveinst.rules | 10 ++++++++++ 2 files changed, 16 insertions(+) create mode 100644 installer/system_files/overrides/etc/polkit-1/rules.d/10-aerocore-liveinst.rules diff --git a/.github/workflows/validate-installer-iso.yml b/.github/workflows/validate-installer-iso.yml index 131ad5b..391afd8 100644 --- a/.github/workflows/validate-installer-iso.yml +++ b/.github/workflows/validate-installer-iso.yml @@ -38,3 +38,9 @@ jobs: bash -n "$script" done bash -n system_files/usr/libexec/aerocore-instruments-setup + + - name: Validate installer polkit rules + run: | + for rule in installer/system_files/overrides/etc/polkit-1/rules.d/*.rules; do + node --check < "$rule" + done diff --git a/installer/system_files/overrides/etc/polkit-1/rules.d/10-aerocore-liveinst.rules b/installer/system_files/overrides/etc/polkit-1/rules.d/10-aerocore-liveinst.rules new file mode 100644 index 0000000..0ebcfdd --- /dev/null +++ b/installer/system_files/overrides/etc/polkit-1/rules.d/10-aerocore-liveinst.rules @@ -0,0 +1,10 @@ +// The installer action is privileged by design. Allow only the local, +// active Live ISO session to launch it without a transient password prompt. +polkit.addRule(function(action, subject) { + if (action.id === "org.fedoraproject.pkexec.liveinst" && + subject.user === "liveuser" && + subject.local === true && + subject.active === true) { + return polkit.Result.YES; + } +}); -- cgit v1.2.3 From 20b653d974a43d277e87a971eeaed22cf22d9811 Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 29 Jul 2026 00:48:06 +0800 Subject: Fix weak password handling in Live installer Keep the Live CD account locked and enforce strict user/root password validation so weak passwords remain on the form instead of aborting the Anaconda installation. --- installer/lorax_templates/remove_root_password_prompt.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer/lorax_templates/remove_root_password_prompt.tmpl b/installer/lorax_templates/remove_root_password_prompt.tmpl index 3bd0342..5e5b60d 100644 --- a/installer/lorax_templates/remove_root_password_prompt.tmpl +++ b/installer/lorax_templates/remove_root_password_prompt.tmpl @@ -1 +1 @@ -append etc/anaconda/profile.d/fedora-kinoite.conf "\\n[User Interface]\\nhidden_spokes =\\n PasswordSpoke" +append etc/anaconda/profile.d/fedora-kinoite.conf "\\n[User Interface]\\nhidden_spokes =\\n PasswordSpoke\\npassword_policies =\\n root (quality 1, length 6, strict)\\n user (quality 1, length 6, empty, strict)\\n luks (quality 1, length 6)" -- cgit v1.2.3 From 13e8465b802802657d10f935bbfc7dae3aa5286b Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 29 Jul 2026 00:51:24 +0800 Subject: Brand the Live installer as AeroCore OS Update the Live ISO product metadata and system release label while preserving the Fedora version and Kinoite variant. --- installer/build.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/installer/build.sh b/installer/build.sh index a382bcf..0cc1b8a 100755 --- a/installer/build.sh +++ b/installer/build.sh @@ -70,7 +70,12 @@ if [[ -f /usr/share/icons/hicolor/scalable/places/distributor-logo.svg ]]; then /usr/share/icons/hicolor/scalable/places/start-here.svg fi -sed -i 's/^LOGO=.*/LOGO=distributor-logo/' /usr/lib/os-release +live_version_id="$(awk -F= '$1 == "VERSION_ID" { gsub(/\"/, "", $2); print $2; exit }' /usr/lib/os-release)" +live_product_name="AeroCore OS" +sed -i "s/^NAME=.*/NAME=\"${live_product_name}\"/" /usr/lib/os-release +sed -i "s/^PRETTY_NAME=.*/PRETTY_NAME=\"${live_product_name} ${live_version_id} (Kinoite)\"/" /usr/lib/os-release +sed -i "s/^LOGO=.*/LOGO=distributor-logo/" /usr/lib/os-release +printf '%s release %s (Kinoite)\n' "${live_product_name}" "${live_version_id}" > /etc/system-release for desktop_file in \ /usr/share/applications/liveinst.desktop \ -- cgit v1.2.3 From a00715659960496be8753aa2adc5ec4ec7afbbf1 Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 29 Jul 2026 08:23:02 +0800 Subject: Fix installer update origin Rewrite installed bootc origins to the configured signed registry reference. --- .github/workflows/build-installer-iso.yml | 2 ++ installer/Containerfile | 6 ++++++ installer/build.sh | 11 +++++++++++ just_scripts/build-installer-iso.sh | 2 ++ 4 files changed, 21 insertions(+) diff --git a/.github/workflows/build-installer-iso.yml b/.github/workflows/build-installer-iso.yml index a6348aa..143eafc 100644 --- a/.github/workflows/build-installer-iso.yml +++ b/.github/workflows/build-installer-iso.yml @@ -91,6 +91,8 @@ jobs: --build-arg "BASE_IMAGE=${LIVE_BASE_IMAGE}" \ --build-arg "INSTALL_IMAGE_PAYLOAD=${install_image_ref}:${IMAGE_TAG}" \ --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ + --build-arg "INSTALL_IMAGE_TAG=${IMAGE_TAG}" \ + --build-arg "OSTREE_IMAGE_REF=${ostree_image_ref}" \ --tag localhost/aerocore-os-installer:latest \ --file installer/Containerfile \ . diff --git a/installer/Containerfile b/installer/Containerfile index cf20e4f..32b327e 100644 --- a/installer/Containerfile +++ b/installer/Containerfile @@ -6,6 +6,8 @@ ARG IMAGE_VENDOR=AeroCore-IO ARG IMAGE_NAME=aerocore-os ARG INSTALL_IMAGE_PAYLOAD=ghcr.io/${IMAGE_VENDOR}/${IMAGE_NAME}:stable ARG INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci +ARG INSTALL_IMAGE_TAG=latest +ARG OSTREE_IMAGE_REF=ostree-image-signed:docker://ghcr.io/${IMAGE_VENDOR}/${IMAGE_NAME} FROM ${BASE_IMAGE} @@ -14,10 +16,14 @@ ARG IMAGE_VENDOR ARG IMAGE_NAME ARG INSTALL_IMAGE_PAYLOAD ARG INSTALL_IMAGE_PAYLOAD_ARCHIVE +ARG INSTALL_IMAGE_TAG +ARG OSTREE_IMAGE_REF RUN --mount=type=bind,source=.,target=/src \ --mount=type=bind,source=output/install-payload.oci,target=/install-payload.oci,ro \ env BASE_IMAGE="${BASE_IMAGE}" \ INSTALL_IMAGE_PAYLOAD="${INSTALL_IMAGE_PAYLOAD}" \ INSTALL_IMAGE_PAYLOAD_ARCHIVE="${INSTALL_IMAGE_PAYLOAD_ARCHIVE}" \ + INSTALL_IMAGE_TAG="${INSTALL_IMAGE_TAG}" \ + OSTREE_IMAGE_REF="${OSTREE_IMAGE_REF}" \ /src/installer/build.sh diff --git a/installer/build.sh b/installer/build.sh index 0cc1b8a..3093dcc 100755 --- a/installer/build.sh +++ b/installer/build.sh @@ -6,6 +6,9 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BASE_IMAGE=${BASE_IMAGE:?} INSTALL_IMAGE_PAYLOAD=${INSTALL_IMAGE_PAYLOAD:?} INSTALL_IMAGE_PAYLOAD_ARCHIVE=${INSTALL_IMAGE_PAYLOAD_ARCHIVE:-} +INSTALL_IMAGE_TAG=${INSTALL_IMAGE_TAG:?} +OSTREE_IMAGE_REF=${OSTREE_IMAGE_REF:?} +ostree_origin_ref="${OSTREE_IMAGE_REF}:${INSTALL_IMAGE_TAG}" # The installer is a live KDE environment. Keep the installed system payload # separate: it is the AeroCore image, while BASE_IMAGE provides the live UI. @@ -124,6 +127,14 @@ df -h /var/tmp \${target_tmp} ostreecontainer --url=${INSTALL_IMAGE_PAYLOAD} --transport=containers-storage --no-signature-verification +# The local containers-storage deployment is intentionally unverified because +# the payload is loaded from an OCI archive. Point future bootc updates at the +# signed registry reference configured for the image instead. +%post --erroronfail --log=/tmp/aerocore-origin.log +set -eux +sed -i 's|container-image-reference=.*|container-image-reference=${ostree_origin_ref}|' /ostree/deploy/default/deploy/*.origin +%end + %post --nochroot --log=/tmp/aerocore-hostname.log set -eux target_root= diff --git a/just_scripts/build-installer-iso.sh b/just_scripts/build-installer-iso.sh index abd668f..2b1f7ae 100755 --- a/just_scripts/build-installer-iso.sh +++ b/just_scripts/build-installer-iso.sh @@ -90,6 +90,8 @@ ensure_rootful_image --build-arg "BASE_IMAGE=${live_base_image}" \ --build-arg "INSTALL_IMAGE_PAYLOAD=${payload}" \ --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ + --build-arg "INSTALL_IMAGE_TAG=${image_tag}" \ + --build-arg "OSTREE_IMAGE_REF=${ostree_image_ref}" \ --tag "${payload}" \ --file installer/Containerfile \ . -- cgit v1.2.3 From 5d7a59e2f180bfbe3cd77bb4ba480048a64bfedd Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 29 Jul 2026 14:50:10 +0800 Subject: Align local installer ISO build with CI Use the pinned Titanoboa builder and matching build arguments so just build-installer-iso produces the same media as the GitHub Actions workflow. --- Justfile | 5 ++-- README.md | 7 +++--- just_scripts/build-installer-iso.sh | 49 +++++++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/Justfile b/Justfile index 8161c52..47567b5 100644 --- a/Justfile +++ b/Justfile @@ -14,7 +14,8 @@ export VERSION_PRETTY := env_var_or_default("VERSION_PRETTY", VERSION_TAG) export BASE_IMAGE := env_var_or_default("BASE_IMAGE", "ghcr.io/ublue-os/bazzite-deck:stable") export OSTREE_IMAGE_REF := env_var_or_default("OSTREE_IMAGE_REF", "ostree-image-signed:docker://ghcr.io/" + repo_organization + "/" + image_name) export LIVE_BASE_IMAGE := env_var_or_default("LIVE_BASE_IMAGE", "quay.io/fedora/fedora-kinoite:43") -export INSTALLER_BUILDER_IMAGE := env_var_or_default("INSTALLER_BUILDER_IMAGE", "ghcr.io/jasonn3/build-container-installer:v1.5.0") +export TITANOBOA_REPOSITORY := env_var_or_default("TITANOBOA_REPOSITORY", "https://github.com/Zeglius/titanoboa.git") +export TITANOBOA_REVISION := env_var_or_default("TITANOBOA_REVISION", "7737f4748458252ac827dca14b3d6dd09298472a") export FLATPAK_REMOTE_URL := env_var_or_default("FLATPAK_REMOTE_URL", "") export HOMEBREW_BOTTLE_DOMAIN := env_var_or_default("HOMEBREW_BOTTLE_DOMAIN", "") export HOMEBREW_API_DOMAIN := env_var_or_default("HOMEBREW_API_DOMAIN", "") @@ -38,7 +39,7 @@ alias run-live-installer := run-installer-iso default: @just --list -# Build a Bazzite-style installer ISO +# Build the same Titanoboa-based installer ISO as CI build-installer-iso $target_image=("localhost/" + image_name) $tag=default_tag: @IMAGE_NAME="{{ target_image }}" IMAGE_TAG="{{ tag }}" ./just_scripts/build-installer-iso.sh diff --git a/README.md b/README.md index de33959..6faf2ae 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ just build-installer-iso just run-installer-iso ``` -This requires privileged Podman, a rootful Podman API socket, and roughly -70 GiB of free space. The installer ISO workflow consumes the published -`latest` AeroCore image and uploads the ISO as a GitHub Actions artifact. +This requires privileged Podman, a rootful Podman API socket, `git`, and +roughly 70 GiB of free space. Local ISO generation uses the same pinned +Titanoboa builder as the installer workflow, and writes the ISO plus its +SHA-256 checksum under `output/`. diff --git a/just_scripts/build-installer-iso.sh b/just_scripts/build-installer-iso.sh index 2b1f7ae..3226527 100755 --- a/just_scripts/build-installer-iso.sh +++ b/just_scripts/build-installer-iso.sh @@ -8,7 +8,8 @@ cd "${project_root}" image_name="${IMAGE_NAME:-localhost/$(just image_name)}" image_tag="${IMAGE_TAG:-$(just generate-default-tag)}" live_base_image="${LIVE_BASE_IMAGE:-quay.io/fedora/fedora-kinoite:43}" -installer_builder_image="${INSTALLER_BUILDER_IMAGE:-ghcr.io/jasonn3/build-container-installer:v1.5.0}" +titanoboa_repository="${TITANOBOA_REPOSITORY:-https://github.com/Zeglius/titanoboa.git}" +titanoboa_revision="${TITANOBOA_REVISION:-7737f4748458252ac827dca14b3d6dd09298472a}" source_image="${image_name}:${image_tag}" # Keep the payload in local container storage, but use the public update # reference as its local tag so Anaconda writes that reference as the boot @@ -102,24 +103,34 @@ else sudo rm -f "${iso}" "${checksum}" fi -"${podman_cmd[@]}" run --rm --privileged \ - --volume "${api_socket}:/var/run/docker.sock" \ - --volume /var/lib/containers/storage:/var/lib/containers/storage \ - --volume "${project_root}/output:/build-container-installer/build" \ - --volume "${project_root}/installer/lorax_templates:/additional_lorax_templates:ro" \ - "${installer_builder_image}" \ - ADDITIONAL_TEMPLATES="/additional_lorax_templates/remove_root_password_prompt.tmpl /additional_lorax_templates/set_default_user.tmpl" \ - ARCH="x86_64" \ - ENABLE_CACHE_DNF="false" \ - ENABLE_CACHE_SKOPEO="false" \ - ENABLE_FLATPAK_DEPENDENCIES="false" \ - IMAGE_NAME="aerocore-os-installer" \ - IMAGE_REPO="localhost" \ - IMAGE_SRC="containers-storage:${payload}" \ - IMAGE_TAG="latest" \ - ISO_NAME="build/aerocore-os-${image_tag}-amd64.iso" \ - VARIANT="Kinoite" \ - VERSION="${FEDORA_VERSION:-44}" +tmp_titanoboa="$(mktemp -d -t aerocore-titanoboa.XXXXXXXXXX)" +trap 'rm -rf "${tmp_titanoboa}"' EXIT + +git clone --quiet --filter=blob:none --no-checkout \ + "${titanoboa_repository}" "${tmp_titanoboa}" +git -C "${tmp_titanoboa}" fetch --quiet origin "${titanoboa_revision}" +git -C "${tmp_titanoboa}" checkout --quiet "${titanoboa_revision}" + +# Keep this invocation aligned with Zeglius/titanoboa's GitHub Action: +# `just build IMAGE 1 0 none squashfs "" 1`. +( + cd "${tmp_titanoboa}" + CI=1 TITANOBOA_WORKDIR="${tmp_titanoboa}/work" \ + sudo PATH="${PATH}" just build "${payload}" 1 0 none squashfs "" 1 +) + +titanoboa_iso="${tmp_titanoboa}/output.iso" +if [[ ! -f "${titanoboa_iso}" ]]; then + echo "Titanoboa did not produce ${titanoboa_iso}" >&2 + exit 1 +fi +if [[ "${EUID}" -eq 0 ]]; then + rm -f "${iso}" "${checksum}" + mv "${titanoboa_iso}" "${iso}" +else + sudo rm -f "${iso}" "${checksum}" + sudo mv "${titanoboa_iso}" "${iso}" +fi if [[ -f "${iso}" ]]; then if [[ "${EUID}" -ne 0 ]]; then -- cgit v1.2.3 From 92262d35d08e3a3bbc70d7c3ee61430cde392a13 Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 29 Jul 2026 15:26:08 +0800 Subject: Fix Titanoboa Justfile lookup Run the pinned builder with explicit Justfile and working directory paths under sudo. --- just_scripts/build-installer-iso.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/just_scripts/build-installer-iso.sh b/just_scripts/build-installer-iso.sh index 3226527..4e634a6 100755 --- a/just_scripts/build-installer-iso.sh +++ b/just_scripts/build-installer-iso.sh @@ -115,8 +115,13 @@ git -C "${tmp_titanoboa}" checkout --quiet "${titanoboa_revision}" # `just build IMAGE 1 0 none squashfs "" 1`. ( cd "${tmp_titanoboa}" - CI=1 TITANOBOA_WORKDIR="${tmp_titanoboa}/work" \ - sudo PATH="${PATH}" just build "${payload}" 1 0 none squashfs "" 1 + sudo env \ + CI=1 \ + TITANOBOA_WORKDIR="${tmp_titanoboa}/work" \ + just \ + --justfile "${tmp_titanoboa}/Justfile" \ + --working-directory "${tmp_titanoboa}" \ + build "${payload}" 1 0 none squashfs "" 1 ) titanoboa_iso="${tmp_titanoboa}/output.iso" -- cgit v1.2.3 From db723765acf537ab469473b0a500eae31dc19455 Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 29 Jul 2026 16:20:38 +0800 Subject: Use Titanoboa main script for ISO builds The pinned Titanoboa revision has no Justfile; invoke its GitHub Action entrypoint and collect the generated ISO. --- just_scripts/build-installer-iso.sh | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/just_scripts/build-installer-iso.sh b/just_scripts/build-installer-iso.sh index 4e634a6..0aacf43 100755 --- a/just_scripts/build-installer-iso.sh +++ b/just_scripts/build-installer-iso.sh @@ -111,22 +111,20 @@ git clone --quiet --filter=blob:none --no-checkout \ git -C "${tmp_titanoboa}" fetch --quiet origin "${titanoboa_revision}" git -C "${tmp_titanoboa}" checkout --quiet "${titanoboa_revision}" -# Keep this invocation aligned with Zeglius/titanoboa's GitHub Action: -# `just build IMAGE 1 0 none squashfs "" 1`. +# Keep this invocation aligned with the pinned revision's GitHub Action. +# This revision exposes main.sh rather than a Justfile. ( cd "${tmp_titanoboa}" - sudo env \ + env \ CI=1 \ - TITANOBOA_WORKDIR="${tmp_titanoboa}/work" \ - just \ - --justfile "${tmp_titanoboa}/Justfile" \ - --working-directory "${tmp_titanoboa}" \ - build "${payload}" 1 0 none squashfs "" 1 + TITANOBOA_CTR_IMAGE="${payload}" \ + TITANOBOA_OUTPUT_DIR="${tmp_titanoboa}/output" \ + "${tmp_titanoboa}/main.sh" ) -titanoboa_iso="${tmp_titanoboa}/output.iso" +titanoboa_iso="$(find "${tmp_titanoboa}/output" -maxdepth 1 -type f -name '*.iso' -print -quit)" if [[ ! -f "${titanoboa_iso}" ]]; then - echo "Titanoboa did not produce ${titanoboa_iso}" >&2 + echo "Titanoboa did not produce an ISO in ${tmp_titanoboa}/output" >&2 exit 1 fi if [[ "${EUID}" -eq 0 ]]; then -- cgit v1.2.3 From 40a5f50c69ec323c7c5d92f6357a9774017f67a1 Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 29 Jul 2026 17:05:41 +0800 Subject: Fix weak password crash in Live installer Restore the Cockpit force-password behavior embedded in Fedora 43's Anaconda WebUI bundle. Apply strict password policy through conf.d so weak passwords remain a form validation error instead of aborting the installer. --- .github/workflows/validate-installer-iso.yml | 11 +++++ installer/build.sh | 5 +++ installer/patch-anaconda-webui.sh | 47 ++++++++++++++++++++++ .../etc/anaconda/conf.d/99-aerocore-password.conf | 5 +++ 4 files changed, 68 insertions(+) create mode 100755 installer/patch-anaconda-webui.sh create mode 100644 installer/system_files/overrides/etc/anaconda/conf.d/99-aerocore-password.conf diff --git a/.github/workflows/validate-installer-iso.yml b/.github/workflows/validate-installer-iso.yml index 391afd8..a93e9cd 100644 --- a/.github/workflows/validate-installer-iso.yml +++ b/.github/workflows/validate-installer-iso.yml @@ -39,6 +39,17 @@ jobs: done bash -n system_files/usr/libexec/aerocore-instruments-setup + - name: Validate Anaconda WebUI patch + run: | + fixture="$(mktemp)" + trap 'rm -f "${fixture}"' EXIT + printf '%s' 'n===0?r(new Error(X2("Password is too weak"))):o(' | + gzip -n > "${fixture}" + installer/patch-anaconda-webui.sh "${fixture}" + gzip -dc "${fixture}" | + grep -Fq 'n===0&&!e?r(new Error(X2("Password is too weak"))):o(' + installer/patch-anaconda-webui.sh "${fixture}" + - name: Validate installer polkit rules run: | for rule in installer/system_files/overrides/etc/polkit-1/rules.d/*.rules; do diff --git a/installer/build.sh b/installer/build.sh index 3093dcc..4535113 100755 --- a/installer/build.sh +++ b/installer/build.sh @@ -31,6 +31,11 @@ dnf --setopt=excludepkgs= reinstall -y \ grub2-efi-x64 \ grub2-efi-x64-cdboot +# Fedora 43's anaconda-webui bundle embeds a Cockpit password helper from +# before cockpit-project/cockpit@900c13f. Restore that upstream fix so a weak +# pwscore result is returned as score 0 instead of rejecting the WebUI promise. +"${SCRIPT_DIR}/patch-anaconda-webui.sh" + # Apply the same AeroCore overlay to the live session where possible. if [[ -d /src/system_files ]]; then cp -a /src/system_files/. / diff --git a/installer/patch-anaconda-webui.sh b/installer/patch-anaconda-webui.sh new file mode 100755 index 0000000..2f61516 --- /dev/null +++ b/installer/patch-anaconda-webui.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +set -euo pipefail + +bundle="${1:-/usr/share/cockpit/anaconda-webui/index.js.gz}" +broken='n===0?r(new Error(X2("Password is too weak"))):o(' +fixed='n===0&&!e?r(new Error(X2("Password is too weak"))):o(' +fixed_sed='n===0\&\&!e?r(new Error(X2("Password is too weak"))):o(' + +if [[ ! -f "${bundle}" ]]; then + echo "Anaconda WebUI bundle not found: ${bundle}" >&2 + exit 1 +fi + +webui_js="$(mktemp)" +patched_js="$(mktemp)" +patched_bundle="$(mktemp)" +trap 'rm -f "${webui_js}" "${patched_js}" "${patched_bundle}"' EXIT + +gzip -dc "${bundle}" > "${webui_js}" + +fixed_count="$( (grep -oF "${fixed}" "${webui_js}" || true) | wc -l | tr -d ' ')" +if [[ "${fixed_count}" == "1" ]]; then + echo "Anaconda WebUI weak-password handling is already fixed" + exit 0 +fi + +broken_count="$( (grep -oF "${broken}" "${webui_js}" || true) | wc -l | tr -d ' ')" +if [[ "${broken_count}" != "1" ]]; then + echo "Unexpected Anaconda WebUI password helper; refusing an unsafe patch" >&2 + echo "Expected one weak-password rejection, found ${broken_count}" >&2 + exit 1 +fi + +sed "s|${broken}|${fixed_sed}|" "${webui_js}" > "${patched_js}" + +fixed_count="$( (grep -oF "${fixed}" "${patched_js}" || true) | wc -l | tr -d ' ')" +if [[ "${fixed_count}" != "1" ]] || grep -Fq "${broken}" "${patched_js}"; then + echo "Failed to patch Anaconda WebUI weak-password handling" >&2 + exit 1 +fi + +gzip -n -9 -c "${patched_js}" > "${patched_bundle}" +chmod 0644 "${patched_bundle}" +mv -f "${patched_bundle}" "${bundle}" + +echo "Patched Anaconda WebUI weak-password handling" diff --git a/installer/system_files/overrides/etc/anaconda/conf.d/99-aerocore-password.conf b/installer/system_files/overrides/etc/anaconda/conf.d/99-aerocore-password.conf new file mode 100644 index 0000000..3105934 --- /dev/null +++ b/installer/system_files/overrides/etc/anaconda/conf.d/99-aerocore-password.conf @@ -0,0 +1,5 @@ +[User Interface] +password_policies = + root (quality 1, length 6, strict) + user (quality 1, length 6, empty, strict) + luks (quality 1, length 6) -- cgit v1.2.3 From e69afd001ef776c5acf1f928e912d4ebf175ef23 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Jul 2026 19:54:24 +0000 Subject: chore(deps): bump docker/login-action from 4.5.1 to 4.5.2 Bumps [docker/login-action](https://github.com/docker/login-action) from 4.5.1 to 4.5.2. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/abd2ef45e78c5afb21d64d4ca52ee8550d9572c7...371161bbe7024a29a25c5e19bfcbc0804fe9ad2c) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.5.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3c8cc06..832b9fa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -167,7 +167,7 @@ jobs: # These `if` statements keep pull requests from publishing packages. # They publish default-branch builds and manual testing branch builds. - name: Login to GitHub Container Registry - uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1 + uses: docker/login-action@371161bbe7024a29a25c5e19bfcbc0804fe9ad2c # v4.5.2 if: github.event_name != 'pull_request' && (github.ref_name == github.event.repository.default_branch || github.ref_name == 'testing') with: registry: ghcr.io -- cgit v1.2.3 From 679bde461b2057d0c5e207daf1aca4c2d1c6080b Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 5 Aug 2026 06:50:26 +0800 Subject: Align ISO workflow live naming Match Bazzite's live ISO workflow label and output filename while keeping local build and run helpers pointed at the same artifact. --- .github/workflows/build-installer-iso.yml | 12 ++++++------ Justfile | 6 +++--- README.md | 4 ++-- just_scripts/build-installer-iso.sh | 2 +- just_scripts/run-installer-iso.sh | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build-installer-iso.yml b/.github/workflows/build-installer-iso.yml index 143eafc..1352080 100644 --- a/.github/workflows/build-installer-iso.yml +++ b/.github/workflows/build-installer-iso.yml @@ -1,4 +1,4 @@ -name: Build installer ISO +name: Build Live ISOs on: workflow_dispatch: @@ -18,7 +18,7 @@ concurrency: jobs: build-installer-iso: - name: Build KDE installer ISO + name: Build KDE live ISO runs-on: ubuntu-24.04 permissions: contents: read @@ -102,13 +102,13 @@ jobs: uses: Zeglius/titanoboa@7737f4748458252ac827dca14b3d6dd09298472a # revamp-pr with: image-ref: localhost/aerocore-os-installer:latest - iso-dest: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-amd64.iso + iso-dest: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-live-amd64.iso - name: Normalize ISO output path shell: bash env: GENERATED_ISO: ${{ steps.build.outputs.iso-dest }} - EXPECTED_ISO: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-amd64.iso + EXPECTED_ISO: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-live-amd64.iso run: | if [[ ! -f "${GENERATED_ISO}" ]]; then echo "::error::Generated ISO does not exist at ${GENERATED_ISO}" @@ -123,7 +123,7 @@ jobs: shell: bash run: | set -o pipefail - iso_path="output/aerocore-os-${ISO_FILE_TAG}-amd64.iso" + iso_path="output/aerocore-os-${ISO_FILE_TAG}-live-amd64.iso" checksum_path="${iso_path}-CHECKSUM" sha256sum "${iso_path}" | tee "${checksum_path}" { @@ -141,7 +141,7 @@ jobs: shell: bash run: | iso_upload_dir="${{ github.workspace }}/output/upload" - iso_path="${{ github.workspace }}/output/aerocore-os-${ISO_FILE_TAG}-amd64.iso" + iso_path="${{ github.workspace }}/output/aerocore-os-${ISO_FILE_TAG}-live-amd64.iso" iso_name="$(basename "${iso_path}")" mkdir -p "${iso_upload_dir}" diff --git a/Justfile b/Justfile index 47567b5..b8d0be9 100644 --- a/Justfile +++ b/Justfile @@ -29,7 +29,7 @@ alias rebuild-vm := rebuild-qcow2 alias run-vm := run-vm-qcow2 alias build-installer := build-installer-iso alias run-installer := run-installer-iso -# Backward-compatible aliases; these refer to the installer ISO, not a Live OS. +# Backward-compatible aliases for the Titanoboa live ISO build. alias build-live-iso := build-installer-iso alias run-live-iso := run-installer-iso alias build-live-installer := build-installer-iso @@ -39,11 +39,11 @@ alias run-live-installer := run-installer-iso default: @just --list -# Build the same Titanoboa-based installer ISO as CI +# Build the same Titanoboa-based live ISO as CI build-installer-iso $target_image=("localhost/" + image_name) $tag=default_tag: @IMAGE_NAME="{{ target_image }}" IMAGE_TAG="{{ tag }}" ./just_scripts/build-installer-iso.sh -# Boot the installer ISO with QEMU +# Boot the live ISO with QEMU run-installer-iso: @./just_scripts/run-installer-iso.sh diff --git a/README.md b/README.md index 6faf2ae..213e029 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ BASE_IMAGE=ghcr.io/ublue-os/bazzite-deck:testing just build ``` -To build the Bazzite-style installer ISO locally, first build the AeroCore +To build the Bazzite-style live ISO locally, first build the AeroCore image and then run: ```bash @@ -66,5 +66,5 @@ just run-installer-iso This requires privileged Podman, a rootful Podman API socket, `git`, and roughly 70 GiB of free space. Local ISO generation uses the same pinned -Titanoboa builder as the installer workflow, and writes the ISO plus its +Titanoboa builder as the live ISO workflow, and writes the ISO plus its SHA-256 checksum under `output/`. diff --git a/just_scripts/build-installer-iso.sh b/just_scripts/build-installer-iso.sh index 0aacf43..3353651 100755 --- a/just_scripts/build-installer-iso.sh +++ b/just_scripts/build-installer-iso.sh @@ -23,7 +23,7 @@ install_image_ref="${install_image_ref#docker://}" payload="${install_image_ref}:${image_tag}" output_dir="${project_root}/output" payload_archive="${output_dir}/install-payload.oci" -iso="${output_dir}/aerocore-os-${image_tag}-amd64.iso" +iso="${output_dir}/aerocore-os-${image_tag}-live-amd64.iso" checksum="${iso}-CHECKSUM" api_socket="${PODMAN_SOCKET:-/run/podman/podman.sock}" if [[ "${EUID}" -eq 0 ]]; then diff --git a/just_scripts/run-installer-iso.sh b/just_scripts/run-installer-iso.sh index 2c49164..c495215 100755 --- a/just_scripts/run-installer-iso.sh +++ b/just_scripts/run-installer-iso.sh @@ -6,7 +6,7 @@ project_root="$(git rev-parse --show-toplevel)" cd "${project_root}" image_tag="${IMAGE_TAG:-$(just generate-default-tag)}" -iso="${project_root}/output/aerocore-os-${image_tag}-amd64.iso" +iso="${project_root}/output/aerocore-os-${image_tag}-live-amd64.iso" if [[ ! -f "${iso}" ]]; then just build-installer-iso -- cgit v1.2.3 From 3b40fd8b92a0749a72db27439402c53d51824247 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Aug 2026 19:54:44 +0000 Subject: chore(deps): bump docker/login-action from 4.5.2 to 4.6.0 Bumps [docker/login-action](https://github.com/docker/login-action) from 4.5.2 to 4.6.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/371161bbe7024a29a25c5e19bfcbc0804fe9ad2c...dbcb813823bdd20940b903addbd779551569679f) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.6.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 832b9fa..0596fab 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -167,7 +167,7 @@ jobs: # These `if` statements keep pull requests from publishing packages. # They publish default-branch builds and manual testing branch builds. - name: Login to GitHub Container Registry - uses: docker/login-action@371161bbe7024a29a25c5e19bfcbc0804fe9ad2c # v4.5.2 + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 if: github.event_name != 'pull_request' && (github.ref_name == github.event.repository.default_branch || github.ref_name == 'testing') with: registry: ghcr.io -- cgit v1.2.3 From cfe590548b967437963cee15e4c00dda9aff71d5 Mon Sep 17 00:00:00 2001 From: tranch Date: Fri, 14 Aug 2026 11:58:13 +0800 Subject: Enable HDMI CEC sleep standby by default --- build_files/build.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/build_files/build.sh b/build_files/build.sh index 03adff0..5618d20 100755 --- a/build_files/build.sh +++ b/build_files/build.sh @@ -14,6 +14,20 @@ esac # Copy the contents of system_files/ of the git repo to / cp -avf "/ctx/system_files"/. / +# Default HDMI-CEC to putting the TV into standby when the system sleeps. +# `ujust toggle-cec-sleep enable` changes this same setting at runtime. Keep +# the default in the base image's config so users do not need to run the +# command manually after a fresh install; the runtime command can still +# change it later. +CEC_CONFIG=/etc/default/cec-control +if [[ -f "${CEC_CONFIG}" ]]; then + if grep -q '^CEC_ONSLEEP_STANDBY=' "${CEC_CONFIG}"; then + sed -i 's/^CEC_ONSLEEP_STANDBY=.*/CEC_ONSLEEP_STANDBY=true/' "${CEC_CONFIG}" + else + printf '%s\n' 'CEC_ONSLEEP_STANDBY=true' >> "${CEC_CONFIG}" + fi +fi + mkdir -p /etc/environment.d if [[ -n "${FLATPAK_REMOTE_URL:-}" || -n "${HOMEBREW_BOTTLE_DOMAIN:-}" || -n "${HOMEBREW_API_DOMAIN:-}" ]]; then -- cgit v1.2.3 From 89e4f1b83d1ac140aedc1f17e350396e7e2c67c5 Mon Sep 17 00:00:00 2001 From: tranch Date: Thu, 20 Aug 2026 07:20:09 +0800 Subject: ci: create GitHub release after image build --- .github/workflows/build.yml | 21 ++++++++++++++ .github/workflows/generate_release.yml | 51 ++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 .github/workflows/generate_release.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 832b9fa..6ff5963 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,11 @@ on: #schedule: # - cron: '05 10 * * *' # 10:05am UTC everyday workflow_dispatch: + inputs: + handwritten: + description: "Small changelog about changes in this build" + required: false + type: string env: IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit @@ -20,6 +25,8 @@ jobs: build_push: name: Build and push image runs-on: ubuntu-24.04 + outputs: + release_tag: ${{ steps.gen-version.outputs.release_tag }} permissions: contents: read @@ -105,6 +112,8 @@ jobs: echo "ALIAS_TAGS=${ALIAS_TAGS}" } >> "$GITHUB_ENV" + echo "release_tag=${VERSION_TAG}" >> "$GITHUB_OUTPUT" + - name: Prepare environment run: | # Lowercase the image uri https://github.com/macbre/push-to-ghcr/issues/12 @@ -211,3 +220,15 @@ jobs: DIGEST: ${{ steps.push-image.outputs.digest }} run: | cosign sign -y --key env://COSIGN_PRIVATE_KEY "${IMAGE_REGISTRY}/${IMAGE_NAME}@${DIGEST}" + + generate_release: + name: Generate Release + needs: [build_push] + if: github.event_name != 'pull_request' + permissions: + contents: write + secrets: inherit + uses: ./.github/workflows/generate_release.yml + with: + release_tag: ${{ needs.build_push.outputs.release_tag }} + handwritten: ${{ inputs.handwritten }} diff --git a/.github/workflows/generate_release.yml b/.github/workflows/generate_release.yml new file mode 100644 index 0000000..ff6ef1e --- /dev/null +++ b/.github/workflows/generate_release.yml @@ -0,0 +1,51 @@ +name: Generate Release + +on: + workflow_call: + inputs: + handwritten: + required: false + type: string + release_tag: + required: true + type: string + workflow_dispatch: + inputs: + handwritten: + description: 'Small changelog about changes in this build' + required: false + type: string + release_tag: + required: true + type: string + +permissions: {} + +jobs: + generate-release: + runs-on: ubuntu-24.04 + permissions: + contents: write + + + steps: + - uses: actions/checkout@v7.0.1 + with: + fetch-depth: 50 + + - name: Determine release channel + id: target + run: | + target="${GITHUB_REF_NAME}" + [[ "${target}" == "main" ]] && target="stable" + echo "target=${target}" >> "$GITHUB_OUTPUT" + + - name: Generate release + uses: softprops/action-gh-release@v3.0.2 + with: + tag_name: "${{ inputs.release_tag }}" + name: "AeroCore OS ${{ inputs.release_tag }}" + body: | + ${{ inputs.handwritten }} + prerelease: ${{ steps.target.outputs.target != 'stable' }} + make_latest: ${{ steps.target.outputs.target == 'stable' }} -- cgit v1.2.3 From 7746ea13756b55b3a2ac376927c02aea5e7f07a9 Mon Sep 17 00:00:00 2001 From: tranch Date: Thu, 20 Aug 2026 07:23:32 +0800 Subject: ci: restrict release creation branches --- .github/workflows/build.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6ff5963..b42fd60 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -224,7 +224,9 @@ jobs: generate_release: name: Generate Release needs: [build_push] - if: github.event_name != 'pull_request' + if: github.event_name != 'pull_request' && + (github.ref_name == github.event.repository.default_branch || + github.ref_name == 'testing') permissions: contents: write secrets: inherit -- cgit v1.2.3 From a7963fca79e92def67fec32d3b58cb834fb6b47f Mon Sep 17 00:00:00 2001 From: tranch Date: Thu, 20 Aug 2026 09:53:57 +0800 Subject: fix(release): Use tag name for release title The release title should reflect the tag name, not include "AeroCore OS". This change updates the `generate_release.yml` workflow to use the tag name directly for the release title. Co-authored-by: llm-git --- .github/workflows/generate_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/generate_release.yml b/.github/workflows/generate_release.yml index ff6ef1e..f741c83 100644 --- a/.github/workflows/generate_release.yml +++ b/.github/workflows/generate_release.yml @@ -44,7 +44,7 @@ jobs: uses: softprops/action-gh-release@v3.0.2 with: tag_name: "${{ inputs.release_tag }}" - name: "AeroCore OS ${{ inputs.release_tag }}" + name: "${{ inputs.release_tag }}" body: | ${{ inputs.handwritten }} prerelease: ${{ steps.target.outputs.target != 'stable' }} -- cgit v1.2.3 From a6a27050efa50c444816905a4c628adc68e8dd12 Mon Sep 17 00:00:00 2001 From: tranch Date: Mon, 14 Sep 2026 00:12:41 +0800 Subject: fix release changelog for unrelated histories --- .github/scripts/generate_changelog.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/.github/scripts/generate_changelog.py b/.github/scripts/generate_changelog.py index 57f7ba9..c4ea8a2 100644 --- a/.github/scripts/generate_changelog.py +++ b/.github/scripts/generate_changelog.py @@ -109,11 +109,25 @@ def main() -> None: previous_info = image_info(args.image, previous) if previous else {} start_revision = previous_info.get("Labels", {}).get("org.opencontainers.image.revision") end_revision = current_info.get("Labels", {}).get("org.opencontainers.image.revision") - commits = ( - run("git", "log", "--format=%H%x09%s%x09%an", f"{start_revision}..{end_revision}").splitlines() - if start_revision and end_revision - else [] - ) + commits: list[str] = [] + if start_revision and end_revision: + try: + commits = run( + "git", + "log", + "--format=%H%x09%s%x09%an", + f"{start_revision}..{end_revision}", + ).splitlines() + except subprocess.CalledProcessError as error: + # A release may be built after histories are intentionally joined + # or rewritten. In that case the previous image revision can be + # valid metadata but not a reachable Git revision in this checkout. + # Package changes and the release itself remain valid, so omit the + # commit section instead of failing the whole release job. + print( + "Warning: unable to determine commit range " + f"{start_revision}..{end_revision}: {error}" + ) lines = [args.handwritten.strip() or f"This is an automatically generated changelog for release `{args.current}`.", ""] if previous: -- cgit v1.2.3 From 3f7496d580f185c0974c5edc107570c471d0cdde Mon Sep 17 00:00:00 2001 From: tranch Date: Mon, 28 Sep 2026 11:14:04 +0800 Subject: Align Live and installer ISO commands Use build-live-iso for the Titanoboa Live ISO workflow and build-installer-iso for bootc-image-builder installer ISO images. Rename the associated workflow and build script, and update local run instructions accordingly. --- .github/workflows/build-installer-iso.yml | 167 ---------------------------- .github/workflows/build-live-iso.yml | 167 ++++++++++++++++++++++++++++ Justfile | 11 +- README.md | 2 +- just_scripts/build-installer-iso.sh | 174 ------------------------------ just_scripts/build-live-iso.sh | 174 ++++++++++++++++++++++++++++++ just_scripts/run-installer-iso.sh | 2 +- 7 files changed, 348 insertions(+), 349 deletions(-) delete mode 100644 .github/workflows/build-installer-iso.yml create mode 100644 .github/workflows/build-live-iso.yml delete mode 100755 just_scripts/build-installer-iso.sh create mode 100755 just_scripts/build-live-iso.sh diff --git a/.github/workflows/build-installer-iso.yml b/.github/workflows/build-installer-iso.yml deleted file mode 100644 index da3ef10..0000000 --- a/.github/workflows/build-installer-iso.yml +++ /dev/null @@ -1,167 +0,0 @@ -name: Build Live ISOs - -on: - workflow_dispatch: - inputs: - image_tag: - description: "AeroCore image tag to install" - required: false - default: latest - type: string - workflow_call: - -permissions: {} - -concurrency: - group: ${{ github.workflow }}-${{ github.ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-installer-iso: - name: Build KDE live ISO - runs-on: ubuntu-24.04 - permissions: - contents: read - packages: read - - env: - IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} - IMAGE_NAME: ${{ vars.IMAGE_NAME || github.event.repository.name }} - IMAGE_TAG: ${{ inputs.image_tag || 'latest' }} - ISO_FILE_TAG: ${{ github.ref_name == 'testing' && 'testing' || (inputs.image_tag || 'latest') }} - # Keep these aligned with the Fedora major used by the target bazzite-deck base image. - LIVE_BASE_IMAGE: quay.io/fedora/fedora-kinoite:44 - FEDORA_VERSION: "44" - OSTREE_IMAGE_REF: ${{ vars.OSTREE_IMAGE_REF }} - - steps: - - name: Maximize build space - uses: ublue-os/remove-unwanted-software@cc0becac701cf642c8f0a6613bbdaf5dc36b259e # v9 - with: - remove-codeql: true - - - name: Mount container storage BTRFS loopback - run: | - sudo truncate -s 70G /mnt/podman-storage.img - sudo mkfs.btrfs -f /mnt/podman-storage.img - sudo podman system reset --force - sudo systemctl stop podman.service - sudo mount -o compress-force=zstd:2 /mnt/podman-storage.img /var/lib/containers/storage - sudo systemctl start podman.service - - - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - - - name: Prepare image references - run: | - image_name="${IMAGE_NAME,,}" - image_registry="${IMAGE_REGISTRY,,}" - echo "IMAGE_NAME=${image_name,,}" >> "$GITHUB_ENV" - echo "IMAGE_REGISTRY=${image_registry}" >> "$GITHUB_ENV" - - - name: Login to GHCR - run: | - echo '${{ secrets.GITHUB_TOKEN }}' | sudo podman login ghcr.io \ - --username '${{ github.actor }}' --password-stdin - - - name: Pull AeroCore install image - run: | - sudo podman pull "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" - - - name: Build installer ISO payload - run: | - mkdir -p output - ostree_image_ref="${OSTREE_IMAGE_REF:-ostree-image-signed:docker://${IMAGE_REGISTRY}/${IMAGE_NAME}}" - install_image_ref="${ostree_image_ref#ostree-image-signed:docker://}" - install_image_ref="${install_image_ref#ostree-unverified-registry:docker://}" - install_image_ref="${install_image_ref#docker://}" - sudo podman tag \ - "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" \ - "${install_image_ref}:${IMAGE_TAG}" - sudo podman save \ - --format oci-archive \ - --output output/install-payload.oci \ - "${install_image_ref}:${IMAGE_TAG}" - - sudo podman build \ - --cap-add sys_admin \ - --security-opt label=disable \ - --build-arg "BASE_IMAGE=${LIVE_BASE_IMAGE}" \ - --build-arg "INSTALL_IMAGE_PAYLOAD=${install_image_ref}:${IMAGE_TAG}" \ - --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ - --build-arg "INSTALL_IMAGE_TAG=${IMAGE_TAG}" \ - --build-arg "OSTREE_IMAGE_REF=${ostree_image_ref}" \ - --tag localhost/aerocore-os-installer:latest \ - --file installer/Containerfile \ - . - - - name: Build ISO - id: build - uses: Zeglius/titanoboa@7737f4748458252ac827dca14b3d6dd09298472a # revamp-pr - with: - image-ref: localhost/aerocore-os-installer:latest - iso-dest: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-live-amd64.iso - - - name: Normalize ISO output path - shell: bash - env: - GENERATED_ISO: ${{ steps.build.outputs.iso-dest }} - EXPECTED_ISO: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-live-amd64.iso - run: | - if [[ ! -f "${GENERATED_ISO}" ]]; then - echo "::error::Generated ISO does not exist at ${GENERATED_ISO}" - exit 1 - fi - if [[ "${GENERATED_ISO}" != "${EXPECTED_ISO}" ]]; then - mkdir -p "$(dirname "${EXPECTED_ISO}")" - mv "${GENERATED_ISO}" "${EXPECTED_ISO}" - fi - - - name: Display checksum - shell: bash - run: | - set -o pipefail - iso_path="output/aerocore-os-${ISO_FILE_TAG}-live-amd64.iso" - checksum_path="${iso_path}-CHECKSUM" - sha256sum "${iso_path}" | tee "${checksum_path}" - { - echo "# ISO Checksum (SHA256)" - echo - echo "ISO: $(basename "${iso_path}")" - echo - echo '```' - cat "${checksum_path}" - echo '```' - } >> "$GITHUB_STEP_SUMMARY" - - - name: Move ISO to upload directory - id: upload-directory - shell: bash - run: | - iso_upload_dir="${{ github.workspace }}/output/upload" - iso_path="${{ github.workspace }}/output/aerocore-os-${ISO_FILE_TAG}-live-amd64.iso" - iso_name="$(basename "${iso_path}")" - - mkdir -p "${iso_upload_dir}" - mv "${iso_path}" "${iso_upload_dir}/" - ( - cd "${iso_upload_dir}" - sha256sum "${iso_name}" | tee "${iso_name}-CHECKSUM" - ) - echo "iso-upload-dir=${iso_upload_dir}" >> "$GITHUB_OUTPUT" - - - name: Upload ISO and checksum to R2 - if: github.event_name == 'workflow_dispatch' && (github.ref_name == 'main' || github.ref_name == 'testing') - shell: bash - env: - RCLONE_CONFIG_R2_TYPE: s3 - RCLONE_CONFIG_R2_PROVIDER: Cloudflare - RCLONE_CONFIG_R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} - RCLONE_CONFIG_R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} - RCLONE_CONFIG_R2_REGION: auto - RCLONE_CONFIG_R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }} - SOURCE_DIR: ${{ steps.upload-directory.outputs.iso-upload-dir }} - run: | - sudo apt-get update - sudo apt-get install -y rclone - rclone copy "$SOURCE_DIR" R2:bazzite diff --git a/.github/workflows/build-live-iso.yml b/.github/workflows/build-live-iso.yml new file mode 100644 index 0000000..a364f6c --- /dev/null +++ b/.github/workflows/build-live-iso.yml @@ -0,0 +1,167 @@ +name: Build Live ISOs + +on: + workflow_dispatch: + inputs: + image_tag: + description: "AeroCore image tag to install" + required: false + default: latest + type: string + workflow_call: + +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + build-live-iso: + name: Build KDE live ISO + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: read + + env: + IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} + IMAGE_NAME: ${{ vars.IMAGE_NAME || github.event.repository.name }} + IMAGE_TAG: ${{ inputs.image_tag || 'latest' }} + ISO_FILE_TAG: ${{ github.ref_name == 'testing' && 'testing' || (inputs.image_tag || 'latest') }} + # Keep these aligned with the Fedora major used by the target bazzite-deck base image. + LIVE_BASE_IMAGE: quay.io/fedora/fedora-kinoite:44 + FEDORA_VERSION: "44" + OSTREE_IMAGE_REF: ${{ vars.OSTREE_IMAGE_REF }} + + steps: + - name: Maximize build space + uses: ublue-os/remove-unwanted-software@cc0becac701cf642c8f0a6613bbdaf5dc36b259e # v9 + with: + remove-codeql: true + + - name: Mount container storage BTRFS loopback + run: | + sudo truncate -s 70G /mnt/podman-storage.img + sudo mkfs.btrfs -f /mnt/podman-storage.img + sudo podman system reset --force + sudo systemctl stop podman.service + sudo mount -o compress-force=zstd:2 /mnt/podman-storage.img /var/lib/containers/storage + sudo systemctl start podman.service + + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + + - name: Prepare image references + run: | + image_name="${IMAGE_NAME,,}" + image_registry="${IMAGE_REGISTRY,,}" + echo "IMAGE_NAME=${image_name,,}" >> "$GITHUB_ENV" + echo "IMAGE_REGISTRY=${image_registry}" >> "$GITHUB_ENV" + + - name: Login to GHCR + run: | + echo '${{ secrets.GITHUB_TOKEN }}' | sudo podman login ghcr.io \ + --username '${{ github.actor }}' --password-stdin + + - name: Pull AeroCore install image + run: | + sudo podman pull "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" + + - name: Build installer ISO payload + run: | + mkdir -p output + ostree_image_ref="${OSTREE_IMAGE_REF:-ostree-image-signed:docker://${IMAGE_REGISTRY}/${IMAGE_NAME}}" + install_image_ref="${ostree_image_ref#ostree-image-signed:docker://}" + install_image_ref="${install_image_ref#ostree-unverified-registry:docker://}" + install_image_ref="${install_image_ref#docker://}" + sudo podman tag \ + "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" \ + "${install_image_ref}:${IMAGE_TAG}" + sudo podman save \ + --format oci-archive \ + --output output/install-payload.oci \ + "${install_image_ref}:${IMAGE_TAG}" + + sudo podman build \ + --cap-add sys_admin \ + --security-opt label=disable \ + --build-arg "BASE_IMAGE=${LIVE_BASE_IMAGE}" \ + --build-arg "INSTALL_IMAGE_PAYLOAD=${install_image_ref}:${IMAGE_TAG}" \ + --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ + --build-arg "INSTALL_IMAGE_TAG=${IMAGE_TAG}" \ + --build-arg "OSTREE_IMAGE_REF=${ostree_image_ref}" \ + --tag localhost/aerocore-os-installer:latest \ + --file installer/Containerfile \ + . + + - name: Build ISO + id: build + uses: Zeglius/titanoboa@7737f4748458252ac827dca14b3d6dd09298472a # revamp-pr + with: + image-ref: localhost/aerocore-os-installer:latest + iso-dest: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-live-amd64.iso + + - name: Normalize ISO output path + shell: bash + env: + GENERATED_ISO: ${{ steps.build.outputs.iso-dest }} + EXPECTED_ISO: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-live-amd64.iso + run: | + if [[ ! -f "${GENERATED_ISO}" ]]; then + echo "::error::Generated ISO does not exist at ${GENERATED_ISO}" + exit 1 + fi + if [[ "${GENERATED_ISO}" != "${EXPECTED_ISO}" ]]; then + mkdir -p "$(dirname "${EXPECTED_ISO}")" + mv "${GENERATED_ISO}" "${EXPECTED_ISO}" + fi + + - name: Display checksum + shell: bash + run: | + set -o pipefail + iso_path="output/aerocore-os-${ISO_FILE_TAG}-live-amd64.iso" + checksum_path="${iso_path}-CHECKSUM" + sha256sum "${iso_path}" | tee "${checksum_path}" + { + echo "# ISO Checksum (SHA256)" + echo + echo "ISO: $(basename "${iso_path}")" + echo + echo '```' + cat "${checksum_path}" + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + + - name: Move ISO to upload directory + id: upload-directory + shell: bash + run: | + iso_upload_dir="${{ github.workspace }}/output/upload" + iso_path="${{ github.workspace }}/output/aerocore-os-${ISO_FILE_TAG}-live-amd64.iso" + iso_name="$(basename "${iso_path}")" + + mkdir -p "${iso_upload_dir}" + mv "${iso_path}" "${iso_upload_dir}/" + ( + cd "${iso_upload_dir}" + sha256sum "${iso_name}" | tee "${iso_name}-CHECKSUM" + ) + echo "iso-upload-dir=${iso_upload_dir}" >> "$GITHUB_OUTPUT" + + - name: Upload ISO and checksum to R2 + if: github.event_name == 'workflow_dispatch' && (github.ref_name == 'main' || github.ref_name == 'testing') + shell: bash + env: + RCLONE_CONFIG_R2_TYPE: s3 + RCLONE_CONFIG_R2_PROVIDER: Cloudflare + RCLONE_CONFIG_R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} + RCLONE_CONFIG_R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} + RCLONE_CONFIG_R2_REGION: auto + RCLONE_CONFIG_R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }} + SOURCE_DIR: ${{ steps.upload-directory.outputs.iso-upload-dir }} + run: | + sudo apt-get update + sudo apt-get install -y rclone + rclone copy "$SOURCE_DIR" R2:bazzite diff --git a/Justfile b/Justfile index a83ba0a..3e744ee 100644 --- a/Justfile +++ b/Justfile @@ -30,9 +30,8 @@ alias run-vm := run-vm-qcow2 alias build-installer := build-installer-iso alias run-installer := run-installer-iso # Backward-compatible aliases for the Titanoboa live ISO build. -alias build-live-iso := build-installer-iso +alias build-live-installer := build-live-iso alias run-live-iso := run-installer-iso -alias build-live-installer := build-installer-iso alias run-live-installer := run-installer-iso [private] @@ -40,8 +39,8 @@ default: @just --list # Build the same Titanoboa-based live ISO as CI -build-installer-iso $target_image=("localhost/" + image_name) $tag=default_tag: - @IMAGE_NAME="{{ target_image }}" IMAGE_TAG="{{ tag }}" ./just_scripts/build-installer-iso.sh +build-live-iso $target_image=("localhost/" + image_name) $tag=default_tag: + @IMAGE_NAME="{{ target_image }}" IMAGE_TAG="{{ tag }}" ./just_scripts/build-live-iso.sh # Boot the live ISO with QEMU run-installer-iso: @@ -385,9 +384,9 @@ build-qcow2 $target_image=("localhost/" + image_name) $tag=default_tag: && (_bui [group('Build Virtal Machine Image')] build-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "raw" "disk_config/disk.toml") -# Build an ISO virtual machine image +# Build an installer ISO image [group('Build Virtal Machine Image')] -build-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "iso" "disk_config/iso-kde.toml") +build-installer-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_build-bib target_image tag "iso" "disk_config/iso-kde.toml") # Rebuild a QCOW2 virtual machine image [group('Build Virtal Machine Image')] diff --git a/README.md b/README.md index ac56ad9..644d8ce 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ image and then run: ```bash sudo just build -just build-installer-iso +just build-live-iso just run-installer-iso ``` diff --git a/just_scripts/build-installer-iso.sh b/just_scripts/build-installer-iso.sh deleted file mode 100755 index 5d40a05..0000000 --- a/just_scripts/build-installer-iso.sh +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -project_root="$(git rev-parse --show-toplevel)" -cd "${project_root}" - -image_name="${IMAGE_NAME:-localhost/$(just image_name)}" -image_tag="${IMAGE_TAG:-$(just generate-default-tag)}" -live_base_image="${LIVE_BASE_IMAGE:-quay.io/fedora/fedora-kinoite:44}" -titanoboa_repository="${TITANOBOA_REPOSITORY:-https://github.com/Zeglius/titanoboa.git}" -titanoboa_revision="${TITANOBOA_REVISION:-7737f4748458252ac827dca14b3d6dd09298472a}" -source_image="${image_name}:${image_tag}" -# Keep the payload in local container storage, but use the public update -# reference as its local tag so Anaconda writes that reference as the boot -# origin instead of persisting the temporary localhost name. OSTREE_IMAGE_REF -# is intentionally tagless, matching the image-info contract. -image_basename="${image_name##*/}" -registry_organization="${REPO_ORGANIZATION:-aerocore-io}" -registry_organization="${registry_organization,,}" -ostree_image_ref="${OSTREE_IMAGE_REF:-ostree-image-signed:docker://ghcr.io/${registry_organization}/${image_basename}}" -ostree_image_ref="${ostree_image_ref,,}" -install_image_ref="${ostree_image_ref#ostree-image-signed:docker://}" -install_image_ref="${install_image_ref#ostree-unverified-registry:docker://}" -install_image_ref="${install_image_ref#docker://}" -payload="${install_image_ref}:${image_tag}" -output_dir="${project_root}/output" -payload_archive="${output_dir}/install-payload.oci" -iso="${output_dir}/aerocore-os-${image_tag}-live-amd64.iso" -checksum="${iso}-CHECKSUM" -api_socket="${PODMAN_SOCKET:-/run/podman/podman.sock}" -if [[ "${EUID}" -eq 0 ]]; then - podman_cmd=(podman) - socket_test=(test -S "${api_socket}") -else - podman_cmd=(sudo podman) - socket_test=(sudo test -S "${api_socket}") -fi - -if ! "${socket_test[@]}"; then - echo "Podman API socket not found: ${api_socket}" >&2 - echo "Set PODMAN_SOCKET to the rootful Podman socket and retry." >&2 - exit 1 -fi - -ensure_rootful_image() { - local root_image_id user_image_id user_name user_uid copy_tmp - - root_image_id="$("${podman_cmd[@]}" images \ - --filter "reference=${source_image}" \ - --format "{{.ID}}" | head -n1)" - - if [[ -n "${root_image_id}" ]]; then - return 0 - fi - - if [[ "${EUID}" -ne 0 ]]; then - just _rootful_load_image "${image_name}" "${image_tag}" - return - fi - - if [[ -z "${SUDO_USER:-}" ]]; then - return - fi - - user_name="${SUDO_USER}" - user_uid="$(id -u "${user_name}")" - user_image_id="$(sudo -u "${user_name}" \ - env XDG_RUNTIME_DIR="/run/user/${user_uid}" \ - podman images \ - --filter "reference=${source_image}" \ - --format "{{.ID}}" | head -n1)" - - if [[ -z "${user_image_id}" ]]; then - return - fi - - copy_tmp="$(mktemp -p "${project_root}" -d -t _build_podman_scp.XXXXXXXXXX)" - TMPDIR="${copy_tmp}" podman image scp \ - "${user_uid}@localhost::${source_image}" \ - "root@localhost::${source_image}" - rm -rf "${copy_tmp}" -} - -validate_install_payload() { - # Run on the build host rather than from installer/Containerfile. Nested - # Podman has no /dev/fuse in the build sandbox, while this check needs to - # mount the payload rootfs to inspect the bootupd label source. - "${podman_cmd[@]}" run --rm --network none --entrypoint /usr/bin/bash \ - "${source_image}" -ceu ' - system_release_target=$(readlink -f /etc/system-release) - if od -An -v -tx1 "$system_release_target" | awk '\''{ for (i = 1; i <= NF; i++) if ($i == "00") found = 1 } END { exit(found ? 0 : 1) }'\''; then - echo "Install payload has a NUL byte in ${system_release_target}" >&2 - exit 1 - fi - case "$(<"$system_release_target")" in - "AeroCore OS release $(rpm -E %fedora) ("*) ;; - *) - echo "Unexpected system-release: $(<"$system_release_target")" >&2 - exit 1 - ;; - esac - jq -e '\''.["image-name"] == "aerocore-os" and .["image-vendor"] == "aerocore-io"'\'' \ - /usr/share/ublue-os/image-info.json >/dev/null - ' -} - -mkdir -p "${output_dir}" -ensure_rootful_image -validate_install_payload - -"${podman_cmd[@]}" tag "${source_image}" "${payload}" -"${podman_cmd[@]}" save --format oci-archive --output "${payload_archive}" "${payload}" - -"${podman_cmd[@]}" build \ - --cap-add sys_admin \ - --security-opt label=disable \ - --build-arg "BASE_IMAGE=${live_base_image}" \ - --build-arg "INSTALL_IMAGE_PAYLOAD=${payload}" \ - --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ - --build-arg "INSTALL_IMAGE_TAG=${image_tag}" \ - --build-arg "OSTREE_IMAGE_REF=${ostree_image_ref}" \ - --tag "${payload}" \ - --file installer/Containerfile \ - . - -if [[ "${EUID}" -eq 0 ]]; then - rm -f "${iso}" "${checksum}" -else - sudo rm -f "${iso}" "${checksum}" -fi - -tmp_titanoboa="$(mktemp -d -t aerocore-titanoboa.XXXXXXXXXX)" -trap 'rm -rf "${tmp_titanoboa}"' EXIT - -git clone --quiet --filter=blob:none --no-checkout \ - "${titanoboa_repository}" "${tmp_titanoboa}" -git -C "${tmp_titanoboa}" fetch --quiet origin "${titanoboa_revision}" -git -C "${tmp_titanoboa}" checkout --quiet "${titanoboa_revision}" - -# Keep this invocation aligned with the pinned revision's GitHub Action. -# This revision exposes main.sh rather than a Justfile. -( - cd "${tmp_titanoboa}" - env \ - CI=1 \ - TITANOBOA_CTR_IMAGE="${payload}" \ - TITANOBOA_OUTPUT_DIR="${tmp_titanoboa}/output" \ - "${tmp_titanoboa}/main.sh" -) - -titanoboa_iso="$(find "${tmp_titanoboa}/output" -maxdepth 1 -type f -name '*.iso' -print -quit)" -if [[ ! -f "${titanoboa_iso}" ]]; then - echo "Titanoboa did not produce an ISO in ${tmp_titanoboa}/output" >&2 - exit 1 -fi -if [[ "${EUID}" -eq 0 ]]; then - rm -f "${iso}" "${checksum}" - mv "${titanoboa_iso}" "${iso}" -else - sudo rm -f "${iso}" "${checksum}" - sudo mv "${titanoboa_iso}" "${iso}" -fi - -if [[ -f "${iso}" ]]; then - if [[ "${EUID}" -ne 0 ]]; then - sudo chown "$(id -u):$(id -g)" "${iso}" - sudo rm -f "${checksum}" - (cd "${output_dir}" && sha256sum "$(basename "${iso}")") | sudo tee "${checksum}" - sudo chown "$(id -u):$(id -g)" "${checksum}" - else - (cd "${output_dir}" && sha256sum "$(basename "${iso}")") | tee "${checksum}" - fi -fi diff --git a/just_scripts/build-live-iso.sh b/just_scripts/build-live-iso.sh new file mode 100755 index 0000000..5d40a05 --- /dev/null +++ b/just_scripts/build-live-iso.sh @@ -0,0 +1,174 @@ +#!/usr/bin/env bash + +set -euo pipefail + +project_root="$(git rev-parse --show-toplevel)" +cd "${project_root}" + +image_name="${IMAGE_NAME:-localhost/$(just image_name)}" +image_tag="${IMAGE_TAG:-$(just generate-default-tag)}" +live_base_image="${LIVE_BASE_IMAGE:-quay.io/fedora/fedora-kinoite:44}" +titanoboa_repository="${TITANOBOA_REPOSITORY:-https://github.com/Zeglius/titanoboa.git}" +titanoboa_revision="${TITANOBOA_REVISION:-7737f4748458252ac827dca14b3d6dd09298472a}" +source_image="${image_name}:${image_tag}" +# Keep the payload in local container storage, but use the public update +# reference as its local tag so Anaconda writes that reference as the boot +# origin instead of persisting the temporary localhost name. OSTREE_IMAGE_REF +# is intentionally tagless, matching the image-info contract. +image_basename="${image_name##*/}" +registry_organization="${REPO_ORGANIZATION:-aerocore-io}" +registry_organization="${registry_organization,,}" +ostree_image_ref="${OSTREE_IMAGE_REF:-ostree-image-signed:docker://ghcr.io/${registry_organization}/${image_basename}}" +ostree_image_ref="${ostree_image_ref,,}" +install_image_ref="${ostree_image_ref#ostree-image-signed:docker://}" +install_image_ref="${install_image_ref#ostree-unverified-registry:docker://}" +install_image_ref="${install_image_ref#docker://}" +payload="${install_image_ref}:${image_tag}" +output_dir="${project_root}/output" +payload_archive="${output_dir}/install-payload.oci" +iso="${output_dir}/aerocore-os-${image_tag}-live-amd64.iso" +checksum="${iso}-CHECKSUM" +api_socket="${PODMAN_SOCKET:-/run/podman/podman.sock}" +if [[ "${EUID}" -eq 0 ]]; then + podman_cmd=(podman) + socket_test=(test -S "${api_socket}") +else + podman_cmd=(sudo podman) + socket_test=(sudo test -S "${api_socket}") +fi + +if ! "${socket_test[@]}"; then + echo "Podman API socket not found: ${api_socket}" >&2 + echo "Set PODMAN_SOCKET to the rootful Podman socket and retry." >&2 + exit 1 +fi + +ensure_rootful_image() { + local root_image_id user_image_id user_name user_uid copy_tmp + + root_image_id="$("${podman_cmd[@]}" images \ + --filter "reference=${source_image}" \ + --format "{{.ID}}" | head -n1)" + + if [[ -n "${root_image_id}" ]]; then + return 0 + fi + + if [[ "${EUID}" -ne 0 ]]; then + just _rootful_load_image "${image_name}" "${image_tag}" + return + fi + + if [[ -z "${SUDO_USER:-}" ]]; then + return + fi + + user_name="${SUDO_USER}" + user_uid="$(id -u "${user_name}")" + user_image_id="$(sudo -u "${user_name}" \ + env XDG_RUNTIME_DIR="/run/user/${user_uid}" \ + podman images \ + --filter "reference=${source_image}" \ + --format "{{.ID}}" | head -n1)" + + if [[ -z "${user_image_id}" ]]; then + return + fi + + copy_tmp="$(mktemp -p "${project_root}" -d -t _build_podman_scp.XXXXXXXXXX)" + TMPDIR="${copy_tmp}" podman image scp \ + "${user_uid}@localhost::${source_image}" \ + "root@localhost::${source_image}" + rm -rf "${copy_tmp}" +} + +validate_install_payload() { + # Run on the build host rather than from installer/Containerfile. Nested + # Podman has no /dev/fuse in the build sandbox, while this check needs to + # mount the payload rootfs to inspect the bootupd label source. + "${podman_cmd[@]}" run --rm --network none --entrypoint /usr/bin/bash \ + "${source_image}" -ceu ' + system_release_target=$(readlink -f /etc/system-release) + if od -An -v -tx1 "$system_release_target" | awk '\''{ for (i = 1; i <= NF; i++) if ($i == "00") found = 1 } END { exit(found ? 0 : 1) }'\''; then + echo "Install payload has a NUL byte in ${system_release_target}" >&2 + exit 1 + fi + case "$(<"$system_release_target")" in + "AeroCore OS release $(rpm -E %fedora) ("*) ;; + *) + echo "Unexpected system-release: $(<"$system_release_target")" >&2 + exit 1 + ;; + esac + jq -e '\''.["image-name"] == "aerocore-os" and .["image-vendor"] == "aerocore-io"'\'' \ + /usr/share/ublue-os/image-info.json >/dev/null + ' +} + +mkdir -p "${output_dir}" +ensure_rootful_image +validate_install_payload + +"${podman_cmd[@]}" tag "${source_image}" "${payload}" +"${podman_cmd[@]}" save --format oci-archive --output "${payload_archive}" "${payload}" + +"${podman_cmd[@]}" build \ + --cap-add sys_admin \ + --security-opt label=disable \ + --build-arg "BASE_IMAGE=${live_base_image}" \ + --build-arg "INSTALL_IMAGE_PAYLOAD=${payload}" \ + --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ + --build-arg "INSTALL_IMAGE_TAG=${image_tag}" \ + --build-arg "OSTREE_IMAGE_REF=${ostree_image_ref}" \ + --tag "${payload}" \ + --file installer/Containerfile \ + . + +if [[ "${EUID}" -eq 0 ]]; then + rm -f "${iso}" "${checksum}" +else + sudo rm -f "${iso}" "${checksum}" +fi + +tmp_titanoboa="$(mktemp -d -t aerocore-titanoboa.XXXXXXXXXX)" +trap 'rm -rf "${tmp_titanoboa}"' EXIT + +git clone --quiet --filter=blob:none --no-checkout \ + "${titanoboa_repository}" "${tmp_titanoboa}" +git -C "${tmp_titanoboa}" fetch --quiet origin "${titanoboa_revision}" +git -C "${tmp_titanoboa}" checkout --quiet "${titanoboa_revision}" + +# Keep this invocation aligned with the pinned revision's GitHub Action. +# This revision exposes main.sh rather than a Justfile. +( + cd "${tmp_titanoboa}" + env \ + CI=1 \ + TITANOBOA_CTR_IMAGE="${payload}" \ + TITANOBOA_OUTPUT_DIR="${tmp_titanoboa}/output" \ + "${tmp_titanoboa}/main.sh" +) + +titanoboa_iso="$(find "${tmp_titanoboa}/output" -maxdepth 1 -type f -name '*.iso' -print -quit)" +if [[ ! -f "${titanoboa_iso}" ]]; then + echo "Titanoboa did not produce an ISO in ${tmp_titanoboa}/output" >&2 + exit 1 +fi +if [[ "${EUID}" -eq 0 ]]; then + rm -f "${iso}" "${checksum}" + mv "${titanoboa_iso}" "${iso}" +else + sudo rm -f "${iso}" "${checksum}" + sudo mv "${titanoboa_iso}" "${iso}" +fi + +if [[ -f "${iso}" ]]; then + if [[ "${EUID}" -ne 0 ]]; then + sudo chown "$(id -u):$(id -g)" "${iso}" + sudo rm -f "${checksum}" + (cd "${output_dir}" && sha256sum "$(basename "${iso}")") | sudo tee "${checksum}" + sudo chown "$(id -u):$(id -g)" "${checksum}" + else + (cd "${output_dir}" && sha256sum "$(basename "${iso}")") | tee "${checksum}" + fi +fi diff --git a/just_scripts/run-installer-iso.sh b/just_scripts/run-installer-iso.sh index c495215..dc75c42 100755 --- a/just_scripts/run-installer-iso.sh +++ b/just_scripts/run-installer-iso.sh @@ -9,7 +9,7 @@ image_tag="${IMAGE_TAG:-$(just generate-default-tag)}" iso="${project_root}/output/aerocore-os-${image_tag}-live-amd64.iso" if [[ ! -f "${iso}" ]]; then - just build-installer-iso + just build-live-iso fi podman run --rm --cap-add NET_ADMIN \ -- cgit v1.2.3