]> git.proxmox.com Git - proxmox-backup.git/blob - src/config/datastore.rs
e27f81db861040bc61622f1259e9bb90c4556814
[proxmox-backup.git] / src / config / datastore.rs
1 use failure::*;
2 use lazy_static::lazy_static;
3 use std::collections::HashMap;
4 use serde::{Serialize, Deserialize};
5
6 use proxmox::api::{api, schema::*};
7 use proxmox::tools::{fs::replace_file, fs::CreateOptions};
8
9 use crate::api2::types::*;
10 use crate::section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
11
12 lazy_static! {
13 static ref CONFIG: SectionConfig = init();
14 }
15
16 // fixme: define better schemas
17
18 pub const DIR_NAME_SCHEMA: Schema = StringSchema::new("Directory name").schema();
19 pub const COMMENT_SCHEMA: Schema = StringSchema::new("Datastore comment").schema();
20
21 #[api(
22 properties: {
23 comment: {
24 optional: true,
25 schema: COMMENT_SCHEMA,
26 },
27 path: {
28 schema: DIR_NAME_SCHEMA,
29 },
30 }
31 )]
32 #[derive(Serialize,Deserialize)]
33 /// Datastore configuration properties.
34 pub struct DataStoreConfig {
35 pub comment: Option<String>,
36 pub path: String,
37 }
38
39 fn init() -> SectionConfig {
40 let obj_schema = match DataStoreConfig::API_SCHEMA {
41 Schema::Object(ref obj_schema) => obj_schema,
42 _ => unreachable!(),
43 };
44
45 let plugin = SectionConfigPlugin::new("datastore".to_string(), obj_schema);
46 let mut config = SectionConfig::new(&DATASTORE_SCHEMA);
47 config.register_plugin(plugin);
48
49 config
50 }
51
52 const DATASTORE_CFG_FILENAME: &str = "/etc/proxmox-backup/datastore.cfg";
53
54 pub fn config() -> Result<SectionConfigData, Error> {
55 let content = match std::fs::read_to_string(DATASTORE_CFG_FILENAME) {
56 Ok(c) => c,
57 Err(err) => {
58 if err.kind() == std::io::ErrorKind::NotFound {
59 String::from("")
60 } else {
61 bail!("unable to read '{}' - {}", DATASTORE_CFG_FILENAME, err);
62 }
63 }
64 };
65
66 CONFIG.parse(DATASTORE_CFG_FILENAME, &content)
67 }
68
69 pub fn save_config(config: &SectionConfigData) -> Result<(), Error> {
70 let raw = CONFIG.write(DATASTORE_CFG_FILENAME, &config)?;
71
72 let backup_user = crate::backup::backup_user()?;
73 let mode = nix::sys::stat::Mode::from_bits_truncate(0o0640);
74 // set the correct owner/group/permissions while saving file
75 // owner(rw) = root, group(r)= backup
76 let options = CreateOptions::new()
77 .perm(mode)
78 .owner(nix::unistd::ROOT)
79 .group(backup_user.gid);
80
81 replace_file(DATASTORE_CFG_FILENAME, raw.as_bytes(), options)?;
82
83 Ok(())
84 }
85
86 // shell completion helper
87 pub fn complete_datastore_name(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
88 match config() {
89 Ok(data) => data.sections.iter().map(|(id, _)| id.to_string()).collect(),
90 Err(_) => return vec![],
91 }
92 }