mirror of
https://github.com/linux-system-roles/network.git
synced 2026-01-23 02:15:17 +00:00
Fix problem when switch provider from initscript to nm
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>
This commit is contained in:
parent
f508c27674
commit
c98c17a236
7 changed files with 126 additions and 0 deletions
4
.github/run_test.sh
vendored
4
.github/run_test.sh
vendored
|
|
@ -8,10 +8,13 @@ C8_CONTAINER_IMAGE="quay.io/linux-system-roles/c8-network-role"
|
|||
C7_CONTAINER_IMAGE="quay.io/linux-system-roles/c7-network-role"
|
||||
PODMAN_OPTS="--systemd=true --privileged"
|
||||
|
||||
# FIXME: test_wireless has been removed because is not supported on CI
|
||||
# container EL7. We need to add this back for EL8 or greater.
|
||||
read -r -d '' TEST_FILES << EOF || :
|
||||
tests_802_1x_nm.yml
|
||||
tests_bond_nm.yml
|
||||
tests_auto_gateway_nm.yml
|
||||
tests_bridge_initscripts.yml
|
||||
tests_bridge_nm.yml
|
||||
tests_change_indication_on_repeat_run.yml
|
||||
tests_dummy_nm.yml
|
||||
|
|
@ -22,6 +25,7 @@ tests_ethtool_ring_nm.yml
|
|||
tests_ipv6_disabled_nm.yml
|
||||
tests_ipv6_nm.yml
|
||||
tests_vlan_mtu_nm.yml
|
||||
tests_switch_provider.yml
|
||||
EOF
|
||||
|
||||
EXEC_PATH=$(dirname "$(realpath "$0")")
|
||||
|
|
|
|||
|
|
@ -2055,6 +2055,16 @@ class Cmd_nm(Cmd):
|
|||
len(self.connections) * DEFAULT_ACTIVATION_TIMEOUT
|
||||
)
|
||||
|
||||
# On NetworkManger 1.18, If user switch from initscripts provider where
|
||||
# NM_CONTROLLED=no defined in ifcfg-ethX file, NetworkManager daemon will treat
|
||||
# that interface as strictly unmanaged, even the follow up deletion of
|
||||
# ifcfg-ethX file cannot change the NetworManager's unmanaged state of this
|
||||
# interface. This will prevent any follow up "nm" provider action on this
|
||||
# interface. To solve that, we instruct NetworkManager to reload the
|
||||
# configuration.
|
||||
if self._nm_provider.get_client_version().startswith("1.18."):
|
||||
self._nm_provider.reload_configuration()
|
||||
|
||||
def rollback_transaction(self, idx, action, error):
|
||||
Cmd.rollback_transaction(self, idx, action, error)
|
||||
self.on_failure()
|
||||
|
|
|
|||
|
|
@ -60,3 +60,31 @@ class NetworkManagerProvider:
|
|||
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()
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ NM_CONDITIONAL_TESTS = {
|
|||
IGNORE = [
|
||||
# checked by tests_regression_nm.yml
|
||||
"playbooks/tests_checkpoint_cleanup.yml",
|
||||
"playbooks/tests_switch_provider.yml",
|
||||
]
|
||||
|
||||
RUN_PLAYBOOK_WITH_INITSCRIPTS = """# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
|
|
|||
7
tests/playbooks/down_profile+delete_interface.yml
Normal file
7
tests/playbooks/down_profile+delete_interface.yml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
---
|
||||
- import_playbook: down_profile.yml
|
||||
- name: Delete the interface when the network provider is initscripts
|
||||
hosts: all
|
||||
tasks:
|
||||
- include_tasks: tasks/delete_interface.yml
|
||||
66
tests/playbooks/tests_switch_provider.yml
Normal file
66
tests/playbooks/tests_switch_provider.yml
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# This file was generated by ensure_provider_tests.py
|
||||
---
|
||||
# set network provider and gather facts
|
||||
- hosts: all
|
||||
name: Switch initscripts provider to nm
|
||||
vars:
|
||||
interface: LSR-TST-br34
|
||||
tasks:
|
||||
- name: set fact to use initscripts network_provider
|
||||
set_fact:
|
||||
network_provider: initscripts
|
||||
tags:
|
||||
- always
|
||||
- name: "Create test bridge {{ interface }} via initscripts provider"
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
state: up
|
||||
type: bridge
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
- include_tasks: tasks/assert_device_present.yml
|
||||
- name: "Take the profile {{ interface }} down via initscripts provider"
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
persistent_state: absent
|
||||
state: down
|
||||
type: bridge
|
||||
# The initscripts should not remove the interface for down/absent
|
||||
- include_tasks: tasks/assert_device_present.yml
|
||||
- name: set fact to use nm network_provider
|
||||
set_fact:
|
||||
network_provider: nm
|
||||
tags:
|
||||
- always
|
||||
- name: "Create test bridge {{ interface }} via nm provider"
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
state: up
|
||||
type: bridge
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
- include_tasks: tasks/assert_device_present.yml
|
||||
- name: "Remove bridge {{ interface }} via nm provider"
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
state: down
|
||||
type: bridge
|
||||
# NetworkManager should not remove pre-exist interface for down/absent
|
||||
- include_tasks: tasks/assert_device_present.yml
|
||||
- include_tasks: tasks/delete_interface.yml
|
||||
- include_tasks: tasks/assert_device_absent.yml
|
||||
10
tests/tests_switch_provider.yml
Normal file
10
tests/tests_switch_provider.yml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
---
|
||||
- hosts: all
|
||||
name: Run playbook 'playbooks/tests_switch_provider.yml'
|
||||
|
||||
- import_playbook: playbooks/tests_switch_provider.yml
|
||||
when:
|
||||
# The test requires or should run with NetworkManager, therefore it cannot
|
||||
# run on RHEL/CentOS 6
|
||||
- ansible_distribution_major_version != '6'
|
||||
Loading…
Add table
Add a link
Reference in a new issue