proxmox-backup/src/api2/node/time.rs
Dietmar Maurer 6a7be83efe avoid chrono dependency, depend on proxmox 0.3.8
- remove chrono dependency

- depend on proxmox 0.3.8

- remove epoch_now, epoch_now_u64 and epoch_now_f64

- remove tm_editor (moved to proxmox crate)

- use new helpers from proxmox 0.3.8
  * epoch_i64 and epoch_f64
  * parse_rfc3339
  * epoch_to_rfc3339_utc
  * strftime_local

- BackupDir changes:
  * store epoch and rfc3339 string instead of DateTime
  * backup_time_to_string now return a Result
  * remove unnecessary TryFrom<(BackupGroup, i64)> for BackupDir

- DynamicIndexHeader: change ctime to i64

- FixedIndexHeader: change ctime to i64
2020-09-15 07:12:57 +02:00

113 lines
2.9 KiB
Rust

use anyhow::{bail, format_err, Error};
use serde_json::{json, Value};
use proxmox::api::{api, Router, Permission};
use proxmox::tools::fs::{file_read_firstline, replace_file, CreateOptions};
use crate::config::acl::PRIV_SYS_MODIFY;
use crate::api2::types::*;
fn read_etc_localtime() -> Result<String, Error> {
// use /etc/timezone
if let Ok(line) = file_read_firstline("/etc/timezone") {
return Ok(line.trim().to_owned());
}
// otherwise guess from the /etc/localtime symlink
let link = std::fs::read_link("/etc/localtime").
map_err(|err| format_err!("failed to guess timezone - {}", err))?;
let link = link.to_string_lossy();
match link.rfind("/zoneinfo/") {
Some(pos) => Ok(link[(pos + 10)..].to_string()),
None => Ok(link.to_string()),
}
}
#[api(
input: {
properties: {
node: {
schema: NODE_SCHEMA,
},
},
},
returns: {
description: "Returns server time and timezone.",
properties: {
timezone: {
schema: TIME_ZONE_SCHEMA,
},
time: {
type: i64,
description: "Seconds since 1970-01-01 00:00:00 UTC.",
minimum: 1_297_163_644,
},
localtime: {
type: i64,
description: "Seconds since 1970-01-01 00:00:00 UTC. (local time)",
minimum: 1_297_163_644,
},
}
},
access: {
permission: &Permission::Anybody,
},
)]
/// Read server time and time zone settings.
fn get_time(_param: Value) -> Result<Value, Error> {
let time = proxmox::tools::time::epoch_i64();
let tm = proxmox::tools::time::localtime(time)?;
let offset = tm.tm_gmtoff;
let localtime = time + offset;
Ok(json!({
"timezone": read_etc_localtime()?,
"time": time,
"localtime": localtime,
}))
}
#[api(
protected: true,
reload_timezone: true,
input: {
properties: {
node: {
schema: NODE_SCHEMA,
},
timezone: {
schema: TIME_ZONE_SCHEMA,
},
},
},
access: {
permission: &Permission::Privilege(&["system", "time"], PRIV_SYS_MODIFY, false),
},
)]
/// Set time zone
fn set_timezone(
timezone: String,
_param: Value,
) -> Result<Value, Error> {
let path = std::path::PathBuf::from(format!("/usr/share/zoneinfo/{}", timezone));
if !path.exists() {
bail!("No such timezone.");
}
replace_file("/etc/timezone", timezone.as_bytes(), CreateOptions::new())?;
let _ = std::fs::remove_file("/etc/localtime");
use std::os::unix::fs::symlink;
symlink(path, "/etc/localtime")?;
Ok(Value::Null)
}
pub const ROUTER: Router = Router::new()
.get(&API_METHOD_GET_TIME)
.put(&API_METHOD_SET_TIMEZONE);