From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id A712F1FF140 for ; Fri, 27 Mar 2026 13:13:53 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 248D38D01; Fri, 27 Mar 2026 13:14:10 +0100 (CET) From: Christian Ebner To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox-backup v4 7/8] config: move node config into pbs-config, including helper tools Date: Fri, 27 Mar 2026 13:13:18 +0100 Message-ID: <20260327121319.628881-8-c.ebner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260327121319.628881-1-c.ebner@proxmox.com> References: <20260327121319.628881-1-c.ebner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1774613563928 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.061 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 SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: TUUDQYMFWHISFPVQYIRHCWMHQ4JABSLV X-Message-ID-Hash: TUUDQYMFWHISFPVQYIRHCWMHQ4JABSLV X-MailFrom: c.ebner@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Backup Server development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: None of the node config helpers and tools are required to live in proxmox-backup directly anymore, all can be encapsulated in the pbs-config crate, aligning the node config code layout to that of other configs. Adapts all callsides to use pbs_config::node to interact with the node config. Signed-off-by: Christian Ebner --- pbs-config/Cargo.toml | 1 + src/tools/config.rs => pbs-config/src/key_value.rs | 0 pbs-config/src/lib.rs | 2 ++ {src/config => pbs-config/src}/node.rs | 11 ++++++----- src/api2/config/remote.rs | 2 +- src/api2/node/apt.rs | 2 +- src/api2/node/certificates.rs | 4 ++-- src/api2/node/config.rs | 8 ++++---- src/api2/node/subscription.rs | 2 +- src/bin/proxmox-backup-proxy.rs | 9 ++++----- src/bin/proxmox-daily-update.rs | 2 +- src/config/mod.rs | 1 - src/tools/mod.rs | 1 - 13 files changed, 23 insertions(+), 22 deletions(-) rename src/tools/config.rs => pbs-config/src/key_value.rs (100%) rename {src/config => pbs-config/src}/node.rs (80%) diff --git a/pbs-config/Cargo.toml b/pbs-config/Cargo.toml index eb81ce004..2b5eb782c 100644 --- a/pbs-config/Cargo.toml +++ b/pbs-config/Cargo.toml @@ -18,6 +18,7 @@ regex.workspace = true serde.workspace = true serde_json.workspace = true +proxmox-http.workspace = true proxmox-notify.workspace = true proxmox-router = { workspace = true, default-features = false } proxmox-s3-client.workspace = true diff --git a/src/tools/config.rs b/pbs-config/src/key_value.rs similarity index 100% rename from src/tools/config.rs rename to pbs-config/src/key_value.rs diff --git a/pbs-config/src/lib.rs b/pbs-config/src/lib.rs index 1ed472385..3be5582e8 100644 --- a/pbs-config/src/lib.rs +++ b/pbs-config/src/lib.rs @@ -4,8 +4,10 @@ pub use cached_user_info::CachedUserInfo; pub mod datastore; pub mod domains; pub mod drive; +pub mod key_value; pub mod media_pool; pub mod metrics; +pub mod node; pub mod notifications; pub mod prune; pub mod remote; diff --git a/src/config/node.rs b/pbs-config/src/node.rs similarity index 80% rename from src/config/node.rs rename to pbs-config/src/node.rs index 6e44495f8..1aeef9080 100644 --- a/src/config/node.rs +++ b/pbs-config/src/node.rs @@ -8,7 +8,8 @@ use proxmox_http::ProxyConfig; use proxmox_schema::ApiType; use pbs_buildcfg::configdir; -use pbs_config::{open_backup_lockfile, BackupLockGuard}; + +use crate::{open_backup_lockfile, BackupLockGuard}; const CONF_FILE: &str = configdir!("/node.cfg"); const LOCK_FILE: &str = configdir!("/.node.lck"); @@ -22,7 +23,7 @@ pub fn config() -> Result<(NodeConfig, [u8; 32]), Error> { let content = proxmox_sys::fs::file_read_optional_string(CONF_FILE)?.unwrap_or_default(); let digest = openssl::sha::sha256(content.as_bytes()); - let data: NodeConfig = crate::tools::config::from_str(&content, &NodeConfig::API_SCHEMA)?; + let data: NodeConfig = crate::key_value::from_str(&content, &NodeConfig::API_SCHEMA)?; Ok((data, digest)) } @@ -44,11 +45,11 @@ pub fn save_config(config: &NodeConfig) -> Result<(), Error> { dummy_acceptor.set_cipher_list(ciphers)?; } - let raw = crate::tools::config::to_bytes(config, &NodeConfig::API_SCHEMA)?; - pbs_config::replace_backup_config(CONF_FILE, &raw) + let raw = crate::key_value::to_bytes(config, &NodeConfig::API_SCHEMA)?; + crate::replace_backup_config(CONF_FILE, &raw) } -pub(crate) fn node_http_proxy_config() -> Result, Error> { +pub fn node_http_proxy_config() -> Result, Error> { let (node_config, _digest) = self::config()?; Ok(node_config.http_proxy()) } diff --git a/src/api2/config/remote.rs b/src/api2/config/remote.rs index 1996ee91b..03eae24dc 100644 --- a/src/api2/config/remote.rs +++ b/src/api2/config/remote.rs @@ -320,7 +320,7 @@ pub fn remote_client_config( options = options.rate_limit(limit); } if remote.config.use_node_proxy.unwrap_or(false) { - let proxy = crate::config::node::node_http_proxy_config()?; + let proxy = pbs_config::node::node_http_proxy_config()?; options = options.proxy(proxy); } diff --git a/src/api2/node/apt.rs b/src/api2/node/apt.rs index c696adb1e..32dfe7def 100644 --- a/src/api2/node/apt.rs +++ b/src/api2/node/apt.rs @@ -15,7 +15,7 @@ use proxmox_sys::fs::{replace_file, CreateOptions}; use pbs_api_types::{NODE_SCHEMA, PRIV_SYS_AUDIT, PRIV_SYS_MODIFY, UPID_SCHEMA}; -use crate::config::node; +use pbs_config::node; #[api( input: { diff --git a/src/api2/node/certificates.rs b/src/api2/node/certificates.rs index e5761e5f5..a69f6511f 100644 --- a/src/api2/node/certificates.rs +++ b/src/api2/node/certificates.rs @@ -328,7 +328,7 @@ fn spawn_certificate_worker( // custom one too hard... We keep the parameter because the widget-toolkit may be using it... let _ = force; - let (node_config, _digest) = crate::config::node::config()?; + let (node_config, _digest) = pbs_config::node::config()?; let auth_id = rpcenv.get_auth_id().unwrap(); @@ -381,7 +381,7 @@ fn spawn_certificate_worker( /// Renew the current ACME certificate if it expires within 30 days (or always if the `force` /// parameter is set). pub fn revoke_acme_cert(rpcenv: &mut dyn RpcEnvironment) -> Result { - let (node_config, _digest) = crate::config::node::config()?; + let (node_config, _digest) = pbs_config::node::config()?; let cert_pem = get_certificate_pem()?; diff --git a/src/api2/node/config.rs b/src/api2/node/config.rs index 619e2b022..fbec79118 100644 --- a/src/api2/node/config.rs +++ b/src/api2/node/config.rs @@ -28,7 +28,7 @@ pub const ROUTER: Router = Router::new() )] /// Get the node configuration pub fn get_node_config(rpcenv: &mut dyn RpcEnvironment) -> Result { - let (config, digest) = crate::config::node::config()?; + let (config, digest) = pbs_config::node::config()?; rpcenv["digest"] = hex::encode(digest).into(); Ok(config) } @@ -104,8 +104,8 @@ pub fn update_node_config( delete: Option>, digest: Option, ) -> Result<(), Error> { - let _lock = crate::config::node::lock()?; - let (mut config, expected_digest) = crate::config::node::config()?; + let _lock = pbs_config::node::lock()?; + let (mut config, expected_digest) = pbs_config::node::config()?; if let Some(digest) = digest { // FIXME: GUI doesn't handle our non-inlined digest part here properly... if !digest.is_empty() { @@ -206,7 +206,7 @@ pub fn update_node_config( config.consent_text = update.consent_text; } - crate::config::node::save_config(&config)?; + pbs_config::node::save_config(&config)?; update_apt_proxy_config(config.http_proxy().as_ref())?; diff --git a/src/api2/node/subscription.rs b/src/api2/node/subscription.rs index 7d9678fc5..03d613ee2 100644 --- a/src/api2/node/subscription.rs +++ b/src/api2/node/subscription.rs @@ -12,10 +12,10 @@ use pbs_api_types::{ Authid, NODE_SCHEMA, PRIV_SYS_AUDIT, PRIV_SYS_MODIFY, SUBSCRIPTION_KEY_SCHEMA, }; -use crate::config::node; use crate::tools::{DEFAULT_USER_AGENT_STRING, PROXMOX_BACKUP_TCP_KEEPALIVE_TIME}; use pbs_buildcfg::PROXMOX_BACKUP_SUBSCRIPTION_FN; +use pbs_config::node; use pbs_config::CachedUserInfo; const PRODUCT_URL: &str = "https://www.proxmox.com/en/proxmox-backup-server/pricing"; diff --git a/src/bin/proxmox-backup-proxy.rs b/src/bin/proxmox-backup-proxy.rs index c1fe3ac15..b04eb7e8e 100644 --- a/src/bin/proxmox-backup-proxy.rs +++ b/src/bin/proxmox-backup-proxy.rs @@ -45,7 +45,6 @@ use pbs_api_types::{ }; use proxmox_backup::auth_helpers::*; -use proxmox_backup::config; use proxmox_backup::server::{self, metric_collection}; use proxmox_backup::tools::PROXMOX_BACKUP_TCP_KEEPALIVE_TIME; @@ -80,7 +79,7 @@ fn get_language(headers: &hyper::http::HeaderMap) -> String { match cookie_from_header(headers, "PBSLangCookie") { Some(cookie_lang) if exists(&cookie_lang) => cookie_lang, - _ => match config::node::config().map(|(cfg, _)| cfg.default_lang) { + _ => match pbs_config::node::config().map(|(cfg, _)| cfg.default_lang) { Ok(Some(default_lang)) if exists(&default_lang) => default_lang, _ => String::from(""), }, @@ -145,7 +144,7 @@ async fn get_index_future(env: RestEnvironment, parts: Parts) -> Response let theme = get_theme(&parts.headers); - let consent = config::node::config() + let consent = pbs_config::node::config() .ok() .and_then(|config| config.0.consent_text) .unwrap_or("".to_string()); @@ -430,7 +429,7 @@ fn make_tls_acceptor() -> Result { let key_path = configdir!("/proxy.key"); let cert_path = configdir!("/proxy.pem"); - let (config, _) = config::node::config()?; + let (config, _) = pbs_config::node::config()?; let ciphers_tls_1_3 = config.ciphers_tls_1_3; let ciphers_tls_1_2 = config.ciphers_tls_1_2; @@ -799,7 +798,7 @@ async fn schedule_task_log_rotate() { let max_size = 512 * 1024 - 1; // an entry has ~ 100b, so > 5000 entries/file let max_files = 20; // times twenty files gives > 100000 task entries - let max_days = proxmox_backup::config::node::config() + let max_days = pbs_config::node::config() .map(|(cfg, _)| cfg.task_log_max_days) .ok() .flatten(); diff --git a/src/bin/proxmox-daily-update.rs b/src/bin/proxmox-daily-update.rs index 025eb47fd..c4d68e306 100644 --- a/src/bin/proxmox-daily-update.rs +++ b/src/bin/proxmox-daily-update.rs @@ -67,7 +67,7 @@ async fn do_update(rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> { } async fn check_acme_certificates(rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> { - let (config, _) = proxmox_backup::config::node::config()?; + let (config, _) = pbs_config::node::config()?; // do we even have any acme domains configures? if config.acme_domains().next().is_none() { diff --git a/src/config/mod.rs b/src/config/mod.rs index f05af90d8..2de76bb14 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -15,7 +15,6 @@ use proxmox_lang::try_block; use pbs_api_types::{PamRealmConfig, PbsRealmConfig}; use pbs_buildcfg::{self, configdir}; -pub mod node; pub mod tfa; /// Check configuration directory permissions diff --git a/src/tools/mod.rs b/src/tools/mod.rs index 6a975bde2..05225a843 100644 --- a/src/tools/mod.rs +++ b/src/tools/mod.rs @@ -13,7 +13,6 @@ use proxmox_http::{client::Client, HttpOptions, ProxyConfig}; use pbs_datastore::backup_info::{BackupDir, BackupInfo}; use pbs_datastore::manifest::BackupManifest; -pub mod config; pub mod disks; pub mod fs; pub mod statistics; -- 2.47.3