Skip to content

Use upstream-compatible Nix store path#46

Open
thrix-bot wants to merge 3 commits intothrix:mainfrom
thrix-bot:use-upstream-nix-store-path
Open

Use upstream-compatible Nix store path#46
thrix-bot wants to merge 3 commits intothrix:mainfrom
thrix-bot:use-upstream-nix-store-path

Conversation

@thrix-bot
Copy link
Copy Markdown
Contributor

@thrix-bot thrix-bot commented Apr 16, 2026

Summary

  • Use $XDG_DATA_HOME/nix/root/nix/ as the default bind mount source for new installs, matching the path used by upstream Nix's user namespace sandboxing (e.g. Fedora's nix-core package)
  • Existing installs with a store directly in $XDG_DATA_HOME/nix/ are auto-detected (by checking for $XDG_DATA_HOME/nix/store) and preserved
  • This enables sharing the Nix store between nix-toolbox and host Nix installations that use user namespace sandboxing

Closes #39

Assisted-by: Claude Code

Summary by Sourcery

Align the toolbox Nix store location with upstream user-namespace Nix defaults while preserving existing installs and document the new host integration model.

New Features:

  • Introduce automatic detection of legacy Nix stores in $XDG_DATA_HOME/nix and preserve them for existing installations.
  • Add documentation for the hostConfig Home Manager module that materializes Nix-managed config symlinks as real files for host access.

Enhancements:

  • Change the default persistent Nix store path to $XDG_DATA_HOME/nix/root/nix/ to match upstream Nix user namespace sandboxing and allow sharing the store with host Nix installations.

Documentation:

  • Update architecture documentation to describe the new default Nix store path and its compatibility with host Nix user-namespace setups.
  • Add a new host-config documentation page explaining how to expose Nix-managed configuration files from the container to the host using the hostConfig Home Manager module.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Apr 16, 2026

Reviewer's Guide

Adjusts nix-toolbox’s persistent Nix store layout to match upstream user-namespace sandboxing defaults, preserves legacy installs automatically, and updates documentation with details on the new path and a new host configuration module for Home Manager users.

Sequence diagram for Home Manager hostConfig activation during home-manager switch

sequenceDiagram
    actor User
    participant HomeManager
    participant hostConfigModule
    participant restoreNixLinks
    participant linkGeneration
    participant createHostConfig
    participant HostFilesystem as Host_filesystem
    participant HostApp as Host_application

    User ->> HomeManager: home-manager switch
    HomeManager ->> hostConfigModule: Evaluate configuration
    hostConfigModule ->> restoreNixLinks: Register pre-activation script
    hostConfigModule ->> createHostConfig: Register post-link script

    Note over restoreNixLinks,createHostConfig: Activation phase begins

    HomeManager ->> restoreNixLinks: Run restoreNixLinks (before checkLinkTargets)
    restoreNixLinks ->> HostFilesystem: Restore .lnk backups
    restoreNixLinks ->> HostFilesystem: Clean up leftover .new files

    HomeManager ->> linkGeneration: Run linkGeneration
    linkGeneration ->> HostFilesystem: Create / update symlinks into /nix/store

    HomeManager ->> createHostConfig: Run createHostConfig (after linkGeneration)
    createHostConfig ->> HostFilesystem: Copy symlink targets to real files
    createHostConfig ->> HostFilesystem: Atomically move temp files into place

    User ->> HostApp: Launch host application
    HostApp ->> HostFilesystem: Read materialized config files
Loading

Flow diagram for Nix store path selection and bind mounting

flowchart TD
    A_start([Start container / run nix.sh]) --> B_check_legacy{Does $XDG_DATA_HOME/nix/store exist?}

    B_check_legacy -- Yes --> C_set_legacy[Set NIX_STORE_DIR = $XDG_DATA_HOME/nix]
    B_check_legacy -- No --> D_set_new[Set NIX_STORE_DIR = $XDG_DATA_HOME/nix/root/nix]

    C_set_legacy --> E_mkdir
    D_set_new --> E_mkdir

    E_mkdir[mkdir -p $NIX_STORE_DIR] --> F_check_nix_exists{Does /nix exist?}

    F_check_nix_exists -- Yes --> G_is_dir{Is /nix a directory?}
    F_check_nix_exists -- No --> H_create_nix_dir[sudo mkdir -p /nix]

    G_is_dir -- No --> I_error_non_dir[/Print error: /nix exists but is not a directory/]
    I_error_non_dir --> J_exit1[Exit 1]

    G_is_dir -- Yes --> K_check_mount
    H_create_nix_dir --> K_check_mount

    K_check_mount{Is /nix a mountpoint?} -- Yes --> L_done([Done: persistent store already mounted])

    K_check_mount -- No --> M_bind_mount[sudo mount --bind $NIX_STORE_DIR /nix]
    M_bind_mount --> N_mount_ok{Bind mount succeeded?}

    N_mount_ok -- No --> O_error_mount[/Print error: Failed to bind-mount $NIX_STORE_DIR to /nix/]
    O_error_mount --> J_exit1

    N_mount_ok -- Yes --> P_done([Done: /nix bind-mounted from persistent store])
Loading

File-Level Changes

Change Details Files
Introduce XDG-based Nix store directory selection that preserves legacy installs and updates bind mount logic to use the selected path.
  • Add logic to choose NIX_STORE_DIR based on whether $XDG_DATA_HOME/nix/store exists, preferring an upstream-compatible $XDG_DATA_HOME/nix/root/nix path for new installs.
  • Ensure the chosen NIX_STORE_DIR directory is created before use.
  • Switch bind-mount command to mount the selected NIX_STORE_DIR to /nix, and update related error messages to reference the dynamic path.
nix.sh
Align architecture documentation with the new upstream-compatible Nix store layout and behavior.
  • Update description of first-time setup to state that the bind mount source is $XDG_DATA_HOME/nix/root/nix instead of $XDG_DATA_HOME/nix.
  • Revise host storage description to mention the new path, legacy path handling, and compatibility with host Nix using user namespace sandboxing.
  • Clarify benefit list to include compatibility with host Nix installations using user namespaces.
docs/architecture.md
Document a Home Manager "hostConfig" module that materializes Nix-managed config symlinks into real files for host visibility when running nix-toolbox containers on Fedora Atomic desktops.
  • Explain the problem of host programs being unable to resolve /nix/store-backed symlinks from outside the container and how the hostConfig module addresses it.
  • Describe the module’s activation scripts (restoreNixLinks and createHostConfig) and their sequencing around Home Manager’s activation steps.
  • Provide installation instructions for consuming the module as a flake output and example usage for configuring hostConfig settings.
  • Document the available hostConfig options, including enable, files, and xdgDesktopEntries, with their types, defaults, and behavior.
docs/host-config.md

Assessment against linked issues

Issue Objective Addressed Explanation
#39 Change the bind mount source for /nix from $XDG_DATA_HOME/nix (e.g. ~/.local/share/nix) to the upstream-compatible path $XDG_DATA_HOME/nix/root/nix/ (e.g. ~/.local/share/nix/root/nix/).
#39 Preserve existing installations that already use $XDG_DATA_HOME/nix as the Nix store, while allowing new installations to use the upstream-compatible path.
#39 Update documentation to reflect the new default Nix store path and its compatibility with upstream Nix user namespace sandboxing.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="nix.sh" line_range="46-50" />
<code_context>
+# Determine persistent Nix store location
+# New installs use upstream-compatible path: $XDG_DATA_HOME/nix/root/nix/
+# Existing installs with store directly in $XDG_DATA_HOME/nix/ are preserved
+if [ -d "$XDG_DATA_HOME/nix/store" ]; then
+    NIX_STORE_DIR="$XDG_DATA_HOME/nix"
+else
+    NIX_STORE_DIR="$XDG_DATA_HOME/nix/root/nix"
+fi
+
 # Ensure /nix is bind-mounted from persistent storage
</code_context>
<issue_to_address>
**issue:** Guard against XDG_DATA_HOME being unset to avoid accidentally probing /nix/store

When XDG_DATA_HOME is unset, this ends up probing `/nix/store`, which can incorrectly treat a system `/nix` as user data and change behavior based on the host. Consider either initializing XDG_DATA_HOME to a safe default earlier, or only running this logic when `[ -n "$XDG_DATA_HOME" ]` so it applies only when explicitly configured.
</issue_to_address>

### Comment 2
<location path="nix.sh" line_range="44-49" />
<code_context>
 export GUM_SPIN_TITLE="Please wait, this might take a while"

+# Determine persistent Nix store location
+# New installs use upstream-compatible path: $XDG_DATA_HOME/nix/root/nix/
+# Existing installs with store directly in $XDG_DATA_HOME/nix/ are preserved
+if [ -d "$XDG_DATA_HOME/nix/store" ]; then
+    NIX_STORE_DIR="$XDG_DATA_HOME/nix"
+else
+    NIX_STORE_DIR="$XDG_DATA_HOME/nix/root/nix"
+fi
+
</code_context>
<issue_to_address>
**suggestion:** Clarify whether NIX_STORE_DIR is intended to point to the Nix root or its parent

`NIX_STORE_DIR` is set to `$XDG_DATA_HOME/nix/root/nix` and then bind-mounted to `/nix`, but in usual setups `/nix` itself is the Nix root (containing `store`, `var`, etc.), not its parent. Please clarify in the comment whether `.../root/nix` is meant to be the actual Nix root or a container directory, and adjust either the directory layout or wording so it’s unambiguous how this relates to upstream’s `$XDG_DATA_HOME/nix/root` convention.
</issue_to_address>

### Comment 3
<location path="docs/host-config.md" line_range="5" />
<code_context>
+
+When running Home Manager inside a nix-toolbox container on Fedora Atomic Desktops, config files managed by Home Manager are symlinks pointing to `/nix/store/...` paths.
+The Nix store data lives on the host at `$XDG_DATA_HOME/nix/root/nix/` (or `$XDG_DATA_HOME/nix` for legacy installs), but the `/nix` bind mount only exists inside the container.
+Host-side programs like sway, waybar, foot, or firefox cannot resolve these symlinks — the config files are effectively invisible to the host.
+
+The `hostConfig` Home Manager module solves this by materializing symlinks as real files after each `home-manager switch`.
</code_context>
<issue_to_address>
**nitpick (typo):** Consider capitalizing “Firefox” to match its usual spelling.

Here, only “Firefox” should be capitalized to match standard usage, while the other program names remain lowercase.

```suggestion
Host-side programs like sway, waybar, foot, or Firefox cannot resolve these symlinks — the config files are effectively invisible to the host.
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread nix.sh
Comment thread nix.sh Outdated
Comment thread docs/host-config.md
thrix-bot and others added 3 commits April 16, 2026 23:52
Use `$XDG_DATA_HOME/nix/root/nix/` as the default bind mount source for
new installs, matching the path used by upstream Nix's user namespace
sandboxing (e.g. Fedora's `nix-core` package).

Existing installs with a store directly in `$XDG_DATA_HOME/nix/` are
auto-detected (by checking for `$XDG_DATA_HOME/nix/store`) and preserved.

This enables sharing the Nix store between nix-toolbox and host Nix
installations that use user namespace sandboxing.

Closes thrix#39

Assisted-by: Claude Code
Signed-off-by: thrix-bot <thrix-bot@users.noreply.github.com>
The variable holds the path to the Nix root directory (containing
`store/`, `var/`, etc.), not just the store. `NIX_ROOT_DIR` better
reflects its purpose as the bind mount source for `/nix`.

Assisted-by: Claude Code
Signed-off-by: thrix-bot <thrix-bot@users.noreply.github.com>
@thrix thrix force-pushed the use-upstream-nix-store-path branch from 98d23e9 to d6c28fa Compare April 16, 2026 21:52
@thrix
Copy link
Copy Markdown
Owner

thrix commented Apr 16, 2026

/test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

use ~/.local/share/nix/root/nix/ ?

2 participants