274 lines
7.3 KiB
Bash
Executable File
274 lines
7.3 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"
|
|
app_id="qortal_integration"
|
|
occ_path=""
|
|
runtime_mode="compose"
|
|
|
|
usage() {
|
|
cat <<'USAGE'
|
|
Usage: ./scripts/diagnose-qortal-gateway-route.sh --compose-file <file> --env-file <file> [options]
|
|
|
|
Inspect whether the qortal_integration gateway routes are registered in the
|
|
running Nextcloud instance and whether the live app path matches repo source.
|
|
|
|
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)
|
|
--app-id <name> App id to inspect (default: qortal_integration)
|
|
--occ-path <path> Host Nextcloud occ path for host-hybrid installs
|
|
-h, --help Show this help
|
|
USAGE
|
|
}
|
|
|
|
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[@]}" "$@"
|
|
}
|
|
|
|
occ() {
|
|
if [[ "${runtime_mode}" == "host" ]]; then
|
|
if [[ -z "${occ_path}" || ! -f "${occ_path}" ]]; then
|
|
echo "Missing host occ path: ${occ_path}" >&2
|
|
return 1
|
|
fi
|
|
if command -v sudo >/dev/null 2>&1; then
|
|
sudo -u www-data php "${occ_path}" "$@"
|
|
return $?
|
|
fi
|
|
if command -v runuser >/dev/null 2>&1; then
|
|
runuser -u www-data -- php "${occ_path}" "$@"
|
|
return $?
|
|
fi
|
|
php "${occ_path}" "$@"
|
|
return $?
|
|
fi
|
|
|
|
docker compose -f "${compose_file}" --env-file "${env_file}" exec -T --user www-data "${app_service}" php occ "$@"
|
|
}
|
|
|
|
tail_nextcloud_log() {
|
|
local log_file=""
|
|
if [[ "${runtime_mode}" == "host" ]]; then
|
|
log_file="$(occ config:system:get logfile 2>/dev/null | tr -d '\r' || true)"
|
|
if [[ -z "${log_file}" ]]; then
|
|
return 1
|
|
fi
|
|
if [[ -f "${log_file}" ]]; then
|
|
tail -n 200 "${log_file}"
|
|
return 0
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
docker compose -f "${compose_file}" --env-file "${env_file}" exec -T "${app_service}" sh -lc '
|
|
if [ -f /var/www/html/data/nextcloud.log ]; then
|
|
tail -n 200 /var/www/html/data/nextcloud.log
|
|
fi
|
|
' 2>/dev/null
|
|
}
|
|
|
|
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
|
|
;;
|
|
--app-id)
|
|
app_id="${2:-}"
|
|
shift 2
|
|
;;
|
|
--app-id=*)
|
|
app_id="${1#*=}"
|
|
shift
|
|
;;
|
|
--occ-path)
|
|
occ_path="${2:-}"
|
|
runtime_mode="host"
|
|
shift 2
|
|
;;
|
|
--occ-path=*)
|
|
occ_path="${1#*=}"
|
|
runtime_mode="host"
|
|
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
|
|
|
|
echo "Qortal gateway route diagnostics"
|
|
echo " compose_file=${compose_file}"
|
|
echo " env_file=${env_file}"
|
|
echo " compose_project=${COMPOSE_PROJECT_NAME:-<unset>}"
|
|
echo " runtime_mode=${runtime_mode}"
|
|
if [[ "${runtime_mode}" == "host" ]]; then
|
|
echo " occ_path=${occ_path}"
|
|
fi
|
|
echo " app_service=${app_service}"
|
|
echo " app_id=${app_id}"
|
|
|
|
echo
|
|
echo "Compose status:"
|
|
docker compose -f "${compose_file}" --env-file "${env_file}" ps || true
|
|
|
|
echo
|
|
echo "App enabled state:"
|
|
occ app:list 2>/dev/null | grep -n "${app_id}" || true
|
|
|
|
echo
|
|
echo "Runtime app path:"
|
|
app_path="$(occ app:getpath "${app_id}" 2>/dev/null | tr -d '\r' || true)"
|
|
if [[ -z "${app_path}" ]]; then
|
|
echo " <unavailable>"
|
|
else
|
|
echo " ${app_path}"
|
|
fi
|
|
|
|
route_file_has_gateway="0"
|
|
if [[ -n "${app_path}" && -f "${app_path}/appinfo/routes.php" ]]; then
|
|
if grep -q 'gateway#proxy\|/gateway/{path}' "${app_path}/appinfo/routes.php"; then
|
|
route_file_has_gateway="1"
|
|
fi
|
|
fi
|
|
|
|
echo
|
|
echo "Gateway route registration:"
|
|
route_output="$(occ app:routes "${app_id}" 2>&1 || true)"
|
|
printf '%s\n' "${route_output}" | grep -n 'gateway\|account\|qapps' || true
|
|
if [[ "${runtime_mode}" == "host" && "${route_file_has_gateway}" == "1" ]]; then
|
|
echo " gateway routes present in appinfo/routes.php"
|
|
elif ! printf '%s\n' "${route_output}" | grep -q 'gateway'; then
|
|
echo " gateway routes not present in OCC output"
|
|
fi
|
|
|
|
echo
|
|
echo "Relevant app config:"
|
|
for key in qortal_node_url external_auth_node_url qortal_gateway_url nextcloud_public_url sc_mode qapps_debug_enabled external_auth_app_id external_auth_app_secret external_auth_node_api_key; do
|
|
value="$(occ config:app:get "${app_id}" "${key}" 2>/dev/null | tr -d '\r' || true)"
|
|
if [[ -z "${value}" ]]; then
|
|
value="<empty>"
|
|
elif [[ "${key}" == *secret* || "${key}" == *api_key* ]]; then
|
|
value="<set>"
|
|
fi
|
|
echo " ${key}=${value}"
|
|
done
|
|
|
|
if [[ -n "${app_path}" ]]; then
|
|
echo
|
|
echo "Live GatewayController markers:"
|
|
if [[ "${runtime_mode}" == "host" ]]; then
|
|
grep -n 'X-QI-Gateway-Powered-Fallback-Used\|function proxy\|function getLogger\|gateway_proxy_response' "${app_path}/lib/Controller/GatewayController.php" || true
|
|
else
|
|
docker compose -f "${compose_file}" --env-file "${env_file}" exec -T "${app_service}" sh -lc "
|
|
grep -n 'X-QI-Gateway-Powered-Fallback-Used\\|function proxy\\|function getLogger\\|gateway_proxy_response' '${app_path}/lib/Controller/GatewayController.php' || true
|
|
" 2>/dev/null || true
|
|
fi
|
|
|
|
echo
|
|
echo "Live routes.php gateway entries:"
|
|
if [[ "${runtime_mode}" == "host" ]]; then
|
|
grep -n 'gateway#proxy\|/gateway/{path}' "${app_path}/appinfo/routes.php" || true
|
|
else
|
|
docker compose -f "${compose_file}" --env-file "${env_file}" exec -T "${app_service}" sh -lc "
|
|
grep -n \"gateway#proxy\\|/gateway/{path}\" '${app_path}/appinfo/routes.php' || true
|
|
" 2>/dev/null || true
|
|
fi
|
|
fi
|
|
|
|
echo
|
|
echo "Recent Nextcloud log lines mentioning qortal_integration or gateway:"
|
|
tail_nextcloud_log 2>/dev/null | grep -E 'qortal_integration|gateway_proxy|GatewayController' || true
|