sd_notify is not synchronous, iow. it only waits until the message reaches the queue not until it is processed by systemd when the process that sent such a message exits before systemd could process it, it cannot be associated to the correct pid so in case of reloading, we send a message with 'MAINPID=<newpid>' to signal that it will change. if now the old process exits before systemd knows this, it will not accept the 'READY=1' message from the child, since it rejects the MAINPID change since there is no (AFAICS) library interface to check the unit status, we use 'systemctl is-active <SERVICE_NAME>' to check the state until it is not 'reloading' anymore. on newer systemd versions, there is 'sd_notify_barrier' which would allow us to wait for systemd to have all messages from the current pid to be processed before acknowledging to the child, but on buster the systemd version is to old... Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
104 lines
3.0 KiB
Rust
104 lines
3.0 KiB
Rust
use anyhow::{bail, Error};
|
|
use futures::*;
|
|
|
|
use proxmox::try_block;
|
|
use proxmox::api::RpcEnvironmentType;
|
|
|
|
//use proxmox_backup::tools;
|
|
//use proxmox_backup::api_schema::config::*;
|
|
use proxmox_backup::server::rest::*;
|
|
use proxmox_backup::server;
|
|
use proxmox_backup::tools::daemon;
|
|
use proxmox_backup::auth_helpers::*;
|
|
use proxmox_backup::config;
|
|
use proxmox_backup::buildcfg;
|
|
|
|
fn main() {
|
|
proxmox_backup::tools::setup_safe_path_env();
|
|
|
|
if let Err(err) = proxmox_backup::tools::runtime::main(run()) {
|
|
eprintln!("Error: {}", err);
|
|
std::process::exit(-1);
|
|
}
|
|
}
|
|
|
|
async fn run() -> Result<(), Error> {
|
|
if let Err(err) = syslog::init(
|
|
syslog::Facility::LOG_DAEMON,
|
|
log::LevelFilter::Info,
|
|
Some("proxmox-backup-api")) {
|
|
bail!("unable to inititialize syslog - {}", err);
|
|
}
|
|
|
|
server::create_task_log_dirs()?;
|
|
|
|
config::create_configdir()?;
|
|
|
|
config::update_self_signed_cert(false)?;
|
|
|
|
proxmox_backup::rrd::create_rrdb_dir()?;
|
|
proxmox_backup::server::jobstate::create_jobstate_dir()?;
|
|
|
|
if let Err(err) = generate_auth_key() {
|
|
bail!("unable to generate auth key - {}", err);
|
|
}
|
|
let _ = private_auth_key(); // load with lazy_static
|
|
|
|
if let Err(err) = generate_csrf_key() {
|
|
bail!("unable to generate csrf key - {}", err);
|
|
}
|
|
let _ = csrf_secret(); // load with lazy_static
|
|
|
|
let mut config = server::ApiConfig::new(
|
|
buildcfg::JS_DIR, &proxmox_backup::api2::ROUTER, RpcEnvironmentType::PRIVILEGED)?;
|
|
|
|
let mut commando_sock = server::CommandoSocket::new(server::our_ctrl_sock());
|
|
|
|
config.enable_file_log(buildcfg::API_ACCESS_LOG_FN, &mut commando_sock)?;
|
|
|
|
let rest_server = RestServer::new(config);
|
|
|
|
// http server future:
|
|
let server = daemon::create_daemon(
|
|
([127,0,0,1], 82).into(),
|
|
move |listener, ready| {
|
|
let incoming = proxmox_backup::tools::async_io::StaticIncoming::from(listener);
|
|
Ok(ready
|
|
.and_then(|_| hyper::Server::builder(incoming)
|
|
.serve(rest_server)
|
|
.with_graceful_shutdown(server::shutdown_future())
|
|
.map_err(Error::from)
|
|
)
|
|
.map(|e| {
|
|
if let Err(e) = e {
|
|
eprintln!("server error: {}", e);
|
|
}
|
|
})
|
|
)
|
|
},
|
|
"proxmox-backup.service",
|
|
);
|
|
|
|
server::write_pid(buildcfg::PROXMOX_BACKUP_API_PID_FN)?;
|
|
daemon::systemd_notify(daemon::SystemdNotify::Ready)?;
|
|
|
|
let init_result: Result<(), Error> = try_block!({
|
|
server::register_task_control_commands(&mut commando_sock)?;
|
|
commando_sock.spawn()?;
|
|
server::server_state_init()?;
|
|
Ok(())
|
|
});
|
|
|
|
if let Err(err) = init_result {
|
|
bail!("unable to start daemon - {}", err);
|
|
}
|
|
|
|
server.await?;
|
|
log::info!("server shutting down, waiting for active workers to complete");
|
|
proxmox_backup::server::last_worker_future().await?;
|
|
|
|
log::info!("done - exit server");
|
|
|
|
Ok(())
|
|
}
|