Add a pre-populate subcommand. (#11)

This commit is contained in:
Ramses 2023-05-08 18:35:43 +02:00 committed by GitHub
parent 9254ace18f
commit cead991210
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 237 additions and 60 deletions

View file

@ -104,7 +104,51 @@ pub fn activate(store_path: &StorePath, ephemeral: bool) -> Result<()> {
}
}
.write_to_file(state_file)?;
Ok(())
}
pub fn prepopulate(store_path: &StorePath, ephemeral: bool) -> Result<()> {
log::info!("Pre-populating system-manager profile: {store_path}");
if ephemeral {
log::info!("Running in ephemeral mode");
}
log::info!("Running pre-activation assertions...");
if !run_preactivation_assertions(store_path)?.success() {
anyhow::bail!("Failure in pre-activation assertions.");
}
let state_file = &get_state_file()?;
let old_state = State::from_file(state_file)?;
log::info!("Activating etc files...");
match etc_files::activate(store_path, old_state.file_tree, ephemeral) {
Ok(etc_tree) => {
log::info!("Registering systemd services...");
match services::get_active_services(store_path, old_state.services) {
Ok(services) => State {
file_tree: etc_tree,
services,
},
Err(ActivationError::WithPartialResult { result, source }) => {
log::error!("Error during activation: {source:?}");
State {
file_tree: etc_tree,
services: result,
}
}
}
}
Err(ActivationError::WithPartialResult { result, source }) => {
log::error!("Error during activation: {source:?}");
State {
file_tree: result,
..old_state
}
}
}
.write_to_file(state_file)?;
Ok(())
}

View file

@ -30,14 +30,10 @@ fn print_services(services: &Services) -> String {
out
}
pub fn activate(
pub fn get_active_services(
store_path: &StorePath,
old_services: Services,
ephemeral: bool,
) -> ServiceActivationResult {
verify_systemd_dir(ephemeral)
.map_err(|e| ActivationError::with_partial_result(old_services.clone(), e))?;
log::info!("Reading new service definitions...");
let file = fs::File::open(
Path::new(&store_path.store_path)
@ -49,6 +45,18 @@ pub fn activate(
let services: Services = serde_json::from_reader(reader)
.map_err(|e| ActivationError::with_partial_result(old_services.clone(), e))?;
log::debug!("{}", print_services(&services));
Ok(services)
}
pub fn activate(
store_path: &StorePath,
old_services: Services,
ephemeral: bool,
) -> ServiceActivationResult {
verify_systemd_dir(ephemeral)
.map_err(|e| ActivationError::with_partial_result(old_services.clone(), e))?;
let services = get_active_services(store_path, old_services.clone())?;
let services_to_stop = old_services.clone().relative_complement(services.clone());
let services_to_reload = get_services_to_reload(services.clone(), old_services.clone());

View file

@ -30,14 +30,14 @@ struct Args {
#[derive(clap::Args, Debug)]
struct BuildArgs {
#[arg(long = "flake", name = "FLAKE_URI")]
/// The flake defining the system-manager profile
/// The flake URI defining the system-manager profile
flake_uri: String,
}
#[derive(clap::Args, Debug)]
struct GenerateArgs {
#[arg(long = "flake", name = "FLAKE_URI")]
/// The flake defining the system-manager profile
/// The flake URI defining the system-manager profile
flake_uri: Option<String>,
#[arg(long)]
@ -71,6 +71,13 @@ enum Action {
#[command(flatten)]
activation_args: ActivationArgs,
},
PrePopulate {
#[arg(long)]
/// The store path containing the system-manager profile to activate
store_path: StorePath,
#[command(flatten)]
activation_args: ActivationArgs,
},
/// Build a new system-manager profile without registering it as a nix profile
Build {
#[command(flatten)]
@ -117,6 +124,13 @@ fn go(args: Args) -> Result<()> {
copy_closure(&store_path, &target_host)?;
activate(&store_path, ephemeral, &target_host, use_remote_sudo)
}
Action::PrePopulate {
store_path,
activation_args: ActivationArgs { ephemeral },
} => {
copy_closure(&store_path, &target_host)?;
prepopulate(&store_path, ephemeral, &target_host, use_remote_sudo)
}
Action::Build {
build_args: BuildArgs { flake_uri },
} => build(&flake_uri, &target_host),
@ -225,6 +239,26 @@ fn activate(
}
}
fn prepopulate(
store_path: &StorePath,
ephemeral: bool,
target_host: &Option<String>,
use_remote_sudo: bool,
) -> Result<()> {
if let Some(target_host) = target_host {
invoke_remote_script(
&store_path.store_path,
"pre-populate",
target_host,
use_remote_sudo,
)?;
Ok(())
} else {
check_root()?;
system_manager::activate::prepopulate(store_path, ephemeral)
}
}
fn deactivate(
store_path: Option<StorePath>,
target_host: &Option<String>,