]> git.proxmox.com Git - proxmox-backup.git/blame - pbs-config/src/datastore.rs
update to proxmox-sys 0.2 crate
[proxmox-backup.git] / pbs-config / src / datastore.rs
CommitLineData
e7d4be9d
DM
1use anyhow::{Error};
2use lazy_static::lazy_static;
3use std::collections::HashMap;
4
6ef1b649
WB
5use proxmox_schema::{ApiType, Schema};
6use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
e7d4be9d
DM
7
8use pbs_api_types::{DataStoreConfig, DATASTORE_SCHEMA};
9
10use crate::{open_backup_lockfile, replace_backup_config, BackupLockGuard};
11
12lazy_static! {
13 pub static ref CONFIG: SectionConfig = init();
14}
15
16fn init() -> SectionConfig {
17 let obj_schema = match DataStoreConfig::API_SCHEMA {
18 Schema::Object(ref obj_schema) => obj_schema,
19 _ => unreachable!(),
20 };
21
22 let plugin = SectionConfigPlugin::new("datastore".to_string(), Some(String::from("name")), obj_schema);
23 let mut config = SectionConfig::new(&DATASTORE_SCHEMA);
24 config.register_plugin(plugin);
25
26 config
27}
28
29pub const DATASTORE_CFG_FILENAME: &str = "/etc/proxmox-backup/datastore.cfg";
30pub const DATASTORE_CFG_LOCKFILE: &str = "/etc/proxmox-backup/.datastore.lck";
31
32/// Get exclusive lock
33pub fn lock_config() -> Result<BackupLockGuard, Error> {
34 open_backup_lockfile(DATASTORE_CFG_LOCKFILE, None, true)
35}
36
37pub fn config() -> Result<(SectionConfigData, [u8;32]), Error> {
38
25877d05 39 let content = proxmox_sys::fs::file_read_optional_string(DATASTORE_CFG_FILENAME)?
e7d4be9d
DM
40 .unwrap_or_else(|| "".to_string());
41
42 let digest = openssl::sha::sha256(content.as_bytes());
43 let data = CONFIG.parse(DATASTORE_CFG_FILENAME, &content)?;
44 Ok((data, digest))
45}
46
47pub fn save_config(config: &SectionConfigData) -> Result<(), Error> {
48 let raw = CONFIG.write(DATASTORE_CFG_FILENAME, &config)?;
49 replace_backup_config(DATASTORE_CFG_FILENAME, raw.as_bytes())
50}
51
52// shell completion helper
53pub fn complete_datastore_name(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
54 match config() {
55 Ok((data, _digest)) => data.sections.iter().map(|(id, _)| id.to_string()).collect(),
56 Err(_) => return vec![],
57 }
58}
59
60pub fn complete_acl_path(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
61 let mut list = Vec::new();
62
63 list.push(String::from("/"));
64 list.push(String::from("/datastore"));
65 list.push(String::from("/datastore/"));
66
67 if let Ok((data, _digest)) = config() {
68 for id in data.sections.keys() {
69 list.push(format!("/datastore/{}", id));
70 }
71 }
72
73 list.push(String::from("/remote"));
74 list.push(String::from("/remote/"));
75
76 list.push(String::from("/tape"));
77 list.push(String::from("/tape/"));
78 list.push(String::from("/tape/drive"));
79 list.push(String::from("/tape/drive/"));
80 list.push(String::from("/tape/changer"));
81 list.push(String::from("/tape/changer/"));
82 list.push(String::from("/tape/pool"));
83 list.push(String::from("/tape/pool/"));
84 list.push(String::from("/tape/job"));
85 list.push(String::from("/tape/job/"));
86
87 list
88}
89
90pub fn complete_calendar_event(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
91 // just give some hints about possible values
92 ["minutely", "hourly", "daily", "mon..fri", "0:0"]
93 .iter().map(|s| String::from(*s)).collect()
94}