mirror of
https://github.com/CCOSTAN/Home-AssistantConfig.git
synced 2026-04-24 09:07:22 +00:00
Enhance docker infrastructure automation with staggered auto-reboot functionality and update README. Added support for scheduling reboots in the APT weekly script and introduced boot report automations for docker hosts. #1539
This commit is contained in:
@@ -45,7 +45,7 @@ Live collection of plug-and-play Home Assistant packages. Each YAML file in this
|
||||
| [lightning.yaml](lightning.yaml) | Blitzortung lightning counter monitoring with snoozeable push actions. | `sensor.blitzortung_lightning_counter`, `input_boolean.snooze_lightning`, notify engine actions |
|
||||
| [logbook_activity_feed.yaml](logbook_activity_feed.yaml) | Dummy `sensor.activity_feed` + helper to write clean Activity entries (Issue #1550). | `sensor.activity_feed`, `script.send_to_logbook` |
|
||||
| [mariadb_monitoring.yaml](mariadb_monitoring.yaml) | MariaDB health sensors and Lovelace dashboard snippet for recorder stats. | `sensor.mariadb_status`, `sensor.database_size` |
|
||||
| [docker_infrastructure.yaml](docker_infrastructure.yaml) | Docker host patching + container-down Repairs alerts. | `sensor.docker_*_apt_status`, `repairs.create` |
|
||||
| [docker_infrastructure.yaml](docker_infrastructure.yaml) | Docker host patching + staggered auto-reboot flow + container-down Repairs alerts. | `sensor.docker_*_apt_status`, `repairs.create`, `repairs.remove` |
|
||||
| [mariadb.yaml](mariadb.yaml) | MariaDB recorder health and capacity SQL sensors. | `sensor.mariadb_status`, `sensor.database_size` |
|
||||
| [tugtainer_updates.yaml](tugtainer_updates.yaml) | Tugtainer container update notifications via webhook + persistent alerts. | `persistent_notification.create`, `input_datetime.tugtainer_last_update` |
|
||||
| [phynplus.yaml](phynplus.yaml) | Phyn shutoff automations with push + Activity feed + Repairs issues for leak events. | `valve.phyn_shutoff_valve`, `binary_sensor.phyn_leak_test_running`, `repairs.create` |
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
# APT webhook results and container down repairs.
|
||||
# -------------------------------------------------------------------
|
||||
# Notes: Hosts run weekly Wed 12:00 APT job and POST JSON to webhooks.
|
||||
# Notes: If reboot is required, hosts auto-schedule reboot after posting status.
|
||||
# Notes: Reboot staggering: docker_14 reboots first, docker_10 reboots later.
|
||||
# Notes: Container watchlist is explicit; extend entity list as needed.
|
||||
######################################################################
|
||||
|
||||
@@ -179,17 +181,21 @@ automation:
|
||||
updated: "{{ payload.get('updated', false) | bool }}"
|
||||
packages: "{{ payload.get('packages', 0) | int(0) }}"
|
||||
reboot_required: "{{ payload.get('reboot_required', false) | bool }}"
|
||||
auto_reboot_scheduled: "{{ payload.get('auto_reboot_scheduled', false) | bool }}"
|
||||
reboot_delay_minutes: "{{ payload.get('reboot_delay_minutes', 0) | int(0) }}"
|
||||
message: "{{ payload.get('message', '') | string }}"
|
||||
result: >-
|
||||
{% if not success %}
|
||||
ERROR{% if (message | trim) != '' %}: {{ message | trim }}{% endif %}
|
||||
{% elif reboot_required and not updated %}
|
||||
REBOOT REQUIRED{% if auto_reboot_scheduled %}; AUTO REBOOT {{ reboot_delay_minutes }}M{% endif %}
|
||||
{% elif updated %}
|
||||
UPDATED {{ packages }} PKGS{% if reboot_required %}; REBOOT REQUIRED{% endif %}
|
||||
UPDATED {{ packages }} PKGS{% if reboot_required %}; REBOOT REQUIRED{% endif %}{% if auto_reboot_scheduled %}; AUTO REBOOT {{ reboot_delay_minutes }}M{% endif %}
|
||||
{% else %}
|
||||
NO UPDATES
|
||||
{% endif %}
|
||||
log_message: >-
|
||||
docker_10 updated {{ packages }} package{% if packages != 1 %}s{% endif %}{% if reboot_required %} (reboot required){% endif %}.
|
||||
docker_10 updated {{ packages }} package{% if packages != 1 %}s{% endif %}{% if reboot_required %} (reboot required){% endif %}{% if auto_reboot_scheduled %}; auto reboot in {{ reboot_delay_minutes }} minute{% if reboot_delay_minutes != 1 %}s{% endif %}{% endif %}.
|
||||
action:
|
||||
- service: input_datetime.set_datetime
|
||||
target:
|
||||
@@ -240,17 +246,21 @@ automation:
|
||||
updated: "{{ payload.get('updated', false) | bool }}"
|
||||
packages: "{{ payload.get('packages', 0) | int(0) }}"
|
||||
reboot_required: "{{ payload.get('reboot_required', false) | bool }}"
|
||||
auto_reboot_scheduled: "{{ payload.get('auto_reboot_scheduled', false) | bool }}"
|
||||
reboot_delay_minutes: "{{ payload.get('reboot_delay_minutes', 0) | int(0) }}"
|
||||
message: "{{ payload.get('message', '') | string }}"
|
||||
result: >-
|
||||
{% if not success %}
|
||||
ERROR{% if (message | trim) != '' %}: {{ message | trim }}{% endif %}
|
||||
{% elif reboot_required and not updated %}
|
||||
REBOOT REQUIRED{% if auto_reboot_scheduled %}; AUTO REBOOT {{ reboot_delay_minutes }}M{% endif %}
|
||||
{% elif updated %}
|
||||
UPDATED {{ packages }} PKGS{% if reboot_required %}; REBOOT REQUIRED{% endif %}
|
||||
UPDATED {{ packages }} PKGS{% if reboot_required %}; REBOOT REQUIRED{% endif %}{% if auto_reboot_scheduled %}; AUTO REBOOT {{ reboot_delay_minutes }}M{% endif %}
|
||||
{% else %}
|
||||
NO UPDATES
|
||||
{% endif %}
|
||||
log_message: >-
|
||||
docker_14 updated {{ packages }} package{% if packages != 1 %}s{% endif %}{% if reboot_required %} (reboot required){% endif %}.
|
||||
docker_14 updated {{ packages }} package{% if packages != 1 %}s{% endif %}{% if reboot_required %} (reboot required){% endif %}{% if auto_reboot_scheduled %}; auto reboot in {{ reboot_delay_minutes }} minute{% if reboot_delay_minutes != 1 %}s{% endif %}{% endif %}.
|
||||
action:
|
||||
- service: input_datetime.set_datetime
|
||||
target:
|
||||
@@ -301,17 +311,21 @@ automation:
|
||||
updated: "{{ payload.get('updated', false) | bool }}"
|
||||
packages: "{{ payload.get('packages', 0) | int(0) }}"
|
||||
reboot_required: "{{ payload.get('reboot_required', false) | bool }}"
|
||||
auto_reboot_scheduled: "{{ payload.get('auto_reboot_scheduled', false) | bool }}"
|
||||
reboot_delay_minutes: "{{ payload.get('reboot_delay_minutes', 0) | int(0) }}"
|
||||
message: "{{ payload.get('message', '') | string }}"
|
||||
result: >-
|
||||
{% if not success %}
|
||||
ERROR{% if (message | trim) != '' %}: {{ message | trim }}{% endif %}
|
||||
{% elif reboot_required and not updated %}
|
||||
REBOOT REQUIRED{% if auto_reboot_scheduled %}; AUTO REBOOT {{ reboot_delay_minutes }}M{% endif %}
|
||||
{% elif updated %}
|
||||
UPDATED {{ packages }} PKGS{% if reboot_required %}; REBOOT REQUIRED{% endif %}
|
||||
UPDATED {{ packages }} PKGS{% if reboot_required %}; REBOOT REQUIRED{% endif %}{% if auto_reboot_scheduled %}; AUTO REBOOT {{ reboot_delay_minutes }}M{% endif %}
|
||||
{% else %}
|
||||
NO UPDATES
|
||||
{% endif %}
|
||||
log_message: >-
|
||||
docker_69 updated {{ packages }} package{% if packages != 1 %}s{% endif %}{% if reboot_required %} (reboot required){% endif %}.
|
||||
docker_69 updated {{ packages }} package{% if packages != 1 %}s{% endif %}{% if reboot_required %} (reboot required){% endif %}{% if auto_reboot_scheduled %}; auto reboot in {{ reboot_delay_minutes }} minute{% if reboot_delay_minutes != 1 %}s{% endif %}{% endif %}.
|
||||
action:
|
||||
- service: input_datetime.set_datetime
|
||||
target:
|
||||
@@ -346,6 +360,105 @@ automation:
|
||||
topic: "APT"
|
||||
message: "{{ log_message }}"
|
||||
|
||||
- alias: "APT Boot Report - docker_10"
|
||||
id: apt_boot_report_docker_10
|
||||
description: "Clear or keep reboot-required flag after docker_10 boots."
|
||||
mode: queued
|
||||
trigger:
|
||||
- platform: webhook
|
||||
webhook_id: !secret apt_boot_webhook_docker_10
|
||||
allowed_methods:
|
||||
- POST
|
||||
local_only: true
|
||||
variables:
|
||||
payload: "{{ trigger.json | default({}) }}"
|
||||
reboot_required: "{{ payload.get('reboot_required', false) | bool }}"
|
||||
action:
|
||||
- choose:
|
||||
- conditions: "{{ reboot_required }}"
|
||||
sequence:
|
||||
- service: input_boolean.turn_on
|
||||
target:
|
||||
entity_id: input_boolean.apt_docker_10_reboot_required
|
||||
- service: script.send_to_logbook
|
||||
data:
|
||||
topic: "APT"
|
||||
message: "docker_10 boot report: reboot is still required."
|
||||
default:
|
||||
- service: input_boolean.turn_off
|
||||
target:
|
||||
entity_id: input_boolean.apt_docker_10_reboot_required
|
||||
- service: script.send_to_logbook
|
||||
data:
|
||||
topic: "APT"
|
||||
message: "docker_10 reboot completed and reboot flag cleared."
|
||||
|
||||
- alias: "APT Boot Report - docker_14"
|
||||
id: apt_boot_report_docker_14
|
||||
description: "Clear or keep reboot-required flag after docker_14 boots."
|
||||
mode: queued
|
||||
trigger:
|
||||
- platform: webhook
|
||||
webhook_id: !secret apt_boot_webhook_docker_14
|
||||
allowed_methods:
|
||||
- POST
|
||||
local_only: true
|
||||
variables:
|
||||
payload: "{{ trigger.json | default({}) }}"
|
||||
reboot_required: "{{ payload.get('reboot_required', false) | bool }}"
|
||||
action:
|
||||
- choose:
|
||||
- conditions: "{{ reboot_required }}"
|
||||
sequence:
|
||||
- service: input_boolean.turn_on
|
||||
target:
|
||||
entity_id: input_boolean.apt_docker_14_reboot_required
|
||||
- service: script.send_to_logbook
|
||||
data:
|
||||
topic: "APT"
|
||||
message: "docker_14 boot report: reboot is still required."
|
||||
default:
|
||||
- service: input_boolean.turn_off
|
||||
target:
|
||||
entity_id: input_boolean.apt_docker_14_reboot_required
|
||||
- service: script.send_to_logbook
|
||||
data:
|
||||
topic: "APT"
|
||||
message: "docker_14 reboot completed and reboot flag cleared."
|
||||
|
||||
- alias: "APT Boot Report - docker_69"
|
||||
id: apt_boot_report_docker_69
|
||||
description: "Clear or keep reboot-required flag after docker_69 boots."
|
||||
mode: queued
|
||||
trigger:
|
||||
- platform: webhook
|
||||
webhook_id: !secret apt_boot_webhook_docker_69
|
||||
allowed_methods:
|
||||
- POST
|
||||
local_only: true
|
||||
variables:
|
||||
payload: "{{ trigger.json | default({}) }}"
|
||||
reboot_required: "{{ payload.get('reboot_required', false) | bool }}"
|
||||
action:
|
||||
- choose:
|
||||
- conditions: "{{ reboot_required }}"
|
||||
sequence:
|
||||
- service: input_boolean.turn_on
|
||||
target:
|
||||
entity_id: input_boolean.apt_docker_69_reboot_required
|
||||
- service: script.send_to_logbook
|
||||
data:
|
||||
topic: "APT"
|
||||
message: "docker_69 boot report: reboot is still required."
|
||||
default:
|
||||
- service: input_boolean.turn_off
|
||||
target:
|
||||
entity_id: input_boolean.apt_docker_69_reboot_required
|
||||
- service: script.send_to_logbook
|
||||
data:
|
||||
topic: "APT"
|
||||
message: "docker_69 reboot completed and reboot flag cleared."
|
||||
|
||||
- alias: "APT Reboot Repairs"
|
||||
id: apt_reboot_repairs
|
||||
description: "Create or clear Repairs issues when Docker hosts need a reboot."
|
||||
|
||||
@@ -27,6 +27,8 @@ Longer-running shell helpers referenced by automations, packages, or cron. Anyth
|
||||
| File | Why it matters |
|
||||
| --- | --- |
|
||||
| [HAUpdate.sh](HAUpdate.sh) | One-command Home Assistant update helper. |
|
||||
| [apt_weekly.sh](apt_weekly.sh) | Weekly APT updater that posts webhook status and can schedule reboot when needed. |
|
||||
| [apt_reboot_report.sh](apt_reboot_report.sh) | Boot-time webhook status reporter that clears/keeps reboot-required state in HA. |
|
||||
| [gitupdate.sh](gitupdate.sh) | Pull the latest config changes on demand. |
|
||||
| [basketball.yaml](basketball.yaml) | ESPN stat scraping helper used by sensors. |
|
||||
| [Jinja Code.py](Jinja Code.py) | Reference Jinja snippets for templating. |
|
||||
|
||||
13
config/shell_scripts/apt_reboot_report.service.sample
Normal file
13
config/shell_scripts/apt_reboot_report.service.sample
Normal file
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Report boot completion for APT reboot tracking
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/sbin/apt_reboot_report.sh https://HOMEASSISTANT_HOST:8123/api/webhook/REPLACE_WITH_BOOT_WEBHOOK_ID docker_10
|
||||
User=root
|
||||
Group=root
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
29
config/shell_scripts/apt_reboot_report.sh
Normal file
29
config/shell_scripts/apt_reboot_report.sh
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Boot report for APT-managed hosts.
|
||||
# Sends current reboot-required state after each system boot.
|
||||
|
||||
WEBHOOK_URL="$1"
|
||||
HOST_NAME="${2:-$(hostname -s)}"
|
||||
|
||||
if [[ -z "$WEBHOOK_URL" ]]; then
|
||||
echo "Usage: $0 <webhook_url> [host_name]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REBOOT_REQUIRED=false
|
||||
if [[ -f /var/run/reboot-required ]]; then
|
||||
REBOOT_REQUIRED=true
|
||||
fi
|
||||
|
||||
payload=$(cat <<JSON
|
||||
{
|
||||
"event": "boot_report",
|
||||
"host": "${HOST_NAME}",
|
||||
"reboot_required": $( $REBOOT_REQUIRED && echo true || echo false )
|
||||
}
|
||||
JSON
|
||||
)
|
||||
|
||||
curl -sS -X POST -H 'Content-Type: application/json' -d "$payload" "$WEBHOOK_URL" || true
|
||||
@@ -5,7 +5,7 @@ Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/sbin/apt_weekly.sh https://HOMEASSISTANT_HOST:8123/api/webhook/REPLACE_WITH_WEBHOOK_ID
|
||||
ExecStart=/usr/local/sbin/apt_weekly.sh https://HOMEASSISTANT_HOST:8123/api/webhook/REPLACE_WITH_APT_WEBHOOK_ID docker_10 20
|
||||
User=root
|
||||
Group=root
|
||||
Nice=10
|
||||
|
||||
@@ -2,15 +2,27 @@
|
||||
set -euo pipefail
|
||||
|
||||
# Weekly APT maintenance for docker hosts (runs Wednesdays at 12:00 local via systemd timer)
|
||||
# Posts results to Home Assistant webhook.
|
||||
# Posts results to Home Assistant webhook and optionally schedules reboot when required.
|
||||
|
||||
WEBHOOK_URL="$1"
|
||||
HOST_NAME="${2:-$(hostname -s)}"
|
||||
REBOOT_DELAY_MINUTES="${3:-}"
|
||||
|
||||
if [[ -z "$WEBHOOK_URL" ]]; then
|
||||
echo "Usage: $0 <webhook_url>" >&2
|
||||
echo "Usage: $0 <webhook_url> [host_name] [reboot_delay_minutes]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AUTO_REBOOT=false
|
||||
if [[ -n "$REBOOT_DELAY_MINUTES" ]]; then
|
||||
if [[ "$REBOOT_DELAY_MINUTES" =~ ^[0-9]+$ ]]; then
|
||||
AUTO_REBOOT=true
|
||||
else
|
||||
echo "reboot_delay_minutes must be a non-negative integer" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
log() { echo "[$(date --iso-8601=seconds)] $*"; }
|
||||
|
||||
UPDATED=false
|
||||
@@ -45,10 +57,13 @@ fi
|
||||
|
||||
payload=$(cat <<JSON
|
||||
{
|
||||
"host": "${HOST_NAME}",
|
||||
"success": $( [[ "$MESSAGE" == "" ]] && echo true || echo false ),
|
||||
"updated": $( $UPDATED && echo true || echo false ),
|
||||
"packages": $PACKAGES,
|
||||
"reboot_required": $( $REBOOT && echo true || echo false ),
|
||||
"auto_reboot_scheduled": $( [[ "$REBOOT" == true && "$AUTO_REBOOT" == true && "$MESSAGE" == "" ]] && echo true || echo false ),
|
||||
"reboot_delay_minutes": ${REBOOT_DELAY_MINUTES:-0},
|
||||
"message": "${MESSAGE}"
|
||||
}
|
||||
JSON
|
||||
@@ -56,3 +71,14 @@ JSON
|
||||
|
||||
log "Posting results to Home Assistant"
|
||||
curl -sS -X POST -H 'Content-Type: application/json' -d "$payload" "$WEBHOOK_URL" || true
|
||||
|
||||
if [[ "$REBOOT" == true && "$AUTO_REBOOT" == true && "$MESSAGE" == "" ]]; then
|
||||
shutdown -c >/dev/null 2>&1 || true
|
||||
if [[ "$REBOOT_DELAY_MINUTES" -eq 0 ]]; then
|
||||
log "Reboot required; rebooting immediately."
|
||||
shutdown -r now "APT weekly maintenance reboot"
|
||||
else
|
||||
log "Reboot required; scheduling reboot in ${REBOOT_DELAY_MINUTES} minute(s)."
|
||||
shutdown -r +"$REBOOT_DELAY_MINUTES" "APT weekly maintenance reboot"
|
||||
fi
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user