59 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
Quinn Damerell
ae9e79c579 feat(octoeverywhere): add OE to the "update all" action (#311) 2023-03-11 23:52:46 +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
1215446a6c feat(octoeverywhere): implement update function (#310) 2023-03-11 20:25:17 +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
th33xitus
8526acf8b6 chore: update copyright notice
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-03-10 20:06:06 +01:00
th33xitus
cc27aaec7c readme: add prerequisites to readme (#309) 2023-03-08 20:07:00 +01:00
Quinn Damerell
1e9493461c feat: add OctoEverywhere for Klipper (#300)
Co-authored-by: th33xitus <th33xitus@googlemail.com>
2023-03-05 17:19:20 +01:00
th33xitus
31616ebad5 fix(crowsnest): silence grep error output in main menu
fixes #308

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-03-04 16:01:06 +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
Stephan Wendel
faf56ed1b1 refactor(crowsnest): improve performance in crowsnest.sh (#306) 2023-02-28 18:37:43 +01:00
th33xitus
d6837af2a2 refactor(klipper): implement blacklisted service names (#304) 2023-02-28 18:29:21 +01:00
Pedro Lamas
afe6f7499a feat(fluidd): use fluidd-config repo for downloading fluidd macros (#305) 2023-02-28 16:33:32 +01:00
Pedro Lamas
e3ed223b5c fix: always use system home directory (#303) 2023-02-28 15:30:42 +01:00
th33xitus
fd27db28d4 feat(mainsail): use mainsail-config repo for downloading mainsail macros (#301) 2023-02-26 16:29:01 +01:00
Michael Bravo
68a02ad3f5 fix(mainsail): set increased read timeout on API endpoint (#294) 2023-02-25 12:59:31 +01:00
CODeRUS
99b7672dc9 fix(telegram bot): Fix service restart (#296) 2023-02-14 19:40:11 +01:00
th33xitus
bb3ec79756 revert(mjpg-streamer): re-add uninstall option for mjpg-streamer
fix #291

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-02-05 08:57:15 +01:00
Kenneth Jiang
ce595abd60 refactor(obico): remove "-s" option from moonraker-obico/install.sh invocation (#292) 2023-02-05 08:50:06 +01:00
th33xitus
c79dc280e3 refactor(moonraker): update cors domains in moonraker.conf template
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-02-05 08:47:46 +01:00
Stephan Wendel
7aa186e8b9 feat: replace mjpg-streamer with crowsnest (#286)
Co-authored-by: th33xitus <th33xitus@googlemail.com>
2023-02-03 21:59:59 +01:00
coderus
7c1c1d8f21 fix(moonraker): remove print at start 2023-01-08 16:36:46 +01:00
th33xitus
8493269c6f refactor: hide currently still disabled functions from the menus
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-01-08 11:05:14 +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
th33xitus
150ef0142f refactor(mainsail/fluidd): move tag urls from globals to respective files
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-12-14 19:40:12 +01:00
th33xitus
f70faa52cc fix(klipper): update python dialog description
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-12-08 19:25:58 +01:00
CODeRUS
e796f74640 refactor(klipper): recommend Python3 for Klipper installation (#246) 2022-12-07 18:42:51 +01:00
Thomas Lété
2c9f5bed60 fix: pull mainsail.cfg from correct location (#272) 2022-12-07 17:34:01 +01:00
th33xitus
e9c23ca93e fix(klipper): use correct value for py_ver variable in update function
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-11-14 19:50:55 +01:00
th33xitus
67afa26ed7 refactor(klipper): full refactor of klipper install/remove part (#264) 2022-11-13 15:51:22 +01:00
th33xitus
54be7e4e21 refactor(obico): update obico installer (#254) 2022-10-31 16:06:45 +01:00
th33xitus
811c071b74 refactor(telegram-bot): update telegram-bot installer (#251) 2022-10-30 18:30:20 +01:00
th33xitus
6116fc92cf fix: allow for any amount of whitespaces after config section in update manager
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-10-30 18:27:13 +01:00
th33xitus
5524a40f04 refactor(klipperscreen): re-enable klipperscreen installer
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-10-25 15:24:25 +02:00
th33xitus
cb3661b8b5 refactor(prettygcode): re-enable pretty gcode installer
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-10-25 15:23:57 +02:00
th33xitus
2cec90b29c refactor(octoprint): update octoprint installer
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-10-24 10:35:30 +02:00
th33xitus
d2c009df9a fix(klipper): network.target is now network-online.target
Signed-off-by: Dominik Willner th33xitus@gmail.com
2022-10-22 23:28:01 +02:00
41 changed files with 1937 additions and 896 deletions

119
README.md
View File

@@ -15,37 +15,91 @@
<a><img src="https://img.shields.io/github/forks/th33xitus/kiauh"></a>
<a><img src="https://img.shields.io/github/languages/top/th33xitus/kiauh?logo=gnubash&logoColor=white"></a>
<a><img src="https://img.shields.io/github/v/tag/th33xitus/kiauh"></a>
<br />
<br />
<a><img src="https://img.shields.io/github/last-commit/th33xitus/kiauh"></a>
<a><img src="https://img.shields.io/github/contributors/th33xitus/kiauh"></a>
</p>
## **🛠️ Instructions:**
<hr>
For downloading this script it is necessary to have git installed.\
If you haven't, please run `sudo apt-get install git -y` to install git first.\
After git is installed, use the following commands in the given order to download and execute the script:
<h2 align="center">
📄️ Instructions 📄
</h2>
```shell
cd ~
### 📋 Prerequisites
KIAUH is a script that assists you in installing Klipper on a Linux operating system that has
already been flashed to your Raspberry Pi's (or other SBC's) SD card. As a result, you must ensure
that you have a functional Linux system on hand. `Raspberry Pi OS Lite (32bit)` is a recommended Linux image
if you are using a Raspberry Pi. The [official Raspberry Pi Imager](https://www.raspberrypi.com/software/)
is the simplest way to flash an image like this to an SD card.
git clone https://github.com/th33xitus/kiauh.git
* Once you downloaded, installed and launched the Raspberry Pi Imager
select `Choose OS -> Raspberry Pi OS (other)`: \
<p align="center">
<img src="https://raw.githubusercontent.com/th33xitus/kiauh/master/resources/screenshots/rpi_imager1.png" alt="KIAUH logo" height="350">
</p>
./kiauh/kiauh.sh
```
* Then select `Raspberry Pi OS Lite (32bit)`:
<p align="center">
<img src="https://raw.githubusercontent.com/th33xitus/kiauh/master/resources/screenshots/rpi_imager2.png" alt="KIAUH logo" height="350">
</p>
* Back in the Raspberry Pi Imager's main menu, select the corresponding SD card to which
you want to flash the image.
* Make sure to go into the Advaced Option (the cog icon in the lower left corner of the main menu)
and enable SSH and configure Wi-Fi.
* If you need more help for using the Raspberry Pi Imager, please visit the [official documentation](https://www.raspberrypi.com/documentation/computers/getting-started.html).
These steps **only** apply if you are actually using a Raspberry Pi. In case you want
to use a different SBC (like an Orange Pi or any other Pi derivates), please look up on how to get an appropriate Linux image flashed
to the SD card before proceeding further (usually done with Balena Etcher in those cases). Also make sure that KIAUH will be able to run
and operate on the Linux Distribution you are going to flash. You likely will have the most success with
distributions based on Debian 11 Bullseye. Read the notes further down below in this document.
### 💾 Download and use KIAUH
**📢 Disclaimer: Usage of this script happens at your own risk!**
* **Step 1:** \
To download this script, it is necessary to have git installed. If you don't have git already installed, or if you are unsure, run the following command:
```shell
sudo apt-get install git -y
```
## **❗ Notes:**
* **Step 2:** \
Once git is installed, use the following command to download KIAUH into your home-directoy:
**📋 Please see the [Changelog](docs/changelog.md) for possible important changes!**
```shell
cd ~ && git clone https://github.com/th33xitus/kiauh.git
```
- Tested **only** on Raspberry Pi OS Lite (Debian 10 Buster)
- Other Debian based distributions can work
- Reported to work on Armbian too
- During the use of this script you might be asked for your sudo password. There are several functions involved which need sudo privileges.
* **Step 3:** \
Finally start KIAUH by running the next command:
## **🌐 Sources & Further Information**
```shell
./kiauh/kiauh.sh
```
* **Step 4:** \
You should now find yourself in the main menu of KIAUH. You will see several actions to choose from depending
on what you want to do. To choose an action, simply type the corresponding number into the "Perform action"
prompt and confirm by hitting ENTER.
<hr>
<h2 align="center">❗ Notes ❗</h2>
### **📋 Please see the [Changelog](docs/changelog.md) for possible important changes!**
- Mainly tested on Raspberry Pi OS Lite (Debian 10 Buster / Debian 11 Bullseye)
- Other Debian based distributions (like Ubuntu 20 to 22) likely work too
- Reported to work on Armbian as well but not tested in detail
- During the use of this script you will be asked for your sudo password. There are several functions involved which need sudo privileges.
<hr>
<h2 align="center">🌐 Sources & Further Information</h2>
<table>
<tr>
@@ -78,26 +132,49 @@ git clone https://github.com/th33xitus/kiauh.git
<th>by <a href="https://github.com/jordanruthe">jordanruthe</a></th>
<th>by <a href="https://github.com/OctoPrint">OctoPrint</a></th>
</tr>
<tr>
<th><h3><a href="https://github.com/nlef/moonraker-telegram-bot">Moonraker-Telegram-Bot</a></h3></th>
<th><h3><a href="https://github.com/Kragrathea/pgcode">PrettyGCode for Klipper</a></h3></th>
<th><h3><a href="https://github.com/TheSpaghettiDetective/moonraker-obico">Obico for Klipper</a></h3></th>
<tr>
</tr>
<tr>
<th><img src="https://avatars.githubusercontent.com/u/52351624?v=4" alt="nlef avatar" height="64"></th>
<th><img src="https://avatars.githubusercontent.com/u/5917231?v=4" alt="Kragrathea avatar" height="64"></th>
<th><img src="https://avatars.githubusercontent.com/u/46323662?s=200&v=4" alt="Obico logo" height="64"></th>
</tr>
<tr>
<th>by <a href="https://github.com/nlef">nlef</a></th>
<th>by <a href="https://github.com/Kragrathea">Kragrathea</a></th>
<th>by <a href="https://github.com/TheSpaghettiDetective">Obico</a></th>
</tr>
<tr>
<th><h3></h3></th>
<th><h3><a href="https://octoeverywhere.com/?source=kiauh_readme">OctoEverywhere For Klipper</a></h3></th>
<th><h3></h3></th>
</tr>
<tr>
<th></th>
<th><a href="https://octoeverywhere.com/?source=kiauh_readme"><img src="https://octoeverywhere.com/img/logo.svg" alt="OctoEverywhere Logo" height="64"></a></th>
<th></th>
</tr>
<tr>
<th></th>
<th>by <a href="https://github.com/QuinnDamerell">Quinn Damerell</a></th>
<th></th>
</tr>
</table>
## **Credits**
<hr>
<h2 align="center">✨ Credits ✨</h2>
* A big thank you to [lixxbox](https://github.com/lixxbox) for that awesome KIAUH-Logo!
* Also a big thank you to everyone who supported my work with a [Ko-fi](https://ko-fi.com/th33xitus) !
* Also, a big thank you to everyone who supported my work with a [Ko-fi](https://ko-fi.com/th33xitus) !
* Last but not least: Thank you to all contributors and members of the Klipper Community who like and share this project!

View File

@@ -2,6 +2,19 @@
This document covers possible important changes to KIAUH.
### 2023-02-03
The installer for MJPG-Streamer got replaced by crowsnest. It is an improved webcam service, utilizing ustreamer.
Please have a look here for additional info about crowsnest and how to configure it: https://github.com/mainsail-crew/crowsnest \
It's unsure if the previous MJPG-Streamer installer will be updated and make its way back into KIAUH.
A big thanks to [KwadFan](https://github.com/KwadFan) for writing the crowsnest implementation.
### 2022-10-31
Some functions got updated, though not all of them.
The following functions are still currently unavailable:
- Installation of: MJPG-Streamer
- All backup functions and the Log-Upload
### 2022-10-20
KIAUH has now reached major version 5 !

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -9,13 +9,8 @@
# This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================#
# TODO: mjpg-streamer
# TODO: moonraker-telegram-bot
# TODO: obico
# TODO: pretty_gcode
# TODO: upload_log
# TODO: all backup functions
# TODO: octoprint
# TODO: doublecheck that nothing got missed!
set -e

View File

@@ -55,6 +55,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
proxy_read_timeout 600;
}
location /webcam/ {

View File

@@ -1,7 +1,7 @@
[Unit]
Description=Klipper 3D Printer Firmware SV1 %INST%
Description=Klipper 3D Printer Firmware SV1
Documentation=https://www.klipper3d.org/
After=network.target
After=network-online.target
Wants=udev.target
[Install]
@@ -10,9 +10,8 @@ WantedBy=multi-user.target
[Service]
Type=simple
User=%USER%
RemainAfterExit=yes
WorkingDirectory=/home/%USER%/klipper
EnvironmentFile=%ENV_FILE%
ExecStart=%ENV%/bin/python $KLIPPER_ARGS
Restart=always
RestartSec=10
RestartSec=10

View File

@@ -55,6 +55,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
proxy_read_timeout 600;
}
location /webcam/ {

View File

@@ -0,0 +1 @@
TELEGRAM_BOT_ARGS="/home/%USER%/moonraker-telegram-bot/bot/main.py -c %CFG% -l %LOG%"

View File

@@ -1,19 +1,16 @@
#Systemd service file for Moonraker Telegram Bot
[Unit]
Description=Starts Moonraker Telegram Bot instance %INST% on startup
Description=Moonraker Telegram Bot SV1 %INST%
Documentation=https://github.com/nlef/moonraker-telegram-bot/wiki
After=network.target
After=network-online.target
[Install]
WantedBy=multi-user.target
[Service]
Environment=TELEGRAM_CONF=%CFG%
Environment=TELEGRAM_LOG=%LOG%
Type=simple
User=%USER%
RemainAfterExit=yes
ExecStart=%ENV%/bin/python %DIR%/bot/main.py -c ${TELEGRAM_CONF} -l ${TELEGRAM_LOG}
WorkingDirectory=/home/%USER%/moonraker-telegram-bot
EnvironmentFile=%ENV_FILE%
ExecStart=%ENV%/bin/python $TELEGRAM_BOT_ARGS
Restart=always
RestartSec=10
RestartSec=10

View File

@@ -14,12 +14,12 @@ trusted_clients:
FE80::/10
::1/128
cors_domains:
http://*.lan
http://*.local
https://my.mainsail.xyz
http://my.mainsail.xyz
https://app.fluidd.xyz
http://app.fluidd.xyz
*.lan
*.local
*://localhost
*://localhost:*
*://my.mainsail.xyz
*://app.fluidd.xyz
[octoprint_compat]

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #

241
scripts/crowsnest.sh Normal file
View File

@@ -0,0 +1,241 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2023 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 2>/dev/null | 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

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -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
@@ -332,8 +341,10 @@ function compare_fluidd_versions() {
#================================================#
function get_fluidd_download_url() {
local tags latest_tag latest_url stable_tag stable_url url
tags=$(curl -s "${FLUIDD_TAGS}" | grep "name" | cut -d'"' -f4)
local fl_tags tags latest_tag latest_url stable_tag stable_url url
fl_tags="https://api.github.com/repos/fluidd-core/fluidd/tags"
tags=$(curl -s "${fl_tags}" | grep "name" | cut -d'"' -f4)
### latest download url including pre-releases (alpha, beta, rc)
latest_tag=$(echo "${tags}" | head -1)
@@ -387,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 |"
@@ -414,12 +425,12 @@ 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"
for conf in ${moonraker_configs}; do
if ! grep -Eq "^\[update_manager fluidd\]$" "${conf}"; then
if ! grep -Eq "^\[update_manager fluidd\]\s*$" "${conf}"; then
### add new line to conf if it doesn't end with one
[[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"
@@ -443,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

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -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

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -42,13 +42,9 @@ function set_globals() {
#================= MAINSAIL ===================#
MAINSAIL_DIR="${HOME}/mainsail"
MAINSAIL_REPO_API="https://api.github.com/repos/mainsail-crew/mainsail/releases"
MAINSAIL_TAGS="https://api.github.com/repos/mainsail-crew/mainsail/tags"
#================== FLUIDD ====================#
FLUIDD_DIR="${HOME}/fluidd"
FLUIDD_REPO_API="https://api.github.com/repos/fluidd-core/fluidd/releases"
FLUIDD_TAGS="https://api.github.com/repos/fluidd-core/fluidd/tags"
#=============== KLIPPERSCREEN ================#
KLIPPERSCREEN_ENV="${HOME}/.KlipperScreen-env"
@@ -72,4 +68,14 @@ function set_globals() {
#=============== MOONRAKER-OBICO ================#
MOONRAKER_OBICO_DIR="${HOME}/moonraker-obico"
MOONRAKER_OBICO_REPO="https://github.com/TheSpaghettiDetective/moonraker-obico.git"
#=============== OCTOEVERYWHERE ================#
OCTOEVERYWHERE_ENV="${HOME}/octoeverywhere-env"
OCTOEVERYWHERE_DIR="${HOME}/octoeverywhere"
OCTOEVERYWHERE_REPO="https://github.com/QuinnDamerell/OctoPrint-OctoEverywhere.git"
#=============== Crowsnest ================#
CROWSNEST_DIR="${HOME}/crowsnest"
CROWSNEST_REPO="https://github.com/mainsail-crew/crowsnest.git"
}

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -11,40 +11,98 @@
set -e
#TODO (multi instance):
# if the klipper installer is started another time while other klipper
# instances are detected, ask if new instances should be added
#=================================================#
#================ INSTALL KLIPPER ================#
#=================================================#
function klipper_setup_dialog() {
status_msg "Initializing Klipper installation ..."
###
# this function detects all installed klipper
# systemd instances and returns their absolute path
function klipper_systemd() {
local services
local blacklist
local ignore
local match
local klipper_initd_service
local klipper_systemd_services
local python_version="${1}" user_input=()
local error
###
# 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"
klipper_initd_service=$(find_klipper_initd)
klipper_systemd_services=$(find_klipper_systemd)
user_input+=("${python_version}")
ignore="${SYSTEMD}/klipper-(${blacklist}).service"
match="${SYSTEMD}/klipper(-[0-9a-zA-Z]+)?.service"
### return early if klipper already exists
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}"
elif [[ -n ${klipper_systemd_services} ]]; then
error="At least one Klipper service is already installed:"
services=$(find "${SYSTEMD}" -maxdepth 1 -regextype awk ! -regex "${ignore}" -regex "${match}" | sort)
echo "${services}"
}
for s in ${klipper_systemd_services}; do
log_info "Found Klipper service: ${s}"
error="${error}\n ➔ ${s}"
function start_klipper_setup() {
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 input
local regex
local blacklist
status_msg "Initializing Klipper installation ...\n"
klipper_instances=$(klipper_systemd)
[[ -n ${klipper_instances} ]] && is_multi_instance_setup="true"
if [[ ${is_multi_instance_setup} == "true" ]]; then
klipper_count=$(echo "${klipper_instances}" | wc -w)
python_version=$(get_klipper_python_ver)
adding_instances="true"
# 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
### ask for amount of instances to create
top_border
echo -e "| Please select the number of Klipper instances to set |"
echo -e "| up. The number of Klipper instances will determine |"
@@ -52,113 +110,139 @@ function klipper_setup_dialog() {
blank_line
echo -e "| ${yellow}WARNING:${white} |"
echo -e "| ${yellow}Setting up too many instances may crash your system.${white} |"
bottom_border
back_footer
### ask for amount of instances
local klipper_count re="^[1-9][0-9]*$"
while [[ ! ${klipper_count} =~ ${re} ]]; do
read -p "${cyan}###### Number of Klipper instances to set up:${white} " -i "1" -e klipper_count
### break if input is valid
[[ ${klipper_count} =~ ${re} ]] && break
### error messages on invalid input
error_msg "Input not a number"
done && select_msg "${klipper_count}"
regex="^[1-9][0-9]*$"
while [[ ! ${input} =~ ${regex} ]]; do
local x=""
[[ ${adding_instances} == "true" ]] && x="additional"
read -p "${cyan}###### Number of ${x} Klipper instances to set up:${white} " -i "1" -e input
user_input+=("${klipper_count}")
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
install_menu
else
error_msg "Invalid Input!\n"
fi
done && input=""
### confirm instance amount
local yn
while true; do
read -p "${cyan}###### Install ${klipper_count} instance(s)? (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 Klipper setup ...\n"
return;;
*)
error_msg "Invalid Input!";;
esac
done
### ask for custom names
if (( klipper_count > 1 )); then
local custom_names="false"
if [[ ${is_multi_instance_setup} == "true" ]]; then
top_border
echo -e "| You can give each instance a custom name or skip. |"
echo -e "| If skipped, KIAUH will automatically assign an index |"
echo -e "| to each instance in ascending order, starting at '1'. |"
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 "| Info: |"
echo -e "| Only alphanumeric characters will be allowed. |"
bottom_border
echo -e "| ${yellow}Info:${white} |"
echo -e "| ${yellow}Only alphanumeric characters are allowed!${white} |"
back_footer
while true; do
read -p "${cyan}###### Use custom names? (y/N):${white} " yn
case "${yn}" in
read -p "${cyan}###### Assign custom names? (y/N):${white} " input
case "${input}" in
Y|y|Yes|yes)
select_msg "Yes"
custom_names="true"
select_msg "Yes\n"
use_custom_names="true"
break;;
N|n|No|no|"")
select_msg "No"
select_msg "No\n"
break;;
B|b)
clear; install_menu; break;;
*)
error_msg "Invalid Input!";;
error_msg "Invalid Input!\n";;
esac
done
### get user input for custom names
if [[ ${custom_names} == "true" ]]; then
local i=1 name re="^[0-9a-zA-Z]+$"
while [[ ! ${name} =~ ${re} || ${i} -le ${klipper_count} ]]; do
read -p "${cyan}###### Name for instance #${i}:${white} " name
if [[ ${name} =~ ${re} ]]; then
select_msg "Name: ${name}"
user_input+=("${name}")
i=$(( i + 1 ))
else
error_msg "Invalid Input!"
fi
done
else
### if no custom names are used, add the respective amount of indices to the user_input array
for (( i=1; i <= klipper_count; i++ )); do
user_input+=("${i}")
done
fi
done && input=""
else
instance_names+=("printer")
fi
### user selection for setting the actual custom names
shopt -s nocasematch
if [[ ${use_custom_names} == "true" ]]; then
regex="^[0-9a-zA-Z]+$"
blacklist="mcu"
(( klipper_count > 1 )) && status_msg "Installing ${klipper_count} Klipper instances ..."
(( klipper_count == 1 )) && status_msg "Installing single Klipper instance ..."
local i=1
while [[ ! ${input} =~ ${regex} || ${input} =~ ${blacklist} || ${i} -le ${instance_count} ]]; do
read -p "${cyan}###### Name for instance #$((klipper_count + i)):${white} " input
klipper_setup "${user_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_name="printer_${input}"
else
instance_name="${input}"
fi
instance_names+=("${instance_name}")
i=$(( i + 1 ))
else
error_msg "Invalid Input!\n"
fi
done && input=""
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
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}" "${adding_instances}" "${instance_names[@]}"
}
function klipper_setup() {
function run_klipper_setup() {
read_kiauh_ini "${FUNCNAME[0]}"
### index 0: python version, index 1: instance count, index 2-n: instance names (optional)
local user_input=("${@}")
local python_version="${user_input[0]}" && unset "user_input[0]"
local instance_arr=("${user_input[@]}") && unset "user_input[@]"
local custom_repo="${custom_klipper_repo}"
local custom_branch="${custom_klipper_repo_branch}"
local dep=(git)
local python_version=${1}
local adding_instances=${2}
local instance_names
local confirm
local custom_repo
local custom_branch
local dep
shift 2 && read -r -a instance_names <<< "${@}"
custom_repo="${custom_klipper_repo}"
custom_branch="${custom_klipper_repo_branch}"
dep=(git)
### 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: configure and create klipper instances
configure_klipper_service "${instance_arr[@]}"
### step 3: create klipper instances
for instance in "${instance_names[@]}"; do
create_klipper_service "${instance}"
done
### step 4: enable and start all instances
do_action_service "enable" "klipper"
@@ -168,9 +252,11 @@ function klipper_setup() {
check_usergroups
### confirm message
local confirm=""
(( instance_arr[0] == 1 )) && confirm="Klipper has been set up!"
(( instance_arr[0] > 1 )) && confirm="${instance_arr[0]} Klipper instances have been set up!"
(( ${#instance_names[@]} == 1 )) && confirm="Klipper has been set up!"
(( ${#instance_names[@]} > 1 )) && confirm="${#instance_names[@]} Klipper instances have been set up!"
### finalizing the setup with writing instance names to the kiauh.ini
set_multi_instance_names
print_confirm "${confirm}" && return
}
@@ -201,37 +287,18 @@ function clone_klipper() {
function create_klipper_virtualenv() {
local python_version="${1}"
[[ ${python_version} == "python2" ]] && \
status_msg "Installing $(python2 -V) virtual environment..."
[[ ${python_version} == "python3" ]] && \
status_msg "Installing $(python3 -V) virtual environment..."
### remove klippy-env if it already exists
[[ -d ${KLIPPY_ENV} ]] && rm -rf "${KLIPPY_ENV}"
if [[ ${python_version} == "python2" ]]; then
if virtualenv -p python2 "${KLIPPY_ENV}"; then
"${KLIPPY_ENV}"/bin/pip install -r "${KLIPPER_DIR}"/scripts/klippy-requirements.txt
else
log_error "failure while creating python2 klippy-env"
error_msg "Creation of Klipper virtualenv failed!"
exit 1
fi
fi
status_msg "Installing $("python${python_version}" -V) virtual environment..."
if [[ ${python_version} == "python3" ]]; then
if virtualenv -p python3 "${KLIPPY_ENV}"; then
"${KLIPPY_ENV}"/bin/pip install -U pip
"${KLIPPY_ENV}"/bin/pip install -r "${KLIPPER_DIR}"/scripts/klippy-requirements.txt
else
log_error "failure while creating python3 klippy-env"
error_msg "Creation of Klipper virtualenv failed!"
exit 1
fi
if virtualenv -p "python${python_version}" "${KLIPPY_ENV}"; then
(( python_version == 3 )) && "${KLIPPY_ENV}"/bin/pip install -U pip
"${KLIPPY_ENV}"/bin/pip install -r "${KLIPPER_DIR}"/scripts/klippy-requirements.txt
else
log_error "failure while creating python3 klippy-env"
error_msg "Creation of Klipper virtualenv failed!"
exit 1
fi
return
}
###
@@ -252,10 +319,10 @@ function install_klipper_packages() {
### add dbus requirement for DietPi distro
[[ -e "/boot/dietpi/.version" ]] && packages+=" dbus"
if [[ ${python_version} == "python3" ]]; then
if (( python_version == 3 )); then
### replace python-dev with python3-dev if python3 was selected
packages="${packages//python-dev/python3-dev}"
elif [[ ${python_version} == "python2" ]]; then
elif (( python_version == 2 )); then
### package name 'python-dev' is deprecated (-> no installation candidate) on more modern linux distros
packages="${packages//python-dev/python2-dev}"
else
@@ -284,95 +351,68 @@ function install_klipper_packages() {
fi
}
function configure_klipper_service() {
local input=("${@}")
local klipper_count=${input[0]} && unset "input[0]"
local names=("${input[@]}") && unset "input[@]"
local printer_data cfg_dir cfg log printer uds service env_file
function create_klipper_service() {
local instance_name=${1}
if (( klipper_count == 1 )) && [[ ${#names[@]} -eq 0 ]]; then
printer_data="${HOME}/printer_data"
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/printer.cfg"
log="${printer_data}/logs/klippy.log"
printer="${printer_data}/comms/klippy.serial"
uds="${printer_data}/comms/klippy.sock"
service="${SYSTEMD}/klipper.service"
env_file="${printer_data}/systemd/klipper.env"
local printer_data
local cfg_dir
local cfg
local log
local klippy_serial
local klippy_socket
local env_file
local service
local service_template
local env_template
local suffix
### create required folder structure
create_required_folders "${printer_data}"
### write single instance service
write_klipper_service "" "${cfg}" "${log}" "${printer}" "${uds}" "${service}" "${env_file}"
write_example_printer_cfg "${cfg_dir}" "${cfg}"
ok_msg "Klipper instance created!"
elif (( klipper_count >= 1 )) && [[ ${#names[@]} -gt 0 ]]; then
local j=0 re="^[1-9][0-9]*$"
for (( i=1; i <= klipper_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}/printer.cfg"
log="${printer_data}/logs/klippy.log"
printer="${printer_data}/comms/klippy.serial"
uds="${printer_data}/comms/klippy.sock"
service="${SYSTEMD}/klipper-${names[${j}]}.service"
env_file="${printer_data}/systemd/klipper.env"
### create required folder structure
create_required_folders "${printer_data}"
### write multi instance service
write_klipper_service "${names[${j}]}" "${cfg}" "${log}" "${printer}" "${uds}" "${service}" "${env_file}"
write_example_printer_cfg "${cfg_dir}" "${cfg}"
ok_msg "Klipper instance 'klipper-${names[${j}]}' created!"
j=$(( j + 1 ))
done && unset j
printer_data="${HOME}/${instance_name}_data"
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/printer.cfg"
log="${printer_data}/logs/klippy.log"
klippy_serial="${printer_data}/comms/klippy.serial"
klippy_socket="${printer_data}/comms/klippy.sock"
env_file="${printer_data}/systemd/klipper.env"
if [[ ${instance_name} == "printer" ]]; then
suffix="${instance_name//printer/}"
else
return 1
suffix="-${instance_name//printer_/}"
fi
}
function write_klipper_service() {
local i=${1} cfg=${2} log=${3} printer=${4} uds=${5} service=${6} env_file=${7}
local service_template="${KIAUH_SRCDIR}/resources/klipper.service"
local env_template="${KIAUH_SRCDIR}/resources/klipper.env"
create_required_folders "${printer_data}"
service_template="${KIAUH_SRCDIR}/resources/klipper.service"
env_template="${KIAUH_SRCDIR}/resources/klipper.env"
service="${SYSTEMD}/klipper${suffix}.service"
### replace all placeholders
if [[ ! -f ${service} ]]; then
status_msg "Creating Klipper Service ${i} ..."
status_msg "Create Klipper service file ..."
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|%USER%|${USER}|g; s|%ENV%|${KLIPPY_ENV}|; s|%ENV_FILE%|${env_file}|" "${service}"
sudo sed -i "s|%USER%|${USER}|; s|%LOG%|${log}|; s|%CFG%|${cfg}|; s|%PRINTER%|${printer}|; s|%UDS%|${uds}|" "${env_file}"
sudo sed -i "s|%USER%|${USER}|; s|%LOG%|${log}|; s|%CFG%|${cfg}|; s|%PRINTER%|${klippy_serial}|; s|%UDS%|${klippy_socket}|" "${env_file}"
ok_msg "Klipper service file created!"
fi
if [[ ! -f ${cfg} ]]; then
write_example_printer_cfg "${cfg}"
fi
}
function write_example_printer_cfg() {
local cfg_dir=${1} cfg=${2}
local cfg_template="${KIAUH_SRCDIR}/resources/example.printer.cfg"
local cfg=${1}
local cfg_template
### create a config directory if it doesn't exist
if [[ ! -d ${cfg_dir} ]]; then
status_msg "Creating '${cfg_dir}' ..."
mkdir -p "${cfg_dir}"
fi
cfg_template="${KIAUH_SRCDIR}/resources/example.printer.cfg"
### create a minimal config if there is no printer.cfg
if [[ ! -f ${cfg} ]]; then
status_msg "Creating minimal example printer.cfg ..."
cp "${cfg_template}" "${cfg}"
status_msg "Creating minimal example printer.cfg ..."
if cp "${cfg_template}" "${cfg}"; then
ok_msg "Minimal example printer.cfg created!"
else
error_msg "Couldn't create minimal example printer.cfg!"
fi
}
@@ -380,110 +420,53 @@ function write_example_printer_cfg() {
#================ REMOVE KLIPPER ================#
#================================================#
function remove_klipper_sysvinit() {
[[ ! -e "${INITD}/klipper" ]] && return
function remove_klipper_service() {
status_msg "Removing Klipper services ..."
status_msg "Removing Klipper SysVinit service ..."
sudo systemctl stop klipper
sudo update-rc.d -f klipper remove
sudo rm -f "${INITD}/klipper" "${ETCDEF}/klipper"
ok_msg "Klipper SysVinit service removed!"
}
function remove_klipper_systemd() {
[[ -z $(find_klipper_systemd) ]] && return
status_msg "Removing Klipper Systemd Services ..."
for service in $(find_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}"
ok_msg "Done!"
done
### reloading units
sudo systemctl daemon-reload
sudo systemctl reset-failed
ok_msg "Klipper Service removed!"
ok_msg "Selected Klipper services removed!"
}
function remove_klipper_env_file() {
local files regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/systemd\/klipper\.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
}
function remove_klipper_logs() {
local files regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/logs\/klippy\.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
}
function remove_legacy_klipper_logs() {
local files regex="klippy(-[0-9a-zA-Z]+)?\.log(.*)?"
files=$(find "${HOME}/klipper_logs" -maxdepth 1 -regextype posix-extended -regex "${HOME}/klipper_logs/${regex}" 2> /dev/null | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_klipper_uds() {
local files regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/comms\/klippy\.sock"
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
}
function remove_klipper_printer() {
local files regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/comms\/klippy\.serial"
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
}
function remove_legacy_klipper_printer() {
function find_instance_files() {
local data_folder=${1}
local target_folder=${2}
local target_name=${3}
local files
files=$(find /tmp -maxdepth 1 -regextype posix-extended -regex "/tmp/printer(-[0-9a-zA-Z]+)?" | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
readarray -t files < <(find "${HOME}" -regex "${data_folder}/${target_folder}/${target_name}" | sort)
echo -e "${files[@]}"
}
function find_legacy_klipper_logs() {
local files
local regex="klippy(-[0-9a-zA-Z]+)?\.log(.*)?"
readarray -t files < <(find "${HOME}/klipper_logs" -maxdepth 1 -regextype posix-extended -regex "${HOME}/klipper_logs/${regex}" 2> /dev/null | sort)
echo -e "${files[@]}"
}
function find_legacy_klipper_uds() {
local files
readarray -t files < <(find /tmp -maxdepth 1 -regextype posix-extended -regex "/tmp/klippy_uds(-[0-9a-zA-Z]+)?" | sort)
echo -e "${files[@]}"
}
function find_legacy_klipper_printer() {
local files
readarray -t files < <(find /tmp -maxdepth 1 -regextype posix-extended -regex "/tmp/printer(-[0-9a-zA-Z]+)?" | sort)
echo -e "${files[@]}"
}
function remove_klipper_dir() {
@@ -502,20 +485,108 @@ function remove_klipper_env() {
ok_msg "Directory removed!"
}
function remove_klipper() {
remove_klipper_sysvinit
remove_klipper_systemd
remove_klipper_env_file
remove_klipper_logs
remove_legacy_klipper_logs
remove_klipper_uds
remove_klipper_printer
remove_legacy_klipper_printer
remove_klipper_dir
remove_klipper_env
###
# takes in a string of space separated absolute
# filepaths and removes those files one after another
#
function remove_files() {
local files
read -r -a files <<< "${@}"
local confirm="Klipper was successfully removed!"
print_confirm "${confirm}" && return
if (( ${#files[@]} > 0 )); then
for file in "${files[@]}"; do
status_msg "Removing ${file} ..."
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() {
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)"
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
}
#================================================#
@@ -533,7 +604,7 @@ function update_klipper() {
local custom_repo="${custom_klipper_repo}"
local custom_branch="${custom_klipper_repo_branch}"
py_ver="python$(get_klipper_python_ver)"
py_ver=$(get_klipper_python_ver)
do_action_service "stop" "klipper"
@@ -560,13 +631,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)
@@ -646,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

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -207,7 +207,7 @@ function patch_klipperscreen_update_manager() {
moonraker_configs=$(find "${KLIPPER_CONFIG}" -type f -name "moonraker.conf" | sort)
for conf in ${moonraker_configs}; do
if ! grep -Eq "^\[update_manager KlipperScreen\]$" "${conf}"; then
if ! grep -Eq "^\[update_manager KlipperScreen\]\s*$" "${conf}"; then
### add new line to conf if it doesn't end with one
[[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -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/MainsailOS/master/src/modules/mainsail/filesystem/home/pi/klipper_config/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)
@@ -502,8 +511,10 @@ function ms_theme_delete() {
#================================================#
function get_mainsail_download_url() {
local tags latest_tag latest_url stable_tag stable_url url
tags=$(curl -s "${MAINSAIL_TAGS}" | grep "name" | cut -d'"' -f4)
local ms_tags tags latest_tag latest_url stable_tag stable_url url
ms_tags="https://api.github.com/repos/mainsail-crew/mainsail/tags"
tags=$(curl -s "${ms_tags}" | grep "name" | cut -d'"' -f4)
### latest download url including pre-releases (alpha, beta, rc)
latest_tag=$(echo "${tags}" | head -1)
@@ -592,12 +603,12 @@ 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"
for conf in ${moonraker_configs}; do
if ! grep -Eq "^\[update_manager mainsail\]$" "${conf}"; then
if ! grep -Eq "^\[update_manager mainsail\]\s*$" "${conf}"; then
### add new line to conf if it doesn't end with one
[[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"
@@ -621,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

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -203,29 +203,40 @@ function create_telegram_conf() {
local input=("${@}")
local telegram_bot_count=${input[0]} && unset "input[0]"
local names=("${input[@]}") && unset "input[@]"
local log="${KLIPPER_LOGS}"
local cfg cfg_dir
local printer_data log_dir cfg cfg_dir
if (( telegram_bot_count == 1 )); then
cfg_dir="${KLIPPER_CONFIG}"
printer_data="${HOME}/printer_data"
log_dir="${printer_data}/logs"
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/telegram.conf"
### create required folder structure
create_required_folders "${printer_data}"
### write single instance config
write_telegram_conf "${cfg_dir}" "${cfg}" "${log}"
write_telegram_conf "${cfg_dir}" "${cfg}"
elif (( telegram_bot_count > 1 )); then
local j=0 re="^[1-9][0-9]*$"
for (( i=1; i <= telegram_bot_count; i++ )); do
### overwrite config folder if name is only a number
if [[ ${names[j]} =~ ${re} ]]; then
cfg_dir="${KLIPPER_CONFIG}/printer_${names[${j}]}"
else
cfg_dir="${KLIPPER_CONFIG}/${names[${j}]}"
fi
printer_data="${HOME}/${names[${j}]}_data"
### prefix instance name with "printer_" if it is only a number
[[ ${names[j]} =~ ${re} ]] && printer_data="${HOME}/printer_${names[${j}]}_data"
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/telegram.conf"
log_dir="${printer_data}/logs"
### create required folder structure
create_required_folders "${printer_data}"
### write multi instance config
write_telegram_conf "${cfg_dir}" "${cfg}" "${log}"
write_telegram_conf "${cfg_dir}" "${cfg}"
j=$(( j + 1 ))
done && unset j
@@ -235,17 +246,15 @@ function create_telegram_conf() {
}
function write_telegram_conf() {
local cfg_dir=${1} cfg=${2} log=${3}
local cfg_dir=${1} cfg=${2}
local conf_template="${TELEGRAM_BOT_DIR}/scripts/base_install_template"
[[ ! -d ${cfg_dir} ]] && mkdir -p "${cfg_dir}"
if [[ ! -f ${cfg} ]]; then
status_msg "Creating telegram.conf in ${cfg_dir} ..."
cp "${conf_template}" "${cfg}"
sed -i "s|some_log_path|${log}|g" "${cfg}"
ok_msg "telegram.conf created!"
else
status_msg "File '${cfg}' already exists!\nSkipping..."
ok_msg "File '${cfg}' already exists! Skipping..."
fi
}
@@ -253,16 +262,22 @@ function create_telegram_bot_service() {
local input=("${@}")
local instances=${input[0]} && unset "input[0]"
local names=("${input[@]}") && unset "input[@]"
local cfg_dir cfg log service
local printer_data cfg_dir cfg log service env_file
if (( instances == 1 )); then
cfg_dir="${KLIPPER_CONFIG}"
printer_data="${HOME}/printer_data"
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/telegram.conf"
log="${KLIPPER_LOGS}/telegram.log"
log="${printer_data}/logs/telegram.log"
service="${SYSTEMD}/moonraker-telegram-bot.service"
env_file="${printer_data}/systemd/moonraker-telegram-bot.env"
### create required folder structure
create_required_folders "${printer_data}"
### write single instance service
write_telegram_bot_service "" "${cfg}" "${log}" "${service}"
ok_msg "Single Telegram Bot instance created!"
write_telegram_bot_service "" "${cfg}" "${log}" "${service}" "${env_file}"
ok_msg "Telegram Bot instance created!"
elif (( instances > 1 )); then
local j=0 re="^[1-9][0-9]*$"
@@ -270,17 +285,27 @@ function create_telegram_bot_service() {
for (( i=1; i <= instances; i++ )); do
### overwrite config folder if name is only a number
if [[ ${names[j]} =~ ${re} ]]; then
cfg_dir="${KLIPPER_CONFIG}/printer_${names[${j}]}"
printer_data="${HOME}/printer_${names[${j}]}_data"
else
cfg_dir="${KLIPPER_CONFIG}/${names[${j}]}"
printer_data="${HOME}/${names[${j}]}_data"
fi
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/telegram.conf"
log="${KLIPPER_LOGS}/telegram-${names[${j}]}.log"
log="${printer_data}/logs/telegram.log"
service="${SYSTEMD}/moonraker-telegram-bot-${names[${j}]}.service"
env_file="${printer_data}/systemd/moonraker-telegram-bot.env"
### create required folder structure
create_required_folders "${printer_data}"
### write multi instance service
write_telegram_bot_service "${names[${j}]}" "${cfg}" "${log}" "${service}"
ok_msg "Telegram Bot instance moonraker-telegram-bot-${names[${j}]} created!"
if write_telegram_bot_service "${names[${j}]}" "${cfg}" "${log}" "${service}" "${env_file}"; then
ok_msg "Telegram Bot instance moonraker-telegram-bot-${names[${j}]} created!"
else
error_msg "An error occured during creation of instance moonraker-telegram-bot-${names[${j}]}!"
fi
j=$(( j + 1 ))
done && unset j
@@ -290,17 +315,24 @@ function create_telegram_bot_service() {
}
function write_telegram_bot_service() {
local i=${1} cfg=${2} log=${3} service=${4}
local i=${1} cfg=${2} log=${3} service=${4} env_file=${5}
local service_template="${KIAUH_SRCDIR}/resources/moonraker-telegram-bot.service"
local env_template="${KIAUH_SRCDIR}/resources/moonraker-telegram-bot.env"
### replace all placeholders
if [[ ! -f ${service} ]]; then
status_msg "Creating Telegram Bot Service ${i} ..."
status_msg "Creating service file for instance ${i} ..."
sudo cp "${service_template}" "${service}"
[[ -z ${i} ]] && sudo sed -i "s|instance %INST% ||" "${service}"
[[ -n ${i} ]] && sudo sed -i "s|%INST%|${i}|" "${service}"
sudo sed -i "s|%USER%|${USER}|; s|%ENV%|${TELEGRAM_BOT_ENV}|; s|%DIR%|${TELEGRAM_BOT_DIR}|" "${service}"
sudo sed -i "s|%CFG%|${cfg}|; s|%LOG%|${log}|" "${service}"
if [[ -z ${i} ]]; then
sudo sed -i "s| %INST%||" "${service}"
else
sudo sed -i "s|%INST%|${i}|" "${service}"
fi
sudo sed -i "s|%USER%|${USER}|g; s|%ENV%|${TELEGRAM_BOT_ENV}|; s|%ENV_FILE%|${env_file}|" "${service}"
status_msg "Creating environment file for instance ${i} ..."
cp "${env_template}" "${env_file}"
sed -i "s|%USER%|${USER}|; s|%CFG%|${cfg}|; s|%LOG%|${log}|" "${env_file}"
fi
}
@@ -343,9 +375,35 @@ function remove_telegram_bot_env() {
ok_msg "Directory removed!"
}
function remove_telegram_bot_env_file() {
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
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_telegram_bot_logs() {
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
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_legacy_telegram_bot_logs() {
local files regex="telegram(-[0-9a-zA-Z]+)?\.log(.*)?"
files=$(find "${KLIPPER_LOGS}" -maxdepth 1 -regextype posix-extended -regex "${KLIPPER_LOGS}/${regex}" | sort)
files=$(find "${HOME}/klipper_logs" -maxdepth 1 -regextype posix-extended -regex "${HOME}/klipper_logs/${regex}" 2> /dev/null | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
@@ -360,7 +418,9 @@ function remove_telegram_bot() {
remove_telegram_bot_systemd
remove_telegram_bot_dir
remove_telegram_bot_env
remove_telegram_bot_env_file
remove_telegram_bot_logs
remove_legacy_telegram_bot_logs
local confirm="Moonraker-Telegram-Bot was successfully removed!"
print_confirm "${confirm}" && return
@@ -458,12 +518,13 @@ function compare_telegram_bot_versions() {
#================================================#
function patch_telegram_bot_update_manager() {
local patched="false"
local moonraker_configs
moonraker_configs=$(find "${KLIPPER_CONFIG}" -type f -name "moonraker.conf" | sort)
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 moonraker-telegram-bot\]$" "${conf}"; then
if ! grep -Eq "^\[update_manager moonraker-telegram-bot\]\s*$" "${conf}"; then
### add new line to conf if it doesn't end with one
[[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -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=$(find_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\/${USER}\/([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\/${USER}\/([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

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -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

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -24,7 +24,7 @@ function moonraker_obico_systemd() {
function moonraker_obico_config() {
local moonraker_cfg_dirs
read -r -a moonraker_cfg_dirs <<< "$(get_config_folders)"
read -r -a moonraker_cfg_dirs <<< "$(get_instance_folder_path "config")"
if (( ${#moonraker_cfg_dirs[@]} > 0 )); then
echo "${moonraker_cfg_dirs[${1}]}/moonraker-obico.cfg"
@@ -65,7 +65,6 @@ function obico_server_url_prompt() {
function moonraker_obico_setup_dialog() {
status_msg "Initializing Moonraker-obico installation ..."
local moonraker_count
local moonraker_names
@@ -103,7 +102,6 @@ function moonraker_obico_setup_dialog() {
if (( existing_moonraker_obico_count > 0 )); then
printf "|${green}%-55s${white}|\n" " ${existing_moonraker_obico_count} Moonraker-obico instances already installed!"
for svc in ${moonraker_obico_services}; do
# printf "|${cyan}%-57s${white}|\n" " ● moonraker-obco-$(get_instance_name "${svc}" moonraker-obico)"
printf "|${cyan}%-57s${white}|\n" " ● moonraker-obco-$(get_instance_name "${svc}")"
done
fi
@@ -179,17 +177,29 @@ function moonraker_obico_setup_dialog() {
### step 6: call moonrake-obico/install.sh with the correct params
local port=7125
local moonraker_cfg_dirs
local instance_cfg_dirs
local instance_log_dirs
read -r -a moonraker_cfg_dirs <<< "$(get_config_folders)"
read -r -a instance_cfg_dirs <<< "$(get_instance_folder_path "config")"
read -r -a instance_log_dirs <<< "$(get_instance_folder_path "logs")"
if (( moonraker_count == 1 )); then
"${MOONRAKER_OBICO_DIR}/install.sh" -C "${moonraker_cfg_dirs[0]}/moonraker.conf" -p "${port}" -H 127.0.0.1 -l "${KLIPPER_LOGS}" -s -L -S "${obico_server_url}"
"${MOONRAKER_OBICO_DIR}/install.sh"\
-C "${instance_cfg_dirs[0]}/moonraker.conf"\
-p "${port}" -H 127.0.0.1 -l\
"${instance_log_dirs[0]}"\
-L -S "${obico_server_url}"
elif (( moonraker_count > 1 )); then
local j=${existing_moonraker_obico_count}
for (( i=1; i <= new_moonraker_obico_count; i++ )); do
"${MOONRAKER_OBICO_DIR}/install.sh" -n "${moonraker_names[${j}]}" -C "${moonraker_cfg_dirs[${j}]}/moonraker.conf" -p $((port+j)) -H 127.0.0.1 -l "${KLIPPER_LOGS}" -s -L -S "${obico_server_url}"
"${MOONRAKER_OBICO_DIR}/install.sh"\
-n "${moonraker_names[${j}]}"\
-C "${instance_cfg_dirs[${j}]}/moonraker.conf"\
-p $((port+j))\
-H 127.0.0.1\
-l "${instance_log_dirs[${j}]}"\
-L -S "${obico_server_url}"
j=$(( j + 1 ))
done && unset j
fi # (( moonraker_count == 1 ))
@@ -301,8 +311,21 @@ function remove_moonraker_obico_systemd() {
}
function remove_moonraker_obico_logs() {
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
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_legacy_moonraker_obico_logs() {
local files regex="moonraker-obico(-[0-9a-zA-Z]+)?\.log(.*)?"
files=$(find "${KLIPPER_LOGS}" -maxdepth 1 -regextype posix-extended -regex "${KLIPPER_LOGS}/${regex}" 2> /dev/null | sort)
files=$(find "${HOME}/klipper_logs" -maxdepth 1 -regextype posix-extended -regex "${HOME}/klipper_logs/${regex}" 2> /dev/null | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
@@ -372,7 +395,7 @@ function get_moonraker_obico_status() {
is_linked="true"
if [[ -n ${moonraker_obico_services} ]]; then
for cfg_dir in $(get_config_folders); do
for cfg_dir in $(get_instance_folder_path "config"); do
if moonraker_obico_needs_linking "${cfg_dir}/moonraker-obico.cfg"; then
is_linked="false"
fi

395
scripts/octoeverywhere.sh Normal file
View File

@@ -0,0 +1,395 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2023 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 #
#=======================================================================#
#
# This file is written and maintained by Quinn Damerell from OctoEverywhere
# Please contact our support team if you need any help!
# https://octoeverywhere.com/support
#
set -e
#===================================================#
#============== Install ============#
#===================================================#
function octoeverywhere_systemd() {
local services
services=$(find "${SYSTEMD}" -maxdepth 1 -regextype posix-extended -regex "${SYSTEMD}/octoeverywhere(-[0-9a-zA-Z]+)?.service")
echo "${services}"
}
function octoeverywhere_setup_dialog() {
status_msg "Initializing OctoEverywhere for Klipper installation ..."
# First, check for moonraker service instances.
local moonraker_count
local moonraker_names
moonraker_count=$(moonraker_systemd | wc -w)
if (( moonraker_count == 0 )); then
### return early if moonraker is not installed
local error="Moonraker not installed! Please install Moonraker first!"
log_error "OctoEverywhere setup started without Moonraker being installed. Aborting setup."
print_error "${error}" && return
elif (( moonraker_count > 1 )); then
# moonraker_names is valid only in case of multi-instance
read -r -a moonraker_names <<< "$(get_multi_instance_names)"
fi
# Next, check for any existing OctoEverywhere services.
local octoeverywhere_services
local existing_octoeverywhere_count
octoeverywhere_services=$(octoeverywhere_systemd)
existing_octoeverywhere_count=$(echo "${octoeverywhere_services}" | wc -w )
# We need to make the moonraker instance count to the OctoEverywhere service count.
local allowed_octoeverywhere_count=$(( moonraker_count - existing_octoeverywhere_count ))
if (( allowed_octoeverywhere_count > 0 )); then
local new_octoeverywhere_count
### Step 1: Ask for the number of OctoEverywhere instances to install
if (( moonraker_count == 1 )); then
ok_msg "Moonraker installation found!\n"
new_octoeverywhere_count=1
elif (( moonraker_count > 1 )); then
top_border
printf "|${green}%-55s${white}|\n" " ${moonraker_count} Moonraker instances found!"
for name in "${moonraker_names[@]}"; do
printf "|${cyan}%-57s${white}|\n" " ● moonraker-${name}"
done
blank_line
if (( existing_octoeverywhere_count > 0 )); then
printf "|${green}%-55s${white}|\n" " ${existing_octoeverywhere_count} OctoEverywhere instances already installed!"
for svc in ${octoeverywhere_services}; do
printf "|${cyan}%-57s${white}|\n" " ● octoeverywhere-$(get_instance_name "${svc}")"
done
fi
blank_line
echo -e "| The setup will apply the same names to |"
echo -e "| OctoEverywhere |"
blank_line
echo -e "| Please select the number of OctoEverywhere instances |"
echo -e "| to install. Usually one OctoEverywhere instance per |"
echo -e "| Moonraker instance is required, but you may not |"
echo -e "| install more OctoEverywhere instances than available |"
echo -e "| Moonraker instances. |"
bottom_border
### ask for amount of instances
local re="^[1-9][0-9]*$"
while [[ ! ${new_octoeverywhere_count} =~ ${re} || ${new_octoeverywhere_count} -gt ${allowed_octoeverywhere_count} ]]; do
read -p "${cyan}###### Number of new OctoEverywhere instances to set up:${white} " -i "${allowed_octoeverywhere_count}" -e new_octoeverywhere_count
### break if input is valid
[[ ${new_octoeverywhere_count} =~ ${re} && ${new_octoeverywhere_count} -le ${allowed_octoeverywhere_count} ]] && break
### conditional error messages
[[ ! ${new_octoeverywhere_count} =~ ${re} ]] && error_msg "Input not a number"
(( new_octoeverywhere_count > allowed_octoeverywhere_count )) && error_msg "Number of OctoEverywhere instances larger than installed Moonraker instances"
done && select_msg "${new_octoeverywhere_count}"
else
log_error "Internal error. moonraker_count of '${moonraker_count}' not equal or grater than one!"
return 1
fi # (( moonraker_count == 1 ))
fi # (( allowed_octoeverywhere_count > 0 ))
# Special case for one moonraker instance with OctoEverywhere already installed.
# If the user selects the install option again, they might be trying to recover the install
# or complete a printer link they didn't finish in the past.
# So in this case, we will allow them to run the install script again, since it's safe to run
# if the service is already installed, it will repair any missing issues.
if (( allowed_octoeverywhere_count == 0 && moonraker_count == 1 )); then
local yn
while true; do
echo "${yellow}OctoEverywhere is already installed.${white}"
echo "It is safe to run the install again to repair any issues or if the printer isn't linked, run the printer linking logic again."
echo ""
local question="Do you want to run the OctoEverywhere recovery or linking logic again?"
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 OctoEverywhere setup ...\n"
return;;
*)
error_msg "Invalid Input!";;
esac
done
# The user responded yes, allow the install to run again.
allowed_octoeverywhere_count=1
fi
# If there's something to install, do it!
if (( allowed_octoeverywhere_count > 0 )); then
(( new_octoeverywhere_count > 1 )) && status_msg "Installing ${new_octoeverywhere_count} OctoEverywhere instances ..."
(( new_octoeverywhere_count == 1 )) && status_msg "Installing OctoEverywhere ..."
# Ensure the basic system dependencies are installed.
local dep=(git dfu-util virtualenv python3 python3-pip python3-venv)
dependency_check "${dep[@]}"
# Close the repo
clone_octoeverywhere "${OCTOEVERYWHERE_REPO}"
# Call install with the correct args.
local instance_cfg_dirs
read -r -a instance_cfg_dirs <<< "$(get_instance_folder_path "config")"
echo instance_cfg_dirs[0]
if (( moonraker_count == 1 )); then
"${OCTOEVERYWHERE_DIR}/install.sh" "${instance_cfg_dirs[0]}/moonraker.conf"
elif (( moonraker_count > 1 )); then
local j=${existing_octoeverywhere_count}
for (( i=1; i <= new_octoeverywhere_count; i++ )); do
"${OCTOEVERYWHERE_DIR}/install.sh" "${instance_cfg_dirs[${j}]}/moonraker.conf"
j=$(( j + 1 ))
done && unset j
fi # (( moonraker_count == 1 ))
fi # (( allowed_octoeverywhere_count > 0 ))
}
function clone_octoeverywhere() {
local repo=${1}
status_msg "Cloning OctoEverywhere..."
### force remove existing repos
[[ -d "${OCTOEVERYWHERE_DIR}" ]] && rm -rf "${OCTOEVERYWHERE_DIR}"
cd "${HOME}" || exit 1
if ! git clone "${repo}" "${OCTOEVERYWHERE_DIR}"; then
print_error "Cloning OctoEverywhere from\n ${repo}\n failed!"
exit 1
fi
}
function octoeverywhere_install() {
"${OCTOEVERYWHERE_DIR}/install.sh" "$@"
}
#===================================================#
#============= Remove ==============#
#===================================================#
function remove_octoeverywhere_systemd() {
[[ -z $(octoeverywhere_systemd) ]] && return
status_msg "Removing OctoEverywhere Systemd Services ..."
for service in $(octoeverywhere_systemd | cut -d"/" -f5); do
status_msg "Removing ${service} ..."
sudo systemctl stop "${service}"
sudo systemctl disable "${service}"
sudo rm -f "${SYSTEMD}/${service}"
ok_msg "Done!"
done
### reloading units
sudo systemctl daemon-reload
sudo systemctl reset-failed
ok_msg "OctoEverywhere Services removed!"
}
function remove_octoeverywhere_logs() {
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/logs\/octoeverywhere(-[0-9a-zA-Z]+)?\.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
}
function remove_octoeverywhere_dir() {
[[ ! -d ${OCTOEVERYWHERE_DIR} ]] && return
status_msg "Removing OctoEverywhere directory ..."
rm -rf "${OCTOEVERYWHERE_DIR}"
ok_msg "Directory removed!"
}
function remove_octoeverywhere_config() {
# Remove the system config but not the main config, so the printer id doesn't get lost.
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/octoeverywhere-system(-[0-9a-zA-Z]+)?\.cfg(.*)?"
files=$(find "${HOME}" -maxdepth 4 -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
}
function remove_octoeverywhere_store_dir() {
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/octoeverywhere-store"
files=$(find "${HOME}" -maxdepth 2 -type d -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -rf "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_octoeverywhere_env() {
[[ ! -d "${HOME}/octoeverywhere-env" ]] && return
status_msg "Removing octoeverywhere-env directory ..."
rm -rf "${HOME}/octoeverywhere-env"
ok_msg "Directory removed!"
}
function remove_octoeverywhere()
{
remove_octoeverywhere_systemd
remove_octoeverywhere_logs
remove_octoeverywhere_dir
remove_octoeverywhere_env
remove_octoeverywhere_config
remove_octoeverywhere_store_dir
print_confirm "OctoEverywhere was successfully removed!"
return
}
#===================================================#
#============= UPDATE ==============#
#===================================================#
function update_octoeverywhere() {
do_action_service "stop" "octoeverywhere"
if [[ ! -d ${OCTOEVERYWHERE_DIR} ]]; then
clone_octoeverywhere "${OCTOEVERYWHERE_REPO}"
else
backup_before_update "octoeverywhere"
status_msg "Updating OctoEverywhere for Klipper ..."
cd "${OCTOEVERYWHERE_DIR}" && git pull
### read PKGLIST and install possible new dependencies
install_octoeverywhere_dependencies
### install possible new python dependencies
"${OCTOEVERYWHERE_ENV}"/bin/pip install -r "${OCTOEVERYWHERE_DIR}/requirements.txt"
fi
ok_msg "Update complete!"
do_action_service "restart" "octoeverywhere"
}
function clone_octoeverywhere() {
local repo=${1}
status_msg "Cloning OctoEverywhere from ${repo} ..."
### force remove existing octoeverywhere dir and clone into fresh octoeverywhere dir
[[ -d ${OCTOEVERYWHERE_DIR} ]] && rm -rf "${OCTOEVERYWHERE_DIR}"
cd "${HOME}" || exit 1
if ! git clone "${OCTOEVERYWHERE_REPO}" "${OCTOEVERYWHERE_DIR}"; then
print_error "Cloning OctoEverywhere from\n ${repo}\n failed!"
exit 1
fi
}
function install_octoeverywhere_dependencies() {
local packages
local install_script="${OCTOEVERYWHERE_DIR}/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 octoeverywhere packages"
error_msg "Installing required packages failed!"
exit 1
fi
}
#===================================================#
#============= STATUS ==============#
#===================================================#
function get_octoeverywhere_status() {
local status
local service_count
local octoeverywhere_services
octoeverywhere_services=$(octoeverywhere_systemd)
service_count=$(echo "${octoeverywhere_services}" | wc -w )
if (( service_count == 0 )); then
status="Not installed!"
elif [[ ! -d "${OCTOEVERYWHERE_DIR}" ]]; then
status="Incomplete!"
else
status="Installed!"
fi
echo "${status}"
}
function get_local_octoeverywhere_commit() {
[[ ! -d ${OCTOEVERYWHERE_DIR} || ! -d "${OCTOEVERYWHERE_DIR}/.git" ]] && return
local commit
cd "${OCTOEVERYWHERE_DIR}"
commit="$(git describe HEAD --always --tags | cut -d "-" -f 1,2)"
echo "${commit}"
}
function get_remote_octoeverywhere_commit() {
[[ ! -d ${OCTOEVERYWHERE_DIR} || ! -d "${OCTOEVERYWHERE_DIR}/.git" ]] && return
local commit
cd "${OCTOEVERYWHERE_DIR}" && git fetch origin -q
commit=$(git describe origin/master --always --tags | cut -d "-" -f 1,2)
echo "${commit}"
}
function compare_octoeverywhere_versions() {
local versions local_ver remote_ver
local_ver="$(get_local_octoeverywhere_commit)"
remote_ver="$(get_remote_octoeverywhere_commit)"
if [[ ${local_ver} != "${remote_ver}" ]]; then
versions="${yellow}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
# Add us to the update file, so if the user selects "update all" it includes us.
add_to_application_updates "octoeverywhere"
else
versions="${green}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
fi
echo "${versions}"
}

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -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."
@@ -227,21 +227,30 @@ function create_octoprint_service() {
local octoprint_count=${input[0]} && unset "input[0]"
local names=("${input[@]}") && unset "input[@]"
local j=0 port=5000
local octo_env service basedir tmp_printer config_yaml restart_cmd
local printer_data octo_env service basedir printer config_yaml restart_cmd
for (( i=1; i <= octoprint_count; i++ )); do
if (( octoprint_count == 1 )); then
printer_data="${HOME}/printer_data"
octo_env="${HOME}/OctoPrint"
service="${SYSTEMD}/octoprint.service"
basedir="${HOME}/.octoprint"
tmp_printer="/tmp/printer"
printer="${printer_data}/comms/klippy.serial"
config_yaml="${basedir}/config.yaml"
restart_cmd="sudo service octoprint restart"
elif (( octoprint_count > 1 )); then
local re="^[1-9][0-9]*$"
if [[ ${names[j]} =~ ${re} ]]; then
printer_data="${HOME}/printer_${names[${j}]}_data"
else
printer_data="${HOME}/${names[${j}]}_data"
fi
octo_env="${HOME}/OctoPrint_${names[${j}]}"
service="${SYSTEMD}/octoprint-${names[${j}]}.service"
basedir="${HOME}/.octoprint_${names[${j}]}"
tmp_printer="/tmp/printer-${names[${j}]}"
printer="${printer_data}/comms/klippy.serial"
config_yaml="${basedir}/config.yaml"
restart_cmd="sudo service octoprint-${names[${j}]} restart"
fi
@@ -280,9 +289,9 @@ OCTOPRINT
/bin/sh -c "cat > ${basedir}/config.yaml" << CONFIGYAML
serial:
additionalPorts:
- ${tmp_printer}
- ${printer}
disconnectOnErrors: false
port: ${tmp_printer}
port: ${printer}
server:
commands:
serverRestartCommand: ${restart_cmd}

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -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

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -26,9 +26,10 @@ function install_ui() {
echo -e "| Klipper Webinterface: | 7) [PrettyGCode] |"
echo -e "| 3) [Mainsail] | 8) [Telegram Bot] |"
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 "| | 10) [OctoEverywhere] |"
echo -e "| Touchscreen GUI: | |"
echo -e "| 5) [KlipperScreen] | Webcam Streamer: |"
echo -e "| | 11) [Crowsnest] |"
back_footer
}
@@ -47,7 +48,7 @@ function install_menu() {
read -p "${cyan}####### Perform action:${white} " action
case "${action}" in
1)
do_action "select_klipper_python_version" "install_ui";;
do_action "start_klipper_setup" "install_ui";;
2)
do_action "moonraker_setup_dialog" "install_ui";;
3)
@@ -55,35 +56,19 @@ function install_menu() {
4)
do_action "install_fluidd" "install_ui";;
5)
#do_action "install_klipperscreen" "install_ui";;
clear && print_header
print_error "Function currently disabled! Sorry!"
install_ui;;
do_action "install_klipperscreen" "install_ui";;
6)
#do_action "octoprint_setup_dialog" "install_ui";;
clear && print_header
print_error "Function currently disabled! Sorry!"
install_ui;;
do_action "octoprint_setup_dialog" "install_ui";;
7)
#do_action "install_pgc_for_klipper" "install_ui";;
clear && print_header
print_error "Function currently disabled! Sorry!"
install_ui;;
do_action "install_pgc_for_klipper" "install_ui";;
8)
#do_action "telegram_bot_setup_dialog" "install_ui";;
clear && print_header
print_error "Function currently disabled! Sorry!"
install_ui;;
do_action "telegram_bot_setup_dialog" "install_ui";;
9)
#do_action "moonraker_obico_setup_dialog" "install_ui";;
clear && print_header
print_error "Function currently disabled! Sorry!"
install_ui;;
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;;
do_action "octoeverywhere_setup_dialog" "install_ui";;
11)
do_action "install_crowsnest" "install_ui";;
B|b)
clear; main_menu; break;;
*)
@@ -92,33 +77,3 @@ function install_menu() {
done
install_menu
}
function select_klipper_python_version() {
top_border
echo -e "| Please select the preferred Python version. | "
echo -e "| The recommended version is Python 2.7. | "
blank_line
echo -e "| Installing Klipper with Python 3 is officially not | "
echo -e "| recommended and should be considered as experimental. | "
hr
echo -e "| 1) [Python 2.7] (recommended) | "
echo -e "| 2) [Python 3.x] ${yellow}(experimental)${white} | "
back_footer
while true; do
read -p "${cyan}###### Select Python version:${white} " action
case "${action}" in
1)
select_msg "Python 2.7"
klipper_setup_dialog "python2"
break;;
2)
select_msg "Python 3.x"
klipper_setup_dialog "python3"
break;;
B|b)
clear; install_menu; break;;
*)
error_msg "Invalid Input!\n";;
esac
done
}

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -19,18 +19,21 @@ function main_ui() {
top_border
echo -e "| $(title_msg "~~~~~~~~~~~~~~~ [ Main Menu ] ~~~~~~~~~~~~~~~") |"
hr
echo -e "| 0) [Log-Upload] | Klipper: $(print_status "klipper")|"
echo -e "| | Repo: $(print_klipper_repo)|"
echo -e "| 1) [Install] | |"
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 "| | KlipperScreen: $(print_status "klipperscreen")|"
echo -e "| 6) [Settings] | Telegram Bot: $(print_status "telegram_bot")|"
echo -e "| | Obico: $(print_status "moonraker_obico")|"
echo -e "| | |"
echo -e "| $(print_kiauh_version)| Octoprint: $(print_status "octoprint")|"
echo -e "| 0) [Log-Upload] | Klipper: $(print_status "klipper")|"
echo -e "| | Repo: $(print_klipper_repo)|"
echo -e "| 1) [Install] | |"
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 "| | 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 "| | OctoEverywhere: $(print_status "octoeverywhere")|"
echo -e "| | |"
echo -e "| $(print_kiauh_version)| Octoprint: $(print_status "octoprint")|"
quit_footer
}
@@ -43,7 +46,7 @@ function get_kiauh_version() {
function print_kiauh_version() {
local version
version="$(printf "%-18s" "$(get_kiauh_version)")"
version="$(printf "%-16s" "$(get_kiauh_version)")"
echo "${cyan}${version}${white}"
}
@@ -106,6 +109,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

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -18,16 +18,18 @@ 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) [OctoEverywhere] |"
echo -e "| | 15) [NGINX] |"
back_footer
}
@@ -45,20 +47,28 @@ 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_octoeverywhere" "remove_ui";;
15)
do_action "remove_nginx" "remove_ui";;
B|b)
clear; main_menu; break;;

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -32,8 +32,10 @@ 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) [OctoEverywhere] |$(compare_octoeverywhere_versions)|"
echo -e "| 10) [Crowsnest] |$(compare_crowsnest_versions)|"
echo -e "| |------------------------------|"
echo -e "| 9) [System] | $(check_system_updates) |"
echo -e "| 11) [System] | $(check_system_updates) |"
back_footer
}
@@ -63,6 +65,10 @@ function update_menu() {
8)
do_action "update_moonraker_obico" "update_ui";;
9)
do_action "update_octoeverywhere" "update_ui";;
10)
do_action "update_crowsnest" "update_ui";;
11)
do_action "update_system" "update_ui";;
a)
do_action "update_all" "update_ui";;
@@ -114,6 +120,9 @@ function update_all() {
[[ "${update_arr[*]}" =~ "telegram_bot" ]] && \
echo -e "| ${cyan}● MoonrakerTelegramBot${white} |"
[[ "${update_arr[*]}" =~ "octoeverywhere" ]] && \
echo -e "| ${cyan}● OctoEverywhere${white} |"
[[ "${update_arr[*]}" =~ "system" ]] && \
echo -e "| ${cyan}● System${white} |"

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# Copyright (C) 2020 - 2023 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
@@ -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")
@@ -597,7 +585,9 @@ function set_multi_instance_names() {
local name
local names=""
local services=$(find_klipper_systemd)
local services
services=$(klipper_systemd)
###
# if value of 'multi_instance_names' is not an empty
@@ -639,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.
@@ -657,16 +671,60 @@ function get_config_folders() {
# by KIAUH convention, all instance names of only numbers
# need to be prefixed with 'printer_'
if [[ ${name} =~ ^[0-9]+$ ]]; then
cfg_dirs+=("${KLIPPER_CONFIG}/printer_${name}")
cfg_dirs+=("${HOME}/printer_${name}_data/config")
else
cfg_dirs+=("${KLIPPER_CONFIG}/${name}")
cfg_dirs+=("${HOME}/${name}_data/config")
fi
done
elif [[ -z ${instance_names} && $(find_klipper_systemd | wc -w) -gt 0 ]]; then
cfg_dirs+=("${KLIPPER_CONFIG}")
elif [[ -z ${instance_names} && $(klipper_systemd | wc -w) -gt 0 ]]; then
cfg_dirs+=("${HOME}/printer_data/config")
else
cfg_dirs=()
fi
echo "${cfg_dirs[@]}"
}
###
# helper function that returns all available absolute directory paths
# based on their instance name and specified target folder
#
# @param {string}: folder name - target instance folder name (e.g. config)
#
# => return an empty string if klipper is not installed
# => return space-separated string of absolute directory paths
#
function get_instance_folder_path() {
local folder_name=${1}
local folder_paths=()
local instance_names
local path
instance_names=$(get_multi_instance_names)
if [[ -n ${instance_names} ]]; then
for name in ${instance_names}; do
###
# by KIAUH convention, all instance names of only numbers
# need to be prefixed with 'printer_'
if [[ ${name} =~ ^[0-9]+$ ]]; then
path="${HOME}/printer_${name}_data/${folder_name}"
if [[ -d ${path} ]]; then
folder_paths+=("${path}")
fi
else
path="${HOME}/${name}_data/${folder_name}"
if [[ -d ${path} ]]; then
folder_paths+=("${path}")
fi
fi
done
elif [[ -z ${instance_names} && $(klipper_systemd | wc -w) -gt 0 ]]; then
path="${HOME}/printer_data/${folder_name}"
if [[ -d ${path} ]]; then
folder_paths+=("${path}")
fi
fi
echo "${folder_paths[@]}"
}