Add --keep-result to create GC roots for profiles
This resembles the behavior of morph. Reference: #18
This commit is contained in:
parent
81375e71b2
commit
610a725ba2
3 changed files with 65 additions and 5 deletions
|
@ -57,6 +57,15 @@ Set to 0 to disable parallemism limit.
|
|||
Err(_) => Err(String::from("The value must be a valid number")),
|
||||
}
|
||||
}))
|
||||
.arg(Arg::with_name("keep-result")
|
||||
.long("keep-result")
|
||||
.help("Create GC roots for built profiles")
|
||||
.long_help(r#"Create GC roots for built profiles.
|
||||
|
||||
The built system profiles will be added as GC roots so that they will not be removed by the garbage collector.
|
||||
The links will be created under .gcroots in the directory the Hive configuration is located.
|
||||
"#)
|
||||
.takes_value(false))
|
||||
.arg(Arg::with_name("verbose")
|
||||
.short("v")
|
||||
.long("verbose")
|
||||
|
@ -101,6 +110,7 @@ pub fn subcommand() -> App<'static, 'static> {
|
|||
|
||||
pub async fn run(_global_args: &ArgMatches<'_>, local_args: &ArgMatches<'_>) {
|
||||
let hive = util::hive_from_args(local_args).unwrap();
|
||||
let hive_base = hive.as_path().parent().unwrap().to_owned();
|
||||
|
||||
log::info!("Enumerating nodes...");
|
||||
let all_nodes = hive.deployment_info().await.unwrap();
|
||||
|
@ -176,6 +186,11 @@ pub async fn run(_global_args: &ArgMatches<'_>, local_args: &ArgMatches<'_>) {
|
|||
options.set_gzip(!local_args.is_present("no-gzip"));
|
||||
options.set_progress_bar(!local_args.is_present("verbose"));
|
||||
options.set_upload_keys(!local_args.is_present("no-keys"));
|
||||
|
||||
if local_args.is_present("keep-result") {
|
||||
options.set_gc_roots(hive_base.join(".gcroots"));
|
||||
}
|
||||
|
||||
deployment.set_options(options);
|
||||
|
||||
if local_args.is_present("no-keys") && goal_arg == "keys" {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use std::cmp::max;
|
||||
use std::sync::Arc;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::AsRef;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
|
||||
use futures::future::join_all;
|
||||
use tokio::sync::{Mutex, Semaphore};
|
||||
|
@ -367,8 +369,7 @@ impl Deployment {
|
|||
);
|
||||
|
||||
let goal = arc_self.goal;
|
||||
let arc_self = arc_self.clone();
|
||||
let profiles = arc_self.build_profiles(&chunk, drv, bar.clone()).await;
|
||||
let profiles = arc_self.clone().build_profiles(&chunk, drv, bar.clone()).await;
|
||||
|
||||
let profiles = match profiles {
|
||||
Some(profiles) => profiles,
|
||||
|
@ -385,6 +386,14 @@ impl Deployment {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(base) = &arc_self.options.gc_roots {
|
||||
// Create GC roots
|
||||
if let Err(e) = profiles.create_gc_roots(base).await {
|
||||
let bar = progress.create_task_progress(BATCH_OPERATION_LABEL.to_string());
|
||||
bar.failure(&format!("Failed to create GC roots: {:?}", e));
|
||||
}
|
||||
}
|
||||
|
||||
drop(permit);
|
||||
profiles
|
||||
};
|
||||
|
@ -582,7 +591,7 @@ impl ParallelismLimit {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DeploymentOptions {
|
||||
/// Whether to show condensed progress bars.
|
||||
///
|
||||
|
@ -597,6 +606,9 @@ pub struct DeploymentOptions {
|
|||
|
||||
/// Whether to upload keys when deploying.
|
||||
upload_keys: bool,
|
||||
|
||||
/// Directory to create GC roots for node profiles in.
|
||||
gc_roots: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl Default for DeploymentOptions {
|
||||
|
@ -606,6 +618,7 @@ impl Default for DeploymentOptions {
|
|||
substituters_push: true,
|
||||
gzip: true,
|
||||
upload_keys: true,
|
||||
gc_roots: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -627,6 +640,10 @@ impl DeploymentOptions {
|
|||
self.upload_keys = enable;
|
||||
}
|
||||
|
||||
pub fn set_gc_roots<P: AsRef<Path>>(&mut self, path: P) {
|
||||
self.gc_roots = Some(path.as_ref().to_owned());
|
||||
}
|
||||
|
||||
fn to_copy_options(&self) -> CopyOptions {
|
||||
let options = CopyOptions::default();
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::fs;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::path::Path;
|
||||
use std::process::Stdio;
|
||||
|
||||
use tokio::process::Command;
|
||||
|
||||
use super::{
|
||||
Goal,
|
||||
|
@ -110,3 +113,28 @@ impl TryFrom<Vec<StorePath>> for ProfileMap {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ProfileMap {
|
||||
/// Create GC roots for all profiles in the map.
|
||||
///
|
||||
/// The created links will be located at `{base}/node-{node_name}`.
|
||||
pub async fn create_gc_roots(&self, base: &Path) -> NixResult<()> {
|
||||
// This will actually try to build all profiles, but since they
|
||||
// already exist only the GC roots will be created.
|
||||
for (node, profile) in self.0.iter() {
|
||||
let path = base.join(format!("node-{}", node));
|
||||
|
||||
let mut command = Command::new("nix-store");
|
||||
command.args(&["--no-build-output", "--indirect", "--add-root", path.to_str().unwrap()]);
|
||||
command.args(&["--realise", profile.as_path().to_str().unwrap()]);
|
||||
command.stdout(Stdio::null());
|
||||
|
||||
let status = command.status().await?;
|
||||
if !status.success() {
|
||||
return Err(NixError::NixFailure { exit_code: status.code().unwrap() });
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue