diff --git a/README.md b/README.md index 067ea80..4e24255 100644 --- a/README.md +++ b/README.md @@ -52,37 +52,47 @@ git clone https://github.com/th33xitus/kiauh.git

Klipper

Moonraker

Mainsail

-

Fluidd

Klipper Logo Arksine avatar Mainsail Logo -Fluidd Logo by KevinOConnor by Arksine by mainsail-crew -by fluidd-core +

Fluidd

KlipperScreen

-

Moonraker-Telegram-Bot

-

PrettyGCode for Klipper

OctoPrint

+Fluidd Logo jordanruthe avatar -nlef avatar -Kragrathea avatar OctoPrint Logo +by fluidd-core by jordanruthe +by OctoPrint + +

Moonraker-Telegram-Bot

+

PrettyGCode for Klipper

+

Obico for Klipper

+ + + +nlef avatar +Kragrathea avatar +Obico logo + + + by nlef by Kragrathea -by OctoPrint +by Obico diff --git a/docs/changelog.md b/docs/changelog.md index 50d7ce0..f449f3a 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,9 @@ This document covers possible important changes to KIAUH. +### 2022-08-15 +Support for "Obico for Klipper" was added! Huge thanks to [kennethjiang](https://github.com/kennethjiang) for helping me with the implementation! + ### 2022-05-29 KIAUH has now reached major version 4 ! * feat: Klipper can be installed under Python3 (still considered as experimental) diff --git a/scripts/globals.sh b/scripts/globals.sh index 4b1ca67..5eb327b 100644 --- a/scripts/globals.sh +++ b/scripts/globals.sh @@ -70,4 +70,8 @@ function set_globals() { NGINX_SA="/etc/nginx/sites-available" NGINX_SE="/etc/nginx/sites-enabled" NGINX_CONFD="/etc/nginx/conf.d" -} \ No newline at end of file + + #=============== MOONRAKER-OBICO ================# + MOONRAKER_OBICO_DIR="${HOME}/moonraker-obico" + MOONRAKER_OBICO_REPO="https://github.com/TheSpaghettiDetective/moonraker-obico.git" +} diff --git a/scripts/moonraker.sh b/scripts/moonraker.sh index 294054c..a773dc5 100644 --- a/scripts/moonraker.sh +++ b/scripts/moonraker.sh @@ -15,9 +15,24 @@ set -e #================ INSTALL MOONRAKER ================# #===================================================# +### +# this function detects all installed moonraker +# systemd instances and returns their absolute path function moonraker_systemd() { local services - services=$(find "${SYSTEMD}" -maxdepth 1 -regextype posix-extended -regex "${SYSTEMD}/moonraker(-[0-9a-zA-Z]+)?.service" | sort) + local blacklist + local ignore + local match + + ### + # any moonraker client that uses "moonraker" in its own name must be blacklisted using + # this variable, otherwise they will be falsely recognized as moonraker instances + blacklist="obico" + + ignore="${SYSTEMD}/moonraker-(${blacklist}).service" + match="${SYSTEMD}/moonraker(-[0-9a-zA-Z]+)?.service" + + services=$(find "${SYSTEMD}" -maxdepth 1 -regextype awk ! -regex "${ignore}" -regex "${match}" | sort) echo "${services}" } @@ -572,4 +587,4 @@ function compare_moonraker_versions() { fi echo "${versions}" -} \ No newline at end of file +} diff --git a/scripts/obico.sh b/scripts/obico.sh new file mode 100644 index 0000000..5ccca70 --- /dev/null +++ b/scripts/obico.sh @@ -0,0 +1,444 @@ +#!/usr/bin/env bash + +#=======================================================================# +# Copyright (C) 2020 - 2022 Dominik Willner # +# # +# This file is part of KIAUH - Klipper Installation And Update Helper # +# https://github.com/th33xitus/kiauh # +# # +# This file may be distributed under the terms of the GNU GPLv3 license # +#=======================================================================# + +set -e + +#===================================================# +#============== INSTALL MOONRAKER-OBICO ============# +#===================================================# + +function moonraker_obico_systemd() { + local services + services=$(find "${SYSTEMD}" -maxdepth 1 -regextype posix-extended -regex "${SYSTEMD}/moonraker-obico(-[0-9a-zA-Z]+)?.service") + echo "${services}" +} + +function moonraker_obico_config() { + local moonraker_cfg_dirs + + read -r -a moonraker_cfg_dirs <<< "$(get_config_folders)" + + if (( ${#moonraker_cfg_dirs[@]} > 0 )); then + echo "${moonraker_cfg_dirs[${1}]}/moonraker-obico.cfg" + else + echo "" + fi +} + +function moonraker_obico_needs_linking() { + local moonraker_obico_cfg=${1} + if [[ ! -f "${moonraker_obico_cfg}" ]]; then + return 1 + fi + if grep -s -E "^[^#]" "${moonraker_obico_cfg}" | grep -q 'auth_token'; then + return 1 + else + return 0 + fi +} + +function obico_server_url_prompt() { + top_border + printf "|${green}%-55s${white}|\n" " Obico Server URL" + blank_line + echo -e "| You can use a self-hosted Obico Server or the Obico |" + echo -e "| Cloud. For more information, please visit: |" + echo -e "| https://obico.io. |" + blank_line + echo -e "| For the Obico Cloud, leave it as the default: |" + printf "|${cyan}%-55s${white}|\n" " https://app.obico.io" + blank_line + echo -e "| For self-hosted server, specify: |" + printf "|${cyan}%-55s${white}|\n" " http://server_ip:port" + echo -e "| For instance, 'http://192.168.0.5:3334'. |" + bottom_border +} + +function moonraker_obico_setup_dialog() { + status_msg "Initializing Moonraker-obico installation ..." + + + local moonraker_count + local moonraker_names + + moonraker_count=$(moonraker_systemd | wc -w) + + if (( moonraker_count == 0 )); then + ### return early if moonraker is not installed + local error="Moonraker not installed! Please install Moonraker first!" + log_error "Moonraker-obico setup started without Moonraker being installed. Aborting setup." + print_error "${error}" && return + elif (( moonraker_count > 1 )); then + # moonraker_names is valid only in case of multi-instance + read -r -a moonraker_names <<< "$(get_multi_instance_names)" + fi + + local moonraker_obico_services + local existing_moonraker_obico_count + moonraker_obico_services=$(moonraker_obico_systemd) + existing_moonraker_obico_count=$(echo "${moonraker_obico_services}" | wc -w ) + local allowed_moonraker_obico_count=$(( moonraker_count - existing_moonraker_obico_count )) + if (( allowed_moonraker_obico_count > 0 )); then + local new_moonraker_obico_count + + ### Step 1: Ask for the number of moonraker-obico instances to install + if (( moonraker_count == 1 )); then + ok_msg "Moonraker installation found!\n" + new_moonraker_obico_count=1 + elif (( moonraker_count > 1 )); then + top_border + printf "|${green}%-55s${white}|\n" " ${moonraker_count} Moonraker instances found!" + for name in "${moonraker_names[@]}"; do + printf "|${cyan}%-57s${white}|\n" " ● moonraker-${name}" + done + blank_line + if (( existing_moonraker_obico_count > 0 )); then + printf "|${green}%-55s${white}|\n" " ${existing_moonraker_obico_count} Moonraker-obico instances already installed!" + for svc in ${moonraker_obico_services}; do +# printf "|${cyan}%-57s${white}|\n" " ● moonraker-obco-$(get_instance_name "${svc}" moonraker-obico)" + printf "|${cyan}%-57s${white}|\n" " ● moonraker-obco-$(get_instance_name "${svc}")" + done + fi + blank_line + echo -e "| The setup will apply the same names to |" + echo -e "| Moonraker-obico! |" + blank_line + echo -e "| Please select the number of Moonraker-obico instances |" + echo -e "| to install. Usually one Moonraker-obico instance per |" + echo -e "| Moonraker instance is required, but you may not |" + echo -e "| install more Moonraker-obico instances than available |" + echo -e "| Moonraker instances. |" + bottom_border + + ### ask for amount of instances + local re="^[1-9][0-9]*$" + while [[ ! ${new_moonraker_obico_count} =~ ${re} || ${new_moonraker_obico_count} -gt ${allowed_moonraker_obico_count} ]]; do + read -p "${cyan}###### Number of new Moonraker-obico instances to set up:${white} " -i "${allowed_moonraker_obico_count}" -e new_moonraker_obico_count + ### break if input is valid + [[ ${new_moonraker_obico_count} =~ ${re} && ${new_moonraker_obico_count} -le ${allowed_moonraker_obico_count} ]] && break + ### conditional error messages + [[ ! ${new_moonraker_obico_count} =~ ${re} ]] && error_msg "Input not a number" + (( new_moonraker_obico_count > allowed_moonraker_obico_count )) && error_msg "Number of Moonraker-obico instances larger than installed Moonraker instances" + done && select_msg "${new_moonraker_obico_count}" + else + log_error "Internal error. moonraker_count of '${moonraker_count}' not equal or grather than one!" + return 1 + fi # (( moonraker_count == 1 )) + + ### Step 2: Confirm instance amount + local yn + while true; do + (( new_moonraker_obico_count == 1 )) && local question="Install Moonraker-obico?" + (( new_moonraker_obico_count > 1 )) && local question="Install ${new_moonraker_obico_count} Moonraker-obico instances?" + read -p "${cyan}###### ${question} (Y/n):${white} " yn + case "${yn}" in + Y|y|Yes|yes|"") + select_msg "Yes" + break;; + N|n|No|no) + select_msg "No" + abort_msg "Exiting Moonraker-obico setup ...\n" + return;; + *) + error_msg "Invalid Input!";; + esac + done + fi # (( allowed_moonraker_obico_count > 0 )) + + if (( new_moonraker_obico_count > 0 )); then + + ### Step 3: Ask for the Obico server URL + obico_server_url_prompt + local obico_server_url + while true; do + read -p "${cyan}###### Obico Server URL:${white} " -i "https://app.obico.io" -e obico_server_url + if echo "${obico_server_url}" | grep -qE "^(http|https)://[a-zA-Z0-9./?=_%:-]*"; then + break + else + error_msg "Invalid server URL!" + fi + done + + (( new_moonraker_obico_count > 1 )) && status_msg "Installing ${new_moonraker_obico_count} Moonraker-obico instances ..." + (( new_moonraker_obico_count == 1 )) && status_msg "Installing Moonraker-obico ..." + + ### Step 4: Install dependencies + local dep=(git dfu-util virtualenv python3 python3-pip python3-venv ffmpeg) + dependency_check "${dep[@]}" + + ### Step 5: Clone the moonraker-obico repo + clone_moonraker_obico "${MOONRAKER_OBICO_REPO}" + + ### step 6: call moonrake-obico/install.sh with the correct params + local port=7125 + local moonraker_cfg_dirs + + read -r -a moonraker_cfg_dirs <<< "$(get_config_folders)" + + if (( moonraker_count == 1 )); then + "${MOONRAKER_OBICO_DIR}/install.sh" -C "${moonraker_cfg_dirs[0]}/moonraker.conf" -p "${port}" -H 127.0.0.1 -l "${KLIPPER_LOGS}" -s -L -S "${obico_server_url}" + elif (( moonraker_count > 1 )); then + local j=${existing_moonraker_obico_count} + + for (( i=1; i <= new_moonraker_obico_count; i++ )); do + "${MOONRAKER_OBICO_DIR}/install.sh" -n "${moonraker_names[${j}]}" -C "${moonraker_cfg_dirs[${j}]}/moonraker.conf" -p $((port+j)) -H 127.0.0.1 -l "${KLIPPER_LOGS}" -s -L -S "${obico_server_url}" + j=$(( j + 1 )) + done && unset j + fi # (( moonraker_count == 1 )) + fi # (( new_moonraker_obico_count > 0 )) + + ### Step 7: Link to the Obico server if necessary + local not_linked_instances=() + if (( moonraker_count == 1 )); then + if moonraker_obico_needs_linking "$(moonraker_obico_config 0)"; then + not_linked_instances+=("0") + fi + elif (( moonraker_count > 1 )); then + for (( i=0; i <= moonraker_count; i++ )); do + if moonraker_obico_needs_linking "$(moonraker_obico_config "${i}")"; then + not_linked_instances+=("${i}") + fi + done + fi # (( moonraker_count == 1 )) + + if (( ${#not_linked_instances[@]} > 0 )); then + top_border + if (( moonraker_count == 1 )); then + printf "|${green}%-55s${white}|\n" " Moonraker-obico not linked to the server!" + else + printf "|${green}%-55s${white}|\n" " ${#not_linked_instances[@]} Moonraker-obico instances not linked to the server!" + for i in "${not_linked_instances[@]}"; do + printf "|${cyan}%-57s${white}|\n" " ● moonraker-obico-${moonraker_names[${i}]}" + done + fi + blank_line + echo -e "| To link to your Obico Server account, you need to |" + echo -e "| obtain the 6-digit verification code in the Obico |" + echo -e "| mobile or web app. For more information, visit: |" + echo -e "| https://www.obico.io/docs/user-guides/klipper-setup/ |" + blank_line + echo -e "| If you don't want to link the printer now, you can |" + echo -e "| restart the linking process later by: |" + echo -e "| 1. 'cd ~/kiauh && ./kiauh.sh' to launch KIAUH. |" + echo -e "| 2. Select ${green}[Install]${white} |" + echo -e "| 3. Select ${green}[Link to Obico Server]${white} |" + bottom_border + + while true; do + read -p "${cyan}###### Link to your Obico Server account now? (Y/n):${white} " yn + case "${yn}" in + Y|y|Yes|yes|"") + select_msg "Yes" + break;; + N|n|No|no) + select_msg "No" + abort_msg "Exiting Moonraker-obico setup ...\n" + return;; + *) + error_msg "Invalid Input!";; + esac + done + + if (( moonraker_count == 1 )); then + status_msg "Link moonraker-obico to the Obico Server..." + "${MOONRAKER_OBICO_DIR}/scripts/link.sh" -q -c "$(moonraker_obico_config 0)" + elif (( moonraker_count > 1 )); then + for i in "${not_linked_instances[@]}"; do + local name="${moonraker_names[i]}" + status_msg "Link moonraker-obico-${name} to the Obico Server..." + "${MOONRAKER_OBICO_DIR}/scripts/link.sh" -q -n "${name}" -c "$(moonraker_obico_config "${i}")" + done + fi # (( moonraker_count == 1 )) + fi # (( ${#not_linked_instances[@]} > 0 )) +} + +function clone_moonraker_obico() { + local repo=${1} + + status_msg "Cloning Moonraker-obico from ${repo} ..." + ### force remove existing Moonraker-obico dir + [[ -d "${MOONRAKER_OBICO_DIR}" ]] && rm -rf "${MOONRAKER_OBICO_DIR}" + + cd "${HOME}" || exit 1 + if ! git clone "${repo}" "${MOONRAKER_OBICO_DIR}"; then + print_error "Cloning Moonraker-obico from\n ${repo}\n failed!" + exit 1 + fi +} + +function moonraker_obico_install() { + "${MOONRAKER_OBICO_DIR}/install.sh" "$@" +} + +#===================================================# +#============= REMOVE MOONRAKER-OBICO ==============# +#===================================================# + +function remove_moonraker_obico_systemd() { + [[ -z $(moonraker_obico_systemd) ]] && return + status_msg "Removing Moonraker-obico Systemd Services ..." + + for service in $(moonraker_obico_systemd | cut -d"/" -f5); do + status_msg "Removing ${service} ..." + sudo systemctl stop "${service}" + sudo systemctl disable "${service}" + sudo rm -f "${SYSTEMD}/${service}" + ok_msg "Done!" + done + + ### reloading units + sudo systemctl daemon-reload + sudo systemctl reset-failed + ok_msg "Moonraker-obico Services removed!" +} + +function remove_moonraker_obico_logs() { + local files regex="moonraker-obico(-[0-9a-zA-Z]+)?\.log(.*)?" + files=$(find "${KLIPPER_LOGS}" -maxdepth 1 -regextype posix-extended -regex "${KLIPPER_LOGS}/${regex}" 2> /dev/null | sort) + + if [[ -n ${files} ]]; then + for file in ${files}; do + status_msg "Removing ${file} ..." + rm -f "${file}" + ok_msg "${file} removed!" + done + fi +} + +function remove_moonraker_obico_dir() { + [[ ! -d ${MOONRAKER_OBICO_DIR} ]] && return + + status_msg "Removing Moonraker-obico directory ..." + rm -rf "${MOONRAKER_OBICO_DIR}" + ok_msg "Directory removed!" +} + +function remove_moonraker_obico_env() { + [[ ! -d "${HOME}/moonraker-obico-env" ]] && return + + status_msg "Removing moonraker-obico-env directory ..." + rm -rf "${HOME}/moonraker-obico-env" + ok_msg "Directory removed!" +} + +function remove_moonraker_obico() { + remove_moonraker_obico_systemd + remove_moonraker_obico_logs + remove_moonraker_obico_dir + remove_moonraker_obico_env + + print_confirm "Moonraker-obico was successfully removed!" + return +} + +#===================================================# +#============= UPDATE MOONRAKER-OBICO ==============# +#===================================================# + +function update_moonraker_obico() { + do_action_service "stop" "moonraker-obico" + + if [[ ! -d ${MOONRAKER_OBICO_DIR} ]]; then + clone_moonraker_obico "${MOONRAKER_OBICO_REPO}" + else + status_msg "Updating Moonraker-obico ..." + cd "${MOONRAKER_OBICO_DIR}" && git pull + fi + + ok_msg "Update complete!" + do_action_service "restart" "moonraker-obico" +} + +#===================================================# +#============= MOONRAKER-OBICO STATUS ==============# +#===================================================# + +function get_moonraker_obico_status() { + local status + local service_count + local is_linked + local moonraker_obico_services + + moonraker_obico_services=$(moonraker_obico_systemd) + service_count=$(echo "${moonraker_obico_services}" | wc -w ) + + is_linked="true" + if [[ -n ${moonraker_obico_services} ]]; then + for cfg_dir in $(get_config_folders); do + if moonraker_obico_needs_linking "${cfg_dir}/moonraker-obico.cfg"; then + is_linked="false" + fi + done + fi + + if (( service_count == 0 )); then + status="Not installed!" + elif [[ ! -d "${MOONRAKER_OBICO_DIR}" ]]; then + status="Incomplete!" + elif [[ ${is_linked} == "false" ]]; then + status="Not linked!" + else + status="Installed!" + fi + + echo "${status}" +} + +function get_local_moonraker_obico_commit() { + [[ ! -d ${MOONRAKER_OBICO_DIR} || ! -d "${MOONRAKER_OBICO_DIR}/.git" ]] && return + + local commit + cd "${MOONRAKER_OBICO_DIR}" + commit="$(git describe HEAD --always --tags | cut -d "-" -f 1,2)" + echo "${commit}" +} + +function get_remote_moonraker_obico_commit() { + [[ ! -d ${MOONRAKER_OBICO_DIR} || ! -d "${MOONRAKER_OBICO_DIR}/.git" ]] && return + + local commit + cd "${MOONRAKER_OBICO_DIR}" && git fetch origin -q + commit=$(git describe origin/master --always --tags | cut -d "-" -f 1,2) + echo "${commit}" +} + +function compare_moonraker_obico_versions() { + local versions local_ver remote_ver + local_ver="$(get_local_moonraker_obico_commit)" + remote_ver="$(get_remote_moonraker_obico_commit)" + + if [[ ${local_ver} != "${remote_ver}" ]]; then + versions="${yellow}$(printf " %-14s" "${local_ver}")${white}" + versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}" + # add moonraker to application_updates_available in kiauh.ini + add_to_application_updates "moonraker_obico" + else + versions="${green}$(printf " %-14s" "${local_ver}")${white}" + versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}" + fi + + echo "${versions}" +} + +### +# it is possible, that moonraker_obico is installed in a so called +# "non-linked" state. the linking can be achieved by running the +# installation script again. this function will check the obico +# installation status and returns the correctly formulated menu title +# +function obico_install_title() { + if [[ $(get_moonraker_obico_status) == "Not linked!" ]]; then + echo "[Link to Obico Server]" + else + echo "[Obico for Klipper] " + fi +} + diff --git a/scripts/octoprint.sh b/scripts/octoprint.sh index 8bdd9f3..db118fe 100644 --- a/scripts/octoprint.sh +++ b/scripts/octoprint.sh @@ -404,4 +404,4 @@ function get_octoprint_status() { fi echo "${status}" -} \ No newline at end of file +} diff --git a/scripts/ui/install_menu.sh b/scripts/ui/install_menu.sh index 4fdb771..9f60e7f 100755 --- a/scripts/ui/install_menu.sh +++ b/scripts/ui/install_menu.sh @@ -19,16 +19,16 @@ function install_ui() { echo -e "| all necessary dependencies for the various |" echo -e "| functions on a completely fresh system. |" hr - echo -e "| Firmware & API: | 3rd Party Webinterface: |" - echo -e "| 1) [Klipper] | 6) [OctoPrint] |" - echo -e "| 2) [Moonraker] | |" - echo -e "| | Other: |" - echo -e "| Klipper Webinterface: | 7) [PrettyGCode] |" - echo -e "| 3) [Mainsail] | 8) [Telegram Bot] |" - echo -e "| 4) [Fluidd] | |" - echo -e "| | Webcam Streamer: |" - echo -e "| Touchscreen GUI: | 9) [MJPG-Streamer] |" - echo -e "| 5) [KlipperScreen] | |" + echo -e "| Firmware & API: | 3rd Party Webinterface: |" + echo -e "| 1) [Klipper] | 6) [OctoPrint] |" + echo -e "| 2) [Moonraker] | |" + echo -e "| | Other: |" + echo -e "| Klipper Webinterface: | 7) [PrettyGCode] |" + echo -e "| 3) [Mainsail] | 8) [Telegram Bot] |" + echo -e "| 4) [Fluidd] | 9) $(obico_install_title) |" + echo -e "| | |" + echo -e "| Touchscreen GUI: | Webcam Streamer: |" + echo -e "| 5) [KlipperScreen] | 10) [MJPG-Streamer] |" back_footer } @@ -36,6 +36,12 @@ function install_menu() { clear && print_header install_ui + ### save all installed webinterface ports to the ini file + fetch_webui_ports + + ### save all klipper multi-instance names to the ini file + set_multi_instance_names + local action while true; do read -p "${cyan}####### Perform action:${white} " action @@ -57,6 +63,8 @@ function install_menu() { 8) do_action "telegram_bot_setup_dialog" "install_ui";; 9) + do_action "moonraker_obico_setup_dialog" "install_ui";; + 10) do_action "install_mjpg-streamer" "install_ui";; B|b) clear; main_menu; break;; diff --git a/scripts/ui/main_menu.sh b/scripts/ui/main_menu.sh index f4e02a1..925fca6 100755 --- a/scripts/ui/main_menu.sh +++ b/scripts/ui/main_menu.sh @@ -24,6 +24,7 @@ function main_ui() { echo -e "| 5) [Backup] | Fluidd: $(print_status "fluidd")|" echo -e "| | KlipperScreen: $(print_status "klipperscreen")|" echo -e "| 6) [Settings] | Telegram Bot: $(print_status "telegram_bot")|" + echo -e "| | Obico: $(print_status "moonraker_obico")|" echo -e "| | |" echo -e "| $(print_kiauh_version)| Octoprint: $(print_status "octoprint")|" quit_footer @@ -50,6 +51,9 @@ function print_status() { status="${red}${status}${white}" elif [[ ${status} == "Incomplete!" ]]; then status="${yellow}${status}${white}" + elif [[ ${status} == "Not linked!" ]]; then + ### "Not linked!" is only required for Moonraker-obico + status="${yellow}${status}${white}" else status="${green}${status}${white}" fi diff --git a/scripts/ui/remove_menu.sh b/scripts/ui/remove_menu.sh index b58d2f9..4cf743d 100755 --- a/scripts/ui/remove_menu.sh +++ b/scripts/ui/remove_menu.sh @@ -26,7 +26,8 @@ function remove_ui() { echo -e "| 4) [Fluidd] | Other: |" echo -e "| | 8) [PrettyGCode] |" echo -e "| Touchscreen GUI: | 9) [Telegram Bot] |" - echo -e "| 5) [KlipperScreen] | 10) [NGINX] |" + echo -e "| 5) [KlipperScreen] | 10) [Obico for Klipper] |" + echo -e "| | 11) [NGINX] |" back_footer } @@ -56,6 +57,8 @@ function remove_menu() { 9) do_action "remove_telegram_bot" "remove_ui";; 10) + do_action "remove_moonraker_obico" "remove_ui";; + 11) do_action "remove_nginx" "remove_ui";; B|b) clear; main_menu; break;; diff --git a/scripts/ui/update_menu.sh b/scripts/ui/update_menu.sh index 3d6338d..a4fb2c3 100755 --- a/scripts/ui/update_menu.sh +++ b/scripts/ui/update_menu.sh @@ -31,8 +31,9 @@ function update_ui() { echo -e "| Other: |---------------|--------------|" echo -e "| 6) [PrettyGCode] |$(compare_prettygcode_versions)|" echo -e "| 7) [Telegram Bot] |$(compare_telegram_bot_versions)|" + echo -e "| 8) [Obico for Klipper]|$(compare_moonraker_obico_versions)|" echo -e "| |------------------------------|" - echo -e "| 8) [System] | $(check_system_updates) |" + echo -e "| 9) [System] | $(check_system_updates) |" back_footer } @@ -60,6 +61,8 @@ function update_menu() { 7) do_action "update_telegram_bot" "update_ui";; 8) + do_action "update_moonraker_obico" "update_ui";; + 9) do_action "update_system" "update_ui";; a) do_action "update_all" "update_ui";; diff --git a/scripts/utilities.sh b/scripts/utilities.sh index 8d4d385..88d83e3 100644 --- a/scripts/utilities.sh +++ b/scripts/utilities.sh @@ -178,16 +178,8 @@ function init_ini() { if ! grep -Eq "^multi_instance_names=" "${INI_FILE}"; then echo -e "\nmulti_instance_names=\c" >> "${INI_FILE}" - else - sed -i "/multi_instance_names=/s/=.*/=/" "${INI_FILE}" fi - ### save all installed webinterface ports to the ini file - fetch_webui_ports - - ### save all klipper multi-instance names to the ini file - fetch_multi_instance_names - ### strip all empty lines out of the file sed -i "/^[[:blank:]]*$/ d" "${INI_FILE}" } @@ -674,13 +666,25 @@ function set_hostname() { ok_msg "Remember to reboot for the changes to take effect!" } -### this function takes in the full path of a systemd service file and returns -### either the instance index or the custom name -### input: /etc/systemd/system/klipper-name.service -### returns: name +#================================================# +#============ INSTANCE MANAGEMENT ===============# +#================================================# + +### +# takes in a systemd service files full path and +# returns the sub-string with the instance name +# +# @param {string}: service file absolute path +# (e.g. '/etc/systemd/system/klipper-.service') +# +# => return sub-string containing only the part of the full string +# function get_instance_name() { - local instance=${1} name - name=$(echo "${instance}" | rev | cut -d"/" -f1 | rev | cut -d"-" -f2 | cut -d"." -f1) + local instance=${1} + local name + + name=$(echo "${instance}" | rev | cut -d"/" -f1 | cut -d"." -f2 | cut -d"-" -f1 | rev) + echo "${name}" } @@ -708,29 +712,84 @@ function get_klipper_instance_name() { } ### -# combines and saves each instance name/identifier -# to the kiauh.ini file in a comma separated format +# loops through all installed klipper services and saves +# each instances name in a comma separated format to the kiauh.ini # -function add_to_multi_instance_names() { +function set_multi_instance_names() { read_kiauh_ini "${FUNCNAME[0]}" - local name="${1}" - local names="${multi_instance_names}" + local name + local names="" + local services=$(klipper_systemd) - if ! grep -Eq "${name}" <<< "${names}"; then - names="${names}${name}," - sed -i "/multi_instance_names=/s/=.*/=${names}/" "${INI_FILE}" + ### + # if value of 'multi_instance_names' is not an empty + # string, delete its value, so it can be re-written + if [[ -n ${multi_instance_names} ]]; then + sed -i "/multi_instance_names=/s/=.*/=/" "${INI_FILE}" fi + + for svc in ${services}; do + name=$(get_klipper_instance_name "${svc}") + + if ! grep -Eq "${name}" <<<"${names}"; then + names="${names}${name}," + fi + + done + + # write up-to-date instance name string to kiauh.ini + sed -i "/multi_instance_names=/s/=.*/=${names}/" "${INI_FILE}" } ### -# loops through all installed klipper services and -# calls the 'add_to_multi_instance_names' on each one +# Helper function that returns all configured instance names # -function fetch_multi_instance_names() { - for service in $(klipper_systemd); do - local name - name=$(get_klipper_instance_name "${service}") - add_to_multi_instance_names "${name}" - done +# => return an empty string if 0 or 1 klipper instance is installed +# => return space-separated string for names of the configured instances +# if 2 or more klipper instances are installed +# +function get_multi_instance_names() { + read_kiauh_ini "${FUNCNAME[0]}" + local instance_names=() + + ### + # convert the comma separates string from the .kiauh.ini into + # an array of instance names. a single instance installation + # results in an empty instance_names array + IFS=',' read -r -a instance_names <<< "${multi_instance_names}" + + echo "${instance_names[@]}" +} + +### +# helper function that returns all possibly available absolute +# klipper config directory paths based on their instance name. +# +# => return an empty string if klipper is not installed +# => return space-separated string of absolute config directory paths +# +function get_config_folders() { + local cfg_dirs=() + local instance_names + instance_names=$(get_multi_instance_names) + + if [[ -n ${instance_names} ]]; then + for name in ${instance_names}; do + ### + # by KIAUH convention, all instance names of only numbers + # need to be prefixed with 'printer_' + if [[ ${name} =~ ^[0-9]+$ ]]; then + cfg_dirs+=("${KLIPPER_CONFIG}/printer_${name}") + else + cfg_dirs+=("${KLIPPER_CONFIG}/${name}") + fi + done + elif [[ -z ${instance_names} && $(klipper_systemd | wc -w) -gt 0 ]]; then + cfg_dirs+=("${KLIPPER_CONFIG}") + else + cfg_dirs=() + fi + + echo "${cfg_dirs[@]}" }