From 898a6bbfd04b96422f4d5a30a206464e7c8b005d Mon Sep 17 00:00:00 2001 From: th33xitus Date: Sun, 3 Apr 2022 20:07:48 +0200 Subject: [PATCH] refactor(octoprint.sh): full refactor Signed-off-by: Dominik Willner th33xitus@gmail.com --- scripts/octoprint.sh | 368 +++++++++++++++++++------------------------ 1 file changed, 164 insertions(+), 204 deletions(-) diff --git a/scripts/octoprint.sh b/scripts/octoprint.sh index 157d112..53314aa 100644 --- a/scripts/octoprint.sh +++ b/scripts/octoprint.sh @@ -19,48 +19,53 @@ OCTOPRINT_ENV="${HOME}/OctoPrint" #=============== INSTALL OCTOPRINT ===============# #=================================================# -octoprint_setup_dialog(){ +function octoprint_setup_dialog(){ status_msg "Initializing OctoPrint installation ..." - ### count amount of klipper services - if [ "$(systemctl list-units --full -all -t service --no-legend | grep -F "klipper.service")" ]; then - INSTANCE_COUNT=1 + local klipper_count + klipper_count=$(klipper_systemd | wc -w) + top_border + if [ -f "${INITD}/klipper" ] || [ -f "${SYSTEMD}/klipper.service" ]; then + printf "|${green}%-55s${white}|\n" " 1 Klipper instance was found!" + elif [ "${klipper_count}" -gt 1 ]; then + printf "|${green}%-55s${white}|\n" " ${klipper_count} Klipper instances were found!" else - INSTANCE_COUNT=$(systemctl list-units --full -all -t service --no-legend | grep -E "klipper-[[:digit:]].service" | wc -l) + echo -e "| ${yellow}INFO: No existing Klipper installation found!${default} |" fi + echo -e "| Usually you need one OctoPrint instance per Klipper |" + echo -e "| instance. Though you can install as many as you wish. |" + bottom_border - ### instance confirmation dialog - while true; do + local count + while [[ ! (${count} =~ ^[1-9]+((0)+)?$) ]]; do + read -p "${cyan}###### Number of OctoPrint instances to set up:${default} " count + if [[ ! (${count} =~ ^[1-9]+((0)+)?$) ]]; then + error_msg "Invalid Input!\n" + else echo - top_border - if [ $INSTANCE_COUNT -gt 1 ]; then - printf "|%-55s|\n" " $INSTANCE_COUNT Klipper instances were found!" - else - echo -e "| 1 Klipper instance was found! | " - fi - echo -e "| You need one OctoPrint instance per Klipper instance. | " - bottom_border - echo - read -p "${cyan}###### Create $INSTANCE_COUNT OctoPrint instances? (Y/n):${white} " yn - case "$yn" in - Y|y|Yes|yes|"") - echo -e "###### > Yes" - status_msg "Creating $INSTANCE_COUNT OctoPrint instances ..." - octoprint_setup - break;; - N|n|No|no) - echo -e "###### > No" - warn_msg "Exiting OctoPrint setup ..." - echo - break;; - *) - print_unkown_cmd - print_msg && clear_msg;; - esac + while true; do + read -p "${cyan}###### Install ${count} instance(s)? (Y/n):${default} " yn + case "${yn}" in + Y|y|Yes|yes|"") + select_msg "Yes" + status_msg "Installing ${count} OctoPrint instance(s) ... \n" + octoprint_setup "${count}" + break;; + N|n|No|no) + select_msg "No" + error_msg "Exiting OctoPrint setup ...\n" + break;; + *) + error_msg "Invalid Input!\n";; + esac + done + fi done } -octoprint_dependencies(){ +function octoprint_setup(){ + local instances="${1}" + ### check and install all dependencies dep=( git wget @@ -70,57 +75,86 @@ octoprint_dependencies(){ build-essential python-setuptools python-virtualenv - ) - dependency_check -} - -octoprint_setup(){ - ### check and install all dependencies - octoprint_dependencies + ) + dependency_check "${dep[@]}" ### add user to usergroups and add reboot permissions add_to_groups add_reboot_permission - ### create and activate the virtualenv - [ ! -d $OCTOPRINT_ENV ] && mkdir -p $OCTOPRINT_ENV - status_msg "Set up virtualenv ..." - cd $OCTOPRINT_ENV - virtualenv --python=python3 venv - source venv/bin/activate + ### install octoprint + install_octoprint - ### install octoprint with pip - status_msg "Download and install OctoPrint ..." + ### set up instances + if [ "${instances}" -eq 1 ]; then + create_single_octoprint_instance + else + create_multi_octoprint_instance "${instances}" + fi + + ### step 6: enable and start all instances + do_action_service "enable" "octoprint" + do_action_service "start" "octoprint" + + ### confirm message + [ "${instances}" -eq 1 ] && confirm_msg="OctoPrint has been set up!" + [ "${instances}" -gt 1 ] && confirm_msg="${instances} OctoPrint instances have been set up!" + print_confirm "${confirm_msg}" + print_op_ip_list "${instances}" +} + +function install_octoprint(){ + ### create and activate the virtualenv + [ ! -d "${OCTOPRINT_ENV}" ] && mkdir -p "${OCTOPRINT_ENV}" + status_msg "Installing python virtual environment..." + cd "${OCTOPRINT_ENV}" && virtualenv --python=python3 venv + ### activate virtualenv + source venv/bin/activate + status_msg "Installing OctoPrint ..." pip install pip --upgrade pip install --no-cache-dir octoprint ok_msg "Download complete!" - ### leave virtualenv deactivate - - ### set up instances - INSTANCE=1 - if [ $INSTANCE_COUNT -eq $INSTANCE ]; then - create_single_octoprint_instance - else - create_multi_octoprint_instance - fi } add_to_groups(){ if [ ! "$(groups | grep tty)" ]; then status_msg "Adding user '${USER}' to group 'tty' ..." - sudo usermod -a -G tty ${USER} && ok_msg "Done!" + sudo usermod -a -G tty "${USER}" && ok_msg "Done!" fi if [ ! "$(groups | grep dialout)" ]; then status_msg "Adding user '${USER}' to group 'dialout' ..." - sudo usermod -a -G dialout ${USER} && ok_msg "Done!" + sudo usermod -a -G dialout "${USER}" && ok_msg "Done!" fi } -create_single_octoprint_startscript(){ -### create single instance systemd service file -sudo /bin/sh -c "cat > ${SYSTEMD}/octoprint.service" << OCTOPRINT +function create_config_yaml(){ + local base_dir=${1} tmp_printer=${2} restart_cmd=${3} + + /bin/sh -c "cat > ${base_dir}/config.yaml" << CONFIGYAML +serial: + additionalPorts: + - ${tmp_printer} + disconnectOnErrors: false + port: ${tmp_printer} +server: + commands: + serverRestartCommand: ${restart_cmd} + systemRestartCommand: sudo shutdown -r now + systemShutdownCommand: sudo shutdown -h now +CONFIGYAML +} + +function create_single_octoprint_instance(){ + local port=5000 + local base_dir="${HOME}/.octoprint" + local tmp_printer="/tmp/printer" + local config_yaml="${base_dir}/config.yaml" + local restart_cmd="sudo service octoprint restart" + + status_msg "Creating OctoPrint instance ..." + sudo /bin/sh -c "cat > ${SYSTEMD}/octoprint.service" << OCTOPRINT [Unit] Description=Starts OctoPrint on startup After=network-online.target @@ -130,19 +164,36 @@ Wants=network-online.target Environment="LC_ALL=C.UTF-8" Environment="LANG=C.UTF-8" Type=simple -User=$USER -ExecStart=${OCTOPRINT_ENV}/venv/bin/octoprint --basedir ${BASEDIR} --config ${CONFIG_YAML} --port=${PORT} serve +User=${USER} +ExecStart=${OCTOPRINT_ENV}/venv/bin/octoprint --basedir ${base_dir} --config ${config_yaml} --port=${port} serve [Install] WantedBy=multi-user.target OCTOPRINT + + ### create the config.yaml + if [ ! -f "${base_dir}/config.yaml" ]; then + status_msg "Creating config.yaml ..." + [ ! -d "${base_dir}" ] && mkdir "${base_dir}" + create_config_yaml "${base_dir}" "${tmp_printer}" "${restart_cmd}" + ok_msg "Config created!" + fi } -create_multi_octoprint_startscript(){ -### create multi instance systemd service file -sudo /bin/sh -c "cat > ${SYSTEMD}/octoprint-$INSTANCE.service" << OCTOPRINT +function create_multi_octoprint_instance(){ + local i=1 port=5000 instance=${1} + while [ "${i}" -le "${instances}" ]; do + ### multi instance variables + local base_dir="${HOME}/.octoprint-${i}" + local tmp_printer="/tmp/printer-${i}" + local config_yaml="${base_dir}/config.yaml" + local restart_cmd="sudo service octoprint-${i} restart" + + ### create instance + status_msg "Creating instance #${i} ..." + sudo /bin/sh -c "cat > ${SYSTEMD}/octoprint-${i}.service" << OCTOPRINT [Unit] -Description=Starts OctoPrint instance $INSTANCE on startup +Description=Starts OctoPrint instance ${instances} on startup After=network-online.target Wants=network-online.target @@ -150,162 +201,71 @@ Wants=network-online.target Environment="LC_ALL=C.UTF-8" Environment="LANG=C.UTF-8" Type=simple -User=$USER -ExecStart=${OCTOPRINT_ENV}/venv/bin/octoprint --basedir ${BASEDIR} --config ${CONFIG_YAML} --port=${PORT} serve +User=${USER} +ExecStart=${OCTOPRINT_ENV}/venv/bin/octoprint --basedir ${base_dir} --config ${config_yaml} --port=${port} serve [Install] WantedBy=multi-user.target OCTOPRINT -} - -create_config_yaml(){ -### create multi instance config.yaml file -/bin/sh -c "cat > ${BASEDIR}/config.yaml" << CONFIGYAML -serial: - additionalPorts: - - ${TMP_PRINTER} - disconnectOnErrors: false - port: ${TMP_PRINTER} -server: - commands: - serverRestartCommand: ${RESTART_COMMAND} - systemRestartCommand: sudo shutdown -r now - systemShutdownCommand: sudo shutdown -h now -CONFIGYAML -} - -create_single_octoprint_instance(){ - status_msg "Setting up 1 OctoPrint instance ..." - - ### single instance variables - PORT=5000 - BASEDIR="${HOME}/.octoprint" - TMP_PRINTER="/tmp/printer" - CONFIG_YAML="$BASEDIR/config.yaml" - RESTART_COMMAND="sudo service octoprint restart" - - ### declare empty array for ips which get displayed to the user at the end of the setup - HOSTNAME=$(hostname -I | cut -d" " -f1) - op_ip_list=() - - ### create instance - status_msg "Creating single OctoPrint instance ..." - create_single_octoprint_startscript - op_ip_list+=("$HOSTNAME:$PORT") - - ### create the config.yaml - if [ ! -f $BASEDIR/config.yaml ]; then - status_msg "Creating config.yaml ..." - [ ! -d $BASEDIR ] && mkdir $BASEDIR - create_config_yaml - ok_msg "Config created!" - fi - - ### enable instance - sudo systemctl enable octoprint.service - ok_msg "Single OctoPrint instance created!" - - ### launching instance - status_msg "Launching OctoPrint instance ..." - sudo systemctl start octoprint - - ### confirm message - CONFIRM_MSG="Single OctoPrint instance has been set up!" - print_msg && clear_msg - - ### display all octoprint ips to the user - print_op_ip_list; echo -} - -create_multi_octoprint_instance(){ - status_msg "Setting up $INSTANCE_COUNT instances of OctoPrint ..." - - ### declare empty array for ips which get displayed to the user at the end of the setup - HOSTNAME=$(hostname -I | cut -d" " -f1) - op_ip_list=() - - ### default port - PORT=5000 - - while [ $INSTANCE -le $INSTANCE_COUNT ]; do - ### multi instance variables - BASEDIR="${HOME}/.octoprint-$INSTANCE" - TMP_PRINTER="/tmp/printer-$INSTANCE" - CONFIG_YAML="$BASEDIR/config.yaml" - RESTART_COMMAND="sudo service octoprint restart" - - ### create instance - status_msg "Creating instance #$INSTANCE ..." - create_multi_octoprint_startscript - op_ip_list+=("$HOSTNAME:$PORT") ### create the config.yaml - if [ ! -f $BASEDIR/config.yaml ]; then - status_msg "Creating config.yaml for instance #$INSTANCE..." - [ ! -d $BASEDIR ] && mkdir $BASEDIR + if [ ! -f "${base_dir}/config.yaml" ]; then + status_msg "Creating config.yaml for instance #${i}..." + [ ! -d "${base_dir}" ] && mkdir "${base_dir}" create_config_yaml - ok_msg "Config #$INSTANCE created!" + ok_msg "Config #${i} created!" fi ### enable instance - sudo systemctl enable octoprint-$INSTANCE.service - ok_msg "OctoPrint instance $INSTANCE created!" + sudo systemctl enable "octoprint-${i}.service" + ok_msg "OctoPrint instance ${i} created!" ### launching instance - status_msg "Launching OctoPrint instance $INSTANCE ..." - sudo systemctl start octoprint-$INSTANCE + status_msg "Launching OctoPrint instance ${i} ..." + sudo systemctl start "octoprint-${i}" - ### instance counter +1 - INSTANCE=$(expr $INSTANCE + 1) - - ### port +1 - PORT=$(expr $PORT + 1) + i=$((i+1)) + port=$((port+1)) done - - ### confirm message - CONFIRM_MSG="$INSTANCE_COUNT OctoPrint instances have been set up!" - print_msg && clear_msg - - ### display all moonraker ips to the user - print_op_ip_list; echo } -add_reboot_permission(){ - USER=${USER} - #create a backup when file already exists +function add_reboot_permission(){ + #create a backup if file already exists if [ -f /etc/sudoers.d/octoprint-shutdown ]; then sudo mv /etc/sudoers.d/octoprint-shutdown /etc/sudoers.d/octoprint-shutdown.old fi #create new permission file - status_msg "Add reboot permission to user '$USER' ..." - cd ${HOME} && echo "$USER ALL=NOPASSWD: /sbin/shutdown" > octoprint-shutdown + status_msg "Add reboot permission to user '${USER}' ..." + cd "${HOME}" && echo "${USER} ALL=NOPASSWD: /sbin/shutdown" > octoprint-shutdown sudo chown 0 octoprint-shutdown sudo mv octoprint-shutdown /etc/sudoers.d/octoprint-shutdown ok_msg "Permission set!" } -print_op_ip_list(){ - i=1 - for ip in ${op_ip_list[@]}; do - echo -e " ${cyan}● Instance $i:${default} $ip" - i=$((i + 1)) - done +function print_op_ip_list(){ + local ip instances="${1}" i=1 port=5000 + ip=$(hostname -I | cut -d" " -f1) + while [ "${i}" -le "${instances}" ] ; do + echo -e " ${cyan}● Instance ${i}:${white} ${ip}:${port}" + port=$((port+1)) + i=$((i+1)) + done && echo } #=================================================# #=============== REMOVE OCTOPRINT ================# #=================================================# -remove_octoprint(){ +function remove_octoprint(){ ###remove all octoprint services if ls /etc/systemd/system/octoprint*.service 2>/dev/null 1>&2; then status_msg "Removing OctoPrint Services ..." for service in $(ls /etc/systemd/system/octoprint*.service | cut -d"/" -f5) do - status_msg "Removing $service ..." - sudo systemctl stop $service - sudo systemctl disable $service - sudo rm -f $SYSTEMDDIR/$service + status_msg "Removing ${service} ..." + sudo systemctl stop "${service}" + sudo systemctl disable "${service}" + sudo rm -f "${SYSTEMD}/${service}" ok_msg "OctoPrint Service removed!" done ### reloading units @@ -319,60 +279,60 @@ remove_octoprint(){ fi ### remove OctoPrint directory - if [ -d ${HOME}/OctoPrint ]; then + if [ -d "${HOME}/OctoPrint" ]; then status_msg "Removing OctoPrint directory ..." - rm -rf ${HOME}/OctoPrint && ok_msg "Directory removed!" + rm -rf "${HOME}/OctoPrint" && ok_msg "Directory removed!" fi ###remove .octoprint directories - if ls -d ${HOME}/.octoprint* 2>/dev/null 1>&2; then + if ls -d "${HOME}"/.octoprint* 2>/dev/null 1>&2; then for folder in $(ls -d ${HOME}/.octoprint*) do - status_msg "Removing $folder ..." && rm -rf $folder && ok_msg "Done!" + status_msg "Removing ${folder} ..." && rm -rf "${folder}" && ok_msg "Done!" done fi ### remove octoprint_port from ~/.kiauh.ini - sed -i "/^octoprint_port=/d" $INI_FILE + sed -i "/^octoprint_port=/d" "${INI_FILE}" - CONFIRM_MSG=" OctoPrint successfully removed!" + print_confirm "OctoPrint successfully removed!" } #=================================================# #=============== OCTOPRINT STATUS ================# #=================================================# -octoprint_status(){ +function octoprint_status(){ ocount=0 octoprint_data=( SERVICE - $OCTOPRINT_DIR + "${OCTOPRINT_DIR}" ) ### count amount of octoprint service files in /etc/systemd/system SERVICE_FILE_COUNT=$(ls /etc/systemd/system | grep -E "^octoprint(\-[[:digit:]]+)?\.service$" | wc -l) ### remove the "SERVICE" entry from the octoprint_data array if a octoprint service is installed - [ $SERVICE_FILE_COUNT -gt 0 ] && unset octoprint_data[0] + [ "${SERVICE_FILE_COUNT}" -gt 0 ] && unset "octoprint_data[0]" #count+1 for each found data-item from array for op in "${octoprint_data[@]}" do - if [ -e $op ]; then - ocount=$(expr $ocount + 1) + if [ -e "${op}" ]; then + ocount=$((ocount+1)) fi done ### display status - if [ "$ocount" == "${#octoprint_data[*]}" ]; then - OCTOPRINT_STATUS="$(printf "${green}Installed: %-5s${default}" $SERVICE_FILE_COUNT)" - elif [ "$ocount" == 0 ]; then + if [ "${ocount}" == "${#octoprint_data[*]}" ]; then + OCTOPRINT_STATUS="$(printf "${green}Installed: %-5s${default}" "${SERVICE_FILE_COUNT}")" + elif [ "${ocount}" == 0 ]; then OCTOPRINT_STATUS="${red}Not installed!${white} " else OCTOPRINT_STATUS="${yellow}Incomplete!${white} " fi } -read_octoprint_service_status(){ +function read_octoprint_service_status(){ unset OPRINT_SERVICE_STATUS if [ ! -f "/etc/systemd/system/octoprint.service" ]; then return 0 @@ -388,7 +348,7 @@ read_octoprint_service_status(){ #=================== HELPERS ====================# #================================================# -toggle_octoprint_service(){ +function toggle_octoprint_service(){ if systemctl list-unit-files | grep -E "octoprint.*" | grep "enabled" &>/dev/null; then do_action_service "stop" "octoprint" do_action_service "disable" "octoprint"