src/section_config.rs - convert_to_array: optionally add digest

datastore::config() -> also return digest
remotes::config() -> also return digest
This commit is contained in:
Dietmar Maurer 2020-01-14 12:57:03 +01:00
parent 4566303b05
commit d0187a51a9
8 changed files with 35 additions and 26 deletions

View File

@ -485,9 +485,9 @@ fn get_datastore_list(
_rpcenv: &mut dyn RpcEnvironment, _rpcenv: &mut dyn RpcEnvironment,
) -> Result<Value, Error> { ) -> Result<Value, Error> {
let config = datastore::config()?; let (config, _digest) = datastore::config()?;
Ok(config.convert_to_array("store")) Ok(config.convert_to_array("store", None))
} }
#[sortable] #[sortable]

View File

@ -28,9 +28,9 @@ pub fn list_datastores(
_rpcenv: &mut dyn RpcEnvironment, _rpcenv: &mut dyn RpcEnvironment,
) -> Result<Value, Error> { ) -> Result<Value, Error> {
let config = datastore::config()?; let (config, digest) = datastore::config()?;
Ok(config.convert_to_array("name")) Ok(config.convert_to_array("name", Some(&digest)))
} }
#[api( #[api(
@ -57,7 +57,7 @@ pub fn create_datastore(name: String, param: Value) -> Result<(), Error> {
let datastore: datastore::DataStoreConfig = serde_json::from_value(param.clone())?; let datastore: datastore::DataStoreConfig = serde_json::from_value(param.clone())?;
let mut config = datastore::config()?; let (mut config, _digest) = datastore::config()?;
if let Some(_) = config.sections.get(&name) { if let Some(_) = config.sections.get(&name) {
bail!("datastore '{}' already exists.", name); bail!("datastore '{}' already exists.", name);
@ -91,7 +91,7 @@ pub fn delete_datastore(name: String) -> Result<(), Error> {
// fixme: locking ? // fixme: locking ?
// fixme: check digest ? // fixme: check digest ?
let mut config = datastore::config()?; let (mut config, _digest) = datastore::config()?;
match config.sections.get(&name) { match config.sections.get(&name) {
Some(_) => { config.sections.remove(&name); }, Some(_) => { config.sections.remove(&name); },

View File

@ -25,9 +25,9 @@ pub fn list_remotes(
_rpcenv: &mut dyn RpcEnvironment, _rpcenv: &mut dyn RpcEnvironment,
) -> Result<Value, Error> { ) -> Result<Value, Error> {
let config = remotes::config()?; let (config, digest) = remotes::config()?;
Ok(config.convert_to_array("name")) Ok(config.convert_to_array("name", Some(&digest)))
} }
#[api( #[api(
@ -60,7 +60,7 @@ pub fn create_remote(name: String, param: Value) -> Result<(), Error> {
let remote: remotes::Remote = serde_json::from_value(param.clone())?; let remote: remotes::Remote = serde_json::from_value(param.clone())?;
let mut config = remotes::config()?; let (mut config, _digest) = remotes::config()?;
if let Some(_) = config.sections.get(&name) { if let Some(_) = config.sections.get(&name) {
bail!("remote '{}' already exists.", name); bail!("remote '{}' already exists.", name);
@ -89,7 +89,7 @@ pub fn delete_remote(name: String) -> Result<(), Error> {
// fixme: locking ? // fixme: locking ?
// fixme: check digest ? // fixme: check digest ?
let mut config = remotes::config()?; let (mut config, _digest) = remotes::config()?;
match config.sections.get(&name) { match config.sections.get(&name) {
Some(_) => { config.sections.remove(&name); }, Some(_) => { config.sections.remove(&name); },

View File

@ -35,17 +35,14 @@ impl DataStore {
pub fn lookup_datastore(name: &str) -> Result<Arc<DataStore>, Error> { pub fn lookup_datastore(name: &str) -> Result<Arc<DataStore>, Error> {
let config = datastore::config()?; let (config, _digest) = datastore::config()?;
let (_, store_config) = config.sections.get(name) let config: datastore::DataStoreConfig = config.lookup("datastore", name)?;
.ok_or(format_err!("no such datastore '{}'", name))?;
let path = store_config["path"].as_str().unwrap();
let mut map = DATASTORE_MAP.lock().unwrap(); let mut map = DATASTORE_MAP.lock().unwrap();
if let Some(datastore) = map.get(name) { if let Some(datastore) = map.get(name) {
// Compare Config - if changed, create new Datastore object! // Compare Config - if changed, create new Datastore object!
if datastore.chunk_store.base == PathBuf::from(path) { if datastore.chunk_store.base == PathBuf::from(&config.path) {
return Ok(datastore.clone()); return Ok(datastore.clone());
} }
} }
@ -60,7 +57,7 @@ impl DataStore {
pub fn open(store_name: &str) -> Result<Self, Error> { pub fn open(store_name: &str) -> Result<Self, Error> {
let config = datastore::config()?; let (config, _digest) = datastore::config()?;
let (_, store_config) = config.sections.get(store_name) let (_, store_config) = config.sections.get(store_name)
.ok_or(format_err!("no such datastore '{}'", store_name))?; .ok_or(format_err!("no such datastore '{}'", store_name))?;

View File

@ -406,7 +406,7 @@ async fn pull_datastore(
let mut client = connect()?; let mut client = connect()?;
let remote_config = remotes::config()?; let (remote_config, _digest) = remotes::config()?;
let remote: Remote = remote_config.lookup("remote", &remote)?; let remote: Remote = remote_config.lookup("remote", &remote)?;
let args = json!({ let args = json!({
@ -451,7 +451,7 @@ pub fn complete_remote_datastore_name(_arg: &str, param: &HashMap<String, String
let _ = proxmox::tools::try_block!({ let _ = proxmox::tools::try_block!({
let remote = param.get("remote").ok_or_else(|| format_err!("no remote"))?; let remote = param.get("remote").ok_or_else(|| format_err!("no remote"))?;
let remote_config = remotes::config()?; let (remote_config, _digest) = remotes::config()?;
let remote: Remote = remote_config.lookup("remote", &remote)?; let remote: Remote = remote_config.lookup("remote", &remote)?;

View File

@ -51,7 +51,7 @@ fn init() -> SectionConfig {
const DATASTORE_CFG_FILENAME: &str = "/etc/proxmox-backup/datastore.cfg"; const DATASTORE_CFG_FILENAME: &str = "/etc/proxmox-backup/datastore.cfg";
pub fn config() -> Result<SectionConfigData, Error> { pub fn config() -> Result<(SectionConfigData, [u8;32]), Error> {
let content = match std::fs::read_to_string(DATASTORE_CFG_FILENAME) { let content = match std::fs::read_to_string(DATASTORE_CFG_FILENAME) {
Ok(c) => c, Ok(c) => c,
Err(err) => { Err(err) => {
@ -63,7 +63,9 @@ pub fn config() -> Result<SectionConfigData, Error> {
} }
}; };
CONFIG.parse(DATASTORE_CFG_FILENAME, &content) let digest = openssl::sha::sha256(content.as_bytes());
let data = CONFIG.parse(DATASTORE_CFG_FILENAME, &content)?;
Ok((data, digest))
} }
pub fn save_config(config: &SectionConfigData) -> Result<(), Error> { pub fn save_config(config: &SectionConfigData) -> Result<(), Error> {
@ -86,7 +88,7 @@ pub fn save_config(config: &SectionConfigData) -> Result<(), Error> {
// shell completion helper // shell completion helper
pub fn complete_datastore_name(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> { pub fn complete_datastore_name(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
match config() { match config() {
Ok(data) => data.sections.iter().map(|(id, _)| id.to_string()).collect(), Ok((data, _digest)) => data.sections.iter().map(|(id, _)| id.to_string()).collect(),
Err(_) => return vec![], Err(_) => return vec![],
} }
} }

View File

@ -62,7 +62,7 @@ fn init() -> SectionConfig {
const REMOTES_CFG_FILENAME: &str = "/etc/proxmox-backup/remotes.cfg"; const REMOTES_CFG_FILENAME: &str = "/etc/proxmox-backup/remotes.cfg";
pub fn config() -> Result<SectionConfigData, Error> { pub fn config() -> Result<(SectionConfigData, [u8;32]), Error> {
let content = match std::fs::read_to_string(REMOTES_CFG_FILENAME) { let content = match std::fs::read_to_string(REMOTES_CFG_FILENAME) {
Ok(c) => c, Ok(c) => c,
Err(err) => { Err(err) => {
@ -74,7 +74,9 @@ pub fn config() -> Result<SectionConfigData, Error> {
} }
}; };
CONFIG.parse(REMOTES_CFG_FILENAME, &content) let digest = openssl::sha::sha256(content.as_bytes());
let data = CONFIG.parse(REMOTES_CFG_FILENAME, &content)?;
Ok((data, digest))
} }
pub fn save_config(config: &SectionConfigData) -> Result<(), Error> { pub fn save_config(config: &SectionConfigData) -> Result<(), Error> {
@ -97,7 +99,7 @@ pub fn save_config(config: &SectionConfigData) -> Result<(), Error> {
// shell completion helper // shell completion helper
pub fn complete_remote_name(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> { pub fn complete_remote_name(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
match config() { match config() {
Ok(data) => data.sections.iter().map(|(id, _)| id.to_string()).collect(), Ok((data, _digest)) => data.sections.iter().map(|(id, _)| id.to_string()).collect(),
Err(_) => return vec![], Err(_) => return vec![],
} }
} }

View File

@ -84,12 +84,20 @@ impl SectionConfigData {
self.order.push_back(section_id.to_string()); self.order.push_back(section_id.to_string());
} }
pub fn convert_to_array(&self, id_prop: &str) -> Value { pub fn convert_to_array(&self, id_prop: &str, digest: Option<&[u8;32]>) -> Value {
let mut list: Vec<Value> = vec![]; let mut list: Vec<Value> = vec![];
let digest: Value = match digest {
Some(v) => proxmox::tools::digest_to_hex(v).into(),
None => Value::Null,
};
for (section_id, (_, data)) in &self.sections { for (section_id, (_, data)) in &self.sections {
let mut item = data.clone(); let mut item = data.clone();
item.as_object_mut().unwrap().insert(id_prop.into(), section_id.clone().into()); item.as_object_mut().unwrap().insert(id_prop.into(), section_id.clone().into());
if !digest.is_null() {
item.as_object_mut().unwrap().insert("digest".into(), digest.clone());
}
list.push(item); list.push(item);
} }