Implement deactivate with a target host + documentation
This commit is contained in:
parent
8888285a10
commit
65321376e8
2 changed files with 71 additions and 24 deletions
16
src/lib.rs
16
src/lib.rs
|
|
@ -8,14 +8,14 @@ use std::os::unix;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::{fs, str};
|
use std::{fs, str};
|
||||||
|
|
||||||
const FLAKE_ATTR: &str = "systemConfigs";
|
pub const FLAKE_ATTR: &str = "systemConfigs";
|
||||||
const PROFILE_DIR: &str = "/nix/var/nix/profiles/system-manager-profiles";
|
pub const PROFILE_DIR: &str = "/nix/var/nix/profiles/system-manager-profiles";
|
||||||
const PROFILE_NAME: &str = "system-manager";
|
pub const PROFILE_NAME: &str = "system-manager";
|
||||||
const GCROOT_PATH: &str = "/nix/var/nix/gcroots/system-manager-current";
|
pub const GCROOT_PATH: &str = "/nix/var/nix/gcroots/system-manager-current";
|
||||||
const SYSTEM_MANAGER_STATE_DIR: &str = "/var/lib/system-manager/state";
|
pub const SYSTEM_MANAGER_STATE_DIR: &str = "/var/lib/system-manager/state";
|
||||||
const SERVICES_STATE_FILE_NAME: &str = "services.json";
|
pub const SERVICES_STATE_FILE_NAME: &str = "services.json";
|
||||||
const ETC_STATE_FILE_NAME: &str = "etc-files.json";
|
pub const ETC_STATE_FILE_NAME: &str = "etc-files.json";
|
||||||
const SYSTEM_MANAGER_STATIC_NAME: &str = ".system-manager-static";
|
pub const SYSTEM_MANAGER_STATIC_NAME: &str = ".system-manager-static";
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||||
#[serde(from = "String", into = "String", rename_all = "camelCase")]
|
#[serde(from = "String", into = "String", rename_all = "camelCase")]
|
||||||
|
|
|
||||||
79
src/main.rs
79
src/main.rs
|
|
@ -1,12 +1,18 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
use std::path::Path;
|
||||||
use std::process::{self, ExitCode};
|
use std::process::{self, ExitCode};
|
||||||
|
|
||||||
use system_manager::StorePath;
|
use system_manager::StorePath;
|
||||||
|
|
||||||
#[derive(clap::Parser, Debug)]
|
#[derive(clap::Parser, Debug)]
|
||||||
#[command(author, version, about, long_about=None)]
|
#[command(
|
||||||
|
author,
|
||||||
|
version,
|
||||||
|
about,
|
||||||
|
long_about = "System Manager -- Manage system configuration with Nix on any distro"
|
||||||
|
)]
|
||||||
struct Args {
|
struct Args {
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
action: Action,
|
action: Action,
|
||||||
|
|
@ -16,6 +22,8 @@ struct Args {
|
||||||
target_host: Option<String>,
|
target_host: Option<String>,
|
||||||
|
|
||||||
#[arg(long, action)]
|
#[arg(long, action)]
|
||||||
|
/// Whether to invoke the remove command with sudo.
|
||||||
|
/// Only useful in combination with
|
||||||
use_remote_sudo: bool,
|
use_remote_sudo: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,6 +52,15 @@ struct ActivationArgs {
|
||||||
ephemeral: bool,
|
ephemeral: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(clap::Args, Debug)]
|
||||||
|
struct DeactivationArgs {
|
||||||
|
#[arg(long)]
|
||||||
|
/// The store path for the system-manager profile.
|
||||||
|
/// You only need to specify this explicitly if it differs from the active
|
||||||
|
/// system-manager profile
|
||||||
|
store_path: Option<StorePath>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(clap::Subcommand, Debug)]
|
#[derive(clap::Subcommand, Debug)]
|
||||||
enum Action {
|
enum Action {
|
||||||
/// Activate a given system-manager profile
|
/// Activate a given system-manager profile
|
||||||
|
|
@ -54,18 +71,23 @@ enum Action {
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
activation_args: ActivationArgs,
|
activation_args: ActivationArgs,
|
||||||
},
|
},
|
||||||
/// Build a new system-manager generation without registering it as a nix profile
|
/// Build a new system-manager profile without registering it as a nix profile
|
||||||
Build {
|
Build {
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
build_args: BuildArgs,
|
build_args: BuildArgs,
|
||||||
},
|
},
|
||||||
Deactivate,
|
/// Deactivate the active system-manager profile, removing all managed configuration
|
||||||
/// Generate a new system-manager generation
|
Deactivate {
|
||||||
|
#[command(flatten)]
|
||||||
|
deactivation_args: DeactivationArgs,
|
||||||
|
},
|
||||||
|
/// Generate a new system-manager profile and
|
||||||
|
/// register is as the active system-manager profile
|
||||||
Generate {
|
Generate {
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
generate_args: GenerateArgs,
|
generate_args: GenerateArgs,
|
||||||
},
|
},
|
||||||
/// Generate a new system-manager generation and activate it
|
/// Generate a new system-manager profile and activate it
|
||||||
Switch {
|
Switch {
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
build_args: BuildArgs,
|
build_args: BuildArgs,
|
||||||
|
|
@ -98,11 +120,9 @@ fn go(args: Args) -> Result<()> {
|
||||||
Action::Build {
|
Action::Build {
|
||||||
build_args: BuildArgs { flake_uri },
|
build_args: BuildArgs { flake_uri },
|
||||||
} => build(&flake_uri, &target_host),
|
} => build(&flake_uri, &target_host),
|
||||||
Action::Deactivate => {
|
Action::Deactivate {
|
||||||
check_root()?;
|
deactivation_args: DeactivationArgs { store_path },
|
||||||
// TODO handle target_host
|
} => deactivate(store_path, &target_host, use_remote_sudo),
|
||||||
deactivate()
|
|
||||||
}
|
|
||||||
Action::Generate { generate_args } => {
|
Action::Generate { generate_args } => {
|
||||||
generate(&generate_args, &target_host, use_remote_sudo)
|
generate(&generate_args, &target_host, use_remote_sudo)
|
||||||
}
|
}
|
||||||
|
|
@ -163,7 +183,12 @@ fn do_generate(
|
||||||
use_remote_sudo: bool,
|
use_remote_sudo: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if let Some(target_host) = target_host {
|
if let Some(target_host) = target_host {
|
||||||
invoke_remote_script(store_path, "register-profile", target_host, use_remote_sudo)?;
|
invoke_remote_script(
|
||||||
|
&store_path.store_path,
|
||||||
|
"register-profile",
|
||||||
|
target_host,
|
||||||
|
use_remote_sudo,
|
||||||
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
check_root()?;
|
check_root()?;
|
||||||
|
|
@ -178,7 +203,12 @@ fn activate(
|
||||||
use_remote_sudo: bool,
|
use_remote_sudo: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if let Some(target_host) = target_host {
|
if let Some(target_host) = target_host {
|
||||||
invoke_remote_script(store_path, "activate", target_host, use_remote_sudo)?;
|
invoke_remote_script(
|
||||||
|
&store_path.store_path,
|
||||||
|
"activate",
|
||||||
|
target_host,
|
||||||
|
use_remote_sudo,
|
||||||
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
check_root()?;
|
check_root()?;
|
||||||
|
|
@ -186,8 +216,26 @@ fn activate(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deactivate() -> Result<()> {
|
fn deactivate(
|
||||||
system_manager::activate::deactivate()
|
store_path: Option<StorePath>,
|
||||||
|
target_host: &Option<String>,
|
||||||
|
use_remote_sudo: bool,
|
||||||
|
) -> Result<()> {
|
||||||
|
if let Some(target_host) = target_host {
|
||||||
|
invoke_remote_script(
|
||||||
|
&store_path.map_or_else(
|
||||||
|
|| Path::new(system_manager::PROFILE_DIR).join("system-manager"),
|
||||||
|
|store_path| store_path.store_path,
|
||||||
|
),
|
||||||
|
"deactivate",
|
||||||
|
target_host,
|
||||||
|
use_remote_sudo,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
check_root()?;
|
||||||
|
system_manager::activate::deactivate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_closure(store_path: &StorePath, target_host: &Option<String>) -> Result<()> {
|
fn copy_closure(store_path: &StorePath, target_host: &Option<String>) -> Result<()> {
|
||||||
|
|
@ -215,7 +263,7 @@ fn do_copy_closure(store_path: &StorePath, target_host: &str) -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invoke_remote_script(
|
fn invoke_remote_script(
|
||||||
store_path: &StorePath,
|
store_path: &Path,
|
||||||
script_name: &str,
|
script_name: &str,
|
||||||
target_host: &str,
|
target_host: &str,
|
||||||
use_remote_sudo: bool,
|
use_remote_sudo: bool,
|
||||||
|
|
@ -228,7 +276,6 @@ fn invoke_remote_script(
|
||||||
let status = cmd
|
let status = cmd
|
||||||
.arg(OsString::from(
|
.arg(OsString::from(
|
||||||
store_path
|
store_path
|
||||||
.store_path
|
|
||||||
.join("bin")
|
.join("bin")
|
||||||
.join(script_name)
|
.join(script_name)
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue