diff --git a/.github/dependabot.yml b/.github/dependabot.yml index eeb59a0..92c44a8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,4 +1,3 @@ ---- # 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: diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index d5eb094..f740b1c 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -1,243 +1,40 @@ ---- -name: Build mcOS-desktop +name: mcos Build Desktop on: - workflow_call: - inputs: - tag_version: - description: "The Tag Version for the Build" - required: true - type: string - -env: - IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} - IMAGE_NAME: mcos - IMAGE_STYLED: mcOS + pull_request: + branches: + - main + paths-ignore: + - "**.md" + push: + branches: + - main + paths-ignore: + - "**.md" + schedule: + - cron: "31 6 * * 0" # 6:31 UTC Sunday + - cron: "31 6 * * 1,2,3,4,5,6" # 6:31 UTC Monday-Saturday + workflow_call: + workflow_dispatch: + +permissions: + contents: read + packages: write + id-token: write jobs: - push-ublue: - name: Build Desktop Images - runs-on: ubuntu-24.04 - continue-on-error: false - permissions: - contents: read - packages: write - id-token: write - strategy: - fail-fast: false - matrix: - image: - - bluefin - - bluefin-nvidia - tag_version: - - ${{ inputs.tag_version }} - - steps: - - name: Build Variables - id: build-vars - uses: Wandalen/wretry.action@v3.5.0 - with: - attempt_limit: 3 - attempt_delay: 15000 - command: | - set -eoux pipefail - image="${{ matrix.image }}" - base_image=${{ matrix.image }} - tag_version=${{ matrix.tag_version }} - - if [[ "$tag_version" == "stable" ]]; then - tag_version="${tag_version}-daily" - fi - - if [[ ! "${image}" =~ cosmic ]]; then - KERNEL_RELEASE=$(skopeo inspect docker://ghcr.io/ublue-os/"${base_image}:${tag_version}" | jq -r '.Labels["ostree.linux"]') - fedora_version=$(echo $KERNEL_RELEASE | grep -oP 'fc\K[0-9]+') - ver=$(skopeo inspect docker://ghcr.io/ublue-os/"${base_image}:$tag_version" | jq -r '.Labels["org.opencontainers.image.version"]') - fi - - case "${image}" in - "bluefin"*|"aurora"*) - upstream_repo=bluefin - ;; - *) - echo "Invalid Choice. Exiting..." - exit 1 - ;; - esac - - if [ -z "$ver" ] || [ "null" = "$ver" ]; then - echo "inspected image version must not be empty or null" - exit 1 - fi - - echo "version=$ver" >> $GITHUB_ENV - echo "tag_version=$tag_version" >> $GITHUB_ENV - echo "kernel_release=${KERNEL_RELEASE}" >> $GITHUB_ENV - echo "fedora_version=${fedora_version}" >> $GITHUB_ENV - echo "upstream_repo=${upstream_repo}" >> $GITHUB_ENV - echo "image=${image}" >> $GITHUB_ENV - echo "base_image=${base_image}" >> $GITHUB_ENV - - - name: Verify Base Image - uses: EyeCantCU/cosign-action/verify@v0.2.2 - with: - containers: ${{ env.base_image }}:${{ env.tag_version }} - pubkey: https://raw.githubusercontent.com/ublue-os/${{ env.upstream_repo }}/main/cosign.pub - registry: ghcr.io/ublue-os - - - name: Pull Images - uses: Wandalen/wretry.action@v3.5.0 - id: pull - with: - attempt_limit: 3 - attempt_delay: 15000 - command: | - set -eoux pipefail - sudo podman pull ghcr.io/ublue-os/${{ env.base_image }}:${{ env.tag_version }} - sudo podman pull ghcr.io/hhd-dev/rechunk:v0.8.6 - - - name: Checkout Push to Registry Action - uses: actions/checkout@v4 - - - name: Generate Tags - id: generate_tags - shell: bash - run: | - TIMESTAMP="$(date +%Y%m%d)" - case "${{ env.image }}" in - "bazzite-deck"*) - tag="bazzite-deck" - ;; - "bazzite"*) - tag="bazzite" - ;; - *) - tag="${{ env.image }}" - esac - - if [[ "${{ matrix.tag_version }}" == "latest" ]]; then - tag=${tag}-latest - fi - - BUILD_TAGS+=("${tag}" "${tag}-${TIMESTAMP}") - - for TAG in "${BUILD_TAGS[@]}"; do - echo "${TAG}" - done - - echo "default_tag=${tag}" >> "$GITHUB_OUTPUT" - echo "build_tags=${BUILD_TAGS[*]}" >> "$GITHUB_OUTPUT" - - - name: Maximize Build Space - uses: ublue-os/remove-unwanted-software@v7 - - - name: Build Image - id: build_image - shell: bash - run: | - sudo buildah build \ - --format "docker" \ - --build-arg IMAGE=${{ env.image }} \ - --build-arg BASE_IMAGE=${{ env.base_image }} \ - --build-arg TAG_VERSION=${{ env.tag_version }} \ - --tag raw-img . - - - name: Remove old Images - run: | - set -eoux pipefail - sudo podman image rm ghcr.io/ublue-os/${{ env.base_image }}:${{ env.tag_version }} - - - name: Rechunk Image - id: rechunk - uses: hhd-dev/rechunk@v0.8.6 - with: - ref: "raw-img" - prev-ref: "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.generate_tags.outputs.default_tag }}" - version: "${{ env.version }}" - rechunk: "ghcr.io/hhd-dev/rechunk:v0.8.6" - labels: | - org.opencontainers.image.title=${{ env.IMAGE_STYLED }} - org.opencontainers.image.description=${{ env.IMAGE_STYLED }} is my customized image of various ublue projects - org.opencontainers.image.version=${{ env.version }} - - - name: Load into Podman and Tag - shell: bash - run: | - set -eoux pipefail - IMAGE=$(podman pull ${{ steps.rechunk.outputs.ref }}) - sudo rm -rf ${{ steps.rechunk.outputs.output }} - for tag in ${{ steps.generate_tags.outputs.build_tags }}; do - podman tag $IMAGE ${{ env.IMAGE_NAME }}:$tag - done - podman tag $IMAGE rechunked-img - - - name: Check Secureboot - id: secureboot - shell: bash - run: | - set -x - if [[ ! $(command -v sbverify) || ! $(command -v curl) || ! $(command -v openssl) ]]; then - sudo apt update - sudo apt install sbsigntool curl openssl - fi - TMP=$(podman create rechunked-img bash) - podman cp $TMP:/usr/lib/modules/${{ env.kernel_release }}/vmlinuz . - podman rm $TMP - # podman run --rm rechunked-img /bin/bash -c "cat /usr/lib/modules/*/vmlinuz" > vmlinuz - sbverify --list vmlinuz - curl --retry 3 -Lo kernel-sign.der https://github.com/ublue-os/kernel-cache/raw/main/certs/public_key.der - curl --retry 3 -Lo akmods.der https://github.com/ublue-os/kernel-cache/raw/main/certs/public_key_2.der - openssl x509 -in kernel-sign.der -out kernel-sign.crt - openssl x509 -in akmods.der -out akmods.crt - sbverify --cert kernel-sign.crt vmlinuz || exit 1 - sbverify --cert akmods.crt vmlinuz || exit 1 - - - name: Lowercase Registry - id: registry_case - uses: ASzc/change-string-case-action@v6 - with: - string: ${{ env.IMAGE_REGISTRY }} - - - name: Push to GHCR - uses: Wandalen/wretry.action@v3.5.0 - id: push - if: github.event_name != 'pull_request' - env: - REGISTRY_USER: ${{ github.actor }} - REGISTRY_PASSWORD: ${{ github.token }} - with: - action: redhat-actions/push-to-registry@v2 - attempt_limit: 3 - attempt_delay: 15000 - with: | - image: ${{ env.IMAGE_NAME }} - tags: ${{ steps.generate_tags.outputs.build_tags }} - registry: ${{ steps.registry_case.outputs.lowercase }} - username: ${{ env.REGISTRY_USER }} - password: ${{ env.REGISTRY_PASSWORD }} - extra-args: | - --disable-content-trust - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - if: github.event_name != 'pull_request' - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - uses: sigstore/cosign-installer@v3.5.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 }}/${{ env.IMAGE_NAME }}@${TAGS} - env: - TAGS: ${{ steps.push.outputs.outputs && fromJSON(steps.push.outputs.outputs).digest }} - COSIGN_EXPERIMENTAL: false - COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} - - - name: Echo Outputs - if: github.event_name != 'pull_request' - run: | - echo "${{ toJSON(steps.push.outputs) }}" + build-desktop-stable: + name: Desktop Stable + uses: ./.github/workflows/reusable-build.yml + secrets: inherit + with: + images: '["bluefin", "bluefin-dx"]' + streams: '["stable"]' + flavors: '["main", "nvidia"]' + build-desktop-testing: + name: Desktop Beta(Testing) + uses: ./.github/workflows/reusable-build.yml + secrets: inherit + with: + images: '["bluefin", "bluefin-dx"]' + streams: '["beta"]' + flavors: '["main", "nvidia"]' diff --git a/.github/workflows/build-server.yml b/.github/workflows/build-server.yml index bc95d2e..0cbd948 100644 --- a/.github/workflows/build-server.yml +++ b/.github/workflows/build-server.yml @@ -1,215 +1,40 @@ ---- -name: Build mcOS-server +name: mcos Build Server on: - workflow_call: - workflow_dispatch: - -env: - IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} - IMAGE_NAME: mcos - IMAGE_STYLED: mcOS + pull_request: + branches: + - main + paths-ignore: + - "**.md" + push: + branches: + - main + paths-ignore: + - "**.md" + schedule: + - cron: "11 6 * * 0" # 6:31 UTC Sunday + - cron: "11 6 * * 1,2,3,4,5,6" # 6:31 UTC Monday-Saturday + workflow_call: + workflow_dispatch: + +permissions: + contents: read + packages: write + id-token: write jobs: - push-ucore: - name: Build Ucore Images - runs-on: ubuntu-24.04 - continue-on-error: false - permissions: - contents: read - packages: write - id-token: write - strategy: - fail-fast: false - matrix: - image: - - stable-zfs - - stable-nvidia-zfs - steps: - - name: Build Variables - id: labels - uses: Wandalen/wretry.action@v3.5.0 - with: - attempt_limit: 3 - attempt_delay: 15000 - command: | - set -eoux pipefail - tag_version=${{ matrix.image }} - KERNEL_RELEASE=$(skopeo inspect docker://ghcr.io/ublue-os/ucore-minimal:${tag_version} | jq -r '.Labels["ostree.linux"]') - upstream_repo=ucore - base_image=ucore-minimal - fedora_version=$(echo $KERNEL_RELEASE | grep -oP 'fc\K[0-9]+') - ver=$(skopeo inspect docker://ghcr.io/ublue-os/${base_image}:"$tag_version" | jq -r '.Labels["org.opencontainers.image.version"]') - if [ -z "$ver" ] || [ "null" = "$ver" ]; then - echo "inspected image version must not be empty or null" - exit 1 - fi - echo "version=$ver" >> $GITHUB_ENV - echo "tag_version=$tag_version" >> $GITHUB_ENV - echo "kernel_release=${KERNEL_RELEASE}" >> $GITHUB_ENV - echo "fedora_version=${fedora_version}" >> $GITHUB_ENV - echo "upstream_repo=${upstream_repo}" >> $GITHUB_ENV - echo "base_image=${base_image}" >> $GITHUB_ENV - - - name: Verify Base Image - uses: EyeCantCU/cosign-action/verify@v0.2.2 - with: - containers: ${{ env.base_image }}:${{ env.tag_version }} - pubkey: https://raw.githubusercontent.com/ublue-os/${{ env.upstream_repo }}/main/cosign.pub - registry: ghcr.io/ublue-os - - - name: Pull Images - uses: Wandalen/wretry.action@v3.5.0 - id: pull - with: - attempt_limit: 3 - attempt_delay: 15000 - command: | - set -eoux pipefail - sudo podman pull ghcr.io/ublue-os/${{ env.base_image }}:${{ env.tag_version }} - sudo podman pull ghcr.io/hhd-dev/rechunk:v0.8.6 - - - name: Checkout Push to Registry Action - uses: actions/checkout@v4 - - - name: Generate Tags - id: generate_tags - shell: bash - run: | - TIMESTAMP="$(date +%Y%m%d)" - if [[ "${{ env.tag_version }}" =~ nvidia ]]; then - tag="ucore-minimal-nvidia" - else - tag="ucore-minimal" - fi - BUILD_TAGS+=("${tag}" "${tag}-${TIMESTAMP}") - for TAG in "${BUILD_TAGS[@]}"; do - echo "${TAG}" - done - echo "image=${tag}" >> "$GITHUB_ENV" - echo "default_tag=${tag}" >> "$GITHUB_OUTPUT" - echo "build_tags=${BUILD_TAGS[*]}" >> "$GITHUB_OUTPUT" - - - name: Image Metadata - uses: docker/metadata-action@v5 - id: meta - with: - images: | - ${{ env.IMAGE_NAME }} - labels: | - org.opencontainers.image.title=${{ env.IMAGE_STYLED }} - org.opencontainers.image.description=${{ env.IMAGE_STYLED }} is my customized image of various ublue projects - org.opencontainers.image.version=${{ env.version }} - - - name: Maximize Build Space - uses: ublue-os/remove-unwanted-software@v7 - - - name: Build Image - id: build_image - shell: bash - run: | - sudo buildah build \ - --format "docker" \ - --build-arg BASE_IMAGE=${{ env.base_image }} \ - --build-arg IMAGE=${{ env.image }} \ - --build-arg TAG_VERSION=${{ env.tag_version }} \ - --tag raw-img . - - - name: Remove old Images - run: | - set -eoux pipefail - sudo podman image rm ghcr.io/ublue-os/${{ env.base_image }}:${{ env.tag_version }} - - - name: Rechunk Image - id: rechunk - uses: hhd-dev/rechunk@v0.8.6 - with: - ref: "raw-img" - prev-ref: "${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.generate_tags.outputs.default_tag }}" - version: "${{ env.version }}" - rechunk: "ghcr.io/hhd-dev/rechunk:v0.8.6" - labels: | - org.opencontainers.image.title=${{ env.IMAGE_STYLED }} - org.opencontainers.image.description=${{ env.IMAGE_STYLED }} is my customized image of various ublue projects - org.opencontainers.image.version=${{ env.version }} - - - name: Load into Podman and Tag - shell: bash - run: | - set -eoux pipefail - IMAGE=$(podman pull ${{ steps.rechunk.outputs.ref }}) - sudo rm -rf ${{ steps.rechunk.outputs.output }} - for tag in ${{ steps.generate_tags.outputs.build_tags }}; do - podman tag $IMAGE ${{ env.IMAGE_NAME }}:$tag - done - podman tag $IMAGE rechunked-img - - - name: Check Secureboot - id: secureboot - shell: bash - run: | - set -x - if [[ ! $(command -v sbverify) || ! $(command -v curl) || ! $(command -v openssl) ]]; then - sudo apt update - sudo apt install sbsigntool curl openssl - fi - TMP=$(podman create rechunked-img bash) - podman cp $TMP:/usr/lib/modules/${{ env.kernel_release }}/vmlinuz . - podman rm $TMP - sbverify --list vmlinuz - curl --retry 3 -Lo kernel-sign.der https://github.com/ublue-os/kernel-cache/raw/main/certs/public_key.der - curl --retry 3 -Lo akmods.der https://github.com/ublue-os/kernel-cache/raw/main/certs/public_key_2.der - openssl x509 -in kernel-sign.der -out kernel-sign.crt - openssl x509 -in akmods.der -out akmods.crt - sbverify --cert kernel-sign.crt vmlinuz || exit 1 - sbverify --cert akmods.crt vmlinuz || exit 1 - - - name: Lowercase Registry - id: registry_case - uses: ASzc/change-string-case-action@v6 - with: - string: ${{ env.IMAGE_REGISTRY }} - - - name: Push to GHCR - uses: Wandalen/wretry.action@v3.5.0 - id: push - if: github.event_name != 'pull_request' - env: - REGISTRY_USER: ${{ github.actor }} - REGISTRY_PASSWORD: ${{ github.token }} - with: - action: redhat-actions/push-to-registry@v2 - attempt_limit: 3 - attempt_delay: 15000 - with: | - image: ${{ env.IMAGE_NAME }} - tags: ${{ steps.generate_tags.outputs.build_tags }} - registry: ${{ steps.registry_case.outputs.lowercase }} - username: ${{ env.REGISTRY_USER }} - password: ${{ env.REGISTRY_PASSWORD }} - extra-args: | - --disable-content-trust - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - if: github.event_name != 'pull_request' - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - uses: sigstore/cosign-installer@v3.5.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 }}/${{ env.IMAGE_NAME }}@${TAGS} - env: - TAGS: ${{ steps.push.outputs.outputs && fromJSON(steps.push.outputs.outputs).digest }} - COSIGN_EXPERIMENTAL: false - COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} - - - name: Echo Outputs - if: github.event_name != 'pull_request' - run: | - echo "${{ toJSON(steps.push.outputs) }}" \ No newline at end of file + build-server-stable: + name: Server Stable + uses: ./.github/workflows/reusable-build.yml + secrets: inherit + with: + images: '["ucore-minimal", "ucore", "ucore-hci"]' + streams: '["stable"]' + flavors: '["main", "nvidia"]' + build-server-testing: + name: Server Testing + uses: ./.github/workflows/reusable-build.yml + secrets: inherit + with: + images: '["ucore-minimal", "ucore", "ucore-hci"]' + streams: '["testing"]' + flavors: '["main", "nvidia"]' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index e9b4716..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -name: Build mcOS -on: - schedule: - - cron: "31 6 * * 0" # 6:31 UTC Sunday - - cron: "31 6 * * 1,2,3,4,5,6" # 6:31 UTC Monday-Saturday - push: - branches: - - main - merge_group: - workflow_dispatch: - -permissions: - contents: read - packages: write - id-token: write - -concurrency: - group: ${{ github.workflow }}-${{ github.ref || github.run_id }} - cancel-in-progress: true - -jobs: - push-desktop-stable: - uses: ./.github/workflows/build-desktop.yml - secrets: inherit - with: - tag_version: stable - - push-desktop-latest: - uses: ./.github/workflows/build-desktop.yml - secrets: inherit - with: - tag_version: latest - - push-server: - uses: ./.github/workflows/build-server.yml - secrets: inherit - -# build-iso: -# uses: ./.github/workflows/build-iso.yml -# secrets: inherit -# needs: push-desktop-stable -# if: (github.event_name == 'schedule' && github.event.schedule != '41 6 * * 1,2,3,4,5,6') || github.event_name == 'workflow_dispatch' \ No newline at end of file diff --git a/.github/workflows/cleanup-old-images.yml b/.github/workflows/cleanup-old-images.yml index 21ab5dd..8860355 100644 --- a/.github/workflows/cleanup-old-images.yml +++ b/.github/workflows/cleanup-old-images.yml @@ -1,4 +1,3 @@ ---- name: Cleanup Old Images on: schedule: @@ -14,11 +13,11 @@ jobs: permissions: packages: write steps: - - name: Delete Images Older Than 30 Days + - name: Delete Images Older Than 90 Days uses: dataaxiom/ghcr-cleanup-action@v1.0.13 with: token: ${{ secrets.GITHUB_TOKEN }} - older-than: 30 days + older-than: 90 days delete-orphaned-images: true #packages: mcos #keep-n-tagged: 7 diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml new file mode 100644 index 0000000..7cf2243 --- /dev/null +++ b/.github/workflows/reusable-build.yml @@ -0,0 +1,189 @@ +name: Reusable Build and Push +on: + workflow_call: + inputs: + images: + description: "JSON string of images to build, eg '[bluefin, bluefin-dx, bazzite, ucore, ucore-hci]'" + required: true + type: string + streams: + description: "JSON string of streams to build, one or all of '[stable, beta, testing]'" + required: true + type: string + flavors: + description: "JSON string of flavors to build, one or both of '[main, nvidia]'" + required: true + type: string + outputs: + images: + description: "An array of images built and pushed to the registry" + value: ${{ jobs.check.outputs.images }} + +env: + IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} + IMAGE_STYLED: mcos + +jobs: + build-image: + name: Build Images + runs-on: ubuntu-24.04 + continue-on-error: false + strategy: + fail-fast: false + matrix: + image: ${{ fromJson(inputs.images) }} + stream: ${{ fromJson(inputs.streams) }} + flavor: ${{ fromJson(inputs.flavors) }} + exclude: + - image: bazzite + stream: beta + - image: bazzite-deck + stream: beta + - image: bazzite + stream: testing + - image: bazzite-deck + stream: testing + - image: ucore-minimal + stream: testing + - image: ucore + stream: testing + - image: ucore-minimal + flavor: nvidia + concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }}-${{ matrix.image }}-${{ matrix.flavor }}-${{ matrix.stream }} + cancel-in-progress: true + steps: + - name: Checkout Push to Registry Action + uses: actions/checkout@v4 + + - name: Setup Just + id: setup_just + shell: bash + run: | + set -eoux pipefail + JUST_VERSION=$(curl -L https://api.github.com/repos/casey/just/releases/latest | jq -r '.tag_name') + curl -sSLO https://github.com/casey/just/releases/download/${JUST_VERSION}/just-${JUST_VERSION}-x86_64-unknown-linux-musl.tar.gz + sudo tar -zxvf just-${JUST_VERSION}-x86_64-unknown-linux-musl.tar.gz -C /usr/local/bin just + rm -f just-${JUST_VERSION}-x86_64-unknown-linux-musl.tar.gz + + cd /usr/bin && \ + sudo curl -sSLO \ + https://github.com/casey/just/releases/download/1.36.0/just-1.36.0-x86_64-unknown-linux-musl.tar.gz && \ + sudo tar -zxvf just-1.36.0-x86_64-unknown-linux-musl.tar.gz just && \ + sudo rm -f just-1.36.0-x86_64-unknown-linux-musl.tar.gz + + - name: Get Source Image Info + id: source_info + shell: bash + run: | + build_src_dst=($(just gen-build-src-dst "${{ matrix.image }}" "${{ matrix.stream }}" "${{ matrix.flavor }}")) + source_image=${build_src_dst[0]} + source_tag=${build_src_dst[1]} + dest_image=${build_src_dst[2]} + dest_tag=${build_src_dst[3]} + + echo "source_image=${source_image}" >> "$GITHUB_ENV" + echo "source_tag=${source_tag}" >> "$GITHUB_ENV" + echo "dest_image=${dest_image}" >> "$GITHUB_ENV" + echo "dest_tag=${dest_tag}" >> "$GITHUB_ENV" + + - name: Generate Tags + id: generate_tags + shell: bash + run: | + TIMESTAMP="$(date +%Y%m%d)" + tag=${{ env.dest_tag }} + + BUILD_TAGS+=("${tag}" "${tag}-${TIMESTAMP}") + for TAG in "${BUILD_TAGS[@]}"; do + echo "${TAG}" + done + + echo "alias_tags=${BUILD_TAGS[*]}" >> "$GITHUB_OUTPUT" + + - name: Verify Source Image + uses: EyeCantCU/cosign-action/verify@58722a084c82190b57863002d494c91eabbe9e79 # v0.3.0 + with: + containers: ${{ env.source_image }}:${{ env.source_tag }} + + - name: Maximize Build Space + uses: ublue-os/remove-unwanted-software@v7 + + - name: Pull Images + uses: Wandalen/wretry.action@v3.7.2 + id: pull + with: + attempt_limit: 3 + attempt_delay: 15000 + command: | + set -eoux pipefail + sudo podman pull ghcr.io/ublue-os/${{ env.source_image }}:${{ env.source_tag }} + + - name: Build Image + id: build_image + shell: bash + run: | + sudo just build "${{ matrix.image }}" "${{ matrix.stream }}" "${{ matrix.flavor }}" + + - name: Rechunk Image + id: rechunk + shell: bash + run: | + sudo just rechunk "${{ matrix.image }}" "${{ matrix.stream }}" "${{ matrix.flavor }}" + + - name: Tag Images + shell: bash + run: | + set -eoux pipefail + sudo podman images + IMAGE="localhost/${{ env.dest_image }}:${{ env.dest_tag }}" + for tag in ${{ steps.generate_tags.outputs.alias_tags }}; do + sudo podman tag $IMAGE ${{ env.dest_image }}:$tag + done + sudo podman tag $IMAGE rechunked-img + sudo podman images + + - name: Lowercase Registry + id: registry_case + uses: ASzc/change-string-case-action@v6 + with: + string: ${{ env.IMAGE_REGISTRY }} + + - name: Login to GitHub Container Registry + if: github.event_name != 'pull_request' + run: | + echo ${{ secrets.GITHUB_TOKEN }} | sudo podman login ghcr.io -u ${{ github.actor }} --password-stdin + echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin + + - name: Push to GHCR + id: push + if: github.event_name != 'pull_request' + uses: Wandalen/wretry.action@v3.7.2 + with: + attempt_limit: 3 + attempt_delay: 15000 + command: | + set -euox pipefail + + for tag in ${{ steps.generate_tags.outputs.alias_tags }}; do + sudo podman push ${{ env.dest_image }}:${tag} ${{ steps.registry_case.outputs.lowercase }}/${{ env.dest_image }}:${tag} + done + digest=$(sudo skopeo inspect docker://${{ steps.registry_case.outputs.lowercase }}/${{ env.dest_image }}:${{ env.dest_tag }} --format '{{.Digest}}') + echo "digest=${digest}" >> $GITHUB_OUTPUT + + - uses: sigstore/cosign-installer@v3.7.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 }}/${{ env.dest_image }}@${TAGS} + env: + TAGS: ${{ steps.push.outputs.outputs && fromJSON(steps.push.outputs.outputs).digest }} + COSIGN_EXPERIMENTAL: false + COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} + + - name: Echo Outputs + if: github.event_name != 'pull_request' + run: | + echo "${{ toJSON(steps.push.outputs) }}" diff --git a/Justfile b/Justfile index 4e2d1f9..4e82c12 100644 --- a/Justfile +++ b/Justfile @@ -1,126 +1,187 @@ +my_image := "mcos" +my_image_styled := "mcos" +repo_name := "mcos" +repo_organization := "johnmmcgee" +rechunker_image := "ghcr.io/hhd-dev/rechunk:v1.0.1" images := '( [bazzite]="bazzite-gnome" [bazzite-deck]="bazzite-deck-gnome" [bluefin]="bluefin" - [bluefin-nvidia]="bluefin-nvidia" - [ucore-hci]="stable-zfs" - [ucore-hci-nvidia]="stable-nvidia-zfs" - [ucore]="stable-zfs" - [ucore-nvidia]="stable-nvidia-zfs" + [bluefin-dx]="bluefin-dx" + [ucore-minimal]="ucore-minimal" + [ucore]="ucore" + [ucore-hci]="ucore-hci" +)' +flavors := '( + [main]=main + [nvidia]=nvidia +)' +tags := '( + [stable]=stable + [beta]=beta + [testing]=testing )' - -_default: +[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 -# Build mcos Image -build image="bluefin": +# Fix Just Syntax +[group('Just')] +fix: #!/usr/bin/bash - set -eou pipefail + 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 + rm -f previous.manifest.json + find *_build* -exec rm -rf {} \; + +# Sudo Clean +[group('Utility')] +sudo-clean: + #!/usr/bin/bash + set -eoux pipefail + just sudoif "rm -f previous.manifest.json" + just sudoif "find *_build* -exec rm -rf {} \;" + +# Check if valid combo +[group('Utility')] +[private] +validate image="" tag="" flavor="": + #!/usr/bin/bash + set -eoux pipefail declare -A images={{ images }} - image={{image}} - check=${images[$image]-} - if [[ -z "$check" ]]; then + declare -A tags={{ tags }} + declare -A flavors={{ flavors }} + image={{ image }} + tag={{ tag }} + flavor={{ flavor }} + checkimage="${images[${image}]-}" + checktag="${tags[${tag}]-}" + checkflavor="${flavors[${flavor}]-}" + + # Validity Checks + if [[ -z "$checkimage" ]]; then + echo "Invalid Image..." exit 1 fi - BUILD_ARGS=() - BUILD_ARGS+=("--label" "org.opencontainers.image.title=mcos") - BUILD_ARGS+=("--label" "org.opencontainers.image.version=localbuild") - BUILD_ARGS+=("--build-arg" "IMAGE=${image}") - case "${image}" in - "aurora"*|"bluefin"*) - skopeo inspect docker://ghcr.io/ublue-os/bluefin:stable-daily > /tmp/inspect.json - BUILD_ARGS+=("--build-arg" "BASE_IMAGE=${image}") - BUILD_ARGS+=("--build-arg" "TAG_VERSION=stable-daily") - BUILD_ARGS+=("--tag" "localhost/mcos:${image}") - ;; - "bazzite"*) - skopeo inspect docker://ghcr.io/ublue-os/bazzite:stable > /tmp/inspect.json - BUILD_ARGS+=("--build-arg" "BASE_IMAGE=${check}") - BUILD_ARGS+=("--build-arg" "TAG_VERSION=stable") - BUILD_ARGS+=("--tag" "localhost/mcos:${image}") - ;; - "ucore-hci"*) - skopeo inspect docker://ghcr.io/ublue-os/ucore-hci:${check} > /tmp/inspect.json - BUILD_ARGS+=("--build-arg" "BASE_IMAGE=ucore-hci") - BUILD_ARGS+=("--build-arg" "TAG_VERSION=${check}") - BUILD_ARGS+=("--tag" "localhost/mcos:${image}") - ;; - "ucore"*) - skopeo inspect docker://ghcr.io/ublue-os/ucore:${check} > /tmp/inspect.json - BUILD_ARGS+=("--build-arg" "BASE_IMAGE=ucore") - BUILD_ARGS+=("--build-arg" "TAG_VERSION=${check}") - BUILD_ARGS+=("--tag" "localhost/mcos:${image}") - ;; - esac - buildah build --format docker --label "org.opencontainers.image.description=mcos is my customized image of various ublue projects" ${BUILD_ARGS[@]} . - -# Build mcos Beta Image -build-beta image="bluefin": - #!/usr/bin/bash - set -eou pipefail - declare -A images={{ images }} - image={{image}} - check=${images[$image]-} - if [[ -z "$check" ]]; then + if [[ -z "$checkflavor" ]]; then + echo "Invalid flavor..." exit 1 fi - BUILD_ARGS=() - BUILD_ARGS+=("--label" "org.opencontainers.image.title=mcos") - BUILD_ARGS+=("--label" "org.opencontainers.image.version=localbuild-$(date +%Y%m%d-%H:%M:%S)") - BUILD_ARGS+=("--build-arg" "IMAGE=${image}") - case "${image}" in - "aurora"*|"bluefin"*) - skopeo inspect docker://ghcr.io/ublue-os/bluefin:beta > /tmp/inspect.json - BUILD_ARGS+=("--build-arg" "BASE_IMAGE=${image}") - BUILD_ARGS+=("--build-arg" "TAG_VERSION=beta") - BUILD_ARGS+=("--tag" "localhost/mcos:${image}") - ;; - "bazzite"*) - skopeo inspect docker://ghcr.io/ublue-os/bazzite:unstable > /tmp/inspect.json - BUILD_ARGS+=("--build-arg" "BASE_IMAGE=${check}") - BUILD_ARGS+=("--build-arg" "TAG_VERSION=unstable") - BUILD_ARGS+=("--tag" "localhost/mcos:${image}") - ;; - *) - echo "No Image Yet..." + if [[ -z "$checktag" ]]; then + echo "Invalid tag..." exit 1 - ;; - esac - buildah build --format docker --label "org.opencontainers.image.description=mcos is my customized image of various ublue projects" ${BUILD_ARGS[@]} . + fi + if [[ "$checkimage" =~ bazzite ]]; then + if [[ "$checktag" != stable ]]; then + echo "Bazzite only builds stable tag..." + exit 1 + fi + if [[ "$checkflavor" != main ]]; then + echo "Bazzite only builds main flavor..." + exit 1 + fi + fi + if [[ "$checkimage" =~ bluefin ]]; then + if [[ "$checktag" =~ testing ]]; then + echo "Bluefin does not build testing tag..." + exit 1 + fi + fi + if [[ "$checkimage" =~ ucore ]]; then + if [[ "$checktag" =~ beta ]]; then + echo "uCore does not build beta tag..." + exit 1 + fi + fi -# Remove Image -remove image="": +# Generate container args, etc +[group('Utility')] +[private] +gen-build-src-dst image="" tag="" flavor="": #!/usr/bin/bash set -eou pipefail - declare -A images={{images}} - image={{image}} - check_image="$image" - if [[ "$check_image" =~ beta ]]; then - check_image=${check_image:0:-5} - fi - check=${images[$check_image]-} - if [[ -z "$check" ]]; then - exit 1 + declare -A images={{ images }} + declare -A tags={{ tags }} + declare -A flavors={{ flavors }} + image={{ image }} + tag={{ tag }} + flavor={{ flavor }} + srcimage="${images[${image}]-}" + srctag="${tags[${tag}]-}" + srcflavor="${flavors[${flavor}]-}" + + # Validate + just validate "${image}" "${tag}" "${flavor}" + + # Image Name (the SOURCE image) + if [[ "${flavor}" =~ main || "${image}" =~ ucore ]]; then + # image name is what was required if it's a main flavor + # OR if it's ucore, since ucore has a different tagging for nivida rather than image + source_image="${srcimage}" + else + source_image="${srcimage}-${srcflavor}" fi - podman rmi localhost/mcos:${image} -# Remove All Images -removeall: - #!/usr/bin/bash - set -euo pipefail - declare -A images={{ images }} - for image in ${!images[@]} - do - podman rmi localhost/mcos:"$image" || true - podman rmi localhost/mcos:"$image"-beta || true - done + # Tag Version (the SOURCE tag) + if [[ "${image}" =~ ucore ]]; then + if [[ "${image}" == ucore-minimal ]]; then + if [[ "${flavor}" =~ main ]]; then + source_tag="${srctag}" + else + source_tag="${srctag}-${srcflavor}" + fi + else + if [[ "${flavor}" =~ main ]]; then + source_tag="${srctag}-zfs" + else + source_tag="${srctag}-${srcflavor}-zfs" + fi + fi + elif [[ "${image}" =~ bluefin && "${tag}" == stable ]]; then + source_tag="${srctag}-daily" + else + source_tag="${srctag}" + fi -# Rechunk Image -rechunk image="bluefin": + # My Tag (the tag I publish for my image) + my_tag_flavor="" # a way to inject flavor for ucore using different tag style + if [[ "${flavor}" != main ]]; then + my_tag_flavor="-${flavor}" + fi + if [[ "${tag}" =~ stable ]]; then + my_tag="${image}${my_tag_flavor}" + else + my_tag="${image}${my_tag_flavor}-${tag}" + fi + echo "${source_image} ${source_tag} {{ my_image }} ${my_tag}" + +# sudoif bash function +[group('Utility')] +[private] +sudoif command *args: #!/usr/bin/bash - set -eou pipefail function sudoif(){ if [[ "${UID}" -eq 0 ]]; then "$@" @@ -132,62 +193,196 @@ rechunk image="bluefin": exit 1 fi } - sudoif podman image scp ${UID}@localhost::localhost/mcos:{{image}} root@localhost::localhost/mcos:{{image}} - CREF=$(sudoif podman create localhost/mcos:{{image}} bash) - MOUNT=$(sudoif podman mount $CREF) - OUT_NAME="mcos_{{image}}" - LABELS=" - org.opencontainers.image.title=mcos - org.opencontainers.image.version=localbuild-$(date +%Y%m%d-%H:%M:%S) - ostree.linux=$(skopeo inspect containers-storage:localhost/mcos:{{image}} | jq -r '.Labels["ostree.linux"]') - org.opencontainers.image.description=mcos is my customized image of various ublue projects" - sudoif podman run --rm \ + sudoif {{ command }} {{ args }} + +# Build Image +[group('Image')] +build image="bluefin" tag="stable" flavor="main" rechunk="0": + #!/usr/bin/bash + set -eoux pipefail + image={{ image }} + tag={{ tag }} + flavor={{ flavor }} + + # Validate is handled by gen-build-src-dst + build_src_dst=($(just gen-build-src-dst "${image}" "${tag}" "${flavor}")) + src_img=${build_src_dst[0]} + src_tag=${build_src_dst[1]} + dst_img=${build_src_dst[2]} + dst_tag=${build_src_dst[3]} + + # Build Arguments + BUILD_ARGS=() + BUILD_ARGS+=("--build-arg" "BASE_IMAGE=${src_img}") + BUILD_ARGS+=("--build-arg" "IMAGE=${src_img}") + BUILD_ARGS+=("--build-arg" "TAG_VERSION=${src_tag}") + + # Labels + LABELS=() + LABELS+=("--label" "io.artifacthub.package.readme-url=https://raw.githubusercontent.com/{{ repo_organization }}/{{ repo_name }}/refs/heads/main/README.md") + LABELS+=("--label" "org.opencontainers.image.title={{ my_image_styled }}") + LABELS+=("--label" "org.opencontainers.image.description=This {{ my_image_styled }} is {{ repo_organization }}'s customized image of ghcr.io/ublue-os/${src_img}:${src_tag}") + + # Build Image + podman build \ + "${BUILD_ARGS[@]}" \ + "${LABELS[@]}" \ + --tag "${dst_img}:${dst_tag}" \ + . + + # Rechunk + if [[ "{{ rechunk }}" == "1" ]]; then + just rechunk "${image}" "${tag}" "${flavor}" + fi + +# Build Image and Rechunk +[group('Image')] +build-rechunk image="bluefin" tag="stable" flavor="main": + @just build {{ image }} {{ tag }} {{ flavor }} 1 + +# Rechunk Image +[group('Image')] +[private] +rechunk image="bluefin" tag="stable" flavor="main": + #!/usr/bin/bash + set -eoux pipefail + + image={{ image }} + tag={{ tag }} + flavor={{ flavor }} + + # Validate is handled by gen-build-src-dst + build_src_dst=($(just gen-build-src-dst "${image}" "${tag}" "${flavor}")) + src_img=${build_src_dst[0]} + src_tag=${build_src_dst[1]} + dst_img=${build_src_dst[2]} + dst_tag=${build_src_dst[3]} + + # debugging + just sudoif podman images + + # Check if image is already built + ID=$(podman images --filter reference=localhost/"${dst_img}":"${dst_tag}" --format "'{{ '{{.ID}}' }}'") + if [[ -z "$ID" ]]; then + just build "${image}" "${tag}" "${flavor}" + fi + + # Load into Rootful Podman + ID=$(just sudoif podman images --filter reference=localhost/"${dst_img}":"${dst_tag}" --format "'{{ '{{.ID}}' }}'") + if [[ -z "$ID" ]]; then + just sudoif podman image scp ${UID}@localhost::localhost/"${dst_img}":"${dst_tag}" root@localhost::localhost/"${dst_img}":"${dst_tag}" + fi + + # Prep Container + CREF=$(just sudoif podman create localhost/"${dst_img}":"${dst_tag}" bash) + MOUNT=$(just sudoif podman mount "${CREF}") + OUT_NAME="${dst_img}_build" + + # Fedora Version + fedora_version=$(just sudoif podman inspect $CREF | jq -r '.[].Config.Labels["ostree.linux"]' | grep -oP 'fc\K[0-9]+') + + # Cleanup space needed for Github Action runner lack of space + ID=$(just sudoif podman images --filter reference=ghcr.io/ublue-os/"${src_img}":${src_tag} --format "'{{ '{{.ID}}' }}'") + if [[ -n "$ID" ]]; then + just sudoif podman rmi "$ID" + fi + + # Run Rechunker's Prune + just sudoif podman run --rm \ + --pull=newer \ --security-opt label=disable \ - -v "$MOUNT":/var/tree \ - -e TREE=/var/tree \ - -u 0:0 \ - ghcr.io/hhd-dev/rechunk:latest \ + --volume "$MOUNT":/var/tree \ + --env TREE=/var/tree \ + --user 0:0 \ + "{{ rechunker_image }}" \ /sources/rechunk/1_prune.sh - sudoif podman run --rm \ + + # Run Rechunker's Create + just sudoif podman run --rm \ --security-opt label=disable \ - -v "$MOUNT":/var/tree \ - -e TREE=/var/tree \ - -v "cache_ostree:/var/ostree" \ - -e REPO=/var/ostree/repo \ - -e RESET_TIMESTAMP=1 \ - -u 0:0 \ - ghcr.io/hhd-dev/rechunk:latest \ + --volume "$MOUNT":/var/tree \ + --volume "cache_ostree:/var/ostree" \ + --env TREE=/var/tree \ + --env REPO=/var/ostree/repo \ + --env RESET_TIMESTAMP=1 \ + --user 0:0 \ + "{{ rechunker_image }}" \ /sources/rechunk/2_create.sh - sudoif podman unmount "$CREF" - sudoif podman rm "$CREF" - sudoif podman run --rm \ + + # Cleanup Temp Container Reference + just sudoif podman unmount "$CREF" + just sudoif podman rm "$CREF" + + # Run Rechunker + just sudoif podman run --rm \ + --pull=newer \ --security-opt label=disable \ - -v "$PWD:/workspace" \ - -v "$PWD:/var/git" \ - -v cache_ostree:/var/ostree \ - -e REPO=/var/ostree/repo \ - -e PREV_REF=ghcr.io/m2giles/mcos:{{image}} \ - -e LABELS="$LABELS" \ - -e OUT_NAME="$OUT_NAME" \ - -e VERSION_FN=/workspace/version.txt \ - -e OUT_REF="oci:$OUT_NAME" \ - -e GIT_DIR="/var/git" \ - -u 0:0 \ - ghcr.io/hhd-dev/rechunk:latest \ + --volume "$PWD:/workspace" \ + --volume "$PWD:/var/git" \ + --volume cache_ostree:/var/ostree \ + --env REPO=/var/ostree/repo \ + --env PREV_REF=ghcr.io/{{ repo_organization }}/"${dst_img}":"${dst_tag}" \ + --env OUT_NAME="$OUT_NAME" \ + --env LABELS="org.opencontainers.image.title={{ my_image_styled }}$'\n'org.opencontainers.image.version=${fedora_version}-$(date +%Y%m%d-%H:%M:%S)$'\n''io.artifacthub.package.readme-url=https://raw.githubusercontent.com/{{ repo_organization }}/{{ repo_name }}/refs/heads/main/README.md'$'\n'" \ + --env "DESCRIPTION='This {{ my_image_styled }} is a {{ repo_organization }} customized version of ghcr.io/ublue-os/${src_img}:${src_tag}'" \ + --env VERSION_FN=/workspace/version.txt \ + --env OUT_REF="oci:$OUT_NAME" \ + --env GIT_DIR="/var/git" \ + --user 0:0 \ + "{{ rechunker_image }}" \ /sources/rechunk/3_chunk.sh - sudoif chown ${UID}:${GROUPS} -R "${PWD}" - sudoif podman volume rm cache_ostree - IMAGE=$(sudoif podman pull oci:${PWD}/mcos_{{image}}) - sudoif podman tag ${IMAGE} localhost/mcos:{{image}} - sudoif podman image scp root@localhost::localhost/mcos:{{image}} ${UID}@localhost::localhost/mcos:{{image}} - sudoif podman rmi localhost/mcos:{{image}} - sudoif podman rmi ghcr.io/hhd-dev/rechunk:latest - sudoif chown ${UID}:${GROUPS} -R "${PWD}"/"${OUT_NAME}" - -# Build and Rechunk -build-rechunk image="bluefin": (build image) (rechunk image) - -# Cleanup -clean: - find ${PWD}/mcos_* -maxdepth 0 -exec rm -rf {} \; || true - rm -rf previous.manifest.json \ No newline at end of file + + # Cleanup + just sudoif "find ${OUT_NAME} -type d -exec chmod 0755 {} \;" || true + just sudoif "find ${OUT_NAME}* -type f -exec chmod 0644 {} \;" || true + if [[ "${UID}" -gt 0 ]]; then + just sudoif chown ${UID}:${GROUPS} -R "${PWD}" + fi + just sudoif podman volume rm cache_ostree + just sudoif podman rmi localhost/"${dst_img}":"${dst_tag}" + + # Load Image into Podman Store + IMAGE=$(podman pull oci:"${PWD}"/"${OUT_NAME}") + podman tag ${IMAGE} localhost/"${dst_img}":"${dst_tag}" + +# Run Container +[group('Image')] +run image="bluefin" tag="stable" flavor="main": + #!/usr/bin/bash + set -eoux pipefail + image={{ image }} + tag={{ tag }} + flavor={{ flavor }} + + # Validate is handled by gen-build-src-dst + build_src_dst=($(just gen-build-src-dst "${image}" "${tag}" "${flavor}")) + src_img=${build_src_dst[0]} + src_tag=${build_src_dst[1]} + dst_img=${build_src_dst[2]} + dst_tag=${build_src_dst[3]} + + # Check if image exists + ID=$(podman images --filter reference=localhost/"${dst_img}":"${dst_tag}" --format "'{{ '{{.ID}}' }}'") + if [[ -z "$ID" ]]; then + just build "$image" "$tag" "$flavor" + fi + + # Run Container + podman run -it --rm localhost/"${dst_img}":"${dst_tag}" bash + +# Get Fedora Version of an image +[group('Utility')] +fedora_version image="bluefin" tag="stable" flavor="main": + #!/usr/bin/bash + set -eou pipefail + just validate {{ image }} {{ tag }} {{ flavor }} + if [[ ! -f /tmp/manifest.json ]]; then + if [[ "{{ tag }}" =~ stable ]]; then + # CoreOS does not uses cosign + skopeo inspect --retry-times 3 docker://quay.io/fedora/fedora-coreos:stable > /tmp/manifest.json + else + skopeo inspect --retry-times 3 docker://ghcr.io/ublue-os/base-main:"{{ tag }}" > /tmp/manifest.json + fi + fi + fedora_version=$(jq -r '.Labels["ostree.linux"]' < /tmp/manifest.json | grep -oP 'fc\K[0-9]+') + echo "${fedora_version}" diff --git a/README.md b/README.md index 79fedc6..40697e1 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ # mcOS -[![build-ublue](https://github.com/johnmmcgee/mcos/actions/workflows/build.yml/badge.svg)](https://github.com/johnmmcgee/mcos/actions/workflows/build.yml) +[![mcos Build Desktop](https://github.com/johnmmcgee/mcos/actions/workflows/build-desktop.yml/badge.svg)](https://github.com/johnmmcgee/mcos/actions/workflows/build-desktop.yml) +[![bOS Build Server](https://github.com/johnmmcgee/mcos/actions/workflows/build-server.yml/badge.svg)](https://github.com/johnmmcgee/mcos/actions/workflows/build-server.yml) + These are mostly stock projected bluefin images that I created for my own personal use. Intial ideas for this repo stemed from: -[https://github.com/bsherman/bOS/] (https://github.com/bsherman/bOS) +[https://github.com/bsherman/bos/] (https://github.com/bsherman/bos) ## Usage diff --git a/build.sh b/build.sh index 4c9de82..245a096 100755 --- a/build.sh +++ b/build.sh @@ -2,6 +2,29 @@ set -ouex pipefail +# there is no 'rpm-ostree cliwrap uninstall-from-root', but this is close enough. See: +# https://github.com/coreos/rpm-ostree/blob/6d2548ddb2bfa8f4e9bafe5c6e717cf9531d8001/rust/src/cliwrap.rs#L25-L32 +if [ -d /usr/libexec/rpm-ostree/wrapped ]; then + # binaries which could be created if they did not exist thus may not be in wrapped dir + rm -f \ + /usr/bin/yum \ + /usr/bin/dnf \ + /usr/bin/kernel-install + # binaries which were wrapped + mv -f /usr/libexec/rpm-ostree/wrapped/* /usr/bin + rm -fr /usr/libexec/rpm-ostree +fi + +rpm-ostree install dnf5 dnf5-plugins + +# temp until https://github.com/ublue-os/main/pull/665 trickles down: +mkdir -p /usr/share/dnf/plugins +cat << EOF > /usr/share/dnf/plugins/copr.vendor.conf +[main] +distribution = fedora +EOF + + case "${IMAGE}" in "bluefin"*) /ctx/build_files/desktop-changes.sh diff --git a/build_files/build-fix.sh b/build_files/build-fix.sh index 741f40f..5758220 100755 --- a/build_files/build-fix.sh +++ b/build_files/build-fix.sh @@ -13,130 +13,105 @@ for repo in "${repos[@]}"; do fi done -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ systemd-libs \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ vulkan-loader \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ alsa-lib \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ gnutls \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ glib2 \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ nspr \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ nss \ nss-softokn \ nss-softokn-freebl \ nss-sysinit \ nss-util \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ atk \ at-spi2-atk \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ libaom \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ gstreamer1 \ gstreamer1-plugins-base \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ libdecor \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ libtirpc \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ libuuid \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ libblkid \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ libmount \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ cups-libs \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ libinput \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ libopenmpt \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ llvm-libs \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ zlib-ng-compat \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ fontconfig \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ pciutils-libs \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ libdrm \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ cpp \ libatomic \ libgcc \ @@ -145,28 +120,25 @@ rpm-ostree override replace \ libobjc \ libstdc++ \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ libX11 \ libX11-common \ libX11-xcb \ || true -rpm-ostree override replace \ - --experimental \ - --from repo=updates \ +dnf5 reinstall -y \ + --repo=updates \ libv4l \ || true if grep -q "aurora" <<< "${IMAGE}"; then \ - rpm-ostree override replace \ - --experimental \ - --from repo=updates \ + dnf5 reinstall -y \ + --repo=updates \ qt6-qtbase \ qt6-qtbase-common \ qt6-qtbase-mysql \ qt6-qtbase-gui \ || true \ ; fi -rpm-ostree override remove \ +dnf5 remove -y \ glibc32 \ || true diff --git a/build_files/desktop-fixups-steam.sh b/build_files/desktop-fixups-steam.sh index 5f1db4d..4474416 100755 --- a/build_files/desktop-fixups-steam.sh +++ b/build_files/desktop-fixups-steam.sh @@ -3,16 +3,14 @@ set -eoux pipefail # OBS-VKcapture -curl -Lo /etc/yum.repos.d/_copr_kylegospo-obs-vkcapture.repo \ - https://copr.fedorainfracloud.org/coprs/kylegospo/obs-vkcapture/repo/fedora-"$(rpm -E %fedora)"/kylegospo-obs-vkcapture-fedora-"$(rpm -E %fedora)".repo?arch=x86_64 +dnf5 -y copr enable kylegospo/obs-vkcapture # Bazzite Repos -curl -Lo /etc/yum.repos.d/_copr_kylegospo-bazzite.repo \ - https://copr.fedorainfracloud.org/coprs/kylegospo/bazzite/repo/fedora-"$(rpm -E %fedora)"/kylegospo-bazzite-fedora-"$(rpm -E %fedora)".repo -curl -Lo /etc/yum.repos.d/_copr_kylegospo-bazzite-multilib.repo \ - https://copr.fedorainfracloud.org/coprs/kylegospo/bazzite-multilib/repo/fedora-"$(rpm -E %fedora)"/kylegospo-bazzite-multilib-fedora-"$(rpm -E %fedora)".repo?arch=x86_64 -curl -Lo /etc/yum.repos.d/_copr_kylegospo-latencyflex.repo \ - https://copr.fedorainfracloud.org/coprs/kylegospo/LatencyFleX/repo/fedora-"$(rpm -E %fedora)"/kylegospo-LatencyFleX-fedora-"$(rpm -E %fedora)".repo +dnf5 -y copr enable kylegospo/bazzite +dnf5 -y copr enable kylegospo/bazzite-multilib +dnf5 -y copr enable kylegospo/LatencyFleX + +find /etc/yum.repos.d/ sed -i "0,/enabled=0/{s/enabled=0/enabled=1/}" /etc/yum.repos.d/negativo17-fedora-multimedia.repo diff --git a/build_files/desktop-packages.sh b/build_files/desktop-packages.sh index 07c5dc1..6c83465 100755 --- a/build_files/desktop-packages.sh +++ b/build_files/desktop-packages.sh @@ -6,7 +6,7 @@ echo "Running desktop packages scripts..." #/ctx/build_files/desktop-1password.sh # common packages installed to desktops -rpm-ostree install \ +dnf5 install -y \ alacritty \ ansible \ autofs \ @@ -59,13 +59,13 @@ rpm-ostree install \ zsh # common packages excluded from desktop -rpm-ostree override remove \ +dnf5 remove -y \ firefox \ firefox-langpacks \ gnome-tour || true ## github direct installs -#/ctx/build_files/github-release-install.sh twpayne/chezmoi x86_64 +/ctx/build_files/github-release-install.sh twpayne/chezmoi x86_64 # Zed because why not? curl -Lo /tmp/zed.tar.gz \ @@ -80,4 +80,4 @@ sed -i "s@Exec=zed@Exec=/usr/lib/zed.app/libexec/zed-editor@g" /usr/share/applic # vscode stuff rpm --import https://packages.microsoft.com/keys/microsoft.asc echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" | tee /etc/yum.repos.d/vscode.repo -rpm-ostree install code \ No newline at end of file +dnf5 install -y code \ No newline at end of file diff --git a/build_files/server-changes.sh b/build_files/server-changes.sh index 8773349..2be2dd6 100755 --- a/build_files/server-changes.sh +++ b/build_files/server-changes.sh @@ -6,7 +6,7 @@ echo "Tweaking existing server config..." #if [[ ${IMAGE} =~ ucore ]]; then # # moby-engine packages on uCore conflict with docker-ce -# rpm-ostree override remove \ +# dnf5 remove -y \ # containerd moby-engine runc # rm -f /usr/bin/docker-compose # rm -fr /usr/libexec/docker diff --git a/build_files/server-cockpit-zfs.sh b/build_files/server-cockpit-zfs.sh index 98ca113..b396cdd 100755 --- a/build_files/server-cockpit-zfs.sh +++ b/build_files/server-cockpit-zfs.sh @@ -3,7 +3,7 @@ set -ouex pipefail # cockpit extensions not in ucore -rpm-ostree install cockpit-files cockpit-ostree +dnf5 install -y cockpit-files cockpit-ostree # cockpit-zfs-manager git clone https://github.com/45drives/cockpit-zfs-manager.git diff --git a/build_files/server-packages.sh b/build_files/server-packages.sh index ddf6228..8845282 100755 --- a/build_files/server-packages.sh +++ b/build_files/server-packages.sh @@ -6,7 +6,7 @@ echo "Running server packages scripts..." #/ctx/build_files/server-docker-ce.sh # common packages installed to desktops and servers -rpm-ostree install \ +dnf5 install -y \ cockpit-storaged \ hdparm \ igt-gpu-tools \ @@ -18,10 +18,10 @@ rpm-ostree install \ nmap \ sanoid -rpm-ostree override remove \ +dnf5 remove -y \ nfs-utils-coreos \ || true -rpm-ostree install \ +dnf5 install -y \ nfs-utils \ || true diff --git a/build_files/steam.sh b/build_files/steam.sh index 7eebab6..74fbbae 100755 --- a/build_files/steam.sh +++ b/build_files/steam.sh @@ -33,7 +33,7 @@ STEAM_PACKAGES=( wine-pulseaudio.x86_64 ) -rpm-ostree install "${STEAM_PACKAGES[@]}" +dnf5 install -y "${STEAM_PACKAGES[@]}" ln -sf wine32 /usr/bin/wine ln -sf wine32-preloader /usr/bin/wine-preloader