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 90b608a..d07b353 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,157 +1,176 @@ --- -name: build-ublue-custom -on: - pull_request: - branches: - - main - schedule: - - cron: '00 10 * * 01' # 10:00am UTC (2am Pacific) every Monday - push: - branches: - - main - paths-ignore: - - '**/README.md' - 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: "HyprBlue Custom Image, based on bluefin-dx-nvidia" - 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 - runs-on: ubuntu-24.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@v4 - - - name: Maximize Build Space - uses: ublue-os/remove-unwanted-software@v8 - - - name: Generate Tags - id: generate-tags - shell: bash - 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}" + name: Build HyprBlue Custom Image + on: + pull_request: + branches: + - main + schedule: + - cron: '05 10 * * *' # 10:05am UTC everyday to pull latest from parent image + push: + branches: + - main + paths-ignore: + - '**/README.md' + workflow_dispatch: + + env: + IMAGE_NAME: "${{ github.event.repository.name }}" # the name of the image produced by this build, matches repo names + MY_IMAGE_DESC: "HyprBlue Custom Image, based on bluefin-dx-nvidia" + IMAGE_REGISTRY: "ghcr.io/${{ github.repository_owner }}" # do not edit + ARTIFACTHUB_LOGO_URL: "https://avatars.githubusercontent.com/u/11263?s=200&v=4" + + 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 + runs-on: ubuntu-24.04 + + permissions: + contents: read + packages: write + id-token: write + + steps: + # 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 + 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@369eb591f429131d6889c46b94e711f089e6ca96 # v5 + 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)". + 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_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: " " + + - 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.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: 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 + 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 }} + + # 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) + id: push + env: + REGISTRY_USER: ${{ github.actor }} + REGISTRY_PASSWORD: ${{ github.token }} + with: + registry: ${{ steps.registry_case.outputs.lowercase }} + 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 + # 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 + 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' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) + run: | + 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 - - 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 - - name: Image Metadata - uses: docker/metadata-action@v5 - id: meta - with: - images: | - ${{ env.MY_IMAGE_NAME }} - - 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 }} - - # 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.MY_IMAGE_NAME }} - tags: | - ${{ steps.generate-tags.outputs.alias_tags }} - 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@v6 - with: - string: ${{ env.IMAGE_REGISTRY }} - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Push Image 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: | - --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 - # 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: 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 }} + env: + TAGS: ${{ steps.push.outputs.digest }} + COSIGN_EXPERIMENTAL: false + COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} diff --git a/.gitignore b/.gitignore index 2f01194..bbc6166 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ cosign.key +_build_* diff --git a/Containerfile b/Containerfile index 51961a9..f486c4c 100644 --- a/Containerfile +++ b/Containerfile @@ -1,54 +1,8 @@ - -## 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="bluefin" - -# 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: -# -# -nvidia -# -zfs -# -nvidia-zfs -ARG SOURCE_SUFFIX="-dx-nvidia" -# ARG SOURCE_SUFFIX="-dx" - -# SOURCE_TAG arg must be a version built for the specific image: eg, 39, 40, gts, latest -ARG SOURCE_TAG="latest" - -## BUILD IMAGE - -FROM ghcr.io/ublue-os/${SOURCE_IMAGE}${SOURCE_SUFFIX}:${SOURCE_TAG} +FROM ghcr.io/ublue-os/bluefin-dx-nvidia:latest COPY build.sh install-chrome.sh /tmp/ 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 commit && \ + bootc container lint diff --git a/Justfile b/Justfile new file mode 100644 index 0000000..260cf62 --- /dev/null +++ b/Justfile @@ -0,0 +1,215 @@ +export repo_organization := env("GITHUB_REPOSITORY_OWNER", "ashebanow") +export image_name := env("IMAGE_NAME", "hyprblue") +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 + +[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 + +# test our githib actions to build image +# act: +# act -s GITHUB_TOKEN="$(gh auth token)" -P ubuntu-24.04=ghcr.io/catthehacker/ubuntu:full-24.04 + +# first, unsigned rebasing step. Reboot afterwards. +rebase-unsigned: + rpm-ostree rebase ostree-unverified-registry:ghcr.io/ashebanow/hyprblue:latest + +# second and final signed rebasing step. Reboot afterwards. +rebase-signed: + rpm-ostree rebase ostree-image-signed:docker://ghcr.io/ashebanow/hyprblue:latest + +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/artifacthub-repo.yml b/artifacthub-repo.yml new file mode 100644 index 0000000..bf2d03d --- /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/build.sh b/build.sh index f1d63a7..e748dc1 100755 --- a/build.sh +++ b/build.sh @@ -21,32 +21,33 @@ USE_SDDM=FALSE # NOTE: chrome .repo file is installed in the Containerfile prior # to running this script. -curl https://copr.fedorainfracloud.org/coprs/solopasha/hyprland/repo/fedora-${RELEASE}/solopasha-hyprland-fedora-${RELEASE}.repo \ - -o /etc/yum.repos.d/solopasha-hyprland.repo - -curl https://copr.fedorainfracloud.org/coprs/erikreider/SwayNotificationCenter/repo/fedora-${RELEASE}/erikreider-SwayNotificationCenter-fedora-${RELEASE}.repo \ - -o /etc/yum.repos.d/erikreider-SwayNotificationCenter.repo - -curl https://copr.fedorainfracloud.org/coprs/errornointernet/packages/repo/fedora-${RELEASE}/errornointernet-packages-fedora-${RELEASE}.repo \ - -o /etc/yum.repos.d/errornointernet-packages.repo - -curl https://copr.fedorainfracloud.org/coprs/tofik/sway/repo/fedora-${RELEASE}/tofik-sway-fedora-${RELEASE}.repo \ - -o /etc/yum.repos.d/tofik-sway.repo - -curl -Lo /etc/yum.repos.d/_copr_pgdev-ghostty-"${RELEASE}".repo https://copr.fedorainfracloud.org/coprs/pgdev/ghostty/repo/fedora-"${RELEASE}"/pgdev-ghostty-fedora-"${RELEASE}".repo +dnf5 -y copr enable solopasha/hyprland +dnf5 -y copr enable erikreider/SwayNotificationCenter +dnf5 -y copr enable errornointernet/packages +dnf5 -y copr enable tofik/sway +dnf5 -y copr enable pgdev/ghostty if [[ $USE_NWG_SHELL == TRUE ]]; then - curl https://copr.fedorainfracloud.org/coprs/tofik/nwg-shell/repo/fedora-${RELEASE}/tofik-nwg-shell-fedora-${RELEASE}.repo \ - -o /etc/yum.repos.d/tofik-nwg-shell.repo - - curl https://copr.fedorainfracloud.org/coprs/mochaa/gtk-session-lock/repo/fedora-${RELEASE}/mochaa-gtk-session-lock-fedora-${RELEASE}.repo \ - -o /etc/yum.repos.d/mochaa-gtk-session-lock.repo + dnf5 -y copr enable tofik/nwg-shell fi ####################################################################### ## Install Packages ####################################################################### +# Packages can be installed from any enabled yum repo on the image. +# RPMfusion repos are available by default in ublue main images + +# this installs a package from fedora repos +# dnf 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 + ### Install 1password using blue-build script curl https://downloads.1password.com/linux/keys/1password.asc | tee /etc/pki/rpm-gpg/1password.gpg curl -Lo 1password.sh https://raw.githubusercontent.com/blue-build/modules/22fe11d844763bf30bd83028970b975676fe7beb/modules/bling/installers/1password.sh @@ -105,7 +106,6 @@ HYPR_DEPS=( qt6-qtsvg qt6ct slurp - SwayNotificationCenter swww tumbler wallust @@ -153,12 +153,8 @@ if [[ $USE_SDDM == TRUE ]]; then ) fi +# 1password* and chrome are installed separately above. LAYERED_APPS=( - # 1password* and chrome are installed separately above. -# 1password -# 1password-cli -# google-chrome-stable - # We really should just pick one terminal emulator! ghostty kitty @@ -171,7 +167,7 @@ LAYERED_APPS=( # we do all package installs in one rpm-ostree command # so that we create minimal layers in the final image -rpm-ostree install \ +dnf5 install -y \ ${FONTS[@]} \ ${HYPR_DEPS[@]} \ ${HYPR_PKGS[@]} \ @@ -179,8 +175,18 @@ rpm-ostree install \ ${NWG_SHELL_PKGS[@]} \ ${LAYERED_APPS[@]} -https://www.google.com/chrome/next-steps.html?statcb=0&installdataindex=empty&defaultbrowser=0# +####################################################################### +### Disable repositeories so they aren't cluttering up the final image +dnf5 -y copr disable solopasha/hyprland +dnf5 -y copr disable erikreider/SwayNotificationCenter +dnf5 -y copr disable errornointernet/packages +dnf5 -y copr disable tofik/sway +dnf5 -y copr disable pgdev/ghostty + +if [[ $USE_NWG_SHELL == TRUE ]]; then + dnf5 -y copr disable tofik/nwg-shell +fi ####################################################################### ### Enable Services 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..733bdbd --- /dev/null +++ b/iso.toml @@ -0,0 +1,19 @@ +[customizations.installer.kickstart] +contents = """ +%post +bootc switch --mutate-in-place --transport registry ghcr.io/ashebanow/hyprblue: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/justfile b/justfile deleted file mode 100644 index 0914a93..0000000 --- a/justfile +++ /dev/null @@ -1,15 +0,0 @@ -# default recipe to display help information -default: - @just --list - -# test our githib actions to build image -act: - act -s GITHUB_TOKEN="$(gh auth token)" -P ubuntu-24.04=ghcr.io/catthehacker/ubuntu:full-24.04 - -# first, unsigned rebasing step. Reboot afterwards. -rebase-unsigned: - rpm-ostree rebase ostree-unverified-registry:ghcr.io/ashebanow/hyprblue:latest - -# second and final signed rebasing step. Reboot afterwards. -rebase-signed: - rpm-ostree rebase ostree-image-signed:docker://ghcr.io/ashebanow/hyprblue:latest