config: accept list of systems as well as single string

This commit is contained in:
Cole Helbling 2022-03-05 12:42:23 -08:00
parent f1258f77ab
commit 62da9b6e3d
2 changed files with 51 additions and 23 deletions

View file

@ -29,21 +29,15 @@ fn main() -> Result<(), Box<dyn Error>> {
};
let conn = easylapin::from_config(&cfg.rabbitmq)?;
let handle = self::create_handle(&conn, &cfg, None)?;
let mut handles = Vec::new();
if let Some(ref additional_build_systems) = cfg.nix.additional_build_systems {
let mut handles = vec![handle];
for system in additional_build_systems {
let handle_ext = self::create_handle(&conn, &cfg, Some(system.to_string()))?;
handles.push(handle_ext);
}
task::block_on(future::join_all(handles));
} else {
task::block_on(handle);
for system in &cfg.nix.system {
let handle_ext = self::create_handle(&conn, &cfg, system.to_string())?;
handles.push(handle_ext);
}
task::block_on(future::join_all(handles));
drop(conn); // Close connection.
info!("Closed the session... EOF");
Ok(())
@ -52,17 +46,12 @@ fn main() -> Result<(), Box<dyn Error>> {
fn create_handle(
conn: &lapin::Connection,
cfg: &config::Config,
system_override: Option<String>,
system: String,
) -> Result<JoinHandle<()>, Box<dyn Error>> {
let mut chan = task::block_on(conn.create_channel())?;
let cloner = checkout::cached_cloner(Path::new(&cfg.checkout.root));
let nix = if let Some(system) = system_override {
cfg.nix().with_system(String::from(system))
} else {
cfg.nix()
};
let system = nix.system.clone();
let nix = cfg.nix().with_system(system.clone());
chan.declare_exchange(easyamqp::ExchangeConfig {
exchange: "build-jobs".to_owned(),

View file

@ -2,14 +2,17 @@ use crate::acl;
use crate::nix::Nix;
use std::collections::HashMap;
use std::fmt;
use std::fs::File;
use std::io::Read;
use std::marker::PhantomData;
use std::path::{Path, PathBuf};
use hubcaps::{Credentials, Github, InstallationTokenGenerator, JWTCredentials};
use hyper::net::HttpsConnector;
use hyper::Client;
use hyper_native_tls::NativeTlsClient;
use serde::de::{self, Deserialize, Deserializer};
use tracing::{debug, error, info, warn};
#[derive(Serialize, Deserialize, Debug)]
@ -40,8 +43,8 @@ pub struct RabbitMqConfig {
#[derive(Serialize, Deserialize, Debug)]
pub struct NixConfig {
pub system: String,
pub additional_build_systems: Option<Vec<String>>,
#[serde(deserialize_with = "deserialize_one_or_many")]
pub system: Vec<String>,
pub remote: String,
pub build_timeout_seconds: u16,
pub initial_heap_size: Option<String>,
@ -88,7 +91,7 @@ pub struct CheckoutConfig {
impl Config {
pub fn whoami(&self) -> String {
format!("{}-{}", self.runner.identity, self.nix.system)
format!("{}-{}", self.runner.identity, self.nix.system.join(","))
}
pub fn acl(&self) -> acl::Acl {
@ -136,7 +139,11 @@ impl Config {
}
Nix::new(
self.nix.system.clone(),
self.nix
.system
.first()
.expect("expected at least one system")
.clone(),
self.nix.remote.clone(),
self.nix.build_timeout_seconds,
self.nix.initial_heap_size.clone(),
@ -224,3 +231,35 @@ impl GithubAppVendingMachine {
}))
}
}
// Copied from https://stackoverflow.com/a/43627388
fn deserialize_one_or_many<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
where
D: Deserializer<'de>,
{
struct StringOrVec(PhantomData<Vec<String>>);
impl<'de> de::Visitor<'de> for StringOrVec {
type Value = Vec<String>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("string or list of strings")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(vec![value.to_owned()])
}
fn visit_seq<S>(self, visitor: S) -> Result<Self::Value, S::Error>
where
S: de::SeqAccess<'de>,
{
Deserialize::deserialize(de::value::SeqAccessDeserializer::new(visitor))
}
}
deserializer.deserialize_any(StringOrVec(PhantomData))
}