Repository: SSSD/sssd-ci-containers
Pull request #117: provision: Install client packages to overlay in image mode
Author: login: jakub-vavra-cz
Created: 2025-02-05T15:24:46Z | Merged: 2025-04-04T12:42:04Z

RHEL image mode does not allow to install packages using dnf nor yum.
We need to use rpm-ostree to install them in the overlay.
This change installs a limited number of packages needed 
on the client as test dependencies.
Move /data and /enrollment under /var as root is read only.
Skip smart-card setup when on rpm-ostree.


Diff:
diff --git a/src/ansible/filter_plugins/distro.py b/src/ansible/filter_plugins/distro.py
index 4068de3f..d6bb304f 100644
--- a/src/ansible/filter_plugins/distro.py
+++ b/src/ansible/filter_plugins/distro.py
@@ -4,7 +4,7 @@ def filters(self):
             'distro_includes': self.distro_includes
         }
 
-    def distro_includes(self, distro, version):
+    def distro_includes(self, distro, version, extra=""):
         """ Create list of distribution specific include files. """
         min_version = 1
         if distro.lower() == 'fedora':
@@ -12,8 +12,8 @@ def distro_includes(self, distro, version):
         elif distro.lower() == 'centos':
             min_version = 8
 
-        out = [f'{distro}.yml']
-        out.extend([ f'{distro}{x}.yml' for x in range(min_version, int(version) + 1) ])
+        out = [f'{distro}{extra}.yml']
+        out.extend([ f'{distro}{x}{extra}.yml' for x in range(min_version, int(version) + 1) ])
         out.reverse()
 
         return out
diff --git a/src/ansible/roles/client/tasks/enroll_AD.yml b/src/ansible/roles/client/tasks/enroll_AD.yml
index 1e323751..802ea098 100644
--- a/src/ansible/roles/client/tasks/enroll_AD.yml
+++ b/src/ansible/roles/client/tasks/enroll_AD.yml
@@ -3,7 +3,7 @@
   set_fact:
     ad_domain: "{{ '.'.join(groups.ad.0.split('.')[1:]) }}"
     safe_password: "{{ service.ad.safe_password }}"
-    ad_keytab: /enrollment/{{ '.'.join(groups.ad.0.split('.')[1:]) }}.keytab
+    ad_keytab: /var/enrollment/{{ '.'.join(groups.ad.0.split('.')[1:]) }}.keytab
 
 - name: Stat {{ ad_keytab }} to detect that we are already joined to AD
   stat:
diff --git a/src/ansible/roles/client/tasks/enroll_IPA.yml b/src/ansible/roles/client/tasks/enroll_IPA.yml
index 3767b136..589d3c62 100644
--- a/src/ansible/roles/client/tasks/enroll_IPA.yml
+++ b/src/ansible/roles/client/tasks/enroll_IPA.yml
@@ -3,7 +3,7 @@
   set_fact:
     ipa_domain: "{{ hostvars[groups.ipa.0]['ipa_domain'] }}"
     ipa_password: "{{ hostvars[groups.ipa.0].ansible_password | default(service.ipa.password) }}"
-    ipa_keytab: /enrollment/{{ hostvars[groups.ipa.0]['ipa_domain'] }}.keytab
+    ipa_keytab: /var/enrollment/{{ hostvars[groups.ipa.0]['ipa_domain'] }}.keytab
 
 - name: Run ipa-client-install
   shell: |
diff --git a/src/ansible/roles/client/tasks/enroll_samba.yml b/src/ansible/roles/client/tasks/enroll_samba.yml
index d5ea3dcf..f1ad6d9d 100644
--- a/src/ansible/roles/client/tasks/enroll_samba.yml
+++ b/src/ansible/roles/client/tasks/enroll_samba.yml
@@ -3,7 +3,7 @@
   set_fact:
     samba_domain: "{{ hostvars[groups.samba.0]['samba_domain'] }}"
     samba_password: "{{ hostvars[groups.samba.0].ansible_password | default(service.samba.password) }}"
-    samba_keytab: /enrollment/{{ hostvars[groups.samba.0]['samba_domain'] }}.keytab
+    samba_keytab: /var/enrollment/{{ hostvars[groups.samba.0]['samba_domain'] }}.keytab
 
 - name: Stat {{ samba_keytab }} to detect that we are already joined
   stat:
diff --git a/src/ansible/roles/client/tasks/main.yml b/src/ansible/roles/client/tasks/main.yml
index 7e4cf272..0534a1f5 100644
--- a/src/ansible/roles/client/tasks/main.yml
+++ b/src/ansible/roles/client/tasks/main.yml
@@ -3,14 +3,30 @@
     domains: []
     client_fqdn: "{{ inventory_hostname }}"
 
-- name: Create /enrollment directory
+- name: Check if we are running in image mode
+  stat:
+    path: /usr/bin/rpm-ostree
+  register: rpm_ostree
+
+- name: Create /var/enrollment directory
   file:
-    path: /enrollment
+    path: /var/enrollment
     state: directory
     owner: root
     group: root
     mode: '0700'
 
+# Backward compatibility symlink
+- name: Create symlink /enrollment to /var/enrollment
+  ansible.builtin.file:
+    src: '/var/enrollment'
+    dest: '/enrollment'
+    state: link
+    owner: root
+    group: root
+  when:
+  - not rpm_ostree.stat.exists
+
 - name: Join IPA domain
   ansible.builtin.include_tasks:
     file: enroll_IPA.yml
@@ -63,11 +79,11 @@
     group: root
     mode: 0644
 
-- name: Set SELinux label for /enrollment
+- name: Set SELinux label for /var/enrollment
   shell: |
     if selinuxenabled; then
-      semanage fcontext -a -t etc_t "/enrollment(/.*)*"
-      restorecon -R -v /enrollment
+      semanage fcontext -a -t etc_t "/var/enrollment(/.*)*"
+      restorecon -R -v /var/enrollment
     else
       exit 0
     fi
diff --git a/src/ansible/roles/client/templates/sssd.conf b/src/ansible/roles/client/templates/sssd.conf
index 0d6d40b0..054a89c9 100644
--- a/src/ansible/roles/client/templates/sssd.conf
+++ b/src/ansible/roles/client/templates/sssd.conf
@@ -7,7 +7,7 @@ domains = {{ ", ".join(domains) }}
 id_provider = ldap
 ldap_uri = _srv_
 ldap_tls_reqcert = demand
-ldap_tls_cacert = /data/certs/ca.crt
+ldap_tls_cacert = /var/data/certs/ca.crt
 dns_discovery_domain = {{ service.ldap.domain }}
 use_fully_qualified_names = true
 {% endif %}
diff --git a/src/ansible/roles/common/tasks/main.yml b/src/ansible/roles/common/tasks/main.yml
index 481d3e96..454ee875 100644
--- a/src/ansible/roles/common/tasks/main.yml
+++ b/src/ansible/roles/common/tasks/main.yml
@@ -2,11 +2,18 @@
   set_fact:
     data_path: '{{ role_path }}/../../../../data'
 
+- name: Check if we are running in image mode
+  stat:
+    path: /usr/bin/rpm-ostree
+  register: rpm_ostree
+
 - name: Set /usr/bin/python to python3
   alternatives:
     name: python
     link: /usr/bin/python
     path: /usr/bin/python3
+  when:
+  - not rpm_ostree.stat.exists
 
 - name: Create /etc/sudoers
   template:
@@ -16,30 +23,41 @@
     group: root
     mode: 0600
 
-- name: Create /data
+- name: Create /var/data
   file:
-    path: '/data'
+    path: '/var/data'
     state: directory
     mode: 0700
 
+# Backward compatibility symlink
+- name: Create symlink /data /var/data
+  ansible.builtin.file:
+    src: '/var/data'
+    dest: '/data'
+    state: link
+    owner: root
+    group: root
+  when:
+  - not rpm_ostree.stat.exists
+
 - name: Copy common data
   synchronize:
     src: '{{ data_path }}/'
-    dest: /data/
+    dest: /var/data/
 
 # synchronize rsync option --chown was ignored for some reason
-- name: Set correct permissions on /data
+- name: Set correct permissions on /var/data
   shell: |
-    chown -R root:root /data
-    chmod -R 0755 /data
-    chmod 0600 $(find /data -type f)
-    chmod 0644 /data/certs/*.crt
+    chown -R root:root /var/data
+    chmod -R 0755 /var/data
+    chmod 0600 $(find /var/data -type f)
+    chmod 0644 /var/data/certs/*.crt
 
-- name: Set SELinux label for /data
+- name: Set SELinux label for /var/data
   shell: |
     if selinuxenabled; then
-      semanage fcontext -a -t etc_t "/data(/.*)*"
-      restorecon -R -v /data
+      semanage fcontext -a -t etc_t "/var/data(/.*)*"
+      restorecon -R -v /var/data
     else
       exit 0
     fi
@@ -125,7 +143,7 @@
 
 - name: Copy CA certificate to local pki anchors
   copy:
-    src: /data/certs/ca.crt
+    src: /var/data/certs/ca.crt
     dest: "{{ ca_trust_dir }}"
     remote_src: yes
 
diff --git a/src/ansible/roles/firewall/tasks/main.yml b/src/ansible/roles/firewall/tasks/main.yml
index 47ed3092..1d5f4d73 100644
--- a/src/ansible/roles/firewall/tasks/main.yml
+++ b/src/ansible/roles/firewall/tasks/main.yml
@@ -1,9 +1,14 @@
+# Workaround for image mode where firewalld goes haywire after installation
+- name: Reload dbus service
+  ansible.builtin.systemd_service:
+    name: dbus
+    state: reloaded
+
 - name: Start firewalld
-  service:
+  ansible.builtin.systemd_service:
     name: firewalld
     enabled: yes
-    state: started
+    state: restarted
 
 - name: Set default firewalld zone to trusted
-  shell: |
-    firewall-cmd --set-default-zone=trusted
+  command: firewall-cmd --set-default-zone=trusted
diff --git a/src/ansible/roles/ipa/tasks/main.yml b/src/ansible/roles/ipa/tasks/main.yml
index 186cdd8a..db36452f 100644
--- a/src/ansible/roles/ipa/tasks/main.yml
+++ b/src/ansible/roles/ipa/tasks/main.yml
@@ -41,16 +41,16 @@
     install-ipa --external-ca
 
     openssl x509 -days 7200 -req                                 \
-      -extfile /data/configs/openssl_sign_ca.ext                 \
-      -CA "/data/certs/ca.crt"                                   \
-      -CAkey "/data/certs/ca.key"                                \
+      -extfile /var/data/configs/openssl_sign_ca.ext                 \
+      -CA "/var/data/certs/ca.crt"                                   \
+      -CAkey "/var/data/certs/ca.key"                                \
       --CAcreateserial                                           \
       -in "/root/ipa.csr"                                        \
       -out "/root/ipa.crt"
 
     install-ipa                                                  \
       --external-cert-file=/root/ipa.crt                         \
-      --external-cert-file=/data/certs/ca.crt
+      --external-cert-file=/var/data/certs/ca.crt
   args:
     creates: /etc/ipa/default.conf
 
diff --git a/src/ansible/roles/keycloak/tasks/main.yml b/src/ansible/roles/keycloak/tasks/main.yml
index a241200c..4b1fb1c3 100644
--- a/src/ansible/roles/keycloak/tasks/main.yml
+++ b/src/ansible/roles/keycloak/tasks/main.yml
@@ -30,26 +30,26 @@
     extra_opts:
     - --strip-components=1
 
-- name: Change ownership of files in /data/certs
+- name: Change ownership of files in /var/data/certs
   file:
-    path: /data/certs/master.keycloak.test.key
+    path: /var/data/certs/master.keycloak.test.key
     mode: 0644
 
 - name: Add CA certificate to keystore
   shell: |
     keytool -noprompt -import \
-      -keystore /data/certs/master.keycloak.test.keystore \
-      -file /data/certs/ca.crt \
+      -keystore /var/data/certs/master.keycloak.test.keystore \
+      -file /var/data/certs/ca.crt \
       -alias ca.crt \
       -trustcacerts -storepass {{ service.keycloak.admin_password }}
   args:
-    creates: /data/certs/master.keycloak.test.keystore
+    creates: /var/data/certs/master.keycloak.test.keystore
 
 - name: Add Keycloak certificate to keystore
   shell: |
     keytool -noprompt -import \
-      -keystore /data/certs/master.keycloak.test.keystore \
-      -file /data/certs/master.keycloak.test.crt \
+      -keystore /var/data/certs/master.keycloak.test.keystore \
+      -file /var/data/certs/master.keycloak.test.crt \
       -alias master.keycloak.test.crt \
       -trustcacerts -storepass {{ service.keycloak.admin_password }}
 
@@ -59,9 +59,9 @@
     export KEYCLOAK_ADMIN=admin
     export KEYCLOAK_ADMIN_PASSWORD={{ service.keycloak.admin_password }}
     export KC_HOSTNAME=$(hostname):8443
-    export KC_HTTPS_CERTIFICATE_FILE=/data/certs/master.keycloak.test.crt
-    export KC_HTTPS_CERTIFICATE_KEY_FILE=/data/certs/master.keycloak.test.key
-    export KC_HTTPS_TRUST_STORE_FILE=/data/certs/master.keycloak.test.keystore
+    export KC_HTTPS_CERTIFICATE_FILE=/var/data/certs/master.keycloak.test.crt
+    export KC_HTTPS_CERTIFICATE_KEY_FILE=/var/data/certs/master.keycloak.test.key
+    export KC_HTTPS_TRUST_STORE_FILE=/var/data/certs/master.keycloak.test.keystore
     export KC_HTTPS_TRUST_STORE_PASSWORD={{ service.keycloak.admin_password }}
     export KC_HTTPS_TRUST_STORE_TYPE=JKS
     export KC_HTTP_RELATIVE_PATH=/auth
@@ -74,9 +74,9 @@
       KEYCLOAK_ADMIN=admin
       KEYCLOAK_ADMIN_PASSWORD={{ service.keycloak.admin_password }}
       KC_HOSTNAME={{ inventory_hostname }}
-      KC_HTTPS_CERTIFICATE_FILE=/data/certs/master.keycloak.test.crt
-      KC_HTTPS_CERTIFICATE_KEY_FILE=/data/certs/master.keycloak.test.key
-      KC_HTTPS_TRUST_STORE_FILE=/data/certs/master.keycloak.test.keystore
+      KC_HTTPS_CERTIFICATE_FILE=/var/data/certs/master.keycloak.test.crt
+      KC_HTTPS_CERTIFICATE_KEY_FILE=/var/data/certs/master.keycloak.test.key
+      KC_HTTPS_TRUST_STORE_FILE=/var/data/certs/master.keycloak.test.keystore
       KC_HTTPS_TRUST_STORE_PASSWORD={{ service.keycloak.admin_password }}
       KC_HTTPS_TRUST_STORE_TYPE=JKS
       KC_HTTP_RELATIVE_PATH=/auth
diff --git a/src/ansible/roles/ldap/tasks/main.yml b/src/ansible/roles/ldap/tasks/main.yml
index 3b04aeb9..ae2489dc 100644
--- a/src/ansible/roles/ldap/tasks/main.yml
+++ b/src/ansible/roles/ldap/tasks/main.yml
@@ -14,9 +14,9 @@
 
 - name: Install ldap certificate
   shell: |
-    dsconf localhost security ca-certificate add --file /data/certs/ca.crt --name "sssd-ca"
+    dsconf localhost security ca-certificate add --file /var/data/certs/ca.crt --name "sssd-ca"
     dsconf localhost security ca-certificate set-trust-flags "sssd-ca" --flags "CT,,"
-    dsctl localhost tls import-server-key-cert /data/certs/master.ldap.test.crt /data/certs/master.ldap.test.key
+    dsctl localhost tls import-server-key-cert /var/data/certs/master.ldap.test.crt /var/data/certs/master.ldap.test.key
 
 - name: Grant read-only anonymous access
   shell: |
diff --git a/src/ansible/roles/packages/tasks/RedHat-rpm-ostree.yml b/src/ansible/roles/packages/tasks/RedHat-rpm-ostree.yml
new file mode 100644
index 00000000..7ad1b20d
--- /dev/null
+++ b/src/ansible/roles/packages/tasks/RedHat-rpm-ostree.yml
@@ -0,0 +1,77 @@
+- name: Install minimal set of client packages on rpm-ostree
+  command: rpm-ostree install --idempotent --apply-live {{ item }} -y
+  with_items:
+    - bind-utils
+    - expect
+    - firewalld
+    - iproute
+    - iproute-tc
+    - net-tools
+    - openldap-clients
+    - openssh-clients
+    - openssh-server
+    - policycoreutils
+    - policycoreutils-python-utils
+    - python3-pip
+    - sudo
+    - rsync
+    - autofs
+    - augeas
+    - krb5-workstation
+    - '{{ ipa.client }}'
+    - oddjob
+    - oddjob-mkhomedir
+    - ldb-tools
+    - net-tools
+    - tcpdump
+    - wireshark-cli
+    - binutils
+  ignore_errors: yes
+  register: inst
+  failed_when:
+  - 'inst.rc != 0 and "is already requested" not in inst.stderr'
+  when:
+  - "'base_client' in group_names or 'client' in group_names"
+
+# The ansible.posix.rhel_rpm_ostree can only check
+# for presence but can not install anything
+- name: Check sssd packages that should be present and fail when they are missing
+  ansible.posix.rhel_rpm_ostree:
+    name:
+    - adcli
+    - authselect
+    - realmd
+    - sssd-idp
+    - sssd-client
+    - sssd-nfs-idmap
+    - sssd-client
+    - sssd-common
+    - sssd-krb5-common
+    - sssd-common-pac
+    - sssd-ad
+    - sssd-ipa
+    - sssd-krb5
+    - sssd-ldap
+    - sssd-dbus
+    - python3-sssdconfig
+    - sssd-proxy
+    - python3-sss
+    - sssd-tools
+    - sssd
+    - sssd-kcm
+    - sssd-idp
+    - sssd-passkey
+    state: present
+
+# If realmd was installed after polkit it needs to be restarted
+- name: Restart polkit
+  ansible.builtin.systemd_service:
+    name: polkit
+    enabled: yes
+    state: restarted
+
+- name: Restart realmd
+  ansible.builtin.systemd_service:
+    name: realmd
+    enabled: yes
+    state: restarted
diff --git a/src/ansible/roles/packages/tasks/main.yml b/src/ansible/roles/packages/tasks/main.yml
index 11bf8d31..9abd1070 100644
--- a/src/ansible/roles/packages/tasks/main.yml
+++ b/src/ansible/roles/packages/tasks/main.yml
@@ -1,15 +1,31 @@
-- name: 'Include distribution specific package tasks [{{ ansible_distribution }} {{ ansible_distribution_major_version }}]'
-  include_tasks: '{{ include_file }}'
-  loop_control:
-    loop_var: include_file
-  with_first_found:
-  - files: '{{ ansible_distribution | distro_includes(ansible_distribution_major_version) }}'
+- name: Package mode installations
+  block:
+    - name: 'Include distribution specific package tasks [{{ ansible_distribution }} {{ ansible_distribution_major_version }}]'
+      include_tasks: '{{ include_file }}'
+      loop_control:
+        loop_var: include_file
+      with_first_found:
+      - files: '{{ ansible_distribution | distro_includes(ansible_distribution_major_version) }}'
 
-- name: 'Clear package manager cache'
-  shell: |
-    if [ -f /usr/bin/apt ]; then
-      rm -rf /var/lib/apt/lists/*
-    fi
-    if [ -f /usr/bin/dnf ]; then
-      dnf clean all
-    fi
+    - name: 'Clear package manager cache'
+      shell: |
+        if [ -f /usr/bin/apt ]; then
+          rm -rf /var/lib/apt/lists/*
+        fi
+        if [ -f /usr/bin/dnf ]; then
+          dnf clean all
+        fi
+  when: ansible_facts['pkg_mgr'] != "atomic_container"
+
+
+# This is bandaid to run tests in image mode until dnf can take over and install test dependencies.
+- name: Image mode rpm-ostree installations
+  block:
+    - name: 'Include distribution specific tasks (rpm-ostree) [{{ ansible_distribution }} {{ ansible_distribution_major_version }}]'
+      include_tasks: '{{ include_file }}'
+      loop_control:
+        loop_var: include_file
+      with_first_found:
+      - files: '{{ ansible_distribution | distro_includes(ansible_distribution_major_version, "-rpm-ostree") }}'
+        skip: True
+  when: ansible_facts['pkg_mgr'] == "atomic_container"
diff --git a/src/ansible/roles/samba/tasks/main.yml b/src/ansible/roles/samba/tasks/main.yml
index 4eab5da0..53f9a340 100644
--- a/src/ansible/roles/samba/tasks/main.yml
+++ b/src/ansible/roles/samba/tasks/main.yml
@@ -117,9 +117,9 @@
     value: '{{ item.value }}'
     mode: 0600
   with_items:
-  - { name: 'tls keyfile', value: '/data/certs/dc.samba.test.key' }
-  - { name: 'tls certfile', value: '/data/certs/dc.samba.test.crt' }
-  - { name: 'tls cafile', value: '/data/certs/ca.crt' }
+  - { name: 'tls keyfile', value: '/var/data/certs/dc.samba.test.key' }
+  - { name: 'tls certfile', value: '/var/data/certs/dc.samba.test.crt' }
+  - { name: 'tls cafile', value: '/var/data/certs/ca.crt' }
 
 - name: Select authselect winbind profile
   shell: |
diff --git a/src/ansible/roles/ssh_server/tasks/main.yml b/src/ansible/roles/ssh_server/tasks/main.yml
index 6037b58b..0e136c78 100644
--- a/src/ansible/roles/ssh_server/tasks/main.yml
+++ b/src/ansible/roles/ssh_server/tasks/main.yml
@@ -1,6 +1,6 @@
 - name: Check if we have pre-generated key
   ansible.builtin.stat:
-    path: "/data/ssh-keys/hosts/{{ inventory_hostname }}.ecdsa_key"
+    path: "/var/data/ssh-keys/hosts/{{ inventory_hostname }}.ecdsa_key"
   register: stat_ecdsa_key
 
 - name: Configure SSH daemon with pre-generated hostkey
diff --git a/src/ansible/roles/ssh_server/templates/sshd.conf b/src/ansible/roles/ssh_server/templates/sshd.conf
index 2984c59b..9d38ea31 100644
--- a/src/ansible/roles/ssh_server/templates/sshd.conf
+++ b/src/ansible/roles/ssh_server/templates/sshd.conf
@@ -1,5 +1,5 @@
-HostKey /data/ssh-keys/hosts/{{ inventory_hostname }}.ecdsa_key
-HostKey /data/ssh-keys/hosts/{{ inventory_hostname }}.ed25519_key
-HostKey /data/ssh-keys/hosts/{{ inventory_hostname }}.rsa_key
+HostKey /var/data/ssh-keys/hosts/{{ inventory_hostname }}.ecdsa_key
+HostKey /var/data/ssh-keys/hosts/{{ inventory_hostname }}.ed25519_key
+HostKey /var/data/ssh-keys/hosts/{{ inventory_hostname }}.rsa_key
 
 PermitRootLogin yes
diff --git a/src/ansible/roles/virtsmartcard/tasks/main.yml b/src/ansible/roles/virtsmartcard/tasks/main.yml
index 30d8c9ec..67ff0437 100644
--- a/src/ansible/roles/virtsmartcard/tasks/main.yml
+++ b/src/ansible/roles/virtsmartcard/tasks/main.yml
@@ -1,3 +1,12 @@
+- name: Check if we are running in image mode
+  stat:
+    path: /usr/bin/rpm-ostree
+  register: rpm_ostree
+
+- name: End play for host on rpm-ostree with ro /opt
+  meta: end_host
+  when: rpm_ostree.stat.exists
+
 - name: Create virtual card dirs
   file:
     path: "{{ item }}"


Reviews:
user: login: pbrezina
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-26T09:28:05Z
user: login: pbrezina
body: Hi, the patch looks good to me, see minor comments inside.

It would be good, if you could use more smaller commits next time for changes that can be separated. In this case move to /var, package installation.
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-04-03T10:06:19Z
user: login: jakub-vavra-cz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-03T11:52:54Z
user: login: jakub-vavra-cz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-03T11:54:45Z
user: login: pbrezina
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-03T12:22:25Z
user: login: ikerexxe
body: Just some minor comments inline.

Apart from that, are CI failures related to this PR?
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-03T13:23:50Z
user: login: jakub-vavra-cz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-03T13:27:38Z
user: login: jakub-vavra-cz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-03T13:31:31Z
user: login: ikerexxe
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-03T14:12:14Z
user: login: ikerexxe
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-03T14:12:41Z
user: login: jakub-vavra-cz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-04T06:46:01Z
user: login: jakub-vavra-cz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-04T06:46:08Z
user: login: ikerexxe
body: LGTM!
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-04T12:41:39Z

Review comments:
diff_hunk: @@ -16,13 +21,19 @@
   set_fact:
     extended_packageset: "{{ extended_packageset | default('no') }}"
 
+- name: 'Install packages via rpm-ostree'
+  include_tasks: 'rpm-ostree.yml'
+  when: rpm_ostree.stat.exists
path: src/ansible/roles/packages/tasks/Fedora.yml
user: login: pbrezina
body: Maybe change the logic in https://github.com/SSSD/sssd-ci-containers/blob/master/src/ansible/roles/packages/tasks/main.yml#L1 instead of adding all the conditions here?

* if rpm-ostree, include $distro.rpm-ostree.yml
created_at: 2025-02-26T09:28:00Z
author_association: MEMBER
diff_hunk: @@ -1,9 +1,14 @@
+# Workaround for image mode where firewalld is borked after installation
+- name: Reload service httpd, in all cases
path: src/ansible/roles/firewall/tasks/main.yml
user: login: pbrezina
body: Which service do you want to reload? httpd or dbus?
created_at: 2025-04-03T10:01:37Z
author_association: MEMBER
diff_hunk: @@ -1,15 +1,37 @@
-- name: 'Include distribution specific package tasks [{{ ansible_distribution }} {{ ansible_distribution_major_version }}]'
-  include_tasks: '{{ include_file }}'
-  loop_control:
-    loop_var: include_file
-  with_first_found:
-  - files: '{{ ansible_distribution | distro_includes(ansible_distribution_major_version) }}'
-
-- name: 'Clear package manager cache'
-  shell: |
-    if [ -f /usr/bin/apt ]; then
-      rm -rf /var/lib/apt/lists/*
-    fi
-    if [ -f /usr/bin/dnf ]; then
-      dnf clean all
-    fi
+- name: Check if there is rpm-ostree
+  stat:
+    path: /usr/bin/rpm-ostree
+  register: rpm_ostree
path: src/ansible/roles/packages/tasks/main.yml
user: login: pbrezina
body: This is not used.
created_at: 2025-04-03T10:03:07Z
author_association: MEMBER
diff_hunk: @@ -1,9 +1,14 @@
+# Workaround for image mode where firewalld is borked after installation
+- name: Reload service httpd, in all cases
path: src/ansible/roles/firewall/tasks/main.yml
user: login: jakub-vavra-cz
body: fixed
created_at: 2025-04-03T11:52:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,15 +1,37 @@
-- name: 'Include distribution specific package tasks [{{ ansible_distribution }} {{ ansible_distribution_major_version }}]'
-  include_tasks: '{{ include_file }}'
-  loop_control:
-    loop_var: include_file
-  with_first_found:
-  - files: '{{ ansible_distribution | distro_includes(ansible_distribution_major_version) }}'
-
-- name: 'Clear package manager cache'
-  shell: |
-    if [ -f /usr/bin/apt ]; then
-      rm -rf /var/lib/apt/lists/*
-    fi
-    if [ -f /usr/bin/dnf ]; then
-      dnf clean all
-    fi
+- name: Check if there is rpm-ostree
+  stat:
+    path: /usr/bin/rpm-ostree
+  register: rpm_ostree
path: src/ansible/roles/packages/tasks/main.yml
user: login: jakub-vavra-cz
body: deleted
created_at: 2025-04-03T11:54:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,9 +1,14 @@
+# Workaround for image mode where firewalld is borked after installation
path: src/ansible/roles/firewall/tasks/main.yml
user: login: ikerexxe
body: Is `borked` an actual word, or did you mistype it?
created_at: 2025-04-03T12:29:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,78 @@
+- name: Install minimal set of client packages on rpm-ostree
+  command: rpm-ostree install --idempotent --apply-live {{ item }} -y
+  with_items:
+    - bind-utils
+    - expect
+    - firewalld
+    - iproute
+    - iproute-tc
+    - net-tools
+    - openldap-clients
+    - openssh-clients
+    - openssh-server
+    - policycoreutils
+    - policycoreutils-python-utils
+    - python3-pip
+    - sudo
+    - rsync
+    - autofs
+    - augeas
+    - krb5-workstation
+    - '{{ ipa.client }}'
+    - oddjob
+    - oddjob-mkhomedir
+    - ldb-tools
+    - net-tools
+    #- nss-pam-ldapd #TODO!
path: src/ansible/roles/packages/tasks/RedHat-rpm-ostree.yml
user: login: ikerexxe
body: What is the problem here?
created_at: 2025-04-03T12:30:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,9 +1,14 @@
+# Workaround for image mode where firewalld is borked after installation
path: src/ansible/roles/firewall/tasks/main.yml
user: login: jakub-vavra-cz
body: It is a slang for [broken](https://www.urbandictionary.com/define.php?term=borked)
created_at: 2025-04-03T13:27:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,78 @@
+- name: Install minimal set of client packages on rpm-ostree
+  command: rpm-ostree install --idempotent --apply-live {{ item }} -y
+  with_items:
+    - bind-utils
+    - expect
+    - firewalld
+    - iproute
+    - iproute-tc
+    - net-tools
+    - openldap-clients
+    - openssh-clients
+    - openssh-server
+    - policycoreutils
+    - policycoreutils-python-utils
+    - python3-pip
+    - sudo
+    - rsync
+    - autofs
+    - augeas
+    - krb5-workstation
+    - '{{ ipa.client }}'
+    - oddjob
+    - oddjob-mkhomedir
+    - ldb-tools
+    - net-tools
+    #- nss-pam-ldapd #TODO!
path: src/ansible/roles/packages/tasks/RedHat-rpm-ostree.yml
user: login: jakub-vavra-cz
body: The package is custom build as it is no longer in rhel. It has only limited use in testing so I decided to skip it until it is really needed for something.
created_at: 2025-04-03T13:31:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,9 +1,14 @@
+# Workaround for image mode where firewalld is borked after installation
path: src/ansible/roles/firewall/tasks/main.yml
user: login: ikerexxe
body: That explains why I was unable to find it in the dictionary. Do you mind changing it?
created_at: 2025-04-03T14:12:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,78 @@
+- name: Install minimal set of client packages on rpm-ostree
+  command: rpm-ostree install --idempotent --apply-live {{ item }} -y
+  with_items:
+    - bind-utils
+    - expect
+    - firewalld
+    - iproute
+    - iproute-tc
+    - net-tools
+    - openldap-clients
+    - openssh-clients
+    - openssh-server
+    - policycoreutils
+    - policycoreutils-python-utils
+    - python3-pip
+    - sudo
+    - rsync
+    - autofs
+    - augeas
+    - krb5-workstation
+    - '{{ ipa.client }}'
+    - oddjob
+    - oddjob-mkhomedir
+    - ldb-tools
+    - net-tools
+    #- nss-pam-ldapd #TODO!
path: src/ansible/roles/packages/tasks/RedHat-rpm-ostree.yml
user: login: ikerexxe
body: Then, let's remove it altogether. If we need it at some point we can add it later on.
created_at: 2025-04-03T14:12:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,78 @@
+- name: Install minimal set of client packages on rpm-ostree
+  command: rpm-ostree install --idempotent --apply-live {{ item }} -y
+  with_items:
+    - bind-utils
+    - expect
+    - firewalld
+    - iproute
+    - iproute-tc
+    - net-tools
+    - openldap-clients
+    - openssh-clients
+    - openssh-server
+    - policycoreutils
+    - policycoreutils-python-utils
+    - python3-pip
+    - sudo
+    - rsync
+    - autofs
+    - augeas
+    - krb5-workstation
+    - '{{ ipa.client }}'
+    - oddjob
+    - oddjob-mkhomedir
+    - ldb-tools
+    - net-tools
+    #- nss-pam-ldapd #TODO!
path: src/ansible/roles/packages/tasks/RedHat-rpm-ostree.yml
user: login: jakub-vavra-cz
body: done
created_at: 2025-04-04T06:46:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,9 +1,14 @@
+# Workaround for image mode where firewalld is borked after installation
path: src/ansible/roles/firewall/tasks/main.yml
user: login: jakub-vavra-cz
body: Done
created_at: 2025-04-04T06:46:08Z
author_association: CONTRIBUTOR

PR comments:
user: login: pbrezina
created_at: 2025-02-06T13:17:27Z
body: Is rpm-ostree supported in image mode? I know bootc currently uses it internally, but it is going away eventually. The correct way is to install it into the image via containerfile. We can produce bootc enabled images but changing the base image.
author_association: MEMBER
user: login: jakub-vavra-cz
created_at: 2025-02-06T13:56:03Z
body: > Is rpm-ostree supported in image mode? I know bootc currently uses it internally, but it is going away eventually. The correct way is to install it into the image via containerfile. We can produce bootc enabled images but changing the base image.

The ostree is there as a way to install temporary  (until reboot or rollback)  packages and as I understand it is to stay.
I expect to have "tested" packages installed using the blueprint build process (in idmci) and have only test dependencies in the ram overlay.
author_association: CONTRIBUTOR
user: login: jakub-vavra-cz
created_at: 2025-02-25T15:13:19Z
body: @pbrezina : I wonder why is the ci completely red.  The ldap role seems to be failing and for some reason changes to directory structure in role common are completely disregarded in the build. 
author_association: CONTRIBUTOR
user: login: pbrezina
created_at: 2025-02-26T09:29:48Z
body: > @pbrezina : I wonder why is the ci completely red. The ldap role seems to be failing and for some reason changes to directory structure in role common are completely disregarded in the build.

I don't know, let's re-run it. Even the get-matrix failed, so might be just infra issue.
author_association: MEMBER
user: login: pbrezina
created_at: 2025-02-26T09:33:49Z
body: > > Is rpm-ostree supported in image mode? I know bootc currently uses it internally, but it is going away eventually. The correct way is to install it into the image via containerfile. We can produce bootc enabled images but changing the base image.
> 
> The ostree is there as a way to install temporary (until reboot or rollback) packages and as I understand it is to stay.

They want to move away from ostree completely. They also want to implement similar overlay system directly in dnf so similar functionality will still be present. But it will be a long way to get there.

author_association: MEMBER
user: login: jakub-vavra-cz
created_at: 2025-03-28T12:32:50Z
body: @pbrezina Can You please re-review? I moved the code as requested to RedHat-rpm-ostree.yml and got it working again. I assume we will replace it with some dnf when it is available in the future. The failures look like either unrelated ipa issues or using old (not rebuilt base image for layered containers).
author_association: CONTRIBUTOR
user: login: jakub-vavra-cz
created_at: 2025-04-03T12:01:38Z
body: > Hi, the patch looks good to me, see minor comments inside.
> 
> It would be good, if you could use more smaller commits next time for changes that can be separated. In this case move to /var, package installation.

I initially had mutiple commits but I messed up when rebasing doing fixups and detached head so I ended up squashing it together. I addressed the inlines.
author_association: CONTRIBUTOR
user: login: jakub-vavra-cz
created_at: 2025-04-04T06:59:35Z
body: > Just some minor comments inline.
> 
> Apart from that, are CI failures related to this PR?

The ci failures in centos look unrelated as the issues is ipa-samba trust.
The debian-based failures are that ldap is not build from the base image created by the ci but an old one that does not have /data moved to /var/data.
author_association: CONTRIBUTOR