Files
Qortal-Nextcloud-Integration/scripts/diagnose-nextcloud-occ-readiness.sh
2026-04-07 14:16:38 -07:00

215 lines
5.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
repo_root="$(cd "${script_dir}/.." && pwd)"
source "${script_dir}/lib-compose-project.sh"
compose_file=""
env_file=""
app_service="app"
db_service="db"
log_tail="80"
usage() {
cat <<USAGE
Usage: ./scripts/diagnose-nextcloud-occ-readiness.sh --compose-file <file> --env-file <file> [options]
Collect basic diagnostics when Nextcloud OCC never becomes ready.
Options:
--compose-file <path> Docker compose file to inspect (required)
--env-file <path> Env file to inspect (required)
--app-service <name> Nextcloud app service name (default: app)
--db-service <name> Database service name (default: db)
--log-tail <n> Number of recent log lines to print (default: 80)
-h, --help Show this help
USAGE
}
read_kv() {
local key="$1"
local line
line="$(grep -m1 -E "^${key}=" "${env_file}" || true)"
if [[ -z "${line}" ]]; then
return 1
fi
echo "${line#*=}"
}
ensure_docker_access() {
local docker_path=""
docker_path="$(type -P docker || true)"
if [[ -z "${docker_path}" ]]; then
echo "docker is required"
exit 1
fi
if "${docker_path}" info >/dev/null 2>&1; then
DOCKER_CMD=("${docker_path}")
return 0
fi
if ! command -v sudo >/dev/null 2>&1; then
echo "docker is installed but this user cannot access it, and sudo is unavailable."
exit 1
fi
if sudo -n "${docker_path}" info >/dev/null 2>&1; then
DOCKER_CMD=(sudo "${docker_path}")
return 0
fi
echo "docker requires elevated privileges on this machine."
echo "You may be prompted for your sudo password."
if sudo "${docker_path}" info >/dev/null 2>&1; then
DOCKER_CMD=(sudo "${docker_path}")
return 0
fi
echo "Unable to access docker, even with sudo."
exit 1
}
docker() {
"${DOCKER_CMD[@]}" "$@"
}
while [[ $# -gt 0 ]]; do
case "$1" in
--compose-file)
compose_file="${2:-}"
shift 2
;;
--compose-file=*)
compose_file="${1#*=}"
shift
;;
--env-file)
env_file="${2:-}"
shift 2
;;
--env-file=*)
env_file="${1#*=}"
shift
;;
--app-service)
app_service="${2:-}"
shift 2
;;
--app-service=*)
app_service="${1#*=}"
shift
;;
--db-service)
db_service="${2:-}"
shift 2
;;
--db-service=*)
db_service="${1#*=}"
shift
;;
--log-tail)
log_tail="${2:-}"
shift 2
;;
--log-tail=*)
log_tail="${1#*=}"
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option: $1"
usage
exit 1
;;
esac
done
if [[ -z "${compose_file}" || -z "${env_file}" ]]; then
usage
exit 1
fi
if [[ "${compose_file}" != /* ]]; then
compose_file="${repo_root}/${compose_file}"
fi
if [[ "${env_file}" != /* ]]; then
env_file="${repo_root}/${env_file}"
fi
if [[ ! -f "${compose_file}" ]]; then
echo "Missing compose file: ${compose_file}"
exit 1
fi
if [[ ! -f "${env_file}" ]]; then
echo "Missing env file: ${env_file}"
exit 1
fi
export_compose_project_name_from_env "${env_file}" || true
ensure_docker_access
mysql_db="$(read_kv "MYSQL_DATABASE" || true)"
mysql_user="$(read_kv "MYSQL_USER" || true)"
mysql_password="$(read_kv "MYSQL_PASSWORD" || true)"
compose_project="${COMPOSE_PROJECT_NAME:-}"
db_container_id="$(docker compose -f "${compose_file}" --env-file "${env_file}" ps -q "${db_service}" 2>/dev/null || true)"
echo "Nextcloud OCC readiness diagnostics"
echo " compose_file=${compose_file}"
echo " env_file=${env_file}"
echo " app_service=${app_service}"
echo " db_service=${db_service}"
echo " compose_project=${compose_project:-<unset>}"
echo
echo "Compose status:"
docker compose -f "${compose_file}" --env-file "${env_file}" ps || true
if [[ -n "${db_container_id}" ]]; then
echo
echo "DB container mounts:"
docker inspect "${db_container_id}" --format '{{ range .Mounts }}{{ .Type }} {{ if .Name }}{{ .Name }}{{ else }}{{ .Source }}{{ end }} -> {{ .Destination }}{{ println }}{{ end }}' 2>/dev/null || true
fi
echo
echo "OCC status attempt:"
docker compose -f "${compose_file}" --env-file "${env_file}" exec -T --user www-data "${app_service}" php occ status 2>&1 || true
echo
echo "config/config.php presence:"
docker compose -f "${compose_file}" --env-file "${env_file}" exec -T "${app_service}" sh -lc '
if [ -f /var/www/html/config/config.php ]; then
echo "present"
else
echo "missing"
fi
' 2>&1 || true
if [[ -n "${mysql_db}" && -n "${mysql_user}" && -n "${mysql_password}" ]]; then
echo
echo "Database schema probe (oc_appconfig):"
schema_probe_output="$(docker compose -f "${compose_file}" --env-file "${env_file}" exec -T "${db_service}" \
mariadb -u"${mysql_user}" -p"${mysql_password}" "${mysql_db}" \
-e "SHOW TABLES LIKE 'oc_appconfig';" 2>&1 || true)"
if [[ -n "${schema_probe_output}" ]]; then
printf '%s\n' "${schema_probe_output}"
else
echo " <no rows>"
echo " Likely cause: database exists but Nextcloud schema was never initialized in this MariaDB volume."
echo " Common reason: Compose project name changed, so this cloud attached to a fresh db_data volume."
fi
fi
echo
echo "Recent ${app_service} logs:"
docker compose -f "${compose_file}" --env-file "${env_file}" logs --tail "${log_tail}" "${app_service}" 2>&1 || true
echo
echo "Recent ${db_service} logs:"
docker compose -f "${compose_file}" --env-file "${env_file}" logs --tail "${log_tail}" "${db_service}" 2>&1 || true