Forget unmanaged state in NetworkManager

When removing a profile with initscripts, also notify NetworkManager so
it can forget that the specified device was to be ignored.
This commit is contained in:
Till Maas 2020-07-07 15:43:18 +02:00
parent 1a9b140647
commit 0b2edc50d8
9 changed files with 173 additions and 6 deletions

View file

@ -60,10 +60,12 @@ Variables
The `network` role is configured via variables starting with `network_` as the name prefix.
List of variables:
* `network_provider` - The `network_provider` variable allows to set a specific
provider (`nm` or `initscripts`) . Setting it to `{{ network_provider_os_default }}`,
the provider is set depending on the operating system. This is usually `nm`
except for RHEL 6 or CentOS 6 systems.
* `network_provider` - The `network_provider` variable allows to set a specific provider
(`nm` or `initscripts`) . Setting it to `{{ network_provider_os_default }}`, the
provider is set depending on the operating system. This is usually `nm` except for
RHEL 6 or CentOS 6 systems. Changing the provider for an existing profile is not
supported. To switch providers, it is recommended to first remove profiles with the
old provider and then create new profiles with the new provider.
* `network_connections` - The connection profiles are configured as `network_connections`,
which is a list of dictionaries that include specific options.
* `network_allow_restart` - Certain configurations require the role to restart network services.

View file

@ -8,6 +8,7 @@ import os
import re
import shlex
import socket
import subprocess
import time
import traceback
@ -2340,6 +2341,36 @@ class Cmd_initscripts(Cmd):
return None
return f
def forget_nm_connection(self, path):
"""
Forget a NetworkManager connection by loading the path of the deleted
profile. This inverts the effect of loading a profile with
`NM_CONTROLLED=no` earlier, which made NetworkManager ignore the
device.
This does not use the Python libnm bindings because they might not be
present on the system, since the module is currently operating for the
initscripts provider. If it fails, assume that NetworkManager is not
present and did not save any state about the corresponding interface.
"""
try:
subprocess.call(
[
"busctl",
"--system",
"call",
"org.freedesktop.NetworkManager",
"/org/freedesktop/NetworkManager/Settings",
"org.freedesktop.NetworkManager.Settings",
"LoadConnections",
"as",
"1",
path,
]
)
except Exception:
pass
def run_action_absent(self, idx):
n = self.connections[idx]["name"]
name = n
@ -2371,6 +2402,7 @@ class Cmd_initscripts(Cmd):
if self.check_mode == CheckMode.REAL_RUN:
try:
os.unlink(path)
self.forget_nm_connection(path)
except Exception as e:
self.log_error(
idx, "delete ifcfg-rh file '%s' failed: %s" % (path, e)

View file

@ -61,12 +61,16 @@ RUN_PLAYBOOK_WITH_NM = """# SPDX-License-Identifier: BSD-3-Clause
MINIMUM_VERSION = "minimum_version"
EXTRA_RUN_CONDITION = "extra_run_condition"
NM_ONLY_TESTS = {
"playbooks/tests_802_1x_updated.yml": {},
"playbooks/tests_802_1x.yml": {},
"playbooks/tests_ethtool_features.yml": {
MINIMUM_VERSION: "'1.20.0'",
"comment": "# NetworkManager 1.20.0 introduced ethtool settings support",
},
"playbooks/tests_802_1x_updated.yml": {},
"playbooks/tests_802_1x.yml": {},
"playbooks/tests_provider.yml": {
MINIMUM_VERSION: "'1.20.0'",
"comment": "# NetworKmanager 1.20.0 added support for forgetting profiles",
},
"playbooks/tests_reapply.yml": {},
# mac80211_hwsim (used for tests_wireless) only seems to be available
# and working on RHEL/CentOS 7

View file

@ -0,0 +1,35 @@
# SPDX-License-Identifier: BSD-3-Clause
---
- hosts: all
vars:
interface: testnic1
profile: "{{ interface }}"
lsr_fail_debug:
- __network_connections_result
tasks:
- debug:
msg: "this is: playbooks/tests_states.yml"
tags:
- always
- block:
- include_tasks: tasks/run_test.yml
vars:
state: present
lsr_description: I can manage a veth interface with NM after I
managed it with initscripts.
lsr_setup:
- tasks/setup_test_interface.yml
# run role once with defaults but nm provider to ensure that
# NetworKManager is running
- tasks/provider/default_with_nm.yml
- tasks/provider/create_and_remove_with_initscripts.yml
lsr_test:
- tasks/provider/create_with_nm.yml
lsr_assert:
- tasks/assert_profile_present.yml
lsr_cleanup:
- tasks/cleanup_profile+device.yml
tags:
- tests::provider:initscripts_to_nm

View file

@ -0,0 +1,23 @@
# SPDX-License-Identifier: BSD-3-Clause
---
- include_role:
name: linux-system-roles.network
vars:
network_connections:
- name: "{{ interface }}"
state: up
persistent_state: present
type: ethernet
autoconnect: yes
ip:
address: 192.0.2.1/24
network_provider: initscripts
- include_role:
name: linux-system-roles.network
vars:
network_connections:
- name: "{{ interface }}"
state: down
persistent_state: absent
network_provider: initscripts
...

View file

@ -0,0 +1,15 @@
# SPDX-License-Identifier: BSD-3-Clause
---
- include_role:
name: linux-system-roles.network
vars:
network_connections:
- name: "{{ interface }}"
state: up
persistent_state: present
type: ethernet
autoconnect: yes
ip:
address: 192.0.2.1/24
network_provider: nm
...

View file

@ -0,0 +1,8 @@
# SPDX-License-Identifier: BSD-3-Clause
---
- include_role:
name: linux-system-roles.network
vars:
network_connections: []
network_provider: nm
...

View file

@ -0,0 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
---
- include_tasks: tasks/manage_test_interface.yml
vars:
state: present
type: veth
...

View file

@ -0,0 +1,41 @@
# SPDX-License-Identifier: BSD-3-Clause
# This file was generated by ensure_provider_tests.py
---
# set network provider and gather facts
- hosts: all
name: Run playbook 'playbooks/tests_provider.yml' with nm as provider
tasks:
- name: Set network provider to 'nm'
set_fact:
network_provider: nm
tags:
- always
- block:
- name: Install NetworkManager
package:
name: NetworkManager
state: present
- name: Get NetworkManager version
command: rpm -q --qf "%{version}" NetworkManager
args:
warn: false
register: NetworkManager_version
when: true
when:
- ansible_distribution_major_version != '6'
tags:
- always
# workaround for: https://github.com/ansible/ansible/issues/27973
# There is no way in Ansible to abort a playbook hosts with specific OS
# releases Therefore we include the playbook with the tests only if the hosts
# would support it.
# The test requires or should run with NetworkManager, therefore it cannot run
# on RHEL/CentOS 6
- import_playbook: playbooks/tests_provider.yml
when:
- ansible_distribution_major_version != '6'
- NetworkManager_version.stdout is version('1.20.0', '>=')