Harden posture/borg audit scripts (robustness + coverage)
Working-tree improvements to the audit scripts (authored locally, not by me; reviewed for correctness + bash -n clean before commit): - compose-runtime-drift: prefer `docker compose config` for the expected image with a raw-parse fallback; raw parser now resolves YAML anchors (*alias) so anchor-based composes (e.g. dawarich) no longer mis-report drift. - komodo-stack-hygiene: treat an unreachable Komodo API as critical and exit 3 so the Healthchecks EXIT trap sends /fail (the monitor itself is down, not "all green"); git fetch before hash-drift compare; clearer "cannot compare" message; pin in-container km host to localhost:9120. - cert-token-check: expand monitored cert domains to the full set incl. hc.kaleschke.info. - gitea-bundle-mirror: skip empty repos without refs instead of failing. - unraid-user-scripts.md: document SEND_NTFY/NTFY_TOPIC for the daily report. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -26,7 +26,73 @@ add_result() {
|
||||
printf '%s\t%s\t%s\n' "$1" "$2" "$3" >> "$RESULTS_FILE"
|
||||
}
|
||||
|
||||
parse_compose() {
|
||||
parse_normalized_compose() {
|
||||
awk '
|
||||
function clean(value) {
|
||||
gsub(/\r/, "", value)
|
||||
gsub(/["'\''"]/, "", value)
|
||||
return value
|
||||
}
|
||||
function emit() {
|
||||
if (in_services && service && image) {
|
||||
print clean(container) "\t" clean(image)
|
||||
}
|
||||
}
|
||||
/^services:/ {
|
||||
emit()
|
||||
in_services=1
|
||||
service=""
|
||||
image=""
|
||||
container=""
|
||||
next
|
||||
}
|
||||
/^[A-Za-z0-9_.-]+:/ && $0 !~ /^services:/ {
|
||||
if (in_services) {
|
||||
emit()
|
||||
in_services=0
|
||||
service=""
|
||||
image=""
|
||||
container=""
|
||||
}
|
||||
}
|
||||
in_services && /^ [A-Za-z0-9_.-]+:/ {
|
||||
emit()
|
||||
service=$1
|
||||
sub(/:$/, "", service)
|
||||
image=""
|
||||
container=service
|
||||
next
|
||||
}
|
||||
in_services && service && /^ image:/ {
|
||||
image=$0
|
||||
sub(/^[[:space:]]*image:[[:space:]]*/, "", image)
|
||||
next
|
||||
}
|
||||
in_services && service && /^ container_name:/ {
|
||||
container=$0
|
||||
sub(/^[[:space:]]*container_name:[[:space:]]*/, "", container)
|
||||
next
|
||||
}
|
||||
END { emit() }
|
||||
'
|
||||
}
|
||||
|
||||
parse_compose_with_docker() {
|
||||
local compose="$1"
|
||||
local dir
|
||||
local file
|
||||
|
||||
command -v docker >/dev/null 2>&1 || return 1
|
||||
|
||||
dir="$(dirname "$compose")"
|
||||
file="$(basename "$compose")"
|
||||
(
|
||||
cd "$dir"
|
||||
docker compose -f "$file" config 2>/dev/null
|
||||
) | parse_normalized_compose
|
||||
}
|
||||
|
||||
parse_compose_raw() {
|
||||
local compose="$1"
|
||||
awk '
|
||||
function clean(value) {
|
||||
@@ -36,9 +102,25 @@ parse_compose() {
|
||||
}
|
||||
function emit() {
|
||||
if (service && image && !has_profile) {
|
||||
if (image ~ /^\*/) {
|
||||
alias=image
|
||||
sub(/^\*/, "", alias)
|
||||
if (alias in anchors) {
|
||||
image=anchors[alias]
|
||||
}
|
||||
}
|
||||
print clean(container) "\t" clean(image)
|
||||
}
|
||||
}
|
||||
/^x-[A-Za-z0-9_.-]+:[[:space:]]*&[A-Za-z0-9_.-]+[[:space:]]+/ {
|
||||
alias=$0
|
||||
sub(/^.*&/, "", alias)
|
||||
sub(/[[:space:]].*$/, "", alias)
|
||||
value=$0
|
||||
sub(/^.*&[A-Za-z0-9_.-]+[[:space:]]+/, "", value)
|
||||
anchors[alias]=value
|
||||
next
|
||||
}
|
||||
/^ [A-Za-z0-9_.-]+:/ {
|
||||
emit()
|
||||
service=$1
|
||||
@@ -66,6 +148,16 @@ parse_compose() {
|
||||
' "$compose"
|
||||
}
|
||||
|
||||
parse_compose() {
|
||||
local compose="$1"
|
||||
|
||||
if parse_compose_with_docker "$compose"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
parse_compose_raw "$compose"
|
||||
}
|
||||
|
||||
while IFS= read -r -d '' compose; do
|
||||
while IFS="$(printf '\t')" read -r container expected_image; do
|
||||
[ -n "$container" ] || continue
|
||||
|
||||
Reference in New Issue
Block a user