From e897ad8d66e1bd77bde9507f4547ef5bbd46378d Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Tue, 6 Jan 2026 11:59:30 +0100 Subject: [PATCH] Forced update command line --- install.sh | 4 ++ src/commandline.sh | 119 +++++++++++++++++++++++++------------ src/logic_update.sh | 141 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+), 38 deletions(-) diff --git a/install.sh b/install.sh index fde4f0d..2c2d931 100755 --- a/install.sh +++ b/install.sh @@ -227,6 +227,10 @@ ohai() { fi } +msgprint() { + printf "%s\n" "$(shell_join "$@")" +} + msgok() { if [ "$NONINTERACTIVE_MODE" = "true" ]; then # shellcheck disable=SC2059 diff --git a/src/commandline.sh b/src/commandline.sh index 24df178..9a5b13f 100644 --- a/src/commandline.sh +++ b/src/commandline.sh @@ -8,7 +8,8 @@ Usage: nightscout-tool [options] Description: - Nightscout-tool is a command-line tool for managing Nightscout. + Nightscout-tool is a command-line tool for managing Nightscout instance + and its containers on mikr.us hosting. In UI mode, tool provides a menu-driven interface for managing Nightscout server, its configuration, updates, cleanup, and diagnostics. @@ -22,11 +23,12 @@ Options: -l, --loud Enable debug logging (UI) or verbose mode (non-int.) -d, --develop Switch to DEVELOP update channel -p, --production Switch to PRODUCTION update channel - -u, --update Force update check + -u, --update Perform unattended update of tool -c, --channel Switch to specified update channel -s, --cleanup Perform cleanup -r, --restart Restart containers --update-ns Update Nightscout and Mongo containers + --force-check Force update check in UI mode -h, --help Show this help message EOF } @@ -35,7 +37,10 @@ parse_commandline_args() { load_update_channel - CMDARGS=$(getopt --quiet -o wvldpuc:srh --long watchdog,version,loud,develop,production,update,channel:,cleanup,restart,update-ns,help -n 'nightscout-tool' -- "$@") + CMDARGS=$(getopt --quiet \ + -o wvldpuc:srh \ + --long watchdog,version,loud,develop,production,update,force-check,channel:,cleanup,restart,update-ns,help \ + -n 'nightscout-tool' -- "$@") # shellcheck disable=SC2181 if [ $? != 0 ]; then @@ -47,7 +52,11 @@ parse_commandline_args() { eval set -- "$CMDARGS" WATCHDOGMODE=false - NONINTERACTIVE_MODE=false + NONINTERACTIVE_MODE=false + local action="" + local new_channel="" + + # First pass: gather configuration and determine action while true; do case "$1" in -w | --watchdog) @@ -56,70 +65,60 @@ parse_commandline_args() { shift ;; -v | --version) - echo "$SCRIPT_VERSION" - exit 0 + action="version" + shift ;; -l | --loud) - warn "Loud mode, enabling debug logging" - FORCE_DEBUG_LOG="1" - update_logto + FORCE_DEBUG_LOG="1" shift ;; -d | --develop) - warn "Switching to DEVELOP update channel" - UPDATE_CHANNEL=develop + new_channel="develop" forceUpdateCheck=1 - echo "$UPDATE_CHANNEL" >"$UPDATE_CHANNEL_FILE" - update_logto shift ;; -p | --production) - warn "Switching to PRODUCTION update channel" - UPDATE_CHANNEL=master + new_channel="master" forceUpdateCheck=1 - echo "$UPDATE_CHANNEL" >"$UPDATE_CHANNEL_FILE" - update_logto shift ;; - -u | --update) - warn "Forcing update check" + -f | --force-check) forceUpdateCheck=1 shift ;; + -u | --update) + action="update" + shift + ;; -c | --channel) shift # The arg is next in position args - UPDATE_CHANNEL_CANDIDATE=$1 + new_channel=$1 forceUpdateCheck=1 - [[ ! "$UPDATE_CHANNEL_CANDIDATE" =~ ^[a-z]{3,}$ ]] && { - echo "Incorrect channel name provided: $UPDATE_CHANNEL_CANDIDATE" + [[ ! "$new_channel" =~ ^[a-z]{3,}$ ]] && { + echo "Incorrect channel name provided: $new_channel" exit 1 } - - warn "Switching to $UPDATE_CHANNEL_CANDIDATE update channel" - UPDATE_CHANNEL="$UPDATE_CHANNEL_CANDIDATE" - echo "$UPDATE_CHANNEL" >"$UPDATE_CHANNEL_FILE" - update_logto shift ;; -s | --cleanup) NONINTERACTIVE_MODE=true - do_cleanup_all - exit 0 + action="cleanup" + shift ;; -r | --restart) NONINTERACTIVE_MODE=true - do_restart - exit 0 + action="restart" + shift ;; --update-ns) NONINTERACTIVE_MODE=true - do_update_ns - exit 0 + action="update-ns" + shift ;; -h | --help) - help - exit 0 + action="help" + shift ;; --) shift @@ -129,10 +128,54 @@ parse_commandline_args() { esac done + # Apply configuration + if [ -n "$FORCE_DEBUG_LOG" ]; then + warn "Loud mode, enabling debug logging" + update_logto + fi + + if [ -n "$new_channel" ]; then + warn "Switching to $new_channel update channel" + UPDATE_CHANNEL="$new_channel" + echo "$UPDATE_CHANNEL" >"$UPDATE_CHANNEL_FILE" + update_logto + fi + + if [ "$forceUpdateCheck" = "1" ]; then + warn "Forcing update check" + fi + + # Second pass: execute action or continue + case "$action" in + version) + echo "$SCRIPT_VERSION" + exit 0 + ;; + help) + help + exit 0 + ;; + cleanup) + do_cleanup_all + exit 0 + ;; + restart) + do_restart + exit 0 + ;; + update) + do_update_tool + exit 0 + ;; + update-ns) + do_update_ns + exit 0 + ;; + esac + if [ "$WATCHDOGMODE" = "true" ]; then - startup_version - startup_debug + startup_version + startup_debug watchdog_check fi - } diff --git a/src/logic_update.sh b/src/logic_update.sh index a1fafd0..632a809 100644 --- a/src/logic_update.sh +++ b/src/logic_update.sh @@ -141,3 +141,144 @@ download_if_needed() { msgok "Too soon to download update, skipping..." fi } + +download_update_forced() { + local timestampNow=$(date +%s) + local lastDownload=$(read_or_default "$UPDATES_DIR/downloaded" "") + + echo "$timestampNow" >"$UPDATES_DIR/timestamp" + ohai "Downloading updates..." + local url=$(get_url "updated") + local onlineUpdated=$(curl -fsSL "$url" 2>>"$LOGTO") + if [[ -z "$onlineUpdated" && -z "$GITHUB_UNAVAILABLE" ]]; then + mark_github_unavailable + url=$(get_url "updated") + ohai "GitHub failed, retrying with Gitea (version check)..." + onlineUpdated=$(curl -fsSL "$url" 2>>"$LOGTO") + fi + + if [ "$onlineUpdated" == "$lastDownload" ] then + msgdebug "Downloaded update will be the same as last downloaded" + fi + + # we downlaod it anyway + download_updates +} + + +do_update_tool() { + download_update_forced + + local lastDownload=$(read_or_default "$UPDATES_DIR/downloaded" "???") + local updateInstalled=$(read_or_default "$UPDATES_DIR/updated" "???") + + if [ "$lastDownload" == "error" ]; then + msgerr "Aktualizacja niemożliwa" + msgerr "Nie można w tej chwili aktualizować narzędzia.${TL}Spróbuj ponownie później.${NL}Jeśli problem nie ustąpi - sprawdź konfigurację kanału aktualizacji" + else + + if [ "$UPDATE_CHANNEL" == "master" ] && [[ "$lastDownload" < "$updateInstalled" ]]; then + msgerr "Downgrade niemożliwy na produkcyjnym kanale aktualizacji" + else + + local changed=0 + local redeploy=0 + + local instOnlineVer=$(extract_version "$(<"$UPDATES_DIR/install.sh")") + local depEnvOnlineVer=$(extract_version "$(<"$UPDATES_DIR/deployment.env")") + local nsEnvOnlineVer=$(extract_version "$(<"$UPDATES_DIR/nightscout.env")") + local compOnlineVer=$(extract_version "$(<"$UPDATES_DIR/docker-compose.yml")") + + local instLocalVer=$(extract_version "$(<"$TOOL_FILE")") + local depEnvLocalVer=$(extract_version "$(<"$ENV_FILE_DEP")") + local nsEnvLocalVer=$(extract_version "$(<"$ENV_FILE_NS")") + local compLocalVer=$(extract_version "$(<"$DOCKER_COMPOSE_FILE")") + + local msgInst="$(printf "\U1F7E2") $instLocalVer" + local msgDep="$(printf "\U1F7E2") $depEnvLocalVer" + local msgNs="$(printf "\U1F7E2") $nsEnvLocalVer" + local msgComp="$(printf "\U1F7E2") $compLocalVer" + + if ! [ "$instOnlineVer" == "$instLocalVer" ] || ! [ "$lastDownload" == "$updateInstalled" ]; then + changed=$((changed + 1)) + msgInst="$(printf "\U1F534") $instLocalVer $(printf "\U27A1") $instOnlineVer" + fi + + if ! [ "$depEnvLocalVer" == "$depEnvOnlineVer" ]; then + changed=$((changed + 1)) + redeploy=$((redeploy + 1)) + msgDep="$(printf "\U1F534") $depEnvLocalVer $(printf "\U27A1") $depEnvOnlineVer" + fi + + if ! [ "$nsEnvLocalVer" == "$nsEnvOnlineVer" ]; then + changed=$((changed + 1)) + redeploy=$((redeploy + 1)) + msgNs="$(printf "\U1F534") $nsEnvLocalVer $(printf "\U27A1") $nsEnvOnlineVer" + fi + + if ! [ "$compLocalVer" == "$compOnlineVer" ]; then + changed=$((changed + 1)) + redeploy=$((redeploy + 1)) + msgComp="$(printf "\U1F534") $compLocalVer $(printf "\U27A1") $compOnlineVer" + fi + + if [ "$changed" -eq 0 ]; then + if [ $# -eq 1 ]; then + msgok "Aktualizacja skryptów nie jest potrzebna" + fi + else + local okTxt="" + if [ "$redeploy" -gt 0 ]; then + okTxt="${TL}${uni_warn} Aktualizacja zrestartuje i zaktualizuje kontenery ${uni_warn}" + fi + + local versionMsg="${TL}Build: ${updateInstalled}" + if [ ! "$lastDownload" == "$updateInstalled" ]; then + versionMsg="$(pad_multiline "${TL}Masz build: ${updateInstalled}${NL} Dostępny: ${lastDownload}")" + fi + + okhaimsgprint "Aktualizacja plików: ${versionMsg}" \ + "$( + pad_multiline \ + "${TL}${uni_bullet}Skrypt instalacyjny: $msgInst" \ + "${NL}${uni_bullet}Konfiguracja deploymentu: $msgDep" \ + "${NL}${uni_bullet}Konfiguracja Nightscout: $msgNs" \ + "${NL}${uni_bullet}Kompozycja usług: $msgComp${NL}" + )" \ + "$okTxt" + + if ! [ $? -eq 1 ]; then + + clear_last_time "update_needed" + + if [ "$redeploy" -gt 0 ]; then + docker_compose_down + fi + + if ! [ "$compOnlineVer" == "$compLocalVer" ]; then + ohai "Updating $DOCKER_COMPOSE_FILE" + cp -fr "$UPDATES_DIR/docker-compose.yml" "$DOCKER_COMPOSE_FILE" + fi + + if ! [ "$depEnvLocalVer" == "$depEnvOnlineVer" ]; then + ohai "Updating $ENV_FILE_DEP" + dotenv-tool -pr -o "$ENV_FILE_DEP" -i "$UPDATES_DIR/deployment.env" "$ENV_FILE_DEP" + fi + + if ! [ "$nsEnvLocalVer" == "$nsEnvOnlineVer" ]; then + ohai "Updating $ENV_FILE_NS" + dotenv-tool -pr -o "$ENV_FILE_NS" -i "$UPDATES_DIR/deployment.env" "$ENV_FILE_NS" + fi + + echo "$lastDownload" >"$UPDATES_DIR/updated" + + if ! [ "$instOnlineVer" == "$instLocalVer" ] || ! [ "$lastDownload" == "$updateInstalled" ]; then + ohai "Updating $TOOL_FILE" + cp -fr "$UPDATES_DIR/install.sh" "$TOOL_FILE" + msgok "Aktualizacja zakończona" + fi + fi + fi + fi + fi +} \ No newline at end of file