diff --git a/.gitea/workflows/build-disk.yml b/.gitea/workflows/build-disk.yml deleted file mode 100644 index 88756c0..0000000 --- a/.gitea/workflows/build-disk.yml +++ /dev/null @@ -1,115 +0,0 @@ ---- -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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 - - - 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/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 6a26172..88a2481 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -38,6 +38,10 @@ jobs: name: Build and push image runs-on: ubuntu-24.04 + strategy: + matrix: + variant: [gnome, niri] + permissions: contents: read packages: write @@ -74,9 +78,9 @@ jobs: # This generates all the tags for your image, you can add custom tags here too! tags: | type=sha,enable=${{ github.event_name == 'pull_request' }} - type=raw,value=latest - type=raw,value=${{ env.FEDORA_BASE }} - type=raw,value=${{ env.FEDORA_BASE }}-{{date 'YYYYMMDD'}} + type=raw,value=latest-${{ matrix.variant }} + type=raw,value=${{ env.FEDORA_BASE }}-${{ matrix.variant }} + type=raw,value=${{ env.FEDORA_BASE }}-${{ matrix.variant }}-{{date 'YYYYMMDD'}} type=ref,event=pr labels: | io.artifacthub.package.readme-url=${{ env.README_URL }} @@ -106,7 +110,7 @@ jobs: uses: redhat-actions/buildah-build@7a95fa7ee0f02d552a32753e7414641a04307056 # v2 with: containerfiles: | - ./Containerfile + ./Containerfile.${{ matrix.variant }} build-args: | FEDORA_BASE=${{ env.FEDORA_BASE }} image: ${{ env.IMAGE_NAME }} diff --git a/Containerfile b/Containerfile.gnome similarity index 94% rename from Containerfile rename to Containerfile.gnome index 588b154..5183285 100644 --- a/Containerfile +++ b/Containerfile.gnome @@ -1,4 +1,4 @@ -ARG FEDORA_BASE=42 +ARG FEDORA_BASE=43 # Allow build scripts to be referenced without being copied into the final image FROM scratch AS ctx @@ -28,7 +28,7 @@ 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/cleanup.sh + /ctx/gnome/build.sh && /ctx/gnome/cleanup.sh ### LINTING ## Verify final image and contents are correct. diff --git a/Containerfile.niri b/Containerfile.niri new file mode 100644 index 0000000..737732a --- /dev/null +++ b/Containerfile.niri @@ -0,0 +1,35 @@ +ARG FEDORA_BASE=43 + +# Allow build scripts to be referenced without being copied into the final image +FROM scratch AS ctx +COPY build_files / +COPY /sys_files /sys_files +COPY cosign.pub /cosign.pub + +# Base Image +FROM quay.io/fedora-ostree-desktops/base-atomic:$FEDORA_BASE + +### [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. + +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/niri/build.sh && /ctx/niri/cleanup.sh + +### LINTING +## Verify final image and contents are correct. +RUN bootc container lint diff --git a/build_files/build.sh b/build_files/gnome/build.sh similarity index 100% rename from build_files/build.sh rename to build_files/gnome/build.sh diff --git a/build_files/cleanup.sh b/build_files/gnome/cleanup.sh similarity index 100% rename from build_files/cleanup.sh rename to build_files/gnome/cleanup.sh diff --git a/build_files/niri/build.sh b/build_files/niri/build.sh new file mode 100755 index 0000000..4b3ab63 --- /dev/null +++ b/build_files/niri/build.sh @@ -0,0 +1,117 @@ +#!/bin/bash + +set -ouex pipefail + +# Copy System Files onto root +rsync -rvK /ctx/sys_files/ / + +# Copy cosign.pub key into the right location +mkdir -p /etc/pki/containers +cp /ctx/cosign.pub /etc/pki/containers/davejansen.pub + +### 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 + +# Install RPMFusion and enable fedora-multimedia with a higher priority than default +if ! grep -q fedora-multimedia <(dnf5 repolist); then + # Enable or Install Repofile + #dnf5 install \ + # https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm \ + # https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm + + # Enable fedora-multimedia + dnf5 config-manager setopt fedora-multimedia.enabled=1 || + dnf5 config-manager addrepo --from-repofile="https://negativo17.org/repos/fedora-multimedia.repo" +fi + +# Set higher priority +dnf5 config-manager setopt fedora-multimedia.priority=90 + +# Remove Fedora's package that enforces their own (filtered) version of the +# flathub repo is present, as-well as the system-installed Firefox as I prefer to use the Flatpak version +dnf5 remove -y fedora-flathub-remote + +# Add Flathub to the image for eventual application +mkdir -p /etc/flatpak/remotes.d/ +curl --retry 3 -Lo /etc/flatpak/remotes.d/flathub.flatpakrepo https://dl.flathub.org/repo/flathub.flatpakrepo + +# use override to replace mesa and others with less crippled versions +OVERRIDES=( + "intel-gmmlib" + "intel-mediasdk" + "intel-vpl-gpu-rt" + "libheif" + "libva" + "libva-intel-media-driver" + "mesa-dri-drivers" + "mesa-filesystem" + "mesa-libEGL" + "mesa-libGL" + "mesa-libgbm" + "mesa-va-drivers" + "mesa-vulkan-drivers" +) + +dnf5 distro-sync --skip-unavailable -y --repo='fedora-multimedia' "${OVERRIDES[@]}" +dnf5 versionlock add "${OVERRIDES[@]}" + +# Remove additional repositories Fedora comes with out of the box +# And don't raise an error if any of these files does not exist when attempting +# to delete them. +rm \ + /etc/yum.repos.d/fedora-cisco-openh264.repo \ + /etc/yum.repos.d/google-chrome.repo \ + /etc/yum.repos.d/rpmfusion-nonfree-nvidia-driver.repo \ + /etc/yum.repos.d/rpmfusion-nonfree-steam.repo \ + /etc/yum.repos.d/_copr:copr.fedorainfracloud.org:phracek:PyCharm.repo \ + 2>&1 + +# Add country query to all repo metalinks +# shellcheck disable=SC2016 +sed -i -e '/^metalink\=/s/\$releasever\&arch\=\$basearch$/\$releasever\&arch\=\$basearch\&country\=KR,JP,TW/g' /etc/yum.repos.d/*.repo + +# Add 1Password repo +#rpmkeys --import https://downloads.1password.com/linux/keys/1password.asc +cp /ctx/rpm-keys/1password.asc /etc/pki/rpm-gpg/1password.asc +sh -c 'echo -e "[1password]\nname=1Password Stable Channel\nbaseurl=https://downloads.1password.com/linux/rpm/stable/\$basearch\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=\"file:///etc/pki/rpm-gpg/1password.asc\"" > /etc/yum.repos.d/1password.repo' + +# Add Tailscale repo +#rpmkeys --import https://pkgs.tailscale.com/stable/fedora/repo.gpg +#dnf5 config-manager addrepo --from-repofile=https://pkgs.tailscale.com/stable/fedora/tailscale.repo +cp /ctx/rpm-keys/tailscale.gpg /etc/pki/rpm-gpg/tailscale.gpg +sh -c 'echo -e "[tailscale-stable]\nname=Tailscale stable\nbaseurl=https://pkgs.tailscale.com/stable/fedora/\$basearch\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=\"file:///etc/pki/rpm-gpg/tailscale.gpg\"" > /etc/yum.repos.d/tailscale.repo' + +# Update all existing packages +# dnf5 update -y + +# Install Niri, the scrollable-tiling window compositor +# https://yalter.github.io/niri/ +dnf5 -y copr enable avengemedia/dms + +# Install my own layered packages +dnf5 install -y \ + git \ + fish \ + gvfs-nfs \ + openssl \ + wl-clipboard \ + ffmpeg ffmpeg-libs ffmpegthumbnailer \ + heif-pixbuf-loader intel-vaapi-driver libavcodec libheif \ + libcamera libcamera-gstreamer libcamera-ipa libcamera-tools pipewire-plugin-libcamera \ + 1password 1password-cli \ + tailscale \ + waypipe \ + htop \ + alacritty \ + niri dms + +dnf5 -y copr disable avengemedia/dms + +# Enable Tailscale service +systemctl enable tailscaled + +echo "Done." diff --git a/build_files/niri/cleanup.sh b/build_files/niri/cleanup.sh new file mode 100755 index 0000000..72f3277 --- /dev/null +++ b/build_files/niri/cleanup.sh @@ -0,0 +1,120 @@ +#!/bin/bash + +set -ouex pipefail + +# Delete 1Password and Tailscale repos once packages are installed +# so they don't end up in the final image, and don't raise an error if any of +# these files does not exist when attempting to delete them. +rm \ + /etc/yum.repos.d/1password.repo \ + /etc/yum.repos.d/tailscale.repo \ + /etc/pki/rpm-gpg/1password.asc \ + /etc/pki/rpm-gpg/tailscale.gpg \ + 2>&1 + +# Or just disable: +# dnf5 config-manager setopt 1password.enabled=0 tailscale-stable.enabled=0 +# sed -i 's/enabled=1/enabled=0/' \ +# /etc/yum.repos.d/1password.repo \ +# /etc/yum.repos.d/tailscale.repo \ + +# Fedora Flatpak service is a part of the flatpak package, ensure it's overridden by moving to replace it at the end of the build. +mv -f /usr/lib/systemd/system/flatpak-add-flathub-repos.service /usr/lib/systemd/system/flatpak-add-fedora-repos.service + +# Re-install all pre-installed (GNOME) applications from Flathub +#flatpak install --reinstall flathub "$(flatpak list --app-runtime=org.fedoraproject.Platform --columns=application | tail -n +1 )" + +# ...and remove the fedora flatpak remotes +#flatpak remote-delete --force fedora +#flatpak remote-delete --force fedora-testing + +# TODO: Add flathub remove, enable, and remove filter +# TODO: Install core GNOME Flatpak apps +# TODO: Install my own commonly used Flatpak apps +# IDEA: Can I set certain dconf settings, like Ptyxis config, temperature settings, etc? +# IDEA: Can I set certain Flatpak system defaults (ie. no read/write anywhere by default) + +# Remove dnf5 versionlocks +dnf5 versionlock clear + +# Remove tmp files and everything in dirs that make bootc unhappy +rm -rf /tmp/* || true +rm -rf /usr/etc +rm -rf /boot && mkdir /boot +# Preserve cache mounts +find /var/* -maxdepth 0 -type d \! -name cache \! -name log -exec rm -rf {} \; +find /var/cache/* -maxdepth 0 -type d \! -name libdnf5 -exec rm -rf {} \; + +# Make sure /var/tmp is properly created +mkdir -p /var/tmp +chmod -R 1777 /var/tmp + +## Handle files that rpm-ostree would normally remove +## Adapted from: https://github.com/hhd-dev/rechunk/blob/master/1_prune.sh#L33 + +# if [ -f /etc/passwd ]; then +# out="$(grep -v 'root' /etc/passwd)" +# +# if [[ ! -z "$out" ]]; then +# echo +# echo Appending the following passwd users to /usr/lib/passwd +# echo "${out}" +# echo "$out" >>/usr/lib/passwd +# fi +# fi + +if [ -f /etc/group ]; then + out="$(grep -v 'root\|wheel' /etc/group)" + + if [[ ! -z "$out" ]]; then + echo + echo Appending the following group entries to /usr/lib/group + echo "$out" + echo "$out" >>/usr/lib/group + fi +fi + +if [ -f /etc/passwd ] || [ -f /etc/group ]; then + echo + echo "Warning: Make sure processed users and groups are from installed programs!" +fi + +# # Create defaults for /etc/passwd, /etc/group +# cat </etc/passwd +# root:x:0:0:root:/root:/bin/bash +# EOT +# cat </etc/group +# root:x:0: +# wheel:x:10: +# EOT + +# Extra lock files created by container processes that might cause issues +rm -rf \ + /etc/.pwd.lock \ + /etc/passwd- \ + /etc/group- \ + /etc/shadow- \ + /etc/gshadow- \ + /etc/subuid- \ + /etc/subgid- \ + /.dockerenv + +# # Merge /usr/etc to /etc +# # OSTree will error out if both dirs exist +# # And rpm-ostree will be confused and use only one of them +# if [ -d /usr/etc ]; then +# echo +# echo WARNING: FOUND /usr/etc. MERGING TO ETC FOR COMPATIBILITY +# echo EXPECT PERMISSIONS ISSUES ON THE MERGED PATHS +# echo The following files from /usr/etc will be merged to /etc: +# tree /usr/etc +# +# echo +# rsync -aAX --numeric-ids --checksum --links /usr/etc/ /etc +# rm -rf /usr/etc +# fi +# +# # Move /etc to /usr/etc +# mv /etc /usr/ + +# ...normal ublue-inspired steps continue.