all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH proxmox-offline-mirror 0/2 RFC] allow key activation through URL
@ 2025-10-17  6:39 Hannes Laimer
  2025-10-17  6:39 ` [pve-devel] [PATCH proxmox-offline-mirror 1/2] helper: allow URL as source for offline key activation Hannes Laimer
  2025-10-17  6:39 ` [pve-devel] [PATCH proxmox-offline-mirror 2/2] docs: add section for activating key over HTTP Hannes Laimer
  0 siblings, 2 replies; 3+ messages in thread
From: Hannes Laimer @ 2025-10-17  6:39 UTC (permalink / raw)
  To: pve-devel

If the medium is served over HTTP we can also load the `.mirror-state`
file over HTTP. This adds support for that.

In case a http server is already setup, additionally requiring mounting
the medium directly anyway, at least for key activation, isn't
necesarry IMHO.

Sending as RFC, since I'm not sure if there's a reason to not allow this
from a security standpoint.


Hannes Laimer (2):
  helper: allow URL as source for offline key activation
  docs: add section for activating key over HTTP

 docs/offline-media.rst                   | 12 +++++
 src/bin/proxmox-offline-mirror-helper.rs | 63 ++++++++++++++++++------
 2 files changed, 61 insertions(+), 14 deletions(-)

-- 
2.47.3



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [pve-devel] [PATCH proxmox-offline-mirror 1/2] helper: allow URL as source for offline key activation
  2025-10-17  6:39 [pve-devel] [PATCH proxmox-offline-mirror 0/2 RFC] allow key activation through URL Hannes Laimer
@ 2025-10-17  6:39 ` Hannes Laimer
  2025-10-17  6:39 ` [pve-devel] [PATCH proxmox-offline-mirror 2/2] docs: add section for activating key over HTTP Hannes Laimer
  1 sibling, 0 replies; 3+ messages in thread
From: Hannes Laimer @ 2025-10-17  6:39 UTC (permalink / raw)
  To: pve-devel

If the HTTP server is setup like in our exmaple, `.mirror-state` is
accessible over HTTP. With this the `offline-key` subcommand also
accepts an URL as a source. So instead of reading the `.mirror-state`
file directly from the fs, we'd load it over HTTP if an URL specified.
This removes to need for mounting the medium directly just for key
activation.

Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
---
 src/bin/proxmox-offline-mirror-helper.rs | 63 ++++++++++++++++++------
 1 file changed, 49 insertions(+), 14 deletions(-)

diff --git a/src/bin/proxmox-offline-mirror-helper.rs b/src/bin/proxmox-offline-mirror-helper.rs
index 07537f0..849465c 100644
--- a/src/bin/proxmox-offline-mirror-helper.rs
+++ b/src/bin/proxmox-offline-mirror-helper.rs
@@ -5,6 +5,8 @@ use std::{collections::HashMap, path::Path};
 
 use anyhow::{Error, bail, format_err};
 
+use proxmox_http::client::sync::Client;
+use proxmox_http::{HttpClient, HttpOptions, ProxyConfig};
 use proxmox_offline_mirror::types::Snapshot;
 use proxmox_subscription::{ProductType, SubscriptionInfo};
 use proxmox_sys::command::run_command;
@@ -24,6 +26,48 @@ use proxmox_offline_mirror::helpers::tty::{
 };
 use proxmox_offline_mirror::medium::{self, MediumState, generate_repo_snippet};
 
+fn load_mirror_state(source: &str) -> Result<MediumState, Error> {
+    if source.starts_with("http://") || source.starts_with("https://") {
+        let state_url = if source.ends_with('/') {
+            format!("{}.mirror-state", source)
+        } else {
+            format!("{}/.mirror-state", source)
+        };
+
+        let options = HttpOptions {
+            user_agent: Some(
+                concat!("proxmox-offline-mirror-helper/", env!("CARGO_PKG_VERSION")).to_string(),
+            ),
+            proxy_config: ProxyConfig::from_proxy_env()?,
+            ..Default::default()
+        };
+        let client = Client::new(options);
+
+        let response = client.get(&state_url, None)?;
+        if !response.status().is_success() {
+            bail!(
+                "Failed to download mirror state from {}: {}",
+                state_url,
+                response.status()
+            );
+        }
+
+        let body: Vec<u8> = response.into_body();
+        serde_json::from_slice(&body).map_err(Error::from)
+    } else {
+        let mountpoint = Path::new(source);
+        if !mountpoint.exists() {
+            bail!("Medium mountpoint doesn't exist.");
+        }
+
+        let mut statefile = mountpoint.to_path_buf();
+        statefile.push(".mirror-state");
+
+        let raw = file_get_contents(&statefile)?;
+        serde_json::from_slice(&raw).map_err(Error::from)
+    }
+}
+
 fn set_subscription_key(
     product: &ProductType,
     subscription: &SubscriptionInfo,
@@ -264,9 +308,9 @@ async fn setup(_param: Value) -> Result<(), Error> {
 #[api(
     input: {
         properties: {
-            mountpoint: {
+            source: {
                 type: String,
-                description: "Path to medium mountpoint",
+                description: "Path to medium mountpoint or URL for key activation",
             },
             product: {
                 type: ProductType,
@@ -277,7 +321,7 @@ async fn setup(_param: Value) -> Result<(), Error> {
 )]
 /// Configures and offline subscription key
 async fn setup_offline_key(
-    mountpoint: String,
+    source: String,
     product: Option<ProductType>,
     _param: Value,
 ) -> Result<(), Error> {
@@ -288,17 +332,8 @@ async fn setup_offline_key(
         );
     }
 
-    let mountpoint = Path::new(&mountpoint);
-    if !mountpoint.exists() {
-        bail!("Medium mountpoint doesn't exist.");
-    }
-
-    let mut statefile = mountpoint.to_path_buf();
-    statefile.push(".mirror-state");
-
-    println!("Loading state from {statefile:?}..");
-    let raw = file_get_contents(&statefile)?;
-    let state: MediumState = serde_json::from_slice(&raw)?;
+    println!("Loading state from {}..", source);
+    let state = load_mirror_state(&source)?;
     println!(
         "Last sync timestamp: {}",
         epoch_to_rfc3339_utc(state.last_sync)?
-- 
2.47.3



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [pve-devel] [PATCH proxmox-offline-mirror 2/2] docs: add section for activating key over HTTP
  2025-10-17  6:39 [pve-devel] [PATCH proxmox-offline-mirror 0/2 RFC] allow key activation through URL Hannes Laimer
  2025-10-17  6:39 ` [pve-devel] [PATCH proxmox-offline-mirror 1/2] helper: allow URL as source for offline key activation Hannes Laimer
@ 2025-10-17  6:39 ` Hannes Laimer
  1 sibling, 0 replies; 3+ messages in thread
From: Hannes Laimer @ 2025-10-17  6:39 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
---
 docs/offline-media.rst | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/docs/offline-media.rst b/docs/offline-media.rst
index f080581..7f02ad5 100644
--- a/docs/offline-media.rst
+++ b/docs/offline-media.rst
@@ -108,3 +108,15 @@ Activating an Subscription Key
 To activate or update a subscription key offline, either use ``proxmox-offline-mirror-helper
 offline-key`` directly or follow the respective step when doing the guided setup via the
 ``proxmox-offline-mirror-helper setup`` command.
+
+The ``offline-key`` command supports both local mountpoints and HTTP URLs. When using an HTTP
+server (as described in the `Local HTTP Server`_ section), you can activate subscription keys
+directly from the HTTP URL without needing to mount the medium locally:
+
+.. code-block:: console
+
+  proxmox-offline-mirror-helper offline-key --source http://proxmox-offline-mirror.domain.example/
+
+This is particularly useful when the mirror is served over HTTP and you only need to activate
+subscription keys. Other operations like the ``status`` command and repository configuration
+still require a local mountpoint.
-- 
2.47.3



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-10-17  6:39 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-10-17  6:39 [pve-devel] [PATCH proxmox-offline-mirror 0/2 RFC] allow key activation through URL Hannes Laimer
2025-10-17  6:39 ` [pve-devel] [PATCH proxmox-offline-mirror 1/2] helper: allow URL as source for offline key activation Hannes Laimer
2025-10-17  6:39 ` [pve-devel] [PATCH proxmox-offline-mirror 2/2] docs: add section for activating key over HTTP Hannes Laimer

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