KAMOS Gaming OS - initial scaffold with branding
build-image / Build & push (${{ matrix.platform }}) (linux/amd64) (push) Failing after 51s
Details
build-image / Build & push (${{ matrix.platform }}) (linux/amd64) (push) Failing after 51s
Details
This commit is contained in:
commit
b09d43fa87
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
|
@ -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
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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 <<EOF
|
||||
[org/gnome/desktop/background]
|
||||
picture-uri='file://${KAMOS_WALLPAPER}'
|
||||
picture-uri-dark='file://${KAMOS_WALLPAPER}'
|
||||
picture-options='zoom'
|
||||
primary-color='#000000'
|
||||
|
||||
[org/gnome/desktop/screensaver]
|
||||
picture-uri='file://${KAMOS_WALLPAPER}'
|
||||
picture-options='zoom'
|
||||
primary-color='#000000'
|
||||
EOF
|
||||
dconf update || true
|
||||
fi
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 6. KAMOS Plymouth boot splash
|
||||
# Files (provided by us in system_files/):
|
||||
# /usr/share/plymouth/themes/kamos/kamos.plymouth
|
||||
# /usr/share/plymouth/themes/kamos/kamos.script
|
||||
# /usr/share/plymouth/themes/kamos/kamos-logo.png (drop your PNG here)
|
||||
# -----------------------------------------------------------------------------
|
||||
if [ -f /usr/share/plymouth/themes/kamos/kamos.plymouth ]; then
|
||||
echo "==> 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"
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEes1gKNIutrZ1lvZDyo7GXBsJh0Xo
|
||||
k1Pdq+dfBYlpZFHHzZISMSxpBbIeB6XB5xSnhTe8IREfdBmVqYunmwsd+A==
|
||||
-----END PUBLIC KEY-----
|
||||
|
|
@ -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"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 280 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 523 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 523 KiB |
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
Loading…
Reference in New Issue