import nmstate-1.0.2-11.el8_4

This commit is contained in:
CentOS Sources 2021-06-29 10:01:58 -04:00 committed by Andrew Lukoshko
parent 8c0f309116
commit 238501763b
8 changed files with 775 additions and 1 deletions

View File

@ -0,0 +1,137 @@
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

View File

@ -0,0 +1,163 @@
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

View File

@ -0,0 +1,222 @@
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

View File

@ -0,0 +1,86 @@
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

View File

@ -0,0 +1,74 @@
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

View File

@ -0,0 +1,35 @@
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

View File

@ -0,0 +1,32 @@
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

View File

@ -4,7 +4,7 @@
Name: nmstate
Version: 1.0.2
Release: 5%{?dist}
Release: 11%{?dist}
Summary: Declarative network manager API
License: LGPLv2+
URL: https://github.com/%{srcname}/%{srcname}
@ -14,6 +14,13 @@ 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
BuildArch: noarch
BuildRequires: python3-devel
BuildRequires: python3-setuptools
@ -86,6 +93,24 @@ gpgv2 --keyring ./gpgkey-mantainers.gpg %{SOURCE1} %{SOURCE0}
%{python3_sitelib}/%{libname}/plugins/__pycache__/nmstate_plugin_ovsdb*
%changelog
* Thu Jun 03 2021 Gris Ge <fge@redhat.com> - 1.0.2-11
- Only validate desired bone interface. RHBZ#1966457
* Tue Jun 01 2021 Gris Ge <fge@redhat.com> - 1.0.2-10
- Fix bond option fail_over_mac=active. RHBZ#1966457
* Tue Jun 01 2021 Gris Ge <fge@redhat.com> - 1.0.2-9
- Fix bond option tlb_dynamic_lb. RHBZ#1966379
* Mon May 31 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 1.0.2-8
- Remove test changes from patches.
* 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
* Wed May 19 2021 Gris Ge <fge@redhat.com> - 1.0.2-6
- Fix OVS bugs: RHBZ#1961912 RHBZ#1961913 RHBZ#1961914
* Wed Mar 03 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 1.0.2-5
- New patch for fixing unmanaged interfaces being managed. RHBZ#1932247