mirror of
https://github.com/linux-system-roles/network.git
synced 2026-01-23 18:35:13 +00:00
Problem:
After `tests_bridge_initscripts.yml` passed, the `tests_bridge_nm.yml`
will fail with NetworkManager 1.18.
Root cause:
1. The `absent` and `down` action of initscript provider will not
remove the bridge interface which fail the assertion in
`tests_bridge_nm.yml`.
2. In initscript mode, network role will create ifcfg file with
`NM_CONTROLLED=no` instructing NetworkManager to mark the bridge as
unmanaged. The follow up `down` and `absent` action of initscript
provider will not change the NetworkManager's understanding on
unmanaged state of this interface.
Fixes:
1. We cannot change existing behaviour of initscript on not deleting
interface in `down` and `absent` action. So we change the test
function `tests/playbooks/down_profile.yml` to delete the interface
manually via `ip link del <ifname>` command.
2. Use `NM.Client.reload_connections_async()` to reload the
configuration for nm provider on NetworkManager 1.18.
Previous test infrastructure is running each test file in a brand new VM
or container which cause this problem not been found before.
Dedicate test case `tests/tests_switch_provider.yml` included.
Signed-off-by: Gris Ge <fge@redhat.com>
90 lines
3.1 KiB
Python
90 lines
3.1 KiB
Python
# SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
__metaclass__ = type
|
|
|
|
import logging
|
|
|
|
# Relative import is not support by ansible 2.8 yet
|
|
# pylint: disable=import-error, no-name-in-module
|
|
from ansible.module_utils.network_lsr.nm import active_connection # noqa:E501
|
|
from ansible.module_utils.network_lsr.nm import client # noqa:E501
|
|
from ansible.module_utils.network_lsr.nm import connection # noqa:E501
|
|
|
|
# pylint: enable=import-error, no-name-in-module
|
|
|
|
|
|
class NetworkManagerProvider:
|
|
def deactivate_connection(self, connection_name, timeout, check_mode):
|
|
"""
|
|
Return True if changed.
|
|
"""
|
|
nm_client = client.get_client()
|
|
changed = False
|
|
for nm_ac in nm_client.get_active_connections():
|
|
nm_profile = nm_ac.get_connection()
|
|
if nm_profile and nm_profile.get_id() == connection_name:
|
|
changed |= active_connection.deactivate_active_connection(
|
|
nm_ac, timeout, check_mode
|
|
)
|
|
if not changed:
|
|
logging.info("No active connection for %s", connection_name)
|
|
|
|
return changed
|
|
|
|
def volatilize_connection_by_uuid(self, uuid, timeout, check_mode):
|
|
"""
|
|
Mark NM.RemoteConnection as volatile(delete on deactivation) via Update2,
|
|
if not supported, delete the profile.
|
|
|
|
Return True if changed.
|
|
"""
|
|
nm_client = client.get_client()
|
|
changed = False
|
|
for nm_profile in nm_client.get_connections():
|
|
if nm_profile and nm_profile.get_uuid() == uuid:
|
|
if hasattr(nm_profile, "update2"):
|
|
changed |= connection.volatilize_remote_connection(
|
|
nm_profile, timeout, check_mode
|
|
)
|
|
else:
|
|
changed |= connection.delete_remote_connection(
|
|
nm_profile, timeout, check_mode
|
|
)
|
|
if not changed:
|
|
logging.info("No connection with UUID %s to volatilize", uuid)
|
|
|
|
return changed
|
|
|
|
def get_connections(self):
|
|
nm_client = client.get_client()
|
|
return nm_client.get_connections()
|
|
|
|
def get_client_version(self):
|
|
nm_client = client.get_client()
|
|
return nm_client.get_version()
|
|
|
|
def reload_configuration(self):
|
|
timeout = 10
|
|
nm_client = client.get_client()
|
|
main_loop = client.get_mainloop(timeout)
|
|
logging.debug("Reloading configuration with timeout %s", timeout)
|
|
nm_client.reload_connections_async(
|
|
main_loop.cancellable, _reload_config_callback, main_loop
|
|
)
|
|
main_loop.run()
|
|
|
|
|
|
def _reload_config_callback(nm_client, result, main_loop):
|
|
try:
|
|
success = nm_client.reload_connections_finish(result)
|
|
except client.GLib.Error as e:
|
|
logging.warn("Failed to reload configuration: %s", e)
|
|
main_loop.quit()
|
|
return
|
|
if success:
|
|
logging.debug("Reloading configuration finished")
|
|
else:
|
|
logging.warn("Failed to reload configuration, no error message")
|
|
main_loop.quit()
|