* [pve-devel] [PATCH installer] fetch-answer: add `$fetchinfo` meta-field to HTTP POST payload
@ 2024-11-13 9:06 Christoph Heiss
0 siblings, 0 replies; only message in thread
From: Christoph Heiss @ 2024-11-13 9:06 UTC (permalink / raw)
To: pve-devel
This adds a metadata-field `$fetchinfo` containing a single key
`version` (for now) to the POST payload json, indicating which schema
version (and thus structure) this document uses.
The version field follows the format "<major>.<minor>" and applies
semantic versioning meaning for both the major and minor number. A patch
version is left out here, as it doesn't make much sense in this context.
Works in the same manner as the post-hook does it [0]. Useful to have it
for this too, as we might change/expand this structure too in the
future.
In the resulting JSON, this will look like this:
{
"$fetchinfo": {
"version": "1.0"
},
"product": ..,
..
}
[0] https://lore.proxmox.com/pve-devel/20241112145405.929194-1-c.heiss@proxmox.com/
Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
proxmox-auto-installer/src/sysinfo.rs | 5 --
proxmox-fetch-answer/Cargo.toml | 2 +
.../src/fetch_plugins/http.rs | 65 ++++++++++++++++++-
3 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/proxmox-auto-installer/src/sysinfo.rs b/proxmox-auto-installer/src/sysinfo.rs
index 0a6aaf2..a45ae59 100644
--- a/proxmox-auto-installer/src/sysinfo.rs
+++ b/proxmox-auto-installer/src/sysinfo.rs
@@ -41,11 +41,6 @@ impl SysInfo {
let info = Self::get()?;
Ok(serde_json::to_string_pretty(&info)?)
}
-
- pub fn as_json() -> Result<String> {
- let info = Self::get()?;
- Ok(serde_json::to_string(&info)?)
- }
}
#[derive(Debug, Serialize)]
diff --git a/proxmox-fetch-answer/Cargo.toml b/proxmox-fetch-answer/Cargo.toml
index 50f3da3..23bd094 100644
--- a/proxmox-fetch-answer/Cargo.toml
+++ b/proxmox-fetch-answer/Cargo.toml
@@ -15,4 +15,6 @@ anyhow.workspace = true
log.workspace = true
proxmox-auto-installer.workspace = true
proxmox-installer-common = { workspace = true, features = ["http"] }
+serde = { workspace = true, features = ["derive"] }
+serde_json.workspace = true
toml.workspace = true
diff --git a/proxmox-fetch-answer/src/fetch_plugins/http.rs b/proxmox-fetch-answer/src/fetch_plugins/http.rs
index 4317430..fb9ffc8 100644
--- a/proxmox-fetch-answer/src/fetch_plugins/http.rs
+++ b/proxmox-fetch-answer/src/fetch_plugins/http.rs
@@ -1,5 +1,6 @@
use anyhow::{bail, Result};
use log::info;
+use serde::Serialize;
use std::{
fs::{self, read_to_string},
process::Command,
@@ -28,6 +29,67 @@ static DHCP_URL_OPTION: &str = "proxmox-auto-installer-manifest-url";
static DHCP_CERT_FP_OPTION: &str = "proxmox-auto-installer-cert-fingerprint";
static DHCP_LEASE_FILE: &str = "/var/lib/dhcp/dhclient.leases";
+/// Metadata of the HTTP POST payload, such as schema version of the document.
+#[derive(Serialize)]
+#[serde(rename_all = "kebab-case")]
+struct HttpFetchInfoMeta {
+ /// major.minor version describing the schema version of this document, in a semanticy-version
+ /// way.
+ ///
+ /// major: Incremented for incompatible/breaking API changes, e.g. removing an existing
+ /// field.
+ /// minor: Incremented when adding functionality in a backwards-compatible matter, e.g.
+ /// adding a new field.
+ version: String,
+}
+
+impl HttpFetchInfoMeta {
+ const SCHEMA_VERSION: &str = "1.0";
+}
+
+impl Default for HttpFetchInfoMeta {
+ fn default() -> Self {
+ Self {
+ version: Self::SCHEMA_VERSION.to_owned(),
+ }
+ }
+}
+
+/// All data sent as request payload with the answerfile fetch POST request.
+///
+/// NOTE: The format is versioned through `fetch_meta.version` (`$fetchinfo.version` in the
+/// resulting JSON), ensure you update it when this struct or any of its members gets modified.
+#[derive(Serialize)]
+#[serde(rename_all = "kebab-case")]
+struct HttpFetchPayload {
+ /// Metadata for the answerfile fetch payload
+ // This field is prefixed by `$` on purpose, to indicate that it is document metadata and not
+ // part of the actual content itself. (E.g. JSON Schema uses a similar naming scheme)
+ #[serde(rename = "$fetchinfo")]
+ fetch_meta: HttpFetchInfoMeta,
+ /// Information about the running system, flattened into this structure directly.
+ #[serde(flatten)]
+ sysinfo: SysInfo,
+}
+
+impl HttpFetchPayload {
+ /// Retrieves the required information from the system and constructs the
+ /// full payload including meta data.
+ fn get() -> Result<Self> {
+ Ok(Self {
+ fetch_meta: HttpFetchInfoMeta::default(),
+ sysinfo: SysInfo::get()?,
+ })
+ }
+
+ /// Retrieves the required information from the system and constructs the
+ /// full payload including meta data, serialized as JSON.
+ pub fn as_json() -> Result<String> {
+ let info = Self::get()?;
+ Ok(serde_json::to_string(&info)?)
+ }
+}
+
pub struct FetchFromHTTP;
impl FetchFromHTTP {
@@ -65,7 +127,8 @@ impl FetchFromHTTP {
}
info!("Gathering system information.");
- let payload = SysInfo::as_json()?;
+ let payload = HttpFetchPayload::as_json()?;
+
info!("Sending POST request to '{answer_url}'.");
let answer =
proxmox_installer_common::http::post(&answer_url, fingerprint.as_deref(), payload)?;
--
2.47.0
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2024-11-13 9:06 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-11-13 9:06 [pve-devel] [PATCH installer] fetch-answer: add `$fetchinfo` meta-field to HTTP POST payload Christoph Heiss
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox