add reload support to api daemon
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
		| @ -4,6 +4,7 @@ extern crate proxmox_backup; | ||||
| use proxmox_backup::api_schema::router::*; | ||||
| use proxmox_backup::api_schema::config::*; | ||||
| use proxmox_backup::server::rest::*; | ||||
| use proxmox_backup::tools::daemon::ReexecStore; | ||||
| use proxmox_backup::auth_helpers::*; | ||||
| use proxmox_backup::config; | ||||
|  | ||||
| @ -11,9 +12,12 @@ use failure::*; | ||||
| use lazy_static::lazy_static; | ||||
|  | ||||
| use futures::future::Future; | ||||
| use tokio::prelude::*; | ||||
|  | ||||
| use hyper; | ||||
|  | ||||
| static mut QUIT_MAIN: bool = false; | ||||
|  | ||||
| fn main() { | ||||
|  | ||||
|     if let Err(err) = run() { | ||||
| @ -23,6 +27,8 @@ fn main() { | ||||
| } | ||||
|  | ||||
| fn run() -> Result<(), Error> { | ||||
|     // This manages data for reloads: | ||||
|     let mut reexecer = ReexecStore::new(); | ||||
|  | ||||
|     if let Err(err) = syslog::init( | ||||
|         syslog::Facility::LOG_DAEMON, | ||||
| @ -43,8 +49,6 @@ fn run() -> Result<(), Error> { | ||||
|     } | ||||
|     let _ = csrf_secret(); // load with lazy_static | ||||
|  | ||||
|     let addr = ([127,0,0,1], 82).into(); | ||||
|  | ||||
|     lazy_static!{ | ||||
|        static ref ROUTER: Router = proxmox_backup::api2::router(); | ||||
|     } | ||||
| @ -54,12 +58,76 @@ fn run() -> Result<(), Error> { | ||||
|  | ||||
|     let rest_server = RestServer::new(config); | ||||
|  | ||||
|     let server = hyper::Server::bind(&addr) | ||||
|     // http server future: | ||||
|  | ||||
|     let listener: tokio::net::TcpListener = reexecer.restore( | ||||
|         "PROXMOX_BACKUP_LISTEN_FD", | ||||
|         || { | ||||
|             let addr = ([127,0,0,1], 82).into(); | ||||
|             Ok(tokio::net::TcpListener::bind(&addr)?) | ||||
|         }, | ||||
|     )?; | ||||
|  | ||||
|     let mut http_server = hyper::Server::builder(listener.incoming()) | ||||
|         .serve(rest_server) | ||||
|         .map_err(|e| eprintln!("server error: {}", e)); | ||||
|  | ||||
|     // Run this server for... forever! | ||||
|     hyper::rt::run(server); | ||||
|     // signalfd future: | ||||
|  | ||||
|     let signal_handler = | ||||
|         proxmox_backup::tools::daemon::default_signalfd_stream( | ||||
|             reexecer, | ||||
|             || { | ||||
|                 unsafe { QUIT_MAIN = true; } | ||||
|                 Ok(()) | ||||
|             }, | ||||
|         )? | ||||
|         .map(|si| { | ||||
|             // debugging... | ||||
|             eprintln!("received signal: {}", si.ssi_signo); | ||||
|         }) | ||||
|         .map_err(|e| { | ||||
|             eprintln!("error from signalfd: {}, shutting down...", e); | ||||
|             unsafe { | ||||
|                 QUIT_MAIN = true; | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|  | ||||
|     // Combined future for signalfd & http server, we want to quit as soon as either of them ends. | ||||
|     // Neither of them is supposed to end unless some weird error happens, so just bail out if is | ||||
|     // the case... | ||||
|     let mut signal_handler = signal_handler.into_future(); | ||||
|     let main = futures::future::poll_fn(move || { | ||||
|         // Helper for some diagnostic error messages: | ||||
|         fn poll_helper<S: Future>(stream: &mut S, name: &'static str) -> bool { | ||||
|             match stream.poll() { | ||||
|                 Ok(Async::Ready(_)) => { | ||||
|                     eprintln!("{} ended, shutting down", name); | ||||
|                     true | ||||
|                 } | ||||
|                 Err(_) => { | ||||
|                     eprintln!("{} error, shutting down", name); | ||||
|                     true | ||||
|                 }, | ||||
|                 _ => false, | ||||
|             } | ||||
|         } | ||||
|         if poll_helper(&mut http_server, "http server") || | ||||
|            poll_helper(&mut signal_handler, "signalfd handler") | ||||
|         { | ||||
|             return Ok(Async::Ready(())); | ||||
|         } | ||||
|  | ||||
|         if unsafe { QUIT_MAIN } { | ||||
|             eprintln!("shutdown requested"); | ||||
|             Ok(Async::Ready(())) | ||||
|         } else { | ||||
|             Ok(Async::NotReady) | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     hyper::rt::run(main); | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user