mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
test(lint): forbid unmarked '|| true' in shell scripts; grandfather the corpus
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
754dd1274c
commit
c505ce7466
62 files changed
+323
-205
No files matched your search
@@ -77,8 +77,8 @@ find_highest_apt_python_pkg() {
|
||||
find_highest_rpm_python_pkg() {
|
||||
local pm="$1"
|
||||
{
|
||||
run_privileged "${pm}" -q list installed "python3.[0-9]*" 2>/dev/null || true
|
||||
run_privileged "${pm}" -q list --available "python3.[0-9]*" 2>/dev/null || true
|
||||
run_privileged "${pm}" -q list installed "python3.[0-9]*" 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
run_privileged "${pm}" -q list --available "python3.[0-9]*" 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
} \
|
||||
| awk '/^python3\.[0-9]+\./ {pkg=$1; sub(/\.[^.]+$/, "", pkg); print pkg}' \
|
||||
| sort -Vu \
|
||||
@@ -98,9 +98,9 @@ install_versioned_rpm_python_and_pip() {
|
||||
local py_pkg="$2"
|
||||
local pip_pkg="${py_pkg}-pip"
|
||||
|
||||
run_privileged "${pm}" -y install "${py_pkg}" || true
|
||||
run_privileged "${pm}" -y install "${py_pkg}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
if rpm_pkg_exists "${pm}" "${pip_pkg}"; then
|
||||
run_privileged "${pm}" -y install "${pip_pkg}" || true
|
||||
run_privileged "${pm}" -y install "${pip_pkg}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
log "Skipping unavailable package ${pip_pkg}; using generic python3-pip fallback if present."
|
||||
fi
|
||||
@@ -112,7 +112,7 @@ install_python_packages() {
|
||||
case "${ID}" in
|
||||
arch | manjaro)
|
||||
run_privileged pacman -Syu --noconfirm --needed python python-pip
|
||||
run_privileged pacman -Scc --noconfirm || true
|
||||
run_privileged pacman -Scc --noconfirm || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
;;
|
||||
|
||||
debian | ubuntu)
|
||||
@@ -124,9 +124,9 @@ install_python_packages() {
|
||||
run_privileged apt-get install -y --no-install-recommends python3 python3-pip
|
||||
apt_best_pkg="$(find_highest_apt_python_pkg || true)"
|
||||
if [[ "${apt_best_pkg}" =~ ^python3\.([0-9]+)$ ]] && (( BASH_REMATCH[1] >= 11 )); then
|
||||
run_privileged apt-get install -y --no-install-recommends "${apt_best_pkg}" || true
|
||||
run_privileged apt-get install -y --no-install-recommends "${apt_best_pkg}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
if apt-cache show "${apt_best_pkg}-venv" >/dev/null 2>&1; then
|
||||
run_privileged apt-get install -y --no-install-recommends "${apt_best_pkg}-venv" || true
|
||||
run_privileged apt-get install -y --no-install-recommends "${apt_best_pkg}-venv" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
fi
|
||||
run_privileged rm -rf /var/lib/apt/lists/*
|
||||
@@ -140,8 +140,8 @@ install_python_packages() {
|
||||
if [[ "${dnf_best_pkg}" =~ ^python3\.([0-9]+)$ ]] && (( BASH_REMATCH[1] >= 11 )); then
|
||||
install_versioned_rpm_python_and_pip dnf "${dnf_best_pkg}"
|
||||
fi
|
||||
run_privileged dnf -y clean all || true
|
||||
run_privileged rm -rf /var/cache/dnf || true
|
||||
run_privileged dnf -y clean all || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
run_privileged rm -rf /var/cache/dnf || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
;;
|
||||
|
||||
centos | rhel)
|
||||
@@ -152,13 +152,13 @@ install_python_packages() {
|
||||
else
|
||||
PM=yum
|
||||
fi
|
||||
run_privileged "${PM}" -y install python3 python3-pip || true
|
||||
run_privileged "${PM}" -y install python3 python3-pip || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
rpm_best_pkg="$(find_highest_rpm_python_pkg "${PM}" || true)"
|
||||
if [[ "${rpm_best_pkg}" =~ ^python3\.([0-9]+)$ ]] && (( BASH_REMATCH[1] >= 11 )); then
|
||||
install_versioned_rpm_python_and_pip "${PM}" "${rpm_best_pkg}"
|
||||
fi
|
||||
run_privileged "${PM}" -y clean all || true
|
||||
run_privileged rm -rf "/var/cache/${PM}" || true
|
||||
run_privileged "${PM}" -y clean all || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
run_privileged rm -rf "/var/cache/${PM}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
;;
|
||||
|
||||
*)
|
||||
@@ -170,13 +170,13 @@ install_python_packages() {
|
||||
else
|
||||
PM=yum
|
||||
fi
|
||||
run_privileged "${PM}" -y install python3 python3-pip || true
|
||||
run_privileged "${PM}" -y install python3 python3-pip || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
rpm_like_best_pkg="$(find_highest_rpm_python_pkg "${PM}" || true)"
|
||||
if [[ "${rpm_like_best_pkg}" =~ ^python3\.([0-9]+)$ ]] && (( BASH_REMATCH[1] >= 11 )); then
|
||||
install_versioned_rpm_python_and_pip "${PM}" "${rpm_like_best_pkg}"
|
||||
fi
|
||||
run_privileged "${PM}" -y clean all || true
|
||||
run_privileged rm -rf "/var/cache/${PM}" || true
|
||||
run_privileged "${PM}" -y clean all || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
run_privileged rm -rf "/var/cache/${PM}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
echo "[ERROR] Unsupported distro for Python install: ID=${ID} ID_LIKE=${ID_LIKE}" >&2
|
||||
exit 1
|
||||
@@ -289,7 +289,7 @@ configure_defaults() {
|
||||
run_privileged ln -sfn "${versioned_pip}" /usr/local/bin/pip3
|
||||
else
|
||||
if ! "${pybin}" -m pip --version >/dev/null 2>&1; then
|
||||
run_privileged "${pybin}" -m ensurepip --upgrade >/dev/null 2>&1 || true
|
||||
run_privileged "${pybin}" -m ensurepip --upgrade >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
if "${pybin}" -m pip --version >/dev/null 2>&1; then
|
||||
run_privileged tee /usr/local/bin/pip3 >/dev/null <<'EOF'
|
||||
@@ -316,7 +316,7 @@ resolve_python_bin_or_fail() {
|
||||
fi
|
||||
echo "[ERROR] No Python >= 3.11 found after installation attempt." >&2
|
||||
if command -v python3 >/dev/null 2>&1; then
|
||||
python3 --version || true
|
||||
python3 --version || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
@@ -324,7 +324,7 @@ resolve_python_bin_or_fail() {
|
||||
ensure_python_bin() {
|
||||
log "Ensuring highest available Python >=3.11 for ID=${ID} ID_LIKE=${ID_LIKE}"
|
||||
install_python_packages
|
||||
hash -r || true
|
||||
hash -r || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
resolve_python_bin_or_fail
|
||||
}
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ bootstrap_cn_config_via_slaptest() {
|
||||
|
||||
if ! has_cn_config; then
|
||||
log "slaptest did not generate cn=config; listing:"
|
||||
ls -la "${SLAPD_D_DIR}" || true
|
||||
ls -la "${SLAPD_D_DIR}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fatal "cn=config missing after slaptest"
|
||||
fi
|
||||
|
||||
@@ -145,7 +145,7 @@ EOF
|
||||
|
||||
# After slapadd, ensure permissions are correct (locks are sensitive)
|
||||
chown -R openldap:openldap "${DB_DIR}"
|
||||
chmod 700 "${DB_DIR}" || true
|
||||
chmod 700 "${DB_DIR}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
if ! has_mdb_files; then
|
||||
fatal "MDB files were not created under ${DB_DIR}"
|
||||
@@ -175,7 +175,7 @@ init_mdb_files_if_needed
|
||||
|
||||
# Final permission sweep (this is often the real fix)
|
||||
chown -R openldap:openldap /run/slapd "${DB_DIR}" "${SLAPD_D_DIR}"
|
||||
chmod 700 "${DB_DIR}" || true
|
||||
chmod 700 "${DB_DIR}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
log "starting slapd (foreground; drop privileges to openldap)"
|
||||
exec /usr/sbin/slapd \
|
||||
|
||||
@@ -49,8 +49,8 @@ for _ in {1..30}; do
|
||||
fi
|
||||
|
||||
cleanup() {
|
||||
container exec "$container" bash -lc "if [ -f \"$backup\" ]; then cp -a \"$backup\" \"$hba_file\" && rm -f \"$backup\"; fi" >/dev/null 2>&1 || true
|
||||
pg_exec 'SELECT pg_reload_conf();' >/dev/null 2>&1 || true
|
||||
container exec "$container" bash -lc "if [ -f \"$backup\" ]; then cp -a \"$backup\" \"$hba_file\" && rm -f \"$backup\"; fi" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
pg_exec 'SELECT pg_reload_conf();' >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
}
|
||||
trap 'cleanup' EXIT
|
||||
|
||||
@@ -103,8 +103,8 @@ container exec "$container" bash -lc "cp -a \"$hba_file\" \"$backup\""
|
||||
# shellcheck disable=SC2329,SC2317
|
||||
restore_hba() {
|
||||
# Restore on exit (best effort)
|
||||
container exec "$container" bash -lc "if [ -f \"$backup\" ]; then cp -a \"$backup\" \"$hba_file\" && rm -f \"$backup\"; fi" >/dev/null 2>&1 || true
|
||||
container exec "$container" bash -lc "psql -U postgres -d postgres -Atc 'SELECT pg_reload_conf();' >/dev/null 2>&1" || true
|
||||
container exec "$container" bash -lc "if [ -f \"$backup\" ]; then cp -a \"$backup\" \"$hba_file\" && rm -f \"$backup\"; fi" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
container exec "$container" bash -lc "psql -U postgres -d postgres -Atc 'SELECT pg_reload_conf();' >/dev/null 2>&1" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
}
|
||||
|
||||
# Register direct function trap so ShellCheck sees the invocation path.
|
||||
|
||||
@@ -19,8 +19,8 @@ if [[ "${DOCKER_IN_CONTAINER:-false}" == "true" ]]; then
|
||||
fi
|
||||
|
||||
# Clean leftover state between ephemeral jobs (container is restarted, not recreated).
|
||||
rm -rf ./_work 2>/dev/null || true
|
||||
find /tmp -mindepth 1 -maxdepth 1 -exec rm -rf {} + 2>/dev/null || true
|
||||
rm -rf ./_work 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
find /tmp -mindepth 1 -maxdepth 1 -exec rm -rf {} + 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
: "${RUNNER_API_TOKEN:?RUNNER_API_TOKEN must be set}"
|
||||
: "${RUNNER_GITHUB_OWNER:?RUNNER_GITHUB_OWNER must be set}"
|
||||
|
||||
@@ -64,7 +64,7 @@ install_anchor() {
|
||||
if command -v update-ca-certificates >/dev/null 2>&1; then
|
||||
log "Detected update-ca-certificates"
|
||||
if install_anchor "$CA_TRUST_CERT" "/usr/local/share/ca-certificates/${name}.crt"; then
|
||||
run update-ca-certificates || true
|
||||
run update-ca-certificates || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -74,7 +74,7 @@ fi
|
||||
if command -v update-ca-trust >/dev/null 2>&1; then
|
||||
log "Detected update-ca-trust"
|
||||
if install_anchor "$CA_TRUST_CERT" "/etc/pki/ca-trust/source/anchors/${name}.crt"; then
|
||||
run update-ca-trust extract || true
|
||||
run update-ca-trust extract || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -84,7 +84,7 @@ fi
|
||||
if command -v trust >/dev/null 2>&1; then
|
||||
log "Detected trust"
|
||||
if install_anchor "$CA_TRUST_CERT" "/etc/ca-certificates/trust-source/anchors/${name}.crt"; then
|
||||
run trust extract-compat || true
|
||||
run trust extract-compat || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -109,18 +109,18 @@ if command -v certutil >/dev/null 2>&1; then
|
||||
log "Detected certutil; importing CA into NSS DB: ${nss_db}"
|
||||
|
||||
# Ensure directory exists
|
||||
run mkdir -p "$nss_db" 2>/dev/null || true
|
||||
run mkdir -p "$nss_db" 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
# Create NSS DB if missing (empty password)
|
||||
if [ ! -f "$nss_db/cert9.db" ]; then
|
||||
run certutil -N -d "sql:${nss_db}" --empty-password 2>/dev/null || true
|
||||
run certutil -N -d "sql:${nss_db}" --empty-password 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
# Remove existing cert entry (best-effort)
|
||||
run certutil -D -d "sql:${nss_db}" -n "$name" >/dev/null 2>&1 || true
|
||||
run certutil -D -d "sql:${nss_db}" -n "$name" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
# Import as trusted CA (C,, = trusted CA for SSL)
|
||||
run certutil -A -d "sql:${nss_db}" -n "$name" -t "C,," -i "$CA_TRUST_CERT" 2>/dev/null || true
|
||||
run certutil -A -d "sql:${nss_db}" -n "$name" -t "C,," -i "$CA_TRUST_CERT" 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
log "NSS trust import attempted (best-effort)"
|
||||
else
|
||||
|
||||
@@ -4,25 +4,25 @@ set -euo pipefail
|
||||
|
||||
echo "=== [cleanup] package manager caches ==="
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
apt-get clean || true
|
||||
apt-get clean || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
if command -v pacman >/dev/null 2>&1; then
|
||||
pacman -Scc --noconfirm || true
|
||||
pacman -Scc --noconfirm || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
if command -v dnf >/dev/null 2>&1; then
|
||||
dnf clean all || true
|
||||
rm -rf /var/cache/dnf || true
|
||||
dnf clean all || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
rm -rf /var/cache/dnf || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
if command -v yum >/dev/null 2>&1; then
|
||||
yum clean all || true
|
||||
rm -rf /var/cache/yum || true
|
||||
yum clean all || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
rm -rf /var/cache/yum || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
echo "=== [cleanup] language/tool caches (best effort) ==="
|
||||
rm -rf /root/.cache/pip /home/*/.cache/pip 2>/dev/null || true
|
||||
rm -rf /root/.npm /home/*/.npm 2>/dev/null || true
|
||||
rm -rf /root/.cache/yarn /home/*/.cache/yarn 2>/dev/null || true
|
||||
rm -rf /root/.cache/go-build /home/*/.cache/go-build 2>/dev/null || true
|
||||
rm -rf /root/.cache/pip /home/*/.cache/pip 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
rm -rf /root/.npm /home/*/.npm 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
rm -rf /root/.cache/yarn /home/*/.cache/yarn 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
rm -rf /root/.cache/go-build /home/*/.cache/go-build 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
@@ -20,18 +20,18 @@ if ! command -v docker >/dev/null 2>&1; then
|
||||
fi
|
||||
|
||||
echo "--- container version ---"
|
||||
container version 2>&1 || true
|
||||
container version 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
|
||||
echo "--- container info (short) ---"
|
||||
container info 2>/dev/null | sed -n '1,120p' || true
|
||||
container info 2>/dev/null | sed -n '1,120p' || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
|
||||
echo "--- container ps ---"
|
||||
if [ "${INCLUDE_EXITED}" = "true" ]; then
|
||||
container ps -a --no-trunc 2>&1 || true
|
||||
container ps -a --no-trunc 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
container ps --no-trunc 2>&1 || true
|
||||
container ps --no-trunc 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
echo
|
||||
|
||||
@@ -60,7 +60,7 @@ for id in ${ids}; do
|
||||
echo " status=${status:-?} health=${health:-n/a}"
|
||||
echo " image=${image:-?}"
|
||||
echo "------------------------------------------------------------"
|
||||
container logs --tail "${TAIL}" "${id}" 2>&1 || true
|
||||
container logs --tail "${TAIL}" "${id}" 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
done
|
||||
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
set -euo pipefail
|
||||
|
||||
echo "Docker disk usage before cleanup:"
|
||||
container system df || true
|
||||
container system df || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
container container prune -f || true
|
||||
container image prune -af || true
|
||||
container volume prune -f || true
|
||||
container container prune -f || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
container image prune -af || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
container volume prune -f || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
container buildx prune -af || true
|
||||
container builder prune -af || true
|
||||
container buildx prune -af || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
container builder prune -af || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
echo "Docker disk usage after cleanup:"
|
||||
container system df || true
|
||||
container system df || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
@@ -76,7 +76,7 @@ Package: docker-compose-v2
|
||||
Pin: release o=Ubuntu
|
||||
Pin-Priority: -1
|
||||
EOF
|
||||
apt-get -y purge docker-compose-v2 >/dev/null 2>&1 || true
|
||||
apt-get -y purge docker-compose-v2 >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
apt-get update
|
||||
@@ -109,16 +109,16 @@ elif [[ "${ID}" == "fedora" ]]; then
|
||||
|
||||
elif [[ "${ID}" == "centos" || "${ID}" == "rhel" || "${ID_LIKE:-}" =~ (rhel|centos) ]]; then
|
||||
if command -v dnf >/dev/null 2>&1; then PM=dnf; else PM=yum; fi
|
||||
${PM} -y install yum-utils || true
|
||||
${PM} -y install dnf-plugins-core || true
|
||||
add_repo_rpm_compatible "${PM}" "https://download.docker.com/linux/centos/docker-ce.repo" || true
|
||||
${PM} -y install yum-utils || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
${PM} -y install dnf-plugins-core || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
add_repo_rpm_compatible "${PM}" "https://download.docker.com/linux/centos/docker-ce.repo" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
if [[ "${REPO_ONLY}" == "1" ]]; then
|
||||
${PM} -y makecache || true
|
||||
${PM} -y makecache || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
# Prefer the same Docker CLI/buildx/compose package set as Fedora.
|
||||
(${PM} -y install docker-ce-cli docker-buildx-plugin docker-compose-plugin) || \
|
||||
(${PM} -y install docker-ce-cli) || \
|
||||
(${PM} -y install docker) || true
|
||||
(${PM} -y install docker) || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
set -o pipefail
|
||||
|
||||
echo "== findmnt -T /mnt/docker =="
|
||||
findmnt -T /mnt/docker || true
|
||||
findmnt -T /mnt/docker || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
|
||||
echo "== df -h / /mnt /mnt/docker /var/lib/docker =="
|
||||
df -h / /mnt /mnt/docker /var/lib/docker || true
|
||||
df -h / /mnt /mnt/docker /var/lib/docker || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
|
||||
echo '== container info | grep "Docker Root Dir" =='
|
||||
container info | grep "Docker Root Dir" || true
|
||||
container info | grep "Docker Root Dir" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
|
||||
echo "== du -xhd1 /usr /usr/local /usr/share /opt /mnt /var | sort -h =="
|
||||
du -xhd1 /usr /usr/local /usr/share /opt /mnt /var 2>/dev/null | sort -h || true
|
||||
du -xhd1 /usr /usr/local /usr/share /opt /mnt /var 2>/dev/null | sort -h || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
@@ -24,10 +24,10 @@ ADDON="$2"
|
||||
DESIRED="$3"
|
||||
|
||||
if [[ "$DESIRED" == "true" ]]; then
|
||||
$CMD addon disable "$ADDON" 2>&1 || true
|
||||
$CMD addon enable "$ADDON" 2>&1 || true
|
||||
$CMD addon disable "$ADDON" 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
$CMD addon enable "$ADDON" 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
$CMD addon disable "$ADDON" 2>&1 || true
|
||||
$CMD addon disable "$ADDON" 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
if $CMD addon list enabled | grep -qE "^\| +${ADDON} +\|$"; then
|
||||
|
||||
@@ -17,13 +17,13 @@ wait_up() {
|
||||
|
||||
complete_wizard() {
|
||||
curl -fsS -X POST "${API}/Startup/Configuration" -H "Content-Type: application/json" -H "${CLIENT_HDR}" \
|
||||
-d '{"UICulture":"en-US","MetadataCountryCode":"US","PreferredMetadataLanguage":"en"}' >/dev/null 2>&1 || true
|
||||
curl -fsS "${API}/Startup/User" -H "${CLIENT_HDR}" >/dev/null 2>&1 || true
|
||||
-d '{"UICulture":"en-US","MetadataCountryCode":"US","PreferredMetadataLanguage":"en"}' >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
curl -fsS "${API}/Startup/User" -H "${CLIENT_HDR}" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
curl -fsS -X POST "${API}/Startup/User" -H "Content-Type: application/json" -H "${CLIENT_HDR}" \
|
||||
-d "{\"Name\":\"${JELLYFIN_ADMIN_USERNAME}\",\"Password\":\"${JELLYFIN_ADMIN_PASSWORD}\"}" >/dev/null 2>&1 || true
|
||||
-d "{\"Name\":\"${JELLYFIN_ADMIN_USERNAME}\",\"Password\":\"${JELLYFIN_ADMIN_PASSWORD}\"}" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
curl -fsS -X POST "${API}/Startup/RemoteAccess" -H "Content-Type: application/json" -H "${CLIENT_HDR}" \
|
||||
-d '{"EnableRemoteAccess":true,"EnableAutomaticPortMapping":false}' >/dev/null 2>&1 || true
|
||||
curl -fsS -X POST "${API}/Startup/Complete" -H "${CLIENT_HDR}" >/dev/null 2>&1 || true
|
||||
-d '{"EnableRemoteAccess":true,"EnableAutomaticPortMapping":false}' >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
curl -fsS -X POST "${API}/Startup/Complete" -H "${CLIENT_HDR}" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
}
|
||||
|
||||
get_token() {
|
||||
@@ -80,7 +80,7 @@ seed_admin_and_get_token || log "WARN: admin token unavailable after wizard retr
|
||||
if [ -n "${TOKEN:-}" ] && [ "${JELLYFIN_SSO_ENABLED}" = "true" ]; then
|
||||
curl -fsS -X POST "${API}/Repositories" -H "Content-Type: application/json" \
|
||||
-H "Authorization: MediaBrowser Token=\"${TOKEN}\"" \
|
||||
-d "[{\"Name\":\"jellyfin-plugin-sso\",\"Url\":\"${JELLYFIN_SSO_PLUGIN_MANIFEST}\",\"Enabled\":true}]" >/dev/null 2>&1 || true
|
||||
-d "[{\"Name\":\"jellyfin-plugin-sso\",\"Url\":\"${JELLYFIN_SSO_PLUGIN_MANIFEST}\",\"Enabled\":true}]" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
[ "${JELLYFIN_LDAP_ENABLED}" = "true" ] && install_ldap_plugin
|
||||
|
||||
@@ -28,7 +28,7 @@ if [[ -n "${CA_FILE}" && -r "${CA_FILE}" ]]; then
|
||||
-alias "${CA_TRUST_NAME}" \
|
||||
-file "${CA_FILE}" \
|
||||
-keystore "${CACERTS}" \
|
||||
-storepass "changeit" >/dev/null 2>&1 || true
|
||||
-storepass "changeit" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
+1
-1
@@ -26,5 +26,5 @@ container exec -i "$KC_CONTAINER" /opt/keycloak/bin/kcadm.sh get components \
|
||||
while IFS= read -r m_id; do
|
||||
[ -z "$m_id" ] && continue
|
||||
container exec -i "$KC_CONTAINER" /opt/keycloak/bin/kcadm.sh delete \
|
||||
"components/$m_id" -r "$KC_REALM" </dev/null || true
|
||||
"components/$m_id" -r "$KC_REALM" </dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
done < /tmp/kc_ldap_roles_ids.txt
|
||||
@@ -23,5 +23,5 @@ awk -F',' '!/^\[/ && !/Cgroup/ && $1 != "" { print $1 }' \
|
||||
while IFS= read -r stale_id; do
|
||||
[ -z "$stale_id" ] && continue
|
||||
container exec -i "$KC_CONTAINER" /opt/keycloak/bin/kcadm.sh delete \
|
||||
"groups/$stale_id" -r "$KC_REALM" </dev/null 2>/dev/null || true
|
||||
"groups/$stale_id" -r "$KC_REALM" </dev/null 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
done < /tmp/kc_app_orphans.txt
|
||||
@@ -41,5 +41,5 @@ awk -F',' -v keep="$DEPLOYED_APP_IDS" '
|
||||
while IFS= read -r stale_id; do
|
||||
[ -z "$stale_id" ] && continue
|
||||
container exec -i "$KC_CONTAINER" /opt/keycloak/bin/kcadm.sh delete \
|
||||
"groups/$stale_id" -r "$KC_REALM" </dev/null 2>/dev/null || true
|
||||
"groups/$stale_id" -r "$KC_REALM" </dev/null 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
done < /tmp/kc_root_to_delete.txt
|
||||
@@ -14,4 +14,4 @@ set -o pipefail
|
||||
|
||||
container exec -i "$KC_CONTAINER" /opt/keycloak/bin/kcadm.sh create \
|
||||
"user-storage/$LDAP_COMPONENT_ID/mappers/$MAPPER_ID/sync?direction=fedToKeycloak" \
|
||||
-r "$KC_REALM" 2>&1 || true
|
||||
-r "$KC_REALM" 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
@@ -41,7 +41,7 @@ if [ -n "$EXISTING_ID" ]; then
|
||||
"$PAYLOAD_FILE" \
|
||||
| container exec -i "$KC_CONTAINER" /opt/keycloak/bin/kcadm.sh update \
|
||||
"components/$EXISTING_ID" -r "$KC_REALM" -f - \
|
||||
>/dev/null 2>&1 || true
|
||||
>/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
printf '%s\n' "$EXISTING_ID"
|
||||
else
|
||||
container exec -i "$KC_CONTAINER" /opt/keycloak/bin/kcadm.sh create \
|
||||
|
||||
@@ -29,7 +29,7 @@ while [ "$attempt" -lt 30 ]; do
|
||||
done
|
||||
if [ "$ready" -ne 1 ]; then
|
||||
echo "!!! matrix-mdad-bootstrap: python runtime never became importable, aborting" >&2
|
||||
"$PYTHON" -c 'import _posixsubprocess' || true
|
||||
"$PYTHON" -c 'import _posixsubprocess' || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ fi
|
||||
_gw="$(printf '%d.%d.%d.%d' "0x${_gw_hex:6:2}" "0x${_gw_hex:4:2}" "0x${_gw_hex:2:2}" "0x${_gw_hex:0:2}")"
|
||||
|
||||
_hosts_tmp="$(mktemp)"
|
||||
grep -v "[[:space:]]${MATRIX_OIDC_ONION_HOST}\$" /etc/hosts > "${_hosts_tmp}" || true
|
||||
grep -v "[[:space:]]${MATRIX_OIDC_ONION_HOST}\$" /etc/hosts > "${_hosts_tmp}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
printf '%s\t%s\n' "${_gw}" "${MATRIX_OIDC_ONION_HOST}" >> "${_hosts_tmp}"
|
||||
cat "${_hosts_tmp}" > /etc/hosts
|
||||
rm -f "${_hosts_tmp}"
|
||||
|
||||
@@ -15,12 +15,12 @@ set -euo pipefail
|
||||
: "${MOODLE_VERSION_FILE:?required}"
|
||||
|
||||
mkdir -p "${MOODLE_DATA_DIR}"
|
||||
chown -R "${MOODLE_RUNTIME_USER}:${MOODLE_RUNTIME_USER}" "${MOODLE_DATA_DIR}" || true
|
||||
chown -R "${MOODLE_RUNTIME_USER}:${MOODLE_RUNTIME_USER}" "${MOODLE_DATA_DIR}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
if [ ! -f "${MOODLE_CODE_DIR}/${MOODLE_VERSION_FILE}" ] && [ -d "${MOODLE_SOURCE_DIR}" ]; then
|
||||
cp -a "${MOODLE_SOURCE_DIR}/." "${MOODLE_CODE_DIR}/"
|
||||
fi
|
||||
chown -R "${MOODLE_RUNTIME_USER}:${MOODLE_RUNTIME_USER}" "${MOODLE_CODE_DIR}" || true
|
||||
chown -R "${MOODLE_RUNTIME_USER}:${MOODLE_RUNTIME_USER}" "${MOODLE_CODE_DIR}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
if [ "$(id -u)" -eq 0 ] && [ "${1:-}" != "php-fpm" ]; then
|
||||
exec gosu "${MOODLE_RUNTIME_USER}" "$@"
|
||||
|
||||
@@ -25,33 +25,33 @@ echo
|
||||
echo "--- State ---"
|
||||
container inspect --format \
|
||||
'Status={{.State.Status}} Running={{.State.Running}} Restarting={{.State.Restarting}} OOMKilled={{.State.OOMKilled}} ExitCode={{.State.ExitCode}} StartedAt={{.State.StartedAt}} FinishedAt={{.State.FinishedAt}} RestartCount={{.RestartCount}}' \
|
||||
"${CONTAINER}" 2>&1 || true
|
||||
"${CONTAINER}" 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
|
||||
echo "--- Health ---"
|
||||
container inspect --format \
|
||||
'{{if .State.Health}}Status={{.State.Health.Status}} FailingStreak={{.State.Health.FailingStreak}}{{range .State.Health.Log}}{{println "log:" .ExitCode .Output}}{{end}}{{else}}no healthcheck configured{{end}}' \
|
||||
"${CONTAINER}" 2>&1 || true
|
||||
"${CONTAINER}" 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
|
||||
echo "--- Resource limits ---"
|
||||
container inspect --format \
|
||||
'MemLimit={{.HostConfig.Memory}} MemSwap={{.HostConfig.MemorySwap}} NanoCpus={{.HostConfig.NanoCpus}} PidsLimit={{.HostConfig.PidsLimit}}' \
|
||||
"${CONTAINER}" 2>&1 || true
|
||||
"${CONTAINER}" 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
|
||||
echo "--- container stats (single snapshot) ---"
|
||||
container stats --no-stream --no-trunc "${CONTAINER}" 2>&1 || true
|
||||
container stats --no-stream --no-trunc "${CONTAINER}" 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
|
||||
echo "--- container logs (last 250 lines) ---"
|
||||
container logs --tail 250 "${CONTAINER}" 2>&1 || true
|
||||
container logs --tail 250 "${CONTAINER}" 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
|
||||
echo "--- Host memory + swap ---"
|
||||
free -h 2>&1 || true
|
||||
free -h 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
swapon --show 2>&1 || true
|
||||
swapon --show 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
|
||||
echo "--- dmesg tail (OOM-killer evidence, best effort) ---"
|
||||
|
||||
@@ -12,10 +12,10 @@ php /wait-for-db.php
|
||||
|
||||
if [ -n "${CA_TRUST_CERT:-}" ] && [ -r "${CA_TRUST_CERT}" ]; then
|
||||
if ! command -v update-ca-certificates >/dev/null 2>&1; then
|
||||
{ apt-get update -y && apt-get install -y --no-install-recommends ca-certificates; } || true
|
||||
{ apt-get update -y && apt-get install -y --no-install-recommends ca-certificates; } || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
cp "${CA_TRUST_CERT}" "/usr/local/share/ca-certificates/${CA_TRUST_NAME}.crt" || true
|
||||
update-ca-certificates || true
|
||||
cp "${CA_TRUST_CERT}" "/usr/local/share/ca-certificates/${CA_TRUST_NAME}.crt" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
update-ca-certificates || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
echo "++++ Start apache... ++++"
|
||||
|
||||
@@ -44,11 +44,11 @@ if [ "$(id -u)" -eq 0 ]; then
|
||||
chown -R www-data:www-data \
|
||||
"$APP_ROOT/public" \
|
||||
"$APP_ROOT/var" \
|
||||
"$APP_ROOT/.infinito" || true
|
||||
"$APP_ROOT/.infinito" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
chmod -R 775 \
|
||||
"$APP_ROOT/public" \
|
||||
"$APP_ROOT/var" \
|
||||
"$APP_ROOT/.infinito" || true
|
||||
"$APP_ROOT/.infinito" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
# Switch to www-data for all subsequent operations
|
||||
exec su -s /bin/sh www-data "$0" "$@"
|
||||
|
||||
@@ -10,7 +10,7 @@ cd "$SHOPWARE_ROOT"
|
||||
old_user="admin"
|
||||
if php bin/console user:list | grep -q "^$old_user "; then
|
||||
echo "[INFO] Renaming Shopware user: $old_user -> $NEW_USER"
|
||||
php bin/console user:update "$old_user" --username="$NEW_USER" || true
|
||||
php bin/console user:update "$old_user" --username="$NEW_USER" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
echo "[INFO] No user named $old_user found (already renamed or custom setup)"
|
||||
fi
|
||||
@@ -68,8 +68,8 @@ fi
|
||||
# Clear Symfony Cache
|
||||
############################################
|
||||
log "Clearing Symfony cache..."
|
||||
php bin/console cache:clear --no-warmup || true
|
||||
php bin/console cache:warmup || true
|
||||
php bin/console cache:clear --no-warmup || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
php bin/console cache:warmup || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
############################################
|
||||
# Healthcheck file
|
||||
|
||||
@@ -44,7 +44,7 @@ container exec "$XWIKI_CONTAINER" sh -lc '
|
||||
grep -E "^xwiki\.superadminpassword=" "$cfg" \
|
||||
| sed "s/^xwiki\.superadminpassword=//" \
|
||||
| sha256sum | awk "{print \$1}"
|
||||
' || true
|
||||
' || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
echo -n "ansible_hash="
|
||||
printf '%s' "$ANSIBLE_PASSWORD" | sha256sum | awk '{print $1}'
|
||||
@@ -58,10 +58,10 @@ for app in "${apps[@]}"; do
|
||||
done
|
||||
|
||||
echo ">>> Wiping token-store entries for: ${apps[*]}"
|
||||
"${python_bin}" -m utils.cleanup.tokens "${apps[@]}" || true
|
||||
"${python_bin}" -m utils.cleanup.tokens "${apps[@]}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
echo ">>> Wiping databases.csv entries for: ${apps[*]}"
|
||||
"${python_bin}" -m utils.cleanup.databases_csv "${apps[@]}" || true
|
||||
"${python_bin}" -m utils.cleanup.databases_csv "${apps[@]}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
if [[ "${#entities[@]}" -lt 1 ]]; then
|
||||
echo "!!! WARNING: no valid entities found: skipping entity purge"
|
||||
@@ -71,12 +71,12 @@ fi
|
||||
for entity in "${entities[@]}"; do
|
||||
echo
|
||||
echo ">>> Purging entity: ${entity}"
|
||||
bash "${ENTITY_DIR}/nginx.sh" "${entity}" || true
|
||||
bash "${ENTITY_DIR}/nginx.sh" "${entity}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
if [[ -d "/opt/compose/${entity}" ]]; then
|
||||
bash "${ENTITY_DIR}/db.sh" "${entity}" || true
|
||||
bash "${ENTITY_DIR}/compose.sh" "${entity}" || true
|
||||
bash "${ENTITY_DIR}/dir.sh" "${entity}" || true
|
||||
bash "${ENTITY_DIR}/network.sh" "${entity}" || true
|
||||
bash "${ENTITY_DIR}/db.sh" "${entity}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
bash "${ENTITY_DIR}/compose.sh" "${entity}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
bash "${ENTITY_DIR}/dir.sh" "${entity}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
bash "${ENTITY_DIR}/network.sh" "${entity}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
echo ">>> /opt/compose/${entity} not present — skipping compose/db/dir/network purges"
|
||||
fi
|
||||
|
||||
@@ -32,7 +32,7 @@ for STACK_NAME in "$@"; do
|
||||
|
||||
log "Compose down for '${STACK_NAME}'..."
|
||||
cd "$STACK_DIR"
|
||||
run_no_stdin compose down --remove-orphans -v || true
|
||||
run_no_stdin compose down --remove-orphans -v || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
) || {
|
||||
rc=$?
|
||||
overall_rc=1
|
||||
|
||||
@@ -249,21 +249,21 @@ for STACK_NAME in "$@"; do
|
||||
KC_DB_URL="$(env_get "${ENV_FILE}" KC_DB_URL || true)"
|
||||
|
||||
if [[ -n "${KC_DB}" ]]; then
|
||||
echo "${KC_DB}" | grep -qi postgres && DB_BACKEND="postgres" || true
|
||||
echo "${KC_DB}" | grep -qi mariadb && DB_BACKEND="mariadb" || true
|
||||
echo "${KC_DB}" | grep -qi postgres && DB_BACKEND="postgres" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo "${KC_DB}" | grep -qi mariadb && DB_BACKEND="mariadb" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
if [[ -n "${KC_DB_URL}" ]]; then
|
||||
echo "${KC_DB_URL}" | grep -qi postgresql && DB_BACKEND="postgres" || true
|
||||
echo "${KC_DB_URL}" | grep -qi mariadb && DB_BACKEND="mariadb" || true
|
||||
echo "${KC_DB_URL}" | grep -qi postgresql && DB_BACKEND="postgres" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo "${KC_DB_URL}" | grep -qi mariadb && DB_BACKEND="mariadb" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
DB_NAME="$(echo "${KC_DB_URL}" | sed -E 's|.*/([^/?#]+).*|\1|')"
|
||||
fi
|
||||
|
||||
if [[ -z "${DB_BACKEND}" ]]; then
|
||||
grep -qi postgres "${ENV_FILE}" && DB_BACKEND="postgres" || true
|
||||
grep -qi postgres "${ENV_FILE}" && DB_BACKEND="postgres" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
if [[ -z "${DB_BACKEND}" ]]; then
|
||||
grep -qi mariadb "${ENV_FILE}" && DB_BACKEND="mariadb" || true
|
||||
grep -qi mariadb "${ENV_FILE}" && DB_BACKEND="mariadb" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
else
|
||||
warn "Env file not found (${ENV_FILE}) — DB name defaults to stack name '${DB_NAME}'"
|
||||
|
||||
@@ -15,7 +15,7 @@ ALL_DISTROS=(arch debian ubuntu fedora centos)
|
||||
version_tag="$(
|
||||
git tag --points-at "${GITHUB_SHA}" |
|
||||
grep -E '^v[0-9]+(\.[0-9]+)*$' |
|
||||
head -n 1 || true
|
||||
head -n 1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
)"
|
||||
|
||||
if [[ -n "$version_tag" ]]; then
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
set -euo pipefail
|
||||
|
||||
echo "=== Cleanup ==="
|
||||
docker buildx prune -af || true
|
||||
docker builder prune -af || true
|
||||
docker image prune -af || true
|
||||
docker container prune -f || true
|
||||
docker buildx prune -af || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
docker builder prune -af || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
docker image prune -af || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
docker container prune -f || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
echo "=== Disk pressure: AFTER CLEANUP ==="
|
||||
df -h
|
||||
echo
|
||||
docker system df || true
|
||||
docker buildx du || true
|
||||
docker system df || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
docker buildx du || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
@@ -14,10 +14,10 @@ echo "Runner: $(uname -a)"
|
||||
echo
|
||||
df -h
|
||||
echo
|
||||
docker version || true
|
||||
docker version || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
docker system df || true
|
||||
docker system df || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
docker buildx version || true
|
||||
docker buildx version || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
docker buildx du || true
|
||||
docker buildx du || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
@@ -22,10 +22,10 @@ echo "--- disk (inodes) ---"
|
||||
df -hi / /mnt 2>/dev/null || df -hi /
|
||||
|
||||
echo "--- block devices ---"
|
||||
lsblk -f || true
|
||||
lsblk -f || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
echo "--- mounts (/, /mnt, /var/lib/docker, /mnt/docker) ---"
|
||||
mount | grep -E ' / | /mnt | /var/lib/docker | /mnt/docker ' || true
|
||||
mount | grep -E ' / | /mnt | /var/lib/docker | /mnt/docker ' || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
echo "--- docker ---"
|
||||
docker info 2>/dev/null |
|
||||
@@ -39,11 +39,11 @@ echo "--- swap ---"
|
||||
swapon --show || echo "no swap active"
|
||||
|
||||
echo "--- largest dirs on / (top 15) ---"
|
||||
sudo du -xh --max-depth=2 / 2>/dev/null | sort -h | tail -15 || true
|
||||
sudo du -xh --max-depth=2 / 2>/dev/null | sort -h | tail -15 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
if [ -d /mnt ]; then
|
||||
echo "--- largest dirs on /mnt (top 15) ---"
|
||||
sudo du -xh --max-depth=2 /mnt 2>/dev/null | sort -h | tail -15 || true
|
||||
sudo du -xh --max-depth=2 /mnt 2>/dev/null | sort -h | tail -15 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
# Nested view — hlth-disc-space runs INSIDE the infinito container and
|
||||
@@ -58,7 +58,7 @@ if [ -n "${INFINITO_CONTAINER}" ]; then
|
||||
docker exec "${INFINITO_CONTAINER}" df -h 2>&1 || echo "docker exec df failed"
|
||||
|
||||
echo "--- df --output=pcent inside container (what hlth-disc-space sees) ---"
|
||||
docker exec "${INFINITO_CONTAINER}" df --output=pcent 2>&1 || true
|
||||
docker exec "${INFINITO_CONTAINER}" df --output=pcent 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
echo "--- failed systemd units inside container ---"
|
||||
docker exec "${INFINITO_CONTAINER}" systemctl --failed --no-pager 2>&1 ||
|
||||
|
||||
@@ -34,7 +34,7 @@ MIN_FREE_GB=$((SWAP_GB + 4)) # need the target size plus a little slack
|
||||
|
||||
"$DUMP" "before swap resize"
|
||||
|
||||
sudo swapoff -a || true
|
||||
sudo swapoff -a || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
sudo rm -f /mnt/swapfile /swapfile
|
||||
|
||||
# Only treat /mnt as a candidate if it is actually a separate mount.
|
||||
|
||||
@@ -57,4 +57,4 @@ for entry in "${entries[@]}"; do
|
||||
bash "${SCRIPT_DIR}/open_pr.sh" "${ROOT}/${entry}"
|
||||
done
|
||||
|
||||
git checkout --quiet --force --detach "${base}" || true
|
||||
git checkout --quiet --force --detach "${base}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
@@ -151,9 +151,9 @@ gh_api_json() {
|
||||
shift # orgs|users
|
||||
|
||||
if [[ "${method}" == "GET" ]]; then
|
||||
gh api -H "Accept: application/vnd.github+json" "/${scope}/${OWNER}/${endpoint}" "$@" 2>/dev/null || true
|
||||
gh api -H "Accept: application/vnd.github+json" "/${scope}/${OWNER}/${endpoint}" "$@" 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
gh api -X "${method}" -H "Accept: application/vnd.github+json" "/${scope}/${OWNER}/${endpoint}" "$@" 2>/dev/null || true
|
||||
gh api -X "${method}" -H "Accept: application/vnd.github+json" "/${scope}/${OWNER}/${endpoint}" "$@" 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -52,5 +52,5 @@ ANSIBLE_COLLECTIONS_DIR="${HOME}/.ansible/collections" bash scripts/install/ansi
|
||||
|
||||
stamp_dir="$(dirname "${STAMP}")"
|
||||
mkdir -p "${stamp_dir}"
|
||||
chmod 0777 "${stamp_dir}" 2>/dev/null || true
|
||||
chmod 0777 "${stamp_dir}" 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
touch "${STAMP}"
|
||||
@@ -25,7 +25,7 @@ build_and_install_arch() {
|
||||
pacman-key --init
|
||||
pacman-key --populate archlinux
|
||||
# Tolerate missing manjaro keyring on pure Arch images (no manjaro.gpg present).
|
||||
pacman-key --populate manjaro 2>/dev/null || true
|
||||
pacman-key --populate manjaro 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
echo "[arch] Installing build toolchain..."
|
||||
pacman -Syu --noconfirm --needed base-devel sudo rsync
|
||||
@@ -132,7 +132,7 @@ build_and_install_rpm_like() {
|
||||
echo "[rpm] Installing ${rpm_path} via ${pm}..."
|
||||
bootstrap_docker_repo
|
||||
"${pm}" -y install "${rpm_path}"
|
||||
"${pm}" -y clean all || true
|
||||
"${pm}" -y clean all || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
}
|
||||
|
||||
main() {
|
||||
|
||||
@@ -180,9 +180,9 @@ if is_truthy "${PARALLEL}"; then
|
||||
# `|| true` so `set -e` does not abort the parent if any worker
|
||||
# exited non-zero — write_status has still run, and we want to reach
|
||||
# the summary block.
|
||||
wait || true
|
||||
wait || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
for w in "${workers[@]}"; do "${w}" || true; done
|
||||
for w in "${workers[@]}"; do "${w}" || true; done # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
# ── summary ──────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -63,7 +63,7 @@ echo ">>> arch/PKGBUILD"
|
||||
run_strict "bash -n syntax" bash -n packaging/arch/PKGBUILD
|
||||
if command -v namcap >/dev/null 2>&1; then
|
||||
echo " namcap report (informational):"
|
||||
namcap packaging/arch/PKGBUILD || true # exit code unreliable → not gating
|
||||
namcap packaging/arch/PKGBUILD || true # exit code unreliable → not gating # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
echo " SKIP: namcap not installed (informational PKGBUILD lint)"
|
||||
fi
|
||||
|
||||
@@ -122,7 +122,7 @@ if [[ -n "${GITHUB_ACTIONS:-}" && -z "${ACT:-}" ]]; then
|
||||
--required-storage "${required_storage}" \
|
||||
--warnings \
|
||||
--format json \
|
||||
>/dev/null || true
|
||||
>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
# Real filter (JSON output)
|
||||
apps_json="$(
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ echo "🔧 Running project setup (no installation)"
|
||||
# Optional: show interpreter for debugging
|
||||
echo "🐍 Using PYTHON=${PYTHON}"
|
||||
if command -v "${PYTHON}" >/dev/null 2>&1; then
|
||||
"${PYTHON}" -c 'import sys; print("sys.executable=", sys.executable)' || true
|
||||
"${PYTHON}" -c 'import sys; print("sys.executable=", sys.executable)' || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
ROLES_DIR="./roles"
|
||||
|
||||
@@ -13,7 +13,7 @@ if ! apparmor_should_manage; then
|
||||
fi
|
||||
|
||||
if apparmor_service_exists; then
|
||||
systemctl stop apparmor || true
|
||||
systemctl stop apparmor || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
echo "[apparmor] apparmor.service not available or systemd inactive; skipping service stop"
|
||||
fi
|
||||
@@ -21,7 +21,7 @@ fi
|
||||
if command -v aa-teardown >/dev/null 2>&1; then
|
||||
aa-teardown || apparmor_warn "[apparmor] aa-teardown returned non-zero; continuing"
|
||||
elif command -v apparmor_parser >/dev/null 2>&1 && compgen -G '/etc/apparmor.d/*' >/dev/null; then
|
||||
apparmor_parser -R /etc/apparmor.d/* || true
|
||||
apparmor_parser -R /etc/apparmor.d/* || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
echo "[apparmor] no AppArmor profile tooling available; skipping profile unload"
|
||||
fi
|
||||
|
||||
Vendored
+2
-2
@@ -32,8 +32,8 @@ source "scripts/meta/env/load.sh"
|
||||
# scope to the two cache services explicitly.
|
||||
if docker ps --format '{{.Names}}' | grep -qE '^infinito-(registry|package)-cache$'; then
|
||||
echo "[clean-cache] stopping infinito-registry-cache + infinito-package-cache"
|
||||
docker stop infinito-registry-cache infinito-package-cache 2>/dev/null || true
|
||||
docker rm infinito-registry-cache infinito-package-cache 2>/dev/null || true
|
||||
docker stop infinito-registry-cache infinito-package-cache 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
docker rm infinito-registry-cache infinito-package-cache 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
PATHS=(
|
||||
|
||||
@@ -9,7 +9,7 @@ run_if_available() {
|
||||
shift
|
||||
command -v "$1" >/dev/null 2>&1 || return 0
|
||||
echo "=== ${label} ==="
|
||||
"$@" 2>/dev/null || true
|
||||
"$@" 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo ""
|
||||
}
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ dns_test_resolution() {
|
||||
echo ">>> Testing resolution"
|
||||
if [[ "${DNS_HOSTS_FILE}" == "/etc/hosts" ]]; then
|
||||
while IFS= read -r host; do
|
||||
getent hosts "${host}" || true
|
||||
getent hosts "${host}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
checked=$((checked + 1))
|
||||
if [[ "${checked}" -ge 3 ]]; then
|
||||
break
|
||||
|
||||
@@ -23,11 +23,11 @@ if systemctl is-active --quiet NetworkManager 2>/dev/null; then
|
||||
fi
|
||||
|
||||
# Remove system dnsmasq snippet (fallback setup)
|
||||
sudo rm -f "${DNS_SYS_DNSMASQ_CONF}" || true
|
||||
sudo rm -f "${DNS_SYS_DNSMASQ_CONF}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
# If system dnsmasq is active, restart to apply
|
||||
if systemctl is-active --quiet dnsmasq 2>/dev/null; then
|
||||
sudo systemctl restart dnsmasq || true
|
||||
sudo systemctl restart dnsmasq || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
echo ">>> Removed."
|
||||
@@ -54,7 +54,7 @@ configure_via_networkmanager_dnsmasq() {
|
||||
# Avoid port conflicts with a system-wide dnsmasq service
|
||||
if systemctl is-enabled --quiet dnsmasq 2>/dev/null || systemctl is-active --quiet dnsmasq 2>/dev/null; then
|
||||
echo ">>> Disabling system dnsmasq to avoid conflicts with NetworkManager dnsmasq"
|
||||
sudo systemctl disable --now dnsmasq || true
|
||||
sudo systemctl disable --now dnsmasq || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
echo ">>> Writing NetworkManager dnsmasq config: ${DNS_NM_CONF}"
|
||||
@@ -76,7 +76,7 @@ EOF
|
||||
sudo systemctl restart NetworkManager
|
||||
|
||||
echo ">>> Resolver status"
|
||||
cat /etc/resolv.conf || true
|
||||
cat /etc/resolv.conf || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
}
|
||||
|
||||
configure_via_system_dnsmasq() {
|
||||
@@ -97,8 +97,8 @@ EOF
|
||||
# Optional: systemd-resolved integration if it exists, but NEVER fail the script
|
||||
if command -v resolvectl >/dev/null 2>&1 && systemctl is-active --quiet systemd-resolved 2>/dev/null; then
|
||||
echo ">>> Configuring systemd-resolved routing for ${DNS_DOMAIN}"
|
||||
sudo resolvectl dns lo 127.0.0.1 || true
|
||||
sudo resolvectl domain lo "~${DNS_DOMAIN}" || true
|
||||
sudo resolvectl dns lo 127.0.0.1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
sudo resolvectl domain lo "~${DNS_DOMAIN}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
echo ">>> systemd-resolved not active -> skipping resolvectl integration"
|
||||
echo ">>> NOTE: Ensure your system resolver uses 127.0.0.1 to query dnsmasq."
|
||||
|
||||
@@ -50,7 +50,7 @@ sudo rm -f "${RESOLV_CONF}"
|
||||
printf 'nameserver 127.0.0.1\n' | sudo tee "${RESOLV_CONF}" >/dev/null
|
||||
|
||||
echo ">>> Restarting dnsmasq"
|
||||
sudo systemctl enable dnsmasq --quiet 2>/dev/null || true
|
||||
sudo systemctl enable dnsmasq --quiet 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
sudo systemctl restart dnsmasq
|
||||
|
||||
# Register WSL interop binfmt handler so Windows .exe files can be executed from WSL
|
||||
@@ -62,7 +62,7 @@ if [[ ! -f "${BINFMT_CONF}" ]]; then
|
||||
sudo systemctl restart systemd-binfmt
|
||||
fi
|
||||
if ! grep -qs "WSLInterop" /proc/sys/fs/binfmt_misc/WSLInterop 2>/dev/null; then
|
||||
printf ':WSLInterop:M::MZ::/init:PF\n' | sudo tee /proc/sys/fs/binfmt_misc/register >/dev/null 2>&1 || true
|
||||
printf ':WSLInterop:M::MZ::/init:PF\n' | sudo tee /proc/sys/fs/binfmt_misc/register >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
echo ">>> WSL2 DNS pre-configuration complete"
|
||||
@@ -68,19 +68,19 @@ cleanup() {
|
||||
mkdir -p "${_playwright_host_dir}"
|
||||
echo ">>> Copying Playwright artifacts from ${INFINITO_CONTAINER} to ${_playwright_host_dir}"
|
||||
docker cp "${INFINITO_CONTAINER}:/var/lib/infinito/logs/test-e2e-playwright/." \
|
||||
"${_playwright_host_dir}" 2>/dev/null || true
|
||||
"${_playwright_host_dir}" 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
if [[ -n "${ANSIBLE_LOG_PATH:-}" ]]; then
|
||||
echo ">>> Copying Ansible log from ${INFINITO_CONTAINER}:${ANSIBLE_LOG_PATH} to ${ANSIBLE_LOG_PATH}"
|
||||
docker cp "${INFINITO_CONTAINER}:${ANSIBLE_LOG_PATH}" "${ANSIBLE_LOG_PATH}" 2>/dev/null || true
|
||||
docker cp "${INFINITO_CONTAINER}:${ANSIBLE_LOG_PATH}" "${ANSIBLE_LOG_PATH}" 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
echo ">>> Removing stack for distro ${INFINITO_DISTRO} (fresh start for next distro)"
|
||||
"${PYTHON}" -m cli.administration.deploy.development down || true
|
||||
"${PYTHON}" -m cli.administration.deploy.development down || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
echo ">>> HARD cleanup (containers/volumes/networks/images/build-cache)"
|
||||
echo ">>> Docker disk usage before HARD cleanup"
|
||||
docker system df || true
|
||||
docker system df || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
# 1) Remove containers belonging to this compose project only.
|
||||
# On shared self-hosted runners multiple projects run in parallel;
|
||||
@@ -92,24 +92,24 @@ cleanup() {
|
||||
mapfile -t ids < <(docker ps -aq || true)
|
||||
fi
|
||||
if ((${#ids[@]} > 0)); then
|
||||
docker rm -f "${ids[@]}" >/dev/null 2>&1 || true
|
||||
docker rm -f "${ids[@]}" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
# 2) Remove networks (except default ones)
|
||||
docker network prune -f >/dev/null 2>&1 || true
|
||||
docker network prune -f >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
# 3) Remove ALL volumes
|
||||
docker volume prune -f >/dev/null 2>&1 || true
|
||||
docker volume prune -f >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
# 4) Optional: leftover stopped containers (usually redundant after rm -f)
|
||||
docker container prune -f >/dev/null 2>&1 || true
|
||||
docker container prune -f >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
# 5) Remove all images + build cache (frees disk on GitHub runners).
|
||||
# Skipped on self-hosted (INFINITO_PRESERVE_DOCKER_CACHE=true) to keep the cache warm.
|
||||
if [[ "${INFINITO_PRESERVE_DOCKER_CACHE}" != "true" ]]; then
|
||||
docker image prune -af >/dev/null 2>&1 || true
|
||||
docker buildx prune -af >/dev/null 2>&1 || true
|
||||
docker builder prune -af >/dev/null 2>&1 || true
|
||||
docker image prune -af >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
docker buildx prune -af >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
docker builder prune -af >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
# On self-hosted runners keep only the current CI image per distro.
|
||||
# Removes all older ci-<hash> tags so disk usage stays flat across runs.
|
||||
@@ -123,7 +123,7 @@ cleanup() {
|
||||
)
|
||||
if ((${#_old_ci_images[@]} > 0)); then
|
||||
echo ">>> Pruning ${#_old_ci_images[@]} stale CI image(s) for ${_image_repo}"
|
||||
docker rmi "${_old_ci_images[@]}" >/dev/null 2>&1 || true
|
||||
docker rmi "${_old_ci_images[@]}" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -137,17 +137,17 @@ cleanup() {
|
||||
echo ">>> CI cleanup: wiping Docker root: ${INFINITO_DOCKER_VOLUME}"
|
||||
|
||||
echo ">>> Pre-clean ownership/permissions (best-effort)"
|
||||
ls -ld "${INFINITO_DOCKER_VOLUME}" || true
|
||||
ls -ld "${INFINITO_DOCKER_VOLUME}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
echo ">>> Removing host docker volume dir: ${INFINITO_DOCKER_VOLUME}"
|
||||
sudo rm -rf "${INFINITO_DOCKER_VOLUME}" || true
|
||||
sudo mkdir -vp "${INFINITO_DOCKER_VOLUME}" || true
|
||||
sudo rm -rf "${INFINITO_DOCKER_VOLUME}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
sudo mkdir -vp "${INFINITO_DOCKER_VOLUME}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
# Optional: keep it writable for the runner user
|
||||
sudo chown -R "$(id -u):$(id -g)" "${INFINITO_DOCKER_VOLUME}" || true
|
||||
sudo chown -R "$(id -u):$(id -g)" "${INFINITO_DOCKER_VOLUME}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
echo ">>> Post-clean ownership/permissions (best-effort)"
|
||||
ls -ld "${INFINITO_DOCKER_VOLUME}" || true
|
||||
ls -ld "${INFINITO_DOCKER_VOLUME}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
echo "[WARN] INFINITO_DOCKER_VOLUME is not an absolute path: '${INFINITO_DOCKER_VOLUME}' (skipping)"
|
||||
fi
|
||||
@@ -155,11 +155,11 @@ cleanup() {
|
||||
|
||||
# 7) Remove root-owned __pycache__/.pyc (else the next checkout fails with EACCES).
|
||||
echo ">>> Removing root-owned Python bytecode from workspace"
|
||||
sudo find "${REPO_ROOT}" -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
|
||||
sudo find "${REPO_ROOT}" -name "*.pyc" -delete 2>/dev/null || true
|
||||
sudo find "${REPO_ROOT}" -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
sudo find "${REPO_ROOT}" -name "*.pyc" -delete 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
echo ">>> Docker disk usage after HARD cleanup"
|
||||
docker system df || true
|
||||
docker system df || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo ">>> HARD cleanup finished"
|
||||
return $rc
|
||||
}
|
||||
@@ -171,12 +171,12 @@ if [[ "${INFINITO_PRESERVE_DOCKER_CACHE}" == "true" ]]; then
|
||||
_disk_pct=$(df --output=pcent / | tail -1 | tr -d ' %')
|
||||
if [[ "${_disk_pct}" -ge 70 && -n "${INFINITO_DOCKER_VOLUME:-}" && "${INFINITO_DOCKER_VOLUME}" == /* ]]; then
|
||||
echo ">>> Disk at ${_disk_pct}% — wiping full inner-Docker volume to reclaim space: ${INFINITO_DOCKER_VOLUME}"
|
||||
sudo rm -rf "${INFINITO_DOCKER_VOLUME}" || true
|
||||
sudo mkdir -p "${INFINITO_DOCKER_VOLUME}" || true
|
||||
sudo chown -R "$(id -u):$(id -g)" "${INFINITO_DOCKER_VOLUME}" || true
|
||||
sudo rm -rf "${INFINITO_DOCKER_VOLUME}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
sudo mkdir -p "${INFINITO_DOCKER_VOLUME}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
sudo chown -R "$(id -u):$(id -g)" "${INFINITO_DOCKER_VOLUME}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
echo ">>> Wiping inner-Docker volumes and container state: ${INFINITO_DOCKER_VOLUME}"
|
||||
sudo rm -rf "${INFINITO_DOCKER_VOLUME}/volumes" "${INFINITO_DOCKER_VOLUME}/containers" || true
|
||||
sudo rm -rf "${INFINITO_DOCKER_VOLUME}/volumes" "${INFINITO_DOCKER_VOLUME}/containers" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -191,7 +191,7 @@ echo ">>> Ensuring stack is up for distro ${INFINITO_DISTRO}"
|
||||
_up_container="${INFINITO_CONTAINER:?INFINITO_CONTAINER is not set (run make dotenv)}"
|
||||
docker exec "${_up_container}" install -m 755 \
|
||||
/opt/src/infinito/roles/sys-ca-selfsigned/files/with-ca-trust.sh \
|
||||
/usr/bin/ca-trust-wrapper 2>/dev/null || true
|
||||
/usr/bin/ca-trust-wrapper 2>/dev/null || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
deploy_args=(
|
||||
--apps "${apps}"
|
||||
@@ -200,8 +200,8 @@ deploy_args=(
|
||||
)
|
||||
|
||||
echo ">>> DISK / DOCKER STATE BEFORE DEPLOY (distro=${INFINITO_DISTRO})"
|
||||
df -h || true
|
||||
docker system df || true
|
||||
df -h || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
docker system df || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo ">>> END STATE BEFORE DEPLOY"
|
||||
|
||||
_init_args=(
|
||||
@@ -232,6 +232,6 @@ echo ">>> deploy (PASS 1 sync + PASS 2 async per variant, --full-cycle)"
|
||||
"${PYTHON}" -m cli.administration.deploy.development deploy "${deploy_args[@]}" --full-cycle
|
||||
|
||||
echo ">>> DISK / DOCKER STATE AFTER DEPLOY (before cleanup, distro=${INFINITO_DISTRO})"
|
||||
df -h || true
|
||||
docker system df || true
|
||||
df -h || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
docker system df || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo ">>> END STATE AFTER DEPLOY"
|
||||
@@ -39,7 +39,7 @@ mkdir -p "${inv_dir}"
|
||||
|
||||
if [[ ! -f "${pw_file}" ]]; then
|
||||
printf '%s\n' 'local-vault-password' >"${pw_file}"
|
||||
chmod 600 "${pw_file}" || true
|
||||
chmod 600 "${pw_file}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
echo ">>> Creating inventory at ${INFINITO_INVENTORY_FILE}"
|
||||
|
||||
@@ -3,5 +3,5 @@ set -euo pipefail
|
||||
|
||||
docker exec "${INFINITO_CONTAINER}" bash -lc "
|
||||
echo \">>> Deleting inventory \"
|
||||
rm -rv ${INFINITO_INVENTORY_DIR} || true
|
||||
rm -rv ${INFINITO_INVENTORY_DIR} || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
"
|
||||
@@ -3,5 +3,5 @@ set -euo pipefail
|
||||
|
||||
docker exec "${INFINITO_CONTAINER}" bash -lc "
|
||||
echo \">>> Cleaning up lib \"
|
||||
rm -rv /var/lib/infinito/ || true
|
||||
rm -rv /var/lib/infinito/ || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
"
|
||||
@@ -5,5 +5,5 @@ set -euo pipefail
|
||||
|
||||
docker exec "${INFINITO_CONTAINER}" bash -lc "
|
||||
echo \">>> Cleaning up Nginx configuration files\"
|
||||
bash ${INFINITO_SRC_DIR}/scripts/container/purge/web.sh || true
|
||||
bash ${INFINITO_SRC_DIR}/scripts/container/purge/web.sh || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
"
|
||||
@@ -90,7 +90,7 @@ echo ">>> Initializing inventory inside container"
|
||||
|
||||
if [[ ! -f \"\${pw_file}\" ]]; then
|
||||
printf '%s\n' 'local-vault-password' > \"\${pw_file}\"
|
||||
chmod 600 \"\${pw_file}\" || true
|
||||
chmod 600 \"\${pw_file}\" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
echo \">>> Creating inventory at \${INFINITO_INVENTORY_FILE}\"
|
||||
|
||||
@@ -64,9 +64,9 @@ cache_retry_recover() {
|
||||
done
|
||||
|
||||
echo "[cache-retry] docker builder prune -af..."
|
||||
docker builder prune -af >/dev/null 2>&1 || true
|
||||
docker builder prune -af >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo "[cache-retry] docker image prune -af..."
|
||||
docker image prune -af >/dev/null 2>&1 || true
|
||||
docker image prune -af >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
}
|
||||
|
||||
# Toggle errexit around the pipeline so a wrapped non-zero exit reaches the caller
|
||||
|
||||
@@ -112,7 +112,7 @@ section "CoreDNS container status"
|
||||
_coredns_name="${INFINITO_RUNNER_PREFIX:-}-coredns"
|
||||
if docker ps --filter name="${_coredns_name}" --format '{{.Names}}' | grep -q "${_coredns_name}"; then
|
||||
docker ps --filter name="${_coredns_name}" --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}'
|
||||
docker logs --tail=10 "${_coredns_name}" || true
|
||||
docker logs --tail=10 "${_coredns_name}" || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
ok "CoreDNS container is running"
|
||||
else
|
||||
fail "CoreDNS container not running"
|
||||
@@ -127,7 +127,7 @@ docker exec "${INFINITO_CONTAINER}" sh -lc "
|
||||
set -e
|
||||
|
||||
echo '>>> /etc/resolv.conf'
|
||||
cat /etc/resolv.conf || true
|
||||
cat /etc/resolv.conf || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
echo
|
||||
|
||||
echo '>>> getent hosts'
|
||||
|
||||
@@ -42,23 +42,23 @@ cleanup() {
|
||||
local current_ref
|
||||
current_ref="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)"
|
||||
if [[ "${current_ref}" == "${TEST_BRANCH}" ]]; then
|
||||
git reset --hard HEAD >/dev/null 2>&1 || true
|
||||
git clean -fd >/dev/null 2>&1 || true
|
||||
git checkout "${ORIGINAL_REF}" >/dev/null 2>&1 || true
|
||||
git reset --hard HEAD >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
git clean -fd >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
git checkout "${ORIGINAL_REF}" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
git branch -D "${TEST_BRANCH}" >/dev/null 2>&1 || true
|
||||
git branch -D "${TEST_BRANCH}" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
if [[ -n "${ORIGINAL_GIT_USER_NAME}" ]]; then
|
||||
git config --local user.name "${ORIGINAL_GIT_USER_NAME}" >/dev/null 2>&1 || true
|
||||
git config --local user.name "${ORIGINAL_GIT_USER_NAME}" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
git config --local --unset user.name >/dev/null 2>&1 || true
|
||||
git config --local --unset user.name >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
if [[ -n "${ORIGINAL_GIT_USER_EMAIL}" ]]; then
|
||||
git config --local user.email "${ORIGINAL_GIT_USER_EMAIL}" >/dev/null 2>&1 || true
|
||||
git config --local user.email "${ORIGINAL_GIT_USER_EMAIL}" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
else
|
||||
git config --local --unset user.email >/dev/null 2>&1 || true
|
||||
git config --local --unset user.email >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
if [[ -n "${WORKTREE_STASH}" ]] && git stash list | grep -F "${WORKTREE_STASH}" >/dev/null 2>&1; then
|
||||
|
||||
@@ -35,7 +35,7 @@ printf '%s\n' \
|
||||
'/' \
|
||||
'exit' |
|
||||
"${PYTHON}" -m cli.console \
|
||||
>"${log_file}" 2>&1 || true
|
||||
>"${log_file}" 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
assert_log_contains() {
|
||||
local needle="${1}"
|
||||
|
||||
@@ -260,7 +260,7 @@ probe_did_inner_build() {
|
||||
rc=1
|
||||
fi
|
||||
rm -rf "${tmpdir}"
|
||||
docker rmi "${tag}" >/dev/null 2>&1 || true
|
||||
docker rmi "${tag}" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
if [[ "${rc}" -ne 0 ]]; then
|
||||
echo "[FAIL] DiD probe: docker build failed (frontend, network or upstream broken)" >&2
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
"""Lint guard: `.sh` files MUST NOT swallow failures with ``|| true``.
|
||||
|
||||
``cmd || true`` unconditionally discards the exit code of ``cmd``, so a
|
||||
real regression (a command that starts failing) passes silently. Under
|
||||
``set -euo pipefail`` that is the whole point — but it also masks the
|
||||
failures you *do* want to see. Prefer catching the specific tolerated
|
||||
condition instead (inspect the output / rc and re-``exit`` on anything
|
||||
unexpected), or gate the command on a precondition.
|
||||
|
||||
Suppress on a per-line basis with a same-line
|
||||
``# nocheck: shell-or-true -- <reason>`` marker. The existing corpus is
|
||||
grandfathered with that marker: those cases have worked in practice and
|
||||
there was no time to narrow each to its exact tolerated error; the guard
|
||||
exists to stop *new* blanket ``|| true`` from creeping in.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
import unittest
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from utils.cache.files import read_text
|
||||
|
||||
from . import PROJECT_ROOT
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from pathlib import Path
|
||||
|
||||
# ``... || true`` (also ``|| :``), optionally followed by a comment.
|
||||
_OR_TRUE_RE = re.compile(r"\|\|\s*(?:true|:)\s*(?:#|;|$)")
|
||||
_NOCHECK_RE = re.compile(r"#\s*nocheck\b")
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Violation:
|
||||
file: str
|
||||
line_no: int
|
||||
detail: str
|
||||
|
||||
|
||||
def _git_ls_files() -> list[str]:
|
||||
out = subprocess.check_output(
|
||||
[
|
||||
"git",
|
||||
"-c",
|
||||
"safe.directory=*",
|
||||
"-C",
|
||||
str(PROJECT_ROOT),
|
||||
"ls-files",
|
||||
],
|
||||
text=True,
|
||||
)
|
||||
return [line for line in out.splitlines() if line]
|
||||
|
||||
|
||||
def _scan_file(path: Path) -> list[Violation]:
|
||||
violations: list[Violation] = []
|
||||
rel = path.relative_to(PROJECT_ROOT).as_posix()
|
||||
try:
|
||||
text = read_text(str(path))
|
||||
except (OSError, UnicodeDecodeError) as exc:
|
||||
return [Violation(rel, 0, str(exc))]
|
||||
|
||||
for idx, raw in enumerate(text.splitlines(), 1):
|
||||
if _NOCHECK_RE.search(raw):
|
||||
continue
|
||||
if _OR_TRUE_RE.search(raw):
|
||||
violations.append(
|
||||
Violation(
|
||||
rel,
|
||||
idx,
|
||||
"`|| true` unconditionally swallows the exit code; catch "
|
||||
"the specific tolerated error and re-exit on anything else, "
|
||||
"or suppress with "
|
||||
"`# nocheck: shell-or-true -- <reason>`",
|
||||
)
|
||||
)
|
||||
return violations
|
||||
|
||||
|
||||
def _scan_targets() -> list[Path]:
|
||||
return [PROJECT_ROOT / rel for rel in _git_ls_files() if rel.endswith(".sh")]
|
||||
|
||||
|
||||
class TestShellNoOrTrue(unittest.TestCase):
|
||||
def test_shell_files_dont_swallow_failures_with_or_true(self) -> None:
|
||||
targets = _scan_targets()
|
||||
self.assertTrue(targets, "no .sh files found to scan")
|
||||
all_violations: list[Violation] = []
|
||||
for path in targets:
|
||||
all_violations.extend(_scan_file(path))
|
||||
if all_violations:
|
||||
grouped: dict[str, list[Violation]] = {}
|
||||
for v in all_violations:
|
||||
grouped.setdefault(v.file, []).append(v)
|
||||
lines = [
|
||||
f"Unmarked `|| true` in .sh "
|
||||
f"({len(all_violations)} violations across "
|
||||
f"{len(grouped)} file(s)):",
|
||||
"",
|
||||
"`cmd || true` discards cmd's exit code, so a future "
|
||||
"regression passes silently. Catch the specific tolerated "
|
||||
"error instead, or suppress per line with "
|
||||
"`# nocheck: shell-or-true -- <reason>`.",
|
||||
"",
|
||||
"Offenders:",
|
||||
]
|
||||
for f, vs in sorted(grouped.items()):
|
||||
lines.append(f" {f}:")
|
||||
lines.extend(f" line {v.line_no}: {v.detail}" for v in vs)
|
||||
self.fail("\n".join(lines))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user