Compare commits
18 Commits
00a6fcc966
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 9ac1187318 | |||
| 6d03aacc85 | |||
| 8be72bc931 | |||
| b9358eb043 | |||
| 36401dc8f4 | |||
| 9a6ac67e20 | |||
| 9d35c16d2c | |||
| 74474c263d | |||
| a82bd5bac5 | |||
| 44f9c8ffa9 | |||
| d509a4946e | |||
| f2ead2ad47 | |||
| af4c561b3d | |||
| d0774ff2b3 | |||
| 21ec247569 | |||
| a0db41cb81 | |||
| e8e8f6d51b | |||
| 907592b88b |
3
.continue/.markdownlint.json
Normal file
3
.continue/.markdownlint.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"MD041": false
|
||||
}
|
||||
127
.continue/rules/ansible.md
Normal file
127
.continue/rules/ansible.md
Normal file
@@ -0,0 +1,127 @@
|
||||
---
|
||||
name: Ansible Best Practices
|
||||
description: Ansible best practices and conventions
|
||||
alwaysApply: false
|
||||
globs:
|
||||
- "**/*.yml"
|
||||
- "**/*.yaml"
|
||||
---
|
||||
|
||||
You are an expert Ansible automation engineer.
|
||||
|
||||
When working with Ansible content, always follow these rules:
|
||||
|
||||
## General
|
||||
|
||||
- Prefer **idempotent** solutions; tasks must be safe to run multiple times.
|
||||
- Use **Ansible built-in modules** instead of shell or command whenever possible.
|
||||
- Do not assume root access; use `become: true` only when required.
|
||||
- Avoid hard-coded values; prefer variables, defaults, and group/host vars.
|
||||
- Use clear, descriptive task names.
|
||||
- Ensure all YAML is valid, properly indented, and ansible-lint compliant.
|
||||
- Favor clarity and maintainability over cleverness.
|
||||
- Add README files to complex directories.
|
||||
- Document complex algorithms and business rules.
|
||||
- Maintain up-to-date dependencies list.
|
||||
|
||||
## Security Hardening
|
||||
|
||||
- **Never embed secrets** directly in playbooks, roles, or templates.
|
||||
- Use **Ansible Vault**, external secret managers, or injected variables for secrets.
|
||||
- Mark sensitive tasks with:
|
||||
|
||||
```yaml
|
||||
no_log: true
|
||||
```
|
||||
|
||||
- Avoid leaking secrets via debug, register, or error messages.
|
||||
- Use least privilege:
|
||||
- Avoid running entire plays as root.
|
||||
- Scope become to individual tasks where possible.
|
||||
- Set secure file permissions explicitly:
|
||||
|
||||
```yaml
|
||||
mode: "0640"
|
||||
owner: root
|
||||
group: root
|
||||
```
|
||||
|
||||
- Validate downloaded files using checksums.
|
||||
- Avoid ignore_errors for security-sensitive operations.
|
||||
- Do not disable SSL/TLS validation unless explicitly required and documented.
|
||||
- Prefer validate_certs: true for network modules.
|
||||
- Assume hosts may be compromised—do not trust remote state blindly.
|
||||
|
||||
## Playbooks
|
||||
|
||||
- Use `hosts`, `gather_facts`, and `become` explicitly.
|
||||
- Keep playbooks minimal; delegate logic to roles.
|
||||
- Apply tags consistently for safe partial execution.
|
||||
- Use serial for rolling updates to reduce blast radius.
|
||||
- Avoid large monolithic plays.
|
||||
|
||||
## Roles
|
||||
|
||||
- Follow the standard role structure:
|
||||
(`tasks/`, `handlers/`, `defaults/`, `vars/`, `templates/`, `files/`).
|
||||
- Put overridable values in `defaults/main.yml`.
|
||||
- Put non-overridable or internal values in `vars/main.yml`.
|
||||
- Namespace all role variables (role_name_variable).
|
||||
- Use meta/main.yml to define role dependencies.
|
||||
- Use handlers only when a change requires a follow-up action.
|
||||
|
||||
## Tasks
|
||||
|
||||
- Always name tasks clearly and descriptively.
|
||||
- Use `state: present/absent/latest` explicitly.
|
||||
- Register variables only when they are actually used.
|
||||
- Use `changed_when` and `failed_when` to ensure correct task status.
|
||||
- Avoid `ignore_errors` unless absolutely necessary.
|
||||
- Avoid shell unless absolutely unavoidable; document why if used.
|
||||
- Prefer creates and removes when using command-like tasks.
|
||||
- Avoid unnecessary loops; simplify logic where possible.
|
||||
|
||||
## Variables & Templates
|
||||
|
||||
- Use snake_case for variable names.
|
||||
- Quote variables in YAML to prevent parsing issues.
|
||||
- Namespace role variables (e.g., `nginx_port`, not `port`).
|
||||
- Avoid complex logic in templates—use when instead.
|
||||
- Use Jinja2 filters safely and defensively (default, bool, int).
|
||||
- Do not reference undefined variables without defaults.
|
||||
|
||||
## Conditionals & Loops
|
||||
|
||||
- Use when for conditionals.
|
||||
- Prefer `loop` over deprecated `with_*`.
|
||||
- Use `ansible_facts` instead of shell commands for system data.
|
||||
- Avoid deeply nested conditionals.
|
||||
|
||||
## Error Handling & Validation
|
||||
|
||||
- Fail fast on critical errors.
|
||||
- Use assert to validate assumptions.
|
||||
- Use check_mode compatibility whenever possible.
|
||||
- Ensure tasks behave correctly in --diff and --check.
|
||||
|
||||
## Linting & Compatibility
|
||||
|
||||
- Code must comply with ansible-lint.
|
||||
- Write code compatible with recent Ansible versions.
|
||||
- Avoid deprecated modules and syntax.
|
||||
- Do not rely on undefined behavior or undocumented features.
|
||||
|
||||
## Performance & Reliability (Tips & Tricks)
|
||||
|
||||
- Use gather_facts: false if facts are not needed.
|
||||
- Use run_once and delegate_to when appropriate.
|
||||
- Cache facts when operating at scale.
|
||||
- Avoid repeated expensive operations.
|
||||
- Prefer block for grouping related tasks and error handling.
|
||||
|
||||
## Output Expectations
|
||||
|
||||
- Generated YAML must be valid and properly indented.
|
||||
- Provide minimal but sufficient comments when clarity is needed.
|
||||
- Do not include explanations unless explicitly requested.
|
||||
- Assume production usage and security-sensitive environments.
|
||||
159
.continue/rules/repo-readme.md
Normal file
159
.continue/rules/repo-readme.md
Normal file
@@ -0,0 +1,159 @@
|
||||
---
|
||||
name: Project README Standards
|
||||
globs: "**/README.md"
|
||||
alwaysApply: false
|
||||
description: Guidelines for creating comprehensive project README files
|
||||
tags:
|
||||
- readme
|
||||
- documentation
|
||||
- markdown
|
||||
- project-setup
|
||||
- best-practices
|
||||
---
|
||||
|
||||
You are an expert in:
|
||||
|
||||
- technical documentation
|
||||
- open source best practices
|
||||
- developer experience.
|
||||
|
||||
## README Structure
|
||||
|
||||
A well-structured README should include these sections in order:
|
||||
|
||||
1. Project Title and Description
|
||||
2. Badges (build status, version, license)
|
||||
3. Key Features
|
||||
4. Screenshots/Demo (if applicable)
|
||||
5. Quick Start
|
||||
6. Installation
|
||||
7. Usage Examples
|
||||
8. API Reference (or link to docs)
|
||||
9. Configuration
|
||||
10. Contributing
|
||||
11. License
|
||||
|
||||
## Essential Sections
|
||||
|
||||
### Project Header
|
||||
|
||||
```markdown
|
||||
# Project Name
|
||||
|
||||
> One-line description of what this project does
|
||||
|
||||
[](https://github.com/user/repo/actions)
|
||||
[](https://www.npmjs.com/package/package-name)
|
||||
[](LICENSE)
|
||||
|
||||
Brief paragraph explaining the project's purpose, main features,
|
||||
and why someone would want to use it.
|
||||
```
|
||||
|
||||
### Quick Start
|
||||
|
||||
```markdown
|
||||
## Quick Start
|
||||
|
||||
Get up and running in less than 5 minutes:
|
||||
|
||||
\`\`\`bash
|
||||
npm install package-name
|
||||
npm run dev
|
||||
\`\`\`
|
||||
|
||||
Visit http://localhost:3000 to see the application.
|
||||
```
|
||||
|
||||
### Installation
|
||||
|
||||
```markdown
|
||||
## Installation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js 18+
|
||||
- PostgreSQL 14+
|
||||
- Redis 6.2+
|
||||
|
||||
### Install from npm
|
||||
|
||||
\`\`\`bash
|
||||
npm install package-name
|
||||
\`\`\`
|
||||
|
||||
### Install from source
|
||||
|
||||
\`\`\`bash
|
||||
git clone https://github.com/user/repo.git
|
||||
cd repo
|
||||
npm install
|
||||
npm run build
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### Usage Examples
|
||||
|
||||
```markdown
|
||||
## Usage
|
||||
|
||||
### Basic Example
|
||||
|
||||
\`\`\`javascript
|
||||
import { Widget } from 'package-name';
|
||||
|
||||
const widget = new Widget({
|
||||
apiKey: 'your-api-key',
|
||||
theme: 'dark'
|
||||
});
|
||||
|
||||
widget.render('#app');
|
||||
\`\`\`
|
||||
|
||||
### Advanced Example
|
||||
|
||||
\`\`\`javascript
|
||||
// Custom configuration with error handling
|
||||
const widget = new Widget({
|
||||
apiKey: process.env.API_KEY,
|
||||
theme: 'dark',
|
||||
onError: (error) => {
|
||||
console.error('Widget error:', error);
|
||||
}
|
||||
});
|
||||
|
||||
// Add custom event handlers
|
||||
widget.on('ready', () => {
|
||||
console.log('Widget is ready');
|
||||
});
|
||||
|
||||
widget.render('#app');
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Keep the README focused and concise
|
||||
- Use clear, simple language
|
||||
- Include code examples that actually work
|
||||
- Add visuals when they help understanding
|
||||
- Link to more detailed documentation
|
||||
- Keep examples up-to-date with the code
|
||||
- Test your installation instructions regularly
|
||||
|
||||
## Common Mistakes to Avoid
|
||||
|
||||
- Don't assume reader knowledge
|
||||
- Don't skip the Quick Start section
|
||||
- Don't use jargon without explanation
|
||||
- Don't forget to update version numbers
|
||||
- Don't include sensitive information
|
||||
|
||||
## Formatting Tips
|
||||
|
||||
- Use consistent heading levels
|
||||
- Include a table of contents for long READMEs
|
||||
- Use code blocks with language highlighting
|
||||
- Add alt text to images
|
||||
- Use tables for comparing options
|
||||
- Include emoji sparingly and purposefully
|
||||
37
.gitea/workflows/AiReviewPR.yaml
Normal file
37
.gitea/workflows/AiReviewPR.yaml
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
# https://github.com/kekxv/AiReviewPR
|
||||
name: ai-reviews
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
|
||||
jobs:
|
||||
review:
|
||||
name: Review PR
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
# Number of commits to fetch. 0 indicates all history for all
|
||||
# branches and tags.
|
||||
# Default: 1
|
||||
fetch-depth: 0
|
||||
# The base URL for the GitHub instance that you are trying to clone
|
||||
# from, will use environment defaults to fetch from the same instance
|
||||
# that the workflow is running from unless specified.
|
||||
# Example URLs are https://github.com or
|
||||
# https://my-ghes-server.example.com
|
||||
github-server-url: ${{ vars.GIT_SERVER_URL }}
|
||||
|
||||
- name: Review code
|
||||
uses: kekxv/AiReviewPR@v0.1.0
|
||||
with:
|
||||
model: ${{ vars.OLLAMA_MODEL }}
|
||||
host: http://192.168.2.233:11435
|
||||
# host: ${{ vars.OLLAMA_HOST }}
|
||||
# ai_token: ${{ secrets.AI_TOKEN }}
|
||||
REVIEW_PULL_REQUEST: false
|
||||
LANGUAGE: English
|
||||
@@ -1,15 +1,17 @@
|
||||
# .github/workflows/ansible-lint.yml
|
||||
---
|
||||
# .gitea/workflows/ansible-lint.yml
|
||||
name: ansible-lint
|
||||
|
||||
on: [pull_request, issues, push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Ansible Lint # Naming the build is important to use it as a status check
|
||||
name: Ansible Lint
|
||||
# Naming the build is important to use it as a status check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
github-server-url: ${{ vars.GIT_SERVER_URL }}
|
||||
|
||||
@@ -21,7 +23,11 @@ jobs:
|
||||
- name: Install ansible-lint
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install ansible ansible-lint
|
||||
pip install ansible ansible-lint yamllint
|
||||
|
||||
- name: Run yamllint
|
||||
run: |
|
||||
yamllint .
|
||||
|
||||
- name: Run ansible-lint
|
||||
run: |
|
||||
|
||||
35
.gitea/workflows/gitleaks.yml
Normal file
35
.gitea/workflows/gitleaks.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: Gitleaks Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
gitleaks:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Install Gitleaks
|
||||
run: |
|
||||
curl -sSL https://github.com/gitleaks/gitleaks/releases/download/v8.30.0/gitleaks_8.30.0_linux_x64.tar.gz \
|
||||
| tar -xz
|
||||
sudo mv gitleaks /usr/local/bin/
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
github-server-url: ${{ vars.GIT_SERVER_URL }}
|
||||
|
||||
- name: Run Gitleaks
|
||||
run: |
|
||||
gitleaks dir . \
|
||||
--redact=10 \
|
||||
--verbose \
|
||||
--exit-code 1
|
||||
# gitleaks detect \
|
||||
# --source . \
|
||||
# --no-git \
|
||||
# --redact=20 \
|
||||
# --verbose \
|
||||
# --exit-code 1
|
||||
71
.gitea/workflows/markdown-lint.yml
Normal file
71
.gitea/workflows/markdown-lint.yml
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
# .gitea/workflows/markdown-lint.yml
|
||||
name: Markdown Lint
|
||||
|
||||
on: [pull_request, issues, push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: markdown-lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
github-server-url: ${{ vars.GIT_SERVER_URL }}
|
||||
|
||||
- name: Install Node.js & markdownlint
|
||||
run: |
|
||||
apt-get update && apt-get install -y npm
|
||||
npm install -g markdownlint-cli2
|
||||
|
||||
- name: Run lint
|
||||
run: markdownlint-cli2 "**/*.md" "#node_modules"
|
||||
|
||||
# on:
|
||||
# push:
|
||||
# branches:
|
||||
# - main
|
||||
# pull_request:
|
||||
# branches:
|
||||
# - main
|
||||
|
||||
# jobs:
|
||||
# markdown-lint:
|
||||
# runs-on: docker
|
||||
# container:
|
||||
# image: node:20-alpine
|
||||
# steps:
|
||||
# - name: Install dependencies
|
||||
# run: |
|
||||
# apk add --no-cache git
|
||||
# npm install -g markdownlint-cli2
|
||||
|
||||
# - name: Run Markdown lint
|
||||
# run: |
|
||||
# markdownlint-cli2 "**/*.md" "#node_modules"
|
||||
|
||||
#########################################à
|
||||
|
||||
# ---
|
||||
# https://github.com/marketplace/actions/markdownlint-cli2-action
|
||||
# name: Markdown Lint
|
||||
|
||||
# on: [pull_request, push]
|
||||
|
||||
# jobs:
|
||||
# build:
|
||||
# name: markdown-lint
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - name: Checkout code
|
||||
# uses: actions/checkout@v4
|
||||
# with:
|
||||
# github-server-url: ${{ vars.GIT_SERVER_URL }}
|
||||
|
||||
# - name: Markdown lint
|
||||
# uses: DavidAnson/markdownlint-cli2-action@v22
|
||||
# with:
|
||||
# globs: '**/*.md'
|
||||
# fix: true
|
||||
# continue-on-error: true
|
||||
72
.gitea/workflows/stale.yml
Normal file
72
.gitea/workflows/stale.yml
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
# This workflow warns and then closes issues and PRs that have
|
||||
# had no activity for a specified amount of time.
|
||||
#
|
||||
# You can adjust the behavior by modifying this file.
|
||||
# For more information, see:
|
||||
# https://github.com/actions/stale
|
||||
name: Mark stale issues and pull requests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '21 3 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write # for actions/stale to close stale issues
|
||||
pull-requests: write # for actions/stale to close stale PRs
|
||||
|
||||
steps:
|
||||
# - name: Checkout code
|
||||
# uses: actions/checkout@v4
|
||||
# with:
|
||||
# # Number of commits to fetch. 0 indicates all history for all branches
|
||||
# # and tags.
|
||||
# # Default: 1
|
||||
# fetch-depth: 0
|
||||
# # The base URL for the GitHub instance that you are trying to clone from,
|
||||
# # will use environment defaults to fetch from the same instance that the
|
||||
# # workflow is running from unless specified.
|
||||
# # Example URLs are https://github.com or
|
||||
# # https://my-ghes-server.example.com
|
||||
# github-server-url: ${{ vars.GIT_SERVER_URL }}
|
||||
|
||||
# The 90 day stale policy
|
||||
# Used for:
|
||||
# - Issues & PRs
|
||||
# - No PRs marked as no-stale or pinned
|
||||
# - No issues marked as no-stale, help-wanted or pinned
|
||||
- name: 90 days stale issues & PRs policy
|
||||
uses: actions/stale@v9.1.0
|
||||
with:
|
||||
# repo-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
||||
days-before-stale: 90
|
||||
days-before-close: 7
|
||||
operations-per-run: 150
|
||||
remove-stale-when-updated: true
|
||||
stale-issue-label: "stale"
|
||||
exempt-issue-labels: "no-stale,help-wanted,pinned,enhancement"
|
||||
stale-issue-message: >
|
||||
There hasn't been any activity on this issue recently. To keep our
|
||||
backlog manageable we have to clean old issues, as many of them have
|
||||
already been resolved with the latest updates.
|
||||
|
||||
Please make sure to update to the latest version and check if that
|
||||
solves the issue. Let us know if that works for you by adding a
|
||||
comment 👍
|
||||
|
||||
This issue has now been marked as stale and will be closed if no
|
||||
further activity occurs. Thank you for your contributions.
|
||||
|
||||
stale-pr-label: "stale"
|
||||
exempt-pr-labels: "no-stale,pinned"
|
||||
stale-pr-message: >
|
||||
There hasn't been any activity on this pull request recently. This
|
||||
pull request has been automatically marked as stale because of that
|
||||
and will be closed if no further activity occurs within 7 days.
|
||||
|
||||
Thank you for your contributions.
|
||||
7
.markdownlint.json
Normal file
7
.markdownlint.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"MD013": {
|
||||
"line_length": 100,
|
||||
"code_block_line_length": 120,
|
||||
"tables": false
|
||||
}
|
||||
}
|
||||
2
.markdownlintignore
Normal file
2
.markdownlintignore
Normal file
@@ -0,0 +1,2 @@
|
||||
# ignore files completely
|
||||
.continue/rules/**/*.md
|
||||
23
.yamllint
Normal file
23
.yamllint
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
# This is my first, very own configuration file for yamllint!
|
||||
# It extends the default conf by adjusting some options.
|
||||
|
||||
extends: default
|
||||
|
||||
rules:
|
||||
comments-indentation: disable # don't bother me with this rule
|
||||
truthy:
|
||||
allowed-values: ['true', 'false', 'yes', 'no', 'on']
|
||||
comments:
|
||||
min-spaces-from-content: 1
|
||||
|
||||
braces:
|
||||
max-spaces-inside: 1
|
||||
|
||||
octal-values:
|
||||
forbid-implicit-octal: true
|
||||
forbid-explicit-octal: true
|
||||
|
||||
line-length:
|
||||
max: 120
|
||||
allow-non-breakable-words: true
|
||||
60
README.md
60
README.md
@@ -1,22 +1,25 @@
|
||||
# ansible_proxmox_WOL
|
||||
|
||||
An Ansible role that configures **persistent Wake‑on‑LAN (WOL)** on Proxmox VE hosts.
|
||||
It discovers all physical Ethernet interfaces, validates WOL support, and then enables or disables WOL on the interfaces that back the bridges you specify.
|
||||
Unlike many WOL setups that rely on *udev* rules, this role uses a lightweight **systemd template unit** (`wol@.service`) so the setting is applied automatically each time an interface comes up, and it survives reboots without any extra steps.
|
||||
It discovers all physical Ethernet interfaces, validates WOL support, and then enables or disables
|
||||
WOL on the interfaces that back the bridges you specify. Unlike many WOL setups that rely on
|
||||
*udev* rules, this role uses a lightweight **systemd template unit** (`wol@.service`) so the setting
|
||||
is applied automatically each time an interface comes up, and it survives reboots without any extra
|
||||
steps.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Features](#features)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Role Variables](#role-variables)
|
||||
- [How It Works](#how-it-works)
|
||||
- [Usage](#usage)
|
||||
- [Common Proxmox Scenarios](#common-proxmox-scenarios)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [License](#license)
|
||||
- [Author](#author)
|
||||
- [Features](#features)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Role Variables](#role-variables)
|
||||
- [How It Works](#how-it-works)
|
||||
- [Usage](#usage)
|
||||
- [Common Proxmox Scenarios](#common-proxmox-scenarios)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [License](#license)
|
||||
- [Author](#author)
|
||||
|
||||
---
|
||||
|
||||
@@ -53,7 +56,7 @@ Unlike many WOL setups that rely on *udev* rules, this role uses a lightweight *
|
||||
wol_bridges: vmbr0 # string or list – bridges that should have WOL enabled
|
||||
wol_mode: "g" # "g"=magic packet (recommended), "d"=disable, "p"/"u"/"m"/"b" for other modes
|
||||
wol_verify: true # Verify the interface state after changes
|
||||
wol_report_mac: true # Include MAC addresses of WOL‑capable senders in the report
|
||||
wol_report_mac: true # Include MAC addresses of WOL-capable senders in the report
|
||||
```
|
||||
|
||||
| Variable | Default | Type | Description |
|
||||
@@ -68,16 +71,22 @@ wol_report_mac: true # Include MAC addresses of WOL‑capable senders in
|
||||
## How It Works
|
||||
|
||||
1. **Package Install** – Ensures the `ethtool` binary is present.
|
||||
2. **Interface Discovery** – Uses `ansible_facts.ansible_interfaces` to collect *all* interfaces, then filters out virtual ones (`veth*`, `tap*`, `docker*`, etc.).
|
||||
3. **WOL Validation** – For each remaining physical NIC, `ethtool <iface> | grep 'Wake-on'` is used to confirm that the NIC supports WOL.
|
||||
4. **Bridge Mapping** – The role resolves each bridge name in `wol_bridges` to the underlying physical interface(s). If a bridge is built on a bond (e.g., `bond0`), every slave is treated as a candidate.
|
||||
2. **Interface Discovery** – Uses `ansible_facts.ansible_interfaces` to collect *all* interfaces,
|
||||
then filters out virtual ones (`veth*`, `tap*`, `docker*`, etc.).
|
||||
3. **WOL Validation** – For each remaining physical NIC, `ethtool <iface> | grep 'Wake-on'`
|
||||
is used to confirm that the NIC supports WOL.
|
||||
4. **Bridge Mapping** – Resolves each bridge name in `wol_bridges` to the physical interface(s).
|
||||
If a bridge is built on a bond (e.g., `bond0`), every slave is treated as a candidate.
|
||||
5. **Idempotency Check** – The current WOL state (`wol_enabled`) is compared to `wol_mode`.
|
||||
6. **Apply WOL** –
|
||||
* If `wol_mode` ≠ `'d'` and the current mode differs, `ethtool -s <iface> wol <mode>` is run.
|
||||
* If `wol_mode` is `'d'`, the role ensures WOL is disabled.
|
||||
7. **Deploy systemd template** – Copies `templates/wol@.service.j2` to `/etc/systemd/system/wol@.service`. The template contains `ExecStart=/usr/sbin/ethtool -s %I wol {{ wol_mode }}`.
|
||||
8. **Enable service per interface** – For every affected interface, the role starts the unit `wol@<iface>.service` and enables it to run on boot.
|
||||
9. **Report** – A final summary is printed, optionally listing MAC addresses if `wol_report_mac` is `true`.
|
||||
- If `wol_mode` ≠ `'d'` and the current mode differs, `ethtool -s <iface> wol <mode>` is run.
|
||||
- If `wol_mode` is `'d'`, the role ensures WOL is disabled.
|
||||
7. **Deploy systemd template** – Copies `templates/wol@.service.j2` to `/etc/systemd/system/wol@.service`.
|
||||
The template contains `ExecStart=/usr/sbin/ethtool -s %I wol {{ wol_mode }}`.
|
||||
8. **Enable service per interface** – For every interface, the role starts the unit
|
||||
`wol@<iface>.service` and enables it to run on boot.
|
||||
9. **Report** – A final summary is printed, optionally listing MAC addresses if `wol_report_mac`
|
||||
is `true`.
|
||||
|
||||
---
|
||||
|
||||
@@ -108,7 +117,8 @@ wol_report_mac: true # Include MAC addresses of WOL‑capable senders in
|
||||
- vmbr2
|
||||
```
|
||||
|
||||
> **Result** – All three bridges are processed; the physical NICs that belong to each bridge receive the configured WOL mode.
|
||||
> **Result** – All three bridges are processed; the physical NICs that belong to each bridge
|
||||
> receive the configured WOL mode.
|
||||
|
||||
### Disable WOL
|
||||
|
||||
@@ -142,10 +152,10 @@ wol_report_mac: true # Include MAC addresses of WOL‑capable senders in
|
||||
## Common Proxmox Scenarios
|
||||
|
||||
| Scenario | Bridge / NIC Layout | What the role does |
|
||||
|----------|---------------------|--------------------|
|
||||
|----------|-------------------|------------------|
|
||||
| **Standard vmbr0** | `eno1` → `vmbr0` | Enables WOL on `eno1`. |
|
||||
| **Bonded NICs** | `eno1`, `eno2` → `bond0` → `vmbr0` | Detects `bond0` and sets WOL on *both* slaves. |
|
||||
| **Multiple Bridges** | `eno1` → `vmbr0` <br> `eno2` → `vmbr1` <br> `eno3`, `eno4` → `bond0` → `vmbr2` | One role run configures all three bridges automatically. |
|
||||
| **Multiple Bridges** | - `eno1` → `vmbr0` - `eno2` → `vmbr1` - `eno3`, `eno4` → `bond0` → `vmbr2` | One role run configures all three bridges automatically. |
|
||||
|
||||
---
|
||||
|
||||
@@ -153,7 +163,7 @@ wol_report_mac: true # Include MAC addresses of WOL‑capable senders in
|
||||
|
||||
| Problem | Likely Cause | Fix |
|
||||
|---------|--------------|-----|
|
||||
| **No interfaces found that support WOL** | BIOS WOL disabled, NIC driver doesn’t expose the feature, or interface isn’t a physical NIC. | Enable WOL in BIOS, run `ethtool <iface>` manually, verify `ansible -m setup <host> | grep ansible_interfaces`. |
|
||||
| **No interfaces found that support WOL** | BIOS WOL disabled, NIC driver doesn’t expose the feature, or interface isn’t a physical NIC. | Enable WOL in BIOS, run `ansible -m setup <host> \| grep ansible_interfaces`. |
|
||||
| **Unable to detect bridge backing NIC(s)** | Bridge doesn’t exist or the NIC isn’t a member of it. | Verify with `bridge link show` / `brctl show`. |
|
||||
| **WOL not persisting after reboot** | `wol@.service` isn’t enabled, or `ethtool` isn’t installed. | Ensure the role ran successfully, check `/etc/systemd/system/wol@.service` and `systemctl status wol@<iface>.service`. |
|
||||
| **Bond0 not detected** | Bond configuration file missing or wrong. | Check `/proc/net/bonding/bond0`. |
|
||||
@@ -169,4 +179,4 @@ MIT
|
||||
|
||||
## Author
|
||||
|
||||
Ansible Proxmox WOL Contributors
|
||||
Ansible Proxmox WOL Contributors
|
||||
|
||||
@@ -18,3 +18,5 @@ wol_verify: true
|
||||
|
||||
# Report MAC addresses for WOL packet senders
|
||||
wol_report_mac: true
|
||||
|
||||
wol_port: 9
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
# ============================================================
|
||||
- name: Install required packages
|
||||
ansible.builtin.apt:
|
||||
name: ethtool
|
||||
name:
|
||||
- ethtool
|
||||
- wakeonlan
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
@@ -26,12 +28,12 @@
|
||||
# ansible.builtin.set_fact:
|
||||
# en_interfaces: "{{ ansible_facts.interfaces | select('match', '^eth|^ens|^enp') | unique | list }}"
|
||||
|
||||
- name: Get interfaces starting with "en or "eth"
|
||||
- name: Get interfaces starting with "en, "eth" or "nic"
|
||||
ansible.builtin.set_fact:
|
||||
en_interfaces: >-
|
||||
{{
|
||||
ansible_facts.interfaces
|
||||
| select('match', '^(eth|en)')
|
||||
| select('match', '^(eth|en|nic)')
|
||||
| list
|
||||
}}
|
||||
|
||||
@@ -106,6 +108,47 @@
|
||||
loop: "{{ en_interfaces }}"
|
||||
when: en_interfaces | length > 0
|
||||
|
||||
- name: Start tcpdump to capture WOL packet
|
||||
become: true
|
||||
ansible.builtin.shell: |
|
||||
timeout 10 tcpdump -i {{ en_interfaces[0] }} -nn -c 1 \
|
||||
'udp and port {{ wol_port }} and (udp[8:4] = 0xffffffff)'
|
||||
register: tcpdump_result
|
||||
async: 12
|
||||
poll: 0
|
||||
changed_when: false
|
||||
|
||||
- name: Give tcpdump time to start
|
||||
ansible.builtin.pause:
|
||||
seconds: 1
|
||||
|
||||
# - name: Send WOL packet via shell
|
||||
# ansible.builtin.shell: wakeonlan {{ wol_mac_addresses[0] }}
|
||||
# delegate_to: localhost
|
||||
|
||||
- name: Send Wake-on-LAN packet from localhost
|
||||
community.general.wakeonlan:
|
||||
mac: "{{ wol_mac_addresses[0] }}"
|
||||
port: "{{ wol_port }}"
|
||||
broadcast: 255.255.255.255
|
||||
# delegate_to: localhost
|
||||
|
||||
- name: Wait for tcpdump to finish
|
||||
ansible.builtin.async_status:
|
||||
jid: "{{ tcpdump_result.ansible_job_id }}"
|
||||
register: tcpdump_status
|
||||
until: tcpdump_status.finished
|
||||
retries: 12
|
||||
delay: 1
|
||||
|
||||
- name: Check if WOL packet was received
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- tcpdump_status.rc == 0
|
||||
success_msg: "✅ Wake-on-LAN magic packet received by host"
|
||||
fail_msg: "❌ Wake-on-LAN magic packet NOT detected"
|
||||
changed_when: tcpdump_status.rc == 0
|
||||
|
||||
- name: Report WOL configuration
|
||||
ansible.builtin.debug:
|
||||
msg: |
|
||||
|
||||
Reference in New Issue
Block a user