Skip to content

nixos/activation: use nixos-init during activation to deduplicate logic - #527922

Open
r-vdp wants to merge 11 commits into
NixOS:staging-nixosfrom
r-vdp:rvdp/nixos-init-activate
Open

r-vdp wants to merge 11 commits into
NixOS:staging-nixosfrom
r-vdp:rvdp/nixos-init-activate

Conversation

@r-vdp

@r-vdp r-vdp commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Part of #475305.

We add an activate entrypoint to nixos-init that calls into the same code path as the initrd activation but with the appropriate arguments. We also add an extra function to setup special filesystems (which is done by systemd in initrd).

In order to be able to handle systems without bootspec, like containers, we extend the config generation and parsing such that without bootspec we generate and parse a dedicated nixos-init.json file. Bootspec enabled systems still use boot.json.

See the commit messages for more detail on the changes.

With this change we deduplicate the bash and rust implementations of a big part of the default nixos activation logic.

After this PR, the only in-tree activation scripts left are the etc setup and the user/group setup, which will be handled separately.

I ran the switch test, activation test, and container tests, and have been running this on my laptop for a couple of days now.

Things done

nixpkgs-branch-check[bot]

This comment was marked as outdated.

@nixpkgs-ci
nixpkgs-ci Bot requested a review from nikstur June 4, 2026 11:22
@nixpkgs-ci nixpkgs-ci Bot added 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-nixos-tests This PR causes rebuilds for all NixOS tests and should normally target the staging branches. 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: changelog This PR adds or changes release notes 8.has: module (update) This PR changes an existing module in `nixos/` 8.has: documentation This PR adds or changes documentation labels Jun 4, 2026
@nikstur

nikstur commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Why don't we make bootspec a part of these other systems (e.g. containers)? I don't see a reason to introduce this separate nixos-init.json

@r-vdp

r-vdp commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

Why don't we make bootspec a part of these other systems (e.g. containers)? I don't see a reason to introduce this separate nixos-init.json

Mainly because bootspec requires things like a kernel, which we don't have for containers. So technically the bootspec wouldn't be valid.

@r-vdp
r-vdp force-pushed the rvdp/nixos-init-activate branch from 59db14f to cd81293 Compare June 4, 2026 21:59
@r-vdp
r-vdp changed the base branch from master to staging-nixos June 4, 2026 22:04
@nixpkgs-ci nixpkgs-ci Bot closed this Jun 4, 2026
@nixpkgs-ci nixpkgs-ci Bot reopened this Jun 4, 2026
@nixpkgs-branch-check
nixpkgs-branch-check Bot dismissed their stale review June 4, 2026 22:12

Review dismissed automatically

@r-vdp
r-vdp requested a review from ElvishJerricco June 4, 2026 22:17
@r-vdp
r-vdp force-pushed the rvdp/nixos-init-activate branch from 031510d to bb3d43a Compare June 17, 2026 08:13
Comment on lines +40 to +64
/// Mount or remount each entry in `boot.specialFileSystems`.
fn setup_special_filesystems(mounts: &[SpecialMount]) -> Result<()> {
let existing = Mounts::parse_from_proc_mounts()?;
for m in mounts {
let (flags, data) = split_mount_opts(&m.options);
if existing.find_mountpoint(&m.mountpoint).is_some() {
mount_remount(m.mountpoint.as_str(), flags, data.as_c_str())
.with_context(|| format!("Failed to remount {}", m.mountpoint))?;
} else {
fs::create_dir_all(&m.mountpoint)
.with_context(|| format!("Failed to create {}", m.mountpoint))?;
let mut perms = fs::metadata(&m.mountpoint)?.permissions();
perms.set_mode(0o755);
fs::set_permissions(&m.mountpoint, perms)?;
mount(
m.device.as_str(),
m.mountpoint.as_str(),
m.fstype.as_str(),
flags,
data.as_c_str(),
)
.with_context(|| format!("Failed to mount {}", m.mountpoint))?;
}
}
Ok(())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I've wanted to get rid of this whole idea of "special file systems" for a long time now, and this is probably the right time to do it. They're handled by systemd and it haven't really made sense for a long time; see

# Sync mount options with systemd's src/core/mount-setup.c: mount_table.
and how we're supposed to keep it in sync with upstream but don't

@r-vdp r-vdp Jun 25, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I agree that it would be nice to get rid of this, but I'm not sure that I'd like to combine that with this PR.

I think we should probably hardcode the mount calls for the things that systemd mounts for us into the scripted stage 1 script, and then drop those entries from filesystems.nix. So that we only mount them explicitly with the scripted initrd, and this code will then be removed when we remove scripted initrd.
I'm not exactly sure what to do about /run/keys, I'm not entirely sure what this is used for, but I didn't look into it in detail.

Then we can deprecate the options completely.

@r-vdp
r-vdp force-pushed the rvdp/nixos-init-activate branch from bb3d43a to 05eae37 Compare July 21, 2026 22:09
@nixpkgs-ci nixpkgs-ci Bot added the 10.rebuild-darwin: 1 This PR causes 1 package to rebuild on Darwin. label Jul 21, 2026
@nixpkgs-ci nixpkgs-ci Bot added the 2.status: merge conflict This PR has merge conflicts with the target branch label Sep 6, 2026
r-vdp added 7 commits October 25, 2026 12:30
Expose activate() as a standalone bin/activate entrypoint so it can
be invoked from outside the initrd.
Allow to opt out of these steps when something else manages them or
they don't apply, for instance in a container without its own kernel.
Containers and systems with `boot.bootspec.enable = false` do not get
a boot.json in their toplevel, so nixos-init could not load its config
in those cases.
For such configs, write the same config to a standalone nixos-init.json
file and have Config::from_toplevel try boot.json first, then nixos-init.json.
This makes the entrypoint self-sufficient with respect to /run,
/proc and others, which is needed for nixos-enter which only inherits
a subset of mounts from the host.
r-vdp added 4 commits October 25, 2026 12:30
Replace the activation script snippets that are covered by
`nixos-init activate` by calling that, to reduce duplication between
the bash and rust implementations.
The main change is that we switch /run/current-system earlier, which
is noted in the release notes.
We provide a variable that contains the store path of the old generation.
Removes the dependency on a `mount` binary on PATH and avoids
process spawns during activation.
@r-vdp
r-vdp force-pushed the rvdp/nixos-init-activate branch from 05eae37 to 36821e6 Compare October 25, 2026 14:18

@nixpkgs-ci nixpkgs-ci Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for contributing to the documentation.

Follow the documentation style guide, especially:

  • Show, don’t tell. Start with a minimal working example. Explain after the code.
  • Avoid meta-commentary. Don’t write "This section explains how to…".
  • Use present tense, imperative mood, and active voice. For example: "Run the command," not "The user should run the following command."
  • Avoid vague references like "this" when the referent is unclear. Write "This command creates a folder," not "This will create a folder."
  • Be direct. Avoid "should", "might", "typically", and "usually".
  • Cut filler words like "simply", "just", "easily", and "basically". Use "to" instead of "in order to".

For larger changes, such as adding or removing whole sections, ask the NixOS documentation team for review.

@nixpkgs-ci nixpkgs-ci Bot removed 2.status: merge conflict This PR has merge conflicts with the target branch 10.rebuild-darwin: 1 This PR causes 1 package to rebuild on Darwin. labels Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: changelog This PR adds or changes release notes 8.has: documentation This PR adds or changes documentation 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 10.rebuild-nixos-tests This PR causes rebuilds for all NixOS tests and should normally target the staging branches.

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants