1 use std
::path
::PathBuf
;
3 use anyhow
::{bail, Error}
;
6 use proxmox
::api
::{api, ApiMethod, Router, RpcEnvironment, Permission}
;
8 use crate::api2
::types
::*;
10 use crate::config
::datastore
;
11 use crate::config
::acl
::{PRIV_DATASTORE_AUDIT, PRIV_DATASTORE_MODIFY}
;
18 description
: "List the configured datastores (with config digest).",
21 description
: "Datastore configuration.",
24 schema
: DATASTORE_SCHEMA
,
27 schema
: datastore
::DIR_NAME_SCHEMA
,
31 schema
: SINGLE_LINE_COMMENT_SCHEMA
,
37 permission
: &Permission
::Privilege(&["datastore"], PRIV_DATASTORE_AUDIT
, false),
40 /// List all datastores
41 pub fn list_datastores(
44 _rpcenv
: &mut dyn RpcEnvironment
,
45 ) -> Result
<Value
, Error
> {
47 let (config
, digest
) = datastore
::config()?
;
49 Ok(config
.convert_to_array("name", Some(&digest
), &[]))
57 schema
: DATASTORE_SCHEMA
,
61 schema
: SINGLE_LINE_COMMENT_SCHEMA
,
64 schema
: datastore
::DIR_NAME_SCHEMA
,
69 permission
: &Permission
::Privilege(&["datastore"], PRIV_DATASTORE_MODIFY
, false),
72 /// Create new datastore config.
73 pub fn create_datastore(name
: String
, param
: Value
) -> Result
<(), Error
> {
75 let _lock
= crate::tools
::open_file_locked(datastore
::DATASTORE_CFG_LOCKFILE
, std
::time
::Duration
::new(10, 0))?
;
77 let datastore
: datastore
::DataStoreConfig
= serde_json
::from_value(param
.clone())?
;
79 let (mut config
, _digest
) = datastore
::config()?
;
81 if let Some(_
) = config
.sections
.get(&name
) {
82 bail
!("datastore '{}' already exists.", name
);
85 let path
: PathBuf
= datastore
.path
.clone().into();
87 let backup_user
= crate::backup
::backup_user()?
;
88 let _store
= ChunkStore
::create(&name
, path
, backup_user
.uid
, backup_user
.gid
)?
;
90 config
.set_data(&name
, "datastore", &datastore
)?
;
92 datastore
::save_config(&config
)?
;
101 schema
: DATASTORE_SCHEMA
,
106 description
: "The datastore configuration (with config digest).",
107 type: datastore
::DataStoreConfig
,
110 permission
: &Permission
::Privilege(&["datastore", "{name}"], PRIV_DATASTORE_AUDIT
, false),
113 /// Read a datastore configuration.
114 pub fn read_datastore(name
: String
) -> Result
<Value
, Error
> {
115 let (config
, digest
) = datastore
::config()?
;
116 let mut data
= config
.lookup_json("datastore", &name
)?
;
117 data
.as_object_mut().unwrap()
118 .insert("digest".into(), proxmox
::tools
::digest_to_hex(&digest
).into());
127 schema
: DATASTORE_SCHEMA
,
131 schema
: SINGLE_LINE_COMMENT_SCHEMA
,
135 schema
: PROXMOX_CONFIG_DIGEST_SCHEMA
,
140 permission
: &Permission
::Privilege(&["datastore", "{name}"], PRIV_DATASTORE_MODIFY
, false),
143 /// Update datastore config.
144 pub fn update_datastore(
146 comment
: Option
<String
>,
147 digest
: Option
<String
>,
148 ) -> Result
<(), Error
> {
150 let _lock
= crate::tools
::open_file_locked(datastore
::DATASTORE_CFG_LOCKFILE
, std
::time
::Duration
::new(10, 0))?
;
152 // pass/compare digest
153 let (mut config
, expected_digest
) = datastore
::config()?
;
155 if let Some(ref digest
) = digest
{
156 let digest
= proxmox
::tools
::hex_to_digest(digest
)?
;
157 crate::tools
::detect_modified_configuration_file(&digest
, &expected_digest
)?
;
160 let mut data
: datastore
::DataStoreConfig
= config
.lookup("datastore", &name
)?
;
162 if let Some(comment
) = comment
{
163 let comment
= comment
.trim().to_string();
164 if comment
.is_empty() {
167 data
.comment
= Some(comment
);
171 config
.set_data(&name
, "datastore", &data
)?
;
173 datastore
::save_config(&config
)?
;
183 schema
: DATASTORE_SCHEMA
,
187 schema
: PROXMOX_CONFIG_DIGEST_SCHEMA
,
192 permission
: &Permission
::Privilege(&["datastore", "{name}"], PRIV_DATASTORE_MODIFY
, false),
195 /// Remove a datastore configuration.
196 pub fn delete_datastore(name
: String
, digest
: Option
<String
>) -> Result
<(), Error
> {
198 let _lock
= crate::tools
::open_file_locked(datastore
::DATASTORE_CFG_LOCKFILE
, std
::time
::Duration
::new(10, 0))?
;
200 let (mut config
, expected_digest
) = datastore
::config()?
;
202 if let Some(ref digest
) = digest
{
203 let digest
= proxmox
::tools
::hex_to_digest(digest
)?
;
204 crate::tools
::detect_modified_configuration_file(&digest
, &expected_digest
)?
;
207 match config
.sections
.get(&name
) {
208 Some(_
) => { config.sections.remove(&name); }
,
209 None
=> bail
!("datastore '{}' does not exist.", name
),
212 datastore
::save_config(&config
)?
;
217 const ITEM_ROUTER
: Router
= Router
::new()
218 .get(&API_METHOD_READ_DATASTORE
)
219 .put(&API_METHOD_UPDATE_DATASTORE
)
220 .delete(&API_METHOD_DELETE_DATASTORE
);
222 pub const ROUTER
: Router
= Router
::new()
223 .get(&API_METHOD_LIST_DATASTORES
)
224 .post(&API_METHOD_CREATE_DATASTORE
)
225 .match_all("name", &ITEM_ROUTER
);