diff --git a/SOURCES/BZ_1866269-preserve_nm_uuid_in_ovsdb.patch b/SOURCES/BZ_1866269-preserve_nm_uuid_in_ovsdb.patch new file mode 100644 index 0000000..214aa8c --- /dev/null +++ b/SOURCES/BZ_1866269-preserve_nm_uuid_in_ovsdb.patch @@ -0,0 +1,120 @@ +From 21e06fd5af76cc1fe65497222a04c1cffa2bc546 Mon Sep 17 00:00:00 2001 +From: Gris Ge +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 +--- + 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 + diff --git a/SPECS/nmstate.spec b/SPECS/nmstate.spec index 02137e4..8abf6d2 100644 --- a/SPECS/nmstate.spec +++ b/SPECS/nmstate.spec @@ -4,7 +4,7 @@ Name: nmstate Version: 0.3.4 -Release: 9%{?dist} +Release: 10%{?dist} Summary: Declarative network manager API License: LGPLv2+ URL: https://github.com/%{srcname}/%{srcname} @@ -17,6 +17,7 @@ Patch3: BZ_1861668_ignore_unknown_iface.patch Patch4: BZ_1862025-remove_existing_profiles.patch Patch5: BZ_1858758-fix_ovs_bond.patch Patch6: BZ_1859844-fix_converting_memory_only.patch +Patch7: BZ_1866269-preserve_nm_uuid_in_ovsdb.patch BuildArch: noarch BuildRequires: python3-devel BuildRequires: python3-setuptools @@ -87,6 +88,9 @@ gpgv2 --keyring ./gpgkey-mantainers.gpg %{SOURCE1} %{SOURCE0} %{python3_sitelib}/%{libname}/plugins/__pycache__/nmstate_plugin_ovsdb* %changelog +* Thu Aug 06 2020 Gris Ge - 0.3.4-10 +- OVSDB: Preserv old external_ids. RHBZ#1866269 + * Tue Aug 04 2020 Gris Ge - 0.3.4-9 - Fix converting memory only profile to persistent. RHBZ#1859844