commit b09d43fa87470bd31be76fd0da0c14b7b84f7bf9 Author: Khalaf Date: Sun May 10 01:24:12 2026 +0400 KAMOS Gaming OS - initial scaffold with branding diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml new file mode 100644 index 0000000..8efed6f --- /dev/null +++ b/.forgejo/workflows/build.yml @@ -0,0 +1,141 @@ +############################################################################### +# Forgejo Actions - build, sign, and push the KAMOS Gaming OS image +# +# Configured for: cgi.medsys.cloud/mkm1971/kamos +# Runner labels: ubuntu-latest / ubuntu-24.04 / ubuntu-22.04 (Forgejo runner v0.4.1) +# +# Prereqs in your Forgejo repo: +# 1. Container Registry feature enabled on cgi.medsys.cloud. +# 2. The runner host must be x86_64 (Bazzite NVIDIA is x86_64 only). +# 3. Repository secrets at /mkm1971/kamos/settings/actions/secrets: +# - SIGNING_SECRET contents of cosign.key (NOT the .pub) +# - REGISTRY_USER mkm1971 +# - REGISTRY_TOKEN Forgejo access token with `package` write scope +############################################################################### + +name: build-image + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + # Rebuild weekly so we pick up base-image security updates. + - cron: "0 6 * * 1" + workflow_dispatch: + +env: + IMAGE_NAME: kamos + IMAGE_TAGS: "stable latest" + # Override this in your Forgejo repo's variables to point at your instance. + REGISTRY: ${{ vars.REGISTRY || 'cgi.medsys.cloud' }} + REGISTRY_USER: ${{ secrets.REGISTRY_USER }} + REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} + +jobs: + build: + name: Build & push (${{ matrix.platform }}) + # Matches your runner labels: ubuntu-latest / ubuntu-24.04 / ubuntu-22.04 + # Assumes the runner host is x86_64 - if it's actually Apple Silicon, the + # build will hit "exec format error" and we'll need to add binfmt qemu setup. + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + strategy: + fail-fast: false + matrix: + platform: [linux/amd64] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Compute tags + id: tags + shell: bash + run: | + DATE_TAG="$(date +%Y%m%d)" + SHA_TAG="${GITHUB_SHA::7}" + { + echo "date_tag=${DATE_TAG}" + echo "sha_tag=${SHA_TAG}" + echo "image_ref=${REGISTRY}/${{ gitea.repository_owner }}/${IMAGE_NAME}" + } >> "$GITHUB_OUTPUT" + + - name: Install build tooling + shell: bash + run: | + sudo apt-get update -y + sudo apt-get install -y podman buildah skopeo cosign jq + + - name: Build image + id: build + shell: bash + env: + IMAGE_REF: ${{ steps.tags.outputs.image_ref }} + DATE_TAG: ${{ steps.tags.outputs.date_tag }} + SHA_TAG: ${{ steps.tags.outputs.sha_tag }} + run: | + set -euxo pipefail + podman build \ + --platform=${{ matrix.platform }} \ + --pull=newer \ + --tag "${IMAGE_REF}:${DATE_TAG}" \ + --tag "${IMAGE_REF}:${SHA_TAG}" \ + $(for t in $IMAGE_TAGS; do echo --tag "${IMAGE_REF}:${t}"; done) \ + . + + - name: Login to Forgejo container registry + if: github.event_name != 'pull_request' + shell: bash + run: | + echo "${REGISTRY_TOKEN}" | podman login \ + --username "${REGISTRY_USER}" \ + --password-stdin \ + "${REGISTRY}" + + - name: Push image + if: github.event_name != 'pull_request' + shell: bash + env: + IMAGE_REF: ${{ steps.tags.outputs.image_ref }} + DATE_TAG: ${{ steps.tags.outputs.date_tag }} + SHA_TAG: ${{ steps.tags.outputs.sha_tag }} + run: | + set -euxo pipefail + for tag in $DATE_TAG $SHA_TAG $IMAGE_TAGS; do + podman push "${IMAGE_REF}:${tag}" + done + + - name: Sign image with cosign + if: github.event_name != 'pull_request' + shell: bash + env: + COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} + COSIGN_PASSWORD: "" + IMAGE_REF: ${{ steps.tags.outputs.image_ref }} + run: | + set -euxo pipefail + for tag in $IMAGE_TAGS; do + DIGEST=$(skopeo inspect --format '{{.Digest}}' "docker://${IMAGE_REF}:${tag}") + cosign sign --yes --key env://COSIGN_PRIVATE_KEY "${IMAGE_REF}@${DIGEST}" + done + + - name: Summary + shell: bash + env: + IMAGE_REF: ${{ steps.tags.outputs.image_ref }} + run: | + { + echo "### Built image" + echo "" + echo "\`${IMAGE_REF}\` with tags: ${IMAGE_TAGS}" + echo "" + echo "Switch a target machine to this image with:" + echo "" + echo "\`\`\`" + echo "sudo bootc switch ${IMAGE_REF}:stable" + echo "\`\`\`" + } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..96345fd --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,62 @@ +############################################################################### +# GitHub Actions equivalent of the Forgejo workflow. +# Disabled by default - rename to build.yml or remove the `if:` guard below +# if you decide to mirror to GitHub. +############################################################################### + +name: build-image-github + +on: + workflow_dispatch: + # Uncomment when you actually want GitHub to build: + # push: + # branches: [main] + # schedule: + # - cron: "0 6 * * 1" + +env: + IMAGE_NAME: kamos + IMAGE_TAGS: "stable latest" + REGISTRY: ghcr.io + +jobs: + build: + runs-on: ubuntu-latest + if: ${{ false }} # remove this line to enable + permissions: + contents: read + packages: write + id-token: write + steps: + - uses: actions/checkout@v4 + + - name: Login to GHCR + uses: redhat-actions/podman-login@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build + run: | + IMAGE_REF="${REGISTRY}/${{ github.repository_owner }}/${IMAGE_NAME}" + podman build \ + --pull=newer \ + $(for t in $IMAGE_TAGS; do echo --tag "${IMAGE_REF}:${t}"; done) \ + . + + - name: Push + run: | + IMAGE_REF="${REGISTRY}/${{ github.repository_owner }}/${IMAGE_NAME}" + for t in $IMAGE_TAGS; do podman push "${IMAGE_REF}:${t}"; done + + - name: Sign + env: + COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }} + COSIGN_PASSWORD: "" + run: | + IMAGE_REF="${REGISTRY}/${{ github.repository_owner }}/${IMAGE_NAME}" + for t in $IMAGE_TAGS; do + DIGEST=$(skopeo inspect --format '{{.Digest}}' "docker://${IMAGE_REF}:${t}") + cosign sign --yes --key env://COSIGN_PRIVATE_KEY "${IMAGE_REF}@${DIGEST}" + done diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..59b15bf --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Build output +output/ +*.qcow2 +*.iso +*.raw + +# Cosign - the .key file MUST never be committed +cosign.key +*.key + +# OS / editor cruft +.DS_Store +.idea/ +.vscode/ +*.swp diff --git a/Containerfile b/Containerfile new file mode 100644 index 0000000..ef59c00 --- /dev/null +++ b/Containerfile @@ -0,0 +1,52 @@ +# ============================================================================= +# KAMOS - Gaming OS - Containerfile +# "Play. Perform. Dominate." +# Base: Bazzite NVIDIA stable (proprietary NVIDIA driver, gaming-tuned bootc) +# ============================================================================= +# +# Why this base: +# ghcr.io/ublue-os/bazzite-nvidia:stable ships with the proprietary NVIDIA +# driver baked in via akmods. If you want the open-kernel-module variant, +# swap to ghcr.io/ublue-os/bazzite-nvidia-open:stable instead. +# +# Architecture: x86_64 only. This image will NOT boot natively on an Apple +# Silicon Mac. Test it inside VMware Fusion (with x86_64 emulation enabled) +# or install on a real NVIDIA PC. +# ----------------------------------------------------------------------------- + +ARG BASE_IMAGE="ghcr.io/ublue-os/bazzite-nvidia" +ARG BASE_TAG="stable" + +FROM ${BASE_IMAGE}:${BASE_TAG} + +# OCI labels - good practice and surface nicely on registries / artifacthub. +LABEL org.opencontainers.image.title="KAMOS" +LABEL org.opencontainers.image.description="KAMOS Gaming OS - Bazzite NVIDIA stable bootc image. Play. Perform. Dominate." +LABEL org.opencontainers.image.vendor="Khalaf" +LABEL org.opencontainers.image.source="https://cgi.medsys.cloud/mkm1971/kamos" +LABEL org.opencontainers.image.licenses="Apache-2.0" +LABEL io.artifacthub.package.readme-url="https://cgi.medsys.cloud/mkm1971/kamos/raw/branch/main/README.md" + +# ----------------------------------------------------------------------------- +# Stage 1: copy our customisations into the build context +# ----------------------------------------------------------------------------- +COPY build_files/ /tmp/build_files/ +COPY system_files/ / + +# ----------------------------------------------------------------------------- +# Stage 2: run the customisation script +# - install / remove packages +# - apply branding (wallpaper, plymouth theme, os-release, GRUB logo) +# - any other system tweaks +# ----------------------------------------------------------------------------- +RUN --mount=type=cache,dst=/var/cache \ + --mount=type=cache,dst=/var/log \ + --mount=type=tmpfs,dst=/tmp \ + /tmp/build_files/build.sh && \ + ostree container commit + +# ----------------------------------------------------------------------------- +# Sanity: make sure the image is bootc-compatible after our changes. +# `bootc container lint` is run by ostree container commit but we surface a +# friendly error via a final no-op so layer caching is clear. +# ----------------------------------------------------------------------------- diff --git a/Justfile b/Justfile new file mode 100644 index 0000000..1f9c3c9 --- /dev/null +++ b/Justfile @@ -0,0 +1,79 @@ +############################################################################### +# Justfile - convenience commands for building and testing the image +# Run `just` (no args) to see the list. Requires `just` (brew install just). +############################################################################### + +image_name := "kamos" +default_tag := "stable" +bib_image := "quay.io/centos-bootc/bootc-image-builder:latest" + +# Show available recipes. +default: + @just --list + +# Build the OCI image with podman. +# On an Apple Silicon Mac you MUST pass --platform=linux/amd64 because the +# upstream Bazzite NVIDIA image is x86_64 only. This will use qemu emulation +# and will be slow. CI is the much faster path. +build target_image=image_name tag=default_tag: + podman build \ + --platform=linux/amd64 \ + --pull=newer \ + --tag {{ target_image }}:{{ tag }} \ + . + +# Build a QCOW2 disk image (good for testing in VMware/UTM/QEMU). +build-qcow2 target_image=image_name tag=default_tag: + just _build-disk {{ target_image }} {{ tag }} qcow2 + +# Build an ISO suitable for installation onto a real NVIDIA PC. +build-iso target_image=image_name tag=default_tag: + just _build-disk {{ target_image }} {{ tag }} iso + +# Build a raw disk image. +build-raw target_image=image_name tag=default_tag: + just _build-disk {{ target_image }} {{ tag }} raw + +# Internal: invoke bootc-image-builder. +_build-disk target_image tag type: + mkdir -p output + podman run \ + --rm \ + --privileged \ + --pull=newer \ + --security-opt label=type:unconfined_t \ + -v $(pwd)/output:/output \ + -v $(pwd)/disk_config:/config:ro \ + -v /var/lib/containers/storage:/var/lib/containers/storage \ + {{ bib_image }} \ + --type {{ type }} \ + --use-librepo=True \ + --local \ + localhost/{{ target_image }}:{{ tag }} + +# Run the QCOW2 image in QEMU directly (fast, headless-friendly). +run-vm-qcow2: + qemu-system-x86_64 \ + -enable-kvm \ + -M q35 \ + -cpu host \ + -smp 4 \ + -m 6G \ + -drive file=output/qcow2/disk.qcow2,if=virtio \ + -nic user,model=virtio-net-pci + +# Lint shell scripts. +lint: + shellcheck build_files/*.sh + +# Format shell scripts. +format: + shfmt -w build_files/*.sh + +# Validate the Justfile itself. +check: + just --fmt --check --unstable + +# Remove build artifacts. +clean: + rm -rf output diff --git a/README.md b/README.md new file mode 100644 index 0000000..d824890 --- /dev/null +++ b/README.md @@ -0,0 +1,141 @@ +# KAMOS - Gaming OS + +> Play. Perform. Dominate. + +KAMOS is a personal Bazzite-based bootc image with custom logo, wallpaper, boot splash, and OS branding. Built on top of `ghcr.io/ublue-os/bazzite-nvidia:stable` so the proprietary NVIDIA driver and Bazzite's gaming/desktop tuning come for free. + +## Architecture note (important if you're on a Mac) + +KAMOS is `linux/amd64` only. Bazzite NVIDIA has no ARM64 build and NVIDIA's proprietary driver doesn't run on Apple Silicon anyway. The MacBook M2 is fine as a *build host* (CI does the heavy lifting) and as a *test host* via VMware Fusion's x86_64 emulation, but KAMOS is meant to run on a real NVIDIA PC. + +## Layout + +``` +kamos/ +├── Containerfile # FROM bazzite-nvidia:stable + COPY + RUN build.sh +├── Justfile # build / build-iso / build-qcow2 / lint +├── build_files/ +│ └── build.sh # all KAMOS customisation lives here +├── disk_config/ +│ └── iso.toml # bootc-image-builder ISO config +├── system_files/ # COPY'd into / inside the image +│ └── usr/share/ +│ ├── backgrounds/kamos/ # drop kamos-wallpaper.jpg here +│ ├── plymouth/themes/kamos/ # boot splash (kamos.plymouth + kamos.script + logo) +│ └── pixmaps/ # drop kamos-logo.png here (GRUB logo) +├── .forgejo/workflows/build.yml # primary CI - builds & pushes to Forgejo +└── .github/workflows/build.yml # disabled GitHub equivalent (mirror if needed) +``` + +## Step 1 — Drop in your KAMOS branding assets + +The repo has placeholder `DROP_*_HERE.txt` files in the right folders. Replace them with: + +| Path | What goes here | Recommended size | +| --------------------------------------------------------------------- | ------------------------------------------- | --------------------- | +| `system_files/usr/share/backgrounds/kamos/kamos-wallpaper.jpg` | Your "Play. Perform. Dominate." wallpaper | 3840x2160 or 1920x1080 | +| `system_files/usr/share/plymouth/themes/kamos/kamos-logo.png` | KAMOS logo (raven crest) for boot splash | 256x256 or 512x512, transparent PNG | +| `system_files/usr/share/pixmaps/kamos-logo.png` | Same logo, used by GRUB boot menu | 256x256 or 512x512, transparent PNG | + +You can drop additional files anywhere under `system_files/`; they'll all be COPY'd into `/`. Delete the `DROP_*_HERE.txt` files once you've added the real assets. + +## Step 2 — Configure your Forgejo registry + +The repo is already wired for `cgi.medsys.cloud/mkm1971/kamos` and the runner label `ubuntu-latest`. You only need to add three secrets so CI can push and sign images. + +Go to **https://cgi.medsys.cloud/mkm1971/kamos/settings/actions/secrets** and add: + +| Secret name | Value | +| ---------------- | -------------------------------------------------------------- | +| `SIGNING_SECRET` | The full contents of `cosign.key` (created in Step 3 below) | +| `REGISTRY_USER` | `mkm1971` | +| `REGISTRY_TOKEN` | A Forgejo access token with `package` write scope | + +To create `REGISTRY_TOKEN`: in Forgejo, click your avatar (top-right) → **Settings → Applications → Generate New Token**. Name it `kamos-ci`, tick the **package: write** scope, click Generate, and copy the token immediately (it's shown only once). + +## Step 3 — Generate a cosign signing key + +On your M2: + +```bash +brew install cosign +cd /path/to/kamos +COSIGN_PASSWORD="" cosign generate-key-pair +``` + +Creates `cosign.key` (private — **never commit**) and `cosign.pub` (commit this). Paste the contents of `cosign.key` into the `SIGNING_SECRET` repository secret. + +## Step 4 — Push to Forgejo and let CI build + +```bash +git init +git add . +git commit -m "KAMOS initial scaffold" +git remote add origin https://cgi.medsys.cloud/mkm1971/kamos.git +git push -u origin main +``` + +Forgejo Actions needs an `linux-amd64` runner. Register one on any x86_64 Linux machine (the NVIDIA PC works perfectly). + +## Step 5 — (Optional) Iterate locally on the M2 + +The base image is x86_64, so Podman has to emulate. Slow but works for quick checks. + +```bash +brew install podman just +podman machine init --cpus 6 --memory 8192 --disk-size 60 +podman machine start +just build +``` + +## Step 6 — Generate a bootable ISO for VMware Fusion + +```bash +just build # builds the OCI image +just build-iso # wraps it with bootc-image-builder into output/bootiso/install.iso +``` + +VMware Fusion 13+ on Apple Silicon supports x86_64 emulation. New VM → install from ISO → choose `output/bootiso/install.iso` → guest type "Other Linux 5.x kernel 64-bit". Expect single-digit FPS in the GUI, but the boot splash and branding will render fine. This is the path you mentioned for your VMware testing setup. + +## Step 7 — Install on the real NVIDIA PC + +If the PC is already on a bootc image (Bazzite, Bluefin, Aurora, etc.): + +```bash +sudo bootc switch cgi.medsys.cloud/mkm1971/kamos:stable +sudo systemctl reboot +``` + +If it's running something else, install Bazzite from its normal ISO first, then `bootc switch` to KAMOS. Or burn the ISO from step 6 to a USB stick and install fresh. + +## Updating + +CI rebuilds weekly so you pick up upstream Bazzite security fixes. Push any commit to `main` or run the workflow manually to bump immediately. + +## What gets branded + +`build.sh` applies KAMOS branding in seven places: + +1. `/etc/os-release` → `NAME`, `PRETTY_NAME`, `VARIANT`, `HOME_URL` (so `neofetch`/`fastfetch` show "KAMOS Gaming OS - Play. Perform. Dominate.") +2. GNOME default wallpaper (system-wide via dconf override, applies to all new users) +3. GNOME lock-screen / screensaver background (same wallpaper) +4. Plymouth boot splash (custom `kamos` theme with pulsing logo on black) +5. Initramfs is regenerated with `dracut --force --regenerate-all` so the splash shows on first boot +6. GRUB boot-menu logo (logo PNG dropped into Bazzite's GRUB theme) +7. Container image labels (visible in registries / artifacthub) + +## Troubleshooting + +**`podman build` fails with "exec format error"**: forgot `--platform=linux/amd64` on Apple Silicon, or QEMU user-static isn't enabled in your Podman machine. + +**Boot splash doesn't show**: confirm the kernel cmdline has `rhgb quiet splash` (it does, via iso.toml). On a `bootc switch` upgrade you may need to re-run `dracut --force --regenerate-all` and reboot once. + +**Wallpaper doesn't apply for existing user**: the dconf override is `system-db:local`, which only affects new users. Existing accounts have their own user dconf — set it manually once with `gsettings set org.gnome.desktop.background picture-uri 'file:///usr/share/backgrounds/kamos/kamos-wallpaper.jpg'`. + +**Image builds but boot loops on real hardware**: usually SecureBoot rejecting unsigned NVIDIA modules. Disable SecureBoot in BIOS or enroll Bazzite's MOK key (Bazzite docs cover this). + +**Cosign signing step fails**: `SIGNING_SECRET` must be the *contents* of `cosign.key`, not a path. The key must be generated with an empty password. + +## License + +Apache-2.0 — same as the upstream `ublue-os/image-template`. diff --git a/build_files/build.sh b/build_files/build.sh new file mode 100644 index 0000000..706638d --- /dev/null +++ b/build_files/build.sh @@ -0,0 +1,143 @@ +#!/usr/bin/env bash +# ============================================================================= +# build.sh - runs INSIDE the container during `podman build` +# +# Anything you'd normally `dnf install`, `systemctl enable`, or drop in +# /etc or /usr goes here. Run as root, on Fedora bootc. +# ============================================================================= +set -euxo pipefail + +# ----------------------------------------------------------------------------- +# 1. Install extra packages +# Bazzite already ships a LOT - check `rpm -qa` on the base before adding. +# Anything you uncomment below will be layered on top. +# ----------------------------------------------------------------------------- +EXTRA_PACKAGES=( + # CLI niceties + # htop + # bat + # ripgrep + # fastfetch + + # Dev tooling + # gh + # tmux +) + +if [ ${#EXTRA_PACKAGES[@]} -gt 0 ]; then + dnf -y install "${EXTRA_PACKAGES[@]}" +fi + +# ----------------------------------------------------------------------------- +# 2. Remove packages you don't want +# Use `dnf -y remove --no-autoremove` so you don't accidentally pull +# half the desktop with you. +# ----------------------------------------------------------------------------- +REMOVE_PACKAGES=( + # firefox +) + +if [ ${#REMOVE_PACKAGES[@]} -gt 0 ]; then + dnf -y remove --no-autoremove "${REMOVE_PACKAGES[@]}" +fi + +# ----------------------------------------------------------------------------- +# 3. Enable systemd units (system-wide) +# ----------------------------------------------------------------------------- +SERVICES_ENABLE=( + # podman.socket +) + +for svc in "${SERVICES_ENABLE[@]}"; do + systemctl enable "$svc" +done + +# ----------------------------------------------------------------------------- +# 4. KAMOS branding - OS release name shown in `neofetch`, login screen, etc. +# The base bazzite-nvidia overrides /etc/os-release; we patch the +# customisable fields without breaking version detection. +# ----------------------------------------------------------------------------- +KAMOS_OS_NAME="KAMOS Gaming OS" +KAMOS_TAGLINE="Play. Perform. Dominate." +KAMOS_HOME_URL="https://cgi.medsys.cloud/mkm1971/kamos" + +if [ -f /usr/lib/os-release ]; then + sed -i \ + -e "s|^NAME=.*|NAME=\"${KAMOS_OS_NAME}\"|" \ + -e "s|^PRETTY_NAME=.*|PRETTY_NAME=\"${KAMOS_OS_NAME} - ${KAMOS_TAGLINE}\"|" \ + -e "s|^HOME_URL=.*|HOME_URL=\"${KAMOS_HOME_URL}\"|" \ + -e "s|^VARIANT=.*|VARIANT=\"KAMOS\"|" \ + -e "s|^VARIANT_ID=.*|VARIANT_ID=kamos|" \ + /usr/lib/os-release +fi + +# ----------------------------------------------------------------------------- +# 5. KAMOS wallpaper +# File: system_files/usr/share/backgrounds/kamos/kamos-wallpaper.jpg +# Sets a system-wide default for all new users via a dconf override. +# ----------------------------------------------------------------------------- +KAMOS_WALLPAPER="/usr/share/backgrounds/kamos/kamos-wallpaper.jpg" + +if [ -f "${KAMOS_WALLPAPER}" ]; then + echo "==> Applying KAMOS wallpaper" + mkdir -p /etc/dconf/db/local.d /etc/dconf/profile + cat > /etc/dconf/profile/user <<'EOF' +user-db:user +system-db:local +EOF + cat > /etc/dconf/db/local.d/01-kamos-wallpaper < Setting KAMOS as default plymouth theme" + plymouth-set-default-theme kamos + # Rebuild the initramfs so the splash is actually used at next boot. + # Bazzite uses dracut. + if command -v dracut >/dev/null 2>&1; then + dracut --force --regenerate-all || true + fi +fi + +# ----------------------------------------------------------------------------- +# 7. KAMOS GRUB logo +# Bazzite ships its own GRUB theme; we replace the logo asset only. +# File: system_files/usr/share/pixmaps/kamos-logo.png (24-bit, ~256x256) +# ----------------------------------------------------------------------------- +KAMOS_LOGO="/usr/share/pixmaps/kamos-logo.png" +if [ -f "${KAMOS_LOGO}" ]; then + echo "==> KAMOS logo present at ${KAMOS_LOGO}" + # If a Bazzite GRUB theme exists, drop the logo into it for the boot menu. + for theme_dir in /usr/share/grub/themes/*/; do + if [ -d "${theme_dir}" ]; then + cp -f "${KAMOS_LOGO}" "${theme_dir}/logo.png" || true + fi + done +fi + +# ----------------------------------------------------------------------------- +# 8. Cleanup +# ----------------------------------------------------------------------------- +dnf clean all +rm -rf /tmp/* /var/* || true +mkdir -p /var/log /var/cache /var/tmp + +echo "==> build.sh finished cleanly" diff --git a/cosign.pub b/cosign.pub new file mode 100644 index 0000000..83a2785 --- /dev/null +++ b/cosign.pub @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEes1gKNIutrZ1lvZDyo7GXBsJh0Xo +k1Pdq+dfBYlpZFHHzZISMSxpBbIeB6XB5xSnhTe8IREfdBmVqYunmwsd+A== +-----END PUBLIC KEY----- diff --git a/disk_config/iso.toml b/disk_config/iso.toml new file mode 100644 index 0000000..96edd89 --- /dev/null +++ b/disk_config/iso.toml @@ -0,0 +1,32 @@ +# KAMOS Gaming OS - bootc-image-builder ISO config +# Used by `just build-iso` and the build-disk workflow. +# Reference: https://osbuild.org/docs/bootc/ + +[customizations] +hostname = "kamos" + +[[customizations.user]] +name = "khalaf" +password = "changeme" +groups = ["wheel"] + +[customizations.kernel] +# NVIDIA proprietary driver works best with the modules baked into Bazzite's +# kernel. `splash` enables Plymouth so the KAMOS boot splash actually shows. +# Don't add nomodeset unless you've fallen back to a recovery scenario. +append = "rhgb quiet splash" + +[customizations.locale] +languages = ["en_US.UTF-8"] +keyboard = "us" + +[customizations.timezone] +timezone = "UTC" + +[[customizations.filesystem]] +mountpoint = "/" +minsize = "10 GiB" + +[[customizations.filesystem]] +mountpoint = "/var" +minsize = "20 GiB" diff --git a/system_files/usr/share/backgrounds/kamos/kamos-wallpaper.jpg b/system_files/usr/share/backgrounds/kamos/kamos-wallpaper.jpg new file mode 100644 index 0000000..92814ee Binary files /dev/null and b/system_files/usr/share/backgrounds/kamos/kamos-wallpaper.jpg differ diff --git a/system_files/usr/share/pixmaps/kamos-logo.png b/system_files/usr/share/pixmaps/kamos-logo.png new file mode 100644 index 0000000..1c38050 Binary files /dev/null and b/system_files/usr/share/pixmaps/kamos-logo.png differ diff --git a/system_files/usr/share/plymouth/themes/kamos/kamos-logo.png b/system_files/usr/share/plymouth/themes/kamos/kamos-logo.png new file mode 100644 index 0000000..1c38050 Binary files /dev/null and b/system_files/usr/share/plymouth/themes/kamos/kamos-logo.png differ diff --git a/system_files/usr/share/plymouth/themes/kamos/kamos.plymouth b/system_files/usr/share/plymouth/themes/kamos/kamos.plymouth new file mode 100644 index 0000000..0f0b8e2 --- /dev/null +++ b/system_files/usr/share/plymouth/themes/kamos/kamos.plymouth @@ -0,0 +1,8 @@ +[Plymouth Theme] +Name=KAMOS +Description=KAMOS Gaming OS boot splash - Play. Perform. Dominate. +ModuleName=script + +[script] +ImageDir=/usr/share/plymouth/themes/kamos +ScriptFile=/usr/share/plymouth/themes/kamos/kamos.script diff --git a/system_files/usr/share/plymouth/themes/kamos/kamos.script b/system_files/usr/share/plymouth/themes/kamos/kamos.script new file mode 100644 index 0000000..ba8feea --- /dev/null +++ b/system_files/usr/share/plymouth/themes/kamos/kamos.script @@ -0,0 +1,38 @@ +// ============================================================================= +// KAMOS Gaming OS - Plymouth boot splash +// Pure black background (matches the wallpaper aesthetic) with the KAMOS logo +// centered, plus a subtle pulsing alpha so it feels alive on long boots. +// ============================================================================= + +// 1. Pure black background +Window.SetBackgroundTopColor(0.0, 0.0, 0.0); +Window.SetBackgroundBottomColor(0.0, 0.0, 0.0); + +// 2. Logo - expects kamos-logo.png in the same theme directory +logo.image = Image("kamos-logo.png"); +logo.sprite = Sprite(logo.image); +logo.x = Window.GetX() + Window.GetWidth() / 2 - logo.image.GetWidth() / 2; +logo.y = Window.GetY() + Window.GetHeight() / 2 - logo.image.GetHeight() / 2; +logo.sprite.SetPosition(logo.x, logo.y, 0); + +// 3. Gentle pulse - alpha bobs between 0.65 and 1.0 over ~2 seconds +progress = 0; +fun refresh_callback () { + progress += 0.02; + alpha = 0.825 + 0.175 * Math.Sin(progress); + logo.sprite.SetOpacity(alpha); +} +Plymouth.SetRefreshFunction(refresh_callback); + +// 4. Show password prompts (LUKS unlock) below the logo if needed +fun display_password_callback (prompt, bullets) { + if (!global.prompt_box) { + global.prompt_box.image = Image.Text(prompt, 1, 1, 1); + global.prompt_box.sprite = Sprite(global.prompt_box.image); + global.prompt_box.sprite.SetPosition( + Window.GetWidth() / 2 - global.prompt_box.image.GetWidth() / 2, + logo.y + logo.image.GetHeight() + 40, + 1); + } +} +Plymouth.SetDisplayPasswordFunction(display_password_callback);