diff --git a/.github/workflows/reusable-build-iso-anaconda.yml b/.github/workflows/reusable-build-iso-anaconda.yml index 77a4f9f..9a833ca 100644 --- a/.github/workflows/reusable-build-iso-anaconda.yml +++ b/.github/workflows/reusable-build-iso-anaconda.yml @@ -56,21 +56,17 @@ jobs: repository: get-aurora-dev/common path: common - - name: Setup Just - uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 - - - name: Check Just Syntax - shell: bash - run: | - just check - - name: Format image ref id: image_ref env: FLAVOR: ${{ matrix.flavor }} run: | set -eoux pipefail - image_name=$(just image_name "aurora" "${{ matrix.image_version}}" "${{ matrix.flavor}}") + if [[ "${{ matrix.flavor }}" =~ main ]]; then + image_name="aurora" + else + image_name="aurora-${{ matrix.flavor }}" + fi image_ref="${IMAGE_REGISTRY}/${image_name}" KARGS="NONE" echo "image_ref=$image_ref" >> "${GITHUB_OUTPUT}" @@ -81,18 +77,31 @@ jobs: id: flatpak_list run: | set -eoux pipefail - FILE_LIST="$(mktemp)" - cat common/system_files/shared/usr/share/ublue-os/homebrew/system-flatpaks.Brewfile | grep -v '#' | grep -F -e "flatpak" | sed 's/flatpak //' | tr -d '"' | tee "${FILE_LIST}" - echo "file_list_path=${FILE_LIST}" | tee "${GITHUB_OUTPUT}" + mkdir -p iso_files + cat common/system_files/shared/usr/share/ublue-os/homebrew/system-flatpaks.Brewfile | grep -v '#' | grep -F -e "flatpak" | sed 's/flatpak //' | tr -d '"' | tee iso_files/flatpaks.list + + - name: Pull base image + run: | + sudo podman pull "${{ steps.image_ref.outputs.image_ref }}:${{ matrix.image_version }}" + + - name: Build Live Container Image + id: build-container + run: | + IMAGE_NAME="aurora-live-${{ matrix.flavor }}:${{ matrix.image_version }}" + sudo podman build \ + --cap-add sys_admin \ + --security-opt label=disable \ + --build-arg BASE_IMAGE=${{ steps.image_ref.outputs.image_ref }}:${{ matrix.image_version }} \ + --tag "${IMAGE_NAME}" \ + -f Containerfile \ + . + echo "image_name=${IMAGE_NAME}" >> "${GITHUB_OUTPUT}" - name: Build ISO id: build - uses: ublue-os/titanoboa@840217d97bd0bc9a52466508c54d8dda5c5ba2fd + uses: ublue-os/titanoboa@5c457c3d0518bd17e754be0fd98a60d29d26abb4 with: - image-ref: ${{ steps.image_ref.outputs.image_ref }}:${{ matrix.image_version }} - flatpaks-list: ${{ steps.flatpak_list.outputs.file_list_path }} - hook-post-rootfs: ${{ github.workspace }}/${{ inputs.hook_script }} - kargs: ${{ steps.image_ref.outputs.kargs }} + image-ref: ${{ steps.build-container.outputs.image_name }} - name: Rename ISO id: rename diff --git a/.github/workflows/validate-just.yml b/.github/workflows/validate-just.yml deleted file mode 100644 index 46481ed..0000000 --- a/.github/workflows/validate-just.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Validate Justfiles - -on: - pull_request: - paths: - - "Justfile" - - "just/*" - push: - branches: - - main - paths: - - "Justfile" - - "just/*" - -jobs: - validate: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - - - name: Setup Just - uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 - - - name: Check Just Syntax - shell: bash - run: | - just check diff --git a/.gitignore b/.gitignore index 5c5e16f..1cdb61c 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,3 @@ __pycache__/ .pytest_cache/ venv/ env/ - -# Just -.just/ diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index cd0c340..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,590 +0,0 @@ -# Aurora ISO Build Copilot Instructions - -This document provides essential information for coding agents working with the Aurora ISO build repository to minimize exploration time and avoid common build failures. - -## Repository Overview - -**Aurora ISO** is a dedicated repository for building bootable Aurora ISOs using Titanoboa and the Anaconda installer with WebUI. This is a specialized build system focused solely on creating installation media. - -- **Type**: ISO build system for Aurora (KDE-based immutable OS) -- **Base**: Uses pre-built Aurora container images from `ghcr.io/ublue-os/aurora` -- **Languages**: Bash scripts, YAML configuration -- **Build System**: Just (command runner), GitHub Actions, Titanoboa (ISO builder) -- **Target**: Bootable installation ISOs with Anaconda WebUI installer for Aurora desktop OS - -## Repository Structure - -### Root Directory Files - -- `Justfile` - Build automation recipes for ISO tasks -- `.pre-commit-config.yaml` - Pre-commit hooks for validation -- `README.md` - Repository documentation -- `AGENTS.md` - This file -- `LICENSE` - Apache 2.0 license - -### Key Directories - -- `.github/workflows/` - GitHub Actions workflows for ISO building - - `build-iso-stable.yml` - Caller workflow for stable variant - - `reusable-build-iso-anaconda.yml` - Main ISO build workflow with matrix strategy - - `validate-just.yml` - Validates Justfile syntax -- `iso_files/` - ISO configuration and customization scripts - - `configure_iso_anaconda.sh` - Main ISO configuration script - - `scope_installer.png` - Aurora installer icon/branding - -### Architecture - -- **Build Target**: Bootable live ISOs with Anaconda WebUI installer -- **Image Flavors**: `main`, `nvidia-open` -- **ISO Variants**: `stable`, `latest` -- **Platforms**: `amd64` (x86_64) only -- **Fedora Versions**: 42+ (WebUI requires F42+) -- **Build Process**: GitHub Actions → Titanoboa → ISO creation with WebUI -- **Base Images**: Uses `ghcr.io/ublue-os/aurora*` as foundation - -## Build Instructions - -### Prerequisites - -**ALWAYS install these tools before attempting any builds:** - -```bash -# Install Just command runner (REQUIRED for build commands) -curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to ~/.local/bin -export PATH="$HOME/.local/bin:$PATH" - -# Verify container runtime (for local builds) -podman --version || docker --version - -# Install pre-commit for validation -pip install pre-commit -``` - -**Note**: Local ISO builds are extremely resource-intensive. Most development work should be tested via GitHub Actions workflows. - -### Essential Commands - -**Validation (ALWAYS run before committing changes):** -```bash -# 1. Validate syntax and formatting (1-2 minutes) -pre-commit run --all-files - -# 2. Check Just syntax (requires Just installation) -just check - -# 3. Check ISO configuration script syntax -just test-iso-config - -# 4. Fix formatting issues automatically -just fix -``` - -**Utility commands:** -```bash -# Clean build artifacts -just clean - -# List all available recipes -just --list - -# Validate image/tag/flavor combinations -just validate aurora stable main - -# Clone common repository (for flatpak lists) -just clone-common - -# Generate flatpak list from common repo Brewfiles -just generate-flatpak-list - -# Get image name for a specific combination -just image_name aurora stable main -# Output: aurora - -just image_name aurora stable nvidia-open -# Output: aurora-nvidia-open -``` - -### Critical Build Notes - -1. **ISOs are built in GitHub Actions** - local builds are not recommended - - Requires 40GB+ free disk space - - Takes 30-60 minutes per ISO - - Requires privileged container access -2. **Always run `just check` before making changes** - catches syntax errors early -3. **Pre-commit hooks are mandatory** - run `pre-commit run --all-files` to validate changes -4. **ISO builds require significant resources** (40GB+ disk, 8GB+ RAM, 60+ minute runtime) -5. **Test the configuration script syntax** with `just test-iso-config` -6. **Test via workflow dispatch** rather than local builds when possible - -### Common Build Failures & Workarounds - -**Pre-commit failures:** -```bash -# Fix end-of-file and trailing whitespace automatically -pre-commit run --all-files -``` - -**Just syntax errors:** -```bash -# Auto-fix formatting -just fix - -# Manual validation -just check -``` - -**ISO configuration script errors:** -```bash -# Validate bash syntax -just test-iso-config - -# Manual check -bash -n iso_files/configure_iso_anaconda.sh -``` - -**ISO build failures:** -- Ensure adequate disk space (40GB+ free) -- Clean previous builds: `just clean` -- Check container runtime: `podman system info` -- Verify base image exists and is pullable -- Check hook scripts for syntax errors - -## Validation Pipeline - -### Pre-commit Hooks (REQUIRED) - -The repository uses mandatory pre-commit validation: - -- `check-json` - Validates JSON syntax -- `check-toml` - Validates TOML syntax -- `check-yaml` - Validates YAML syntax (includes workflow files) -- `end-of-file-fixer` - Ensures files end with newline -- `trailing-whitespace` - Removes trailing whitespace - -**Always run:** `pre-commit run --all-files` before committing changes. - -### GitHub Actions Workflows - -- `build-iso-stable.yml` - Builds stable ISO images (calls reusable workflow) - - Triggers on: PR (when ISO files change), weekly schedule (Tuesdays), workflow dispatch -- `reusable-build-iso-anaconda.yml` - Core ISO build logic with matrix strategy - - Builds multiple flavor combinations in parallel - - Uses Titanoboa for ISO generation - - Uploads to CloudFlare R2 test bucket (scheduled/manual) or GitHub artifacts (configurable) -- `validate-just.yml` - Validates Justfile syntax - -**Workflow Architecture:** - -- Caller workflow (stable) calls reusable workflow with input-controlled uploads -- Reusable workflow uses matrix strategy for parallel builds -- Supports workflow dispatch for manual builds with configurable upload destinations -- Automatically builds on ISO configuration changes (PR validation only, no uploads) -- ISO builds use Titanoboa action from `ublue-os/titanoboa` -- Configuration happens in `configure_iso_anaconda.sh` -- Flatpaks are dynamically generated from Brewfiles in `get-aurora-dev/common` repository -- ISOs are uploaded to CloudFlare R2 test bucket (scheduled builds) or GitHub artifacts (optional) -- PR builds validate configuration but do not upload ISOs - -### Manual Validation Steps - -1. `pre-commit run --all-files` - Runs validation hooks (1-2 minutes) -2. `just check` - Validates Just syntax (30 seconds) -3. `just test-iso-config` - Validates ISO configuration script (5 seconds) -4. `just fix` - Auto-fixes formatting issues (30 seconds) -5. Test via workflow dispatch rather than local builds when possible - -## ISO Configuration - -### Main Configuration Script - -The ISO is customized via `iso_files/configure_iso_anaconda.sh`: - -**Key Customizations:** -- Installs Anaconda WebUI installer (anaconda-webui, anaconda-live, firefox) -- Configures Anaconda profile for Aurora (`/etc/anaconda/profile.d/aurora.conf`) -- Sets up BTRFS partitioning scheme with zstd:1 compression -- Adds installer to KDE panel and kickoff menu -- Configures secure boot key enrollment (password: `universalblue`) -- Installs flatpaks dynamically generated from Brewfiles -- Disables unnecessary services in live environment -- Configures KDE desktop environment for installer - -**Making Configuration Changes:** - -1. Edit `iso_files/configure_iso_anaconda.sh` -2. Validate syntax: `just test-iso-config` -3. Run pre-commit hooks: `pre-commit run --all-files` -4. Test in PR to trigger ISO build via GitHub Actions - -### Anaconda Configuration - -The ISO includes a custom Anaconda profile at `/etc/anaconda/profile.d/aurora.conf`: - -- **Profile ID**: aurora -- **OS Detection**: Matches os-release with `os_id = aurora` -- **Network**: First wired connection auto-enabled -- **Bootloader**: Uses Fedora EFI directory, auto-hide menu -- **Storage**: BTRFS with zstd:1 compression, custom partitioning scheme -- **UI**: Custom stylesheet, hides network and password spokes -- **WebUI**: Uses Anaconda WebUI for modern installer experience (F42+) - -### Kickstart Configuration - -Interactive kickstart includes: -- OSTree container source from `ghcr.io/ublue-os/aurora` -- Bootc configuration for signed images -- Fedora Flatpak repo disabling -- System flatpak installation -- Secure boot key enrollment (password: `universalblue`) - -### Flatpak Management - -Flatpaks are pre-installed on the ISO for offline installation: - -**Dynamic Generation:** -- Flatpak lists are dynamically generated from Brewfiles in `get-aurora-dev/common` repository -- The workflow clones the common repo and extracts flatpak IDs from `*system-flatpaks.Brewfile` files -- Generated list is passed to Titanoboa during ISO build - -**Adding Flatpaks:** -1. Edit Brewfile in `get-aurora-dev/common` repository (not this repo) -2. Add flatpak entries in Brewfile format: `flatpak "app.id"` -3. Flatpaks are automatically included in next ISO build -4. Ensure flatpaks exist on Flathub before adding - -## Build System Deep Dive - -### Justfile Structure - -The `Justfile` contains ISO-specific build orchestration: - -**Validation Recipes:** -- `just check` - Validates Just syntax across all .just files -- `just fix` - Auto-formats Just files -- `just validate ` - Validates image/tag/flavor combinations -- `just test-iso-config` - Validates ISO configuration script syntax - -**Utility Recipes:** -- `just clean` - Removes build artifacts and cloned repos -- `just image_name ` - Generates image name for specific combo -- `just clone-common` - Clones get-aurora-dev/common repository -- `just generate-flatpak-list` - Generates flatpak list from common repo Brewfiles -- `just verify-container ` - Verifies container signatures with cosign - -**Image/Tag Definitions:** - -```bash -images: aurora -flavors: main, nvidia-open -tags: stable, latest -``` - -### GitHub Actions Workflow - -The `reusable-build-iso-anaconda.yml` workflow: - -1. **Maximizes build space** - Removes unnecessary software (amd64 only) -2. **Validates Just syntax** - Ensures build recipes are valid -3. **Formats image reference** - Constructs proper image reference -4. **Generates flatpak list** - Dynamically from Brewfiles in common repo -5. **Builds ISO with Titanoboa** - Uses `ublue-os/titanoboa@main` action -6. **Renames and checksums ISO** - Prepares for distribution -7. **Uploads artifacts** - To GitHub Actions (PRs) or CloudFlare R2 (stable) - -**Build Arguments:** -- `image-ref` - Full container image reference (e.g., `ghcr.io/ublue-os/aurora:stable`) -- `flatpaks-list` - Path to dynamically generated flatpak list file -- `hook-post-rootfs` - Path to ISO configuration script (`configure_iso_anaconda.sh`) -- `kargs` - Kernel arguments (currently NONE) - -**Build Matrix:** -- **Platform**: amd64 (x86_64) only -- **Flavors**: main, nvidia-open -- **Variants**: stable (latest can be added as needed) -- Parallel builds for each flavor combination - -## Workflow Deep Dive - -### Reusable ISO Build Workflow - -The `reusable-build-iso-anaconda.yml` is the core workflow: - -**Trigger conditions:** -- Workflow dispatch (manual builds) -- Pull requests - on ISO configuration changes -- Schedule - Monthly builds on 1st at 2:00 AM UTC -- Workflow call - from other workflows (e.g., stable) - -**Build matrix:** -Dynamically generates matrix based on configuration: -- **Platform**: amd64 (x86_64) - uses `ubuntu-24.04` runner -- **Flavors**: main, nvidia-open -- **Variants**: stable (primary), latest (when needed) - -**Build process:** -1. Checkout repository and setup Just -2. Validate Just syntax with `just check` -3. Format image reference and determine kernel args -4. Clone common repo and generate flatpak list from Brewfiles -5. Build ISO using Titanoboa action with WebUI configuration -6. Rename ISO and generate checksum -7. Upload to CloudFlare R2 (stable, non-PR) or GitHub artifacts (PRs) - -**Key workflow features:** -- Parallel builds across matrix -- Conditional uploads based on event type and variant -- Dynamic flatpak list generation from external Brewfile repository -- WebUI-specific Anaconda configuration -- Separate artifact naming for each flavor/variant combination - -### Stable Workflow - -The `build-iso-stable.yml` is a caller workflow: -- Triggers on PR (ISO file changes), weekly schedule (Tuesdays at 03:15 UTC), or workflow dispatch -- Calls reusable workflow with input-controlled upload parameters -- Builds both main and nvidia-open flavors for stable variant -- Uses `secrets: inherit` to pass CloudFlare R2 credentials -- Passes upload_artifacts and upload_r2 inputs to control upload destinations - -### Standard Caller Workflow Pattern - -**All caller workflows MUST follow this pattern without deviation.** - -Caller workflows follow a **strict, consistent structure** to ensure maintainability: - -```yaml ---- -name: Build Stable ISOs -on: - pull_request: - branches: - - main - paths: - - ".github/workflows/build-iso-stable.yml" - - ".github/workflows/reusable-build-iso-anaconda.yml" - - "iso_files/**" - schedule: - - cron: "15 3 * * 2" # 3:15am UTC on Tuesdays - workflow_call: - workflow_dispatch: - -jobs: - build-iso-stable: - name: Build Stable ISOs - uses: ./.github/workflows/reusable-build-iso-anaconda.yml - secrets: inherit - with: - upload_artifacts: ${{ github.event_name == 'workflow_dispatch' && inputs.upload_artifacts || false }} - upload_r2: ${{ github.event_name == 'workflow_dispatch' && inputs.upload_r2 || true }} -``` - -**Key Pattern Rules:** - -1. **NO permissions block in caller**: The reusable workflow handles all permissions internally -2. **Use `secrets: inherit`**: Required for CloudFlare R2 upload credentials -3. **Consistent triggers**: PR, schedule, workflow_dispatch (workflow_call optional if needed by other workflows) -4. **Single job pattern**: Each caller has exactly one job calling the reusable workflow -5. **Path filters**: Only trigger on relevant file changes -6. **Input passing**: Use `with:` block to pass inputs to reusable workflow for upload control - -## Configuration Files - -### Key Configuration Locations - -- `iso_files/` - ISO configuration and hook scripts -- `.github/workflows/` - CI/CD pipeline definitions -- `Justfile` - Main build recipes -- `.pre-commit-config.yaml` - Pre-commit hook configuration -- `.gitignore` - Git ignore patterns for build artifacts - -### Linting/Build Configurations - -- `.pre-commit-config.yaml` - Pre-commit hook configuration -- `Justfile` - ISO build recipe definitions -- `.gitignore` - Git ignore patterns (output/, common/, *.iso*, flatpaks.list) - -## Development Guidelines - -### Making Changes - -1. **ALWAYS validate first:** `just check && pre-commit run --all-files` -2. **Make minimal modifications** - prefer configuration over code changes -3. **Test formatting:** `just fix` to auto-format -4. **Test ISO config syntax:** `just test-iso-config` -5. **Test in PRs** - ISO builds run automatically on PR creation for ISO file changes -6. **Use workflow dispatch** for manual testing without PR - -### File Editing Best Practices - -- **JSON files**: Validate syntax with `pre-commit run check-json` -- **YAML files**: Validate syntax with `pre-commit run check-yaml` -- **Justfile**: Always run `just check` after modifications -- **Shell scripts**: Follow existing patterns in `iso_files/`, validate with `bash -n` -- **Workflow files**: Test in fork first before opening PR - -### Common Modification Patterns - -- **ISO branding**: Update files in `iso_files/` (images, scripts) -- **Anaconda configuration**: Edit profile in `configure_iso_anaconda.sh` -- **Flatpak lists**: Modify Brewfiles in `get-aurora-dev/common` repository (not this repo) -- **Build workflow**: Edit `.github/workflows/reusable-build-iso-anaconda.yml` -- **Partitioning scheme**: Update `default_partitioning` in Anaconda profile -- **Live environment**: Add/remove packages in `configure_iso_anaconda.sh` -- **WebUI configuration**: Modify Anaconda WebUI settings in configuration script - -### Testing ISO Changes - -1. **Configuration script changes**: Validate with `just test-iso-config` first -2. **Workflow changes**: Test via workflow dispatch in your fork -3. **Flatpak changes**: Edit Brewfiles in common repo, trigger new ISO build -4. **PR testing**: ISOs build automatically for PRs with ISO file changes -5. **Manual testing**: Use workflow dispatch for on-demand builds - -## Trust These Instructions - -**The information in this document has been validated against the current repository state.** Only search for additional information if: -- Instructions are incomplete for your specific task -- You encounter errors not covered in the workarounds section -- Repository structure has changed significantly - -This repository is focused and straightforward. Following these instructions will significantly reduce build failures and exploration time. - -## Best Practices for AI Agents - -### DO: -- ✅ Make minimal, surgical changes -- ✅ Focus on ISO configuration and workflows -- ✅ Use conventional commits -- ✅ Run validation before committing -- ✅ Test via workflow dispatch when possible -- ✅ Use existing patterns and conventions -- ✅ Include AI attribution in commits - -### DON'T: -- ❌ Modify base image building (wrong repo) -- ❌ Remove or edit working code unnecessarily -- ❌ Skip validation steps -- ❌ Build ISOs locally unless necessary -- ❌ Use non-conventional commit messages -- ❌ Add flatpaks directly to this repo (use common repo Brewfiles) -- ❌ Change workflow patterns without understanding the architecture - -### Common Pitfalls: -- **Large builds:** ISOs are resource-intensive (40GB+ disk, 60+ min), prefer GitHub Actions -- **Pre-commit failures:** Always run `pre-commit run --all-files` before commit -- **Just syntax errors:** Run `just check` and `just fix` -- **Workflow testing:** Test in fork first with workflow dispatch -- **Flatpak management:** Flatpaks come from common repo Brewfiles, not managed here -- **WebUI requirements:** Anaconda WebUI requires Fedora 42+ - -## Commit Conventions (MANDATORY) - -This repository uses [Conventional Commits](https://www.conventionalcommits.org/): - -**Format:** `(): ` - -**Types:** -- `feat:` - New features -- `fix:` - Bug fixes -- `docs:` - Documentation changes -- `ci:` - CI/CD changes -- `chore:` - Maintenance tasks -- `refactor:` - Code refactoring - -**Scopes:** -- `iso` - ISO configuration and build -- `workflow` - GitHub Actions workflows -- `config` - Configuration files -- `flatpak` - Flatpak management - -**Examples:** -- `feat(iso): add support for latest tag` -- `fix(config): correct Anaconda profile syntax` -- `docs(readme): update build instructions` -- `ci(workflow): optimize matrix strategy` - -**AI Attribution (REQUIRED):** -AI agents must disclose what tool and model they are using in the "Assisted-by" commit footer: - -```text -Assisted-by: [Model Name] via [Tool Name] -``` - -Example: - -```text -feat(iso): add KDE plasma widget to installer - -Add custom KDE widget to installer panel - -Assisted-by: Claude 3.5 Sonnet via Zed AI -``` - -## Key Differences from Aurora Main Repository - -This repository is **ISO-only** and differs from the main Aurora repository: - -1. **No container building** - Uses pre-built Aurora images from GHCR -2. **No image variants** - Only builds ISOs, not the OS itself -3. **Simplified Justfile** - Only ISO-related recipes -4. **Single workflow focus** - ISO building only with WebUI -5. **External dependencies** - Dynamically generates flatpak lists from Brewfiles in `get-aurora-dev/common` -6. **WebUI-specific** - Uses Anaconda WebUI installer (requires F42+) -7. **KDE-focused** - Configuration optimized for KDE Plasma desktop - -## Other Rules Important to Maintainers - -- Ensure that [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/#specification) are used and enforced for every commit and pull request title -- Always be surgical with the least amount of code, the project strives to be easy to maintain -- Documentation for Aurora exists at https://docs.getaurora.dev/ -- Main Aurora repository: https://github.com/ublue-os/aurora -- Common configuration repository: https://github.com/get-aurora-dev/common - -## Quick Reference - -### Validation Commands -```bash -pre-commit run --all-files # Full validation -just check # Just syntax -just test-iso-config # ISO script syntax -just fix # Auto-fix formatting -``` - -### Utility Commands -```bash -just clean # Clean artifacts -just clone-common # Clone common repo -just generate-flatpak-list # Generate flatpak list -just image_name aurora stable main # Get image name -just verify-container # Verify container signature -``` - -### Valid Combinations -```bash -# Images: aurora -# Flavors: main, nvidia-open -# Tags: stable, latest - -just validate aurora stable main -just validate aurora stable nvidia-open -just validate aurora latest main -just validate aurora latest nvidia-open -``` - -### Build Matrix (Current) -- **Platforms**: amd64 only -- **Flavors**: main, nvidia-open -- **Variants**: stable (primary), latest (when needed) -- **Total ISOs**: 2 (amd64 × main, amd64 × nvidia-open) for stable - -## Related Resources - -- **Aurora documentation:** https://docs.getaurora.dev/ -- **Main Aurora repo:** https://github.com/ublue-os/aurora -- **Common config repo:** https://github.com/get-aurora-dev/common -- **Titanoboa ISO builder:** https://github.com/ublue-os/titanoboa -- **Universal Blue:** https://universal-blue.org/ - -## Summary - -This repository is focused exclusively on ISO generation for Aurora with Anaconda WebUI. It uses pre-built container images and configures them for bootable installation media using Titanoboa. Development should focus on ISO configuration scripts, workflows, and coordination with the common repository for flatpak management. Always validate changes, use conventional commits, and prefer GitHub Actions for testing over local builds due to resource requirements. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c9bebb6..98437c0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,17 +24,12 @@ This project follows the [Universal Blue Code of Conduct](https://universal-blue Before you begin, ensure you have the following tools installed: - **Git**: Version control -- **Just**: Command runner for automation - **Pre-commit**: For running validation hooks - **Bash**: For running scripts ### Installation ```bash -# Install Just command runner -curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to ~/.local/bin -export PATH="$HOME/.local/bin:$PATH" - # Install pre-commit pip install pre-commit @@ -125,14 +120,9 @@ Always validate your changes before committing: # Run all pre-commit hooks pre-commit run --all-files -# Validate Just syntax -just check - # Test ISO configuration script syntax -just test-iso-config - -# Auto-fix formatting issues -just fix +bash -n iso_files/configure_iso_anaconda.sh +bash -n iso_files/build.sh ``` ### ISO Build Testing @@ -151,9 +141,6 @@ To manually test the ISO configuration script: ```bash # Validate bash syntax bash -n iso_files/configure_iso_anaconda-webui.sh - -# Or use the Just recipe -just test-iso-config ``` ## Submitting Changes @@ -169,8 +156,8 @@ just test-iso-config 2. **Run validation**: ```bash pre-commit run --all-files - just check - just test-iso-config + bash -n iso_files/configure_iso_anaconda.sh + bash -n iso_files/build.sh ``` 3. **Test your changes**: Ensure the ISO builds successfully in GitHub Actions @@ -189,7 +176,6 @@ just test-iso-config - Screenshots or logs (if relevant) 3. **Wait for CI checks** to complete: - - Just syntax validation - Pre-commit hooks - ISO build (if workflow files changed) @@ -210,7 +196,6 @@ Brief description of what this PR does. - [ ] Maintenance/chore ## Testing -- [ ] Validated locally with `just check` - [ ] Ran pre-commit hooks - [ ] Tested ISO configuration script syntax - [ ] ISO builds successfully in GitHub Actions @@ -253,24 +238,6 @@ fi - Use `---` document separator - Keep workflows readable with descriptive names -### Justfile - -- Use descriptive recipe names -- Add comments for complex recipes -- Group related recipes with `[group('name')]` -- Mark internal recipes with `[private]` -- Use consistent formatting (run `just fix`) - -**Example:** -```just -# Build ISO for specific flavor -[group('ISO')] -build-iso flavor="main": - #!/usr/bin/bash - set -eoux pipefail - echo "Building ISO for {{ flavor }}" -``` - ### Markdown - Use descriptive headings @@ -283,7 +250,7 @@ build-iso flavor="main": ### Adding New ISO Configuration 1. Edit `iso_files/configure_iso_anaconda-webui.sh` -2. Test syntax: `just test-iso-config` +2. Test syntax: `bash -n iso_files/configure_iso_anaconda-webui.sh` 3. Create PR with changes 4. Wait for ISO build to complete 5. Test the generated ISO @@ -302,20 +269,11 @@ build-iso flavor="main": 3. Create PR and monitor workflow execution 4. Ensure all checks pass -### Modifying Justfile - -1. Edit `Justfile` -2. Validate syntax: `just check` -3. Test affected recipes -4. Run `just fix` to format -5. Create PR - ## Resources ### Documentation - [Aurora Documentation](https://docs.getaurora.dev/) - [Universal Blue Docs](https://universal-blue.org/) -- [AGENTS.md](AGENTS.md) - AI agent development guide - [Titanoboa](https://github.com/ublue-os/titanoboa) - ISO builder ### Community @@ -324,7 +282,6 @@ build-iso flavor="main": - [Discord](https://discord.gg/universalblue) ### Tools -- [Just Manual](https://just.systems/man/en/) - [Pre-commit](https://pre-commit.com/) - [Conventional Commits](https://www.conventionalcommits.org/) @@ -333,10 +290,9 @@ build-iso flavor="main": If you need help: 1. Check the [documentation](https://docs.getaurora.dev/) -2. Review [AGENTS.md](AGENTS.md) for detailed instructions -3. Search existing [issues](https://github.com/ublue-os/aurora-iso/issues) -4. Ask in [Discourse forums](https://universal-blue.discourse.group/c/aurora/11) -5. Join our [Discord](https://discord.gg/universalblue) +2. Search existing [issues](https://github.com/ublue-os/aurora-iso/issues) +3. Ask in [Discourse forums](https://universal-blue.discourse.group/c/aurora/11) +4. Join our [Discord](https://discord.gg/universalblue) ## Recognition diff --git a/Containerfile b/Containerfile new file mode 100644 index 0000000..dd17bd7 --- /dev/null +++ b/Containerfile @@ -0,0 +1,8 @@ +# run with --cap-add sys_admin --security-opt label=disable --squash +ARG BASE_IMAGE +FROM ${BASE_IMAGE} +ENV BASE_IMAGE=${BASE_IMAGE} + +COPY iso_files/ /src/iso_files/ +RUN --mount=type=cache,target=/var/tmp/libdnf5,id=libdnf5 \ + bash /src/iso_files/build.sh diff --git a/Justfile b/Justfile deleted file mode 100644 index f2c89be..0000000 --- a/Justfile +++ /dev/null @@ -1,165 +0,0 @@ -repo_organization := "ublue-os" -common_image := "ghcr.io/get-aurora-dev/common:latest" -images := '( - [aurora]=aurora -)' -flavors := '( - [main]=main - [nvidia-open]=nvidia-open -)' -tags := '( - [stable]=stable - [latest]=latest - [testing]=testing -)' -export SUDO_DISPLAY := if `if [ -n "${DISPLAY:-}" ] || [ -n "${WAYLAND_DISPLAY:-}" ]; then echo true; fi` == "true" { "true" } else { "false" } -export SUDOIF := if `id -u` == "0" { "" } else if SUDO_DISPLAY == "true" { "sudo --askpass" } else { "sudo" } -export PODMAN := if path_exists("/usr/bin/podman") == "true" { env("PODMAN", "/usr/bin/podman") } else if path_exists("/usr/bin/docker") == "true" { env("PODMAN", "docker") } else { env("PODMAN", "exit 1 ; ") } -just := just_executable() - -[private] -default: - @{{ just }} --list - -# Check Just Syntax -[group('Just')] -check: - #!/usr/bin/bash - find . -type f -name "*.just" | while read -r file; do - echo "Checking syntax: $file" - {{ just }} --unstable --fmt --check -f $file - done - echo "Checking syntax: Justfile" - {{ just }} --unstable --fmt --check -f Justfile - -# Fix Just Syntax -[group('Just')] -fix: - #!/usr/bin/bash - find . -type f -name "*.just" | while read -r file; do - echo "Checking syntax: $file" - {{ just }} --unstable --fmt -f $file - done - echo "Checking syntax: Justfile" - {{ just }} --unstable --fmt -f Justfile || { exit 1; } - -# Clean Repo -[group('Utility')] -clean: - #!/usr/bin/bash - set -eoux pipefail - rm -rf output/ - rm -rf common/ - rm -f *.iso* - rm -f flatpaks.list - -# Check if valid combo -[group('Utility')] -[private] -validate $image $tag $flavor: - #!/usr/bin/bash - set -eou pipefail - declare -A images={{ images }} - declare -A tags={{ tags }} - declare -A flavors={{ flavors }} - - # Handle Stable Daily - if [[ "${tag}" == "stable-daily" ]]; then - tag="stable" - fi - - checkimage="${images[${image}]-}" - checktag="${tags[${tag}]-}" - checkflavor="${flavors[${flavor}]-}" - - # Validity Checks - if [[ -z "$checkimage" ]]; then - echo "Invalid Image..." - exit 1 - fi - if [[ -z "$checktag" ]]; then - echo "Invalid tag..." - exit 1 - fi - if [[ -z "$checkflavor" ]]; then - echo "Invalid flavor..." - exit 1 - fi - -# Image Name -[group('Utility')] -image_name image="aurora" tag="stable" flavor="main": - #!/usr/bin/bash - set -eou pipefail - {{ just }} validate {{ image }} {{ tag }} {{ flavor }} - if [[ "{{ flavor }}" =~ main ]]; then - image_name={{ image }} - else - image_name="{{ image }}-{{ flavor }}" - fi - echo "${image_name}" - -# Clone Common Repository -[group('ISO')] -clone-common: - #!/usr/bin/bash - set -eoux pipefail - if [[ ! -d "common" ]]; then - git clone https://github.com/get-aurora-dev/common.git common - else - echo "Common repository already cloned" - fi - -# Generate Flatpak List -[group('ISO')] -generate-flatpak-list: - #!/usr/bin/bash - set -eoux pipefail - {{ just }} clone-common - find common -iname "*system-flatpaks.Brewfile" -exec cat '{}' ';' | \ - grep -v '#' | \ - grep -F -e "flatpak" | \ - sed 's/flatpak //' | \ - tr -d '"' | \ - tee flatpaks.list - -# Verify Container with Cosign -[group('Utility')] -verify-container container="" registry="ghcr.io/ublue-os" key="": - #!/usr/bin/bash - set -eou pipefail - - # Get Cosign if Needed - if [[ ! $(command -v cosign) ]]; then - COSIGN_CONTAINER_ID=$(${SUDOIF} ${PODMAN} create cgr.dev/chainguard/cosign:latest bash) - ${SUDOIF} ${PODMAN} cp "${COSIGN_CONTAINER_ID}":/usr/bin/cosign /usr/local/bin/cosign - ${SUDOIF} ${PODMAN} rm -f "${COSIGN_CONTAINER_ID}" - fi - - # Verify Cosign Image Signatures if needed - if [[ -n "${COSIGN_CONTAINER_ID:-}" ]]; then - if ! cosign verify --certificate-oidc-issuer=https://token.actions.githubusercontent.com --certificate-identity=https://github.com/chainguard-images/images/.github/workflows/release.yaml@refs/heads/main cgr.dev/chainguard/cosign >/dev/null; then - echo "NOTICE: Failed to verify cosign image signatures." - exit 1 - fi - fi - - # Public Key for Container Verification - key={{ key }} - if [[ -z "${key:-}" ]]; then - key="https://raw.githubusercontent.com/ublue-os/main/main/cosign.pub" - fi - - # Verify Container using cosign public key - if ! cosign verify --key "${key}" "{{ registry }}"/"{{ container }}" >/dev/null; then - echo "NOTICE: Verification failed. Please ensure your public key is correct." - exit 1 - fi - -# Test ISO Configuration Script -[group('ISO')] -test-iso-config: - #!/usr/bin/bash - set -eoux pipefail - bash -n iso_files/configure_iso_anaconda-webui.sh - echo "ISO configuration script syntax is valid" diff --git a/README.md b/README.md index 6b247a8..d648534 100644 --- a/README.md +++ b/README.md @@ -31,14 +31,11 @@ Testing ISOs are available [here](https://docs.getaurora.dev/guides/iso-testing) │ └── workflows/ │ ├── build-iso-stable.yml # Caller workflow for stable ISOs │ ├── reusable-build-iso-anaconda.yml # Reusable ISO build workflow -│ ├── promote-iso.yml # ISO promotion workflow -│ └── validate-just.yml # Justfile validation +│ └── promote-iso.yml # ISO promotion workflow ├── iso_files/ │ ├── configure_iso_anaconda.sh # ISO configuration script │ └── scope_installer.png # Installer branding ├── .pre-commit-config.yaml # Pre-commit hooks -├── AGENTS.md # AI agent documentation -├── Justfile # Build automation recipes └── README.md # This file ``` @@ -49,10 +46,6 @@ Testing ISOs are available [here](https://docs.getaurora.dev/guides/iso-testing) ISOs are built using GitHub Actions, but you can validate your changes locally: ```bash -# Install Just command runner -curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to ~/.local/bin -export PATH="$HOME/.local/bin:$PATH" - # Install pre-commit pip install pre-commit pre-commit install @@ -66,36 +59,9 @@ Before submitting changes, validate your code: # Check all syntax and formatting pre-commit run --all-files -# Validate Justfile syntax -just check - -# Test ISO configuration script -just test-iso-config - -# Auto-fix formatting issues -just fix -``` - -### Available Just Recipes - -```bash -# List all available recipes -just --list - -# Clean build artifacts -just clean - -# Clone common repository (flatpak lists) -just clone-common - -# Generate flatpak list from common repo -just generate-flatpak-list - -# Get image name for specific combination -just image_name aurora stable main - -# Validate image/tag/flavor combination -just validate aurora stable nvidia-open +# Test ISO configuration script syntax +bash -n iso_files/configure_iso_anaconda.sh +bash -n iso_files/build.sh ``` ## ISO Variants @@ -160,12 +126,11 @@ The workflow builds ISOs for: 1. Maximize build space (removes unnecessary software) 2. Checkout repository -3. Validate Just syntax -4. Format image reference -5. Generate flatpak list dynamically from Brewfiles in common repo -6. Build ISO with Titanoboa -7. Generate checksums -8. Upload to CloudFlare R2 test bucket (scheduled builds) or GitHub artifacts (configurable via inputs) +3. Format image reference +4. Generate flatpak list dynamically from Brewfiles in common repo +5. Build ISO with Titanoboa +6. Generate checksums +7. Upload to CloudFlare R2 test bucket (scheduled builds) or GitHub artifacts (configurable via inputs) #### Upload Behavior @@ -214,8 +179,8 @@ Contributions are welcome! Please follow these guidelines: ### Before Committing -1. Run validation: `just check && pre-commit run --all-files` -2. Test ISO script syntax: `just test-iso-config` +1. Run validation: `pre-commit run --all-files` +2. Test ISO script syntax: `bash -n iso_files/configure_iso_anaconda.sh && bash -n iso_files/build.sh` 3. Use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/#specification) 4. Keep changes minimal and focused @@ -242,7 +207,6 @@ Contributions are welcome! Please follow these guidelines: - [Aurora Documentation](https://docs.getaurora.dev/) - [Universal Blue Docs](https://universal-blue.org/) -- [AGENTS.md](AGENTS.md) - Comprehensive guide for AI-assisted development - [Titanoboa](https://github.com/ublue-os/titanoboa) - ISO builder tool ## Resources diff --git a/iso_files/build.sh b/iso_files/build.sh new file mode 100755 index 0000000..99a0dc1 --- /dev/null +++ b/iso_files/build.sh @@ -0,0 +1,123 @@ +#!/usr/bin/bash + +set -exo pipefail + +{ export PS4='+( ${BASH_SOURCE}:${LINENO} ): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'; } 2>/dev/null + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Create the directory that /root is symlinked to +mkdir -p "$(realpath /root)" + +# bwrap tries to write /proc/sys/user/max_user_namespaces which is mounted as ro +# so we need to remount it as rw +mount -o remount,rw /proc/sys + +# Install flatpaks if list exists +if [[ -f "$SCRIPT_DIR/flatpaks.list" ]]; then + echo "Installing flatpaks..." + curl --retry 3 -Lo /etc/flatpak/remotes.d/flathub.flatpakrepo https://dl.flathub.org/repo/flathub.flatpakrepo + xargs -r flatpak install -y --noninteractive < "$SCRIPT_DIR/flatpaks.list" || true +fi + +# Configure podman temporarily to write to /usr/lib/containers/storage +# This avoids storing the huge base image in /var/lib/containers/storage +# (which is empty/tmpfs in the booted live environment and would exhaust RAM) +mkdir -p /etc/containers +cat >/etc/containers/storage.conf <<'EOF' +[storage] +driver = "overlay" +runroot = "/run/containers/storage" +graphroot = "/usr/lib/containers/storage" +EOF + +# Pull the container image to be installed +if [[ -n "${BASE_IMAGE:-}" ]]; then + podman pull "${BASE_IMAGE}" +else + # Fallback to reading image-info.json if BASE_IMAGE not set + IMAGE_INFO="$(cat /usr/share/ublue-os/image-info.json)" + IMAGE_TAG="$(jq -c -r '."image-tag"' <<<"$IMAGE_INFO")" + IMAGE_REF="$(jq -c -r '."image-ref"' <<<"$IMAGE_INFO")" + IMAGE_REF="${IMAGE_REF##*://}" + podman pull "${IMAGE_REF}:${IMAGE_TAG}" +fi + +# Clean up the temporary storage configuration so that runtime podman uses the default +rm -f /etc/containers/storage.conf + +# Install required packages +dnf install -y \ + dracut-live \ + livesys-scripts \ + git \ + jq \ + rsync \ + desktop-file-utils \ + anaconda-live \ + anaconda-webui \ + libblockdev-btrfs \ + libblockdev-lvm \ + libblockdev-dm + +kernel=$(find /usr/lib/modules -maxdepth 1 -type d -printf '%P\n' | grep . | head -1) +DRACUT_NO_XATTR=1 dracut -v --force --zstd --reproducible --no-hostonly \ + --add "dmsquash-live dmsquash-live-autooverlay" \ + "/usr/lib/modules/${kernel}/initramfs.img" "${kernel}" + +# Configure livesys-scripts +sed -i "s/^livesys_session=.*/livesys_session=kde/" /etc/sysconfig/livesys +systemctl enable livesys.service livesys-late.service + +# Run the configure/postrootfs hook +# We pass BASE_IMAGE so it can be used inside the script +export BASE_IMAGE="${BASE_IMAGE:-}" +bash "$SCRIPT_DIR/configure_iso_anaconda.sh" + +# image-builder needs gcdx64.efi / grub modules +_arch=$(uname -m) +if [[ $_arch == "x86_64" ]]; then + dnf install -y grub2-efi-x64-cdboot +elif [[ $_arch == "aarch64" ]]; then + dnf install -y grub2-efi-aa64-modules +fi + +# image-builder expects the EFI directory to be in /boot/efi +mkdir -p /boot/efi +cp -av /usr/lib/efi/*/*/EFI /boot/efi/ + +# Remove fallback efi +_arch=$(uname -m) +if [[ $_arch == "x86_64" ]]; then + cp -v /boot/efi/EFI/fedora/grubx64.efi /boot/efi/EFI/BOOT/fbx64.efi +elif [[ $_arch == "aarch64" ]]; then + cp -v /boot/efi/EFI/fedora/grubaa64.efi /boot/efi/EFI/BOOT/fbaa64.efi +fi + +# Set the timezone to UTC +rm -f /etc/localtime +systemd-firstboot --timezone UTC + +# Mount a larger tmpfs to /var/tmp at boot time to avoid disk space issues +mkdir -p /var/tmp +cat >/etc/systemd/system/var-tmp.mount <<'EOF' +[Unit] +Description=Larger tmpfs for /var/tmp on live system + +[Mount] +What=tmpfs +Where=/var/tmp +Type=tmpfs +Options=size=50%,nr_inodes=1m,x-systemd.graceful-option=usrquota + +[Install] +WantedBy=local-fs.target +EOF +systemctl enable var-tmp.mount + +# Copy in the iso config for image-builder +mkdir -p /usr/lib/bootc-image-builder +cp "$SCRIPT_DIR/iso.yaml" /usr/lib/bootc-image-builder/iso.yaml + +# Clean up dnf cache to save space +dnf clean all diff --git a/iso_files/configure_iso_anaconda.sh b/iso_files/configure_iso_anaconda.sh index c96d9cb..4a613ae 100644 --- a/iso_files/configure_iso_anaconda.sh +++ b/iso_files/configure_iso_anaconda.sh @@ -2,10 +2,15 @@ set -eoux pipefail -IMAGE_INFO="$(cat /usr/share/ublue-os/image-info.json)" -IMAGE_TAG="$(jq -c -r '."image-tag"' <<<"$IMAGE_INFO")" -IMAGE_REF="$(jq -c -r '."image-ref"' <<<"$IMAGE_INFO")" -IMAGE_REF="${IMAGE_REF##*://}" +if [[ -n "${BASE_IMAGE:-}" ]]; then + IMAGE_REF="${BASE_IMAGE%%:*}" + IMAGE_TAG="${BASE_IMAGE##*:}" +else + IMAGE_INFO="$(cat /usr/share/ublue-os/image-info.json)" + IMAGE_TAG="$(jq -c -r '."image-tag"' <<<"$IMAGE_INFO")" + IMAGE_REF="$(jq -c -r '."image-ref"' <<<"$IMAGE_INFO")" + IMAGE_REF="${IMAGE_REF##*://}" +fi sbkey='https://github.com/ublue-os/akmods/raw/main/certs/public_key.der' # Configure Live Environment @@ -24,21 +29,10 @@ rm /usr/share/applications/dev.getaurora.system-update.desktop systemctl --global disable bazaar.service -# Configure Anaconda - -SPECS=( - "libblockdev-btrfs" - "libblockdev-lvm" - "libblockdev-dm" - "anaconda-live" - "anaconda-webui" -) - -dnf install -y "${SPECS[@]}" - # Anaconda Profile Detection # Aurora +mkdir -p /etc/anaconda/profile.d tee /etc/anaconda/profile.d/aurora.conf <<'EOF' # Anaconda configuration file for Aurora diff --git a/iso_files/iso.yaml b/iso_files/iso.yaml new file mode 100644 index 0000000..4d8a564 --- /dev/null +++ b/iso_files/iso.yaml @@ -0,0 +1,10 @@ +label: "Aurora-Live" +grub2: + timeout: 10 + entries: + - name: "Aurora Live ISO" + linux: "/images/pxeboot/vmlinuz quiet rhgb root=live:CDLABEL=Aurora-Live enforcing=0 rd.live.image" + initrd: "/images/pxeboot/initrd.img" + - name: "Aurora Live ISO (Safe Graphics Mode)" + linux: "/images/pxeboot/vmlinuz quiet rhgb root=live:CDLABEL=Aurora-Live enforcing=0 rd.live.image nomodeset" + initrd: "/images/pxeboot/initrd.img"