|
|
8f4f2d |
From 37f47c373a99771d42799941ba96cf4f8a173c75 Mon Sep 17 00:00:00 2001
|
|
|
8f4f2d |
From: Gris Ge <fge@redhat.com>
|
|
|
8f4f2d |
Date: Thu, 26 Mar 2020 19:50:03 +0800
|
|
|
8f4f2d |
Subject: [PATCH 09/10] state: allow missing arp_ip_target when ARP monitoring
|
|
|
8f4f2d |
disabled
|
|
|
8f4f2d |
|
|
|
8f4f2d |
Got verification failure when disabling `arp_interval` of existing bond
|
|
|
8f4f2d |
regarding `arp_ip_target: ''` not included in new state.
|
|
|
8f4f2d |
|
|
|
8f4f2d |
This is because NetworkManager does not store `arp_ip_target: ''` in
|
|
|
8f4f2d |
on-disk profile when `arp_interval` is zero/disabled.
|
|
|
8f4f2d |
|
|
|
8f4f2d |
The fix is allowing backend to skip `arp_ip_target` when ARP monitoring
|
|
|
8f4f2d |
is disabled(`arp_interval==0`) by fix the bond option before
|
|
|
8f4f2d |
verification.
|
|
|
8f4f2d |
|
|
|
8f4f2d |
Added function `libnmstate.applier.bond.iface_state_pre_verify_fix()`.
|
|
|
8f4f2d |
|
|
|
8f4f2d |
Introduced `self._pre_verification_fix()` to `State.verify_interfaces()`
|
|
|
8f4f2d |
allowing `state.py` to delegating state modification to interface
|
|
|
8f4f2d |
specific function without knowing the detail.
|
|
|
8f4f2d |
|
|
|
8f4f2d |
Integration test case added.
|
|
|
8f4f2d |
|
|
|
8f4f2d |
Signed-off-by: Gris Ge <fge@redhat.com>
|
|
|
8f4f2d |
---
|
|
|
8f4f2d |
libnmstate/appliers/bond.py | 13 +++++++++
|
|
|
8f4f2d |
libnmstate/state.py | 10 +++++++
|
|
|
8f4f2d |
tests/integration/bond_test.py | 39 +++++++++++++++++++++++---
|
|
|
8f4f2d |
tests/integration/testlib/assertlib.py | 21 ++++++++++++++
|
|
|
8f4f2d |
4 files changed, 79 insertions(+), 4 deletions(-)
|
|
|
8f4f2d |
|
|
|
8f4f2d |
diff --git a/libnmstate/appliers/bond.py b/libnmstate/appliers/bond.py
|
|
|
8f4f2d |
index 785d8f3..5602adb 100644
|
|
|
8f4f2d |
--- a/libnmstate/appliers/bond.py
|
|
|
8f4f2d |
+++ b/libnmstate/appliers/bond.py
|
|
|
8f4f2d |
@@ -113,3 +113,16 @@ def get_bond_named_option_value_by_id(option_name, option_id_value):
|
|
|
8f4f2d |
with contextlib.suppress(ValueError, IndexError):
|
|
|
8f4f2d |
return option_value[int(option_id_value)]
|
|
|
8f4f2d |
return option_id_value
|
|
|
8f4f2d |
+
|
|
|
8f4f2d |
+
|
|
|
8f4f2d |
+def fix_bond_option_arp_monitor(cur_iface_state):
|
|
|
8f4f2d |
+ """
|
|
|
8f4f2d |
+ Fix the current iface_state by
|
|
|
8f4f2d |
+ adding 'arp_ip_target=""' when ARP monitor is disabled by `arp_interval=0`
|
|
|
8f4f2d |
+ """
|
|
|
8f4f2d |
+ bond_options = cur_iface_state[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE]
|
|
|
8f4f2d |
+ if (
|
|
|
8f4f2d |
+ bond_options.get("arp_interval") in ("0", 0)
|
|
|
8f4f2d |
+ and "arp_ip_target" not in bond_options
|
|
|
8f4f2d |
+ ):
|
|
|
8f4f2d |
+ bond_options["arp_ip_target"] = ""
|
|
|
8f4f2d |
diff --git a/libnmstate/state.py b/libnmstate/state.py
|
|
|
8f4f2d |
index 960558a..98be33d 100644
|
|
|
8f4f2d |
--- a/libnmstate/state.py
|
|
|
8f4f2d |
+++ b/libnmstate/state.py
|
|
|
8f4f2d |
@@ -321,6 +321,7 @@ class State:
|
|
|
8f4f2d |
|
|
|
8f4f2d |
metadata.remove_ifaces_metadata(self)
|
|
|
8f4f2d |
other_state.sanitize_dynamic_ip()
|
|
|
8f4f2d |
+ other_state._pre_verification_fix()
|
|
|
8f4f2d |
|
|
|
8f4f2d |
self.merge_interfaces(other_state)
|
|
|
8f4f2d |
|
|
|
8f4f2d |
@@ -329,6 +330,15 @@ class State:
|
|
|
8f4f2d |
|
|
|
8f4f2d |
self._assert_interfaces_equal(other_state)
|
|
|
8f4f2d |
|
|
|
8f4f2d |
+ def _pre_verification_fix(self):
|
|
|
8f4f2d |
+ """
|
|
|
8f4f2d |
+ Invoking iface specific fixes.
|
|
|
8f4f2d |
+ Supposed to only run againt current state.
|
|
|
8f4f2d |
+ """
|
|
|
8f4f2d |
+ for iface_state in self.interfaces.values():
|
|
|
8f4f2d |
+ if iface_state.get(Interface.TYPE) == InterfaceType.BOND:
|
|
|
8f4f2d |
+ bond.fix_bond_option_arp_monitor(iface_state)
|
|
|
8f4f2d |
+
|
|
|
8f4f2d |
def verify_routes(self, other_state):
|
|
|
8f4f2d |
for iface_name, routes in self.config_iface_routes.items():
|
|
|
8f4f2d |
other_routes = other_state.config_iface_routes.get(iface_name, [])
|
|
|
8f4f2d |
--
|
|
|
8f4f2d |
2.25.1
|
|
|
8f4f2d |
|