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")),
|
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")
|
.arg(Arg::with_name("verbose")
|
||||||
.short("v")
|
.short("v")
|
||||||
.long("verbose")
|
.long("verbose")
|
||||||
|
@ -101,6 +110,7 @@ pub fn subcommand() -> App<'static, 'static> {
|
||||||
|
|
||||||
pub async fn run(_global_args: &ArgMatches<'_>, local_args: &ArgMatches<'_>) {
|
pub async fn run(_global_args: &ArgMatches<'_>, local_args: &ArgMatches<'_>) {
|
||||||
let hive = util::hive_from_args(local_args).unwrap();
|
let hive = util::hive_from_args(local_args).unwrap();
|
||||||
|
let hive_base = hive.as_path().parent().unwrap().to_owned();
|
||||||
|
|
||||||
log::info!("Enumerating nodes...");
|
log::info!("Enumerating nodes...");
|
||||||
let all_nodes = hive.deployment_info().await.unwrap();
|
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_gzip(!local_args.is_present("no-gzip"));
|
||||||
options.set_progress_bar(!local_args.is_present("verbose"));
|
options.set_progress_bar(!local_args.is_present("verbose"));
|
||||||
options.set_upload_keys(!local_args.is_present("no-keys"));
|
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);
|
deployment.set_options(options);
|
||||||
|
|
||||||
if local_args.is_present("no-keys") && goal_arg == "keys" {
|
if local_args.is_present("no-keys") && goal_arg == "keys" {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::convert::AsRef;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use futures::future::join_all;
|
use futures::future::join_all;
|
||||||
use tokio::sync::{Mutex, Semaphore};
|
use tokio::sync::{Mutex, Semaphore};
|
||||||
|
@ -367,8 +369,7 @@ impl Deployment {
|
||||||
);
|
);
|
||||||
|
|
||||||
let goal = arc_self.goal;
|
let goal = arc_self.goal;
|
||||||
let arc_self = arc_self.clone();
|
let profiles = arc_self.clone().build_profiles(&chunk, drv, bar.clone()).await;
|
||||||
let profiles = arc_self.build_profiles(&chunk, drv, bar.clone()).await;
|
|
||||||
|
|
||||||
let profiles = match profiles {
|
let profiles = match profiles {
|
||||||
Some(profiles) => 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);
|
drop(permit);
|
||||||
profiles
|
profiles
|
||||||
};
|
};
|
||||||
|
@ -582,7 +591,7 @@ impl ParallelismLimit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DeploymentOptions {
|
pub struct DeploymentOptions {
|
||||||
/// Whether to show condensed progress bars.
|
/// Whether to show condensed progress bars.
|
||||||
///
|
///
|
||||||
|
@ -597,6 +606,9 @@ pub struct DeploymentOptions {
|
||||||
|
|
||||||
/// Whether to upload keys when deploying.
|
/// Whether to upload keys when deploying.
|
||||||
upload_keys: bool,
|
upload_keys: bool,
|
||||||
|
|
||||||
|
/// Directory to create GC roots for node profiles in.
|
||||||
|
gc_roots: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DeploymentOptions {
|
impl Default for DeploymentOptions {
|
||||||
|
@ -606,6 +618,7 @@ impl Default for DeploymentOptions {
|
||||||
substituters_push: true,
|
substituters_push: true,
|
||||||
gzip: true,
|
gzip: true,
|
||||||
upload_keys: true,
|
upload_keys: true,
|
||||||
|
gc_roots: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -627,6 +640,10 @@ impl DeploymentOptions {
|
||||||
self.upload_keys = enable;
|
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 {
|
fn to_copy_options(&self) -> CopyOptions {
|
||||||
let options = CopyOptions::default();
|
let options = CopyOptions::default();
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::ops::{Deref, DerefMut};
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::process::Stdio;
|
||||||
|
|
||||||
|
use tokio::process::Command;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Goal,
|
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