refactor(octoprint.sh): full refactor

Signed-off-by: Dominik Willner th33xitus@gmail.com
This commit is contained in:
th33xitus
2022-04-03 20:07:48 +02:00
parent 81b69d455a
commit 898a6bbfd0

View File

@@ -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"