Skip to content

Commit

Permalink
Reload hostmap on sighup
Browse files Browse the repository at this point in the history
  • Loading branch information
Virv12 committed Oct 9, 2024
1 parent f61c28f commit 433370a
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 28 deletions.
10 changes: 10 additions & 0 deletions pixie-server/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pixie-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ postcard = { version = "1.0.8", default-features = false, features = ["alloc"] }
serde = "1.0.193"
serde_derive = "1.0.193"
serde_yaml = "0.9"
tokio = { version = "1.34.0", features = ["macros", "fs", "rt-multi-thread", "sync"] }
tokio = { version = "1.34.0", features = ["macros", "fs", "rt-multi-thread", "sync", "signal"] }
serde_json = "1.0.108"
hostfile = "0.2.0"
hex = "0.4.3"
Expand Down
34 changes: 23 additions & 11 deletions pixie-server/src/dnsmasq.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{
collections::HashMap,
fs::File,
io::{BufWriter, Error, Write},
net::Ipv4Addr,
Expand Down Expand Up @@ -99,23 +100,30 @@ async fn write_hosts(state: &State, hosts: &[(MacAddr6, Ipv4Addr, Option<String>
Ok(())
}

fn get_hosts(state: &State, units: &[Unit]) -> Vec<(MacAddr6, Ipv4Addr, Option<String>)> {
fn get_hosts(
hostmap: &HashMap<Ipv4Addr, String>,
units: &[Unit],
) -> Vec<(MacAddr6, Ipv4Addr, Option<String>)> {
units
.iter()
.map(|unit| {
let mac = unit.mac;
let ip = unit.static_ip();
let hostname = state.hostmap.get(&ip).cloned();
let hostname = hostmap.get(&ip).cloned();
(mac, ip, hostname)
})
.collect()
}

pub async fn main(state: Arc<State>) -> Result<()> {
let mut units_rx = state.units.subscribe();
let mut hostmap_rx = state.hostmap.subscribe();

write_config(&state).await?;
let mut hosts = get_hosts(&state, &units_rx.borrow_and_update());
let mut hosts = get_hosts(
&hostmap_rx.borrow_and_update(),
&units_rx.borrow_and_update(),
);
write_hosts(&state, &hosts).await?;

let dnsmasq = DnsmasqHandle {
Expand All @@ -132,14 +140,18 @@ pub async fn main(state: Arc<State>) -> Result<()> {

loop {
tokio::select! {
_ = units_rx.changed() => {
let hosts2 = get_hosts(&state, &units_rx.borrow_and_update());
if hosts != hosts2 {
hosts = hosts2;
write_hosts(&state, &hosts).await?;
dnsmasq.reload()?;
}
}
ret = units_rx.changed() => ret.unwrap(),
ret = hostmap_rx.changed() => ret.unwrap(),
}

let hosts2 = get_hosts(
&hostmap_rx.borrow_and_update(),
&units_rx.borrow_and_update(),
);
if hosts != hosts2 {
hosts = hosts2;
write_hosts(&state, &hosts).await?;
dnsmasq.reload()?;
}
}
}
26 changes: 11 additions & 15 deletions pixie-server/src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,23 +161,19 @@ async fn gc(extract::State(state): extract::State<Arc<State>>) -> impl IntoRespo
}

async fn status(extract::State(state): extract::State<Arc<State>>) -> impl IntoResponse {
let initial_messages = vec![
StatusUpdate::Config(state.config.clone()),
StatusUpdate::HostMap(state.hostmap.clone()),
];
let mut units_rx = state.units.subscribe();
units_rx.mark_changed();
let units_rx = WatchStream::new(units_rx);

let mut image_rx = state.image_stats.subscribe();
image_rx.mark_changed();
let image_rx = WatchStream::new(image_rx);

let messages =
futures::stream::iter(initial_messages.into_iter()).chain(futures::stream::select(
let initial_messages = [StatusUpdate::Config(state.config.clone())];

let units_rx = WatchStream::new(state.units.subscribe());
let image_rx = WatchStream::new(state.image_stats.subscribe());
let hostmap_rx = WatchStream::new(state.hostmap.subscribe());

let messages = futures::stream::iter(initial_messages).chain(futures::stream::select(
futures::stream::select(
image_rx.map(StatusUpdate::ImageStats),
units_rx.map(StatusUpdate::Units),
));
),
hostmap_rx.map(StatusUpdate::HostMap),
));
let lines = messages.map(|msg| serde_json::to_string(&msg).map(|x| x + "\n"));

let mut res = Response::new(Body::from_stream(lines));
Expand Down
9 changes: 9 additions & 0 deletions pixie-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,15 @@ async fn main() -> Result<()> {

let state = Arc::new(State::load(options.storage_dir)?);

let state2 = state.clone();
tokio::spawn(async move {
let mut signal = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::hangup())
.expect("failed to register signal handler");
while let Some(()) = signal.recv().await {
state2.reload().unwrap();
}
});

async fn flatten(task: JoinHandle<Result<()>>) -> Result<()> {
task.await??;
Ok(())
Expand Down
18 changes: 17 additions & 1 deletion pixie-server/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn get_image_csize(image: &Image) -> u64 {
pub struct State {
pub storage_dir: PathBuf,
pub config: Config,
pub hostmap: HashMap<Ipv4Addr, String>,
pub hostmap: watch::Sender<HashMap<Ipv4Addr, String>>,

pub units: watch::Sender<Vec<Unit>>,
// TODO: use an Option
Expand Down Expand Up @@ -64,6 +64,7 @@ impl State {
}
}
}
let hostmap = watch::Sender::new(hostmap);

let units_path = storage_dir.join("registered.json");
let units = watch::Sender::new({
Expand Down Expand Up @@ -152,6 +153,21 @@ impl State {
})
}

pub fn reload(&self) -> Result<()> {
let mut hostmap = HashMap::new();
if let Some(hostsfile) = &self.config.hosts.hostsfile {
let hosts = hostfile::parse_file(hostsfile)
.map_err(|e| anyhow!("Error parsing host file: {e}"))?;
for host in hosts {
if let IpAddr::V4(ip) = host.ip {
hostmap.insert(ip, host.names[0].clone());
}
}
}
self.hostmap.send_replace(hostmap);
Ok(())
}

pub fn gc_chunks(&self) -> Result<()> {
self.image_stats.send_modify(|image_stats| {
let mut chunk_stats = self.chunk_stats.lock().unwrap();
Expand Down
1 change: 1 addition & 0 deletions pixie.service
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Group=root
ExecStart=/usr/local/bin/pixie-server -s /var/local/lib/pixie
Environment=RUST_LOG=info
WorkingDirectory=/var/local/lib/pixie
ExecReload=kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

0 comments on commit 433370a

Please sign in to comment.