[pbs-devel] [PATCH proxmox-backup 1/9] cli: manager: move update-to-prune-jobs command to new migrate-config sub-command
Lukas Wagner
l.wagner at proxmox.com
Mon Jun 23 16:13:07 CEST 2025
The new subcommand is introduced so that we have a common name space for
any config migration tasks which are triggered by d/postinst (or potentially
by hand).
No functional changes.
Signed-off-by: Lukas Wagner <l.wagner at proxmox.com>
---
Notes:
I guess at this point we could also drop this code entirely?
debian/postinst | 2 +-
src/bin/proxmox-backup-manager.rs | 6 +-
.../proxmox_backup_manager/migrate_config.rs | 98 +++++++++++++++++++
src/bin/proxmox_backup_manager/mod.rs | 1 +
src/bin/proxmox_backup_manager/prune.rs | 87 +---------------
5 files changed, 104 insertions(+), 90 deletions(-)
create mode 100644 src/bin/proxmox_backup_manager/migrate_config.rs
diff --git a/debian/postinst b/debian/postinst
index f38a8c66..7f4c57cc 100644
--- a/debian/postinst
+++ b/debian/postinst
@@ -35,7 +35,7 @@ case "$1" in
if dpkg --compare-versions "$2" 'lt' '2.2.2~'; then
echo "moving prune schedule from datacenter config to new prune job config"
- proxmox-backup-manager update-to-prune-jobs-config \
+ proxmox-backup-manager migrate-config update-to-prune-jobs-config \
|| echo "Failed to move prune jobs, please check manually"
true
fi
diff --git a/src/bin/proxmox-backup-manager.rs b/src/bin/proxmox-backup-manager.rs
index d4363e71..378c5c7f 100644
--- a/src/bin/proxmox-backup-manager.rs
+++ b/src/bin/proxmox-backup-manager.rs
@@ -712,9 +712,9 @@ async fn run() -> Result<(), Error> {
.insert("report", CliCommand::new(&API_METHOD_REPORT))
.insert("versions", CliCommand::new(&API_METHOD_GET_VERSIONS));
- let args: Vec<String> = std::env::args().take(2).collect();
- if args.len() >= 2 && args[1] == "update-to-prune-jobs-config" {
- return update_to_prune_jobs_config();
+ let args: Vec<String> = std::env::args().take(3).collect();
+ if args.len() >= 3 && args[1] == "migrate-config" {
+ return migrate_config::handle_command(&args[2]);
}
let avoid_init = args.len() >= 2 && (args[1] == "bashcomplete" || args[1] == "printdoc");
diff --git a/src/bin/proxmox_backup_manager/migrate_config.rs b/src/bin/proxmox_backup_manager/migrate_config.rs
new file mode 100644
index 00000000..214c8d71
--- /dev/null
+++ b/src/bin/proxmox_backup_manager/migrate_config.rs
@@ -0,0 +1,98 @@
+use anyhow::{bail, Error};
+use serde::Deserialize;
+
+use pbs_api_types::{DataStoreConfig, PruneJobConfig, PruneJobOptions};
+use pbs_config::prune;
+
+/// Handle a 'migrate-config' command.
+pub fn handle_command(command: &str) -> Result<(), Error> {
+ match command {
+ "update-to-prune-jobs-config" => return update_to_prune_jobs_config(),
+ _ => bail!("invalid fixup command: {command}"),
+ }
+}
+
+/// Migrate a datastore's prune setting to a prune job.
+pub(crate) fn update_to_prune_jobs_config() -> Result<(), Error> {
+ use pbs_config::datastore;
+
+ let _prune_lock = prune::lock_config()?;
+ let _datastore_lock = datastore::lock_config()?;
+
+ let (mut data, _digest) = prune::config()?;
+ let (mut storeconfig, _digest) = datastore::config()?;
+
+ for (store, entry) in storeconfig.sections.iter_mut() {
+ let ty = &entry.0;
+
+ if ty != "datastore" {
+ continue;
+ }
+
+ let mut config = match DataStoreConfig::deserialize(&entry.1) {
+ Ok(c) => c,
+ Err(err) => {
+ eprintln!("failed to parse config of store {store}: {err}");
+ continue;
+ }
+ };
+
+ let options = PruneJobOptions {
+ keep: std::mem::take(&mut config.keep),
+ ..Default::default()
+ };
+
+ let schedule = config.prune_schedule.take();
+
+ entry.1 = serde_json::to_value(config)?;
+
+ let schedule = match schedule {
+ Some(s) => s,
+ None => {
+ if options.keeps_something() {
+ eprintln!(
+ "dropping prune job without schedule from datastore '{store}' in datastore.cfg"
+ );
+ } else {
+ eprintln!("ignoring empty prune job of datastore '{store}' in datastore.cfg");
+ }
+ continue;
+ }
+ };
+
+ let mut id = format!("storeconfig-{store}");
+ id.truncate(32);
+ if data.sections.contains_key(&id) {
+ eprintln!("skipping existing converted prune job for datastore '{store}': {id}");
+ continue;
+ }
+
+ if !options.keeps_something() {
+ eprintln!("dropping empty prune job of datastore '{store}' in datastore.cfg");
+ continue;
+ }
+
+ let prune_config = PruneJobConfig {
+ id: id.clone(),
+ store: store.clone(),
+ disable: false,
+ comment: None,
+ schedule,
+ options,
+ };
+
+ let prune_config = serde_json::to_value(prune_config)?;
+
+ data.sections
+ .insert(id, ("prune".to_string(), prune_config));
+
+ eprintln!(
+ "migrating prune job of datastore '{store}' from datastore.cfg to prune.cfg jobs"
+ );
+ }
+
+ prune::save_config(&data)?;
+ datastore::save_config(&storeconfig)?;
+
+ Ok(())
+}
diff --git a/src/bin/proxmox_backup_manager/mod.rs b/src/bin/proxmox_backup_manager/mod.rs
index 11fb6dd3..14bd729e 100644
--- a/src/bin/proxmox_backup_manager/mod.rs
+++ b/src/bin/proxmox_backup_manager/mod.rs
@@ -36,3 +36,4 @@ mod openid;
pub use openid::*;
mod traffic_control;
pub use traffic_control::*;
+pub mod migrate_config;
diff --git a/src/bin/proxmox_backup_manager/prune.rs b/src/bin/proxmox_backup_manager/prune.rs
index 923eb6f5..eb06608b 100644
--- a/src/bin/proxmox_backup_manager/prune.rs
+++ b/src/bin/proxmox_backup_manager/prune.rs
@@ -1,13 +1,12 @@
use std::collections::HashMap;
use anyhow::Error;
-use serde::Deserialize;
use serde_json::Value;
use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
use proxmox_schema::api;
-use pbs_api_types::{DataStoreConfig, PruneJobConfig, PruneJobOptions, JOB_ID_SCHEMA};
+use pbs_api_types::{PruneJobConfig, JOB_ID_SCHEMA};
use pbs_config::prune;
use proxmox_backup::api2;
@@ -180,87 +179,3 @@ fn get_prune_job(id: &str) -> Result<PruneJobConfig, Error> {
config.lookup("prune", id)
}
-
-pub(crate) fn update_to_prune_jobs_config() -> Result<(), Error> {
- use pbs_config::datastore;
-
- let _prune_lock = prune::lock_config()?;
- let _datastore_lock = datastore::lock_config()?;
-
- let (mut data, _digest) = prune::config()?;
- let (mut storeconfig, _digest) = datastore::config()?;
-
- for (store, entry) in storeconfig.sections.iter_mut() {
- let ty = &entry.0;
-
- if ty != "datastore" {
- continue;
- }
-
- let mut config = match DataStoreConfig::deserialize(&entry.1) {
- Ok(c) => c,
- Err(err) => {
- eprintln!("failed to parse config of store {store}: {err}");
- continue;
- }
- };
-
- let options = PruneJobOptions {
- keep: std::mem::take(&mut config.keep),
- ..Default::default()
- };
-
- let schedule = config.prune_schedule.take();
-
- entry.1 = serde_json::to_value(config)?;
-
- let schedule = match schedule {
- Some(s) => s,
- None => {
- if options.keeps_something() {
- eprintln!(
- "dropping prune job without schedule from datastore '{store}' in datastore.cfg"
- );
- } else {
- eprintln!("ignoring empty prune job of datastore '{store}' in datastore.cfg");
- }
- continue;
- }
- };
-
- let mut id = format!("storeconfig-{store}");
- id.truncate(32);
- if data.sections.contains_key(&id) {
- eprintln!("skipping existing converted prune job for datastore '{store}': {id}");
- continue;
- }
-
- if !options.keeps_something() {
- eprintln!("dropping empty prune job of datastore '{store}' in datastore.cfg");
- continue;
- }
-
- let prune_config = PruneJobConfig {
- id: id.clone(),
- store: store.clone(),
- disable: false,
- comment: None,
- schedule,
- options,
- };
-
- let prune_config = serde_json::to_value(prune_config)?;
-
- data.sections
- .insert(id, ("prune".to_string(), prune_config));
-
- eprintln!(
- "migrating prune job of datastore '{store}' from datastore.cfg to prune.cfg jobs"
- );
- }
-
- prune::save_config(&data)?;
- datastore::save_config(&storeconfig)?;
-
- Ok(())
-}
--
2.39.5
More information about the pbs-devel
mailing list