28 Commits

Author SHA1 Message Date
th33xitus
70c316b512 refactor(klipper): tweak klipper install dialogs
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-03-13 22:24:03 +01:00
th33xitus
4bbab899e7 Merge branch 'master' into install-remove-instances 2023-03-11 23:54:41 +01:00
th33xitus
c148b0e8ac refactor(klipper): refactor klipper remove procedure
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-03-11 23:51:36 +01:00
th33xitus
38090816ca revert(klipper): revert klipper update function
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-03-11 22:22:11 +01:00
th33xitus
2b168e2463 refactor(klipper): first refactor of klipper installation procedure
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-03-11 12:33:05 +01:00
th33xitus
37f673dde9 revert(klipper): revert changes to run_klipper_setup
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-03-11 12:22:20 +01:00
th33xitus
516af17df0 revert(klipper): revert changes to clone_klipper
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-03-11 12:19:38 +01:00
th33xitus
4543ccff20 fix: fix SC2155
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-03-11 09:19:35 +01:00
th33xitus
4c2d834560 Merge branch 'master' into install-remove-instances 2023-03-11 09:11:09 +01:00
coderus
176c44d6e4 fix(moonraker): remove init.d cleanup code 2023-02-28 22:23:03 +01:00
coderus
b11fbdb953 fix(crownest): remove errors output from menu 2023-02-28 22:22:46 +01:00
coderus
e0d65cc447 Merge branch 'master' into install-remove-instances 2023-02-28 22:21:53 +01:00
coderus
7c1c1d8f21 fix(moonraker): remove print at start 2023-01-08 16:36:46 +01:00
coderus
00a3fbe43b refactor(moonraker): refactor UI dialogs 2023-01-08 00:13:05 +01:00
coderus
d02fc2e01f refactor(klipper): refactor UI dialogs 2023-01-08 00:13:00 +01:00
coderus
26d27a03ec fix(moonraker): remove single instance 2023-01-07 20:48:22 +01:00
coderus
57e7b476fa refactor(moonraker): install/remove single instances 2023-01-07 20:39:12 +01:00
coderus
3071e1e037 refactor(moonraker): instance installation
a bit messy commit, might require more polishing
2023-01-07 17:36:52 +01:00
coderus
2b53e005e6 refactor(moonraker): funcs to get and print actual moonraker addressses with ports 2023-01-07 17:34:12 +01:00
coderus
937ad4cffd refactor(utilities): get_data_folder function 2023-01-07 17:32:33 +01:00
coderus
40fee65bf4 refactor(moonraker): do not remove dir for clone if exists, do not reset venv 2023-01-07 17:32:07 +01:00
coderus
3b68783f3b refactor(klipper): Install additional instances without full reinstall 2023-01-06 19:56:18 +01:00
coderus
72b5038e71 refactor(klipper): Just update venv if already exists 2023-01-06 19:56:15 +01:00
coderus
3556a009ec refactor(klipper): Do not clone in Update if no dir exists 2023-01-06 19:54:49 +01:00
coderus
b131cf56ef refactor(klipper): confirm instalaltion to existing instance folder 2023-01-06 15:46:51 +01:00
coderus
c07c17e8c9 refactor(python): Add default input to Python version selector 2023-01-06 15:43:59 +01:00
coderus
810fcde5c1 refactor(klipper): do not force remove and clone if already exists 2023-01-06 15:37:21 +01:00
coderus
ea5219ddc9 fix(systemd): remove RemainAfterExit from services
RemainAfterExit=yes makes impossible for service to restart automatically if exited with 0 exit code
2023-01-06 15:30:22 +01:00
5 changed files with 451 additions and 314 deletions

View File

@@ -10,7 +10,6 @@ WantedBy=multi-user.target
[Service]
Type=simple
User=%USER%
RemainAfterExit=yes
WorkingDirectory=/home/%USER%/klipper
EnvironmentFile=%ENV_FILE%
ExecStart=%ENV%/bin/python $KLIPPER_ARGS

View File

@@ -11,7 +11,6 @@ WantedBy=multi-user.target
Type=simple
User=%USER%
SupplementaryGroups=moonraker-admin
RemainAfterExit=yes
WorkingDirectory=/home/%USER%/moonraker
EnvironmentFile=%ENV_FILE%
ExecStart=%ENV%/bin/python $MOONRAKER_ARGS

View File

@@ -43,59 +43,84 @@ function klipper_systemd() {
}
function start_klipper_setup() {
local klipper_systemd_services
local is_multi_instance_setup="false"
local adding_instances="false"
local use_custom_names="false"
local klipper_count=0
local klipper_instances
local python_version
local instance_count
local instance_names
local use_custom_names
local input
local regex
local blacklist
local error
status_msg "Initializing Klipper installation ...\n"
### return early if klipper already exists
klipper_systemd_services=$(klipper_systemd)
klipper_instances=$(klipper_systemd)
[[ -n ${klipper_instances} ]] && is_multi_instance_setup="true"
if [[ -n ${klipper_systemd_services} ]]; then
error="At least one Klipper service is already installed:"
if [[ ${is_multi_instance_setup} == "true" ]]; then
klipper_count=$(echo "${klipper_instances}" | wc -w)
python_version=$(get_klipper_python_ver)
adding_instances="true"
for s in ${klipper_systemd_services}; do
log_info "Found Klipper service: ${s}"
error="${error}\n${s}"
# print list of already installed instances
top_border
printf "|${green}%-55s${white}|\n" " ${klipper_count} Klipper instances are already installed!"
local klipper_folder
for s in ${klipper_instances}; do
klipper_folder="$(get_data_folder "$(basename "${s}")" klipper)"
printf "|${cyan}%-57s${white}|\n" " ● klipper-$(get_instance_name "${s}") - ${klipper_folder}"
done
bottom_border && echo
else
top_border
echo -e "| Please select your preferred Python version. | "
echo -e "| The recommended version is Python 3.x. | "
hr
echo -e "| 1) [Python 3.x] (recommended) | "
echo -e "| 2) [Python 2.7] ${yellow}(legacy)${white} | "
back_footer
while true; do
read -p "${cyan}###### Select Python version:${white} " -e -i 1 input
case "${input}" in
1)
select_msg "Python 3.x\n"
python_version=3
break;;
2)
select_msg "Python 2.7\n"
python_version=2
break;;
B|b)
clear; install_menu; break;;
*)
error_msg "Invalid Input!\n";;
esac
done && input=""
fi
[[ -n ${error} ]] && print_error "${error}" && return
### user selection for python version
print_dialog_user_select_python_version
while true; do
read -p "${cyan}###### Select Python version:${white} " input
case "${input}" in
1)
select_msg "Python 3.x\n"
python_version=3
break;;
2)
select_msg "Python 2.7\n"
python_version=2
break;;
B|b)
clear; install_menu; break;;
*)
error_msg "Invalid Input!\n";;
esac
done && input=""
top_border
echo -e "| Please select the number of Klipper instances to set |"
echo -e "| up. The number of Klipper instances will determine |"
echo -e "| the amount of printers you can run from this host. |"
blank_line
echo -e "| ${yellow}WARNING:${white} |"
echo -e "| ${yellow}Setting up too many instances may crash your system.${white} |"
back_footer
### user selection for instance count
print_dialog_user_select_instance_count
regex="^[1-9][0-9]*$"
while [[ ! ${input} =~ ${regex} ]]; do
read -p "${cyan}###### Number of Klipper instances to set up:${white} " -i "1" -e input
local x=""
[[ ${adding_instances} == "true" ]] && x="additional"
read -p "${cyan}###### Number of ${x} Klipper instances to set up:${white} " -i "1" -e input
if [[ ${input} =~ ${regex} ]]; then
instance_count="${input}"
(( instance_count > 1 )) && is_multi_instance_setup="true"
select_msg "Instance count: ${instance_count}\n"
break
elif [[ ${input} == "B" || ${input} == "b" ]]; then
@@ -105,10 +130,15 @@ function start_klipper_setup() {
fi
done && input=""
### user selection for custom names
use_custom_names="false"
if (( instance_count > 1 )); then
print_dialog_user_select_custom_name_bool
if [[ ${is_multi_instance_setup} == "true" ]]; then
top_border
echo -e "| You can now give each instance a custom name. If you |"
echo -e "| select 'N', each instance will get an index assigned |"
echo -e "| in ascending order, starting at index '$((klipper_count + 1))'. |"
blank_line
echo -e "| ${yellow}Info:${white} |"
echo -e "| ${yellow}Only alphanumeric characters are allowed!${white} |"
back_footer
while true; do
read -p "${cyan}###### Assign custom names? (y/N):${white} " input
case "${input}" in
@@ -131,86 +161,67 @@ function start_klipper_setup() {
### user selection for setting the actual custom names
shopt -s nocasematch
if (( instance_count > 1 )) && [[ ${use_custom_names} == "true" ]]; then
local i
i=1
if [[ ${use_custom_names} == "true" ]]; then
regex="^[0-9a-zA-Z]+$"
blacklist="mcu"
while [[ ! ${input} =~ ${regex} || ${input} =~ ${blacklist} || ${i} -le ${instance_count} ]]; do
read -p "${cyan}###### Name for instance #${i}:${white} " input
if [[ ${input} =~ ${blacklist} ]]; then
error_msg "Name not allowed! You are trying to use a reserved name."
local i=1
while [[ ! ${input} =~ ${regex} || ${input} =~ ${blacklist} || ${i} -le ${instance_count} ]]; do
read -p "${cyan}###### Name for instance #$((klipper_count + i)):${white} " input
if [[ ! ${input} =~ ${regex} ]]; then
error_msg "Invalid Input!\n"
elif [[ ${input} =~ ${blacklist} ]]; then
error_msg "Name not allowed! You are trying to use a reserved name.\n"
elif get_multi_instance_names | grep -q "${input}"; then
error_msg "Instance with name '${input}' already exists. Please choose a different name.\n"
elif echo "${instance_names[@]}" | grep -q "${input}"; then
error_msg "Name already assigned. Please choose a different name.\n"
elif [[ ${input} =~ ${regex} && ! ${input} =~ ${blacklist} ]]; then
select_msg "Name: ${input}\n"
local instance_name
if [[ ${input} =~ ^[0-9]+$ ]]; then
instance_names+=("printer_${input}")
instance_name="printer_${input}"
else
instance_names+=("${input}")
instance_name="${input}"
fi
instance_names+=("${instance_name}")
i=$(( i + 1 ))
else
error_msg "Invalid Input!\n"
fi
done && input=""
elif (( instance_count > 1 )) && [[ ${use_custom_names} == "false" ]]; then
for (( i=1; i <= instance_count; i++ )); do
elif [[ ${is_multi_instance_setup} == "true" && ${use_custom_names} == "false" ]]; then
for (( i=klipper_count+1; i <= instance_count+klipper_count; ++i )); do
instance_names+=("printer_${i}")
done
fi
shopt -u nocasematch
(( instance_count > 1 )) && status_msg "Installing ${instance_count} Klipper instances ..."
(( instance_count == 1 )) && status_msg "Installing single Klipper instance ..."
local msg="Installing Klipper ..."
if [[ ${is_multi_instance_setup} == "true" && ${adding_instances} == "false" ]]; then
msg="Installing ${instance_count} Klipper instances ..."
elif [[ ${adding_instances} == "true" ]]; then
msg="Installing ${instance_count} additional Klipper instances ..."
fi
status_msg "${msg}"
run_klipper_setup "${python_version}" "${instance_names[@]}"
}
function print_dialog_user_select_python_version() {
top_border
echo -e "| Please select your preferred Python version. | "
echo -e "| The recommended version is Python 3.x. | "
hr
echo -e "| 1) [Python 3.x] (recommended) | "
echo -e "| 2) [Python 2.7] ${yellow}(legacy)${white} | "
back_footer
}
function print_dialog_user_select_instance_count() {
top_border
echo -e "| Please select the number of Klipper instances to set |"
echo -e "| up. The number of Klipper instances will determine |"
echo -e "| the amount of printers you can run from this host. |"
blank_line
echo -e "| ${yellow}WARNING:${white} |"
echo -e "| ${yellow}Setting up too many instances may crash your system.${white} |"
back_footer
}
function print_dialog_user_select_custom_name_bool() {
top_border
echo -e "| You can now assign a custom name to each instance. |"
echo -e "| If skipped, each instance will get an index assigned |"
echo -e "| in ascending order, starting at index '1'. |"
blank_line
echo -e "| Info: |"
echo -e "| Only alphanumeric characters for names are allowed! |"
back_footer
run_klipper_setup "${python_version}" "${adding_instances}" "${instance_names[@]}"
}
function run_klipper_setup() {
read_kiauh_ini "${FUNCNAME[0]}"
local python_version=${1}
local adding_instances=${2}
local instance_names
local confirm
local custom_repo
local custom_branch
local dep
shift 1
read -r -a instance_names <<< "${@}"
shift 2 && read -r -a instance_names <<< "${@}"
custom_repo="${custom_klipper_repo}"
custom_branch="${custom_klipper_repo_branch}"
@@ -219,12 +230,14 @@ function run_klipper_setup() {
### checking dependencies
dependency_check "${dep[@]}"
### step 1: clone klipper
clone_klipper "${custom_repo}" "${custom_branch}"
if [[ "${adding_instances}" == "false" ]]; then
### step 1: clone klipper
clone_klipper "${custom_repo}" "${custom_branch}"
### step 2: install klipper dependencies and create python virtualenv
install_klipper_packages "${python_version}"
create_klipper_virtualenv "${python_version}"
### step 2: install klipper dependencies and create python virtualenv
install_klipper_packages "${python_version}"
create_klipper_virtualenv "${python_version}"
fi
### step 3: create klipper instances
for instance in "${instance_names[@]}"; do
@@ -408,28 +421,28 @@ function write_example_printer_cfg() {
#================================================#
function remove_klipper_service() {
[[ -z $(klipper_systemd) ]] && return
status_msg "Removing Klipper services ..."
for service in $(klipper_systemd | cut -d"/" -f5); do
for service in "${@}"; do
status_msg "Removing ${service} ..."
sudo systemctl stop "${service}"
sudo systemctl disable "${service}"
sudo rm -f "${SYSTEMD}/${service}"
sudo systemctl daemon-reload
sudo systemctl reset-failed
done
ok_msg "All Klipper services removed!"
sudo systemctl daemon-reload
sudo systemctl reset-failed
ok_msg "Selected Klipper services removed!"
}
function find_instance_files() {
local target_folder=${1}
local target_name=${2}
local data_folder=${1}
local target_folder=${2}
local target_name=${3}
local files
readarray -t files < <(find "${HOME}" -regex "${HOME}/[A-Za-z0-9_]+_data/${target_folder}/${target_name}" | sort)
readarray -t files < <(find "${HOME}" -regex "${data_folder}/${target_folder}/${target_name}" | sort)
echo -e "${files[@]}"
}
@@ -483,25 +496,95 @@ function remove_files() {
if (( ${#files[@]} > 0 )); then
for file in "${files[@]}"; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
if rm -f "${file}"; then
ok_msg "${file} removed!"
else
error_msg "${file} could not be removed! Please remove it manually!"
fi
done
fi
}
function remove_klipper_files() {
status_msg "Removing Klipper files ..."
for service in "${@}"; do
local data_folder
data_folder=$(get_data_folder "${service}")
remove_files "$(find_instance_files "${data_folder}" "systemd" "klipper.env")"
remove_files "$(find_instance_files "${data_folder}" "logs" "klippy.log.*")"
remove_files "$(find_instance_files "${data_folder}" "comms" "klippy.sock")"
remove_files "$(find_instance_files "${data_folder}" "comms" "klippy.serial")"
done
ok_msg "Files removed!"
}
function remove_klipper() {
remove_klipper_service
remove_files "$(find_instance_files "systemd" "klipper.env")"
remove_files "$(find_instance_files "logs" "klippy.log.*")"
remove_files "$(find_instance_files "comms" "klippy.sock")"
remove_files "$(find_instance_files "comms" "klippy.serial")"
local klipper_systemd_services
local klipper_services_count
local user_input=()
local klipper_names=()
local service_name
klipper_systemd_services=$(klipper_systemd)
if [[ -z ${klipper_systemd_services} ]]; then
print_error "Klipper not installed, nothing to do!"
return
fi
remove_files "$(find_legacy_klipper_logs)"
remove_files "$(find_legacy_klipper_uds)"
remove_files "$(find_legacy_klipper_printer)"
remove_klipper_dir
remove_klipper_env
top_border
echo -e "| ${red}~~~~~~~~ [ Klipper instance remover ] ~~~~~~~${white} |"
hr
klipper_services_count="$(echo "${klipper_systemd_services}" | wc -w)"
if (( klipper_services_count == 1 )); then
service_name=$(basename "${klipper_systemd_services}")
klipper_names+=( "${service_name}" )
printf "| 0) %-51s|\n" "${service_name}"
else
printf "| 0) %-51s|\n" "Remove all"
local i=1
for name in ${klipper_systemd_services}; do
service_name=$(basename "${name}")
klipper_names+=( "${service_name}" )
printf "| ${i}) %-51s|\n" "${service_name}"
i=$(( i + 1 ))
done
fi
back_footer
local option
while true; do
read -p "${cyan}Instance to remove:${white} " option
if [[ ${option} == "B" || ${option} == "b" ]]; then
return
elif [[ $((option)) != "${option}" ]]; then
error_msg "Invalid command!"
elif (( option >= 0 && option <= ${#klipper_names[@]} )); then
break
else
error_msg "Invalid command!"
fi
done
if (( option == 0 )); then
user_input=( "${klipper_names[@]}" )
else
user_input=( "${klipper_names[(( option - 1 ))]}" )
fi
remove_klipper_service "${user_input[@]}"
remove_klipper_files "${user_input[@]}"
if (( klipper_services_count == 1 )) || [[ "${option}" == "0" ]]; then
remove_klipper_dir
remove_klipper_env
fi
print_confirm "Klipper was successfully removed!" && return
}
@@ -628,4 +711,4 @@ function get_klipper_python_ver() {
local version
version=$("${KLIPPY_ENV}"/bin/python --version 2>&1 | cut -d" " -f2 | cut -d"." -f1)
echo "${version}"
}
}

View File

@@ -37,8 +37,6 @@ function moonraker_systemd() {
}
function moonraker_setup_dialog() {
status_msg "Initializing Moonraker installation ..."
### return early if python version check fails
if [[ $(python3_check) == "false" ]]; then
local error="Versioncheck failed! Python 3.7 or newer required!\n"
@@ -46,97 +44,85 @@ function moonraker_setup_dialog() {
print_error "${error}" && return
fi
### return early if moonraker already exists
local moonraker_services
moonraker_services=$(moonraker_systemd)
if [[ -n ${moonraker_services} ]]; then
local error="At least one Moonraker service is already installed:"
for s in ${moonraker_services}; do
log_info "Found Moonraker service: ${s}"
error="${error}\n ➔ ${s}"
done
print_error "${error}" && return
fi
local klipper_services=$(klipper_systemd)
local klipper_count=$(echo "${klipper_services}" | wc -w )
for service in ${klipper_services}; do
klipper_names+=( "$(get_instance_name "${service}")" )
done
local moonraker_services=$(moonraker_systemd)
local moonraker_count=$(echo "${moonraker_services}" | wc -w )
for service in ${moonraker_services}; do
moonraker_names+=( "$(get_instance_name "${service}")" )
done
### return early if klipper is not installed
local klipper_services
klipper_services=$(klipper_systemd)
if [[ -z ${klipper_services} ]]; then
local error="Klipper not installed! Please install Klipper first!"
log_error "Moonraker setup started without Klipper being installed. Aborting setup."
print_error "${error}" && return
fi
local klipper_count user_input=() klipper_names=()
klipper_count=$(echo "${klipper_services}" | wc -w )
for service in ${klipper_services}; do
klipper_names+=( "$(get_instance_name "${service}")" )
top_border
echo -e "| ${red}~~~~~~~~~ [ Moonraker installation ] ~~~~~~~~${white} |"
hr
printf "|${green}%-55s${white}|\n" " ${moonraker_count} Moonraker services found!"
local moonraker_folders=()
for name in ${moonraker_services}; do
local moonraker_folder=$(get_data_folder $(basename ${name}) moonraker)
printf "|${cyan}%-57s${white}|\n" "$(basename ${name}) - $(get_moonraker_address $(basename ${name}))"
moonraker_folders+=( "${moonraker_folder}" )
done
blank_line
printf "|${green}%-55s${white}|\n" " ${klipper_count} Klipper services found!"
local klipper_available=()
for name in ${klipper_services}; do
local klipper_folder=$(get_data_folder $(basename ${name}) klipper)
printf "|${cyan}%-57s${white}|\n" "$(basename ${name}) - ${klipper_folder}"
if [[ ! " ${moonraker_folders[*]} " =~ " ${klipper_folder} " ]]; then
klipper_available+=( "$(basename ${name})" )
fi
done
local klipper_available_count=${#klipper_available[@]}
hr
local moonraker_count
if (( klipper_count == 1 )); then
ok_msg "Klipper installation found!\n"
moonraker_count=1
elif (( klipper_count > 1 )); then
top_border
printf "|${green}%-55s${white}|\n" " ${klipper_count} Klipper instances found!"
for name in "${klipper_names[@]}"; do
printf "|${cyan}%-57s${white}|\n" " ● klipper-${name}"
done
blank_line
echo -e "| The setup will apply the same names to Moonraker! |"
blank_line
echo -e "| Please select the number of Moonraker instances to |"
echo -e "| install. Usually one Moonraker instance per Klipper |"
echo -e "| instance is required, but you may not install more |"
echo -e "| Moonraker instances than available Klipper instances. |"
bottom_border
### ask for amount of instances
local re="^[1-9][0-9]*$"
while [[ ! ${moonraker_count} =~ ${re} || ${moonraker_count} -gt ${klipper_count} ]]; do
read -p "${cyan}###### Number of Moonraker instances to set up:${white} " -i "${klipper_count}" -e moonraker_count
### break if input is valid
[[ ${moonraker_count} =~ ${re} && ${moonraker_count} -le ${klipper_count} ]] && break
### conditional error messages
[[ ! ${moonraker_count} =~ ${re} ]] && error_msg "Input not a number"
(( moonraker_count > klipper_count )) && error_msg "Number of Moonraker instances larger than installed Klipper instances"
done && select_msg "${moonraker_count}"
printf "|${green}%-55s${white}|\n" " ${klipper_available_count} Moonraker services can be installed:"
local service_name
if (( klipper_available_count == 1 )); then
service_name=$(basename "${klipper_available[@]}")
printf "| 0) %-51s|\n" "${service_name}"
else
log_error "Internal error. klipper_count of '${klipper_count}' not equal or grather than one!"
return 1
fi
user_input+=("${moonraker_count}")
### confirm instance amount
local yn
while true; do
(( moonraker_count == 1 )) && local question="Install Moonraker?"
(( moonraker_count > 1 )) && local question="Install ${moonraker_count} Moonraker 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 setup ...\n"
return;;
*)
error_msg "Invalid Input!";;
esac
done
### write existing klipper names into user_input array to use them as names for moonraker
if (( klipper_count > 1 )); then
for name in "${klipper_names[@]}"; do
user_input+=("${name}")
printf "| 0) %-51s|\n" "Install all"
local i=1
for name in "${klipper_available[@]}"; do
printf "| ${i}) %-51s|\n" "${name}"
(( i=i+1 ))
done
fi
back_footer
(( moonraker_count > 1 )) && status_msg "Installing ${moonraker_count} Moonraker instances ..."
(( moonraker_count == 1 )) && status_msg "Installing Moonraker ..."
local option
while true; do
read -p "${cyan}Install moonraker for:${white} " option
if [[ ${option} == "B" || ${option} == "b" ]]; then
return
elif [[ $((option)) != $option ]]; then
error_msg "Invalid command!"
elif (( option >= 0 && option < ${#klipper_available[@]} )); then
break
else
error_msg "Invalid command!"
fi
done
if (( option == 0 )); then
user_input=( ${klipper_available[@]} )
else
user_input=( "${klipper_available[(( option-1 ))]}" )
fi
status_msg "Installing Moonraker ..."
moonraker_setup "${user_input[@]}"
}
@@ -199,7 +185,10 @@ function moonraker_setup() {
### step 2: install moonraker dependencies and create python virtualenv
status_msg "Installing dependencies ..."
install_moonraker_dependencies
create_moonraker_virtualenv
if [[ "${moonraker_clone_result}" == "0" ]]; then
create_moonraker_virtualenv
fi
unset moonraker_clone_result
### step 3: create moonraker.conf
create_moonraker_conf "${instance_arr[@]}"
@@ -216,9 +205,10 @@ function moonraker_setup() {
### confirm message
local confirm=""
(( instance_arr[0] == 1 )) && confirm="Moonraker has been set up!"
(( instance_arr[0] > 1 )) && confirm="${instance_arr[0]} Moonraker instances have been set up!"
print_confirm "${confirm}" && print_mr_ip_list "${instance_arr[0]}" && return
(( ${#instance_arr[@]} == 1 )) && confirm="Moonraker has been set up!"
(( ${#instance_arr[@]} > 1 )) && confirm="${#instance_arr[@]} Moonraker instances have been set up!"
print_confirm "${confirm}"
print_moonraker_addresses
}
function clone_moonraker() {
@@ -226,6 +216,15 @@ function clone_moonraker() {
status_msg "Cloning Moonraker from ${repo} ..."
if [[ -d ${MOONRAKER_DIR} ]]
then
status_msg "Moonraker already cloned, pulling recent changes ..."
git -C ${MOONRAKER_DIR} stash
git -C ${MOONRAKER_DIR} pull --ff-only
moonraker_clone_result="1"
return
fi
### force remove existing moonraker dir and clone into fresh moonraker dir
[[ -d ${MOONRAKER_DIR} ]] && rm -rf "${MOONRAKER_DIR}"
@@ -234,50 +233,29 @@ function clone_moonraker() {
print_error "Cloning Moonraker from\n ${repo}\n failed!"
exit 1
fi
moonraker_clone_result="0"
}
function create_moonraker_conf() {
local input=("${@}")
local moonraker_count=${input[0]} && unset "input[0]"
local names=("${input[@]}") && unset "input[@]"
local port lan printer_data cfg_dir cfg uds
local names=("${@}")
local moonraker_count=${#names[@]}
local lan printer_data cfg_dir cfg uds
local port=$(get_moonraker_next_port)
port=7125
lan="$(hostname -I | cut -d" " -f1 | cut -d"." -f1-2).0.0/16"
if (( moonraker_count == 1 )); then
printer_data="${HOME}/printer_data"
for service in "${names[@]}"; do
### overwrite config folder if name is only a number
printer_data=$(get_data_folder "${service}" "klipper")
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/moonraker.conf"
uds="${printer_data}/comms/klippy.sock"
### write single instance config
### write multi instance config
write_moonraker_conf "${cfg_dir}" "${cfg}" "${port}" "${uds}" "${lan}"
elif (( moonraker_count > 1 )); then
local j=0 re="^[1-9][0-9]*$"
for (( i=1; i <= moonraker_count; i++ )); do
### overwrite config folder if name is only a number
if [[ ${names[j]} =~ ${re} ]]; then
printer_data="${HOME}/printer_${names[${j}]}_data"
else
printer_data="${HOME}/${names[${j}]}_data"
fi
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/moonraker.conf"
uds="${printer_data}/comms/klippy.sock"
### write multi instance config
write_moonraker_conf "${cfg_dir}" "${cfg}" "${port}" "${uds}" "${lan}"
port=$(( port + 1 ))
j=$(( j + 1 ))
done && unset j
else
return 1
fi
(( port=port+1 ))
done && unset j
}
function write_moonraker_conf() {
@@ -304,56 +282,29 @@ function write_moonraker_conf() {
}
function configure_moonraker_service() {
local input=("${@}")
local moonraker_count=${input[0]} && unset "input[0]"
local names=("${input[@]}") && unset "input[@]"
local printer_data cfg_dir service env_file
local names=("${@}")
local moonraker_count=${#names[@]}
local printer_data cfg_dir service env_file service_name
for service in "${names[@]}"; do
printer_data=$(get_data_folder "${service}" "klipper")
if (( moonraker_count == 1 )) && [[ ${#names[@]} -eq 0 ]]; then
i=""
printer_data="${HOME}/printer_data"
cfg_dir="${printer_data}/config"
service="${SYSTEMD}/moonraker.service"
service_name="${service/"klipper"/"moonraker"}"
service="${SYSTEMD}/${service_name}"
env_file="${printer_data}/systemd/moonraker.env"
### create required folder structure
create_required_folders "${printer_data}"
### write single instance service
write_moonraker_service "" "${printer_data}" "${service}" "${env_file}"
ok_msg "Moonraker instance created!"
### write multi instance service
write_moonraker_service "${service_name}" "${printer_data}" "${service}" "${env_file}"
ok_msg "Moonraker instance '${service_name}' created!"
done && unset i
elif (( moonraker_count > 1 )) && [[ ${#names[@]} -gt 0 ]]; then
local j=0 re="^[1-9][0-9]*$"
for (( i=1; i <= moonraker_count; i++ )); do
### overwrite config folder if name is only a number
if [[ ${names[j]} =~ ${re} ]]; then
printer_data="${HOME}/printer_${names[${j}]}_data"
else
printer_data="${HOME}/${names[${j}]}_data"
fi
cfg_dir="${printer_data}/config"
service="${SYSTEMD}/moonraker-${names[${j}]}.service"
env_file="${printer_data}/systemd/moonraker.env"
### create required folder structure
create_required_folders "${printer_data}"
### write multi instance service
write_moonraker_service "${names[${j}]}" "${printer_data}" "${service}" "${env_file}"
ok_msg "Moonraker instance 'moonraker-${names[${j}]}' created!"
j=$(( j + 1 ))
done && unset i
### enable mainsails remoteMode if mainsail is found
if [[ -d ${MAINSAIL_DIR} ]]; then
enable_mainsail_remotemode
fi
else
return 1
### enable mainsails remoteMode if mainsail is found
if [[ -d ${MAINSAIL_DIR} ]]; then
enable_mainsail_remotemode
fi
}
@@ -361,6 +312,7 @@ function write_moonraker_service() {
local i=${1} printer_data=${2} service=${3} env_file=${4}
local service_template="${KIAUH_SRCDIR}/resources/moonraker.service"
local env_template="${KIAUH_SRCDIR}/resources/moonraker.env"
local instance_name=$(get_instance_name "${i}")
### replace all placeholders
if [[ ! -f ${service} ]]; then
@@ -368,8 +320,7 @@ function write_moonraker_service() {
sudo cp "${service_template}" "${service}"
sudo cp "${env_template}" "${env_file}"
[[ -z ${i} ]] && sudo sed -i "s| %INST%||" "${service}"
[[ -n ${i} ]] && sudo sed -i "s|%INST%|${i}|" "${service}"
sudo sed -i "s|%INST%|${instance_name}|" "${service}"
sudo sed -i "s|%USER%|${USER}|g; s|%ENV%|${MOONRAKER_ENV}|; s|%ENV_FILE%|${env_file}|" "${service}"
sudo sed -i "s|%USER%|${USER}|; s|%PRINTER_DATA%|${printer_data}|" "${env_file}"
fi
@@ -385,6 +336,45 @@ function print_mr_ip_list() {
done && echo
}
function get_moonraker_next_port() {
local port=7125
local moonraker_services=$(moonraker_systemd) moonraker_ports=()
for service in ${moonraker_services}
do
service_name=$(basename ${service})
moonraker_ports+=( "$(get_moonraker_port ${service_name})" )
done
while true; do
if [[ ! " ${moonraker_ports[*]} " =~ " ${port} " ]]; then
break
fi
(( port=port+1 ))
done
echo "${port}"
}
function get_moonraker_port() {
local service=${1}
local printer_data=$(get_data_folder ${service} moonraker)
local port=$(grep "^port:" "${printer_data}/config/moonraker.conf" | cut -f 2 -d " ")
echo "${port}"
}
function get_moonraker_address() {
local ip=$(hostname -I | cut -d" " -f1)
local port=$(get_moonraker_port ${1})
echo "${ip}:${port}"
}
function print_moonraker_addresses() {
local service_name moonraker_services=$(moonraker_systemd)
for service in ${moonraker_services}
do
service_name=$(basename ${service})
echo " ${cyan}${service_name}:${white} $(get_moonraker_address ${service_name})"
done
}
### introduced due to
### https://github.com/Arksine/moonraker/issues/349
### https://github.com/Arksine/moonraker/pull/346
@@ -435,22 +425,10 @@ function install_moonraker_polkit() {
#================ REMOVE MOONRAKER ================#
#==================================================#
function remove_moonraker_sysvinit() {
[[ ! -e "${INITD}/moonraker" ]] && return
status_msg "Removing Moonraker SysVinit service ..."
sudo systemctl stop moonraker
sudo update-rc.d -f moonraker remove
sudo rm -f "${INITD}/moonraker" "${ETCDEF}/moonraker"
ok_msg "Moonraker SysVinit service removed!"
}
function remove_moonraker_systemd() {
[[ -z $(moonraker_systemd) ]] && return
status_msg "Removing Moonraker Systemd Services ..."
for service in $(moonraker_systemd | cut -d"/" -f5); do
for service in "${@}"; do
status_msg "Removing ${service} ..."
sudo systemctl stop "${service}"
sudo systemctl disable "${service}"
@@ -465,29 +443,25 @@ function remove_moonraker_systemd() {
}
function remove_moonraker_env_file() {
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/systemd\/moonraker\.env"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
local printer_data file
for service in "${@}"; do
printer_data=$(get_data_folder ${service} moonraker)
file="${printer_data}/systemd/moonraker.env"
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
}
function remove_moonraker_logs() {
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/logs\/moonraker\.log.*"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
local printer_data file
for service in "${@}"; do
printer_data=$(get_data_folder ${service} moonraker)
file="${printer_data}/systemd/moonraker.lo"*
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
}
function remove_legacy_moonraker_logs() {
@@ -544,15 +518,72 @@ function remove_moonraker_polkit() {
}
function remove_moonraker() {
remove_moonraker_sysvinit
remove_moonraker_systemd
remove_moonraker_env_file
remove_moonraker_logs
local moonraker_services=$(moonraker_systemd)
if [[ -z ${moonraker_services} ]]; then
print_error "Moonraker not installed, nothing to do!"
return
fi
local moonraker_services=$(moonraker_systemd)
if [[ -z ${moonraker_services} ]]; then
print_error "Moonraker not installed, nothing to do!"
return
fi
top_border
echo -e "| ${red}~~~~~~~ [ Moonraker instance remover ] ~~~~~~${white} |"
hr
local user_input=() moonraker_names=()
local moonraker_services_count="$(moonraker_systemd | wc -w)"
if (( moonraker_services_count == 1 )); then
service_name=$(basename ${moonraker_services})
moonraker_names+=( "${service_name}" )
printf "| 0) %-51s|\n" "${service_name}"
else
printf "| 0) %-51s|\n" "Remove all"
local i=1 service_name
for name in ${moonraker_services}; do
service_name=$(basename ${name})
moonraker_names+=( "${service_name}" )
printf "| ${i}) %-51s|\n" "${service_name}"
(( i=i+1 ))
done
fi
back_footer
local option
while true; do
read -p "${cyan}Remove Moonraker instance:${white} " option
if [[ ${option} == "B" || ${option} == "b" ]]; then
return
elif [[ $((option)) != $option ]]; then
error_msg "Invalid command!"
elif (( option >= 0 && option < ${#moonraker_names[@]} )); then
break
else
error_msg "Invalid command!"
fi
done
if (( option == 0 )); then
user_input=( ${moonraker_names[@]} )
else
user_input=( "${moonraker_names[(( option-1 ))]}" )
fi
remove_moonraker_systemd "${user_input[@]}"
remove_moonraker_env_file "${user_input[@]}"
remove_moonraker_logs "${user_input[@]}"
remove_legacy_moonraker_logs
remove_moonraker_api_key
remove_moonraker_polkit
remove_moonraker_dir
remove_moonraker_env
if (( ${moonraker_services_count} == 1 )) || [[ "${option}" == "0" ]]; then
remove_moonraker_api_key
remove_moonraker_polkit
remove_moonraker_dir
remove_moonraker_env
fi
print_confirm "Moonraker was successfully removed!"
return
@@ -566,7 +597,8 @@ function update_moonraker() {
do_action_service "stop" "moonraker"
if [[ ! -d ${MOONRAKER_DIR} ]]; then
clone_moonraker "${MOONRAKER_REPO}"
error_msg "Nothing to update, Moonraker directory doesn't exists! Please install Moonraker first."
return
else
backup_before_update "moonraker"
status_msg "Updating Moonraker ..."

View File

@@ -629,6 +629,30 @@ function get_multi_instance_names() {
echo "${instance_names[@]}"
}
###
# helper function that returns klipper data directory
# path based on systemd service name.
#
# => return an empty string if klipper is not installed
# => return absolute config directory path
#
function get_data_folder() {
local service_name=${1}
local service_type=${2}
local instance_name
if [[ "${service_name}" == "${service_type}.service" ]]; then
echo "${HOME}/printer_data"
else
instance_name=$(get_instance_name "${service_name}")
if [[ ${instance_name} =~ ^[0-9]+$ ]]; then
echo "${HOME}/printer_${instance_name}_data"
else
echo "${HOME}/${instance_name}_data"
fi
fi
}
###
# helper function that returns all possibly available absolute
# klipper config directory paths based on their instance name.