Re: [pve-devel] [RFC pve-storage 01/36] plugin: base: remove old fixme comments

2024-07-18 Thread Max Carrara
On Wed Jul 17, 2024 at 6:02 PM CEST, Thomas Lamprecht wrote:
> Am 17/07/2024 um 11:39 schrieb Max Carrara:
> > These have been around since 2012 - suffice to say they're not needed
> > anymore.
>
> That's really not a good argument though? Just because nobody checked
> those closely for a long time it does not mean that they became
> magically irrelevant.
>
> Look, it can be (and probably _is_) fine to remove them, but stating
> that this is fine just because they were not touched since a while is a
> rather dangerous tactic. Someone had some thoughts when adding this,
> they might be still relevant or not, but it's definitively *not*
> "suffice to say" that they aren't just because they have been around
> since 2012, (iSCSI) portals and local storage still exist and are not
> working really different compared to 12 years ago.
>
> The node restriction FIXME comment can e.g. be removed as we delete any
> such restriction in "parse_config", mentioning that as a reason would
> make doing so fine, saying "it's old and unchanged" doesn't.
>
> The storage portal one could be argued with not being defined elsewhere
> and all use cases being covered by pve-storage-portal-dns, so removing
> it won't hurt, especially as we can always recover it from history.
>
> I think your intention quite surely matched those and meant well, but
> removing something just because it's old is on its own IMO a bit of a
> red flag, so one should get too used to that argumentation style even
> if it's for removing comments, or other stuff that won't change semantics.

I completely agree with you, I probably should've stated a better reason
there. IIRC I removed those two things for a valid reason, but because
the commit was made a while ago, I'm not actually sure anymore what they
were exactly. I guess this proves your point. ;)

In a future RFC / Series, this will definitely be updated. Thanks for
pointing that out.

>
> Anyhow, do not let this demotivate you from your clean-up efforts, they
> are still quite appreciated.
> While removing dead code is good, the argumentation behind should be
> sound, and I only write this long tirade (sorry) as we got bitten by
> some innocent looking changes stemming from a similar argumentation in
> the past.

No worries, no offense taken here - I really appreciate comment.
Sometimes these things do need to be pointed out, because e.g. for me
personally it just wasn't on my radar that a commit like this could
become a tough to debug issue in case things go south. That's probably
because I've never had to deal with debugging such a thing myself.

So again, no worries, I appreciate it!



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



[pve-devel] [PATCH docs] qm: fix typo

2024-07-18 Thread Dominik Csapak
s/untis/units/

Signed-off-by: Dominik Csapak 
---
 qm.adoc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qm.adoc b/qm.adoc
index 8369492..5a65455 100644
--- a/qm.adoc
+++ b/qm.adoc
@@ -368,7 +368,7 @@ up to use more CPU time than just its virtual CPUs could 
use. To ensure that a
 VM never uses more CPU time than vCPUs assigned, set the *cpulimit* to
 the same value as the total core count.
 
-*cpuuntis*
+*cpuunits*
 
 With the *cpuunits* option, nowadays often called CPU shares or CPU weight, you
 can control how much CPU time a VM gets compared to other running VMs. It is a
-- 
2.39.2



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



[pve-devel] [PATCH proxmox-i18n] es: update translations

2024-07-18 Thread Maximiliano Sandoval
Signed-off-by: Maximiliano Sandoval 
---
 es.po | 98 +++
 1 file changed, 38 insertions(+), 60 deletions(-)

diff --git a/es.po b/es.po
index cd6de10..51c36cd 100644
--- a/es.po
+++ b/es.po
@@ -8,7 +8,7 @@ msgstr ""
 "Project-Id-Version: proxmox translations\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: Thu Jun 20 10:46:36 2024\n"
-"PO-Revision-Date: 2024-04-23 10:07+0200\n"
+"PO-Revision-Date: 2024-07-18 11:23+0200\n"
 "Last-Translator: Maximiliano Sandoval \n"
 "Language-Team: Spanish\n"
 "Language: es\n"
@@ -85,9 +85,8 @@ msgid "ACME Directory"
 msgstr "Directorio ACME"
 
 #: proxmox-backup/www/Utils.js:445
-#, fuzzy
 msgid "ACME certificate renewal"
-msgstr "Cadena de certificados"
+msgstr "Renovación del certificado ACME"
 
 #: pve-manager/www/manager6/qemu/Options.js:175
 #: pve-manager/www/manager6/qemu/Options.js:180
@@ -255,9 +254,8 @@ msgid "Active Directory Server"
 msgstr "Servidor de directorio activo"
 
 #: proxmox-backup/www/tape/ChangerStatus.js:856
-#, fuzzy
 msgid "Activity"
-msgstr "Activo"
+msgstr "Actividad"
 
 #: proxmox-widget-toolkit/src/Utils.js:642
 #: proxmox-widget-toolkit/src/node/APTRepositories.js:162
@@ -1283,9 +1281,8 @@ msgid "Busy"
 msgstr "Ocupado"
 
 #: proxmox-backup/www/tape/TapeInventory.js:331
-#, fuzzy
 msgid "Bytes Used"
-msgstr "Taza de entrada usada"
+msgstr "Bytes utilizados"
 
 #: pve-manager/www/manager6/window/GuestImport.js:931
 msgid ""
@@ -1384,9 +1381,8 @@ msgid "Cache"
 msgstr "Caché"
 
 #: proxmox-backup/www/Utils.js:710
-#, fuzzy
 msgid "Calibrating"
-msgstr "Migración"
+msgstr "Calibrando"
 
 #: pve-manager/www/manager6/form/TagEdit.js:348
 msgid "Cancel Edit"
@@ -1639,9 +1635,8 @@ msgid "Clean Drive"
 msgstr "Limpiar dispositivo"
 
 #: proxmox-backup/www/Utils.js:700
-#, fuzzy
 msgid "Cleaning"
-msgstr "Limpiar"
+msgstr "Limpiando"
 
 #: pve-manager/www/manager6/ceph/OSD.js:179
 #: pve-manager/www/manager6/window/SafeDestroyStorage.js:15
@@ -3141,7 +3136,7 @@ msgstr "Unidad"
 
 #: proxmox-backup/www/tape/DriveStatus.js:352
 msgid "Drive Activity"
-msgstr ""
+msgstr "Actividad de la unidad"
 
 #: proxmox-backup/www/tape/DriveConfig.js:168
 #: proxmox-backup/www/tape/window/DriveEdit.js:56
@@ -3276,6 +3271,8 @@ msgid ""
 "EXPERIMENTAL: Mode to detect file changes and archive encoding format for "
 "container backups."
 msgstr ""
+"EXPERIMENTAL: Modo de detección de cambios en archivos y formato de "
+"codificación de archivos para copias de seguridad de contenedores."
 
 #: proxmox-widget-toolkit/src/Utils.js:647
 #: proxmox-widget-toolkit/src/node/DNSView.js:49
@@ -3637,9 +3634,8 @@ msgid "Erase data"
 msgstr "Borrar datos"
 
 #: proxmox-backup/www/Utils.js:708
-#, fuzzy
 msgid "Erasing"
-msgstr "Borrar datos"
+msgstr "Borrando"
 
 #: proxmox-widget-toolkit/src/Utils.js:50
 #: proxmox-widget-toolkit/src/Utils.js:489
@@ -4016,9 +4012,8 @@ msgid "Field"
 msgstr "Campo"
 
 #: proxmox-backup/www/window/NotificationMatcherOverride.js:1046
-#, fuzzy
 msgid "Field Name"
-msgstr "Nombre del FS"
+msgstr "Nombre del campo"
 
 #: proxmox-widget-toolkit/src/node/Tasks.js:185
 msgid "Fields"
@@ -4285,9 +4280,8 @@ msgid "Format/Erase"
 msgstr "Formatear/Borrar"
 
 #: proxmox-backup/www/Utils.js:709
-#, fuzzy
 msgid "Formatting"
-msgstr "Formato"
+msgstr "Formateando"
 
 #: proxmox-widget-toolkit/src/Utils.js:685
 msgid "Forwarded mails to the local root user"
@@ -4401,12 +4395,10 @@ msgid "Garbage Collect"
 msgstr "Coleccionar basura"
 
 #: proxmox-backup/www/config/GCView.js:21
-#, fuzzy
 msgid "Garbage Collect Jobs"
-msgstr "Coleccionar basura"
+msgstr "Trabajos de colección de basura"
 
 #: proxmox-backup/www/window/GCJobEdit.js:10
-#, fuzzy
 msgid "Garbage Collect Schedule"
 msgstr "Cronograma de colección de basura"
 
@@ -4415,9 +4407,8 @@ msgid "Garbage Collection"
 msgstr "Colección de basura"
 
 #: proxmox-backup/www/Utils.js:446
-#, fuzzy
 msgid "Garbage collection"
-msgstr "Colecciones de basura"
+msgstr "Colección de basura"
 
 #: proxmox-backup/www/dashboard/TaskSummary.js:31
 msgid "Garbage collections"
@@ -5532,9 +5523,8 @@ msgid "Last Backup"
 msgstr "Último respaldos"
 
 #: proxmox-backup/www/config/GCView.js:171
-#, fuzzy
 msgid "Last GC"
-msgstr "Último"
+msgstr "Última colección de basura"
 
 #: pmg-gui/js/UserEdit.js:125 pve-manager/www/manager6/dc/UserEdit.js:88
 #: proxmox-backup/www/window/UserEdit.js:154
@@ -5550,9 +5540,8 @@ msgid "Last Prune"
 msgstr "Última podada"
 
 #: proxmox-backup/www/config/GCView.js:185
-#, fuzzy
 msgid "Last Status"
-msgstr "Configurar estado"
+msgstr "Último estado"
 
 #: pve-manager/www/manager6/grid/Replication.js:356
 #: proxmox-backup/www/config/SyncView.js:261
@@ -5715,9 +5704,8 @@ msgid "Local Store"
 msgstr "Almacenamiento local"
 
 #: proxmox-backup/www/Utils.js:706
-#, fuzzy
 msgid "Locating"
-msgstr "Ubicación"
+msgstr "Localizando"
 
 #: proxmox-backup/www/tape/TapeInventory.js:299
 #: proxmox-backup/www/window/SyncJobEdit.js:152
@@ -6790,7

[pve-devel] applied: [PATCH proxmox-i18n] es: update translations

2024-07-18 Thread Thomas Lamprecht
Am 18/07/2024 um 11:32 schrieb Maximiliano Sandoval:
> Signed-off-by: Maximiliano Sandoval 
> ---
>  es.po | 98 +++
>  1 file changed, 38 insertions(+), 60 deletions(-)
> 
>

applied, thanks!


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



[pve-devel] [PATCH installer v2 07/17] debian: strip unused library dependencies

2024-07-18 Thread Christoph Heiss
Rust links in some dynamic libraries even if only used by a disabled
feature gate.

This will be needed due to moving http-related code into the
proxmox-installer-common crate and thus pulling it in at more places.

Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * print libraries being stripped from each binary
---
 debian/control |  1 +
 debian/rules   | 13 +
 2 files changed, 14 insertions(+)

diff --git a/debian/control b/debian/control
index eb4d3be..b7ddc11 100644
--- a/debian/control
+++ b/debian/control
@@ -26,6 +26,7 @@ Build-Depends: cargo:native,
librust-toml-0.7-dev,
librust-ureq-2.6-dev,
libtest-mockmodule-perl,
+   patchelf,
perl,
rustc:native,
shellcheck,
diff --git a/debian/rules b/debian/rules
index 1c03065..3cebdff 100755
--- a/debian/rules
+++ b/debian/rules
@@ -10,3 +10,16 @@ export BUILD_MODE=release
 
 override_dh_missing:
dh_missing --fail-missing
+
+override_dh_strip:
+   dh_strip
+   for f in $$(find debian/proxmox-installer 
debian/proxmox-auto-install-assistant -executable -type f); do \
+ if file -bi "$$f" | grep -qP '^application'; then \
+   deps="$$(ldd -u "$$f" | grep -oP '[^/:]+$$')"; \
+   if [ ! -z "$$deps" ]; then \
+ printf "stripping unused dependencies from $$f: "; \
+ echo "$$deps" | tr '\n' ' '; echo; \
+ echo "$$deps" | sed 's/^/--remove-needed /g' | xargs patchelf 
"$$f"; \
+   fi \
+ fi; \
+   done
-- 
2.45.1



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



[pve-devel] [PATCH installer v2 06/17] common: setup: deserialize `secure_boot` property from runtime env

2024-07-18 Thread Christoph Heiss
Needed for the post-hook functionality, which sends this information as
part of its information set.

Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * new patch
---
 Proxmox/Install/RunEnv.pm |  1 +
 proxmox-installer-common/src/setup.rs | 12 
 2 files changed, 13 insertions(+)

diff --git a/Proxmox/Install/RunEnv.pm b/Proxmox/Install/RunEnv.pm
index 7eaf96a..bb60080 100644
--- a/Proxmox/Install/RunEnv.pm
+++ b/Proxmox/Install/RunEnv.pm
@@ -236,6 +236,7 @@ my sub detect_country_tracing_to : prototype($$) {
 # kernel_cmdline = ,
 # total_memory = ,
 # hvm_supported = <1 if the CPU supports hardware-accelerated 
virtualization>,
+# secure_boot = <1 if SecureBoot is enabled>,
 # boot_type = ,
 # disks => ,
 # network => {
diff --git a/proxmox-installer-common/src/setup.rs 
b/proxmox-installer-common/src/setup.rs
index ee3d0c9..2ca9641 100644
--- a/proxmox-installer-common/src/setup.rs
+++ b/proxmox-installer-common/src/setup.rs
@@ -236,6 +236,14 @@ where
 Ok(val != 0)
 }
 
+fn deserialize_bool_from_int_maybe<'de, D>(deserializer: D) -> 
Result, D::Error>
+where
+D: Deserializer<'de>,
+{
+let val: Option = Deserialize::deserialize(deserializer)?;
+Ok(val.map(|v| v != 0))
+}
+
 fn deserialize_cczones_map<'de, D>(
 deserializer: D,
 ) -> Result>, D::Error>
@@ -333,6 +341,10 @@ pub struct RuntimeInfo {
 /// Whether the CPU supports hardware-accelerated virtualization
 #[serde(deserialize_with = "deserialize_bool_from_int")]
 pub hvm_supported: bool,
+
+/// Whether the system was booted with SecureBoot enabled
+#[serde(default, deserialize_with = "deserialize_bool_from_int_maybe")]
+pub secure_boot: Option,
 }
 
 #[derive(Copy, Clone, Eq, Deserialize, PartialEq)]
-- 
2.45.1



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



[pve-devel] [PATCH installer v2 11/17] auto-installer: tests: replace manual panic!() with assert_eq!()

2024-07-18 Thread Christoph Heiss
Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * new patch, suggested by Stefan
---
 proxmox-auto-installer/tests/parse-answer.rs | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/proxmox-auto-installer/tests/parse-answer.rs 
b/proxmox-auto-installer/tests/parse-answer.rs
index 450915a..1fc515e 100644
--- a/proxmox-auto-installer/tests/parse-answer.rs
+++ b/proxmox-auto-installer/tests/parse-answer.rs
@@ -75,12 +75,8 @@ fn test_parse_answers() {
 path.push(format!("{name}.json"));
 let compare_raw = std::fs::read_to_string(&path).unwrap();
 let compare: Value = serde_json::from_str(&compare_raw).unwrap();
-if config != compare {
-panic!(
-"Test {} failed:\nleft:  {:#?}\nright: {:#?}\n",
-name, config, compare
-);
-}
+
+assert_eq!(config, compare);
 }
 }
 }
-- 
2.45.1



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



[pve-devel] [PATCH installer v2 15/17] fix #5536: auto-installer: answer: add `posthook` section

2024-07-18 Thread Christoph Heiss
Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * no changes
---
 proxmox-auto-installer/src/answer.rs | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/proxmox-auto-installer/src/answer.rs 
b/proxmox-auto-installer/src/answer.rs
index aab7198..e27a321 100644
--- a/proxmox-auto-installer/src/answer.rs
+++ b/proxmox-auto-installer/src/answer.rs
@@ -16,6 +16,8 @@ pub struct Answer {
 pub network: Network,
 #[serde(rename = "disk-setup")]
 pub disks: Disks,
+#[serde(default)]
+pub posthook: Option,
 }
 
 #[derive(Clone, Deserialize, Debug)]
@@ -33,6 +35,15 @@ pub struct Global {
 pub root_ssh_keys: Vec,
 }
 
+#[derive(Clone, Deserialize, Debug)]
+#[serde(deny_unknown_fields)]
+pub struct PostNotificationHookInfo {
+/// URL to send a POST request to
+pub url: String,
+/// SHA256 cert fingerprint if certificate pinning should be used.
+pub cert_fingerprint: Option,
+}
+
 #[derive(Clone, Deserialize, Debug, Default, PartialEq)]
 #[serde(deny_unknown_fields)]
 enum NetworkConfigMode {
-- 
2.45.1



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



[pve-devel] [PATCH installer v2 13/17] auto-installer: tests: replace `PathBuf` parameters with `AsRef`

2024-07-18 Thread Christoph Heiss
Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * new patch, suggested by Stefan
---
 proxmox-auto-installer/tests/parse-answer.rs | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/proxmox-auto-installer/tests/parse-answer.rs 
b/proxmox-auto-installer/tests/parse-answer.rs
index ff25a65..53ead8c 100644
--- a/proxmox-auto-installer/tests/parse-answer.rs
+++ b/proxmox-auto-installer/tests/parse-answer.rs
@@ -18,7 +18,7 @@ fn get_test_resource_path() -> Result {
 .join("tests/resources"))
 }
 
-fn get_answer(path: PathBuf) -> Result {
+fn get_answer(path: impl AsRef) -> Result {
 let answer_raw = std::fs::read_to_string(path).unwrap();
 let answer: answer::Answer = toml::from_str(&answer_raw)
 .map_err(|err| format!("error parsing answer.toml: {err}"))
@@ -27,11 +27,12 @@ fn get_answer(path: PathBuf) -> Result {
 Ok(answer)
 }
 
-pub fn setup_test_basic(path: &Path) -> (SetupInfo, LocaleInfo, RuntimeInfo, 
UdevInfo) {
-let (installer_info, locale_info, mut runtime_info) = 
load_installer_setup_files(path).unwrap();
+pub fn setup_test_basic(path: impl AsRef) -> (SetupInfo, LocaleInfo, 
RuntimeInfo, UdevInfo) {
+let (installer_info, locale_info, mut runtime_info) =
+load_installer_setup_files(&path).unwrap();
 
 let udev_info: UdevInfo = {
-let mut path = path.to_path_buf();
+let mut path = path.as_ref().to_path_buf();
 path.push("run-env-udev.json");
 
 read_json(&path)
-- 
2.45.1



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



[pve-devel] [PATCH installer v2 01/17] tree-wide: fix some typos

2024-07-18 Thread Christoph Heiss
Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * new patch
---
 proxmox-auto-install-assistant/src/main.rs  | 4 ++--
 proxmox-installer-common/src/disk_checks.rs | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/proxmox-auto-install-assistant/src/main.rs 
b/proxmox-auto-install-assistant/src/main.rs
index 1447175..c6f1ec8 100644
--- a/proxmox-auto-install-assistant/src/main.rs
+++ b/proxmox-auto-install-assistant/src/main.rs
@@ -55,7 +55,7 @@ struct CommandDeviceInfo {
 /// Filters support the following syntax:
 /// ?  Match a single character
 /// *  Match any number of characters
-/// [a], [0-9] Specifc character or range of characters
+/// [a], [0-9] Specific character or range of characters
 /// [!a]   Negate a specific character of range
 ///
 /// To avoid globbing characters being interpreted by the shell, use single 
quotes.
@@ -419,7 +419,7 @@ fn get_iso_uuid(iso: &PathBuf) -> Result {
 uuid = line
 .split(' ')
 .last()
-.ok_or_else(|| format_err!("xorriso did behave unexpextedly"))?
+.ok_or_else(|| format_err!("xorriso did behave unexpectedly"))?
 .replace('\'', "")
 .trim()
 .into();
diff --git a/proxmox-installer-common/src/disk_checks.rs 
b/proxmox-installer-common/src/disk_checks.rs
index 89b300c..ecc43bd 100644
--- a/proxmox-installer-common/src/disk_checks.rs
+++ b/proxmox-installer-common/src/disk_checks.rs
@@ -24,7 +24,7 @@ pub fn check_for_duplicate_disks(disks: &[Disk]) -> 
Result<(), &Disk> {
 ///
 /// # Arguments
 ///
-/// * `disks` - A list of disks to check the lenght of.
+/// * `disks` - A list of disks to check the length of.
 /// * `min` - Minimum number of disks
 pub fn check_raid_min_disks(disks: &[Disk], min: usize) -> Result<(), String> {
 if disks.len() < min {
-- 
2.45.1



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



[pve-devel] [PATCH installer v2 14/17] auto-installer: move `SystemDMI` struct to common crate

2024-07-18 Thread Christoph Heiss
This functionality will be reused by the post-hook, which sends this
data as part of its information set.

Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * new patch
---
 proxmox-auto-installer/src/sysinfo.rs   | 51 +---
 proxmox-installer-common/src/lib.rs |  1 +
 proxmox-installer-common/src/sysinfo.rs | 52 +
 3 files changed, 55 insertions(+), 49 deletions(-)
 create mode 100644 proxmox-installer-common/src/sysinfo.rs

diff --git a/proxmox-auto-installer/src/sysinfo.rs 
b/proxmox-auto-installer/src/sysinfo.rs
index 112e898..0a6aaf2 100644
--- a/proxmox-auto-installer/src/sysinfo.rs
+++ b/proxmox-auto-installer/src/sysinfo.rs
@@ -1,15 +1,14 @@
 use anyhow::{bail, Result};
 use proxmox_installer_common::{
 setup::{IsoInfo, ProductConfig, SetupInfo},
+sysinfo::SystemDMI,
 RUNTIME_DIR,
 };
 use serde::Serialize;
-use std::{collections::HashMap, fs, io, path::PathBuf};
+use std::{fs, io, path::PathBuf};
 
 use crate::utils::get_nic_list;
 
-const DMI_PATH: &str = "/sys/devices/virtual/dmi/id";
-
 #[derive(Debug, Serialize)]
 pub struct SysInfo {
 product: ProductConfig,
@@ -70,49 +69,3 @@ impl NetdevWithMac {
 Ok(result)
 }
 }
-
-#[derive(Debug, Serialize)]
-struct SystemDMI {
-system: HashMap,
-baseboard: HashMap,
-chassis: HashMap,
-}
-
-impl SystemDMI {
-pub(crate) fn get() -> Result {
-let system_files = [
-"product_serial",
-"product_sku",
-"product_uuid",
-"product_name",
-];
-let baseboard_files = ["board_asset_tag", "board_serial", 
"board_name"];
-let chassis_files = ["chassis_serial", "chassis_sku", 
"chassis_asset_tag"];
-
-Ok(Self {
-system: Self::get_dmi_infos(&system_files)?,
-baseboard: Self::get_dmi_infos(&baseboard_files)?,
-chassis: Self::get_dmi_infos(&chassis_files)?,
-})
-}
-
-fn get_dmi_infos(files: &[&str]) -> Result> {
-let mut res: HashMap = HashMap::new();
-
-for file in files {
-let path = format!("{DMI_PATH}/{file}");
-let content = match fs::read_to_string(&path) {
-Err(ref err) if err.kind() == std::io::ErrorKind::NotFound => 
continue,
-Err(ref err) if err.kind() == 
std::io::ErrorKind::PermissionDenied => {
-bail!("Could not read data. Are you running as root or 
with sudo?")
-}
-Err(err) => bail!("Error: '{err}' on '{path}'"),
-Ok(content) => content.trim().into(),
-};
-let key = file.splitn(2, '_').last().unwrap();
-res.insert(key.into(), content);
-}
-
-Ok(res)
-}
-}
diff --git a/proxmox-installer-common/src/lib.rs 
b/proxmox-installer-common/src/lib.rs
index ee9f2a8..59f1ab1 100644
--- a/proxmox-installer-common/src/lib.rs
+++ b/proxmox-installer-common/src/lib.rs
@@ -1,6 +1,7 @@
 pub mod disk_checks;
 pub mod options;
 pub mod setup;
+pub mod sysinfo;
 pub mod utils;
 
 #[cfg(feature = "http")]
diff --git a/proxmox-installer-common/src/sysinfo.rs 
b/proxmox-installer-common/src/sysinfo.rs
new file mode 100644
index 000..9746cb2
--- /dev/null
+++ b/proxmox-installer-common/src/sysinfo.rs
@@ -0,0 +1,52 @@
+use std::{collections::HashMap, fs};
+
+use anyhow::{bail, Result};
+use serde::Serialize;
+
+const DMI_PATH: &str = "/sys/devices/virtual/dmi/id";
+
+#[derive(Debug, Serialize)]
+pub struct SystemDMI {
+system: HashMap,
+baseboard: HashMap,
+chassis: HashMap,
+}
+
+impl SystemDMI {
+pub fn get() -> Result {
+let system_files = [
+"product_serial",
+"product_sku",
+"product_uuid",
+"product_name",
+];
+let baseboard_files = ["board_asset_tag", "board_serial", 
"board_name"];
+let chassis_files = ["chassis_serial", "chassis_sku", 
"chassis_asset_tag"];
+
+Ok(Self {
+system: Self::get_dmi_infos(&system_files)?,
+baseboard: Self::get_dmi_infos(&baseboard_files)?,
+chassis: Self::get_dmi_infos(&chassis_files)?,
+})
+}
+
+fn get_dmi_infos(files: &[&str]) -> Result> {
+let mut res: HashMap = HashMap::new();
+
+for file in files {
+let path = format!("{DMI_PATH}/{file}");
+let content = match fs::read_to_string(&path) {
+Err(ref err) if err.kind() == std::io::ErrorKind::NotFound => 
continue,
+Err(ref err) if err.kind() == 
std::io::ErrorKind::PermissionDenied => {
+bail!("Could not read data. Are you running as root or 
with sudo?")
+}
+Err(err) => bail!("Error: '{err}' on '{path}'"),
+Ok(content) => content.trim().into(),
+};
+let key = file.splitn(2, '_').last().unwrap();
+res.insert(key.into(), content);
+}
+

[pve-devel] [PATCH installer v2 04/17] common: setup: serialize `target_hd` as string explicitly

2024-07-18 Thread Christoph Heiss
Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * no changes
---
 proxmox-auto-installer/src/utils.rs   | 15 +++
 proxmox-installer-common/src/setup.rs | 23 ++-
 proxmox-tui-installer/src/setup.rs|  2 +-
 3 files changed, 14 insertions(+), 26 deletions(-)

diff --git a/proxmox-auto-installer/src/utils.rs 
b/proxmox-auto-installer/src/utils.rs
index cc47f5f..fefcac9 100644
--- a/proxmox-auto-installer/src/utils.rs
+++ b/proxmox-auto-installer/src/utils.rs
@@ -171,7 +171,7 @@ fn set_single_disk(
 .iter()
 .find(|item| item.path.ends_with(disk_name.as_str()));
 match disk {
-Some(disk) => config.target_hd = Some(disk.clone()),
+Some(disk) => config.target_hd = Some(disk.path.clone()),
 None => bail!("disk in 'disk_selection' not found"),
 }
 }
@@ -181,10 +181,10 @@ fn set_single_disk(
 .disks
 .iter()
 .find(|item| item.index == disk_index);
-config.target_hd = disk.cloned();
+config.target_hd = disk.map(|d| d.path.clone());
 }
 }
-info!("Selected disk: {}", config.target_hd.clone().unwrap().path);
+info!("Selected disk: {}", config.target_hd.clone().unwrap());
 Ok(())
 }
 
@@ -350,7 +350,14 @@ pub fn parse_answer(
 set_disks(answer, udev_info, runtime_info, &mut config)?;
 match &answer.disks.fs_options {
 answer::FsOptions::LVM(lvm) => {
-config.hdsize = 
lvm.hdsize.unwrap_or(config.target_hd.clone().unwrap().size);
+let disk = runtime_info
+.disks
+.iter()
+.find(|d| Some(&d.path) == config.target_hd.as_ref());
+
+config.hdsize = lvm
+.hdsize
+.unwrap_or_else(|| disk.map(|d| d.size).unwrap_or_default());
 config.swapsize = lvm.swapsize;
 config.maxroot = lvm.maxroot;
 config.maxvz = lvm.maxvz;
diff --git a/proxmox-installer-common/src/setup.rs 
b/proxmox-installer-common/src/setup.rs
index e0ac8d6..c0d701e 100644
--- a/proxmox-installer-common/src/setup.rs
+++ b/proxmox-installer-common/src/setup.rs
@@ -458,16 +458,8 @@ pub struct InstallConfig {
 #[serde(skip_serializing_if = "Option::is_none")]
 pub zfs_opts: Option,
 
-#[serde(
-serialize_with = "serialize_disk_opt",
-skip_serializing_if = "Option::is_none",
-// only the 'path' property is serialized -> deserialization is 
problematic
-// The information would be present in the 'run-env-info-json', but 
for now there is no
-// need for it in any code that deserializes the low-level config. 
Therefore we are
-// currently skipping it on deserialization
-skip_deserializing
-)]
-pub target_hd: Option,
+#[serde(skip_serializing_if = "Option::is_none")]
+pub target_hd: Option,
 #[serde(skip_serializing_if = "BTreeMap::is_empty")]
 pub disk_selection: BTreeMap,
 
@@ -491,14 +483,3 @@ pub struct InstallConfig {
 pub gateway: IpAddr,
 pub dns: IpAddr,
 }
-
-fn serialize_disk_opt(value: &Option, serializer: S) -> Result
-where
-S: Serializer,
-{
-if let Some(disk) = value {
-serializer.serialize_str(&disk.path)
-} else {
-serializer.serialize_none()
-}
-}
diff --git a/proxmox-tui-installer/src/setup.rs 
b/proxmox-tui-installer/src/setup.rs
index 02d9ece..033d642 100644
--- a/proxmox-tui-installer/src/setup.rs
+++ b/proxmox-tui-installer/src/setup.rs
@@ -42,7 +42,7 @@ impl From for InstallConfig {
 match &options.bootdisk.advanced {
 AdvancedBootdiskOptions::Lvm(lvm) => {
 config.hdsize = lvm.total_size;
-config.target_hd = Some(options.bootdisk.disks[0].clone());
+config.target_hd = 
Some(options.bootdisk.disks[0].path.clone());
 config.swapsize = lvm.swap_size;
 config.maxroot = lvm.max_root_size;
 config.minfree = lvm.min_lvm_free;
-- 
2.45.1



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



[pve-devel] [PATCH installer v2 05/17] common: split out installer setup files loading functionality

2024-07-18 Thread Christoph Heiss
This allows re-using this piece of code in e.g. the post hook, instead
of having to open-code it there.

No functional changes.

Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * change `&PathBuf` parameter to `impl AsRef`
---
 proxmox-auto-installer/tests/parse-answer.rs | 40 +---
 proxmox-installer-common/src/setup.rs| 13 +--
 2 files changed, 19 insertions(+), 34 deletions(-)

diff --git a/proxmox-auto-installer/tests/parse-answer.rs 
b/proxmox-auto-installer/tests/parse-answer.rs
index 4014b6d..450915a 100644
--- a/proxmox-auto-installer/tests/parse-answer.rs
+++ b/proxmox-auto-installer/tests/parse-answer.rs
@@ -1,4 +1,4 @@
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 
 use serde_json::Value;
 use std::fs;
@@ -8,13 +8,16 @@ use proxmox_auto_installer::answer::Answer;
 use proxmox_auto_installer::udevinfo::UdevInfo;
 use proxmox_auto_installer::utils::parse_answer;
 
-use proxmox_installer_common::setup::{read_json, LocaleInfo, RuntimeInfo, 
SetupInfo};
+use proxmox_installer_common::setup::{
+load_installer_setup_files, read_json, LocaleInfo, RuntimeInfo, SetupInfo,
+};
 
 fn get_test_resource_path() -> Result {
 Ok(std::env::current_dir()
 .expect("current dir failed")
 .join("tests/resources"))
 }
+
 fn get_answer(path: PathBuf) -> Result {
 let answer_raw = std::fs::read_to_string(path).unwrap();
 let answer: answer::Answer = toml::from_str(&answer_raw)
@@ -24,46 +27,23 @@ fn get_answer(path: PathBuf) -> Result {
 Ok(answer)
 }
 
-fn setup_test_basic(path: &PathBuf) -> (SetupInfo, LocaleInfo, RuntimeInfo, 
UdevInfo) {
-let installer_info: SetupInfo = {
-let mut path = path.clone();
-path.push("iso-info.json");
-
-read_json(&path)
-.map_err(|err| format!("Failed to retrieve setup info: {err}"))
-.unwrap()
-};
-
-let locale_info = {
-let mut path = path.clone();
-path.push("locales.json");
-
-read_json(&path)
-.map_err(|err| format!("Failed to retrieve locale info: {err}"))
-.unwrap()
-};
-
-let mut runtime_info: RuntimeInfo = {
-let mut path = path.clone();
-path.push("run-env-info.json");
-
-read_json(&path)
-.map_err(|err| format!("Failed to retrieve runtime environment 
info: {err}"))
-.unwrap()
-};
+pub fn setup_test_basic(path: &Path) -> (SetupInfo, LocaleInfo, RuntimeInfo, 
UdevInfo) {
+let (installer_info, locale_info, mut runtime_info) = 
load_installer_setup_files(path).unwrap();
 
 let udev_info: UdevInfo = {
-let mut path = path.clone();
+let mut path = path.to_path_buf();
 path.push("run-env-udev.json");
 
 read_json(&path)
 .map_err(|err| format!("Failed to retrieve udev info details: 
{err}"))
 .unwrap()
 };
+
 runtime_info.disks.sort();
 if runtime_info.disks.is_empty() {
 panic!("disk list is empty!");
 }
+
 (installer_info, locale_info, runtime_info, udev_info)
 }
 
diff --git a/proxmox-installer-common/src/setup.rs 
b/proxmox-installer-common/src/setup.rs
index c0d701e..ee3d0c9 100644
--- a/proxmox-installer-common/src/setup.rs
+++ b/proxmox-installer-common/src/setup.rs
@@ -163,24 +163,29 @@ pub fn installer_setup(in_test_mode: bool) -> 
Result<(SetupInfo, LocaleInfo, Run
 } else {
 crate::RUNTIME_DIR.to_owned()
 };
-let path = PathBuf::from(base_path);
 
+load_installer_setup_files(base_path)
+}
+
+pub fn load_installer_setup_files(
+base_path: impl AsRef,
+) -> Result<(SetupInfo, LocaleInfo, RuntimeInfo), String> {
 let installer_info: SetupInfo = {
-let mut path = path.clone();
+let mut path = base_path.as_ref().to_path_buf();
 path.push("iso-info.json");
 
 read_json(&path).map_err(|err| format!("Failed to retrieve setup info: 
{err}"))?
 };
 
 let locale_info = {
-let mut path = path.clone();
+let mut path = base_path.as_ref().to_path_buf();
 path.push("locales.json");
 
 read_json(&path).map_err(|err| format!("Failed to retrieve locale 
info: {err}"))?
 };
 
 let mut runtime_info: RuntimeInfo = {
-let mut path = path.clone();
+let mut path = base_path.as_ref().to_path_buf();
 path.push("run-env-info.json");
 
 read_json(&path)
-- 
2.45.1



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



[pve-devel] [PATCH installer v2 00/17] fix #5536: implement post-(auto-)installation notification mechanism

2024-07-18 Thread Christoph Heiss
This implements a mechanism for post-installation "notifications" via a
POST request [0] when using the auto-installer.

It's implemented as a separate, small utility to facilitate separation
of concerns and make the information gathering easier by having it
isolated in one place.

Patches #1 through #3 are simply clean-ups, refactors, etc. that were
done along the way and can be applied independently.

Most interesting here will be patch #16, which adds the actual
implementation of the post-hook. (Bind-)mounting the installed host
system is done using the existing `proxmox-chroot` utility, and the HTTP
POST functionality can fortunately be re-used 1:1 from
`proxmox-fetch-answer`.

I've also included an example of how the JSON body (pretty-printed and
reduced some things for readability) of such a post-installation request
would look like below, for reference. 
Where applicable (and sensible), I have tried to align the format as
much as possible with 1) the format as used in the `fetch-answer` POST
request and 2) PVE's /nodes//status API endpoint.

Feedback on the post-hook information schema is of course also very much
appreciated!

It should be noted that some information like DMI is generally very
depended on the motherboard/firmware, on what information is actually
available and filled-in. So the contents are expected to vary wildly
between machines and may also be empty, as in the example below from a
VM.

Tested this with both PVE and PBS ISOs, PMG did not (yet) have a
release with an auto-installation capable ISO. The only really
product-specific code is the version detection in `proxmox-post-hook`,
which already handles all three products.

[0] https://bugzilla.proxmox.com/show_bug.cgi?id=5536

previous revisions
--

v1: https://lists.proxmox.com/pipermail/pve-devel/2024-July/064580.html

Notable changes v1 -> v2:
  * dropped already applied patches & rebased on master
  * new fields; now includes ISO version, SecureBoot state, CPU and DMI 
info 
  * product information was split into separate fields & expanded
  * boot mode information was split into separate fields
  * product version is now retrieved from the package using dpkg-query 
directly
  * kernel version was split into separate fields
  * all disks and NICs are now included, a field indicates whether they
are boot disk or management interface, respectively
  * some new cleanup/refactoring patches as noted on v1 
(thanks Stefan for the in-depth review!)

post notification example json
--

{
  "debian-version": "12.5",
  "product": {
"fullname": "Proxmox VE",
"short": "pve",
"version": "8.2.2"
  },
  "iso": {
"release": "8.2",
"isorelease": "1"
  },
  "kernel-version": {
"sysname": "Linux",
"release": "6.8.4-2-pve",
"version": "#1 SMP PREEMPT_DYNAMIC PMX 6.8.4-2 (2024-04-10T17:36Z)",
"machine": "x86_64"
  },
  "boot-info": {
"mode": "efi",
"secureboot": true
  },
  "cpu-info": {
"cores": 4,
"cpus": 4,
"flags": "fpu vme [..]",
"hvm": true,
"model": "AMD Ryzen 7 3700X 8-Core Processor",
"sockets": 1
  },
  "dmi": {
"system": {
  "serial": "",
  "sku": "",
  "uuid": "b2fd1aa2-dc6e-4d8f-ad67-6dcc31984938",
  "name": "Standard PC (Q35 + ICH9, 2009)"
},
"baseboard": {},
"chassis": {
  "asset_tag": "",
  "serial": ""
}
  },
  "filesystem": "ext4",
  "fqdn": "host.domain",
  "machine-id": "b8737afea804482697ffe04db69c73d1",
  "disks": [
{
  "size": 8589934592,
  "is-bootdisk": true,
  "udev-properties": {
"DEVNAME": "/dev/vda",
[..]
  }
},
{
  "size": 8589934592,
  "udev-properties": {
"DEVNAME": "/dev/vdb",
[..]
  }
}
  ],
  "network-interfaces": [
{
  "mac": "de:ad:ff:c2:63:5e",
  "address": "10.0.0.27/24",
  "is-management": true,
  "udev-properties": {
"INTERFACE": "enp6s18",
[..]
  }
},
{
  "mac": "de:ad:ff:1c:c9:01",
  "udev-properties": {
"INTERFACE": "enp6s19",
[..]
  }
}
  ],
  "ssh-public-host-keys": {
"ecdsa": "ecdsa-sha2-nistp256 [..] root@host.domain",
"ed25519": "ssh-ed25519 [..] root@host.domain",
"rsa": "ssh-rsa [..] root@host.domain"
  }
}

git shortlog


Christoph Heiss (17):
  tree-wide: fix some typos
  fetch-answer: partition: fix clippy warning
  common: simplify filesystem type serializing & Display trait impl
  common: setup: serialize `target_hd` as string explicitly
  common: split out installer setup files loading functionality
  common: setup: deserialize `secure_boot` property from runtime env
  debian: strip unused library dependencies
  fetch-answer: move http-related code to gated module in
installer-common
  tree-wide: convert some more crates to use workspace dependencies
  auto-install-assistant: replace `PathBuf` parameters with
`AsRef`
  auto-installer: test

[pve-devel] [PATCH installer v2 12/17] auto-installer: tests: simplify empty disks check

2024-07-18 Thread Christoph Heiss
Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * new patch, suggested by Stefan
---
 proxmox-auto-installer/tests/parse-answer.rs | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/proxmox-auto-installer/tests/parse-answer.rs 
b/proxmox-auto-installer/tests/parse-answer.rs
index 1fc515e..ff25a65 100644
--- a/proxmox-auto-installer/tests/parse-answer.rs
+++ b/proxmox-auto-installer/tests/parse-answer.rs
@@ -40,9 +40,7 @@ pub fn setup_test_basic(path: &Path) -> (SetupInfo, 
LocaleInfo, RuntimeInfo, Ude
 };
 
 runtime_info.disks.sort();
-if runtime_info.disks.is_empty() {
-panic!("disk list is empty!");
-}
+assert!(!runtime_info.disks.is_empty(), "disk list cannot be empty");
 
 (installer_info, locale_info, runtime_info, udev_info)
 }
-- 
2.45.1



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



[pve-devel] [PATCH installer v2 03/17] common: simplify filesystem type serializing & Display trait impl

2024-07-18 Thread Christoph Heiss
Implements the proper de-/serializer directly on the type and then
use serde_plain::derive_display_from_serialize where applicable, instead
of separate serializer functions somewhere else.

Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * implement FromStr instead of Deserialize and use
serde_plain::derive_deserialize_from_fromstr!()

Signed-off-by: Christoph Heiss 
---
 proxmox-installer-common/Cargo.toml |   1 +
 proxmox-installer-common/src/options.rs | 116 +---
 proxmox-installer-common/src/setup.rs   |  59 +---
 3 files changed, 67 insertions(+), 109 deletions(-)

diff --git a/proxmox-installer-common/Cargo.toml 
b/proxmox-installer-common/Cargo.toml
index 70f828a..4b72041 100644
--- a/proxmox-installer-common/Cargo.toml
+++ b/proxmox-installer-common/Cargo.toml
@@ -11,3 +11,4 @@ homepage = "https://www.proxmox.com";
 regex = "1.7"
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
+serde_plain = "1.0"
diff --git a/proxmox-installer-common/src/options.rs 
b/proxmox-installer-common/src/options.rs
index e77914b..32c62a7 100644
--- a/proxmox-installer-common/src/options.rs
+++ b/proxmox-installer-common/src/options.rs
@@ -1,5 +1,6 @@
-use serde::Deserialize;
+use serde::{Deserialize, Serialize};
 use std::net::{IpAddr, Ipv4Addr};
+use std::str::FromStr;
 use std::{cmp, fmt};
 
 use crate::setup::{
@@ -7,55 +8,33 @@ use crate::setup::{
 };
 use crate::utils::{CidrAddress, Fqdn};
 
-#[derive(Copy, Clone, Debug, Deserialize, Eq, PartialEq)]
-#[serde(rename_all = "lowercase")]
+#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
+#[serde(rename_all(deserialize = "lowercase", serialize = "UPPERCASE"))]
 pub enum BtrfsRaidLevel {
 Raid0,
 Raid1,
 Raid10,
 }
 
-impl fmt::Display for BtrfsRaidLevel {
-fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-use BtrfsRaidLevel::*;
-match self {
-Raid0 => write!(f, "RAID0"),
-Raid1 => write!(f, "RAID1"),
-Raid10 => write!(f, "RAID10"),
-}
-}
-}
+serde_plain::derive_display_from_serialize!(BtrfsRaidLevel);
 
-#[derive(Copy, Clone, Debug, Deserialize, Eq, PartialEq)]
-#[serde(rename_all = "lowercase")]
+#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
+#[serde(rename_all(deserialize = "lowercase", serialize = "UPPERCASE"))]
 pub enum ZfsRaidLevel {
 Raid0,
 Raid1,
 Raid10,
-#[serde(rename = "raidz-1")]
+#[serde(rename = "RAIDZ-1")]
 RaidZ,
-#[serde(rename = "raidz-2")]
+#[serde(rename = "RAIDZ-2")]
 RaidZ2,
-#[serde(rename = "raidz-3")]
+#[serde(rename = "RAIDZ-3")]
 RaidZ3,
 }
 
-impl fmt::Display for ZfsRaidLevel {
-fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-use ZfsRaidLevel::*;
-match self {
-Raid0 => write!(f, "RAID0"),
-Raid1 => write!(f, "RAID1"),
-Raid10 => write!(f, "RAID10"),
-RaidZ => write!(f, "RAIDZ-1"),
-RaidZ2 => write!(f, "RAIDZ-2"),
-RaidZ3 => write!(f, "RAIDZ-3"),
-}
-}
-}
+serde_plain::derive_display_from_serialize!(ZfsRaidLevel);
 
-#[derive(Copy, Clone, Debug, Deserialize, Eq, PartialEq)]
-#[serde(rename_all = "lowercase")]
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum FsType {
 Ext4,
 Xfs,
@@ -71,16 +50,59 @@ impl FsType {
 
 impl fmt::Display for FsType {
 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-use FsType::*;
+// Values displayed to the user in the installer UI
 match self {
-Ext4 => write!(f, "ext4"),
-Xfs => write!(f, "XFS"),
-Zfs(level) => write!(f, "ZFS ({level})"),
-Btrfs(level) => write!(f, "Btrfs ({level})"),
+FsType::Ext4 => write!(f, "ext4"),
+FsType::Xfs => write!(f, "XFS"),
+FsType::Zfs(level) => write!(f, "ZFS ({level})"),
+FsType::Btrfs(level) => write!(f, "Btrfs ({level})"),
+}
+}
+}
+
+impl Serialize for FsType {
+fn serialize(&self, serializer: S) -> Result
+where
+S: serde::Serializer,
+{
+// These values must match exactly what the low-level installer expects
+let value = match self {
+// proxinstall::$fssetup
+FsType::Ext4 => "ext4",
+FsType::Xfs => "xfs",
+// proxinstall::get_zfs_raid_setup()
+FsType::Zfs(level) => &format!("zfs ({level})"),
+// proxinstall::get_btrfs_raid_setup()
+FsType::Btrfs(level) => &format!("btrfs ({level})"),
+};
+
+serializer.collect_str(value)
+}
+}
+
+impl FromStr for FsType {
+type Err = String;
+
+fn from_str(s: &str) -> Result {
+match s {
+"ext4" => Ok(FsType::Ext4),
+"xfs" => Ok(FsType::Xfs),
+"zfs (RAID0)" => Ok(FsType::Zfs(ZfsRaidLevel::Raid0)),
+"zfs (RAID1)" => Ok(FsType::Zfs(Zfs

[pve-devel] [PATCH installer v2 17/17] unconfigured.sh: run proxmox-post-hook after successful auto-install

2024-07-18 Thread Christoph Heiss
Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * no changes
---
 unconfigured.sh | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/unconfigured.sh b/unconfigured.sh
index a39e6ad..34951e7 100755
--- a/unconfigured.sh
+++ b/unconfigured.sh
@@ -253,7 +253,10 @@ elif [ $start_auto_installer -ne 0 ]; then
 debugsh || true
 fi
 echo "Starting automatic installation"
-/usr/bin/proxmox-auto-installer /dev/tty2 2>&1
@@ -262,7 +265,7 @@ fi
 # just to be sure everything is on disk
 sync
 
-if [ $proxdebug -ne 0 ]; then 
+if [ $proxdebug -ne 0 ]; then
 printf "\nDebug shell after installation exited (type exit or CTRL-D to 
reboot)\n"
 debugsh || true
 fi
-- 
2.45.1



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



[pve-devel] [PATCH installer v2 10/17] auto-install-assistant: replace `PathBuf` parameters with `AsRef`

2024-07-18 Thread Christoph Heiss
Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * new patch, suggestion by Stefan
---
 proxmox-auto-install-assistant/src/main.rs | 23 +-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/proxmox-auto-install-assistant/src/main.rs 
b/proxmox-auto-install-assistant/src/main.rs
index c6f1ec8..3cf42f6 100644
--- a/proxmox-auto-install-assistant/src/main.rs
+++ b/proxmox-auto-install-assistant/src/main.rs
@@ -5,7 +5,7 @@ use regex::Regex;
 use serde::Serialize;
 use std::{
 collections::BTreeMap,
-fs,
+fmt, fs,
 io::{self, Read},
 path::{Path, PathBuf},
 process::{Command, Stdio},
@@ -377,7 +377,12 @@ fn final_iso_location(args: &CommandPrepareISO) -> PathBuf 
{
 target.to_path_buf()
 }
 
-fn inject_file_to_iso(iso: &PathBuf, file: &PathBuf, location: &str, uuid: 
&String) -> Result<()> {
+fn inject_file_to_iso(
+iso: impl AsRef + fmt::Debug,
+file: &PathBuf,
+location: &str,
+uuid: &String,
+) -> Result<()> {
 let result = Command::new("xorriso")
 .arg("-boot_image")
 .arg("any")
@@ -386,7 +391,7 @@ fn inject_file_to_iso(iso: &PathBuf, file: &PathBuf, 
location: &str, uuid: &Stri
 .arg("uuid")
 .arg(uuid)
 .arg("-dev")
-.arg(iso)
+.arg(iso.as_ref())
 .arg("-map")
 .arg(file)
 .arg(location)
@@ -400,10 +405,10 @@ fn inject_file_to_iso(iso: &PathBuf, file: &PathBuf, 
location: &str, uuid: &Stri
 Ok(())
 }
 
-fn get_iso_uuid(iso: &PathBuf) -> Result {
+fn get_iso_uuid(iso: impl AsRef) -> Result {
 let result = Command::new("xorriso")
 .arg("-dev")
-.arg(iso)
+.arg(iso.as_ref())
 .arg("-report_system_area")
 .arg("cmd")
 .output()?;
@@ -530,11 +535,11 @@ fn get_nics() -> Result>> {
 Ok(nics)
 }
 
-fn get_udev_properties(path: &PathBuf) -> Result {
+fn get_udev_properties(path: impl AsRef + fmt::Debug) -> Result {
 let udev_output = Command::new("udevadm")
 .arg("info")
 .arg("--path")
-.arg(path)
+.arg(path.as_ref())
 .arg("--query")
 .arg("all")
 .output()?;
@@ -544,8 +549,8 @@ fn get_udev_properties(path: &PathBuf) -> Result {
 Ok(String::from_utf8(udev_output.stdout)?)
 }
 
-fn parse_answer(path: &PathBuf) -> Result {
-let mut file = match fs::File::open(path) {
+fn parse_answer(path: impl AsRef + fmt::Debug) -> Result {
+let mut file = match fs::File::open(&path) {
 Ok(file) => file,
 Err(err) => bail!("Opening answer file {path:?} failed: {err}"),
 };
-- 
2.45.1



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



[pve-devel] [PATCH installer v2 09/17] tree-wide: convert some more crates to use workspace dependencies

2024-07-18 Thread Christoph Heiss
No functional changes.

Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * no changes
---
 Cargo.toml|  4 
 proxmox-auto-install-assistant/Cargo.toml | 14 +++---
 proxmox-auto-installer/Cargo.toml | 15 +++
 proxmox-chroot/Cargo.toml |  8 
 proxmox-installer-common/Cargo.toml   |  7 +++
 proxmox-tui-installer/Cargo.toml  |  8 
 6 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 1dcf669..94a4dec 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,6 +12,10 @@ members = [
 [workspace.dependencies]
 anyhow = "1.0"
 log = "0.4.20"
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
+serde_plain = "1.0"
 toml = "0.7"
+regex = "1.7"
 proxmox-auto-installer.path = "./proxmox-auto-installer"
 proxmox-installer-common.path = "./proxmox-installer-common"
diff --git a/proxmox-auto-install-assistant/Cargo.toml 
b/proxmox-auto-install-assistant/Cargo.toml
index eaca7f8..1f46042 100644
--- a/proxmox-auto-install-assistant/Cargo.toml
+++ b/proxmox-auto-install-assistant/Cargo.toml
@@ -11,12 +11,12 @@ exclude = [ "build", "debian" ]
 homepage = "https://www.proxmox.com";
 
 [dependencies]
-anyhow = "1.0"
+anyhow.workspace = true
+log.workspace = true
+proxmox-auto-installer.workspace = true
+serde.workspace = true
+serde_json.workspace = true
+toml.workspace = true
+regex.workspace = true
 clap = { version = "4.0", features = ["derive"] }
 glob = "0.3"
-log = "0.4.20"
-proxmox-auto-installer = { path = "../proxmox-auto-installer" }
-regex = "1.7"
-serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0"
-toml = "0.7"
diff --git a/proxmox-auto-installer/Cargo.toml 
b/proxmox-auto-installer/Cargo.toml
index 4f54439..beec046 100644
--- a/proxmox-auto-installer/Cargo.toml
+++ b/proxmox-auto-installer/Cargo.toml
@@ -11,13 +11,12 @@ exclude = [ "build", "debian" ]
 homepage = "https://www.proxmox.com";
 
 [dependencies]
-anyhow = "1.0"
+anyhow.workspace = true
+log.workspace = true
+proxmox-installer-common.workspace = true
+serde.workspace = true
+serde_json.workspace = true
+serde_plain.workspace = true
+toml.workspace = true
 clap = { version = "4.0", features = ["derive"] }
 glob = "0.3"
-log = "0.4.20"
-proxmox-installer-common = { path = "../proxmox-installer-common" }
-regex = "1.7"
-serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0"
-serde_plain = "1.0"
-toml = "0.7"
diff --git a/proxmox-chroot/Cargo.toml b/proxmox-chroot/Cargo.toml
index 43b96ff..be5cc57 100644
--- a/proxmox-chroot/Cargo.toml
+++ b/proxmox-chroot/Cargo.toml
@@ -8,9 +8,9 @@ exclude = [ "build", "debian" ]
 homepage = "https://www.proxmox.com";
 
 [dependencies]
-anyhow = "1.0"
+anyhow.workspace = true
+proxmox-installer-common.workspace = true
+serde_json.workspace = true
+regex.workspace = true
 clap = { version = "4.0", features = ["derive"] }
 nix = "0.26.1"
-proxmox-installer-common = { path = "../proxmox-installer-common" }
-regex = "1.7"
-serde_json = "1.0"
diff --git a/proxmox-installer-common/Cargo.toml 
b/proxmox-installer-common/Cargo.toml
index d8e9e06..62a8622 100644
--- a/proxmox-installer-common/Cargo.toml
+++ b/proxmox-installer-common/Cargo.toml
@@ -8,10 +8,9 @@ exclude = [ "build", "debian" ]
 homepage = "https://www.proxmox.com";
 
 [dependencies]
-regex = "1.7"
-serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0"
-serde_plain = "1.0"
+serde.workspace = true
+serde_json.workspace = true
+serde_plain.workspace = true
 
 # `http` feature
 anyhow = { workspace = true, optional = true }
diff --git a/proxmox-tui-installer/Cargo.toml b/proxmox-tui-installer/Cargo.toml
index fc653f0..ed38875 100644
--- a/proxmox-tui-installer/Cargo.toml
+++ b/proxmox-tui-installer/Cargo.toml
@@ -8,8 +8,8 @@ exclude = [ "build", "debian" ]
 homepage = "https://www.proxmox.com";
 
 [dependencies]
+proxmox-installer-common.workspace = true
+serde.workspace = true
+serde_json.workspace = true
+regex.workspace = true
 cursive = { version = "0.20.0", default-features = false, features = 
["termion-backend"] }
-serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0"
-regex = "1.7"
-proxmox-installer-common = { path = "../proxmox-installer-common" }
-- 
2.45.1



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



[pve-devel] [PATCH installer v2 08/17] fetch-answer: move http-related code to gated module in installer-common

2024-07-18 Thread Christoph Heiss
This enable reusage of this code in other crates. Needed esp. by the
upcoming post-installation notification hook functionality.

No functional changes overall.

Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * no changes
---
 Cargo.toml|   6 ++
 proxmox-fetch-answer/Cargo.toml   |  17 +--
 .../src/fetch_plugins/http.rs | 100 +-
 proxmox-installer-common/Cargo.toml   |  20 
 proxmox-installer-common/src/http.rs  |  94 
 proxmox-installer-common/src/lib.rs   |   3 +
 6 files changed, 130 insertions(+), 110 deletions(-)
 create mode 100644 proxmox-installer-common/src/http.rs

diff --git a/Cargo.toml b/Cargo.toml
index 1e730ce..1dcf669 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,3 +9,9 @@ members = [
 "proxmox-tui-installer",
 ]
 
+[workspace.dependencies]
+anyhow = "1.0"
+log = "0.4.20"
+toml = "0.7"
+proxmox-auto-installer.path = "./proxmox-auto-installer"
+proxmox-installer-common.path = "./proxmox-installer-common"
diff --git a/proxmox-fetch-answer/Cargo.toml b/proxmox-fetch-answer/Cargo.toml
index 964682a..50f3da3 100644
--- a/proxmox-fetch-answer/Cargo.toml
+++ b/proxmox-fetch-answer/Cargo.toml
@@ -10,16 +10,9 @@ license = "AGPL-3"
 exclude = [ "build", "debian" ]
 homepage = "https://www.proxmox.com";
 
-# See more keys and their definitions at 
https://doc.rust-lang.org/cargo/reference/manifest.html
-
 [dependencies]
-anyhow = "1.0"
-hex = "0.4"
-log = "0.4.20"
-native-tls = "0.2"
-proxmox-auto-installer = { path = "../proxmox-auto-installer" }
-rustls = { version = "0.20", features = [ "dangerous_configuration" ] }
-rustls-native-certs = "0.6"
-sha2 = "0.10"
-toml = "0.7"
-ureq = { version = "2.6", features = [ "native-certs", "native-tls" ] }
+anyhow.workspace = true
+log.workspace = true
+proxmox-auto-installer.workspace = true
+proxmox-installer-common = { workspace = true, features = ["http"] }
+toml.workspace = true
diff --git a/proxmox-fetch-answer/src/fetch_plugins/http.rs 
b/proxmox-fetch-answer/src/fetch_plugins/http.rs
index 21bc6a2..a6a8de0 100644
--- a/proxmox-fetch-answer/src/fetch_plugins/http.rs
+++ b/proxmox-fetch-answer/src/fetch_plugins/http.rs
@@ -67,7 +67,8 @@ impl FetchFromHTTP {
 info!("Gathering system information.");
 let payload = SysInfo::as_json()?;
 info!("Sending POST request to '{answer_url}'.");
-let answer = http_post::call(answer_url, fingerprint.as_deref(), 
payload)?;
+let answer =
+proxmox_installer_common::http::post(answer_url, 
fingerprint.as_deref(), payload)?;
 Ok(answer)
 }
 
@@ -179,100 +180,3 @@ impl FetchFromHTTP {
 value.map(|value| String::from(&value[1..value.len() - 2]))
 }
 }
-
-mod http_post {
-use anyhow::Result;
-use rustls::ClientConfig;
-use sha2::{Digest, Sha256};
-use std::sync::Arc;
-use ureq::{Agent, AgentBuilder};
-
-/// Issues a POST request with the payload (JSON). Optionally a SHA256 
fingerprint can be used to
-/// check the cert against it, instead of the regular cert validation.
-/// To gather the sha256 fingerprint you can use the following command:
-/// ```no_compile
-/// openssl s_client -connect :443 < /dev/null 2>/dev/null | openssl 
x509 -fingerprint -sha256  -noout -in /dev/stdin
-/// ```
-///
-/// # Arguemnts
-/// * `url` - URL to call
-/// * `fingerprint` - SHA256 cert fingerprint if certificate pinning 
should be used. Optional.
-/// * `payload` - The payload to send to the server. Expected to be a JSON 
formatted string.
-pub fn call(url: String, fingerprint: Option<&str>, payload: String) -> 
Result {
-let answer;
-
-if let Some(fingerprint) = fingerprint {
-let tls_config = ClientConfig::builder()
-.with_safe_defaults()
-
.with_custom_certificate_verifier(VerifyCertFingerprint::new(fingerprint)?)
-.with_no_client_auth();
-
-let agent: Agent = 
AgentBuilder::new().tls_config(Arc::new(tls_config)).build();
-
-answer = agent
-.post(&url)
-.set("Content-type", "application/json; charset=utf-8")
-.send_string(&payload)?
-.into_string()?;
-} else {
-let mut roots = rustls::RootCertStore::empty();
-for cert in rustls_native_certs::load_native_certs()? {
-roots.add(&rustls::Certificate(cert.0)).unwrap();
-}
-
-let tls_config = rustls::ClientConfig::builder()
-.with_safe_defaults()
-.with_root_certificates(roots)
-.with_no_client_auth();
-
-let agent = AgentBuilder::new()
-.tls_connector(Arc::new(native_tls::TlsConnector::new()?))
-.tls_config(Arc::new(tls_config))
-.build();
-answer = agent
-  

[pve-devel] [PATCH installer v2 16/17] fix #5536: post-hook: add utility for sending notifications after auto-install

2024-07-18 Thread Christoph Heiss
This utility can be called with the low-level install config after a
successful installation to send a notification via a HTTP POST request,
if the user has configured an endpoint for that in the answer file.

Signed-off-by: Christoph Heiss 
---
Changes v1 -> v2:
  * squash implementation and unit tests into one patch
  * simplify udev property retrieving by introducing proper helpers on
`UdevInfo` itself
  * rename Answer::from_reader() -> Answer::try_from_reader to better
reflect it returns a Result<>
  * improved error message in some places
  * added new fields; now includes ISO version, SecureBoot state, CPU
and DMI info
  * product information was split into separate fields
  * boot mode information was split into separate fields
  * product version is now retrieved from the package using dpkg-query
directly
  * kernel version was split into separate fields, retrieving version
string from the image directly
  * all disks and NICs are now included, a field indicates whether they
are boot disk or management interface, respectively
  * move with_chroot() invocation out of PostHookInfo::gather()

Signed-off-by: Christoph Heiss 
---
 Cargo.toml|   1 +
 Makefile  |   8 +-
 debian/install|   1 +
 proxmox-auto-installer/src/answer.rs  |  16 +-
 .../src/bin/proxmox-auto-installer.rs |  13 +-
 proxmox-auto-installer/src/udevinfo.rs|   8 +-
 .../src/fetch_plugins/http.rs |   2 +-
 proxmox-installer-common/src/http.rs  |   6 +-
 proxmox-installer-common/src/options.rs   |   5 +
 proxmox-installer-common/src/setup.rs |   2 +-
 proxmox-installer-common/src/utils.rs |   2 +
 proxmox-post-hook/Cargo.toml  |  18 +
 proxmox-post-hook/src/main.rs | 784 ++
 13 files changed, 843 insertions(+), 23 deletions(-)
 create mode 100644 proxmox-post-hook/Cargo.toml
 create mode 100644 proxmox-post-hook/src/main.rs

diff --git a/Cargo.toml b/Cargo.toml
index 94a4dec..6d1e667 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,6 +7,7 @@ members = [
 "proxmox-fetch-answer",
 "proxmox-installer-common",
 "proxmox-tui-installer",
+"proxmox-post-hook",
 ]
 
 [workspace.dependencies]
diff --git a/Makefile b/Makefile
index e96a0f2..9dc4c22 100644
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,8 @@ USR_BIN := \
   proxmox-tui-installer\
   proxmox-fetch-answer\
   proxmox-auto-install-assistant \
-  proxmox-auto-installer
+  proxmox-auto-installer \
+  proxmox-post-hook
 
 COMPILED_BINS := \
$(addprefix $(CARGO_COMPILEDIR)/,$(USR_BIN))
@@ -59,6 +60,7 @@ $(BUILDDIR):
  proxmox-chroot \
  proxmox-tui-installer/ \
  proxmox-installer-common/ \
+ proxmox-post-hook \
  test/ \
  $(SHELL_SCRIPTS) \
  $@.tmp
@@ -132,7 +134,9 @@ cargo-build:
--package proxmox-auto-installer --bin proxmox-auto-installer \
--package proxmox-fetch-answer --bin proxmox-fetch-answer \
--package proxmox-auto-install-assistant --bin 
proxmox-auto-install-assistant \
-   --package proxmox-chroot --bin proxmox-chroot 
$(CARGO_BUILD_ARGS)
+   --package proxmox-chroot --bin proxmox-chroot \
+   --package proxmox-post-hook --bin proxmox-post-hook \
+   $(CARGO_BUILD_ARGS)
 
 %-banner.png: %-banner.svg
rsvg-convert -o $@ $<
diff --git a/debian/install b/debian/install
index bb91da7..b64c8ec 100644
--- a/debian/install
+++ b/debian/install
@@ -15,4 +15,5 @@ usr/bin/proxmox-chroot
 usr/bin/proxmox-fetch-answer
 usr/bin/proxmox-low-level-installer
 usr/bin/proxmox-tui-installer
+usr/bin/proxmox-post-hook
 var
diff --git a/proxmox-auto-installer/src/answer.rs 
b/proxmox-auto-installer/src/answer.rs
index e27a321..2670735 100644
--- a/proxmox-auto-installer/src/answer.rs
+++ b/proxmox-auto-installer/src/answer.rs
@@ -1,10 +1,11 @@
+use anyhow::{format_err, Result};
 use clap::ValueEnum;
 use proxmox_installer_common::{
 options::{BtrfsRaidLevel, FsType, ZfsChecksumOption, ZfsCompressOption, 
ZfsRaidLevel},
 utils::{CidrAddress, Fqdn},
 };
 use serde::{Deserialize, Serialize};
-use std::{collections::BTreeMap, net::IpAddr};
+use std::{collections::BTreeMap, io::BufRead, net::IpAddr};
 
 // BTreeMap is used to store filters as the order of the filters will be 
stable, compared to
 // storing them in a HashMap
@@ -20,6 +21,19 @@ pub struct Answer {
 pub posthook: Option,
 }
 
+impl Answer {
+pub fn try_from_reader(reader: impl BufRead) -> Result {
+let mut buffer = String::new();
+let lines = reader.lines();
+for line in lines {
+buffer.push_str(&line.unwrap());
+buffer.push('\n');
+}
+
+toml::from_str(&buffer).map_err(|err| format_err!("Failed 

Re: [pve-devel] [PATCH qemu-server] fix 4493: cloud-init: fix generated Windows config

2024-07-18 Thread Friedrich Weber
On 09/07/2024 17:12, Mira Limbeck wrote:
> cloudbase-init, a cloud-init reimplementation for Windows, supports only
> a subset of the configuration options of cloud-init. Some features
> depend on support by the Metadata Service (ConfigDrive2 here) and have
> further limitations [0].
> 
> To support a basic setup the following changes were made:
>  - password is saved as plaintext for any Windows guests (ostype)
>  - DNS servers are added to each of the interfaces
>  - SSH public keys are passed via metadata
> 
> Network and metadata generation for cloudbase-init is separate from the
> default ConfigDrive2 one so as to not interfere with any other OSes that
> depend on the current ConfigDrive2 implementation.

I tested the following:

- Install cloudbase-init beta in a Windows 2022 Server VM
- Shutdown VM
- Attach cloudinit drive, set network config
- Start VM
- After some time, Windows renames itself to the VM name and reboots
- Network config gets applied after some time (see below)

One thing I noticed: Without modifying the the standard in-guest
cloudbase-init configuration, it takes ~2min until cloudbase-init does
anything (in particular apply the network config). Apparently
cloudbase-init tries to find an HTTP server with the cloudinit data
first, and only looks into the configdrive after a timeout.

To avoid that, Mira suggested to change `metadata_services` [1] in the
cloudbase-init config to
`cloudbaseinit.metadata.services.configdrive.ConfigDriveService`.
Indeed, with this setting the network config gets applied immediately on
boot. It may be nice to add this to the documentation.

I'm not sure if the default behavior of changing the hostname to match
the VM name is something that Windows admins expect? Should the docs
mention more prominently how to disable this?

> There seems to be an issue with the network adapter. Whenever the guest
> is shutdown and started again it finds a new network adapter. Rebooting
> instead of shutting down doesn't show the same behavior.
> 
> I'm not sure yet why this happens, but it seems to be caused by
> cloudbase-init.

I couldn't reproduce this issue so far (using a virtio NIC).


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