Blob Blame History Raw
From 6334eb32df01326b85ca6cd589a5ea91117189e6 Mon Sep 17 00:00:00 2001
From: Gris Ge <fge@redhat.com>
Date: Fri, 9 Aug 2019 13:26:02 +0800
Subject: [PATCH] nm: Ignore not active failure when deactivate

Ignore the failure:

    Connection deactivation failed on nm2: error=nm-manager-error-quark: The
    connection was not active.

Even we check activate connection status before deactivating, there is
still a small chance that NM deactivated the connection after we
checked.

This patch also fix the random failure of
`test_add_bond_with_slaves_and_ipv4` test when tear down:

 * The tear down will delete bond99 and eth1/eth2.
 * After bond99 got deleted, the connections of eth1/eth2 will be
   brought down automatically by NM.
 * There is a small chance(about 1 out of 10) to trigger the problem of
   deactivating a non-active connection.

Signed-off-by: Gris Ge <fge@redhat.com>
---
 libnmstate/nm/active_connection.py     | 27 +++++++++++++++++++-----
 tests/lib/nm/active_connection_test.py | 29 ++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 5 deletions(-)
 create mode 100644 tests/lib/nm/active_connection_test.py

diff --git a/libnmstate/nm/active_connection.py b/libnmstate/nm/active_connection.py
index 81ec9b5..28a89d5 100644
--- a/libnmstate/nm/active_connection.py
+++ b/libnmstate/nm/active_connection.py
@@ -20,6 +20,11 @@
 import logging
 
 from . import nmclient
+from .nmclient import GLib
+from .nmclient import NM
+
+
+NM_MANAGER_ERROR_DOMAIN = 'nm-manager-error-quark'
 
 
 class AlternativeACState(object):
@@ -96,12 +101,24 @@ class ActiveConnection(object):
                     e,
                 )
             else:
-                self._mainloop.quit(
-                    'Connection deactivation failed on {}: error={}'.format(
-                        self._nmdev.get_iface(), e
+                if (
+                    isinstance(e, GLib.GError)
+                    # pylint: disable=no-member
+                    and e.domain == NM_MANAGER_ERROR_DOMAIN
+                    and e.code == NM.ManagerError.CONNECTIONNOTACTIVE
+                    # pylint: enable=no-member
+                ):
+                    success = True
+                    logging.debug(
+                        'Connection is not active on {}, no need to '
+                        'deactivate'.format(self.devname)
                     )
-                )
-            return
+                else:
+                    self._mainloop.quit(
+                        'Connection deactivation failed on {}: '
+                        'error={}'.format(self._nmdev.get_iface(), e)
+                    )
+                    return
 
         if success:
             logging.debug(
diff --git a/tests/lib/nm/active_connection_test.py b/tests/lib/nm/active_connection_test.py
new file mode 100644
index 0000000..5bd6d66
--- /dev/null
+++ b/tests/lib/nm/active_connection_test.py
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2019 Red Hat, Inc.
+#
+# This file is part of nmstate
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+
+from libnmstate.nm.nmclient import NM
+from libnmstate.nm.nmclient import GLib
+
+from libnmstate.nm.active_connection import NM_MANAGER_ERROR_DOMAIN
+
+
+def test_nm_manager_error_domain_str():
+    assert NM_MANAGER_ERROR_DOMAIN == GLib.quark_to_string(
+        NM.ManagerError.quark()
+    )
-- 
2.22.0