ifaces: Ignore interface even mentioned in port list

In old Python API, we ignore interfaces only depend on `interfaces`
section of desire state regardless it is mentioned in port list or not.

To be consistent, we changed the rust code to align with it.

Integration test case included.

Signed-off-by: Gris Ge <fge@redhat.com>
This commit is contained in:
Gris Ge 2022-08-06 20:38:57 +08:00 committed by Fernando Fernández Mancera
parent 8e122d436e
commit b1e5028d6e
3 changed files with 37 additions and 55 deletions

@ -724,7 +724,7 @@ fn mark_orphan_interface_as_absent(
// Special cases:
// * Inherit the ignore state from current if desire not mentioned in interface
// section and port section
// section
pub(crate) fn get_ignored_ifaces(
desired: &Interfaces,
current: &Interfaces,
@ -744,22 +744,8 @@ pub(crate) fn get_ignored_ifaces(
.map(|i| (i.name().to_string(), i.iface_type()))
.collect();
let mut desired_ports: HashSet<String> = HashSet::new();
for desire_iface in desired
.kernel_ifaces
.values()
.chain(desired.user_ifaces.values())
.filter(|i| !i.is_ignore() && i.is_controller())
{
if let Some(ports) = desire_iface.ports() {
desired_ports.extend(ports.iter().map(|p| p.to_string()));
}
}
for iface_name in current.ignored_kernel_iface_names().drain() {
if !desired_kernel_ifaces.contains(&iface_name)
&& !desired_ports.contains(&iface_name)
{
if !desired_kernel_ifaces.contains(&iface_name) {
ignored_kernel_ifaces.insert(iface_name);
}
}

@ -166,12 +166,6 @@ fn handle_changed_ports_of_iface(
(Option<String>, Option<InterfaceType>),
>,
) -> Result<(), NmstateError> {
include_ignored_iface_if_desired_in_port(
iface,
cur_ifaces,
pending_changes,
);
let desire_port_names = match iface.ports() {
Some(p) => HashSet::from_iter(p.iter().cloned()),
None => return Ok(()),
@ -213,38 +207,6 @@ fn handle_changed_ports_of_iface(
Ok(())
}
// When desire desire a port which is ignored in current, we should
// include this port also even it is already assigned to desired controller,
// so that it could change state from ignore to up.
fn include_ignored_iface_if_desired_in_port(
des_iface: &Interface,
cur_ifaces: &Interfaces,
pending_changes: &mut HashMap<
String,
(Option<String>, Option<InterfaceType>),
>,
) {
if let Some(ports) = des_iface.ports().or_else(|| {
cur_ifaces
.get_iface(des_iface.name(), des_iface.iface_type())
.and_then(|i| i.ports())
}) {
for port_name in ports {
if let Some(cur_iface) = cur_ifaces.kernel_ifaces.get(port_name) {
if cur_iface.is_ignore() {
pending_changes.insert(
port_name.to_string(),
(
Some(des_iface.name().to_string()),
Some(des_iface.iface_type()),
),
);
}
}
}
}
}
// TODO: user space interfaces
// Return True if we have all up_priority fixed.
pub(crate) fn set_ifaces_up_priority(ifaces: &mut Interfaces) -> bool {

@ -1,5 +1,5 @@
#
# Copyright (c) 2018-2021 Red Hat, Inc.
# Copyright (c) 2018-2022 Red Hat, Inc.
#
# This file is part of nmstate
#
@ -266,3 +266,37 @@ def test_linux_bridge_does_not_lose_unmanaged_port_on_rollback(
port_names = [port[LB.Port.NAME] for port in bridge_state[LB.PORT_SUBTREE]]
assert "eth1" in port_names
assert VETH0 in port_names
def test_ignore_interface_mentioned_in_port_list(
external_managed_bridge_with_unmanaged_ports, eth1_up
):
desired_state = {
Interface.KEY: [
{
Interface.NAME: BRIDGE0,
Interface.STATE: InterfaceState.UP,
Interface.TYPE: InterfaceType.LINUX_BRIDGE,
LB.CONFIG_SUBTREE: {
LB.PORT_SUBTREE: [
{LB.Port.NAME: DUMMY0},
{LB.Port.NAME: DUMMY1},
{LB.Port.NAME: "eth1"},
],
},
},
]
}
libnmstate.apply(desired_state)
assert (
"unmanaged"
in exec_cmd(
f"nmcli -g GENERAL.STATE d show {DUMMY0}".split(), check=True
)[1]
)
assert (
"unmanaged"
in exec_cmd(
f"nmcli -g GENERAL.STATE d show {DUMMY1}".split(), check=True
)[1]
)