Capture current Ansible control plane state

Commit the accumulated infrastructure work that was living only in the
working tree: monitoring stack, emergency access/bot, gyro allocator,
grimmory, adguard, backup audit and the OpenCode agent definitions.

Also ignore Python bytecode, local archives and Nix/direnv artifacts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTocXkGUUazHdKKd3r9k71
This commit is contained in:
Dmitry
2026-08-26 21:39:28 +03:00
co-authored by Claude Opus 5
parent 4bafa7d09e
commit c676be81ec
126 changed files with 10583 additions and 44 deletions
+219
View File
@@ -0,0 +1,219 @@
---
- name: Install offsite backup packages
ansible.builtin.apt:
name:
- restic
- rclone
- sqlite3
- ca-certificates
state: present
update_cache: true
- name: Ensure rclone config directory exists
ansible.builtin.file:
path: /root/.config/rclone
state: directory
owner: root
group: root
mode: "0700"
- name: Install rclone config
ansible.builtin.copy:
src: "{{ offsite_rclone_config_local }}"
dest: /root/.config/rclone/rclone.conf
owner: root
group: root
mode: "0600"
no_log: true
- name: Ensure restic config directory exists
ansible.builtin.file:
path: /etc/restic
state: directory
owner: root
group: root
mode: "0700"
- name: Install restic repository password
ansible.builtin.copy:
src: "{{ offsite_restic_password_local }}"
dest: "/etc/restic/{{ offsite_profile }}.password"
owner: root
group: root
mode: "0600"
no_log: true
- name: Ensure offsite backup directories exist
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: root
group: root
mode: "0700"
loop:
- /etc/homelab-restic
- /var/lib/homelab-restic
- /var/log/homelab-restic
- name: Install restic exclude file
ansible.builtin.copy:
dest: "/etc/homelab-restic/{{ offsite_profile }}.exclude"
owner: root
group: root
mode: "0644"
content: |
{% for exclude in offsite_excludes %}
{{ exclude }}
{% endfor %}
- name: Install restic environment file
ansible.builtin.copy:
dest: "/etc/homelab-restic/{{ offsite_profile }}.env"
owner: root
group: root
mode: "0600"
content: |
RESTIC_REPOSITORY={{ offsite_repository }}
RESTIC_PASSWORD_FILE=/etc/restic/{{ offsite_profile }}.password
RCLONE_CONFIG=/root/.config/rclone/rclone.conf
HOMELAB_RESTIC_PROFILE={{ offsite_profile }}
HOMELAB_RESTIC_SOURCE={{ offsite_source_path }}
HOMELAB_RESTIC_SQLITE_DB={{ offsite_sqlite_db | default('') }}
HOMELAB_RESTIC_MARIADB_CONTAINER={{ offsite_mariadb_container | default('') }}
HOMELAB_RESTIC_MARIADB_DATABASE={{ offsite_mariadb_database | default('') }}
HOMELAB_RESTIC_MARIADB_USER={{ offsite_mariadb_user | default('') }}
HOMELAB_RESTIC_MARIADB_ENV={{ offsite_mariadb_env | default('') }}
HOMELAB_RESTIC_MARIADB_DUMP_NAME={{ offsite_mariadb_dump_name | default('') }}
HOMELAB_RESTIC_EXCLUDE_FILE=/etc/homelab-restic/{{ offsite_profile }}.exclude
HOMELAB_RESTIC_STAGING=/var/lib/homelab-restic/{{ offsite_profile }}
HOMELAB_RESTIC_TAGS={{ offsite_backup_tag }}
HOMELAB_RESTIC_KEEP_DAILY=14
HOMELAB_RESTIC_KEEP_WEEKLY=8
HOMELAB_RESTIC_KEEP_MONTHLY=6
- name: Install restic offsite backup script
ansible.builtin.copy:
dest: /usr/local/sbin/homelab-restic-offsite-backup
owner: root
group: root
mode: "0755"
content: |
#!/bin/sh
set -eu
if [ "$#" -ne 1 ]; then
echo "usage: $0 <profile>" >&2
exit 64
fi
env_file="/etc/homelab-restic/$1.env"
if [ ! -f "$env_file" ]; then
echo "missing env file: $env_file" >&2
exit 66
fi
set -a
. "$env_file"
set +a
export RESTIC_REPOSITORY RESTIC_PASSWORD_FILE RCLONE_CONFIG
mkdir -p "$HOMELAB_RESTIC_STAGING"
rm -rf "$HOMELAB_RESTIC_STAGING"/*
if [ -n "${HOMELAB_RESTIC_SQLITE_DB:-}" ] && [ -f "$HOMELAB_RESTIC_SQLITE_DB" ]; then
sqlite_backup="$HOMELAB_RESTIC_STAGING/$(basename "$HOMELAB_RESTIC_SQLITE_DB")"
sqlite3 -cmd 'PRAGMA busy_timeout=30000;' "$HOMELAB_RESTIC_SQLITE_DB" ".backup '$sqlite_backup'"
sqlite3 -cmd 'PRAGMA busy_timeout=30000;' "$sqlite_backup" "PRAGMA integrity_check;" | grep -qx ok
fi
if [ -n "${HOMELAB_RESTIC_MARIADB_CONTAINER:-}" ]; then
if [ ! -f "$HOMELAB_RESTIC_MARIADB_ENV" ]; then
echo "missing MariaDB env file: $HOMELAB_RESTIC_MARIADB_ENV" >&2
exit 66
fi
set -a
. "$HOMELAB_RESTIC_MARIADB_ENV"
set +a
dump_tmp="$HOMELAB_RESTIC_STAGING/${HOMELAB_RESTIC_MARIADB_DUMP_NAME}.tmp"
dump_final="$HOMELAB_RESTIC_STAGING/$HOMELAB_RESTIC_MARIADB_DUMP_NAME"
docker exec -e MYSQL_PWD="$DB_PASSWORD" "$HOMELAB_RESTIC_MARIADB_CONTAINER" \
mariadb-dump --user="$HOMELAB_RESTIC_MARIADB_USER" --single-transaction --routines --events \
--databases "$HOMELAB_RESTIC_MARIADB_DATABASE" > "$dump_tmp"
test -s "$dump_tmp"
mv "$dump_tmp" "$dump_final"
{
printf '%s\n' 'grimmory_image=grimmory/grimmory:v3.2.4@sha256:dfa7afdfcf25d649fd664497a62385dd00cd9678c37546e182c172e41c8e80cb'
printf '%s\n' 'mariadb_image=lscr.io/linuxserver/mariadb:11.4.8@sha256:91de7f701bc7fc3a424b81beafca7a7c6c4c5b7c8be6afd2ae148698695c0b0c'
printf 'created_at=%s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
} > "$HOMELAB_RESTIC_STAGING/manifest.txt"
fi
restic snapshots >/dev/null 2>&1 || restic init
tag_args=""
old_ifs="$IFS"
IFS=,
for tag in $HOMELAB_RESTIC_TAGS; do
tag_args="$tag_args --tag $tag"
done
IFS="$old_ifs"
# shellcheck disable=SC2086
restic backup "$HOMELAB_RESTIC_SOURCE" "$HOMELAB_RESTIC_STAGING" \
--exclude-file "$HOMELAB_RESTIC_EXCLUDE_FILE" \
--one-file-system \
$tag_args
restic forget --prune \
--keep-daily "$HOMELAB_RESTIC_KEEP_DAILY" \
--keep-weekly "$HOMELAB_RESTIC_KEEP_WEEKLY" \
--keep-monthly "$HOMELAB_RESTIC_KEEP_MONTHLY"
if [ -n "${HOMELAB_RESTIC_MARIADB_CONTAINER:-}" ]; then
rm -rf "$HOMELAB_RESTIC_STAGING"/*
fi
- name: Install restic offsite systemd service
ansible.builtin.copy:
dest: "/etc/systemd/system/homelab-restic-offsite-{{ offsite_profile }}.service"
owner: root
group: root
mode: "0644"
content: |
[Unit]
Description=HomeLab restic offsite backup ({{ offsite_profile }})
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/bin/flock -w 1800 /var/lock/homelab-restic-{{ offsite_profile }}.lock /usr/local/sbin/homelab-restic-offsite-backup {{ offsite_profile }}
- name: Install restic offsite systemd timer
ansible.builtin.copy:
dest: "/etc/systemd/system/homelab-restic-offsite-{{ offsite_profile }}.timer"
owner: root
group: root
mode: "0644"
content: |
[Unit]
Description=Run HomeLab restic offsite backup ({{ offsite_profile }})
[Timer]
OnCalendar={{ offsite_timer_oncalendar }}
Persistent=true
RandomizedDelaySec=15m
[Install]
WantedBy=timers.target
- name: Reload systemd
ansible.builtin.systemd:
daemon_reload: true
- name: Enable restic offsite timer
ansible.builtin.systemd:
name: "homelab-restic-offsite-{{ offsite_profile }}.timer"
enabled: true
state: started