Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 76 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use anyhow::Result;
use clap::Parser;
use std::ffi::OsString;
use std::fs::{create_dir_all, File};
use std::io::Write;
use std::mem;
use std::path::{Path, PathBuf};
use std::process::{self, ExitCode};
Expand Down Expand Up @@ -31,11 +33,18 @@ struct Args {
nix_options: Option<Vec<String>>,
}

#[derive(clap::Args, Debug)]
struct InitArgs {
#[arg(long = "config_dir", name = "CONFIG_DIR")]
/// The configuration directory in which to initialize the system-manager flake
config_dir: Option<String>,
}

#[derive(clap::Args, Debug)]
struct BuildArgs {
#[arg(long = "flake", name = "FLAKE_URI")]
/// The flake URI defining the system-manager profile
flake_uri: String,
flake_uri: Option<String>,
}

#[derive(clap::Args, Debug)]
Expand Down Expand Up @@ -83,6 +92,13 @@ struct StoreOrFlakeArgs {

#[derive(clap::Subcommand, Debug)]
enum Action {
/// Initialize a new system-manager flake
Init {
/// The path to the directory containing the system-manager flake
#[command(flatten)]
init_args: InitArgs,
},

/// Build a new system-manager generation, register it as the active profile, and activate it
Switch {
#[command(flatten)]
Expand Down Expand Up @@ -151,6 +167,7 @@ fn go(args: Args) -> Result<()> {
}));

match action {
Action::Init { init_args } => do_init(init_args.config_dir),
Action::PrePopulate {
store_or_flake_args,
activation_args: ActivationArgs { ephemeral },
Expand Down Expand Up @@ -196,14 +213,56 @@ fn go(args: Args) -> Result<()> {
}
}

fn do_init(path: Option<String>) -> Result<()> {
let config_path = match path {
Some(p) => PathBuf::from(p),
None => default_config_path(),
};

if config_path.exists() {
anyhow::bail!(
"System-manager config directory already exists at {}",
config_path.display()
)
}

create_dir_all(&config_path)?;

let flake_path = config_path.join("flake.nix");
let mut flake_file = File::create(flake_path)?;
let flake_text = r#"{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

system-manager = {
url = "github:numtide/system-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
};

outputs = { self, flake-utils, nixpkgs, system-manager }: {
systemConfigs.default = system-manager.lib.makeSystemConfig {
modules = [
./modules
];
};
};
}"#;
write!(flake_file, "{}", flake_text)?;

println!("Created system-manager flake at {}", config_path.display());

Ok(())
}

fn print_store_path<SP: AsRef<StorePath>>(store_path: SP) -> Result<()> {
// Print the raw store path to stdout
println!("{}", store_path.as_ref());
Ok(())
}

fn build(
flake_uri: &str,
flake_uri: &Option<String>,
target_host: &Option<String>,
nix_options: &NixOptions,
) -> Result<StorePath> {
Expand All @@ -212,8 +271,15 @@ fn build(
Ok(store_path)
}

fn do_build(flake_uri: &str, nix_options: &NixOptions) -> Result<StorePath> {
system_manager::register::build(flake_uri, nix_options)
fn do_build(flake_uri: &Option<String>, nix_options: &NixOptions) -> Result<StorePath> {
let flake_path = match flake_uri {
Some(f) => f.to_string(),
None => default_config_path()
.into_os_string()
.into_string()
.unwrap(),
};
system_manager::register::build(&flake_path, nix_options)
}

fn register(
Expand All @@ -233,7 +299,7 @@ fn register(
maybe_flake_uri: Some(flake_uri),
},
} => {
let store_path = do_build(&flake_uri, nix_options)?;
let store_path = do_build(&Some(flake_uri), nix_options)?;
copy_closure(&store_path, target_host)?;
do_register(&store_path, target_host, use_remote_sudo, nix_options)?;
Ok(store_path)
Expand Down Expand Up @@ -325,7 +391,7 @@ fn prepopulate(
maybe_flake_uri: Some(flake_uri),
},
} => {
let store_path = do_build(&flake_uri, nix_options)?;
let store_path = do_build(&Some(flake_uri), nix_options)?;
copy_closure(&store_path, target_host)?;
do_register(&store_path, target_host, use_remote_sudo, nix_options)?;
do_prepopulate(&store_path, ephemeral, target_host, use_remote_sudo)?;
Expand Down Expand Up @@ -458,3 +524,7 @@ fn handle_toplevel_error<T>(r: Result<T>) -> ExitCode {
}
ExitCode::SUCCESS
}

fn default_config_path() -> PathBuf {
PathBuf::from("/etc/system-manager")
}