Skip to content

Commit cea6cfb

Browse files
authored
Merge pull request #151 from benthecarman/systemd
2 parents 41443a4 + 754e6c7 commit cea6cfb

3 files changed

Lines changed: 73 additions & 0 deletions

File tree

ldk-server/src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ use crate::service::NodeService;
5151
use crate::util::config::{load_config, ArgsConfig, ChainSource};
5252
use crate::util::logger::ServerLogger;
5353
use crate::util::proto_adapter::{forwarded_payment_to_proto, payment_to_proto};
54+
use crate::util::systemd;
5455
use crate::util::tls::get_or_generate_tls_config;
5556

5657
const API_KEY_FILE: &str = "api_key";
@@ -277,6 +278,8 @@ fn main() {
277278
let tls_acceptor = tokio_rustls::TlsAcceptor::from(Arc::new(server_config));
278279
info!("TLS enabled for REST service on {}", config_file.rest_service_addr);
279280

281+
systemd::notify_ready();
282+
280283
loop {
281284
select! {
282285
event = event_node.next_event_async() => {
@@ -453,6 +456,7 @@ fn main() {
453456
}
454457
});
455458

459+
systemd::notify_stopping();
456460
node.stop().expect("Shutdown should always succeed.");
457461
info!("Shutdown complete..");
458462
}

ldk-server/src/util/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@
1010
pub(crate) mod config;
1111
pub(crate) mod logger;
1212
pub(crate) mod proto_adapter;
13+
pub(crate) mod systemd;
1314
pub(crate) mod tls;

ldk-server/src/util/systemd.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// This file is Copyright its original authors, visible in version control
2+
// history.
3+
//
4+
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5+
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7+
// You may not use this file except in accordance with one or both of these
8+
// licenses.
9+
10+
#[cfg(target_os = "linux")]
11+
use std::os::linux::net::SocketAddrExt;
12+
#[cfg(target_os = "linux")]
13+
use std::os::unix::net::UnixDatagram;
14+
15+
#[cfg(target_os = "linux")]
16+
use log::{info, warn};
17+
18+
#[cfg(target_os = "linux")]
19+
fn notify(state: &str) {
20+
let socket_path = match std::env::var("NOTIFY_SOCKET") {
21+
Ok(path) => path,
22+
Err(_) => return,
23+
};
24+
25+
let socket = match UnixDatagram::unbound() {
26+
Ok(s) => s,
27+
Err(e) => {
28+
warn!("Failed to create socket for systemd notification: {e}");
29+
return;
30+
},
31+
};
32+
33+
// systemd sets NOTIFY_SOCKET to either a filesystem path (e.g. /run/systemd/notify)
34+
// or an abstract socket prefixed with '@'. Abstract sockets require special addressing.
35+
let result = if let Some(abstract_name) = socket_path.strip_prefix('@') {
36+
match std::os::unix::net::SocketAddr::from_abstract_name(abstract_name) {
37+
Ok(addr) => socket.send_to_addr(state.as_bytes(), &addr),
38+
Err(e) => {
39+
warn!("Failed to create abstract socket address: {e}");
40+
return;
41+
},
42+
}
43+
} else {
44+
socket.send_to(state.as_bytes(), &socket_path)
45+
};
46+
47+
if let Err(e) = result {
48+
warn!("Failed to send systemd notification: {e}");
49+
} else {
50+
info!("Sent systemd notification: {state}");
51+
}
52+
}
53+
54+
#[cfg(target_os = "linux")]
55+
pub fn notify_ready() {
56+
notify("READY=1");
57+
}
58+
59+
#[cfg(target_os = "linux")]
60+
pub fn notify_stopping() {
61+
notify("STOPPING=1");
62+
}
63+
64+
#[cfg(not(target_os = "linux"))]
65+
pub fn notify_ready() {}
66+
67+
#[cfg(not(target_os = "linux"))]
68+
pub fn notify_stopping() {}

0 commit comments

Comments
 (0)