refactor: improve support for ostree systems

The dependency on `ansible.utils.update_fact` is causing issue with
some users who now must install that collection in order to run
the role, even if they do not care about ostree.

The fix is to stop trying to set `ansible_facts.pkg_mgr`, and instead
force the use of the ostree package manager with the `package:` module
`use:` option.  The strategy is - on ostree systems, set the flag
`__$ROLENAME_is_ostree` if the system is an ostree system.  The flag
will either be undefined or `false` on non-ostree systems.
Then, change every invocation of the `package:` module like this:

```yaml
- name: Ensure required packages are present
  package:
    name: "{{ __$ROLENAME_packages }}"
    state: present
    use: "{{ (__$ROLENAME_is_ostree | d(false)) |
      ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
```

This should ensure that the `use:` parameter is not used if the system
is non-ostree.  The goal is to make the ostree support as unobtrusive
as possible for non-ostree systems.
The user can also set `__$ROLENAME_is_ostree: true` in the inventory or play
if the user knows that ostree is being used and wants to skip the check.
Or, the user is concerned about the performance hit for ostree detection
on non-ostree systems, and sets `__$ROLENAME_is_ostree: false` to skip
the check.
The flag `__$ROLENAME_is_ostree` can also be used in the role or tests to
include or exclude tasks from being run on ostree systems.

This fix also improves error reporting in the `get_ostree_data.sh` script
when included roles cannot be found.

Signed-off-by: Rich Megginson <rmeggins@redhat.com>
This commit is contained in:
Rich Megginson 2023-11-20 13:46:10 -07:00 committed by Richard Megginson
parent c7a31e7079
commit 0c590cdf5a
34 changed files with 111 additions and 55 deletions

View file

@ -25,5 +25,3 @@ exclude_paths:
- examples/roles/
mock_roles:
- linux-system-roles.network
mock_modules:
- ansible.utils.update_fact

View file

@ -2,7 +2,6 @@
set -euo pipefail
role_collection_dir="${ROLE_COLLECTION_DIR:-fedora/linux_system_roles}"
ostree_dir="${OSTREE_DIR:-"$(dirname "$(realpath "$0")")"}"
if [ -z "${4:-}" ] || [ "${1:-}" = help ] || [ "${1:-}" = -h ]; then
@ -29,7 +28,7 @@ if [ "$pkgtype" = testing ]; then
fi
get_rolepath() {
local ostree_dir role rolesdir roles_parent_dir
local ostree_dir role rolesdir roles_parent_dir coll_path pth
ostree_dir="$1"
role="$2"
roles_parent_dir="$(dirname "$(dirname "$ostree_dir")")"
@ -47,16 +46,22 @@ get_rolepath() {
fi
done
# look elsewhere
if [ -n "${ANSIBLE_COLLECTIONS_PATHS:-}" ]; then
for pth in ${ANSIBLE_COLLECTIONS_PATHS//:/ }; do
rolesdir="$pth/ansible_collections/$role_collection_dir/roles/$role/.ostree"
if [ -d "$rolesdir" ]; then
echo "$rolesdir"
return 0
fi
coll_path="${ANSIBLE_COLLECTIONS_PATH:-}"
if [ -z "$coll_path" ]; then
coll_path="${ANSIBLE_COLLECTIONS_PATHS:-}"
fi
if [ -n "${coll_path}" ]; then
for pth in ${coll_path//:/ }; do
for rolesdir in "$pth"/ansible_collections/*/*_system_roles/roles/"$role"/.ostree; do
if [ -d "$rolesdir" ]; then
echo "$rolesdir"
return 0
fi
done
done
fi
return 1
1>&2 echo ERROR - could not find role "$role" - please use ANSIBLE_COLLECTIONS_PATH
exit 2
}
get_packages() {
@ -75,6 +80,10 @@ get_packages() {
roles="$(cat "$rolefile")"
for role in $roles; do
rolepath="$(get_rolepath "$ostree_dir" "$role")"
if [ -z "$rolepath" ]; then
1>&2 echo ERROR - could not find role "$role" - please use ANSIBLE_COLLECTIONS_PATH
exit 2
fi
get_packages "$rolepath"
done
fi

View file

@ -1,4 +1,3 @@
---
collections:
- name: ansible.posix
- name: ansible.utils

View file

@ -31,6 +31,8 @@
package:
name: "{{ network_packages }}"
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
when:
- not network_packages is subset(ansible_facts.packages.keys())
register: __network_package_install
@ -41,6 +43,8 @@
- NetworkManager
- nmstate
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
when:
- network_state is defined
- ansible_distribution == 'Fedora' and
@ -53,6 +57,8 @@
name:
- python3-libnmstate
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
when:
- network_state is defined
- ansible_distribution == 'Fedora' and

View file

@ -7,23 +7,17 @@
difference(ansible_facts.keys() | list) | length > 0
no_log: true
- name: Ensure correct package manager for ostree systems
vars:
ostree_pkg_mgr: ansible.posix.rhel_rpm_ostree
ostree_booted_file: /run/ostree-booted
when: ansible_facts.pkg_mgr | d("") != ostree_pkg_mgr
- name: Determine if system is ostree and set flag
when: not __network_is_ostree is defined
block:
- name: Check if system is ostree
stat:
path: "{{ ostree_booted_file }}"
path: /run/ostree-booted
register: __ostree_booted_stat
- name: Set package manager to use for ostree
ansible.utils.update_fact:
updates:
- path: ansible_facts.pkg_mgr
value: "{{ ostree_pkg_mgr }}"
when: __ostree_booted_stat.stat.exists
- name: Set flag to indicate system is ostree
set_fact:
__network_is_ostree: "{{ __ostree_booted_stat.stat.exists }}"
- name: Check which services are running
service_facts:

View file

@ -21,6 +21,8 @@ GET_NM_VERSION = """
package:
name: NetworkManager
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Get package info
package_facts:
- name: Get NetworkManager version

View file

@ -13,6 +13,8 @@
package:
state: present
name: "{{ rpmdependencies }}"
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Install Pytest
command: "pip3 install pytest"
@ -151,6 +153,8 @@
package:
name: network-scripts
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Run pytest with initscripts
command: >
pytest

View file

@ -21,6 +21,8 @@
package:
name: ethtool
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Test ethtool coalesce settings
block:
- name: >-

View file

@ -42,6 +42,8 @@
package:
name: iputils
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: "TEST: I can ping the EAP server"
command: ping -c1 203.0.113.1
changed_when: false

View file

@ -8,6 +8,8 @@
package:
name: NetworkManager
state: latest # noqa package-latest
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Restart NetworkManager
service:
name: NetworkManager

View file

@ -28,6 +28,8 @@
package:
name: dbus-tools
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
# create test profile
- name: Include network role
include_role:

View file

@ -27,6 +27,8 @@
package:
name: ethtool
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Test ethtool coalesce settings
block:

View file

@ -27,6 +27,8 @@
package:
name: ethtool
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Test ethtool features settings

View file

@ -27,6 +27,8 @@
package:
name: ethtool
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Test ethtool ring settings
block:

View file

@ -83,6 +83,8 @@
package:
name: iputils
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Test gateway can be pinged
command: ping6 -c1 2001:db8::1
when:

View file

@ -145,6 +145,8 @@
package:
name: systemd-resolved
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
when:
- ansible_distribution_major_version | int > 8

View file

@ -5,7 +5,7 @@
tasks:
- name: Check if rpm ostree system - cannot test
meta: end_host
when: ansible_facts.pkg_mgr == "ansible.posix.rhel_rpm_ostree"
when: __network_is_ostree | d(false)
- name: Remove the NetworkManager-team package
package:

View file

@ -5,7 +5,7 @@
tasks:
- name: Check if rpm ostree system - cannot test
meta: end_host
when: ansible_facts.pkg_mgr == "ansible.posix.rhel_rpm_ostree"
when: __network_is_ostree | d(false)
- name: Remove the NetworkManager-wifi package
package:

View file

@ -4,11 +4,15 @@
package:
name: dnsmasq
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Install pgrep, sysctl
package:
name: procps
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
when:
- ansible_os_family == 'RedHat'
- ansible_distribution_major_version is version('6', '<=')
@ -17,6 +21,8 @@
package:
name: procps-ng
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
when:
- ansible_os_family == 'RedHat'
- ansible_distribution_major_version is version('7', '>=')

View file

@ -13,23 +13,17 @@
- distribution_version
- os_family
- name: Ensure correct package manager for ostree systems
vars:
ostree_pkg_mgr: ansible.posix.rhel_rpm_ostree
ostree_booted_file: /run/ostree-booted
when: ansible_facts.pkg_mgr | d("") != ostree_pkg_mgr
- name: Determine if system is ostree and set flag
when: not __network_is_ostree is defined
block:
- name: Check if system is ostree
stat:
path: "{{ ostree_booted_file }}"
path: /run/ostree-booted
register: __ostree_booted_stat
- name: Set package manager to use for ostree
ansible.utils.update_fact:
updates:
- path: ansible_facts.pkg_mgr
value: "{{ ostree_pkg_mgr }}"
when: __ostree_booted_stat.stat.exists
- name: Set flag to indicate system is ostree
set_fact:
__network_is_ostree: "{{ __ostree_booted_stat.stat.exists }}"
- name: Fix CentOS6 Base repo
copy:
@ -58,4 +52,4 @@
- ansible_distribution_major_version == '6'
- name: Include the task 'enable_epel.yml'
include_tasks: enable_epel.yml
when: ansible_facts["pkg_mgr"] != "ansible.posix.rhel_rpm_ostree"
when: not __network_is_ostree | d(false)

View file

@ -17,6 +17,8 @@
package:
name: iproute
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
# veth
- name: Create veth interface {{ interface }}

View file

@ -1,10 +1,14 @@
# SPDX-License-Identifier: BSD-3-Clause
---
- name: Debug
debug:
msg: facts {{ ansible_facts | to_nice_json }}
# This task can be removed once the RHEL-8.5 is not tested anymore
- name: Install hostapd via CentOS Stream
command: dnf -y install http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os/Packages/hostapd-2.10-1.el8.x86_64.rpm # noqa yaml[line-length]
when:
- ansible_distribution_version | float < 8.6
- ansible_distribution_version is version('8.6', '<')
- ansible_distribution_major_version == '8'
- ansible_distribution == 'RedHat'
changed_when: false
@ -13,6 +17,8 @@
package:
name: hostapd
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Create directory for test certificates
file:

View file

@ -7,6 +7,8 @@
- NetworkManager
- wpa_supplicant
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Ensure NetworkManager is running
service:

View file

@ -6,6 +6,8 @@
- NetworkManager
- wpa_supplicant
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Check if can test on CentOS 8 and setup if possible
when:
@ -16,7 +18,7 @@
# if using rpm ostree - so just skip this test
- name: Check if rpm ostree system - cannot test
meta: end_host
when: ansible_facts.pkg_mgr == "ansible.posix.rhel_rpm_ostree"
when: __network_is_ostree | d(false)
# yamllint disable rule:line-length
# Even though hostapd can be installed via EPEL 8, Opportunistic Wireless Encryption

View file

@ -6,6 +6,8 @@
- NetworkManager
- wpa_supplicant
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Configure CentOS 8 system for testing, if possible
when:
@ -16,7 +18,7 @@
# if using rpm ostree - so just skip this test
- name: Check if rpm ostree system - cannot test
meta: end_host
when: ansible_facts.pkg_mgr == "ansible.posix.rhel_rpm_ostree"
when: __network_is_ostree | d(false)
# yamllint disable rule:line-length
# Even though hostapd can be installed via EPEL 8, Simultaneous Authentication

View file

@ -33,6 +33,8 @@
package:
name: openssl
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Hash cacert
command: openssl x509 -hash -noout
-in /etc/pki/tls/my_ca_certs/cacert.pem
@ -77,6 +79,8 @@
package:
name: iputils
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: "TEST: I can ping the EAP server"
command: ping -c1 203.0.113.1
changed_when: false

View file

@ -7,23 +7,17 @@
type: veth
name: Test change indication on repeat run
tasks:
- name: Ensure correct package manager for ostree systems
vars:
ostree_pkg_mgr: ansible.posix.rhel_rpm_ostree
ostree_booted_file: /run/ostree-booted
when: ansible_facts.pkg_mgr | d("") != ostree_pkg_mgr
- name: Determine if system is ostree and set flag
when: not __network_is_ostree is defined
block:
- name: Check if system is ostree
stat:
path: "{{ ostree_booted_file }}"
path: /run/ostree-booted
register: __ostree_booted_stat
- name: Set package manager to use for ostree
ansible.utils.update_fact:
updates:
- path: ansible_facts.pkg_mgr
value: "{{ ostree_pkg_mgr }}"
when: __ostree_booted_stat.stat.exists
- name: Set flag to indicate system is ostree
set_fact:
__network_is_ostree: "{{ __ostree_booted_stat.stat.exists }}"
- name: Include the task 'manage_test_interface.yml'
include_tasks: tasks/manage_test_interface.yml
vars:

View file

@ -24,6 +24,8 @@
package:
name: NetworkManager
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Get package info
package_facts:
- name: Get NetworkManager version

View file

@ -24,6 +24,8 @@
package:
name: NetworkManager
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Get package info
package_facts:
- name: Get NetworkManager version

View file

@ -24,6 +24,8 @@
package:
name: NetworkManager
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Get package info
package_facts:
- name: Get NetworkManager version

View file

@ -24,6 +24,8 @@
package:
name: NetworkManager
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Get package info
package_facts:
- name: Get NetworkManager version

View file

@ -24,6 +24,8 @@
package:
name: NetworkManager
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Get package info
package_facts:
- name: Get NetworkManager version

View file

@ -15,6 +15,8 @@
package:
name: NetworkManager
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Get package info
package_facts:
- name: Get NetworkManager version

View file

@ -10,6 +10,8 @@
package:
name: "{{ item }}"
state: present
use: "{{ (__network_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
# Ignore error because some package names might not be available
ignore_errors: true # noqa ignore-errors
loop: