From: Christoph Heiss <c.heiss@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH installer 5/6] tui: network: only display pinnable devices in pinning options dialog
Date: Thu, 13 Nov 2025 14:49:53 +0100 [thread overview]
Message-ID: <20251113135023.1038305-6-c.heiss@proxmox.com> (raw)
In-Reply-To: <20251113135023.1038305-1-c.heiss@proxmox.com>
Virtual devices such as e.g. bridges, bonds etc. otherwise also show up,
where name pinning does not make sense.
The `pinned_id` property has been made optional, thus adapt to that.
Not really an issue during bare-metal installations, as there aren't any
bridges/bonds set up yet - no changes there.
But it's a nice future-proofing and improves developing/testing
experience, as such interfaces are now suppressed).
Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
proxmox-installer-common/src/options.rs | 31 ++++++++++++--------
proxmox-installer-common/src/setup.rs | 33 +++++++++++++---------
proxmox-tui-installer/src/views/network.rs | 33 +++++++++++++++-------
3 files changed, 61 insertions(+), 36 deletions(-)
diff --git a/proxmox-installer-common/src/options.rs b/proxmox-installer-common/src/options.rs
index a07fe58..8f3b3aa 100644
--- a/proxmox-installer-common/src/options.rs
+++ b/proxmox-installer-common/src/options.rs
@@ -595,8 +595,10 @@ impl NetworkOptions {
{
// we got some ipv4 connectivity, so use that
- if let Some(opts) = pinning_opts {
- this.ifname.clone_from(&iface.to_pinned(opts).name);
+ if let Some(opts) = pinning_opts
+ && let Some(pinned) = iface.to_pinned(opts)
+ {
+ this.ifname.clone_from(&pinned.name);
} else {
this.ifname.clone_from(&iface.name);
}
@@ -609,8 +611,10 @@ impl NetworkOptions {
&& let Some(addr) = iface.addresses.iter().find(|addr| addr.is_ipv6())
{
// no ipv4, but ipv6 connectivity
- if let Some(opts) = pinning_opts {
- this.ifname.clone_from(&iface.to_pinned(opts).name);
+ if let Some(opts) = pinning_opts
+ && let Some(pinned) = iface.to_pinned(opts)
+ {
+ this.ifname.clone_from(&pinned.name);
} else {
this.ifname.clone_from(&iface.name);
}
@@ -627,19 +631,22 @@ impl NetworkOptions {
if this.ifname.is_empty()
&& let Some(iface) = network.interfaces.values().min_by_key(|v| v.index)
{
- if let Some(opts) = pinning_opts {
- this.ifname.clone_from(&iface.to_pinned(opts).name);
+ if let Some(opts) = pinning_opts
+ && let Some(pinned) = iface.to_pinned(opts)
+ {
+ this.ifname.clone_from(&pinned.name);
} else {
this.ifname.clone_from(&iface.name);
}
}
if let Some(ref mut opts) = this.pinning_opts {
- // Ensure that all unique interfaces indeed have an entry in the map,
- // as required by the low-level installer
+ // Ensure that all unique, pinnable interfaces indeed have an entry in the map, as
+ // required by the low-level installer
for iface in network.interfaces.values() {
- let pinned_name = iface.to_pinned(opts).name;
- opts.mapping.entry(iface.mac.clone()).or_insert(pinned_name);
+ if let Some(pinned) = iface.to_pinned(opts) {
+ opts.mapping.entry(iface.mac.clone()).or_insert(pinned.name);
+ }
}
}
@@ -767,7 +774,7 @@ mod tests {
Interface {
name: "eth0".to_owned(),
index: 0,
- pinned_id: "0".to_owned(),
+ pinned_id: Some("0".to_owned()),
state: InterfaceState::Up,
driver: "dummy".to_owned(),
mac: "01:23:45:67:89:ab".to_owned(),
@@ -901,7 +908,7 @@ mod tests {
Interface {
name: "eth0".to_owned(),
index: 0,
- pinned_id: "0".to_owned(),
+ pinned_id: Some("0".to_owned()),
state: InterfaceState::Up,
driver: "dummy".to_owned(),
mac: "01:23:45:67:89:ab".to_owned(),
diff --git a/proxmox-installer-common/src/setup.rs b/proxmox-installer-common/src/setup.rs
index c93ee30..35949f0 100644
--- a/proxmox-installer-common/src/setup.rs
+++ b/proxmox-installer-common/src/setup.rs
@@ -465,8 +465,9 @@ pub struct Interface {
pub index: usize,
- /// Sequential interface ID for pinning interface names.
- pub pinned_id: String,
+ /// Sequential interface ID for pinning interface names. If unset, the
+ /// interface name cannot/should not be pinned due to being e.g. a non-physical link.
+ pub pinned_id: Option<String>,
pub mac: String,
@@ -492,19 +493,23 @@ impl Interface {
)
}
- pub fn to_pinned(&self, options: &NetworkInterfacePinningOptions) -> Self {
- let mut this = self.clone();
- this.name = options
- .mapping
- .get(&this.mac)
- .unwrap_or(&format!(
- "{}{}",
- NetworkInterfacePinningOptions::DEFAULT_PREFIX,
- this.pinned_id
- ))
- .clone();
+ pub fn to_pinned(&self, options: &NetworkInterfacePinningOptions) -> Option<Self> {
+ if let Some(pinned_id) = &self.pinned_id {
+ let mut this = self.clone();
+ this.name = options
+ .mapping
+ .get(&this.mac)
+ .unwrap_or(&format!(
+ "{}{}",
+ NetworkInterfacePinningOptions::DEFAULT_PREFIX,
+ pinned_id
+ ))
+ .clone();
- this
+ Some(this)
+ } else {
+ None
+ }
}
}
diff --git a/proxmox-tui-installer/src/views/network.rs b/proxmox-tui-installer/src/views/network.rs
index 4388c7d..970c353 100644
--- a/proxmox-tui-installer/src/views/network.rs
+++ b/proxmox-tui-installer/src/views/network.rs
@@ -189,9 +189,12 @@ impl NetworkOptionsView {
.map(|opt| opt.pinning_enabled.then_some(opt.pinning_options.clone()))
.map_err(|err| err.to_string())?;
- let ifname = match &pinning_opts {
- Some(opts) => iface.to_pinned(opts).name,
- None => iface.name,
+ let ifname = if let Some(opts) = &pinning_opts
+ && let Some(pinned) = iface.to_pinned(opts)
+ {
+ pinned.name
+ } else {
+ iface.name
};
if address.addr().is_ipv4() != gateway.is_ipv4() {
@@ -291,13 +294,13 @@ impl NetworkOptionsView {
let ifnames = ifaces
.iter()
.map(|iface| {
- let iface = if options.pinning_enabled {
- &iface.to_pinned(&options.pinning_options)
+ if options.pinning_enabled
+ && let Some(pinned) = iface.to_pinned(&options.pinning_options)
+ {
+ (pinned.render(), pinned.clone())
} else {
- iface
- };
-
- (iface.render(), iface.clone())
+ (iface.render(), (*iface).clone())
+ }
})
.collect::<Vec<(String, Interface)>>();
@@ -337,6 +340,11 @@ impl InterfacePinningOptionsView {
fn new(interfaces: &[&Interface], options_ref: NetworkViewOptionsRef) -> Self {
let options = options_ref.lock().expect("unpoisoned lock");
+ // Filter out all non-physical links, as it does not make sense to pin their names
+ // in this way.
+ // The low-level installer will skip them anyway.
+ let interfaces = interfaces.iter().filter(|iface| iface.pinned_id.is_some());
+
let mut form = FormView::<String>::new();
for iface in interfaces {
@@ -349,7 +357,12 @@ impl InterfacePinningOptionsView {
.child(DummyView.full_width()) // right align below form elements
.child(
EditView::new()
- .content(iface.to_pinned(&options.pinning_options).name)
+ .content(
+ iface
+ .to_pinned(&options.pinning_options)
+ .expect("always pinnable interface")
+ .name,
+ )
.max_content_width(MAX_IFNAME_LEN)
.fixed_width(MAX_IFNAME_LEN),
);
--
2.51.0
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
next prev parent reply other threads:[~2025-11-13 13:50 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-13 13:49 [pve-devel] [PATCH installer 0/6] interface name pinning followups Christoph Heiss
2025-11-13 13:49 ` [pve-devel] [PATCH installer 1/6] sys: net: pinning: make interface name checks stricter Christoph Heiss
2025-11-13 13:49 ` [pve-devel] [PATCH installer 2/6] common: " Christoph Heiss
2025-11-13 13:49 ` [pve-devel] [PATCH installer 3/6] test: validate-link-pin-map: give all tests a name Christoph Heiss
2025-11-13 13:49 ` [pve-devel] [PATCH installer 4/6] gui: network: only display pinnable devices in pinning options dialog Christoph Heiss
2025-11-13 13:49 ` Christoph Heiss [this message]
2025-11-13 13:49 ` [pve-devel] [PATCH installer 6/6] tree-wide: run cargo fmt Christoph Heiss
2025-11-13 20:00 ` [pve-devel] applied: [PATCH installer 0/6] interface name pinning followups Thomas Lamprecht
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=20251113135023.1038305-6-c.heiss@proxmox.com \
--to=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.