]> git.proxmox.com Git - proxmox-backup.git/blob - pbs-config/src/media_pool.rs
3512c70a4c17a1c31438960a003b9aae32c17938
[proxmox-backup.git] / pbs-config / src / media_pool.rs
1 //! Media Pool configuration (Tape backup)
2 //!
3 //! This configuration module is based on [`SectionConfig`], and
4 //! provides a type safe interface to store [`MediaPoolConfig`],
5 //!
6 //! [MediaPoolConfig]: crate::api2::types::MediaPoolConfig
7 //! [SectionConfig]: proxmox::api::section_config::SectionConfig
8
9 use std::collections::HashMap;
10
11 use anyhow::Error;
12 use lazy_static::lazy_static;
13
14 use proxmox::{
15 api::{
16 schema::*,
17 section_config::{
18 SectionConfig,
19 SectionConfigData,
20 SectionConfigPlugin,
21 }
22 },
23 };
24
25 use pbs_api_types::{MEDIA_POOL_NAME_SCHEMA, MediaPoolConfig};
26
27 use crate::{open_backup_lockfile, replace_backup_config, BackupLockGuard};
28
29 lazy_static! {
30 /// Static [`SectionConfig`] to access parser/writer functions.
31 pub static ref CONFIG: SectionConfig = init();
32 }
33
34 fn init() -> SectionConfig {
35 let mut config = SectionConfig::new(&MEDIA_POOL_NAME_SCHEMA);
36
37 let obj_schema = match MediaPoolConfig::API_SCHEMA {
38 Schema::Object(ref obj_schema) => obj_schema,
39 _ => unreachable!(),
40 };
41 let plugin = SectionConfigPlugin::new("pool".to_string(), Some("name".to_string()), obj_schema);
42 config.register_plugin(plugin);
43
44 config
45 }
46
47 /// Configuration file name
48 pub const MEDIA_POOL_CFG_FILENAME: &str = "/etc/proxmox-backup/media-pool.cfg";
49 /// Lock file name (used to prevent concurrent access)
50 pub const MEDIA_POOL_CFG_LOCKFILE: &str = "/etc/proxmox-backup/.media-pool.lck";
51
52 /// Get exclusive lock
53 pub fn lock() -> Result<BackupLockGuard, Error> {
54 open_backup_lockfile(MEDIA_POOL_CFG_LOCKFILE, None, true)
55 }
56
57 /// Read and parse the configuration file
58 pub fn config() -> Result<(SectionConfigData, [u8;32]), Error> {
59
60 let content = proxmox::tools::fs::file_read_optional_string(MEDIA_POOL_CFG_FILENAME)?
61 .unwrap_or_else(|| "".to_string());
62
63 let digest = openssl::sha::sha256(content.as_bytes());
64 let data = CONFIG.parse(MEDIA_POOL_CFG_FILENAME, &content)?;
65 Ok((data, digest))
66 }
67
68 /// Save the configuration file
69 pub fn save_config(config: &SectionConfigData) -> Result<(), Error> {
70 let raw = CONFIG.write(MEDIA_POOL_CFG_FILENAME, &config)?;
71 replace_backup_config(MEDIA_POOL_CFG_FILENAME, raw.as_bytes())
72 }
73
74 // shell completion helper
75
76 /// List existing pool names
77 pub fn complete_pool_name(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
78 match config() {
79 Ok((data, _digest)) => data.sections.iter().map(|(id, _)| id.to_string()).collect(),
80 Err(_) => return vec![],
81 }
82 }