#!/usr/bin/env bash set -Eeuo pipefail usage() { cat <<'EOF' Quicksh docker 0.1.0 — Docker client and daemon diagnostics Usage: bash docker.sh [--help|-h|--version] Reports the client version and checks the active Docker endpoint with docker info. Honors the existing Docker context and environment, which may point to a remote daemon. Output never includes full daemon information or endpoint addresses. Uses a 10-second timeout when the timeout tool is available. Exit 1 means the client is missing, unusable, or the daemon check failed. Never installs Docker, starts services, or changes groups/socket permissions. EOF } guidance() { local ID=unknown if [[ -r /etc/os-release ]]; then # shellcheck disable=SC1091 if ! . /etc/os-release; then printf 'quicksh docker: could not read OS identification.\n' >&2 return 1 fi fi printf '\nInstallation and setup guidance:\n' case "$ID" in arch) printf ' Arch Linux: https://wiki.archlinux.org/title/Docker\n' printf ' Review the docker package and service setup in the Arch documentation.\n' ;; ubuntu) printf ' Ubuntu: https://docs.docker.com/engine/install/ubuntu/\n' printf ' Follow the official repository and package instructions for your release.\n' ;; *) printf ' Use your distribution documentation: https://docs.docker.com/engine/install/\n' ;; esac printf ' Docker group membership grants root-level privileges on the host.\n' printf ' Consider rootless Docker; never make the socket world-writable.\n' } main() { if (( $# > 1 )); then printf 'quicksh docker: expected at most one option. Use --help.\n' >&2 return 2 fi case "${1:-}" in --help|-h) usage; return ;; --version) printf 'Quicksh docker 0.1.0\n'; return ;; '') ;; *) printf 'quicksh docker: unsupported option: %s. Use --help.\n' "$1" >&2; return 2 ;; esac printf 'Quicksh docker 0.1.0\n' if ! command -v docker >/dev/null 2>&1; then printf 'Docker client: not found in PATH. This is not a daemon permission error.\n' >&2 guidance return 1 fi if ! docker --version; then printf 'quicksh docker: the installed client failed to report its version.\n' >&2 return 1 fi local diagnostic status local -a limit=() if command -v timeout >/dev/null 2>&1; then limit=(timeout 10s) else printf 'No timeout tool: the endpoint check may wait; press Ctrl-C to cancel.\n' fi if diagnostic=$("${limit[@]}" docker info --format '{{.ServerVersion}}' 2>&1); then printf 'Docker daemon: reachable using the active endpoint.\n' return 0 else status=$? fi # Classify locally without echoing daemon diagnostics, which can contain endpoints. if (( status == 124 || status == 137 )); then printf 'Docker daemon check timed out. Check the active context and connectivity.\n' >&2 elif [[ "${diagnostic,,}" == *'permission denied'* || "${diagnostic,,}" == *'access is denied'* ]]; then printf 'Docker is installed, but the endpoint reported insufficient permissions.\n' >&2 printf 'Check the socket owner, active context, and rootless setup before changing access.\n' >&2 else printf 'Docker is installed, but the active daemon endpoint is not reachable.\n' >&2 printf 'Possible causes: stopped service, incorrect context, credentials, or network failure.\n' >&2 fi guidance return 1 } main "$@"