proxmox-backup/src/bin/proxmox-backup-api.rs
Thomas Lamprecht 8e7e2223d8 server/rest: implement request access log
reuse the FileLogger module in append mode.
As it implements write, which is not thread safe (mutable self) and
we use it in a async context we need to serialize access using a
mutex.

Try to use the same format we do in pveproxy, namely the one which is
also used in apache or nginx by default.

Use the response extensions to pass up the userid, if we extract it
from a ticket.

The privileged and unprivileged dameons log both to the same file, to
have a unified view, and avoiding the need to handle more log files.
We avoid extra intra-process locking by reusing the fact that a write
smaller than PIPE_BUF (4k on linux) is atomic for files opened with
the 'O_APPEND' flag. For now the logged request path is not yet
guaranteed to be smaller than that, this will be improved in a future
patch.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2020-10-16 11:23:49 +02:00

99 lines
2.8 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::config::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)?;
config.enable_file_log(buildcfg::API_ACCESS_LOG_FN)?;
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);
}
})
)
},
);
daemon::systemd_notify(daemon::SystemdNotify::Ready)?;
let init_result: Result<(), Error> = try_block!({
server::create_task_control_socket()?;
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(())
}