public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Aaron Lauterer <a.lauterer@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH installer v5 34/36] fetch-answer: use ISO specified configurations
Date: Tue, 16 Apr 2024 17:33:23 +0200	[thread overview]
Message-ID: <20240416153325.1154224-35-a.lauterer@proxmox.com> (raw)
In-Reply-To: <20240416153325.1154224-1-a.lauterer@proxmox.com>

This patch switches the behavior to use the settings that can be
specified in the ISO.

This means, that it is possible to control how the answer file should be
fetched:

* auto - as usually, go through the options until one works (partition,
  http)
* included - the answer file is included in the ISO
* partition - only check for an answer file in a partition called
  'proxmoxinst' in lower or uppercase
* http - only fetch the answer file via an HTTP POST request.

Additionally it is possible to specify the HTTP URL directly in the ISO.

Placing the SSL fingerprint on a partition is not possible anymore. If
one wants to provide it right away (besides DHCP or DNS), it must be
incluced in the ISO itself. This reduced the need for another USB flash
drive.

Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
---
 proxmox-fetch-answer/Cargo.toml               |  1 +
 .../src/fetch_plugins/http.rs                 | 65 +++++++------------
 proxmox-fetch-answer/src/main.rs              | 64 ++++++++++++++----
 3 files changed, 77 insertions(+), 53 deletions(-)

diff --git a/proxmox-fetch-answer/Cargo.toml b/proxmox-fetch-answer/Cargo.toml
index fbcca46..797c185 100644
--- a/proxmox-fetch-answer/Cargo.toml
+++ b/proxmox-fetch-answer/Cargo.toml
@@ -17,6 +17,7 @@ log = "0.4.20"
 ureq = { version = "2.6", features = [ "native-certs", "native-tls" ] }
 rustls = { version = "0.20", features = [ "dangerous_configuration" ] }
 rustls-native-certs = "0.6"
+toml = "0.7"
 native-tls = "0.2"
 sha2 = "0.10"
 hex = "0.4"
diff --git a/proxmox-fetch-answer/src/fetch_plugins/http.rs b/proxmox-fetch-answer/src/fetch_plugins/http.rs
index 5772c42..b5550fe 100644
--- a/proxmox-fetch-answer/src/fetch_plugins/http.rs
+++ b/proxmox-fetch-answer/src/fetch_plugins/http.rs
@@ -2,16 +2,12 @@ use anyhow::{bail, Error, Result};
 use log::info;
 use std::{
     fs::{self, read_to_string},
-    path::Path,
     process::Command,
 };
 
 use crate::fetch_plugins::utils::post;
-use proxmox_auto_installer::sysinfo;
+use proxmox_auto_installer::{sysinfo, utils::AutoInstSettings};
 
-use super::utils;
-
-static CERT_FINGERPRINT_FILE: &str = "cert_fingerprint.txt";
 static ANSWER_SUBDOMAIN: &str = "proxmoxinst";
 static ANSWER_SUBDOMAIN_FP: &str = "proxmoxinst-fp";
 
@@ -37,30 +33,33 @@ pub struct FetchFromHTTP;
 
 impl FetchFromHTTP {
     /// Will try to fetch the answer.toml by sending a HTTP POST request. The URL can be configured
-    /// either via DHCP or DNS.
-    /// DHCP options are checked first. The SSL certificate need to be either trusted by the root
-    /// certs or a SHA256 fingerprint needs to be provided. The SHA256 SSL fingerprint can either
-    /// be placed in a `cert_fingerprint.txt` file in the `proxmoxinst` partition, as DHCP option,
-    /// or as DNS TXT record. If provided, the `cert_fingerprint.txt` file has preference.
-    pub fn get_answer() -> Result<String> {
-        info!("Checking for certificate fingerprint in file.");
-        let mut fingerprint: Option<String> = match Self::get_cert_fingerprint_from_file() {
-            Ok(fp) => Some(fp),
-            Err(err) => {
-                info!("{err}");
-                None
+    /// either via DHCP or DNS or preconfigured in the ISO.
+    /// If the URL is not defined in the ISO, it will first check DHCP options. The SSL certificate
+    /// needs to be either trusted by the root certs or a SHA256 fingerprint needs to be provided.
+    /// The SHA256 SSL fingerprint can either be defined in the ISO, as DHCP option, or as DNS TXT
+    /// record. If provided, the fingerprint provided in the ISO has preference.
+    pub fn get_answer(settings: &AutoInstSettings) -> Result<String> {
+        let mut fingerprint: Option<String> = match settings.ssl_fingerprint.clone() {
+            Some(fp) => {
+                info!("SSL fingerprint provided through ISO.");
+                Some(fp)
             }
+            None => None,
         };
 
         let answer_url: String;
-
-        (answer_url, fingerprint) = match Self::fetch_dhcp(fingerprint.clone()) {
-            Ok((url, fp)) => (url, fp),
-            Err(err) => {
-                info!("{err}");
-                Self::fetch_dns(fingerprint.clone())?
-            }
-        };
+        if let Some(url) = settings.http_url.clone() {
+            info!("URL specified in ISO");
+            answer_url = url;
+        } else {
+            (answer_url, fingerprint) = match Self::fetch_dhcp(fingerprint.clone()) {
+                Ok((url, fp)) => (url, fp),
+                Err(err) => {
+                    info!("{err}");
+                    Self::fetch_dns(fingerprint.clone())?
+                }
+            };
+        }
 
         if fingerprint.is_some() {
             let fp = fingerprint.clone();
@@ -74,22 +73,6 @@ impl FetchFromHTTP {
         Ok(answer)
     }
 
-    /// Reads certificate fingerprint from file
-    pub fn get_cert_fingerprint_from_file() -> Result<String> {
-        let mount_path = utils::mount_proxmoxinst_part()?;
-        let cert_path = Path::new(mount_path.as_str()).join(CERT_FINGERPRINT_FILE);
-        match cert_path.try_exists() {
-            Ok(true) => {
-                info!("Found certifacte fingerprint file.");
-                Ok(fs::read_to_string(cert_path)?.trim().into())
-            }
-            _ => Err(Error::msg(format!(
-                "could not find cert fingerprint file expected at: {}",
-                cert_path.display()
-            ))),
-        }
-    }
-
     /// Fetches search domain from resolv.conf file
     fn get_search_domain() -> Result<String> {
         info!("Retrieving default search domain.");
diff --git a/proxmox-fetch-answer/src/main.rs b/proxmox-fetch-answer/src/main.rs
index 8c762e9..fe5d599 100644
--- a/proxmox-fetch-answer/src/main.rs
+++ b/proxmox-fetch-answer/src/main.rs
@@ -1,13 +1,15 @@
 use anyhow::{anyhow, Error, Result};
 use fetch_plugins::{http::FetchFromHTTP, partition::FetchFromPartition};
 use log::{error, info, LevelFilter};
-use proxmox_auto_installer::log::AutoInstLogger;
+use proxmox_auto_installer::{log::AutoInstLogger, utils::{AutoInstModes, AutoInstSettings}};
+use std::{fs, path::PathBuf};
 use std::io::Write;
 use std::process::{Command, ExitCode, Stdio};
 
 mod fetch_plugins;
 
 static LOGGER: AutoInstLogger = AutoInstLogger;
+static AUTOINST_MODE_FILE: &str = "/cdrom/autoinst-mode.toml";
 
 pub fn init_log() -> Result<()> {
     AutoInstLogger::init("/tmp/fetch_answer.log")?;
@@ -16,16 +18,40 @@ pub fn init_log() -> Result<()> {
         .map_err(|err| anyhow!(err))
 }
 
-fn fetch_answer() -> Result<String> {
-    match FetchFromPartition::get_answer() {
-        Ok(answer) => return Ok(answer),
-        Err(err) => info!("Fetching answer file from partition failed: {err}"),
-    }
-    match FetchFromHTTP::get_answer() {
-        Ok(answer) => return Ok(answer),
-        Err(err) => info!("Fetching answer file via HTTP failed: {err}"),
-    }
+fn fetch_answer(install_settings: &AutoInstSettings) -> Result<String> {
+    info!("Fetching answer file in mode {:?}:", &install_settings.mode);
+    match install_settings.mode {
+        AutoInstModes::Auto => {
+            match FetchFromPartition::get_answer() {
+                Ok(answer) => return Ok(answer),
+                Err(err) => info!("Fetching answer file from partition failed: {err}"),
+            }
+            match FetchFromHTTP::get_answer(install_settings) {
+                Ok(answer) => return Ok(answer),
+                Err(err) => info!("Fetching answer file via HTTP failed: {err}"),
+            }
+        },
+        AutoInstModes::Included => {
+            let answer_path = PathBuf::from("/cdrom/answer.toml");
+            match fetch_plugins::utils::get_answer_file(&answer_path) {
+                Ok(answer) => return Ok(answer),
+                Err(err) => info!("Fetching answer file from ISO failed: {err}"),
+            }
+        },
+        AutoInstModes::Partition => {
+            match FetchFromPartition::get_answer() {
+                Ok(answer) => return Ok(answer),
+                Err(err) => info!("Fetching answer file from partition failed: {err}"),
+            }
+        },
+        AutoInstModes::Http => {
+            match FetchFromHTTP::get_answer(install_settings) {
+                Ok(answer) => return Ok(answer),
+                Err(err) => info!("Fetching answer file via HTTP failed: {err}"),
+            }
+        },
 
+    }
     Err(Error::msg("Could not find any answer file!"))
 }
 
@@ -34,8 +60,22 @@ fn main() -> ExitCode {
         panic!("could not initialize logging: {err}");
     }
 
-    info!("Fetching answer file");
-    let answer = match fetch_answer() {
+    let raw_install_settings = match fs::read_to_string(AUTOINST_MODE_FILE) {
+        Ok(f) => f,
+        Err(err) => {
+            error!("Could not find needed file '{AUTOINST_MODE_FILE}' in live environment: {err}");
+            return ExitCode::FAILURE;
+        },
+    };
+    let install_settings: AutoInstSettings = match toml::from_str(raw_install_settings.as_str()) {
+        Ok(content) => content,
+        Err(err) => {
+            error!("Failed to parse '{AUTOINST_MODE_FILE}': {err}");
+            return ExitCode::FAILURE;
+        },
+    };
+
+    let answer = match fetch_answer(&install_settings) {
         Ok(answer) => answer,
         Err(err) => {
             error!("Aborting: {}", err);
-- 
2.39.2





  parent reply	other threads:[~2024-04-16 15:37 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-16 15:32 [pve-devel] [PATCH installer v5 00/36] add automated/unattended installation Aaron Lauterer
2024-04-16 15:32 ` [pve-devel] [PATCH installer v5 01/36] tui: common: move InstallConfig struct to common crate Aaron Lauterer
2024-04-16 15:32 ` [pve-devel] [PATCH installer v5 02/36] common: make InstallZfsOption members public Aaron Lauterer
2024-04-16 15:32 ` [pve-devel] [PATCH installer v5 03/36] common: tui: use BTreeMap for predictable ordering Aaron Lauterer
2024-04-16 15:32 ` [pve-devel] [PATCH installer v5 04/36] common: utils: add deserializer for CidrAddress Aaron Lauterer
2024-04-16 15:32 ` [pve-devel] [PATCH installer v5 05/36] common: options: add Deserialize trait Aaron Lauterer
2024-04-16 15:32 ` [pve-devel] [PATCH installer v5 06/36] low-level: add dump-udev command Aaron Lauterer
2024-04-16 15:32 ` [pve-devel] [PATCH installer v5 07/36] add auto-installer crate Aaron Lauterer
2024-04-16 15:32 ` [pve-devel] [PATCH installer v5 08/36] auto-installer: add dependencies Aaron Lauterer
2024-04-16 15:32 ` [pve-devel] [PATCH installer v5 09/36] auto-installer: add answer file definition Aaron Lauterer
2024-04-16 15:32 ` [pve-devel] [PATCH installer v5 10/36] auto-installer: add struct to hold udev info Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 11/36] auto-installer: add utils Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 12/36] auto-installer: add simple logging Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 13/36] auto-installer: add tests for answer file parsing Aaron Lauterer
2024-04-16 15:36   ` [pve-devel] [PATCH installer v5 13/36, follow-up] " Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 14/36] auto-installer: add auto-installer binary Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 15/36] auto-installer: add fetch answer binary Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 16/36] unconfigured: add proxauto as option to start auto installer Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 17/36] auto-installer: use glob crate for pattern matching Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 18/36] auto-installer: utils: make get_udev_index functions public Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 19/36] auto-installer: add proxmox-autoinst-helper tool Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 20/36] common: add Display trait to ProxmoxProduct Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 21/36] auto-installer: fetch: add gathering of system identifiers and restructure code Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 22/36] auto-installer: helper: add subcommand to view indentifiers Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 23/36] auto-installer: fetch: add http post utility module Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 24/36] auto-installer: fetch: add http plugin to fetch answer Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 25/36] control: update build depends for auto installer Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 26/36] auto installer: factor out fetch-answer and autoinst-helper Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 27/36] low-level: write low level config to /tmp Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 28/36] common: add deserializer for FsType Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 29/36] common: skip target_hd when deserializing InstallConfig Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 30/36] add proxmox-chroot utility Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 31/36] auto-installer: answer: deny unknown fields Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 32/36] fetch-answer: move get_answer_file to utils Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 33/36] auto-installer: utils: define ISO specified settings Aaron Lauterer
2024-04-16 15:33 ` Aaron Lauterer [this message]
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 35/36] fetch-answer: dpcp: improve logging of steps taken Aaron Lauterer
2024-04-16 15:33 ` [pve-devel] [PATCH installer v5 36/36] autoinst-helper: add prepare-iso subcommand Aaron Lauterer
2024-04-17  5:22 ` [pve-devel] [PATCH installer v5 00/36] add automated/unattended installation Thomas Lamprecht
2024-04-17  7:30   ` Aaron Lauterer
2024-04-17 12:32 ` Aaron Lauterer

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=20240416153325.1154224-35-a.lauterer@proxmox.com \
    --to=a.lauterer@proxmox.com \
    --cc=pve-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 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