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