nmstate/SOURCES/BZ_1866269-preserve_nm_uuid...

121 lines
4.4 KiB
Diff

From 21e06fd5af76cc1fe65497222a04c1cffa2bc546 Mon Sep 17 00:00:00 2001
From: Gris Ge <fge@redhat.com>
Date: Thu, 6 Aug 2020 13:07:59 +0800
Subject: [PATCH] ovsdb: Preserve the NM external_ids
For newly created OVS internal interface with customer external_ids,
the ovsdb plugin will remove the NM external_ids `NM.connection.uuid`.
The fix is read the current `NM.connection.uuid` before applying
configure and merge it with original desired state.
Integration test cases added.
Signed-off-by: Gris Ge <fge@redhat.com>
---
libnmstate/plugins/nmstate_plugin_ovsdb.py | 69 +++++++++++++---------
1 file changed, 40 insertions(+), 29 deletions(-)
diff --git a/libnmstate/plugins/nmstate_plugin_ovsdb.py b/libnmstate/plugins/nmstate_plugin_ovsdb.py
index 83965e1..12ab10d 100644
--- a/libnmstate/plugins/nmstate_plugin_ovsdb.py
+++ b/libnmstate/plugins/nmstate_plugin_ovsdb.py
@@ -161,7 +161,14 @@ class NmstateOvsdbPlugin(NmstatePlugin):
return ifaces
def apply_changes(self, net_state, save_to_disk):
+ # State might changed after other plugin invoked apply_changes()
self.refresh_content()
+ cur_iface_to_ext_ids = {}
+ for iface_info in self.get_interfaces():
+ cur_iface_to_ext_ids[iface_info[Interface.NAME]] = iface_info[
+ OvsDB.OVS_DB_SUBTREE
+ ][OvsDB.EXTERNAL_IDS]
+
pending_changes = []
for iface in net_state.ifaces.values():
if not iface.is_changed and not iface.is_desired:
@@ -174,7 +181,34 @@ class NmstateOvsdbPlugin(NmstatePlugin):
table_name = "Interface"
else:
continue
- pending_changes.extend(_generate_db_change(table_name, iface))
+ ids_after_nm_applied = cur_iface_to_ext_ids.get(iface.name, {})
+ ids_before_nm_applied = (
+ iface.to_dict()
+ .get(OvsDB.OVS_DB_SUBTREE, {})
+ .get(OvsDB.EXTERNAL_IDS, {})
+ )
+ original_desire_ids = iface.original_dict.get(
+ OvsDB.OVS_DB_SUBTREE, {}
+ ).get(OvsDB.EXTERNAL_IDS)
+
+ desire_ids = []
+
+ if original_desire_ids is None:
+ desire_ids = ids_before_nm_applied
+ else:
+ desire_ids = original_desire_ids
+
+ # should include external_id created by NetworkManager.
+ if NM_EXTERNAL_ID in ids_after_nm_applied:
+ desire_ids[NM_EXTERNAL_ID] = ids_after_nm_applied[
+ NM_EXTERNAL_ID
+ ]
+ if desire_ids != ids_after_nm_applied:
+ pending_changes.append(
+ _generate_db_change_external_ids(
+ table_name, iface.name, desire_ids
+ )
+ )
if pending_changes:
if not save_to_disk:
raise NmstateNotImplementedError(
@@ -242,38 +276,15 @@ class NmstateOvsdbPlugin(NmstatePlugin):
)
-def _generate_db_change(table_name, iface_state):
- return _generate_db_change_external_ids(table_name, iface_state)
-
-
-def _generate_db_change_external_ids(table_name, iface_state):
- pending_changes = []
- desire_ids = iface_state.original_dict.get(OvsDB.OVS_DB_SUBTREE, {}).get(
- OvsDB.EXTERNAL_IDS
- )
+def _generate_db_change_external_ids(table_name, iface_name, desire_ids):
if desire_ids and not isinstance(desire_ids, dict):
raise NmstateValueError("Invalid external_ids, should be dictionary")
- if desire_ids or desire_ids == {}:
- # should include external_id required by NetworkManager.
- merged_ids = (
- iface_state.to_dict()
- .get(OvsDB.OVS_DB_SUBTREE, {})
- .get(OvsDB.EXTERNAL_IDS, {})
- )
- if NM_EXTERNAL_ID in merged_ids:
- desire_ids[NM_EXTERNAL_ID] = merged_ids[NM_EXTERNAL_ID]
-
- # Convert all value to string
- for key, value in desire_ids.items():
- desire_ids[key] = str(value)
+ # Convert all value to string
+ for key, value in desire_ids.items():
+ desire_ids[key] = str(value)
- pending_changes.append(
- _Changes(
- table_name, OvsDB.EXTERNAL_IDS, iface_state.name, desire_ids
- )
- )
- return pending_changes
+ return _Changes(table_name, OvsDB.EXTERNAL_IDS, iface_name, desire_ids)
NMSTATE_PLUGIN = NmstateOvsdbPlugin
--
2.28.0