diff --git a/scripts/install_octoprint.sh b/scripts/install_octoprint.sh index 273a129..3a117bc 100755 --- a/scripts/install_octoprint.sh +++ b/scripts/install_octoprint.sh @@ -1,30 +1,50 @@ -install_octoprint(){ - #check for other enabled web interfaces - unset SET_LISTEN_PORT - detect_enabled_sites - #ask user for customization - get_user_selections_octoprint - #octoprint main installation - octoprint_dependencies - octoprint_setup - add_groups - configure_autostart - add_reboot_permission - create_config_yaml - #execute customizations - set_nginx_cfg "octoprint" - set_hostname - #after install actions - load_octoprint_server -} +############################################################################################## +#********************************************************************************************# +############################################################################################## -get_user_selections_octoprint(){ +### base variables +SYSTEMDDIR="/etc/systemd/system" +OCTOPRINT_ENV="${HOME}/OctoPrint" + +octoprint_setup_dialog(){ status_msg "Initializing OctoPrint installation ..." - #ask user to set a reverse proxy - octoprint_reverse_proxy_dialog - #ask to change hostname - [ "$SET_NGINX_CFG" = "true" ] && create_custom_hostname - status_msg "Installation will start now! Please wait ..." + + ### count amount of klipper services + if [ "$(systemctl list-units --full -all -t service --no-legend | grep -F "klipper.service")" ]; then + INSTANCE_COUNT=1 + else + INSTANCE_COUNT=$(systemctl list-units --full -all -t service --no-legend | grep -E "klipper-[[:digit:]].service" | wc -l) + fi + + ### instance confirmation dialog + while true; do + 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):${default} " 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 + done } octoprint_dependencies(){ @@ -42,25 +62,39 @@ octoprint_dependencies(){ } octoprint_setup(){ - if [ ! -d $OCTOPRINT_DIR ];then - status_msg "Create OctoPrint directory ..." - mkdir -p $OCTOPRINT_DIR && ok_msg "Directory created!" - fi - cd $OCTOPRINT_DIR - #create the virtualenv + ### check and install all dependencies + octoprint_dependencies + + ### 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 venv source venv/bin/activate - #install octoprint with pip + + ### install octoprint with pip status_msg "Download and install OctoPrint ..." pip install pip --upgrade pip install --no-cache-dir octoprint ok_msg "Download complete!" - #leave virtualenv + + ### 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_groups(){ +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!" @@ -71,143 +105,176 @@ add_groups(){ fi } -configure_autostart(){ - USER=$(whoami) - cd $OCTOPRINT_DIR - status_msg "Downloading files ..." - wget https://github.com/foosel/OctoPrint/raw/master/scripts/octoprint.init - wget https://github.com/foosel/OctoPrint/raw/master/scripts/octoprint.default - ok_msg "Files downloaded successfully!" - #make necessary changes in default file - status_msg "Configure OctoPrint Service ..." - DEFAULT_FILE=$OCTOPRINT_DIR/octoprint.default - sed -i "s/pi/$USER/g" $DEFAULT_FILE - sed -i "s/#BASEDIR=/BASEDIR=/" $DEFAULT_FILE - sed -i "s/#CONFIGFILE=/CONFIGFILE=/" $DEFAULT_FILE - sed -i "s/#DAEMON=/DAEMON=/" $DEFAULT_FILE - #move files to correct location - sudo mv octoprint.init $OCTOPRINT_SERVICE1 - sudo mv octoprint.default $OCTOPRINT_SERVICE2 - #make file in init.d executable - sudo chmod +x $OCTOPRINT_SERVICE1 - status_msg "Reload systemd configuration files" - sudo update-rc.d octoprint defaults - sudo systemctl daemon-reload - ok_msg "Configuration complete!" - ok_msg "OctoPrint installed!" +create_single_octoprint_startscript(){ +### create single instance systemd service file +sudo /bin/sh -c "cat > ${SYSTEMDDIR}/octoprint.service" << OCTOPRINT +[Unit] +Description=Starts OctoPrint on startup +After=network-online.target +Wants=network-online.target + +[Service] +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 + +[Install] +WantedBy=multi-user.target +OCTOPRINT +} + +create_multi_octoprint_startscript(){ +### create multi instance systemd service file +sudo /bin/sh -c "cat > ${SYSTEMDDIR}/octoprint-$INSTANCE.service" << OCTOPRINT +[Unit] +Description=Starts OctoPrint instance $INSTANCE on startup +After=network-online.target +Wants=network-online.target + +[Service] +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 + +[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 + create_config_yaml + ok_msg "Config #$INSTANCE created!" + fi + + ### enable instance + sudo systemctl enable octoprint-$INSTANCE.service + ok_msg "OctoPrint instance $INSTANCE created!" + + ### launching instance + status_msg "Launching OctoPrint instance $INSTANCE ..." + sudo systemctl start octoprint-$INSTANCE + + ### instance counter +1 + INSTANCE=$(expr $INSTANCE + 1) + + ### port +1 + PORT=$(expr $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=$(whoami) + USER=${USER} #create a backup when 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 $OCTOPRINT_DIR - echo "$USER ALL=NOPASSWD: /sbin/shutdown" > octoprint-shutdown + 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!" - sleep 2 } -octoprint_reverse_proxy_dialog(){ - echo - top_border - echo -e "| If you want to have nicer URLs or simply need | " - echo -e "| OctoPrint to run on port 80 (http's default port) | " - echo -e "| due to some network restrictions, you can set up a | " - echo -e "| reverse proxy instead of configuring OctoPrint to | " - echo -e "| run on port 80. | " - bottom_border - while true; do - echo -e "${cyan}" - read -p "###### Do you want to set up a reverse proxy now? (y/N): " yn - echo -e "${default}" - case "$yn" in - Y|y|Yes|yes) - octoprint_port_check - break;; - N|n|No|no|"") - break;; - *) - print_unkown_cmd - print_msg && clear_msg;; - esac +print_op_ip_list(){ + i=1 + for ip in ${op_ip_list[@]}; do + echo -e " ${cyan}● Instance $i:${default} $ip" + i=$((i + 1)) done -} - -octoprint_port_check(){ - if [ "$OCTOPRINT_ENABLED" = "false" ]; then - if [ "$SITE_ENABLED" = "true" ]; then - status_msg "Detected other enabled interfaces:" - [ "$MAINSAIL_ENABLED" = "true" ] && echo " ${cyan}● Mainsail - Port:$MAINSAIL_PORT${default}" - [ "$FLUIDD_ENABLED" = "true" ] && echo " ${cyan}● Fluidd - Port:$FLUIDD_PORT${default}" - [ "$DWC2_ENABLED" = "true" ] && echo " ${cyan}● DWC2 - Port:$DWC2_PORT${default}" - if [ "$MAINSAIL_PORT" = "80" ] || [ "$DWC2_PORT" = "80" ] || [ "$FLUIDD_PORT" = "80" ]; then - PORT_80_BLOCKED="true" - select_octoprint_port - fi - else - DEFAULT_PORT=$(grep listen ${SRCDIR}/kiauh/resources/octoprint_nginx.cfg | head -1 | sed 's/^\s*//' | cut -d" " -f2 | cut -d";" -f1) - SET_LISTEN_PORT=$DEFAULT_PORT - fi - SET_NGINX_CFG="true" - else - SET_NGINX_CFG="false" - fi -} - -select_octoprint_port(){ - if [ "$PORT_80_BLOCKED" = "true" ]; then - echo - top_border - echo -e "| ${red}!!!WARNING!!!${default} |" - echo -e "| ${red}You need to choose a different port for OctoPrint!${default} |" - echo -e "| ${red}The following web interface is listening at port 80:${default} |" - blank_line - [ "$MAINSAIL_PORT" = "80" ] && echo "| ● Mainsail |" - [ "$FLUIDD_PORT" = "80" ] && echo "| ● Fluidd |" - [ "$DWC2_PORT" = "80" ] && echo "| ● DWC2 |" - blank_line - echo -e "| Make sure you don't choose a port which was already |" - echo -e "| assigned to one of the other web interfaces! |" - blank_line - echo -e "| Be aware: there is ${red}NO${default} sanity check for the following |" - echo -e "| input. So make sure to choose a valid port! |" - bottom_border - while true; do - read -p "${cyan}Please enter a new Port:${default} " NEW_PORT - if [ "$NEW_PORT" != "$MAINSAIL_PORT" ] && [ "$NEW_PORT" != "$FLUIDD_PORT" ] && [ "$NEW_PORT" != "$DWC2_PORT" ]; then - echo "Setting port $NEW_PORT for OctoPrint!" - SET_LISTEN_PORT=$NEW_PORT - break - else - echo "That port is already taken! Select a different one!" - fi - done - fi -} - -create_config_yaml(){ - if [ ! -d $OCTOPRINT_CFG_DIR ]; then - status_msg "Creating config.yaml ..." - mkdir $OCTOPRINT_CFG_DIR - cp ${HOME}/kiauh/resources/octoprint_config.cfg $OCTOPRINT_CFG_DIR/config.yaml - ok_msg "Config created!" - fi -} - -load_octoprint_server(){ - start_octoprint - #create an octoprint.log symlink in home-dir just for convenience - if [ ! -e ${HOME}/octoprint.log ]; then - status_msg "Creating octoprint.log Symlink ..." - ln -s ${HOME}/.octoprint/logs/octoprint.log ${HOME}/octoprint.log && ok_msg "Symlink created!" - fi - ok_msg "OctoPrint is now running on:" - ok_msg "$(hostname -I | cut -d " " -f1):5000 or" - ok_msg "http://localhost:5000"; echo } \ No newline at end of file diff --git a/scripts/status.sh b/scripts/status.sh index d5b8ecb..5c5a204 100755 --- a/scripts/status.sh +++ b/scripts/status.sh @@ -156,11 +156,21 @@ fluidd_status(){ octoprint_status(){ ocount=0 octoprint_data=( + SERVICE $OCTOPRINT_DIR - $OCTOPRINT_CFG_DIR - $OCTOPRINT_SERVICE1 - $OCTOPRINT_SERVICE2 ) + #remove the "SERVICE" entry from the octoprint array if an octoprint service is installed + if [ "$(systemctl list-units --full -all -t service --no-legend | grep -F "octoprint.service")" ] || [ "$(systemctl list-units --full -all -t service --no-legend | grep -E "octoprint-[[:digit:]].service")" ]; then + unset octoprint_data[0] + fi + + ### count amount of octoprint services + if [ "$(systemctl list-units --full -all -t service --no-legend | grep -F "octoprint.service")" ]; then + instances=1 + else + instances=$(systemctl list-units --full -all -t service --no-legend | grep -E "octoprint-[[:digit:]].service" | wc -l) + fi + #count+1 for each found data-item from array for op in "${octoprint_data[@]}" do @@ -168,8 +178,10 @@ octoprint_status(){ ocount=$(expr $ocount + 1) fi done + + ### display status if [ "$ocount" == "${#octoprint_data[*]}" ]; then - OCTOPRINT_STATUS="${green}Installed!${default} " + OCTOPRINT_STATUS="$(printf "${green}Installed: %-5s${default}" $instances)" elif [ "$ocount" == 0 ]; then OCTOPRINT_STATUS="${red}Not installed!${default} " else diff --git a/scripts/ui/install_menu.sh b/scripts/ui/install_menu.sh index 074479f..db12c2e 100755 --- a/scripts/ui/install_menu.sh +++ b/scripts/ui/install_menu.sh @@ -64,7 +64,7 @@ install_menu(){ 7) clear print_header - install_octoprint + octoprint_setup_dialog print_msg && clear_msg install_ui;; Q|q)