diff --git a/Cargo.lock b/Cargo.lock index 4fb35f4391f..56371608fbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1398,6 +1398,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.10" @@ -2423,6 +2432,7 @@ dependencies = [ "cli-table", "dir-diff", "flate2", + "itertools 0.12.1", "lzma-rs", "pretty_assertions", "quick-xml", diff --git a/relay/sources/rudder-package/Cargo.toml b/relay/sources/rudder-package/Cargo.toml index 5a6b41e69d3..b49a59d05eb 100644 --- a/relay/sources/rudder-package/Cargo.toml +++ b/relay/sources/rudder-package/Cargo.toml @@ -37,3 +37,4 @@ flate2 = "1.0.28" cli-table = "0.4.7" spinners = "4.1.1" rudder_cli = { path = "../../../policies/rudder-cli" } +itertools = "0.12.1" diff --git a/relay/sources/rudder-package/src/database.rs b/relay/sources/rudder-package/src/database.rs index bb0b6af0895..0d3f41e17ff 100644 --- a/relay/sources/rudder-package/src/database.rs +++ b/relay/sources/rudder-package/src/database.rs @@ -10,6 +10,7 @@ use std::{ }; use anyhow::{anyhow, bail, Context, Result}; +use itertools::Itertools; use serde::{Deserialize, Serialize}; use tracing::{debug, info, warn}; @@ -212,16 +213,27 @@ impl Database { Ok(()) } - pub fn enabled_plugins_save(&self, backup_path: &Path, webapp: &mut Webapp) -> Result<()> { - let saved = webapp - .jars()? - .iter() - // Let's ignore unknown jars - .flat_map(|j| self.plugin_provides_jar(j)) - .map(|p| format!("enable {}", p.metadata.name)) - .collect::>() - .join("\n"); - fs::write(backup_path, saved).with_context(|| { + pub fn disabled_plugins_save(&self, backup_path: &Path, webapp: &mut Webapp) -> Result<()> { + let mut disabled = Vec::new(); + let enabled_jars = webapp.jars()?; + for (name, p) in self.plugins.iter().sorted_by_key(|x| x.0) { + if !p.metadata.jar_files.is_empty() + && !p + .metadata + .jar_files + .iter() + .all(|j| enabled_jars.contains(j)) + { + disabled.push(format!("disabled {}", name)); + } + } + fs::write( + backup_path, + disabled + .iter() + .fold("".to_string(), |acc, s| format!("{}{}\n", acc, s)), + ) + .with_context(|| { format!( "Failed to save the plugins statuses in the backup file {}", backup_path.to_string_lossy() @@ -250,8 +262,8 @@ impl Database { })?; if plugin_name.ends_with(".jar") && plugin_name.starts_with('/') { match status { - "disable" => webapp.disable_jars(&[plugin_name.to_owned()]), - "enable" => webapp.enable_jars(&[plugin_name.to_owned()]), + "disabled" => webapp.disable_jars(&[plugin_name.to_owned()]), + "enabled" => webapp.enable_jars(&[plugin_name.to_owned()]), _ => bail!("Unexpected plugin status in the backup file: {}", line), } } else { @@ -260,8 +272,8 @@ impl Database { plugin_name ))?; match status { - "disable" => i.disable(webapp), - "enable" => i.enable(webapp), + "disabled" => i.disable(webapp), + "enabled" => i.enable(webapp), _ => bail!("Unexpected plugin status in the backup file: {}", line), } } @@ -351,7 +363,31 @@ mod tests { use crate::{archive, versions::RudderVersion}; #[test] - fn test_read_plugin_status_line_from_backup() { + fn test_save_plugin_statuses() { + let temp_dir = TempDir::new().unwrap(); + let database_path = temp_dir.path().join("database.json"); + let webapp_path = temp_dir.path().join("webappPath.json"); + let backup_path = temp_dir.path().join("backup.json"); + fs::copy( + "tests/status_backup_file/database.json", + database_path.clone(), + ) + .unwrap(); + fs::copy("tests/status_backup_file/webapp.xml", webapp_path.clone()).unwrap(); + let mut w = Webapp::new( + webapp_path, + RudderVersion::from_path("./tests/versions/rudder-server-version").unwrap(), + ); + let d = Database::read(Path::new(&database_path)).unwrap(); + d.disabled_plugins_save(&backup_path, &mut w).unwrap(); + assert_eq!( + fs::read_to_string(backup_path).unwrap(), + fs::read_to_string("./tests/status_backup_file/backup.expected").unwrap() + ); + } + + #[test] + fn test_apply_plugin_status_line_from_backup() { let temp_dir = TempDir::new().unwrap(); let database_path = temp_dir.path().join("database.json"); let webapp_path = temp_dir.path().join("webappPath.json"); @@ -367,7 +403,7 @@ mod tests { ); let d = Database::read(Path::new(&database_path)).unwrap(); // Enable >8.1 syntax - d.apply_plugin_status_line_from_backup("enable rudder-plugin-dsc", &mut w) + d.apply_plugin_status_line_from_backup("enabled rudder-plugin-dsc", &mut w) .unwrap(); assert!(w .jars() @@ -375,7 +411,7 @@ mod tests { .contains(&"/opt/rudder/share/plugins/dsc/dsc.jar".to_string())); // Disable >8.1 syntax - d.apply_plugin_status_line_from_backup("disable rudder-plugin-dsc", &mut w) + d.apply_plugin_status_line_from_backup("disabled rudder-plugin-dsc", &mut w) .unwrap(); assert!(!w .jars() @@ -384,7 +420,7 @@ mod tests { // Enable <8.0 syntax d.apply_plugin_status_line_from_backup( - "enable /opt/rudder/share/plugins/dsc/dsc.jar", + "enabled /opt/rudder/share/plugins/dsc/dsc.jar", &mut w, ) .unwrap(); @@ -395,7 +431,7 @@ mod tests { // Disable <8.0 syntax d.apply_plugin_status_line_from_backup( - "disable /opt/rudder/share/plugins/dsc/dsc.jar", + "disabled /opt/rudder/share/plugins/dsc/dsc.jar", &mut w, ) .unwrap(); @@ -406,17 +442,17 @@ mod tests { // Unsupported plugin name syntax assert!(d - .apply_plugin_status_line_from_backup("enable dsc", &mut w) + .apply_plugin_status_line_from_backup("enabled dsc", &mut w) .is_err()); // Unsupported plugin status syntax assert!(d - .apply_plugin_status_line_from_backup("eNable rudder-plugin-dsc", &mut w) + .apply_plugin_status_line_from_backup("eNabled rudder-plugin-dsc", &mut w) .is_err()); // Non installed plugin assert!(d - .apply_plugin_status_line_from_backup("enable rudder-plugin-unknown", &mut w) + .apply_plugin_status_line_from_backup("enabled rudder-plugin-unknown", &mut w) .is_err()); } diff --git a/relay/sources/rudder-package/src/lib.rs b/relay/sources/rudder-package/src/lib.rs index 190121154ca..407c190693a 100644 --- a/relay/sources/rudder-package/src/lib.rs +++ b/relay/sources/rudder-package/src/lib.rs @@ -261,7 +261,7 @@ pub fn run_inner(args: Args) -> Result<()> { if to_enable.is_empty() { let backup_path = Path::new(PLUGIN_STATUS_BACKUP_PATH); if save { - db.enabled_plugins_save(backup_path, &mut webapp)?; + db.disabled_plugins_save(backup_path, &mut webapp)?; info!("Plugins status successfully saved"); } else if restore { db.enabled_plugins_restore(backup_path, &mut webapp)?; diff --git a/relay/sources/rudder-package/tests/status_backup_file/backup.expected b/relay/sources/rudder-package/tests/status_backup_file/backup.expected new file mode 100644 index 00000000000..d410803c276 --- /dev/null +++ b/relay/sources/rudder-package/tests/status_backup_file/backup.expected @@ -0,0 +1,2 @@ +disabled rudder-plugin-dsc +disabled rudder-plugin-system-updates