From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id AD9221FF13A for ; Wed, 27 May 2026 14:52:57 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 66DCA1C1F6; Wed, 27 May 2026 14:52:55 +0200 (CEST) From: Shannon Sterz To: pdm-devel@lists.proxmox.com Subject: [PATCH datacenter-manager 5/6] ui: auto-installer: load fingerprint and use it as initial value Date: Wed, 27 May 2026 14:52:16 +0200 Message-ID: <20260527125217.260760-6-s.sterz@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260527125217.260760-1-s.sterz@proxmox.com> References: <20260527125217.260760-1-s.sterz@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1779886313446 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.110 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record WEIRD_PORT 0.001 Uses non-standard port number for HTTP Message-ID-Hash: 2YJUMFDVJHD323C7GFUYAICMTN4TRQVG X-Message-ID-Hash: 2YJUMFDVJHD323C7GFUYAICMTN4TRQVG X-MailFrom: s.sterz@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Datacenter Manager development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: the answers and token panel now load the fingerprint when initialized and hand it over to dialogs that they spawn to add the fingerprint to the command presented to the user. Signed-off-by: Shannon Sterz --- .../prepared_answer_add_wizard.rs | 4 +-- .../auto_installer/prepared_answer_form.rs | 12 ++++++-- .../auto_installer/prepared_answers_panel.rs | 28 +++++++++++++++++-- ui/src/remotes/auto_installer/token_panel.rs | 19 +++++++++++++ 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/ui/src/remotes/auto_installer/prepared_answer_add_wizard.rs b/ui/src/remotes/auto_installer/prepared_answer_add_wizard.rs index e909b6e..03d78be 100644 --- a/ui/src/remotes/auto_installer/prepared_answer_add_wizard.rs +++ b/ui/src/remotes/auto_installer/prepared_answer_add_wizard.rs @@ -44,7 +44,7 @@ pub struct AddAnswerWizardProperties { } impl AddAnswerWizardProperties { - pub fn new() -> Self { + pub fn new(fingerprint: Option) -> Self { let mut template_counters = BTreeMap::new(); template_counters.insert("installation_nr".to_owned(), 0i32); @@ -79,8 +79,8 @@ impl AddAnswerWizardProperties { disk_filter: BTreeMap::new(), disk_filter_match: None, // post hook - post_hook_cert_fp: None, post_hook_base_url: pdm_origin(), + post_hook_cert_fp: fingerprint, // templating template_counters, // subscription diff --git a/ui/src/remotes/auto_installer/prepared_answer_form.rs b/ui/src/remotes/auto_installer/prepared_answer_form.rs index 44cfcc5..46867a2 100644 --- a/ui/src/remotes/auto_installer/prepared_answer_form.rs +++ b/ui/src/remotes/auto_installer/prepared_answer_form.rs @@ -974,6 +974,7 @@ pub fn render_show_secret_dialog( config_id: Option<&str>, token: &AnswerToken, secret: &str, + fingerprint: &Option, on_close: Callback<()>, ) -> Option { let token = format!("{}:{secret}", token.id); @@ -1009,10 +1010,17 @@ pub fn render_show_secret_dialog( "{}/api2/json/auto-install/answer", pdm_origin().unwrap_or_else(|| "https://pdm.example.com:8443".to_owned()) ); - let commandline = format!( - "proxmox-auto-install-assistant prepare-iso --fetch-from http --url {answer_url} --answer-auth-token {token} INPUT.iso", + + let mut commandline = format!( + "proxmox-auto-install-assistant prepare-iso --fetch-from http --url {answer_url} --answer-auth-token {token}", ); + if let Some(fingerprint) = fingerprint { + commandline = format!("{commandline} --cert-fingerprint {fingerprint}"); + } + + commandline = format!("{commandline} INPUT.iso"); + let copy_commandline_view = Container::new() .class("pwt-form-grid-col4") .with_child(FieldLabel::new(tr!("Command Line"))) diff --git a/ui/src/remotes/auto_installer/prepared_answers_panel.rs b/ui/src/remotes/auto_installer/prepared_answers_panel.rs index 0cff7fd..a55c029 100644 --- a/ui/src/remotes/auto_installer/prepared_answers_panel.rs +++ b/ui/src/remotes/auto_installer/prepared_answers_panel.rs @@ -66,6 +66,7 @@ enum Message { token: AnswerToken, secret: String, }, + FingerprintLoaded(Option), } struct PreparedAnswersPanelComponent { @@ -73,6 +74,7 @@ struct PreparedAnswersPanelComponent { selection: Selection, store: Store, columns: Rc>>, + fingerprint: Option, } pwt::impl_deref_mut_property!( @@ -94,12 +96,24 @@ impl LoadableComponent for PreparedAnswersPanelComponent { |a: &PreparedInstallationConfig, b: &PreparedInstallationConfig| a.id.cmp(&b.id), ); + let link = ctx.link().clone(); + ctx.link().spawn(async move { + link.send_message(Message::FingerprintLoaded( + pdm_client() + .certificate_info() + .await + .ok() + .and_then(|mut c| c.pop().and_then(|c| c.fingerprint)), + )); + }); + Self { state: LoadableComponentState::new(), selection: Selection::new() .on_select(ctx.link().callback(|_| Message::SelectionChange)), store, columns: Rc::new(columns()), + fingerprint: None, } } @@ -148,6 +162,10 @@ impl LoadableComponent for PreparedAnswersPanelComponent { })); false } + Message::FingerprintLoaded(fp) => { + self.fingerprint = fp; + false + } } } @@ -221,7 +239,7 @@ impl LoadableComponent for PreparedAnswersPanelComponent { match view_state { Self::ViewState::Create => Some( - AddAnswerWizardProperties::new() + AddAnswerWizardProperties::new(self.fingerprint.clone()) .on_submit_result(on_submit_result) .on_close(on_close) .into(), @@ -259,7 +277,13 @@ impl LoadableComponent for PreparedAnswersPanelComponent { config_id, token, secret, - } => render_show_secret_dialog(Some(config_id), token, secret, on_close), + } => render_show_secret_dialog( + Some(config_id), + token, + secret, + &self.fingerprint, + on_close, + ), } } } diff --git a/ui/src/remotes/auto_installer/token_panel.rs b/ui/src/remotes/auto_installer/token_panel.rs index d213f39..d5f1ff7 100644 --- a/ui/src/remotes/auto_installer/token_panel.rs +++ b/ui/src/remotes/auto_installer/token_panel.rs @@ -53,6 +53,7 @@ enum Message { SelectionChange, RemoveEntry, RegenerateSecret, + FingerprintLoaded(Option), } struct AuthTokenPanelComponent { @@ -60,6 +61,7 @@ struct AuthTokenPanelComponent { selection: Selection, store: Store, columns: Rc>>, + fingerprint: Option, } pwt::impl_deref_mut_property!( @@ -78,12 +80,24 @@ impl LoadableComponent for AuthTokenPanelComponent { Store::with_extract_key(|record: &AnswerToken| Key::from(record.id.to_string())); store.set_sorter(|a: &AnswerToken, b: &AnswerToken| a.id.cmp(&b.id)); + let link = ctx.link().clone(); + ctx.link().spawn(async move { + link.send_message(Message::FingerprintLoaded( + pdm_client() + .certificate_info() + .await + .ok() + .and_then(|mut c| c.pop().and_then(|c| c.fingerprint)), + )); + }); + Self { state: LoadableComponentState::new(), selection: Selection::new() .on_select(ctx.link().callback(|_| Message::SelectionChange)), store, columns: Rc::new(columns()), + fingerprint: None, } } @@ -142,6 +156,10 @@ impl LoadableComponent for AuthTokenPanelComponent { } false } + Message::FingerprintLoaded(fingerprint) => { + self.fingerprint = fingerprint; + false + } } } @@ -209,6 +227,7 @@ impl LoadableComponent for AuthTokenPanelComponent { None, token, secret, + &self.fingerprint, ctx.link().change_view_callback(|_| None), ), } -- 2.47.3