import nmstate-1.1.0-3.el8
This commit is contained in:
parent
1bb48d27a3
commit
aaa1c8b9f1
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,2 @@
|
||||
SOURCES/nmstate-1.0.2.tar.gz
|
||||
SOURCES/nmstate-1.1.0.tar.gz
|
||||
SOURCES/nmstate.gpg
|
||||
|
@ -1,2 +1,2 @@
|
||||
eeda8a0238732e5dc37e2217ed6e316f76c93145 SOURCES/nmstate-1.0.2.tar.gz
|
||||
0b7795853d1f7735cb05817389f188884d1f6f09 SOURCES/nmstate-1.1.0.tar.gz
|
||||
b5f872551d434e2c62b30d70471efaeede83ab44 SOURCES/nmstate.gpg
|
||||
|
53
SOURCES/0001-nmstatectl-fix-long-arguments-support.patch
Normal file
53
SOURCES/0001-nmstatectl-fix-long-arguments-support.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From 99c7f643bab33a26c317e1b72ca3b8490cb1ea60 Mon Sep 17 00:00:00 2001
|
||||
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Date: Fri, 16 Jul 2021 08:57:27 +0200
|
||||
Subject: [PATCH 1/4] nmstatectl: fix long arguments support
|
||||
|
||||
The support for long arguments is broken. This patch is fixing it and
|
||||
solving the following errors:
|
||||
|
||||
```
|
||||
[root@d0b4a6a0f7a5 nmstate-workspace]# nmstatectl show --running-config
|
||||
usage: nmstatectl [-h] [--version]
|
||||
{commit,edit,rollback,set,apply,show,version,gc} ...
|
||||
nmstatectl: error: unrecognized arguments: --running-config
|
||||
[root@d0b4a6a0f7a5 nmstate-workspace]# nmstatectl show --show-secrets
|
||||
usage: nmstatectl [-h] [--version]
|
||||
{commit,edit,rollback,set,apply,show,version,gc} ...
|
||||
nmstatectl: error: unrecognized arguments: --show-secrets
|
||||
```
|
||||
|
||||
Integration test case added.
|
||||
|
||||
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
nmstatectl/nmstatectl.py | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/nmstatectl/nmstatectl.py b/nmstatectl/nmstatectl.py
|
||||
index a9f4cb6..6f83069 100644
|
||||
--- a/nmstatectl/nmstatectl.py
|
||||
+++ b/nmstatectl/nmstatectl.py
|
||||
@@ -223,14 +223,16 @@ def setup_subcommand_show(subparsers):
|
||||
dest="yaml",
|
||||
)
|
||||
parser_show.add_argument(
|
||||
- "-r, --running-config",
|
||||
+ "-r",
|
||||
+ "--running-config",
|
||||
help="Show running configurations",
|
||||
default=False,
|
||||
action="store_true",
|
||||
dest="running_config",
|
||||
)
|
||||
parser_show.add_argument(
|
||||
- "-s, --show-secrets",
|
||||
+ "-s",
|
||||
+ "--show-secrets",
|
||||
help="Show secrets also",
|
||||
default=False,
|
||||
action="store_true",
|
||||
--
|
||||
2.32.0
|
||||
|
@ -0,0 +1,105 @@
|
||||
From b1cb57d1dc4bba6592ba5cfc5c810a2ad19ac941 Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Thu, 22 Jul 2021 18:40:50 +0800
|
||||
Subject: [PATCH 2/4] nm ethtool: Preserve existing ethtool settings when
|
||||
undesired
|
||||
|
||||
When user does not define ethtool settings in desire state,
|
||||
we should preserve existing ethtool setting.
|
||||
|
||||
Integration test case included.
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
---
|
||||
libnmstate/nm/connection.py | 18 +++---------------
|
||||
libnmstate/nm/ethtool.py | 26 +++++++++++++++++++++++++-
|
||||
2 files changed, 28 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/libnmstate/nm/connection.py b/libnmstate/nm/connection.py
|
||||
index 5d60f6d..5a79c6f 100644
|
||||
--- a/libnmstate/nm/connection.py
|
||||
+++ b/libnmstate/nm/connection.py
|
||||
@@ -22,8 +22,6 @@
|
||||
import uuid
|
||||
|
||||
from libnmstate.error import NmstatePluginError
|
||||
-from libnmstate.ifaces import IfaceEthtool
|
||||
-from libnmstate.schema import Ethtool
|
||||
from libnmstate.schema import Interface
|
||||
from libnmstate.schema import InterfaceType
|
||||
from libnmstate.schema import LinuxBridge as LB
|
||||
@@ -240,19 +238,9 @@ def create_new_nm_simple_conn(iface, nm_profile):
|
||||
if iface.ieee_802_1x_conf:
|
||||
settings.append(create_802_1x_setting(iface.ieee_802_1x_conf))
|
||||
|
||||
- if Ethtool.CONFIG_SUBTREE in iface.original_desire_dict:
|
||||
- iface_ethtool = IfaceEthtool(
|
||||
- iface.original_desire_dict[Ethtool.CONFIG_SUBTREE]
|
||||
- )
|
||||
- iface_ethtool.canonicalize(
|
||||
- iface.original_desire_dict[Ethtool.CONFIG_SUBTREE]
|
||||
- )
|
||||
- setting = create_ethtool_setting(
|
||||
- iface_ethtool,
|
||||
- nm_profile,
|
||||
- )
|
||||
- if setting:
|
||||
- settings.append(setting)
|
||||
+ ethtool_setting = create_ethtool_setting(iface, nm_profile)
|
||||
+ if ethtool_setting:
|
||||
+ settings.append(ethtool_setting)
|
||||
|
||||
nm_simple_conn = NM.SimpleConnection.new()
|
||||
for setting in settings:
|
||||
diff --git a/libnmstate/nm/ethtool.py b/libnmstate/nm/ethtool.py
|
||||
index 466f4f9..3cad1bf 100644
|
||||
--- a/libnmstate/nm/ethtool.py
|
||||
+++ b/libnmstate/nm/ethtool.py
|
||||
@@ -22,6 +22,7 @@ import logging
|
||||
from .common import NM
|
||||
from .common import GLib
|
||||
|
||||
+from libnmstate.ifaces import IfaceEthtool
|
||||
from libnmstate.schema import Ethtool
|
||||
|
||||
|
||||
@@ -59,7 +60,7 @@ _NM_COALESCE_OPT_NAME_MAP = {
|
||||
}
|
||||
|
||||
|
||||
-def create_ethtool_setting(iface_ethtool, base_con_profile):
|
||||
+def _create_ethtool_setting(iface_ethtool, base_con_profile):
|
||||
nm_setting = None
|
||||
|
||||
if base_con_profile:
|
||||
@@ -159,3 +160,26 @@ def nm_set_pause(nm_setting, autoneg, rx, tx):
|
||||
tx_value,
|
||||
)
|
||||
# pylint: enable=no-member
|
||||
+
|
||||
+
|
||||
+def create_ethtool_setting(iface, base_con_profile):
|
||||
+ if Ethtool.CONFIG_SUBTREE in iface.original_desire_dict:
|
||||
+ iface_ethtool = IfaceEthtool(
|
||||
+ iface.original_desire_dict[Ethtool.CONFIG_SUBTREE]
|
||||
+ )
|
||||
+ iface_ethtool.canonicalize(
|
||||
+ iface.original_desire_dict[Ethtool.CONFIG_SUBTREE]
|
||||
+ )
|
||||
+ return _create_ethtool_setting(
|
||||
+ iface_ethtool,
|
||||
+ base_con_profile,
|
||||
+ )
|
||||
+ else:
|
||||
+ # Preserve existing setting but not create new
|
||||
+ if base_con_profile:
|
||||
+ ethtool_setting = base_con_profile.get_setting_by_name(
|
||||
+ NM.SETTING_ETHTOOL_SETTING_NAME
|
||||
+ )
|
||||
+ if ethtool_setting:
|
||||
+ return ethtool_setting.duplicate()
|
||||
+ return None
|
||||
--
|
||||
2.32.0
|
||||
|
@ -0,0 +1,87 @@
|
||||
From f4d190653c55d399b32afc956b2b4a1ff8d20101 Mon Sep 17 00:00:00 2001
|
||||
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Date: Mon, 26 Jul 2021 09:58:23 +0200
|
||||
Subject: [PATCH 3/4] ovs: fix state=ignore for ovs port when removing them
|
||||
|
||||
When removing an ovs port while the interface is marked as ignored, the
|
||||
interface should not being removed from the ovs bridge as the user
|
||||
specidied it should be ignored.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
interfaces:
|
||||
- name: dummy0
|
||||
type: dummy
|
||||
state: ignore
|
||||
- name: ovsbr0
|
||||
type: ovs-bridge
|
||||
state: up
|
||||
bridge:
|
||||
port:
|
||||
- name: ovs0
|
||||
```
|
||||
|
||||
Integration test case added.
|
||||
|
||||
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
libnmstate/nm/profiles.py | 22 ++++++++++++++++++++--
|
||||
1 file changed, 20 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libnmstate/nm/profiles.py b/libnmstate/nm/profiles.py
|
||||
index beda5c7..3b0b6be 100644
|
||||
--- a/libnmstate/nm/profiles.py
|
||||
+++ b/libnmstate/nm/profiles.py
|
||||
@@ -23,6 +23,8 @@
|
||||
import logging
|
||||
from operator import attrgetter
|
||||
|
||||
+from libnmstate.schema import Interface
|
||||
+from libnmstate.schema import InterfaceState
|
||||
from libnmstate.schema import InterfaceType
|
||||
|
||||
from .common import NM
|
||||
@@ -359,7 +361,7 @@ def _delete_orphan_nm_ovs_port_profiles(
|
||||
continue
|
||||
# When OVS port has no child, delete it
|
||||
ovs_bridge_iface = ovs_bridge_profile.iface
|
||||
- if not _nm_ovs_port_has_child(
|
||||
+ if not _nm_ovs_port_has_child_or_is_ignored(
|
||||
nm_profile, ovs_bridge_iface, net_state
|
||||
):
|
||||
ProfileDelete(
|
||||
@@ -404,7 +406,9 @@ def _use_uuid_as_controller_and_parent(nm_profiles):
|
||||
nm_profile.update_parent(uuid)
|
||||
|
||||
|
||||
-def _nm_ovs_port_has_child(nm_profile, ovs_bridge_iface, net_state):
|
||||
+def _nm_ovs_port_has_child_or_is_ignored(
|
||||
+ nm_profile, ovs_bridge_iface, net_state
|
||||
+):
|
||||
ovs_port_uuid = nm_profile.get_uuid()
|
||||
ovs_port_name = nm_profile.get_interface_name()
|
||||
for ovs_iface_name in ovs_bridge_iface.port:
|
||||
@@ -415,4 +419,18 @@ def _nm_ovs_port_has_child(nm_profile, ovs_bridge_iface, net_state):
|
||||
and ovs_iface.controller_type == InterfaceType.OVS_PORT
|
||||
):
|
||||
return True
|
||||
+ # Gather the ovs bridge interface from the current state in order to check
|
||||
+ # if any port is ignored in the original desired state.
|
||||
+ current_ovs_bridge = net_state.ifaces.get_cur_iface(
|
||||
+ ovs_bridge_iface.name, InterfaceType.OVS_BRIDGE
|
||||
+ )
|
||||
+ if current_ovs_bridge:
|
||||
+ for port_name in current_ovs_bridge.port:
|
||||
+ port_iface = net_state.ifaces.all_kernel_ifaces.get(port_name)
|
||||
+ if (
|
||||
+ port_iface
|
||||
+ and port_iface.original_desire_dict.get(Interface.STATE)
|
||||
+ == InterfaceState.IGNORE
|
||||
+ ):
|
||||
+ return True
|
||||
return False
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,7 +1,8 @@
|
||||
From ab55d90e31a121f1cb18d79582a8f4d2a138df91 Mon Sep 17 00:00:00 2001
|
||||
From 369ed3210ecedfa1deda88a6eb7cacc19a47f89d Mon Sep 17 00:00:00 2001
|
||||
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Date: Mon, 26 Jul 2021 16:13:15 +0200
|
||||
Subject: [PATCH] nispor: fix show of empty next_hop_address and destination
|
||||
Subject: [PATCH 4/4] nispor: fix show of empty next_hop_address and
|
||||
destination
|
||||
|
||||
The correct way of representing an empty next_hop_address is using
|
||||
"0.0.0.0" for IPv4 and "::" for IPv6. This configuration is valid
|
||||
@ -33,10 +34,10 @@ Integration test case added.
|
||||
Ref: https://bugzilla.redhat.com/1985879
|
||||
|
||||
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
libnmstate/nispor/route.py | 13 +++++++++----
|
||||
tests/integration/route_test.py | 30 +++++++++++++++++++++++++++++-
|
||||
2 files changed, 38 insertions(+), 5 deletions(-)
|
||||
libnmstate/nispor/route.py | 13 +++++++++----
|
||||
1 file changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libnmstate/nispor/route.py b/libnmstate/nispor/route.py
|
||||
index 510ddc3..9852ba5 100644
|
||||
@ -81,5 +82,5 @@ index 510ddc3..9852ba5 100644
|
||||
return {
|
||||
Route.TABLE_ID: np_rt.table,
|
||||
--
|
||||
2.31.1
|
||||
2.32.0
|
||||
|
@ -1,166 +0,0 @@
|
||||
From 80c97b27707b036f0a54988ade4bda3ccb342b34 Mon Sep 17 00:00:00 2001
|
||||
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Date: Mon, 22 Feb 2021 12:03:11 +0100
|
||||
Subject: [PATCH 1/2] SR-IOV: increase the verification timeout if SR-IOV is
|
||||
present
|
||||
|
||||
Certain drivers like i40e take a long time to modify the VFs in the
|
||||
kernel. Nmstate is timing out on verification because of that. In order
|
||||
to fix this, nmstate is incresing the verification time if SR-IOV is
|
||||
present on the desired state.
|
||||
|
||||
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
libnmstate/ifaces/ethernet.py | 6 ++++++
|
||||
libnmstate/netapplier.py | 18 +++++++++++++++++-
|
||||
2 files changed, 23 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libnmstate/ifaces/ethernet.py b/libnmstate/ifaces/ethernet.py
|
||||
index 292b7bc..ca8501b 100644
|
||||
--- a/libnmstate/ifaces/ethernet.py
|
||||
+++ b/libnmstate/ifaces/ethernet.py
|
||||
@@ -65,6 +65,12 @@ class EthernetIface(BaseIface):
|
||||
def is_peer(self):
|
||||
return self._is_peer
|
||||
|
||||
+ @property
|
||||
+ def is_sriov(self):
|
||||
+ return self.raw.get(Ethernet.CONFIG_SUBTREE, {}).get(
|
||||
+ Ethernet.SRIOV_SUBTREE
|
||||
+ )
|
||||
+
|
||||
def create_sriov_vf_ifaces(self):
|
||||
return [
|
||||
EthernetIface(
|
||||
diff --git a/libnmstate/netapplier.py b/libnmstate/netapplier.py
|
||||
index cf208d1..3c5759b 100644
|
||||
--- a/libnmstate/netapplier.py
|
||||
+++ b/libnmstate/netapplier.py
|
||||
@@ -24,6 +24,7 @@ import time
|
||||
|
||||
from libnmstate import validator
|
||||
from libnmstate.error import NmstateVerificationError
|
||||
+from libnmstate.schema import InterfaceType
|
||||
|
||||
from .nmstate import create_checkpoints
|
||||
from .nmstate import destroy_checkpoints
|
||||
@@ -37,6 +38,7 @@ from .version import get_version
|
||||
MAINLOOP_TIMEOUT = 35
|
||||
VERIFY_RETRY_INTERNAL = 1
|
||||
VERIFY_RETRY_TIMEOUT = 5
|
||||
+VERIFY_RETRY_TIMEOUT_INCREASE = 4
|
||||
|
||||
|
||||
def apply(
|
||||
@@ -109,7 +111,13 @@ def _apply_ifaces_state(plugins, net_state, verify_change, save_to_disk):
|
||||
plugin.apply_changes(net_state, save_to_disk)
|
||||
verified = False
|
||||
if verify_change:
|
||||
- for _ in range(VERIFY_RETRY_TIMEOUT):
|
||||
+ if _net_state_contains_sriov_interface(net_state):
|
||||
+ # If SR-IOV is present, the verification timeout is being increased
|
||||
+ # to avoid timeouts due to slow drivers like i40e.
|
||||
+ verify_retry = VERIFY_RETRY_TIMEOUT * VERIFY_RETRY_TIMEOUT_INCREASE
|
||||
+ else:
|
||||
+ verify_retry = VERIFY_RETRY_TIMEOUT
|
||||
+ for _ in range(verify_retry):
|
||||
try:
|
||||
_verify_change(plugins, net_state)
|
||||
verified = True
|
||||
@@ -120,6 +128,14 @@ def _apply_ifaces_state(plugins, net_state, verify_change, save_to_disk):
|
||||
_verify_change(plugins, net_state)
|
||||
|
||||
|
||||
+def _net_state_contains_sriov_interface(net_state):
|
||||
+ for iface in net_state.ifaces.all_kernel_ifaces.values():
|
||||
+ if iface.type == InterfaceType.ETHERNET and iface.is_sriov:
|
||||
+ return True
|
||||
+
|
||||
+ return False
|
||||
+
|
||||
+
|
||||
def _verify_change(plugins, net_state):
|
||||
current_state = show_with_plugins(plugins)
|
||||
net_state.verify(current_state)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
|
||||
From 439fe3a51a82060c5b62974c6c9fbdf403c4196b Mon Sep 17 00:00:00 2001
|
||||
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Date: Mon, 22 Feb 2021 13:33:06 +0100
|
||||
Subject: [PATCH 2/2] SR-IOV: fail on verification if `total_vfs` does not
|
||||
match vfs len
|
||||
|
||||
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
libnmstate/ifaces/ethernet.py | 11 +++++++++++
|
||||
libnmstate/ifaces/ifaces.py | 14 ++++++++++++++
|
||||
2 files changed, 25 insertions(+)
|
||||
|
||||
diff --git a/libnmstate/ifaces/ethernet.py b/libnmstate/ifaces/ethernet.py
|
||||
index ca8501b..55772ce 100644
|
||||
--- a/libnmstate/ifaces/ethernet.py
|
||||
+++ b/libnmstate/ifaces/ethernet.py
|
||||
@@ -61,6 +61,14 @@ class EthernetIface(BaseIface):
|
||||
.get(Ethernet.SRIOV.TOTAL_VFS, 0)
|
||||
)
|
||||
|
||||
+ @property
|
||||
+ def sriov_vfs(self):
|
||||
+ return (
|
||||
+ self.raw.get(Ethernet.CONFIG_SUBTREE, {})
|
||||
+ .get(Ethernet.SRIOV_SUBTREE, {})
|
||||
+ .get(Ethernet.SRIOV.VFS_SUBTREE, [])
|
||||
+ )
|
||||
+
|
||||
@property
|
||||
def is_peer(self):
|
||||
return self._is_peer
|
||||
@@ -108,6 +116,9 @@ class EthernetIface(BaseIface):
|
||||
for i in range(self.sriov_total_vfs, old_sriov_total_vfs)
|
||||
]
|
||||
|
||||
+ def check_total_vfs_matches_vf_list(self, total_vfs):
|
||||
+ return total_vfs == len(self.sriov_vfs)
|
||||
+
|
||||
|
||||
def _capitalize_sriov_vf_mac(state):
|
||||
vfs = (
|
||||
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
|
||||
index 44c9e61..6c94a98 100644
|
||||
--- a/libnmstate/ifaces/ifaces.py
|
||||
+++ b/libnmstate/ifaces/ifaces.py
|
||||
@@ -238,6 +238,8 @@ class Ifaces:
|
||||
if new_iface.name not in self._kernel_ifaces:
|
||||
new_iface.mark_as_desired()
|
||||
new_ifaces.append(new_iface)
|
||||
+ else:
|
||||
+ self._kernel_ifaces[new_iface.name].mark_as_desired()
|
||||
for new_iface in new_ifaces:
|
||||
self._kernel_ifaces[new_iface.name] = new_iface
|
||||
|
||||
@@ -656,6 +658,18 @@ class Ifaces:
|
||||
cur_iface.state_for_verify(),
|
||||
)
|
||||
)
|
||||
+ elif (
|
||||
+ iface.type == InterfaceType.ETHERNET and iface.is_sriov
|
||||
+ ):
|
||||
+ if not cur_iface.check_total_vfs_matches_vf_list(
|
||||
+ iface.sriov_total_vfs
|
||||
+ ):
|
||||
+ raise NmstateVerificationError(
|
||||
+ "The NIC exceeded the waiting time for "
|
||||
+ "verification and it is failing because "
|
||||
+ "the `total_vfs` does not match the VF "
|
||||
+ "list length."
|
||||
+ )
|
||||
|
||||
def gen_dns_metadata(self, dns_state, route_state):
|
||||
iface_metadata = dns_state.gen_metadata(self, route_state)
|
||||
--
|
||||
2.27.0
|
||||
|
@ -1,29 +0,0 @@
|
||||
From b26ab850172a41557cad42cc011bd00d7c108c88 Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Tue, 23 Feb 2021 13:52:19 +0800
|
||||
Subject: [PATCH] nmstatectl: Fix return code of set command
|
||||
|
||||
The deprecated command `set` should still return the error like
|
||||
old behaviour.
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
nmstatectl/nmstatectl.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/nmstatectl/nmstatectl.py b/nmstatectl/nmstatectl.py
|
||||
index df59942..c94d603 100644
|
||||
--- a/nmstatectl/nmstatectl.py
|
||||
+++ b/nmstatectl/nmstatectl.py
|
||||
@@ -323,7 +323,7 @@ def show(args):
|
||||
|
||||
def set(args):
|
||||
warnings.warn("Using 'set' is deprecated, use 'apply' instead.")
|
||||
- apply(args)
|
||||
+ return apply(args)
|
||||
|
||||
|
||||
def apply(args):
|
||||
--
|
||||
2.27.0
|
||||
|
@ -1,223 +0,0 @@
|
||||
From ccdcd8f86544a6364109a0c0142d05a5afacf64e Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Tue, 2 Mar 2021 15:31:20 +0800
|
||||
Subject: [PATCH] nm: Don't touch unmanaged interface unless desired
|
||||
|
||||
We should ignore NetworkManager unmanaged interface when applying and
|
||||
verifying unless certain interface listed in desired state explicitly.
|
||||
|
||||
Introduced new plugin interface
|
||||
`NmstatePlugin.get_ignored_kernel_interface_names()` where plugin may
|
||||
include a list of interface names which should be ignored during
|
||||
verification stage.
|
||||
|
||||
Integration test case added to simulate CNV usage on partial editing
|
||||
a linux bridge holding NM unmanaged interface.
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
libnmstate/ifaces/base_iface.py | 3 ++
|
||||
libnmstate/ifaces/ifaces.py | 26 ++++++++--------
|
||||
libnmstate/netapplier.py | 6 ++++
|
||||
libnmstate/nispor/plugin.py | 6 +++-
|
||||
libnmstate/nm/plugin.py | 25 ++++++++++++++++
|
||||
libnmstate/plugin.py | 7 +++++
|
||||
tests/integration/linux_bridge_test.py | 8 +----
|
||||
tests/integration/nm/linux_bridge_test.py | 36 ++++++++++++++++++++++-
|
||||
8 files changed, 95 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/libnmstate/ifaces/base_iface.py b/libnmstate/ifaces/base_iface.py
|
||||
index 227c1d20..e3f2a1ca 100644
|
||||
--- a/libnmstate/ifaces/base_iface.py
|
||||
+++ b/libnmstate/ifaces/base_iface.py
|
||||
@@ -322,6 +322,9 @@ class BaseIface:
|
||||
def mark_as_up(self):
|
||||
self.raw[Interface.STATE] = InterfaceState.UP
|
||||
|
||||
+ def mark_as_ignored(self):
|
||||
+ self.raw[Interface.STATE] = InterfaceState.IGNORE
|
||||
+
|
||||
@property
|
||||
def is_controller(self):
|
||||
return False
|
||||
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
|
||||
index 6c94a986..efa24aa3 100644
|
||||
--- a/libnmstate/ifaces/ifaces.py
|
||||
+++ b/libnmstate/ifaces/ifaces.py
|
||||
@@ -95,7 +95,6 @@ class Ifaces:
|
||||
self._kernel_ifaces = {}
|
||||
self._user_space_ifaces = _UserSpaceIfaces()
|
||||
self._cur_user_space_ifaces = _UserSpaceIfaces()
|
||||
- self._ignored_ifaces = set()
|
||||
if cur_iface_infos:
|
||||
for iface_info in cur_iface_infos:
|
||||
cur_iface = _to_specific_iface_obj(iface_info, save_to_disk)
|
||||
@@ -143,10 +142,6 @@ class Ifaces:
|
||||
):
|
||||
# Ignore interface with unknown type
|
||||
continue
|
||||
- if iface.is_ignore:
|
||||
- self._ignored_ifaces.add(
|
||||
- (iface.name, iface.type, iface.is_user_space_only)
|
||||
- )
|
||||
if cur_iface:
|
||||
iface.merge(cur_iface)
|
||||
iface.mark_as_desired()
|
||||
@@ -169,6 +164,10 @@ class Ifaces:
|
||||
|
||||
self._pre_edit_validation_and_cleanup()
|
||||
|
||||
+ @property
|
||||
+ def _ignored_ifaces(self):
|
||||
+ return [iface for iface in self.all_ifaces() if iface.is_ignore]
|
||||
+
|
||||
def _apply_copy_mac_from(self):
|
||||
for iface in self.all_kernel_ifaces.values():
|
||||
if iface.type not in (
|
||||
@@ -284,7 +283,7 @@ class Ifaces:
|
||||
if not defiend in desire state
|
||||
"""
|
||||
for iface in self.all_ifaces():
|
||||
- if iface.is_up and iface.is_controller:
|
||||
+ if iface.is_desired and iface.is_up and iface.is_controller:
|
||||
for port_name in iface.port:
|
||||
port_iface = self._kernel_ifaces[port_name]
|
||||
if not port_iface.is_desired and not port_iface.is_up:
|
||||
@@ -550,13 +549,14 @@ class Ifaces:
|
||||
return None
|
||||
|
||||
def _remove_iface(self, iface_name, iface_type):
|
||||
- cur_iface = self._cur_kernel_ifaces.get(iface_name, iface_type)
|
||||
+ cur_iface = self._user_space_ifaces.get(iface_name, iface_type)
|
||||
if cur_iface:
|
||||
self._user_space_ifaces.remove(cur_iface)
|
||||
else:
|
||||
cur_iface = self._kernel_ifaces.get(iface_name)
|
||||
if (
|
||||
- iface_type
|
||||
+ cur_iface
|
||||
+ and iface_type
|
||||
and iface_type != InterfaceType.UNKNOWN
|
||||
and iface_type == cur_iface.type
|
||||
):
|
||||
@@ -813,14 +813,14 @@ class Ifaces:
|
||||
port_controller_map[port_name] = iface.name
|
||||
|
||||
def _remove_ignore_interfaces(self, ignored_ifaces):
|
||||
- for iface_name, iface_type, _ in ignored_ifaces:
|
||||
- self._remove_iface(iface_name, iface_type)
|
||||
+ for iface in ignored_ifaces:
|
||||
+ self._remove_iface(iface.name, iface.type)
|
||||
|
||||
# Only kernel interface can be used as port
|
||||
ignored_kernel_iface_names = set(
|
||||
- iface_name
|
||||
- for iface_name, _, is_user_space_only in ignored_ifaces
|
||||
- if not is_user_space_only
|
||||
+ iface.name
|
||||
+ for iface in ignored_ifaces
|
||||
+ if not iface.is_user_space_only
|
||||
)
|
||||
|
||||
# Remove ignored port
|
||||
diff --git a/libnmstate/netapplier.py b/libnmstate/netapplier.py
|
||||
index 3c5759b4..a020f003 100644
|
||||
--- a/libnmstate/netapplier.py
|
||||
+++ b/libnmstate/netapplier.py
|
||||
@@ -107,8 +107,14 @@ def rollback(*, checkpoint=None):
|
||||
|
||||
|
||||
def _apply_ifaces_state(plugins, net_state, verify_change, save_to_disk):
|
||||
+ for plugin in plugins:
|
||||
+ for iface_name in plugin.get_ignored_kernel_interface_names():
|
||||
+ iface = net_state.ifaces.all_kernel_ifaces.get(iface_name)
|
||||
+ if iface and not iface.is_desired:
|
||||
+ iface.mark_as_ignored()
|
||||
for plugin in plugins:
|
||||
plugin.apply_changes(net_state, save_to_disk)
|
||||
+
|
||||
verified = False
|
||||
if verify_change:
|
||||
if _net_state_contains_sriov_interface(net_state):
|
||||
diff --git a/libnmstate/nispor/plugin.py b/libnmstate/nispor/plugin.py
|
||||
index dc0ea760..19b21d56 100644
|
||||
--- a/libnmstate/nispor/plugin.py
|
||||
+++ b/libnmstate/nispor/plugin.py
|
||||
@@ -159,7 +159,11 @@ class NisporPlugin(NmstatePlugin):
|
||||
np_state = NisporNetState.retrieve()
|
||||
logging.debug(f"Nispor: current network state {np_state}")
|
||||
for iface in net_state.ifaces.all_ifaces():
|
||||
- if iface.is_desired:
|
||||
+ if iface.is_ignore:
|
||||
+ logging.debug(
|
||||
+ f"Nispor: Interface {iface.name} {iface.type} ignored"
|
||||
+ )
|
||||
+ elif iface.is_desired:
|
||||
logging.debug(
|
||||
f"Nispor: desired network state {iface.to_dict()}"
|
||||
)
|
||||
diff --git a/libnmstate/nm/plugin.py b/libnmstate/nm/plugin.py
|
||||
index 302b4cca..335d93c7 100644
|
||||
--- a/libnmstate/nm/plugin.py
|
||||
+++ b/libnmstate/nm/plugin.py
|
||||
@@ -36,6 +36,7 @@ from .checkpoint import get_checkpoints
|
||||
from .common import NM
|
||||
from .context import NmContext
|
||||
from .device import get_device_common_info
|
||||
+from .device import get_iface_type
|
||||
from .device import list_devices
|
||||
from .dns import get_running as get_dns_running
|
||||
from .dns import get_running_config as get_dns_running_config
|
||||
@@ -268,6 +269,21 @@ class NetworkManagerPlugin(NmstatePlugin):
|
||||
)
|
||||
return NmProfiles(None).generate_config_strings(net_state)
|
||||
|
||||
+ def get_ignored_kernel_interface_names(self):
|
||||
+ """
|
||||
+ Return a list of unmanged kernel interface names.
|
||||
+ """
|
||||
+ ignored_ifaces = set()
|
||||
+ for nm_dev in list_devices(self.client):
|
||||
+ if (
|
||||
+ nm_dev
|
||||
+ and nm_dev.get_iface()
|
||||
+ and not nm_dev.get_managed()
|
||||
+ and _is_kernel_iface(nm_dev)
|
||||
+ ):
|
||||
+ ignored_ifaces.add(nm_dev.get_iface())
|
||||
+ return list(ignored_ifaces)
|
||||
+
|
||||
|
||||
def _remove_ovs_bridge_unsupported_entries(iface_info):
|
||||
"""
|
||||
@@ -283,3 +299,12 @@ def _remove_ovs_bridge_unsupported_entries(iface_info):
|
||||
|
||||
def _nm_utils_decode_version():
|
||||
return f"{NM.MAJOR_VERSION}.{NM.MINOR_VERSION}.{NM.MICRO_VERSION}"
|
||||
+
|
||||
+
|
||||
+def _is_kernel_iface(nm_dev):
|
||||
+ iface_type = get_iface_type(nm_dev)
|
||||
+ return iface_type != InterfaceType.UNKNOWN and iface_type not in (
|
||||
+ InterfaceType.OVS_BRIDGE,
|
||||
+ InterfaceType.OVS_INTERFACE,
|
||||
+ InterfaceType.OVS_PORT,
|
||||
+ )
|
||||
diff --git a/libnmstate/plugin.py b/libnmstate/plugin.py
|
||||
index ef3874ff..e1d9ad58 100644
|
||||
--- a/libnmstate/plugin.py
|
||||
+++ b/libnmstate/plugin.py
|
||||
@@ -128,3 +128,10 @@ class NmstatePlugin(metaclass=ABCMeta):
|
||||
persistently.
|
||||
"""
|
||||
return []
|
||||
+
|
||||
+ def get_ignored_kernel_interface_names(self):
|
||||
+ """
|
||||
+ Return a list of kernel interface names which should be ignored
|
||||
+ during verification stage.
|
||||
+ """
|
||||
+ return []
|
||||
--
|
||||
2.29.2
|
||||
|
@ -1,137 +0,0 @@
|
||||
From 95d77329b30c9a9a435a881941e27f9a1bed074e Mon Sep 17 00:00:00 2001
|
||||
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Date: Wed, 5 May 2021 10:14:40 +0200
|
||||
Subject: [PATCH 1/2] nm.profile: do not activate new interfaces twice
|
||||
|
||||
The current code is always adding the action MODIFIED if the interface
|
||||
is marked as up on the desired state. When a new interface is being
|
||||
added, Nmstate is adding two actions MODIFIED and NEW_*, that is
|
||||
incorrect.
|
||||
|
||||
This patch is improving the performance when creating new interfaces.
|
||||
|
||||
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
libnmstate/nm/profile.py | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libnmstate/nm/profile.py b/libnmstate/nm/profile.py
|
||||
index b4814d9..e117dfe 100644
|
||||
--- a/libnmstate/nm/profile.py
|
||||
+++ b/libnmstate/nm/profile.py
|
||||
@@ -164,7 +164,6 @@ class NmProfile:
|
||||
if self._iface.is_virtual and self._nm_dev:
|
||||
self._add_action(NmProfile.ACTION_DELETE_DEVICE)
|
||||
elif self._iface.is_up and not self._needs_veth_activation():
|
||||
- self._add_action(NmProfile.ACTION_MODIFIED)
|
||||
if not self._nm_dev:
|
||||
if self._iface.type == InterfaceType.OVS_PORT:
|
||||
self._add_action(NmProfile.ACTION_NEW_OVS_PORT)
|
||||
@@ -176,6 +175,8 @@ class NmProfile:
|
||||
self._add_action(NmProfile.ACTION_NEW_VXLAN)
|
||||
else:
|
||||
self._add_action(NmProfile.ACTION_NEW_IFACES)
|
||||
+ else:
|
||||
+ self._add_action(NmProfile.ACTION_MODIFIED)
|
||||
|
||||
elif self._iface.is_down:
|
||||
if self._nm_ac:
|
||||
--
|
||||
2.31.1
|
||||
|
||||
|
||||
From 9ea925a9a978671881e428abf82aac39c01376e8 Mon Sep 17 00:00:00 2001
|
||||
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Date: Wed, 5 May 2021 10:52:32 +0200
|
||||
Subject: [PATCH 2/2] nm.profile: activate modified ovs-port first
|
||||
|
||||
When removing an ovs-br with an ovs-iface attached and creating a new
|
||||
ovs-br with the ovs-iface attached in the same transaction the order of
|
||||
the activations is important.
|
||||
|
||||
The ovs-port must be activated before the ovs-iface. If not, NM will
|
||||
throw a dependency error. This error is correct because the ovs-iface
|
||||
depends on the ovs-port, so it must be updated first.
|
||||
|
||||
This fixes:
|
||||
|
||||
```
|
||||
Traceback (most recent call last):
|
||||
File "/usr/lib/python3.6/site-packages/libnmstate/nm/checkpoint.py", line 93, in _refresh_checkpoint_timeout
|
||||
self._dbuspath, self._timeout, cancellable, cb, cb_data
|
||||
TypeError: Argument 1 does not allow None as a value
|
||||
^CTraceback (most recent call last):
|
||||
File "/usr/lib/python3.6/site-packages/libnmstate/nmstate.py", line 53, in plugin_context
|
||||
yield plugins
|
||||
File "/usr/lib/python3.6/site-packages/libnmstate/netapplier.py", line 78, in apply
|
||||
_apply_ifaces_state(plugins, net_state, verify_change, save_to_disk)
|
||||
File "/usr/lib/python3.6/site-packages/libnmstate/netapplier.py", line 116, in _apply_ifaces_state
|
||||
plugin.apply_changes(net_state, save_to_disk)
|
||||
File "/usr/lib/python3.6/site-packages/libnmstate/nm/plugin.py", line 204, in apply_changes
|
||||
NmProfiles(self.context).apply_config(net_state, save_to_disk)
|
||||
File "/usr/lib/python3.6/site-packages/libnmstate/nm/profiles.py", line 89, in apply_config
|
||||
self._ctx.wait_all_finish()
|
||||
File "/usr/lib/python3.6/site-packages/libnmstate/nm/context.py", line 213, in wait_all_finish
|
||||
raise tmp_error
|
||||
libnmstate.error.NmstateLibnmError: Activate profile uuid:3a359cd0-d68a-4c7a-ae50-f97b47390142 iface:net type: ovs-interface failed: reason=<enum NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED of type NM.ActiveConnectionStateReason> <enum NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED of type NM.DeviceStateReason>
|
||||
```
|
||||
|
||||
Integration test added
|
||||
|
||||
Ref: https://bugzilla.redhat.com/1947287
|
||||
|
||||
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
libnmstate/nm/profile.py | 13 ++++++++++++-
|
||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libnmstate/nm/profile.py b/libnmstate/nm/profile.py
|
||||
index e117dfe..b655885 100644
|
||||
--- a/libnmstate/nm/profile.py
|
||||
+++ b/libnmstate/nm/profile.py
|
||||
@@ -69,6 +69,8 @@ class NmProfile:
|
||||
ACTION_OTHER_MASTER = "other_master"
|
||||
ACTION_DELETE_PROFILE = "delete_profile"
|
||||
ACTION_TOP_MASTER = "top_master"
|
||||
+ ACTION_MODIFIED_OVS_PORT = "modified_ovs_port"
|
||||
+ ACTION_MODIFIED_OVS_IFACE = "modified_ovs_iface"
|
||||
|
||||
# This is order on group for activation/deactivation
|
||||
ACTIONS = (
|
||||
@@ -81,6 +83,8 @@ class NmProfile:
|
||||
ACTION_NEW_OVS_IFACE,
|
||||
ACTION_NEW_VETH,
|
||||
ACTION_NEW_VETH_PEER,
|
||||
+ ACTION_MODIFIED_OVS_PORT,
|
||||
+ ACTION_MODIFIED_OVS_IFACE,
|
||||
ACTION_MODIFIED,
|
||||
ACTION_NEW_VLAN,
|
||||
ACTION_NEW_VXLAN,
|
||||
@@ -176,7 +180,12 @@ class NmProfile:
|
||||
else:
|
||||
self._add_action(NmProfile.ACTION_NEW_IFACES)
|
||||
else:
|
||||
- self._add_action(NmProfile.ACTION_MODIFIED)
|
||||
+ if self._iface.type == InterfaceType.OVS_PORT:
|
||||
+ self._add_action(NmProfile.ACTION_MODIFIED_OVS_PORT)
|
||||
+ if self._iface.type == InterfaceType.OVS_INTERFACE:
|
||||
+ self._add_action(NmProfile.ACTION_MODIFIED_OVS_IFACE)
|
||||
+ else:
|
||||
+ self._add_action(NmProfile.ACTION_MODIFIED)
|
||||
|
||||
elif self._iface.is_down:
|
||||
if self._nm_ac:
|
||||
@@ -420,6 +429,8 @@ class NmProfile:
|
||||
def do_action(self, action):
|
||||
if action in (
|
||||
NmProfile.ACTION_MODIFIED,
|
||||
+ NmProfile.ACTION_MODIFIED_OVS_PORT,
|
||||
+ NmProfile.ACTION_MODIFIED_OVS_IFACE,
|
||||
NmProfile.ACTION_ACTIVATE_FIRST,
|
||||
NmProfile.ACTION_TOP_MASTER,
|
||||
NmProfile.ACTION_NEW_IFACES,
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,163 +0,0 @@
|
||||
From 72edab395316ba1ae69ea4d788b0572c935759ac Mon Sep 17 00:00:00 2001
|
||||
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Date: Tue, 27 Apr 2021 10:19:02 +0200
|
||||
Subject: [PATCH] net_state: mark ifaces as ignored earlier
|
||||
|
||||
Nmstate is not touching unmanaged interfaces if they are not being
|
||||
included in the desired state. If an unmanaged interface has a default
|
||||
gateway configured and we try to add a dns server, Nmstate will pick the
|
||||
unmanaged interface because at that point it is not marked as ignored.
|
||||
|
||||
As the interface is being marked as ignored later, the changes are not
|
||||
being applied and is failing on verification. In order to avoid this,
|
||||
the unmanaged interfaces should be marked as ignored earlier so they are
|
||||
not considered for DNS/Routes changes.
|
||||
|
||||
Ref: https://bugzilla.redhat.com/1944582
|
||||
|
||||
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
libnmstate/dns.py | 11 +++++++++--
|
||||
libnmstate/net_state.py | 13 +++++++++++--
|
||||
libnmstate/netapplier.py | 19 +++++++++++++------
|
||||
3 files changed, 33 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/libnmstate/dns.py b/libnmstate/dns.py
|
||||
index 1fb2cc8..d44a869 100644
|
||||
--- a/libnmstate/dns.py
|
||||
+++ b/libnmstate/dns.py
|
||||
@@ -133,7 +133,7 @@ class DnsState:
|
||||
Return tuple: (ipv4_iface, ipv6_iface)
|
||||
"""
|
||||
ipv4_iface, ipv6_iface = self._find_ifaces_with_static_gateways(
|
||||
- route_state
|
||||
+ ifaces, route_state
|
||||
)
|
||||
if not (ipv4_iface and ipv6_iface):
|
||||
(
|
||||
@@ -147,7 +147,7 @@ class DnsState:
|
||||
|
||||
return ipv4_iface, ipv6_iface
|
||||
|
||||
- def _find_ifaces_with_static_gateways(self, route_state):
|
||||
+ def _find_ifaces_with_static_gateways(self, ifaces, route_state):
|
||||
"""
|
||||
Return tuple of interfaces with IPv4 and IPv6 static gateways.
|
||||
"""
|
||||
@@ -158,6 +158,11 @@ class DnsState:
|
||||
if ipv4_iface and ipv6_iface:
|
||||
return (ipv4_iface, ipv6_iface)
|
||||
if route.is_gateway:
|
||||
+ # Only interfaces not ignored can be considered as valid
|
||||
+ # static gateway for nameservers.
|
||||
+ iface = ifaces.all_kernel_ifaces.get(iface_name)
|
||||
+ if iface and iface.is_ignore:
|
||||
+ continue
|
||||
if route.is_ipv6:
|
||||
ipv6_iface = iface_name
|
||||
else:
|
||||
@@ -168,6 +173,8 @@ class DnsState:
|
||||
ipv4_iface = None
|
||||
ipv6_iface = None
|
||||
for iface in ifaces.all_kernel_ifaces.values():
|
||||
+ if iface.is_ignore:
|
||||
+ continue
|
||||
if ipv4_iface and ipv6_iface:
|
||||
return (ipv4_iface, ipv6_iface)
|
||||
for family in (Interface.IPV4, Interface.IPV6):
|
||||
diff --git a/libnmstate/net_state.py b/libnmstate/net_state.py
|
||||
index 5dc7b43..713b7dc 100644
|
||||
--- a/libnmstate/net_state.py
|
||||
+++ b/libnmstate/net_state.py
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
-# Copyright (c) 2020 Red Hat, Inc.
|
||||
+# Copyright (c) 2020-2021 Red Hat, Inc.
|
||||
#
|
||||
# This file is part of nmstate
|
||||
#
|
||||
@@ -26,8 +26,8 @@ from libnmstate.schema import Interface
|
||||
from libnmstate.schema import Route
|
||||
from libnmstate.schema import RouteRule
|
||||
|
||||
-from .ifaces import Ifaces
|
||||
from .dns import DnsState
|
||||
+from .ifaces import Ifaces
|
||||
from .route import RouteState
|
||||
from .route_rule import RouteRuleState
|
||||
from .state import state_match
|
||||
@@ -37,6 +37,7 @@ class NetState:
|
||||
def __init__(
|
||||
self,
|
||||
desire_state,
|
||||
+ ignored_ifnames=[],
|
||||
current_state=None,
|
||||
save_to_disk=True,
|
||||
gen_conf_mode=False,
|
||||
@@ -49,6 +50,8 @@ class NetState:
|
||||
save_to_disk,
|
||||
gen_conf_mode,
|
||||
)
|
||||
+ if not gen_conf_mode:
|
||||
+ self._mark_ignored_kernel_ifaces(ignored_ifnames)
|
||||
self._route = RouteState(
|
||||
self._ifaces,
|
||||
desire_state.get(Route.KEY),
|
||||
@@ -70,6 +73,12 @@ class NetState:
|
||||
self._ifaces.gen_route_metadata(self._route)
|
||||
self._ifaces.gen_route_rule_metadata(self._route_rule, self._route)
|
||||
|
||||
+ def _mark_ignored_kernel_ifaces(self, ignored_ifnames):
|
||||
+ for iface_name in ignored_ifnames:
|
||||
+ iface = self._ifaces.all_kernel_ifaces.get(iface_name)
|
||||
+ if iface and not iface.is_desired:
|
||||
+ iface.mark_as_ignored()
|
||||
+
|
||||
def verify(self, current_state):
|
||||
self._ifaces.verify(current_state.get(Interface.KEY))
|
||||
self._dns.verify(current_state.get(DNS.KEY))
|
||||
diff --git a/libnmstate/netapplier.py b/libnmstate/netapplier.py
|
||||
index a020f00..202494d 100644
|
||||
--- a/libnmstate/netapplier.py
|
||||
+++ b/libnmstate/netapplier.py
|
||||
@@ -73,7 +73,10 @@ def apply(
|
||||
validator.validate_capabilities(
|
||||
desired_state, plugins_capabilities(plugins)
|
||||
)
|
||||
- net_state = NetState(desired_state, current_state, save_to_disk)
|
||||
+ ignored_ifnames = _get_ignored_interface_names(plugins)
|
||||
+ net_state = NetState(
|
||||
+ desired_state, ignored_ifnames, current_state, save_to_disk
|
||||
+ )
|
||||
checkpoints = create_checkpoints(plugins, rollback_timeout)
|
||||
_apply_ifaces_state(plugins, net_state, verify_change, save_to_disk)
|
||||
if commit:
|
||||
@@ -107,11 +110,6 @@ def rollback(*, checkpoint=None):
|
||||
|
||||
|
||||
def _apply_ifaces_state(plugins, net_state, verify_change, save_to_disk):
|
||||
- for plugin in plugins:
|
||||
- for iface_name in plugin.get_ignored_kernel_interface_names():
|
||||
- iface = net_state.ifaces.all_kernel_ifaces.get(iface_name)
|
||||
- if iface and not iface.is_desired:
|
||||
- iface.mark_as_ignored()
|
||||
for plugin in plugins:
|
||||
plugin.apply_changes(net_state, save_to_disk)
|
||||
|
||||
@@ -145,3 +143,12 @@ def _net_state_contains_sriov_interface(net_state):
|
||||
def _verify_change(plugins, net_state):
|
||||
current_state = show_with_plugins(plugins)
|
||||
net_state.verify(current_state)
|
||||
+
|
||||
+
|
||||
+def _get_ignored_interface_names(plugins):
|
||||
+ ifaces = set()
|
||||
+ for plugin in plugins:
|
||||
+ for iface_name in plugin.get_ignored_kernel_interface_names():
|
||||
+ ifaces.add(iface_name)
|
||||
+
|
||||
+ return ifaces
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,222 +0,0 @@
|
||||
From 48c7645ce8849ac31298e6c2b1d5661d0f581279 Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Mon, 17 May 2021 16:09:52 +0800
|
||||
Subject: [PATCH 1/2] ovs: Fix `is_ovs_running()` in container environment.
|
||||
|
||||
In k8s container environment, the OVS database socket
|
||||
/var/run/openvswitch/db.sock is mounted from host, so NM can managed it
|
||||
without the ovs daemon running in container.
|
||||
|
||||
To support that, this patch removed the top level checking on
|
||||
`is_ovs_running()` and trust plugin raise the proper error on failure.
|
||||
|
||||
Patched the NM plugin to check the error
|
||||
`NM.DeviceStateReason.OVSDB_FAILED` on activation failure, raise
|
||||
`NmstateDependencyError` if OVS DB failed to connected.
|
||||
|
||||
NM will not raise any error when creating OVS internal interface with
|
||||
OVSDB mounted to /dev/null, NM will keep showing the OVS interface as
|
||||
ACTIVATING, changed the fallback checker to give only 30 seconds for OVS
|
||||
interface to exit `NM.DeviceState.PREPARE`, if not treat it as OVS
|
||||
daemon malfunctioning.
|
||||
|
||||
Updated integration test case to mask(mount /dev/null) the OVS DB socket
|
||||
file for simulating the stopped OVS daemon.
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
---
|
||||
libnmstate/ifaces/ovs.py | 15 ----------
|
||||
libnmstate/nm/active_connection.py | 47 ++++++++++++++++++++++++++----
|
||||
libnmstate/nm/plugin.py | 3 +-
|
||||
libnmstate/validator.py | 16 +++-------
|
||||
tests/integration/ovs_test.py | 41 +++++++++++---------------
|
||||
5 files changed, 64 insertions(+), 58 deletions(-)
|
||||
|
||||
diff --git a/libnmstate/ifaces/ovs.py b/libnmstate/ifaces/ovs.py
|
||||
index 24d4aba..28892ad 100644
|
||||
--- a/libnmstate/ifaces/ovs.py
|
||||
+++ b/libnmstate/ifaces/ovs.py
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
from copy import deepcopy
|
||||
from operator import itemgetter
|
||||
-import subprocess
|
||||
import warnings
|
||||
|
||||
from libnmstate.error import NmstateValueError
|
||||
@@ -252,20 +251,6 @@ class OvsInternalIface(BaseIface):
|
||||
self._info.pop(Interface.MAC, None)
|
||||
|
||||
|
||||
-def is_ovs_running():
|
||||
- try:
|
||||
- subprocess.run(
|
||||
- ("systemctl", "status", "openvswitch"),
|
||||
- stdout=subprocess.DEVNULL,
|
||||
- stderr=subprocess.DEVNULL,
|
||||
- check=True,
|
||||
- timeout=SYSTEMCTL_TIMEOUT_SECONDS,
|
||||
- )
|
||||
- return True
|
||||
- except Exception:
|
||||
- return False
|
||||
-
|
||||
-
|
||||
def is_ovs_lag_port(port_state):
|
||||
return port_state.get(OVSBridge.Port.LINK_AGGREGATION_SUBTREE) is not None
|
||||
|
||||
diff --git a/libnmstate/nm/active_connection.py b/libnmstate/nm/active_connection.py
|
||||
index ddf93a7..150256f 100644
|
||||
--- a/libnmstate/nm/active_connection.py
|
||||
+++ b/libnmstate/nm/active_connection.py
|
||||
@@ -20,6 +20,7 @@
|
||||
import logging
|
||||
|
||||
from libnmstate.error import NmstateLibnmError
|
||||
+from libnmstate.error import NmstateDependencyError
|
||||
from libnmstate.error import NmstateInternalError
|
||||
|
||||
from .common import GLib
|
||||
@@ -33,6 +34,7 @@ from .ipv6 import is_dynamic as is_ipv6_dynamic
|
||||
|
||||
NM_AC_STATE_CHANGED_SIGNAL = "state-changed"
|
||||
FALLBACK_CHECKER_INTERNAL = 15
|
||||
+MAX_OVS_IFACE_PREPARE_TIME = FALLBACK_CHECKER_INTERNAL * 2
|
||||
GIO_ERROR_DOMAIN = "g-io-error-quark"
|
||||
|
||||
|
||||
@@ -92,6 +94,7 @@ class ProfileActivation:
|
||||
self._dev_handlers = set()
|
||||
self._action = None
|
||||
self._fallback_checker = None
|
||||
+ self._fallback_checker_counter = 0
|
||||
|
||||
def run(self):
|
||||
specific_object = None
|
||||
@@ -336,19 +339,53 @@ class ProfileActivation:
|
||||
self._activation_clean_up()
|
||||
self._ctx.finish_async(self._action)
|
||||
elif not is_activating(self._nm_ac, self._nm_dev):
|
||||
- reason = f"{self._nm_ac.get_state_reason()}"
|
||||
+ nm_ac_reason = f"{self._nm_ac.get_state_reason()}"
|
||||
+ nm_dev_reason = None
|
||||
if self._nm_dev:
|
||||
- reason += f" {self._nm_dev.get_state_reason()}"
|
||||
+ nm_dev_reason = self._nm_dev.get_state_reason()
|
||||
+
|
||||
+ if nm_dev_reason == NM.DeviceStateReason.OVSDB_FAILED:
|
||||
+ error = NmstateDependencyError(
|
||||
+ f"{self._action} failed: failed to communicating with "
|
||||
+ f"Open vSwitch database, {nm_dev_reason}"
|
||||
+ )
|
||||
+ else:
|
||||
+ reason = nm_ac_reason + (
|
||||
+ str(nm_dev_reason) if nm_dev_reason else ""
|
||||
+ )
|
||||
+ error = NmstateLibnmError(
|
||||
+ f"{self._action} failed: reason={reason}"
|
||||
+ )
|
||||
self._activation_clean_up()
|
||||
- self._ctx.fail(
|
||||
- NmstateLibnmError(f"{self._action} failed: reason={reason}")
|
||||
- )
|
||||
+ self._ctx.fail(error)
|
||||
|
||||
def _fallback_checker_callback(self, _user_data):
|
||||
+ self._fallback_checker_counter += 1
|
||||
nm_dev = get_nm_dev(self._ctx, self._iface_name, self._iface_type)
|
||||
if nm_dev:
|
||||
self._nm_dev = nm_dev
|
||||
self._activation_progress_check()
|
||||
+ # When OVSDB connection is invalid(such as been mounted as
|
||||
+ # /dev/null), NM will hang on the activation of ovs internal
|
||||
+ # interface with state ACITVATING with reason UNKNOWN forever with
|
||||
+ # no state change signal. The fallback check only found it
|
||||
+ # as activating which lead us hang till killed by idle timeout.
|
||||
+ # To prevent that, when we found OVS interface interface in
|
||||
+ # `NM.DeviceState.PREPARE` on in second call of fallbacker,
|
||||
+ # we fail the action as NmstateDependencyError.
|
||||
+ if (
|
||||
+ self._fallback_checker_counter
|
||||
+ >= MAX_OVS_IFACE_PREPARE_TIME / FALLBACK_CHECKER_INTERNAL
|
||||
+ and nm_dev.get_device_type() == NM.DeviceType.OVS_INTERFACE
|
||||
+ and nm_dev.get_state() == NM.DeviceState.PREPARE
|
||||
+ ):
|
||||
+ self._ctx.fail(
|
||||
+ NmstateDependencyError(
|
||||
+ f"{self._action} failed: timeout on creating OVS "
|
||||
+ "interface, please check Open vSwitch daemon"
|
||||
+ )
|
||||
+ )
|
||||
+
|
||||
return GLib.SOURCE_CONTINUE
|
||||
|
||||
|
||||
diff --git a/libnmstate/nm/plugin.py b/libnmstate/nm/plugin.py
|
||||
index 335d93c..da933b3 100644
|
||||
--- a/libnmstate/nm/plugin.py
|
||||
+++ b/libnmstate/nm/plugin.py
|
||||
@@ -23,7 +23,6 @@ from operator import itemgetter
|
||||
from libnmstate.error import NmstateDependencyError
|
||||
from libnmstate.error import NmstateNotSupportedError
|
||||
from libnmstate.error import NmstateValueError
|
||||
-from libnmstate.ifaces.ovs import is_ovs_running
|
||||
from libnmstate.schema import DNS
|
||||
from libnmstate.schema import Interface
|
||||
from libnmstate.schema import InterfaceType
|
||||
@@ -103,7 +102,7 @@ class NetworkManagerPlugin(NmstatePlugin):
|
||||
@property
|
||||
def capabilities(self):
|
||||
capabilities = []
|
||||
- if has_ovs_capability(self.client) and is_ovs_running():
|
||||
+ if has_ovs_capability(self.client):
|
||||
capabilities.append(NmstatePlugin.OVS_CAPABILITY)
|
||||
if has_team_capability(self.client):
|
||||
capabilities.append(NmstatePlugin.TEAM_CAPABILITY)
|
||||
diff --git a/libnmstate/validator.py b/libnmstate/validator.py
|
||||
index 02890b4..cd3b540 100644
|
||||
--- a/libnmstate/validator.py
|
||||
+++ b/libnmstate/validator.py
|
||||
@@ -22,7 +22,6 @@ import logging
|
||||
|
||||
import jsonschema as js
|
||||
|
||||
-from libnmstate.ifaces.ovs import is_ovs_running
|
||||
from libnmstate.schema import Interface
|
||||
from libnmstate.schema import InterfaceType
|
||||
from libnmstate.error import NmstateDependencyError
|
||||
@@ -50,7 +49,6 @@ def validate_interface_capabilities(ifaces_state, capabilities):
|
||||
ifaces_types = {iface_state.get("type") for iface_state in ifaces_state}
|
||||
has_ovs_capability = NmstatePlugin.OVS_CAPABILITY in capabilities
|
||||
has_team_capability = NmstatePlugin.TEAM_CAPABILITY in capabilities
|
||||
- ovs_is_running = is_ovs_running()
|
||||
for iface_type in ifaces_types:
|
||||
is_ovs_type = iface_type in (
|
||||
InterfaceType.OVS_BRIDGE,
|
||||
@@ -58,18 +56,12 @@ def validate_interface_capabilities(ifaces_state, capabilities):
|
||||
InterfaceType.OVS_PORT,
|
||||
)
|
||||
if is_ovs_type and not has_ovs_capability:
|
||||
- if not ovs_is_running:
|
||||
- raise NmstateDependencyError(
|
||||
- "openvswitch service is not started."
|
||||
- )
|
||||
- else:
|
||||
- raise NmstateDependencyError(
|
||||
- "Open vSwitch NetworkManager support not installed "
|
||||
- "and started"
|
||||
- )
|
||||
+ raise NmstateDependencyError(
|
||||
+ "Open vSwitch support not properly installed or started"
|
||||
+ )
|
||||
elif iface_type == InterfaceType.TEAM and not has_team_capability:
|
||||
raise NmstateDependencyError(
|
||||
- "NetworkManager-team plugin not installed and started"
|
||||
+ "Team support not properly installed or started"
|
||||
)
|
||||
|
||||
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,86 +0,0 @@
|
||||
From af8199135907d300014b5052571ca3e445455af7 Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Tue, 25 May 2021 16:50:06 +0800
|
||||
Subject: [PATCH 2/2] nm ipv4: Deactivate profile when route removed.
|
||||
|
||||
The bug https://bugzilla.redhat.com/show_bug.cgi?id=1962551 has shown
|
||||
IPv4 route also share the same problem.
|
||||
|
||||
Whenever we got a route removal, we deactivate that profile via
|
||||
NetworkManager.
|
||||
|
||||
Integration test case included.
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
---
|
||||
libnmstate/nm/profile.py | 5 +++--
|
||||
libnmstate/route.py | 19 +++++++----------
|
||||
tests/integration/route_test.py | 37 ++++++++++++++++++++++++++++++---
|
||||
3 files changed, 45 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/libnmstate/nm/profile.py b/libnmstate/nm/profile.py
|
||||
index b655885..6b20b21 100644
|
||||
--- a/libnmstate/nm/profile.py
|
||||
+++ b/libnmstate/nm/profile.py
|
||||
@@ -49,7 +49,7 @@ from .translator import Api2Nm
|
||||
IMPORT_NM_DEV_TIMEOUT = 5
|
||||
IMPORT_NM_DEV_RETRY_INTERNAL = 0.5
|
||||
FALLBACK_CHECKER_INTERNAL = 15
|
||||
-IPV6_ROUTE_REMOVED = "_ipv6_route_removed"
|
||||
+ROUTE_REMOVED = "_route_removed"
|
||||
|
||||
|
||||
class NmProfile:
|
||||
@@ -193,9 +193,10 @@ class NmProfile:
|
||||
elif self._iface.is_virtual and self._nm_dev:
|
||||
self._add_action(NmProfile.ACTION_DELETE_DEVICE)
|
||||
|
||||
- if self._iface.raw.get(IPV6_ROUTE_REMOVED):
|
||||
+ if self._iface.raw.get(ROUTE_REMOVED):
|
||||
# This is a workaround for NM bug:
|
||||
# https://bugzilla.redhat.com/1837254
|
||||
+ # https://bugzilla.redhat.com/1962551
|
||||
self._add_action(NmProfile.ACTION_DEACTIVATE_FIRST)
|
||||
|
||||
if self._iface.is_controller and self._iface.is_up:
|
||||
diff --git a/libnmstate/route.py b/libnmstate/route.py
|
||||
index cdea198..d373427 100644
|
||||
--- a/libnmstate/route.py
|
||||
+++ b/libnmstate/route.py
|
||||
@@ -36,7 +36,7 @@ from .state import StateEntry
|
||||
DEFAULT_ROUTE_TABLE = 254
|
||||
|
||||
|
||||
-IPV6_ROUTE_REMOVED = "_ipv6_route_removed"
|
||||
+ROUTE_REMOVED = "_route_removed"
|
||||
|
||||
|
||||
class RouteEntry(StateEntry):
|
||||
@@ -235,16 +235,13 @@ class RouteState:
|
||||
for route in route_set:
|
||||
if not rt.match(route):
|
||||
new_routes.add(route)
|
||||
- if route.is_ipv6:
|
||||
- # The routes match and therefore it is being removed.
|
||||
- # Nmstate will check if it is an IPv6 route and if so,
|
||||
- # marking the interface as deactivate first.
|
||||
- #
|
||||
- # This is a workaround for NM bug:
|
||||
- # https://bugzilla.redhat.com/1837254
|
||||
- ifaces.all_kernel_ifaces[iface_name].raw[
|
||||
- IPV6_ROUTE_REMOVED
|
||||
- ] = True
|
||||
+ # The routes match and therefore it is being removed.
|
||||
+ # marking the interface as deactivate first.
|
||||
+ #
|
||||
+ # This is a workaround for NM bug:
|
||||
+ # https://bugzilla.redhat.com/1837254
|
||||
+ # https://bugzilla.redhat.com/1962551
|
||||
+ ifaces.all_kernel_ifaces[iface_name].raw[ROUTE_REMOVED] = True
|
||||
if new_routes != route_set:
|
||||
self._routes[iface_name] = new_routes
|
||||
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,74 +0,0 @@
|
||||
From e503eb8241dda600ef16741c29cab83443ae0528 Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Tue, 1 Jun 2021 10:13:33 +0800
|
||||
Subject: [PATCH 1/2] nm bond: Fixing `tlb_dynamic_lb` option
|
||||
|
||||
NM only takes 1 or 0 for True/False, currently only "use_carrier"
|
||||
and "tlb_dynamic_lb" are boolean.
|
||||
|
||||
Integration test case included. NM 1.31 is required for bug
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1959934
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
libnmstate/nm/bond.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libnmstate/nm/bond.py b/libnmstate/nm/bond.py
|
||||
index cebac4d..067d87f 100644
|
||||
--- a/libnmstate/nm/bond.py
|
||||
+++ b/libnmstate/nm/bond.py
|
||||
@@ -92,7 +92,7 @@ def _nm_fix_bond_options(option_name, option_value):
|
||||
option_name, option_value
|
||||
)
|
||||
)
|
||||
- elif option_name == "use_carrier":
|
||||
+ elif option_name in ("use_carrier", "tlb_dynamic_lb"):
|
||||
option_value = 1 if option_value else 0
|
||||
|
||||
return str(option_value)
|
||||
--
|
||||
2.31.1
|
||||
|
||||
|
||||
From 1d6c7715dfbcb5021016bcd7b4f1f9fa357b2f20 Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Tue, 1 Jun 2021 10:41:57 +0800
|
||||
Subject: [PATCH 2/2] nm bond: Fix preserving `all_slaves_active` option
|
||||
|
||||
When `all_slaves_active` was previously set via nmstate or NM, follow up
|
||||
bond modification will fail with:
|
||||
|
||||
NmstateNotImplementedError: Unsupported bond option: 'all_slaves_active'='0'
|
||||
|
||||
This is because the option returned by `_get_bond_options_from_profiles()` is
|
||||
not canonicalized.
|
||||
|
||||
Expand the check to cover `1` and `0`.
|
||||
|
||||
Integration test case included.
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
libnmstate/nm/bond.py | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libnmstate/nm/bond.py b/libnmstate/nm/bond.py
|
||||
index 067d87f..1642319 100644
|
||||
--- a/libnmstate/nm/bond.py
|
||||
+++ b/libnmstate/nm/bond.py
|
||||
@@ -82,9 +82,9 @@ def create_setting(iface, wired_setting, base_con_profile):
|
||||
|
||||
def _nm_fix_bond_options(option_name, option_value):
|
||||
if option_name == "all_slaves_active":
|
||||
- if option_value == "delivered":
|
||||
+ if option_value in ("delivered", "1"):
|
||||
option_value = 1
|
||||
- elif option_value == "dropped":
|
||||
+ elif option_value in ("dropped", "0"):
|
||||
option_value = 0
|
||||
else:
|
||||
raise NmstateNotImplementedError(
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,35 +0,0 @@
|
||||
From b1e94d1aa04f51b2d15711c8e7ab37198b173065 Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Tue, 1 Jun 2021 16:33:15 +0800
|
||||
Subject: [PATCH] bond: Fix bond fail_over_mac=active
|
||||
|
||||
With bond interface in fail_over_mac=active and active-backup mode,
|
||||
any future change via nmstate will fail as nmstate is validating
|
||||
on current state instead of desire state for this bond mac restriction.
|
||||
|
||||
Fixed the code to only validate bond mac restriction on desired or
|
||||
changed bond interface.
|
||||
|
||||
Integration test case include.
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
libnmstate/ifaces/bond.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libnmstate/ifaces/bond.py b/libnmstate/ifaces/bond.py
|
||||
index 138386e..01859b0 100644
|
||||
--- a/libnmstate/ifaces/bond.py
|
||||
+++ b/libnmstate/ifaces/bond.py
|
||||
@@ -88,7 +88,7 @@ class BondIface(BaseIface):
|
||||
|
||||
def pre_edit_validation_and_cleanup(self):
|
||||
super().pre_edit_validation_and_cleanup()
|
||||
- if self.is_up:
|
||||
+ if self.is_up and (self.is_desired or self.is_changed):
|
||||
self._discard_bond_option_when_mode_change()
|
||||
self._validate_bond_mode()
|
||||
self._fix_mac_restriced_mode()
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,32 +0,0 @@
|
||||
From 355bc8f052e35084405343a0b94ccf06007c31f3 Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Wed, 2 Jun 2021 19:53:25 +0800
|
||||
Subject: [PATCH] bond: Don't validate current bond status
|
||||
|
||||
If a bond interface is only marked as changed due to other
|
||||
interface(like bridge port list change), its original desire information
|
||||
is fully read from current status, there is no need to validate it.
|
||||
|
||||
The fix is only validate on desired bond interface.
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
libnmstate/ifaces/bond.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libnmstate/ifaces/bond.py b/libnmstate/ifaces/bond.py
|
||||
index 01859b0..6311f5f 100644
|
||||
--- a/libnmstate/ifaces/bond.py
|
||||
+++ b/libnmstate/ifaces/bond.py
|
||||
@@ -88,7 +88,7 @@ class BondIface(BaseIface):
|
||||
|
||||
def pre_edit_validation_and_cleanup(self):
|
||||
super().pre_edit_validation_and_cleanup()
|
||||
- if self.is_up and (self.is_desired or self.is_changed):
|
||||
+ if self.is_up and self.is_desired:
|
||||
self._discard_bond_option_when_mode_change()
|
||||
self._validate_bond_mode()
|
||||
self._fix_mac_restriced_mode()
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,245 +0,0 @@
|
||||
From 9f505f21b90cf122539fbe9bc3bf78ef170f5c12 Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Tue, 6 Jul 2021 11:53:55 +0800
|
||||
Subject: [PATCH] nm ovs: Fix OVS bridge and interface using the same name
|
||||
|
||||
Nmstate will fail on verification when setting ip to OVS interface
|
||||
sharing the same name with OVS bridge.
|
||||
|
||||
This is caused by NM plugin does not index with interface type when
|
||||
retrieving interface applied configure which lead to OVS bridge or OVS
|
||||
interface applied configure overlapping each other.
|
||||
|
||||
To fix this problem, we use `NetworkManagerPlugin._kernel_nic_applied_configs`
|
||||
and `NetworkManagerPlugin._userspace_nic_applied_configs()` to
|
||||
differentiate them. The kernel data is still indexed by interface name,
|
||||
the user space data is indexed by interface name and type.
|
||||
|
||||
Integration test case included as tier 1 as OpenShift need it.
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
libnmstate/nm/device.py | 8 +++++
|
||||
libnmstate/nm/plugin.py | 61 ++++++++++++++++++++++++++-------------
|
||||
libnmstate/nm/profiles.py | 38 ++++++++++++++++++++----
|
||||
3 files changed, 81 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/libnmstate/nm/device.py b/libnmstate/nm/device.py
|
||||
index 3c58bae..4c97733 100644
|
||||
--- a/libnmstate/nm/device.py
|
||||
+++ b/libnmstate/nm/device.py
|
||||
@@ -198,3 +198,11 @@ def get_nm_dev(ctx, iface_name, iface_type):
|
||||
):
|
||||
return nm_dev
|
||||
return None
|
||||
+
|
||||
+
|
||||
+def is_kernel_iface(nm_dev):
|
||||
+ iface_type = get_iface_type(nm_dev)
|
||||
+ return iface_type != InterfaceType.UNKNOWN and iface_type not in (
|
||||
+ InterfaceType.OVS_BRIDGE,
|
||||
+ InterfaceType.OVS_PORT,
|
||||
+ )
|
||||
diff --git a/libnmstate/nm/plugin.py b/libnmstate/nm/plugin.py
|
||||
index da933b3..9c774e5 100644
|
||||
--- a/libnmstate/nm/plugin.py
|
||||
+++ b/libnmstate/nm/plugin.py
|
||||
@@ -36,6 +36,7 @@ from .common import NM
|
||||
from .context import NmContext
|
||||
from .device import get_device_common_info
|
||||
from .device import get_iface_type
|
||||
+from .device import is_kernel_iface
|
||||
from .device import list_devices
|
||||
from .dns import get_running as get_dns_running
|
||||
from .dns import get_running_config as get_dns_running_config
|
||||
@@ -63,7 +64,8 @@ class NetworkManagerPlugin(NmstatePlugin):
|
||||
def __init__(self):
|
||||
self._ctx = None
|
||||
self._checkpoint = None
|
||||
- self.__applied_configs = None
|
||||
+ self.__kernel_nic_applied_configs = None
|
||||
+ self.__userspace_nic_applied_configs = None
|
||||
|
||||
@property
|
||||
def priority(self):
|
||||
@@ -79,10 +81,28 @@ class NetworkManagerPlugin(NmstatePlugin):
|
||||
self._ctx = None
|
||||
|
||||
@property
|
||||
- def _applied_configs(self):
|
||||
- if self.__applied_configs is None:
|
||||
- self.__applied_configs = get_all_applied_configs(self.context)
|
||||
- return self.__applied_configs
|
||||
+ def _kernel_nic_applied_configs(self):
|
||||
+ if (
|
||||
+ self.__kernel_nic_applied_configs is None
|
||||
+ or self.__userspace_nic_applied_configs is None
|
||||
+ ):
|
||||
+ (
|
||||
+ self.__kernel_nic_applied_configs,
|
||||
+ self.__userspace_nic_applied_configs,
|
||||
+ ) = get_all_applied_configs(self.context)
|
||||
+ return self.__kernel_nic_applied_configs
|
||||
+
|
||||
+ @property
|
||||
+ def _userspace_nic_applied_configs(self):
|
||||
+ if (
|
||||
+ self.__kernel_nic_applied_configs is None
|
||||
+ or self.__userspace_nic_applied_configs is None
|
||||
+ ):
|
||||
+ (
|
||||
+ self.__kernel_nic_applied_configs,
|
||||
+ self.__userspace_nic_applied_configs,
|
||||
+ ) = get_all_applied_configs(self.context)
|
||||
+ return self.__userspace_nic_applied_configs
|
||||
|
||||
@property
|
||||
def checkpoint(self):
|
||||
@@ -120,8 +140,6 @@ class NetworkManagerPlugin(NmstatePlugin):
|
||||
def get_interfaces(self):
|
||||
info = []
|
||||
|
||||
- applied_configs = self._applied_configs
|
||||
-
|
||||
devices_info = [
|
||||
(dev, get_device_common_info(dev))
|
||||
for dev in list_devices(self.client)
|
||||
@@ -131,6 +149,16 @@ class NetworkManagerPlugin(NmstatePlugin):
|
||||
if not dev.get_managed():
|
||||
# Skip unmanaged interface
|
||||
continue
|
||||
+ if is_kernel_iface(dev):
|
||||
+ applied_config = self._kernel_nic_applied_configs.get(
|
||||
+ dev.get_iface()
|
||||
+ )
|
||||
+ else:
|
||||
+ iface_type = get_iface_type(dev)
|
||||
+ applied_config = self._userspace_nic_applied_configs.get(
|
||||
+ f"{dev.get_iface()}{iface_type}"
|
||||
+ )
|
||||
+
|
||||
nm_ac = dev.get_active_connection()
|
||||
if (
|
||||
nm_ac
|
||||
@@ -140,7 +168,6 @@ class NetworkManagerPlugin(NmstatePlugin):
|
||||
continue
|
||||
|
||||
iface_info = Nm2Api.get_common_device_info(devinfo)
|
||||
- applied_config = applied_configs.get(iface_info[Interface.NAME])
|
||||
|
||||
act_con = dev.get_active_connection()
|
||||
iface_info[Interface.IPV4] = get_ipv4_info(act_con, applied_config)
|
||||
@@ -193,11 +220,14 @@ class NetworkManagerPlugin(NmstatePlugin):
|
||||
def get_dns_client_config(self):
|
||||
return {
|
||||
DNS.RUNNING: get_dns_running(self.client),
|
||||
- DNS.CONFIG: get_dns_running_config(self._applied_configs),
|
||||
+ DNS.CONFIG: get_dns_running_config(
|
||||
+ self._kernel_nic_applied_configs
|
||||
+ ),
|
||||
}
|
||||
|
||||
def refresh_content(self):
|
||||
- self.__applied_configs = None
|
||||
+ self.__kernel_nic_applied_configs = None
|
||||
+ self.__userspace_nic_applied_configs = None
|
||||
|
||||
def apply_changes(self, net_state, save_to_disk):
|
||||
NmProfiles(self.context).apply_config(net_state, save_to_disk)
|
||||
@@ -278,7 +308,7 @@ class NetworkManagerPlugin(NmstatePlugin):
|
||||
nm_dev
|
||||
and nm_dev.get_iface()
|
||||
and not nm_dev.get_managed()
|
||||
- and _is_kernel_iface(nm_dev)
|
||||
+ and is_kernel_iface(nm_dev)
|
||||
):
|
||||
ignored_ifaces.add(nm_dev.get_iface())
|
||||
return list(ignored_ifaces)
|
||||
@@ -298,12 +328,3 @@ def _remove_ovs_bridge_unsupported_entries(iface_info):
|
||||
|
||||
def _nm_utils_decode_version():
|
||||
return f"{NM.MAJOR_VERSION}.{NM.MINOR_VERSION}.{NM.MICRO_VERSION}"
|
||||
-
|
||||
-
|
||||
-def _is_kernel_iface(nm_dev):
|
||||
- iface_type = get_iface_type(nm_dev)
|
||||
- return iface_type != InterfaceType.UNKNOWN and iface_type not in (
|
||||
- InterfaceType.OVS_BRIDGE,
|
||||
- InterfaceType.OVS_INTERFACE,
|
||||
- InterfaceType.OVS_PORT,
|
||||
- )
|
||||
diff --git a/libnmstate/nm/profiles.py b/libnmstate/nm/profiles.py
|
||||
index 905a6c8..90e0e70 100644
|
||||
--- a/libnmstate/nm/profiles.py
|
||||
+++ b/libnmstate/nm/profiles.py
|
||||
@@ -27,7 +27,9 @@ from libnmstate.schema import InterfaceType
|
||||
from .common import NM
|
||||
from .device import is_externally_managed
|
||||
from .device import list_devices
|
||||
+from .device import get_iface_type
|
||||
from .device import get_nm_dev
|
||||
+from .device import is_kernel_iface
|
||||
from .dns import get_dns_config_iface_names
|
||||
from .ipv4 import acs_and_ip_profiles as acs_and_ip4_profiles
|
||||
from .ipv6 import acs_and_ip_profiles as acs_and_ip6_profiles
|
||||
@@ -129,7 +131,13 @@ def _append_nm_ovs_port_iface(net_state):
|
||||
|
||||
|
||||
def get_all_applied_configs(context):
|
||||
- applied_configs = {}
|
||||
+ """
|
||||
+ Return two dictionaries.
|
||||
+ First one for kernel interface with interface name as key.
|
||||
+ Second one for user space interface with interface name and type as key.
|
||||
+ """
|
||||
+ kernel_nic_applied_configs = {}
|
||||
+ userspace_nic_applid_configs = {}
|
||||
for nm_dev in list_devices(context.client):
|
||||
if (
|
||||
nm_dev.get_state()
|
||||
@@ -150,19 +158,37 @@ def get_all_applied_configs(context):
|
||||
flags=0,
|
||||
cancellable=context.cancellable,
|
||||
callback=_get_applied_config_callback,
|
||||
- user_data=(iface_name, action, applied_configs, context),
|
||||
+ user_data=(
|
||||
+ iface_name,
|
||||
+ action,
|
||||
+ kernel_nic_applied_configs,
|
||||
+ userspace_nic_applid_configs,
|
||||
+ context,
|
||||
+ ),
|
||||
)
|
||||
context.wait_all_finish()
|
||||
- return applied_configs
|
||||
+ return kernel_nic_applied_configs, userspace_nic_applid_configs
|
||||
|
||||
|
||||
def _get_applied_config_callback(nm_dev, result, user_data):
|
||||
- iface_name, action, applied_configs, context = user_data
|
||||
+ (
|
||||
+ iface_name,
|
||||
+ action,
|
||||
+ kernel_nic_applied_configs,
|
||||
+ userspace_nic_applid_configs,
|
||||
+ context,
|
||||
+ ) = user_data
|
||||
context.finish_async(action)
|
||||
try:
|
||||
+ iface_name = nm_dev.get_iface()
|
||||
remote_conn, _ = nm_dev.get_applied_connection_finish(result)
|
||||
- # TODO: We should use both interface name and type as key below.
|
||||
- applied_configs[nm_dev.get_iface()] = remote_conn
|
||||
+ if is_kernel_iface(nm_dev):
|
||||
+ kernel_nic_applied_configs[iface_name] = remote_conn
|
||||
+ else:
|
||||
+ iface_type = get_iface_type(nm_dev)
|
||||
+ userspace_nic_applid_configs[
|
||||
+ f"{iface_name}{iface_type}"
|
||||
+ ] = remote_conn
|
||||
except Exception as e:
|
||||
logging.warning(
|
||||
"Failed to retrieve applied config for device "
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,125 +0,0 @@
|
||||
From 61e775a19652ff1b17581e53367f05921304edfb Mon Sep 17 00:00:00 2001
|
||||
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
Date: Thu, 10 Jun 2021 14:55:33 +0200
|
||||
Subject: [PATCH 1/2] SR-IOV: Fix BCM57416 failure when creating VFs
|
||||
|
||||
Currently there is not a way to see the relation between a SR-IOV PF and
|
||||
its VFs. Broadcom BCM57416 follows a different name pattern for PF and
|
||||
VF, therefore it needs to be parsed if present.
|
||||
|
||||
PF name: ens2f0np0
|
||||
VF name: ens2f0v0
|
||||
|
||||
The different name pattern is due to:
|
||||
1. The `n` is for `multi-port PCI device` support.
|
||||
2. The `p*` is `phys_port_name` provided by the BCM driver `bnxt_en`.
|
||||
|
||||
Ref: https://bugzilla.redhat.com/1959679
|
||||
|
||||
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
|
||||
---
|
||||
libnmstate/ifaces/ethernet.py | 38 ++++++++++++++++++++++++++++++++---
|
||||
libnmstate/nm/profiles.py | 8 ++++++++
|
||||
2 files changed, 43 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libnmstate/ifaces/ethernet.py b/libnmstate/ifaces/ethernet.py
|
||||
index 55772ce..a47a718 100644
|
||||
--- a/libnmstate/ifaces/ethernet.py
|
||||
+++ b/libnmstate/ifaces/ethernet.py
|
||||
@@ -25,6 +25,11 @@ from libnmstate.schema import InterfaceState
|
||||
from .base_iface import BaseIface
|
||||
|
||||
|
||||
+BNXT_DRIVER_PHYS_PORT_PREFIX = "p"
|
||||
+MULTIPORT_PCI_DEVICE_PREFIX = "n"
|
||||
+IS_GENERATED_VF_METADATA = "_is_generated_vf"
|
||||
+
|
||||
+
|
||||
class EthernetIface(BaseIface):
|
||||
def __init__(self, info, save_to_disk=True):
|
||||
super().__init__(info, save_to_disk)
|
||||
@@ -80,21 +85,48 @@ class EthernetIface(BaseIface):
|
||||
)
|
||||
|
||||
def create_sriov_vf_ifaces(self):
|
||||
- return [
|
||||
+ # Currently there is not a way to see the relation between a SR-IOV PF
|
||||
+ # and its VFs. Broadcom BCM57416 follows a different name pattern for
|
||||
+ # PF and VF, therefore it needs to be parsed if present.
|
||||
+ #
|
||||
+ # PF name: ens2f0np0
|
||||
+ # VF name: ens2f0v0
|
||||
+ #
|
||||
+ # The different name pattern is due to:
|
||||
+ # 1. The `n` is for `multi-port PCI device` support.
|
||||
+ # 2. The `p*` is `phys_port_name` provided by the BCM driver
|
||||
+ # `bnxt_en`.
|
||||
+ #
|
||||
+ # If the NIC is following the standard pattern "pfname+v+vfid", this
|
||||
+ # split will not touch it and the vf_pattern will be the PF name.
|
||||
+ # Ref: https://bugzilla.redhat.com/1959679
|
||||
+ vf_pattern = self.name
|
||||
+ multiport_pattern = (
|
||||
+ MULTIPORT_PCI_DEVICE_PREFIX + BNXT_DRIVER_PHYS_PORT_PREFIX
|
||||
+ )
|
||||
+ if len(self.name.split(multiport_pattern)) == 2:
|
||||
+ vf_pattern = self.name.split(multiport_pattern)[0]
|
||||
+
|
||||
+ vf_ifaces = [
|
||||
EthernetIface(
|
||||
{
|
||||
# According to manpage of systemd.net-naming-scheme(7),
|
||||
# SRIOV VF interface will have v{slot} in device name.
|
||||
# Currently, nmstate has no intention to support
|
||||
# user-defined udev rule on SRIOV interface naming policy.
|
||||
- Interface.NAME: f"{self.name}v{i}",
|
||||
+ Interface.NAME: f"{vf_pattern}v{i}",
|
||||
Interface.TYPE: InterfaceType.ETHERNET,
|
||||
- # VF will be in DOWN state initialy.
|
||||
+ # VF will be in DOWN state initialy
|
||||
Interface.STATE: InterfaceState.DOWN,
|
||||
}
|
||||
)
|
||||
for i in range(0, self.sriov_total_vfs)
|
||||
]
|
||||
+ # The generated vf metadata cannot be part of the original dict.
|
||||
+ for vf in vf_ifaces:
|
||||
+ vf._info[IS_GENERATED_VF_METADATA] = True
|
||||
+
|
||||
+ return vf_ifaces
|
||||
|
||||
def remove_vfs_entry_when_total_vfs_decreased(self):
|
||||
vfs_count = len(
|
||||
diff --git a/libnmstate/nm/profiles.py b/libnmstate/nm/profiles.py
|
||||
index 90e0e70..ec3ef70 100644
|
||||
--- a/libnmstate/nm/profiles.py
|
||||
+++ b/libnmstate/nm/profiles.py
|
||||
@@ -40,6 +40,9 @@ from .veth import create_iface_for_nm_veth_peer
|
||||
from .veth import is_nm_veth_supported
|
||||
|
||||
|
||||
+IS_GENERATED_VF_METADATA = "_is_generated_vf"
|
||||
+
|
||||
+
|
||||
class NmProfiles:
|
||||
def __init__(self, context):
|
||||
self._ctx = context
|
||||
@@ -63,6 +66,7 @@ class NmProfiles:
|
||||
all_profiles = [
|
||||
NmProfile(self._ctx, iface)
|
||||
for iface in net_state.ifaces.all_ifaces()
|
||||
+ if not _is_only_for_verify(iface)
|
||||
]
|
||||
|
||||
for profile in all_profiles:
|
||||
@@ -409,3 +413,7 @@ def _nm_ovs_port_has_child(nm_profile, ovs_bridge_iface, net_state):
|
||||
):
|
||||
return True
|
||||
return False
|
||||
+
|
||||
+
|
||||
+def _is_only_for_verify(iface):
|
||||
+ return iface.to_dict().get(IS_GENERATED_VF_METADATA)
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,103 +0,0 @@
|
||||
From 55d5092c04a974985c4db8609c73d6b92a674cae Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Thu, 8 Jul 2021 15:49:48 +0800
|
||||
Subject: [PATCH 2/2] ovs: Regenerate iface metadata after RouteRule metadata
|
||||
generation
|
||||
|
||||
When desire state only contain route rule for OVS interface route table
|
||||
ID, NetworkManager will complains:
|
||||
|
||||
A connection with a 'ovs-interface' setting must have a master.
|
||||
|
||||
The root cause is because interface metadata is not generated if desire
|
||||
state has no interface at all.
|
||||
|
||||
The fix is regenerate interface metadata on changed/desired interface
|
||||
after route rule metadata generation.
|
||||
|
||||
Integration test case added and marked as tier1 due to RHV requirement.
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
libnmstate/ifaces/base_iface.py | 5 ++--
|
||||
libnmstate/ifaces/ifaces.py | 4 ++--
|
||||
libnmstate/ifaces/linux_bridge.py | 8 +++++--
|
||||
libnmstate/net_state.py | 3 +++
|
||||
tests/integration/ovs_test.py | 40 +++++++++++++++++++++++++++++++
|
||||
5 files changed, 54 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/libnmstate/ifaces/base_iface.py b/libnmstate/ifaces/base_iface.py
|
||||
index e3f2a1c..a76491e 100644
|
||||
--- a/libnmstate/ifaces/base_iface.py
|
||||
+++ b/libnmstate/ifaces/base_iface.py
|
||||
@@ -350,8 +350,9 @@ class BaseIface:
|
||||
def gen_metadata(self, ifaces):
|
||||
if self.is_controller and not self.is_absent:
|
||||
for port_name in self.port:
|
||||
- port_iface = ifaces.all_kernel_ifaces[port_name]
|
||||
- port_iface.set_controller(self.name, self.type)
|
||||
+ port_iface = ifaces.all_kernel_ifaces.get(port_name)
|
||||
+ if port_iface:
|
||||
+ port_iface.set_controller(self.name, self.type)
|
||||
|
||||
def update(self, info):
|
||||
self._info.update(info)
|
||||
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
|
||||
index efa24aa..c240abd 100644
|
||||
--- a/libnmstate/ifaces/ifaces.py
|
||||
+++ b/libnmstate/ifaces/ifaces.py
|
||||
@@ -158,7 +158,7 @@ class Ifaces:
|
||||
self._validate_infiniband_as_bridge_port()
|
||||
self._validate_infiniband_as_bond_port()
|
||||
self._apply_copy_mac_from()
|
||||
- self._gen_metadata()
|
||||
+ self.gen_metadata()
|
||||
for iface in self.all_ifaces():
|
||||
iface.pre_edit_validation_and_cleanup()
|
||||
|
||||
@@ -569,7 +569,7 @@ class Ifaces:
|
||||
else:
|
||||
self._kernel_ifaces[iface.name] = iface
|
||||
|
||||
- def _gen_metadata(self):
|
||||
+ def gen_metadata(self):
|
||||
for iface in self.all_ifaces():
|
||||
# Generate metadata for all interface in case any of them
|
||||
# been marked as changed by DNS/Route/RouteRule.
|
||||
diff --git a/libnmstate/ifaces/linux_bridge.py b/libnmstate/ifaces/linux_bridge.py
|
||||
index bc7768f..09d68cb 100644
|
||||
--- a/libnmstate/ifaces/linux_bridge.py
|
||||
+++ b/libnmstate/ifaces/linux_bridge.py
|
||||
@@ -125,9 +125,13 @@ class LinuxBridgeIface(BridgeIface):
|
||||
super().gen_metadata(ifaces)
|
||||
if not self.is_absent:
|
||||
for port_config in self.port_configs:
|
||||
- ifaces.all_kernel_ifaces[
|
||||
+ port_iface = ifaces.all_kernel_ifaces.get(
|
||||
port_config[LinuxBridge.Port.NAME]
|
||||
- ].update({BridgeIface.BRPORT_OPTIONS_METADATA: port_config})
|
||||
+ )
|
||||
+ if port_iface:
|
||||
+ port_iface.update(
|
||||
+ {BridgeIface.BRPORT_OPTIONS_METADATA: port_config}
|
||||
+ )
|
||||
|
||||
def remove_port(self, port_name):
|
||||
if self._bridge_config:
|
||||
diff --git a/libnmstate/net_state.py b/libnmstate/net_state.py
|
||||
index 713b7dc..780981c 100644
|
||||
--- a/libnmstate/net_state.py
|
||||
+++ b/libnmstate/net_state.py
|
||||
@@ -72,6 +72,9 @@ class NetState:
|
||||
self._ifaces.gen_dns_metadata(self._dns, self._route)
|
||||
self._ifaces.gen_route_metadata(self._route)
|
||||
self._ifaces.gen_route_rule_metadata(self._route_rule, self._route)
|
||||
+ # DND/Route/RouteRule might introduced new changed interface
|
||||
+ # Regnerate interface metadata
|
||||
+ self._ifaces.gen_metadata()
|
||||
|
||||
def _mark_ignored_kernel_ifaces(self, ignored_ifnames):
|
||||
for iface_name in ignored_ifnames:
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,16 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCAAdFiEEfUQ+BAINyWGvqJXerIciWuEsPqMFAmAueEYACgkQrIciWuEs
|
||||
PqPJxw//UmWdCJgoClFkEpWqWUkjMmfkGh70PoxtuOeNrAYwHv9zCHDBFjLtaDG1
|
||||
18+jakwrVIlTiFHZqfz1g3o0Te86w5rKiU2y0FBtBPZ1cdcJZk2Is5wb/JJo78n+
|
||||
9sWRfZmSN0SMiJ5HfzhTdZ2RsZYRSaDPSUxchRY03LzsBusxoK8swWu9oUHqmYKd
|
||||
S3k4skP5ZQvpHtKzq9w1lfU4YAw42sRvXHW/++HqGgE0rypf+Wlcu9C+It9kVLCr
|
||||
3rdp8iTGTg+LRg7LxFmEsRlmPpxhO25LaxjFvYSFnhE94xOt28KXeHBYs8hPPRwh
|
||||
+z2w6zJ3hgIrLh10IPzePTWk//KNWDRaAJXQTCma1UE4jdL3+wbxb8H3vl5VCrBU
|
||||
3fuj3JwfvFU1NuDf+yuJ0sCKzNXaAzpYYgfIaCaPdtBpg5jl2DTEfEF8QZKYuJDU
|
||||
ueCo6reBAlwJzce433aSzBXshFbHG/RdD09duS3p84Dn6ljEN3GfJwUAC9s9TsAQ
|
||||
U5+rWog6zMpVke/9yqwEf1KmqtLM3/+Ih30CHb3ZoPTf05KB14k0d1CLDdC9d9dy
|
||||
gN0w8xjdTUXbUXW/XIvRVX9KWqyNI6lnZoL0MWzPwUmMxwPJkRpAVpLKpgyUrVpD
|
||||
yjtLTFDZJNmfmbi2b0myFFcc2chaXmYlpLCP8vfRYJA3mCee6Xg=
|
||||
=b/Mh
|
||||
-----END PGP SIGNATURE-----
|
16
SOURCES/nmstate-1.1.0.tar.gz.asc
Normal file
16
SOURCES/nmstate-1.1.0.tar.gz.asc
Normal file
@ -0,0 +1,16 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCAAdFiEE8f1XsqXpyNthgIbGbM3lj+QeKP8FAmDvw+4ACgkQbM3lj+Qe
|
||||
KP+WjA/+Nky4rMOTNG16iwV8wc0hvWJdHL6XzDnHR2rrUHPGLMg4ia2B5MhYGKpl
|
||||
/1eQk2UnA2rFTLC2P+TlKJbTFTUytxDvoCbR7ODCmneSJ65txG3XFDEd0soGayn4
|
||||
w5UchowGTqGEMu/P1ORihYtYC6b8Q1gHFUomqcvryOtdE6b6lzQAMyU/VrG3vEwG
|
||||
dSsFWJh6PyMi2WTS5+CAHUYPbs3wZbNxTU74PyHch1Hcl3zwXa3bheqzHZojYh28
|
||||
GvvaPXBAHD6xwnCOWTMw3hBgLnjTZKsc62aFqgJ1Zz1VqN+Xlo8mlTZYDGhzwNU3
|
||||
m0UfRz2tSeqpbTFty3ObzTfDNYiXe4Y3J6ktD3pjt7Pf/uKY8NNbOKlZ4WhWrqPn
|
||||
VGB67ci/pcMQjw/vCPVjOQwpjVMm/EaZ6GQw8TAxbsb9tB5w2NoTncMkNNiPNB4/
|
||||
5gquK2zZL8hsPqcE5yY/n+2/zgxhO7E7KuE20dbt1BCW+wmS4e77a7cx3EFgLc7f
|
||||
oTGGuh3T+zdI/kxt5FAUBNnFiPWN9zJjQ8e080j7UIyL1Rhpvp+xG70ujwHvfL1I
|
||||
qczeFT77eI2aMNU9iX/vbkVdgEKlxD6YDw626PxJR5WQz99zHiKwfDPUf9rJW72q
|
||||
tAbGZ3DjfMk/VrerOMFDEGPA1V9Fs9kxGye1DIPAVw4IOwAbqE8=
|
||||
=9EnL
|
||||
-----END PGP SIGNATURE-----
|
@ -3,28 +3,18 @@
|
||||
%define libname libnmstate
|
||||
|
||||
Name: nmstate
|
||||
Version: 1.0.2
|
||||
Release: 14%{?dist}
|
||||
Version: 1.1.0
|
||||
Release: 3%{?dist}
|
||||
Summary: Declarative network manager API
|
||||
License: LGPLv2+
|
||||
URL: https://github.com/%{srcname}/%{srcname}
|
||||
Source0: %{url}/releases/download/v%{version}/%{srcname}-%{version}.tar.gz
|
||||
Source1: %{url}/releases/download/v%{version}/%{srcname}-%{version}.tar.gz.asc
|
||||
Source2: https://www.nmstate.io/nmstate.gpg
|
||||
Patch1: BZ_1931751-nmstate-fix-return-code.patch
|
||||
Patch2: BZ_1931355-SRIOV-wait-VF-mount-decrease.patch
|
||||
Patch3: BZ_1932247-nm-Don-t-touch-unmanaged-interface-unless-desired.patch
|
||||
Patch4: BZ_1961914-do-not-use-unmanaged-interface-for-dns.patch
|
||||
Patch5: BZ_1961912-fix-ovs-interface-activation.patch
|
||||
Patch6: BZ_1964439-ovs-Fix-is_ovs_running-in-container-environment.patch
|
||||
Patch7: BZ_1964440-nm-ipv4-Deactivate-profile-when-route-removed.patch
|
||||
Patch8: BZ_1966379_fix_bond_opt_tlb_dynamic_lb.patch
|
||||
Patch9: BZ_1966457_Fix_bond_fail_over_mac.patch
|
||||
Patch10: BZ_1966457_only_validate_desired_bond.patch
|
||||
Patch11: BZ_1979220_static_ip_on_ovs_same_name.patch
|
||||
Patch12: BZ_1979515-SR-IOV-Fix-BCM57416-failure-when-creating-VFs.patch
|
||||
Patch13: BZ_1979943-ovs-Regenerate-iface-metadata-after-RouteRule-metada.patch
|
||||
Patch14: BZ_1986285-nispor-fix-show-of-empty-next_hop_address-and-destin.patch
|
||||
Patch1: 0001-nmstatectl-fix-long-arguments-support.patch
|
||||
Patch2: 0002-nm-ethtool-Preserve-existing-ethtool-settings-when-u.patch
|
||||
Patch3: 0003-ovs-fix-state-ignore-for-ovs-port-when-removing-them.patch
|
||||
Patch4: 0004-nispor-fix-show-of-empty-next_hop_address-and-destin.patch
|
||||
BuildArch: noarch
|
||||
BuildRequires: python3-devel
|
||||
BuildRequires: python3-setuptools
|
||||
@ -82,8 +72,10 @@ gpgv2 --keyring ./gpgkey-mantainers.gpg %{SOURCE1} %{SOURCE0}
|
||||
%doc README.md
|
||||
%doc examples/
|
||||
%{_mandir}/man8/nmstatectl.8*
|
||||
%{_mandir}/man8/nmstate-autoconf.8*
|
||||
%{python3_sitelib}/nmstatectl
|
||||
%{_bindir}/nmstatectl
|
||||
%{_bindir}/nmstate-autoconf
|
||||
|
||||
%files -n python3-%{libname}
|
||||
%license LICENSE
|
||||
@ -97,36 +89,45 @@ gpgv2 --keyring ./gpgkey-mantainers.gpg %{SOURCE1} %{SOURCE0}
|
||||
%{python3_sitelib}/%{libname}/plugins/__pycache__/nmstate_plugin_ovsdb*
|
||||
|
||||
%changelog
|
||||
* Wed Jul 28 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 1.0.2-14
|
||||
- Fix showing routes without next-hop-address or destination. RHBZ#1986285
|
||||
* Tue Jul 27 2021 Gris Ge <fge@redhat.com> - 1.1.0-3
|
||||
- Fix state=ignore for OVS interface. RHBZ#1944054
|
||||
- Fix verification for next hop address 0.0.0.0. RHBZ#1985879
|
||||
|
||||
* Thu Jul 08 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 1.0.2-13
|
||||
- Fix SR-IOV BCM57416 failure when creating VFs. RHBZ#1979515
|
||||
- Fix applying route rule changes over ovs interface. RHBZ#1979943
|
||||
* Fri Jul 23 2021 Gris Ge <fge@redhat.com> - 1.1.0-2
|
||||
- Preserving existing ethtool settings. RHBZ#1984764
|
||||
|
||||
* Tue Jul 06 2021 Gris Ge <fge@redhat.com> - 1.0.2-12
|
||||
- Fix setting IP on ovs interface sharing the same name with bridge. RHBZ#1979220
|
||||
* Thu Jul 15 2021 Gris Ge <fge@redhat.com> - 1.1.0-1
|
||||
- Upgrade to 1.1.0.
|
||||
|
||||
* Thu Jun 03 2021 Gris Ge <fge@redhat.com> - 1.0.2-11
|
||||
- Only validate desired bone interface. RHBZ#1966457
|
||||
* Fri Jul 09 2021 Gris Ge <fge@redhat.com> - 1.1.0-0.7.alpha7
|
||||
- Upgarde to 1.1.0 alpha7.
|
||||
|
||||
* Tue Jun 01 2021 Gris Ge <fge@redhat.com> - 1.0.2-10
|
||||
- Fix bond option fail_over_mac=active. RHBZ#1966457
|
||||
* Thu Jul 01 2021 Gris Ge <fge@redhat.com> - 1.1.0-0.6.alpha6
|
||||
- Upgrade to 1.1.0 alpha6.
|
||||
|
||||
* Tue Jun 01 2021 Gris Ge <fge@redhat.com> - 1.0.2-9
|
||||
- Fix bond option tlb_dynamic_lb. RHBZ#1966379
|
||||
* Mon Jun 21 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 1.1.0-0.5.alpha4
|
||||
- Upgrade to 1.1.0 alpha4.
|
||||
|
||||
* Mon May 31 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 1.0.2-8
|
||||
- Remove test changes from patches.
|
||||
* Wed Jun 16 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 1.1.0-0.4.alpha3
|
||||
- Rebuild to introduce CI gating tier1 tests. RHBZ#1813357
|
||||
|
||||
* Mon May 31 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 1.0.2-7
|
||||
- Fix OVS bugs and route removal bug: RHBZ#1964440 RHBZ#1964439
|
||||
* Tue Jun 08 2021 Gris Ge <fge@redhat.com> - 1.1.0-0.3.alpha3
|
||||
- Upgrade to 1.1.0 alpha3.
|
||||
|
||||
* Wed May 19 2021 Gris Ge <fge@redhat.com> - 1.0.2-6
|
||||
- Fix OVS bugs: RHBZ#1961912 RHBZ#1961913 RHBZ#1961914
|
||||
* Mon Jun 07 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 1.1.0-0.2
|
||||
- Upgrade to 1.1.0 alpha2.
|
||||
|
||||
* Wed Mar 03 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 1.0.2-5
|
||||
- New patch for fixing unmanaged interfaces being managed. RHBZ#1932247
|
||||
* Wed May 19 2021 Wen Liang <wenliang@redhat.com> - 1.1.0-0.1
|
||||
- Upgrade to 1.1.0 alpha1.
|
||||
|
||||
* Tue Apr 20 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 1.0.3-1
|
||||
- Upgrade to 1.0.3. RHBZ#1942458
|
||||
|
||||
* Fri Mar 26 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 1.0.2-6
|
||||
- Rebuild for RHEL 8.5. RHBZ#1935710
|
||||
|
||||
* Fri Mar 26 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 1.0.2-5
|
||||
- New patch for fixing unmanaged interfaces being managed. RHBZ#1935710
|
||||
|
||||
* Tue Feb 23 2021 Gris Ge <fge@redhat.com> - 1.0.2-4
|
||||
- New patch for SRIOV decrease VF amount. RHBZ#1931355
|
||||
|
Loading…
Reference in New Issue
Block a user