diff --git a/Containerfile b/Containerfile index ae783ca..ad130dd 100644 --- a/Containerfile +++ b/Containerfile @@ -29,19 +29,15 @@ RUN --mount=type=bind,from=ctx,source=/,target=/ctx \ --mount=type=cache,dst=/var/log \ --mount=type=tmpfs,dst=/tmp \ echo -e "\033[31mBUILD SCRIPT >>>>\033[0m" && \ - /ctx/build.sh && \ - echo -e "\033[31mINSTALL ZFS >>>>\033[0m" && \ - /ctx/install_zfs.sh && \ - echo -e "\033[31mLAYER APPIMAGES >>>>\033[0m" && \ - /ctx/layered_appimages.sh && \ + /ctx/01-build.sh && \ echo -e "\033[31mOPT FIXER >>>>\033[0m" && \ - /ctx/fix_opt.sh && \ + /ctx/03-fix-opt.sh && \ echo -e "\033[31mSYSTEM CONFIG >>>>\033[0m" && \ - /ctx/config.sh && \ + /ctx/04-config.sh && \ echo -e "\033[31mKERENEL SCRIPT >>>>\033[0m" && \ - /ctx/kernel_modules.sh && \ + /ctx/05-kernel-modules.sh && \ echo -e "\033[31mREMOTE GRABBER >>>>\033[0m" && \ - /ctx/remote_grabber_new.sh && \ + /ctx/06-remote-grabber.sh && \ echo -e "\033[31mOSTREE COMMIT\033[0m" && \ ostree container commit diff --git a/README.md b/README.md index 7f8913d..3c383a1 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,111 @@ # DistinctionOS -### DistinctionOS is built upon [Bazzite](https://github.com/ublue-os/bazzite). DistinctionOS is intended as a full experience and the opposite of minimalism. -##### Please note: I'm not a Developer, Just someone who keeps tinkering until something finally works and sometimes I learn from it. +> A fully-featured [Bazzite](https://github.com/ublue-os/bazzite)-based gaming and development environment + +[![Built on Bazzite](https://img.shields.io/badge/Built%20on-Bazzite-blue)](https://github.com/ublue-os/bazzite) +[![Fedora Atomic](https://img.shields.io/badge/Fedora-Atomic-51A2DA)](https://fedoraproject.org/) +[![License](https://img.shields.io/github/license/phantomcortex/distinctionos)](./LICENSE) + +**DistinctionOS** embraces the philosophy of abundance. a curated experience built for creators, gamers, and tinkerers who want it all, out of the box. + +--- + +## ๐Ÿš€ Quick Start + +Rebase your existing system to DistinctionOS: -#### If you want to try out DistinctionOS you do so with: ```bash +# Using bootc (recommended) sudo bootc switch ghcr.io/phantomcortex/distinctionos + +# Using rpm-ostree +rpm-ostree rebase ostree-unverified-registry:docker://ghcr.io/phantomcortex/distinctionos:latest ``` -or + +After reboot, run the first-time setup: ```bash -rpm-ostree rebase ostree-unverified-registry:docker://ghcr.io/phantomcortex/distinctionos:latest +ujust distinction-install ``` --- -## Miscellaneous packages that aren't included with bazzite -- `docker` & `docker-compose` -- `libheif-tools` (for .heic images thumbnails) -- `flatpak-builder` -- `freerdp` (useful for [winboat](https://github.com/TibixDev/winboat) or [winapps](https://github.com/winapps-org/winapps)) -- `pandoc` -- `totem-video-thumbnailer` (Video thumbnails) -- `Cider` is Music Client for Apple Music. **NOTE:** ***This is Cider version 3. You need to purchase an license from itch.io to use it, But it should be a one-time payment. See: https://cidercollective.itch.io/cider You will still need an active Apple Music subscription to use it.*** -- `Audacity-Freeworld` is better than fedora's default audacity because it ships patent encumbered codecs that fedora can't/won't ship in their official repositories. -- [BlackBox-Terminal](https://github.com/yonasBSD/blackbox-terminal) is currently unmaintained But I still love it, Which is why it's here. -- [xpadneo](https://github.com/atar-axis/xpadneo) is here for controller input over bluetooth and support for xbox series elite controllers (which I have and use) -- [zoxide](https://github.com/ajeetdsouza/zoxide) (smart cd) -- [dysk](https://github.com/Canop/dysk) -- Custom Image-raw thumbnailer via `dcraw` (tested with Sony's .ARW format from my own camera. Other formats untested.) -- Custom dds texture thumbnailer via `ImageMagick` (This won't work for every last texture, but should work for most.) - - ### Miscellaneous /bin -- `advcp` ( `cp` command with progress bar `advcp -g` ) -- `advmv` ( `mv` command with progress bar `advmv -g` ) -- `rpm-ostree-search-hl` (rpm-ostree search highlighting) (also aliased to `rosh`, use with `rosh search gcc`) -- `xiso` renamed from: [extract-xiso](https://github.com/XboxDev/extract-xiso) + +## โœจ What's Included + +### ๐ŸŽฎ Gaming Enhancements +- **xpadneo** - Enhanced Xbox controller support with full Bluetooth functionality + +### ๐ŸŽจ Creative Tools +- **Cider** - Premium Apple Music client ([requires license](https://cidercollective.itch.io/cider)) +- **Audacity Freeworld** - Full codec support for audio editing +- **dcraw** - RAW image format support with thumbnail generation +- **ImageMagick DDS thumbnailer** - Texture file previews + +### ๐Ÿ› ๏ธ Development & Productivity +- Docker & Docker Compose +- Flatpak Builder +- FreeRDP (for remote Windows applications) +- Pandoc (universal document converter) +- Zfs kernel module + +### ๐Ÿ“ฆ Quality of Life +- **zoxide** - Smart directory navigation (`z` command) +- **dysk** - Modern disk usage analyzer +- **advcp/advmv** - Progress bars for copy/move operations +- Video thumbnail generation +- HEIC image format support + +### ๐ŸŽจ Theming +- Kora icon theme (custom build) +- Coordinated GTK styling + +--- + +## ๐Ÿ”‘ Key Features + +| Feature | Description | +|---------|-------------| +| **Immutable Base** | Built on Fedora Atomic for reliability and easy rollback | +| **Automatic Updates** | Fresh images built every 5 days with latest packages | +| **TPM Auto-Unlock** | Optional LUKS unlock with TPM 2.0 (setup via `ujust distinction-tpm-unlock-setup`) | +| **ZSH by Default** | Oh My Zsh + Powerlevel10k configured automatically | +| **Just Recipes** | Simple commands for common tasks (`ujust` for menu) | --- -## Special thanks for making this unholy creation possible -- [fedora linux](https://fedoraproject.org) and it's developers, maintainers, and it's community for being an incredible OS by default. -- [UniveralBlue](https://github.com/ublue-os) and it's developers, maintainers, and contributers for making [Bazzite](https://github.com/ublue-os/bazzite), [Bluefin](https://github.com/ublue-os/bluefin), and the [image-template](https://github.com/ublue-os/image-template). -- [Amy OS](https://github.com/astrovm/amyos) for being an example on a cleaner build system. -- [vst-name's ublue-aurora-dx](https://github.com/vst-name/ublue-aurora-dx) for being an example of working rechunker - -## Community Examples - -- [m2Giles' OS](https://github.com/m2giles/m2os) -- [bOS](https://github.com/bsherman/bos) -- [Homer](https://github.com/bketelsen/homer/) -- [Amy OS](https://github.com/astrovm/amyos) -- [VeneOS](https://github.com/Venefilyn/veneos) + +## ๐ŸŽฏ Philosophy + +**DistinctionOS is for those who want:** +- A complete, ready-to-use system without manual configuration +- Gaming performance with development tools side-by-side +- Professional applications without hunting through repositories + +If you prefer minimalism and building from scratch, this isn't your distributionโ€”and that's perfectly fine. + +--- + +## ๐Ÿ“š Documentation + +- **[Developer Documentation](./docs/developer.md)** - Build process, architecture, contributing +- **[AI Assistant Context](./docs/claude.md)** - Complete project context for AI tools + +--- + +## ๐Ÿ™ Acknowledgements + +Special Thanks: + +- **[Fedora Project](https://fedoraproject.org)** - The foundation of it all +- **[Universal Blue](https://github.com/ublue-os)** - Bazzite, Bluefin, and the image template +- **[Bazzite](https://github.com/ublue-os/bazzite)** - The direct parent of this project +- **Community Examples**: [Amy OS](https://github.com/astrovm/amyos), [vst-name's Aurora DX](https://github.com/vst-name/ublue-aurora-dx), [m2OS](https://github.com/m2giles/m2os), [bOS](https://github.com/bsherman/bos), [Homer](https://github.com/bketelsen/homer/), [VeneOS](https://github.com/Venefilyn/veneos) + + +--- + +
+ +**Built with โค๏ธ by [phantomcortex](https://github.com/phantomcortex)** + +*For those who want it all* + +
diff --git a/build_files/01-build.sh b/build_files/01-build.sh new file mode 100755 index 0000000..57e6ffe --- /dev/null +++ b/build_files/01-build.sh @@ -0,0 +1,538 @@ +#!/usr/bin/bash +set -uo pipefail + +# ============================================================================ +# DistinctionOS Build Script - Package Management & Repository Configuration +# ============================================================================ +# Purpose: Install system packages with resilient "best-effort" approach +# Strategy: Attempt bulk installation, fall back to individual installation on failure +# Note: Build continues even if some packages fail (repository outages, etc.) +# repository outages have occured with openzfs, crossover, and Cider +# ============================================================================ + +# Source utility functions +source /ctx/95-utility-functions.sh + +# ============================================================================ +# Package Installation Tracking +# ============================================================================ + +# Arrays to track installation results +declare -a FAILED_PACKAGES=() +declare -a SUCCEEDED_PACKAGES=() +declare -a SKIPPED_REPOS=() + +# ============================================================================ +# Best-Effort Package Installation Function +# ============================================================================ +# Attempts bulk installation first, falls back to individual installation +# Tracks successes and failures without halting the build + +install_packages_resilient() { + local repo="$1" + shift + local -a packages=("$@") + + log_section "Installing from repository: $repo" + log_info "Attempting to install ${#packages[@]} package(s)" + + # Attempt bulk installation first + local enable_opt="" + [[ $repo != "fedora" ]] && enable_opt="--enablerepo=$repo" + + local -a install_cmd=(dnf5 -y install) + [[ -n "$enable_opt" ]] && install_cmd+=("$enable_opt") + install_cmd+=("${packages[@]}") + + if "${install_cmd[@]}" &>/dev/null; then + log_success "Bulk installation from $repo succeeded" + SUCCEEDED_PACKAGES+=("${packages[@]}") + return 0 + fi + + log_warning "Bulk installation from $repo failed, attempting individual installation" + + # Fall back to individual package installation + local success_count=0 + local fail_count=0 + + for pkg in "${packages[@]}"; do + local -a single_install_cmd=(dnf5 -y install) + [[ -n "$enable_opt" ]] && single_install_cmd+=("$enable_opt") + single_install_cmd+=("$pkg") + + if "${single_install_cmd[@]}" &>/dev/null; then + log_success " โœ“ $pkg" + SUCCEEDED_PACKAGES+=("$pkg") + ((success_count++)) + else + log_warning " โœ— $pkg (failed)" + FAILED_PACKAGES+=("$pkg") + ((fail_count++)) + fi + done + + log_info "Repository $repo: $success_count succeeded, $fail_count failed" +} + +# ============================================================================ +# Best-Effort COPR Installation Function +# ============================================================================ + +install_copr_resilient() { + local copr_repo="$1" + shift + local -a packages=("$@") + + log_section "Installing from COPR: $copr_repo" + + # Enable COPR repository + if ! dnf5 -y copr enable "$copr_repo" &>/dev/null; then + log_error "Failed to enable COPR: $copr_repo" + SKIPPED_REPOS+=("copr:$copr_repo") + FAILED_PACKAGES+=("${packages[@]}") + return 1 + fi + + log_info "Attempting to install ${#packages[@]} package(s)" + + # Attempt bulk installation + if dnf5 -y install "${packages[@]}" &>/dev/null; then + log_success "Bulk installation from $copr_repo succeeded" + SUCCEEDED_PACKAGES+=("${packages[@]}") + dnf5 -y copr disable "$copr_repo" &>/dev/null || true + return 0 + fi + + log_warning "Bulk installation from $copr_repo failed, attempting individual installation" + + # Fall back to individual installation + local success_count=0 + local fail_count=0 + + for pkg in "${packages[@]}"; do + if dnf5 -y install "$pkg" &>/dev/null; then + log_success " โœ“ $pkg" + SUCCEEDED_PACKAGES+=("$pkg") + ((success_count++)) + else + log_warning " โœ— $pkg (failed)" + FAILED_PACKAGES+=("$pkg") + ((fail_count++)) + fi + done + + log_info "COPR $copr_repo: $success_count succeeded, $fail_count failed" + + # Disable COPR + dnf5 -y copr disable "$copr_repo" &>/dev/null || true +} + +# ============================================================================ +# Resilient Single Package Installation +# ============================================================================ +# For special cases like CrossOver, Kora theme, etc. + +install_single_package_resilient() { + local package_source="$1" + local package_name="$2" + + log_info "Installing $package_name from: $package_source" + + if dnf5 -y install "$package_source" &>/dev/null; then + log_success "$package_name installed successfully" + SUCCEEDED_PACKAGES+=("$package_name") + return 0 + else + log_warning "$package_name installation failed" + FAILED_PACKAGES+=("$package_name") + return 1 + fi +} + +# ============================================================================ +# Script Start +# ============================================================================ + +script_start "DistinctionOS Package Installation" "Best-effort resilient installation" + +log_info "Build strategy: Continue despite individual package failures" +log_info "Repositories and packages will be retried individually if bulk fails" + +# ============================================================================ +# Package Removal - Critical Packages Only +# ============================================================================ + +log_section "Removing conflicting packages" + +# These packages MUST be removed (conflicts or unwanted) +readonly -a REMOVE_PACKAGES=( + "waydroid" # Not needed + "sunshine" # Not needed + "gnome-shell-extension-compiz-windows-effect" # Not needed + "openssh-askpass" # Not needed + "zfs-fuse" # Conflicts with ZFS kernel module +) + +removed_count=0 +for pkg in "${REMOVE_PACKAGES[@]}"; do + if rpm -q "$pkg" &>/dev/null; then + if dnf5 -y remove "$pkg" &>/dev/null; then + log_success "Removed: $pkg" + ((removed_count++)) + else + log_warning "Failed to remove: $pkg (non-critical)" + fi + fi +done + +counter_display "$removed_count" "package" "packages" "removed" + +# ============================================================================ +# Repository Configuration +# ============================================================================ + +log_section "Configuring additional repositories" + +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Cider Collective Repository +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +log_info "Adding Cider Collective repository" + +if rpm --import https://repo.cider.sh/RPM-GPG-KEY &>/dev/null; then + log_success "Cider GPG key imported" +else + log_warning "Failed to import Cider GPG key (repository may be unavailable)" +fi + +tee /etc/yum.repos.d/cider.repo > /dev/null << 'EOF' +[cidercollective] +name=Cider Collective Repository +baseurl=https://repo.cider.sh/rpm/RPMS +enabled=1 +gpgcheck=1 +gpgkey=https://repo.cider.sh/RPM-GPG-KEY +EOF + +log_success "Cider repository configured" + +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Refresh Repository Metadata +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +log_info "Refreshing repository metadata" +if dnf5 makecache &>/dev/null; then + log_success "Metadata cache updated" +else + log_warning "Metadata refresh encountered issues (continuing anyway)" +fi + +# ============================================================================ +# ZFS Repository & Package Installation +# ============================================================================ +# Issue: ZFS repository occasionally experiences downtime +# Solution: Best-effort installation, build continues if unavailable + +log_section "Installing ZFS (best-effort)" + +log_info "Adding ZFS repository" +if install_single_package_resilient \ + "https://zfsonlinux.org/fedora/zfs-release-2-8.fc42.noarch.rpm" \ + "zfs-release"; then + + log_info "Installing ZFS packages" + if dnf5 -y install zfs &>/dev/null; then + log_success "ZFS packages installed (DKMS compilation in kernel-modules.sh)" + SUCCEEDED_PACKAGES+=("zfs") + else + log_warning "ZFS package installation failed (repository may be down)" + FAILED_PACKAGES+=("zfs") + fi +else + log_warning "ZFS repository unavailable (skipping ZFS installation)" + SKIPPED_REPOS+=("zfs-release") +fi + +# ============================================================================ +# Create Required Directories +# ============================================================================ + +log_section "Creating required directories" + +create_dir_with_log "/var/opt" "Package directory for fix-opt.sh" + +# ============================================================================ +# Package Installation - Organized by Repository +# ============================================================================ + +log_section "Installing packages from configured repositories" + +# Associative array mapping repositories to their packages +declare -A RPM_PACKAGES=( + # Core Fedora repositories + ["fedora"]="\ + yt-dlp \ + zsh \ + zsh-syntax-highlighting \ + zsh-autosuggestions \ + neovim \ + file-roller \ + bat \ + evince \ + loupe \ + zoxide \ + sassc \ + blackbox-terminal \ + gstreamer1-plugins-good-extras \ + decibels \ + dconf \ + gtk-murrine-engine \ + glib2-devel \ + perl-File-Copy \ + winetricks \ + lutris \ + sox \ + totem-video-thumbnailer \ + mediainfo \ + pandoc \ + docker \ + docker-compose \ + flatpak-builder \ + gnome-tweaks \ + freerdp \ + dkms \ + nss-mdns.i686 \ + pcsc-lite-libs.i686 \ + nmap-ncat \ + sane-backends-libs.i686 \ + sane-backends-libs.x86_64 \ + dcraw \ + perl-Image-ExifTool \ + libheif-tools \ + heif-pixbuf-loader \ + wine \ + meson \ + cmake \ + boost" + + ["rpmfusion-free,rpmfusion-free-updates,rpmfusion-nonfree,rpmfusion-nonfree-updates"]="\ + audacity-freeworld \ + libavcodec-freeworld \ + gstreamer1-plugins-bad-freeworld \ + gstreamer1-plugins-ugly \ + libheif-freeworld" + + # Fedora Multimedia (optimized multimedia packages) + ["fedora-multimedia"]="mpv" + + # Third-party repositories + ["brave-browser"]="brave-browser" + ["cidercollective"]="Cider" +) + +# Install packages from standard repositories +for repo in "${!RPM_PACKAGES[@]}"; do + read -ra pkg_array <<<"${RPM_PACKAGES[$repo]}" + install_packages_resilient "$repo" "${pkg_array[@]}" +done + +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# COPR Repository Packages +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +log_section "Installing packages from COPR repositories" + +# COPR packages (handled separately due to enable/disable requirement) +declare -A COPR_PACKAGES=( + ["ilyaz/LACT"]="lact" # AMD GPU control + ["fernando-debian/dysk"]="dysk" # Disk usage analyzer + ["atim/heroic-games-launcher"]="heroic-games-launcher-bin" # Epic/GOG launcher + ["sergiomb/clonezilla"]="clonezilla" # Disk cloning utility + ["alternateved/eza"]="eza" # Modern ls replacement +) + +for copr_repo in "${!COPR_PACKAGES[@]}"; do + read -ra pkg_array <<<"${COPR_PACKAGES[$copr_repo]}" + install_copr_resilient "$copr_repo" "${pkg_array[@]}" +done + +# ============================================================================ +# Wine Version Locking +# ============================================================================ + +log_section "Applying Wine version lock" + +if rpm -q wine &>/dev/null; then + if dnf5 versionlock add wine &>/dev/null; then + log_success "Wine version locked" + log_info "Current version locks:" + dnf5 versionlock list || true + else + log_warning "Wine version lock failed (non-critical)" + fi +else + log_warning "Wine not installed, cannot apply version lock" +fi + +# ============================================================================ +# Special Package Installations +# ============================================================================ + +log_section "Installing special packages" + +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# CrossOver (Commercial Wine Implementation) +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +log_info "Installing CrossOver from CodeWeavers" +install_single_package_resilient \ + "http://crossover.codeweavers.com/redirect/crossover.rpm" \ + "crossover" + +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Kora Icon Theme (Custom Build) +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +log_info "Installing Kora icon theme (latest release)" + +# Get latest release URL +kora_url=$(curl -s https://api.github.com/repos/phantomcortex/kora/releases/latest 2>/dev/null | \ + grep "browser_download_url.*\.rpm" | \ + cut -d '"' -f 4) + +if [[ -n "$kora_url" ]]; then + install_single_package_resilient "$kora_url" "kora-icon-theme" +else + log_warning "Failed to retrieve Kora theme URL (GitHub API may be down)" + FAILED_PACKAGES+=("kora-icon-theme") +fi + +# ============================================================================ +# System Upgrade (Best-Effort) +# ============================================================================ + +log_section "Performing system upgrade (best-effort)" + +log_info "Upgrading all packages to latest versions" +if dnf5 -y upgrade &>/dev/null; then + log_success "System upgrade complete" +else + log_warning "System upgrade encountered issues (non-critical)" +fi + +# ============================================================================ +# Critical Package Validation +# ============================================================================ +# These packages are essential - report if missing but don't fail build + +log_section "Validating critical packages" + +readonly -a CRITICAL_PACKAGES=( + "zsh" + "neovim" + "docker" + "brave-browser" + "wine" + "blackbox-terminal" + "totem-video-thumbnailer" +) + +validation_failures=0 +for pkg in "${CRITICAL_PACKAGES[@]}"; do + if rpm -q "$pkg" &>/dev/null; then + log_success " โœ“ $pkg" + else + log_warning " โœ— $pkg (CRITICAL - missing)" + ((validation_failures++)) + fi +done + +if [[ $validation_failures -eq 0 ]]; then + log_success "All critical packages validated" +else + log_warning "$validation_failures critical package(s) missing" +fi + +# ============================================================================ +# Wine Fallback Installation +# ============================================================================ +# If Wine failed earlier, try one more time with --skip-broken + +if ! rpm -q wine &>/dev/null; then + log_section "Wine fallback installation" + log_info "Attempting Wine installation with --skip-broken" + + if dnf5 -y install wine --skip-broken &>/dev/null; then + log_success "Wine installed via fallback method" + SUCCEEDED_PACKAGES+=("wine") + else + log_warning "Wine installation failed even with --skip-broken" + fi +fi + +# ============================================================================ +# Cleanup +# ============================================================================ + +log_section "Cleaning package manager cache" + +if dnf5 clean all &>/dev/null; then + log_success "Cache cleaned" +else + log_warning "Cache cleanup failed (non-critical)" +fi + +# ============================================================================ +# Installation Summary Report +# ============================================================================ + +script_complete "Package Installation" "Review summary below" + +log_header "Installation Summary" + +# Calculate statistics +total_attempted=$((${#SUCCEEDED_PACKAGES[@]} + ${#FAILED_PACKAGES[@]})) +success_rate=0 +[[ $total_attempted -gt 0 ]] && success_rate=$(( (${#SUCCEEDED_PACKAGES[@]} * 100) / total_attempted )) + +echo "" +log_info "Package Installation Statistics:" +echo " Total Attempted: $total_attempted" +echo " Successful: ${#SUCCEEDED_PACKAGES[@]}" +echo " Failed: ${#FAILED_PACKAGES[@]}" +echo " Success Rate: ${success_rate}%" + +if [[ ${#SKIPPED_REPOS[@]} -gt 0 ]]; then + echo "" + log_warning "Skipped Repositories (unavailable):" + for repo in "${SKIPPED_REPOS[@]}"; do + echo " - $repo" + done +fi + +if [[ ${#FAILED_PACKAGES[@]} -gt 0 ]]; then + echo "" + log_warning "Failed Package Installations:" + for pkg in "${FAILED_PACKAGES[@]}"; do + echo " - $pkg" + done + echo "" + log_info "Failed packages may be due to:" + echo " โ€ข Repository downtime (e.g., ZFS repository)" + echo " โ€ข Package name changes" + echo " โ€ข Temporary network issues" + echo " โ€ข Dependency conflicts" + echo "" + log_info "Build will continue - these packages can be installed later if needed" +fi + +if [[ ${#SUCCEEDED_PACKAGES[@]} -gt 0 ]]; then + echo "" + log_success "Build completed successfully with ${#SUCCEEDED_PACKAGES[@]} packages installed" +fi + +echo "" +log_info "Next: 03-fix-opt.sh will configure /opt persistence" + +exit 0 diff --git a/build_files/02-install-zfs.sh b/build_files/02-install-zfs.sh new file mode 100755 index 0000000..1b6e523 --- /dev/null +++ b/build_files/02-install-zfs.sh @@ -0,0 +1,30 @@ +#!/usr/bin/bash + +set -euo pipefail + +# ============================================================================ +# ZFS Installation +# ============================================================================ +# Install ZFS filesystem driver and prepare for DKMS compilation +# Note: DKMS compilation handled by kernel-modules.sh +# ============================================================================ + +# Source utility functions +source /ctx/95-utility-functions.sh + +# ============================================================================ +# ZFS Repository & Package Installation +# ============================================================================ + +log_section "Installing ZFS repository" +dnf install -y https://zfsonlinux.org/fedora/zfs-release-2-8.fc42.noarch.rpm +log_success "ZFS repository configured" + +log_section "Installing ZFS packages" +dnf -y install zfs +log_success "ZFS packages installed" + +log_section "ZFS installation complete" +echo " โ„น DKMS compilation will be handled by kernel-modules.sh" + +exit 0 diff --git a/build_files/03-fix-opt.sh b/build_files/03-fix-opt.sh new file mode 100755 index 0000000..6055af5 --- /dev/null +++ b/build_files/03-fix-opt.sh @@ -0,0 +1,39 @@ +#!/usr/bin/bash + +set -euo pipefail + +# ============================================================================ +# /opt Directory Persistence Configuration +# ============================================================================ +# Purpose: Generate tmpfiles.d config to persist /opt packages across reboots +# Mechanism: Dynamically scans /var/opt and creates symlink definitions +# Runtime: systemd-tmpfiles executes this config at boot +# ============================================================================ + +# Source utility functions +source /ctx/95-utility-functions.sh + +# ============================================================================ +# Directory Preparation & tmpfiles.d Generation +# ============================================================================ + +log_section "Configuring /opt directory persistence" + +# Ensure required directories exist +mkdir -p /usr/lib/opt +mkdir -p /var/opt + +# Process each directory in /var/opt +for dir in /var/opt/*/; do + [ -d "$dir" ] || continue + dirname=$(basename "$dir") + + echo " Processing: $dirname" + mv "$dir" "/usr/lib/opt/$dirname" + echo "L+ /var/opt/$dirname - - - - /usr/lib/opt/$dirname" >> /usr/lib/tmpfiles.d/distinction-opt-fix.conf +done + +log_success "/opt persistence configured" +echo " โ„น Packages in /opt will persist across reboots via tmpfiles.d" + +exit 0 diff --git a/build_files/04-config.sh b/build_files/04-config.sh new file mode 100755 index 0000000..d15b766 --- /dev/null +++ b/build_files/04-config.sh @@ -0,0 +1,305 @@ +#!/usr/bin/bash + +set -euo pipefail + +# ============================================================================ +# DistinctionOS System Configuration +# ============================================================================ +# Purpose: System service configuration, application customization, cleanup +# Execution: Fifth script in build sequence +# Note: Miscellaneous tasks that don't fit elsewhere in the build process +# ============================================================================ + +# Source utility functions +source /ctx/95-utility-functions.sh + +# ============================================================================ +# Main Configuration Process +# ============================================================================ + +log_header "DistinctionOS System Configuration" + +# ============================================================================ +# Shell Configuration +# ============================================================================ +# Set ZSH as default shell for new users and root +# Reason: Provides better interactive experience with enhanced features + +log_section "Configuring default shell (ZSH)" + +# Configure default shell for new users via useradd defaults +if [[ -e /etc/default/useradd ]]; then + log_info "Setting ZSH as default shell for new users" + sed -i 's|SHELL=/bin/bash|SHELL=/usr/bin/zsh|' /etc/default/useradd + log_success "Default shell configured in /etc/default/useradd" +else + log_warning "/etc/default/useradd not found, skipping new user default" +fi + +# Set root shell to ZSH +log_info "Setting root shell to ZSH" +if usermod -s /usr/bin/zsh root; then + log_success "Root shell changed to ZSH" +else + log_error "Failed to change root shell" +fi + +# ============================================================================ +# SystemD Service Configuration +# ============================================================================ +# Enable/disable system services for DistinctionOS functionality + +log_section "Configuring SystemD services" + +# Note: Services currently disabled during testing phase +# Uncomment when ready for production: +# +# log_info "Enabling distinction-firstrun.service" +# systemctl enable distinction-firstrun.service +# log_success "First-run service enabled" +# +# log_info "Enabling TPM monitor services" +# systemctl enable distinction-tpm-monitor.timer +# systemctl enable distinction-tpm-monitor.service +# log_success "TPM monitoring enabled" + +log_info "SystemD service configuration complete (services currently disabled)" + +# ============================================================================ +# Just Recipe Integration +# ============================================================================ +# Add DistinctionOS custom recipes and hide incompatible Bazzite recipes + +log_section "Integrating DistinctionOS Just recipes" + +# Import DistinctionOS recipes into the main justfile +readonly UBLUE_JUSTFILE="/usr/share/ublue-os/justfile" +readonly DISTINCTION_JUST="/usr/share/DistinctionOS/just/distinction.just" + +if [[ -f "$UBLUE_JUSTFILE" ]]; then + log_info "Adding DistinctionOS recipes to Universal Blue justfile" + echo "import \"$DISTINCTION_JUST\"" >> "$UBLUE_JUSTFILE" + log_success "DistinctionOS recipes imported" +else + log_error "Universal Blue justfile not found at $UBLUE_JUSTFILE" +fi + +# Hide incompatible Bazzite just recipes by prefixing with underscore +# Reason: Certain Bazzite recipes conflict with DistinctionOS configuration +log_section "Hiding incompatible Bazzite recipes" + +readonly -a INCOMPATIBLE_RECIPES=( + "install-coolercontrol" # Conflicts with our thermal management + "install-openrgb" # Conflicts with our RGB control setup +) + +for recipe in "${INCOMPATIBLE_RECIPES[@]}"; do + log_info "Hiding recipe: $recipe" + + # Find which just file contains this recipe + recipe_file=$(grep -l "^$recipe:" /usr/share/ublue-os/just/*.just 2>/dev/null || true) + + if [[ -n "$recipe_file" ]]; then + # Prefix recipe name with underscore to hide it + sed -i "s/^$recipe:/_$recipe:/" "$recipe_file" + log_success "Recipe '$recipe' hidden" + else + log_warning "Recipe '$recipe' not found in any just file" + fi +done + +# ============================================================================ +# Application Customization +# ============================================================================ +# Modify .desktop files and application configurations + +log_section "Customizing application configurations" + +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Cider Music Player Icon Fix +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Issue: Cider doesn't respect icon themes properly +# Solution: Hard-code path to Kora theme icon + +readonly CIDER_DESKTOP="/usr/share/applications/Cider.desktop" +if [[ -f "$CIDER_DESKTOP" ]]; then + log_info "Fixing Cider icon path" + sed -i 's@Icon=Cider@Icon=/usr/share/icons/kora/apps/scalable/cider.svg@g' "$CIDER_DESKTOP" + log_success "Cider icon path updated" +else + log_info "Cider not installed, skipping icon fix" +fi + +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Winetricks Debug Output Suppression +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Issue: Winetricks GUI produces excessive Wine debug messages +# Solution: Set WINEDEBUG=-all environment variable in .desktop file + +readonly WINETRICKS_DESKTOP="/usr/share/applications/winetricks.desktop" + +if [[ -f "$WINETRICKS_DESKTOP" ]]; then + log_info "Suppressing Winetricks debug output" + sed -i 's@Exec=winetricks --gui@Exec=/usr/bin/env WINEDEBUG=-all winetricks -q --gui@g' "$WINETRICKS_DESKTOP" + log_success "Winetricks debug output suppressed" +else + log_warning "Winetricks .desktop file not found" + + # Create .desktop file if winetricks is installed but missing desktop file + if rpm -q winetricks &>/dev/null; then + log_info "Creating winetricks.desktop file" + tee "$WINETRICKS_DESKTOP" > /dev/null << 'EOF' +[Desktop Entry] +Name=Winetricks +Comment=Work around problems and install applications under Wine +Exec=/usr/bin/env WINEDEBUG=-all winetricks -q --gui +Terminal=false +Icon=winetricks +Type=Application +Categories=Utility; +EOF + log_success "Winetricks .desktop file created" + fi +fi + +# ============================================================================ +# System Cache Updates +# ============================================================================ +# Refresh system caches after modifications + +log_section "Updating system caches" + +#some of the steps here are excessively error prone, thus breaking the build constantly +set +eu + +# Icon cache refresh (required after Kora theme installation) +log_info "Updating icon cache" +if gtk-update-icon-cache -f /usr/share/icons/kora; then + log_success "Icon cache updated" +else + log_warning "Icon cache update failed (non-critical)" +fi + +# Desktop database refresh (required after .desktop file modifications) +log_info "Updating desktop database" +if update-desktop-database /usr/share/applications; then + log_success "Desktop database updated" +else + log_warning "Desktop database update failed (non-critical)" +fi + +# GLib schemas compilation (required after GNOME extension installation) +log_info "Compiling GLib schemas" +if glib-compile-schemas /usr/share/glib-2.0/schemas; then + log_success "GLib schemas compiled" +else + log_warning "GLib schema compilation failed (non-critical)" +fi + +# MIME database refresh (required after MIME type changes) +log_info "Updating MIME database" +if update-mime-database /usr/share/mime; then + log_success "MIME database updated" +else + log_warning "MIME database update failed (non-critical)" +fi + +# ============================================================================ +# Cleanup - Unwanted Applications +# ============================================================================ +# Remove .desktop files for applications we don't want visible + +log_section "Removing unwanted application shortcuts" + +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Waydroid Applications +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Reason: Waydroid was removed from base image, cleanup leftover shortcuts + +log_info "Removing Waydroid application shortcuts" +waydroid_count=$(find /usr/share/applications -iname '*waydroid*' 2>/dev/null | wc -l) +if [[ $waydroid_count -gt 0 ]]; then + find /usr/share/applications -iname '*waydroid*' -exec rm -rf {} + + log_success "Removed $waydroid_count Waydroid shortcut(s)" +else + log_info "No Waydroid shortcuts found" +fi + +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Wine Utility Applications +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Reason: These Wine utilities clutter the application menu unnecessarily + +log_info "Removing unwanted Wine application shortcuts" + +readonly -a WINE_DESKTOP_FILES=( + "wine-notepad.desktop" + "wine-oleview.desktop" + "wine-winemine.desktop" + "wine-wordpad.desktop" + "wine-winhelp.desktop" +) + +wine_removed=0 +for desktop_file in "${WINE_DESKTOP_FILES[@]}"; do + desktop_path="/usr/share/applications/$desktop_file" + if [[ -e "$desktop_path" ]]; then + rm -f "$desktop_path" + ((wine_removed++)) + fi +done + +if [[ $wine_removed -gt 0 ]]; then + log_success "Removed $wine_removed Wine shortcut(s)" +else + log_info "No Wine shortcuts found" +fi + +# ============================================================================ +# Cleanup - Bazzite Remnants +# ============================================================================ +# Remove Bazzite-specific files that don't apply to DistinctionOS + +log_section "Removing Bazzite-specific files" + +# Array of files to remove with reasons +declare -A BAZZITE_FILES=( + ["/etc/profile.d/askpass.sh"]="SSH askpass conflicts with our authentication" + ["/usr/libexec/openssh/gnome-ssh-askpass"]="GNOME SSH askpass binary" + ["/usr/share/applications/gnome-ssh-askpass.desktop"]="SSH askpass desktop entry" + ["/etc/profile.d/bazzite-neofetch.sh"]="Bazzite-branded neofetch configuration" + ["/etc/yum.repos.d/charm.repo"]="Charm repository (unused)" +) + +bazzite_removed=0 +for file_path in "${!BAZZITE_FILES[@]}"; do + reason="${BAZZITE_FILES[$file_path]}" + + if [[ -e "$file_path" ]]; then + log_info "Removing: $file_path" + log_info " Reason: $reason" + rm -f "$file_path" + ((bazzite_removed++)) + fi +done + +if [[ $bazzite_removed -gt 0 ]]; then + log_success "Removed $bazzite_removed Bazzite file(s)" +else + log_info "No Bazzite remnants found" +fi + +# ============================================================================ +# Configuration Complete +# ============================================================================ + +log_header "System configuration phase complete" + +log_info "Configuration summary:" +echo " โ€ข Default shell: ZSH" +echo " โ€ข Just recipes: Integrated" +echo " โ€ข Applications: Customized" +echo " โ€ข System caches: Updated" +echo " โ€ข Unwanted files: Removed" + +exit 0 diff --git a/build_files/05-kernel-modules.sh b/build_files/05-kernel-modules.sh new file mode 100755 index 0000000..6a933d5 --- /dev/null +++ b/build_files/05-kernel-modules.sh @@ -0,0 +1,194 @@ +#!/usr/bin/bash + +set -euo pipefail + +# ============================================================================ +# Kernel Module Compilation +# ============================================================================ + +# Source utility functions +source /ctx/95-utility-functions.sh + +# ============================================================================ +# Kernel Detection +# ============================================================================ + +log_header "Kernel Module Compilation" + +log_section "Detecting installed kernel" + +# Find the Bazzite kernel version +KERNEL=$(ls /lib/modules/ | grep ba | tail -1) + +if [[ -z "$KERNEL" ]]; then + log_error "No Bazzite kernel found in /lib/modules/" + exit 1 +fi + +log_success "Detected kernel: $KERNEL" + +# Set kernel build directory for compilation +export KERNELDIR="/lib/modules/${KERNEL}/build" +log_info "Kernel build directory: $KERNELDIR" + +# ============================================================================ +# xpadneo Module Compilation +# ============================================================================ +# Enhanced Xbox controller driver with better wireless support + +log_section "Building xpadneo kernel module" + +# Store current directory (with unbound variable protection) +set +u # Temporarily disable unbound variable check +PREV_DIR=$(pwd) +set -u + +log_info "Cloning xpadneo repository" +if git clone https://github.com/atar-axis/xpadneo.git /tmp/xpadneo; then + log_success "Repository cloned to /tmp/xpadneo" +else + log_error "Failed to clone xpadneo repository" + exit 1 +fi + +cd /tmp/xpadneo/hid-xpadneo + +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Custom Makefile Generation +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Modified from xpadneo's original makefile to work with ostree systems +# DO NOT MODIFY THE HEREDOC BELOW - IT IS CAREFULLY CRAFTED FOR COMPATIBILITY + +log_info "Generating custom makefile for ostree compatibility" + +tee makefile << 'EOF' +KERNEL_SOURCE_DIR ?= /lib/modules/$(shell ls /lib/modules/ | grep ba | tail -1)/build +LD := ld.bfd + +all: modules + +.INTERMEDIATE: ../VERSION + +../VERSION: + $(MAKE) -C .. $(@:../%=%) + +# convenience rules for local development + +clean modules modules_install: ../VERSION + $(MAKE) -C $(KERNEL_SOURCE_DIR) INSTALL_MOD_DIR="kernel/drivers/hid" LD=$(LD) M=$(shell pwd)/src VERSION="$(shell cat ../VERSION)" $@ + +reinstall: modules + sudo make modules_install + sudo rmmod hid-xpadneo || true + sudo modprobe hid-xpadneo $(MOD_PARAMS) + +# DKMS support rules + +dkms.conf: dkms.conf.in ../VERSION + sed 's/"@DO_NOT_CHANGE@"/"$(shell cat ../VERSION)"/g' <"$<" >"$@" +EOF + +log_success "Custom makefile generated" + +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Module Compilation +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +log_section "Compiling xpadneo module" + +if make modules; then + log_success "Module compilation successful" +else + log_error "Module compilation failed" + exit 1 +fi + +log_section "Installing xpadneo module" + +if make modules_install; then + log_success "Module installation successful" +else + log_error "Module installation failed" + exit 1 +fi + +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Installation Verification +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +log_section "Verifying xpadneo installation" + +# Check for module in possible installation locations +readonly FILE1="/lib/modules/${KERNEL}/extra/xpadneo/xpadneo.ko.zst" +readonly FILE2="/lib/modules/${KERNEL}/kernel/drivers/hid/hid-xpadneo.ko" + +if [[ -f "$FILE1" || -f "$FILE2" ]]; then + log_success "xpadneo module verified at:" + [[ -f "$FILE1" ]] && echo " $FILE1" + [[ -f "$FILE2" ]] && echo " $FILE2" +else + log_error "xpadneo module not found in expected locations" + log_error "Expected locations:" + echo " $FILE1" + echo " $FILE2" + exit 1 +fi + +# Return to root directory +cd / + +# ============================================================================ +# Initramfs Regeneration +# ============================================================================ +# Rebuild initramfs to include new kernel modules + +log_section "Regenerating initramfs with new modules" + +# Get precise kernel version for dracut +KERNEL_VERSION="$(dnf5 repoquery --installed --queryformat='%{evr}.%{arch}' kernel)" +log_info "Kernel version: $KERNEL_VERSION" + +log_info "Running dracut to rebuild initramfs" +if /usr/bin/dracut \ + --no-hostonly \ + --kver "$KERNEL_VERSION" \ + --reproducible \ + --zstd \ + -v \ + --add ostree \ + -f "/usr/lib/modules/$KERNEL_VERSION/initramfs.img"; then + log_success "Initramfs regenerated successfully" +else + log_error "Initramfs regeneration failed" + exit 1 +fi + +# Set secure permissions on initramfs +log_info "Setting initramfs permissions (0600)" +chmod 0600 "/usr/lib/modules/$KERNEL_VERSION/initramfs.img" +log_success "Initramfs permissions secured" + +# ============================================================================ +# Build Complete +# ============================================================================ + +log_header "Kernel module compilation complete" + +log_info "Installed modules:" +echo " โ€ข xpadneo (Xbox controller driver)" +if command -v zfs &>/dev/null; then + echo " โ€ข ZFS (filesystem driver)" +fi + +log_info "Next step:" +echo " 7. remote-grabber.sh - GNOME extension management" + +# ============================================================================ +# Future Improvements (TODO) +# ============================================================================ +# - Integrate CachyOS-LTO kernel as default +# - Investigate kmod package installation after initramfs regeneration +# - Consider switching to packaged variant of xpadneo if available +# - Add support for additional controller drivers if needed + +exit 0 diff --git a/build_files/remote_grabber_new.sh b/build_files/06-remote-grabber.sh similarity index 88% rename from build_files/remote_grabber_new.sh rename to build_files/06-remote-grabber.sh index 2539130..2c549d6 100755 --- a/build_files/remote_grabber_new.sh +++ b/build_files/06-remote-grabber.sh @@ -1,21 +1,14 @@ #!/bin/bash - -# Author Note: This entire script is from Claude Sonnet 4 -# Yes I know, 'Vibe code bad!' -# But I don't think I would've made it this far without it... -# For better or worse I've managed to create an entire build system \ -# and Modify bazzite into an unholy creation of my design, without much expierence in shell scripts. -# Make of that what you will. - # ============================================================================= # GNOME Shell Extensions Installation Script # Enhanced version with proper error handling and modular design # ============================================================================= +# Source utility functions +source /ctx/95-utility-functions.sh - -set -euo pipefail # Exit on any error, undefined variable, or pipe failure +set -euo pipefail # Constants and Configuration readonly SCRIPT_NAME="${0##*/}" @@ -23,13 +16,6 @@ readonly EXTENSIONS_DIR="/usr/share/gnome-shell/extensions" readonly TMP_DIR="/tmp/gnome-shell-extensions" readonly LOG_FILE="${TMP_DIR}/installation.log" -# Colour constants for elegant output -readonly RED='\033[31m' -readonly GREEN='\033[32m' -readonly YELLOW='\033[33m' -readonly BLUE='\033[34m' -readonly NC='\033[0m' - # Extension definitions - structured data approach declare -A EXTENSIONS_GIT=( ["pip-on-top@rafostar.github.com"]="https://github.com/Rafostar/gnome-shell-extension-pip-on-top.git" @@ -59,17 +45,6 @@ setup_environment() { mkdir -p "$TMP_DIR" "$EXTENSIONS_DIR" } -log() { - local level="$1" - shift - echo -e "[$(date '+%H:%M:%S')] [$level] $*" -} - -log_info() { log "INFO" "$@"; } -log_success() { log "SUCCESS" "${GREEN}$*${NC}"; } -log_warning() { log "WARNING" "${YELLOW}$*${NC}"; } -log_error() { log "ERROR" "${RED}$*${NC}"; } - install_git_extension() { local extension_id="$1" local repository_url="$2" diff --git a/build_files/95-utility-functions.sh b/build_files/95-utility-functions.sh new file mode 100755 index 0000000..8ce40b7 --- /dev/null +++ b/build_files/95-utility-functions.sh @@ -0,0 +1,361 @@ +#!/usr/bin/bash + +# ============================================================================ +# DistinctionOS Build Utility Functions Library +# ============================================================================ +# Purpose: Shared functions and constants for all build scripts +# Usage: source /ctx/utility-functions.sh +# Version: 1.0 +# Created: 2025-10-27 +# ============================================================================ + +# Prevent multiple sourcing +[[ -n "${DISTINCTION_UTILS_LOADED:-}" ]] && return 0 +readonly DISTINCTION_UTILS_LOADED=1 + +# ============================================================================ +# ANSI Color Codes +# ============================================================================ + +readonly COLOR_RESET='\033[0m' +readonly COLOR_RED='\033[31m' +readonly COLOR_GREEN='\033[32m' +readonly COLOR_YELLOW='\033[33m' +readonly COLOR_BLUE='\033[34m' +readonly COLOR_MAGENTA='\033[35m' +readonly COLOR_CYAN='\033[36m' +readonly COLOR_ORANGE='\033[38;5;208m' + +# ============================================================================ +# Logging Functions +# ============================================================================ + +# Major section headers with box-drawing characters +log_header() { + echo -e "${COLOR_BLUE}โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—${COLOR_RESET}" + echo -e "${COLOR_BLUE}โ•‘${COLOR_RESET} $* " + echo -e "${COLOR_BLUE}โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${COLOR_RESET}" +} + +# Subsection headers with arrow indicator +log_section() { + echo -e "\n${COLOR_CYAN}โ–ถ $*${COLOR_RESET}" +} + +# Success messages with checkmark +log_success() { + echo -e "${COLOR_GREEN}โœ“ $*${COLOR_RESET}" +} + +# Warning messages for non-critical issues +log_warning() { + echo -e "${COLOR_YELLOW}โš  $*${COLOR_RESET}" +} + +# Error messages sent to stderr +log_error() { + echo -e "${COLOR_RED}โœ— $*${COLOR_RESET}" >&2 +} + +# Informational messages +log_info() { + echo -e "${COLOR_MAGENTA}โ„น $*${COLOR_RESET}" +} + +# ============================================================================ +# Debug & Tracing Functions +# ============================================================================ + +# Enable command tracing for debugging (excludes echo and log commands) +enable_debug_trace() { + trap '[[ $BASH_COMMAND != echo* ]] && [[ $BASH_COMMAND != log* ]] && echo "+ $BASH_COMMAND"' DEBUG +} + +# Disable command tracing +disable_debug_trace() { + trap - DEBUG +} + +# ============================================================================ +# Package Validation Functions +# ============================================================================ + +# Validate that a single package is installed +# Usage: validate_package_installed "package-name" +# Returns: 0 if installed, 1 if not +validate_package_installed() { + local package="$1" + + if rpm -q "$package" &>/dev/null; then + log_success "$package installed successfully" + return 0 + else + log_warning "$package installation could not be verified" + return 1 + fi +} + +# Validate that all critical packages are installed +# Usage: validate_critical_packages "pkg1" "pkg2" "pkg3" +# Returns: 0 if all installed, 1 if any missing +validate_critical_packages() { + local -a critical_packages=("$@") + local failed=0 + + log_info "Validating ${#critical_packages[@]} critical package(s)" + + for pkg in "${critical_packages[@]}"; do + if ! rpm -q "$pkg" &>/dev/null; then + log_error "Critical package missing: $pkg" + ((failed++)) + fi + done + + if [[ $failed -gt 0 ]]; then + log_error "$failed critical package(s) failed to install" + return 1 + fi + + log_success "All critical packages validated" + return 0 +} + +# ============================================================================ +# File & Directory Management Functions +# ============================================================================ + +# Check if file exists and log appropriately +# Usage: check_file_exists "/path/to/file" "descriptive name" +# Returns: 0 if exists, 1 if not +check_file_exists() { + local file_path="$1" + local description="${2:-file}" + + if [[ -f "$file_path" ]]; then + log_success "$description found: $file_path" + return 0 + else + log_warning "$description not found: $file_path" + return 1 + fi +} + +# Check if directory exists and log appropriately +# Usage: check_dir_exists "/path/to/dir" "descriptive name" +# Returns: 0 if exists, 1 if not +check_dir_exists() { + local dir_path="$1" + local description="${2:-directory}" + + if [[ -d "$dir_path" ]]; then + log_success "$description found: $dir_path" + return 0 + else + log_warning "$description not found: $dir_path" + return 1 + fi +} + +# Create directory with logging +# Usage: create_dir_with_log "/path/to/dir" "descriptive name" +# Returns: 0 on success, 1 on failure +create_dir_with_log() { + local dir_path="$1" + local description="${2:-directory}" + + if [[ -d "$dir_path" ]]; then + log_info "$description already exists: $dir_path" + return 0 + fi + + if mkdir -p "$dir_path"; then + log_success "$description created: $dir_path" + return 0 + else + log_error "Failed to create $description: $dir_path" + return 1 + fi +} + +# Remove file with logging and counting +# Usage: remove_file_with_log "/path/to/file" "descriptive name" +# Returns: 0 if removed or didn't exist, 1 on failure +remove_file_with_log() { + local file_path="$1" + local description="${2:-file}" + + if [[ ! -e "$file_path" ]]; then + log_info "$description not present: $file_path" + return 0 + fi + + if rm -f "$file_path"; then + log_success "$description removed: $file_path" + return 0 + else + log_error "Failed to remove $description: $file_path" + return 1 + fi +} + +# ============================================================================ +# Command Execution Wrappers +# ============================================================================ + +# Execute command with success/failure logging +# Usage: run_with_log "descriptive message" command arg1 arg2... +# Returns: command exit code +run_with_log() { + local description="$1" + shift + + log_info "$description" + + if "$@"; then + log_success "$description - completed" + return 0 + else + local exit_code=$? + log_error "$description - failed (exit code: $exit_code)" + return $exit_code + fi +} + +# Execute command silently with only success/failure logging +# Usage: run_silent_with_log "descriptive message" command arg1 arg2... +# Returns: command exit code +run_silent_with_log() { + local description="$1" + shift + + if "$@" &>/dev/null; then + log_success "$description" + return 0 + else + local exit_code=$? + log_warning "$description - failed (exit code: $exit_code)" + return $exit_code + fi +} + +# ============================================================================ +# Counter Functions +# ============================================================================ + +# Initialize a counter variable +# Usage: counter_init +# Returns: 0 +counter_init() { + echo "0" +} + +# Increment a counter +# Usage: count=$(counter_increment "$count") +# Returns: incremented value +counter_increment() { + local current="${1:-0}" + echo $((current + 1)) +} + +# Display counter result with appropriate singular/plural +# Usage: counter_display "$count" "item" "items" "action" +# Example: counter_display "$removed" "file" "files" "removed" +counter_display() { + local count="$1" + local singular="$2" + local plural="$3" + local action="${4:-processed}" + + if [[ $count -eq 0 ]]; then + log_info "No ${plural} ${action}" + elif [[ $count -eq 1 ]]; then + log_success "${count} ${singular} ${action}" + else + log_success "${count} ${plural} ${action}" + fi +} + +# ============================================================================ +# System Information Functions +# ============================================================================ + +# Get the current Bazzite kernel version +# Usage: kernel_version=$(get_bazzite_kernel) +# Returns: kernel version string or empty if not found +get_bazzite_kernel() { + local kernel + kernel=$(ls /lib/modules/ | grep bazzite | sort -V | tail -1) + + if [[ -n "$kernel" ]]; then + echo "$kernel" + return 0 + else + return 1 + fi +} + +# Get precise kernel version for DNF queries +# Usage: kernel_ver=$(get_kernel_version) +# Returns: kernel version in format suitable for dracut +get_kernel_version() { + dnf5 repoquery --installed --queryformat='%{evr}.%{arch}' kernel 2>/dev/null | head -1 +} + +# ============================================================================ +# Script Lifecycle Functions +# ============================================================================ + +# Print script start header +# Usage: script_start "Script Name" "Brief description" +script_start() { + local script_name="$1" + local description="${2:-}" + + log_header "$script_name" + [[ -n "$description" ]] && echo " $description" +} + +# Print script completion header with next steps +# Usage: script_complete "Script Name" "next step description" +script_complete() { + local script_name="$1" + local next_step="${2:-}" + + log_header "$script_name - Complete" + + if [[ -n "$next_step" ]]; then + log_info "Next step:" + echo " $next_step" + fi +} + +# ============================================================================ +# Utility Functions +# ============================================================================ + +# Check if running as root +# Usage: require_root +# Exits if not root +require_root() { + if [[ $EUID -ne 0 ]]; then + log_error "This script must be run as root" + exit 1 + fi +} + +# Print a simple divider line +divider() { + echo "โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€" +} + +# Print library load confirmation (for debugging) +confirm_library_loaded() { + log_success "DistinctionOS utility functions library loaded" +} + +# ============================================================================ +# Library Initialization Complete +# ============================================================================ + +# Uncomment for debugging library load: +# confirm_library_loaded diff --git a/build_files/build.sh b/build_files/build.sh deleted file mode 100755 index 7c60dba..0000000 --- a/build_files/build.sh +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/bash -set -euo pipefail - -# CREDIT: https://github.com/ExistingPerson08/amyos-gnome/blob/main/build_files/install-apps.sh -# A good example on what to improve upon - -trap '[[ $BASH_COMMAND != echo* ]] && [[ $BASH_COMMAND != log* ]] && echo "+ $BASH_COMMAND"' DEBUG - -log() { - echo "=== $* ===" -} - - -#remove pesky bazzite things -remove_packages=(waydroid \ - sunshine \ - gnome-shell-extension-compiz-windows-effect \ - openssh-askpass \ - zfs-fuse) -# TODO: Rebrand Bazzite things to DistinctionOS -# TODO: Figure out why certain packages seem to be omitted during install - -for pkg in "${remove_packages[@]}"; do - if rpm -q "$pkg" &>/dev/null; then - echo "Removing $pkg..." - dnf5 -y remove "$pkg" - fi -done - - -#=================Cider===================== -# Cider workaround because I don't want to \ -# mess with the main installer portion -rpm --import https://repo.cider.sh/RPM-GPG-KEY - -tee /etc/yum.repos.d/cider.repo << 'EOF' -[cidercollective] -name=Cider Collective Repository -baseurl=https://repo.cider.sh/rpm/RPMS -enabled=1 -gpgcheck=1 -gpgkey=https://repo.cider.sh/RPM-GPG-KEY -EOF - -dnf makecache -#=================Cider===================== -# RPM packages list -declare -A RPM_PACKAGES=( - ["fedora"]="\ - yt-dlp \ - zsh \ - zsh-syntax-highlighting \ - zsh-autosuggestions \ - neovim \ - file-roller \ - bat \ - evince \ - loupe \ - zoxide \ - ardour8 \ - sassc \ - blackbox-terminal \ - gstreamer1-plugins-good-extras - decibels \ - dconf \ - gtk-murrine-engine \ - glib2-devel \ - perl-File-Copy \ - winetricks \ - lutris \ - sox \ - totem-video-thumbnailer \ - mediainfo \ - pandoc \ - docker \ - docker-compose \ - flatpak-builder \ - gnome-tweaks \ - freerdp" - - ["rpmfusion-free,rpmfusion-free-updates,rpmfusion-nonfree,rpmfusion-nonfree-updates"]="\ - audacity-freeworld \ - libavcodec-freeworld \ - gstreamer1-plugins-bad-freeworld \ - gstreamer1-plugins-ugly" - - ["fedora-multimedia"]="mpv" - - ["brave-browser"]="brave-browser" - ["cidercollective"]="Cider" - ["copr:ilyaz/LACT"]="lact" - ["copr:fernando-debian/dysk"]="dysk" - ["copr:atim/heroic-games-launcher"]="heroic-games-launcher-bin" - ["copr:sergiomb/clonezilla"]="clonezilla" - #["copr:monkeygold/nautilus-open-any-terminal"]="nautilus-open-any-terminal" - ["copr:alternateved/eza"]="eza" -) - -log "Starting DistinctionOS build process" - -log "Installing RPM packages" -mkdir -p /var/opt -for repo in "${!RPM_PACKAGES[@]}"; do - read -ra pkg_array <<<"${RPM_PACKAGES[$repo]}" - if [[ $repo == copr:* ]]; then - # Handle COPR packages - copr_repo=${repo#copr:} - dnf5 -y copr enable "$copr_repo" - dnf5 -y install "${pkg_array[@]}" - dnf5 -y copr disable "$copr_repo" - else - # Handle regular packages - [[ $repo != "fedora" ]] && enable_opt="--enable-repo=$repo" || enable_opt="" - cmd=(dnf5 -y install --best) - [[ -n "$enable_opt" ]] && cmd+=("$enable_opt") - cmd+=("${pkg_array[@]}") - "${cmd[@]}" - fi -done - -dnf5 -y install --best \ - dkms \ - nss-mdns.i686 \ - pcsc-lite-libs.i686 \ - freerdp \ - nmap-ncat \ - pandoc \ - docker \ - docker-compose \ - flatpak-builder \ - gnome-tweaks \ - sane-backends-libs.i686 \ - sane-backends-libs.x86_64 \ - sox \ - totem-video-thumbnailer \ - mediainfo \ - dcraw \ - perl-Image-ExifTool - -# Install traditional wine -dnf5 -y install wine --skip-broken -dnf5 versionlock add wine gcc make bazaar glycin-loaders # probably unecessary -echo "VERSIONLOCK LIST >>" -dnf versionlock list -# this should be temporary-- There seems to be an issue where [heif]-images become washed out/really bright -rpm -e --nodeps libheif heif-pixbuf-loader -dnf5 -y install libheif libheif-tools heif-pixbuf-loader || echo "install of libheif failed" -dnf5 -y --enablerepo=rpmfusion-free install libheif-freeworld || echo "install of libheif-freeworld failed" -[ rpm -q glycin-loaders ] || dnf5 -y install glycin-loaders -[ rpm -q bazaar ] || dnf5 -y install bazaar -[ rpm -q glycin-gtk4-libs ] || dnf5 -y install glycin-gtk4-libs -[ rpm -q loupe ] || dnf5 -y install loupe - -# TODO: add ujust recipe for crossover or make custom rpm .spec -dnf5 -y install http://crossover.codeweavers.com/redirect/crossover.rpm - -dnf5 -y upgrade - -# custom kora icon theme - -# Install latest release directly with dnf5 -dnf5 -y install $(curl -s https://api.github.com/repos/phantomcortex/kora/releases/latest | grep "browser_download_url.*\.rpm" | cut -d '"' -f 4) -# Winboat (Added @ 0.7.11) -#dnf5 -y install $(curl -s https://api.github.com/repos/TibixDev/winboat/releases/latest | grep "browser_download_url.*\.rpm" | cut -d '"' -f 4) - - diff --git a/build_files/config.sh b/build_files/config.sh deleted file mode 100755 index fb6d657..0000000 --- a/build_files/config.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/bash -set -euo pipefail - -# script for things that don't really have a specific place -log() { - echo "=== $* ===" -} - - -# Change the default shell to zsh -if [ -e /etc/default/useradd ];then - sed -i 's|SHELL=/bin/bash|SHELL=/usr/bin/zsh|' /etc/default/useradd -fi -usermod -s /usr/bin/zsh root -# - -# enable distictionos-firstrun -#systemctl enable distinction-firstrun.service - -# Enable TPM monitoring services -echo "Enabling TPM monitor services..." -#systemctl enable distinction-tpm-monitor.timer -#systemctl enable distinction-tpm-monitor.service - -log "Enabling system services" - -log "Adding DistinctionOS just recipes" -echo "import \"/usr/share/DistinctionOS/just/distinction.just\"" >>/usr/share/ublue-os/justfile - -log "Hide incompatible Bazzite just recipes" -for recipe in "install-coolercontrol" "install-openrgb"; do - if ! grep -l "^$recipe:" /usr/share/ublue-os/just/*.just | grep -q .; then - echo "Error: Recipe $recipe not found in any just file" - exit 1 - fi - sed -i "s/^$recipe:/_$recipe:/" /usr/share/ublue-os/just/*.just -done - -log "Build process completed" - - -# remove bazzite things intended for waydroid -find /usr/share/applications -iname '*waydroid*' -exec rm -rf {} + - -# custom icon for Cider because it doesn't seem to use it regardless of what icon theme is used -sed -i 's@Icon=Cider@Icon=/usr/share/icons/kora/apps/scalable/cider.svg@g' /usr/share/applications/Cider.desktop - -# modify winetricks due to winetricks telling me 'You are using 64 bit verb' or 'You seem to be using wow64 mode!' five-thousand times... -if [ -f /usr/share/applications/winetricks.desktop ]; then - sed -i 's@Exec=winetricks --gui@Exec=/usr/bin/env WINEDEBUG-all winetricks -q --gui@g' /usr/share/applications/winetricks.desktop -else - echo "winetricks.desktop does not exist for some reason" - if [ rpm -q winetricks ]; then - tee /usr/share/applications/winetricks.desktop << 'EOF' -[Desktop Entry] -Name=Winetricks -Comment=Work around problems and install applications under Wine -Exec=/usr/bin/env WINEDEBUG=-all winetricks -q --gui -Terminal=false -Icon=winetricks -Type=Application -Categories=Utility; -EOF - fi -fi - - -gtk-update-icon-cache -f /usr/share/icons/kora -#few updates () -update-desktop-database -glib-compile-schemas /usr/share/glib-2.0 -update-mime-database -V /usr/share/mime - - -# remove pesky askpass -if [ -e /etc/profile.d/askpass.sh ]; then - rm -f /etc/profile.d/askpass.sh - [ -e /usr/libexec/openssh/gnome-ssh-askpass ] && rm -f /usr/libexec/openssh/gnome-ssh-askpass -fi - -# rm other bazzite things - [ -e /etc/profile.d/bazzite-neofetch.sh ] && rm -f /etc/profile.d/bazzite-neofetch.sh - [ -e /usr/share/applications/gnome-ssh-askpass.desktop ] && rm -f /usr/share/applications/gnome-ssh-askpass.desktop - [ -e /etc/yum.repos.d/charm.repo ] && rm -f /etc/yum.repos.d/charm.repo - -# rm dumb wine things -[ -e /usr/share/applications/wine-notepad.desktop ] && rm -f /usr/share/applications/wine-notepad.desktop -[ -e /usr/share/applications/wine-oleview.desktop ] && rm -f /usr/share/applications/wine-oleview.desktop -[ -e /usr/share/applications/wine-winemine.desktop ] && rm -f /usr/share/applications/wine-winemine.desktop -[ -e /usr/share/applications/wine-wordpad.desktop ] && rm -f /usr/share/applications/wine-wordpad.desktop -[ -e /usr/share/applications/wine-winhelp.desktop ] && rm -f /usr/share/applications/wine-winhelp.desktop diff --git a/build_files/fix_opt.sh b/build_files/fix_opt.sh deleted file mode 100755 index 066b026..0000000 --- a/build_files/fix_opt.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/bash -set -euo pipefail - -# Alternative approach: Full copy for complete writeability -# Use this if you prefer simplicity over immutability benefits - -trap '[[ $BASH_COMMAND != echo* ]] && [[ $BASH_COMMAND != log* ]] && echo "+ $BASH_COMMAND"' DEBUG - -log() { - echo "=== $* ===" -} - -log "Starting /opt directory fix (full-copy variant)" - -# Ensure required directories exist -mkdir -p /usr/lib/opt -mkdir -p /var/opt - -# Process each directory in /var/opt -for dir in /var/opt/*/; do - [ -d "$dir" ] || continue - dirname=$(basename "$dir") - - - - log "Processing standard package: $dirname" - mv "$dir" "/usr/lib/opt/$dirname" - echo "L+ /var/opt/$dirname - - - - /usr/lib/opt/$dirname" >> /usr/lib/tmpfiles.d/distinction-opt-fix.conf - log "Fix completed successfully" -done diff --git a/build_files/install_zfs.sh b/build_files/install_zfs.sh deleted file mode 100755 index 13826dc..0000000 --- a/build_files/install_zfs.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# ZFS filesystem driver -dnf install -y https://zfsonlinux.org/fedora/zfs-release-2-8.fc42.noarch.rpm -# Install ZFS -dnf -y install zfs - - -#kernel module - -# Build ZFS modules for the target kernel specifically -dkms autoinstall -k ${KERNEL} - -if [ -d "/lib/modules/${KERNEL}/extra/zfs" ]; then - echo "ZFS modules successfully built for kernel ${KERNEL}" -else - echo "Warning: ZFS module build may have failed for kernel ${KERNEL}" - # Fallback: attempt to build for all installed kernels -fi -# Set up the build environment properly - diff --git a/build_files/kernel_modules.sh b/build_files/kernel_modules.sh deleted file mode 100755 index 9984072..0000000 --- a/build_files/kernel_modules.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/bash -set -euo pipefail - -KERNEL=$(ls /lib/modules/ | grep bazzite | sort -V | tail -1) - -export KERNELDIR="/lib/modules/${KERNEL}/build" -echo -e "\033[31mINSTALL XPADNEO\033[0m" -set +u #these are here prevent 'unbound variable' which doesn't make ANY sense. -PREV_DIR=$(pwd) && echo -e "\033[33m$pwd\033[0m" -set -u -git clone https://github.com/atar-axis/xpadneo.git /tmp/xpadneo -cd /tmp/xpadneo/hid-xpadneo - -#modified straight from xpadneo's makefile -tee makefile << 'EOF' -KERNEL_SOURCE_DIR ?= /lib/modules/$(shell ls /lib/modules/ | grep bazzite | tail -1)/build -LD := ld.bfd - -all: modules - -.INTERMEDIATE: ../VERSION - -../VERSION: - $(MAKE) -C .. $(@:../%=%) - -# convenience rules for local development - -clean modules modules_install: ../VERSION - $(MAKE) -C $(KERNEL_SOURCE_DIR) INSTALL_MOD_DIR="kernel/drivers/hid" LD=$(LD) M=$(shell pwd)/src VERSION="$(shell cat ../VERSION)" $@ - -reinstall: modules - sudo make modules_install - sudo rmmod hid-xpadneo || true - sudo modprobe hid-xpadneo $(MOD_PARAMS) - -# DKMS support rules - -dkms.conf: dkms.conf.in ../VERSION - sed 's/"@DO_NOT_CHANGE@"/"$(shell cat ../VERSION)"/g' <"$<" >"$@" -EOF -echo -e "\033[31mMAKE MODULES\033[0m" -make modules -echo -e "\033[31mMODULES_INSTALL\033[0m" -make modules_install -echo -e "\033[31mMODULES DONE\033[0m" -sleep 5 - -FILE1="/lib/modules/${KERNEL}/extra/xpadneo/xpadneo.ko.zst" -FILE2="/lib/modules/${KERNEL}/kernel/drivers/hid/hid-xpadneo.ko" - -if [[ -f "$FILE1" || -f "$FILE2" ]]; then - # Orange text: ANSI escape code 38;5;208 - echo -e "\033[38;5;208mXPADNEO INSTALLED\033[0m" - else - echo -e "\033[33;5mXPADNEO FAILED TO INSTALL\033[0m" && exit 1 -fi #sanity check - - -# Get kernel version and build initramfs -KERNEL_VERSION="$(dnf5 repoquery --installed --queryformat='%{evr}.%{arch}' kernel)" -/usr/bin/dracut \ - --no-hostonly \ - --kver "$KERNEL_VERSION" \ - --reproducible \ - --zstd \ - -v \ - --add ostree \ - -f "/usr/lib/modules/$KERNEL_VERSION/initramfs.img" - -chmod 0600 "/usr/lib/modules/$KERNEL_VERSION/initramfs.img" - -#cd $PREV_DIR -cd / - -#TODO: get cachyos kernel working -#TODO: investigate if kmod packages are installed correctly after init-regen \ -# and consider switching to packaged variant of xpadneo diff --git a/build_files/layered_appimages.sh b/build_files/layered_appimages.sh deleted file mode 100755 index e28c800..0000000 --- a/build_files/layered_appimages.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/bash -set -euo pipefail - -# Is it wise or should i really be layering appimages on the OS? -# Probably not. maybe this 'fixation' will pass and I'll use those appimages \ -# like I'm supposed to - - -mkdir -p /var/opt/cemu/ -curl -L https://github.com/cemu-project/Cemu/releases/download/v2.6/Cemu-2.6-x86_64.AppImage -o /var/opt/cemu/cemu-2.6.AppImage - -mkdir -p /var/opt/yuzu/ -curl -L https://github.com/phantomcortex/yuzu/releases/download/r_limbo_1/Yuzu-EA-4176.AppImage -o /var/opt/yuzu/yuzu-4176.AppImage - -tee /usr/share/applications/yuzu.desktop << 'EOF' -[Desktop Entry] -Version=1.0 -Type=Application -Name=Yuzu -GenericName=Switch Emulator -Exec=env DESKTOPINTEGRATION=1 /opt/yuzu/yuzu-4176.AppImage -Icon=/usr/share/icons/kora/apps/scalable/yuzu.svg -Categories=Game;Emulator;Qt; -MimeType=application/x-nx-nro;application/x-nx-nso;application/x-nx-nsp;application/x-nx-xcii -Keywords=Nintendo;Switch; -StartupWMClass=yuzu -x-AppImage-Integrate=false -x-AppImage-Version=9f20b0 -EOF - -tee /usr/share/applications/cemu.desktop << 'EOF' -[Desktop Entry] -Version=1.0 -Name=Cemu -GenericName=Wii U Emulator -Terminal=false -Exec=env DESKTOPINTEGRATION=1 /opt/cemu/cemu-2.6.AppImage -TryExec=/opt/cemu/cemu-2.6.AppImage -Icon=/usr/share/icons/kora/apps/scalable/cemu.svg -Categories=Game;Emulator;Qt; -Keywords=Nintendo; -MimeType=application/x-wii-u-rom; -x-AppImage-Version=a6fb0a4 -EOF - -if [ ! -e /var/opt/yuzu/yuzu-4176.AppImage ]; then - echo "yuzu does not exist!" - exit -elif [ ! -e /var/opt/cemu/cemu-2.6.AppImage ]; then - echo "cemu does not exists!" - exit -else - echo "yuzu/cemu should work fine" - chmod +x /var/opt/yuzu/yuzu-4176.AppImage - chmod +x /var/opt/cemu/cemu-2.6.AppImage -fi diff --git a/claude.md b/claude.md deleted file mode 100644 index 70a89b3..0000000 --- a/claude.md +++ /dev/null @@ -1,263 +0,0 @@ -# Claude Context: DistinctionOS - -## Project Overview - -**DistinctionOS** is a custom immutable Linux image built upon the Bazzite foundation, leveraging Universal Blue's infrastructure and tooling. This repository represents a personalised gaming and development environment optimised for a fully-featured experience. - -### Key Characteristics -- **Base System**: Bazzite (gaming-focused Fedora Atomic variant) -- **Build System**: Built from Universal Blue's github Image template and uses github-actions to build & push to ghcr -- **Target Audience**: Mainly Personal use, with gaming and development focus -- **Deployment**: OCI container images via GitHub Container Registry -- **Philosophy**: "Swiss Army Knife" approach - versatile powerhouse over minimalism - -## Repository Structure - -``` -DistinctionOS/ -โ”œโ”€โ”€ system_files/ # Static files copied into the image -โ”‚ โ”œโ”€โ”€ usr/ -โ”‚ โ”‚ โ”œโ”€โ”€ bin/ # Custom executables (firstrun, tpm-monitor, advmv, advcp) -โ”‚ โ”‚ โ”œโ”€โ”€ lib/systemd/ # SystemD services and timers -โ”‚ โ”‚ โ””โ”€โ”€ share/DistinctionOS/just/ # Just recipes -โ”‚ โ””โ”€โ”€ etc/ -โ”‚ โ””โ”€โ”€ sudoers.d/ # Sudo configuration -โ”œโ”€โ”€ build_files/ # Build-time scripts -โ”‚ โ”œโ”€โ”€ build_new.sh # Main package installer -โ”‚ โ”œโ”€โ”€ fix_opt.sh # Fixes /opt packages at runtime -โ”‚ โ”œโ”€โ”€ kernel_modules.sh # Compiles xpadneo kernel module -โ”‚ โ”œโ”€โ”€ config.sh # Intended for System Configuration or miscellaneous things that don't have a proper place -โ”‚ โ”œโ”€โ”€ layered_appimages.sh # Layers AppImages (user aware of unconventional approach) -โ”‚ โ”œโ”€โ”€ remote_grabber.sh # GNOME Shell extension management -โ”‚ โ””โ”€โ”€ wine_installer.sh # Installs Kron4ek Wine builds -โ”œโ”€โ”€ repo_files/ # Resources for just recipes -โ”œโ”€โ”€ disk_config/ # Configuration for build-disk.yml -โ”œโ”€โ”€ Containerfile # Custom container build instructions -โ””โ”€โ”€ .github/workflows/ # GitHub Actions (build.yml & build-disk.yml) -``` - -## Technical Architecture - -### Build Process -1. **Base Layer**: Starts with Bazzite's gaming-optimized foundation -2. **Customization Layer**: Applies personal configurations and packages -3. **Distribution**: Publishes to GHCR for atomic updates - -### Key Technologies -- **Fedora Atomic**: Immutable base system with atomic updates -- **rpm-ostree**: Package layer management -- **Podman/Docker**: Container runtime and build system -- **GitHub Actions**: Automated CI/CD pipeline -- **OCI Images**: Distribution format - -## Customization Philosophy - -### Design Principles -- **Fully Featured OS**: Focus on versatility, -- **Development-Friendly**: Include essential development tools -- **Reproducible**: Declarative configuration for consistent builds -- **Personal**: Tailored to individual workflow preferences -- **** - -### Package Management Strategy -- **System Packages**: Added during build process for base image inclusion -- **User Packages**: Installed via RPM packages, flatpak, distrobox containers, or homebrew packages -- **Development Tools**: Integrated into base image for immediate availability - -## Configuration Areas - -### System Customizations -- **Desktop Environment**: GNOME with personal extensions and themes -- **Shell Configuration**: Zsh with Oh My Zsh and Powerlevel10k installed via just script from a seperate repo -- **Development Environment**: Pre-configured toolchains and editors -- **Gaming Optimizations**: Inherited from Bazzite base - -### User Experience Enhancements -- **Dotfiles Integration**: Automated personal configuration deployment -- **Theme Consistency**: Coordinated visual styling across applications -- **Workflow Optimization**: Shortcuts and automation for common tasks - -## Development Workflow -- **w**: - -### CI/CD Pipeline -- **Trigger**: Push to main branch or pull requests -- **Build**: Multi-architecture container builds -- **Test**: Validation of image integrity and functionality -- **Deploy**: Automatic publishing to GitHub Container Registry - -## Key Files and Their Purposes - -### `build_files/build.sh` -The main package installer of the configuration, defining: -- Package installations and removals -- RPM repos configuration -- asc key additions - -### `build_files/fix_opt.sh` -For packages installed to /opt: -- Fixes packages installed to opt vanishing at run-time - -### `build_files/kernel_modules.sh` -For one kernel compilied from source: -- Compiles and adds xpadneo kernel module -- Other dkms modules can added to build process later - -### `build_files/layered_appimages.sh` -As the name implies adds directly to the OS image: -- user states that he is aware that you probably shouldn't layer appimages onto OCI images but is currently adament that these appimages stay in place - -### `build_files/install_zfs.sh` -complete build process for the zfs kernel module: -- currently inactive - -### `build_files/remote_grabber.sh` -This script adds gnome-shell extenstions to OS image: -- Manages the addition, removal, and compiles the gschemas for certain extensions - -### `build_files/wine_installer.sh` -This Installs custom wine-builds from Kron4ek: -- A full script dedicated to grabbing the most recent wine version from Kron4ek/Wine-builds release page and installing it -- will add the release with this string: 'staging-tkg-ntsync-amd64-wow64' - -### `Containerfile` -Advanced container build instructions for: -- Base Image -- Multi-stage builds -- Custom optimization steps - -### `system_files/` Directory -Contains custom files added at build time: -- Probably akin to Bluebuild's 'overlay' - -## Maintenance Considerations - -### Update Strategy -- **Base Image Updates**: Automatic rebuilds when Bazzite releases updates -- **Security Updates**: Regular rebuilds for security patches -- **Feature Updates**: Manual integration of new customizations - -### Testing Approach -- **Build Verification**: Ensure successful image creation -- **Functionality Testing**: Validate key features and applications -- **Integration Testing**: Verify compatibility with upstream changes - -## Common Modification Areas - -### Adding New Packages -- Edit `build.sh` where it declares packages and corresponding repositories -- Edit `config.sh` for enabling system services - -## Current Implementation Status - -### โœ… Completed Features - -#### Default Shell Configuration -- **ZSH as System Default**: Configured for all new users via `/etc/default/useradd` -- **First-Run Automation**: SystemD service (`distinction-firstrun.service`) that: - - Triggers on first boot after rebase - - Runs `ujust distinction-install` automatically - - Creates log at `/var/DistinctionOS/DistinctionOS_firstrun.log` - - Only runs once (checks for log file existence) - -#### TPM Unlock System -- **Interactive Setup**: `ujust distinction-tpm-unlock-setup` with preset PCR configurations: - - Maximum Security (PCR 0,1,4,5,7,8,9) - - Balanced (PCR 0,4,7,9) - - Convenience (PCR 7) - - Custom selection -- **Proactive Monitoring**: `distinction-tpm-monitor` service that: - - Detects kernel, bootloader, firmware changes - - Warns BEFORE reboot when updates will break TPM - - Monitors rpm-ostree deployments - - Runs every 30 minutes via SystemD timer -- **Recovery Tools**: - - `ujust distinction-tpm-reenrol`: Quick re-enrollment - - `ujust distinction-tpm-verify`: Status check - - `ujust distinction-tpm-reset`: Complete reset with auth - - `ujust distinction-tpm-logs`: View monitor logs - -#### Just Recipe System -- **Main Recipe**: `distinction.just` with modular imports -- **Installation Recipes**: - - Flatpak installation from GitHub-hosted list - - Homebrew package management - - Oh-my-zsh with Powerlevel10k theme - - NvChad configuration for Neovim - - Nautilus scripts integration - - **TPM Management**: Separate recipe file for TPM operations - -#### Security Configuration - - **Passwordless Sudo**: Configured for wheel group (user aware of security implications) - - Located at `/etc/sudoers.d/99-distinction-wheel-nopasswd` - -### ๐Ÿšง Known Issues -- NvChad installation for root may need verification after first run -- Some just recipes need error handling improvements -- TPM re-enrollment requires manual password entry (by design for security) -- In testing System sometimes hangs at plymouth screen for a short while after system receives shutdown signal -## Maintenance Procedures - -### After System Updates -```bash -rpm-ostree upgrade -# Monitor will detect and notify about TPM changes -ujust distinction-tpm-reenrol # If notified -systemctl reboot -``` - -### TPM Management -```bash -ujust distinction-tpm-check # Check if re-enrollment needed -ujust distinction-tpm-verify # Verify current status -ujust distinction-tpm-logs # View recent activity -``` - -### Theme and Appearance -1. Add theme files to `system_files/usr/share/themes/` -2. Configure default selections in system settings -3. Test across different applications - -### User Data Management -- **Persistent Storage**: User data remains intact across image updates -- **Configuration Persistence**: Personal settings preserved in `/var/home/` -- **Application Data**: Flatpak and container app data maintained - -### Debug Approaches -- **Build Logs**: Examine GitHub Actions output for build-time issues -- **System Logs**: Use `journalctl` for runtime problem diagnosis -- **Layer Inspection**: Analyze image layers with `podman history` - -## Future Roadmap - -### Eventual Goals -- [ ] Standalone installable ISO image file (that actually works) -- [x] Rechunker support -- [ ] Ship CachyOS-lto kernel by default -- [ ] Steam icon/.desktop manager service -- [x] User uses ZSH by default โœ… (untested) -- [x] Auto-install oh-my-zsh, powerlevel10k on fresh installation โœ… (untested) -- [x] TPM auto-recovery mechanism โœ… (untested) - ---- - -## Notes for AI Assistants -Note: This project does not use BlueBuild. Some legacy scripts may not follow style conventions fully. - -### Code Style Preferences -- **Shell Scripts**: Follow Google Shell Style Guide conventions -- **YAML Files**: 2-space indentation, explicit string quoting where beneficial -- **Documentation**: Clear, concise explanations with practical examples -- **Context Generation**: At the end of a session, user will ask for an updated claude.md context file - -### Project Philosophy -- Fully-featured experience prioritized over minimalism -- Native RPM packages preferred over Flatpaks where sensible -- Elegant solutions balancing functionality with maintainability -- Proactive problem prevention over reactive fixes -- This is a personal project focused on creating an optimal Linux environment for both gaming and development work. The user values clean, maintainable configurations and appreciates detailed explanations of technical concepts. - -### User Technical Level -- Intermediate Linux system administration skills -- Comfortable with containers, package management, system configuration -- Appreciates detailed technical explanations with practical application diff --git a/docs/claude.md b/docs/claude.md new file mode 100644 index 0000000..cbe507f --- /dev/null +++ b/docs/claude.md @@ -0,0 +1,578 @@ +# Claude Context: DistinctionOS + +## Project Overview + +**DistinctionOS** is a custom immutable Linux image built upon the Bazzite foundation, leveraging Universal Blue's infrastructure and tooling. This repository represents a personalised gaming and development environment optimised for a fully-featured experience. + +### Key Characteristics +- **Base System**: Bazzite (gaming-focused Fedora Atomic variant) +- **Build System**: Built from Universal Blue's GitHub image template using GitHub Actions to build & push to GHCR +- **Target Audience**: Primarily personal use, with gaming and development focus +- **Deployment**: OCI container images via GitHub Container Registry +- **Philosophy**: "Swiss Army Knife" approach - versatile powerhouse over minimalism +- **Code Quality**: Professional-grade with standardized logging, comprehensive error handling, and utility function library + +## Repository Structure + +``` +DistinctionOS/ +โ”œโ”€โ”€ build-files/ # Build-time execution scripts (numerically ordered) +โ”‚ โ”œโ”€โ”€ 01-build.sh # Package management (RPM, repos, keys) - FIRST +โ”‚ โ”œโ”€โ”€ 02-install-zfs.sh # ZFS package installation - SECOND +โ”‚ โ”œโ”€โ”€ 03-fix-opt.sh # /opt persistence configuration - THIRD +โ”‚ โ”œโ”€โ”€ 04-config.sh # System services and misc config - FOURTH +โ”‚ โ”œโ”€โ”€ 05-kernel-modules.sh # xpadneo & ZFS DKMS compilation - FIFTH +โ”‚ โ”œโ”€โ”€ 06-remote-grabber.sh # GNOME Shell extension management - SIXTH (FINAL) +โ”‚ โ”œโ”€โ”€ 95-utility-functions.sh # Shared utility functions library - SOURCED BY ALL +โ”‚ โ””โ”€โ”€ wine-installer.sh # Custom Wine builds (INACTIVE - not in build sequence) +โ”‚ +โ”œโ”€โ”€ system-files/ # Static files copied into the image +โ”‚ โ”œโ”€โ”€ usr/ +โ”‚ โ”‚ โ”œโ”€โ”€ bin/ # Custom executables (firstrun, tpm-monitor, advmv, advcp) +โ”‚ โ”‚ โ”œโ”€โ”€ lib/systemd/ # SystemD services and timers +โ”‚ โ”‚ โ””โ”€โ”€ share/DistinctionOS/just/ # Just recipes +โ”‚ โ””โ”€โ”€ etc/ +โ”‚ โ””โ”€โ”€ sudoers.d/ # Sudo configuration +โ”‚ +โ”œโ”€โ”€ repo-files/ # Resources for just recipes (hosted on GitHub) +โ”‚ โ”œโ”€โ”€ brews # Homebrew package list (for post-install) +โ”‚ โ””โ”€โ”€ flatpaks # Flatpak application list (for post-install) +โ”‚ +โ”œโ”€โ”€ disk-config/ # Configuration for bootable disk creation +โ”‚ โ”œโ”€โ”€ disk.toml # QCOW2/RAW VM disk configuration +โ”‚ โ””โ”€โ”€ iso.toml # ISO installer configuration +โ”‚ +โ”œโ”€โ”€ docs/ # Project documentation +โ”‚ โ”œโ”€โ”€ claude.md # This file - AI assistant context +โ”‚ โ”œโ”€โ”€ developer.md # Comprehensive developer documentation +โ”‚ โ””โ”€โ”€ (planned: wine.md, planning.md) +โ”‚ +โ”œโ”€โ”€ Containerfile # Custom container build instructions +โ”œโ”€โ”€ Justfile # Local development tooling (build, test, lint) +โ”œโ”€โ”€ cosign.pub # Image signing public key +โ””โ”€โ”€ .github/workflows/ # GitHub Actions (build.yml & build-disk.yml) +``` + +## Technical Architecture + +### Build Process Overview +1. **Base Layer**: Starts with Bazzite's gaming-optimized foundation +2. **Customization Layer**: Applies personal configurations and packages via numbered build scripts +3. **Distribution**: Publishes to GHCR for atomic updates with Rechunker optimization + +### Build Script Execution Order + +**CRITICAL**: Scripts execute in numerical order (01 โ†’ 06), with 95-utility-functions.sh sourced by all scripts. + +``` +Containerfile Execution: + โ”‚ + โ”œโ”€โ†’ COPY system-files/ โ†’ / + โ”‚ + โ”œโ”€โ†’ 01-build.sh + โ”‚ โ”œโ”€ Source utility-functions.sh + โ”‚ โ”œโ”€ Remove unwanted Bazzite packages + โ”‚ โ”œโ”€ Configure repositories (Cider, COPR, etc.) + โ”‚ โ”œโ”€ Install RPM packages by repository + โ”‚ โ”œโ”€ Version-lock Wine + โ”‚ โ”œโ”€ Install CrossOver and themes + โ”‚ โ””โ”€ Validate critical packages + โ”‚ + โ”œโ”€โ†’ 02-install-zfs.sh + โ”‚ โ”œโ”€ Source utility-functions.sh + โ”‚ โ”œโ”€ Install ZFS repository + โ”‚ โ””โ”€ Install ZFS packages (DKMS compilation happens later) + โ”‚ + โ”œโ”€โ†’ 03-fix-opt.sh + โ”‚ โ”œโ”€ Source utility-functions.sh + โ”‚ โ”œโ”€ Scan /var/opt directory + โ”‚ โ”œโ”€ Move directories to /usr/lib/opt + โ”‚ โ””โ”€ Generate tmpfiles.d config for runtime persistence + โ”‚ + โ”œโ”€โ†’ 04-config.sh + โ”‚ โ”œโ”€ Source utility-functions.sh + โ”‚ โ”œโ”€ Configure default shell (ZSH) + โ”‚ โ”œโ”€ Setup SystemD services (currently disabled) + โ”‚ โ”œโ”€ Integrate Just recipes + โ”‚ โ”œโ”€ Hide incompatible Bazzite recipes + โ”‚ โ”œโ”€ Customize applications (Cider, Winetricks) + โ”‚ โ”œโ”€ Update system caches + โ”‚ โ””โ”€ Remove unwanted files (Waydroid, Wine utilities, Bazzite remnants) + โ”‚ + โ”œโ”€โ†’ 05-kernel-modules.sh + โ”‚ โ”œโ”€ Source utility-functions.sh + โ”‚ โ”œโ”€ Detect Bazzite kernel version + โ”‚ โ”œโ”€ Clone & compile xpadneo module + โ”‚ โ”œโ”€ Verify module installation + โ”‚ โ”œโ”€ Run DKMS autoinstall (compiles ZFS + xpadneo) + โ”‚ โ””โ”€ Regenerate initramfs with new modules + โ”‚ + โ””โ”€โ†’ 06-remote-grabber.sh + โ”œโ”€ Source utility-functions.sh + โ”œโ”€ Download GNOME Shell extensions + โ””โ”€ Compile gschemas for extensions +``` + +### Key Technologies +- **Fedora Atomic**: Immutable base system with atomic updates +- **rpm-ostree**: Package layer management (runtime) +- **dnf5**: Package management (build-time) +- **Podman/Buildah**: Container runtime and build system +- **GitHub Actions**: Automated CI/CD pipeline +- **OCI Images**: Distribution format +- **Rechunker**: Layer optimization for efficient updates + +## Customization Philosophy + +### Design Principles +- **Fully Featured OS**: Focus on versatility and completeness +- **Development-Friendly**: Include essential development tools +- **Reproducible**: Declarative configuration for consistent builds +- **Personal**: Tailored to individual workflow preferences +- **Professional Quality**: Industry-standard code practices, comprehensive documentation +- **Maintainable**: DRY principle, utility function library, standardized patterns + +### Package Management Strategy +- **System Packages (Build-time)**: Added during build via dnf5 for base image inclusion +- **User Packages (Runtime)**: Installed via Flatpak, Homebrew, or distrobox containers +- **Development Tools**: Integrated into base image for immediate availability + +## Configuration Areas + +### System Customizations +- **Desktop Environment**: GNOME with personal extensions and themes +- **Shell Configuration**: ZSH with Oh My Zsh and Powerlevel10k (installed via just recipe post-rebase) +- **Development Environment**: Pre-configured toolchains and editors +- **Gaming Optimizations**: Inherited from Bazzite base + xpadneo for Xbox controllers + +### User Experience Enhancements +- **Dotfiles Integration**: Automated personal configuration deployment +- **Theme Consistency**: Kora icon theme, coordinated visual styling +- **Workflow Optimization**: Shortcuts and automation for common tasks +- **First-Run Automation**: SystemD service runs ujust distinction-install on first boot + +## Development Workflow + +### CI/CD Pipeline +- **Trigger**: Push to main branch, pull requests, scheduled (every 5 days), or manual dispatch +- **Build**: Multi-stage container build with Buildah +- **Rechunker**: Layer optimization for efficient updates +- **Test**: Validation of image integrity +- **Sign**: Cosign image signing +- **Deploy**: Automatic publishing to GitHub Container Registry + +### Local Development +```bash +# Build locally +just build + +# Build and test in VM +just build-qcow2 +just run-vm-qcow2 + +# Lint and format shell scripts +just lint +just format + +# Clean build artifacts +just clean +``` + +## Key Files and Their Purposes + +### Build Scripts (Executed at Build-Time) + +#### `01-build.sh` - Package Management & Repository Configuration +**Purpose**: Core package installation, repository setup, package removal +**Key Features**: +- Color-coded logging with validation +- Organized package installation by repository (associative array) +- HEIF/Glycin workaround for image rendering +- Wine version-locking +- Critical package validation +- CrossOver and theme installation from GitHub releases + +**When to Edit**: +- Adding new RPM packages +- Adding/removing repositories +- Modifying package removal list +- Updating version locks + +#### `02-install-zfs.sh` - ZFS Package Installation +**Purpose**: Install ZFS packages for later DKMS compilation +**Key Features**: +- Minimal, concise design +- Repository configuration +- Package installation only (compilation happens in 05-kernel-modules.sh) + +**When to Edit**: +- Updating ZFS repository URL +- Changing ZFS version + +**Note**: Can be disabled by commenting out in Containerfile during rapid development to speed builds. + +#### `03-fix-opt.sh` - /opt Directory Persistence +**Purpose**: Ensure packages in /opt persist across reboots +**Key Features**: +- Dynamically scans /var/opt +- Generates tmpfiles.d configuration +- Executed at runtime by systemd-tmpfiles + +**Technical Background**: On immutable systems, /opt can be ephemeral. This creates symlinks from /var/opt to /usr/lib/opt, ensuring packages like Brave Browser and CrossOver remain accessible. + +**When to Edit**: Rarely needed - automatically handles all /opt packages. + +#### `04-config.sh` - System Configuration & Cleanup +**Purpose**: System service config, application customization, file cleanup +**Key Features**: +- Six major organized sections +- Shell configuration (ZSH default) +- Just recipe integration +- Application .desktop file modifications +- System cache updates +- Cleanup of unwanted files (documented reasons for each) + +**When to Edit**: +- Enabling/disabling SystemD services +- Adding Just recipe customizations +- Customizing application behavior +- Adding files to cleanup lists + +#### `05-kernel-modules.sh` - Kernel Module Compilation +**Purpose**: Compile xpadneo module and run DKMS autoinstall +**Key Features**: +- Kernel version detection +- Custom makefile generation for ostree compatibility +- Module compilation and verification +- DKMS autoinstall (compiles both xpadneo and ZFS) +- Initramfs regeneration with secure permissions + +**When to Edit**: +- Adding new kernel modules +- Modifying xpadneo compilation parameters + +**Note**: Custom makefile is critical for ostree systems - do not modify heredoc section. + +#### `06-remote-grabber.sh` - GNOME Extension Management +**Purpose**: Install and configure GNOME Shell extensions system-wide +**Key Features**: +- Extension download and installation +- Gschema compilation +- System-wide enablement + +**When to Edit**: +- Adding/removing GNOME Shell extensions +- Updating extension sources + +#### `95-utility-functions.sh` - Shared Utility Library +**Purpose**: Centralized functions and constants for all build scripts +**Key Features**: +- 8 ANSI color codes +- 6 logging functions (header, section, success, warning, error, info) +- Debug tracing functions +- Package validation functions +- File management helpers +- Command execution wrappers +- Counter utilities +- System information helpers +- Script lifecycle functions + +**Usage**: `source /ctx/utility-functions.sh` at the start of every build script + +**Benefits**: +- Eliminates ~300 lines of code duplication across scripts +- Single source of truth for logging behavior +- Consistent formatting and error handling +- Enhanced functionality (25+ utility functions) +- Easier maintenance (change once, affects all scripts) + +**When to Edit**: +- Modifying logging format/behavior globally +- Adding new shared utility functions +- Changing color scheme +- Adding new validation patterns + +**CRITICAL**: Changes affect ALL build scripts - test thoroughly! + +#### `wine-installer.sh` - Custom Wine Build Installation (INACTIVE) +**Purpose**: Install Kron4ek Wine builds with specific features +**Status**: Currently inactive, not in build sequence +**When Active**: Installs wine-staging-tkg-ntsync-amd64-wow64 from GitHub releases + +**Note**: Remains separate from numbered sequence as it's intermittently used. + +### `Containerfile` - Container Build Instructions +**Purpose**: Define the multi-stage build process +**Key Features**: +- Base image selection (Bazzite GNOME) +- Build context layer for script access +- system-files overlay copy +- Sequential script execution (01-06) +- Color-coded build progress output +- OSTree container commit + +**When to Edit**: +- Changing base image +- Modifying script execution order (rare) +- Enabling/disabling scripts (comment out execution line) +- Adjusting build optimizations + +### `system-files/` Directory +Contains custom files added at build time (akin to BlueBuild's 'overlay'): +- **usr/bin/**: Custom executables (firstrun, tpm-monitor, advmv, advcp) +- **usr/lib/systemd/**: SystemD units and timers (distinction-firstrun, tpm-monitor) +- **usr/share/DistinctionOS/just/**: Just recipes (distinction.just, tpm.just) +- **etc/sudoers.d/**: Passwordless sudo configuration (user aware of security implications) + +## Maintenance Considerations + +### Update Strategy +- **Base Image Updates**: Automatic rebuilds when Bazzite releases updates (every 5 days scheduled) +- **Security Updates**: Regular rebuilds for security patches +- **Feature Updates**: Manual integration of new customizations via feature branches + +### Testing Approach +- **Local Testing**: `just build` โ†’ `just run-vm-qcow2` for VM validation +- **Build Verification**: GitHub Actions logs for build-time issues +- **Functionality Testing**: Validate key features in VM before merge +- **Integration Testing**: Verify compatibility with upstream Bazzite changes + +### Debug Approaches +- **Build Logs**: Examine GitHub Actions output for build-time issues (color-coded logging) +- **System Logs**: Use `journalctl` for runtime problem diagnosis +- **Layer Inspection**: Analyze image layers with `podman history` +- **Local Debugging**: `podman run -it localhost/distinctionos:test /bin/bash` + +## Current Implementation Status + +### โœ… Completed Features + +#### Build System (2025-10-27 Major Refactoring) +- **Utility Functions Library**: Centralized logging, validation, and helper functions +- **Color-Coded Logging**: Consistent visual feedback across all build scripts +- **Comprehensive Error Handling**: Validation, error reporting, graceful degradation +- **Professional Code Quality**: DRY principle, documentation standards, consistent patterns +- **Script Organization**: Numerically ordered execution (01-06) + +#### Default Shell Configuration +- **ZSH as System Default**: Configured for all new users via `/etc/default/useradd` +- **Root Shell**: ZSH configured for root user +- **First-Run Automation**: SystemD service (`distinction-firstrun.service`) that: + - Triggers on first boot after rebase + - Runs `ujust distinction-install` automatically + - Creates log at `/var/DistinctionOS/DistinctionOS_firstrun.log` + - Only runs once (checks for log file existence) + +#### TPM Unlock System +- **Interactive Setup**: `ujust distinction-tpm-unlock-setup` with preset PCR configurations: + - Maximum Security (PCR 0,1,4,5,7,8,9) + - Balanced (PCR 0,4,7,9) + - Convenience (PCR 7) + - Custom selection +- **Proactive Monitoring**: `distinction-tpm-monitor` service that: + - Detects kernel, bootloader, firmware changes + - Warns BEFORE reboot when updates will break TPM + - Monitors rpm-ostree deployments + - Runs every 30 minutes via SystemD timer +- **Recovery Tools**: + - `ujust distinction-tpm-reenrol`: Quick re-enrollment + - `ujust distinction-tpm-verify`: Status check + - `ujust distinction-tpm-reset`: Complete reset with auth + - `ujust distinction-tpm-logs`: View monitor logs + +#### Just Recipe System +- **Main Recipe**: `distinction.just` with modular imports +- **Installation Recipes**: + - Flatpak installation from GitHub-hosted list + - Homebrew package management + - Oh-my-zsh with Powerlevel10k theme + - NvChad configuration for Neovim + - Nautilus scripts integration +- **TPM Management**: Separate recipe file for TPM operations + +#### Security Configuration +- **Passwordless Sudo**: Configured for wheel group (user aware of security implications) +- Located at `/etc/sudoers.d/99-distinction-wheel-nopasswd` + +### ๐Ÿšง Known Issues +- **NvChad root installation**: May need verification after first run (`sudo nvim` to complete) +- **TPM re-enrollment**: Requires manual password entry (by design for security) +- **Plymouth hang**: System occasionally hangs briefly at Plymouth screen after shutdown signal (cosmetic, under investigation) +- **Build time**: ZFS compilation adds ~10-15 minutes (acceptable as system matures) + +## Maintenance Procedures + +### After System Updates +```bash +rpm-ostree upgrade +# TPM monitor will detect and notify about changes +ujust distinction-tpm-reenrol # If notified +systemctl reboot +``` + +### TPM Management +```bash +ujust distinction-tpm-check # Check if re-enrollment needed +ujust distinction-tpm-verify # Verify current status +ujust distinction-tpm-logs # View recent activity +``` + +### Adding Packages + +#### Build-Time Packages (in the image) +Edit `01-build.sh`: +```bash +declare -A RPM_PACKAGES=( + ["fedora"]="existing-packages new-package" + ["copr:user/repo"]="copr-package" +) +``` + +#### Runtime Packages (post-install) +- **Flatpaks**: Add to `repo-files/flatpaks` on GitHub +- **Homebrews**: Add to `repo-files/brews` on GitHub +- Run: `ujust distinction-install` or specific recipe + +### Modifying Build Scripts +1. Edit appropriate numbered script (01-06) +2. Maintain logging patterns using utility functions +3. Test locally: `just build` +4. Commit to feature branch +5. Create pull request for CI/CD validation +6. Merge after successful build + +## Future Roadmap + +### Short-Term Goals (1-3 months) +- [ ] Apply utility function patterns to system-files/ shell scripts +- [ ] Create `wine.md` documentation for Wine installation process +- [ ] Enhanced build time optimization strategies +- [ ] Comprehensive testing suite for Just recipes + +### Long-Term Goals (6-12 months) +- [ ] **Standalone ISO**: Fully functional installer ISO (in progress via build-disk.yml) +- [ ] **CachyOS-LTO Kernel**: Ship optimized kernel by default +- [ ] **Steam Icon Manager**: Automated service for managing Steam game shortcuts +- [ ] **Extended TPM Recovery**: Fully automated re-enrollment without password prompt +- [ ] **Build Caching**: Implement layer caching for faster iteration + +### Completed Goals โœ… +- Rechunker support for efficient updates +- ZSH as default shell with automated configuration +- Oh-my-zsh and Powerlevel10k automatic installation +- TPM auto-unlock with proactive monitoring system +- **Build Script Refactoring** (2025-10-27): + - Complete overhaul of all build scripts + - Utility functions library implementation + - Color-coded logging system + - Comprehensive error handling + - Professional code quality standards + - ~300 lines of duplication eliminated + +## Notes for AI Assistants + +### Code Style Preferences +- **Shell Scripts**: Follow Google Shell Style Guide conventions +- **Utility Functions**: Always source `/ctx/utility-functions.sh` in build scripts +- **Logging**: Use utility function logging (log_header, log_section, log_success, etc.) +- **Error Handling**: Use utility wrappers (run_with_log, check_file_exists, etc.) +- **Validation**: Use validation functions (validate_critical_packages, etc.) +- **YAML Files**: 2-space indentation, explicit string quoting where beneficial +- **Documentation**: Clear, concise explanations with practical examples +- **Context Generation**: At end of session, update claude.md and developer.md + +### Project Philosophy +- Fully-featured experience prioritized over minimalism +- Native RPM packages preferred over Flatpaks where sensible +- Elegant solutions balancing functionality with maintainability +- Proactive problem prevention over reactive fixes +- Professional code quality with comprehensive documentation +- DRY principle - don't repeat yourself +- This is a personal project focused on creating an optimal Linux environment for both gaming and development work + +### Build Script Development Guidelines + +#### When Creating/Modifying Build Scripts: +1. **Always source utility functions first**: `source /ctx/utility-functions.sh` +2. **Use consistent logging**: log_header โ†’ log_section โ†’ log_success/error/warning +3. **Validate critical operations**: Use validation functions for important packages/files +4. **Document WHY, not just WHAT**: Inline comments should explain rationale +5. **Follow the established pattern**: Look at existing scripts for reference +6. **Test locally first**: `just build` before committing +7. **Use helper functions**: Take advantage of utility functions library (30+ functions) + +#### Script Structure Template: +```bash +#!/usr/bin/bash +set -euo pipefail + +# ============================================================================ +# Script Name +# ============================================================================ +# Purpose: Brief description +# Execution: Position in sequence +# ============================================================================ + +source /ctx/utility-functions.sh + +script_start "Script Name" "Brief description" + +log_section "Major operation" +# ... operations with logging ... +log_success "Operation complete" + +script_complete "Script Name" "Next step: ..." +exit 0 +``` + +### Important Distinctions + +#### Build-Time vs Runtime: +- **Build-Time**: Scripts in build-files/ execute during image creation + - Use `dnf5` for package management + - Use utility functions for logging/validation + - Changes require rebuild + - Files go into /usr (immutable) + +- **Runtime**: User operations after rebase + - Use `rpm-ostree` for system packages + - Use `flatpak` or `brew` for user packages + - Use `ujust` recipes for automation + - Changes persist in /var or /home + +#### Directory Naming: +- **Filesystem**: Still uses `build_files/` and `system_files/` (underscores) +- **Documentation**: References `build-files/` and `system-files/` (hyphens) for consistency +- **Future**: Will be renamed to match documentation + +### User Technical Level +- Intermediate Linux system administration skills +- Comfortable with containers, package management, system configuration +- Appreciates detailed technical explanations with practical application +- Values clean, maintainable code with comprehensive documentation +- Prefers professional-grade solutions over quick hacks + +### When Generating Context Updates +At the end of a session, user will request updated context files: +- **claude.md**: Comprehensive overview for AI assistants (this file) +- **developer.md**: Detailed technical documentation for human developers +- Include all architectural changes, new features, and rationale +- Update roadmap and completed goals +- Reflect current state accurately + +--- + +## Document Metadata + +**Version**: 3.0 +**Last Updated**: 2025-10-27 +**Major Changes**: +- Complete build script refactoring documentation +- Utility functions library implementation +- Script renaming to numerical order (01-06, 95) +- Enhanced code quality standards +- Comprehensive error handling patterns +- ~300 lines of duplication eliminated + +**Maintainer**: phantomcortex +**Purpose**: Provide comprehensive context to AI assistants working with DistinctionOS diff --git a/docs/developer.md b/docs/developer.md new file mode 100644 index 0000000..9055e3a --- /dev/null +++ b/docs/developer.md @@ -0,0 +1,865 @@ +# DistinctionOS Developer Documentation + +## Current Status + +**Build System**: Fully operational with automated CI/CD via GitHub Actions +**Base System**: Bazzite (Fedora Atomic Desktop) +**Last Updated**: 2025-10-27 +**Stability**: Maturing - ZFS module enabled by default +**Recent Changes**: Complete build script refactoring with enhanced logging and documentation + +### Active Features +- Automated image builds every 5 days +- Rechunker optimization for efficient updates +- Image signing with Cosign +- TPM auto-unlock system with monitoring +- First-run automation for post-rebase setup +- ZSH as default shell with automated configuration +- Just recipe system for user-space tooling + +### Build Configuration +- **Image Registry**: `ghcr.io` +- **Default Tag**: `latest` +- **Build Frequency**: Every 5 days (scheduled) + on-demand +- **Build Platform**: Ubuntu 24.04 (GitHub Actions) + +--- + +## Repository Structure + +### Directory Layout (Post-Cleanup) + +``` +DistinctionOS/ +โ”œโ”€โ”€ build-files/ # Build-time execution scripts +โ”‚ โ”œโ”€โ”€ 01-build.sh # Package management (RPM, repos, keys) +โ”‚ โ”œโ”€โ”€ 02-install-zfs.sh # ZFS kernel module compilation +โ”‚ โ”œโ”€โ”€ 03-fix-opt.sh # /opt persistence configuration +โ”‚ โ”œโ”€โ”€ 04-config.sh # System services and misc config +โ”‚ โ”œโ”€โ”€ 05-kernel-modules.sh # xpadneo kernel module compilation +โ”‚ โ”œโ”€โ”€ 06-remote-grabber.sh # GNOME Shell extension management +โ”‚ โ”œโ”€โ”€ remote-grabber.sh # (inactive) +โ”‚ โ””โ”€โ”€ 95-kernel-modules.sh # logging functions & color codes +โ”‚ +โ”œโ”€โ”€ system-files/ # Static files overlaid onto the image +โ”‚ โ”œโ”€โ”€ usr/ +โ”‚ โ”‚ โ”œโ”€โ”€ bin/ # Custom executables +โ”‚ โ”‚ โ”œโ”€โ”€ lib/systemd/ # SystemD units and timers +โ”‚ โ”‚ โ””โ”€โ”€ share/DistinctionOS/just/ # Just recipes +โ”‚ โ””โ”€โ”€ etc/ +โ”‚ โ””โ”€โ”€ sudoers.d/ # Sudo configuration +โ”‚ +โ”œโ”€โ”€ repo-files/ # Package manifest lists +โ”‚ โ”œโ”€โ”€ brews # Homebrew package list +โ”‚ โ””โ”€โ”€ flatpaks # Flatpak application list +โ”‚ +โ”œโ”€โ”€ disk-config/ # Bootable disk configuration +โ”‚ โ”œโ”€โ”€ disk.toml # QCOW2/RAW configuration +โ”‚ โ””โ”€โ”€ iso.toml # ISO installer configuration +โ”‚ +โ”œโ”€โ”€ docs/ # Project documentation +โ”‚ โ”œโ”€โ”€ developer.md # This file +โ”‚ โ”œโ”€โ”€ claude.md # AI assistant context +โ”‚ โ””โ”€โ”€ (future: wine.md, planning.md, etc.) +โ”‚ +โ”œโ”€โ”€ .github/workflows/ # CI/CD automation +โ”‚ โ”œโ”€โ”€ build.yml # Main image build workflow +โ”‚ โ””โ”€โ”€ build-disk.yml # Bootable disk creation +โ”‚ +โ”œโ”€โ”€ Containerfile # Image build instructions +โ”œโ”€โ”€ Justfile # Local development tooling +โ”œโ”€โ”€ cosign.pub # Image signing public key +โ””โ”€โ”€ README.md # Project overview +``` + +--- + +## Build Process Architecture + +### Overview + +DistinctionOS employs a multi-stage build process that transforms a base Bazzite image into a fully customized, production-ready system. The build occurs in two primary contexts: + +1. **Build-Time**: Image layer construction via `Containerfile` and build scripts +2. **Runtime**: Post-rebase user configuration via Just recipes and systemd services + +### Build Script Execution Flow + +```mermaid +flowchart TD + Start([Containerfile Execution]) --> Copy[Copy system-files overlay] + Copy --> B1[1. build.sh] + + B1 --> B1A[Add RPM repositories] + B1A --> B1B[Import GPG keys] + B1B --> B1C[Install/remove RPM packages] + B1C --> B1D[Validate critical packages] + B1D --> B2 + + B2[2. install-zfs.sh] --> B2A[Install ZFS repository] + B2A --> B2B[Install ZFS packages] + B2B --> B3 + + B3[3. fix-opt.sh] --> B3A[Scan /opt directory] + B3A --> B3B[Generate tmpfiles.d config] + B3B --> B3C[Ensure /opt persistence] + B3C --> B4 + + B4[4. config.sh] --> B4A[Configure default shell] + B4A --> B4B[Setup Just recipes] + B4B --> B4C[Customize applications] + B4C --> B4D[Update system caches] + B4D --> B4E[Remove unwanted files] + B4E --> B5 + + B5[5. kernel-modules.sh] --> B5A[Detect kernel version] + B5A --> B5B[Compile xpadneo module] + B5B --> B5C[Regenerate initramfs] + B5C --> B6 + + B6[6. remote-grabber.sh] --> B6A[Download GNOME Shell extensions] + B6A --> B6B[Compile gschemas] + B6B --> Finish + + Finish([Image Complete]) --> Push[Push to GHCR] + + style Start fill:#4a9eff + style Finish fill:#4caf50 + style Push fill:#ff9800 +``` + +### GitHub Actions Workflow Execution + +```mermaid +flowchart TD + Trigger{Trigger Event} --> |Push to main| Build + Trigger --> |Pull Request| Build + Trigger --> |Schedule: Every 5 days| Build + Trigger --> |Manual Dispatch| Build + + Build[Checkout Repository] --> Env[Prepare Environment] + Env --> Meta[Generate Image Metadata] + Meta --> Space[Maximize Build Space] + + Space --> BuildImg[Build Image with Buildah] + BuildImg --> |Rootful podman| Clean[Remove Source Images] + + Clean --> Rechunk[Run Rechunker Optimization] + Rechunk --> |Efficient layer compression| RechunkClean[Remove Rechunker Image] + + RechunkClean --> Load[Load and Tag Image] + Load --> Login{Is Pull Request?} + + Login --> |No| Push[Push to GHCR] + Login --> |Yes| Skip[Skip Push] + + Push --> Sign[Sign with Cosign] + Sign --> Done[Complete] + Skip --> Done + + style Trigger fill:#9c27b0 + style BuildImg fill:#2196f3 + style Rechunk fill:#ff9800 + style Sign fill:#4caf50 + style Done fill:#4caf50 +``` + +### Post-Rebase Runtime Flow + +```mermaid +flowchart TD + Rebase[User Rebases to DistinctionOS] --> FirstBoot{First Boot?} + + FirstBoot --> |Yes| Service[distinction-firstrun.service] + FirstBoot --> |No| Normal[Normal Boot] + + Service --> Install[ujust distinction-install] + + Install --> Flat[Install Flatpaks from remote list] + Flat --> Brew[Install Homebrew packages] + Brew --> Shell[Configure ZSH + Dotfiles] + Shell --> NvChad[Install NvChad for Neovim] + + NvChad --> Log[Create log at /var/DistinctionOS/] + Log --> Normal + + Normal --> TPM[TPM Monitor Timer] + TPM --> |Every 30 minutes| Check[Check for bootloader/kernel changes] + Check --> |Changes detected| Warn[Notify user before reboot] + Check --> |No changes| Continue[Continue normally] + + style Rebase fill:#4a9eff + style Service fill:#ff9800 + style Install fill:#2196f3 + style TPM fill:#4caf50 + style Warn fill:#f44336 +``` + +--- + +## Script Detailed Reference + +### 1. `01-build.sh` +**Purpose**: Core package management and repository configuration +**Execution Stage**: Build-time (first script) +**Key Functions**: +- Add/remove RPM repositories (e.g., Brave, Cider, COPR repos) +- Import GPG/ASC keys for package verification +- Remove unwanted packages from base image +- Validate critical package installation +- Package versionlock section + +**Enhanced Features** (2025-10-27 Refactoring): +- Color-coded logging with visual indicators (โœ“, โœ—, โš , โ„น, โ–ถ) +- Package validation to catch installation failures +- Comprehensive error handling with clear messages +- Organized package installation by repository +- Theme installation from GitHub releases + +--- + +### 2. `02-install-zfs.sh` +**Purpose**: Install ZFS filesystem driver and prepare for DKMS compilation +**Execution Stage**: Build-time (second script) +**Status**: Currently active (intermittently disabled during rapid development to speed up builds) +**Key Functions**: +- Install ZFS repository +- Install ZFS packages +- Note: DKMS compilation handled by `05-kernel-modules.sh` + +**Enhanced Features** (2025-10-27 Refactoring): +- Minimal color-coded logging for consistency +- Clean, concise structure (~35 lines total) +- Clear indication that DKMS happens later + +--- + +### 3. `03-fix-opt.sh` +**Purpose**: Ensure `/opt` directory persistence across reboots +**Execution Stage**: Build-time (third script) +**Mechanism**: Creates systemd tmpfiles.d configuration +**Key Functions**: +- Dynamically scans `/var/opt` directory at build time +- Moves directories to `/usr/lib/opt` +- Generates `/usr/lib/tmpfiles.d/distinction-opt-fix.conf` +- Configuration executed at runtime by systemd-tmpfiles + +**Enhanced Features** (2025-10-27 Refactoring): +- Minimal color-coded logging for consistency +- Clean structure (~45 lines total) +- Clear informational notes about persistence mechanism + +**Technical Background**: +On immutable systems, `/opt` can be ephemeral. The tmpfiles.d configuration ensures that packages installed to `/opt` (like Brave Browser, CrossOver) remain accessible after reboot by creating symlinks from `/var/opt` to `/usr/lib/opt`. + +**Example Generated Config**: +```ini +# Generated by fix-opt.sh +L+ /var/opt/brave-browser - - - - /usr/lib/opt/brave-browser +L+ /var/opt/crossover - - - - /usr/lib/opt/crossover +``` + +--- + +### 4. `04-config.sh` +**Purpose**: System service configuration, application customization, and cleanup +**Execution Stage**: Build-time (fourth script) +**Key Functions**: +- Configure default shell (ZSH for new users and root) +- Setup SystemD services (currently disabled during testing) +- Integrate Just recipes and hide incompatible Bazzite recipes +- Customize application .desktop files (Cider icon, Winetricks debug suppression) +- Update system caches (icon, desktop, glib schemas, MIME) +- Remove unwanted application shortcuts (Waydroid, Wine utilities) +- Cleanup Bazzite remnants + +**Enhanced Features** (2025-10-27 Refactoring): +- Complete reorganization into six major sections +- Comprehensive color-coded logging throughout +- Associative array for Bazzite file removal with documented reasons +- Counters for removal operations with clear summaries +- Extensive inline documentation explaining WHY operations are performed +- Visual subsection separators for related tasks +- Configuration summary at completion + +**Major Sections**: +1. Shell Configuration +2. SystemD Service Configuration +3. Just Recipe Integration +4. Application Customization +5. System Cache Updates +6. Cleanup (Applications & Bazzite Remnants) + +**Common Tasks**: +```bash +# Enable a service +systemctl enable service-name.service + +# Disable a service +systemctl disable unwanted-service.service + +# Mask a service (prevent activation) +systemctl mask problematic-service.service + +# Add files to cleanup with documented reasons +declare -A CLEANUP_FILES=( + ["/path/to/file"]="Reason for removal" +) +``` + +--- + +### 5. `05-kernel-modules.sh` +**Purpose**: Compile xpadneo kernel module for enhanced Xbox controller support and regenerate initramfs +**Execution Stage**: Build-time (fifth script) +**Key Functions**: +- Detect installed Bazzite kernel version +- Clone xpadneo repository from GitHub +- Generate custom makefile for ostree compatibility +- Compile xpadneo kernel module +- Install module to kernel directories +- Verify module installation +- Regenerate initramfs with new modules (includes ZFS if installed) + +**Enhanced Features** (2025-10-27 Refactoring): +- Complete color-coded logging system +- Kernel detection validation +- Repository clone verification +- Installation verification with specific file location reporting +- Initramfs regeneration with validation +- Summary of installed modules at completion + +**Technical Notes**: +- Custom makefile required for ostree/immutable systems +- Makefile heredoc preserved exactly as needed for compatibility +- Handles both xpadneo and ZFS DKMS compilation +- Sets secure permissions (0600) on initramfs + +**Future TODOs**: +- Integrate CachyOS-LTO kernel as default +- Investigate kmod package installation after initramfs regeneration +- Consider packaged xpadneo variant if available +- Fix SecureBoot + +--- + +### 6. 06-remote-grabber.sh +**Purpose**: Manage GNOME Shell extensions in the system image +**Key Functions**: +- Download specified GNOME Shell extensions +- Compile gschemas for extensions +- Enable extensions system-wide + +**Advantages**: +- Extensions available immediately after installation +- No manual installation required +- Version control for extension consistency + +--- + +## Code Quality & Logging Standards + +### Logging System (Established 2025-10-27) + +All build scripts now follow a standardized color-coded logging system for consistent, readable output during builds. + +#### Logging Functions + +```bash +# ANSI color codes (defined in each script) +readonly COLOR_RESET='\033[0m' +readonly COLOR_RED='\033[31m' +readonly COLOR_GREEN='\033[32m' +readonly COLOR_YELLOW='\033[33m' +readonly COLOR_BLUE='\033[34m' +readonly COLOR_MAGENTA='\033[35m' +readonly COLOR_CYAN='\033[36m' + +# Logging function templates +log_header() # Blue box-drawing characters for major sections +log_section() # Cyan arrows (โ–ถ) for subsections +log_success() # Green checkmarks (โœ“) for successful operations +log_warning() # Yellow warnings (โš ) for non-critical issues +log_error() # Red X marks (โœ—) for errors +log_info() # Magenta info symbols (โ„น) for informational messages +``` + +#### Color Coding Standards + +| Color | Symbol | Purpose | Usage Example | +|-------|--------|---------|---------------| +| **Blue** | โ•”โ•โ•โ•โ•— | Major section headers | Script start/completion | +| **Cyan** | โ–ถ | Subsection starts | "Installing packages" | +| **Green** | โœ“ | Success messages | "Package installed successfully" | +| **Yellow** | โš  | Warnings (non-critical) | "Some packages may have failed" | +| **Red** | โœ— | Errors (critical) | "Critical package missing" | +| **Magenta** | โ„น | Informational messages | "Current version locks" | + +#### Visual Output Example + +``` +โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— +โ•‘ DistinctionOS Package Installation & Configuration +โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + +โ–ถ Installing packages from configured repositories +โ„น Installing from fedora: yt-dlp zsh neovim... +โœ“ Installed packages from fedora + +โ–ถ Validating critical package installation +โœ“ All critical packages validated + +โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— +โ•‘ Package installation phase complete +โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• +``` + +### Code Quality Guidelines + +#### Script Structure + +All build scripts should follow this structure: + +1. **Header Comment Block** + ```bash + # ============================================================================ + # Script Name and Purpose + # ============================================================================ + # Note: Important caveats or context + # ============================================================================ + ``` + +2. **Shebang and Error Handling** + ```bash + #!/usr/bin/bash + set -euo pipefail + ``` + +3. **Logging Function Definitions** + ```bash + # Color codes and logging functions + ``` + +4. **Main Script Logic** + - Major sections with clear headers + - Subsections with visual separators + - Comprehensive comments explaining WHY + +5. **Completion Summary** + ```bash + log_header "Script phase complete" + log_info "Next steps: ..." + exit 0 + ``` + +#### Documentation Standards + +**Section Headers**: +```bash +# ============================================================================ +# Major Section Name +# ============================================================================ +# Purpose explanation +# Context or caveats +``` + +**Subsection Headers** (for related operations within a section): +```bash +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Subsection Name +# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +# Issue: Problem description +# Solution: How we're solving it +``` + +**Inline Comments**: +- Focus on **WHY**, not WHAT +- Provide context for unusual approaches +- Document workarounds with issue descriptions +- Explain rationale for future maintainers + +#### Error Handling Patterns + +```bash +# File existence checks +if [[ -f "$file_path" ]]; then + log_info "Processing file" + # ... operation + log_success "File processed" +else + log_warning "File not found, skipping" +fi + +# Command success validation +if command_here; then + log_success "Operation successful" +else + log_error "Operation failed" + exit 1 # Exit on critical failures only +fi + +# Non-critical operations +if optional_command || true; then + log_success "Optional operation completed" +else + log_warning "Optional operation failed (non-critical)" +fi +``` + +#### Variable Conventions + +```bash +# Constants (readonly, UPPERCASE) +readonly COLOR_RESET='\033[0m' +readonly KERNEL_VERSION="5.14.0" + +# Arrays (readonly where appropriate) +readonly -a REMOVE_PACKAGES=(...) +declare -A PACKAGE_REPOS=(...) + +# Local variables (lowercase with underscores) +local package_count=0 +local file_path="/path/to/file" +``` + +#### Validation Patterns + +```bash +# Package validation +validate_critical_packages() { + local -a critical_packages=("$@") + local failed=0 + + for pkg in "${critical_packages[@]}"; do + if ! rpm -q "$pkg" &>/dev/null; then + log_error "Critical package missing: $pkg" + ((failed++)) + fi + done + + if [[ $failed -gt 0 ]]; then + return 1 + fi + return 0 +} + +# Counters for removal operations +removed_count=0 +for item in "${items[@]}"; do + if [[ -e "$item" ]]; then + rm -f "$item" + ((removed_count++)) + fi +done +log_success "Removed $removed_count item(s)" +``` + +### Script Length Guidelines + +- **Minimal scripts** (install-zfs.sh, fix-opt.sh): ~35-50 lines + - Brief logging, essential operations only + - Clear section headers, minimal validation + +- **Standard scripts** (kernel-modules.sh): ~200-250 lines + - Full logging system, comprehensive error handling + - Detailed documentation, validation at key points + +- **Complex scripts** (build.sh, config.sh): ~300-400 lines + - Extensive documentation and inline comments + - Multiple major sections with subsections + - Comprehensive validation and error handling + +**Note**: Length is acceptable when driven by documentation and error handling, not code duplication. + +--- + +## Adding New Packages and Services + +### Adding RPM Packages + +**Edit**: `build-files/build.sh` + +**Method 1: Add to RPM_PACKAGES associative array** +```bash +# Add packages to the appropriate repository section +declare -A RPM_PACKAGES=( + ["fedora"]="existing-packages new-package-name" + ["rpmfusion-free,rpmfusion-free-updates"]="rpmfusion-package" + ["copr:username/repo"]="copr-package" +) +``` + +**Method 2: Add custom repository** +```bash +# Add repository configuration before RPM_PACKAGES declaration +log_info "Adding custom repository" +tee /etc/yum.repos.d/custom.repo > /dev/null << 'EOF' +[custom] +name=Custom Repository +baseurl=https://repo.example.com/ +enabled=1 +gpgcheck=1 +gpgkey=https://repo.example.com/key.asc +EOF + +# Import GPG key +rpm --import https://repo.example.com/key.asc + +# Add to RPM_PACKAGES +declare -A RPM_PACKAGES=( + ... + ["custom"]="package-from-custom-repo" +) +``` + +**Method 3: Direct installation (for special cases)** +```bash +# After the main RPM_PACKAGES loop +log_section "Installing special packages" +if dnf5 -y install special-package; then + log_success "Special package installed" +else + log_warning "Special package installation failed" +fi +``` + +**Note**: Build scripts use `dnf5` at build-time. Runtime package management uses `rpm-ostree`. + +### Adding Flatpak Applications + +**Edit**: `repo-files/flatpaks` (stored in GitHub repository) + +```bash +# Add Flatpak identifier to the list +echo "com.example.Application" >> repo-files/flatpaks + +# Users will receive this on next distinction-install run +``` + +**Alternative**: Direct installation via Just recipe +```bash +ujust distinction-install-flatpaks +``` + +### Adding Homebrew Packages + +**Edit**: `repo-files/brews` (stored in GitHub repository) + +```bash +# Add package name to the list +echo "package-name" >> repo-files/brews + +# Users will receive this on next distinction-install run +``` + +### Adding GNOME Shell Extensions + +**Edit**: `build-files/remote-grabber.sh` + +```bash +# Add extension UUID or URL to download list +# Script handles installation and gschema compilation +``` + +### Adding System Services + +**Method 1**: Enable existing service in `config.sh` +```bash +systemctl enable service-name.service +``` + +**Method 2**: Add custom systemd unit +1. Create unit file in `system-files/usr/lib/systemd/system/` +2. Enable in `config.sh`: +```bash +systemctl enable custom-service.service +``` + +### Adding Custom Executables + +1. Place executable in `system-files/usr/bin/` +2. Ensure executable permissions in Containerfile: +```dockerfile +RUN chmod +x /usr/bin/custom-script +``` + +--- + +## Local Development Workflow + +### Building Locally + +The root `Justfile` provides comprehensive local development tools: + +```bash +# Build the container image locally +just build + +# Build and create a bootable QCOW2 VM image +just build-qcow2 + +# Build and create an ISO installer +just build-iso + +# Run the image in a VM for testing +just run-vm-qcow2 + +# Alternative: Use systemd-vmspawn +just spawn-vm + +# Lint all shell scripts +just lint + +# Format all shell scripts +just format + +# Clean build artifacts +just clean +``` + +### Testing Changes + +1. **Make changes** to build scripts or system files +2. **Build locally**: `just build` +3. **Test in VM**: `just run-vm-qcow2` +4. **Verify functionality** within VM +5. **Commit changes** to feature branch +6. **Create Pull Request** for CI/CD validation + +### Debugging Build Failures + +```bash +# Check GitHub Actions logs +# Navigate to: Repository โ†’ Actions โ†’ Failed Workflow + +# Build locally with verbose output +podman build --format docker --tag localhost/distinctionos:test . + +# Inspect specific build stage +podman build --target --tag test-stage . + +# Enter container for debugging +podman run -it localhost/distinctionos:test /bin/bash +``` + +--- + +## Known Issues + +### Current Issues + +1. **NvChad Root Installation**: May require verification after first run + - **Workaround**: Run `sudo nvim` manually to complete setup + + +### Error Handling Improvements Needed + +- Just recipes require better error handling for network failures +- Improved logging for post-rebase first-run automation + +**Completed (2025-10-27)**: +- โœ… Build scripts now validate package installation +- โœ… Comprehensive color-coded logging implemented across all build scripts +- โœ… Error handling patterns standardized +- โœ… Critical package validation added to build.sh + +--- + +## Roadmap + +### Short-Term Goals (1-3 months) + +- [ ] Apply refactoring patterns to remaining shell scripts in system-files/ + +### Long-Term Goals (Help Wanted) + +- [ ] **Standalone ISO**: Fully functional installer ISO (in progress via build-disk.yml) +- [ ] **CachyOS-LTO Kernel**: Ship optimized kernel by default +- [ ] **Build Caching**: Implement layer caching for faster iteration +- [ ] **Build Time Optimization** Build time optimization strategies + +### Completed Goals + +- [โœ…] Rechunker support for efficient updates +- [โœ…] ZSH as default shell with automated configuration +- [โœ…] Oh-my-zsh and Powerlevel10k automatic installation +- [โœ…] TPM auto-unlock with proactive monitoring system +- [โœ…] **Build Script Refactoring** (2025-10-27): + - Complete overhaul of build.sh with enhanced logging and validation + - Refactored install-zfs.sh for clarity + - Refactored fix-opt.sh with minimal logging + - Complete reorganization of config.sh into six major sections + - Refactored kernel-modules.sh with comprehensive error handling + - Established standardized color-coded logging system + - Implemented code quality guidelines and documentation standards +- [โœ…] Consolidated `layered-appimages.sh` functionality (removed separate script) + +--- + +## Additional Notes + +### Image Signing + +Images are signed with Cosign for verification: +```bash +# Public key location +cosign.pub + +# Verification command (for users) +cosign verify --key cosign.pub ghcr.io/username/distinctionos:latest +``` + +### Rechunker Optimization + +Rechunker provides: +- **Efficient layer compression**: Reduces bandwidth for updates +- **Deduplication**: Eliminates redundant data across layers +- **Faster updates**: Users download only changed content +- **Configuration**: `max-layers: 100` for optimal balance + +### First-Run Automation + +The `distinction-firstrun.service` ensures a seamless post-rebase experience: +- Triggers automatically on first boot after rebase +- Runs `ujust distinction-install` to configure user environment +- Creates log at `/var/DistinctionOS/DistinctionOS_firstrun.log` +- Only executes once (checks for log file existence) +- User can manually re-run with `ujust distinction-install` + +### Security Considerations + +**Passwordless Sudo**: +- Configured for `wheel` group +- Location: `/etc/sudoers.d/99-distinction-wheel-nopasswd` +- **Author is aware of security implications** +- Recommended for personal systems only + +**TPM Security Levels**: +- **Maximum Security**: PCR 0,1,4,5,7,8,9 (most sensitive to changes) +- **Balanced**: PCR 0,4,7,9 (recommended default) +- **Convenience**: PCR 7 only (least restrictive) + +### Contributing Guidelines + +When submitting changes: +1. Follow Google Shell Style Guide for bash scripts +2. Use 2-space indentation in YAML files +3. Test locally before pushing to remote +4. Update documentation for user-facing changes +5. Use descriptive commit messages +6. Create feature branches for significant changes + +### Useful Resources + +- [Universal Blue Documentation](https://universal-blue.org/) +- [Bazzite Documentation](https://docs.bazzite.gg/) +- [rpm-ostree Documentation](https://coreos.github.io/rpm-ostree/) +- [Bootc Image Builder](https://github.com/osbuild/bootc-image-builder) +- [Systemd tmpfiles.d](https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html) + +--- + +**Document Version**: 2.0 +**Last Updated**: 2025-10-27 +**Major Changes**: Complete build script refactoring with standardized logging, enhanced error handling, and comprehensive documentation +**Maintainer**: phantomcortex diff --git a/system_files/etc/profile.d/rpm-ostree-search-hl.sh b/system_files/etc/profile.d/rpm-ostree-search-hl.sh index b5cf50d..1c62bd8 100644 --- a/system_files/etc/profile.d/rpm-ostree-search-hl.sh +++ b/system_files/etc/profile.d/rpm-ostree-search-hl.sh @@ -1 +1,3 @@ alias rpm-ostree="rpm-ostree-search-hl" +alias rosh="rpm-ostree-search-hl search" +alias rosv="rpm-ostree status -v" diff --git a/system_files/usr/share/glib-2.0/schemas/zz0-04-bazzite-desktop-silverblue-theme.gschema.override b/system_files/usr/share/glib-2.0/schemas/zz0-04-bazzite-desktop-silverblue-theme.gschema.override index 336b070..a6f2640 100644 --- a/system_files/usr/share/glib-2.0/schemas/zz0-04-bazzite-desktop-silverblue-theme.gschema.override +++ b/system_files/usr/share/glib-2.0/schemas/zz0-04-bazzite-desktop-silverblue-theme.gschema.override @@ -15,7 +15,7 @@ accent-color='red' cursor-theme='capitaine-cursors' cursor-size=36 font-antialiasing='rgba' -icon-theme=kora +icon-theme='kora' [org.gnome.desktop.sound] theme-name='_custom' @@ -28,7 +28,6 @@ titlebar-font='Berserker Bold Medium 12' color-shading-type='solid' picture-options='zoom' picture-uri='file:///usr/share/backgrounds/michal-kus-skyrimspeed2.jpeg' -picture-uri-dark='file:///usr/share/backgrounds/michal-kus-skyrimspeed2.jpeg' primary-color='#310042' secondary-color='#000622' @@ -41,6 +40,7 @@ secondary-color='#000622' [org.gnome.shell.extensions.just-perfection] theme=true +panel-size=36 window-demands-attention-focus=true switcher-popup-delay=true workspace-wrap-around=true @@ -78,7 +78,7 @@ blur=true [org.gnome.shell.extensions.blur-my-shell.applications] opacity=200 sigma=70 -whilelist=['org.gnome.Nautilus', 'org.gnome.Shell.Extensions', 'com.mattjakeman.ExtensionManager', 'org.gnome.Shell.Extensions', 'com.raggesilver.BlackBox', 'crossover', 'org.gnome.TextEditor', 'io.github.ilya_zlobintsev.LACT', 'org.gnome.Settings', 'org.gnome.clocks', 'org.gnome.font-viewer', 'gnome-disks', 'org.gnome.baobab', 'org.gnome.Logs', 'io.github.realmazharhussain.GdmSettings', 'io.missioncenter.MissionCenter', 'it.mijorus.gearlever', 'io.gitlab.adhami3310.Impression', 'io.github.flattool.Ignition', 'org.gnome.FileRoller', 'openrgb', 'org.gnome.tweaks', 'com.vysp3r.ProtonPlus', 'opensnitch_ui', 'gnome-abrt', 'zenity', 'com.github.tchx84.Flatseal', 'page.codeberg.JakobDev.jdDesktopEntryEdit', 'app.drey.EarTag', 'dconf-editor', 'com.github.unrud.VideoDownloader', 'com.github.unrud.VideoDownloader', 'org.gnome.Decibels', 'org.gnome.Loupe', 'io.bassi.Amberol', 'zen', 'com.github.neithern.g4music', 'org.gnome.Boxes', 're.sonny.Workbench', 'org.gnome.Builder', 'yelp', 'io.github.dvlv.boxbuddyrs', 'gnome-builder', 'org.gnome.Software', 'org.gnome.Ptyxis'] +whitelist=['org.gnome.Nautilus', 'org.gnome.Shell.Extensions', 'com.mattjakeman.ExtensionManager', 'org.gnome.Shell.Extensions', 'com.raggesilver.BlackBox', 'crossover', 'org.gnome.TextEditor', 'io.github.ilya_zlobintsev.LACT', 'org.gnome.Settings', 'org.gnome.clocks', 'org.gnome.font-viewer', 'gnome-disks', 'org.gnome.baobab', 'org.gnome.Logs', 'io.github.realmazharhussain.GdmSettings', 'io.missioncenter.MissionCenter', 'it.mijorus.gearlever', 'io.gitlab.adhami3310.Impression', 'io.github.flattool.Ignition', 'org.gnome.FileRoller', 'openrgb', 'org.gnome.tweaks', 'com.vysp3r.ProtonPlus', 'opensnitch_ui', 'gnome-abrt', 'zenity', 'com.github.tchx84.Flatseal', 'page.codeberg.JakobDev.jdDesktopEntryEdit', 'app.drey.EarTag', 'dconf-editor', 'com.github.unrud.VideoDownloader', 'com.github.unrud.VideoDownloader', 'org.gnome.Decibels', 'org.gnome.Loupe', 'io.bassi.Amberol', 'zen', 'com.github.neithern.g4music', 'org.gnome.Boxes', 're.sonny.Workbench', 'org.gnome.Builder', 'yelp', 'io.github.dvlv.boxbuddyrs', 'gnome-builder', 'org.gnome.Software', 'org.gnome.Ptyxis'] [org.gnome.shell.extensions.ncom.github.hermes83.compiz-alike-magic-lamp-effect] duration=250 @@ -91,12 +91,17 @@ pattern='EEEE, MMMM d h:mm a' font-size=12 [org.gnome.shell.extensions.dash-to-dock] +running-indicator-dominant-color=true running-indicator-style='SEGMENTED' show-mounts=false show-dock-urgent-notify=false dash-max-icon-size=64 intellihide-mode='ALL_WINDOWS' height-fraction=-0.9 +show-icons-emblems=false +show-mounts=false +show-mounts-network=false +show-mounts-only-mounted=false [com.raggesilver.BlackBox] font='0xProto Nerd Font Bold 12' @@ -105,10 +110,15 @@ theme-dark='Pencil Dark' pretty=false cursor-blink-mode=1 fill-tabs=true -window-width=1,800 -window-height=1,200 +window-width=uint32 1800 +window-height=uint32 1200 scrollback-mode=1 +[org.gnome.shell.extensions.date-menu-formatter] +font-size=12 +pattern='EEEE, MMMM d h:mm a' +text-align='center' + [org.gnome.shell.extensions.tilingshell] inner-gaps=8 outer-gaps=8 @@ -124,10 +134,3 @@ enable-snap-assist=false [org.gnome.shell.extensions.SettingsCenter.items] items=Extensions Preferences;org.gnome.Extensions.desktop;1;gnome-extensions-app|Gnome Tweaks;gnome-tweaks.desktop;1;gnome-tweaks|Desktop Config Editor;dconf-editor.desktop;1;dconf-editor|Gnome Config Editor;gconf-editor.desktop;0;gconf-editor|Passwords and Keys;seahorse.desktop;0;seahorse|Session Properties;session-properties.desktop;0;gnome-session-properties -[org/gnome/shell/extensions/desktop-cube] -last-first-gap=false -enable-desktop-edge-switch=false -enable-panel-dragging=true -enable-desktop-dragging=true -enable-overview-edge-switch=false -enable-overview-dragging=false