From d4e84b0e41d92db0343d4c6b481ab0066c1a1090 Mon Sep 17 00:00:00 2001 From: randogoth Date: Mon, 22 Dec 2025 21:13:22 +0200 Subject: [PATCH 1/6] daemonix approach --- files/scripts/install-nix.sh | 13 +++++++++++ files/system/etc/modules-load.d/overlay.conf | 1 + files/system/usr/bin/mount-nix-overlay.sh | 13 +++++++++++ files/system/usr/bin/nix-toolbox-ensure | 22 ------------------- .../lib/systemd/system/nix-overlay.service | 14 ++++++++++++ .../systemd/user/nix-toolbox-create.service | 14 ------------ recipes/recipe.yml | 9 ++++++-- 7 files changed, 48 insertions(+), 38 deletions(-) create mode 100755 files/scripts/install-nix.sh create mode 100644 files/system/etc/modules-load.d/overlay.conf create mode 100755 files/system/usr/bin/mount-nix-overlay.sh delete mode 100755 files/system/usr/bin/nix-toolbox-ensure create mode 100644 files/system/usr/lib/systemd/system/nix-overlay.service delete mode 100644 files/system/usr/lib/systemd/user/nix-toolbox-create.service diff --git a/files/scripts/install-nix.sh b/files/scripts/install-nix.sh new file mode 100755 index 0000000..39a0332 --- /dev/null +++ b/files/scripts/install-nix.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +rpm_url="https://nix-community.github.io/nix-installers/nix/x86_64/nix-multi-user-2.24.10.rpm" + +install -d /usr/share/nix-store /var/lib/nix-store /var/cache/nix-store /nix + +dnf install -y "$rpm_url" + +# Move the pre-populated store out of /nix so it can serve as the immutable lowerdir. +if compgen -G "/nix/*" >/dev/null; then + mv /nix/* /usr/share/nix-store/ +fi diff --git a/files/system/etc/modules-load.d/overlay.conf b/files/system/etc/modules-load.d/overlay.conf new file mode 100644 index 0000000..08047cf --- /dev/null +++ b/files/system/etc/modules-load.d/overlay.conf @@ -0,0 +1 @@ +overlay diff --git a/files/system/usr/bin/mount-nix-overlay.sh b/files/system/usr/bin/mount-nix-overlay.sh new file mode 100755 index 0000000..22ad012 --- /dev/null +++ b/files/system/usr/bin/mount-nix-overlay.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +mkdir -p /usr/share/nix-store /var/lib/nix-store /var/cache/nix-store /nix + +# Skip if already mounted to avoid errors on reload. +if mountpoint -q /nix; then + exit 0 +fi + +mount -t overlay overlay \ + -o lowerdir=/usr/share/nix-store,upperdir=/var/lib/nix-store,workdir=/var/cache/nix-store \ + /nix diff --git a/files/system/usr/bin/nix-toolbox-ensure b/files/system/usr/bin/nix-toolbox-ensure deleted file mode 100755 index 690afc4..0000000 --- a/files/system/usr/bin/nix-toolbox-ensure +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -image_ref="${NIX_TOOLBOX_IMAGE:-ghcr.io/thrix/nix-toolbox:42}" -container_name="${NIX_TOOLBOX_CONTAINER:-nix-toolbox-42}" - -if ! command -v toolbox >/dev/null 2>&1; then - echo "toolbox not installed; skipping nix-toolbox setup" >&2 - exit 0 -fi - -if ! command -v podman >/dev/null 2>&1; then - echo "podman not installed; skipping nix-toolbox setup" >&2 - exit 0 -fi - -if podman container exists "$container_name"; then - exit 0 -fi - -echo "Creating $container_name from $image_ref" -distrobox create --name "$container_name" --image "$image_ref" diff --git a/files/system/usr/lib/systemd/system/nix-overlay.service b/files/system/usr/lib/systemd/system/nix-overlay.service new file mode 100644 index 0000000..df9b154 --- /dev/null +++ b/files/system/usr/lib/systemd/system/nix-overlay.service @@ -0,0 +1,14 @@ +[Unit] +Description=Mount OverlayFS for /nix +DefaultDependencies=no +After=local-fs.target +Before=nix-daemon.service +ConditionPathExists=/usr/bin/mount-nix-overlay.sh + +[Service] +Type=oneshot +ExecStart=/usr/bin/mount-nix-overlay.sh +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/files/system/usr/lib/systemd/user/nix-toolbox-create.service b/files/system/usr/lib/systemd/user/nix-toolbox-create.service deleted file mode 100644 index 686483a..0000000 --- a/files/system/usr/lib/systemd/user/nix-toolbox-create.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=Ensure nix-toolbox container is available for this user -After=network-online.target -Wants=network-online.target - -[Service] -Type=oneshot -ExecStart=/usr/bin/nix-toolbox-ensure -RemainAfterExit=yes -Restart=on-failure -RestartSec=10 - -[Install] -WantedBy=default.target diff --git a/recipes/recipe.yml b/recipes/recipe.yml index b9356c8..b208b11 100644 --- a/recipes/recipe.yml +++ b/recipes/recipe.yml @@ -18,10 +18,15 @@ modules: - source: system destination: / # copies files/system/* (* means everything inside it) into your image's root folder / + - type: script + scripts: + - files/scripts/install-nix.sh + - type: systemd - user: + system: enabled: - - nix-toolbox-create.service + - nix-overlay.service + - nix-daemon.service - type: dnf install: From 4de510d1f9e316b5660eddd3c96306afbf2db20f Mon Sep 17 00:00:00 2001 From: randogoth Date: Mon, 22 Dec 2025 21:21:02 +0200 Subject: [PATCH 2/6] script fix --- recipes/recipe.yml | 2 +- {files/scripts => scripts}/install-nix.sh | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {files/scripts => scripts}/install-nix.sh (100%) diff --git a/recipes/recipe.yml b/recipes/recipe.yml index b208b11..93eccea 100644 --- a/recipes/recipe.yml +++ b/recipes/recipe.yml @@ -20,7 +20,7 @@ modules: - type: script scripts: - - files/scripts/install-nix.sh + - install-nix.sh - type: systemd system: diff --git a/files/scripts/install-nix.sh b/scripts/install-nix.sh similarity index 100% rename from files/scripts/install-nix.sh rename to scripts/install-nix.sh From 9e859af388c5c3c1bedd7096df5cc79e5eb51af3 Mon Sep 17 00:00:00 2001 From: randogoth Date: Mon, 22 Dec 2025 21:56:28 +0200 Subject: [PATCH 3/6] ignore gpg --- .gitignore | 1 + {scripts => files/scripts}/install-nix.sh | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) rename {scripts => files/scripts}/install-nix.sh (51%) diff --git a/.gitignore b/.gitignore index 8703795..8199d78 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ cosign.key cosign.private /Containerfile +/.bluebuild-scripts_* diff --git a/scripts/install-nix.sh b/files/scripts/install-nix.sh similarity index 51% rename from scripts/install-nix.sh rename to files/scripts/install-nix.sh index 39a0332..05e0457 100755 --- a/scripts/install-nix.sh +++ b/files/scripts/install-nix.sh @@ -5,9 +5,16 @@ rpm_url="https://nix-community.github.io/nix-installers/nix/x86_64/nix-multi-use install -d /usr/share/nix-store /var/lib/nix-store /var/cache/nix-store /nix -dnf install -y "$rpm_url" +# Avoid systemd calls during RPM %post in the image build environment. +export SYSTEMD_OFFLINE=1 + +# Install the RPM; allow missing GPG key since we fetch directly by URL. +dnf install -y --nogpgcheck "$rpm_url" # Move the pre-populated store out of /nix so it can serve as the immutable lowerdir. if compgen -G "/nix/*" >/dev/null; then mv /nix/* /usr/share/nix-store/ fi + +# The RPM %post handles sysusers/tmpfiles; if we ran with SYSTEMD_OFFLINE the +# post scripts are still executed, so no extra calls are needed here. From 9d5b4ddecd2cd8b672c8f358150f7f8b57a2b31d Mon Sep 17 00:00:00 2001 From: randogoth Date: Tue, 23 Dec 2025 19:34:21 +0200 Subject: [PATCH 4/6] nix package installer --- files/scripts/example.sh | 6 ------ files/scripts/nixpkgs.sh | 23 +++++++++++++++++++++++ recipes/recipe.yml | 5 ++++- 3 files changed, 27 insertions(+), 7 deletions(-) delete mode 100644 files/scripts/example.sh create mode 100644 files/scripts/nixpkgs.sh diff --git a/files/scripts/example.sh b/files/scripts/example.sh deleted file mode 100644 index 1cded87..0000000 --- a/files/scripts/example.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -# Tell this script to exit if there are any errors. -# You should have this in every custom script, to ensure that your completed -# builds actually ran successfully without any errors! -set -oue pipefail \ No newline at end of file diff --git a/files/scripts/nixpkgs.sh b/files/scripts/nixpkgs.sh new file mode 100644 index 0000000..cd7ecf9 --- /dev/null +++ b/files/scripts/nixpkgs.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -oue pipefail +nix run github:nix-community/home-manager/release-25.11 -- init --switch + +pkgs='uv micro vscodium mc lagrange' +f=~/.config/home-manager/home.nix +tmp="$(mktemp)" +{ + echo " home.packages = [" + for p in $pkgs; do echo " pkgs.$p"; done + echo " ];" +} > "$tmp" + +sed -i "/^[[:space:]]*home\.packages[[:space:]]*=[[:space:]]*\[/,/^[[:space:]]*];[[:space:]]*$/{ + /^[[:space:]]*home\.packages[[:space:]]*=/{ + r $tmp + } + d +}" "$f" + +rm -f "$tmp" + +home-manager switch diff --git a/recipes/recipe.yml b/recipes/recipe.yml index 93eccea..d1b2bb9 100644 --- a/recipes/recipe.yml +++ b/recipes/recipe.yml @@ -60,10 +60,13 @@ modules: # If no repo information is specified, Flathub will be used by default install: # system flatpaks we want all users to have and not remove - net.waterfox.waterfox - - com.vscodium.codium - org.telegram.desktop remove: # replace default Firefox with Waterfox - org.mozilla.firefox - scope: user # Also add Flathub user repo, but no user packages + - type: script + scripts: + - nixpkgs.sh + - type: signing # this sets up the proper policy & signing files for signed images to work fully From 83e657e74be75aab96d6af3956a7599f85829216 Mon Sep 17 00:00:00 2001 From: randogoth Date: Tue, 23 Dec 2025 20:35:57 +0200 Subject: [PATCH 5/6] bootstrap home manager and nix packages on login --- README.md | 59 +++++++++---------- files/scripts/nixpkgs.sh | 24 +------- .../randofin-nixpkgs-init.service | 1 + .../user/randofin-nixpkgs-init.service | 13 ++++ .../system/usr/libexec/randofin-os/nixpkgs.sh | 23 ++++++++ recipes/recipe.yml | 4 -- 6 files changed, 67 insertions(+), 57 deletions(-) mode change 100644 => 120000 files/scripts/nixpkgs.sh create mode 120000 files/system/usr/lib/systemd/user/default.target.wants/randofin-nixpkgs-init.service create mode 100644 files/system/usr/lib/systemd/user/randofin-nixpkgs-init.service create mode 100755 files/system/usr/libexec/randofin-os/nixpkgs.sh diff --git a/README.md b/README.md index 351f8a0..2097600 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,42 @@ # randofin-os   [![bluebuild build badge](https://github.com/randogoth/randofin-os/actions/workflows/build.yml/badge.svg)](https://github.com/randogoth/randofin-os/actions/workflows/build.yml) -See the [BlueBuild docs](https://blue-build.org/how-to/setup/) for quick setup instructions for setting up your own repository based on this template. +randofin-os is a personal spin of the UBlue Bluefin DX image with Nix baked in and a first-login bootstrap for home-manager packages. -After setup, it is recommended you update this README to describe your custom image. +## What’s inside +- Base: `ghcr.io/ublue-os/bluefin-dx:latest` without Cockpit, Docker, Firefox, VS Code +- Nix: multi-user install baked in; `nix-overlay.service` and `nix-daemon.service` enabled. +- First-login bootstrap: installs nix packages `uv micro vscodium mc` via `home-manager`. +- System packages added: `syncthing`, `waydroid`; +- System flatpaks added: Telegram Desktop, Waterfox -## Installation +## First login behavior +- Triggers for each non-root user on their first session. +- Writes state to `~/.local/state/randofin-os/nixpkgs-init.done`; delete it to rerun. +- Bootstraps `~/.config/home-manager/home.nix` and runs `home-manager switch` with the package set above. -> [!WARNING] -> [This is an experimental feature](https://www.fedoraproject.org/wiki/Changes/OstreeNativeContainerStable), try at your own discretion. +## Install / Rebase +> [!WARNING] +> Uses the Fedora Atomic native container workflow. -To rebase an existing atomic Fedora installation to the latest build: +```bash +# First pull unsigned to get signing policy +rpm-ostree rebase ostree-unverified-registry:ghcr.io/randogoth/randofin-os:latest +systemctl reboot -- First rebase to the unsigned image, to get the proper signing keys and policies installed: - ``` - rpm-ostree rebase ostree-unverified-registry:ghcr.io/randogoth/randofin-os:latest - ``` -- Reboot to complete the rebase: - ``` - systemctl reboot - ``` -- Then rebase to the signed image, like so: - ``` - rpm-ostree rebase ostree-image-signed:docker://ghcr.io/randogoth/randofin-os:latest - ``` -- Reboot again to complete the installation - ``` - systemctl reboot - ``` +# Then move to the signed image +rpm-ostree rebase ostree-image-signed:docker://ghcr.io/randogoth/randofin-os:latest +systemctl reboot +``` -The `latest` tag will automatically point to the latest build. That build will still always use the Fedora version specified in `recipe.yml`, so you won't get accidentally updated to the next major version. +The `latest` tag always tracks the latest build for the Fedora base set in `recipes/recipe.yml`. -## ISO - -If build on Fedora Atomic, you can generate an offline ISO with the instructions available [here](https://blue-build.org/learn/universal-blue/#fresh-install-from-an-iso). These ISOs cannot unfortunately be distributed on GitHub for free due to large sizes, so for public projects something else has to be used for hosting. - -## Verification - -These images are signed with [Sigstore](https://www.sigstore.dev/)'s [cosign](https://github.com/sigstore/cosign). You can verify the signature by downloading the `cosign.pub` file from this repo and running the following command: +## Building locally +```bash +bluebuild build --recipe recipes/recipe.yml +``` +## Signature verification +Images are signed with Sigstore/cosign. Verify with the repo's `cosign.pub`: ```bash cosign verify --key cosign.pub ghcr.io/randogoth/randofin-os ``` diff --git a/files/scripts/nixpkgs.sh b/files/scripts/nixpkgs.sh deleted file mode 100644 index cd7ecf9..0000000 --- a/files/scripts/nixpkgs.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash -set -oue pipefail -nix run github:nix-community/home-manager/release-25.11 -- init --switch - -pkgs='uv micro vscodium mc lagrange' -f=~/.config/home-manager/home.nix -tmp="$(mktemp)" -{ - echo " home.packages = [" - for p in $pkgs; do echo " pkgs.$p"; done - echo " ];" -} > "$tmp" - -sed -i "/^[[:space:]]*home\.packages[[:space:]]*=[[:space:]]*\[/,/^[[:space:]]*];[[:space:]]*$/{ - /^[[:space:]]*home\.packages[[:space:]]*=/{ - r $tmp - } - d -}" "$f" - -rm -f "$tmp" - -home-manager switch diff --git a/files/scripts/nixpkgs.sh b/files/scripts/nixpkgs.sh new file mode 120000 index 0000000..a232a07 --- /dev/null +++ b/files/scripts/nixpkgs.sh @@ -0,0 +1 @@ +../system/usr/libexec/randofin-os/nixpkgs.sh \ No newline at end of file diff --git a/files/system/usr/lib/systemd/user/default.target.wants/randofin-nixpkgs-init.service b/files/system/usr/lib/systemd/user/default.target.wants/randofin-nixpkgs-init.service new file mode 120000 index 0000000..5f245da --- /dev/null +++ b/files/system/usr/lib/systemd/user/default.target.wants/randofin-nixpkgs-init.service @@ -0,0 +1 @@ +../randofin-nixpkgs-init.service \ No newline at end of file diff --git a/files/system/usr/lib/systemd/user/randofin-nixpkgs-init.service b/files/system/usr/lib/systemd/user/randofin-nixpkgs-init.service new file mode 100644 index 0000000..5d5aa9e --- /dev/null +++ b/files/system/usr/lib/systemd/user/randofin-nixpkgs-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Install Nix Home Manager and packages on first login +ConditionUser=!root +ConditionPathExists=!%h/.local/state/randofin-os/nixpkgs-init.done + +[Service] +Type=oneshot +ExecStart=/usr/libexec/randofin-os/nixpkgs.sh +ExecStartPost=/usr/bin/mkdir -p %h/.local/state/randofin-os +ExecStartPost=/usr/bin/touch %h/.local/state/randofin-os/nixpkgs-init.done + +[Install] +WantedBy=default.target diff --git a/files/system/usr/libexec/randofin-os/nixpkgs.sh b/files/system/usr/libexec/randofin-os/nixpkgs.sh new file mode 100755 index 0000000..dae46d0 --- /dev/null +++ b/files/system/usr/libexec/randofin-os/nixpkgs.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -oue pipefail +nix run github:nix-community/home-manager/release-25.11 -- init --switch + +pkgs='uv micro vscodium mc' +f=~/.config/home-manager/home.nix +tmp="$(mktemp)" +{ + echo " home.packages = [" + for p in $pkgs; do echo " pkgs.$p"; done + echo " ];" +} > "$tmp" + +sed -i "/^[[:space:]]*home\.packages[[:space:]]*=[[:space:]]*\[/,/^[[:space:]]*];[[:space:]]*$/{ + /^[[:space:]]*home\.packages[[:space:]]*=/{ + r $tmp + } + d +}" "$f" + +rm -f "$tmp" + +home-manager switch diff --git a/recipes/recipe.yml b/recipes/recipe.yml index d1b2bb9..0130d9d 100644 --- a/recipes/recipe.yml +++ b/recipes/recipe.yml @@ -65,8 +65,4 @@ modules: - org.mozilla.firefox - scope: user # Also add Flathub user repo, but no user packages - - type: script - scripts: - - nixpkgs.sh - - type: signing # this sets up the proper policy & signing files for signed images to work fully From 46955716545a3ec52e89fb28d956ed0253e22474 Mon Sep 17 00:00:00 2001 From: randogoth Date: Tue, 23 Dec 2025 21:11:11 +0200 Subject: [PATCH 6/6] renamed --- README.md | 14 +++++++------- .../lib/systemd/user/randofin-nixpkgs-init.service | 8 ++++---- .../libexec/{randofin-os => deinonyxus}/nixpkgs.sh | 0 recipes/recipe.yml | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) rename files/system/usr/libexec/{randofin-os => deinonyxus}/nixpkgs.sh (100%) diff --git a/README.md b/README.md index 2097600..5d78b16 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# randofin-os   [![bluebuild build badge](https://github.com/randogoth/randofin-os/actions/workflows/build.yml/badge.svg)](https://github.com/randogoth/randofin-os/actions/workflows/build.yml) +# Deinonyxus   [![bluebuild build badge](https://github.com/randogoth/deinonyxus/actions/workflows/build.yml/badge.svg)](https://github.com/randogoth/deinonyxus/actions/workflows/build.yml) -randofin-os is a personal spin of the UBlue Bluefin DX image with Nix baked in and a first-login bootstrap for home-manager packages. +*Deinonyxus* is a personal spin of the UBlue Bluefin DX image with experimental Nix package manager baked in (borrowed from the great [Daemonix](https://github.com/DXC-0/daemonix/) image) and a first-login bootstrap for `home-manager` packages. ## What’s inside - Base: `ghcr.io/ublue-os/bluefin-dx:latest` without Cockpit, Docker, Firefox, VS Code @@ -11,7 +11,7 @@ randofin-os is a personal spin of the UBlue Bluefin DX image with Nix baked in a ## First login behavior - Triggers for each non-root user on their first session. -- Writes state to `~/.local/state/randofin-os/nixpkgs-init.done`; delete it to rerun. +- Writes state to `~/.local/state/deinonyxus/nixpkgs-init.done`; delete it to rerun. - Bootstraps `~/.config/home-manager/home.nix` and runs `home-manager switch` with the package set above. ## Install / Rebase @@ -20,11 +20,11 @@ randofin-os is a personal spin of the UBlue Bluefin DX image with Nix baked in a ```bash # First pull unsigned to get signing policy -rpm-ostree rebase ostree-unverified-registry:ghcr.io/randogoth/randofin-os:latest +rpm-ostree rebase ostree-unverified-registry:ghcr.io/randogoth/deinonyxus:latest systemctl reboot # Then move to the signed image -rpm-ostree rebase ostree-image-signed:docker://ghcr.io/randogoth/randofin-os:latest +rpm-ostree rebase ostree-image-signed:docker://ghcr.io/randogoth/deinonyxus:latest systemctl reboot ``` @@ -38,5 +38,5 @@ bluebuild build --recipe recipes/recipe.yml ## Signature verification Images are signed with Sigstore/cosign. Verify with the repo's `cosign.pub`: ```bash -cosign verify --key cosign.pub ghcr.io/randogoth/randofin-os -``` +cosign verify --key cosign.pub ghcr.io/randogoth/deinonyxus +``` \ No newline at end of file diff --git a/files/system/usr/lib/systemd/user/randofin-nixpkgs-init.service b/files/system/usr/lib/systemd/user/randofin-nixpkgs-init.service index 5d5aa9e..4e1ca95 100644 --- a/files/system/usr/lib/systemd/user/randofin-nixpkgs-init.service +++ b/files/system/usr/lib/systemd/user/randofin-nixpkgs-init.service @@ -1,13 +1,13 @@ [Unit] Description=Install Nix Home Manager and packages on first login ConditionUser=!root -ConditionPathExists=!%h/.local/state/randofin-os/nixpkgs-init.done +ConditionPathExists=!%h/.local/state/deinonyxus/nixpkgs-init.done [Service] Type=oneshot -ExecStart=/usr/libexec/randofin-os/nixpkgs.sh -ExecStartPost=/usr/bin/mkdir -p %h/.local/state/randofin-os -ExecStartPost=/usr/bin/touch %h/.local/state/randofin-os/nixpkgs-init.done +ExecStart=/usr/libexec/deinonyxus/nixpkgs.sh +ExecStartPost=/usr/bin/mkdir -p %h/.local/state/deinonyxus +ExecStartPost=/usr/bin/touch %h/.local/state/deinonyxus/nixpkgs-init.done [Install] WantedBy=default.target diff --git a/files/system/usr/libexec/randofin-os/nixpkgs.sh b/files/system/usr/libexec/deinonyxus/nixpkgs.sh similarity index 100% rename from files/system/usr/libexec/randofin-os/nixpkgs.sh rename to files/system/usr/libexec/deinonyxus/nixpkgs.sh diff --git a/recipes/recipe.yml b/recipes/recipe.yml index 0130d9d..f169d3e 100644 --- a/recipes/recipe.yml +++ b/recipes/recipe.yml @@ -1,7 +1,7 @@ --- # yaml-language-server: $schema=https://schema.blue-build.org/recipe-v1.json # image will be published to ghcr.io// -name: randofin-os +name: deinonyxus # description will be included in the image's metadata description: This is my personal spin based on the latest bluefin image.