Skip to content

Commit 9379040

Browse files
committed
feat: support for ostree systems
Feature: Allow running and testing the role with ostree managed nodes. Reason: We have users who want to use the role to manage ostree systems. Result: Users can use the role to manage ostree managed nodes. Signed-off-by: Rich Megginson <[email protected]>
1 parent 43eb12c commit 9379040

32 files changed

+343
-3
lines changed

.ansible-lint

+2
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,5 @@ exclude_paths:
2424
- examples/roles/
2525
mock_roles:
2626
- linux-system-roles.timesync
27+
mock_modules:
28+
- ansible.utils.update_fact

.ostree/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*NOTE*: The `*.txt` files are used by `get_ostree_data.sh` to create the lists
2+
of packages, and to find other system roles used by this role. DO NOT use them
3+
directly.

.ostree/get_ostree_data.sh

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
role_collection_dir="${ROLE_COLLECTION_DIR:-fedora/linux_system_roles}"
6+
ostree_dir="${OSTREE_DIR:-"$(dirname "$(realpath "$0")")"}"
7+
8+
if [ -z "${4:-}" ] || [ "${1:-}" = help ] || [ "${1:-}" = -h ]; then
9+
cat <<EOF
10+
Usage: $0 packages [runtime|testing] DISTRO-MAJOR[.MINOR] [json|yaml|raw|toml]
11+
The script will use the packages and roles files in $ostree_dir to
12+
construct the list of packages needed to build the ostree image. The script
13+
will output the list of packages in the given format
14+
- json is a JSON list like ["pkg1","pkg2",....,"pkgN"]
15+
- yaml is the YAML list format
16+
- raw is the list of packages, one per line
17+
- toml is a list of [[packages]] elements as in https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html-single/composing_installing_and_managing_rhel_for_edge_images/index#creating-an-image-builder-blueprint-for-a-rhel-for-edge-image-using-the-command-line-interface_composing-a-rhel-for-edge-image-using-image-builder-command-line
18+
The DISTRO-MAJOR.MINOR is the same format used by Ansible for distribution e.g. CentOS-8, RedHat-8.9, etc.
19+
EOF
20+
exit 1
21+
fi
22+
category="$1"
23+
pkgtype="$2"
24+
distro_ver="$3"
25+
format="$4"
26+
pkgtypes=("$pkgtype")
27+
if [ "$pkgtype" = testing ]; then
28+
pkgtypes+=(runtime)
29+
fi
30+
31+
get_rolepath() {
32+
local ostree_dir role rolesdir roles_parent_dir
33+
ostree_dir="$1"
34+
role="$2"
35+
roles_parent_dir="$(dirname "$(dirname "$ostree_dir")")"
36+
rolesdir="$roles_parent_dir/$role/.ostree"
37+
# assumes collection format
38+
if [ -d "$rolesdir" ]; then
39+
echo "$rolesdir"
40+
return 0
41+
fi
42+
# assumes legacy role format like linux-system-roles.$role/
43+
for rolesdir in "$roles_parent_dir"/*-system-roles."$role"/.ostree; do
44+
if [ -d "$rolesdir" ]; then
45+
echo "$rolesdir"
46+
return 0
47+
fi
48+
done
49+
# look elsewhere
50+
if [ -n "${ANSIBLE_COLLECTIONS_PATHS:-}" ]; then
51+
for pth in ${ANSIBLE_COLLECTIONS_PATHS//:/ }; do
52+
rolesdir="$pth/ansible_collections/$role_collection_dir/roles/$role/.ostree"
53+
if [ -d "$rolesdir" ]; then
54+
echo "$rolesdir"
55+
return 0
56+
fi
57+
done
58+
fi
59+
return 1
60+
}
61+
62+
get_packages() {
63+
local ostree_dir pkgtype pkgfile rolefile
64+
ostree_dir="$1"
65+
for pkgtype in "${pkgtypes[@]}"; do
66+
for suff in "" "-$distro" "-${distro}-${major_ver}" "-${distro}-${ver}"; do
67+
pkgfile="$ostree_dir/packages-${pkgtype}${suff}.txt"
68+
if [ -f "$pkgfile" ]; then
69+
cat "$pkgfile"
70+
fi
71+
done
72+
rolefile="$ostree_dir/roles-${pkgtype}.txt"
73+
if [ -f "$rolefile" ]; then
74+
local roles role rolepath
75+
roles="$(cat "$rolefile")"
76+
for role in $roles; do
77+
rolepath="$(get_rolepath "$ostree_dir" "$role")"
78+
get_packages "$rolepath"
79+
done
80+
fi
81+
done | sort -u
82+
}
83+
84+
format_packages_json() {
85+
local comma pkgs pkg
86+
comma=""
87+
pkgs="["
88+
while read -r pkg; do
89+
pkgs="${pkgs}${comma}\"${pkg}\""
90+
comma=,
91+
done
92+
pkgs="${pkgs}]"
93+
echo "$pkgs"
94+
}
95+
96+
format_packages_raw() {
97+
cat
98+
}
99+
100+
format_packages_yaml() {
101+
while read -r pkg; do
102+
echo "- $pkg"
103+
done
104+
}
105+
106+
format_packages_toml() {
107+
while read -r pkg; do
108+
echo "[[packages]]"
109+
echo "name = \"$pkg\""
110+
echo "version = \"*\""
111+
done
112+
}
113+
114+
distro="${distro_ver%%-*}"
115+
ver="${distro_ver##*-}"
116+
if [[ "$ver" =~ ^([0-9]*) ]]; then
117+
major_ver="${BASH_REMATCH[1]}"
118+
else
119+
echo ERROR: cannot parse major version number from version "$ver"
120+
exit 1
121+
fi
122+
123+
"get_$category" "$ostree_dir" | "format_${category}_$format"

.ostree/packages-runtime-CentOS-7.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ntp

.ostree/packages-runtime-RedHat-6.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ntp

.ostree/packages-runtime-RedHat-7.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ntp

.ostree/packages-runtime.txt

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
chrony
2+
linuxptp

.ostree/packages-testing-CentOS-7.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ntp

.ostree/packages-testing-RedHat-6.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ntp

.ostree/packages-testing-RedHat-7.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ntp

.ostree/packages-testing.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
chrony
2+
ethtool
3+
iproute

.sanity-ansible-ignore-2.10.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
plugins/modules/timesync_provider.sh shebang
2+
roles/timesync/.ostree/get_ostree_data.sh shebang!skip

.sanity-ansible-ignore-2.11.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
plugins/modules/timesync_provider.sh shebang
2+
roles/timesync/.ostree/get_ostree_data.sh shebang!skip

.sanity-ansible-ignore-2.12.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
plugins/modules/timesync_provider.sh shebang
2+
roles/timesync/.ostree/get_ostree_data.sh shebang!skip

.sanity-ansible-ignore-2.13.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
plugins/modules/timesync_provider.sh shebang
2+
roles/timesync/.ostree/get_ostree_data.sh shebang!skip

.sanity-ansible-ignore-2.14.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
plugins/modules/timesync_provider.sh shebang
22
plugins/modules/timesync_provider.sh validate-modules:invalid-extension
33
plugins/modules/timesync_provider.sh validate-modules:python-syntax-error
4+
roles/timesync/.ostree/get_ostree_data.sh shebang!skip

.sanity-ansible-ignore-2.15.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
plugins/modules/timesync_provider.sh shebang
22
plugins/modules/timesync_provider.sh validate-modules:invalid-extension
33
plugins/modules/timesync_provider.sh validate-modules:python-syntax-error
4+
roles/timesync/.ostree/get_ostree_data.sh shebang!skip

.sanity-ansible-ignore-2.9.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
plugins/modules/timesync_provider.sh shebang
2+
roles/timesync/.ostree/get_ostree_data.sh shebang!skip

README-ostree.md

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# rpm-ostree
2+
3+
The role supports running on [rpm-ostree](https://coreos.github.io/rpm-ostree/)
4+
systems. The primary issue is that the `/usr` filesystem is read-only, and the
5+
role cannot install packages. Instead, it will just verify that the necessary
6+
packages and any other `/usr` files are pre-installed. The role will change the
7+
package manager to one that is compatible with `rpm-ostree` systems.
8+
9+
## Building
10+
11+
To build an ostree image for a particular operating system distribution and
12+
version, use the script `.ostree/get_ostree_data.sh` to get the list of
13+
packages. If the role uses other system roles, then the script will include the
14+
packages for the other roles in the list it outputs. The list of packages will
15+
be sorted in alphanumeric order.
16+
17+
Usage:
18+
19+
```bash
20+
.ostree/get_ostree_data.sh packages runtime DISTRO-VERSION FORMAT
21+
```
22+
23+
`DISTRO-VERSION` is in the format that Ansible uses for `ansible_distribution`
24+
and `ansible_distribution_version` - for example, `Fedora-38`, `CentOS-8`,
25+
`RedHat-9.4`
26+
27+
`FORMAT` is one of `toml`, `json`, `yaml`, `raw`
28+
29+
* `toml` - each package in a TOML `[[packages]]` element
30+
31+
```toml
32+
[[packages]]
33+
name = "package-a"
34+
version = "*"
35+
[[packages]]
36+
name = "package-b"
37+
version = "*"
38+
...
39+
```
40+
41+
* `yaml` - a YAML list of packages
42+
43+
```yaml
44+
- package-a
45+
- package-b
46+
...
47+
```
48+
49+
* `json` - a JSON list of packages
50+
51+
```json
52+
["package-a","package-b",...]
53+
```
54+
55+
* `raw` - a plain text list of packages, one per line
56+
57+
```bash
58+
package-a
59+
package-b
60+
...
61+
```
62+
63+
What format you choose depends on which image builder you are using. For
64+
example, if you are using something based on
65+
[osbuild-composer](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html-single/composing_installing_and_managing_rhel_for_edge_images/index#creating-an-image-builder-blueprint-for-a-rhel-for-edge-image-using-the-command-line-interface_composing-a-rhel-for-edge-image-using-image-builder-command-line),
66+
you will probably want to use the `toml` output format.

README.md

+17
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@ replaced entirely). The only setting which is preserved is the choice
1919
of provider if `timesync_ntp_provider` is not defined (see the
2020
description of this variable below).
2121

22+
## Requirements
23+
24+
See below
25+
26+
### Collection requirements
27+
28+
In order to manage `rpm-ostree` systems, the role requires modules from external
29+
collections. Use the following command to install them:
30+
31+
```bash
32+
ansible-galaxy collection install -vv -r meta/collection-requirements.yml
33+
```
34+
2235
## Role Variables
2336

2437
The variables that can be passed to this role are as follows:
@@ -181,3 +194,7 @@ into `/var/log/chrony`:
181194
roles:
182195
- linux-system-roles.timesync
183196
```
197+
198+
## rpm-ostree
199+
200+
See README-ostree.md

meta/collection-requirements.yml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# SPDX-License-Identifier: MIT
2+
---
3+
collections:
4+
- ansible.posix
5+
- ansible.utils

tasks/set_vars.yml

+18
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,24 @@
55
when: __timesync_required_facts |
66
difference(ansible_facts.keys() | list) | length > 0
77

8+
- name: Ensure correct package manager for ostree systems
9+
vars:
10+
ostree_pkg_mgr: ansible.posix.rhel_rpm_ostree
11+
ostree_booted_file: /run/ostree-booted
12+
when: ansible_facts.pkg_mgr | d("") != ostree_pkg_mgr
13+
block:
14+
- name: Check if system is ostree
15+
stat:
16+
path: "{{ ostree_booted_file }}"
17+
register: __ostree_booted_stat
18+
19+
- name: Set package manager to use for ostree
20+
ansible.utils.update_fact:
21+
updates:
22+
- path: ansible_facts.pkg_mgr
23+
value: "{{ ostree_pkg_mgr }}"
24+
when: __ostree_booted_stat.stat.exists
25+
826
- name: Set platform/version specific variables
927
include_vars: "{{ lookup('first_found', ffparams) }}"
1028
vars:

tests/tasks/setup.yml

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
# common test setup tasks
3+
- name: Ensure correct package manager for ostree systems
4+
vars:
5+
ostree_pkg_mgr: ansible.posix.rhel_rpm_ostree
6+
ostree_booted_file: /run/ostree-booted
7+
when: ansible_facts.pkg_mgr | d("") != ostree_pkg_mgr
8+
block:
9+
- name: Check if system is ostree
10+
stat:
11+
path: "{{ ostree_booted_file }}"
12+
register: __ostree_booted_stat
13+
14+
- name: Set package manager to use for ostree
15+
ansible.utils.update_fact:
16+
updates:
17+
- path: ansible_facts.pkg_mgr
18+
value: "{{ ostree_pkg_mgr }}"
19+
when: __ostree_booted_stat.stat.exists
20+
21+
- name: Ensure iproute for gathering default_ipv4 fact
22+
package:
23+
name: iproute # for fact gathering for ip facts
24+
state: present
25+
26+
- name: Ensure ansible_facts used by test
27+
setup:
28+
gather_subset: "{{ __required_facts_subsets }}"
29+
when: __required_facts |
30+
difference(ansible_facts.keys() | list) | length > 0
31+
vars:
32+
__required_facts:
33+
- default_ipv4
34+
- distribution
35+
- distribution_major_version
36+
- distribution_version
37+
- os_family
38+
__required_facts_subsets: "{{ ['!all', '!min'] + __required_facts }}"
39+
40+
- name: Debug
41+
debug:
42+
msg: facts {{ ansible_facts | to_nice_json }}
43+
44+
- name: Skip test on ostree systems if unsupported
45+
meta: end_host
46+
when:
47+
- __timesync_ostree_unsupported | d(false)
48+
- ansible_facts.pkg_mgr | d() == "ansible.posix.rhel_rpm_ostree"

tests/tests_ntp_provider1.yml

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
- linux-system-roles.timesync
99

1010
pre_tasks:
11+
- name: Common test setup tasks
12+
include_tasks: tasks/setup.yml
13+
vars:
14+
__timesync_ostree_unsupported: true
15+
1116
- name: Remove provider packages
1217
check_mode: false
1318
tags: tests::setup

tests/tests_ntp_provider2.yml

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
- linux-system-roles.timesync
99

1010
pre_tasks:
11+
- name: Common test setup tasks
12+
include_tasks: tasks/setup.yml
13+
vars:
14+
__timesync_ostree_unsupported: true
15+
1116
- name: Remove the install ntp
1217
check_mode: false
1318
tags: tests::setup

tests/tests_ntp_provider3.yml

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
- linux-system-roles.timesync
99

1010
pre_tasks:
11+
- name: Common test setup tasks
12+
include_tasks: tasks/setup.yml
13+
vars:
14+
__timesync_ostree_unsupported: true
15+
1116
- name: Remove then install chrony
1217
check_mode: false
1318
tags: tests::setup

0 commit comments

Comments
 (0)