From f3bf3dc492045072dbad9e69d1c5199dc77649c0 Mon Sep 17 00:00:00 2001 From: Zhaofeng Li Date: Wed, 13 Jan 2021 12:20:27 -0800 Subject: [PATCH] Allow disabling --use-substitutes and --gzip during copying --- src/command/apply.rs | 22 ++++++++++++++-- src/nix/host.rs | 62 +++++++++++++++++++++++++++++++++++++------- src/nix/mod.rs | 15 +++++++++-- 3 files changed, 85 insertions(+), 14 deletions(-) diff --git a/src/command/apply.rs b/src/command/apply.rs index 449aa0c..cb0515d 100644 --- a/src/command/apply.rs +++ b/src/command/apply.rs @@ -1,6 +1,7 @@ use clap::{Arg, App, SubCommand, ArgMatches}; use crate::nix::{DeploymentTask, DeploymentGoal}; +use crate::nix::host::CopyOptions; use crate::deployment::deploy; use crate::util; @@ -35,7 +36,18 @@ Set to 0 to disable parallemism limit. .long("verbose") .help("Be verbose") .long_help("Deactivates the progress spinner and prints every line of output.") - .takes_value(false)); + .takes_value(false)) + .arg(Arg::with_name("no-substitutes") + .long("no-substitutes") + .help("Do not use substitutes") + .long_help("Disables the use of substituters when copying closures to the remote host.") + .takes_value(false)) + .arg(Arg::with_name("no-gzip") + .long("no-gzip") + .help("Do not use gzip") + .long_help("Disables the use of gzip when copying closures to the remote host.") + .takes_value(false)) + ; util::register_selector_args(command) } @@ -82,7 +94,13 @@ pub async fn run(_global_args: &ArgMatches<'_>, local_args: &ArgMatches<'_>) { match target { Some(target) => { - let task = DeploymentTask::new(name, target, profile, goal); + let mut task = DeploymentTask::new(name, target, profile, goal); + let options = CopyOptions::default() + .gzip(!local_args.is_present("no-gzip")) + .use_substitutes(!local_args.is_present("no-substitutes")) + ; + + task.set_copy_options(options); task_list.push(task); } None => { diff --git a/src/nix/host.rs b/src/nix/host.rs index f86d0d7..58a5778 100644 --- a/src/nix/host.rs +++ b/src/nix/host.rs @@ -19,6 +19,40 @@ pub enum CopyDirection { FromRemote, } +#[derive(Copy, Clone, Debug)] +pub struct CopyOptions { + include_outputs: bool, + use_substitutes: bool, + gzip: bool, +} + +impl Default for CopyOptions { + fn default() -> Self { + Self { + include_outputs: true, + use_substitutes: true, + gzip: true, + } + } +} + +impl CopyOptions { + pub fn include_outputs(mut self, val: bool) -> Self { + self.include_outputs = val; + self + } + + pub fn use_substitutes(mut self, val: bool) -> Self { + self.use_substitutes = val; + self + } + + pub fn gzip(mut self, val: bool) -> Self { + self.gzip = val; + self + } +} + /// A Nix(OS) host. /// /// The underlying implementation must be Send and Sync. @@ -27,7 +61,7 @@ pub trait Host: Send + Sync + std::fmt::Debug { /// Sends or receives the specified closure to the host /// /// The StorePath and its dependent paths will then exist on this host. - async fn copy_closure(&mut self, closure: &StorePath, direction: CopyDirection, include_outputs: bool) -> NixResult<()>; + async fn copy_closure(&mut self, closure: &StorePath, direction: CopyDirection, options: CopyOptions) -> NixResult<()>; /// Realizes the specified derivation on the host /// @@ -38,9 +72,11 @@ pub trait Host: Send + Sync + std::fmt::Debug { /// Realizes the specified local derivation on the host then retrieves the outputs. async fn realize(&mut self, derivation: &StorePath) -> NixResult> { - self.copy_closure(derivation, CopyDirection::ToRemote, false).await?; + let options = CopyOptions::default(); + + self.copy_closure(derivation, CopyDirection::ToRemote, options.include_outputs(false)).await?; let paths = self.realize_remote(derivation).await?; - self.copy_closure(derivation, CopyDirection::FromRemote, true).await?; + self.copy_closure(derivation, CopyDirection::FromRemote, options.include_outputs(true)).await?; Ok(paths) } @@ -71,7 +107,7 @@ pub struct Local {} #[async_trait] impl Host for Local { - async fn copy_closure(&mut self, _closure: &StorePath, _direction: CopyDirection, _include_outputs: bool) -> NixResult<()> { + async fn copy_closure(&mut self, _closure: &StorePath, _direction: CopyDirection, _options: CopyOptions) -> NixResult<()> { Ok(()) } async fn realize_remote(&mut self, derivation: &StorePath) -> NixResult> { @@ -120,8 +156,8 @@ pub struct SSH { #[async_trait] impl Host for SSH { - async fn copy_closure(&mut self, closure: &StorePath, direction: CopyDirection, include_outputs: bool) -> NixResult<()> { - let command = self.nix_copy_closure(closure, direction, include_outputs); + async fn copy_closure(&mut self, closure: &StorePath, direction: CopyDirection, options: CopyOptions) -> NixResult<()> { + let command = self.nix_copy_closure(closure, direction, options); self.run_command(command).await } async fn realize_remote(&mut self, derivation: &StorePath) -> NixResult> { @@ -205,7 +241,7 @@ impl SSH { format!("{}@{}", self.user, self.host) } - fn nix_copy_closure(&self, path: &StorePath, direction: CopyDirection, include_outputs: bool) -> Command { + fn nix_copy_closure(&self, path: &StorePath, direction: CopyDirection, options: CopyOptions) -> Command { let mut command = Command::new("nix-copy-closure"); match direction { CopyDirection::ToRemote => { @@ -215,13 +251,19 @@ impl SSH { command.arg("--from"); } } - if include_outputs { + + // FIXME: Host-agnostic abstraction + if options.include_outputs { command.arg("--include-outputs"); } + if options.use_substitutes { + command.arg("--use-substitutes"); + } + if options.gzip { + command.arg("--gzip"); + } command - .arg("--gzip") - .arg("--use-substitutes") .arg(&self.ssh_target()) .arg(path.as_path()); diff --git a/src/nix/mod.rs b/src/nix/mod.rs index e6df34a..c30d511 100644 --- a/src/nix/mod.rs +++ b/src/nix/mod.rs @@ -15,7 +15,7 @@ use tokio::process::Command; use tokio::sync::Mutex; pub mod host; -pub use host::{Host, CopyDirection}; +pub use host::{Host, CopyDirection, CopyOptions}; use host::SSH; const HIVE_EVAL: &'static [u8] = include_bytes!("eval.nix"); @@ -383,6 +383,9 @@ pub struct DeploymentTask { /// The goal of this deployment. goal: DeploymentGoal, + + /// Options used for copying closures to the remote host. + copy_options: CopyOptions, } impl DeploymentTask { @@ -392,12 +395,18 @@ impl DeploymentTask { target: Mutex::new(target), profile, goal, + copy_options: CopyOptions::default(), } } pub fn name(&self) -> &str { &self.name } pub fn goal(&self) -> DeploymentGoal { self.goal } + /// Set options used for copying closures to the remote host. + pub fn set_copy_options(&mut self, options: CopyOptions) { + self.copy_options = options; + } + /// Set the progress bar used during deployment. pub async fn set_progress_bar(&mut self, progress: ProgressBar) { let mut target = self.target.lock().await; @@ -423,7 +432,9 @@ impl DeploymentTask { async fn push(&mut self) -> NixResult<()> { let mut target = self.target.lock().await; - target.copy_closure(&self.profile, CopyDirection::ToRemote, true).await + let options = self.copy_options.include_outputs(true); + + target.copy_closure(&self.profile, CopyDirection::ToRemote, options).await } async fn push_and_activate(&mut self) -> NixResult<()> {