switch-to-configuration-ng: improve user experience

When calling switch-to-configuration (ng) as a non-root user, the user
calling the program should be guided to calling the program in the
correct way, not given a confusing error message.
This commit is contained in:
Jared Baur 2024-10-19 11:08:34 -07:00
parent ba9222ea03
commit d98f11e96f
No known key found for this signature in database

View File

@ -937,8 +937,21 @@ fn do_user_switch(parent_exe: String) -> anyhow::Result<()> {
Ok(())
}
fn usage(argv0: &str) -> ! {
eprintln!(
r#"Usage: {} [switch|boot|test|dry-activate]
switch: make the configuration the boot default and activate now
boot: make the configuration the boot default
test: activate the configuration, but don't make it the boot default
dry-activate: show what would be done if this configuration were activated
"#,
argv0
);
std::process::exit(1);
}
/// Performs switch-to-configuration functionality for the entire system
fn do_system_switch() -> anyhow::Result<()> {
fn do_system_switch(action: Action) -> anyhow::Result<()> {
let out = PathBuf::from(required_env("OUT")?);
let toplevel = PathBuf::from(required_env("TOPLEVEL")?);
let distro_id = required_env("DISTRO_ID")?;
@ -946,25 +959,6 @@ fn do_system_switch() -> anyhow::Result<()> {
let locale_archive = required_env("LOCALE_ARCHIVE")?;
let new_systemd = PathBuf::from(required_env("SYSTEMD")?);
let mut args = std::env::args();
let argv0 = args.next().ok_or(anyhow!("no argv[0]"))?;
let Some(Ok(action)) = args.next().map(|a| Action::from_str(&a)) else {
eprintln!(
r#"Usage: {} [switch|boot|test|dry-activate]
switch: make the configuration the boot default and activate now
boot: make the configuration the boot default
test: activate the configuration, but don't make it the boot default
dry-activate: show what would be done if this configuration were activated
"#,
argv0
.split(std::path::MAIN_SEPARATOR_STR)
.last()
.unwrap_or("switch-to-configuration")
);
std::process::exit(1);
};
let action = ACTION.get_or_init(|| action);
// The action that is to be performed (like switch, boot, test, dry-activate) Also exposed via
@ -1939,13 +1933,26 @@ won't take effect until you reboot the system.
}
fn main() -> anyhow::Result<()> {
match (
unsafe { nix::libc::geteuid() },
std::env::var("__NIXOS_SWITCH_TO_CONFIGURATION_PARENT_EXE").ok(),
) {
(0, None) => do_system_switch(),
(1..=u32::MAX, None) => bail!("This program does not support being ran outside of the switch-to-configuration environment"),
(_, Some(parent_exe)) => do_user_switch(parent_exe),
match std::env::var("__NIXOS_SWITCH_TO_CONFIGURATION_PARENT_EXE").ok() {
Some(parent_exe) => do_user_switch(parent_exe),
None => {
let mut args = std::env::args();
let argv0 = args.next().ok_or(anyhow!("no argv[0]"))?;
let argv0 = argv0
.split(std::path::MAIN_SEPARATOR_STR)
.last()
.unwrap_or("switch-to-configuration");
let Some(Ok(action)) = args.next().map(|a| Action::from_str(&a)) else {
usage(&argv0);
};
if unsafe { nix::libc::geteuid() } == 0 {
do_system_switch(action)
} else {
bail!("{} must be run as the root user", argv0);
}
}
}
}