all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Shannon Sterz <s.sterz@proxmox.com>
To: pdm-devel@lists.proxmox.com
Subject: [PATCH datacenter-manager v2 1/2] server: subscription: always get fresh subscription info on update
Date: Wed,  3 Jun 2026 14:27:32 +0200	[thread overview]
Message-ID: <20260603122735.425390-2-s.sterz@proxmox.com> (raw)
In-Reply-To: <20260603122735.425390-1-s.sterz@proxmox.com>

otherwise the cached information is used. since the cache does not
include the server id, not suitable information will be detected. to
avoid that freshly fetch the subscription info, including the server
id, when updating the subscription status.

adds a helper that guarantees complete, freshly fetched information as
the existing `get_subscription_info_for_remote` helper can still
return cached information. this can happen when another thread updated
the cache sooner than the current thread can.

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 server/src/api/nodes/subscription.rs | 47 +++++++++++++++++++++++-----
 server/src/api/resources.rs          | 13 ++++++++
 2 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/server/src/api/nodes/subscription.rs b/server/src/api/nodes/subscription.rs
index d6ae48b5..dd47836e 100644
--- a/server/src/api/nodes/subscription.rs
+++ b/server/src/api/nodes/subscription.rs
@@ -15,7 +15,9 @@ use pdm_api_types::subscription::{
     NodeSubscriptionInfo, PdmSubscriptionInfo, SubscriptionLevel, SubscriptionStatistics,
 };
 
-use crate::api::resources::get_subscription_info_for_remote;
+use crate::api::resources::{
+    fetch_complete_subscription_info_for_remote, get_subscription_info_for_remote,
+};
 
 const PRODUCT_URL: &str = "https://pdm.proxmox.com/faq.html";
 const APT_AUTH_FN: &str = "/etc/apt/auth.conf.d/pdm.conf";
@@ -153,7 +155,7 @@ pub async fn check_subscription() -> Result<(), Error> {
     }
 
     let mut found = false;
-    'outer: for (remote, (remote_type, remote_info)) in infos.iter() {
+    'outer: for (remote_name, (remote_type, remote_info)) in infos.iter() {
         if *remote_type != RemoteType::Pve && *remote_type != RemoteType::Pbs {
             log::warn!("skipping unknown remote type {remote_type}");
             continue;
@@ -163,12 +165,43 @@ pub async fn check_subscription() -> Result<(), Error> {
                 if info.status == SubscriptionStatus::Active
                     && info.level >= SubscriptionLevel::Basic
                     && info.key.is_some()
-                    && info.serverid.is_some()
                 {
-                    log::info!(
-                        "Using subscription of node '{node}' of remote '{remote}' for enterprise \
-                         repository access"
-                    );
+                    // Get fresh subscription info. The cache does not store the serverid, so we
+                    // need to fetch it from the remote. This has the upside of always yielding
+                    // fresh results.
+                    let (remote_config, _digest) = pdm_config::remotes::config()?;
+                    let Some(remote) = remote_config.get(remote_name) else {
+                        log::debug!(
+                            "Remote vanished while updating subscription information \
+                            '{remote_name}'."
+                        );
+                        continue 'outer;
+                    };
+                    let node_info = fetch_complete_subscription_info_for_remote(remote).await?;
+                    let Some(info) = node_info.iter().find_map(|(node, val)| {
+                        if let Some(info) = val.as_ref() {
+                            if info.status == SubscriptionStatus::Active
+                                && info.level >= SubscriptionLevel::Basic
+                                && info.key.is_some()
+                                && info.serverid.is_some()
+                            {
+                                log::info!(
+                                    "Using subscription of node '{node}' of remote '{remote_name}' \
+                                    for enterprise repository access"
+                                );
+
+                                return Some(info.clone());
+                            }
+                        }
+                        None
+                    }) else {
+                        log::debug!(
+                            "Could not find any eligibile subscription information for remote \
+                            '{remote_name}' while updating the subscription information."
+                        );
+                        continue 'outer;
+                    };
+
                     update_apt_auth(
                         APT_AUTH_FN,
                         apt_auth_file_opts(),
diff --git a/server/src/api/resources.rs b/server/src/api/resources.rs
index f2ef4101..09d2b88d 100644
--- a/server/src/api/resources.rs
+++ b/server/src/api/resources.rs
@@ -866,6 +866,19 @@ pub async fn get_subscription_info_for_remote(
     }
 }
 
+/// Always fetches fresh complete subscription information for a remote.
+///
+/// The cache will be updated, but never read from. This guarantees that the `serverid` is set, as
+/// it cannot be stored in the cache.
+pub async fn fetch_complete_subscription_info_for_remote(
+    remote: &Remote,
+) -> Result<HashMap<String, Option<NodeSubscriptionInfo>>, Error> {
+    let node_info = fetch_remote_subscription_info(remote).await?;
+    let now = proxmox_time::epoch_i64();
+    let _ = update_cached_subscription_info(&remote.id, node_info.clone(), now).await?;
+    Ok(node_info)
+}
+
 const SUBSCRIPTION_STATE_CACHE_KEY: &str = "subscription-state";
 
 async fn get_cached_subscription_info(
-- 
2.47.3





  reply	other threads:[~2026-06-03 12:28 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-03 12:27 [PATCH datacenter-manager v2 0/2] fix an issue with cached subscription info Shannon Sterz
2026-06-03 12:27 ` Shannon Sterz [this message]
2026-06-03 12:27 ` [PATCH datacenter-manager v2 2/2] server: cache: short-circuit on special max age value 0 Shannon Sterz
2026-06-03 12:55 ` applied-series: [PATCH datacenter-manager v2 0/2] fix an issue with cached subscription info Fabian Grünbichler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260603122735.425390-2-s.sterz@proxmox.com \
    --to=s.sterz@proxmox.com \
    --cc=pdm-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal