From 3637436c97ef9af2d3483330ce39bcdac97cdbf6 Mon Sep 17 00:00:00 2001 From: pablomendezroyo Date: Tue, 17 Mar 2026 08:06:27 +0100 Subject: [PATCH 1/7] Add port conflict checks for HTTPS and VPN in installer script --- scripts/dappnode_install.sh | 106 +++++++++++++++++++++++++++++------- 1 file changed, 85 insertions(+), 21 deletions(-) diff --git a/scripts/dappnode_install.sh b/scripts/dappnode_install.sh index 32f82f9..2f7f9a3 100755 --- a/scripts/dappnode_install.sh +++ b/scripts/dappnode_install.sh @@ -37,18 +37,37 @@ DNCORE_COMPOSE_ARGS=() log() { # LOGFILE is created after dir bootstrap; until then we just print to stdout. if [[ -n "${LOGFILE:-}" && -d "${LOGS_DIR:-}" ]]; then - printf '%s\n' "$*" | tee -a "$LOGFILE" + printf '%s\n' "[INFO] $*" | tee -a "$LOGFILE" else - printf '%s\n' "$*" + printf '%s\n' "[INFO] $*" fi } warn() { - log "[WARN] $*" + # LOGFILE is created after dir bootstrap; until then we just print to stdout. + if [[ -n "${LOGFILE:-}" && -d "${LOGS_DIR:-}" ]]; then + printf '%s\n' "[WARN] $*" | tee -a "$LOGFILE" + else + printf '%s\n' "[WARN] $*" + fi +} + +error() { + # LOGFILE is created after dir bootstrap; until then we just print to stdout. + if [[ -n "${LOGFILE:-}" && -d "${LOGS_DIR:-}" ]]; then + printf '%s\n' "[ERROR] $*" | tee -a "$LOGFILE" + else + printf '%s\n' "[ERROR] $*" + fi } die() { - log "[ERROR] $*" + # LOGFILE is created after dir bootstrap; until then we just print to stdout. + if [[ -n "${LOGFILE:-}" && -d "${LOGS_DIR:-}" ]]; then + printf '%s\n' "[ERROR] $*" | tee -a "$LOGFILE" + else + printf '%s\n' "[ERROR] $*" + fi exit 1 } @@ -523,35 +542,79 @@ bootstrap_filesystem() { touch "${LOGFILE}" || true } -# Check if port 80 is in use (necessary for HTTPS) -# Returns IS_PORT_USED=true only if port 80 or 443 is used by something OTHER than our HTTPS container -is_port_used() { - # Check if port 80 or 443 is in use at all - local port80_used port443_used - if command -v lsof >/dev/null 2>&1; then - lsof -i -P -n | grep ":80 (LISTEN)" &>/dev/null && port80_used=true || port80_used=false - lsof -i -P -n | grep ":443 (LISTEN)" &>/dev/null && port443_used=true || port443_used=false +# Generic helper: returns 0 if a process is bound to the given port, 1 if not. +# Usage: is_port_listening [tcp|udp] +# tcp (default): matches TCP sockets in LISTEN state +# udp: matches any process bound to the UDP port +is_port_listening() { + local port="$1" + local proto="${2:-tcp}" + if [[ "$proto" == "udp" ]]; then + lsof -i "udp:${port}" -P -n 2>/dev/null | grep -q . else + lsof -i "tcp:${port}" -P -n 2>/dev/null | grep -q "(LISTEN)" + fi +} + +# Check if ports 80/443 are occupied by something other than our own HTTPS container. +# Sets HTTPS_PORTS_BLOCKED=true/false. +check_https_ports_conflict() { + if ! command -v lsof >/dev/null 2>&1; then warn "lsof not found; assuming ports 80/443 are in use (HTTPS will be skipped)" - IS_PORT_USED=true + HTTPS_PORTS_BLOCKED=true return fi - if [ "$port80_used" = false ] && [ "$port443_used" = false ]; then - IS_PORT_USED=false + if ! is_port_listening 80 && ! is_port_listening 443; then + HTTPS_PORTS_BLOCKED=false return fi - # If either port is in use, check if it's our HTTPS container + # Port 80 or 443 is in use; check if it's our own HTTPS container if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^DAppNodeCore-https.dnp.dappnode.eth$"; then - # Port 80 or 443 is used by our HTTPS container, so we consider it "not used" for package determination - IS_PORT_USED=false + # Our own HTTPS container already holds the port — not a conflict + HTTPS_PORTS_BLOCKED=false else # Port 80 or 443 is used by something else - IS_PORT_USED=true + HTTPS_PORTS_BLOCKED=true fi } +# Check that ports required by VPN/Wireguard are not already in use by another process. +# Must be called after PKGS is populated. Exits with a helpful error on conflict. +check_vpn_ports_conflict() { + if ! command -v lsof >/dev/null 2>&1; then + return # cannot check; proceed and let the container report a bind error + fi + + local pkg + for pkg in "${PKGS[@]}"; do + case "$pkg" in + WIREGUARD) + if is_port_listening 51820 udp; then + error "Port 51820/UDP is already in use on this host." + error "This port is required by the Wireguard package and must be free before installing." + error "Free up port 51820 and re-run the installer, or — if you do not need VPN" + error "connectivity — consider using --minimal instead (advanced users only)." + exit 1 + fi + ;; + VPN) + local vpn_blocked=() + is_port_listening 1194 udp && vpn_blocked+=(1194/UDP) + is_port_listening 8092 tcp && vpn_blocked+=(8092/TCP) + if [[ ${#vpn_blocked[@]} -gt 0 ]]; then + error "Port(s) ${vpn_blocked[*]} are already in use on this host." + error "These ports are required by the OpenVPN package and must be free before installing." + error "Free up the port(s) and re-run the installer, or — if you do not need VPN" + error "connectivity — consider using --minimal instead (advanced users only)." + exit 1 + fi + ;; + esac + done +} + # Determine packages to be installed determine_packages() { # Explicit package list override from flag/env always has top priority. @@ -649,8 +712,8 @@ determine_packages() { # Default mode (no --packages/--minimal/--lite): install full package set. # HTTPS is included only when ports 80/443 are available. - is_port_used - if [ "$IS_PORT_USED" == "true" ]; then + check_https_ports_conflict + if [ "$HTTPS_PORTS_BLOCKED" == "true" ]; then PKGS=(BIND IPFS VPN WIREGUARD DAPPMANAGER WIFI NOTIFICATIONS PREMIUM) else PKGS=(HTTPS BIND IPFS VPN WIREGUARD DAPPMANAGER WIFI NOTIFICATIONS PREMIUM) @@ -710,6 +773,7 @@ resolve_packages() { # If such variable with 'dev:'' suffix is used, then the component is built from specified branch or commit. # you can also specify an IPFS version like /ipfs/: (the exact version is required). determine_packages + check_vpn_ports_conflict for comp in "${PKGS[@]}"; do ver="${comp}_VERSION" log "Processing $comp: ${!ver-}" From 00ea62e97278690475e1b516129ef62d0ff6cb3b Mon Sep 17 00:00:00 2001 From: pablomendezroyo Date: Tue, 17 Mar 2026 08:22:51 +0100 Subject: [PATCH 2/7] Update notifications and premium package versions in .dappnode_profile --- .dappnode_profile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.dappnode_profile b/.dappnode_profile index ece7e1b..35dbcd2 100755 --- a/.dappnode_profile +++ b/.dappnode_profile @@ -14,8 +14,8 @@ export DAPPMANAGER_VERSION="${DAPPMANAGER_VERSION:-0.2.99}" export WIFI_VERSION="${WIFI_VERSION:-0.2.9}" export WIREGUARD_VERSION="${WIREGUARD_VERSION:-0.1.3}" export HTTPS_VERSION="${HTTPS:-0.2.2}" -export NOTIFICATIONS_VERSION="/ipfs/QmQubxH4WgqEFxvFntef4H2DmuU6mxBRS6XeuShc3owNi9" -export PREMIUM_VERSION="/ipfs/QmXDddoa56HkrvtkGsa3mozpsn9SzQZtoVBWgagcW6SsHy" +export NOTIFICATIONS_VERSION="/ipfs/QmX6kkG8bwZVNdhYnPjhz9p6SKnbozHrVFwPMvU1a2YN2s" +export PREMIUM_VERSION="/ipfs/QmRorK6DQUen31vJdfT8TaJsD4QQqbWg9xFQNixwoQEPKy" export DAPPNODE_DIR="/usr/src/dappnode" export DAPPNODE_CORE_DIR="${DAPPNODE_DIR}/DNCORE" From 2176d3508ab744413e2918656a44d92bcf85ac37 Mon Sep 17 00:00:00 2001 From: pablomendezroyo Date: Tue, 17 Mar 2026 08:22:58 +0100 Subject: [PATCH 3/7] Refactor logging in dappnode_install.sh to use log function for consistency --- scripts/dappnode_install.sh | 169 +++++++++++++++++++----------------- 1 file changed, 87 insertions(+), 82 deletions(-) diff --git a/scripts/dappnode_install.sh b/scripts/dappnode_install.sh index 2f7f9a3..180f441 100755 --- a/scripts/dappnode_install.sh +++ b/scripts/dappnode_install.sh @@ -4,35 +4,12 @@ # thanks to the shebang), but users sometimes invoke it as `zsh ./script.sh` or `source ./script.sh`. # - If sourced, bail out (sourcing would pollute the current shell and can break it). # - If invoked by a non-bash shell, re-exec with bash before hitting bash-specific builtins. -if (return 0 2>/dev/null); then - echo "This script must be executed, not sourced. Run: bash $0" - return 1 -fi - -if [ -z "${BASH_VERSION:-}" ]; then - exec /usr/bin/env bash "$0" "$@" -fi - -set -Eeuo pipefail - -# Optional env inputs (avoid unbound-variable errors under `set -u`) -: "${UPDATE:=false}" -: "${STATIC_IP:=}" -: "${LOCAL_PROFILE_PATH:=}" -: "${MINIMAL:=false}" -: "${LITE:=false}" -: "${PACKAGES:=}" - -# Enable alias expansion in non-interactive bash scripts. -# Required so commands like `dappnode_wireguard` (defined as aliases in `.dappnode_profile`) work. -shopt -s expand_aliases - -# Ensure array is always defined (avoid `set -u` edge cases) -DNCORE_COMPOSE_ARGS=() ############################## # Logging / Errors # ############################## +# Note: LOGFILE and LOGS_DIR are set during bootstrap_filesystem based on DAPPNODE_DIR +# Early definition allows these functions to be used throughout the script. log() { # LOGFILE is created after dir bootstrap; until then we just print to stdout. @@ -71,6 +48,35 @@ die() { exit 1 } +############################## +# Script Guards # +############################## + +if (return 0 2>/dev/null); then + die "This script must be executed, not sourced. Run: bash $0" +fi + +if [ -z "${BASH_VERSION:-}" ]; then + exec /usr/bin/env bash "$0" "$@" +fi + +set -Eeuo pipefail + +# Optional env inputs (avoid unbound-variable errors under `set -u`) +: "${UPDATE:=false}" +: "${STATIC_IP:=}" +: "${LOCAL_PROFILE_PATH:=}" +: "${MINIMAL:=false}" +: "${LITE:=false}" +: "${PACKAGES:=}" + +# Enable alias expansion in non-interactive bash scripts. +# Required so commands like `dappnode_wireguard` (defined as aliases in `.dappnode_profile`) work. +shopt -s expand_aliases + +# Ensure array is always defined (avoid `set -u` edge cases) +DNCORE_COMPOSE_ARGS=() + usage() { cat <<'EOF' Usage: dappnode_install.sh [options] @@ -200,7 +206,7 @@ wait_for_internal_ip() { local internal_ip_url="http://127.0.0.1/global-envs/INTERNAL_IP" local hostname_url="http://127.0.0.1/global-envs/HOSTNAME" - echo "Waiting for dappmanager to publish INTERNAL_IP and HOSTNAME..." + log "Waiting for dappmanager to publish INTERNAL_IP and HOSTNAME..." sleep "$initial_sleep_seconds" local start_seconds internal_http_code internal_value internal_result @@ -235,12 +241,12 @@ wait_for_internal_ip() { if [[ "$internal_http_code" == "200" && -n "$internal_value" && "$internal_value" != "null" && "$hostname_http_code" == "200" && -n "$hostname_value" && "$hostname_value" != "null" ]]; then sleep "$final_sleep_seconds" # Extra buffer to ensure values are fully propagated before we proceed - echo "INTERNAL_IP is ready: $internal_value" - echo "HOSTNAME is ready: $hostname_value" + log "INTERNAL_IP is ready: $internal_value" + log "HOSTNAME is ready: $hostname_value" return 0 fi - echo "INTERNAL_IP/HOSTNAME not ready yet (INTERNAL_IP code=${internal_http_code:-?}, HOSTNAME code=${hostname_http_code:-?}). Retrying..." + log "INTERNAL_IP/HOSTNAME not ready yet (INTERNAL_IP code=${internal_http_code:-?}, HOSTNAME code=${hostname_http_code:-?}). Retrying..." sleep 2 done } @@ -266,43 +272,42 @@ print_vpn_access_credentials() { done if [[ "$has_wireguard" != "true" && "$has_vpn" != "true" ]]; then - echo "" - echo "No VPN package selected (VPN/WIREGUARD). Skipping credentials output." + log "No VPN package selected (VPN/WIREGUARD). Skipping credentials output." return 0 fi - echo "" - echo "Waiting for VPN initialization..." + log "" + log "Waiting for VPN initialization..." wait_for_internal_ip "DAppNodeCore-dappmanager.dnp.dappnode.eth" 120 20 10 - echo "" - echo "##############################################" - echo "# DAppNode VPN Access Credentials #" - echo "##############################################" - echo "" - echo "Your DAppNode is ready! Connect using your preferred VPN client." - echo "Choose either Wireguard (recommended) or OpenVPN and import the" - echo "credentials below into your VPN app to access your DAppNode." - echo "" + log "" + log "##############################################" + log "# DAppNode VPN Access Credentials #" + log "##############################################" + log "" + log "Your DAppNode is ready! Connect using your preferred VPN client." + log "Choose either Wireguard (recommended) or OpenVPN and import the" + log "credentials below into your VPN app to access your DAppNode." + log "" if [[ "$has_wireguard" == "true" ]]; then - echo "--- Wireguard ---" + log "--- Wireguard ---" docker exec -i DAppNodeCore-api.wireguard.dnp.dappnode.eth getWireguardCredentials "${localhost_flag[@]}" 2>&1 || \ - echo "Wireguard credentials not yet available. Try later with: dappnode_wireguard${localhost_flag:+ ${localhost_flag[*]}}" + log "Wireguard credentials not yet available. Try later with: dappnode_wireguard${localhost_flag:+ ${localhost_flag[*]}}" fi if [[ "$has_wireguard" == "true" && "$has_vpn" == "true" ]]; then - echo "" + log "" fi if [[ "$has_vpn" == "true" ]]; then - echo "--- OpenVPN ---" + log "--- OpenVPN ---" docker exec -i DAppNodeCore-vpn.dnp.dappnode.eth vpncli get dappnode_admin "${localhost_flag[@]}" 2>&1 || \ - echo "OpenVPN credentials not yet available. Try later with: dappnode_openvpn_get dappnode_admin${localhost_flag:+ ${localhost_flag[*]}}" + log "OpenVPN credentials not yet available. Try later with: dappnode_openvpn_get dappnode_admin${localhost_flag:+ ${localhost_flag[*]}}" fi - echo "" - echo "Import the configuration above into your VPN client of choice to access your DAppNode at http://my.dappnode" + log "" + log "Import the configuration above into your VPN client of choice to access your DAppNode at http://my.dappnode" } # Build docker compose "-f " args from downloaded compose files. @@ -421,8 +426,8 @@ normalize_ipfs_version_ref() { local manifest manifest="$(download_stdout "$manifest_url" 2>/dev/null || true)" if [[ -z "$manifest" ]]; then - echo "[ERROR] Could not fetch IPFS manifest for ${comp} from: $manifest_url" 1>&2 - echo "[ERROR] Provide ${comp}_VERSION as /ipfs/: (example: /ipfs/Qm...:0.2.11)" 1>&2 + error "Could not fetch IPFS manifest for ${comp} from: $manifest_url" + error "Provide ${comp}_VERSION as /ipfs/: (example: /ipfs/Qm...:0.2.11)" return 1 fi @@ -435,8 +440,8 @@ normalize_ipfs_version_ref() { )" if [[ -z "$inferred_version" || "$inferred_version" == "$manifest" ]]; then - echo "[ERROR] Could not infer version for ${comp} from IPFS manifest: $manifest_url" 1>&2 - echo "[ERROR] Provide ${comp}_VERSION as /ipfs/:" 1>&2 + error "Could not infer version for ${comp} from IPFS manifest: $manifest_url" + error "Provide ${comp}_VERSION as /ipfs/:" return 1 fi @@ -520,7 +525,7 @@ patch_dappmanager_compose_for_macos() { bootstrap_filesystem() { # Clean if update if [[ "${UPDATE}" == "true" ]]; then - echo "Cleaning for update..." + log "Cleaning for update..." rm -f "${LOGFILE}" || true rm -f "${DAPPNODE_CORE_DIR}"/docker-compose-*.yml || true rm -f "${DAPPNODE_CORE_DIR}"/dappnode_package-*.json || true @@ -805,17 +810,17 @@ dappnode_core_build() { ver="${comp}_VERSION" if [[ ${!ver} == dev:* ]]; then if $IS_MACOS; then - echo "Development builds (dev:*) are not supported on macOS." + error "Development builds (dev:*) are not supported on macOS." exit 1 fi - echo "Cloning & building DNP_${comp}..." + log "Cloning & building DNP_${comp}..." if ! dpkg -s git >/dev/null 2>&1; then apt-get install -y git fi local tmpdir tmpdir="$(mktemp -d)" pushd "$tmpdir" >/dev/null || { - echo "Error on pushd" + error "Error on pushd" exit 1 } git clone -b "${!ver##*:}" https://github.com/dappnode/DNP_"${comp}" @@ -829,7 +834,7 @@ dappnode_core_build() { cp "./DNP_${comp}/dappnode_package.json" "${DAPPNODE_CORE_DIR}/dappnode_package-${comp_lower}.json" rm -rf "./DNP_${comp}" popd >/dev/null || { - echo "Error on popd" + error "Error on popd" exit 1 } rm -rf "$tmpdir" @@ -849,13 +854,13 @@ dappnode_core_download() { local manifest_var="${comp}_MANIFEST" # Download DAppNode Core Images if needed - echo "Downloading ${comp} tar..." + log "Downloading ${comp} tar..." [ -f "${!file_var}" ] || download_file "${!file_var}" "${!url_var}" || exit 1 # Download DAppNode Core docker-compose yml files if needed - echo "Downloading ${comp} yml..." + log "Downloading ${comp} yml..." [ -f "${!yml_file_var}" ] || download_file "${!yml_file_var}" "${!yml_var}" || exit 1 # Download DAppNode Core manifest files if needed - echo "Downloading ${comp} manifest..." + log "Downloading ${comp} manifest..." [ -f "${!manifest_file_var}" ] || download_file "${!manifest_file_var}" "${!manifest_var}" || exit 1 # macOS: patch compose files for Docker Desktop compatibility @@ -941,7 +946,7 @@ addSwap() { # if not then create it if [ "$IS_SWAP" -eq 0 ]; then - echo 'Swap not found. Adding swapfile.' + log 'Swap not found. Adding swapfile.' #RAM=$(awk '/MemTotal/ {print $2}' /proc/meminfo) #SWAP=$(($RAM * 2)) SWAP=8388608 @@ -951,7 +956,7 @@ addSwap() { swapon /swapfile echo '/swapfile none swap defaults 0 0' >>/etc/fstab else - echo 'Swap found. No changes made.' + log 'Swap found. No changes made.' fi } @@ -1000,7 +1005,7 @@ add_profile_to_shell() { } dappnode_core_start() { - echo "DAppNode starting..." 2>&1 | tee -a "$LOGFILE" + log "DAppNode starting..." if [[ ${#DNCORE_COMPOSE_ARGS[@]} -eq 0 ]]; then build_dncore_compose_args @@ -1008,7 +1013,7 @@ dappnode_core_start() { [[ ${#DNCORE_COMPOSE_ARGS[@]} -gt 0 ]] || die "No docker-compose-*.yml files found in ${DAPPNODE_CORE_DIR}" docker compose "${DNCORE_COMPOSE_ARGS[@]}" up -d 2>&1 | tee -a "$LOGFILE" - echo "DAppNode started" 2>&1 | tee -a "$LOGFILE" + log "DAppNode started" # Add profile sourcing to user's shell configuration add_profile_to_shell @@ -1027,7 +1032,7 @@ dappnode_core_start() { fi # Display help message to the user - echo "Execute dappnode_help to see a full list with commands available" + log "Execute dappnode_help to see a full list with commands available" } grabContentHashes() { @@ -1100,58 +1105,58 @@ main() { resolve_packages echo "" 2>&1 | tee -a "$LOGFILE" - echo "##############################################" 2>&1 | tee -a "$LOGFILE" - echo "#### DAPPNODE INSTALLER ####" 2>&1 | tee -a "$LOGFILE" - echo "##############################################" 2>&1 | tee -a "$LOGFILE" + log "##############################################" + log "#### DAPPNODE INSTALLER ####" + log "##############################################" # --- Linux-only setup steps --- if $IS_LINUX; then if [[ "${MINIMAL}" != "true" && "${LITE}" != "true" ]]; then - echo "Creating swap memory..." 2>&1 | tee -a "$LOGFILE" + log "Creating swap memory..." addSwap - echo "Customizing login..." 2>&1 | tee -a "$LOGFILE" + log "Customizing login..." customMotd - echo "Installing extra packages..." 2>&1 | tee -a "$LOGFILE" + log "Installing extra packages..." installExtraDpkg - echo "Grabbing latest content hashes..." 2>&1 | tee -a "$LOGFILE" + log "Grabbing latest content hashes..." grabContentHashes if [ "$ARCH" == "amd64" ]; then - echo "Installing SGX modules..." 2>&1 | tee -a "$LOGFILE" + log "Installing SGX modules..." installSgx - echo "Installing extra packages..." 2>&1 | tee -a "$LOGFILE" + log "Installing extra packages..." installExtraDpkg # TODO: Why is this being called twice? fi fi - echo "Adding user to docker group..." 2>&1 | tee -a "$LOGFILE" + log "Adding user to docker group..." addUserToDockerGroup fi # --- Common steps (Linux and macOS) --- - echo "Creating dncore_network if needed..." 2>&1 | tee -a "$LOGFILE" + log "Creating dncore_network if needed..." docker network create --driver bridge --subnet 172.33.0.0/16 dncore_network 2>&1 | tee -a "$LOGFILE" || true - echo "Building DAppNode Core if needed..." 2>&1 | tee -a "$LOGFILE" + log "Building DAppNode Core if needed..." dappnode_core_build - echo "Downloading DAppNode Core..." 2>&1 | tee -a "$LOGFILE" + log "Downloading DAppNode Core..." dappnode_core_download # Build compose args now that compose files exist build_dncore_compose_args - echo "Loading DAppNode Core..." 2>&1 | tee -a "$LOGFILE" + log "Loading DAppNode Core..." dappnode_core_load # --- Start DAppNode --- if $IS_LINUX; then if [ ! -f "${DAPPNODE_DIR}/.firstboot" ]; then - echo "DAppNode installed" 2>&1 | tee -a "$LOGFILE" + log "DAppNode installed" dappnode_core_start print_vpn_access_credentials fi @@ -1166,7 +1171,7 @@ main() { fi if $IS_MACOS; then - echo "DAppNode installed" 2>&1 | tee -a "$LOGFILE" + log "DAppNode installed" dappnode_core_start print_vpn_access_credentials fi From ece45c3abfed377c6327435dcbe629672d867d00 Mon Sep 17 00:00:00 2001 From: pablomendezroyo Date: Tue, 17 Mar 2026 08:31:21 +0100 Subject: [PATCH 4/7] Update package versions in .dappnode_profile for consistency --- .dappnode_profile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.dappnode_profile b/.dappnode_profile index 35dbcd2..a063e33 100755 --- a/.dappnode_profile +++ b/.dappnode_profile @@ -7,12 +7,12 @@ # - `/ipfs/QmRe6...` -> indicates the ipfs hash used to download the content # - `0.2.71` -> indicates the version. It must be the one uploaded to such IPFS hash -export BIND_VERSION="${BIND_VERSION:-0.2.11}" -export IPFS_VERSION="${IPFS_VERSION:-0.2.23}" -export VPN_VERSION="${VPN_VERSION:-0.2.10}" -export DAPPMANAGER_VERSION="${DAPPMANAGER_VERSION:-0.2.99}" -export WIFI_VERSION="${WIFI_VERSION:-0.2.9}" -export WIREGUARD_VERSION="${WIREGUARD_VERSION:-0.1.3}" +export BIND_VERSION="${BIND_VERSION:-0.2.13}" +export IPFS_VERSION="${IPFS_VERSION:-0.2.27}" +export VPN_VERSION="${VPN_VERSION:-0.2.11}" +export DAPPMANAGER_VERSION="${DAPPMANAGER_VERSION:-0.2.121}" +export WIFI_VERSION="${WIFI_VERSION:-0.2.11}" +export WIREGUARD_VERSION="${WIREGUARD_VERSION:-0.1.4}" export HTTPS_VERSION="${HTTPS:-0.2.2}" export NOTIFICATIONS_VERSION="/ipfs/QmX6kkG8bwZVNdhYnPjhz9p6SKnbozHrVFwPMvU1a2YN2s" export PREMIUM_VERSION="/ipfs/QmRorK6DQUen31vJdfT8TaJsD4QQqbWg9xFQNixwoQEPKy" From 804f5b0aeb39968776445b6e01f81f07907b98ed Mon Sep 17 00:00:00 2001 From: pablomendezroyo Date: Tue, 17 Mar 2026 08:41:11 +0100 Subject: [PATCH 5/7] Enhance logging and retry mechanism in wait_for_internal_ip function; update warnings for credential availability --- scripts/dappnode_install.sh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/scripts/dappnode_install.sh b/scripts/dappnode_install.sh index 180f441..78d634f 100755 --- a/scripts/dappnode_install.sh +++ b/scripts/dappnode_install.sh @@ -216,6 +216,7 @@ wait_for_internal_ip() { internal_value="" hostname_http_code="" hostname_value="" + local retry_count=0 while true; do if (( SECONDS - start_seconds >= timeout_seconds )); then @@ -246,7 +247,10 @@ wait_for_internal_ip() { return 0 fi - log "INTERNAL_IP/HOSTNAME not ready yet (INTERNAL_IP code=${internal_http_code:-?}, HOSTNAME code=${hostname_http_code:-?}). Retrying..." + retry_count=$((retry_count + 1)) + if (( retry_count % 5 == 1 )); then + log "INTERNAL_IP/HOSTNAME not ready yet (INTERNAL_IP code=${internal_http_code:-?}, HOSTNAME code=${hostname_http_code:-?}). Retrying..." + fi sleep 2 done } @@ -293,7 +297,7 @@ print_vpn_access_credentials() { if [[ "$has_wireguard" == "true" ]]; then log "--- Wireguard ---" docker exec -i DAppNodeCore-api.wireguard.dnp.dappnode.eth getWireguardCredentials "${localhost_flag[@]}" 2>&1 || \ - log "Wireguard credentials not yet available. Try later with: dappnode_wireguard${localhost_flag:+ ${localhost_flag[*]}}" + warn "Wireguard credentials not yet available. Try later with: dappnode_wireguard${localhost_flag:+ ${localhost_flag[*]}}" fi if [[ "$has_wireguard" == "true" && "$has_vpn" == "true" ]]; then @@ -303,7 +307,7 @@ print_vpn_access_credentials() { if [[ "$has_vpn" == "true" ]]; then log "--- OpenVPN ---" docker exec -i DAppNodeCore-vpn.dnp.dappnode.eth vpncli get dappnode_admin "${localhost_flag[@]}" 2>&1 || \ - log "OpenVPN credentials not yet available. Try later with: dappnode_openvpn_get dappnode_admin${localhost_flag:+ ${localhost_flag[*]}}" + warn "OpenVPN credentials not yet available. Try later with: dappnode_openvpn_get dappnode_admin${localhost_flag:+ ${localhost_flag[*]}}" fi log "" @@ -1041,7 +1045,7 @@ grabContentHashes() { for comp in "${content_hash_pkgs[@]}"; do CONTENT_HASH=$(download_stdout "https://github.com/dappnode/DAppNodePackage-${comp}/releases/latest/download/content-hash") if [ -z "$CONTENT_HASH" ]; then - echo "ERROR! Failed to find content hash of ${comp}." 2>&1 | tee -a "$LOGFILE" + error "Failed to find content hash of ${comp}." exit 1 fi echo "${comp}.dnp.dappnode.eth,${CONTENT_HASH}" >>"${CONTENT_HASH_FILE}" @@ -1074,12 +1078,12 @@ addUserToDockerGroup() { # If USER is not found, warn the user and return if [ -z "$user" ]; then - echo "WARN: Default user not found. Could not add it to the docker group." 2>&1 | tee -a "$LOGFILE" + warn "Default user not found. Could not add it to the docker group." return fi if groups "$user" | grep &>/dev/null '\bdocker\b'; then - echo "User $user is already in the docker group" 2>&1 | tee -a "$LOGFILE" + log "User $user is already in the docker group" return fi @@ -1087,7 +1091,7 @@ addUserToDockerGroup() { # but it's not working in the Ubuntu ISO because the late-commands in the autoinstall.yaml # file are executed before the user is created. usermod -aG docker "$user" - echo "User $user added to the docker group" 2>&1 | tee -a "$LOGFILE" + log "User $user added to the docker group" } ############################################## From 0c96431aa7d2d466ddb35a94b218091bd5ee10de Mon Sep 17 00:00:00 2001 From: pablomendezroyo Date: Tue, 17 Mar 2026 08:41:30 +0100 Subject: [PATCH 6/7] Update IPFS endpoint URL in dappnode_install.sh for stability --- scripts/dappnode_install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dappnode_install.sh b/scripts/dappnode_install.sh index 78d634f..0379827 100755 --- a/scripts/dappnode_install.sh +++ b/scripts/dappnode_install.sh @@ -360,7 +360,7 @@ if $IS_LINUX; then UPDATE_MOTD_DIR="/etc/update-motd.d" fi # Get URLs -IPFS_ENDPOINT=${IPFS_ENDPOINT:-"https://ipfs-gateway-dev.dappnode.net"} +IPFS_ENDPOINT=${IPFS_ENDPOINT:-"https://ipfs-gateway.dappnode.net"} # PROFILE_URL env is used to fetch the core packages versions that will be used to build the release in script install method PROFILE_URL=${PROFILE_URL:-"https://github.com/dappnode/DAppNode/releases/latest/download/dappnode_profile.sh"} DAPPNODE_ACCESS_CREDENTIALS="${DAPPNODE_DIR}/scripts/dappnode_access_credentials.sh" From 689dcb1876fe907095c1ffdfee6157a40e6b3261 Mon Sep 17 00:00:00 2001 From: pablomendezroyo Date: Tue, 17 Mar 2026 08:42:10 +0100 Subject: [PATCH 7/7] Update notifications and premium package versions in .dappnode_profile for consistency --- .dappnode_profile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.dappnode_profile b/.dappnode_profile index a063e33..4d4943b 100755 --- a/.dappnode_profile +++ b/.dappnode_profile @@ -14,8 +14,8 @@ export DAPPMANAGER_VERSION="${DAPPMANAGER_VERSION:-0.2.121}" export WIFI_VERSION="${WIFI_VERSION:-0.2.11}" export WIREGUARD_VERSION="${WIREGUARD_VERSION:-0.1.4}" export HTTPS_VERSION="${HTTPS:-0.2.2}" -export NOTIFICATIONS_VERSION="/ipfs/QmX6kkG8bwZVNdhYnPjhz9p6SKnbozHrVFwPMvU1a2YN2s" -export PREMIUM_VERSION="/ipfs/QmRorK6DQUen31vJdfT8TaJsD4QQqbWg9xFQNixwoQEPKy" +export NOTIFICATIONS_VERSION="/ipfs/QmW5CSZv8x8ZktiNodJ9P8M6ZSRNX93jmB8oU6RtGermBc" +export PREMIUM_VERSION="/ipfs/QmUEmjt1yXLyGjnqf3BCiVenQtDhFwt4eMkx1sDemeEidM" export DAPPNODE_DIR="/usr/src/dappnode" export DAPPNODE_CORE_DIR="${DAPPNODE_DIR}/DNCORE"