all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Aaron Lauterer <a.lauterer@proxmox.com>
To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>,
	Christoph Heiss <c.heiss@proxmox.com>
Subject: Re: [pve-devel] [PATCH installer v2 16/17] fix #5536: post-hook: add utility for sending notifications after auto-install
Date: Wed, 24 Jul 2024 13:21:11 +0200	[thread overview]
Message-ID: <4050129c-55e5-4784-bcf7-ba176a04a14e@proxmox.com> (raw)
In-Reply-To: <20240718134905.1177775-17-c.heiss@proxmox.com>

Two few small things inline

On  2024-07-18  15:49, Christoph Heiss wrote:
> 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 <c.heiss@proxmox.com>
> ---
> 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 <c.heiss@proxmox.com>
> ---
>   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/proxmox-post-hook/Cargo.toml b/proxmox-post-hook/Cargo.toml
> new file mode 100644
> index 0000000..3acea6c
> --- /dev/null
> +++ b/proxmox-post-hook/Cargo.toml
> @@ -0,0 +1,18 @@
> +[package]
> +name = "proxmox-post-hook"
> +version = "0.1.0"
> +edition = "2021"
> +authors = [
> +    "Christoph Heiss <c.heiss@proxmox.com>",
> +    "Proxmox Support Team <support@proxmox.com>",
> +]
> +license = "AGPL-3"
> +exclude = [ "build", "debian" ]
> +homepage = "https://www.proxmox.com"
> +
> +[dependencies]
> +anyhow.workspace = true
> +proxmox-auto-installer.workspace = true
> +proxmox-installer-common = { workspace = true, features = ["http"] }
> +serde.workspace = true
> +serde_json.workspace = true
> diff --git a/proxmox-post-hook/src/main.rs b/proxmox-post-hook/src/main.rs
> new file mode 100644
> index 0000000..d3e5b5c
> --- /dev/null
> +++ b/proxmox-post-hook/src/main.rs
> @@ -0,0 +1,784 @@
> +//! Post installation hook for the Proxmox installer, mainly for combination
> +//! with the auto-installer.
> +//!
> +//! If a `[posthook]` section is specified in the given answer file, it will
> +//! send a HTTP POST request to that URL, with an optional certificate fingerprint
> +//! for usage with (self-signed) TLS certificates.
> +//! In the body of the request, information about the newly installed system is sent.
> +//!
> +//! Relies on `proxmox-chroot` as an external dependency to (bind-)mount the
> +//! previously installed system.
> +
> +use std::{
> +    collections::HashSet,
> +    ffi::CStr,
> +    fs::{self, File},
> +    io::BufReader,
> +    os::unix::fs::FileExt,
> +    path::PathBuf,
> +    process::{Command, ExitCode},
> +};
> +
> +use anyhow::{anyhow, bail, Context, Result};
> +use proxmox_auto_installer::{
> +    answer::{Answer, PostNotificationHookInfo},
> +    udevinfo::{UdevInfo, UdevProperties},
> +};
> +use proxmox_installer_common::{
> +    options::{Disk, FsType},
> +    setup::{
> +        load_installer_setup_files, BootType, InstallConfig, IsoInfo, ProxmoxProduct, RuntimeInfo,
> +        SetupInfo,
> +    },
> +    sysinfo::SystemDMI,
> +    utils::CidrAddress,
> +};
> +use serde::Serialize;
> +
> +/// Information about the system boot status.
> +#[derive(Serialize)]
> +struct BootInfo {
> +    /// Whether the system is booted using UEFI or legacy BIOS.
> +    mode: BootType,
> +    /// Whether SecureBoot is enabled for the installation.
> +    #[serde(skip_serializing_if = "Option::is_none")]
> +    secureboot: Option<bool>,
> +}
> +
> +/// Holds all the public keys for the different algorithms available.
> +#[derive(Serialize)]
> +struct SshPublicHostKeys {
> +    // ECDSA-based public host key
> +    ecdsa: String,
> +    // ED25519-based public host key
> +    ed25519: String,
> +    // RSA-based public host key
> +    rsa: String,
> +}
> +
> +/// A single disk configured as boot disk.
Is this comment valid this way? AFAIU there was a dedicated struct for 
boot disks in the previous version, but now this struct is for all 
disks, optionally marking it as boot disk.

> +#[derive(Serialize)]
> +#[serde(rename_all = "kebab-case")]
> +struct DiskInfo {
> +    /// Size in bytes
> +    size: usize,
> +    /// Set to true if the disk is used for booting.
> +    #[serde(skip_serializing_if = "Option::is_none")]
> +    is_bootdisk: Option<bool>,
> +    /// Properties about the device as given by udev.
> +    udev_properties: UdevProperties,
> +}
> +
> +/// Holds information about the management network interface.
> +#[derive(Serialize)]
> +#[serde(rename_all = "kebab-case")]
> +struct NetworkInterfaceInfo {
> +    /// MAC address of the interface
> +    mac: String,
> +    /// (Designated) IP address of the interface
> +    #[serde(skip_serializing_if = "Option::is_none")]
> +    address: Option<CidrAddress>,
> +    /// Set to true if the interface is the chosen management interface during
> +    /// installation.
> +    #[serde(skip_serializing_if = "Option::is_none")]
> +    is_management: Option<bool>,
> +    /// Properties about the device as given by udev.
> +    udev_properties: UdevProperties,
> +}
> +
> +/// Information about the installed product itself.
> +#[derive(Serialize)]
> +#[serde(rename_all = "kebab-case")]
> +struct ProductInfo {
> +    /// Full name of the product
> +    fullname: String,
> +    /// Product abbreviation
> +    short: ProxmoxProduct,
> +    /// Version of the installed product
> +    version: String,
> +}
> +
> +/// The current kernel version.
> +/// Aligns with the format as used by the /nodes/<node>/status API of each product.
> +#[derive(Serialize)]
> +struct KernelVersionInformation {
> +    /// The systemname/nodename
> +    pub sysname: String,
> +    /// The kernel release number
> +    pub release: String,
> +    /// The kernel version
> +    pub version: String,
> +    /// The machine architecture
> +    pub machine: String,
> +}
> +
> +/// Information about the CPU(s) installed in the system
> +#[derive(Serialize)]
> +struct CpuInfo {
> +    /// Number of physical CPU cores.
> +    cores: usize,
> +    /// Number of logical CPU cores aka. threads.
> +    cpus: usize,
> +    /// CPU feature flag set as a space-delimited list.
> +    flags: String,
> +    /// Whether hardware-accelerated virtualization is supported.
> +    hvm: bool,
> +    /// Reported model of the CPU(s)
> +    model: String,
> +    /// Number of physical CPU sockets
> +    sockets: usize,
> +}
> +
> +/// All data sent as request payload with the post-hook POST request.
> +#[derive(Serialize)]
> +#[serde(rename_all = "kebab-case")]
> +struct PostHookInfo {
> +    /// major.minor version of Debian as installed, retrieved from /etc/debian_version
> +    debian_version: String,
> +    /// PVE/PMG/PBS version as reported by `pveversion`, `pmgversion` or
> +    /// `proxmox-backup-manager version`, respectively.
> +    product: ProductInfo,
> +    /// Release information for the ISO used for the installation.
> +    iso: IsoInfo,
> +    /// Installed kernel version
> +    kernel_version: KernelVersionInformation,
> +    /// Describes the boot mode of the machine and the SecureBoot status.
> +    boot_info: BootInfo,
> +    /// Information about the installed CPU(s)
> +    cpu_info: CpuInfo,
> +    /// DMI information about the system
> +    dmi: SystemDMI,
> +    /// Filesystem used for boot disk(s)
> +    filesystem: FsType,
> +    /// Fully qualified domain name of the installed system
> +    fqdn: String,
> +    /// Unique systemd-id128 identifier of the installed system (128-bit, 16 bytes)
> +    machine_id: String,
> +    /// All disks detected on the system.
> +    disks: Vec<DiskInfo>,
> +    /// All network interfaces detected on the system.
> +    network_interfaces: Vec<NetworkInterfaceInfo>,
> +    /// Public parts of SSH host keys of the installed system
> +    ssh_public_host_keys: SshPublicHostKeys,
> +}
> +
> +/// Defines the size of a gibibyte in bytes.
> +const SIZE_GIB: usize = 1024 * 1024 * 1024;
> +
> +impl PostHookInfo {
> +    /// Gathers all needed information about the newly installed system for sending
> +    /// it to a specified server.
> +    ///
> +    /// # Arguments
> +    ///
> +    /// * `target_path` - Path to where the chroot environment root is mounted
> +    /// * `answer` - Answer file as provided by the user
> +    fn gather(target_path: &str, answer: &Answer) -> Result<Self> {
> +        println!("Gathering installed system data ..");
The three dots at the end can most likely be either 3 (or UTF-8 3-dots) 
or just one?
> +
> +        let config: InstallConfig =
> +            serde_json::from_reader(BufReader::new(File::open("/tmp/low-level-config.json")?))?;
> +
[…]


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

  parent reply	other threads:[~2024-07-24 11:20 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-18 13:48 [pve-devel] [PATCH installer v2 00/17] fix #5536: implement post-(auto-)installation notification mechanism Christoph Heiss
2024-07-18 13:48 ` [pve-devel] [PATCH installer v2 01/17] tree-wide: fix some typos Christoph Heiss
2024-07-18 13:48 ` [pve-devel] [PATCH installer v2 02/17] fetch-answer: partition: fix clippy warning Christoph Heiss
2024-07-18 13:48 ` [pve-devel] [PATCH installer v2 03/17] common: simplify filesystem type serializing & Display trait impl Christoph Heiss
2024-07-18 13:48 ` [pve-devel] [PATCH installer v2 04/17] common: setup: serialize `target_hd` as string explicitly Christoph Heiss
2024-07-18 13:48 ` [pve-devel] [PATCH installer v2 05/17] common: split out installer setup files loading functionality Christoph Heiss
2024-07-18 13:48 ` [pve-devel] [PATCH installer v2 06/17] common: setup: deserialize `secure_boot` property from runtime env Christoph Heiss
2024-07-23 14:31   ` Aaron Lauterer
2024-08-05 13:12     ` Christoph Heiss
2024-08-19 10:32     ` Christoph Heiss
2024-08-20 14:56       ` Christoph Heiss
2024-07-18 13:48 ` [pve-devel] [PATCH installer v2 07/17] debian: strip unused library dependencies Christoph Heiss
2024-07-18 13:48 ` [pve-devel] [PATCH installer v2 08/17] fetch-answer: move http-related code to gated module in installer-common Christoph Heiss
2024-07-18 13:48 ` [pve-devel] [PATCH installer v2 09/17] tree-wide: convert some more crates to use workspace dependencies Christoph Heiss
2024-07-18 13:48 ` [pve-devel] [PATCH installer v2 10/17] auto-install-assistant: replace `PathBuf` parameters with `AsRef<Path>` Christoph Heiss
2024-07-18 13:48 ` [pve-devel] [PATCH installer v2 11/17] auto-installer: tests: replace manual panic!() with assert_eq!() Christoph Heiss
2024-07-23 10:39   ` Aaron Lauterer
2024-07-23 10:40     ` Aaron Lauterer
2024-07-23 10:46     ` Christoph Heiss
2024-07-23 11:04       ` Aaron Lauterer
2024-07-23 11:37         ` Christoph Heiss
2024-07-24  7:54           ` Thomas Lamprecht
2024-07-18 13:48 ` [pve-devel] [PATCH installer v2 12/17] auto-installer: tests: simplify empty disks check Christoph Heiss
2024-07-18 13:48 ` [pve-devel] [PATCH installer v2 13/17] auto-installer: tests: replace `PathBuf` parameters with `AsRef<Path>` Christoph Heiss
2024-07-18 13:48 ` [pve-devel] [PATCH installer v2 14/17] auto-installer: move `SystemDMI` struct to common crate Christoph Heiss
2024-07-18 13:49 ` [pve-devel] [PATCH installer v2 15/17] fix #5536: auto-installer: answer: add `posthook` section Christoph Heiss
2024-07-18 13:49 ` [pve-devel] [PATCH installer v2 16/17] fix #5536: post-hook: add utility for sending notifications after auto-install Christoph Heiss
2024-07-23 14:57   ` Aaron Lauterer
2024-07-24  8:24     ` Thomas Lamprecht
2024-07-24 11:21   ` Aaron Lauterer [this message]
2024-08-05 13:17     ` Christoph Heiss
2024-07-18 13:49 ` [pve-devel] [PATCH installer v2 17/17] unconfigured.sh: run proxmox-post-hook after successful auto-install Christoph Heiss
2024-07-24 11:34 ` [pve-devel] [PATCH installer v2 00/17] fix #5536: implement post-(auto-)installation notification mechanism Aaron Lauterer
2024-08-21  9:41 ` Christoph Heiss

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=4050129c-55e5-4784-bcf7-ba176a04a14e@proxmox.com \
    --to=a.lauterer@proxmox.com \
    --cc=c.heiss@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 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