Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions roles/ipmi_exporter/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ ipmi_exporter_config_dir: /etc/ipmi_exporter

# Local path to stash and extract the archive
ipmi_exporter_local_cache_path: "/tmp/ipmi_exporter-{{ ansible_facts['system'] | lower }}-{{ _ipmi_exporter_go_ansible_arch }}/{{ ipmi_exporter_version }}"

ipmi_exporter_udev_enable: false
ipmi_exporter_udev_rule_path: "/etc/udev/rules.d/99-ipmi-exporter.rules"
9 changes: 9 additions & 0 deletions roles/ipmi_exporter/handlers/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,12 @@
state: restarted
when:
- not ansible_check_mode

- name: Reload udev rules
listen: "reload udev rules"
become: true
ansible.builtin.command:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would a systemd restart of systemd-udev-trigger.service be enough for this? It's preferred to avoid command since it's not idempotent.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The --subsystem-match=ipmi filter was intentional here to limit the trigger to IPMI devices only. Restarting systemd-udev-trigger.service would re-trigger all devices system-wide which is broader.

Since changed_when: false is already set, the idempotency concern is addressed at the Ansible reporting level.

I agree command isn't ideal, but there's no clean module equivalent for a scoped udevadm trigger

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@SuperQ any additional feedback needed to move this forward ?

cmd: udevadm control --reload-rules && udevadm trigger --subsystem-match=ipmi
changed_when: false
when:
- not ansible_check_mode
9 changes: 9 additions & 0 deletions roles/ipmi_exporter/meta/argument_specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,12 @@ argument_specs:
ipmi_exporter_config_dir:
description: "Path to directory with ipmi_exporter configuration"
default: "/etc/ipmi_exporter"
ipmi_exporter_udev_enable:
description:
- "When true, deploy a udev rule granting the service group read/write access to /dev/ipmi* devices."
- "This allows freeipmi tools to access IPMI hardware without sudo."
type: "bool"
default: false
ipmi_exporter_udev_rule_path:
description: "Path where the udev rule file is deployed when ipmi_exporter_udev_enable is true."
default: "/etc/udev/rules.d/99-ipmi-exporter.rules"
7 changes: 7 additions & 0 deletions roles/ipmi_exporter/molecule/capabilities/molecule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
provisioner:
inventory:
group_vars:
all:
ipmi_exporter_web_listen_address: "127.0.0.1:9290"
ipmi_exporter_udev_enable: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

from testinfra_helpers import get_target_hosts

testinfra_hosts = get_target_hosts()


def test_udev_rule_exists(host):
f = host.file("/etc/udev/rules.d/99-ipmi-exporter.rules")
assert f.exists
assert f.is_file


def test_udev_rule_permissions(host):
f = host.file("/etc/udev/rules.d/99-ipmi-exporter.rules")
assert f.user == "root"
assert f.group == "root"
assert f.mode == 0o644


def test_udev_rule_content(host):
f = host.file("/etc/udev/rules.d/99-ipmi-exporter.rules")
assert 'KERNEL=="ipmi*"' in f.content_string
assert 'SUBSYSTEM=="ipmi"' in f.content_string
assert 'GROUP="ipmi-exp"' in f.content_string
assert 'MODE="0660"' in f.content_string


def test_service(host):
s = host.service("ipmi_exporter")
try:
assert s.is_running
except AssertionError:
journal_output = host.run('journalctl -u ipmi_exporter --since "1 hour ago"')
print("\n==== journalctl -u ipmi_exporter Output ====\n")
print(journal_output)
print("\n============================================\n")
raise


def test_socket(host):
sockets = [
"tcp://127.0.0.1:9290"
]
for socket in sockets:
s = host.socket(socket)
assert s.is_listening
29 changes: 29 additions & 0 deletions roles/ipmi_exporter/tasks/configure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,35 @@
- configure
- ipmi_exporter_configure

- name: Deploy udev rule for IPMI device access
ansible.builtin.template:
src: ipmi_udev.rules.j2
dest: "{{ ipmi_exporter_udev_rule_path }}"
owner: root
group: root
mode: 0644
become: true
when: ipmi_exporter_udev_enable
notify:
- reload udev rules
tags:
- ipmi_exporter
- configure
- ipmi_exporter_configure

- name: Remove udev rule for IPMI device access
ansible.builtin.file:
path: "{{ ipmi_exporter_udev_rule_path }}"
state: absent
become: true
when: not ipmi_exporter_udev_enable
notify:
- reload udev rules
tags:
- ipmi_exporter
- configure
- ipmi_exporter_configure

- name: Copy the ipmi_exporter config file
ansible.builtin.template:
src: config.yaml.j2
Expand Down
3 changes: 3 additions & 0 deletions roles/ipmi_exporter/templates/ipmi_udev.rules.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{{ ansible_managed | comment }}

KERNEL=="ipmi*", SUBSYSTEM=="ipmi", GROUP="{{ ipmi_exporter_system_group }}", MODE="0660"
Loading