--- # ============================================================ # Install required packages # ============================================================ - name: Install required packages ansible.builtin.apt: name: ethtool state: present update_cache: true # ============================================================ # Detect physical NICs with WOL support using Ansible facts # ============================================================ - name: Gather network interface facts ansible.builtin.setup: gather_subset: - network when: ansible_facts.interfaces is not defined - name: Display interfaces ansible.builtin.debug: msg: > {{ ansible_facts.interfaces }} # - name: Get interfaces starting with "en" or "eth" # ansible.builtin.set_fact: # en_interfaces: "{{ ansible_facts.interfaces | select('match', '^eth|^ens|^enp') | unique | list }}" - name: Get interfaces starting with "en or "eth" ansible.builtin.set_fact: en_interfaces: >- {{ ansible_facts.interfaces | select('match', '^(eth|en)') | list }} - name: Display debug selected interfaces ansible.builtin.debug: msg: > {{ en_interfaces }} - name: Check supported Wake-on-LAN modes ansible.builtin.shell: "ethtool {{ item }} | grep 'Supports Wake-on' | tail -1 | awk '{print $3}'" loop: "{{ en_interfaces }}" register: wol_supported changed_when: false when: en_interfaces | length > 0 - name: WOL | Check if enabled shell: > ethtool {{ item }} | grep 'Wake-on' | tail -1 | awk '{print substr($0,length,1)}' register: wol_enabled changed_when: false failed_when: false loop: "{{ en_interfaces }}" when: en_interfaces | length > 0 - name: "Set Wake-on-LAN to {{ wol_mode }}" ansible.builtin.command: "ethtool -s {{ item.0 }} wol {{ wol_mode }}" loop: "{{ en_interfaces | zip(wol_enabled.results, wol_supported.results) | list }}" loop_control: label: "{{ item.0 }}" when: - wol_mode not in item.1.stdout - wol_mode in item.2.stdout - name: "Disable Wake-on-LAN" ansible.builtin.command: "ethtool -s {{ item.0 }} wol {{ wol_mode }}" loop: "{{ en_interfaces | zip(wol_enabled.results, wol_supported.results) | list }}" loop_control: label: "{{ item.0 }}" when: - wol_mode == 'd' - wol_mode not in item.1.stdout # ------------------------- # 4. Create systemd service for persistence # ------------------------- - name: Create systemd service to persist WoL ansible.builtin.copy: dest: /etc/systemd/system/wol-interfaces.service content: | [Unit] Description=Set Wake-on-LAN on network interfaces After=network.target Wants=network.target [Service] Type=oneshot ExecStart=/bin/bash -c ' {% for intf, enabled, supported in en_interfaces | zip(wol_enabled.results, wol_supported.results) %} {% if wol_mode in supported.stdout %} {% if wol_mode not in enabled.stdout %} /sbin/ethtool -s {{ intf }} wol {{ wol_mode }}; {% endif %} {% endif %} {% endfor %} ' RemainAfterExit=yes [Install] WantedBy=multi-user.target notify: - Reload systemd - name: Enable and start WoL service ansible.builtin.systemd: name: wol-interfaces.service enabled: yes state: started # # ============================================================ # # Verification & Reporting # # ============================================================ # - name: Verify Wake-on-LAN status # ansible.builtin.command: "ethtool {{ item }}" # register: wol_status # changed_when: false # loop: "{{ wol_final_interfaces }}" # loop_control: # label: "{{ item }}" # when: wol_verify # - name: Display WOL status per interface # ansible.builtin.debug: # msg: > # Interface {{ item.item }} WOL Status: # {{ item.stdout_lines | select('search', 'Wake-on:') | first | default('Status Unknown') }} # loop: "{{ wol_status.results | default([]) }}" # loop_control: # label: "{{ item.item }}" # when: wol_verify # - name: Get MAC addresses for all interfaces # ansible.builtin.set_fact: # wol_mac_addresses: >- # {{ # wol_final_interfaces # | map('extract', hostvars[inventory_hostname]['ansible_' ~ item] | default({}), 'macaddress') # | list # }} # - name: Report WOL configuration # ansible.builtin.debug: # msg: | # Wake-on-LAN Configuration Summary: # =================================== # Bridges Configured: {{ wol_bridges_list | join(', ') }} # Physical Interfaces: {{ wol_final_interfaces | join(', ') }} # WOL Mode: {{ wol_mode }} # {% if wol_has_bond0 | default(false) %} # Bond0 Detected: Yes # Bond0 Slaves: {{ wol_bond0_slaves | join(', ') }} # {% endif %} # {% if wol_report_mac and wol_mac_addresses | length > 0 %} # MAC Addresses: # {% for iface, mac in (wol_final_interfaces | zip(wol_mac_addresses) | list) %} # - {{ iface }}: {{ mac | default('Unable to detect') }} # {% endfor %} # {% endif %}