Compare commits

..

24 Commits

Author SHA1 Message Date
th33xitus
046178f801 refactor!: update KIAUH for recent moonraker changes (#245) 2022-10-20 11:20:34 +02:00
cobyn
442980dbd0 fix(flash_klipper): spelling mistake (#242) 2022-10-05 17:22:31 +02:00
th33xitus
798e56f4dc refactor(mainsail): replace deprecated remote mode with new instanceDB
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-09-18 23:45:02 +02:00
th33xitus
9d90daec7f fix(switch_klipper_repo): use of case didn't allow selections of 2 and above
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-09-10 20:25:05 +02:00
megapro17
f25726cfed fix: typo in mjpg-streamer dialog (#239) 2022-09-08 09:15:24 +02:00
th33xitus
f46b099b74 refactor(klipper): more verbose error message if SysVinit script is detected
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-09-03 14:14:37 +02:00
th33xitus
03be46f012 refactor(moonraker): skip polkit script execution if polkit rules already installed
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-09-03 13:41:02 +02:00
th33xitus
c11e628c55 fix(moonraker): do not exit if moonraker_polkit exits with an error during moonraker update
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-09-03 11:34:45 +02:00
th33xitus
4c8d43e365 refactor: use OS independent method to check/set for correct home folder permissions
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-08-27 22:08:01 +02:00
Kenneth Jiang
9d7144b493 feat: add Obico for Klipper to KIAUH (#227)
Co-authored-by: th33xitus <th33xitus@googlemail.com>
2022-08-15 19:44:04 +02:00
th33xitus
6df388f42b refactor: install webcamd from self provided resources
with the upcoming release of a new MainsailOS image, mjpg-streamer is replaced by crowsnest. it is therefore not possible anymore to pull the files from the mainsailOS repository. hence adding them to the KIAUH repository.

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-07-29 19:46:39 +02:00
th33xitus
1d7fb010af refactor: remove unused kiauh_macros.cfg
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-07-24 08:51:48 +02:00
th33xitus
d4207d710c fix: restart moonraker after moonraker.conf patch (fixes #225)
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-07-22 10:16:00 +02:00
th33xitus
6cb8d70b63 fix: replace generic nginx webui cfg by their respective ones
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-07-22 10:06:35 +02:00
th33xitus
ae011963da fix: install mainsail theme to correct folder (fixes #222)
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-07-20 22:41:42 +02:00
th33xitus
491d6f40bb refactor: move ini initialization to main_menu()
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-07-20 22:34:07 +02:00
th33xitus
8bbe2f79ea feat: save multi instance klipper names/identifier to kiauh.ini
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2022-07-20 22:33:33 +02:00
th33xitus
0bdf61a714 fix: do not install py2 packages if venv is py3 (fixes #211)
Signed-off-by: Dominik Willner th33xitus@gmail.com
2022-06-30 20:41:36 +02:00
th33xitus
b07a83c8ad fix: update all function (#204) (#217)
* fix: update all function (fixes #204)
* fix: replace non-existing `print_unkown_cmd` function

Signed-off-by: Dominik Willner th33xitus@gmail.com
2022-06-30 11:08:09 +02:00
th33xitus
39e22acbed fix(octoprint.sh): script exiting without error message (fixes #216)
- the script was exiting without notifying the user that klipper has to be installed first

Signed-off-by: Dominik Willner th33xitus@gmail.com
2022-06-26 08:48:38 +02:00
th33xitus
8ba46fa4ac fix(pretty_gcode.sh): use main instead of master (fixes #203)
- pgc uses main instead of master. so checking for origin/master leads to an error

Signed-off-by: Dominik Willner th33xitus@gmail.com
2022-05-31 17:27:52 +02:00
th33xitus
d6b95c9d10 refactor(nginx.sh): refactor set_nginx_cfg()
- implements two dedicated nginx configs for mainsail and fluidd

Signed-off-by: Dominik Willner th33xitus@gmail.com
2022-05-30 18:38:45 +02:00
th33xitus
f3a769e03e README.md: reworded a feature description
Signed-off-by: Dominik Willner th33xitus@gmail.com
2022-05-29 22:02:03 +02:00
th33xitus
646e5acd3a README.md: update README.md
Signed-off-by: Dominik Willner th33xitus@gmail.com
2022-05-29 20:35:07 +02:00
36 changed files with 2012 additions and 816 deletions

View File

@@ -52,37 +52,47 @@ git clone https://github.com/th33xitus/kiauh.git
<th><h3><a href="https://github.com/Klipper3d/klipper">Klipper</a></h3></th>
<th><h3><a href="https://github.com/Arksine/moonraker">Moonraker</a></h3></th>
<th><h3><a href="https://github.com/mainsail-crew/mainsail">Mainsail</a></h3></th>
<th><h3><a href="https://github.com/fluidd-core/fluidd">Fluidd</a></h3></th>
</tr>
<tr>
<th><img src="https://raw.githubusercontent.com/Klipper3d/klipper/master/docs/img/klipper-logo.png" alt="Klipper Logo" height="64"></th>
<th><img src="https://avatars.githubusercontent.com/u/9563098?v=4" alt="Arksine avatar" height="64"></th>
<th><img src="https://raw.githubusercontent.com/mainsail-crew/docs/master/assets/img/logo.png" alt="Mainsail Logo" height="64"></th>
<th><img src="https://raw.githubusercontent.com/fluidd-core/fluidd/master/docs/assets/images/logo.svg" alt="Fluidd Logo" height="64"></th>
</tr>
<tr>
<th>by <a href="https://github.com/KevinOConnor">KevinOConnor</a></th>
<th>by <a href="https://github.com/Arksine">Arksine</a></th>
<th>by <a href="https://github.com/mainsail-crew">mainsail-crew</a></th>
<th>by <a href="https://github.com/fluidd-core">fluidd-core</a></th>
</tr>
<tr>
<th><h3><a href="https://github.com/fluidd-core/fluidd">Fluidd</a></h3></th>
<th><h3><a href="https://github.com/jordanruthe/KlipperScreen">KlipperScreen</a></h3></th>
<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/OctoPrint/OctoPrint">OctoPrint</a></h3></th>
</tr>
<tr>
<th><img src="https://raw.githubusercontent.com/fluidd-core/fluidd/master/docs/assets/images/logo.svg" alt="Fluidd Logo" height="64"></th>
<th><img src="https://avatars.githubusercontent.com/u/31575189?v=4" alt="jordanruthe avatar" height="64"></th>
<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://camo.githubusercontent.com/627be7fc67195b626b298af9b9677d7c58e698c67305e54324cffbe06130d4a4/68747470733a2f2f6f63746f7072696e742e6f72672f6173736574732f696d672f6c6f676f2e706e67" alt="OctoPrint Logo" height="64"></th>
</tr>
<tr>
<th>by <a href="https://github.com/fluidd-core">fluidd-core</a></th>
<th>by <a href="https://github.com/jordanruthe">jordanruthe</a></th>
<th>by <a href="https://github.com/OctoPrint">OctoPrint</a></th>
</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/OctoPrint">OctoPrint</a></th>
<th>by <a href="https://github.com/TheSpaghettiDetective">Obico</a></th>
</tr>
</table>

View File

@@ -2,20 +2,77 @@
This document covers possible important changes to KIAUH.
### 2022-04-XX
### 2022-10-20
KIAUH has now reached major version 5 !
Recently Moonraker introduced some changes which makes it necessary to change the folder structure of printer setups.
If you are interested in the details, check out this PR: https://github.com/Arksine/moonraker/pull/491 \
Although Moonraker has some mechanics available to migrate existing setups to the new file structure with the use of symlinks, fresh and clean installs
should be considered.
The version jump of KIAUH to v5 is a breaking change due to those major changes! That means v4 and v5 are not compatible with each other!
This is also the reason why you will currently be greeted by a yellow notification in the main menu of KIAUH leading to this changelog.
I decided to disable a few functions of the script and focus on releasing the required changes to the core components of this script.
I will work on updating the other parts of the script piece by piece during the next days/weeks.
So I am already sorry in advance if one of your desired components you wanted to install or use temporarily cannot be installed or used right now.
The following functions are currently unavailable:
- Installation of: KlipperScreen, Obico, Octoprint, MJPG-Streamer, Telegram Bot and PrettyGCode
- All backup functions and the Log-Upload
**So what is working?**\
Installation of Klipper, Moonraker, Mainsail and Fluidd. Both, single and multi-instance setups work!\
As already said, the rest will follow in the near future. Updating and removal of already installed components should continue to work.
**What was removed?**\
The option to change Klippers configuration directory got removed. From now on it will not be possible anymore to change
the configuration directory from within KIAUH and the new filestructure is enforced.
**What if I don't have an existing Klipper/Moonraker install right now?**\
Nothing important to think about, install Klipper and Moonraker. KIAUH will install both of them with the new filestructure.
**What if I have an existing Klipper/Moonraker install?**\
First of all: Backups! Please copy all of your config files and the Moonraker database (it is a hidden folder, usually `~/.moonraker_database`) to a safe location.
After that, uninstall Klipper and Moonraker with KIAUH. You can then proceed and re-install both of them with KIAUH again. It is important that you are on KIAUH v5 for that!
Once everything is installed again, you need to manually copy your configuration files from the old `~/klipper_config` folder to the new `~/printer_data/config` folder.
Previous, by Moonraker created symlinks to folder of the old filestructure will not work anymore, you need to move the files to their new location now!
Do the same with the two files inside of `~/.moonraker_database`. Move/copy them into `~/printer_data/database`. If `~/printer_data/database` is already populated with a `data.mdb` and `lock.mdb`
delete them or simply overwrite them. Nothing should be lost as those should be empty database files. Anyway, you made backups, right?
You can now proceed and restart Moonraker. Either from within Mainsail or Fluidd, or use SSH and execute `sudo systemctl restart moonraker`.
If everything went smooth, you should be good to go again. If you see some Moonraker warnings about deprecated options in the `moonraker.conf`, go ahead and resolve them.
I will not cover them in detail here. A good source is the Moonraker documentation: https://moonraker.readthedocs.io/en/latest/configuration/
**What if I have an existing Klipper/Moonraker multi-instance install?**\
Pretty much the same steps that are required for single instance installs apply to multi-instance setups. So please go ahead and read the previous paragraph if you didn't already.
Make backups of everything first. Then remove and install the desired amount of Klipper and Moonraker instances again.
Now you need to move all config and database files to their new locations.\
Example with an instance called `printer_1`:\
The config files go from `~/klipper_config/printer_1` to `~/printer_1_data/config`.
The database files go from `~/.moonraker_database_1` to `~/printer_1_data/database`.
Now restart all Moonraker services. You can restart all of them at once if you launch KIAUH, and in the main menu type `restart moonraker` and hit Enter.
I hope I have covered the most important things. In case you need further support, the official Klipper Discord is a good place to ask for help.
### 2022-08-15
Support for "Obico for Klipper" was added! Huge thanks to [kennethjiang](https://github.com/kennethjiang) for helping me with the implementation!
### 2022-05-29
KIAUH has now reached major version 4 !
* feat: Klipper can be installed under Python3 (considered as experimental)
* feat: Klipper can be installed under Python3 (still considered as experimental)
* feat: Klipper can be installed from custom repositories / inofficial forks
* feat: Custom instance name for multi instance installations of Klipper
* Any other multi instance will share the same name given to the corresponding Klipper instance
* E.g. klipper-voron2 -> moonraker-voron2 -> moonraker-telegram-bot-voron2
* feat: Option to only allow the installation of stable Mainsail and Fluidd versions
* feat: Option to allow installation of / updating to unstable Mainsail and Fluidd versions
* by default only stable versions get installed/updated
* feat: Multi-Instance OctoPrint installations now each have their own virtual python environment
* allows independent installation of plugins for each instance
* feat: Implementing the use of shellcheck during development
* feat: Implementing a simple logging mechanic
* feat: Log-upload function now also allows uploading other logfiles (kiauh.log, webcamd.log etc.)
* feat: added several new help dialogs which try to explain various functions
* fix: During Klipper installation, checks for group membership of `tty` and `dialout` are made
* refactor: rework of the settings menu for better control the new KIAUH features
* refactor: Support for DWC and DWC-for-Klipper has been removed
* refactor: The backup before update settings were moved to the KIAUH settings menu
* refactor: Switch branch function has been removed (was replaced by the custom Klipper repo feature)

View File

@@ -9,6 +9,15 @@
# 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
clear
@@ -84,6 +93,5 @@ function kiauh_update_dialog() {
check_euid
init_logfile
set_globals
init_ini
kiauh_update_dialog
main_menu

View File

@@ -1,10 +1,10 @@
# /etc/nginx/sites-available/<<UI>>
# /etc/nginx/sites-available/fluidd
server {
listen 80;
access_log /var/log/nginx/<<UI>>-access.log;
error_log /var/log/nginx/<<UI>>-error.log;
access_log /var/log/nginx/fluidd-access.log;
error_log /var/log/nginx/fluidd-error.log;
# disable this section on smaller hardware like a pi zero
gzip on;
@@ -16,8 +16,8 @@ server {
gzip_http_version 1.1;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/x-javascript application/json application/xml;
# web_path from <<UI>> static files
root /home/pi/<<UI>>;
# web_path from fluidd static files
root /home/pi/fluidd;
index index.html;
server_name _;

View File

@@ -1,59 +0,0 @@
################################################################################
# ~~~~~~~~~~~~~~~~~~~~~~~~ AUTOCREATED WITH KIAUH ~~~~~~~~~~~~~~~~~~~~~~~~~~ #
################################################################################
# Recommended macros and config entries if you use Mainsail or Fluidd! #
# You can edit or delete those macros if you already defined them elsewhere! #
################################################################################
[pause_resume]
[display_status]
[gcode_macro CANCEL_PRINT]
rename_existing: BASE_CANCEL_PRINT
gcode:
TURN_OFF_HEATERS
CLEAR_PAUSE
SDCARD_RESET_FILE
BASE_CANCEL_PRINT
[gcode_macro PAUSE]
rename_existing: BASE_PAUSE
gcode:
##### set defaults #####
{% set x = params.X|default(230) %} #edit to your park position
{% set y = params.Y|default(230) %} #edit to your park position
{% set z = params.Z|default(10)|float %} #edit to your park position
{% set e = params.E|default(1) %} #edit to your retract length
##### calculate save lift position #####
{% set max_z = printer.toolhead.axis_maximum.z|float %}
{% set act_z = printer.toolhead.position.z|float %}
{% set lift_z = z|abs %}
{% if act_z < (max_z - lift_z) %}
{% set z_safe = lift_z %}
{% else %}
{% set z_safe = max_z - act_z %}
{% endif %}
##### end of definitions #####
SAVE_GCODE_STATE NAME=PAUSE_state
BASE_PAUSE
G91
G1 E-{e} F2100
G1 Z{z_safe}
G90
G1 X{x} Y{y} F6000
[gcode_macro RESUME]
rename_existing: BASE_RESUME
gcode:
##### set defaults #####
{% set e = params.E|default(1) %} #edit to your retract length
G91
G1 E{e} F2100
G90
RESTORE_GCODE_STATE NAME=PAUSE_state MOVE=1
BASE_RESUME
################################################################################
################################################################################

1
resources/klipper.env Normal file
View File

@@ -0,0 +1 @@
KLIPPER_ARGS="/home/%USER%/klipper/klippy/klippy.py %CFG% -I %PRINTER% -l %LOG% -a %UDS%"

View File

@@ -1,7 +1,5 @@
#Systemd Klipper Service
[Unit]
Description=Systemd Klipper Service for instance klipper-%INST%
Description=Klipper 3D Printer Firmware SV1 %INST%
Documentation=https://www.klipper3d.org/
After=network.target
Wants=udev.target
@@ -10,13 +8,11 @@ Wants=udev.target
WantedBy=multi-user.target
[Service]
Environment=KLIPPER_CONFIG=%CFG%
Environment=KLIPPER_LOG=%LOG%
Environment=KLIPPER_SOCKET=%UDS%
Environment=KLIPPER_PRINTER=%PRINTER%
Type=simple
User=%USER%
RemainAfterExit=yes
ExecStart=%ENV%/bin/python %DIR%/klippy/klippy.py ${KLIPPER_CONFIG} -I ${KLIPPER_PRINTER} -l ${KLIPPER_LOG} -a ${KLIPPER_SOCKET}
WorkingDirectory=/home/%USER%/klipper
EnvironmentFile=%ENV_FILE%
ExecStart=%ENV%/bin/python $KLIPPER_ARGS
Restart=always
RestartSec=10

95
resources/mainsail Normal file
View File

@@ -0,0 +1,95 @@
# /etc/nginx/sites-available/mainsail
server {
listen 80;
access_log /var/log/nginx/mainsail-access.log;
error_log /var/log/nginx/mainsail-error.log;
# disable this section on smaller hardware like a pi zero
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_proxied expired no-cache no-store private auth;
gzip_comp_level 4;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/x-javascript application/json application/xml;
# web_path from mainsail static files
root /home/pi/mainsail;
index index.html;
server_name _;
# disable max upload size checks
client_max_body_size 0;
# disable proxy request buffering
proxy_request_buffering off;
location / {
try_files $uri $uri/ /index.html;
}
location = /index.html {
add_header Cache-Control "no-store, no-cache, must-revalidate";
}
location /websocket {
proxy_pass http://apiserver/websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 86400;
}
location ~ ^/(printer|api|access|machine|server)/ {
proxy_pass http://apiserver$request_uri;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $http_host;
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;
}
location /webcam/ {
postpone_output 0;
proxy_buffering off;
proxy_ignore_headers X-Accel-Buffering;
access_log off;
error_log off;
proxy_pass http://mjpgstreamer1/;
}
location /webcam2/ {
postpone_output 0;
proxy_buffering off;
proxy_ignore_headers X-Accel-Buffering;
access_log off;
error_log off;
proxy_pass http://mjpgstreamer2/;
}
location /webcam3/ {
postpone_output 0;
proxy_buffering off;
proxy_ignore_headers X-Accel-Buffering;
access_log off;
error_log off;
proxy_pass http://mjpgstreamer3/;
}
location /webcam4/ {
postpone_output 0;
proxy_buffering off;
proxy_ignore_headers X-Accel-Buffering;
access_log off;
error_log off;
proxy_pass http://mjpgstreamer4/;
}
}

View File

@@ -0,0 +1,79 @@
### Windows users: To edit this file use Notepad++, VSCode, Atom or SublimeText.
### Do not use Notepad or WordPad.
### MacOSX users: If you use Textedit to edit this file make sure to use
### "plain text format" and "disable smart quotes" in "Textedit > Preferences"
### Configure which camera to use
#
# Available options are:
# - auto: tries first usb webcam, if that's not available tries raspi cam
# - usb: only tries usb webcam
# - raspi: only tries raspi cam
#
# Defaults to auto
#
#camera="auto"
### Additional options to supply to MJPG Streamer for the USB camera
#
# See https://faq.octoprint.org/mjpg-streamer-config for available options
#
# Defaults to a resolution of 640x480 px and a framerate of 10 fps
#
#camera_usb_options="-r 640x480 -f 10"
### Additional webcam devices known to cause problems with -f
#
# Apparently there a some devices out there that with the current
# mjpg_streamer release do not support the -f parameter (for specifying
# the capturing framerate) and will just refuse to output an image if it
# is supplied.
#
# The webcam daemon will detect those devices by their USB Vendor and Product
# ID and remove the -f parameter from the options provided to mjpg_streamer.
#
# By default, this is done for the following devices:
# Logitech C170 (046d:082b)
# GEMBIRD (1908:2310)
# Genius F100 (0458:708c)
# Cubeternet GL-UPC822 UVC WebCam (1e4e:0102)
#
# Using the following option it is possible to add additional devices. If
# your webcam happens to show above symptoms, try determining your cam's
# vendor and product id via lsusb, activating the line below by removing # and
# adding it, e.g. for two broken cameras "aabb:ccdd" and "aabb:eeff"
#
# additional_brokenfps_usb_devices=("aabb:ccdd" "aabb:eeff")
#
#
#additional_brokenfps_usb_devices=()
### Additional options to supply to MJPG Streamer for the RasPi Cam
#
# See https://faq.octoprint.org/mjpg-streamer-config for available options
#
# Defaults to 10fps
#
#camera_raspi_options="-fps 10"
### Configuration of camera HTTP output
#
# Usually you should NOT need to change this at all! Only touch if you
# know what you are doing and what the parameters mean.
#
# Below settings are used in the mjpg-streamer call like this:
#
# -o "output_http.so -w $camera_http_webroot $camera_http_options"
#
# Current working directory is the mjpg-streamer base directory.
#
#camera_http_webroot="./www-mainsail"
#camera_http_options="-n"
### EXPERIMENTAL
# Support for different streamer types.
#
# Available options:
# mjpeg [default] - stable MJPG-streamer
#camera_streamer=mjpeg

View File

@@ -0,0 +1,303 @@
#!/bin/bash
########################################################################
### DO NOT EDIT THIS FILE TO CHANGE THE CONFIG!!! ###
### ---------------------------------------------------------------- ###
### There is no need to edit this file for changing resolution, ###
### frame rates or any other mjpg-streamer parameters. Please edit ###
### /home/pi/klipper_config/webcam.txt instead - that's what it's ###
### there for! You can even do this with your Pi powered down by ###
### directly accessing the file when using the SD card as thumb ###
### drive in your regular computer. ###
########################################################################
MJPGSTREAMER_HOME=/home/pi/mjpg-streamer
MJPGSTREAMER_INPUT_USB="input_uvc.so"
MJPGSTREAMER_INPUT_RASPICAM="input_raspicam.so"
brokenfps_usb_devices=("046d:082b" "1908:2310" "0458:708c" "1e4e:0102" "0471:0311" "038f:6001" "046d:0804" "046d:0825" "046d:0994" "0ac8:3450")
config_dir="/home/pi/klipper_config"
echo "Starting up webcamDaemon..."
echo ""
cfg_files=()
#cfg_files+=/boot/mainsail.txt
if [[ -d ${config_dir} ]]; then
cfg_files+=( `ls ${config_dir}/webcam*.txt` )
fi
array_camera_config=()
array_camera=()
array_camera_usb_options=()
array_camera_usb_device=()
array_camera_raspi_options=()
array_camera_http_webroot=()
array_camera_http_options=()
array_additional_brokenfps_usb_devices=()
array_camera_device=()
array_assigned_device=()
echo "--- Configuration: ----------------------------"
for cfg_file in ${cfg_files[@]}; do
# init configuration - DO NOT EDIT, USE /home/pi/klipper_config/webcam*.txt INSTEAD!
camera="auto"
camera_usb_options="-r 640x480 -f 10"
camera_raspi_options="-fps 10"
camera_http_webroot="./www-mjpgstreamer"
camera_http_options="-n"
additional_brokenfps_usb_devices=()
if [[ -e ${cfg_file} ]]; then
source "$cfg_file"
fi
usb_options="$camera_usb_options"
# if webcam device is explicitly given in /home/pi/klipper_config/webcam*.txt, save the path of the device
# to a variable and remove its parameter from usb_options
extracted_device=`echo $usb_options | sed 's@.*-d \(/dev/\(video[0-9]\+\|v4l/[^ ]*\)\).*@\1@'`
if [ "$extracted_device" != "$usb_options" ]
then
# the camera options refer to a device, save it in a variable
# replace video device parameter with empty string and strip extra whitespace
usb_options=`echo $usb_options | sed 's/\-d \/dev\/\(video[0-9]\+\|v4l\/[^ ]*\)//g' | awk '$1=$1'`
else
extracted_device=""
fi
# echo configuration
echo "cfg_file: $cfg_file"
echo "camera: $camera"
echo "usb options: $camera_usb_options"
echo "raspi options: $camera_raspi_options"
echo "http options: -w $camera_http_webroot $camera_http_options"
echo ""
echo "Explicitly USB device: $extracted_device"
echo "-----------------------------------------------"
echo ""
array_camera_config+=( $cfg_file )
array_camera+=( $camera )
array_camera_usb_options+=("$usb_options")
array_camera_usb_device+=("$extracted_device")
array_camera_raspi_options+=("$camera_raspi_options")
array_camera_http_webroot+=("$camera_http_webroot")
array_camera_http_options+=("$camera_http_options")
array_camera_brokenfps_usb_devices+=("${brokenfps_usb_devices[*]} ${additional_brokenfps_usb_devices[*]}")
array_camera_device+=("")
done
# check if array contains a string
function containsString() {
local e match="$1"
shift
for e; do [[ "$e" == "$match" ]] && return 0; done
return 1
}
# cleans up when the script receives a SIGINT or SIGTERM
function cleanup() {
# make sure that all child processed die when we die
local pids=$(jobs -pr)
[ -n "$pids" ] && kill $pids
exit 0
}
# says goodbye when the script shuts down
function goodbye() {
# say goodbye
echo ""
echo "Goodbye..."
echo ""
}
# runs MJPG Streamer, using the provided input plugin + configuration
function runMjpgStreamer {
input=$1
# There are problems with 0x000137ab firmware on VL805 (Raspberry Pi 4}).
# Try to autodetect offending firmware and temporarily fix the issue
# by changing power management mode
echo "Checking for VL805 (Raspberry Pi 4)..."
if [[ -f /usr/bin/vl805 ]]; then
VL805_VERSION=$(/usr/bin/vl805)
VL805_VERSION=${VL805_VERSION#*: }
echo " - version 0x${VL805_VERSION} detected"
case "$VL805_VERSION" in
00013701)
echo " - nothing to be done. It shouldn't cause USB problems."
;;
000137ab)
echo -e " - \e[31mThis version is known to cause problems with USB cameras.\e[39m"
echo -e " You may want to downgrade to 0x0013701."
echo -e " - [FIXING] Trying the setpci -s 01:00.0 0xD4.B=0x41 hack to mitigate the"
echo -e " issue. It disables ASPM L1 on the VL805. Your board may (or may not) get"
echo -e " slightly hotter. For details see:"
echo -e " https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=244421"
setpci -s 01:00.0 0xD4.B=0x41
;;
*)
echo " - unknown firmware version. Doing nothing."
;;
esac
else
echo " - It seems that you don't have VL805 (Raspberry Pi 4)."
echo " There should be no problems with USB (a.k.a. select() timeout)"
fi
pushd $MJPGSTREAMER_HOME > /dev/null 2>&1
echo Running ./mjpg_streamer -o "output_http.so -w $camera_http_webroot $camera_http_options" -i "$input"
LD_LIBRARY_PATH=. ./mjpg_streamer -o "output_http.so -w $camera_http_webroot $camera_http_options" -i "$input" &
sleep 1 &
sleep_pid=$!
wait ${sleep_pid}
popd > /dev/null 2>&1
}
# starts up the RasPiCam
function startRaspi {
logger -s "Starting Raspberry Pi camera"
runMjpgStreamer "$MJPGSTREAMER_INPUT_RASPICAM $camera_raspi_options"
}
# starts up the USB webcam
function startUsb {
options="$usb_options"
device="video0"
# check for parameter and set the device if it is given as a parameter
input=$1
if [[ -n $input ]]; then
device=`basename "$input"`
fi
# add video device into options
options="$options -d /dev/$device"
uevent_file="/sys/class/video4linux/$device/device/uevent"
if [ -e $uevent_file ]; then
# let's see what kind of webcam we have here, fetch vid and pid...
product=`cat $uevent_file | grep PRODUCT | cut -d"=" -f2`
vid=`echo $product | cut -d"/" -f1`
pid=`echo $product | cut -d"/" -f2`
vidpid=`printf "%04x:%04x" "0x$vid" "0x$pid"`
# ... then look if it is in our list of known broken-fps-devices and if so remove
# the -f parameter from the options (if it's in there, else that's just a no-op)
for identifier in ${brokenfps_usb_devices[@]};
do
if [ "$vidpid" = "$identifier" ]; then
echo
echo "Camera model $vidpid is known to not work with -f parameter, stripping it out"
echo
options=`echo $options | sed -e "s/\(\s\+\|^\)-f\s\+[0-9]\+//g"`
fi
done
fi
logger -s "Starting USB webcam"
runMjpgStreamer "$MJPGSTREAMER_INPUT_USB $options"
}
# make sure our cleanup function gets called when we receive SIGINT, SIGTERM
trap "cleanup" SIGINT SIGTERM
# say goodbye when we EXIT
trap "goodbye" EXIT
# we need this to prevent the later calls to vcgencmd from blocking
# I have no idea why, but that's how it is...
vcgencmd version > /dev/null 2>&1
# keep mjpg streamer running if some camera is attached
while true; do
# get list of usb video devices into an array
video_devices=($(find /dev -regextype sed -regex '\/dev/video[0-9]\+' | sort -nk1.11 2> /dev/null))
# add list of raspi camera into an array
if [ "`vcgencmd get_camera`" = "supported=1 detected=1" ]; then
video_devices+=( "raspi" )
fi
echo "Found video devices:"
printf '%s\n' "${video_devices[@]}"
for scan_mode in "usb" "usb-auto" "raspi" "auto"; do
camera=$scan_mode
if [[ "usb-auto" == "$scan_mode" ]]; then
camera="usb"
fi
for ((i=0;i<${#array_camera[@]};i++)); do
if [[ -z ${array_camera_device[${i}]} ]] && [[ $camera == ${array_camera[${i}]} ]]; then
camera_config="${array_camera_config[${i}]}"
usb_options="${array_camera_usb_options[${i}]}"
camera_usb_device="${array_camera_usb_device[${i}]}"
camera_raspi_options="${array_camera_raspi_options[${i}]}"
camera_http_webroot="${array_camera_http_webroot[${i}]}"
camera_http_options="${array_camera_http_options[${i}]}"
brokenfps_usb_devices="${array_camera_brokenfps_usb_devices[${i}]}"
if [[ ${camera_usb_device} ]] && { [[ "usb" == ${scan_mode} ]] || [[ "auto" == ${scan_mode} ]]; }; then
# usb device is explicitly set in options
usb_device_path=`readlink -f ${camera_usb_device}`
if containsString "$usb_device_path" "${array_camera_device[@]}"; then
if [[ "auto" != ${scan_mode} ]]; then
array_camera_device[${i}]="alredy_in_use"
echo "config file='$camera_config':Video device already in use."
continue
fi
elif containsString "$usb_device_path" "${video_devices[@]}"; then
array_camera_device[${i}]="$usb_device_path"
# explicitly set usb device was found in video_devices array, start usb with the found device
echo "config file='$camera_config':USB device was set in options and found in devices, start MJPG-streamer with the configured USB video device: $usb_device_path"
startUsb "$usb_device_path"
continue
fi
elif [[ -z ${camera_usb_device} ]] && { [[ "usb-auto" == ${scan_mode} ]] || [[ "auto" == ${scan_mode} ]]; }; then
for video_device in "${video_devices[@]}"; do
if [[ "raspi" != "$video_device" ]]; then
if containsString "$video_device" "${array_camera_device[@]}"; then
: #already in use
else
array_camera_device[${i}]="$video_device"
# device is not set explicitly in options, start usb with first found usb camera as the device
echo "config file='$camera_config':USB device was not set in options, start MJPG-streamer with the first found video device: ${video_device}"
startUsb "${video_device}"
break
fi
fi
done
if [[ -n ${array_camera_device[${i}]} ]]; then
continue
fi
fi
if [[ "raspi" == ${scan_mode} ]] || [[ "auto" == ${scan_mode} ]]; then
video_device="raspi"
if containsString "$video_device" "${array_camera_device[@]}"; then
if [[ "auto" != ${scan_mode} ]]; then
array_camera_device[${i}]="alredy_in_use"
echo "config file='$camera_config':RasPiCam device already in use."
fi
elif containsString "$video_device" "${video_devices[@]}"; then
array_camera_device[${i}]="$video_device"
echo "config file='$camera_config':Start MJPG-streamer with video device: ${video_device}"
startRaspi
sleep 30 &
sleep_pid=$!
wait ${sleep_pid}
fi
fi
fi
done
done
array_assigned_device=( ${array_camera_device[*]} )
if [[ ${#array_camera[@]} -eq ${#array_assigned_device[@]} ]]; then
echo "Done bring up all configured video device"
exit 0
else
echo "Scan again in two minutes"
sleep 120 &
sleep_pid=$!
wait ${sleep_pid}
fi
done

View File

@@ -1,7 +1,6 @@
[server]
host: 0.0.0.0
port: %PORT%
enable_debug_logging: False
klippy_uds_address: %UDS%
[authorization]
@@ -22,13 +21,6 @@ cors_domains:
https://app.fluidd.xyz
http://app.fluidd.xyz
[database]
database_path: %DB%
[file_manager]
config_path: %CFG%
log_path: %LOG%
[octoprint_compat]
[history]

1
resources/moonraker.env Normal file
View File

@@ -0,0 +1 @@
MOONRAKER_ARGS="/home/%USER%/moonraker/moonraker/moonraker.py -d %PRINTER_DATA%"

View File

@@ -1,20 +1,19 @@
#Systemd Moonraker Service
[Unit]
Description=Systemd Moonraker Service for instance moonraker-%INST%
Description=API Server for Klipper SV1 %INST%
Documentation=https://moonraker.readthedocs.io/
After=network.target
Requires=network-online.target
After=network-online.target
[Install]
WantedBy=multi-user.target
[Service]
Environment=MOONRAKER_CONF=%CFG%
Environment=MOONRAKER_LOG=%LOG%
Type=simple
SupplementaryGroups=moonraker-admin
User=%USER%
SupplementaryGroups=moonraker-admin
RemainAfterExit=yes
ExecStart=%ENV%/bin/python %DIR%/moonraker/moonraker.py -c ${MOONRAKER_CONF} -l ${MOONRAKER_LOG}
WorkingDirectory=/home/%USER%/moonraker
EnvironmentFile=%ENV_FILE%
ExecStart=%ENV%/bin/python $MOONRAKER_ARGS
Restart=always
RestartSec=10

View File

@@ -102,7 +102,7 @@ function print_detected_mcu_to_screen() {
local i=1
if (( ${#mcu_list[@]} < 1 )); then
print_error "No MCU found!\n MCU eihter not connected or not detected!"
print_error "No MCU found!\n MCU either not connected or not detected!"
return
fi
@@ -121,7 +121,7 @@ function select_mcu_id() {
local i=0 sel_index=0 method=${1}
if (( ${#mcu_list[@]} < 1 )); then
print_error "No MCU found!\n MCU eihter not connected or not detected!"
print_error "No MCU found!\n MCU either not connected or not detected!"
return
fi

View File

@@ -39,29 +39,29 @@ 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 MJGP-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
# ### 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
@@ -83,7 +83,7 @@ function install_fluidd() {
patch_fluidd_update_manager
### install mjpg-streamer
[[ ${install_mjpg_streamer} == "true" ]] && install_mjpg-streamer
# [[ ${install_mjpg_streamer} == "true" ]] && install_mjpg-streamer
fetch_webui_ports #WIP
@@ -124,9 +124,11 @@ function install_fluidd_macros() {
}
function download_fluidd_macros() {
local fluidd_cfg="https://raw.githubusercontent.com/fluidd-core/FluiddPI/master/src/modules/fluidd/filesystem/home/pi/klipper_config/fluidd.cfg"
local configs path
configs=$(find "${KLIPPER_CONFIG}" -type f -name "printer.cfg" | sort)
local fluidd_cfg path configs regex
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"
configs=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${configs} ]]; then
for config in ${configs}; do
@@ -214,8 +216,23 @@ function remove_fluidd_logs() {
}
function remove_fluidd_log_symlinks() {
local files regex
regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/logs\/fluidd-.*"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${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_legacy_fluidd_log_symlinks() {
local files
files=$(find "${KLIPPER_LOGS}" -name "fluidd*" 2> /dev/null | sort)
files=$(find "${HOME}/klipper_logs" -name "fluidd*" 2> /dev/null | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
@@ -231,6 +248,7 @@ function remove_fluidd() {
remove_fluidd_config
remove_fluidd_logs
remove_fluidd_log_symlinks
remove_legacy_fluidd_log_symlinks
### remove fluidd_port from ~/.kiauh.ini
sed -i "/^fluidd_port=/d" "${INI_FILE}"
@@ -292,20 +310,18 @@ function get_remote_fluidd_version() {
}
function compare_fluidd_versions() {
unset FLUIDD_UPDATE_AVAIL
local versions local_ver remote_ver
local_ver="$(get_local_fluidd_version)"
remote_ver="$(get_remote_fluidd_version)"
if [[ ${local_ver} != "${remote_ver}" ]]; then
if [[ ${local_ver} != "${remote_ver}" && ${local_ver} != "" ]]; then
versions="${yellow}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
# add fluidd to the update all array for the update all function in the updater
FLUIDD_UPDATE_AVAIL="true" && update_arr+=(update_fluidd)
# add moonraker to application_updates_available in kiauh.ini
add_to_application_updates "fluidd"
else
versions="${green}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
FLUIDD_UPDATE_AVAIL="false"
fi
echo "${versions}"
@@ -351,7 +367,7 @@ function fluidd_port_check() {
select_fluidd_port
fi
else
DEFAULT_PORT=$(grep listen "${KIAUH_SRCDIR}/resources/klipper_webui_nginx.cfg" | head -1 | sed 's/^\s*//' | cut -d" " -f2 | cut -d";" -f1)
DEFAULT_PORT=$(grep listen "${KIAUH_SRCDIR}/resources/fluidd" | head -1 | sed 's/^\s*//' | cut -d" " -f2 | cut -d";" -f1)
SET_LISTEN_PORT=${DEFAULT_PORT}
fi
SET_NGINX_CFG="true"
@@ -397,9 +413,11 @@ function select_fluidd_port() {
}
function patch_fluidd_update_manager() {
local moonraker_configs
moonraker_configs=$(find "${KLIPPER_CONFIG}" -type f -name "moonraker.conf" | sort)
local patched moonraker_configs regex
regex="\/home\/${USER}\/([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
### add new line to conf if it doesn't end with one
@@ -417,5 +435,11 @@ path: ~/fluidd
MOONRAKER_CONF
fi
patched="true"
done
}
if [[ ${patched} == "true" ]]; then
do_action_service "restart" "moonraker"
fi
}

View File

@@ -105,10 +105,11 @@ function create_example_shell_command() {
### create a backup of the config folder
backup_klipper_config_dir
local printer_cfgs path
printer_cfgs=$(find "$(get_klipper_cfg_dir)" -type f -name "printer.cfg" | sort)
local configs regex path
regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/config\/printer\.cfg"
configs=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
for cfg in ${printer_cfgs}; do
for cfg in ${configs}; do
path=$(echo "${cfg}" | rev | cut -d"/" -f2- | rev)
if [[ ! -f "${path}/shell_command.cfg" ]]; then

View File

@@ -34,8 +34,6 @@ function set_globals() {
KLIPPY_ENV="${HOME}/klippy-env"
KLIPPER_DIR="${HOME}/klipper"
KLIPPER_REPO="https://github.com/Klipper3d/klipper.git"
KLIPPER_LOGS="${HOME}/klipper_logs"
KLIPPER_CONFIG="$(get_klipper_cfg_dir)" # default: ${HOME}/klipper_config
#================= MOONRAKER ==================#
MOONRAKER_ENV="${HOME}/moonraker-env"
@@ -70,4 +68,8 @@ function set_globals() {
NGINX_SA="/etc/nginx/sites-available"
NGINX_SE="/etc/nginx/sites-enabled"
NGINX_CONFD="/etc/nginx/conf.d"
}
#=============== MOONRAKER-OBICO ================#
MOONRAKER_OBICO_DIR="${HOME}/moonraker-obico"
MOONRAKER_OBICO_REPO="https://github.com/TheSpaghettiDetective/moonraker-obico.git"
}

View File

@@ -15,46 +15,35 @@ set -e
#================ INSTALL KLIPPER ================#
#=================================================#
### check for existing klipper service installations
function klipper_initd() {
local services
services=$(find "${INITD}" -maxdepth 1 -regextype posix-extended -regex "${INITD}/klipper(-[^0])?[0-9]*" | sort)
echo "${services}"
}
function klipper_systemd() {
local services
services=$(find "${SYSTEMD}" -maxdepth 1 -regextype posix-extended -regex "${SYSTEMD}/klipper(-[0-9a-zA-Z]+)?.service" | sort)
echo "${services}"
}
function klipper_exists() {
local services
[[ -n $(klipper_initd) ]] && services+="$(klipper_initd) "
[[ -n $(klipper_systemd) ]] && services+="$(klipper_systemd)"
echo "${services}"
}
function klipper_setup_dialog() {
status_msg "Initializing Klipper installation ..."
local klipper_services
local klipper_initd_service
local klipper_systemd_services
local python_version="${1}" user_input=()
klipper_services=$(klipper_exists)
local error
klipper_initd_service=$(find_klipper_initd)
klipper_systemd_services=$(find_klipper_systemd)
user_input+=("${python_version}")
### return early if klipper already exists
if [[ -n ${klipper_services} ]]; then
local error="At least one Klipper service is already installed:"
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:"
for s in ${klipper_services}; do
for s in ${klipper_systemd_services}; do
log_info "Found Klipper service: ${s}"
error="${error}\n ➔ ${s}"
done
print_error "${error}" && return
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 |"
@@ -148,42 +137,63 @@ function klipper_setup_dialog() {
klipper_setup "${user_input[@]}"
}
function install_klipper_packages() {
local packages python_version="${1}"
local install_script="${KLIPPER_DIR}/scripts/install-debian.sh"
function 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)
status_msg "Reading dependencies..."
# shellcheck disable=SC2016
packages=$(grep "PKGLIST=" "${install_script}" | cut -d'"' -f2 | sed 's/\${PKGLIST}//g' | tr -d '\n')
### add dfu-util for octopi-images
packages+=" dfu-util"
### add dbus requirement for DietPi distro
[[ -e "/boot/dietpi/.version" ]] && packages+=" dbus"
### checking dependencies
dependency_check "${dep[@]}"
if [[ ${python_version} == "python3" ]]; then
### replace python-dev with python3-dev if python3 was selected
packages="${packages//python-dev/python3-dev}"
### 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 3: configure and create klipper instances
configure_klipper_service "${instance_arr[@]}"
### step 4: enable and start all instances
do_action_service "enable" "klipper"
do_action_service "start" "klipper"
### step 5: check for dialout group membership
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!"
print_confirm "${confirm}" && return
}
function clone_klipper() {
local repo=${1} branch=${2}
[[ -z ${repo} ]] && repo="${KLIPPER_REPO}"
repo=$(echo "${repo}" | sed -r "s/^(http|https):\/\/github\.com\///i; s/\.git$//")
repo="https://github.com/${repo}"
[[ -z ${branch} ]] && branch="master"
### force remove existing klipper dir and clone into fresh klipper dir
[[ -d ${KLIPPER_DIR} ]] && rm -rf "${KLIPPER_DIR}"
status_msg "Cloning Klipper from ${repo} ..."
cd "${HOME}" || exit 1
if git clone "${repo}" "${KLIPPER_DIR}"; then
cd "${KLIPPER_DIR}" && git checkout "${branch}"
else
### package name 'python-dev' is deprecated (-> no installation candidate) on more modern linux distros
packages="${packages//python-dev/python2-dev}"
fi
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 klipper packages"
error_msg "Installing required packages failed!"
print_error "Cloning Klipper from\n ${repo}\n failed!"
exit 1
fi
}
@@ -224,88 +234,134 @@ function create_klipper_virtualenv() {
return
}
function 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}"
### checking dependencies
local dep=(git)
dependency_check "${dep[@]}"
###
# extracts the required packages from the
# install-debian.sh script and installs them
#
# @param {string}: python_version - klipper-env python version
#
function install_klipper_packages() {
local packages python_version="${1}"
local install_script="${KLIPPER_DIR}/scripts/install-debian.sh"
### step 1: clone klipper
clone_klipper "${custom_repo}" "${custom_branch}"
status_msg "Reading dependencies..."
# shellcheck disable=SC2016
packages=$(grep "PKGLIST=" "${install_script}" | cut -d'"' -f2 | sed 's/\${PKGLIST}//g' | tr -d '\n')
### add dfu-util for octopi-images
packages+=" dfu-util"
### add dbus requirement for DietPi distro
[[ -e "/boot/dietpi/.version" ]] && packages+=" dbus"
### step 2: install klipper dependencies and create python virtualenv
install_klipper_packages "${python_version}"
create_klipper_virtualenv "${python_version}"
### step 3: create gcode_files and logs folder
[[ ! -d "${HOME}/gcode_files" ]] && mkdir -p "${HOME}/gcode_files"
[[ ! -d ${KLIPPER_LOGS} ]] && mkdir -p "${KLIPPER_LOGS}"
### step 4: create klipper instances
create_klipper_service "${instance_arr[@]}"
### step 5: enable and start all instances
do_action_service "enable" "klipper"
do_action_service "start" "klipper"
### step 6: check for dialout group membership
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!"
print_confirm "${confirm}" && return
}
function clone_klipper() {
local repo=${1} branch=${2}
[[ -z ${repo} ]] && repo="${KLIPPER_REPO}"
repo=$(echo "${repo}" | sed -r "s/^(http|https):\/\/github\.com\///i; s/\.git$//")
repo="https://github.com/${repo}"
[[ -z ${branch} ]] && branch="master"
### force remove existing klipper dir and clone into fresh klipper dir
[[ -d ${KLIPPER_DIR} ]] && rm -rf "${KLIPPER_DIR}"
status_msg "Cloning Klipper from ${repo} ..."
cd "${HOME}" || exit 1
if git clone "${repo}" "${KLIPPER_DIR}"; then
cd "${KLIPPER_DIR}" && git checkout "${branch}"
if [[ ${python_version} == "python3" ]]; then
### replace python-dev with python3-dev if python3 was selected
packages="${packages//python-dev/python3-dev}"
elif [[ ${python_version} == "python2" ]]; then
### package name 'python-dev' is deprecated (-> no installation candidate) on more modern linux distros
packages="${packages//python-dev/python2-dev}"
else
print_error "Cloning Klipper from\n ${repo}\n failed!"
log_error "Internal Error: missing parameter 'python_version' during function call of ${FUNCNAME[0]}"
error_msg "Internal Error: missing parameter 'python_version' during function call of ${FUNCNAME[0]}"
exit 1
fi
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 klipper packages"
error_msg "Installing required packages failed!"
exit 1
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
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"
### 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
else
return 1
fi
}
function write_klipper_service() {
local i=${1} cfg=${2} log=${3} printer=${4} uds=${5} service=${6}
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"
### replace all placeholders
if [[ ! -f ${service} ]]; then
status_msg "Creating Klipper Service ${i} ..."
sudo cp "${service_template}" "${service}"
[[ -z ${i} ]] && sudo sed -i "s| for instance klipper-%INST%||" "${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}|; s|%ENV%|${KLIPPY_ENV}|; s|%DIR%|${KLIPPER_DIR}|" "${service}"
sudo sed -i "s|%LOG%|${log}|; s|%CFG%|${cfg}|; s|%PRINTER%|${printer}|; s|%UDS%|${uds}|" "${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}"
fi
}
function write_example_printer_cfg() {
local cfg_dir=${1} cfg=${2}
local cfg_template="${KIAUH_SRCDIR}/resources/printer.cfg"
local cfg_template="${KIAUH_SRCDIR}/resources/example.printer.cfg"
### create a config directory if it doesn't exist
if [[ ! -d ${cfg_dir} ]]; then
@@ -320,52 +376,6 @@ function write_example_printer_cfg() {
fi
}
function create_klipper_service() {
local input=("${@}")
local klipper_count=${input[0]} && unset "input[0]"
local names=("${input[@]}") && unset "input[@]"
local cfg_dir cfg log printer uds service
if (( klipper_count == 1 )) && [[ ${#names[@]} -eq 0 ]]; then
cfg_dir="${KLIPPER_CONFIG}"
cfg="${cfg_dir}/printer.cfg"
log="${KLIPPER_LOGS}/klippy.log"
printer="/tmp/printer"
uds="/tmp/klippy_uds"
service="${SYSTEMD}/klipper.service"
### write single instance service
write_klipper_service "" "${cfg}" "${log}" "${printer}" "${uds}" "${service}"
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
cfg_dir="${KLIPPER_CONFIG}/printer_${names[${j}]}"
else
cfg_dir="${KLIPPER_CONFIG}/${names[${j}]}"
fi
cfg="${cfg_dir}/printer.cfg"
log="${KLIPPER_LOGS}/klippy-${names[${j}]}.log"
printer="/tmp/printer-${names[${j}]}"
uds="/tmp/klippy_uds-${names[${j}]}"
service="${SYSTEMD}/klipper-${names[${j}]}.service"
### write multi instance service
write_klipper_service "${names[${j}]}" "${cfg}" "${log}" "${printer}" "${uds}" "${service}"
write_example_printer_cfg "${cfg_dir}" "${cfg}"
ok_msg "Klipper instance 'klipper-${names[${j}]}' created!"
j=$(( j + 1 ))
done && unset j
else
return 1
fi
}
#================================================#
#================ REMOVE KLIPPER ================#
#================================================#
@@ -381,10 +391,10 @@ function remove_klipper_sysvinit() {
}
function remove_klipper_systemd() {
[[ -z $(klipper_systemd) ]] && return
[[ -z $(find_klipper_systemd) ]] && return
status_msg "Removing Klipper Systemd Services ..."
for service in $(klipper_systemd | cut -d"/" -f5); do
for service in $(find_klipper_systemd | cut -d"/" -f5); do
status_msg "Removing ${service} ..."
sudo systemctl stop "${service}"
sudo systemctl disable "${service}"
@@ -398,9 +408,35 @@ function remove_klipper_systemd() {
ok_msg "Klipper Service 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 "${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
@@ -412,8 +448,8 @@ function remove_klipper_logs() {
}
function remove_klipper_uds() {
local files
files=$(find /tmp -maxdepth 1 -regextype posix-extended -regex "/tmp/klippy_uds(-[0-9a-zA-Z]+)?" | sort)
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
@@ -425,9 +461,22 @@ function remove_klipper_uds() {
}
function remove_klipper_printer() {
local files
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() {
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} ..."
@@ -456,9 +505,12 @@ function remove_klipper_env() {
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
@@ -470,21 +522,30 @@ function remove_klipper() {
#================ UPDATE KLIPPER ================#
#================================================#
###
# stops klipper, performs a git pull, installs
# possible new dependencies, then restarts klipper
#
function update_klipper() {
read_kiauh_ini "${FUNCNAME[0]}"
local py_ver
local custom_repo="${custom_klipper_repo}"
local custom_branch="${custom_klipper_repo_branch}"
py_ver="python$(get_klipper_python_ver)"
do_action_service "stop" "klipper"
if [[ ! -d ${KLIPPER_DIR} ]]; then
clone_klipper "${custom_repo}" "${custom_branch}"
else
backup_before_update "klipper"
status_msg "Updating Klipper ..."
cd "${KLIPPER_DIR}" && git pull
### read PKGLIST and install possible new dependencies
install_klipper_packages
install_klipper_packages "${py_ver}"
### install possible new python dependencies
"${KLIPPY_ENV}"/bin/pip install -r "${KLIPPER_DIR}/scripts/klippy-requirements.txt"
fi
@@ -499,11 +560,11 @@ function update_klipper() {
function get_klipper_status() {
local sf_count status py_ver
sf_count="$(klipper_systemd | wc -w)"
sf_count="$(find_klipper_systemd | wc -w)"
### detect an existing "legacy" klipper init.d installation
if [[ $(klipper_systemd | wc -w) -eq 0 ]] \
&& [[ $(klipper_initd | wc -w) -ge 1 ]]; then
if [[ $(find_klipper_systemd | wc -w) -eq 0 ]] \
&& [[ $(find_klipper_initd | wc -w) -ge 1 ]]; then
sf_count=1
fi
@@ -553,7 +614,6 @@ function get_remote_klipper_commit() {
}
function compare_klipper_versions() {
unset KLIPPER_UPDATE_AVAIL
local versions local_ver remote_ver
local_ver="$(get_local_klipper_commit)"
remote_ver="$(get_remote_klipper_commit)"
@@ -561,12 +621,11 @@ function compare_klipper_versions() {
if [[ ${local_ver} != "${remote_ver}" ]]; then
versions="${yellow}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
# add klipper to the update all array for the update all function in the updater
KLIPPER_UPDATE_AVAIL="true" && update_arr+=(update_klipper)
# add klipper to application_updates_available in kiauh.ini
add_to_application_updates "klipper"
else
versions="${green}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
KLIPPER_UPDATE_AVAIL="false"
fi
echo "${versions}"
@@ -576,20 +635,11 @@ function compare_klipper_versions() {
#=================== HELPERS ====================#
#================================================#
function get_klipper_cfg_dir() {
local cfg_dir
read_kiauh_ini "${FUNCNAME[0]}"
if [[ -z ${custom_klipper_cfg_loc} ]]; then
cfg_dir="${HOME}/klipper_config"
else
cfg_dir="${custom_klipper_cfg_loc}"
fi
echo "${cfg_dir}"
}
### returns the major python version the klippy-env was created with
###
# reads the python version from the klipper virtual environment
#
# @output: writes the python major version to STDOUT
#
function get_klipper_python_ver() {
[[ ! -d ${KLIPPY_ENV} ]] && return

View File

@@ -180,7 +180,6 @@ function get_remote_klipperscreen_commit() {
}
function compare_klipperscreen_versions() {
unset KLIPPERSCREEN_UPDATE_AVAIL
local versions local_ver remote_ver
local_ver="$(get_local_klipperscreen_commit)"
remote_ver="$(get_remote_klipperscreen_commit)"
@@ -188,12 +187,11 @@ function compare_klipperscreen_versions() {
if [[ ${local_ver} != "${remote_ver}" ]]; then
versions="${yellow}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
# add klipperscreen to the update all array for the update all function in the updater
KLIPPERSCREEN_UPDATE_AVAIL="true" && update_arr+=(update_klipperscreen)
# add moonraker to application_updates_available in kiauh.ini
add_to_application_updates "klipperscreen"
else
versions="${green}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
KLIPPERSCREEN_UPDATE_AVAIL="false"
fi
echo "${versions}"
@@ -204,6 +202,7 @@ function compare_klipperscreen_versions() {
#================================================#
function patch_klipperscreen_update_manager() {
local patched="false"
local moonraker_configs
moonraker_configs=$(find "${KLIPPER_CONFIG}" -type f -name "moonraker.conf" | sort)
@@ -226,5 +225,11 @@ install_script: scripts/KlipperScreen-install.sh
MOONRAKER_CONF
fi
patched="true"
done
if [[ ${patched} == "true" ]]; then
do_action_service "restart" "moonraker"
fi
}

View File

@@ -39,29 +39,29 @@ 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 MJGP-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
# ### 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
@@ -83,7 +83,7 @@ function install_mainsail() {
patch_mainsail_update_manager
### install mjpg-streamer
[[ ${install_mjpg_streamer} == "true" ]] && install_mjpg-streamer
# [[ ${install_mjpg_streamer} == "true" ]] && install_mjpg-streamer
fetch_webui_ports #WIP
@@ -124,9 +124,11 @@ function install_mainsail_macros() {
}
function download_mainsail_macros() {
local ms_cfg="https://raw.githubusercontent.com/mainsail-crew/MainsailOS/master/src/modules/mainsail/filesystem/home/pi/klipper_config/mainsail.cfg"
local configs path
configs=$(find "${KLIPPER_CONFIG}" -type f -name "printer.cfg" | sort)
local ms_cfg path configs regex
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"
configs=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${configs} ]]; then
for config in ${configs}; do
@@ -219,8 +221,23 @@ function remove_mainsail_logs() {
}
function remove_mainsail_log_symlinks() {
local files regex
regex="\/home\/${USER}\/([A-Za-z0-9_]+)\/logs\/mainsail-.*"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${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_legacy_mainsail_log_symlinks() {
local files
files=$(find "${KLIPPER_LOGS}" -name "mainsail*" 2> /dev/null | sort)
files=$(find "${HOME}/klipper_logs" -name "mainsail*" 2> /dev/null | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
@@ -236,6 +253,7 @@ function remove_mainsail() {
remove_mainsail_config
remove_mainsail_logs
remove_mainsail_log_symlinks
remove_legacy_mainsail_log_symlinks
### remove mainsail_port from ~/.kiauh.ini
sed -i "/^mainsail_port=/d" "${INI_FILE}"
@@ -297,20 +315,18 @@ function get_remote_mainsail_version() {
}
function compare_mainsail_versions() {
unset MAINSAIL_UPDATE_AVAIL
local versions local_ver remote_ver
local_ver="$(get_local_mainsail_version)"
remote_ver="$(get_remote_mainsail_version)"
if [[ ${local_ver} != "${remote_ver}" ]]; then
if [[ ${local_ver} != "${remote_ver}" && ${local_ver} != "" ]]; then
versions="${yellow}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
# add mainsail to the update all array for the update all function in the updater
MAINSAIL_UPDATE_AVAIL="true" && update_arr+=(update_mainsail)
# add moonraker to application_updates_available in kiauh.ini
add_to_application_updates "mainsail"
else
versions="${green}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
MAINSAIL_UPDATE_AVAIL="false"
fi
echo "${versions}"
@@ -379,23 +395,41 @@ function ms_theme_installer_menu() {
}
function ms_theme_install() {
local theme_url=${1} theme_name theme_note
theme_name=${2} theme_note=${3}
read_kiauh_ini "${FUNCNAME[0]}"
local config_folders target_folders=()
config_folders=$(find "${KLIPPER_CONFIG}" -mindepth 1 -maxdepth 1 -type d | sort)
local theme_url
local theme_name
local theme_note
theme_url=${1}
theme_name=${2}
theme_note=${3}
### build target folder array
for folder in ${config_folders}; do
target_folders+=("${folder}")
done
local folder_arr
local folder_names="${multi_instance_names}"
local target_folders=()
IFS=',' read -r -a folder_arr <<< "${folder_names}"
### build theme target folder array
if (( ${#folder_arr[@]} > 1 )); then
for folder in "${folder_arr[@]}"; do
### instance names/identifier of only numbers need to be prefixed with 'printer_'
if [[ ${folder} =~ ^[0-9]+$ ]]; then
target_folders+=("${HOME}/printer_${folder}_data/config")
else
target_folders+=("${HOME}/${folder}_data/config")
fi
done
else
target_folders+=("${HOME}/printer_data/config")
fi
if (( ${#target_folders[@]} > 1 )); then
top_border
echo -e "| Please select the printer you want to apply the theme |"
echo -e "| installation to: |"
for (( i=0; i < ${#target_folders[@]}; i++ )); do
folder=$(echo "${target_folders[${i}]}" | rev | cut -d "/" -f1 | rev)
folder=$(echo "${target_folders[${i}]}" | rev | cut -d "/" -f2 | cut -d"_" -f2- | rev)
printf "|${cyan}%-55s${white}|\n" " ${i}) ${folder}"
done
bottom_border
@@ -424,15 +458,21 @@ function ms_theme_install() {
}
function ms_theme_delete() {
local theme_folders target_folders=()
theme_folders=$(find "${KLIPPER_CONFIG}" -mindepth 1 -type d -name ".theme" | sort)
local regex theme_folders target_folders=()
regex="\/home\/${USER}\/([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)
### build target folder array
for folder in ${theme_folders}; do
target_folders+=("${folder}")
done
if (( ${#target_folders[@]} > 0 )); then
if (( ${#target_folders[@]} == 0 )); then
status_msg "No Themes installed!\n"
return
elif (( ${#target_folders[@]} > 1 )); then
top_border
echo -e "| Please select the printer you want to remove the |"
echo -e "| theme installation from. |"
@@ -449,9 +489,6 @@ function ms_theme_delete() {
[[ ${target} =~ ${re} && ${target} -lt ${#target_folders[@]} ]] && break
error_msg "Invalid command!"
done
else
status_msg "No Themes installed!\n"
return
fi
status_msg "Removing ${target_folders[${target}]} ..."
@@ -500,7 +537,7 @@ function mainsail_port_check() {
select_mainsail_port
fi
else
DEFAULT_PORT=$(grep listen "${KIAUH_SRCDIR}/resources/klipper_webui_nginx.cfg" | head -1 | sed 's/^\s*//' | cut -d" " -f2 | cut -d";" -f1)
DEFAULT_PORT=$(grep listen "${KIAUH_SRCDIR}/resources/mainsail" | head -1 | sed 's/^\s*//' | cut -d" " -f2 | cut -d";" -f1)
SET_LISTEN_PORT=${DEFAULT_PORT}
fi
SET_NGINX_CFG="true"
@@ -548,14 +585,17 @@ function select_mainsail_port() {
function enable_mainsail_remotemode() {
[[ ! -f "${MAINSAIL_DIR}/config.json" ]] && return
rm -f "${MAINSAIL_DIR}/config.json"
echo -e "{\n \"remoteMode\":true\n}" >> "${MAINSAIL_DIR}/config.json"
status_msg "Setting instance storage location to 'browser' ..."
sed -i 's|"instancesDB": "moonraker"|"instancesDB": "browser"|' "${MAINSAIL_DIR}/config.json"
ok_msg "Done!"
}
function patch_mainsail_update_manager() {
local moonraker_configs
moonraker_configs=$(find "${KLIPPER_CONFIG}" -type f -name "moonraker.conf" | sort)
local patched moonraker_configs regex
regex="\/home\/${USER}\/([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
### add new line to conf if it doesn't end with one
@@ -573,5 +613,11 @@ path: ~/mainsail
MOONRAKER_CONF
fi
patched="true"
done
}
if [[ ${patched} == "true" ]]; then
do_action_service "restart" "moonraker"
fi
}

View File

@@ -16,10 +16,10 @@ set -e
#=================================================#
function install_mjpg-streamer() {
local webcamd="https://raw.githubusercontent.com/mainsail-crew/MainsailOS/master/src/modules/mjpgstreamer/filesystem/root/usr/local/bin/webcamd"
local webcam_txt="https://raw.githubusercontent.com/mainsail-crew/MainsailOS/master/src/modules/mjpgstreamer/filesystem/home/pi/klipper_config/webcam.txt"
local webcamd="${KIAUH_SRCDIR}/resources/mjpg-streamer/webcamd"
local webcam_txt="${KIAUH_SRCDIR}/resources/mjpg-streamer/webcam.txt"
local service="${KIAUH_SRCDIR}/resources/mjpg-streamer/webcamd.service"
local repo="https://github.com/jacksonliam/mjpg-streamer.git"
local service="${KIAUH_SRCDIR}/resources/webcamd.service"
### return early if webcamd.service already exists
if [[ -f "${SYSTEMD}/webcamd.service" ]]; then
@@ -77,7 +77,7 @@ function install_mjpg-streamer() {
</html>
EOT
sudo wget "${webcamd}" -O "/usr/local/bin/webcamd"
sudo cp "${webcamd}" "/usr/local/bin/webcamd"
sudo sed -i "/^config_dir=/ s|=.*|=${KLIPPER_CONFIG}|" /usr/local/bin/webcamd
sudo sed -i "/MJPGSTREAMER_HOME/ s/pi/${USER}/" /usr/local/bin/webcamd
sudo chmod +x /usr/local/bin/webcamd
@@ -86,7 +86,7 @@ EOT
[[ ! -d ${KLIPPER_CONFIG} ]] && mkdir -p "${KLIPPER_CONFIG}"
if [[ ! -f "${KLIPPER_CONFIG}/webcam.txt" ]]; then
status_msg "Creating webcam.txt config file ..."
wget "${webcam_txt}" -O "${KLIPPER_CONFIG}/webcam.txt"
cp "${webcam_txt}" "${KLIPPER_CONFIG}/webcam.txt"
ok_msg "Done!"
fi

View File

@@ -436,7 +436,6 @@ function get_remote_telegram_bot_commit() {
}
function compare_telegram_bot_versions() {
unset MOONRAKER_TELEGRAM_BOT_UPDATE_AVAIL
local versions local_ver remote_ver
local_ver="$(get_local_telegram_bot_commit)"
remote_ver="$(get_remote_telegram_bot_commit)"
@@ -444,12 +443,11 @@ function compare_telegram_bot_versions() {
if [[ ${local_ver} != "${remote_ver}" ]]; then
versions="${yellow}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
# add moonraker-telegram-bot to the update all array for the update all function in the updater
MOONRAKER_TELEGRAM_BOT_UPDATE_AVAIL="true" && update_arr+=(update_telegram_bot)
# add moonraker to application_updates_available in kiauh.ini
add_to_application_updates "telegram_bot"
else
versions="${green}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
MOONRAKER_TELEGRAM_BOT_UPDATE_AVAIL="false"
fi
echo "${versions}"
@@ -460,6 +458,7 @@ 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)
@@ -482,5 +481,11 @@ install_script: scripts/install.sh
MOONRAKER_CONF
fi
patched="true"
done
if [[ ${patched} == "true" ]]; then
do_action_service "restart" "moonraker"
fi
}

View File

@@ -15,9 +15,24 @@ set -e
#================ INSTALL MOONRAKER ================#
#===================================================#
###
# this function detects all installed moonraker
# systemd instances and returns their absolute path
function moonraker_systemd() {
local services
services=$(find "${SYSTEMD}" -maxdepth 1 -regextype posix-extended -regex "${SYSTEMD}/moonraker(-[0-9a-zA-Z]+)?.service" | sort)
local blacklist
local ignore
local match
###
# any moonraker client that uses "moonraker" in its own name must be blacklisted using
# this variable, otherwise they will be falsely recognized as moonraker instances
blacklist="obico"
ignore="${SYSTEMD}/moonraker-(${blacklist}).service"
match="${SYSTEMD}/moonraker(-[0-9a-zA-Z]+)?.service"
services=$(find "${SYSTEMD}" -maxdepth 1 -regextype awk ! -regex "${ignore}" -regex "${match}" | sort)
echo "${services}"
}
@@ -45,7 +60,7 @@ function moonraker_setup_dialog() {
### return early if klipper is not installed
local klipper_services
klipper_services=$(klipper_systemd)
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."
@@ -190,10 +205,10 @@ function moonraker_setup() {
create_moonraker_conf "${instance_arr[@]}"
### step 4: create moonraker instances
create_moonraker_service "${instance_arr[@]}"
configure_moonraker_service "${instance_arr[@]}"
### step 5: create polkit rules for moonraker
moonraker_polkit || true
install_moonraker_polkit || true
### step 6: enable and start all instances
do_action_service "enable" "moonraker"
@@ -225,18 +240,19 @@ function create_moonraker_conf() {
local input=("${@}")
local moonraker_count=${input[0]} && unset "input[0]"
local names=("${input[@]}") && unset "input[@]"
local log="${KLIPPER_LOGS}"
local lan
local port lan printer_data cfg_dir cfg uds
port=7125
lan="$(hostname -I | cut -d" " -f1 | cut -d"." -f1-2).0.0/16"
local port=7125 cfg_dir cfg db uds
if (( moonraker_count == 1 )); then
cfg_dir="${KLIPPER_CONFIG}"
printer_data="${HOME}/printer_data"
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/moonraker.conf"
db="${HOME}/.moonraker_database"
uds="/tmp/klippy_uds"
uds="${printer_data}/comms/klippy.sock"
### write single instance config
write_moonraker_conf "${cfg_dir}" "${cfg}" "${port}" "${log}" "${db}" "${uds}" "${lan}"
write_moonraker_conf "${cfg_dir}" "${cfg}" "${port}" "${uds}" "${lan}"
elif (( moonraker_count > 1 )); then
local j=0 re="^[1-9][0-9]*$"
@@ -244,16 +260,17 @@ function create_moonraker_conf() {
for (( i=1; i <= moonraker_count; 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}/moonraker.conf"
uds="/tmp/klippy_uds-${names[${j}]}"
db="${HOME}/.moonraker_database_${names[${j}]}"
uds="${printer_data}/comms/klippy.sock"
### write multi instance config
write_moonraker_conf "${cfg_dir}" "${cfg}" "${port}" "${log}" "${db}" "${uds}" "${lan}"
write_moonraker_conf "${cfg_dir}" "${cfg}" "${port}" "${uds}" "${lan}"
port=$(( port + 1 ))
j=$(( j + 1 ))
done && unset j
@@ -264,7 +281,7 @@ function create_moonraker_conf() {
}
function write_moonraker_conf() {
local cfg_dir=${1} cfg=${2} port=${3} log=${4} db=${5} uds=${6} lan=${7}
local cfg_dir=${1} cfg=${2} port=${3} uds=${4} lan=${5}
local conf_template="${KIAUH_SRCDIR}/resources/moonraker.conf"
[[ ! -d ${cfg_dir} ]] && mkdir -p "${cfg_dir}"
@@ -272,8 +289,7 @@ function write_moonraker_conf() {
if [[ ! -f ${cfg} ]]; then
status_msg "Creating moonraker.conf in ${cfg_dir} ..."
cp "${conf_template}" "${cfg}"
sed -i "s|%USER%|${USER}|g" "${cfg}"
sed -i "s|%CFG%|${cfg_dir}|; s|%PORT%|${port}|; s|%LOG%|${log}|; s|%DB%|${db}|; s|%UDS%|${uds}|" "${cfg}"
sed -i "s|%USER%|${USER}|g; s|%PORT%|${port}|; s|%UDS%|${uds}|" "${cfg}"
# if host ip is not in the default ip ranges replace placeholder,
# otherwise remove placeholder from config
if ! grep -q "${lan}" "${cfg}"; then
@@ -287,20 +303,24 @@ function write_moonraker_conf() {
fi
}
function create_moonraker_service() {
function configure_moonraker_service() {
local input=("${@}")
local moonraker_count=${input[0]} && unset "input[0]"
local names=("${input[@]}") && unset "input[@]"
local cfg_dir cfg log service
local printer_data cfg_dir service env_file
if (( moonraker_count == 1 )) && [[ ${#names[@]} -eq 0 ]]; then
i=""
cfg_dir="${KLIPPER_CONFIG}"
cfg="${cfg_dir}/moonraker.conf"
log="${KLIPPER_LOGS}/moonraker.log"
printer_data="${HOME}/printer_data"
cfg_dir="${printer_data}/config"
service="${SYSTEMD}/moonraker.service"
env_file="${printer_data}/systemd/moonraker.env"
### create required folder structure
create_required_folders "${printer_data}"
### write single instance service
write_moonraker_service "" "${cfg}" "${log}" "${service}"
write_moonraker_service "" "${printer_data}" "${service}" "${env_file}"
ok_msg "Moonraker instance created!"
elif (( moonraker_count > 1 )) && [[ ${#names[@]} -gt 0 ]]; then
@@ -309,25 +329,27 @@ function create_moonraker_service() {
for (( i=1; i <= moonraker_count; 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="${cfg_dir}/moonraker.conf"
log="${KLIPPER_LOGS}/moonraker-${names[${j}]}.log"
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}]}" "${cfg}" "${log}" "${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
status_msg "Mainsail installation found! Enabling Mainsail remote mode ..."
enable_mainsail_remotemode
ok_msg "Mainsails remote mode enabled!"
fi
else
@@ -336,18 +358,20 @@ function create_moonraker_service() {
}
function write_moonraker_service() {
local i=${1} cfg=${2} log=${3} service=${4}
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"
### replace all placeholders
if [[ ! -f ${service} ]]; then
status_msg "Creating Moonraker Service ${i} ..."
sudo cp "${service_template}" "${service}"
sudo cp "${env_template}" "${env_file}"
[[ -z ${i} ]] && sudo sed -i "s| for instance moonraker-%INST%||" "${service}"
[[ -z ${i} ]] && sudo sed -i "s| %INST%||" "${service}"
[[ -n ${i} ]] && sudo sed -i "s|%INST%|${i}|" "${service}"
sudo sed -i "s|%USER%|${USER}|; s|%ENV%|${MOONRAKER_ENV}|; s|%DIR%|${MOONRAKER_DIR}|" "${service}"
sudo sed -i "s|%CFG%|${cfg}|; s|%LOG%|${log}|" "${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
}
@@ -364,8 +388,20 @@ function print_mr_ip_list() {
### introduced due to
### https://github.com/Arksine/moonraker/issues/349
### https://github.com/Arksine/moonraker/pull/346
function moonraker_polkit() {
function install_moonraker_polkit() {
local POLKIT_LEGACY_FILE="/etc/polkit-1/localauthority/50-local.d/10-moonraker.pkla"
local POLKIT_FILE="/etc/polkit-1/rules.d/moonraker.rules"
local POLKIT_USR_FILE="/usr/share/polkit-1/rules.d/moonraker.rules"
local legacy_file_exists
local file_exists
local usr_file_exists
local has_sup
local require_daemon_reload="false"
legacy_file_exists=$(sudo find "${POLKIT_LEGACY_FILE}" 2> /dev/null)
file_exists=$(sudo find "${POLKIT_FILE}" 2> /dev/null)
usr_file_exists=$(sudo find "${POLKIT_USR_FILE}" 2> /dev/null)
### check for required SupplementaryGroups entry in service files
### write it to the service if it doesn't exist
@@ -374,14 +410,25 @@ function moonraker_polkit() {
if [[ -z ${has_sup} ]]; then
status_msg "Adding moonraker-admin supplementary group to ${service} ..."
sudo sed -i "/^Type=simple$/a SupplementaryGroups=moonraker-admin" "${service}"
require_daemon_reload="true"
ok_msg "Adding moonraker-admin supplementary group successfull!"
fi
done
[[ -z ${has_sup} ]] && echo "reloading services!!!" && sudo systemctl daemon-reload
if [[ ${require_daemon_reload} == "true" ]]; then
status_msg "Reloading unit files ..."
sudo systemctl daemon-reload
ok_msg "Unit files reloaded!"
fi
### execute moonrakers policykit-rules script
"${HOME}"/moonraker/scripts/set-policykit-rules.sh
### execute moonrakers policykit-rules script only if rule files do not already exist
if [[ -z ${legacy_file_exists} && ( -z ${file_exists} || -z ${usr_file_exists} ) ]]; then
status_msg "Installing Moonraker policykit rules ..."
"${HOME}"/moonraker/scripts/set-policykit-rules.sh
ok_msg "Moonraker policykit rules installed!"
fi
return
}
#==================================================#
@@ -417,9 +464,35 @@ function remove_moonraker_systemd() {
ok_msg "Moonraker Services removed!"
}
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
}
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
}
function remove_legacy_moonraker_logs() {
local files regex="moonraker(-[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
@@ -473,7 +546,9 @@ function remove_moonraker_polkit() {
function remove_moonraker() {
remove_moonraker_sysvinit
remove_moonraker_systemd
remove_moonraker_env_file
remove_moonraker_logs
remove_legacy_moonraker_logs
remove_moonraker_api_key
remove_moonraker_polkit
remove_moonraker_dir
@@ -503,7 +578,7 @@ function update_moonraker() {
fi
### required due to https://github.com/Arksine/moonraker/issues/349
moonraker_polkit
install_moonraker_polkit || true
ok_msg "Update complete!"
do_action_service "restart" "moonraker"
@@ -557,7 +632,6 @@ function get_remote_moonraker_commit() {
}
function compare_moonraker_versions() {
unset MOONRAKER_UPDATE_AVAIL
local versions local_ver remote_ver
local_ver="$(get_local_moonraker_commit)"
remote_ver="$(get_remote_moonraker_commit)"
@@ -565,13 +639,12 @@ function compare_moonraker_versions() {
if [[ ${local_ver} != "${remote_ver}" ]]; then
versions="${yellow}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
# add moonraker to the update all array for the update all function in the updater
MOONRAKER_UPDATE_AVAIL="true" && update_arr+=(update_moonraker)
# add moonraker to application_updates_available in kiauh.ini
add_to_application_updates "moonraker"
else
versions="${green}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
MOONRAKER_UPDATE_AVAIL="false"
fi
echo "${versions}"
}
}

View File

@@ -74,23 +74,29 @@ function set_upstream_nginx_cfg() {
}
function symlink_webui_nginx_log() {
local interface=${1} path="${KLIPPER_LOGS}"
local access_log="/var/log/nginx/${interface}-access.log"
local error_log="/var/log/nginx/${interface}-error.log"
local interface path access_log error_log regex logpaths
[[ ! -d ${path} ]] && mkdir -p "${path}"
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"
logpaths=$(find "${HOME}" -maxdepth 2 -type d -regextype posix-extended -regex "${regex}" | sort)
if [[ -f ${access_log} && ! -L "${path}/${interface}-access.log" ]]; then
status_msg "Creating symlink for ${access_log} ..."
ln -s "${access_log}" "${path}"
ok_msg "Done!"
fi
for path in ${logpaths}; do
[[ ! -d ${path} ]] && mkdir -p "${path}"
if [[ -f ${error_log} && ! -L "${path}/${interface}-error.log" ]]; then
status_msg "Creating symlink for ${error_log} ..."
ln -s "${error_log}" "${path}"
ok_msg "Done!"
fi
if [[ -f ${access_log} && ! -L "${path}/${interface}-access.log" ]]; then
status_msg "Creating symlink for ${access_log} ..."
ln -s "${access_log}" "${path}"
ok_msg "Symlink created: ${path}/${interface}-access.log"
fi
if [[ -f ${error_log} && ! -L "${path}/${interface}-error.log" ]]; then
status_msg "Creating symlink for ${error_log} ..."
ln -s "${error_log}" "${path}"
ok_msg "Symlink created: ${path}/${interface}-error.log"
fi
done
}
function match_nginx_configs() {
@@ -100,7 +106,9 @@ function match_nginx_configs() {
local common_vars="${NGINX_CONFD}/common_vars.conf"
local mainsail_nginx_cfg="/etc/nginx/sites-available/mainsail"
local fluidd_nginx_cfg="/etc/nginx/sites-available/fluidd"
local upstreams_webcams mainsail_webcams fluidd_webcams
local upstreams_webcams
local mainsail_webcams
local fluidd_webcams
### reinstall nginx configs if the amount of upstreams don't match anymore
upstreams_webcams=$(grep -Ec "mjpgstreamer" "/etc/nginx/conf.d/upstreams.conf")
@@ -124,7 +132,7 @@ function match_nginx_configs() {
status_msg "Outdated Mainsail config found! Updating ..."
sudo rm -f "${mainsail_nginx_cfg}"
sudo cp "${RESOURCES}/klipper_webui_nginx.cfg" "${mainsail_nginx_cfg}"
sudo cp "${RESOURCES}/mainsail" "${mainsail_nginx_cfg}"
sudo sed -i "s/<<UI>>/mainsail/g" "${mainsail_nginx_cfg}"
sudo sed -i "/root/s/pi/${USER}/" "${mainsail_nginx_cfg}"
sudo sed -i "s/listen\s[0-9]*;/listen ${mainsail_port};/" "${mainsail_nginx_cfg}"
@@ -138,7 +146,7 @@ function match_nginx_configs() {
status_msg "Outdated Fluidd config found! Updating ..."
sudo rm -f "${fluidd_nginx_cfg}"
sudo cp "${RESOURCES}/klipper_webui_nginx.cfg" "${fluidd_nginx_cfg}"
sudo cp "${RESOURCES}/fluidd" "${fluidd_nginx_cfg}"
sudo sed -i "s/<<UI>>/fluidd/g" "${fluidd_nginx_cfg}"
sudo sed -i "/root/s/pi/${USER}/" "${fluidd_nginx_cfg}"
sudo sed -i "s/listen\s[0-9]*;/listen ${fluidd_port};/" "${fluidd_nginx_cfg}"
@@ -260,8 +268,7 @@ function detect_conflicting_packages() {
echo -e "###### > Skip"
break;;
*)
print_unkown_cmd
print_msg && clear_msg;;
error_msg "Invalid command!";;
esac
done
fi
@@ -269,34 +276,25 @@ function detect_conflicting_packages() {
function set_nginx_cfg() {
local interface=${1}
if [[ ${SET_NGINX_CFG} == "true" ]]; then
local cfg="${RESOURCES}/${interface}"
#check for dependencies
local dep=(nginx)
dependency_check "${dep[@]}"
status_msg "Creating Nginx configuration for ${interface^} ..."
cat "${RESOURCES}/klipper_webui_nginx.cfg" > "${cfg}"
sed -i "s/<<UI>>/${interface}/g" "${cfg}"
local cfg_src="${RESOURCES}/${interface}"
local cfg_dest="/etc/nginx/sites-available/${interface}"
status_msg "Creating NGINX configuration for ${interface^} ..."
# copy config to destination and set correct username
[[ -f ${cfg_dest} ]] && sudo rm -f "${cfg_dest}"
sudo cp "${cfg_src}" "${cfg_dest}"
sudo sed -i "/root/s/pi/${USER}/" "${cfg_dest}"
if [[ ${SET_LISTEN_PORT} != "${DEFAULT_PORT}" ]]; then
status_msg "Configuring port for ${interface^} ..."
sed -i "s/listen\s[0-9]*;/listen ${SET_LISTEN_PORT};/" "${cfg}"
sed -i "s/listen\s\[\:*\]\:[0-9]*;/listen \[::\]\:${SET_LISTEN_PORT};/" "${cfg}"
fi
#set correct user
if [[ ${interface} == "mainsail" || ${interface} == "fluidd" ]]; then
sudo sed -i "/root/s/pi/${USER}/" "${cfg}"
fi
#moving the config file into correct directory
sudo mv "${cfg}" "/etc/nginx/sites-available/${interface}"
ok_msg "Nginx configuration for ${interface^} was set!"
if [[ -n ${SET_LISTEN_PORT} ]]; then
ok_msg "${interface^} configured for port ${SET_LISTEN_PORT}!"
else
ok_msg "${interface^} configured for default port ${DEFAULT_PORT}!"
sudo sed -i "s/listen\s[0-9]*;/listen ${SET_LISTEN_PORT};/" "${cfg_dest}"
sudo sed -i "s/listen\s\[\:*\]\:[0-9]*;/listen \[::\]\:${SET_LISTEN_PORT};/" "${cfg_dest}"
fi
#remove nginx default config
@@ -308,17 +306,32 @@ function set_nginx_cfg() {
if [[ ! -e "/etc/nginx/sites-enabled/${interface}" ]]; then
sudo ln -s "/etc/nginx/sites-available/${interface}" "/etc/nginx/sites-enabled/"
fi
if [[ -n ${SET_LISTEN_PORT} ]]; then
ok_msg "${interface^} configured for port ${SET_LISTEN_PORT}!"
else
ok_msg "${interface^} configured for default port ${DEFAULT_PORT}!"
fi
sudo systemctl restart nginx.service
ok_msg "NGINX configuration for ${interface^} was set!"
fi
}
###
# check if permissions of the users home directory
# grant execution rights to group and other which is
# required for NGINX to be able to serve Mainsail/Fluidd
#
function set_nginx_permissions() {
local distro_name version_id
local homedir_perm
local exec_perms_count
distro_name=$(grep -E "^NAME=" /etc/os-release | cut -d'"' -f2)
version_id=$(grep -E "^VERSION_ID=" /etc/os-release | cut -d'"' -f2)
homedir_perm=$(ls -ld "${HOME}")
exec_perms_count=$(echo "${homedir_perm}" | cut -d" " -f1 | grep -c "x")
if [[ ${distro_name} == "Ubuntu" && ( ${version_id} == "21.10" || ${version_id} == "22.04") ]]; then
if (( exec_perms_count < 3 )); then
status_msg "Granting NGINX the required permissions ..."
chmod og+x "${HOME}" && ok_msg "Done!"
fi

444
scripts/obico.sh Normal file
View File

@@ -0,0 +1,444 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh #
# #
# This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================#
set -e
#===================================================#
#============== INSTALL MOONRAKER-OBICO ============#
#===================================================#
function moonraker_obico_systemd() {
local services
services=$(find "${SYSTEMD}" -maxdepth 1 -regextype posix-extended -regex "${SYSTEMD}/moonraker-obico(-[0-9a-zA-Z]+)?.service")
echo "${services}"
}
function moonraker_obico_config() {
local moonraker_cfg_dirs
read -r -a moonraker_cfg_dirs <<< "$(get_config_folders)"
if (( ${#moonraker_cfg_dirs[@]} > 0 )); then
echo "${moonraker_cfg_dirs[${1}]}/moonraker-obico.cfg"
else
echo ""
fi
}
function moonraker_obico_needs_linking() {
local moonraker_obico_cfg=${1}
if [[ ! -f "${moonraker_obico_cfg}" ]]; then
return 1
fi
if grep -s -E "^[^#]" "${moonraker_obico_cfg}" | grep -q 'auth_token'; then
return 1
else
return 0
fi
}
function obico_server_url_prompt() {
top_border
printf "|${green}%-55s${white}|\n" " Obico Server URL"
blank_line
echo -e "| You can use a self-hosted Obico Server or the Obico |"
echo -e "| Cloud. For more information, please visit: |"
echo -e "| https://obico.io. |"
blank_line
echo -e "| For the Obico Cloud, leave it as the default: |"
printf "|${cyan}%-55s${white}|\n" " https://app.obico.io"
blank_line
echo -e "| For self-hosted server, specify: |"
printf "|${cyan}%-55s${white}|\n" " http://server_ip:port"
echo -e "| For instance, 'http://192.168.0.5:3334'. |"
bottom_border
}
function moonraker_obico_setup_dialog() {
status_msg "Initializing Moonraker-obico installation ..."
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 "Moonraker-obico 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
local moonraker_obico_services
local existing_moonraker_obico_count
moonraker_obico_services=$(moonraker_obico_systemd)
existing_moonraker_obico_count=$(echo "${moonraker_obico_services}" | wc -w )
local allowed_moonraker_obico_count=$(( moonraker_count - existing_moonraker_obico_count ))
if (( allowed_moonraker_obico_count > 0 )); then
local new_moonraker_obico_count
### Step 1: Ask for the number of moonraker-obico instances to install
if (( moonraker_count == 1 )); then
ok_msg "Moonraker installation found!\n"
new_moonraker_obico_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_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
blank_line
echo -e "| The setup will apply the same names to |"
echo -e "| Moonraker-obico! |"
blank_line
echo -e "| Please select the number of Moonraker-obico instances |"
echo -e "| to install. Usually one Moonraker-obico instance per |"
echo -e "| Moonraker instance is required, but you may not |"
echo -e "| install more Moonraker-obico instances than available |"
echo -e "| Moonraker instances. |"
bottom_border
### ask for amount of instances
local re="^[1-9][0-9]*$"
while [[ ! ${new_moonraker_obico_count} =~ ${re} || ${new_moonraker_obico_count} -gt ${allowed_moonraker_obico_count} ]]; do
read -p "${cyan}###### Number of new Moonraker-obico instances to set up:${white} " -i "${allowed_moonraker_obico_count}" -e new_moonraker_obico_count
### break if input is valid
[[ ${new_moonraker_obico_count} =~ ${re} && ${new_moonraker_obico_count} -le ${allowed_moonraker_obico_count} ]] && break
### conditional error messages
[[ ! ${new_moonraker_obico_count} =~ ${re} ]] && error_msg "Input not a number"
(( new_moonraker_obico_count > allowed_moonraker_obico_count )) && error_msg "Number of Moonraker-obico instances larger than installed Moonraker instances"
done && select_msg "${new_moonraker_obico_count}"
else
log_error "Internal error. moonraker_count of '${moonraker_count}' not equal or grather than one!"
return 1
fi # (( moonraker_count == 1 ))
### Step 2: Confirm instance amount
local yn
while true; do
(( new_moonraker_obico_count == 1 )) && local question="Install Moonraker-obico?"
(( new_moonraker_obico_count > 1 )) && local question="Install ${new_moonraker_obico_count} Moonraker-obico 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-obico setup ...\n"
return;;
*)
error_msg "Invalid Input!";;
esac
done
fi # (( allowed_moonraker_obico_count > 0 ))
if (( new_moonraker_obico_count > 0 )); then
### Step 3: Ask for the Obico server URL
obico_server_url_prompt
local obico_server_url
while true; do
read -p "${cyan}###### Obico Server URL:${white} " -i "https://app.obico.io" -e obico_server_url
if echo "${obico_server_url}" | grep -qE "^(http|https)://[a-zA-Z0-9./?=_%:-]*"; then
break
else
error_msg "Invalid server URL!"
fi
done
(( new_moonraker_obico_count > 1 )) && status_msg "Installing ${new_moonraker_obico_count} Moonraker-obico instances ..."
(( new_moonraker_obico_count == 1 )) && status_msg "Installing Moonraker-obico ..."
### Step 4: Install dependencies
local dep=(git dfu-util virtualenv python3 python3-pip python3-venv ffmpeg)
dependency_check "${dep[@]}"
### Step 5: Clone the moonraker-obico repo
clone_moonraker_obico "${MOONRAKER_OBICO_REPO}"
### step 6: call moonrake-obico/install.sh with the correct params
local port=7125
local moonraker_cfg_dirs
read -r -a moonraker_cfg_dirs <<< "$(get_config_folders)"
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}"
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}"
j=$(( j + 1 ))
done && unset j
fi # (( moonraker_count == 1 ))
fi # (( new_moonraker_obico_count > 0 ))
### Step 7: Link to the Obico server if necessary
local not_linked_instances=()
if (( moonraker_count == 1 )); then
if moonraker_obico_needs_linking "$(moonraker_obico_config 0)"; then
not_linked_instances+=("0")
fi
elif (( moonraker_count > 1 )); then
for (( i=0; i <= moonraker_count; i++ )); do
if moonraker_obico_needs_linking "$(moonraker_obico_config "${i}")"; then
not_linked_instances+=("${i}")
fi
done
fi # (( moonraker_count == 1 ))
if (( ${#not_linked_instances[@]} > 0 )); then
top_border
if (( moonraker_count == 1 )); then
printf "|${green}%-55s${white}|\n" " Moonraker-obico not linked to the server!"
else
printf "|${green}%-55s${white}|\n" " ${#not_linked_instances[@]} Moonraker-obico instances not linked to the server!"
for i in "${not_linked_instances[@]}"; do
printf "|${cyan}%-57s${white}|\n" " ● moonraker-obico-${moonraker_names[${i}]}"
done
fi
blank_line
echo -e "| To link to your Obico Server account, you need to |"
echo -e "| obtain the 6-digit verification code in the Obico |"
echo -e "| mobile or web app. For more information, visit: |"
echo -e "| https://www.obico.io/docs/user-guides/klipper-setup/ |"
blank_line
echo -e "| If you don't want to link the printer now, you can |"
echo -e "| restart the linking process later by: |"
echo -e "| 1. 'cd ~/kiauh && ./kiauh.sh' to launch KIAUH. |"
echo -e "| 2. Select ${green}[Install]${white} |"
echo -e "| 3. Select ${green}[Link to Obico Server]${white} |"
bottom_border
while true; do
read -p "${cyan}###### Link to your Obico Server account now? (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-obico setup ...\n"
return;;
*)
error_msg "Invalid Input!";;
esac
done
if (( moonraker_count == 1 )); then
status_msg "Link moonraker-obico to the Obico Server..."
"${MOONRAKER_OBICO_DIR}/scripts/link.sh" -q -c "$(moonraker_obico_config 0)"
elif (( moonraker_count > 1 )); then
for i in "${not_linked_instances[@]}"; do
local name="${moonraker_names[i]}"
status_msg "Link moonraker-obico-${name} to the Obico Server..."
"${MOONRAKER_OBICO_DIR}/scripts/link.sh" -q -n "${name}" -c "$(moonraker_obico_config "${i}")"
done
fi # (( moonraker_count == 1 ))
fi # (( ${#not_linked_instances[@]} > 0 ))
}
function clone_moonraker_obico() {
local repo=${1}
status_msg "Cloning Moonraker-obico from ${repo} ..."
### force remove existing Moonraker-obico dir
[[ -d "${MOONRAKER_OBICO_DIR}" ]] && rm -rf "${MOONRAKER_OBICO_DIR}"
cd "${HOME}" || exit 1
if ! git clone "${repo}" "${MOONRAKER_OBICO_DIR}"; then
print_error "Cloning Moonraker-obico from\n ${repo}\n failed!"
exit 1
fi
}
function moonraker_obico_install() {
"${MOONRAKER_OBICO_DIR}/install.sh" "$@"
}
#===================================================#
#============= REMOVE MOONRAKER-OBICO ==============#
#===================================================#
function remove_moonraker_obico_systemd() {
[[ -z $(moonraker_obico_systemd) ]] && return
status_msg "Removing Moonraker-obico Systemd Services ..."
for service in $(moonraker_obico_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 "Moonraker-obico Services removed!"
}
function remove_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)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_moonraker_obico_dir() {
[[ ! -d ${MOONRAKER_OBICO_DIR} ]] && return
status_msg "Removing Moonraker-obico directory ..."
rm -rf "${MOONRAKER_OBICO_DIR}"
ok_msg "Directory removed!"
}
function remove_moonraker_obico_env() {
[[ ! -d "${HOME}/moonraker-obico-env" ]] && return
status_msg "Removing moonraker-obico-env directory ..."
rm -rf "${HOME}/moonraker-obico-env"
ok_msg "Directory removed!"
}
function remove_moonraker_obico() {
remove_moonraker_obico_systemd
remove_moonraker_obico_logs
remove_moonraker_obico_dir
remove_moonraker_obico_env
print_confirm "Moonraker-obico was successfully removed!"
return
}
#===================================================#
#============= UPDATE MOONRAKER-OBICO ==============#
#===================================================#
function update_moonraker_obico() {
do_action_service "stop" "moonraker-obico"
if [[ ! -d ${MOONRAKER_OBICO_DIR} ]]; then
clone_moonraker_obico "${MOONRAKER_OBICO_REPO}"
else
status_msg "Updating Moonraker-obico ..."
cd "${MOONRAKER_OBICO_DIR}" && git pull
fi
ok_msg "Update complete!"
do_action_service "restart" "moonraker-obico"
}
#===================================================#
#============= MOONRAKER-OBICO STATUS ==============#
#===================================================#
function get_moonraker_obico_status() {
local status
local service_count
local is_linked
local moonraker_obico_services
moonraker_obico_services=$(moonraker_obico_systemd)
service_count=$(echo "${moonraker_obico_services}" | wc -w )
is_linked="true"
if [[ -n ${moonraker_obico_services} ]]; then
for cfg_dir in $(get_config_folders); do
if moonraker_obico_needs_linking "${cfg_dir}/moonraker-obico.cfg"; then
is_linked="false"
fi
done
fi
if (( service_count == 0 )); then
status="Not installed!"
elif [[ ! -d "${MOONRAKER_OBICO_DIR}" ]]; then
status="Incomplete!"
elif [[ ${is_linked} == "false" ]]; then
status="Not linked!"
else
status="Installed!"
fi
echo "${status}"
}
function get_local_moonraker_obico_commit() {
[[ ! -d ${MOONRAKER_OBICO_DIR} || ! -d "${MOONRAKER_OBICO_DIR}/.git" ]] && return
local commit
cd "${MOONRAKER_OBICO_DIR}"
commit="$(git describe HEAD --always --tags | cut -d "-" -f 1,2)"
echo "${commit}"
}
function get_remote_moonraker_obico_commit() {
[[ ! -d ${MOONRAKER_OBICO_DIR} || ! -d "${MOONRAKER_OBICO_DIR}/.git" ]] && return
local commit
cd "${MOONRAKER_OBICO_DIR}" && git fetch origin -q
commit=$(git describe origin/master --always --tags | cut -d "-" -f 1,2)
echo "${commit}"
}
function compare_moonraker_obico_versions() {
local versions local_ver remote_ver
local_ver="$(get_local_moonraker_obico_commit)"
remote_ver="$(get_remote_moonraker_obico_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 "moonraker_obico"
else
versions="${green}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
fi
echo "${versions}"
}
###
# it is possible, that moonraker_obico is installed in a so called
# "non-linked" state. the linking can be achieved by running the
# installation script again. this function will check the obico
# installation status and returns the correctly formulated menu title
#
function obico_install_title() {
if [[ $(get_moonraker_obico_status) == "Not linked!" ]]; then
echo "[Link to Obico Server]"
else
echo "[Obico for Klipper] "
fi
}

View File

@@ -24,10 +24,16 @@ function octoprint_systemd() {
function octoprint_setup_dialog() {
status_msg "Initializing OctoPrint installation ..."
local klipper_services klipper_count user_input=() klipper_names=()
klipper_services=$(klipper_systemd)
klipper_count=$(echo "${klipper_services}" | wc -w )
local klipper_services
klipper_services=$(find_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."
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}")" )
done
@@ -63,7 +69,7 @@ function octoprint_setup_dialog() {
done && select_msg "${octoprint_count}"
else
log_error "Internal error. octoprint_count of '${octoprint_count}' not equal or grather than one!"
log_error "Internal error. klipper_count of '${klipper_count}' not equal or grather than one!"
return 1
fi
@@ -398,4 +404,4 @@ function get_octoprint_status() {
fi
echo "${status}"
}
}

View File

@@ -104,12 +104,11 @@ function get_remote_prettygcode_commit() {
[[ ! -d ${PGC_DIR} || ! -d "${PGC_DIR}/.git" ]] && return
cd "${PGC_DIR}" && git fetch origin -q
commit=$(git describe origin/master --always --tags | cut -d "-" -f 1,2)
commit=$(git describe origin/main --always --tags | cut -d "-" -f 1,2)
echo "${commit}"
}
function compare_prettygcode_versions() {
unset PGC_UPDATE_AVAIL
local versions local_ver remote_ver
local_ver="$(get_local_prettygcode_commit)"
remote_ver="$(get_remote_prettygcode_commit)"
@@ -117,12 +116,11 @@ function compare_prettygcode_versions() {
if [[ ${local_ver} != "${remote_ver}" ]]; then
versions="${yellow}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
# add prettygcode to the update all array for the update all function in the updater
PGC_UPDATE_AVAIL="true" && update_arr+=(update_pgc_for_klipper)
# add moonraker to application_updates_available in kiauh.ini
add_to_application_updates "pgc_for_klipper"
else
versions="${green}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
PGC_UPDATE_AVAIL="false"
fi
echo "${versions}"

View File

@@ -43,53 +43,57 @@ function change_klipper_repo_menu() {
back_help_footer
local option
local num="^[0-9]+$"
local back="^(B|b)$"
local help="^(H|h)$"
while true; do
read -p "${cyan}###### Perform action:${white} " option
case "${option}" in
0 | "$(( option < ${#repos[@]} ))")
select_msg "Repo: ${repos[option]} Branch: ${branches[option]}"
if [[ -d ${KLIPPER_DIR} ]]; then
top_border
echo -e "| ${red}!!! ATTENTION !!!${white} |"
echo -e "| Existing Klipper folder found! Proceeding will remove | "
echo -e "| the existing Klipper folder and replace it with a | "
echo -e "| clean copy of the previously selected source repo! | "
bottom_border
local yn
while true; do
read -p "${cyan}###### Proceed? (Y/n):${white} " yn
case "${yn}" in
Y|y|Yes|yes|"")
select_msg "Yes"
switch_klipper_repo "${repos[${option}]}" "${branches[${option}]}"
set_custom_klipper_repo "${repos[${option}]}" "${branches[${option}]}"
break;;
N|n|No|no)
select_msg "No"
break;;
*)
error_msg "Invalid command!";;
esac
done
else
status_msg "Set custom Klipper repository to:\n ● Repository: ${repos[${option}]}\n ● Branch: ${branches[${option}]}"
set_custom_klipper_repo "${repos[${option}]}" "${branches[${option}]}"
ok_msg "This repo will now be used for new Klipper installations!\n"
fi
break;;
B|b)
clear && print_header
settings_menu
break;;
H|h)
clear && print_header
show_custom_klipper_repo_help
break;;
*)
error_msg "Invalid command!";;
esac
if [[ ${option} =~ ${num} && ${option} -lt ${#repos[@]} ]]; then
select_msg "Repo: ${repos[option]} Branch: ${branches[option]}"
if [[ -d ${KLIPPER_DIR} ]]; then
top_border
echo -e "| ${red}!!! ATTENTION !!!${white} |"
echo -e "| Existing Klipper folder found! Proceeding will remove | "
echo -e "| the existing Klipper folder and replace it with a | "
echo -e "| clean copy of the previously selected source repo! | "
bottom_border
local yn
while true; do
read -p "${cyan}###### Proceed? (Y/n):${white} " yn
case "${yn}" in
Y|y|Yes|yes|"")
select_msg "Yes"
switch_klipper_repo "${repos[${option}]}" "${branches[${option}]}"
set_custom_klipper_repo "${repos[${option}]}" "${branches[${option}]}"
break;;
N|n|No|no)
select_msg "No"
break;;
*)
error_msg "Invalid command!";;
esac
done
else
status_msg "Set custom Klipper repository to:\n ● Repository: ${repos[${option}]}\n ● Branch: ${branches[${option}]}"
set_custom_klipper_repo "${repos[${option}]}" "${branches[${option}]}"
ok_msg "This repo will now be used for new Klipper installations!\n"
fi
elif [[ ${option} =~ ${back} ]]; then
clear && print_header
settings_menu
elif [[ ${option} =~ ${help} ]]; then
clear && print_header
show_custom_klipper_repo_help
else
error_msg "Invalid command!"
fi
done
change_klipper_repo_menu
}

View File

@@ -19,16 +19,16 @@ function install_ui() {
echo -e "| all necessary dependencies for the various |"
echo -e "| functions on a completely fresh system. |"
hr
echo -e "| Firmware & API: | 3rd Party Webinterface: |"
echo -e "| 1) [Klipper] | 6) [OctoPrint] |"
echo -e "| 2) [Moonraker] | |"
echo -e "| | Other: |"
echo -e "| Klipper Webinterface: | 7) [PrettyGCode] |"
echo -e "| 3) [Mainsail] | 8) [Telegram Bot] |"
echo -e "| 4) [Fluidd] | |"
echo -e "| | Webcam Streamer: |"
echo -e "| Touchscreen GUI: | 9) [MJPG-Streamer] |"
echo -e "| 5) [KlipperScreen] | |"
echo -e "| Firmware & API: | 3rd Party Webinterface: |"
echo -e "| 1) [Klipper] | 6) [OctoPrint] |"
echo -e "| 2) [Moonraker] | |"
echo -e "| | Other: |"
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] |"
back_footer
}
@@ -36,6 +36,12 @@ function install_menu() {
clear && print_header
install_ui
### save all installed webinterface ports to the ini file
fetch_webui_ports
### save all klipper multi-instance names to the ini file
set_multi_instance_names
local action
while true; do
read -p "${cyan}####### Perform action:${white} " action
@@ -49,15 +55,35 @@ function install_menu() {
4)
do_action "install_fluidd" "install_ui";;
5)
do_action "install_klipperscreen" "install_ui";;
#do_action "install_klipperscreen" "install_ui";;
clear && print_header
print_error "Function currently disabled! Sorry!"
install_ui;;
6)
do_action "octoprint_setup_dialog" "install_ui";;
#do_action "octoprint_setup_dialog" "install_ui";;
clear && print_header
print_error "Function currently disabled! Sorry!"
install_ui;;
7)
do_action "install_pgc_for_klipper" "install_ui";;
#do_action "install_pgc_for_klipper" "install_ui";;
clear && print_header
print_error "Function currently disabled! Sorry!"
install_ui;;
8)
do_action "telegram_bot_setup_dialog" "install_ui";;
#do_action "telegram_bot_setup_dialog" "install_ui";;
clear && print_header
print_error "Function currently disabled! Sorry!"
install_ui;;
9)
do_action "install_mjpg-streamer" "install_ui";;
#do_action "moonraker_obico_setup_dialog" "install_ui";;
clear && print_header
print_error "Function currently disabled! Sorry!"
install_ui;;
10)
#do_action "install_mjpg-streamer" "install_ui";;
clear && print_header
print_error "Function currently disabled! Sorry!"
install_ui;;
B|b)
clear; main_menu; break;;
*)

View File

@@ -12,6 +12,10 @@
set -e
function main_ui() {
echo -e "${yellow}/=======================================================\\"
echo -e "| Please read the newest changelog carefully: |"
echo -e "| https://git.io/JnmlX |"
echo -e "\=======================================================/${white}"
top_border
echo -e "| $(title_msg "~~~~~~~~~~~~~~~ [ Main Menu ] ~~~~~~~~~~~~~~~") |"
hr
@@ -24,6 +28,7 @@ function main_ui() {
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")|"
quit_footer
@@ -50,6 +55,9 @@ function print_status() {
status="${red}${status}${white}"
elif [[ ${status} == "Incomplete!" ]]; then
status="${yellow}${status}${white}"
elif [[ ${status} == "Not linked!" ]]; then
### "Not linked!" is only required for Moonraker-obico
status="${yellow}${status}${white}"
else
status="${green}${status}${white}"
fi
@@ -79,7 +87,11 @@ function print_klipper_repo() {
function main_menu() {
print_header && main_ui
clear && print_header
main_ui
### initialize kiauh.ini
init_ini
local action
while true; do
@@ -96,8 +108,9 @@ function main_menu() {
"restart octoprint") do_action_service "restart" "octoprint"; main_ui;;
update) do_action "update_kiauh" "main_ui";;
0)clear && print_header
upload_selection
break;;
#upload_selection
print_error "Function currently disabled! Sorry!"
main_ui;;
1)clear && print_header
install_menu
break;;
@@ -111,8 +124,9 @@ function main_menu() {
advanced_menu
break;;
5)clear && print_header
backup_menu
break;;
#backup_menu
print_error "Function currently disabled! Sorry!"
main_ui;;
6)clear && print_header
settings_menu
break;;
@@ -123,5 +137,5 @@ function main_menu() {
deny_action "main_ui";;
esac
done
clear; main_menu
main_menu
}

View File

@@ -26,7 +26,8 @@ function remove_ui() {
echo -e "| 4) [Fluidd] | Other: |"
echo -e "| | 8) [PrettyGCode] |"
echo -e "| Touchscreen GUI: | 9) [Telegram Bot] |"
echo -e "| 5) [KlipperScreen] | 10) [NGINX] |"
echo -e "| 5) [KlipperScreen] | 10) [Obico for Klipper] |"
echo -e "| | 11) [NGINX] |"
back_footer
}
@@ -56,6 +57,8 @@ function remove_menu() {
9)
do_action "remove_telegram_bot" "remove_ui";;
10)
do_action "remove_moonraker_obico" "remove_ui";;
11)
do_action "remove_nginx" "remove_ui";;
B|b)
clear; main_menu; break;;

View File

@@ -14,20 +14,12 @@ set -e
function settings_ui() {
read_kiauh_ini "${FUNCNAME[0]}"
local custom_cfg_loc="${custom_klipper_cfg_loc}"
local custom_repo="${custom_klipper_repo}"
local custom_branch="${custom_klipper_repo_branch}"
local ms_pre_rls="${mainsail_install_unstable}"
local fl_pre_rls="${fluidd_install_unstable}"
local bbu="${backup_before_update}"
### config location
if [[ -z ${custom_cfg_loc} ]]; then
custom_cfg_loc="${cyan}${KLIPPER_CONFIG}${white}"
else
custom_cfg_loc="${cyan}${custom_cfg_loc}${white}"
fi
### custom repository
custom_repo=$(echo "${custom_repo}" | sed "s/https:\/\/github\.com\///" | sed "s/\.git$//" )
if [[ -z ${custom_repo} ]]; then
@@ -67,8 +59,6 @@ function settings_ui() {
echo -e "| $(title_msg "~~~~~~~~~~~~ [ KIAUH Settings ] ~~~~~~~~~~~~~") |"
hr
echo -e "| Klipper: |"
echo -e "| ● Config folder: |"
printf "| %-60s|\n" "${custom_cfg_loc}"
echo -e "| ● Repository: |"
printf "| %-70s|\n" "${custom_repo} (${custom_branch})"
hr
@@ -77,24 +67,23 @@ function settings_ui() {
hr
printf "| Backup before updating: %-42s|\n" "${bbu}"
hr
echo -e "| 1) Change Klipper config folder location |"
echo -e "| 2) Set custom Klipper repository |"
echo -e "| 1) Set custom Klipper repository |"
blank_line
if [[ ${mainsail_install_unstable} == "false" ]]; then
echo -e "| 3) ${green}Allow${white} unstable Mainsail releases |"
echo -e "| 2) ${green}Allow${white} unstable Mainsail releases |"
else
echo -e "| 3) ${red}Disallow${white} unstable Mainsail releases |"
echo -e "| 2) ${red}Disallow${white} unstable Mainsail releases |"
fi
if [[ ${fluidd_install_unstable} == "false" ]]; then
echo -e "| 4) ${green}Allow${white} unstable Fluidd releases |"
echo -e "| 3) ${green}Allow${white} unstable Fluidd releases |"
else
echo -e "| 4) ${red}Disallow${white} unstable Fluidd releases |"
echo -e "| 3) ${red}Disallow${white} unstable Fluidd releases |"
fi
blank_line
if [[ ${backup_before_update} == "false" ]]; then
echo -e "| 5) ${green}Enable${white} automatic backups before updates |"
echo -e "| 4) ${green}Enable${white} automatic backups before updates |"
else
echo -e "| 5) ${red}Disable${white} automatic backups before updates |"
echo -e "| 4) ${red}Disable${white} automatic backups before updates |"
fi
back_help_footer
}
@@ -105,16 +94,6 @@ function show_settings_help() {
top_border
echo -e "| ~~~~~~ < ? > Help: KIAUH Settings < ? > ~~~~~~ |"
hr
echo -e "| ${cyan}Klipper config folder:${white} |"
echo -e "| The location of your printer.cfg and all other config |"
echo -e "| files that gets used during installation of Klipper |"
echo -e "| and all other components which need that location. |"
echo -e "| It is not recommended to change this location. |"
echo -e "| Be advised, that negative side effects could occur. |"
blank_line
printf "| Default: %-55s|\n" "${default_cfg}"
blank_line
hr
echo -e "| ${cyan}Install unstable releases:${white} |"
echo -e "| If set to ${green}true${white}, KIAUH installs/updates the software |"
echo -e "| with the latest, currently available release. |"
@@ -160,20 +139,16 @@ function settings_menu() {
read -p "${cyan}####### Perform action:${white} " action
case "${action}" in
1)
clear && print_header
change_klipper_cfg_folder
settings_ui;;
2)
clear && print_header
change_klipper_repo_menu
settings_ui;;
3)
2)
switch_mainsail_releasetype
settings_menu;;
4)
3)
switch_fluidd_releasetype
settings_menu;;
5)
4)
toggle_backup_before_update
settings_menu;;
B|b)

View File

@@ -31,13 +31,13 @@ function update_ui() {
echo -e "| Other: |---------------|--------------|"
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 "| |------------------------------|"
echo -e "| 8) [System] | $(check_system_updates) |"
echo -e "| 9) [System] | $(check_system_updates) |"
back_footer
}
function update_menu() {
unset update_arr
do_action "" "update_ui"
local action
@@ -61,6 +61,8 @@ function update_menu() {
7)
do_action "update_telegram_bot" "update_ui";;
8)
do_action "update_moonraker_obico" "update_ui";;
9)
do_action "update_system" "update_ui";;
a)
do_action "update_all" "update_ui";;
@@ -74,6 +76,13 @@ function update_menu() {
}
function update_all() {
read_kiauh_ini "${FUNCNAME[0]}"
local update_arr
local app_update_state="${application_updates_available}"
IFS=', ' read -r -a update_arr <<< "${app_update_state}"
while true; do
if (( ${#update_arr[@]} == 0 )); then
print_confirm "Everything is already up-to-date!"
@@ -83,49 +92,47 @@ function update_all() {
echo
top_border
echo -e "| The following installations will be updated: |"
if [[ "${KLIPPER_UPDATE_AVAIL}" = "true" ]]; then
echo -e "| ${cyan}● Klipper${white} |"
fi
if [[ "${MOONRAKER_UPDATE_AVAIL}" = "true" ]]; then
echo -e "| ${cyan}● Moonraker${white} |"
fi
if [[ "${MAINSAIL_UPDATE_AVAIL}" = "true" ]]; then
echo -e "| ${cyan}● Mainsail${white} |"
fi
if [[ "${FLUIDD_UPDATE_AVAIL}" = "true" ]]; then
echo -e "| ${cyan}● Fluidd${white} |"
fi
if [[ "${KLIPPERSCREEN_UPDATE_AVAIL}" = "true" ]]; then
echo -e "| ${cyan}● KlipperScreen${white} |"
fi
if [[ "${PGC_UPDATE_AVAIL}" = "true" ]]; then
echo -e "| ${cyan}● PrettyGCode for Klipper${white} |"
fi
if [[ "${MOONRAKER_TELEGRAM_BOT_UPDATE_AVAIL}" = "true" ]]; then
echo -e "| ${cyan}● MoonrakerTelegramBot${white} |"
fi
if [[ "${SYS_UPDATE_AVAIL}" = "true" ]]; then
echo -e "| ${cyan}● System${white} |"
fi
[[ "${update_arr[*]}" =~ "klipper" ]] && \
echo -e "| ${cyan}● Klipper${white} |"
[[ "${update_arr[*]}" =~ "moonraker" ]] && \
echo -e "| ${cyan}● Moonraker${white} |"
[[ "${update_arr[*]}" =~ "mainsail" ]] && \
echo -e "| ${cyan}● Mainsail${white} |"
[[ "${update_arr[*]}" =~ "fluidd" ]] && \
echo -e "| ${cyan}● Fluidd${white} |"
[[ "${update_arr[*]}" =~ "klipperscreen" ]] && \
echo -e "| ${cyan}● KlipperScreen${white} |"
[[ "${update_arr[*]}" =~ "pgc_for_klipper" ]] && \
echo -e "| ${cyan}● PrettyGCode for Klipper${white} |"
[[ "${update_arr[*]}" =~ "telegram_bot" ]] && \
echo -e "| ${cyan}● MoonrakerTelegramBot${white} |"
[[ "${update_arr[*]}" =~ "system" ]] && \
echo -e "| ${cyan}● System${white} |"
bottom_border
local yn
if (( ${#update_arr[@]} != 0 )); then
read -p "${cyan}###### Do you want to proceed? (Y/n):${white} " yn
case "${yn}" in
Y|y|Yes|yes|"")
for update in "${update_arr[@]}"
do
#shellcheck disable=SC2250
$update
done
break;;
N|n|No|no)
break;;
*)
print_unkown_cmd
print_msg && clear_msg;;
esac
fi
read -p "${cyan}###### Do you want to proceed? (Y/n):${white} " yn
case "${yn}" in
Y|y|Yes|yes|"")
for app in "${update_arr[@]}"; do
local update="update_${app}"
#shellcheck disable=SC2250
$update
done
break;;
N|n|No|no)
break;;
*)
error_msg "Invalid command!";;
esac
done
}

View File

@@ -138,9 +138,16 @@ function init_ini() {
echo -e "# DO NOT edit this file! #"
echo -e "#=================================================#"
echo -e "# KIAUH v4.0.0"
echo -e "#"
} >> "${INI_FILE}"
fi
if ! grep -Eq "^application_updates_available=" "${INI_FILE}"; then
echo -e "\napplication_updates_available=\c" >> "${INI_FILE}"
else
sed -i "/application_updates_available=/s/=.*/=/" "${INI_FILE}"
fi
if ! grep -Eq "^backup_before_update=." "${INI_FILE}"; then
echo -e "\nbackup_before_update=false\c" >> "${INI_FILE}"
fi
@@ -149,10 +156,6 @@ function init_ini() {
echo -e "\nlogupload_accepted=false\c" >> "${INI_FILE}"
fi
if ! grep -Eq "^custom_klipper_cfg_loc=" "${INI_FILE}"; then
echo -e "\ncustom_klipper_cfg_loc=\c" >> "${INI_FILE}"
fi
if ! grep -Eq "^custom_klipper_repo=" "${INI_FILE}"; then
echo -e "\ncustom_klipper_repo=\c" >> "${INI_FILE}"
fi
@@ -169,158 +172,12 @@ function init_ini() {
echo -e "\nfluidd_install_unstable=false\c" >> "${INI_FILE}"
fi
fetch_webui_ports
}
function change_klipper_cfg_folder() {
local current_cfg_loc example_loc recommended_loc new_cfg_loc
current_cfg_loc="$(get_klipper_cfg_dir)"
example_loc=$(printf "%s/<your_config_folder>" "${HOME}")
recommended_loc=$(printf "%s/klipper_config" "${HOME}")
local yn
while true; do
top_border
echo -e "| ${yellow}IMPORTANT:${white} |"
echo -e "| Please enter the new path in the following format: |"
printf "| ${cyan}%-51s${white} |\n" "${example_loc}"
blank_line
echo -e "| ${red}WARNING: ${white} |"
echo -e "| ${red}There will be no validation checks! Make sure to set${white} |"
echo -e "| ${red}a valid directory to prevent possible problems!${white} |"
blank_line
printf "| Recommended: ${cyan}%-38s${white} |\n" "${recommended_loc}"
bottom_border
echo
echo -e "${cyan}###### Please set the new Klipper config directory:${white} "
read -e -i "${current_cfg_loc}" -e new_cfg_loc
echo
read -p "${cyan}###### Set config directory to '${yellow}${new_cfg_loc}${cyan}' ? (Y/n):${white} " yn
case "${yn}" in
Y|y|Yes|yes|"")
select_msg "Yes"
set_klipper_cfg_path "${current_cfg_loc}" "${new_cfg_loc}"
print_confirm "New config directory set!"
break;;
N|n|No|no)
select_msg "No"
break;;
*)
print_error "Invalid command!";;
esac
done
}
function set_klipper_cfg_path() {
local current_cfg_loc="${1}" new_cfg_loc="${2}"
local instance klipper_services moonraker_services moonraker_configs
log_info "Function set_klipper_cfg_path invoked\nCurrent location: ${1}\nNew location: ${2}"
### backup the old config dir
backup_klipper_config_dir
### write new location to .kiauh.ini
sed -i "/^custom_klipper_cfg_loc=/d" "${INI_FILE}"
sed -i '$a'"custom_klipper_cfg_loc=${new_cfg_loc}" "${INI_FILE}"
status_msg "New directory was set to '${new_cfg_loc}'!"
### stop services
do_action_service "stop" "klipper"
do_action_service "stop" "moonraker"
### copy config files to new klipper config folder
if [[ -n ${current_cfg_loc} && -d ${current_cfg_loc} ]]; then
status_msg "Copy config files to '${new_cfg_loc}' ..."
if [[ ! -d ${new_cfg_loc} ]]; then
log_info "Copy process started"
mkdir -p "${new_cfg_loc}"
cd "${current_cfg_loc}"
cp -r -v ./* "${new_cfg_loc}"
ok_msg "Done!"
else
log_warning "Copy process skipped, new config directory already exists and may not be empty!"
warn_msg "New config directory already exists! Copy process skipped!"
fi
if ! grep -Eq "^multi_instance_names=" "${INI_FILE}"; then
echo -e "\nmulti_instance_names=\c" >> "${INI_FILE}"
fi
klipper_services=$(klipper_systemd)
if [[ -n ${klipper_services} ]]; then
status_msg "Re-writing Klipper services to use new config file location ..."
for service in ${klipper_services}; do
if [[ ${service} = "/etc/systemd/system/klipper.service" ]]; then
if grep -q "Environment=KLIPPER_CONFIG=" "${service}"; then
### single instance klipper service installed by kiauh v4 / MainsailOS > 0.5.0
sudo sed -i -r "/KLIPPER_CONFIG=/ s|CONFIG=(.+)\/printer\.cfg|CONFIG=${new_cfg_loc}/printer\.cfg|" "${service}"
else
### single instance klipper service installed by kiauh v3
sudo sed -i -r "/ExecStart=/ s|klippy\.py (.+)\/printer\.cfg|klippy\.py ${new_cfg_loc}\/printer\.cfg|" "${service}"
fi
else
instance=$(echo "${service}" | cut -d"-" -f2 | cut -d"." -f1)
if grep -q "Environment=KLIPPER_CONFIG=" "${service}"; then
### multi instance klipper service installed by kiauh v4 / MainsailOS > 0.5.0
sudo sed -i -r "/KLIPPER_CONFIG=/ s|CONFIG=(.+)\/printer_${instance}\/printer\.cfg|CONFIG=${new_cfg_loc}\/printer_${instance}\/printer\.cfg|" "${service}"
else
### multi instance klipper service installed by kiauh v3
sudo sed -i -r "/ExecStart=/ s|klippy\.py (.+)\/printer_${instance}\/printer\.cfg|klippy\.py ${new_cfg_loc}\/printer_${instance}\/printer\.cfg|" "${service}"
fi
fi
done
ok_msg "OK!"
fi
moonraker_services=$(moonraker_systemd)
if [[ -n ${moonraker_services} ]]; then
### handle multi moonraker instance service file
status_msg "Re-writing Moonraker services to use new config file location ..."
for service in ${moonraker_services}; do
if [[ ${service} = "/etc/systemd/system/moonraker.service" ]]; then
if grep -q "Environment=MOONRAKER_CONF=" "${service}"; then
### single instance moonraker service installed by kiauh v4 / MainsailOS > 0.5.0
sudo sed -i -r "/MOONRAKER_CONF=/ s|_CONF=(.+)\/moonraker\.conf|_CONF=${new_cfg_loc}\/moonraker\.conf|" "${service}"
else
### single instance moonraker service installed by kiauh v3
sudo sed -i -r "/ExecStart=/ s| -c (.+)\/moonraker\.conf| -c ${new_cfg_loc}\/moonraker\.conf|" "${service}"
fi
else
instance=$(echo "${service}" | cut -d"-" -f2 | cut -d"." -f1)
if grep -q "Environment=MOONRAKER_CONF=" "${service}"; then
### multi instance moonraker service installed by kiauh v4 / MainsailOS > 0.5.0
sudo sed -i -r "/MOONRAKER_CONF=/ s|_CONF=(.+)\/printer_${instance}\/moonraker\.conf|_CONF=${new_cfg_loc}\/printer_${instance}\/moonraker\.conf|" "${service}"
else
### multi instance moonraker service installed by kiauh v3
sudo sed -i -r "/ExecStart=/ s| -c (.+)\/printer_${instance}\/moonraker\.conf| -c ${new_cfg_loc}\/printer_${instance}\/moonraker\.conf|" "${service}"
fi
fi
done
moonraker_configs=$(find "${new_cfg_loc}" -type f -name "moonraker.conf" | sort)
### replace old file path with new one in moonraker.conf
local loc
for conf in ${moonraker_configs}; do
loc=$(echo "${conf}" | rev | cut -d"/" -f2- | rev)
sed -i -r "/config_path:/ s|config_path:.*|config_path: ${loc}|" "${conf}"
done
ok_msg "OK!"
fi
### reloading units
sudo systemctl daemon-reload
### restart services
do_action_service "restart" "klipper"
do_action_service "restart" "moonraker"
### strip all empty lines out of the file
sed -i "/^[[:blank:]]*$/ d" "${INI_FILE}"
}
function switch_mainsail_releasetype() {
@@ -370,6 +227,18 @@ function set_custom_klipper_repo() {
sed -i '$a'"custom_klipper_repo_branch=${branch}" "${INI_FILE}"
}
function add_to_application_updates() {
read_kiauh_ini "${FUNCNAME[0]}"
local application="${1}"
local app_update_state="${application_updates_available}"
if ! grep -Eq "${application}" <<< "${app_update_state}"; then
app_update_state="${app_update_state}${application},"
sed -i "/application_updates_available=/s/=.*/=${app_update_state}/" "${INI_FILE}"
fi
}
#================================================#
#=============== HANDLE SERVICES ================#
#================================================#
@@ -469,16 +338,47 @@ 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")
for folder in "${folders[@]}"; do
local dir="${printer_data}/${folder}"
### remove possible symlink created by moonraker
if [[ -L "${dir}" && -d "${dir}" ]]; then
rm "${dir}"
fi
if [[ ! -d "${dir}" ]]; then
status_msg "Creating folder '${dir}' ..."
mkdir -p "${dir}"
ok_msg "Folder '${dir}' created!"
fi
done
}
function check_system_updates() {
local updates_avail info_msg
updates_avail=$(apt list --upgradeable 2>/dev/null | sed "1d")
if [[ -n ${updates_avail} ]]; then
# add system updates to the update all array for the update all function in the updater
SYS_UPDATE_AVAIL="true" && update_arr+=(update_system)
info_msg="${yellow}System upgrade available!${white}"
# add system to application_updates_available in kiauh.ini
add_to_application_updates "system"
else
SYS_UPDATE_AVAIL="false"
info_msg="${green}System up to date! ${white}"
fi
@@ -643,12 +543,130 @@ function set_hostname() {
ok_msg "Remember to reboot for the changes to take effect!"
}
### this function takes in the full path of a systemd service file and returns
### either the instance index or the custom name
### input: /etc/systemd/system/klipper-name.service
### returns: name
#================================================#
#============ INSTANCE MANAGEMENT ===============#
#================================================#
###
# takes in a systemd service files full path and
# returns the sub-string with the instance name
#
# @param {string}: service file absolute path
# (e.g. '/etc/systemd/system/klipper-<name>.service')
#
# => return sub-string containing only the <name> part of the full string
#
function get_instance_name() {
local instance=${1} name
name=$(echo "${instance}" | rev | cut -d"/" -f1 | rev | cut -d"-" -f2 | cut -d"." -f1)
local instance=${1}
local name
name=$(echo "${instance}" | rev | cut -d"/" -f1 | cut -d"." -f2 | cut -d"-" -f1 | rev)
echo "${name}"
}
}
###
# returns the instance name/identifier of the klipper service
# if the klipper service is part of a multi instance setup
# otherwise returns an emtpy string
#
# @param {string}: name - klipper service name (e.g. klipper-name.service)
#
function get_klipper_instance_name() {
local instance=${1}
local name
name=$(echo "${instance}" | rev | cut -d"/" -f1 | cut -d"." -f2 | rev)
local regex="^klipper-[0-9a-zA-Z]+$"
if [[ ${name} =~ ${regex} ]]; then
name=$(echo "${name}" | cut -d"-" -f2)
else
name=""
fi
echo "${name}"
}
###
# loops through all installed klipper services and saves
# each instances name in a comma separated format to the kiauh.ini
#
function set_multi_instance_names() {
read_kiauh_ini "${FUNCNAME[0]}"
local name
local names=""
local services=$(find_klipper_systemd)
###
# if value of 'multi_instance_names' is not an empty
# string, delete its value, so it can be re-written
if [[ -n ${multi_instance_names} ]]; then
sed -i "/multi_instance_names=/s/=.*/=/" "${INI_FILE}"
fi
for svc in ${services}; do
name=$(get_klipper_instance_name "${svc}")
if ! grep -Eq "${name}" <<<"${names}"; then
names="${names}${name},"
fi
done
# write up-to-date instance name string to kiauh.ini
sed -i "/multi_instance_names=/s/=.*/=${names}/" "${INI_FILE}"
}
###
# Helper function that returns all configured instance names
#
# => return an empty string if 0 or 1 klipper instance is installed
# => return space-separated string for names of the configured instances
# if 2 or more klipper instances are installed
#
function get_multi_instance_names() {
read_kiauh_ini "${FUNCNAME[0]}"
local instance_names=()
###
# convert the comma separates string from the .kiauh.ini into
# an array of instance names. a single instance installation
# results in an empty instance_names array
IFS=',' read -r -a instance_names <<< "${multi_instance_names}"
echo "${instance_names[@]}"
}
###
# helper function that returns all possibly available absolute
# klipper config directory paths based on their instance name.
#
# => return an empty string if klipper is not installed
# => return space-separated string of absolute config directory paths
#
function get_config_folders() {
local cfg_dirs=()
local instance_names
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
cfg_dirs+=("${KLIPPER_CONFIG}/printer_${name}")
else
cfg_dirs+=("${KLIPPER_CONFIG}/${name}")
fi
done
elif [[ -z ${instance_names} && $(find_klipper_systemd | wc -w) -gt 0 ]]; then
cfg_dirs+=("${KLIPPER_CONFIG}")
else
cfg_dirs=()
fi
echo "${cfg_dirs[@]}"
}