public inbox for pve-devel@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal