From ffd15abb42643e474dc93fddf327d670c5da9b1f Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Wed, 17 Jan 2024 08:48:38 +0000 Subject: [PATCH 01/14] Better watchdog logs --- CHANGELOG.md | 6 ++++++ install.sh | 24 ++++++++++++++++++++---- package.json | 2 +- src/lib.sh | 18 +++++++++++++++++- src/setup.sh | 2 +- updated | 2 +- 6 files changed, 46 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb9cbb5..9990d11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.8.1] - 2024-01-17 + +### Changed + +- Added more detailed logs in case of watchdog failure + ## [1.8.0] - 2024-01-07 ### Added diff --git a/install.sh b/install.sh index 8c688f3..9797b1d 100644 --- a/install.sh +++ b/install.sh @@ -1,6 +1,6 @@ #!/bin/bash -### version: 1.8.0 +### version: 1.8.1 # ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.# # Nightscout Mikr.us setup script # @@ -34,6 +34,7 @@ RESERVED_DB_FILE=/srv/nightscout/data/reserved.db WATCHDOG_STATUS_FILE=/srv/nightscout/data/watchdog_status WATCHDOG_TIME_FILE=/srv/nightscout/data/watchdog_time WATCHDOG_LOG_FILE=/srv/nightscout/data/watchdog.log +WATCHDOG_FAILURES_FILE=/srv/nightscout/data/watchdog-failures.log WATCHDOG_CRON_LOG=/srv/nightscout/data/watchdog-cron.log UPDATE_CHANNEL_FILE=/srv/nightscout/data/update_channel MONGO_DB_DIR=/srv/nightscout/data/mongodb @@ -41,8 +42,8 @@ TOOL_FILE=/srv/nightscout/tools/nightscout-tool TOOL_LINK=/usr/bin/nightscout-tool UPDATES_DIR=/srv/nightscout/updates UPDATE_CHANNEL=master -SCRIPT_VERSION="1.8.0" #auto-update -SCRIPT_BUILD_TIME="2024.01.07" #auto-update +SCRIPT_VERSION="1.8.1" #auto-update +SCRIPT_BUILD_TIME="2024.01.17" #auto-update #======================================= # SETUP @@ -1599,7 +1600,7 @@ watchdog_check() { local domainLen=${#domain} if ((domainLen > 15)); then - local html=$(curl -Lks "$domain") + local html=$(curl -Lksi "$domain") WATCHDOG_STATUS="detection_failed" @@ -1623,6 +1624,15 @@ watchdog_check() { WATCHDOG_STATUS="restarting" fi + if [ "$WATCHDOG_STATUS" = "detection_failed" ]; then + { + echo "----------------------------------------------------------------" + echo "[$WATCHDOG_TIME] Unknown server failure:" + echo "HTTP DUMP:" + echo "$html" + } >>"$WATCHDOG_FAILURES_FILE" + fi + else WATCHDOG_STATUS="domain_failed" fi @@ -1646,6 +1656,12 @@ watchdog_check() { fi # fi + FAILSIZE=$(wc -l <$WATCHDOG_FAILURES_FILE) + if [ "$FAILSIZE" -gt 10000 ]; then + tail -10000 $WATCHDOG_FAILURES_FILE >"$WATCHDOG_FAILURES_FILE.tmp" + mv -f "$WATCHDOG_FAILURES_FILE.tmp" "$WATCHDOG_FAILURES_FILE" + fi + echo "$WATCHDOG_TIME" >$WATCHDOG_TIME_FILE echo "$WATCHDOG_STATUS" >$WATCHDOG_STATUS_FILE diff --git a/package.json b/package.json index 778e5d1..a5a5ce4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dlvoy/ns-installer-mikrus", - "version": "1.8.0", + "version": "1.8.1", "description": "Nightscout installer for mikr.us VPS", "main": "index.js", "scripts": { diff --git a/src/lib.sh b/src/lib.sh index dca70f5..21c9e08 100644 --- a/src/lib.sh +++ b/src/lib.sh @@ -18,6 +18,7 @@ RESERVED_DB_FILE=/srv/nightscout/data/reserved.db WATCHDOG_STATUS_FILE=/srv/nightscout/data/watchdog_status WATCHDOG_TIME_FILE=/srv/nightscout/data/watchdog_time WATCHDOG_LOG_FILE=/srv/nightscout/data/watchdog.log +WATCHDOG_FAILURES_FILE=/srv/nightscout/data/watchdog-failures.log WATCHDOG_CRON_LOG=/srv/nightscout/data/watchdog-cron.log UPDATE_CHANNEL_FILE=/srv/nightscout/data/update_channel MONGO_DB_DIR=/srv/nightscout/data/mongodb @@ -1583,7 +1584,7 @@ watchdog_check() { local domainLen=${#domain} if ((domainLen > 15)); then - local html=$(curl -Lks "$domain") + local html=$(curl -Lksi "$domain") WATCHDOG_STATUS="detection_failed" @@ -1607,6 +1608,15 @@ watchdog_check() { WATCHDOG_STATUS="restarting" fi + if [ "$WATCHDOG_STATUS" = "detection_failed" ]; then + { + echo "----------------------------------------------------------------" + echo "[$WATCHDOG_TIME] Unknown server failure:" + echo "HTTP DUMP:" + echo "$html" + } >>"$WATCHDOG_FAILURES_FILE" + fi + else WATCHDOG_STATUS="domain_failed" fi @@ -1630,6 +1640,12 @@ watchdog_check() { fi # fi + FAILSIZE=$(wc -l <$WATCHDOG_FAILURES_FILE) + if [ "$FAILSIZE" -gt 10000 ]; then + tail -10000 $WATCHDOG_FAILURES_FILE >"$WATCHDOG_FAILURES_FILE.tmp" + mv -f "$WATCHDOG_FAILURES_FILE.tmp" "$WATCHDOG_FAILURES_FILE" + fi + echo "$WATCHDOG_TIME" >$WATCHDOG_TIME_FILE echo "$WATCHDOG_STATUS" >$WATCHDOG_STATUS_FILE diff --git a/src/setup.sh b/src/setup.sh index 26783a9..1574b02 100755 --- a/src/setup.sh +++ b/src/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash -### version: 1.8.0 +### version: 1.8.1 # ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.# # Nightscout Mikr.us setup script # diff --git a/updated b/updated index ff41ff3..dafd8f1 100644 --- a/updated +++ b/updated @@ -1 +1 @@ -2024-01-07T18:29:57.941Z \ No newline at end of file +2024-01-17T08:47:45.288Z \ No newline at end of file -- 2.38.5 From 3970a25243311ee423ad5c3dc33460887e0f3d8f Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Wed, 17 Jan 2024 09:25:33 +0000 Subject: [PATCH 02/14] Logging fixes, addded channel support --- CHANGELOG.md | 4 ++++ install.sh | 26 +++++++++++++++++++++----- src/lib.sh | 26 +++++++++++++++++++++----- updated | 2 +- 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9990d11..c8e0cd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.8.1] - 2024-01-17 +### Added + +- Custom update channels support + ### Changed - Added more detailed logs in case of watchdog failure diff --git a/install.sh b/install.sh index 9797b1d..7dd29f0 100644 --- a/install.sh +++ b/install.sh @@ -1656,10 +1656,12 @@ watchdog_check() { fi # fi - FAILSIZE=$(wc -l <$WATCHDOG_FAILURES_FILE) - if [ "$FAILSIZE" -gt 10000 ]; then - tail -10000 $WATCHDOG_FAILURES_FILE >"$WATCHDOG_FAILURES_FILE.tmp" - mv -f "$WATCHDOG_FAILURES_FILE.tmp" "$WATCHDOG_FAILURES_FILE" + if [[ -f $WATCHDOG_FAILURES_FILE ]]; then + FAILSIZE=$(wc -l <$WATCHDOG_FAILURES_FILE) + if [ "$FAILSIZE" -gt 10000 ]; then + tail -10000 $WATCHDOG_FAILURES_FILE >"$WATCHDOG_FAILURES_FILE.tmp" + mv -f "$WATCHDOG_FAILURES_FILE.tmp" "$WATCHDOG_FAILURES_FILE" + fi fi echo "$WATCHDOG_TIME" >$WATCHDOG_TIME_FILE @@ -1685,7 +1687,7 @@ parse_commandline_args() { load_update_channel - CMDARGS=$(getopt --quiet -o wvdp --long watchdog,version,develop,production -n 'nightscout-tool' -- "$@") + CMDARGS=$(getopt --quiet -o wvdpc: --long watchdog,version,develop,production,channel: -n 'nightscout-tool' -- "$@") # shellcheck disable=SC2181 if [ $? != 0 ]; then @@ -1719,6 +1721,20 @@ parse_commandline_args() { echo "$UPDATE_CHANNEL" >$UPDATE_CHANNEL_FILE shift ;; + -c | --channel) + shift # The arg is next in position args + UPDATE_CHANNEL_CANDIDATE=$1 + + [[ ! "$UPDATE_CHANNEL_CANDIDATE" =~ ^[a-z]{3,}$ ]] && { + echo "Incorrect channel name provided: $UPDATE_CHANNEL_CANDIDATE" + exit 1 + } + + warn "Switching to $UPDATE_CHANNEL_CANDIDATE update channel" + UPDATE_CHANNEL="$UPDATE_CHANNEL_CANDIDATE" + echo "$UPDATE_CHANNEL" >$UPDATE_CHANNEL_FILE + shift + ;; --) shift break diff --git a/src/lib.sh b/src/lib.sh index 21c9e08..4cfb024 100644 --- a/src/lib.sh +++ b/src/lib.sh @@ -1640,10 +1640,12 @@ watchdog_check() { fi # fi - FAILSIZE=$(wc -l <$WATCHDOG_FAILURES_FILE) - if [ "$FAILSIZE" -gt 10000 ]; then - tail -10000 $WATCHDOG_FAILURES_FILE >"$WATCHDOG_FAILURES_FILE.tmp" - mv -f "$WATCHDOG_FAILURES_FILE.tmp" "$WATCHDOG_FAILURES_FILE" + if [[ -f $WATCHDOG_FAILURES_FILE ]]; then + FAILSIZE=$(wc -l <$WATCHDOG_FAILURES_FILE) + if [ "$FAILSIZE" -gt 10000 ]; then + tail -10000 $WATCHDOG_FAILURES_FILE >"$WATCHDOG_FAILURES_FILE.tmp" + mv -f "$WATCHDOG_FAILURES_FILE.tmp" "$WATCHDOG_FAILURES_FILE" + fi fi echo "$WATCHDOG_TIME" >$WATCHDOG_TIME_FILE @@ -1669,7 +1671,7 @@ parse_commandline_args() { load_update_channel - CMDARGS=$(getopt --quiet -o wvdp --long watchdog,version,develop,production -n 'nightscout-tool' -- "$@") + CMDARGS=$(getopt --quiet -o wvdpc: --long watchdog,version,develop,production,channel: -n 'nightscout-tool' -- "$@") # shellcheck disable=SC2181 if [ $? != 0 ]; then @@ -1703,6 +1705,20 @@ parse_commandline_args() { echo "$UPDATE_CHANNEL" >$UPDATE_CHANNEL_FILE shift ;; + -c | --channel) + shift # The arg is next in position args + UPDATE_CHANNEL_CANDIDATE=$1 + + [[ ! "$UPDATE_CHANNEL_CANDIDATE" =~ ^[a-z]{3,}$ ]] && { + echo "Incorrect channel name provided: $UPDATE_CHANNEL_CANDIDATE" + exit 1 + } + + warn "Switching to $UPDATE_CHANNEL_CANDIDATE update channel" + UPDATE_CHANNEL="$UPDATE_CHANNEL_CANDIDATE" + echo "$UPDATE_CHANNEL" >$UPDATE_CHANNEL_FILE + shift + ;; --) shift break diff --git a/updated b/updated index dafd8f1..e5a7bb5 100644 --- a/updated +++ b/updated @@ -1 +1 @@ -2024-01-17T08:47:45.288Z \ No newline at end of file +2024-01-17T09:24:04.563Z \ No newline at end of file -- 2.38.5 From 02faa934a59b9260ac65ae2974b5ea470e74a22e Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Thu, 18 Jan 2024 16:53:45 +0000 Subject: [PATCH 03/14] additional logs --- install.sh | 4 +++- src/lib.sh | 2 ++ updated | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/install.sh b/install.sh index 7dd29f0..f120020 100644 --- a/install.sh +++ b/install.sh @@ -43,7 +43,7 @@ TOOL_LINK=/usr/bin/nightscout-tool UPDATES_DIR=/srv/nightscout/updates UPDATE_CHANNEL=master SCRIPT_VERSION="1.8.1" #auto-update -SCRIPT_BUILD_TIME="2024.01.17" #auto-update +SCRIPT_BUILD_TIME="2024.01.18" #auto-update #======================================= # SETUP @@ -1628,6 +1628,8 @@ watchdog_check() { { echo "----------------------------------------------------------------" echo "[$WATCHDOG_TIME] Unknown server failure:" + echo "CONTAINERS:" + docker stats --no-stream echo "HTTP DUMP:" echo "$html" } >>"$WATCHDOG_FAILURES_FILE" diff --git a/src/lib.sh b/src/lib.sh index 4cfb024..1b8befd 100644 --- a/src/lib.sh +++ b/src/lib.sh @@ -1612,6 +1612,8 @@ watchdog_check() { { echo "----------------------------------------------------------------" echo "[$WATCHDOG_TIME] Unknown server failure:" + echo "CONTAINERS:" + docker stats --no-stream echo "HTTP DUMP:" echo "$html" } >>"$WATCHDOG_FAILURES_FILE" diff --git a/updated b/updated index e5a7bb5..120c826 100644 --- a/updated +++ b/updated @@ -1 +1 @@ -2024-01-17T09:24:04.563Z \ No newline at end of file +2024-01-18T16:53:04.730Z \ No newline at end of file -- 2.38.5 From 638f1a1fc28650b4d7ed41c0850e0d00f3801bec Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Sat, 20 Jan 2024 18:25:47 +0000 Subject: [PATCH 04/14] Fixed curl invocation --- install.sh | 4 ++-- src/lib.sh | 2 +- updated | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/install.sh b/install.sh index f120020..7065be4 100644 --- a/install.sh +++ b/install.sh @@ -43,7 +43,7 @@ TOOL_LINK=/usr/bin/nightscout-tool UPDATES_DIR=/srv/nightscout/updates UPDATE_CHANNEL=master SCRIPT_VERSION="1.8.1" #auto-update -SCRIPT_BUILD_TIME="2024.01.18" #auto-update +SCRIPT_BUILD_TIME="2024.01.20" #auto-update #======================================= # SETUP @@ -1600,7 +1600,7 @@ watchdog_check() { local domainLen=${#domain} if ((domainLen > 15)); then - local html=$(curl -Lksi "$domain") + local html=$(curl -iLsk "$domain") WATCHDOG_STATUS="detection_failed" diff --git a/src/lib.sh b/src/lib.sh index 1b8befd..df3bf21 100644 --- a/src/lib.sh +++ b/src/lib.sh @@ -1584,7 +1584,7 @@ watchdog_check() { local domainLen=${#domain} if ((domainLen > 15)); then - local html=$(curl -Lksi "$domain") + local html=$(curl -iLsk "$domain") WATCHDOG_STATUS="detection_failed" diff --git a/updated b/updated index 120c826..32fb888 100644 --- a/updated +++ b/updated @@ -1 +1 @@ -2024-01-18T16:53:04.730Z \ No newline at end of file +2024-01-20T18:24:52.704Z \ No newline at end of file -- 2.38.5 From 00c45a6002f075db4d48025bc33a8168ce82a6b9 Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Sat, 5 Oct 2024 23:11:50 +0000 Subject: [PATCH 05/14] Cleanup an diagnostics --- install.sh | 527 +++++++++++++++++++++++++++++++++++++++++++++------ package.json | 2 +- src/lib.sh | 523 ++++++++++++++++++++++++++++++++++++++++++++------ src/setup.sh | 4 +- updated | 2 +- 5 files changed, 946 insertions(+), 112 deletions(-) diff --git a/install.sh b/install.sh index 7065be4..9b160c4 100644 --- a/install.sh +++ b/install.sh @@ -1,6 +1,6 @@ #!/bin/bash -### version: 1.8.1 +### version: 1.9.0 # ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.# # Nightscout Mikr.us setup script # @@ -28,6 +28,7 @@ CONFIG_ROOT_DIR=/srv/nightscout/config ENV_FILE_ADMIN=/srv/nightscout/config/admin.env ENV_FILE_NS=/srv/nightscout/config/nightscout.env ENV_FILE_DEP=/srv/nightscout/config/deployment.env +LOG_ENCRYPTION_KEY_FILE=/srv/nightscout/config/log.key DOCKER_COMPOSE_FILE=/srv/nightscout/config/docker-compose.yml PROFANITY_DB_FILE=/srv/nightscout/data/profanity.db RESERVED_DB_FILE=/srv/nightscout/data/reserved.db @@ -36,14 +37,15 @@ WATCHDOG_TIME_FILE=/srv/nightscout/data/watchdog_time WATCHDOG_LOG_FILE=/srv/nightscout/data/watchdog.log WATCHDOG_FAILURES_FILE=/srv/nightscout/data/watchdog-failures.log WATCHDOG_CRON_LOG=/srv/nightscout/data/watchdog-cron.log +SUPPORT_LOG=/srv/nightscout/data/support.log UPDATE_CHANNEL_FILE=/srv/nightscout/data/update_channel MONGO_DB_DIR=/srv/nightscout/data/mongodb TOOL_FILE=/srv/nightscout/tools/nightscout-tool TOOL_LINK=/usr/bin/nightscout-tool UPDATES_DIR=/srv/nightscout/updates UPDATE_CHANNEL=master -SCRIPT_VERSION="1.8.1" #auto-update -SCRIPT_BUILD_TIME="2024.01.20" #auto-update +SCRIPT_VERSION="1.9.0" #auto-update +SCRIPT_BUILD_TIME="2024.10.05" #auto-update #======================================= # SETUP @@ -126,6 +128,9 @@ tty_red="$(tty_mkbold 31)" tty_bold="$(tty_mkbold 39)" tty_reset="$(tty_escape 0)" +NL="\n" +TL="\n\n" + #======================================= # EMOJIS #======================================= @@ -154,6 +159,7 @@ uni_confirm_upd=" $(printf '\U1F199') Aktualizuj " uni_confirm_ed=" $(printf '\U1F4DD') Edytuj " uni_install=" $(printf '\U1F680') Instaluj " uni_resign=" $(printf '\U1F6AB') Rezygnuję " +uni_send=" $(printf '\U1F4E7') Wyślij " uni_ns_ok="$(printf '\U1F7E2') działa" uni_watchdog_ok="$(printf '\U1F415') Nightscout działa" @@ -296,6 +302,13 @@ center_text() { echo "${spaces:0:$((($2 - len) / 2))}$1" } +rpad_text() { + local inText="$1" + local len=${#inText} + local spaces=" " + echo "$1${spaces:0:$(($2 - len))}" +} + multiline_length() { local string=$1 local maxLen=0 @@ -314,13 +327,16 @@ multiline_length() { center_multiline() { local maxLen=70 + local string="$*" + if [ $# -gt 1 ]; then - maxLen=$2 + maxLen=$1 + shift 1 + string="$*" else - maxLen=$(multiline_length "$1") + maxLen=$(multiline_length "$string") fi - local string=$1 # shellcheck disable=SC2059 readarray -t array <<<"$(printf "$string")" for i in "${!array[@]}"; do @@ -330,18 +346,77 @@ center_multiline() { done } +pad_multiline() { + local string="$*" + local maxLen=$(multiline_length "$string") + + # shellcheck disable=SC2059 + readarray -t array <<<"$(printf "$string")" + for i in "${!array[@]}"; do + local line=${array[i]} + # shellcheck disable=SC2005 + echo "$(rpad_text "$line" "$maxLen")" + done +} + okdlg() { - local msg=$2 - local lcount=$(echo -e "$2" | grep -c '^') + local title=$1 + shift 1 + local msg="$*" + local lcount=$(echo -e "$msg" | grep -c '^') local width=$(multiline_length "$msg") - whiptail --title "$1" --msgbox "$(center_multiline "$msg" $((width + 4)))" $((lcount + 6)) $((width + 9)) + whiptail --title "$title" --msgbox "$(center_multiline $((width + 4)) "$msg")" $((lcount + 6)) $((width + 9)) } confirmdlg() { - local msg=$2 - local lcount=$(echo -e "$2" | grep -c '^') + local title=$1 + local btnlabel=$2 + shift 2 + local msg="$*" + local lcount=$(echo -e "$msg" | grep -c '^') local width=$(multiline_length "$msg") - whiptail --title "$1" --ok-button "$3" --msgbox "$(center_multiline "$msg" $((width + 4)))" $((lcount + 6)) $((width + 9)) + whiptail --title "$title" --ok-button "$btnlabel" --msgbox "$(center_multiline $((width + 4)) "$msg")" $((lcount + 6)) $((width + 9)) +} + +yesnodlg() { + yesnodlg_base "y" "$@" +} + +noyesdlg() { + yesnodlg_base "n" "$@" +} + +yesnodlg_base() { + local defaultbtn=$1 + local title=$2 + local ybtn=$3 + local nbtn=$4 + shift 4 + local msg="$*" + # shellcheck disable=SC2059 + local linec=$(printf "$msg" | grep -c '^') + local width=$(multiline_length "$msg") + local ylen=${#ybtn} + local nlen=${#nbtn} + # we need space for all < > around buttons + local minbtn=$((ylen + nlen + 6)) + # minimal nice width of dialog + local minlen=$((minbtn > 15 ? minbtn : 15)) + local mwidth=$((minlen > width ? minlen : width)) + + # whiptail has bug, buttons are NOT centered + local rpad=$((width < minbtn ? (nlen - 2) + ((nlen - 2) / 2) : 4)) + local padw=$((mwidth + rpad)) + + if [[ "$defaultbtn" == "y" ]]; then + whiptail --title "$title" --yesno "$(center_multiline $padw "$msg")" \ + --yes-button "$ybtn" --no-button "$nbtn" \ + $((linec + 7)) $((padw + 4)) + else + whiptail --title "$title" --yesno --defaultno "$(center_multiline $padw "$msg")" \ + --yes-button "$ybtn" --no-button "$nbtn" \ + $((linec + 7)) $((padw + 4)) + fi } #======================================= @@ -352,6 +427,7 @@ packages=() aptGetWasUpdated=0 freshInstall=0 cachedMenuDomain='' +lastTimeSpaceInfo=0 MIKRUS_APIKEY='' MIKRUS_HOST='' @@ -446,10 +522,28 @@ check_dateutils() { add_if_not_ok "Date Utils" "dateutils" } +check_diceware() { + diceware --version >/dev/null 2>&1 + add_if_not_ok "Secure Password Generator" "diceware" +} + +setup_security() { + if [[ -f $LOG_ENCRYPTION_KEY_FILE ]]; then + msgok "Found log encryption key" + else + ohai "Generating log encryption file..." + diceware -n 5 -d - >$LOG_ENCRYPTION_KEY_FILE + msgcheck "Key generated" + fi +} + setup_packages() { # shellcheck disable=SC2145 # shellcheck disable=SC2068 - (ifIsSet packages && setup_update_repo && ohai "Installing packages: ${packages[@]}" && apt-get -yq install ${packages[@]} >>$LOGTO 2>&1 && msgcheck "Install successfull") || msgok "All required packages already installed" + (ifIsSet packages && setup_update_repo && + ohai "Installing packages: ${packages[@]}" && + apt-get -yq install ${packages[@]} >>$LOGTO 2>&1 && + msgcheck "Install successfull") || msgok "All required packages already installed" } setup_node() { @@ -580,6 +674,10 @@ get_docker_status() { fi } +get_space_info() { + df -B1 --output=target,size,avail,pcent | tail -n +2 | awk '$1 ~ /^\/$/' +} + install_containers() { docker-compose --env-file /srv/nightscout/config/deployment.env -f /srv/nightscout/config/docker-compose.yml up --no-recreate -d >>$LOGTO 2>&1 } @@ -772,23 +870,42 @@ update_if_needed() { } about_dialog() { + LOG_KEY=$(<$LOG_ENCRYPTION_KEY_FILE) okdlg "O tym narzędziu..." \ - "$(printf '\U1F9D1') (c) 2023 Dominik Dzienia\n$(printf '\U1F4E7') dominik.dzienia@gmail.com\n\n$(printf '\U1F3DB') To narzędzie jest dystrybuowane na licencji CC BY-NC-ND 4.0\nhttps://creativecommons.org/licenses/by-nc-nd/4.0/deed.pl\n\nwersja: $SCRIPT_VERSION ($SCRIPT_BUILD_TIME) $UPDATE_CHANNEL" + "$(printf '\U1F9D1') (c) 2023 Dominik Dzienia" \ + "${NL}$(printf '\U1F4E7') dominik.dzienia@gmail.com" \ + "${TL}$(printf '\U1F3DB') To narzędzie jest dystrybuowane na licencji CC BY-NC-ND 4.0" \ + "${NL}htps://creativecommons.org/licenses/by-nc-nd/4.0/deed.pl" \ + "${TL}wersja: $SCRIPT_VERSION ($SCRIPT_BUILD_TIME) $UPDATE_CHANNEL" \ + "${TL}hasło do logów: $LOG_KEY" } prompt_welcome() { - whiptail --title "Witamy" --yesno "$(center_multiline "Ten skrypt zainstaluje Nightscout na bieżącym serwerze mikr.us\n\nJeśli na tym serwerze jest już Nightscout \n- ten skrypt umożliwia jego aktualizację oraz diagnostykę." 65)" --yes-button "$uni_start" --no-button "$uni_exit" 12 70 + yesnodlg "Witamy" "$uni_start" "$uni_exit" \ + "Ten skrypt zainstaluje Nightscout na bieżącym serwerze mikr.us" \ + "${TL}Jeśli na tym serwerze jest już Nightscout " \ + "${NL}- ten skrypt umożliwia jego aktualizację oraz diagnostykę.${TL}" exit_on_no_cancel } - prompt_disclaimer() { confirmdlg "Ostrzeżenie!" \ - "Te narzędzie pozwala TOBIE zainstalować WŁASNĄ instancję Nightscout.\nTy odpowiadasz za ten serwer i ewentualne skutki jego używania.\nTy nim zarządzasz, to nie jest usługa czy produkt.\nTo rozwiązanie \"Zrób to sam\" - SAM za nie odpowiadasz!\n\nAutorzy skryptu nie ponoszą odpowiedzialności za skutki jego użycia!\nNie dajemy żadnych gwarancji co do jego poprawności czy dostępności!\nUżywasz go na własną odpowiedzialność!\nNie opieraj decyzji terapeutycznych na podstawie wskazań tego narzędzia!\n\nTwórcy tego narzędzia NIE SĄ administratorami Mikr.us-ów ani Hetznera!\nW razie problemów z dostępnością serwera najpierw sprawdź status Mikr.us-a!" \ - "Zrozumiano!" + "Zrozumiano!" \ + "Te narzędzie pozwala TOBIE zainstalować WŁASNĄ instancję Nightscout." \ + "${NL}Ty odpowiadasz za ten serwer i ewentualne skutki jego używania." \ + "${NL}Ty nim zarządzasz, to nie jest usługa czy produkt." \ + "${NL}To rozwiązanie \"Zrób to sam\" - SAM za nie odpowiadasz!" \ + "${TL}Autorzy skryptu nie ponoszą odpowiedzialności za skutki jego użycia!" \ + "${NL}Nie dajemy żadnych gwarancji co do jego poprawności czy dostępności!" \ + "${NL}Używasz go na własną odpowiedzialność!" \ + "${NL}Nie opieraj decyzji terapeutycznych na podstawie wskazań tego narzędzia!" \ + "${TL}Twórcy tego narzędzia NIE SĄ administratorami Mikr.us-ów ani Hetznera!" \ + "${NL}W razie problemów z dostępnością serwera najpierw sprawdź status Mikr.us-a!" } instal_now_prompt() { - whiptail --title "Instalować Nightscout?" --yesno "$(center_multiline "Wykryto konfigurację ale brak uruchomionych usług\nCzy chcesz zainstalować teraz kontenery Nightscout?" 65)" --yes-button "$uni_install" --no-button "$uni_noenter" 9 70 + yesnodlg "Instalować Nightscout?" "$uni_install" "$uni_noenter" \ + "Wykryto konfigurację ale brak uruchomionych usług" \ + "${NL}Czy chcesz zainstalować teraz kontenery Nightscout?" } prompt_mikrus_host() { @@ -947,10 +1064,11 @@ domain_setup() { local domain=$(get_td_domain) local domainLen=${#domain} if ((domainLen > 15)); then - msgcheck "Subdomena jest już skonfigurowana ($domain)" okdlg "Subdomena już ustawiona" \ - "Wykryto poprzednio skonfigurowaną subdomenę:\n\n$domain\n\nStrona Nightscout powinna być widoczna z internetu." + "Wykryto poprzednio skonfigurowaną subdomenę:" \ + "${TL}$domain" \ + "${TL}Strona Nightscout powinna być widoczna z internetu." return fi @@ -970,14 +1088,20 @@ domain_setup() { if printf "%s" "$SUBDOMAIN" | grep -f "$PROFANITY_DB_FILE" >>$LOGTO 2>&1; then okdlg "$uni_excl Nieprawidłowa subdomena $uni_excl" \ - "Podana wartość:\n$SUBDOMAIN\n\njest zajęta, zarezerwowana lub niedopuszczalna.\n\nWymyśl coś innego" + "Podana wartość:" \ + "${NL}$SUBDOMAIN" \ + "${TL}jest zajęta, zarezerwowana lub niedopuszczalna." \ + "${TL}Wymyśl coś innego" SUBDOMAIN='' continue fi if printf "%s" "$SUBDOMAIN" | grep -xf "$RESERVED_DB_FILE" >>$LOGTO 2>&1; then okdlg "$uni_excl Nieprawidłowa subdomena $uni_excl" \ - "Podana wartość:\n$SUBDOMAIN\n\njest zajęta lub zarezerwowana.\n\nWymyśl coś innego" + "Podana wartość:" \ + "${NL}$SUBDOMAIN" \ + "${TL}jest zajęta lub zarezerwowana." \ + "${TL}Wymyśl coś innego" SUBDOMAIN='' continue fi @@ -986,7 +1110,9 @@ domain_setup() { else okdlg "$uni_excl Nieprawidłowy początek subdomeny $uni_excl" \ - "Podany początek subdomeny:\n$SUBDOMAIN\n\nma nieprawidłowy format. Wymyśl coś innego" + "Podany początek subdomeny:" \ + "${NL}$SUBDOMAIN" \ + "${TL}ma nieprawidłowy format. Wymyśl coś innego" if [ $? -eq 1 ]; then SUBDOMAIN='' continue @@ -1027,7 +1153,12 @@ domain_setup() { } admin_panel_promo() { - whiptail --title "Panel zarządzania Mikr.us-em" --msgbox "$(center_multiline "Ta instalacja Nightscout dodaje dodatkowy panel administracyjny\ndo zarządzania serwerem i konfiguracją - online.\n\nZnajdziesz go klikając na ikonkę serwera w menu strony Nightscout\nlub dodając /mikrus na końcu swojego adresu Nightscout" 70)" 12 75 + whiptail --title "Panel zarządzania Mikr.us-em" --msgbox "$(center_multiline 70 \ + "Ta instalacja Nightscout dodaje dodatkowy panel administracyjny" \ + "${NL}do zarządzania serwerem i konfiguracją - online." \ + "${TL}Znajdziesz go klikając na ikonkę serwera w menu strony Nightscout" \ + "${NL}lub dodając /mikrus na końcu swojego adresu Nightscout")" \ + 12 75 } get_watchdog_age_string() { @@ -1241,7 +1372,7 @@ get_container_status_code() { show_logs() { local col=$((COLUMNS - 10)) - local rws=$((LINES - 3)) + local rws=$((LINES - 4)) if [ $col -gt 120 ]; then col=160 fi @@ -1349,7 +1480,13 @@ version_menu() { ohai "Changing Nightscout container tag from: $ns_tag to: $CHOICE" dotenv-tool -pmr -i $ENV_FILE_DEP -- "NS_NIGHTSCOUT_TAG=$CHOICE" docker_compose_update - whiptail --title "Zmieniono wersję Nightscout" --msgbox "$(center_multiline "Zmieniono wersję Nightscout na: $CHOICE\n\nSprawdź czy Nightscout działa poprawnie, w razie problemów:\n${uni_bullet}aktualizuj kontenery\n${uni_bullet}spróbuj wyczyścić bazę danych\n${uni_bullet}wróć do poprzedniej wersji ($ns_tag)" 65)" 13 70 + whiptail --title "Zmieniono wersję Nightscout" --msgbox "$(center_multiline 65 \ + "Zmieniono wersję Nightscout na: $CHOICE" \ + "${TL}Sprawdź czy Nightscout działa poprawnie, w razie problemów:" \ + "${NL}${uni_bullet}aktualizuj kontenery" \ + "${NL}${uni_bullet}spróbuj wyczyścić bazę danych" \ + "${NL}${uni_bullet}wróć do poprzedniej wersji ($ns_tag)")" \ + 13 70 break fi @@ -1358,6 +1495,144 @@ version_menu() { done } +do_cleanup_sys() { + ohai "Sprzątanie dziennik systemowego..." + journalctl --vacuum-size=50M >>$LOGTO 2>&1 + ohai "Czyszczenie systemu apt..." + apt autoremove >>$LOGTO 2>&1 +} + +do_cleanup_docker() { + ohai "Usuwanie nieużywanych obrazów Dockera..." + docker image prune -af >>$LOGTO 2>&1 +} + +do_cleanup_db() { + ohai "Usuwanie kopii zapasowych bazy danych..." + rm -f "/srv/nightscout/data/dbbackup/*" >>$LOGTO 2>&1 +} + +cleanup_menu() { + + while :; do + + local spaceInfo=$(get_space_info) + local remainingTxt=$(echo "$spaceInfo" | awk '{print $3}' | numfmt --to iec-i --suffix=B) + local totalTxt=$(echo "$spaceInfo" | awk '{print $2}' | numfmt --to iec-i --suffix=B) + local percTxt=$(echo "$spaceInfo" | awk '{print $4}') + local fixedPerc=${percTxt/[%]/=} + + local nowB=$(echo "$spaceInfo" | awk '{print $3}') + local lastTimeB=$(echo "$lastTimeSpaceInfo" | awk '{print $3}') + local savedB=$((nowB - lastTimeB)) + local savedTxt=$(echo "$savedB" | numfmt --to iec-i --suffix=B) + + if (( savedB < 1)); then + savedTxt="---" + fi + + local statusTitle="\n$(center_multiline 45 "$( + pad_multiline \ + " Dostępne: ${remainingTxt}" \ + "\n Zwolniono: ${savedTxt}" \ + "\n Zajęte: ${fixedPerc} (z ${totalTxt})" + )")\n" + + local CHOICE=$(whiptail --title "Sprzątanie" --menu \ + "${statusTitle/=/%}" \ + 16 50 5 \ + "A)" "Posprzątaj wszystko" \ + "S)" "Posprzątaj zasoby systemowe" \ + "D)" "Usuń nieużywane obrazy Dockera" \ + "B)" "Usuń kopie zapasowe bazy danych" \ + "M)" "Powrót do menu" \ + --ok-button="Wybierz" --cancel-button="$uni_back" \ + 3>&2 2>&1 1>&3) + + case $CHOICE in + "A)") + noyesdlg "Posprzątać wszystko?" "$uni_confirm_del" "$uni_resign" \ + "Czy chcesz posprzątać i usunąć:" \ + "$( + pad_multiline \ + "${NL}${uni_bullet}nieużywane pliki apt i dziennika" \ + "${NL}${uni_bullet}nieużywane obrazy Dockera" \ + "${NL}${uni_bullet}kopie zapasowe bazy danych" + )" + if ! [ $? -eq 1 ]; then + do_cleanup_sys + do_cleanup_docker + do_cleanup_db + fi + ;; + "S)") + noyesdlg "Posprzątać zasoby systemowe?" "$uni_confirm_del" "$uni_resign" \ + "Czy chcesz usunąć nieużywane pakiety apt i poprzątać dziennik systemowy?" + if ! [ $? -eq 1 ]; then + do_cleanup_sys + fi + ;; + "D)") + noyesdlg "Posprzątać obrazy Dockera?" "$uni_confirm_del" "$uni_resign" \ + "Czy chcesz usunąć nieużywane obrazy Dockera?" + if ! [ $? -eq 1 ]; then + do_cleanup_docker + fi + ;; + "B)") + noyesdlg "Usunąć kopie zapasowe bazy danych?" "$uni_confirm_del" "$uni_resign" \ + "Czy chcesz usunąć kopie zapasowe bazy danych?" \ + "${NL}(na razie i tak nie ma automatycznego mechanizmu ich wykorzystania)" + if ! [ $? -eq 1 ]; then + do_cleanup_db + fi + ;; + "M)") + break + ;; + "") + break + ;; + esac + done +} + +update_menu() { + while :; do + local CHOICE=$(whiptail --title "Aktualizuj" --menu "\n" 11 40 4 \ + "S)" "Aktualizuj system" \ + "N)" "Aktualizuj to narzędzie" \ + "K)" "Aktualizuj kontenery" \ + "M)" "Powrót do menu" \ + --ok-button="$uni_select" --cancel-button="$uni_back" \ + 3>&2 2>&1 1>&3) + + case $CHOICE in + "S)") + ohai "Updating package list" + dialog --title " Aktualizacja systemu " --infobox "\n Pobieranie listy pakietów\n ..... Proszę czekać ....." 6 33 + apt-get -yq update >>$LOGTO 2>&1 + ohai "Upgrading system" + dialog --title " Aktualizacja systemu " --infobox "\n Instalowanie pakietów\n ... Proszę czekać ..." 6 33 + apt-get -yq upgrade >>$LOGTO 2>&1 + ;; + "N)") + update_if_needed "Wszystkie pliki narzędzia są aktualne" + ;; + "K)") + docker_compose_down + docker_compose_update + ;; + "M)") + break + ;; + "") + break + ;; + esac + done +} + uninstall_menu() { while :; do local extraMenu=() @@ -1386,7 +1661,8 @@ uninstall_menu() { if ! [[ "$0" =~ .*"/usr/bin/nightscout-tool" ]]; then okdlg "Opcja niedostępna" \ - "Edytor ustawień dostępny po uruchomieniu narzędzia komendą:\n\nnightscout-tool" + "Edytor ustawień dostępny po uruchomieniu narzędzia komendą:" \ + "${TL}nightscout-tool" else whiptail --title "Edycja ustawień Nightscout" --yesno "Za chwilę otworzę plik konfiguracji Nightscout w edytorze NANO\n\nWskazówki co do obsługi edytora:\n${uni_bullet}Aby ZAPISAĆ zmiany naciśnij Ctrl+O\n${uni_bullet}Aby ZAKOŃCZYĆ edycję naciśnij Ctrl+X\n\n $(printf "\U26A0") Edycja spowoduje też restart i aktualizację kontenerów $(printf "\U26A0")" --yes-button "$uni_confirm_ed" --no-button "$uni_resign" 15 68 if ! [ $? -eq 1 ]; then @@ -1419,7 +1695,11 @@ uninstall_menu() { rm -r "${MONGO_DB_DIR:?}/data" dialog --title " Czyszczenie konfiguracji" --infobox "\n Usuwanie konfiguracji\n ... Proszę czekać ..." 6 32 rm -r "${CONFIG_ROOT_DIR:?}" - whiptail --title "Usunięto dane użytkownika" --msgbox "$(center_multiline "Usunęto dane użytkwnika i konfigurację.\n\nAby zainstalować Nightscout od zera:\nuruchom ponownie skrypt i podaj konfigurację" 65)" 11 70 + whiptail --title "Usunięto dane użytkownika" --msgbox "$(center_multiline 65 \ + "Usunęto dane użytkwnika i konfigurację." \ + "${TL}Aby zainstalować Nightscout od zera:" \ + "${NL}uruchom ponownie skrypt i podaj konfigurację")" \ + 11 70 exit 0 fi ;; @@ -1434,7 +1714,12 @@ uninstall_menu() { rm "$TOOL_LINK" rm -r "${NIGHTSCOUT_ROOT_DIR:?}/tools" rm -r "${NIGHTSCOUT_ROOT_DIR:?}/updates" - whiptail --title "Odinstalowano" --msgbox "$(center_multiline "Odinstalowano Nightscout z Mikr.us-a\n\nAby ponownie zainstalować, postępuj według instrukcji na stronie:\nhttps://t1d.dzienia.pl/mikrus\n\nDziękujemy i do zobaczenia!" 65)" 13 70 + whiptail --title "Odinstalowano" --msgbox "$(center_multiline 65 \ + "Odinstalowano Nightscout z Mikr.us-a" \ + "${TL}Aby ponownie zainstalować, postępuj według instrukcji na stronie:" \ + "${NL}https://t1d.dzienia.pl/mikrus" \ + "${TL}Dziękujemy i do zobaczenia!")" \ + 13 70 exit 0 fi ;; @@ -1464,53 +1749,181 @@ get_domain_status() { fi } +send_diagnostics() { + LOG_KEY=$(<$LOG_ENCRYPTION_KEY_FILE) + + yesnodlg "Wysyłać diagnostykę?" \ + "$uni_send" "$uni_resign" \ + "Czy chcesz zgromadzić i wysłać sobie mailem dane diagnostyczne?" \ + "\n$( + pad_multiline \ + "\n${uni_bullet}diagnostyka zawiera logi i informacje o serwerze i usługach" \ + "\n${uni_bullet}wysyłka na e-mail na który zamówiono serwer Mikr.us" \ + "\n${uni_bullet}dane będą skompresowane i zaszyfrowane" \ + "\n${uni_bullet}maila prześlij dalej do zaufanej osoby wspierającej" \ + "\n${uni_bullet_pad}(z którą to wcześniej zaplanowano i uzgodniono!!!)" \ + "\n${uni_bullet}hasło przekaż INNĄ DROGĄ (komunikatorem, SMSem, osobiście)" \ + "\n\n${uni_bullet_pad}Hasło do logów: $LOG_KEY" + )" + + if ! [ $? -eq 1 ]; then + + ohai "Zbieranie diagnostyki" + + local domain=$(get_td_domain) + local curr_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ") + local ns_tag=$(dotenv-tool -r get -f $ENV_FILE_DEP "NS_NIGHTSCOUT_TAG") + local mikrus_h=$(hostname) + + local LOG_DIVIDER="=======================================================" + + rm -f $SUPPORT_LOG + rm -f "$SUPPORT_LOG.gz" + rm -f "$SUPPORT_LOG.gz.asc" + + { + echo "Dane diagnostyczne zebrane $curr_time" + echo " serwer : $mikrus_h" + echo " domena : $domain" + echo " wersja NS : $ns_tag" + } >$SUPPORT_LOG + + ohai "Zbieranie statusu usług" + + { + echo "$LOG_DIVIDER" + echo " Statusy usług" + echo "$LOG_DIVIDER" + echo " Nightscout: $(get_container_status 'ns-server')" + echo " Baza danych: $(get_container_status 'ns-database')" + echo " Backup: $(get_container_status 'ns-backup')" + echo " Watchdog: $(get_watchdog_status "$(get_watchdog_status_code)" "$uni_watchdog_ok")" + } >>$SUPPORT_LOG + + ohai "Zbieranie informacji o zasobach" + local spaceInfo=$(get_space_info) + local remainingTxt=$(echo "$spaceInfo" | awk '{print $3}' | numfmt --to iec-i --suffix=B) + local totalTxt=$(echo "$spaceInfo" | awk '{print $2}' | numfmt --to iec-i --suffix=B) + local percTxt=$(echo "$spaceInfo" | awk '{print $4}') + + { + echo "$LOG_DIVIDER" + echo " Miejsce na dysku" + echo "$LOG_DIVIDER" + echo " Dostępne: ${remainingTxt}" + echo " Zajęte: ${percTxt} (z ${totalTxt})" + } >>$SUPPORT_LOG + + ohai "Zbieranie logów watchdoga" + + if [[ -f $WATCHDOG_LOG_FILE ]]; then + { + echo "$LOG_DIVIDER" + echo " Watchdog log" + echo "$LOG_DIVIDER" + timeout -k 15 10 cat $WATCHDOG_LOG_FILE + } >>$SUPPORT_LOG + fi + + if [[ -f $WATCHDOG_FAILURES_FILE ]]; then + { + echo "$LOG_DIVIDER" + echo " Watchdog failures log" + echo "$LOG_DIVIDER" + timeout -k 15 10 cat $WATCHDOG_FAILURES_FILE + } >>$SUPPORT_LOG + fi + + ohai "Zbieranie logów usług" + + { + echo "$LOG_DIVIDER" + echo " Nightscout log" + echo "$LOG_DIVIDER" + timeout -k 15 10 docker logs ns-server --tail 500 >>$SUPPORT_LOG 2>&1 + echo "$LOG_DIVIDER" + echo " MongoDB database log" + echo "$LOG_DIVIDER" + timeout -k 15 10 docker logs ns-database --tail 100 >>$SUPPORT_LOG 2>&1 + } >>$SUPPORT_LOG + + ohai "Kompresowanie i szyfrowanie raportu" + + gzip $SUPPORT_LOG + + local logkey=$(<$LOG_ENCRYPTION_KEY_FILE) + + gpg --passphrase "$logkey" --batch --quiet --yes -a -c "$SUPPORT_LOG.gz" + + ohai "Wysyłanie maila" + + { + echo "Ta wiadomość zawiera poufne dane diagnostyczne Twojego serwera Nightscout." + echo "Mogą one pomóc Tobie lub zaufanej osobie w identyfikacji problemu." + echo " " + echo "Prześlij ten mail dalej do zaufanej osoby, umówionej na udzielenie wsparcia." + echo "Przekaż tej osobie w bezpieczny sposób hasło szyfrowania" + echo " (w narzędziu nightscout-tool można je znaleźć w pozycji 'O tym narzędziu...')." + echo "Do przekazania hasła użyj INNEJ metody (komunikator, SMS, osobiście...)." + echo "Nie przesyłaj tej wiadomości do administratorów grupy lub serwera bez wcześniejszego uzgodnienia!" + echo " " + echo "Instrukcje i narzędzie do odszyfrowania logów dostępne pod adresem: https://t1d.dzienia.pl/decoder/" + echo " " + echo " " + cat "$SUPPORT_LOG.gz.asc" + } | pusher "Diagnostyka_serwera_Nightscout_-_$curr_time" + + okdlg "Diagnostyka wysłana" \ + "Sprawdź swoją skrzynkę pocztową,\n" \ + "otrzymanego maila przekaż zaufanemu wspierającemu.\n\n" \ + "Komunikatorem lub SMS przekaż hasło do logów:\n\n$LOG_KEY" + + fi +} + main_menu() { while :; do local ns_tag=$(dotenv-tool -r get -f $ENV_FILE_DEP "NS_NIGHTSCOUT_TAG") local quickStatus=$(center_text "Strona Nightscout: $(get_watchdog_status "$(get_watchdog_status_code_live)" "$uni_ns_ok")" 55) local quickVersion=$(center_text "Wersja: $ns_tag" 55) local quickDomain=$(center_text "Domena: $(get_domain_status 'ns-server')" 55) - local CHOICE=$(whiptail --title "Zarządzanie Nightscoutem :: $SCRIPT_VERSION" --menu "\n$quickStatus\n$quickVersion\n$quickDomain\n" 20 60 9 \ - "1)" "Status kontenerów i logi" \ - "2)" "Pokaż port i API SECRET" \ - "S)" "Aktualizuj system" \ - "N)" "Aktualizuj to narzędzie" \ - "K)" "Aktualizuj kontenery" \ + local CHOICE=$(whiptail --title "Zarządzanie Nightscoutem :: $SCRIPT_VERSION" --menu "\n$quickStatus\n$quickVersion\n$quickDomain\n" 19 60 9 \ + "S)" "Status kontenerów i logi" \ + "P)" "Pokaż port i API SECRET" \ + "U)" "Aktualizuj..." \ + "C)" "Sprztąj..." \ "R)" "Uruchom ponownie kontenery" \ - "Z)" "Zmień lub odinstaluj" \ + "D)" "Wyślij diagnostykę i logi" \ + "Z)" "Zmień lub odinstaluj..." \ "I)" "O tym narzędziu..." \ "X)" "Wyjście" \ --ok-button="$uni_select" --cancel-button="$uni_exit" \ 3>&2 2>&1 1>&3) case $CHOICE in - "1)") + "S)") status_menu ;; - "2)") + "P)") local ns_external_port=$(dotenv-tool -r get -f $ENV_FILE_DEP "NS_PORT") local ns_api_secret=$(dotenv-tool -r get -f $ENV_FILE_NS "API_SECRET") - whiptail --title "Podgląd konfiguracji Nightscout" --msgbox "\n Port usługi Nightscout: $ns_external_port\n API_SECRET: $ns_api_secret" 10 60 + whiptail --title "Podgląd konfiguracji Nightscout" --msgbox \ + "\n Port usługi Nightscout: $ns_external_port\n API_SECRET: $ns_api_secret" \ + 10 60 ;; - "S)") - ohai "Updating package list" - dialog --title " Aktualizacja systemu " --infobox "\n Pobieranie listy pakietów\n ..... Proszę czekać ....." 6 33 - apt-get -yq update >>$LOGTO 2>&1 - ohai "Upgrading system" - dialog --title " Aktualizacja systemu " --infobox "\n Instalowanie pakietów\n ... Proszę czekać ..." 6 33 - apt-get -yq upgrade >>$LOGTO 2>&1 - ;; - "N)") - update_if_needed "Wszystkie pliki narzędzia są aktualne" + "U)") + update_menu ;; - "K)") - docker_compose_down - docker_compose_update + "C)") + cleanup_menu ;; "R)") docker_compose_down docker_compose_up ;; + "D)") + send_diagnostics + ;; "Z)") uninstall_menu ;; @@ -1535,6 +1948,8 @@ setup_done() { install_or_menu() { STATUS_NS=$(get_docker_status "ns-server") + lastTimeSpaceInfo=$(get_space_info) + if [ "$STATUS_NS" = "missing" ]; then if [ "$freshInstall" -eq 0 ]; then @@ -1628,8 +2043,8 @@ watchdog_check() { { echo "----------------------------------------------------------------" echo "[$WATCHDOG_TIME] Unknown server failure:" - echo "CONTAINERS:" - docker stats --no-stream + echo "CONTAINERS:" + docker stats --no-stream echo "HTTP DUMP:" echo "$html" } >>"$WATCHDOG_FAILURES_FILE" @@ -1766,6 +2181,7 @@ check_jq check_ufw check_nano check_dateutils +check_diceware setup_packages setup_node check_dotenv @@ -1773,6 +2189,7 @@ setup_users setup_dir_structure download_conf download_tools +setup_security update_if_needed setup_firewall diff --git a/package.json b/package.json index a5a5ce4..9ef045b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dlvoy/ns-installer-mikrus", - "version": "1.8.1", + "version": "1.9.0", "description": "Nightscout installer for mikr.us VPS", "main": "index.js", "scripts": { diff --git a/src/lib.sh b/src/lib.sh index df3bf21..13b2d64 100644 --- a/src/lib.sh +++ b/src/lib.sh @@ -12,6 +12,7 @@ CONFIG_ROOT_DIR=/srv/nightscout/config ENV_FILE_ADMIN=/srv/nightscout/config/admin.env ENV_FILE_NS=/srv/nightscout/config/nightscout.env ENV_FILE_DEP=/srv/nightscout/config/deployment.env +LOG_ENCRYPTION_KEY_FILE=/srv/nightscout/config/log.key DOCKER_COMPOSE_FILE=/srv/nightscout/config/docker-compose.yml PROFANITY_DB_FILE=/srv/nightscout/data/profanity.db RESERVED_DB_FILE=/srv/nightscout/data/reserved.db @@ -20,14 +21,15 @@ WATCHDOG_TIME_FILE=/srv/nightscout/data/watchdog_time WATCHDOG_LOG_FILE=/srv/nightscout/data/watchdog.log WATCHDOG_FAILURES_FILE=/srv/nightscout/data/watchdog-failures.log WATCHDOG_CRON_LOG=/srv/nightscout/data/watchdog-cron.log +SUPPORT_LOG=/srv/nightscout/data/support.log UPDATE_CHANNEL_FILE=/srv/nightscout/data/update_channel MONGO_DB_DIR=/srv/nightscout/data/mongodb TOOL_FILE=/srv/nightscout/tools/nightscout-tool TOOL_LINK=/usr/bin/nightscout-tool UPDATES_DIR=/srv/nightscout/updates UPDATE_CHANNEL=master -SCRIPT_VERSION="1.8.0" #auto-update -SCRIPT_BUILD_TIME="2024.01.07" #auto-update +SCRIPT_VERSION="1.9.0" #auto-update +SCRIPT_BUILD_TIME="2024.10.06" #auto-update #======================================= # SETUP @@ -110,6 +112,9 @@ tty_red="$(tty_mkbold 31)" tty_bold="$(tty_mkbold 39)" tty_reset="$(tty_escape 0)" +NL="\n" +TL="\n\n" + #======================================= # EMOJIS #======================================= @@ -138,6 +143,7 @@ uni_confirm_upd=" $(printf '\U1F199') Aktualizuj " uni_confirm_ed=" $(printf '\U1F4DD') Edytuj " uni_install=" $(printf '\U1F680') Instaluj " uni_resign=" $(printf '\U1F6AB') Rezygnuję " +uni_send=" $(printf '\U1F4E7') Wyślij " uni_ns_ok="$(printf '\U1F7E2') działa" uni_watchdog_ok="$(printf '\U1F415') Nightscout działa" @@ -280,6 +286,13 @@ center_text() { echo "${spaces:0:$((($2 - len) / 2))}$1" } +rpad_text() { + local inText="$1" + local len=${#inText} + local spaces=" " + echo "$1${spaces:0:$(($2 - len))}" +} + multiline_length() { local string=$1 local maxLen=0 @@ -298,13 +311,16 @@ multiline_length() { center_multiline() { local maxLen=70 + local string="$*" + if [ $# -gt 1 ]; then - maxLen=$2 + maxLen=$1 + shift 1 + string="$*" else - maxLen=$(multiline_length "$1") + maxLen=$(multiline_length "$string") fi - local string=$1 # shellcheck disable=SC2059 readarray -t array <<<"$(printf "$string")" for i in "${!array[@]}"; do @@ -314,18 +330,77 @@ center_multiline() { done } +pad_multiline() { + local string="$*" + local maxLen=$(multiline_length "$string") + + # shellcheck disable=SC2059 + readarray -t array <<<"$(printf "$string")" + for i in "${!array[@]}"; do + local line=${array[i]} + # shellcheck disable=SC2005 + echo "$(rpad_text "$line" "$maxLen")" + done +} + okdlg() { - local msg=$2 - local lcount=$(echo -e "$2" | grep -c '^') + local title=$1 + shift 1 + local msg="$*" + local lcount=$(echo -e "$msg" | grep -c '^') local width=$(multiline_length "$msg") - whiptail --title "$1" --msgbox "$(center_multiline "$msg" $((width + 4)))" $((lcount + 6)) $((width + 9)) + whiptail --title "$title" --msgbox "$(center_multiline $((width + 4)) "$msg")" $((lcount + 6)) $((width + 9)) } confirmdlg() { - local msg=$2 - local lcount=$(echo -e "$2" | grep -c '^') + local title=$1 + local btnlabel=$2 + shift 2 + local msg="$*" + local lcount=$(echo -e "$msg" | grep -c '^') local width=$(multiline_length "$msg") - whiptail --title "$1" --ok-button "$3" --msgbox "$(center_multiline "$msg" $((width + 4)))" $((lcount + 6)) $((width + 9)) + whiptail --title "$title" --ok-button "$btnlabel" --msgbox "$(center_multiline $((width + 4)) "$msg")" $((lcount + 6)) $((width + 9)) +} + +yesnodlg() { + yesnodlg_base "y" "$@" +} + +noyesdlg() { + yesnodlg_base "n" "$@" +} + +yesnodlg_base() { + local defaultbtn=$1 + local title=$2 + local ybtn=$3 + local nbtn=$4 + shift 4 + local msg="$*" + # shellcheck disable=SC2059 + local linec=$(printf "$msg" | grep -c '^') + local width=$(multiline_length "$msg") + local ylen=${#ybtn} + local nlen=${#nbtn} + # we need space for all < > around buttons + local minbtn=$((ylen + nlen + 6)) + # minimal nice width of dialog + local minlen=$((minbtn > 15 ? minbtn : 15)) + local mwidth=$((minlen > width ? minlen : width)) + + # whiptail has bug, buttons are NOT centered + local rpad=$((width < minbtn ? (nlen - 2) + ((nlen - 2) / 2) : 4)) + local padw=$((mwidth + rpad)) + + if [[ "$defaultbtn" == "y" ]]; then + whiptail --title "$title" --yesno "$(center_multiline $padw "$msg")" \ + --yes-button "$ybtn" --no-button "$nbtn" \ + $((linec + 7)) $((padw + 4)) + else + whiptail --title "$title" --yesno --defaultno "$(center_multiline $padw "$msg")" \ + --yes-button "$ybtn" --no-button "$nbtn" \ + $((linec + 7)) $((padw + 4)) + fi } #======================================= @@ -336,6 +411,7 @@ packages=() aptGetWasUpdated=0 freshInstall=0 cachedMenuDomain='' +lastTimeSpaceInfo=0 MIKRUS_APIKEY='' MIKRUS_HOST='' @@ -430,10 +506,28 @@ check_dateutils() { add_if_not_ok "Date Utils" "dateutils" } +check_diceware() { + diceware --version >/dev/null 2>&1 + add_if_not_ok "Secure Password Generator" "diceware" +} + +setup_security() { + if [[ -f $LOG_ENCRYPTION_KEY_FILE ]]; then + msgok "Found log encryption key" + else + ohai "Generating log encryption file..." + diceware -n 5 -d - >$LOG_ENCRYPTION_KEY_FILE + msgcheck "Key generated" + fi +} + setup_packages() { # shellcheck disable=SC2145 # shellcheck disable=SC2068 - (ifIsSet packages && setup_update_repo && ohai "Installing packages: ${packages[@]}" && apt-get -yq install ${packages[@]} >>$LOGTO 2>&1 && msgcheck "Install successfull") || msgok "All required packages already installed" + (ifIsSet packages && setup_update_repo && + ohai "Installing packages: ${packages[@]}" && + apt-get -yq install ${packages[@]} >>$LOGTO 2>&1 && + msgcheck "Install successfull") || msgok "All required packages already installed" } setup_node() { @@ -564,6 +658,10 @@ get_docker_status() { fi } +get_space_info() { + df -B1 --output=target,size,avail,pcent | tail -n +2 | awk '$1 ~ /^\/$/' +} + install_containers() { docker-compose --env-file /srv/nightscout/config/deployment.env -f /srv/nightscout/config/docker-compose.yml up --no-recreate -d >>$LOGTO 2>&1 } @@ -756,23 +854,42 @@ update_if_needed() { } about_dialog() { + LOG_KEY=$(<$LOG_ENCRYPTION_KEY_FILE) okdlg "O tym narzędziu..." \ - "$(printf '\U1F9D1') (c) 2023 Dominik Dzienia\n$(printf '\U1F4E7') dominik.dzienia@gmail.com\n\n$(printf '\U1F3DB') To narzędzie jest dystrybuowane na licencji CC BY-NC-ND 4.0\nhttps://creativecommons.org/licenses/by-nc-nd/4.0/deed.pl\n\nwersja: $SCRIPT_VERSION ($SCRIPT_BUILD_TIME) $UPDATE_CHANNEL" + "$(printf '\U1F9D1') (c) 2023 Dominik Dzienia" \ + "${NL}$(printf '\U1F4E7') dominik.dzienia@gmail.com" \ + "${TL}$(printf '\U1F3DB') To narzędzie jest dystrybuowane na licencji CC BY-NC-ND 4.0" \ + "${NL}htps://creativecommons.org/licenses/by-nc-nd/4.0/deed.pl" \ + "${TL}wersja: $SCRIPT_VERSION ($SCRIPT_BUILD_TIME) $UPDATE_CHANNEL" \ + "${TL}hasło do logów: $LOG_KEY" } prompt_welcome() { - whiptail --title "Witamy" --yesno "$(center_multiline "Ten skrypt zainstaluje Nightscout na bieżącym serwerze mikr.us\n\nJeśli na tym serwerze jest już Nightscout \n- ten skrypt umożliwia jego aktualizację oraz diagnostykę." 65)" --yes-button "$uni_start" --no-button "$uni_exit" 12 70 + yesnodlg "Witamy" "$uni_start" "$uni_exit" \ + "Ten skrypt zainstaluje Nightscout na bieżącym serwerze mikr.us" \ + "${TL}Jeśli na tym serwerze jest już Nightscout " \ + "${NL}- ten skrypt umożliwia jego aktualizację oraz diagnostykę.${TL}" exit_on_no_cancel } - prompt_disclaimer() { confirmdlg "Ostrzeżenie!" \ - "Te narzędzie pozwala TOBIE zainstalować WŁASNĄ instancję Nightscout.\nTy odpowiadasz za ten serwer i ewentualne skutki jego używania.\nTy nim zarządzasz, to nie jest usługa czy produkt.\nTo rozwiązanie \"Zrób to sam\" - SAM za nie odpowiadasz!\n\nAutorzy skryptu nie ponoszą odpowiedzialności za skutki jego użycia!\nNie dajemy żadnych gwarancji co do jego poprawności czy dostępności!\nUżywasz go na własną odpowiedzialność!\nNie opieraj decyzji terapeutycznych na podstawie wskazań tego narzędzia!\n\nTwórcy tego narzędzia NIE SĄ administratorami Mikr.us-ów ani Hetznera!\nW razie problemów z dostępnością serwera najpierw sprawdź status Mikr.us-a!" \ - "Zrozumiano!" + "Zrozumiano!" \ + "Te narzędzie pozwala TOBIE zainstalować WŁASNĄ instancję Nightscout." \ + "${NL}Ty odpowiadasz za ten serwer i ewentualne skutki jego używania." \ + "${NL}Ty nim zarządzasz, to nie jest usługa czy produkt." \ + "${NL}To rozwiązanie \"Zrób to sam\" - SAM za nie odpowiadasz!" \ + "${TL}Autorzy skryptu nie ponoszą odpowiedzialności za skutki jego użycia!" \ + "${NL}Nie dajemy żadnych gwarancji co do jego poprawności czy dostępności!" \ + "${NL}Używasz go na własną odpowiedzialność!" \ + "${NL}Nie opieraj decyzji terapeutycznych na podstawie wskazań tego narzędzia!" \ + "${TL}Twórcy tego narzędzia NIE SĄ administratorami Mikr.us-ów ani Hetznera!" \ + "${NL}W razie problemów z dostępnością serwera najpierw sprawdź status Mikr.us-a!" } instal_now_prompt() { - whiptail --title "Instalować Nightscout?" --yesno "$(center_multiline "Wykryto konfigurację ale brak uruchomionych usług\nCzy chcesz zainstalować teraz kontenery Nightscout?" 65)" --yes-button "$uni_install" --no-button "$uni_noenter" 9 70 + yesnodlg "Instalować Nightscout?" "$uni_install" "$uni_noenter" \ + "Wykryto konfigurację ale brak uruchomionych usług" \ + "${NL}Czy chcesz zainstalować teraz kontenery Nightscout?" } prompt_mikrus_host() { @@ -931,10 +1048,11 @@ domain_setup() { local domain=$(get_td_domain) local domainLen=${#domain} if ((domainLen > 15)); then - msgcheck "Subdomena jest już skonfigurowana ($domain)" okdlg "Subdomena już ustawiona" \ - "Wykryto poprzednio skonfigurowaną subdomenę:\n\n$domain\n\nStrona Nightscout powinna być widoczna z internetu." + "Wykryto poprzednio skonfigurowaną subdomenę:" \ + "${TL}$domain" \ + "${TL}Strona Nightscout powinna być widoczna z internetu." return fi @@ -954,14 +1072,20 @@ domain_setup() { if printf "%s" "$SUBDOMAIN" | grep -f "$PROFANITY_DB_FILE" >>$LOGTO 2>&1; then okdlg "$uni_excl Nieprawidłowa subdomena $uni_excl" \ - "Podana wartość:\n$SUBDOMAIN\n\njest zajęta, zarezerwowana lub niedopuszczalna.\n\nWymyśl coś innego" + "Podana wartość:" \ + "${NL}$SUBDOMAIN" \ + "${TL}jest zajęta, zarezerwowana lub niedopuszczalna." \ + "${TL}Wymyśl coś innego" SUBDOMAIN='' continue fi if printf "%s" "$SUBDOMAIN" | grep -xf "$RESERVED_DB_FILE" >>$LOGTO 2>&1; then okdlg "$uni_excl Nieprawidłowa subdomena $uni_excl" \ - "Podana wartość:\n$SUBDOMAIN\n\njest zajęta lub zarezerwowana.\n\nWymyśl coś innego" + "Podana wartość:" \ + "${NL}$SUBDOMAIN" \ + "${TL}jest zajęta lub zarezerwowana." \ + "${TL}Wymyśl coś innego" SUBDOMAIN='' continue fi @@ -970,7 +1094,9 @@ domain_setup() { else okdlg "$uni_excl Nieprawidłowy początek subdomeny $uni_excl" \ - "Podany początek subdomeny:\n$SUBDOMAIN\n\nma nieprawidłowy format. Wymyśl coś innego" + "Podany początek subdomeny:" \ + "${NL}$SUBDOMAIN" \ + "${TL}ma nieprawidłowy format. Wymyśl coś innego" if [ $? -eq 1 ]; then SUBDOMAIN='' continue @@ -1011,7 +1137,12 @@ domain_setup() { } admin_panel_promo() { - whiptail --title "Panel zarządzania Mikr.us-em" --msgbox "$(center_multiline "Ta instalacja Nightscout dodaje dodatkowy panel administracyjny\ndo zarządzania serwerem i konfiguracją - online.\n\nZnajdziesz go klikając na ikonkę serwera w menu strony Nightscout\nlub dodając /mikrus na końcu swojego adresu Nightscout" 70)" 12 75 + whiptail --title "Panel zarządzania Mikr.us-em" --msgbox "$(center_multiline 70 \ + "Ta instalacja Nightscout dodaje dodatkowy panel administracyjny" \ + "${NL}do zarządzania serwerem i konfiguracją - online." \ + "${TL}Znajdziesz go klikając na ikonkę serwera w menu strony Nightscout" \ + "${NL}lub dodając /mikrus na końcu swojego adresu Nightscout")" \ + 12 75 } get_watchdog_age_string() { @@ -1225,7 +1356,7 @@ get_container_status_code() { show_logs() { local col=$((COLUMNS - 10)) - local rws=$((LINES - 3)) + local rws=$((LINES - 4)) if [ $col -gt 120 ]; then col=160 fi @@ -1333,7 +1464,13 @@ version_menu() { ohai "Changing Nightscout container tag from: $ns_tag to: $CHOICE" dotenv-tool -pmr -i $ENV_FILE_DEP -- "NS_NIGHTSCOUT_TAG=$CHOICE" docker_compose_update - whiptail --title "Zmieniono wersję Nightscout" --msgbox "$(center_multiline "Zmieniono wersję Nightscout na: $CHOICE\n\nSprawdź czy Nightscout działa poprawnie, w razie problemów:\n${uni_bullet}aktualizuj kontenery\n${uni_bullet}spróbuj wyczyścić bazę danych\n${uni_bullet}wróć do poprzedniej wersji ($ns_tag)" 65)" 13 70 + whiptail --title "Zmieniono wersję Nightscout" --msgbox "$(center_multiline 65 \ + "Zmieniono wersję Nightscout na: $CHOICE" \ + "${TL}Sprawdź czy Nightscout działa poprawnie, w razie problemów:" \ + "${NL}${uni_bullet}aktualizuj kontenery" \ + "${NL}${uni_bullet}spróbuj wyczyścić bazę danych" \ + "${NL}${uni_bullet}wróć do poprzedniej wersji ($ns_tag)")" \ + 13 70 break fi @@ -1342,6 +1479,144 @@ version_menu() { done } +do_cleanup_sys() { + ohai "Sprzątanie dziennik systemowego..." + journalctl --vacuum-size=50M >>$LOGTO 2>&1 + ohai "Czyszczenie systemu apt..." + apt autoremove >>$LOGTO 2>&1 +} + +do_cleanup_docker() { + ohai "Usuwanie nieużywanych obrazów Dockera..." + docker image prune -af >>$LOGTO 2>&1 +} + +do_cleanup_db() { + ohai "Usuwanie kopii zapasowych bazy danych..." + rm -f "/srv/nightscout/data/dbbackup/*" >>$LOGTO 2>&1 +} + +cleanup_menu() { + + while :; do + + local spaceInfo=$(get_space_info) + local remainingTxt=$(echo "$spaceInfo" | awk '{print $3}' | numfmt --to iec-i --suffix=B) + local totalTxt=$(echo "$spaceInfo" | awk '{print $2}' | numfmt --to iec-i --suffix=B) + local percTxt=$(echo "$spaceInfo" | awk '{print $4}') + local fixedPerc=${percTxt/[%]/=} + + local nowB=$(echo "$spaceInfo" | awk '{print $3}') + local lastTimeB=$(echo "$lastTimeSpaceInfo" | awk '{print $3}') + local savedB=$((nowB - lastTimeB)) + local savedTxt=$(echo "$savedB" | numfmt --to iec-i --suffix=B) + + if (( savedB < 1)); then + savedTxt="---" + fi + + local statusTitle="\n$(center_multiline 45 "$( + pad_multiline \ + " Dostępne: ${remainingTxt}" \ + "\n Zwolniono: ${savedTxt}" \ + "\n Zajęte: ${fixedPerc} (z ${totalTxt})" + )")\n" + + local CHOICE=$(whiptail --title "Sprzątanie" --menu \ + "${statusTitle/=/%}" \ + 16 50 5 \ + "A)" "Posprzątaj wszystko" \ + "S)" "Posprzątaj zasoby systemowe" \ + "D)" "Usuń nieużywane obrazy Dockera" \ + "B)" "Usuń kopie zapasowe bazy danych" \ + "M)" "Powrót do menu" \ + --ok-button="Wybierz" --cancel-button="$uni_back" \ + 3>&2 2>&1 1>&3) + + case $CHOICE in + "A)") + noyesdlg "Posprzątać wszystko?" "$uni_confirm_del" "$uni_resign" \ + "Czy chcesz posprzątać i usunąć:" \ + "$( + pad_multiline \ + "${NL}${uni_bullet}nieużywane pliki apt i dziennika" \ + "${NL}${uni_bullet}nieużywane obrazy Dockera" \ + "${NL}${uni_bullet}kopie zapasowe bazy danych" + )" + if ! [ $? -eq 1 ]; then + do_cleanup_sys + do_cleanup_docker + do_cleanup_db + fi + ;; + "S)") + noyesdlg "Posprzątać zasoby systemowe?" "$uni_confirm_del" "$uni_resign" \ + "Czy chcesz usunąć nieużywane pakiety apt i poprzątać dziennik systemowy?" + if ! [ $? -eq 1 ]; then + do_cleanup_sys + fi + ;; + "D)") + noyesdlg "Posprzątać obrazy Dockera?" "$uni_confirm_del" "$uni_resign" \ + "Czy chcesz usunąć nieużywane obrazy Dockera?" + if ! [ $? -eq 1 ]; then + do_cleanup_docker + fi + ;; + "B)") + noyesdlg "Usunąć kopie zapasowe bazy danych?" "$uni_confirm_del" "$uni_resign" \ + "Czy chcesz usunąć kopie zapasowe bazy danych?" \ + "${NL}(na razie i tak nie ma automatycznego mechanizmu ich wykorzystania)" + if ! [ $? -eq 1 ]; then + do_cleanup_db + fi + ;; + "M)") + break + ;; + "") + break + ;; + esac + done +} + +update_menu() { + while :; do + local CHOICE=$(whiptail --title "Aktualizuj" --menu "\n" 11 40 4 \ + "S)" "Aktualizuj system" \ + "N)" "Aktualizuj to narzędzie" \ + "K)" "Aktualizuj kontenery" \ + "M)" "Powrót do menu" \ + --ok-button="$uni_select" --cancel-button="$uni_back" \ + 3>&2 2>&1 1>&3) + + case $CHOICE in + "S)") + ohai "Updating package list" + dialog --title " Aktualizacja systemu " --infobox "\n Pobieranie listy pakietów\n ..... Proszę czekać ....." 6 33 + apt-get -yq update >>$LOGTO 2>&1 + ohai "Upgrading system" + dialog --title " Aktualizacja systemu " --infobox "\n Instalowanie pakietów\n ... Proszę czekać ..." 6 33 + apt-get -yq upgrade >>$LOGTO 2>&1 + ;; + "N)") + update_if_needed "Wszystkie pliki narzędzia są aktualne" + ;; + "K)") + docker_compose_down + docker_compose_update + ;; + "M)") + break + ;; + "") + break + ;; + esac + done +} + uninstall_menu() { while :; do local extraMenu=() @@ -1370,7 +1645,8 @@ uninstall_menu() { if ! [[ "$0" =~ .*"/usr/bin/nightscout-tool" ]]; then okdlg "Opcja niedostępna" \ - "Edytor ustawień dostępny po uruchomieniu narzędzia komendą:\n\nnightscout-tool" + "Edytor ustawień dostępny po uruchomieniu narzędzia komendą:" \ + "${TL}nightscout-tool" else whiptail --title "Edycja ustawień Nightscout" --yesno "Za chwilę otworzę plik konfiguracji Nightscout w edytorze NANO\n\nWskazówki co do obsługi edytora:\n${uni_bullet}Aby ZAPISAĆ zmiany naciśnij Ctrl+O\n${uni_bullet}Aby ZAKOŃCZYĆ edycję naciśnij Ctrl+X\n\n $(printf "\U26A0") Edycja spowoduje też restart i aktualizację kontenerów $(printf "\U26A0")" --yes-button "$uni_confirm_ed" --no-button "$uni_resign" 15 68 if ! [ $? -eq 1 ]; then @@ -1403,7 +1679,11 @@ uninstall_menu() { rm -r "${MONGO_DB_DIR:?}/data" dialog --title " Czyszczenie konfiguracji" --infobox "\n Usuwanie konfiguracji\n ... Proszę czekać ..." 6 32 rm -r "${CONFIG_ROOT_DIR:?}" - whiptail --title "Usunięto dane użytkownika" --msgbox "$(center_multiline "Usunęto dane użytkwnika i konfigurację.\n\nAby zainstalować Nightscout od zera:\nuruchom ponownie skrypt i podaj konfigurację" 65)" 11 70 + whiptail --title "Usunięto dane użytkownika" --msgbox "$(center_multiline 65 \ + "Usunęto dane użytkwnika i konfigurację." \ + "${TL}Aby zainstalować Nightscout od zera:" \ + "${NL}uruchom ponownie skrypt i podaj konfigurację")" \ + 11 70 exit 0 fi ;; @@ -1418,7 +1698,12 @@ uninstall_menu() { rm "$TOOL_LINK" rm -r "${NIGHTSCOUT_ROOT_DIR:?}/tools" rm -r "${NIGHTSCOUT_ROOT_DIR:?}/updates" - whiptail --title "Odinstalowano" --msgbox "$(center_multiline "Odinstalowano Nightscout z Mikr.us-a\n\nAby ponownie zainstalować, postępuj według instrukcji na stronie:\nhttps://t1d.dzienia.pl/mikrus\n\nDziękujemy i do zobaczenia!" 65)" 13 70 + whiptail --title "Odinstalowano" --msgbox "$(center_multiline 65 \ + "Odinstalowano Nightscout z Mikr.us-a" \ + "${TL}Aby ponownie zainstalować, postępuj według instrukcji na stronie:" \ + "${NL}https://t1d.dzienia.pl/mikrus" \ + "${TL}Dziękujemy i do zobaczenia!")" \ + 13 70 exit 0 fi ;; @@ -1448,53 +1733,181 @@ get_domain_status() { fi } +send_diagnostics() { + LOG_KEY=$(<$LOG_ENCRYPTION_KEY_FILE) + + yesnodlg "Wysyłać diagnostykę?" \ + "$uni_send" "$uni_resign" \ + "Czy chcesz zgromadzić i wysłać sobie mailem dane diagnostyczne?" \ + "\n$( + pad_multiline \ + "\n${uni_bullet}diagnostyka zawiera logi i informacje o serwerze i usługach" \ + "\n${uni_bullet}wysyłka na e-mail na który zamówiono serwer Mikr.us" \ + "\n${uni_bullet}dane będą skompresowane i zaszyfrowane" \ + "\n${uni_bullet}maila prześlij dalej do zaufanej osoby wspierającej" \ + "\n${uni_bullet_pad}(z którą to wcześniej zaplanowano i uzgodniono!!!)" \ + "\n${uni_bullet}hasło przekaż INNĄ DROGĄ (komunikatorem, SMSem, osobiście)" \ + "\n\n${uni_bullet_pad}Hasło do logów: $LOG_KEY" + )" + + if ! [ $? -eq 1 ]; then + + ohai "Zbieranie diagnostyki" + + local domain=$(get_td_domain) + local curr_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ") + local ns_tag=$(dotenv-tool -r get -f $ENV_FILE_DEP "NS_NIGHTSCOUT_TAG") + local mikrus_h=$(hostname) + + local LOG_DIVIDER="=======================================================" + + rm -f $SUPPORT_LOG + rm -f "$SUPPORT_LOG.gz" + rm -f "$SUPPORT_LOG.gz.asc" + + { + echo "Dane diagnostyczne zebrane $curr_time" + echo " serwer : $mikrus_h" + echo " domena : $domain" + echo " wersja NS : $ns_tag" + } >$SUPPORT_LOG + + ohai "Zbieranie statusu usług" + + { + echo "$LOG_DIVIDER" + echo " Statusy usług" + echo "$LOG_DIVIDER" + echo " Nightscout: $(get_container_status 'ns-server')" + echo " Baza danych: $(get_container_status 'ns-database')" + echo " Backup: $(get_container_status 'ns-backup')" + echo " Watchdog: $(get_watchdog_status "$(get_watchdog_status_code)" "$uni_watchdog_ok")" + } >>$SUPPORT_LOG + + ohai "Zbieranie informacji o zasobach" + local spaceInfo=$(get_space_info) + local remainingTxt=$(echo "$spaceInfo" | awk '{print $3}' | numfmt --to iec-i --suffix=B) + local totalTxt=$(echo "$spaceInfo" | awk '{print $2}' | numfmt --to iec-i --suffix=B) + local percTxt=$(echo "$spaceInfo" | awk '{print $4}') + + { + echo "$LOG_DIVIDER" + echo " Miejsce na dysku" + echo "$LOG_DIVIDER" + echo " Dostępne: ${remainingTxt}" + echo " Zajęte: ${percTxt} (z ${totalTxt})" + } >>$SUPPORT_LOG + + ohai "Zbieranie logów watchdoga" + + if [[ -f $WATCHDOG_LOG_FILE ]]; then + { + echo "$LOG_DIVIDER" + echo " Watchdog log" + echo "$LOG_DIVIDER" + timeout -k 15 10 cat $WATCHDOG_LOG_FILE + } >>$SUPPORT_LOG + fi + + if [[ -f $WATCHDOG_FAILURES_FILE ]]; then + { + echo "$LOG_DIVIDER" + echo " Watchdog failures log" + echo "$LOG_DIVIDER" + timeout -k 15 10 cat $WATCHDOG_FAILURES_FILE + } >>$SUPPORT_LOG + fi + + ohai "Zbieranie logów usług" + + { + echo "$LOG_DIVIDER" + echo " Nightscout log" + echo "$LOG_DIVIDER" + timeout -k 15 10 docker logs ns-server --tail 500 >>$SUPPORT_LOG 2>&1 + echo "$LOG_DIVIDER" + echo " MongoDB database log" + echo "$LOG_DIVIDER" + timeout -k 15 10 docker logs ns-database --tail 100 >>$SUPPORT_LOG 2>&1 + } >>$SUPPORT_LOG + + ohai "Kompresowanie i szyfrowanie raportu" + + gzip $SUPPORT_LOG + + local logkey=$(<$LOG_ENCRYPTION_KEY_FILE) + + gpg --passphrase "$logkey" --batch --quiet --yes -a -c "$SUPPORT_LOG.gz" + + ohai "Wysyłanie maila" + + { + echo "Ta wiadomość zawiera poufne dane diagnostyczne Twojego serwera Nightscout." + echo "Mogą one pomóc Tobie lub zaufanej osobie w identyfikacji problemu." + echo " " + echo "Prześlij ten mail dalej do zaufanej osoby, umówionej na udzielenie wsparcia." + echo "Przekaż tej osobie w bezpieczny sposób hasło szyfrowania" + echo " (w narzędziu nightscout-tool można je znaleźć w pozycji 'O tym narzędziu...')." + echo "Do przekazania hasła użyj INNEJ metody (komunikator, SMS, osobiście...)." + echo "Nie przesyłaj tej wiadomości do administratorów grupy lub serwera bez wcześniejszego uzgodnienia!" + echo " " + echo "Instrukcje i narzędzie do odszyfrowania logów dostępne pod adresem: https://t1d.dzienia.pl/decoder/" + echo " " + echo " " + cat "$SUPPORT_LOG.gz.asc" + } | pusher "Diagnostyka_serwera_Nightscout_-_$curr_time" + + okdlg "Diagnostyka wysłana" \ + "Sprawdź swoją skrzynkę pocztową,\n" \ + "otrzymanego maila przekaż zaufanemu wspierającemu.\n\n" \ + "Komunikatorem lub SMS przekaż hasło do logów:\n\n$LOG_KEY" + + fi +} + main_menu() { while :; do local ns_tag=$(dotenv-tool -r get -f $ENV_FILE_DEP "NS_NIGHTSCOUT_TAG") local quickStatus=$(center_text "Strona Nightscout: $(get_watchdog_status "$(get_watchdog_status_code_live)" "$uni_ns_ok")" 55) local quickVersion=$(center_text "Wersja: $ns_tag" 55) local quickDomain=$(center_text "Domena: $(get_domain_status 'ns-server')" 55) - local CHOICE=$(whiptail --title "Zarządzanie Nightscoutem :: $SCRIPT_VERSION" --menu "\n$quickStatus\n$quickVersion\n$quickDomain\n" 20 60 9 \ - "1)" "Status kontenerów i logi" \ - "2)" "Pokaż port i API SECRET" \ - "S)" "Aktualizuj system" \ - "N)" "Aktualizuj to narzędzie" \ - "K)" "Aktualizuj kontenery" \ + local CHOICE=$(whiptail --title "Zarządzanie Nightscoutem :: $SCRIPT_VERSION" --menu "\n$quickStatus\n$quickVersion\n$quickDomain\n" 19 60 9 \ + "S)" "Status kontenerów i logi" \ + "P)" "Pokaż port i API SECRET" \ + "U)" "Aktualizuj..." \ + "C)" "Sprztąj..." \ "R)" "Uruchom ponownie kontenery" \ - "Z)" "Zmień lub odinstaluj" \ + "D)" "Wyślij diagnostykę i logi" \ + "Z)" "Zmień lub odinstaluj..." \ "I)" "O tym narzędziu..." \ "X)" "Wyjście" \ --ok-button="$uni_select" --cancel-button="$uni_exit" \ 3>&2 2>&1 1>&3) case $CHOICE in - "1)") + "S)") status_menu ;; - "2)") + "P)") local ns_external_port=$(dotenv-tool -r get -f $ENV_FILE_DEP "NS_PORT") local ns_api_secret=$(dotenv-tool -r get -f $ENV_FILE_NS "API_SECRET") - whiptail --title "Podgląd konfiguracji Nightscout" --msgbox "\n Port usługi Nightscout: $ns_external_port\n API_SECRET: $ns_api_secret" 10 60 + whiptail --title "Podgląd konfiguracji Nightscout" --msgbox \ + "\n Port usługi Nightscout: $ns_external_port\n API_SECRET: $ns_api_secret" \ + 10 60 ;; - "S)") - ohai "Updating package list" - dialog --title " Aktualizacja systemu " --infobox "\n Pobieranie listy pakietów\n ..... Proszę czekać ....." 6 33 - apt-get -yq update >>$LOGTO 2>&1 - ohai "Upgrading system" - dialog --title " Aktualizacja systemu " --infobox "\n Instalowanie pakietów\n ... Proszę czekać ..." 6 33 - apt-get -yq upgrade >>$LOGTO 2>&1 - ;; - "N)") - update_if_needed "Wszystkie pliki narzędzia są aktualne" + "U)") + update_menu ;; - "K)") - docker_compose_down - docker_compose_update + "C)") + cleanup_menu ;; "R)") docker_compose_down docker_compose_up ;; + "D)") + send_diagnostics + ;; "Z)") uninstall_menu ;; @@ -1519,6 +1932,8 @@ setup_done() { install_or_menu() { STATUS_NS=$(get_docker_status "ns-server") + lastTimeSpaceInfo=$(get_space_info) + if [ "$STATUS_NS" = "missing" ]; then if [ "$freshInstall" -eq 0 ]; then @@ -1612,8 +2027,8 @@ watchdog_check() { { echo "----------------------------------------------------------------" echo "[$WATCHDOG_TIME] Unknown server failure:" - echo "CONTAINERS:" - docker stats --no-stream + echo "CONTAINERS:" + docker stats --no-stream echo "HTTP DUMP:" echo "$html" } >>"$WATCHDOG_FAILURES_FILE" diff --git a/src/setup.sh b/src/setup.sh index 1574b02..6c72582 100755 --- a/src/setup.sh +++ b/src/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash -### version: 1.8.1 +### version: 1.9.0 # ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.# # Nightscout Mikr.us setup script # @@ -36,6 +36,7 @@ check_jq check_ufw check_nano check_dateutils +check_diceware setup_packages setup_node check_dotenv @@ -43,6 +44,7 @@ setup_users setup_dir_structure download_conf download_tools +setup_security update_if_needed setup_firewall diff --git a/updated b/updated index 32fb888..ea1a940 100644 --- a/updated +++ b/updated @@ -1 +1 @@ -2024-01-20T18:24:52.704Z \ No newline at end of file +2024-10-05T23:10:49.329Z \ No newline at end of file -- 2.38.5 From 9eae37ecfafb423bb6e8ccae873b262b7da28a32 Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Sun, 6 Oct 2024 07:02:45 +0000 Subject: [PATCH 06/14] Fixed cleanup --- install.sh | 19 +++++++++++++------ src/lib.sh | 17 ++++++++++++----- updated | 2 +- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/install.sh b/install.sh index 9b160c4..19423b4 100644 --- a/install.sh +++ b/install.sh @@ -45,7 +45,7 @@ TOOL_LINK=/usr/bin/nightscout-tool UPDATES_DIR=/srv/nightscout/updates UPDATE_CHANNEL=master SCRIPT_VERSION="1.9.0" #auto-update -SCRIPT_BUILD_TIME="2024.10.05" #auto-update +SCRIPT_BUILD_TIME="2024.10.06" #auto-update #======================================= # SETUP @@ -1499,17 +1499,22 @@ do_cleanup_sys() { ohai "Sprzątanie dziennik systemowego..." journalctl --vacuum-size=50M >>$LOGTO 2>&1 ohai "Czyszczenie systemu apt..." - apt autoremove >>$LOGTO 2>&1 + msgnote "Ta operacja może TROCHĘ potrwać (od kilku do kilkudziesięciu minut...)" + apt-get -y autoremove >>$LOGTO 2>&1 && apt-get -y clean >>$LOGTO 2>&1 + msgcheck "Czyszczenie dziennika i apt zakończono" } do_cleanup_docker() { ohai "Usuwanie nieużywanych obrazów Dockera..." + msgnote "Ta operacja może TROCHĘ potrwać (do kilku minut...)" docker image prune -af >>$LOGTO 2>&1 + msgcheck "Czyszczenie Dockera zakończono" } do_cleanup_db() { ohai "Usuwanie kopii zapasowych bazy danych..." - rm -f "/srv/nightscout/data/dbbackup/*" >>$LOGTO 2>&1 + find /srv/nightscout/data/dbbackup ! -type d -delete + msgcheck "Czyszczenie kopii zapasowych zakończono" } cleanup_menu() { @@ -1558,7 +1563,7 @@ cleanup_menu() { "${NL}${uni_bullet}nieużywane pliki apt i dziennika" \ "${NL}${uni_bullet}nieużywane obrazy Dockera" \ "${NL}${uni_bullet}kopie zapasowe bazy danych" - )" + )":w if ! [ $? -eq 1 ]; then do_cleanup_sys do_cleanup_docker @@ -1567,14 +1572,16 @@ cleanup_menu() { ;; "S)") noyesdlg "Posprzątać zasoby systemowe?" "$uni_confirm_del" "$uni_resign" \ - "Czy chcesz usunąć nieużywane pakiety apt i poprzątać dziennik systemowy?" + "Czy chcesz usunąć nieużywane pakiety apt i poprzątać dziennik systemowy?" \ + "${TL}(ta operacja może potrwać od kilku do kilkudziesięciu minut)" if ! [ $? -eq 1 ]; then do_cleanup_sys fi ;; "D)") noyesdlg "Posprzątać obrazy Dockera?" "$uni_confirm_del" "$uni_resign" \ - "Czy chcesz usunąć nieużywane obrazy Dockera?" + "Czy chcesz usunąć nieużywane obrazy Dockera?" \ + "${TL}(ta operacja może potrwać kilka minut)" if ! [ $? -eq 1 ]; then do_cleanup_docker fi diff --git a/src/lib.sh b/src/lib.sh index 13b2d64..33967ba 100644 --- a/src/lib.sh +++ b/src/lib.sh @@ -1483,17 +1483,22 @@ do_cleanup_sys() { ohai "Sprzątanie dziennik systemowego..." journalctl --vacuum-size=50M >>$LOGTO 2>&1 ohai "Czyszczenie systemu apt..." - apt autoremove >>$LOGTO 2>&1 + msgnote "Ta operacja może TROCHĘ potrwać (od kilku do kilkudziesięciu minut...)" + apt-get -y autoremove >>$LOGTO 2>&1 && apt-get -y clean >>$LOGTO 2>&1 + msgcheck "Czyszczenie dziennika i apt zakończono" } do_cleanup_docker() { ohai "Usuwanie nieużywanych obrazów Dockera..." + msgnote "Ta operacja może TROCHĘ potrwać (do kilku minut...)" docker image prune -af >>$LOGTO 2>&1 + msgcheck "Czyszczenie Dockera zakończono" } do_cleanup_db() { ohai "Usuwanie kopii zapasowych bazy danych..." - rm -f "/srv/nightscout/data/dbbackup/*" >>$LOGTO 2>&1 + find /srv/nightscout/data/dbbackup ! -type d -delete + msgcheck "Czyszczenie kopii zapasowych zakończono" } cleanup_menu() { @@ -1542,7 +1547,7 @@ cleanup_menu() { "${NL}${uni_bullet}nieużywane pliki apt i dziennika" \ "${NL}${uni_bullet}nieużywane obrazy Dockera" \ "${NL}${uni_bullet}kopie zapasowe bazy danych" - )" + )":w if ! [ $? -eq 1 ]; then do_cleanup_sys do_cleanup_docker @@ -1551,14 +1556,16 @@ cleanup_menu() { ;; "S)") noyesdlg "Posprzątać zasoby systemowe?" "$uni_confirm_del" "$uni_resign" \ - "Czy chcesz usunąć nieużywane pakiety apt i poprzątać dziennik systemowy?" + "Czy chcesz usunąć nieużywane pakiety apt i poprzątać dziennik systemowy?" \ + "${TL}(ta operacja może potrwać od kilku do kilkudziesięciu minut)" if ! [ $? -eq 1 ]; then do_cleanup_sys fi ;; "D)") noyesdlg "Posprzątać obrazy Dockera?" "$uni_confirm_del" "$uni_resign" \ - "Czy chcesz usunąć nieużywane obrazy Dockera?" + "Czy chcesz usunąć nieużywane obrazy Dockera?" \ + "${TL}(ta operacja może potrwać kilka minut)" if ! [ $? -eq 1 ]; then do_cleanup_docker fi diff --git a/updated b/updated index ea1a940..757b6f5 100644 --- a/updated +++ b/updated @@ -1 +1 @@ -2024-10-05T23:10:49.329Z \ No newline at end of file +2024-10-06T07:01:18.222Z \ No newline at end of file -- 2.38.5 From 5734af5092b474cf2aefdc8de2ebc91427a7a8c0 Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Sun, 6 Oct 2024 07:13:41 +0000 Subject: [PATCH 07/14] Long operation warning added --- install.sh | 7 +++---- src/lib.sh | 7 +++---- updated | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/install.sh b/install.sh index 19423b4..90d4e09 100644 --- a/install.sh +++ b/install.sh @@ -1558,12 +1558,11 @@ cleanup_menu() { "A)") noyesdlg "Posprzątać wszystko?" "$uni_confirm_del" "$uni_resign" \ "Czy chcesz posprzątać i usunąć:" \ - "$( - pad_multiline \ + "$(pad_multiline \ "${NL}${uni_bullet}nieużywane pliki apt i dziennika" \ "${NL}${uni_bullet}nieużywane obrazy Dockera" \ - "${NL}${uni_bullet}kopie zapasowe bazy danych" - )":w + "${NL} ${uni_bullet}kopie zapasowe bazy danych")" \ + "${TL}(ta operacja może potrwać od kilku do kilkudziesięciu minut)" if ! [ $? -eq 1 ]; then do_cleanup_sys do_cleanup_docker diff --git a/src/lib.sh b/src/lib.sh index 33967ba..64ba934 100644 --- a/src/lib.sh +++ b/src/lib.sh @@ -1542,12 +1542,11 @@ cleanup_menu() { "A)") noyesdlg "Posprzątać wszystko?" "$uni_confirm_del" "$uni_resign" \ "Czy chcesz posprzątać i usunąć:" \ - "$( - pad_multiline \ + "$(pad_multiline \ "${NL}${uni_bullet}nieużywane pliki apt i dziennika" \ "${NL}${uni_bullet}nieużywane obrazy Dockera" \ - "${NL}${uni_bullet}kopie zapasowe bazy danych" - )":w + "${NL} ${uni_bullet}kopie zapasowe bazy danych")" \ + "${TL}(ta operacja może potrwać od kilku do kilkudziesięciu minut)" if ! [ $? -eq 1 ]; then do_cleanup_sys do_cleanup_docker diff --git a/updated b/updated index 757b6f5..e4f1eb4 100644 --- a/updated +++ b/updated @@ -1 +1 @@ -2024-10-06T07:01:18.222Z \ No newline at end of file +2024-10-06T07:12:57.316Z \ No newline at end of file -- 2.38.5 From 9e6cb0a281964c151244b1e983c9f176b81d0a5f Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Sun, 6 Oct 2024 08:08:09 +0000 Subject: [PATCH 08/14] Add size checking and retry for diagnostics --- install.sh | 248 ++++++++++++++++++++++++++++++++--------------------- src/lib.sh | 248 ++++++++++++++++++++++++++++++++--------------------- updated | 2 +- 3 files changed, 297 insertions(+), 201 deletions(-) diff --git a/install.sh b/install.sh index 90d4e09..5c97c3b 100644 --- a/install.sh +++ b/install.sh @@ -428,6 +428,7 @@ aptGetWasUpdated=0 freshInstall=0 cachedMenuDomain='' lastTimeSpaceInfo=0 +diagnosticsSizeOk=0 MIKRUS_APIKEY='' MIKRUS_HOST='' @@ -1499,22 +1500,22 @@ do_cleanup_sys() { ohai "Sprzątanie dziennik systemowego..." journalctl --vacuum-size=50M >>$LOGTO 2>&1 ohai "Czyszczenie systemu apt..." - msgnote "Ta operacja może TROCHĘ potrwać (od kilku do kilkudziesięciu minut...)" - apt-get -y autoremove >>$LOGTO 2>&1 && apt-get -y clean >>$LOGTO 2>&1 - msgcheck "Czyszczenie dziennika i apt zakończono" + msgnote "Ta operacja może TROCHĘ potrwać (od kilku do kilkudziesięciu minut...)" + apt-get -y autoremove >>$LOGTO 2>&1 && apt-get -y clean >>$LOGTO 2>&1 + msgcheck "Czyszczenie dziennika i apt zakończono" } do_cleanup_docker() { ohai "Usuwanie nieużywanych obrazów Dockera..." - msgnote "Ta operacja może TROCHĘ potrwać (do kilku minut...)" + msgnote "Ta operacja może TROCHĘ potrwać (do kilku minut...)" docker image prune -af >>$LOGTO 2>&1 - msgcheck "Czyszczenie Dockera zakończono" + msgcheck "Czyszczenie Dockera zakończono" } do_cleanup_db() { ohai "Usuwanie kopii zapasowych bazy danych..." - find /srv/nightscout/data/dbbackup ! -type d -delete - msgcheck "Czyszczenie kopii zapasowych zakończono" + find /srv/nightscout/data/dbbackup ! -type d -delete + msgcheck "Czyszczenie kopii zapasowych zakończono" } cleanup_menu() { @@ -1532,7 +1533,7 @@ cleanup_menu() { local savedB=$((nowB - lastTimeB)) local savedTxt=$(echo "$savedB" | numfmt --to iec-i --suffix=B) - if (( savedB < 1)); then + if ((savedB < 1)); then savedTxt="---" fi @@ -1559,10 +1560,10 @@ cleanup_menu() { noyesdlg "Posprzątać wszystko?" "$uni_confirm_del" "$uni_resign" \ "Czy chcesz posprzątać i usunąć:" \ "$(pad_multiline \ - "${NL}${uni_bullet}nieużywane pliki apt i dziennika" \ - "${NL}${uni_bullet}nieużywane obrazy Dockera" \ - "${NL} ${uni_bullet}kopie zapasowe bazy danych")" \ - "${TL}(ta operacja może potrwać od kilku do kilkudziesięciu minut)" + "${NL}${uni_bullet}nieużywane pliki apt i dziennika" \ + "${NL}${uni_bullet}nieużywane obrazy Dockera" \ + "${NL} ${uni_bullet}kopie zapasowe bazy danych")" \ + "${TL}(ta operacja może potrwać od kilku do kilkudziesięciu minut)" if ! [ $? -eq 1 ]; then do_cleanup_sys do_cleanup_docker @@ -1572,7 +1573,7 @@ cleanup_menu() { "S)") noyesdlg "Posprzątać zasoby systemowe?" "$uni_confirm_del" "$uni_resign" \ "Czy chcesz usunąć nieużywane pakiety apt i poprzątać dziennik systemowy?" \ - "${TL}(ta operacja może potrwać od kilku do kilkudziesięciu minut)" + "${TL}(ta operacja może potrwać od kilku do kilkudziesięciu minut)" if ! [ $? -eq 1 ]; then do_cleanup_sys fi @@ -1580,7 +1581,7 @@ cleanup_menu() { "D)") noyesdlg "Posprzątać obrazy Dockera?" "$uni_confirm_del" "$uni_resign" \ "Czy chcesz usunąć nieużywane obrazy Dockera?" \ - "${TL}(ta operacja może potrwać kilka minut)" + "${TL}(ta operacja może potrwać kilka minut)" if ! [ $? -eq 1 ]; then do_cleanup_docker fi @@ -1606,8 +1607,8 @@ cleanup_menu() { update_menu() { while :; do local CHOICE=$(whiptail --title "Aktualizuj" --menu "\n" 11 40 4 \ - "S)" "Aktualizuj system" \ "N)" "Aktualizuj to narzędzie" \ + "S)" "Aktualizuj system" \ "K)" "Aktualizuj kontenery" \ "M)" "Powrót do menu" \ --ok-button="$uni_select" --cancel-button="$uni_back" \ @@ -1755,115 +1756,153 @@ get_domain_status() { fi } -send_diagnostics() { - LOG_KEY=$(<$LOG_ENCRYPTION_KEY_FILE) +gather_diagnostics() { - yesnodlg "Wysyłać diagnostykę?" \ - "$uni_send" "$uni_resign" \ - "Czy chcesz zgromadzić i wysłać sobie mailem dane diagnostyczne?" \ - "\n$( - pad_multiline \ - "\n${uni_bullet}diagnostyka zawiera logi i informacje o serwerze i usługach" \ - "\n${uni_bullet}wysyłka na e-mail na który zamówiono serwer Mikr.us" \ - "\n${uni_bullet}dane będą skompresowane i zaszyfrowane" \ - "\n${uni_bullet}maila prześlij dalej do zaufanej osoby wspierającej" \ - "\n${uni_bullet_pad}(z którą to wcześniej zaplanowano i uzgodniono!!!)" \ - "\n${uni_bullet}hasło przekaż INNĄ DROGĄ (komunikatorem, SMSem, osobiście)" \ - "\n\n${uni_bullet_pad}Hasło do logów: $LOG_KEY" - )" + local maxNsLogs=$1 + local maxDbLogs=$2 + local curr_time=$3 - if ! [ $? -eq 1 ]; then + diagnosticsSizeOk=0 - ohai "Zbieranie diagnostyki" + ohai "Zbieranie diagnostyki" - local domain=$(get_td_domain) - local curr_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ") - local ns_tag=$(dotenv-tool -r get -f $ENV_FILE_DEP "NS_NIGHTSCOUT_TAG") - local mikrus_h=$(hostname) + local domain=$(get_td_domain) + local ns_tag=$(dotenv-tool -r get -f $ENV_FILE_DEP "NS_NIGHTSCOUT_TAG") + local mikrus_h=$(hostname) - local LOG_DIVIDER="=======================================================" + local LOG_DIVIDER="=======================================================" - rm -f $SUPPORT_LOG - rm -f "$SUPPORT_LOG.gz" - rm -f "$SUPPORT_LOG.gz.asc" + rm -f $SUPPORT_LOG + rm -f "$SUPPORT_LOG.gz" + rm -f "$SUPPORT_LOG.gz.asc" - { - echo "Dane diagnostyczne zebrane $curr_time" - echo " serwer : $mikrus_h" - echo " domena : $domain" - echo " wersja NS : $ns_tag" - } >$SUPPORT_LOG + { + echo "Dane diagnostyczne zebrane $curr_time" + echo " serwer : $mikrus_h" + echo " domena : $domain" + echo " wersja NS : $ns_tag" + } >$SUPPORT_LOG + + ohai "Zbieranie statusu usług" - ohai "Zbieranie statusu usług" + { + echo "$LOG_DIVIDER" + echo " Statusy usług" + echo "$LOG_DIVIDER" + echo " Nightscout: $(get_container_status 'ns-server')" + echo " Baza danych: $(get_container_status 'ns-database')" + echo " Backup: $(get_container_status 'ns-backup')" + echo " Watchdog: $(get_watchdog_status "$(get_watchdog_status_code)" "$uni_watchdog_ok")" + } >>$SUPPORT_LOG + + local spaceInfo=$(get_space_info) + local remainingTxt=$(echo "$spaceInfo" | awk '{print $3}' | numfmt --to iec-i --suffix=B) + local totalTxt=$(echo "$spaceInfo" | awk '{print $2}' | numfmt --to iec-i --suffix=B) + local percTxt=$(echo "$spaceInfo" | awk '{print $4}') + + { + echo "$LOG_DIVIDER" + echo " Miejsce na dysku" + echo "$LOG_DIVIDER" + echo " Dostępne: ${remainingTxt}" + echo " Zajęte: ${percTxt} (z ${totalTxt})" + } >>$SUPPORT_LOG + ohai "Zbieranie logów watchdoga" + + if [[ -f $WATCHDOG_LOG_FILE ]]; then { echo "$LOG_DIVIDER" - echo " Statusy usług" + echo " Watchdog log" echo "$LOG_DIVIDER" - echo " Nightscout: $(get_container_status 'ns-server')" - echo " Baza danych: $(get_container_status 'ns-database')" - echo " Backup: $(get_container_status 'ns-backup')" - echo " Watchdog: $(get_watchdog_status "$(get_watchdog_status_code)" "$uni_watchdog_ok")" + timeout -k 15 10 cat $WATCHDOG_LOG_FILE } >>$SUPPORT_LOG + fi - ohai "Zbieranie informacji o zasobach" - local spaceInfo=$(get_space_info) - local remainingTxt=$(echo "$spaceInfo" | awk '{print $3}' | numfmt --to iec-i --suffix=B) - local totalTxt=$(echo "$spaceInfo" | awk '{print $2}' | numfmt --to iec-i --suffix=B) - local percTxt=$(echo "$spaceInfo" | awk '{print $4}') - + if [[ -f $WATCHDOG_FAILURES_FILE ]]; then { echo "$LOG_DIVIDER" - echo " Miejsce na dysku" + echo " Watchdog failures log" echo "$LOG_DIVIDER" - echo " Dostępne: ${remainingTxt}" - echo " Zajęte: ${percTxt} (z ${totalTxt})" + timeout -k 15 10 cat $WATCHDOG_FAILURES_FILE } >>$SUPPORT_LOG + fi - ohai "Zbieranie logów watchdoga" + ohai "Zbieranie logów usług" - if [[ -f $WATCHDOG_LOG_FILE ]]; then - { - echo "$LOG_DIVIDER" - echo " Watchdog log" - echo "$LOG_DIVIDER" - timeout -k 15 10 cat $WATCHDOG_LOG_FILE - } >>$SUPPORT_LOG - fi + { + echo "$LOG_DIVIDER" + echo " Nightscout log" + echo "$LOG_DIVIDER" + timeout -k 15 10 docker logs ns-server --tail "$maxNsLogs" >>$SUPPORT_LOG 2>&1 + echo "$LOG_DIVIDER" + echo " MongoDB database log" + echo "$LOG_DIVIDER" + timeout -k 15 10 docker logs ns-database --tail "$maxDbLogs" >>$SUPPORT_LOG 2>&1 + } >>$SUPPORT_LOG - if [[ -f $WATCHDOG_FAILURES_FILE ]]; then - { - echo "$LOG_DIVIDER" - echo " Watchdog failures log" - echo "$LOG_DIVIDER" - timeout -k 15 10 cat $WATCHDOG_FAILURES_FILE - } >>$SUPPORT_LOG - fi + ohai "Kompresowanie i szyfrowanie raportu" - ohai "Zbieranie logów usług" + gzip -9 $SUPPORT_LOG - { - echo "$LOG_DIVIDER" - echo " Nightscout log" - echo "$LOG_DIVIDER" - timeout -k 15 10 docker logs ns-server --tail 500 >>$SUPPORT_LOG 2>&1 - echo "$LOG_DIVIDER" - echo " MongoDB database log" - echo "$LOG_DIVIDER" - timeout -k 15 10 docker logs ns-database --tail 100 >>$SUPPORT_LOG 2>&1 - } >>$SUPPORT_LOG + local logkey=$(<$LOG_ENCRYPTION_KEY_FILE) + + gpg --passphrase "$logkey" --batch --quiet --yes -a -c "$SUPPORT_LOG.gz" +} + +retry_diagnostics() { + local maxNsLogs=$1 + local maxDbLogs=$2 + local curr_time=$3 + + if ((diagnosticsSizeOk == 0)); then + + ohai "Sprawdzanie rozmiaru raportu" + + local logSize=$(stat --printf="%s" "$SUPPORT_LOG.gz.asc") + local allowedTxt=$(echo "18000" | numfmt --to si --suffix=B) + local currentTxt=$(echo "$logSize" | numfmt --to si --suffix=B) + + if ((logSize > 18000)); then + msgerr "Zebrana diagnostyka jest zbyt duża do wysłania (${currentTxt})" + ohai "Spróbuję zebrać mniej danych aby zmieścić się w limicie (${allowedTxt})" + gather_diagnostics "$maxNsLogs" "$maxDbLogs" "$curr_time" + else + diagnosticsSizeOk=1 + msgok "Raport ma rozmiar ${currentTxt} i mieści się w limicie ${allowedTxt} dla usługi pusher-a" + fi + fi +} + +send_diagnostics() { + LOG_KEY=$(<$LOG_ENCRYPTION_KEY_FILE) - ohai "Kompresowanie i szyfrowanie raportu" + yesnodlg "Wysyłać diagnostykę?" \ + "$uni_send" "$uni_resign" \ + "Czy chcesz zgromadzić i wysłać sobie mailem dane diagnostyczne?" \ + "\n$( + pad_multiline \ + "\n${uni_bullet}diagnostyka zawiera logi i informacje o serwerze i usługach" \ + "\n${uni_bullet}wysyłka na e-mail na który zamówiono serwer Mikr.us" \ + "\n${uni_bullet}dane będą skompresowane i zaszyfrowane" \ + "\n${uni_bullet}maila prześlij dalej do zaufanej osoby wspierającej" \ + "\n${uni_bullet_pad}(z którą to wcześniej zaplanowano i uzgodniono!!!)" \ + "\n${uni_bullet}hasło przekaż INNĄ DROGĄ (komunikatorem, SMSem, osobiście)" \ + "\n\n${uni_bullet_pad}Hasło do logów: $LOG_KEY" + )" - gzip $SUPPORT_LOG + if ! [ $? -eq 1 ]; then - local logkey=$(<$LOG_ENCRYPTION_KEY_FILE) + local curr_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ") - gpg --passphrase "$logkey" --batch --quiet --yes -a -c "$SUPPORT_LOG.gz" + gather_diagnostics 500 100 "$curr_time" + retry_diagnostics 200 50 "$curr_time" + retry_diagnostics 100 50 "$curr_time" + retry_diagnostics 50 50 "$curr_time" ohai "Wysyłanie maila" - { + local sentStatus=$({ echo "Ta wiadomość zawiera poufne dane diagnostyczne Twojego serwera Nightscout." echo "Mogą one pomóc Tobie lub zaufanej osobie w identyfikacji problemu." echo " " @@ -1877,12 +1916,21 @@ send_diagnostics() { echo " " echo " " cat "$SUPPORT_LOG.gz.asc" - } | pusher "Diagnostyka_serwera_Nightscout_-_$curr_time" - - okdlg "Diagnostyka wysłana" \ - "Sprawdź swoją skrzynkę pocztową,\n" \ - "otrzymanego maila przekaż zaufanemu wspierającemu.\n\n" \ - "Komunikatorem lub SMS przekaż hasło do logów:\n\n$LOG_KEY" + } | pusher "Diagnostyka_serwera_Nightscout_-_$curr_time") + + local regexEm='Email sent' + if [[ "$sentStatus" =~ $regexEm ]]; then + okdlg "Diagnostyka wysłana" \ + "Sprawdź swoją skrzynkę pocztową,\n" \ + "otrzymanego maila przekaż zaufanemu wspierającemu.\n\n" \ + "Komunikatorem lub SMS przekaż hasło do logów:\n\n$LOG_KEY" + else + msgerr "Błąd podczas wysyłki maila: $sentStatus" + okdlg "Błąd wysyłki maila" \ + "Nieststy nie udało się wysłać diagnostyki" \ + "${NL}zgłoś poniższy błąd twórcom narzędzia (na grupie Technologie Diabetyka)" \ + "${TL}$sentStatus" + fi fi } diff --git a/src/lib.sh b/src/lib.sh index 64ba934..ea04d68 100644 --- a/src/lib.sh +++ b/src/lib.sh @@ -412,6 +412,7 @@ aptGetWasUpdated=0 freshInstall=0 cachedMenuDomain='' lastTimeSpaceInfo=0 +diagnosticsSizeOk=0 MIKRUS_APIKEY='' MIKRUS_HOST='' @@ -1483,22 +1484,22 @@ do_cleanup_sys() { ohai "Sprzątanie dziennik systemowego..." journalctl --vacuum-size=50M >>$LOGTO 2>&1 ohai "Czyszczenie systemu apt..." - msgnote "Ta operacja może TROCHĘ potrwać (od kilku do kilkudziesięciu minut...)" - apt-get -y autoremove >>$LOGTO 2>&1 && apt-get -y clean >>$LOGTO 2>&1 - msgcheck "Czyszczenie dziennika i apt zakończono" + msgnote "Ta operacja może TROCHĘ potrwać (od kilku do kilkudziesięciu minut...)" + apt-get -y autoremove >>$LOGTO 2>&1 && apt-get -y clean >>$LOGTO 2>&1 + msgcheck "Czyszczenie dziennika i apt zakończono" } do_cleanup_docker() { ohai "Usuwanie nieużywanych obrazów Dockera..." - msgnote "Ta operacja może TROCHĘ potrwać (do kilku minut...)" + msgnote "Ta operacja może TROCHĘ potrwać (do kilku minut...)" docker image prune -af >>$LOGTO 2>&1 - msgcheck "Czyszczenie Dockera zakończono" + msgcheck "Czyszczenie Dockera zakończono" } do_cleanup_db() { ohai "Usuwanie kopii zapasowych bazy danych..." - find /srv/nightscout/data/dbbackup ! -type d -delete - msgcheck "Czyszczenie kopii zapasowych zakończono" + find /srv/nightscout/data/dbbackup ! -type d -delete + msgcheck "Czyszczenie kopii zapasowych zakończono" } cleanup_menu() { @@ -1516,7 +1517,7 @@ cleanup_menu() { local savedB=$((nowB - lastTimeB)) local savedTxt=$(echo "$savedB" | numfmt --to iec-i --suffix=B) - if (( savedB < 1)); then + if ((savedB < 1)); then savedTxt="---" fi @@ -1543,10 +1544,10 @@ cleanup_menu() { noyesdlg "Posprzątać wszystko?" "$uni_confirm_del" "$uni_resign" \ "Czy chcesz posprzątać i usunąć:" \ "$(pad_multiline \ - "${NL}${uni_bullet}nieużywane pliki apt i dziennika" \ - "${NL}${uni_bullet}nieużywane obrazy Dockera" \ - "${NL} ${uni_bullet}kopie zapasowe bazy danych")" \ - "${TL}(ta operacja może potrwać od kilku do kilkudziesięciu minut)" + "${NL}${uni_bullet}nieużywane pliki apt i dziennika" \ + "${NL}${uni_bullet}nieużywane obrazy Dockera" \ + "${NL} ${uni_bullet}kopie zapasowe bazy danych")" \ + "${TL}(ta operacja może potrwać od kilku do kilkudziesięciu minut)" if ! [ $? -eq 1 ]; then do_cleanup_sys do_cleanup_docker @@ -1556,7 +1557,7 @@ cleanup_menu() { "S)") noyesdlg "Posprzątać zasoby systemowe?" "$uni_confirm_del" "$uni_resign" \ "Czy chcesz usunąć nieużywane pakiety apt i poprzątać dziennik systemowy?" \ - "${TL}(ta operacja może potrwać od kilku do kilkudziesięciu minut)" + "${TL}(ta operacja może potrwać od kilku do kilkudziesięciu minut)" if ! [ $? -eq 1 ]; then do_cleanup_sys fi @@ -1564,7 +1565,7 @@ cleanup_menu() { "D)") noyesdlg "Posprzątać obrazy Dockera?" "$uni_confirm_del" "$uni_resign" \ "Czy chcesz usunąć nieużywane obrazy Dockera?" \ - "${TL}(ta operacja może potrwać kilka minut)" + "${TL}(ta operacja może potrwać kilka minut)" if ! [ $? -eq 1 ]; then do_cleanup_docker fi @@ -1590,8 +1591,8 @@ cleanup_menu() { update_menu() { while :; do local CHOICE=$(whiptail --title "Aktualizuj" --menu "\n" 11 40 4 \ - "S)" "Aktualizuj system" \ "N)" "Aktualizuj to narzędzie" \ + "S)" "Aktualizuj system" \ "K)" "Aktualizuj kontenery" \ "M)" "Powrót do menu" \ --ok-button="$uni_select" --cancel-button="$uni_back" \ @@ -1739,115 +1740,153 @@ get_domain_status() { fi } -send_diagnostics() { - LOG_KEY=$(<$LOG_ENCRYPTION_KEY_FILE) +gather_diagnostics() { - yesnodlg "Wysyłać diagnostykę?" \ - "$uni_send" "$uni_resign" \ - "Czy chcesz zgromadzić i wysłać sobie mailem dane diagnostyczne?" \ - "\n$( - pad_multiline \ - "\n${uni_bullet}diagnostyka zawiera logi i informacje o serwerze i usługach" \ - "\n${uni_bullet}wysyłka na e-mail na który zamówiono serwer Mikr.us" \ - "\n${uni_bullet}dane będą skompresowane i zaszyfrowane" \ - "\n${uni_bullet}maila prześlij dalej do zaufanej osoby wspierającej" \ - "\n${uni_bullet_pad}(z którą to wcześniej zaplanowano i uzgodniono!!!)" \ - "\n${uni_bullet}hasło przekaż INNĄ DROGĄ (komunikatorem, SMSem, osobiście)" \ - "\n\n${uni_bullet_pad}Hasło do logów: $LOG_KEY" - )" + local maxNsLogs=$1 + local maxDbLogs=$2 + local curr_time=$3 - if ! [ $? -eq 1 ]; then + diagnosticsSizeOk=0 - ohai "Zbieranie diagnostyki" + ohai "Zbieranie diagnostyki" - local domain=$(get_td_domain) - local curr_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ") - local ns_tag=$(dotenv-tool -r get -f $ENV_FILE_DEP "NS_NIGHTSCOUT_TAG") - local mikrus_h=$(hostname) + local domain=$(get_td_domain) + local ns_tag=$(dotenv-tool -r get -f $ENV_FILE_DEP "NS_NIGHTSCOUT_TAG") + local mikrus_h=$(hostname) - local LOG_DIVIDER="=======================================================" + local LOG_DIVIDER="=======================================================" - rm -f $SUPPORT_LOG - rm -f "$SUPPORT_LOG.gz" - rm -f "$SUPPORT_LOG.gz.asc" + rm -f $SUPPORT_LOG + rm -f "$SUPPORT_LOG.gz" + rm -f "$SUPPORT_LOG.gz.asc" - { - echo "Dane diagnostyczne zebrane $curr_time" - echo " serwer : $mikrus_h" - echo " domena : $domain" - echo " wersja NS : $ns_tag" - } >$SUPPORT_LOG + { + echo "Dane diagnostyczne zebrane $curr_time" + echo " serwer : $mikrus_h" + echo " domena : $domain" + echo " wersja NS : $ns_tag" + } >$SUPPORT_LOG + + ohai "Zbieranie statusu usług" - ohai "Zbieranie statusu usług" + { + echo "$LOG_DIVIDER" + echo " Statusy usług" + echo "$LOG_DIVIDER" + echo " Nightscout: $(get_container_status 'ns-server')" + echo " Baza danych: $(get_container_status 'ns-database')" + echo " Backup: $(get_container_status 'ns-backup')" + echo " Watchdog: $(get_watchdog_status "$(get_watchdog_status_code)" "$uni_watchdog_ok")" + } >>$SUPPORT_LOG + + local spaceInfo=$(get_space_info) + local remainingTxt=$(echo "$spaceInfo" | awk '{print $3}' | numfmt --to iec-i --suffix=B) + local totalTxt=$(echo "$spaceInfo" | awk '{print $2}' | numfmt --to iec-i --suffix=B) + local percTxt=$(echo "$spaceInfo" | awk '{print $4}') + + { + echo "$LOG_DIVIDER" + echo " Miejsce na dysku" + echo "$LOG_DIVIDER" + echo " Dostępne: ${remainingTxt}" + echo " Zajęte: ${percTxt} (z ${totalTxt})" + } >>$SUPPORT_LOG + ohai "Zbieranie logów watchdoga" + + if [[ -f $WATCHDOG_LOG_FILE ]]; then { echo "$LOG_DIVIDER" - echo " Statusy usług" + echo " Watchdog log" echo "$LOG_DIVIDER" - echo " Nightscout: $(get_container_status 'ns-server')" - echo " Baza danych: $(get_container_status 'ns-database')" - echo " Backup: $(get_container_status 'ns-backup')" - echo " Watchdog: $(get_watchdog_status "$(get_watchdog_status_code)" "$uni_watchdog_ok")" + timeout -k 15 10 cat $WATCHDOG_LOG_FILE } >>$SUPPORT_LOG + fi - ohai "Zbieranie informacji o zasobach" - local spaceInfo=$(get_space_info) - local remainingTxt=$(echo "$spaceInfo" | awk '{print $3}' | numfmt --to iec-i --suffix=B) - local totalTxt=$(echo "$spaceInfo" | awk '{print $2}' | numfmt --to iec-i --suffix=B) - local percTxt=$(echo "$spaceInfo" | awk '{print $4}') - + if [[ -f $WATCHDOG_FAILURES_FILE ]]; then { echo "$LOG_DIVIDER" - echo " Miejsce na dysku" + echo " Watchdog failures log" echo "$LOG_DIVIDER" - echo " Dostępne: ${remainingTxt}" - echo " Zajęte: ${percTxt} (z ${totalTxt})" + timeout -k 15 10 cat $WATCHDOG_FAILURES_FILE } >>$SUPPORT_LOG + fi - ohai "Zbieranie logów watchdoga" + ohai "Zbieranie logów usług" - if [[ -f $WATCHDOG_LOG_FILE ]]; then - { - echo "$LOG_DIVIDER" - echo " Watchdog log" - echo "$LOG_DIVIDER" - timeout -k 15 10 cat $WATCHDOG_LOG_FILE - } >>$SUPPORT_LOG - fi + { + echo "$LOG_DIVIDER" + echo " Nightscout log" + echo "$LOG_DIVIDER" + timeout -k 15 10 docker logs ns-server --tail "$maxNsLogs" >>$SUPPORT_LOG 2>&1 + echo "$LOG_DIVIDER" + echo " MongoDB database log" + echo "$LOG_DIVIDER" + timeout -k 15 10 docker logs ns-database --tail "$maxDbLogs" >>$SUPPORT_LOG 2>&1 + } >>$SUPPORT_LOG - if [[ -f $WATCHDOG_FAILURES_FILE ]]; then - { - echo "$LOG_DIVIDER" - echo " Watchdog failures log" - echo "$LOG_DIVIDER" - timeout -k 15 10 cat $WATCHDOG_FAILURES_FILE - } >>$SUPPORT_LOG - fi + ohai "Kompresowanie i szyfrowanie raportu" - ohai "Zbieranie logów usług" + gzip -9 $SUPPORT_LOG - { - echo "$LOG_DIVIDER" - echo " Nightscout log" - echo "$LOG_DIVIDER" - timeout -k 15 10 docker logs ns-server --tail 500 >>$SUPPORT_LOG 2>&1 - echo "$LOG_DIVIDER" - echo " MongoDB database log" - echo "$LOG_DIVIDER" - timeout -k 15 10 docker logs ns-database --tail 100 >>$SUPPORT_LOG 2>&1 - } >>$SUPPORT_LOG + local logkey=$(<$LOG_ENCRYPTION_KEY_FILE) + + gpg --passphrase "$logkey" --batch --quiet --yes -a -c "$SUPPORT_LOG.gz" +} + +retry_diagnostics() { + local maxNsLogs=$1 + local maxDbLogs=$2 + local curr_time=$3 + + if ((diagnosticsSizeOk == 0)); then + + ohai "Sprawdzanie rozmiaru raportu" + + local logSize=$(stat --printf="%s" "$SUPPORT_LOG.gz.asc") + local allowedTxt=$(echo "18000" | numfmt --to si --suffix=B) + local currentTxt=$(echo "$logSize" | numfmt --to si --suffix=B) + + if ((logSize > 18000)); then + msgerr "Zebrana diagnostyka jest zbyt duża do wysłania (${currentTxt})" + ohai "Spróbuję zebrać mniej danych aby zmieścić się w limicie (${allowedTxt})" + gather_diagnostics "$maxNsLogs" "$maxDbLogs" "$curr_time" + else + diagnosticsSizeOk=1 + msgok "Raport ma rozmiar ${currentTxt} i mieści się w limicie ${allowedTxt} dla usługi pusher-a" + fi + fi +} + +send_diagnostics() { + LOG_KEY=$(<$LOG_ENCRYPTION_KEY_FILE) - ohai "Kompresowanie i szyfrowanie raportu" + yesnodlg "Wysyłać diagnostykę?" \ + "$uni_send" "$uni_resign" \ + "Czy chcesz zgromadzić i wysłać sobie mailem dane diagnostyczne?" \ + "\n$( + pad_multiline \ + "\n${uni_bullet}diagnostyka zawiera logi i informacje o serwerze i usługach" \ + "\n${uni_bullet}wysyłka na e-mail na który zamówiono serwer Mikr.us" \ + "\n${uni_bullet}dane będą skompresowane i zaszyfrowane" \ + "\n${uni_bullet}maila prześlij dalej do zaufanej osoby wspierającej" \ + "\n${uni_bullet_pad}(z którą to wcześniej zaplanowano i uzgodniono!!!)" \ + "\n${uni_bullet}hasło przekaż INNĄ DROGĄ (komunikatorem, SMSem, osobiście)" \ + "\n\n${uni_bullet_pad}Hasło do logów: $LOG_KEY" + )" - gzip $SUPPORT_LOG + if ! [ $? -eq 1 ]; then - local logkey=$(<$LOG_ENCRYPTION_KEY_FILE) + local curr_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ") - gpg --passphrase "$logkey" --batch --quiet --yes -a -c "$SUPPORT_LOG.gz" + gather_diagnostics 500 100 "$curr_time" + retry_diagnostics 200 50 "$curr_time" + retry_diagnostics 100 50 "$curr_time" + retry_diagnostics 50 50 "$curr_time" ohai "Wysyłanie maila" - { + local sentStatus=$({ echo "Ta wiadomość zawiera poufne dane diagnostyczne Twojego serwera Nightscout." echo "Mogą one pomóc Tobie lub zaufanej osobie w identyfikacji problemu." echo " " @@ -1861,12 +1900,21 @@ send_diagnostics() { echo " " echo " " cat "$SUPPORT_LOG.gz.asc" - } | pusher "Diagnostyka_serwera_Nightscout_-_$curr_time" - - okdlg "Diagnostyka wysłana" \ - "Sprawdź swoją skrzynkę pocztową,\n" \ - "otrzymanego maila przekaż zaufanemu wspierającemu.\n\n" \ - "Komunikatorem lub SMS przekaż hasło do logów:\n\n$LOG_KEY" + } | pusher "Diagnostyka_serwera_Nightscout_-_$curr_time") + + local regexEm='Email sent' + if [[ "$sentStatus" =~ $regexEm ]]; then + okdlg "Diagnostyka wysłana" \ + "Sprawdź swoją skrzynkę pocztową,\n" \ + "otrzymanego maila przekaż zaufanemu wspierającemu.\n\n" \ + "Komunikatorem lub SMS przekaż hasło do logów:\n\n$LOG_KEY" + else + msgerr "Błąd podczas wysyłki maila: $sentStatus" + okdlg "Błąd wysyłki maila" \ + "Nieststy nie udało się wysłać diagnostyki" \ + "${NL}zgłoś poniższy błąd twórcom narzędzia (na grupie Technologie Diabetyka)" \ + "${TL}$sentStatus" + fi fi } diff --git a/updated b/updated index e4f1eb4..f9623ad 100644 --- a/updated +++ b/updated @@ -1 +1 @@ -2024-10-06T07:12:57.316Z \ No newline at end of file +2024-10-06T08:06:29.319Z \ No newline at end of file -- 2.38.5 From 178db788c9d089b1caa55147e364944b8cb0b3df Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Sun, 6 Oct 2024 08:31:38 +0000 Subject: [PATCH 09/14] Added tool version to diagnostics --- install.sh | 8 +++++--- src/lib.sh | 8 +++++--- updated | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/install.sh b/install.sh index 5c97c3b..c5f136b 100644 --- a/install.sh +++ b/install.sh @@ -1778,9 +1778,10 @@ gather_diagnostics() { { echo "Dane diagnostyczne zebrane $curr_time" - echo " serwer : $mikrus_h" - echo " domena : $domain" - echo " wersja NS : $ns_tag" + echo " serwer : $mikrus_h" + echo " domena : $domain" + echo " wersja nightscout : $ns_tag" + echo " wersja nightscout-tool : $SCRIPT_VERSION ($SCRIPT_BUILD_TIME) $UPDATE_CHANNEL" } >$SUPPORT_LOG ohai "Zbieranie statusu usług" @@ -1920,6 +1921,7 @@ send_diagnostics() { local regexEm='Email sent' if [[ "$sentStatus" =~ $regexEm ]]; then + msgok "Mail wysłany!" okdlg "Diagnostyka wysłana" \ "Sprawdź swoją skrzynkę pocztową,\n" \ "otrzymanego maila przekaż zaufanemu wspierającemu.\n\n" \ diff --git a/src/lib.sh b/src/lib.sh index ea04d68..fb1797d 100644 --- a/src/lib.sh +++ b/src/lib.sh @@ -1762,9 +1762,10 @@ gather_diagnostics() { { echo "Dane diagnostyczne zebrane $curr_time" - echo " serwer : $mikrus_h" - echo " domena : $domain" - echo " wersja NS : $ns_tag" + echo " serwer : $mikrus_h" + echo " domena : $domain" + echo " wersja nightscout : $ns_tag" + echo " wersja nightscout-tool : $SCRIPT_VERSION ($SCRIPT_BUILD_TIME) $UPDATE_CHANNEL" } >$SUPPORT_LOG ohai "Zbieranie statusu usług" @@ -1904,6 +1905,7 @@ send_diagnostics() { local regexEm='Email sent' if [[ "$sentStatus" =~ $regexEm ]]; then + msgok "Mail wysłany!" okdlg "Diagnostyka wysłana" \ "Sprawdź swoją skrzynkę pocztową,\n" \ "otrzymanego maila przekaż zaufanemu wspierającemu.\n\n" \ diff --git a/updated b/updated index f9623ad..a703fa9 100644 --- a/updated +++ b/updated @@ -1 +1 @@ -2024-10-06T08:06:29.319Z \ No newline at end of file +2024-10-06T08:31:11.350Z \ No newline at end of file -- 2.38.5 From 2e44882db410c0439944950c179cd6edaf9ae61d Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Sun, 6 Oct 2024 12:44:37 +0000 Subject: [PATCH 10/14] Handles edge case when apt is locked and diceware not installed --- install.sh | 85 +++++++++++++++++++++++++++++++++++++++++++++++++----- src/lib.sh | 85 +++++++++++++++++++++++++++++++++++++++++++++++++----- updated | 2 +- 3 files changed, 157 insertions(+), 15 deletions(-) diff --git a/install.sh b/install.sh index c5f136b..afe240c 100644 --- a/install.sh +++ b/install.sh @@ -523,18 +523,85 @@ check_dateutils() { add_if_not_ok "Date Utils" "dateutils" } -check_diceware() { +test_diceware() { diceware --version >/dev/null 2>&1 +} + +check_diceware() { + test_diceware add_if_not_ok "Secure Password Generator" "diceware" } +setup_provisional_key() { + ohai "Generating provisional log encryption key" + local randPass=$(openssl rand -base64 30) + local fixedPass=$(echo "$randPass" | sed -e 's/[+\/]/-/g') + echo "tymczasowe-${fixedPass}" >$LOG_ENCRYPTION_KEY_FILE + msgcheck "Provisional key generated" +} + setup_security() { if [[ -f $LOG_ENCRYPTION_KEY_FILE ]]; then - msgok "Found log encryption key" + # -------------------- + # JAKIŚ klucz istnieje + # -------------------- + local logKey=$(<$LOG_ENCRYPTION_KEY_FILE) + local regexTemp='tymczasowe-' + + # ----------------------- + # ...ale jest tymczasowy + # ----------------------- + if [[ "$logKey" =~ $regexTemp ]]; then + msgerr "Using provisional key" + test_diceware + local RESULT=$? + if [ $RESULT -eq 0 ]; then + ohai "Generating proper log encryption file..." + diceware -n 5 -d - >$LOG_ENCRYPTION_KEY_FILE + msgcheck "Key generated" + else + msgerr "Required tool (diceware) still cannot be installed - apt is locked!" + msgnote "Zrestartuj serwer mikr.us i sprawdź czy ten błąd nadal występuje - wtedy odbokuj apt-get i zainstaluj diceware (apt-get install diceware)" + fi + else + local keySize=${#logKey} + + # ---------------------- + # ...ale jest za krótki + # ---------------------- + if ((keySize < 12)); then + msgerr "Encryption key empty or too short, generating better one" + test_diceware + local RESULT=$? + if [ $RESULT -eq 0 ]; then + ohai "Generating proper log encryption file..." + diceware -n 5 -d - >$LOG_ENCRYPTION_KEY_FILE + msgcheck "Key generated" + else + msgerr "Generating provisional key while diceware tool is not installed" + setup_provisional_key + fi + else + msgok "Found log encryption key" + fi + fi else - ohai "Generating log encryption file..." - diceware -n 5 -d - >$LOG_ENCRYPTION_KEY_FILE - msgcheck "Key generated" + + # --------------------- + # jescze nie ma klucza + # --------------------- + + test_diceware + local RESULT=$? + if [ $RESULT -eq 0 ]; then + ohai "Generating log encryption key..." + diceware -n 5 -d - >$LOG_ENCRYPTION_KEY_FILE + msgcheck "Key generated" + else + msgerr "Generating provisional key while diceware tool is not installed" + setup_provisional_key + fi + fi } @@ -1781,7 +1848,7 @@ gather_diagnostics() { echo " serwer : $mikrus_h" echo " domena : $domain" echo " wersja nightscout : $ns_tag" - echo " wersja nightscout-tool : $SCRIPT_VERSION ($SCRIPT_BUILD_TIME) $UPDATE_CHANNEL" + echo " wersja nightscout-tool : $SCRIPT_VERSION ($SCRIPT_BUILD_TIME) $UPDATE_CHANNEL" } >$SUPPORT_LOG ohai "Zbieranie statusu usług" @@ -1876,6 +1943,9 @@ retry_diagnostics() { } send_diagnostics() { + + setup_security + LOG_KEY=$(<$LOG_ENCRYPTION_KEY_FILE) yesnodlg "Wysyłać diagnostykę?" \ @@ -1900,6 +1970,7 @@ send_diagnostics() { retry_diagnostics 200 50 "$curr_time" retry_diagnostics 100 50 "$curr_time" retry_diagnostics 50 50 "$curr_time" + retry_diagnostics 50 20 "$curr_time" ohai "Wysyłanie maila" @@ -1921,7 +1992,7 @@ send_diagnostics() { local regexEm='Email sent' if [[ "$sentStatus" =~ $regexEm ]]; then - msgok "Mail wysłany!" + msgcheck "Mail wysłany!" okdlg "Diagnostyka wysłana" \ "Sprawdź swoją skrzynkę pocztową,\n" \ "otrzymanego maila przekaż zaufanemu wspierającemu.\n\n" \ diff --git a/src/lib.sh b/src/lib.sh index fb1797d..c814882 100644 --- a/src/lib.sh +++ b/src/lib.sh @@ -507,18 +507,85 @@ check_dateutils() { add_if_not_ok "Date Utils" "dateutils" } -check_diceware() { +test_diceware() { diceware --version >/dev/null 2>&1 +} + +check_diceware() { + test_diceware add_if_not_ok "Secure Password Generator" "diceware" } +setup_provisional_key() { + ohai "Generating provisional log encryption key" + local randPass=$(openssl rand -base64 30) + local fixedPass=$(echo "$randPass" | sed -e 's/[+\/]/-/g') + echo "tymczasowe-${fixedPass}" >$LOG_ENCRYPTION_KEY_FILE + msgcheck "Provisional key generated" +} + setup_security() { if [[ -f $LOG_ENCRYPTION_KEY_FILE ]]; then - msgok "Found log encryption key" + # -------------------- + # JAKIŚ klucz istnieje + # -------------------- + local logKey=$(<$LOG_ENCRYPTION_KEY_FILE) + local regexTemp='tymczasowe-' + + # ----------------------- + # ...ale jest tymczasowy + # ----------------------- + if [[ "$logKey" =~ $regexTemp ]]; then + msgerr "Using provisional key" + test_diceware + local RESULT=$? + if [ $RESULT -eq 0 ]; then + ohai "Generating proper log encryption file..." + diceware -n 5 -d - >$LOG_ENCRYPTION_KEY_FILE + msgcheck "Key generated" + else + msgerr "Required tool (diceware) still cannot be installed - apt is locked!" + msgnote "Zrestartuj serwer mikr.us i sprawdź czy ten błąd nadal występuje - wtedy odbokuj apt-get i zainstaluj diceware (apt-get install diceware)" + fi + else + local keySize=${#logKey} + + # ---------------------- + # ...ale jest za krótki + # ---------------------- + if ((keySize < 12)); then + msgerr "Encryption key empty or too short, generating better one" + test_diceware + local RESULT=$? + if [ $RESULT -eq 0 ]; then + ohai "Generating proper log encryption file..." + diceware -n 5 -d - >$LOG_ENCRYPTION_KEY_FILE + msgcheck "Key generated" + else + msgerr "Generating provisional key while diceware tool is not installed" + setup_provisional_key + fi + else + msgok "Found log encryption key" + fi + fi else - ohai "Generating log encryption file..." - diceware -n 5 -d - >$LOG_ENCRYPTION_KEY_FILE - msgcheck "Key generated" + + # --------------------- + # jescze nie ma klucza + # --------------------- + + test_diceware + local RESULT=$? + if [ $RESULT -eq 0 ]; then + ohai "Generating log encryption key..." + diceware -n 5 -d - >$LOG_ENCRYPTION_KEY_FILE + msgcheck "Key generated" + else + msgerr "Generating provisional key while diceware tool is not installed" + setup_provisional_key + fi + fi } @@ -1765,7 +1832,7 @@ gather_diagnostics() { echo " serwer : $mikrus_h" echo " domena : $domain" echo " wersja nightscout : $ns_tag" - echo " wersja nightscout-tool : $SCRIPT_VERSION ($SCRIPT_BUILD_TIME) $UPDATE_CHANNEL" + echo " wersja nightscout-tool : $SCRIPT_VERSION ($SCRIPT_BUILD_TIME) $UPDATE_CHANNEL" } >$SUPPORT_LOG ohai "Zbieranie statusu usług" @@ -1860,6 +1927,9 @@ retry_diagnostics() { } send_diagnostics() { + + setup_security + LOG_KEY=$(<$LOG_ENCRYPTION_KEY_FILE) yesnodlg "Wysyłać diagnostykę?" \ @@ -1884,6 +1954,7 @@ send_diagnostics() { retry_diagnostics 200 50 "$curr_time" retry_diagnostics 100 50 "$curr_time" retry_diagnostics 50 50 "$curr_time" + retry_diagnostics 50 20 "$curr_time" ohai "Wysyłanie maila" @@ -1905,7 +1976,7 @@ send_diagnostics() { local regexEm='Email sent' if [[ "$sentStatus" =~ $regexEm ]]; then - msgok "Mail wysłany!" + msgcheck "Mail wysłany!" okdlg "Diagnostyka wysłana" \ "Sprawdź swoją skrzynkę pocztową,\n" \ "otrzymanego maila przekaż zaufanemu wspierającemu.\n\n" \ diff --git a/updated b/updated index a703fa9..b2ae9c3 100644 --- a/updated +++ b/updated @@ -1 +1 @@ -2024-10-06T08:31:11.350Z \ No newline at end of file +2024-10-06T12:43:24.897Z \ No newline at end of file -- 2.38.5 From ef6fa8e33eab474c42940b6dcdb63063aaddb676 Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Sun, 6 Oct 2024 20:33:08 +0000 Subject: [PATCH 11/14] Extended watchdog --- install.sh | 85 +++++++++++++++++++++++++++++++++--------------------- src/lib.sh | 85 +++++++++++++++++++++++++++++++++--------------------- updated | 2 +- 3 files changed, 105 insertions(+), 67 deletions(-) diff --git a/install.sh b/install.sh index afe240c..d745e40 100644 --- a/install.sh +++ b/install.sh @@ -534,23 +534,23 @@ check_diceware() { setup_provisional_key() { ohai "Generating provisional log encryption key" - local randPass=$(openssl rand -base64 30) - local fixedPass=$(echo "$randPass" | sed -e 's/[+\/]/-/g') - echo "tymczasowe-${fixedPass}" >$LOG_ENCRYPTION_KEY_FILE + local randPass=$(openssl rand -base64 30) + local fixedPass=$(echo "$randPass" | sed -e 's/[+\/]/-/g') + echo "tymczasowe-${fixedPass}" >$LOG_ENCRYPTION_KEY_FILE msgcheck "Provisional key generated" } setup_security() { if [[ -f $LOG_ENCRYPTION_KEY_FILE ]]; then - # -------------------- - # JAKIŚ klucz istnieje - # -------------------- + # -------------------- + # JAKIŚ klucz istnieje + # -------------------- local logKey=$(<$LOG_ENCRYPTION_KEY_FILE) local regexTemp='tymczasowe-' - - # ----------------------- - # ...ale jest tymczasowy - # ----------------------- + + # ----------------------- + # ...ale jest tymczasowy + # ----------------------- if [[ "$logKey" =~ $regexTemp ]]; then msgerr "Using provisional key" test_diceware @@ -560,15 +560,15 @@ setup_security() { diceware -n 5 -d - >$LOG_ENCRYPTION_KEY_FILE msgcheck "Key generated" else - msgerr "Required tool (diceware) still cannot be installed - apt is locked!" - msgnote "Zrestartuj serwer mikr.us i sprawdź czy ten błąd nadal występuje - wtedy odbokuj apt-get i zainstaluj diceware (apt-get install diceware)" + msgerr "Required tool (diceware) still cannot be installed - apt is locked!" + msgnote "Zrestartuj serwer mikr.us i sprawdź czy ten błąd nadal występuje - wtedy odbokuj apt-get i zainstaluj diceware (apt-get install diceware)" fi else local keySize=${#logKey} - # ---------------------- - # ...ale jest za krótki - # ---------------------- + # ---------------------- + # ...ale jest za krótki + # ---------------------- if ((keySize < 12)); then msgerr "Encryption key empty or too short, generating better one" test_diceware @@ -586,10 +586,10 @@ setup_security() { fi fi else - - # --------------------- - # jescze nie ma klucza - # --------------------- + + # --------------------- + # jescze nie ma klucza + # --------------------- test_diceware local RESULT=$? @@ -1310,9 +1310,9 @@ get_watchdog_status_code_live() { status="crashed" fi - regex3='MIKR.US - coś poszło nie tak' + regex3='coś poszło nie tak' if [[ "$html" =~ $regex3 ]]; then - status="restarting" + status="awaiting" fi else @@ -1321,7 +1321,7 @@ get_watchdog_status_code_live() { else if [ "$NS_STATUS" = "restarting" ] || [ "$DB_STATUS" = "restarting" ]; then - status="restarting" + status="awaiting" else status="not_running" fi @@ -1339,9 +1339,15 @@ get_watchdog_status() { "restart") printf "\U1F680 wymuszono restart NS" ;; - "restarting") + "awaiting") printf "\U23F3 uruchamia się" ;; + "restart_failed") + printf "\U1F680 restart NS to za mało" + ;; + "full_restart") + printf "\U1F680 restart NS i DB" + ;; "unknown") printf "\U1F4A4 brak statusu" ;; @@ -1944,7 +1950,7 @@ retry_diagnostics() { send_diagnostics() { - setup_security + setup_security LOG_KEY=$(<$LOG_ENCRYPTION_KEY_FILE) @@ -2152,18 +2158,31 @@ watchdog_check() { fi if [[ "$html" =~ 'MongoDB connection failed' ]]; then - echo "Nightscout is crashed, restarting..." + echo "Nightscout crash detected" WATCHDOG_STATUS="restart" - if [ "$WATCHDOG_LAST_STATUS" != "restart" ]; then + if [ "$WATCHDOG_LAST_STATUS" == "restart_failed" ]; then + echo "Restarting DB first..." + docker restart 'ns-database' + echo "Then, restarting Nightscout..." docker restart 'ns-server' echo "...done" + WATCHDOG_STATUS="full_restart" + else + if [ "$WATCHDOG_LAST_STATUS" != "restart" ]; then + echo "Restarting only Nightscout..." + docker restart 'ns-server' + echo "...done" + else + echo "Restart was tried but NS still crashed, will retry restart next time" + WATCHDOG_STATUS="restart_failed" + fi + fi + else + regex3='coś poszło nie tak' + if [[ "$html" =~ $regex3 ]]; then + echo "Nightscout is still restarting..." + WATCHDOG_STATUS="awaiting" fi - fi - - regex3='MIKR.US - coś poszło nie tak' - if [[ "$html" =~ $regex3 ]]; then - echo "Nightscout is still restarting..." - WATCHDOG_STATUS="restarting" fi if [ "$WATCHDOG_STATUS" = "detection_failed" ]; then @@ -2183,7 +2202,7 @@ watchdog_check() { else if [ "$NS_STATUS" = "restarting" ] || [ "$DB_STATUS" = "restarting" ]; then - WATCHDOG_STATUS="restarting" + WATCHDOG_STATUS="awaiting" else WATCHDOG_STATUS="not_running" fi diff --git a/src/lib.sh b/src/lib.sh index c814882..b46148d 100644 --- a/src/lib.sh +++ b/src/lib.sh @@ -518,23 +518,23 @@ check_diceware() { setup_provisional_key() { ohai "Generating provisional log encryption key" - local randPass=$(openssl rand -base64 30) - local fixedPass=$(echo "$randPass" | sed -e 's/[+\/]/-/g') - echo "tymczasowe-${fixedPass}" >$LOG_ENCRYPTION_KEY_FILE + local randPass=$(openssl rand -base64 30) + local fixedPass=$(echo "$randPass" | sed -e 's/[+\/]/-/g') + echo "tymczasowe-${fixedPass}" >$LOG_ENCRYPTION_KEY_FILE msgcheck "Provisional key generated" } setup_security() { if [[ -f $LOG_ENCRYPTION_KEY_FILE ]]; then - # -------------------- - # JAKIŚ klucz istnieje - # -------------------- + # -------------------- + # JAKIŚ klucz istnieje + # -------------------- local logKey=$(<$LOG_ENCRYPTION_KEY_FILE) local regexTemp='tymczasowe-' - - # ----------------------- - # ...ale jest tymczasowy - # ----------------------- + + # ----------------------- + # ...ale jest tymczasowy + # ----------------------- if [[ "$logKey" =~ $regexTemp ]]; then msgerr "Using provisional key" test_diceware @@ -544,15 +544,15 @@ setup_security() { diceware -n 5 -d - >$LOG_ENCRYPTION_KEY_FILE msgcheck "Key generated" else - msgerr "Required tool (diceware) still cannot be installed - apt is locked!" - msgnote "Zrestartuj serwer mikr.us i sprawdź czy ten błąd nadal występuje - wtedy odbokuj apt-get i zainstaluj diceware (apt-get install diceware)" + msgerr "Required tool (diceware) still cannot be installed - apt is locked!" + msgnote "Zrestartuj serwer mikr.us i sprawdź czy ten błąd nadal występuje - wtedy odbokuj apt-get i zainstaluj diceware (apt-get install diceware)" fi else local keySize=${#logKey} - # ---------------------- - # ...ale jest za krótki - # ---------------------- + # ---------------------- + # ...ale jest za krótki + # ---------------------- if ((keySize < 12)); then msgerr "Encryption key empty or too short, generating better one" test_diceware @@ -570,10 +570,10 @@ setup_security() { fi fi else - - # --------------------- - # jescze nie ma klucza - # --------------------- + + # --------------------- + # jescze nie ma klucza + # --------------------- test_diceware local RESULT=$? @@ -1294,9 +1294,9 @@ get_watchdog_status_code_live() { status="crashed" fi - regex3='MIKR.US - coś poszło nie tak' + regex3='coś poszło nie tak' if [[ "$html" =~ $regex3 ]]; then - status="restarting" + status="awaiting" fi else @@ -1305,7 +1305,7 @@ get_watchdog_status_code_live() { else if [ "$NS_STATUS" = "restarting" ] || [ "$DB_STATUS" = "restarting" ]; then - status="restarting" + status="awaiting" else status="not_running" fi @@ -1323,9 +1323,15 @@ get_watchdog_status() { "restart") printf "\U1F680 wymuszono restart NS" ;; - "restarting") + "awaiting") printf "\U23F3 uruchamia się" ;; + "restart_failed") + printf "\U1F680 restart NS to za mało" + ;; + "full_restart") + printf "\U1F680 restart NS i DB" + ;; "unknown") printf "\U1F4A4 brak statusu" ;; @@ -1928,7 +1934,7 @@ retry_diagnostics() { send_diagnostics() { - setup_security + setup_security LOG_KEY=$(<$LOG_ENCRYPTION_KEY_FILE) @@ -2136,18 +2142,31 @@ watchdog_check() { fi if [[ "$html" =~ 'MongoDB connection failed' ]]; then - echo "Nightscout is crashed, restarting..." + echo "Nightscout crash detected" WATCHDOG_STATUS="restart" - if [ "$WATCHDOG_LAST_STATUS" != "restart" ]; then + if [ "$WATCHDOG_LAST_STATUS" == "restart_failed" ]; then + echo "Restarting DB first..." + docker restart 'ns-database' + echo "Then, restarting Nightscout..." docker restart 'ns-server' echo "...done" + WATCHDOG_STATUS="full_restart" + else + if [ "$WATCHDOG_LAST_STATUS" != "restart" ]; then + echo "Restarting only Nightscout..." + docker restart 'ns-server' + echo "...done" + else + echo "Restart was tried but NS still crashed, will retry restart next time" + WATCHDOG_STATUS="restart_failed" + fi + fi + else + regex3='coś poszło nie tak' + if [[ "$html" =~ $regex3 ]]; then + echo "Nightscout is still restarting..." + WATCHDOG_STATUS="awaiting" fi - fi - - regex3='MIKR.US - coś poszło nie tak' - if [[ "$html" =~ $regex3 ]]; then - echo "Nightscout is still restarting..." - WATCHDOG_STATUS="restarting" fi if [ "$WATCHDOG_STATUS" = "detection_failed" ]; then @@ -2167,7 +2186,7 @@ watchdog_check() { else if [ "$NS_STATUS" = "restarting" ] || [ "$DB_STATUS" = "restarting" ]; then - WATCHDOG_STATUS="restarting" + WATCHDOG_STATUS="awaiting" else WATCHDOG_STATUS="not_running" fi diff --git a/updated b/updated index b2ae9c3..b9b3476 100644 --- a/updated +++ b/updated @@ -1 +1 @@ -2024-10-06T12:43:24.897Z \ No newline at end of file +2024-10-06T20:32:19.387Z \ No newline at end of file -- 2.38.5 From d7ca97839943ee91bd9150b3649a2a88d9463721 Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Sat, 12 Oct 2024 09:37:43 +0000 Subject: [PATCH 12/14] Free space warnings --- install.sh | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++-- src/lib.sh | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++-- updated | 2 +- 3 files changed, 217 insertions(+), 9 deletions(-) diff --git a/install.sh b/install.sh index d745e40..ef1d27f 100644 --- a/install.sh +++ b/install.sh @@ -25,6 +25,7 @@ REQUIRED_NODE_VERSION=18.0.0 LOGTO=/dev/null NIGHTSCOUT_ROOT_DIR=/srv/nightscout CONFIG_ROOT_DIR=/srv/nightscout/config +DATA_ROOT_DIR=/srv/nightscout/data ENV_FILE_ADMIN=/srv/nightscout/config/admin.env ENV_FILE_NS=/srv/nightscout/config/nightscout.env ENV_FILE_DEP=/srv/nightscout/config/deployment.env @@ -44,8 +45,12 @@ TOOL_FILE=/srv/nightscout/tools/nightscout-tool TOOL_LINK=/usr/bin/nightscout-tool UPDATES_DIR=/srv/nightscout/updates UPDATE_CHANNEL=master +DISK_LOW_WARNING=838860800 # == 800 MiB +DISK_LOW_MAIL=5184000 # == 60 days in seconds +DISK_CRITICAL_WARNING=104857600 # == 100 MiB +DISK_CRITICAL_MAIL=604800 # == 7 days in seconds SCRIPT_VERSION="1.9.0" #auto-update -SCRIPT_BUILD_TIME="2024.10.06" #auto-update +SCRIPT_BUILD_TIME="2024.10.12" #auto-update #======================================= # SETUP @@ -243,6 +248,31 @@ exit_on_no_cancel() { fi } +get_since_last_time() { + local actionName=$1 + local actionFile="${DATA_ROOT_DIR}/last_${actionName}" + if [ -f "$actionFile" ]; then + local actionLast="$(<"$actionFile")" + local nowDate="$(date +'%s')" + echo $((nowDate - actionLast)) + else + echo -1 + fi +} + +set_last_time() { + local actionName=$1 + local actionFile="${DATA_ROOT_DIR}/last_${actionName}" + local nowDate="$(date +'%s')" + echo "$nowDate" > "$actionFile" +} + +clear_last_time() { + local actionName=$1 + local actionFile="${DATA_ROOT_DIR}/last_${actionName}" + rm -f "$actionFile" +} + #======================================= # HELPERS #======================================= @@ -1310,7 +1340,7 @@ get_watchdog_status_code_live() { status="crashed" fi - regex3='coś poszło nie tak' + regex3='poszło nie tak' if [[ "$html" =~ $regex3 ]]; then status="awaiting" fi @@ -2020,7 +2050,7 @@ main_menu() { local quickStatus=$(center_text "Strona Nightscout: $(get_watchdog_status "$(get_watchdog_status_code_live)" "$uni_ns_ok")" 55) local quickVersion=$(center_text "Wersja: $ns_tag" 55) local quickDomain=$(center_text "Domena: $(get_domain_status 'ns-server')" 55) - local CHOICE=$(whiptail --title "Zarządzanie Nightscoutem :: $SCRIPT_VERSION" --menu "\n$quickStatus\n$quickVersion\n$quickDomain\n" 19 60 9 \ + local CHOICE=$(whiptail --title "Zarządzanie Nightscoutem :: $SCRIPT_VERSION" --menu "\n$quickStatus\n$quickVersion\n$quickDomain\n" 21 60 9 \ "S)" "Status kontenerów i logi" \ "P)" "Pokaż port i API SECRET" \ "U)" "Aktualizuj..." \ @@ -2108,6 +2138,78 @@ install_or_menu() { fi } +free_space_check() { + lastTimeSpaceInfo=$(get_space_info) + + local remainingB=$(echo "$lastTimeSpaceInfo" | awk '{print $3}') + local remainingTxt=$(echo "$lastTimeSpaceInfo" | awk '{print $3}' | numfmt --to iec-i --suffix=B) + + if ((remainingB < DISK_LOW_WARNING)); then + if ((remainingB < DISK_CRITICAL_WARNING)); then + local lastCalled=$(get_since_last_time "disk_critical") + local domain=$(get_td_domain) + if ((lastCalled == -1)) || ((lastCalled > DISK_CRITICAL_MAIL)); then + set_last_time "disk_critical" + { + echo "Na twoim serwerze mikr.us z Nightscoutem (https://$domain) zostało krytycznie mało miejsca (${remainingTxt})!" + echo " " + echo "Tak mała ilość miejsca nie pozwala serwerowi na stabilne działanie!" + echo "🚨PILNIE🚨 posprzątaj na serwerze, aby to zrobić możesz:" + echo " " + echo "1. Usunąć stare statusy i wpisy z poziomu strony Nightscout:" + echo " - wejdź do hamburger menu strony Nightscout i wybierz: 【 Narzędzia administratora 】- wymaga zalogowania" + echo " to powinno otwórzyć adres: https://${domain}/admin" + echo " - w polach tekstowych poustawiaj ile dni historii chcesz zachować, i w odpowiednich sekcjach kliknij:" + echo " 【 Usuń stare dokumenty 】" + echo " " + echo "2. Posprzątać nieużywane pliki na serwerze mikr.us:" + echo " - zaloguj się na swój mikr.us do panelu administracyjnego, przejdź do WebSSH" + echo " https://mikr.us/panel/?a=webssh" + echo " - zaloguj się, uruchom narzędzie komendą: nightscout-tool" + echo " - wybierz: 【 C) Sprztąj... 】" + echo " - wybierz: 【 A) Posprzątaj wszystko 】 i potwierdź 【 Tak 】" + echo " - cierpliwie poczekaj, po sprzątaniu narzędzie pokaże ile miejsca zwolniono" + } | pusher "🚨_Krytycznie_mało_miejsca_na_Twoim_serwerze_Nightscout!" + echo "Free space on server: CRITICALLY LOW (${remainingTxt}) - sending email to user" + else + echo "Free space on server: CRITICALLY LOW (${remainingTxt}) - user already notified" + fi + else + local lastCalled=$(get_since_last_time "disk_warning") + local domain=$(get_td_domain) + if ((lastCalled == -1)) || ((lastCalled > DISK_LOW_MAIL)); then + set_last_time "disk_warning" + { + echo "Na twoim serwerze mikr.us z Nightscout-em (https://$domain) powoli kończy się miejsce (${remainingTxt})!" + echo " " + echo "🧹 W wolnej chwili posprzątaj na serwerze, aby to zrobić możesz:" + echo " " + echo "1. Usunąć stare statusy i wpisy z poziomu strony Nightscout:" + echo " - wejdź do hamburger menu strony Nightscout i wybierz:【 Narzędzia administratora 】- wymaga zalogowania" + echo " to powinno otwórzyć adres: https://${domain}/admin" + echo " - w polach tekstowych poustawiaj ile dni historii chcesz zachować, i w odpowiednich sekcjach kliknij:" + echo " 【 Usuń stare dokumenty 】" + echo " " + echo "2. Posprzątać nieużywane pliki na serwerze mikr.us:" + echo " - zaloguj się na swój mikr.us do panelu administracyjnego, przejdź do WebSSH" + echo " https://mikr.us/panel/?a=webssh" + echo " - zaloguj się, uruchom narzędzie komendą: nightscout-tool" + echo " - wybierz: 【 C) Sprztąj... 】" + echo " - wybierz: 【 A) Posprzątaj wszystko 】 i potwierdź 【 Tak 】" + echo " - cierpliwie poczekaj, po sprzątaniu narzędzie pokaże ile miejsca zwolniono" + } | pusher "🧹_Powoli_kończy_sie_miejsce_na_Twoim_serwerze_Nightscout!" + echo "Free space on server: LOW (${remainingTxt}) - sending email to user" + else + echo "Free space on server: LOW (${remainingTxt}) - user already notified" + fi + fi + else + clear_last_time "disk_critical" + clear_last_time "disk_warning" + echo "Free space on server: OK (${remainingTxt})" + fi +} + watchdog_check() { echo "Nightscout Watchdog mode" @@ -2135,6 +2237,8 @@ watchdog_check() { WATCHDOG_LAST_STATUS="unknown" fi + free_space_check + local NS_STATUS=$(get_container_status_code 'ns-server') local DB_STATUS=$(get_container_status_code 'ns-database') local COMBINED_STATUS="$NS_STATUS $DB_STATUS" @@ -2178,7 +2282,7 @@ watchdog_check() { fi fi else - regex3='coś poszło nie tak' + regex3='poszło nie tak' if [[ "$html" =~ $regex3 ]]; then echo "Nightscout is still restarting..." WATCHDOG_STATUS="awaiting" diff --git a/src/lib.sh b/src/lib.sh index b46148d..8d301fc 100644 --- a/src/lib.sh +++ b/src/lib.sh @@ -9,6 +9,7 @@ REQUIRED_NODE_VERSION=18.0.0 LOGTO=/dev/null NIGHTSCOUT_ROOT_DIR=/srv/nightscout CONFIG_ROOT_DIR=/srv/nightscout/config +DATA_ROOT_DIR=/srv/nightscout/data ENV_FILE_ADMIN=/srv/nightscout/config/admin.env ENV_FILE_NS=/srv/nightscout/config/nightscout.env ENV_FILE_DEP=/srv/nightscout/config/deployment.env @@ -28,8 +29,12 @@ TOOL_FILE=/srv/nightscout/tools/nightscout-tool TOOL_LINK=/usr/bin/nightscout-tool UPDATES_DIR=/srv/nightscout/updates UPDATE_CHANNEL=master +DISK_LOW_WARNING=838860800 # == 800 MiB +DISK_LOW_MAIL=5184000 # == 60 days in seconds +DISK_CRITICAL_WARNING=104857600 # == 100 MiB +DISK_CRITICAL_MAIL=604800 # == 7 days in seconds SCRIPT_VERSION="1.9.0" #auto-update -SCRIPT_BUILD_TIME="2024.10.06" #auto-update +SCRIPT_BUILD_TIME="2024.10.12" #auto-update #======================================= # SETUP @@ -227,6 +232,31 @@ exit_on_no_cancel() { fi } +get_since_last_time() { + local actionName=$1 + local actionFile="${DATA_ROOT_DIR}/last_${actionName}" + if [ -f "$actionFile" ]; then + local actionLast="$(<"$actionFile")" + local nowDate="$(date +'%s')" + echo $((nowDate - actionLast)) + else + echo -1 + fi +} + +set_last_time() { + local actionName=$1 + local actionFile="${DATA_ROOT_DIR}/last_${actionName}" + local nowDate="$(date +'%s')" + echo "$nowDate" > "$actionFile" +} + +clear_last_time() { + local actionName=$1 + local actionFile="${DATA_ROOT_DIR}/last_${actionName}" + rm -f "$actionFile" +} + #======================================= # HELPERS #======================================= @@ -1294,7 +1324,7 @@ get_watchdog_status_code_live() { status="crashed" fi - regex3='coś poszło nie tak' + regex3='poszło nie tak' if [[ "$html" =~ $regex3 ]]; then status="awaiting" fi @@ -2004,7 +2034,7 @@ main_menu() { local quickStatus=$(center_text "Strona Nightscout: $(get_watchdog_status "$(get_watchdog_status_code_live)" "$uni_ns_ok")" 55) local quickVersion=$(center_text "Wersja: $ns_tag" 55) local quickDomain=$(center_text "Domena: $(get_domain_status 'ns-server')" 55) - local CHOICE=$(whiptail --title "Zarządzanie Nightscoutem :: $SCRIPT_VERSION" --menu "\n$quickStatus\n$quickVersion\n$quickDomain\n" 19 60 9 \ + local CHOICE=$(whiptail --title "Zarządzanie Nightscoutem :: $SCRIPT_VERSION" --menu "\n$quickStatus\n$quickVersion\n$quickDomain\n" 21 60 9 \ "S)" "Status kontenerów i logi" \ "P)" "Pokaż port i API SECRET" \ "U)" "Aktualizuj..." \ @@ -2092,6 +2122,78 @@ install_or_menu() { fi } +free_space_check() { + lastTimeSpaceInfo=$(get_space_info) + + local remainingB=$(echo "$lastTimeSpaceInfo" | awk '{print $3}') + local remainingTxt=$(echo "$lastTimeSpaceInfo" | awk '{print $3}' | numfmt --to iec-i --suffix=B) + + if ((remainingB < DISK_LOW_WARNING)); then + if ((remainingB < DISK_CRITICAL_WARNING)); then + local lastCalled=$(get_since_last_time "disk_critical") + local domain=$(get_td_domain) + if ((lastCalled == -1)) || ((lastCalled > DISK_CRITICAL_MAIL)); then + set_last_time "disk_critical" + { + echo "Na twoim serwerze mikr.us z Nightscoutem (https://$domain) zostało krytycznie mało miejsca (${remainingTxt})!" + echo " " + echo "Tak mała ilość miejsca nie pozwala serwerowi na stabilne działanie!" + echo "🚨PILNIE🚨 posprzątaj na serwerze, aby to zrobić możesz:" + echo " " + echo "1. Usunąć stare statusy i wpisy z poziomu strony Nightscout:" + echo " - wejdź do hamburger menu strony Nightscout i wybierz: 【 Narzędzia administratora 】- wymaga zalogowania" + echo " to powinno otwórzyć adres: https://${domain}/admin" + echo " - w polach tekstowych poustawiaj ile dni historii chcesz zachować, i w odpowiednich sekcjach kliknij:" + echo " 【 Usuń stare dokumenty 】" + echo " " + echo "2. Posprzątać nieużywane pliki na serwerze mikr.us:" + echo " - zaloguj się na swój mikr.us do panelu administracyjnego, przejdź do WebSSH" + echo " https://mikr.us/panel/?a=webssh" + echo " - zaloguj się, uruchom narzędzie komendą: nightscout-tool" + echo " - wybierz: 【 C) Sprztąj... 】" + echo " - wybierz: 【 A) Posprzątaj wszystko 】 i potwierdź 【 Tak 】" + echo " - cierpliwie poczekaj, po sprzątaniu narzędzie pokaże ile miejsca zwolniono" + } | pusher "🚨_Krytycznie_mało_miejsca_na_Twoim_serwerze_Nightscout!" + echo "Free space on server: CRITICALLY LOW (${remainingTxt}) - sending email to user" + else + echo "Free space on server: CRITICALLY LOW (${remainingTxt}) - user already notified" + fi + else + local lastCalled=$(get_since_last_time "disk_warning") + local domain=$(get_td_domain) + if ((lastCalled == -1)) || ((lastCalled > DISK_LOW_MAIL)); then + set_last_time "disk_warning" + { + echo "Na twoim serwerze mikr.us z Nightscout-em (https://$domain) powoli kończy się miejsce (${remainingTxt})!" + echo " " + echo "🧹 W wolnej chwili posprzątaj na serwerze, aby to zrobić możesz:" + echo " " + echo "1. Usunąć stare statusy i wpisy z poziomu strony Nightscout:" + echo " - wejdź do hamburger menu strony Nightscout i wybierz:【 Narzędzia administratora 】- wymaga zalogowania" + echo " to powinno otwórzyć adres: https://${domain}/admin" + echo " - w polach tekstowych poustawiaj ile dni historii chcesz zachować, i w odpowiednich sekcjach kliknij:" + echo " 【 Usuń stare dokumenty 】" + echo " " + echo "2. Posprzątać nieużywane pliki na serwerze mikr.us:" + echo " - zaloguj się na swój mikr.us do panelu administracyjnego, przejdź do WebSSH" + echo " https://mikr.us/panel/?a=webssh" + echo " - zaloguj się, uruchom narzędzie komendą: nightscout-tool" + echo " - wybierz: 【 C) Sprztąj... 】" + echo " - wybierz: 【 A) Posprzątaj wszystko 】 i potwierdź 【 Tak 】" + echo " - cierpliwie poczekaj, po sprzątaniu narzędzie pokaże ile miejsca zwolniono" + } | pusher "🧹_Powoli_kończy_sie_miejsce_na_Twoim_serwerze_Nightscout!" + echo "Free space on server: LOW (${remainingTxt}) - sending email to user" + else + echo "Free space on server: LOW (${remainingTxt}) - user already notified" + fi + fi + else + clear_last_time "disk_critical" + clear_last_time "disk_warning" + echo "Free space on server: OK (${remainingTxt})" + fi +} + watchdog_check() { echo "Nightscout Watchdog mode" @@ -2119,6 +2221,8 @@ watchdog_check() { WATCHDOG_LAST_STATUS="unknown" fi + free_space_check + local NS_STATUS=$(get_container_status_code 'ns-server') local DB_STATUS=$(get_container_status_code 'ns-database') local COMBINED_STATUS="$NS_STATUS $DB_STATUS" @@ -2162,7 +2266,7 @@ watchdog_check() { fi fi else - regex3='coś poszło nie tak' + regex3='poszło nie tak' if [[ "$html" =~ $regex3 ]]; then echo "Nightscout is still restarting..." WATCHDOG_STATUS="awaiting" diff --git a/updated b/updated index b9b3476..f53efe9 100644 --- a/updated +++ b/updated @@ -1 +1 @@ -2024-10-06T20:32:19.387Z \ No newline at end of file +2024-10-12T09:37:14.904Z \ No newline at end of file -- 2.38.5 From b42f7f6608e23ba1b50a84c10fb6f996e6adfc61 Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Sat, 12 Oct 2024 23:28:13 +0000 Subject: [PATCH 13/14] Release 1.9.0 --- updated | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/updated b/updated index f53efe9..74577c3 100644 --- a/updated +++ b/updated @@ -1 +1 @@ -2024-10-12T09:37:14.904Z \ No newline at end of file +2024-10-12T23:27:19.837Z \ No newline at end of file -- 2.38.5 From af56d0c08e429a2c94c1650856e67e2bb7a6ceb2 Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Sat, 12 Oct 2024 23:42:11 +0000 Subject: [PATCH 14/14] Release 1.9.0 --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8e0cd0..d6dab05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.9.0] - 2024-10-12 + +### Added + +- Cleanup menu +- Gathering and sending encrypted diagnostics +- Watchdog notifications for low free space + +### Changed + +- Main menu, moved update items to its own submenu +- Added diagnostics encryption key to about dialog + +### Fixed + +- More robust watchdog, detects and restarts stale MongoDB + ## [1.8.1] - 2024-01-17 ### Added -- 2.38.5