From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id B4AE41FF0E7 for ; Thu, 13 Aug 2026 19:10:50 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 3CCEB21AA8; Thu, 13 Aug 2026 19:10:36 +0200 (CEST) From: Christian Ebner To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox-backup 08/28] client: avoid error in status if user lacks permissions Date: Thu, 13 Aug 2026 19:09:42 +0200 Message-ID: <20260813171002.809441-9-c.ebner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260813171002.809441-1-c.ebner@proxmox.com> References: <20260813171002.809441-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: 1786641014458 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.214 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust RDNS_NONE 1.274 Delivered to internal network by a host with no rDNS 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: NSWJ4JQJU53TYOYLSX77EHQCCLZ65GHE X-Message-ID-Hash: NSWJ4JQJU53TYOYLSX77EHQCCLZ65GHE 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: In case of missing permissions the total storage space will be returned as zero, leading to the status output not being rendered since protected from zero division. This is however neither user friendly as the error does not reflect there being a lack of permissions, nor is it the correct behaviour, since the user still might have access to other information such as snapshot count (although currently not exposed in the CLI). Fix this by showing the values as returned by the API and skipping the percentage display if this would lead to zero division. While at it, rename the closure to reflect this behaviour and convert value parsing issues to errors instead of panics. Signed-off-by: Christian Ebner --- proxmox-backup-client/src/main.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/proxmox-backup-client/src/main.rs b/proxmox-backup-client/src/main.rs index e77661b22..ab77f0bbf 100644 --- a/proxmox-backup-client/src/main.rs +++ b/proxmox-backup-client/src/main.rs @@ -2082,23 +2082,27 @@ async fn status(param: Value) -> Result { record_repository(&repo); - let render_total_percentage = |v: &Value, record: &Value| -> Result { - let v = v.as_u64().unwrap(); - let total = record["total"].as_u64().unwrap(); + let total_with_opt_percentage = |v: &Value, record: &Value| -> Result { + let v = v + .as_u64() + .ok_or_else(|| format_err!("value is not a number"))?; + let total = record["total"] + .as_u64() + .ok_or_else(|| format_err!("total is not a number"))?; let roundup = total / 200; if let Some(per) = ((v + roundup) * 100).checked_div(total) { let info = format!(" ({per} %)"); Ok(format!("{v} {info:>8}")) } else { - bail!("Cannot render total percentage: denominator is zero"); + Ok(v.to_string()) } }; let options = default_table_format_options() .noheader(true) - .column(ColumnConfig::new("total").renderer(render_total_percentage)) - .column(ColumnConfig::new("used").renderer(render_total_percentage)) - .column(ColumnConfig::new("avail").renderer(render_total_percentage)); + .column(ColumnConfig::new("total").renderer(total_with_opt_percentage)) + .column(ColumnConfig::new("used").renderer(total_with_opt_percentage)) + .column(ColumnConfig::new("avail").renderer(total_with_opt_percentage)); let return_type = &API_METHOD_STATUS.returns; -- 2.47.3