* [PATCH datacenter-manager v2 0/2] fix an issue with cached subscription info
@ 2026-06-03 12:27 Shannon Sterz
2026-06-03 12:27 ` [PATCH datacenter-manager v2 1/2] server: subscription: always get fresh subscription info on update Shannon Sterz
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Shannon Sterz @ 2026-06-03 12:27 UTC (permalink / raw)
To: pdm-devel
and slightly improve the caching mechanism. the second patch here is
optional, it's just something i noticed while debugging.
Changelog
---------
changes since v1 (thanks @ Fabian Grünbichler):
- https://lore.proxmox.com/pdm-devel/20260603115442.361184-1-s.sterz@proxmox.com/)
* added a helper function that guarantees freshly fetched info that
never touched the cache. the last version had a slight chance of a
race occurring and us again getting cached, incomplete information.
* improved logging.
Shannon Sterz (2):
server: subscription: always get fresh subscription info on update
server: cache: short-circuit on special max age value 0
server/src/api/nodes/subscription.rs | 47 +++++++++++++++++++++++-----
server/src/api/resources.rs | 13 ++++++++
server/src/namespaced_cache.rs | 4 +++
3 files changed, 57 insertions(+), 7 deletions(-)
--
2.47.3
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH datacenter-manager v2 1/2] server: subscription: always get fresh subscription info on update
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
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
2 siblings, 0 replies; 4+ messages in thread
From: Shannon Sterz @ 2026-06-03 12:27 UTC (permalink / raw)
To: pdm-devel
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
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH datacenter-manager v2 2/2] server: cache: short-circuit on special max age value 0
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 ` [PATCH datacenter-manager v2 1/2] server: subscription: always get fresh subscription info on update Shannon Sterz
@ 2026-06-03 12:27 ` 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
2 siblings, 0 replies; 4+ messages in thread
From: Shannon Sterz @ 2026-06-03 12:27 UTC (permalink / raw)
To: pdm-devel
a max age of 0 means that the cached information is always considered
outdated. instead of reading from the cache first and then checking
the max age parameter, simply return early.
Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
Notes:
note, currently the cache only reads from the tmpfs /run. so the
speed-up is likely minimal for now. however, once we persist the cache
further this should help a bit.
server/src/namespaced_cache.rs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/server/src/namespaced_cache.rs b/server/src/namespaced_cache.rs
index 2f96df41..ccdec92f 100644
--- a/server/src/namespaced_cache.rs
+++ b/server/src/namespaced_cache.rs
@@ -554,6 +554,10 @@ fn get_impl<T: Serialize + DeserializeOwned>(
// Namespace should already be verified at this point, no point in checking it again.
ensure_valid_key(key)?;
+ if max_age == Some(0) {
+ return Ok(None);
+ }
+
let path = get_path(base, namespace, key);
Ok(get_from_path(&path, max_age)?.map(|a| a.value))
--
2.47.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* applied-series: [PATCH datacenter-manager v2 0/2] fix an issue with cached subscription info
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 ` [PATCH datacenter-manager v2 1/2] server: subscription: always get fresh subscription info on update Shannon Sterz
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 ` Fabian Grünbichler
2 siblings, 0 replies; 4+ messages in thread
From: Fabian Grünbichler @ 2026-06-03 12:55 UTC (permalink / raw)
To: pdm-devel, Shannon Sterz
On Wed, 03 Jun 2026 14:27:31 +0200, Shannon Sterz wrote:
> and slightly improve the caching mechanism. the second patch here is
> optional, it's just something i noticed while debugging.
>
> Changelog
> ---------
>
> changes since v1 (thanks @ Fabian Grünbichler):
> - https://lore.proxmox.com/pdm-devel/20260603115442.361184-1-s.sterz@proxmox.com/)
> * added a helper function that guarantees freshly fetched info that
> never touched the cache. the last version had a slight chance of a
> race occurring and us again getting cached, incomplete information.
> * improved logging.
>
> [...]
Applied, thanks!
[1/2] server: subscription: always get fresh subscription info on update
commit: 72d513fd6e700cc8fb9bc97d427e5d8a6b7934e3
[2/2] server: cache: short-circuit on special max age value 0
commit: 108de23bd062838c50e4b9d52cb0ad936c2a6bf3
Best regards,
--
Fabian Grünbichler <f.gruenbichler@proxmox.com>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-06-03 12:56 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH datacenter-manager v2 1/2] server: subscription: always get fresh subscription info on update Shannon Sterz
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox