Allow disabling --use-substitutes and --gzip during copying

This commit is contained in:
Zhaofeng Li 2021-01-13 12:20:27 -08:00
parent 2cb429ed8d
commit f3bf3dc492
3 changed files with 85 additions and 14 deletions

View file

@ -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 => {

View file

@ -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<Vec<StorePath>> {
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<Vec<StorePath>> {
@ -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<Vec<StorePath>> {
@ -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());

View file

@ -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<()> {