diff --git a/config/lovelace/infrastructure_apt_updates_card.yaml b/config/lovelace/infrastructure_apt_updates_card.yaml index bc88f4d2..4e08f3c0 100644 --- a/config/lovelace/infrastructure_apt_updates_card.yaml +++ b/config/lovelace/infrastructure_apt_updates_card.yaml @@ -36,3 +36,9 @@ entities: - entity: sensor.docker_69_apt_status - entity: sensor.docker_69_apt_last_check - entity: sensor.docker_69_apt_last_update + + - type: section + label: docker_13 + - entity: sensor.docker_13_apt_status + - entity: sensor.docker_13_apt_last_check + - entity: sensor.docker_13_apt_last_update diff --git a/config/lovelace/infrastructure_apt_updates_view.yaml b/config/lovelace/infrastructure_apt_updates_view.yaml index 69ae4520..49d6e7cd 100644 --- a/config/lovelace/infrastructure_apt_updates_view.yaml +++ b/config/lovelace/infrastructure_apt_updates_view.yaml @@ -49,3 +49,11 @@ sections: - entity: sensor.docker_69_apt_status - entity: sensor.docker_69_apt_last_check - entity: sensor.docker_69_apt_last_update + + - type: entities + title: docker_13 + show_header_toggle: false + entities: + - entity: sensor.docker_13_apt_status + - entity: sensor.docker_13_apt_last_check + - entity: sensor.docker_13_apt_last_update diff --git a/config/packages/docker_infrastructure.yaml b/config/packages/docker_infrastructure.yaml index d9e2e946..530b9369 100644 --- a/config/packages/docker_infrastructure.yaml +++ b/config/packages/docker_infrastructure.yaml @@ -9,11 +9,11 @@ # Video: https://youtu.be/aceV7ObKJVA # Blog: https://www.vcloudinfo.com/2026/07/using-codex-clean-up-home-assistant-entities.html # ------------------------------------------------------------------- -# Notes: Hosts run daily read-only APT pending checks plus staggered Mon/Thu overnight APT jobs. -# Notes: All Docker hosts use America/New_York; maintenance starts at 00:30 and is sequenced by host. +# Notes: Hosts run daily APT pending checks plus staggered daily overnight APT jobs. +# Notes: All Docker hosts use America/New_York; maintenance starts at 00:30 daily and is sequenced by host. # Notes: Reboots are handled directly on each host by apt_weekly.sh. # Notes: Boot reports reuse the registered APT webhook and retry while Home Assistant starts. -# Notes: Reboot order: docker_14, docker_69, docker_17, docker_10; codex-appliance follows after its SMB dependencies recover. +# Notes: Reboot order: docker_14, docker_69, docker_17, docker_10; docker_13 (codex-appliance) follows after its SMB dependencies recover. # Notes: Per-host action-due helpers preserve overdue state across daily checks and HA restarts. # Notes: Monitored workload count deduplicates Portainer `_container_2` companion entities. # Notes: Container monitoring is dynamic with binary_sensor status preferred over switch state. @@ -81,6 +81,18 @@ input_datetime: name: "docker_69 APT action due" has_date: true has_time: true + apt_docker_13_last_check: + name: "docker_13 APT last check" + has_date: true + has_time: true + apt_docker_13_last_update: + name: "docker_13 APT last update" + has_date: true + has_time: true + apt_docker_13_action_due: + name: "docker_13 APT action due" + has_date: true + has_time: true docker_container_alerts_snooze_until: name: "Docker container alerts snooze until" has_date: true @@ -99,6 +111,9 @@ input_text: apt_docker_69_last_result: name: "docker_69 APT last result" max: 255 + apt_docker_13_last_result: + name: "docker_13 APT last result" + max: 255 switch: - platform: group @@ -282,6 +297,26 @@ template: {% if stamp not in ['unknown', 'unavailable', 'none', ''] %} {{ as_local(as_datetime(stamp)) }} {% endif %} + - name: "docker_13 APT status" + unique_id: apt_docker_13_status + icon: mdi:package-up + state: "{{ states('input_text.apt_docker_13_last_result') }}" + - name: "docker_13 APT last check" + unique_id: apt_docker_13_last_check + device_class: timestamp + state: >- + {% set stamp = states('input_datetime.apt_docker_13_last_check') %} + {% if stamp not in ['unknown', 'unavailable', 'none', ''] %} + {{ as_local(as_datetime(stamp)) }} + {% endif %} + - name: "docker_13 APT last update" + unique_id: apt_docker_13_last_update + device_class: timestamp + state: >- + {% set stamp = states('input_datetime.apt_docker_13_last_update') %} + {% if stamp not in ['unknown', 'unavailable', 'none', ''] %} + {{ as_local(as_datetime(stamp)) }} + {% endif %} - sensor: - name: "Docker Monitored Switch Inventory" @@ -949,6 +984,12 @@ automation: allowed_methods: - POST local_only: true + - platform: webhook + webhook_id: !secret apt_webhook_docker_13 + id: docker_13 + allowed_methods: + - POST + local_only: true variables: host_id: "{{ trigger.id }}" payload: "{{ trigger.json | default({}) }}" @@ -988,6 +1029,13 @@ automation: action_due: input_datetime.apt_docker_69_action_due reboot_delay: 10 maintenance_offset: 15 + docker_13: + last_check: input_datetime.apt_docker_13_last_check + last_update: input_datetime.apt_docker_13_last_update + last_result: input_text.apt_docker_13_last_result + action_due: input_datetime.apt_docker_13_action_due + reboot_delay: 35 + maintenance_offset: 65 host_helpers: "{{ helpers[host_id] if host_id in helpers else none }}" previous_result: "{{ states(host_helpers.last_result) | upper }}" previous_actionable: >- @@ -1003,18 +1051,15 @@ automation: (not previous_actionable or due_missing or previous_reboot != reboot_required) }} action_due: >- {% set maintenance_at = today_at('00:30') + timedelta(minutes=host_helpers.maintenance_offset | int(0)) %} - {% set weekday = now().weekday() %} {% set maintenance_report = event_kind == 'maintenance' %} - {% set current_window = maintenance_report and weekday in [0, 3] + {% set current_window = maintenance_report and now() >= maintenance_at and now() < maintenance_at + timedelta(hours=4) %} {% if current_window %} {% set offset = 0 %} - {% elif weekday in [0, 3] and now() < maintenance_at %} + {% elif now() < maintenance_at %} {% set offset = 0 %} - {% elif weekday < 3 %} - {% set offset = 3 - weekday %} {% else %} - {% set offset = 7 - weekday %} + {% set offset = 1 %} {% endif %} {% set delay = host_helpers.reboot_delay if reboot_required else 0 %} {{ (maintenance_at + timedelta(days=offset, minutes=delay)).strftime('%Y-%m-%d %H:%M:%S') }} diff --git a/config/shell_scripts/apt_reboot_report.sh b/config/shell_scripts/apt_reboot_report.sh index 1f9016aa..b6e0e098 100644 --- a/config/shell_scripts/apt_reboot_report.sh +++ b/config/shell_scripts/apt_reboot_report.sh @@ -12,6 +12,7 @@ case "$HOST_NAME" in docker14) HOST_NAME="docker_14" ;; docker17) HOST_NAME="docker_17" ;; docker69) HOST_NAME="docker_69" ;; + docker13|codex-appliance) HOST_NAME="docker_13" ;; esac if [[ "$WEBHOOK_SOURCE" == "--from-apt-weekly" ]]; then diff --git a/config/shell_scripts/apt_weekly.sh b/config/shell_scripts/apt_weekly.sh index 5b42a2ce..9de23c41 100644 --- a/config/shell_scripts/apt_weekly.sh +++ b/config/shell_scripts/apt_weekly.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -# Twice-weekly overnight APT maintenance for Docker hosts (host-specific Mon/Thu timers). +# Daily overnight APT maintenance for Docker hosts (host-specific staggered timers). # Posts results to Home Assistant webhook and optionally schedules reboot when required. WEBHOOK_URL="$1" diff --git a/config/shell_scripts/apt_weekly.timer.sample b/config/shell_scripts/apt_weekly.timer.sample index eb04b268..71653849 100644 --- a/config/shell_scripts/apt_weekly.timer.sample +++ b/config/shell_scripts/apt_weekly.timer.sample @@ -1,9 +1,9 @@ [Unit] -Description=Run APT maintenance twice weekly overnight +Description=Run APT maintenance daily overnight [Timer] -# Deploy host-specific overnight slots from docs/agent_ops_baselines.md. -OnCalendar=Mon,Thu *-*-* 00:30:00 +# Deploy host-specific daily overnight slots from docs/agent_ops_baselines.md. +OnCalendar=*-*-* 00:30:00 Persistent=true Unit=apt_weekly.service