Merge branch 'master' into install-remove-instances

This commit is contained in:
coderus
2023-02-28 21:57:01 +01:00
22 changed files with 562 additions and 216 deletions

241
scripts/crowsnest.sh Normal file
View File

@@ -0,0 +1,241 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# #
# 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 #
#=======================================================================#
#=======================================================================#
# Crowsnest Installer brought to you by KwadFan <me@stephanwe.de> #
# Copyright (C) 2022 KwadFan <me@stephanwe.de> #
# https://github.com/KwadFan/crowsnest #
#=======================================================================#
# Error Handling
set -e
# Helper messages
function multi_instance_message(){
echo -e "Crowsnest is NOT designed to support multi instances."
echo -e "A workaround for this is to choose the most used instance as a 'master'"
echo -e "Use this instance to set up your 'crowsnest.conf' and steering it's service.\n"
echo -e "Found the following instances:\n"
for i in ${1}; do
select_msg "${i}"
done
echo -e "\nLaunching crowsnest's configuration tool ..."
continue_config
}
# Helper funcs
function clone_crowsnest(){
$(command -v git) clone "${CROWSNEST_REPO}" -b master "${CROWSNEST_DIR}"
}
function check_multi_instance(){
local -a instances
readarray -t instances < <(find "${HOME}" -regex "${HOME}/[a-zA-Z0-9_]+_data/*" -printf "%P\n" 2> /dev/null | sort)
if [[ "${#instances[@]}" -gt 1 ]]; then
status_msg "Multi instance install detected ..."
multi_instance_message "${instances[*]}"
if [[ -d "${HOME}/crowsnest" ]]; then
pushd "${HOME}/crowsnest" &> /dev/null || exit 1
if ! make config ;then
error_msg "Something went wrong! Please try again..."
if [[ -f "tools/.config" ]]; then
rm -f tools/.config
fi
exit 1
fi
if [[ ! -f "tools/.config" ]]; then
log_error "failure while generating .config"
error_msg "Generating .config failed, installation aborted"
exit 1
fi
popd &> /dev/null || exit 1
fi
fi
}
function continue_config() {
local reply
while true; do
read -erp "${cyan}###### Continue with configuration? (y/N):${white} " reply
case "${reply}" in
Y|y|Yes|yes)
select_msg "Yes"
break;;
N|n|No|no|"")
select_msg "No"
warn_msg "Installation aborted by user ... Exiting!"
exit 1;;
*)
error_msg "Invalid Input!\n";;
esac
done
return 0
}
# Install func
function install_crowsnest(){
# Step 1: jump to home directory
pushd "${HOME}" &> /dev/null || exit 1
# Step 2: Clone crowsnest repo
status_msg "Cloning 'crowsnest' repository ..."
if [[ ! -d "${HOME}/crowsnest" && -z "$(ls -A "${HOME}/crowsnest" 2> /dev/null)" ]]; then
clone_crowsnest
else
ok_msg "crowsnest repository already exists ..."
fi
# Step 3: Install dependencies
dependency_check git make
# Step 4: Check for Multi Instance
check_multi_instance
# Step 5: Launch crowsnest installer
pushd "${HOME}/crowsnest" &> /dev/null || exit 1
title_msg "Installer will prompt you for sudo password!"
status_msg "Launching crowsnest installer ..."
if ! sudo make install; then
error_msg "Something went wrong! Please try again..."
exit 1
fi
# Step 5: Leave directory (twice due two pushd)
popd &> /dev/null || exit 1
popd &> /dev/null || exit 1
}
# Remove func
function remove_crowsnest(){
pushd "${HOME}/crowsnest" &> /dev/null || exit 1
title_msg "Uninstaller will prompt you for sudo password!"
status_msg "Launching crowsnest uninstaller ..."
if ! make uninstall; then
error_msg "Something went wrong! Please try again..."
exit 1
fi
if [[ -e "${CROWSNEST_DIR}" ]]; then
status_msg "Removing crowsnest directory ..."
rm -rf "${CROWSNEST_DIR}"
ok_msg "Directory removed!"
fi
}
# Status funcs
get_crowsnest_status(){
local -a files
local env_file
env_file="$(grep "EnvironmentFile" /etc/systemd/system/crowsnest.service | cut -d "=" -f2)"
files=(
"${CROWSNEST_DIR}"
"/usr/local/bin/crowsnest"
"/etc/logrotate.d/crowsnest"
"/etc/systemd/system/crowsnest.service"
"${env_file}"
)
local count
count=0
for file in "${files[@]}"; do
[[ -e "${file}" ]] && count=$(( count +1 ))
done
if [[ "${count}" -eq "${#files[*]}" ]]; then
echo "Installed"
elif [[ "${count}" -gt 0 ]]; then
echo "Incomplete!"
else
echo "Not installed!"
fi
}
# Update funcs
# Shameless stolen from KlipperScreen.sh
function get_local_crowsnest_commit() {
[[ ! -d ${CROWSNEST_DIR} || ! -d "${CROWSNEST_DIR}/.git" ]] && return
local commit
cd "${CROWSNEST_DIR}"
commit="$(git describe HEAD --always --tags | cut -d "-" -f 1,2)"
echo "${commit}"
}
function get_remote_crowsnest_commit() {
[[ ! -d ${CROWSNEST_DIR} || ! -d "${CROWSNEST_DIR}/.git" ]] && return
local commit
cd "${CROWSNEST_DIR}" && git fetch origin -q
commit=$(git describe origin/master --always --tags | cut -d "-" -f 1,2)
echo "${commit}"
}
function compare_crowsnest_versions() {
local versions local_ver remote_ver
local_ver="$(get_local_crowsnest_commit)"
remote_ver="$(get_remote_crowsnest_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 "crowsnest"
else
versions="${green}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
fi
echo "${versions}"
}
function install_crowsnest_dependencies() {
local packages
local install_script="${CROWSNEST_DIR}/tools/install.sh"
### read PKGLIST from official install-script
status_msg "Reading dependencies..."
# shellcheck disable=SC2016
packages="$(grep "PKGLIST=" "${install_script}" | cut -d'"' -f2 | sed 's/\${PKGLIST}//g' | tr -d '\n')"
echo "${cyan}${packages}${white}" | tr '[:space:]' '\n'
read -r -a packages <<< "${packages}"
### Update system package info
status_msg "Updating package lists..."
if ! sudo apt-get update --allow-releaseinfo-change; then
log_error "failure while updating package lists"
error_msg "Updating package lists failed!"
exit 1
fi
### Install required packages
status_msg "Installing required packages..."
if ! sudo apt-get install --yes "${packages[@]}"; then
log_error "failure while installing required crowsnest packages"
error_msg "Installing required packages failed!"
exit 1
fi
}
function update_crowsnest() {
do_action_service "stop" "crowsnest"
if [[ ! -d ${CROWSNEST_DIR} ]]; then
clone_crowsnest
else
status_msg "Updating Crowsnest ..."
cd "${CROWSNEST_DIR}" && git pull
### read PKGLIST and install possible new dependencies
install_crowsnest_dependencies
fi
ok_msg "Update complete!"
do_action_service "restart" "crowsnest"
}

View File

@@ -39,30 +39,6 @@ function install_fluidd() {
### check if another site already listens to port 80
fluidd_port_check
# ### ask user to install mjpg-streamer
# local install_mjpg_streamer
# if [[ ! -f "${SYSTEMD}/webcamd.service" ]]; then
# while true; do
# echo
# top_border
# echo -e "| Install MJPG-Streamer for webcam support? |"
# bottom_border
# read -p "${cyan}###### Please select (y/N):${white} " yn
# case "${yn}" in
# Y|y|Yes|yes)
# select_msg "Yes"
# install_mjpg_streamer="true"
# break;;
# N|n|No|no|"")
# select_msg "No"
# install_mjpg_streamer="false"
# break;;
# *)
# error_msg "Invalid command!";;
# esac
# done
# fi
### download fluidd
download_fluidd
@@ -82,9 +58,6 @@ function install_fluidd() {
### add fluidd to the update manager in moonraker.conf
patch_fluidd_update_manager
### install mjpg-streamer
# [[ ${install_mjpg_streamer} == "true" ]] && install_mjpg-streamer
fetch_webui_ports #WIP
### confirm message
@@ -92,22 +65,21 @@ function install_fluidd() {
}
function install_fluidd_macros() {
local yn
while true; do
echo
top_border
echo -e "| It is recommended to have some important macros in |"
echo -e "| your printer configuration to have Fluidd fully |"
echo -e "| functional and working. |"
echo -e "| It is recommended to use special macros in order to |"
echo -e "| have Fluidd fully functional and working. |"
blank_line
echo -e "| The recommended macros for Fluidd can be found here: |"
echo -e "| https://docs.fluidd.xyz/configuration/initial_setup |"
echo -e "| https://github.com/fluidd-core/fluidd-config |"
blank_line
echo -e "| If you already have these macros in your config file, |"
echo -e "| skip this step and answer with 'no'. |"
echo -e "| If you already use these macros skip this step. |"
echo -e "| Otherwise you should consider to answer with 'yes' to |"
echo -e "| add the recommended example macros to your config. |"
echo -e "| download the recommended macros. |"
bottom_border
read -p "${cyan}###### Add the recommended macros? (Y/n):${white} " yn
read -p "${cyan}###### Download the recommended macros? (Y/n):${white} " yn
case "${yn}" in
Y|y|Yes|yes|"")
select_msg "Yes"
@@ -124,36 +96,64 @@ function install_fluidd_macros() {
}
function download_fluidd_macros() {
local fluidd_cfg path configs regex
local ms_cfg_repo path configs regex line gcode_dir
fluidd_cfg="https://raw.githubusercontent.com/fluidd-core/FluiddPI/master/src/modules/fluidd/filesystem/home/pi/klipper_config/fluidd.cfg"
regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/config\/printer\.cfg"
ms_cfg_repo="https://github.com/fluidd-core/fluidd-config.git"
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/printer\.cfg"
configs=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${configs} ]]; then
for config in ${configs}; do
path=$(echo "${config}" | rev | cut -d"/" -f2- | rev)
if [[ ! -f "${path}/fluidd.cfg" ]]; then
status_msg "Downloading fluidd.cfg to ${path} ..."
log_info "downloading fluidd.cfg to: ${path}"
wget "${fluidd_cfg}" -O "${path}/fluidd.cfg"
### replace user 'pi' with current username to prevent issues in cases where the user is not called 'pi'
log_info "modify fluidd.cfg"
sed -i "/^path: \/home\/pi\/gcode_files/ s/\/home\/pi/\/home\/${USER}/" "${path}/fluidd.cfg"
### write include to the very first line of the printer.cfg
if ! grep -Eq "^[include fluidd.cfg]$" "${path}/printer.cfg"; then
log_info "modify printer.cfg"
sed -i "1 i [include fluidd.cfg]" "${path}/printer.cfg"
fi
ok_msg "Done!"
fi
done
else
if [[ -z ${configs} ]]; then
print_error "No printer.cfg found! Installation of Macros will be skipped ..."
log_error "execution stopped! reason: no printer.cfg found"
return
fi
status_msg "Cloning fluidd-config ..."
[[ -d "${HOME}/fluidd-config" ]] && rm -rf "${HOME}/fluidd-config"
if git clone --recurse-submodules "${ms_cfg_repo}" "${HOME}/fluidd-config"; then
for config in ${configs}; do
path=$(echo "${config}" | rev | cut -d"/" -f2- | rev)
if [[ -e "${path}/fluidd.cfg" && ! -h "${path}/fluidd.cfg" ]]; then
warn_msg "Attention! Existing fluidd.cfg detected!"
warn_msg "The file will be renamed to 'fluidd.bak.cfg' to be able to continue with the installation."
if ! mv "${path}/fluidd.cfg" "${path}/fluidd.bak.cfg"; then
error_msg "Renaming fluidd.cfg failed! Aborting installation ..."
return
fi
fi
if [[ -h "${path}/fluidd.cfg" ]]; then
warn_msg "Recreating symlink in ${path} ..."
rm -rf "${path}/fluidd.cfg"
fi
if ! ln -sf "${HOME}/fluidd-config/client.cfg" "${path}/fluidd.cfg"; then
error_msg "Creating symlink failed! Aborting installation ..."
return
fi
if ! grep -Eq "^\[include fluidd.cfg\]$" "${path}/printer.cfg"; then
log_info "${path}/printer.cfg"
sed -i "1 i [include fluidd.cfg]" "${path}/printer.cfg"
fi
line=$(($(grep -n "\[include fluidd.cfg\]" "${path}/printer.cfg" | tail -1 | cut -d: -f1) + 1))
gcode_dir=${path/config/gcodes}
if ! grep -Eq "^\[virtual_sdcard\]$" "${path}/printer.cfg"; then
log_info "${path}/printer.cfg"
sed -i "${line} i \[virtual_sdcard]\npath: ${gcode_dir}\non_error_gcode: CANCEL_PRINT\n" "${path}/printer.cfg"
fi
done
else
print_error "Cloning failed! Aborting installation ..."
log_error "execution stopped! reason: cloning failed"
return
fi
patch_fluidd_config_update_manager
ok_msg "Done!"
}
function download_fluidd() {
@@ -191,7 +191,7 @@ function remove_fluidd_dir() {
rm -rf "${FLUIDD_DIR}" && ok_msg "Directory removed!"
}
function remove_fluidd_config() {
function remove_fluidd_nginx_config() {
if [[ -e "/etc/nginx/sites-available/fluidd" ]]; then
status_msg "Removing Fluidd configuration for Nginx ..."
sudo rm "/etc/nginx/sites-available/fluidd" && ok_msg "File removed!"
@@ -218,7 +218,7 @@ function remove_fluidd_logs() {
function remove_fluidd_log_symlinks() {
local files regex
regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/logs\/fluidd-.*"
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/logs\/fluidd-.*"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" 2> /dev/null | sort)
if [[ -n ${files} ]]; then
@@ -243,9 +243,18 @@ function remove_legacy_fluidd_log_symlinks() {
fi
}
function remove_fluidd_config() {
if [[ -d "${HOME}/fluidd-config" ]]; then
status_msg "Removing ${HOME}/fluidd-config ..."
rm -rf "${HOME}/fluidd-config"
ok_msg "${HOME}/fluidd-config removed!"
print_confirm "Fluidd-Config successfully removed!"
fi
}
function remove_fluidd() {
remove_fluidd_dir
remove_fluidd_config
remove_fluidd_nginx_config
remove_fluidd_logs
remove_fluidd_log_symlinks
remove_legacy_fluidd_log_symlinks
@@ -389,7 +398,7 @@ function select_fluidd_port() {
blank_line
[[ ${MAINSAIL_PORT} == "80" ]] && echo "| ● Mainsail |"
blank_line
echo -e "| Make sure you don't choose a port which is already |"
echo -e "| Make sure you don't choose a port which was already |"
echo -e "| assigned to another webinterface! |"
blank_line
echo -e "| Be aware: there is ${red}NO${white} sanity check for the following |"
@@ -416,7 +425,7 @@ function select_fluidd_port() {
function patch_fluidd_update_manager() {
local patched moonraker_configs regex
regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/config\/moonraker\.conf"
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/moonraker\.conf"
moonraker_configs=$(find "${HOME}" -maxdepth 3 -type f -regextype posix-extended -regex "${regex}" | sort)
patched="false"
@@ -445,3 +454,36 @@ MOONRAKER_CONF
do_action_service "restart" "moonraker"
fi
}
function patch_fluidd_config_update_manager() {
local patched moonraker_configs regex
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/moonraker\.conf"
moonraker_configs=$(find "${HOME}" -maxdepth 3 -type f -regextype posix-extended -regex "${regex}" | sort)
patched="false"
for conf in ${moonraker_configs}; do
if ! grep -Eq "^\[update_manager fluidd-config\]\s*$" "${conf}"; then
### add new line to conf if it doesn't end with one
[[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"
### add Fluidds update manager section to moonraker.conf
status_msg "Adding Fluidd-Config to update manager in file:\n ${conf}"
/bin/sh -c "cat >> ${conf}" << MOONRAKER_CONF
[update_manager fluidd-config]
type: git_repo
primary_branch: master
path: ~/fluidd-config
origin: https://github.com/fluidd-core/fluidd-config.git
managed_services: klipper
MOONRAKER_CONF
fi
patched="true"
done
if [[ ${patched} == "true" ]]; then
do_action_service "restart" "moonraker"
fi
}

View File

@@ -106,7 +106,7 @@ function create_example_shell_command() {
backup_klipper_config_dir
local configs regex path
regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/config\/printer\.cfg"
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/printer\.cfg"
configs=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
for cfg in ${configs}; do

View File

@@ -68,4 +68,9 @@ function set_globals() {
#=============== MOONRAKER-OBICO ================#
MOONRAKER_OBICO_DIR="${HOME}/moonraker-obico"
MOONRAKER_OBICO_REPO="https://github.com/TheSpaghettiDetective/moonraker-obico.git"
#=============== Crowsnest ================#
CROWSNEST_DIR="${HOME}/crowsnest"
CROWSNEST_REPO="https://github.com/mainsail-crew/crowsnest.git"
}

View File

@@ -19,8 +19,30 @@ set -e
#================ INSTALL KLIPPER ================#
#=================================================#
###
# this function detects all installed klipper
# systemd instances and returns their absolute path
function klipper_systemd() {
local services
local blacklist
local ignore
local match
###
# any service that uses "klipper" in its own name but isn't a full klipper service must be blacklisted using
# this variable, otherwise they will be falsely recognized as klipper instances. E.g. "klipper-mcu.service"
# is not a klipper service, but related to klippers linux mcu, which also requires its own service file, hence
# it must be blacklisted.
blacklist="mcu"
ignore="${SYSTEMD}/klipper-(${blacklist}).service"
match="${SYSTEMD}/klipper(-[0-9a-zA-Z]+)?.service"
services=$(find "${SYSTEMD}" -maxdepth 1 -regextype awk ! -regex "${ignore}" -regex "${match}" | sort)
echo "${services}"
}
function start_klipper_setup() {
local klipper_initd_service
local klipper_systemd_services
local python_version
local instance_count
@@ -28,24 +50,17 @@ function start_klipper_setup() {
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_initd_service=$(find_klipper_initd)
klipper_systemd_services=$(find_klipper_systemd)
if [[ -n ${klipper_initd_service} ]]; then
error="Unsupported Klipper SysVinit service detected:"
error="${error}\n ➔ ${klipper_initd_service}"
error="${error}\n Please re-install Klipper with KIAUH!"
log_info "Unsupported Klipper SysVinit service detected: ${klipper_initd_service}"
fi
klipper_systemd_services=$(klipper_systemd)
local klipper_systemd_services_count=0
if [[ -n ${klipper_systemd_services} ]]; then
klipper_systemd_services_count=$(find_klipper_systemd | wc -w)
klipper_systemd_services_count=$(klipper_systemd | wc -w)
status_msg "Following Klipper instances are already installed:"
for s in ${klipper_systemd_services}; do
@@ -117,15 +132,19 @@ function start_klipper_setup() {
fi
### user selection for setting the actual custom names
shopt -s nocasematch
if [[ ${use_custom_names} == "true" ]]; then
local i
i=1
regex="^[0-9a-zA-Z]+$"
while [[ ! ${input} =~ ${regex} || ${i} -le ${instance_count} ]]; do
blacklist="mcu"
while [[ ! ${input} =~ ${regex} || ${input} =~ ${blacklist} || ${i} -le ${instance_count} ]]; do
read -p "${cyan}###### Name for instance #${i}:${white} " input
if [[ ${input} =~ ${regex} ]]; then
if [[ ${input} =~ ${blacklist} ]]; then
error_msg "Name not allowed! You are trying to use a reserved name."
elif [[ ${input} =~ ${regex} && ! ${input} =~ ${blacklist} ]]; then
select_msg "Name: ${input}\n"
local instance_name
if [[ ${input} =~ ^[0-9]+$ ]]; then
@@ -153,6 +172,7 @@ function start_klipper_setup() {
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 ..."
@@ -426,12 +446,6 @@ function write_example_printer_cfg() {
function remove_klipper_service() {
status_msg "Removing Klipper services ..."
if [[ -e "${INITD}/klipper" ]]; then
sudo systemctl stop klipper
sudo update-rc.d -f klipper remove
sudo rm -f "${INITD}/klipper" "${ETCDEF}/klipper"
fi
for service in "${@}"; do
status_msg "Removing ${service} ..."
sudo systemctl stop "${service}"
@@ -547,7 +561,7 @@ function remove_klipper() {
remove_files "$(find_legacy_klipper_uds)"
remove_files "$(find_legacy_klipper_printer)"
local klipper_systemd_services=$(find_klipper_systemd)
local klipper_systemd_services=$(klipper_systemd)
if [[ -z ${klipper_systemd_services} ]]; then
print_error "Klipper not installed, nothing to do!"
return
@@ -558,7 +572,7 @@ function remove_klipper() {
hr
local user_input=() klipper_names=()
local klipper_services_count="$(find_klipper_systemd | wc -w)"
local klipper_services_count="$(klipper_systemd | wc -w)"
if (( klipper_services_count == 1 )); then
service_name=$(basename ${klipper_systemd_services})
klipper_names+=( "${service_name}" )
@@ -598,7 +612,7 @@ function remove_klipper() {
remove_klipper_service "${user_input[@]}"
remove_klipper_files "${user_input[@]}"
if (( ${klipper_services_count} == 1 )) || [[ "${klipper_count}" == "0" ]]; then
if (( ${klipper_services_count} == 1 )) || [[ "${option}" == "0" ]]; then
remove_klipper_dir
remove_klipper_env
fi
@@ -649,13 +663,7 @@ function update_klipper() {
function get_klipper_status() {
local sf_count status py_ver
sf_count="$(find_klipper_systemd | wc -w)"
### detect an existing "legacy" klipper init.d installation
if [[ $(find_klipper_systemd | wc -w) -eq 0 ]] \
&& [[ $(find_klipper_initd | wc -w) -ge 1 ]]; then
sf_count=1
fi
sf_count="$(klipper_systemd | wc -w)"
py_ver=$(get_klipper_python_ver)
@@ -735,4 +743,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

@@ -30,7 +30,7 @@ function install_mainsail() {
status_msg "Initializing Mainsail installation ..."
### first, we create a backup of the full klipper_config dir - safety first!
backup_klipper_config_dir
#backup_klipper_config_dir
### check for other enabled web interfaces
unset SET_LISTEN_PORT
@@ -39,30 +39,6 @@ function install_mainsail() {
### check if another site already listens to port 80
mainsail_port_check
# ### ask user to install mjpg-streamer
# local install_mjpg_streamer
# if [[ ! -f "${SYSTEMD}/webcamd.service" ]]; then
# while true; do
# echo
# top_border
# echo -e "| Install MJPG-Streamer for webcam support? |"
# bottom_border
# read -p "${cyan}###### Please select (y/N):${white} " yn
# case "${yn}" in
# Y|y|Yes|yes)
# select_msg "Yes"
# install_mjpg_streamer="true"
# break;;
# N|n|No|no|"")
# select_msg "No"
# install_mjpg_streamer="false"
# break;;
# *)
# error_msg "Invalid command!";;
# esac
# done
# fi
### download mainsail
download_mainsail
@@ -82,9 +58,6 @@ function install_mainsail() {
### add mainsail to the update manager in moonraker.conf
patch_mainsail_update_manager
### install mjpg-streamer
# [[ ${install_mjpg_streamer} == "true" ]] && install_mjpg-streamer
fetch_webui_ports #WIP
### confirm message
@@ -92,22 +65,21 @@ function install_mainsail() {
}
function install_mainsail_macros() {
local yn
while true; do
echo
top_border
echo -e "| It is recommended to have some important macros in |"
echo -e "| your printer configuration to have Mainsail fully |"
echo -e "| functional and working. |"
echo -e "| It is recommended to use special macros in order to |"
echo -e "| have Mainsail fully functional and working. |"
blank_line
echo -e "| The recommended macros for Mainsail can be seen here: |"
echo -e "| https://docs.mainsail.xyz/configuration#macros |"
echo -e "| https://github.com/mainsail-crew/mainsail-config |"
blank_line
echo -e "| If you already have these macros in your config file, |"
echo -e "| skip this step and answer with 'no'. |"
echo -e "| If you already use these macros skip this step. |"
echo -e "| Otherwise you should consider to answer with 'yes' to |"
echo -e "| add the recommended example macros to your config. |"
echo -e "| download the recommended macros. |"
bottom_border
read -p "${cyan}###### Add the recommended macros? (Y/n):${white} " yn
read -p "${cyan}###### Download the recommended macros? (Y/n):${white} " yn
case "${yn}" in
Y|y|Yes|yes|"")
select_msg "Yes"
@@ -124,36 +96,64 @@ function install_mainsail_macros() {
}
function download_mainsail_macros() {
local ms_cfg path configs regex
local ms_cfg_repo path configs regex line gcode_dir
ms_cfg="https://raw.githubusercontent.com/mainsail-crew/mainsail-config/master/mainsail.cfg"
regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/config\/printer\.cfg"
ms_cfg_repo="https://github.com/mainsail-crew/mainsail-config.git"
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/printer\.cfg"
configs=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${configs} ]]; then
for config in ${configs}; do
path=$(echo "${config}" | rev | cut -d"/" -f2- | rev)
if [[ ! -f "${path}/mainsail.cfg" ]]; then
status_msg "Downloading mainsail.cfg to ${path} ..."
log_info "downloading mainsail.cfg to: ${path}"
wget "${ms_cfg}" -O "${path}/mainsail.cfg"
### replace user 'pi' with current username to prevent issues in cases where the user is not called 'pi'
log_info "modify mainsail.cfg"
sed -i "/^path: \/home\/pi\/gcode_files/ s/\/home\/pi/\/home\/${USER}/" "${path}/mainsail.cfg"
### write include to the very first line of the printer.cfg
if ! grep -Eq "^[include mainsail.cfg]$" "${path}/printer.cfg"; then
log_info "modify printer.cfg"
sed -i "1 i [include mainsail.cfg]" "${path}/printer.cfg"
fi
ok_msg "Done!"
fi
done
else
if [[ -z ${configs} ]]; then
print_error "No printer.cfg found! Installation of Macros will be skipped ..."
log_error "execution stopped! reason: no printer.cfg found"
return
fi
status_msg "Cloning mainsail-config ..."
[[ -d "${HOME}/mainsail-config" ]] && rm -rf "${HOME}/mainsail-config"
if git clone "${ms_cfg_repo}" "${HOME}/mainsail-config"; then
for config in ${configs}; do
path=$(echo "${config}" | rev | cut -d"/" -f2- | rev)
if [[ -e "${path}/mainsail.cfg" && ! -h "${path}/mainsail.cfg" ]]; then
warn_msg "Attention! Existing mainsail.cfg detected!"
warn_msg "The file will be renamed to 'mainsail.bak.cfg' to be able to continue with the installation."
if ! mv "${path}/mainsail.cfg" "${path}/mainsail.bak.cfg"; then
error_msg "Renaming mainsail.cfg failed! Aborting installation ..."
return
fi
fi
if [[ -h "${path}/mainsail.cfg" ]]; then
warn_msg "Recreating symlink in ${path} ..."
rm -rf "${path}/mainsail.cfg"
fi
if ! ln -sf "${HOME}/mainsail-config/client.cfg" "${path}/mainsail.cfg"; then
error_msg "Creating symlink failed! Aborting installation ..."
return
fi
if ! grep -Eq "^\[include mainsail.cfg\]$" "${path}/printer.cfg"; then
log_info "${path}/printer.cfg"
sed -i "1 i [include mainsail.cfg]" "${path}/printer.cfg"
fi
line=$(($(grep -n "\[include mainsail.cfg\]" "${path}/printer.cfg" | tail -1 | cut -d: -f1) + 1))
gcode_dir=${path/config/gcodes}
if ! grep -Eq "^\[virtual_sdcard\]$" "${path}/printer.cfg"; then
log_info "${path}/printer.cfg"
sed -i "${line} i \[virtual_sdcard]\npath: ${gcode_dir}\non_error_gcode: CANCEL_PRINT\n" "${path}/printer.cfg"
fi
done
else
print_error "Cloning failed! Aborting installation ..."
log_error "execution stopped! reason: cloning failed"
return
fi
patch_mainsail_config_update_manager
ok_msg "Done!"
}
function download_mainsail() {
@@ -196,7 +196,7 @@ function remove_mainsail_dir() {
rm -rf "${MAINSAIL_DIR}" && ok_msg "Directory removed!"
}
function remove_mainsail_config() {
function remove_mainsail_nginx_config() {
if [[ -e "/etc/nginx/sites-available/mainsail" ]]; then
status_msg "Removing Mainsail configuration for Nginx ..."
sudo rm "/etc/nginx/sites-available/mainsail" && ok_msg "File removed!"
@@ -223,7 +223,7 @@ function remove_mainsail_logs() {
function remove_mainsail_log_symlinks() {
local files regex
regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/logs\/mainsail-.*"
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/logs\/mainsail-.*"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" 2> /dev/null | sort)
if [[ -n ${files} ]]; then
@@ -248,9 +248,18 @@ function remove_legacy_mainsail_log_symlinks() {
fi
}
function remove_mainsail_config() {
if [[ -d "${HOME}/mainsail-config" ]]; then
status_msg "Removing ${HOME}/mainsail-config ..."
rm -rf "${HOME}/mainsail-config"
ok_msg "${HOME}/mainsail-config removed!"
print_confirm "Mainsail-Config successfully removed!"
fi
}
function remove_mainsail() {
remove_mainsail_dir
remove_mainsail_config
remove_mainsail_nginx_config
remove_mainsail_logs
remove_mainsail_log_symlinks
remove_legacy_mainsail_log_symlinks
@@ -460,7 +469,7 @@ function ms_theme_install() {
function ms_theme_delete() {
local regex theme_folders target_folders=()
regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/config\/\.theme"
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/\.theme"
theme_folders=$(find "${HOME}" -maxdepth 3 -type d -regextype posix-extended -regex "${regex}" | sort)
# theme_folders=$(find "${KLIPPER_CONFIG}" -mindepth 1 -type d -name ".theme" | sort)
@@ -594,7 +603,7 @@ function enable_mainsail_remotemode() {
function patch_mainsail_update_manager() {
local patched moonraker_configs regex
regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/config\/moonraker\.conf"
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/moonraker\.conf"
moonraker_configs=$(find "${HOME}" -maxdepth 3 -type f -regextype posix-extended -regex "${regex}" | sort)
patched="false"
@@ -623,3 +632,36 @@ MOONRAKER_CONF
do_action_service "restart" "moonraker"
fi
}
function patch_mainsail_config_update_manager() {
local patched moonraker_configs regex
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/moonraker\.conf"
moonraker_configs=$(find "${HOME}" -maxdepth 3 -type f -regextype posix-extended -regex "${regex}" | sort)
patched="false"
for conf in ${moonraker_configs}; do
if ! grep -Eq "^\[update_manager mainsail-config\]\s*$" "${conf}"; then
### add new line to conf if it doesn't end with one
[[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"
### add Mainsails update manager section to moonraker.conf
status_msg "Adding Mainsail-Config to update manager in file:\n ${conf}"
/bin/sh -c "cat >> ${conf}" << MOONRAKER_CONF
[update_manager mainsail-config]
type: git_repo
primary_branch: master
path: ~/mainsail-config
origin: https://github.com/mainsail-crew/mainsail-config.git
managed_services: klipper
MOONRAKER_CONF
fi
patched="true"
done
if [[ ${patched} == "true" ]]; then
do_action_service "restart" "moonraker"
fi
}

View File

@@ -376,7 +376,7 @@ function remove_telegram_bot_env() {
}
function remove_telegram_bot_env_file() {
local files regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/systemd\/moonraker-telegram-bot\.env"
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/systemd\/moonraker-telegram-bot\.env"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${files} ]]; then
@@ -389,7 +389,7 @@ function remove_telegram_bot_env_file() {
}
function remove_telegram_bot_logs() {
local files regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/logs\/telegram\.log.*"
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/logs\/telegram\.log.*"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${files} ]]; then
@@ -519,7 +519,7 @@ function compare_telegram_bot_versions() {
function patch_telegram_bot_update_manager() {
local patched moonraker_configs regex
regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/config\/moonraker\.conf"
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/moonraker\.conf"
moonraker_configs=$(find "${HOME}" -maxdepth 3 -type f -regextype posix-extended -regex "${regex}" | sort)
patched="false"

View File

@@ -44,7 +44,7 @@ function moonraker_setup_dialog() {
print_error "${error}" && return
fi
local klipper_services=$(find_klipper_systemd)
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}")" )
@@ -590,7 +590,7 @@ function remove_moonraker() {
remove_legacy_moonraker_logs
if (( ${moonraker_services_count} == 1 )) || [[ "${moonraker_count}" == "0" ]]; then
if (( ${moonraker_services_count} == 1 )) || [[ "${option}" == "0" ]]; then
remove_moonraker_api_key
remove_moonraker_polkit
remove_moonraker_dir

View File

@@ -79,7 +79,7 @@ function symlink_webui_nginx_log() {
interface=${1}
access_log="/var/log/nginx/${interface}-access.log"
error_log="/var/log/nginx/${interface}-error.log"
regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/logs"
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/logs"
logpaths=$(find "${HOME}" -maxdepth 2 -type d -regextype posix-extended -regex "${regex}" | sort)
for path in ${logpaths}; do

View File

@@ -188,7 +188,7 @@ function moonraker_obico_setup_dialog() {
-C "${instance_cfg_dirs[0]}/moonraker.conf"\
-p "${port}" -H 127.0.0.1 -l\
"${instance_log_dirs[0]}"\
-s -L -S "${obico_server_url}"
-L -S "${obico_server_url}"
elif (( moonraker_count > 1 )); then
local j=${existing_moonraker_obico_count}
@@ -199,7 +199,7 @@ function moonraker_obico_setup_dialog() {
-p $((port+j))\
-H 127.0.0.1\
-l "${instance_log_dirs[${j}]}"\
-s -L -S "${obico_server_url}"
-L -S "${obico_server_url}"
j=$(( j + 1 ))
done && unset j
fi # (( moonraker_count == 1 ))
@@ -311,7 +311,7 @@ function remove_moonraker_obico_systemd() {
}
function remove_moonraker_obico_logs() {
local files regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/logs\/moonraker-obico(-[0-9a-zA-Z]+)?\.log(.*)?"
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/logs\/moonraker-obico(-[0-9a-zA-Z]+)?\.log(.*)?"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${files} ]]; then

View File

@@ -25,7 +25,7 @@ function octoprint_setup_dialog() {
status_msg "Initializing OctoPrint installation ..."
local klipper_services
klipper_services=$(find_klipper_systemd)
klipper_services=$(klipper_systemd)
if [[ -z ${klipper_services} ]]; then
local error="Klipper not installed! Please install Klipper first!"
log_error "OctoPrint setup started without Klipper being installed. Aborting setup."

View File

@@ -38,7 +38,7 @@ function install_pgc_for_klipper() {
fi
sudo cp "${pgconfsrc}" "${pgconf}"
sudo sed -i "s|/home/pi/pgcode;|/home/${USER}/pgcode;|" "${pgconf}"
sudo sed -i "s|/home/pi/pgcode;|${HOME}/pgcode;|" "${pgconf}"
### replace default port
if (( pgc_custom_port != pgc_default_port )); then

View File

@@ -28,7 +28,7 @@ function install_ui() {
echo -e "| 4) [Fluidd] | 9) $(obico_install_title) |"
echo -e "| | |"
echo -e "| Touchscreen GUI: | Webcam Streamer: |"
echo -e "| 5) [KlipperScreen] | 10) [MJPG-Streamer] |"
echo -e "| 5) [KlipperScreen] | 10) [Crowsnest] |"
back_footer
}
@@ -64,11 +64,8 @@ function install_menu() {
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";;
clear && print_header
print_error "Function currently disabled! Sorry!"
install_ui;;
10)
do_action "install_crowsnest" "install_ui";;
B|b)
clear; main_menu; break;;
*)

View File

@@ -25,9 +25,11 @@ function main_ui() {
echo -e "| 2) [Update] | Moonraker: $(print_status "moonraker")|"
echo -e "| 3) [Remove] | |"
echo -e "| 4) [Advanced] | Mainsail: $(print_status "mainsail")|"
echo -e "| 5) [Backup] | Fluidd: $(print_status "fluidd")|"
# echo -e "| 5) [Backup] | Fluidd: $(print_status "fluidd")|"
echo -e "| | Fluidd: $(print_status "fluidd")|"
echo -e "| | KlipperScreen: $(print_status "klipperscreen")|"
echo -e "| 6) [Settings] | Telegram Bot: $(print_status "telegram_bot")|"
echo -e "| | Crowsnest: $(print_status "crowsnest")|"
echo -e "| | Obico: $(print_status "moonraker_obico")|"
echo -e "| | |"
echo -e "| $(print_kiauh_version)| Octoprint: $(print_status "octoprint")|"
@@ -106,6 +108,9 @@ function main_menu() {
"start octoprint") do_action_service "start" "octoprint"; main_ui;;
"stop octoprint") do_action_service "stop" "octoprint"; main_ui;;
"restart octoprint") do_action_service "restart" "octoprint"; main_ui;;
"start crowsnest") do_action_service "start" "crowsnest"; main_ui;;
"stop crowsnest") do_action_service "stop" "crowsnest"; main_ui;;
"restart crowsnest") do_action_service "restart" "crowsnest"; main_ui;;
update) do_action "update_kiauh" "main_ui";;
0)clear && print_header
#upload_selection

View File

@@ -18,16 +18,17 @@ function remove_ui() {
echo -e "| ${yellow}INFO: Configurations and/or any backups will be kept!${white} |"
hr
echo -e "| Firmware & API: | 3rd Party Webinterface: |"
echo -e "| 1) [Klipper] | 6) [OctoPrint] |"
echo -e "| 1) [Klipper] | 8) [OctoPrint] |"
echo -e "| 2) [Moonraker] | |"
echo -e "| | Webcam Streamer: |"
echo -e "| Klipper Webinterface: | 7) [MJPG-Streamer] |"
echo -e "| 3) [Mainsail] | |"
echo -e "| 4) [Fluidd] | Other: |"
echo -e "| | 8) [PrettyGCode] |"
echo -e "| Touchscreen GUI: | 9) [Telegram Bot] |"
echo -e "| 5) [KlipperScreen] | 10) [Obico for Klipper] |"
echo -e "| | 11) [NGINX] |"
echo -e "| Klipper Webinterface: | 9) [Crowsnest] |"
echo -e "| 3) [Mainsail] | 10) [MJPG-Streamer] |"
echo -e "| 4) [Mainsail-Config] | |"
echo -e "| 5) [Fluidd] | Other: |"
echo -e "| 6) [Fluidd-Config] | 11) [PrettyGCode] |"
echo -e "| | 12) [Telegram Bot] |"
echo -e "| Touchscreen GUI: | 13) [Obico for Klipper] |"
echo -e "| 7) [KlipperScreen] | 14) [NGINX] |"
back_footer
}
@@ -45,20 +46,26 @@ function remove_menu() {
3)
do_action "remove_mainsail" "remove_ui";;
4)
do_action "remove_fluidd" "remove_ui";;
do_action "remove_mainsail_config" "remove_ui";;
5)
do_action "remove_klipperscreen" "remove_ui";;
do_action "remove_fluidd" "remove_ui";;
6)
do_action "remove_octoprint" "remove_ui";;
do_action "remove_fluidd_config" "remove_ui";;
7)
do_action "remove_mjpg-streamer" "remove_ui";;
do_action "remove_klipperscreen" "remove_ui";;
8)
do_action "remove_prettygcode" "remove_ui";;
do_action "remove_octoprint" "remove_ui";;
9)
do_action "remove_telegram_bot" "remove_ui";;
do_action "remove_crowsnest" "remove_ui";;
10)
do_action "remove_moonraker_obico" "remove_ui";;
do_action "remove_mjpg-streamer" "remove_ui";;
11)
do_action "remove_prettygcode" "remove_ui";;
12)
do_action "remove_telegram_bot" "remove_ui";;
13)
do_action "remove_moonraker_obico" "remove_ui";;
14)
do_action "remove_nginx" "remove_ui";;
B|b)
clear; main_menu; break;;

View File

@@ -32,8 +32,9 @@ function update_ui() {
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 "| 9) [Crowsnest] |$(compare_crowsnest_versions)|"
echo -e "| |------------------------------|"
echo -e "| 9) [System] | $(check_system_updates) |"
echo -e "| 10)[System] | $(check_system_updates) |"
back_footer
}
@@ -63,6 +64,8 @@ function update_menu() {
8)
do_action "update_moonraker_obico" "update_ui";;
9)
do_action "update_crowsnest" "update_ui";;
10)
do_action "update_system" "update_ui";;
a)
do_action "update_all" "update_ui";;

View File

@@ -338,18 +338,6 @@ function fetch_webui_ports() {
#=================== SYSTEM =====================#
#================================================#
function find_klipper_initd() {
local services
services=$(find "${INITD}" -maxdepth 1 -regextype posix-extended -regex "${INITD}/klipper(-[^0])?[0-9]*" | sort)
echo "${services}"
}
function find_klipper_systemd() {
local services
services=$(find "${SYSTEMD}" -maxdepth 1 -regextype posix-extended -regex "${SYSTEMD}/klipper(-[0-9a-zA-Z]+)?.service" | sort)
echo "${services}"
}
function create_required_folders() {
local printer_data=${1} folders
folders=("backup" "certs" "config" "database" "gcodes" "comms" "logs" "systemd")
@@ -599,7 +587,7 @@ function set_multi_instance_names() {
local names=""
local services
services=$(find_klipper_systemd)
services=$(klipper_systemd)
###
# if value of 'multi_instance_names' is not an empty
@@ -686,7 +674,7 @@ function get_config_folders() {
cfg_dirs+=("${HOME}/${name}_data/config")
fi
done
elif [[ -z ${instance_names} && $(find_klipper_systemd | wc -w) -gt 0 ]]; then
elif [[ -z ${instance_names} && $(klipper_systemd | wc -w) -gt 0 ]]; then
cfg_dirs+=("${HOME}/printer_data/config")
else
cfg_dirs=()
@@ -729,7 +717,7 @@ function get_instance_folder_path() {
fi
fi
done
elif [[ -z ${instance_names} && $(find_klipper_systemd | wc -w) -gt 0 ]]; then
elif [[ -z ${instance_names} && $(klipper_systemd | wc -w) -gt 0 ]]; then
path="${HOME}/printer_data/${folder_name}"
if [[ -d ${path} ]]; then
folder_paths+=("${path}")