5
0
mirror of git://git.proxmox.com/git/proxmox-backup.git synced 2025-01-11 05:18:01 +03:00

implement relead_timezone flag

This commit is contained in:
Dietmar Maurer 2019-02-01 09:54:56 +01:00
parent c82bc1a1f9
commit 4b2cdeb9a6
3 changed files with 28 additions and 8 deletions

View File

@ -64,7 +64,12 @@ type ApiHandlerFn = fn(Value, &ApiMethod, &mut dyn RpcEnvironment) -> Result<Val
type ApiAsyncHandlerFn = fn(Parts, Body, Value, &ApiAsyncMethod, &mut dyn RpcEnvironment) -> Result<BoxFut, Error>; type ApiAsyncHandlerFn = fn(Parts, Body, Value, &ApiAsyncMethod, &mut dyn RpcEnvironment) -> Result<BoxFut, Error>;
pub struct ApiMethod { pub struct ApiMethod {
/// The protected flag indicates that the provides function should be forwarded
/// to the deaemon running in priviledged mode.
pub protected: bool, pub protected: bool,
/// This flag indicates that the provided method may change the local timezone, so the server
/// should do a tzset afterwards
pub reload_timezone: bool,
pub parameters: ObjectSchema, pub parameters: ObjectSchema,
pub returns: Arc<Schema>, pub returns: Arc<Schema>,
pub handler: ApiHandlerFn, pub handler: ApiHandlerFn,
@ -78,6 +83,7 @@ impl ApiMethod {
handler, handler,
returns: Arc::new(Schema::Null), returns: Arc::new(Schema::Null),
protected: false, protected: false,
reload_timezone: false,
} }
} }
@ -94,6 +100,13 @@ impl ApiMethod {
self self
} }
pub fn reload_timezone(mut self, reload_timezone: bool) -> Self {
self.reload_timezone = reload_timezone;
self
}
} }
pub struct ApiAsyncMethod { pub struct ApiAsyncMethod {

View File

@ -32,10 +32,6 @@ fn get_time(
})) }))
} }
extern "C" { fn tzset(); }
// Note:: this needs root rights ??
fn set_timezone( fn set_timezone(
param: Value, param: Value,
_info: &ApiMethod, _info: &ApiMethod,
@ -57,8 +53,6 @@ fn set_timezone(
use std::os::unix::fs::symlink; use std::os::unix::fs::symlink;
symlink(path, "/etc/localtime")?; symlink(path, "/etc/localtime")?;
unsafe { tzset() };
Ok(Value::Null) Ok(Value::Null)
} }
@ -83,7 +77,7 @@ pub fn router() -> Router {
set_timezone, set_timezone,
ObjectSchema::new("Set time zone.") ObjectSchema::new("Set time zone.")
.required("timezone", StringSchema::new("Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names.")) .required("timezone", StringSchema::new("Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names."))
).protected(true) ).protected(true).reload_timezone(true)
); );

View File

@ -27,6 +27,8 @@ use hyper::service::{Service, NewService};
use hyper::rt::{Future, Stream}; use hyper::rt::{Future, Stream};
use hyper::header; use hyper::header;
extern "C" { fn tzset(); }
pub struct RestServer { pub struct RestServer {
pub api_config: Arc<ApiConfig>, pub api_config: Arc<ApiConfig>,
} }
@ -135,6 +137,7 @@ fn get_request_parameters_async(
} }
fn proxy_protected_request( fn proxy_protected_request(
info: &'static ApiMethod,
mut parts: Parts, mut parts: Parts,
req_body: Body, req_body: Body,
) -> BoxFut ) -> BoxFut
@ -154,6 +157,12 @@ fn proxy_protected_request(
.request(request) .request(request)
.map_err(|e| Error::from(e)); .map_err(|e| Error::from(e));
let resp = if info.reload_timezone {
Either::A(resp.then(|resp| {unsafe { tzset() }; resp }))
} else {
Either::B(resp)
};
return Box::new(resp); return Box::new(resp);
} }
@ -183,6 +192,10 @@ fn handle_sync_api_request(
} }
}; };
if info.reload_timezone {
unsafe { tzset() };
}
if delay { if delay {
let delayed_response = tokio::timer::Delay::new(delay_unauth_time) let delayed_response = tokio::timer::Delay::new(delay_unauth_time)
.map_err(|err| http_err!(INTERNAL_SERVER_ERROR, format!("tokio timer delay error: {}", err))) .map_err(|err| http_err!(INTERNAL_SERVER_ERROR, format!("tokio timer delay error: {}", err)))
@ -462,7 +475,7 @@ pub fn handle_request(api: Arc<ApiConfig>, req: Request<Body>) -> BoxFut {
MethodDefinition::None => {} MethodDefinition::None => {}
MethodDefinition::Simple(api_method) => { MethodDefinition::Simple(api_method) => {
if api_method.protected && env_type == RpcEnvironmentType::PUBLIC { if api_method.protected && env_type == RpcEnvironmentType::PUBLIC {
return proxy_protected_request(parts, body); return proxy_protected_request(api_method, parts, body);
} else { } else {
return handle_sync_api_request(rpcenv, api_method, formatter, parts, body, uri_param); return handle_sync_api_request(rpcenv, api_method, formatter, parts, body, uri_param);
} }