From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id BB2081FF185 for ; Mon, 23 Jun 2025 16:13:17 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 0000C142BA; Mon, 23 Jun 2025 16:13:45 +0200 (CEST) From: Lukas Wagner To: pbs-devel@lists.proxmox.com Date: Mon, 23 Jun 2025 16:13:07 +0200 Message-Id: <20250623141315.288681-3-l.wagner@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250623141315.288681-1-l.wagner@proxmox.com> References: <20250623141315.288681-1-l.wagner@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.980 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_MAILER 2 Automated Mailer Tag Left in Email SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pbs-devel] [PATCH proxmox-backup 1/9] cli: manager: move update-to-prune-jobs command to new migrate-config sub-command X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox Backup Server development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pbs-devel-bounces@lists.proxmox.com Sender: "pbs-devel" 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 --- 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 = 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 = 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 { 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 _______________________________________________ pbs-devel mailing list pbs-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel