Skip to content

support single-command elevation for switches - #797

Open
atagen wants to merge 2 commits into
nix-community:masterfrom
atagen:single-command-activation
Open

atagen wants to merge 2 commits into
nix-community:masterfrom
atagen:single-command-activation

Conversation

@atagen

@atagen atagen commented Sep 17, 2026

Copy link
Copy Markdown

this PR enables "single elevation", ie. a full switch to be performed in a single child process.

this benefits run0 users and others without persistent/cached authorisation in their environment.

it is used with the --single-elevation flag, or the NH_SINGLE_ELEVATION variable (which can be set by a module option).
exclusion is achieved with --no-single-elevation in the case of the variable being present but the user desiring a one-off non-single-elevation switch.

it is achieved by the nh process re-executing itself privileged using a hidden argument, with the elevated child performing all necessary actions for the switch.

presently, it only effects the switch command, although could be extended to others if desired.

in order to make this feasible without bloating function signatures, it also flattens the elevate/ElevationStrategy bool/enum pair to an Option<ElevationStrategy>, with the matching semantics you'd expect.

Sanity Checking

  • I have read and understood the contribution guidelines
  • I have updated the changelog as per my changes
  • I have tested, and self-reviewed my code
  • Style and consistency
    • I ran nix fmt to format my Nix code
    • I ran cargo fmt to format my Rust code
    • I have added appropriate documentation to new code
    • My changes are consistent with the rest of the codebase
  • Correctness
    • I ran cargo clippy and fixed any new linter warnings.
  • If new changes are particularly complex:
    • My code includes comments in particularly complex areas to explain the
      logic
    • I have documented the motive for those changes in the PR body or commit
      description.
  • Tested on platform(s):
    • x86_64-linux
    • aarch64-linux
    • aarch64-darwin

Add a 👍 reaction to pull requests you find important.

Elevation programs without cached authorization otherwise prompt once for every privileged switch step.
@coderabbitai

coderabbitai Bot commented Sep 17, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 4e795ef8-9c43-4b48-a976-9044ee5f65c6

📥 Commits

Reviewing files that changed from the base of the PR and between 3c05c01 and d55a464.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • crates/nh-nixos/src/args.rs
  • crates/nh-nixos/src/nixos.rs
  • crates/nh/src/interface.rs
  • crates/xtask/src/man.rs
  • docs/README.md

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The PR adds --single-elevation and NH_SINGLE_ELEVATION for local nh os switch operations. It introduces a hidden internal command that runs activation, profile installation, and bootloader updates within one elevated process.

Changes

Single-elevation switch

Layer / File(s) Summary
Command and argument contract
crates/nh-nixos/src/args.rs, crates/nh/src/interface.rs
The switch command accepts single-elevation flags and defines arguments for the hidden __single-elevation command. Dispatch and feature handling support the new command.
Elevated switch execution
crates/nh-nixos/src/nixos.rs
Local switch execution can re-execute the binary with elevation, then run activation, profile installation, and bootloader commands. The option is rejected with --target-host.
Configuration and documentation
CHANGELOG.md, crates/xtask/src/man.rs, docs/README.md
The changelog, man-page environment table, README configuration example, and environment-variable documentation describe single elevation.

Suggested reviewers: faukah

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to d55a4

This change adds an opt-in single-elevation mode for local NixOS switches that consolidates repeated authorization prompts into one privileged re-execution, while preserving the existing remote and non-single-elevation behavior. Inspection of the new privileged execution path found the expected safeguards in place (an independent root check in the elevated child, and normal dry-run handling before any elevation occurs), so this looks safe to merge as an opt-in feature.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.89% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 4 files. (2 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely describes the main change: single-command elevation for switch operations.
Description check ✅ Passed The description directly explains single-elevation support, its configuration flags, behavior, motivation, and scope.
Full details: Docstring Coverage

Explanation

Docstring coverage is 38.89% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 4 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@atagen atagen changed the title nh-nixos: model activation elevation as an option support single-command elevation for switches Sep 17, 2026
Comment thread docs/README.md
programs.nh = {
enable = true;
clean.enable = true;
enable = true;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You seem to have forgotten to add this option to the NixOS module. Do you intend for this to be nixpkgs-module exclusive?

@atagen atagen Sep 17, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

oops, I didn't even realise you'd nuked this repo's module and I guess I just skipped over it, lol

Comment on lines +205 to +209
#[arg(long, env = "NH_SINGLE_ELEVATION", value_parser = clap::builder::BoolishValueParser::new())]
pub single_elevation: bool,

#[arg(long)]
pub no_single_elevation: bool,

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.

Why would we use both of these? I assume we can just do --single-elevation=false if we want to disable single-command elevation?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

makes sense, the main reason is giving an escape hatch to people who set single elevation in their system and want a one-off, but just making it an on-by-default boolean is probably better

Comment thread crates/nh-nixos/src/nixos.rs
Comment on lines +193 to +209
fn forwarded_verbosity_args(
args: impl IntoIterator<Item = OsString>,
) -> Vec<OsString> {
args
.into_iter()
.take_while(|arg| arg != "--")
.filter(|arg| {
arg.to_str().is_some_and(|arg| {
matches!(arg, "--verbose" | "--quiet")
|| arg.strip_prefix('-').is_some_and(|short| {
!short.is_empty()
&& short.chars().all(|flag| matches!(flag, 'v' | 'q'))
})
})
})
.collect()
}

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.

coal.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

💔

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

its true...

@atagen

atagen commented Sep 17, 2026

Copy link
Copy Markdown
Author

thank you both for the review - before I take any further action to rectify these issues, @faukah has mentioned that you'd consider making single elevation the default strategy.

what do you think, @NotAShelf ? I'd be happy enough to expand the scope here if it's desired, or I can just patch up and follow @faukah's suggestion up in later work.

@NotAShelf

Copy link
Copy Markdown
Member

thank you both for the review - before I take any further action to rectify these issues, @faukah has mentioned that you'd consider making single elevation the default strategy.

what do you think, @NotAShelf ? I'd be happy enough to expand the scope here if it's desired, or I can just patch up and follow @faukah's suggestion up in later work.

Fine by me.

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.

3 participants