Skip to content

fix: Better support for check mode - #93

Merged
richm merged 6 commits into
linux-system-roles:mainfrom
robertwelch:main
Jul 8, 2026
Merged

fix: Better support for check mode#93
richm merged 6 commits into
linux-system-roles:mainfrom
robertwelch:main

Conversation

@robertwelch

@robertwelch robertwelch commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Enhancement:
Don't fail if check mode.

Reason:
Check mode failed because aide was not yet installed but the failure was about formatting in the "Set AIDE version" task (see below).

TASK [redhat.rhel_system_roles.aide : Set AIDE version]
fatal: [rocky8]: FAILED! => 
    msg: 'Unexpected templating type error occurred on ({{ __output | regex_search(''(?m)^A[iI][dD][eE]
        (\\d.*)$'', ''\\1'') | first }}): ''NoneType'' object is not iterable. ''NoneType''
        object is not iterable'

Result:
Check mode will not fail because the packages are not yet installed. If you launch with check mode and "__aide_install_packages" indicates a change (i.e. packages are not installed), nothing else will run.

Issue Tracker Tickets (Jira or BZ if any):
N/A

Summary by CodeRabbit

  • Bug Fixes
    • Improved check-mode behavior so package installation and AIDE-related actions only run when appropriate.
    • Prevented database initialization, fetch, integrity checks, and updates from running during check mode.
    • Made AIDE setup and service steps depend more reliably on whether required packages are already installed.
    • Kept cron-related configuration and success reporting working as before.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR modifies tasks/main.yml to introduce check-mode-aware gating. Package installation is registered, and an outer block conditions subsequent tasks on check-mode state. Database init, fetch, check, and update tasks add explicit not ansible_check_mode conditions alongside existing feature flags.

Changes

Check-mode gating

Layer / File(s) Summary
Outer gating block and version/service/config setup
tasks/main.yml
Registers the package install result and adds an outer block so AIDE version detection, service enablement, and config template rendering run only when not in check mode or when check mode would not change anything.
Database operation gating
tasks/main.yml
Adds not ansible_check_mode conditions to the AIDE database initialization, fetch, integrity check, and update/fetch tasks, alongside their existing feature flags (aide_init, aide_fetch_db, aide_check, aide_update).
Cron configuration and success reporting
tasks/main.yml
Cron line add/remove logic remains keyed by aide_cron_check, and the success fingerprint task is unchanged, both now running within the new gated block.

Sequence Diagram(s)

flowchart TD
PackageInstall --> RegisterResult
RegisterResult --> CheckModeGate
CheckModeGate -->|"not check_mode or unchanged"| PackagesInstalledBlock
PackagesInstalledBlock --> VersionDetection
PackagesInstalledBlock --> ServiceEnable
PackagesInstalledBlock --> ConfigRender
PackagesInstalledBlock --> DatabaseInit
PackagesInstalledBlock --> DatabaseFetch
PackagesInstalledBlock --> DatabaseCheck
PackagesInstalledBlock --> DatabaseUpdate
PackagesInstalledBlock --> CronConfig
PackagesInstalledBlock --> SuccessReport
Loading

Related issues: None specified.

Related PRs: None specified.

Suggested labels: ansible, check-mode, tasks

Suggested reviewers: None specified.

Poem: 🐰 A rabbit checked the mode with care, / Before it touched a database square. / "Not in check mode?" it did ask, / Then gently tackled every task. / Cron and fingerprint still stand true, / Gated safely, through and through.

🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description Format ⚠️ Warning The description matches Enhancement/Reason/Result, but it lacks the required Signed-off-by section and Assisted-by is optional. Add a Signed-off-by: Name <email> line; keep Enhancement/Reason/Result and optional Issue Tracker/Assisted-by as needed.
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title follows Conventional Commits with a valid type and clear description of the check mode fix.
Description check ✅ Passed The description matches the required template and includes all required sections with enough detail.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tasks/main.yml`:
- Around line 13-160: Add check-mode test coverage for the new gating in
tasks/main.yml, focusing on the top-level “Packages are installed” block and the
nested init/update/fetch/check paths. Create tests that run the role with
ansible_check_mode enabled in both package-present and package-absent states so
the new not ansible_check_mode guards are exercised and stay protected. Use the
existing task names like “Packages are installed”, “Initialize AIDE database”,
and “Update AIDE database and fetch it” to target the relevant behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 47275f3e-e5e7-4a28-8dc2-9a0eff1d525c

📥 Commits

Reviewing files that changed from the base of the PR and between 8ef1897 and 8d419ff.

📒 Files selected for processing (1)
  • tasks/main.yml

Comment thread tasks/main.yml
Comment on lines +13 to +160
register: __aide_install_packages

- name: Get AIDE version
ansible.builtin.command:
cmd: aide --version
register: __aide_version_register
changed_when: false

# assumes the version starts with a digit and goes to the end of the line
- name: Set AIDE version
set_fact:
aide_version: "{{ __output | regex_search('(?m)^A[iI][dD][eE] (\\d.*)$', '\\1') | first }}"
vars:
__output: "{{ __aide_version_register.stdout if __aide_version_register.stdout | length > 0
else __aide_version_register.stderr }}"

- name: Ensure required services are enabled and started
ansible.builtin.service:
name: "{{ item }}"
state: started
enabled: true
loop: "{{ __aide_services }}"

- name: Generate "/etc/{{ __aide_config }}"
ansible.builtin.template:
src: "{{ aide_config_template }}"
dest: "/etc/{{ __aide_config }}"
mode: "0400"
when: aide_config_template is not none

# - name: Print Header
# ansible.builtin.command: head /etc/aide.conf || true

- name: Initialize AIDE database
when: aide_init | bool
- name: Packages are installed
# either run mode or check mode and no changes to packages
when: not ansible_check_mode or (ansible_check_mode and not __aide_install_packages.changed)
block:
- name: Initialize AIDE database
ansible.builtin.command:
cmd: aide --init
changed_when: true

- name: Copy AIDE reference database
ansible.builtin.copy:
remote_src: true
src: "{{ __aide_db_new_name }}"
dest: "{{ __aide_db_name }}"
owner: root
group: root
mode: "0440"
force: true
when: not aide_fetch_db | bool

- name: Remove remote AIDE database file
ansible.builtin.file:
path: "{{ __aide_db_new_name }}"
state: absent
when: not aide_fetch_db | bool

- name: Fetch AIDE database
when: aide_fetch_db | bool
block:
- name: Fetch AIDE database
ansible.builtin.fetch:
src: "{{ __aide_db_new_name }}"
dest: "{{ aide_db_fetch_dir }}"

- name: Remove remote AIDE database file
ansible.builtin.file:
path: "{{ __aide_db_new_name }}"
state: absent

- name: Check AIDE integrity
when: aide_check | bool
block:
- name: Copy AIDE reference database
ansible.builtin.copy:
src: >-
{{ aide_db_fetch_dir }}/{{ inventory_hostname }}{{ __aide_db_new_name }}
dest: "{{ __aide_db_name }}"
owner: root
group: root
mode: "0440"
when: aide_fetch_db | bool

- name: Check against AIDE reference database
- name: Get AIDE version
ansible.builtin.command:
cmd: aide --check
cmd: aide --version
check_mode: false
register: __aide_version_register
changed_when: false

- name: Update AIDE database and fetch it
when: aide_update | bool
block:
- name: Update AIDE database
ansible.builtin.command:
cmd: aide --update
register: __aide_update_result
failed_when: __msg not in __aide_update_result.stdout
changed_when: true
# assumes the version starts with a digit and goes to the end of the line
- name: Set AIDE version
set_fact:
aide_version: "{{ __output | regex_search('(?m)^A[iI][dD][eE] (\\d.*)$', '\\1') | first }}"
vars:
__msg: >-
AIDE found NO differences between database and filesystem. Looks okay!!
__output: "{{ __aide_version_register.stdout if __aide_version_register.stdout | length > 0
else __aide_version_register.stderr }}"

- name: Ensure required services are enabled and started
ansible.builtin.service:
name: "{{ item }}"
state: started
enabled: true
loop: "{{ __aide_services }}"

- name: Generate "/etc/{{ __aide_config }}"
ansible.builtin.template:
src: "{{ aide_config_template }}"
dest: "/etc/{{ __aide_config }}"
mode: "0400"
when: aide_config_template is not none

# - name: Print Header
# ansible.builtin.command: head /etc/aide.conf || true

- name: Fetch AIDE database
ansible.builtin.fetch:
src: "{{ __aide_db_new_name }}"
dest: "{{ aide_db_fetch_dir }}"
- name: Initialize AIDE database
when:
- not ansible_check_mode
- aide_init | bool
block:
- name: Initialize AIDE database
ansible.builtin.command:
cmd: aide --init
changed_when: true

- name: Copy AIDE reference database
ansible.builtin.copy:
remote_src: true
src: "{{ __aide_db_new_name }}"
dest: "{{ __aide_db_name }}"
owner: root
group: root
mode: "0440"
force: true
when: not aide_fetch_db | bool

- name: Remove remote AIDE database file
ansible.builtin.file:
path: "{{ __aide_db_new_name }}"
state: absent
when: not aide_fetch_db | bool

- name: Remove remote AIDE database file
ansible.builtin.file:
path: "{{ __aide_db_new_name }}"
- name: Fetch AIDE database
when:
- not ansible_check_mode
- aide_fetch_db | bool
block:
- name: Fetch AIDE database
ansible.builtin.fetch:
src: "{{ __aide_db_new_name }}"
dest: "{{ aide_db_fetch_dir }}"

- name: Remove remote AIDE database file
ansible.builtin.file:
path: "{{ __aide_db_new_name }}"
state: absent

- name: Check AIDE integrity
when:
- not ansible_check_mode
- aide_check | bool
block:
- name: Copy AIDE reference database
ansible.builtin.copy:
src: >-
{{ aide_db_fetch_dir }}/{{ inventory_hostname }}{{ __aide_db_new_name }}
dest: "{{ __aide_db_name }}"
owner: root
group: root
mode: "0440"
when: aide_fetch_db | bool

- name: Check against AIDE reference database
ansible.builtin.command:
cmd: aide --check
changed_when: false

- name: Update AIDE database and fetch it
when:
- not ansible_check_mode
- aide_update | bool
block:
- name: Update AIDE database
ansible.builtin.command:
cmd: aide --update
register: __aide_update_result
failed_when: __msg not in __aide_update_result.stdout
changed_when: true
vars:
__msg: >-
AIDE found NO differences between database and filesystem. Looks okay!!

- name: Fetch AIDE database
ansible.builtin.fetch:
src: "{{ __aide_db_new_name }}"
dest: "{{ aide_db_fetch_dir }}"

- name: Remove remote AIDE database file
ansible.builtin.file:
path: "{{ __aide_db_new_name }}"
state: absent

- name: Update aide check cron configuration if necessary
ansible.builtin.lineinfile:
path: /etc/crontab
regexp: "^.* root {{ __aide_bin_path }} --check"
line: "{{ aide_cron_interval }} root {{ __aide_bin_path }} --check"
when:
- aide_cron_check is not none
- aide_cron_check | bool

- name: Remove aide check cron configuration if necessary
ansible.builtin.lineinfile:
path: /etc/crontab
state: absent

- name: Update aide check cron configuration if necessary
ansible.builtin.lineinfile:
path: /etc/crontab
regexp: "^.* root {{ __aide_bin_path }} --check"
line: "{{ aide_cron_interval }} root {{ __aide_bin_path }} --check"
when:
- aide_cron_check is not none
- aide_cron_check | bool

- name: Remove aide check cron configuration if necessary
ansible.builtin.lineinfile:
path: /etc/crontab
state: absent
regexp: "^.* root {{ __aide_bin_path }} --check"
when:
- aide_cron_check is not none
- not aide_cron_check | bool

- name: Record role success fingerprint
sr_fingerprint:
sr_message: >-
success system_role:aide ansible_version={{ ansible_version.full }}
{{ ansible_facts['distribution'] }}-{{ ansible_facts['distribution_version'] }}
regexp: "^.* root {{ __aide_bin_path }} --check"
when:
- aide_cron_check is not none
- not aide_cron_check | bool

- name: Record role success fingerprint
sr_fingerprint:
sr_message: >-
success system_role:aide ansible_version={{ ansible_version.full }}
{{ ansible_facts['distribution'] }}-{{ ansible_facts['distribution_version'] }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Search for test files that exercise check-mode behavior for the AIDE role.

# Look for test files in the tests/ directory
fd -t f 'tests_' tests/ 2>/dev/null || echo "No tests/ directory or test files found"

# Search for check_mode references in test files
rg -n 'check_mode|ansible_check_mode|--check' tests/ 2>/dev/null || echo "No check_mode references found in tests/"

Repository: linux-system-roles/aide

Length of output: 827


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== tests files ==\n'
git ls-files 'tests/*.yml' | sed 's#^`#-` #'

printf '\n== check-mode related references ==\n'
rg -n 'check_mode|ansible_check_mode|--check|aide_check|aide_update|aide_init|aide_fetch_db' tests/*.yml

printf '\n== task file context ==\n'
sed -n '1,220p' tasks/main.yml

Repository: linux-system-roles/aide

Length of output: 6544


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== candidate test playbooks ==\n'
sed -n '1,220p' tests/tests_default.yml
printf '\n---\n'
sed -n '1,220p' tests/tests_deploy.yml
printf '\n---\n'
sed -n '1,220p' tests/tests_custom_template.yml
printf '\n---\n'
sed -n '1,220p' tests/tests_check_cron.yml

printf '\n== role runner helpers ==\n'
sed -n '1,220p' tests/roles/caller/tasks/main.yml
printf '\n---\n'
sed -n '1,220p' tests/tasks/run_role_with_clear_facts.yml
printf '\n---\n'
sed -n '1,220p' tests/tasks/check_header.yml
printf '\n---\n'
sed -n '1,220p' tests/tasks/check_not_present_header.yml

Repository: linux-system-roles/aide

Length of output: 8530


Add check-mode test coverage for the new gating
Existing playbooks cover install/init/cron paths, but none exercise the role under --check with packages already present and absent. Add coverage for both states so the new not ansible_check_mode guards stay protected.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tasks/main.yml` around lines 13 - 160, Add check-mode test coverage for the
new gating in tasks/main.yml, focusing on the top-level “Packages are installed”
block and the nested init/update/fetch/check paths. Create tests that run the
role with ansible_check_mode enabled in both package-present and package-absent
states so the new not ansible_check_mode guards are exercised and stay
protected. Use the existing task names like “Packages are installed”,
“Initialize AIDE database”, and “Update AIDE database and fetch it” to target
the relevant behavior.

Source: Path instructions

@spetrosi

spetrosi commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

[citest]

@spetrosi spetrosi changed the title Better support for check mode fix: Better support for check mode Jul 8, 2026
@richm
richm merged commit df809eb into linux-system-roles:main Jul 8, 2026
36 of 38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants