Check hickory-dns is fully started
When starting `hickory-dns` there is no easy way to check the start sequence has finished & its fully ready to accept connections. Other tools, e.g. unbound, are designed as services, they will correctly manage their `pidfile`. They also could be queried by the `servicectl` inside the Docker container.
This commit is contained in:
parent
fe3961ffe1
commit
2e46421927
@ -55,6 +55,11 @@ impl Implementation {
|
|||||||
matches!(self, Self::Bind)
|
matches!(self, Self::Bind)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn is_hickory(&self) -> bool {
|
||||||
|
matches!(self, Self::Hickory(_))
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn format_config(&self, config: Config) -> String {
|
pub(crate) fn format_config(&self, config: Config) -> String {
|
||||||
match config {
|
match config {
|
||||||
Config::Resolver {
|
Config::Resolver {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
|
use std::io::{BufRead, BufReader};
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
use crate::container::{Child, Container, Network};
|
use crate::container::{Child, Container, Network};
|
||||||
@ -38,23 +39,26 @@ impl Resolver {
|
|||||||
self.container.ipv4_addr()
|
self.container.ipv4_addr()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// gracefully terminates the name server collecting all logs
|
/// Gracefully terminates the name server collecting all logs
|
||||||
pub fn terminate(self) -> Result<String> {
|
pub fn terminate(self) -> Result<String> {
|
||||||
let pidfile = self.implementation.pidfile(Role::Resolver);
|
let Resolver {
|
||||||
|
implementation,
|
||||||
|
container,
|
||||||
|
child,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
let pidfile = implementation.pidfile(Role::Resolver);
|
||||||
let kill = format!(
|
let kill = format!(
|
||||||
"test -f {pidfile} || sleep 1
|
"test -f {pidfile} || sleep 1
|
||||||
kill -TERM $(cat {pidfile})"
|
kill -TERM $(cat {pidfile})"
|
||||||
);
|
);
|
||||||
self.container.status_ok(&["sh", "-c", &kill])?;
|
container.status_ok(&["sh", "-c", &kill])?;
|
||||||
let output = self.child.wait()?;
|
let output = child.wait()?;
|
||||||
|
|
||||||
// the hickory-dns binary does not do signal handling so it won't shut down gracefully; we
|
// the hickory-dns binary does not do signal handling so it won't shut down gracefully; we
|
||||||
// will still get some logs so we'll ignore the fact that it fails to shut down ...
|
// will still get some logs so we'll ignore the fact that it fails to shut down ...
|
||||||
let is_hickory = matches!(self.implementation, Implementation::Hickory(_));
|
if !implementation.is_hickory() && !output.status.success() {
|
||||||
if !is_hickory && !output.status.success() {
|
return Err(format!("could not terminate the `{}` process", implementation).into());
|
||||||
return Err(
|
|
||||||
format!("could not terminate the `{}` process", self.implementation).into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
@ -115,7 +119,21 @@ impl ResolverSettings {
|
|||||||
container.cp(path, &contents)?;
|
container.cp(path, &contents)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let child = container.spawn(implementation.cmd_args(config.role()))?;
|
let mut child = container.spawn(implementation.cmd_args(config.role()))?;
|
||||||
|
|
||||||
|
// For HickoryDNS we need to wait until its start sequence finished. Only then the server is able
|
||||||
|
// to accept connections. The start sequence logs are consumed here.
|
||||||
|
if implementation.is_hickory() {
|
||||||
|
let stdout = child.stdout()?;
|
||||||
|
let lines = BufReader::new(stdout).lines();
|
||||||
|
|
||||||
|
for line in lines {
|
||||||
|
let line = line?;
|
||||||
|
if line.contains("Server starting up") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Resolver {
|
Ok(Resolver {
|
||||||
child,
|
child,
|
||||||
@ -195,14 +213,8 @@ mod tests {
|
|||||||
)))?;
|
)))?;
|
||||||
let logs = resolver.terminate()?;
|
let logs = resolver.terminate()?;
|
||||||
|
|
||||||
eprintln!("{logs}");
|
// Hickory-DNS start sequence log has been consumed in `ResolverSettings.start`.
|
||||||
let mut found = false;
|
assert!(logs.is_empty());
|
||||||
for line in logs.lines() {
|
|
||||||
if line.contains("Hickory DNS") && line.contains("starting") {
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert!(found);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user