forked from DGNum/colmena
Merge pull request #21 from jasonrm/machines-file
eval.nix: Adds meta.machinesFile option that is passed to Nix as builder option
This commit is contained in:
commit
99ba8db335
8 changed files with 69 additions and 6 deletions
|
@ -54,6 +54,15 @@ Here is a sample `hive.nix` with two nodes, with some common configurations appl
|
||||||
nodeNixpkgs = {
|
nodeNixpkgs = {
|
||||||
node-b = ./another-nixos-checkout;
|
node-b = ./another-nixos-checkout;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# If your Colmena host has nix configured to allow for remote builds
|
||||||
|
# (for nix-daemon, your user being included in trusted-users)
|
||||||
|
# you can set a machines file that will be passed to the underlying
|
||||||
|
# nix-store command during derivation realization as a builders option.
|
||||||
|
# For example, if you support multiple orginizations each with their own
|
||||||
|
# build machine(s) you can ensure that builds only take place on your
|
||||||
|
# local machine and/or the machines specified in this file.
|
||||||
|
# machinesFile = ./machines.client-a;
|
||||||
};
|
};
|
||||||
|
|
||||||
defaults = { pkgs, ... }: {
|
defaults = { pkgs, ... }: {
|
||||||
|
|
|
@ -121,6 +121,8 @@ pub async fn run(_global_args: &ArgMatches<'_>, local_args: &ArgMatches<'_>) {
|
||||||
log::info!("Enumerating nodes...");
|
log::info!("Enumerating nodes...");
|
||||||
let all_nodes = hive.deployment_info().await.unwrap();
|
let all_nodes = hive.deployment_info().await.unwrap();
|
||||||
|
|
||||||
|
let nix_options = hive.nix_options().await.unwrap();
|
||||||
|
|
||||||
let selected_nodes = match local_args.value_of("on") {
|
let selected_nodes = match local_args.value_of("on") {
|
||||||
Some(filter) => {
|
Some(filter) => {
|
||||||
util::filter_nodes(&all_nodes, filter)
|
util::filter_nodes(&all_nodes, filter)
|
||||||
|
@ -165,7 +167,7 @@ pub async fn run(_global_args: &ArgMatches<'_>, local_args: &ArgMatches<'_>) {
|
||||||
if build_only {
|
if build_only {
|
||||||
targets.insert(
|
targets.insert(
|
||||||
node.clone(),
|
node.clone(),
|
||||||
Target::new(localhost(), config.clone()),
|
Target::new(localhost(nix_options.clone()), config.clone()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,13 +100,14 @@ pub async fn run(_global_args: &ArgMatches<'_>, local_args: &ArgMatches<'_>) {
|
||||||
|
|
||||||
let target: Target = {
|
let target: Target = {
|
||||||
if let Some(info) = hive.deployment_info_for(&hostname).await.unwrap() {
|
if let Some(info) = hive.deployment_info_for(&hostname).await.unwrap() {
|
||||||
|
let nix_options = hive.nix_options().await.unwrap();
|
||||||
if !info.allows_local_deployment() {
|
if !info.allows_local_deployment() {
|
||||||
log::error!("Local deployment is not enabled for host {}.", hostname);
|
log::error!("Local deployment is not enabled for host {}.", hostname);
|
||||||
log::error!("Hint: Set deployment.allowLocalDeployment to true.");
|
log::error!("Hint: Set deployment.allowLocalDeployment to true.");
|
||||||
quit::with_code(2);
|
quit::with_code(2);
|
||||||
}
|
}
|
||||||
Target::new(
|
Target::new(
|
||||||
host::local(),
|
host::local(nix_options),
|
||||||
info.clone(),
|
info.clone(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -460,8 +460,9 @@ impl Deployment {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn build_profiles(self: Arc<Self>, chunk: &Vec<String>, derivation: StoreDerivation<ProfileMap>, progress: TaskProgress) -> Option<ProfileMap> {
|
async fn build_profiles(self: Arc<Self>, chunk: &Vec<String>, derivation: StoreDerivation<ProfileMap>, progress: TaskProgress) -> Option<ProfileMap> {
|
||||||
|
let nix_options = self.hive.nix_options().await.unwrap();
|
||||||
// FIXME: Remote build?
|
// FIXME: Remote build?
|
||||||
let mut builder = host::local();
|
let mut builder = host::local(nix_options);
|
||||||
|
|
||||||
builder.set_progress_bar(progress.clone());
|
builder.set_progress_bar(progress.clone());
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,25 @@ let
|
||||||
type = types.attrsOf types.unspecified;
|
type = types.attrsOf types.unspecified;
|
||||||
default = {};
|
default = {};
|
||||||
};
|
};
|
||||||
|
machinesFile = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Use the machines listed in this file when building this hive configuration.
|
||||||
|
|
||||||
|
If your Colmena host has nix configured to allow for remote builds
|
||||||
|
(for nix-daemon, your user being included in trusted-users)
|
||||||
|
you can set a machines file that will be passed to the underlying
|
||||||
|
nix-store command during derivation realization as a builders option.
|
||||||
|
For example, if you support multiple orginizations each with their own
|
||||||
|
build machine(s) you can ensure that builds only take place on your
|
||||||
|
local machine and/or the machines specified in this file.
|
||||||
|
|
||||||
|
See https://nixos.org/manual/nix/stable/#chap-distributed-builds
|
||||||
|
for the machine specification format.
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
apply = value: if value == null then null else toString value;
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -327,4 +346,5 @@ let
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
inherit nodes deploymentConfigJson toplevel buildAll buildSelected introspect;
|
inherit nodes deploymentConfigJson toplevel buildAll buildSelected introspect;
|
||||||
|
meta = hive.meta;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,23 @@ impl Hive {
|
||||||
self.show_trace = value;
|
self.show_trace = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn nix_options(&self) -> NixResult<Vec<String>> {
|
||||||
|
let mut options:Vec<String> = Vec::new();
|
||||||
|
if let Some(machines_file) = self.machines_file().await.unwrap() {
|
||||||
|
options.append(&mut vec![
|
||||||
|
"--option".to_owned(),
|
||||||
|
"builders".to_owned(),
|
||||||
|
format!("@{}", machines_file).to_owned()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.show_trace {
|
||||||
|
options.push("--show-trace".to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(options)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_path(&self) -> &Path {
|
pub fn as_path(&self) -> &Path {
|
||||||
&self.hive
|
&self.hive
|
||||||
}
|
}
|
||||||
|
@ -62,6 +79,15 @@ impl Hive {
|
||||||
Ok(configs)
|
Ok(configs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieve machinesFile setting for the hive.
|
||||||
|
pub async fn machines_file(&self) -> NixResult<Option<String>> {
|
||||||
|
let expr = "toJSON (hive.meta.machinesFile or null)";
|
||||||
|
let s: String = self.nix_instantiate(&expr).eval()
|
||||||
|
.capture_json().await?;
|
||||||
|
|
||||||
|
Ok(serde_json::from_str(&s).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
/// Retrieve deployment info for a single node.
|
/// Retrieve deployment info for a single node.
|
||||||
pub async fn deployment_info_for(&self, node: &str) -> NixResult<Option<NodeConfig>> {
|
pub async fn deployment_info_for(&self, node: &str) -> NixResult<Option<NodeConfig>> {
|
||||||
let expr = format!("toJSON (hive.nodes.\"{}\".config.deployment or null)", node);
|
let expr = format!("toJSON (hive.nodes.\"{}\".config.deployment or null)", node);
|
||||||
|
|
|
@ -18,13 +18,15 @@ use crate::progress::TaskProgress;
|
||||||
pub struct Local {
|
pub struct Local {
|
||||||
progress_bar: TaskProgress,
|
progress_bar: TaskProgress,
|
||||||
logs: String,
|
logs: String,
|
||||||
|
nix_options: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Local {
|
impl Local {
|
||||||
pub fn new() -> Self {
|
pub fn new(nix_options: Vec<String>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
progress_bar: TaskProgress::default(),
|
progress_bar: TaskProgress::default(),
|
||||||
logs: String::new(),
|
logs: String::new(),
|
||||||
|
nix_options,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +38,8 @@ impl Host for Local {
|
||||||
}
|
}
|
||||||
async fn realize_remote(&mut self, derivation: &StorePath) -> NixResult<Vec<StorePath>> {
|
async fn realize_remote(&mut self, derivation: &StorePath) -> NixResult<Vec<StorePath>> {
|
||||||
let mut command = Command::new("nix-store");
|
let mut command = Command::new("nix-store");
|
||||||
|
|
||||||
|
command.args(self.nix_options.clone());
|
||||||
command
|
command
|
||||||
.arg("--no-gc-warning")
|
.arg("--no-gc-warning")
|
||||||
.arg("--realise")
|
.arg("--realise")
|
||||||
|
|
|
@ -13,8 +13,8 @@ pub use local::Local;
|
||||||
|
|
||||||
mod key_uploader;
|
mod key_uploader;
|
||||||
|
|
||||||
pub(crate) fn local() -> Box<dyn Host + 'static> {
|
pub(crate) fn local(nix_options: Vec<String>) -> Box<dyn Host + 'static> {
|
||||||
Box::new(Local::new())
|
Box::new(Local::new(nix_options))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
|
Loading…
Reference in a new issue