Implement deactivate with a target host + documentation

This commit is contained in:
r-vdp 2023-03-23 17:07:04 +01:00
parent 8888285a10
commit 65321376e8
No known key found for this signature in database
2 changed files with 71 additions and 24 deletions

View file

@ -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")]

View file

@ -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,9 +216,27 @@ fn activate(
} }
} }
fn deactivate() -> Result<()> { fn 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() 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<()> {
target_host target_host
@ -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()