Compare commits
No commits in common. "master" and "zfs-monitoring" have entirely different histories.
master
...
zfs-monito
5 changed files with 0 additions and 435 deletions
|
|
@ -25,7 +25,6 @@
|
||||||
name:
|
name:
|
||||||
- ca-certificates
|
- ca-certificates
|
||||||
- curl
|
- curl
|
||||||
- gnupg
|
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Create directory for Docker GPG key
|
- name: Create directory for Docker GPG key
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,3 @@ bitcoin_rpc_password: "CHANGE_ME_TO_SECURE_PASSWORD"
|
||||||
# Mempool MariaDB credentials
|
# Mempool MariaDB credentials
|
||||||
# Used by: services/mempool/deploy_mempool_playbook.yml
|
# Used by: services/mempool/deploy_mempool_playbook.yml
|
||||||
mariadb_mempool_password: "CHANGE_ME_TO_SECURE_PASSWORD"
|
mariadb_mempool_password: "CHANGE_ME_TO_SECURE_PASSWORD"
|
||||||
|
|
||||||
# Forgejo Runner registration token
|
|
||||||
# Used by: services/forgejo-runner/deploy_forgejo_runner_playbook.yml
|
|
||||||
# See: services/forgejo-runner/SETUP.md for how to obtain this token
|
|
||||||
forgejo_runner_registration_token: "YOUR_RUNNER_TOKEN_HERE"
|
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
# Forgejo Runner Setup
|
|
||||||
|
|
||||||
## Obtaining the Registration Token
|
|
||||||
|
|
||||||
1. Log in to the Forgejo instance at `https://forgejo.contrapeso.xyz`
|
|
||||||
2. Go to **Site Administration** > **Actions** > **Runners**
|
|
||||||
3. Click **Create new runner**
|
|
||||||
4. Copy the registration token
|
|
||||||
|
|
||||||
## Configuring the Token
|
|
||||||
|
|
||||||
Paste the token into `ansible/infra_secrets.yml`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
forgejo_runner_registration_token: "YOUR_TOKEN_HERE"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Running the Playbook
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ansible-playbook ansible/services/forgejo-runner/deploy_forgejo_runner_playbook.yml
|
|
||||||
```
|
|
||||||
|
|
||||||
## Verifying
|
|
||||||
|
|
||||||
1. On the VM: `systemctl status forgejo-runner` should show active
|
|
||||||
2. In Forgejo: **Site Administration** > **Actions** > **Runners** should show the runner as online
|
|
||||||
3. In Uptime Kuma: the `forgejo-runner-healthcheck` push monitor should be receiving pings
|
|
||||||
|
|
@ -1,392 +0,0 @@
|
||||||
- name: Install Forgejo Runner on Debian 13
|
|
||||||
hosts: forgejo_runner_local
|
|
||||||
become: yes
|
|
||||||
vars_files:
|
|
||||||
- ../../infra_vars.yml
|
|
||||||
- ../../services_config.yml
|
|
||||||
- ../../infra_secrets.yml
|
|
||||||
- ./forgejo_runner_vars.yml
|
|
||||||
vars:
|
|
||||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
|
||||||
ntfy_topic: "{{ service_settings.ntfy.topic }}"
|
|
||||||
healthcheck_interval_seconds: 60
|
|
||||||
healthcheck_timeout_seconds: 90
|
|
||||||
healthcheck_retries: 1
|
|
||||||
healthcheck_script_dir: /opt/forgejo-runner-healthcheck
|
|
||||||
healthcheck_script_path: "{{ healthcheck_script_dir }}/forgejo_runner_healthcheck.sh"
|
|
||||||
healthcheck_log_file: "{{ healthcheck_script_dir }}/forgejo_runner_healthcheck.log"
|
|
||||||
healthcheck_service_name: forgejo-runner-healthcheck
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
# ── 1. Assert Docker is available ──────────────────────────────────
|
|
||||||
- name: Check if Docker is installed
|
|
||||||
command: docker --version
|
|
||||||
register: docker_check
|
|
||||||
changed_when: false
|
|
||||||
failed_when: docker_check.rc != 0
|
|
||||||
|
|
||||||
- name: Fail if Docker is not available
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- docker_check.rc == 0
|
|
||||||
fail_msg: >
|
|
||||||
Docker is not installed or not in PATH.
|
|
||||||
Please install Docker before running this playbook.
|
|
||||||
|
|
||||||
# ── 2. Download forgejo-runner binary ──────────────────────────────
|
|
||||||
- name: Download forgejo-runner binary
|
|
||||||
get_url:
|
|
||||||
url: "{{ forgejo_runner_url }}"
|
|
||||||
dest: "{{ forgejo_runner_bin_path }}"
|
|
||||||
mode: '0755'
|
|
||||||
|
|
||||||
# ── 3. Create runner system user ───────────────────────────────────
|
|
||||||
- name: Create runner system user
|
|
||||||
user:
|
|
||||||
name: "{{ forgejo_runner_user }}"
|
|
||||||
system: yes
|
|
||||||
shell: /usr/sbin/nologin
|
|
||||||
home: "{{ forgejo_runner_dir }}"
|
|
||||||
create_home: no
|
|
||||||
groups: docker
|
|
||||||
append: yes
|
|
||||||
comment: 'Forgejo Runner'
|
|
||||||
|
|
||||||
# ── 4. Create working directory ────────────────────────────────────
|
|
||||||
- name: Create forgejo-runner working directory
|
|
||||||
file:
|
|
||||||
path: "{{ forgejo_runner_dir }}"
|
|
||||||
state: directory
|
|
||||||
owner: "{{ forgejo_runner_user }}"
|
|
||||||
group: "{{ forgejo_runner_user }}"
|
|
||||||
mode: '0750'
|
|
||||||
|
|
||||||
# ── 5. Generate default config ─────────────────────────────────────
|
|
||||||
- name: Check if config already exists
|
|
||||||
stat:
|
|
||||||
path: "{{ forgejo_runner_config_path }}"
|
|
||||||
register: config_stat
|
|
||||||
|
|
||||||
- name: Generate default config
|
|
||||||
shell: "{{ forgejo_runner_bin_path }} generate-config > {{ forgejo_runner_config_path }}"
|
|
||||||
args:
|
|
||||||
chdir: "{{ forgejo_runner_dir }}"
|
|
||||||
when: not config_stat.stat.exists
|
|
||||||
|
|
||||||
- name: Set config file ownership
|
|
||||||
file:
|
|
||||||
path: "{{ forgejo_runner_config_path }}"
|
|
||||||
owner: "{{ forgejo_runner_user }}"
|
|
||||||
group: "{{ forgejo_runner_user }}"
|
|
||||||
when: not config_stat.stat.exists
|
|
||||||
|
|
||||||
# ── 6. Register runner ─────────────────────────────────────────────
|
|
||||||
- name: Check if runner is already registered
|
|
||||||
stat:
|
|
||||||
path: "{{ forgejo_runner_dir }}/.runner"
|
|
||||||
register: runner_stat
|
|
||||||
|
|
||||||
- name: Register runner with Forgejo instance
|
|
||||||
command: >
|
|
||||||
{{ forgejo_runner_bin_path }} register --no-interactive
|
|
||||||
--instance {{ forgejo_instance_url }}
|
|
||||||
--token {{ forgejo_runner_registration_token }}
|
|
||||||
--name forgejo-runner-box
|
|
||||||
--labels "{{ forgejo_runner_labels }}"
|
|
||||||
args:
|
|
||||||
chdir: "{{ forgejo_runner_dir }}"
|
|
||||||
when: not runner_stat.stat.exists
|
|
||||||
|
|
||||||
- name: Set runner registration file ownership
|
|
||||||
file:
|
|
||||||
path: "{{ forgejo_runner_dir }}/.runner"
|
|
||||||
owner: "{{ forgejo_runner_user }}"
|
|
||||||
group: "{{ forgejo_runner_user }}"
|
|
||||||
when: not runner_stat.stat.exists
|
|
||||||
|
|
||||||
# ── 7. Create systemd service ──────────────────────────────────────
|
|
||||||
- name: Create forgejo-runner systemd service
|
|
||||||
copy:
|
|
||||||
dest: /etc/systemd/system/forgejo-runner.service
|
|
||||||
content: |
|
|
||||||
[Unit]
|
|
||||||
Description=Forgejo Runner
|
|
||||||
Documentation=https://forgejo.org/docs/latest/admin/actions/
|
|
||||||
After=docker.service
|
|
||||||
Requires=docker.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
User={{ forgejo_runner_user }}
|
|
||||||
Group={{ forgejo_runner_user }}
|
|
||||||
WorkingDirectory={{ forgejo_runner_dir }}
|
|
||||||
ExecStart={{ forgejo_runner_bin_path }} daemon --config {{ forgejo_runner_config_path }}
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=10
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
# ── 8. Reload systemd, enable and start ────────────────────────────
|
|
||||||
- name: Reload systemd
|
|
||||||
systemd:
|
|
||||||
daemon_reload: yes
|
|
||||||
|
|
||||||
- name: Enable and start forgejo-runner service
|
|
||||||
systemd:
|
|
||||||
name: forgejo-runner
|
|
||||||
enabled: yes
|
|
||||||
state: started
|
|
||||||
|
|
||||||
# ── 9. Verify runner is active ─────────────────────────────────────
|
|
||||||
- name: Verify forgejo-runner is active
|
|
||||||
command: systemctl is-active forgejo-runner
|
|
||||||
register: runner_active
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Assert runner is running
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- runner_active.stdout == "active"
|
|
||||||
fail_msg: "forgejo-runner service is not active: {{ runner_active.stdout }}"
|
|
||||||
|
|
||||||
# ── 10. Set up Uptime Kuma push monitor ────────────────────────────
|
|
||||||
- name: Create Uptime Kuma push monitor setup script
|
|
||||||
copy:
|
|
||||||
dest: /tmp/setup_forgejo_runner_monitor.py
|
|
||||||
content: |
|
|
||||||
#!/usr/bin/env python3
|
|
||||||
import sys
|
|
||||||
import json
|
|
||||||
from uptime_kuma_api import UptimeKumaApi
|
|
||||||
|
|
||||||
def main():
|
|
||||||
api_url = sys.argv[1]
|
|
||||||
username = sys.argv[2]
|
|
||||||
password = sys.argv[3]
|
|
||||||
group_name = sys.argv[4]
|
|
||||||
monitor_name = sys.argv[5]
|
|
||||||
monitor_description = sys.argv[6]
|
|
||||||
interval = int(sys.argv[7])
|
|
||||||
retries = int(sys.argv[8])
|
|
||||||
ntfy_topic = sys.argv[9] if len(sys.argv) > 9 else "alerts"
|
|
||||||
|
|
||||||
api = UptimeKumaApi(api_url, timeout=60, wait_events=2.0)
|
|
||||||
api.login(username, password)
|
|
||||||
|
|
||||||
# Get all monitors
|
|
||||||
monitors = api.get_monitors()
|
|
||||||
|
|
||||||
# Get all notifications and find ntfy notification
|
|
||||||
notifications = api.get_notifications()
|
|
||||||
ntfy_notification = next((n for n in notifications if n.get('name') == f'ntfy ({ntfy_topic})'), None)
|
|
||||||
notification_id_list = {}
|
|
||||||
if ntfy_notification:
|
|
||||||
notification_id_list[ntfy_notification['id']] = True
|
|
||||||
|
|
||||||
# Find or create group
|
|
||||||
group = next((m for m in monitors if m.get('name') == group_name and m.get('type') == 'group'), None)
|
|
||||||
if not group:
|
|
||||||
group_result = api.add_monitor(type='group', name=group_name)
|
|
||||||
# Refresh to get the full group object with id
|
|
||||||
monitors = api.get_monitors()
|
|
||||||
group = next((m for m in monitors if m.get('name') == group_name and m.get('type') == 'group'), None)
|
|
||||||
|
|
||||||
# Find or create/update push monitor
|
|
||||||
existing_monitor = next((m for m in monitors if m.get('name') == monitor_name), None)
|
|
||||||
|
|
||||||
monitor_data = {
|
|
||||||
'type': 'push',
|
|
||||||
'name': monitor_name,
|
|
||||||
'parent': group['id'],
|
|
||||||
'interval': interval,
|
|
||||||
'upsideDown': False,
|
|
||||||
'maxretries': retries,
|
|
||||||
'description': monitor_description,
|
|
||||||
'notificationIDList': notification_id_list
|
|
||||||
}
|
|
||||||
|
|
||||||
if existing_monitor:
|
|
||||||
monitor = api.edit_monitor(existing_monitor['id'], **monitor_data)
|
|
||||||
# Refresh to get the full monitor object with pushToken
|
|
||||||
monitors = api.get_monitors()
|
|
||||||
monitor = next((m for m in monitors if m.get('name') == monitor_name), None)
|
|
||||||
else:
|
|
||||||
monitor_result = api.add_monitor(**monitor_data)
|
|
||||||
# Refresh to get the full monitor object with pushToken
|
|
||||||
monitors = api.get_monitors()
|
|
||||||
monitor = next((m for m in monitors if m.get('name') == monitor_name), None)
|
|
||||||
|
|
||||||
result = {
|
|
||||||
'monitor_id': monitor['id'],
|
|
||||||
'push_token': monitor['pushToken'],
|
|
||||||
'group_name': group_name,
|
|
||||||
'group_id': group['id'],
|
|
||||||
'monitor_name': monitor_name
|
|
||||||
}
|
|
||||||
print(json.dumps(result))
|
|
||||||
|
|
||||||
api.disconnect()
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
mode: '0755'
|
|
||||||
delegate_to: localhost
|
|
||||||
become: no
|
|
||||||
|
|
||||||
- name: Run Uptime Kuma push monitor setup
|
|
||||||
command: >
|
|
||||||
{{ ansible_playbook_python }}
|
|
||||||
/tmp/setup_forgejo_runner_monitor.py
|
|
||||||
"{{ uptime_kuma_api_url }}"
|
|
||||||
"{{ uptime_kuma_username }}"
|
|
||||||
"{{ uptime_kuma_password }}"
|
|
||||||
"services"
|
|
||||||
"forgejo-runner-healthcheck"
|
|
||||||
"Forgejo Runner healthcheck - ping every {{ healthcheck_interval_seconds }}s"
|
|
||||||
"{{ healthcheck_timeout_seconds }}"
|
|
||||||
"{{ healthcheck_retries }}"
|
|
||||||
"{{ ntfy_topic }}"
|
|
||||||
register: monitor_setup_result
|
|
||||||
delegate_to: localhost
|
|
||||||
become: no
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Parse monitor setup result
|
|
||||||
set_fact:
|
|
||||||
monitor_info_parsed: "{{ monitor_setup_result.stdout | from_json }}"
|
|
||||||
|
|
||||||
- name: Set push URL
|
|
||||||
set_fact:
|
|
||||||
uptime_kuma_push_url: "{{ uptime_kuma_api_url }}/api/push/{{ monitor_info_parsed.push_token }}"
|
|
||||||
|
|
||||||
- name: Create healthcheck script directory
|
|
||||||
file:
|
|
||||||
path: "{{ healthcheck_script_dir }}"
|
|
||||||
state: directory
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0755'
|
|
||||||
|
|
||||||
- name: Create forgejo-runner healthcheck script
|
|
||||||
copy:
|
|
||||||
dest: "{{ healthcheck_script_path }}"
|
|
||||||
content: |
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Forgejo Runner Healthcheck Script
|
|
||||||
# Checks if forgejo-runner is active and pings Uptime Kuma on success
|
|
||||||
|
|
||||||
LOG_FILE="{{ healthcheck_log_file }}"
|
|
||||||
UPTIME_KUMA_URL="{{ uptime_kuma_push_url }}"
|
|
||||||
|
|
||||||
log_message() {
|
|
||||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
main() {
|
|
||||||
if systemctl is-active --quiet forgejo-runner; then
|
|
||||||
log_message "forgejo-runner is active, sending ping"
|
|
||||||
response=$(curl -s -w "\n%{http_code}" "$UPTIME_KUMA_URL?status=up&msg=forgejo-runner%20is%20active" 2>&1)
|
|
||||||
http_code=$(echo "$response" | tail -n1)
|
|
||||||
if [ "$http_code" = "200" ] || [ "$http_code" = "201" ]; then
|
|
||||||
log_message "Ping sent successfully (HTTP $http_code)"
|
|
||||||
else
|
|
||||||
log_message "ERROR: Failed to send ping (HTTP $http_code)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
log_message "ERROR: forgejo-runner is not active"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
main
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0755'
|
|
||||||
|
|
||||||
- name: Create healthcheck systemd service
|
|
||||||
copy:
|
|
||||||
dest: "/etc/systemd/system/{{ healthcheck_service_name }}.service"
|
|
||||||
content: |
|
|
||||||
[Unit]
|
|
||||||
Description=Forgejo Runner Healthcheck
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
ExecStart={{ healthcheck_script_path }}
|
|
||||||
User=root
|
|
||||||
StandardOutput=journal
|
|
||||||
StandardError=journal
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Create healthcheck systemd timer
|
|
||||||
copy:
|
|
||||||
dest: "/etc/systemd/system/{{ healthcheck_service_name }}.timer"
|
|
||||||
content: |
|
|
||||||
[Unit]
|
|
||||||
Description=Run Forgejo Runner Healthcheck every minute
|
|
||||||
Requires={{ healthcheck_service_name }}.service
|
|
||||||
|
|
||||||
[Timer]
|
|
||||||
OnBootSec=30sec
|
|
||||||
OnUnitActiveSec={{ healthcheck_interval_seconds }}sec
|
|
||||||
Persistent=true
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=timers.target
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Reload systemd for healthcheck units
|
|
||||||
systemd:
|
|
||||||
daemon_reload: yes
|
|
||||||
|
|
||||||
- name: Enable and start healthcheck timer
|
|
||||||
systemd:
|
|
||||||
name: "{{ healthcheck_service_name }}.timer"
|
|
||||||
enabled: yes
|
|
||||||
state: started
|
|
||||||
|
|
||||||
- name: Test healthcheck script
|
|
||||||
command: "{{ healthcheck_script_path }}"
|
|
||||||
register: healthcheck_test
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Verify healthcheck script works
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- healthcheck_test.rc == 0
|
|
||||||
fail_msg: "Healthcheck script failed to execute properly"
|
|
||||||
|
|
||||||
- name: Display deployment summary
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
Forgejo Runner deployed successfully!
|
|
||||||
|
|
||||||
Runner Name: forgejo-runner-box
|
|
||||||
Instance: {{ forgejo_instance_url }}
|
|
||||||
Working Directory: {{ forgejo_runner_dir }}
|
|
||||||
Service: forgejo-runner.service ({{ runner_active.stdout }})
|
|
||||||
|
|
||||||
Healthcheck Monitor: forgejo-runner-healthcheck
|
|
||||||
Healthcheck Interval: Every {{ healthcheck_interval_seconds }}s
|
|
||||||
Timeout: {{ healthcheck_timeout_seconds }}s
|
|
||||||
|
|
||||||
- name: Clean up temporary monitor setup script
|
|
||||||
file:
|
|
||||||
path: /tmp/setup_forgejo_runner_monitor.py
|
|
||||||
state: absent
|
|
||||||
delegate_to: localhost
|
|
||||||
become: no
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
forgejo_runner_version: "6.3.1"
|
|
||||||
forgejo_runner_arch: "linux-amd64"
|
|
||||||
forgejo_runner_url: "https://code.forgejo.org/forgejo/runner/releases/download/v{{ forgejo_runner_version }}/forgejo-runner-{{ forgejo_runner_version }}-{{ forgejo_runner_arch }}"
|
|
||||||
forgejo_runner_bin_path: "/usr/local/bin/forgejo-runner"
|
|
||||||
forgejo_runner_user: "runner"
|
|
||||||
forgejo_runner_dir: "/opt/forgejo-runner"
|
|
||||||
forgejo_runner_config_path: "{{ forgejo_runner_dir }}/config.yml"
|
|
||||||
forgejo_runner_labels: "docker:docker://node:20-bookworm,ubuntu-latest:docker://node:20-bookworm,ubuntu-22.04:docker://node:20-bookworm,ubuntu-24.04:docker://node:20-bookworm"
|
|
||||||
forgejo_instance_url: "https://forgejo.contrapeso.xyz"
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue