diff --git a/packages/dns-test/src/client.rs b/packages/dns-test/src/client.rs index 2119f24b..b66b73ca 100644 --- a/packages/dns-test/src/client.rs +++ b/packages/dns-test/src/client.rs @@ -13,7 +13,7 @@ pub struct Client { impl Client { pub fn new(network: &Network) -> Result { Ok(Self { - inner: Container::run(Implementation::Unbound, network)?, + inner: Container::run(&Implementation::Unbound, network)?, }) } diff --git a/packages/dns-test/src/container.rs b/packages/dns-test/src/container.rs index 0008344b..f1ef2277 100644 --- a/packages/dns-test/src/container.rs +++ b/packages/dns-test/src/container.rs @@ -22,7 +22,7 @@ const PACKAGE_NAME: &str = env!("CARGO_PKG_NAME"); impl Container { /// Starts the container in a "parked" state - pub fn run(implementation: Implementation, network: &Network) -> Result { + pub fn run(implementation: &Implementation, network: &Network) -> Result { // TODO make this configurable and support hickory & bind let dockerfile = implementation.dockerfile(); let docker_build_dir = TempDir::new()?; @@ -37,7 +37,26 @@ impl Container { .arg(&image_tag) .arg(docker_build_dir); + let srcdir = if let Implementation::Hickory { url } = implementation { + Some(url) + } else { + None + }; + implementation.once().call_once(|| { + if let Some(srcdir) = srcdir { + let mut cp_r = Command::new("git"); + cp_r.args([ + "clone", + "--depth", + "1", + srcdir, + &docker_build_dir.join("src").display().to_string(), + ]); + + exec_or_panic(&mut cp_r, false); + } + exec_or_panic(&mut command, verbose_docker_build()); }); @@ -312,7 +331,7 @@ mod tests { #[test] fn run_works() -> Result<()> { let network = Network::new()?; - let container = Container::run(Implementation::Unbound, &network)?; + let container = Container::run(&Implementation::Unbound, &network)?; let output = container.output(&["true"])?; assert!(output.status.success()); @@ -323,7 +342,7 @@ mod tests { #[test] fn ipv4_addr_works() -> Result<()> { let network = Network::new()?; - let container = Container::run(Implementation::Unbound, &network)?; + let container = Container::run(&Implementation::Unbound, &network)?; let ipv4_addr = container.ipv4_addr(); let output = container.output(&["ping", "-c1", &format!("{ipv4_addr}")])?; @@ -335,7 +354,7 @@ mod tests { #[test] fn cp_works() -> Result<()> { let network = Network::new()?; - let container = Container::run(Implementation::Unbound, &network)?; + let container = Container::run(&Implementation::Unbound, &network)?; let path = "/tmp/somefile"; let contents = "hello"; diff --git a/packages/dns-test/src/container/network.rs b/packages/dns-test/src/container/network.rs index 4199f9ee..7e9f81b1 100644 --- a/packages/dns-test/src/container/network.rs +++ b/packages/dns-test/src/container/network.rs @@ -146,7 +146,7 @@ mod tests { let network = Network::new().expect("Failed to create network"); let network_name = network.name().to_string(); let container = - Container::run(Implementation::Unbound, &network).expect("Failed to start container"); + Container::run(&Implementation::Unbound, &network).expect("Failed to start container"); assert!(exists_network(&network_name)); drop(network); diff --git a/packages/dns-test/src/docker/hickory.Dockerfile b/packages/dns-test/src/docker/hickory.Dockerfile index d2edd1a9..4cedaf46 100644 --- a/packages/dns-test/src/docker/hickory.Dockerfile +++ b/packages/dns-test/src/docker/hickory.Dockerfile @@ -4,5 +4,6 @@ RUN apt-get update && \ apt-get install -y \ tshark -RUN cargo install hickory-dns --version 0.24.0 --features recursor --debug +COPY ./src /usr/src/hickory +RUN cargo install --path /usr/src/hickory/bin --features recursor --debug env RUST_LOG=debug diff --git a/packages/dns-test/src/lib.rs b/packages/dns-test/src/lib.rs index 6c9d32e8..82d90851 100644 --- a/packages/dns-test/src/lib.rs +++ b/packages/dns-test/src/lib.rs @@ -21,17 +21,17 @@ mod trust_anchor; pub mod tshark; pub mod zone_file; -#[derive(Clone, Copy)] +#[derive(Clone)] pub enum Implementation { Unbound, - Hickory, + Hickory { url: String }, } impl Implementation { fn dockerfile(&self) -> &'static str { match self { Implementation::Unbound => include_str!("docker/unbound.Dockerfile"), - Implementation::Hickory => include_str!("docker/hickory.Dockerfile"), + Implementation::Hickory { .. } => include_str!("docker/hickory.Dockerfile"), } } @@ -41,7 +41,8 @@ impl Implementation { static UNBOUND_ONCE: Once = Once::new(); &UNBOUND_ONCE } - Implementation::Hickory => { + + Implementation::Hickory { .. } => { static HICKORY_ONCE: Once = Once::new(); &HICKORY_ONCE } @@ -59,7 +60,7 @@ impl fmt::Display for Implementation { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let s = match self { Implementation::Unbound => "unbound", - Implementation::Hickory => "hickory", + Implementation::Hickory { .. } => "hickory", }; f.write_str(s) } @@ -67,10 +68,20 @@ impl fmt::Display for Implementation { pub fn subject() -> Implementation { if let Ok(subject) = std::env::var("DNS_TEST_SUBJECT") { - match subject.as_str() { - "hickory" => Implementation::Hickory, - "unbound" => Implementation::Unbound, - _ => panic!("unknown implementation: {subject}"), + if subject == "unbound" { + return Implementation::Unbound; + } + + if subject.starts_with("hickory") { + if let Some(url) = subject.strip_prefix("hickory ") { + Implementation::Hickory { + url: url.to_string(), + } + } else { + panic!("the syntax of DNS_TEST_SUBJECT is 'hickory $URL', e.g. 'hickory /tmp/hickory' or 'hickory https://github.com/owner/repo'") + } + } else { + panic!("unknown implementation: {subject}") } } else { Implementation::default() diff --git a/packages/dns-test/src/name_server.rs b/packages/dns-test/src/name_server.rs index 66bbb1bf..8033b676 100644 --- a/packages/dns-test/src/name_server.rs +++ b/packages/dns-test/src/name_server.rs @@ -43,7 +43,7 @@ impl<'a> NameServer<'a, Stopped> { }); Ok(Self { - container: Container::run(Implementation::Unbound, network)?, + container: Container::run(&Implementation::Unbound, network)?, zone_file, state: Stopped, }) diff --git a/packages/dns-test/src/resolver.rs b/packages/dns-test/src/resolver.rs index 02e40721..091e59b1 100644 --- a/packages/dns-test/src/resolver.rs +++ b/packages/dns-test/src/resolver.rs @@ -33,7 +33,7 @@ impl Resolver { "must configure at least one local root server" ); - let container = Container::run(implementation, network)?; + let container = Container::run(&implementation, network)?; let mut hints = String::new(); for root in roots { @@ -51,7 +51,7 @@ impl Resolver { )?; } - Implementation::Hickory => { + Implementation::Hickory { .. } => { container.status_ok(&["mkdir", "-p", "/etc/hickory"])?; container.cp("/etc/hickory/root.hints", &hints)?; @@ -66,7 +66,7 @@ impl Resolver { let command: &[_] = match implementation { Implementation::Unbound => &["unbound", "-d"], - Implementation::Hickory => &["hickory-dns", "-d"], + Implementation::Hickory { .. } => &["hickory-dns", "-d"], }; let child = container.spawn(command)?;