Blob Blame History Raw
From 37f47c373a99771d42799941ba96cf4f8a173c75 Mon Sep 17 00:00:00 2001
From: Gris Ge <fge@redhat.com>
Date: Thu, 26 Mar 2020 19:50:03 +0800
Subject: [PATCH 09/10] state: allow missing arp_ip_target when ARP monitoring
 disabled

Got verification failure when disabling `arp_interval` of existing bond
regarding `arp_ip_target: ''` not included in new state.

This is because NetworkManager does not store `arp_ip_target: ''` in
on-disk profile when `arp_interval` is zero/disabled.

The fix is allowing backend to skip `arp_ip_target` when ARP monitoring
is disabled(`arp_interval==0`) by fix the bond option before
verification.

Added function `libnmstate.applier.bond.iface_state_pre_verify_fix()`.

Introduced `self._pre_verification_fix()` to `State.verify_interfaces()`
allowing `state.py` to delegating state modification to interface
specific function without knowing the detail.

Integration test case added.

Signed-off-by: Gris Ge <fge@redhat.com>
---
 libnmstate/appliers/bond.py            | 13 +++++++++
 libnmstate/state.py                    | 10 +++++++
 tests/integration/bond_test.py         | 39 +++++++++++++++++++++++---
 tests/integration/testlib/assertlib.py | 21 ++++++++++++++
 4 files changed, 79 insertions(+), 4 deletions(-)

diff --git a/libnmstate/appliers/bond.py b/libnmstate/appliers/bond.py
index 785d8f3..5602adb 100644
--- a/libnmstate/appliers/bond.py
+++ b/libnmstate/appliers/bond.py
@@ -113,3 +113,16 @@ def get_bond_named_option_value_by_id(option_name, option_id_value):
         with contextlib.suppress(ValueError, IndexError):
             return option_value[int(option_id_value)]
     return option_id_value
+
+
+def fix_bond_option_arp_monitor(cur_iface_state):
+    """
+    Fix the current iface_state by
+    adding 'arp_ip_target=""' when ARP monitor is disabled by `arp_interval=0`
+    """
+    bond_options = cur_iface_state[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE]
+    if (
+        bond_options.get("arp_interval") in ("0", 0)
+        and "arp_ip_target" not in bond_options
+    ):
+        bond_options["arp_ip_target"] = ""
diff --git a/libnmstate/state.py b/libnmstate/state.py
index 960558a..98be33d 100644
--- a/libnmstate/state.py
+++ b/libnmstate/state.py
@@ -321,6 +321,7 @@ class State:
 
         metadata.remove_ifaces_metadata(self)
         other_state.sanitize_dynamic_ip()
+        other_state._pre_verification_fix()
 
         self.merge_interfaces(other_state)
 
@@ -329,6 +330,15 @@ class State:
 
         self._assert_interfaces_equal(other_state)
 
+    def _pre_verification_fix(self):
+        """
+        Invoking iface specific fixes.
+        Supposed to only run againt current state.
+        """
+        for iface_state in self.interfaces.values():
+            if iface_state.get(Interface.TYPE) == InterfaceType.BOND:
+                bond.fix_bond_option_arp_monitor(iface_state)
+
     def verify_routes(self, other_state):
         for iface_name, routes in self.config_iface_routes.items():
             other_routes = other_state.config_iface_routes.get(iface_name, [])
-- 
2.25.1