85 Commits
v4 ... master

Author SHA1 Message Date
Justin Otherguy
a374ac8fac fix: add unzip to dependencies for Mainsail and Fluidd 2024-05-09 20:56:16 +02:00
Christian Würthner
f2691f33d3 feat: add OctoApp support (#454)
* Add OctoApp support

* Update scripts/octoapp.sh

Co-authored-by: dw-0 <domwil1091+github@gmail.com>

* Remove duplicate clone function

* Update Readme link

* Use "OctoApp for Klipper" in install menu

---------

Co-authored-by: dw-0 <domwil1091+github@gmail.com>
2024-03-31 17:15:47 +02:00
dw-0
d800d356ca fix(backups): backup config folder only if it exists
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-03-24 19:45:02 +01:00
dw-0
b6c6edb622 refactor(Mobileraker): update companion install script (#431) (#433) 2024-02-24 14:53:41 +01:00
dw-0
099d47df2f fix: revert "refactor(Mobileraker): update companion install script (#431)" (#432)
This reverts commit ba1cdb3739.
2024-01-29 17:17:09 +01:00
Patrick Schmidt
ba1cdb3739 refactor(Mobileraker): update companion install script (#431) 2024-01-29 17:09:30 +01:00
Anna
8e7d4db988 fix: OctoPrint logo in README.md (#424)
* Fix OctoPrint logo in Readme

Fixed the broken link to the OctoPrint logo in the Readme under the Sources section. Now uses the logo present in the octoprint docs directory.

* Update OctoPrint logo to "raw" cdn link

* Changed ?raw=true link to raw.githubusercontent.com

---------

Co-authored-by: dw-0 <th33xitus@gmail.com>
2024-01-23 22:47:37 +01:00
jneilliii
8f960495ba fix: OctoPrint logo in README.md (#423) 2024-01-22 17:57:37 +01:00
dw-0
095823bf28 chore(kiauh): update FUNDING.yml
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-01-01 20:02:29 +01:00
dw-0
397038e43e chore(kiauh): add .idea to .gitignore
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-01-01 19:55:47 +01:00
dw-0
061e222664 chore(kiauh): update copyright
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-01-01 19:54:13 +01:00
dw-0
3f5ff50d69 refactor(kiauh): use sudo true instead of sudo -v to prevent password prompts
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-01-01 19:51:56 +01:00
dw-0
5ebe941125 readme: don't recommend a specific architecture anymore
Fixes #403 

Both 32bit and 64bit images were reported to work fine. So we don't need a strict 32bit recommendation anymore which may confuses users, why they should pick 32bit over 64bit.

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 12:18:04 +01:00
dw-0
f5eb9486cc refactor(kiauh): use sudo true instead of sudo -v to prevent password prompts
Fixes #395 

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-12-17 12:10:36 +01:00
Stefan Dej
7a9e752f9c fix: fix typo in example.printer.cfg (#412)
rename virtual_sd_card to virtual_sdcard

Signed-off-by: Stefan Dej <meteyou@gmail.com>
2023-12-12 08:21:51 +01:00
CODeRUS
30bc56b198 feat(advanced): add selection between flash/serialflash methods (#410) 2023-12-10 16:57:59 +01:00
dw-0
b2567995de feat(klipper): add virtual_sd_card_block to example printer.cfg (#411) 2023-12-10 15:12:28 +01:00
dw-0
6fcd7a3f08 refactor(klipper): improve disruptive package handling
fix #293

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-10-31 15:09:31 +01:00
dw-0
25dfbb83df fix(kiauh): display custom repo dialog again after user interaction
fix #394

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-10-28 20:48:57 +02:00
Sineos
899b204dc7 refactor: show full path of mcu (#391) 2023-10-15 10:08:41 +02:00
Kenneth Jiang
5cf4b018fc refactor: change wording now that moonraker-obico can link printer using auto-discovery (#389) 2023-10-12 20:26:30 +02:00
dw-0
ae9d1b98da feat(klipper): remove/disable brltty and ModemManager during installation (#387) 2023-10-01 18:30:01 +02:00
Kenneth Jiang
16d3388ff2 refactor: make the 'Obico for Klipper' name consistent (#385) 2023-09-29 20:20:21 +02:00
th33xitus
b88d0085ba fix(backups): fix broken config target folder name
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-09-04 21:17:10 +02:00
th33xitus
0b6613e464 fix(backups): fix broken moonraker database target folder name
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-09-04 21:02:22 +02:00
th33xitus
d99cda544a fix(backups): add backup before update function for KlipperScreen
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-08-30 19:48:55 +02:00
th33xitus
a50dce20de fix(backups): add backup function for OctoEverywhere
fix #380

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-08-30 19:48:53 +02:00
th33xitus
f45da66e9e fix(crowsnest): uninstaller exited KIAUH if crowsnest not installed
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-08-26 18:31:37 +02:00
th33xitus
2822499344 refactor(copyright): update copyright comment
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-08-26 18:11:00 +02:00
th33xitus
c777ba3e6b refactor(log-upload): update log upload functions and re-enable access
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-08-26 18:06:14 +02:00
th33xitus
9f410450d7 refactor(backups): update backup functions for config and moonraker database and enable backup-before-update again
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-08-23 23:22:23 +02:00
dw-0
0497d49066 Update README.md 2023-08-15 16:42:38 +02:00
dw-0
229da227b0 Update FUNDING.yml
use updated ko-fi username
2023-08-14 23:06:44 +02:00
th33xitus
65854c8da6 fix(updates): make update all function also update system again
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-07-22 23:24:29 +02:00
Kenneth Jiang
5985646633 refactor(obico): move dependency handling to obico's own install script (#361) 2023-07-10 17:44:05 +02:00
th33xitus
979c39dc02 refactor(mainsail/fluidd): allow reading of version from release_info.json
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-07-01 20:59:46 +02:00
th33xitus
197058bd00 changelog: update Changelog
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-06-17 21:19:49 +02:00
th33xitus
d3b5122ebb refactor(UI): move version and added changelog link to own row in main menu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-06-17 21:11:23 +02:00
th33xitus
8ce4daf403 refactor(klipper): pre-select python3 for klipper install
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-06-17 19:51:41 +02:00
th33xitus
b0a65fe14e refactor(UI): remove warn message
more than half a year is gone, the warning should not be that important anymore

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-06-17 19:49:57 +02:00
Patrick Schmidt
98866caefa feat: add Mobileraker (#343)
Co-authored-by: th33xitus <th33xitus@googlemail.com>
2023-06-17 19:34:26 +02:00
phizev
345b7b66a3 refactor: use service specific directories in templates (#355) 2023-06-17 18:22:16 +02:00
cravl-dev
8eb2924832 refactor: update package lists only when stale (#346)
Co-authored-by: th33xitus <th33xitus@googlemail.com>
2023-06-17 18:08:24 +02:00
Kyriel Abad
5d7debd65e readme: fix typos in README.md (#352) 2023-06-10 23:00:23 +02:00
th33xitus
7df3dd489f fix(mainsail/fluidd): show correct version number in update menu
fixes #350

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-06-07 21:48:17 +02:00
marbocub
0cd058320f feat: allow to install Mainsail/Fluidd without Moonraker (#347)
Co-authored-by: th33xitus <th33xitus@googlemail.com>
2023-06-06 21:09:47 +02:00
th33xitus
bcbb185bd7 readme: update README.md
also fixes #327
2023-06-04 21:57:56 +02:00
CODeRUS
477f3ca72c feat: flash DFU device in HID mode (#337)
Co-authored-by: th33xitus <th33xitus@googlemail.com>
2023-06-04 21:23:32 +02:00
th33xitus
c19acb1694 fix(mainsail/fluidd): fall back to latest stable url if fetching tags fails (#348) 2023-06-04 19:12:53 +02:00
Jookia
8228943850 fix(klipper): if set, use custom branch to check for update (#332) 2023-04-16 08:56:18 +02:00
Stefan Dej
5b890fb0fb refactor(mainsail): update themes.csv url for mainsail themes (#329) 2023-04-13 17:59:14 +02:00
Piotr Banasik
7989cec8d4 fix(crowsnest): override installers BASE_USER to current user (#317) 2023-03-19 11:50:06 +01:00
th33xitus
858301aa9a fix: temporary disable backup_before_update
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-03-18 18:15:11 +01:00
Quinn Damerell
ae9e79c579 feat(octoeverywhere): add OE to the "update all" action (#311) 2023-03-11 23:52:46 +01:00
th33xitus
1215446a6c feat(octoeverywhere): implement update function (#310) 2023-03-11 20:25:17 +01:00
th33xitus
8526acf8b6 chore: update copyright notice
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2023-03-10 20:06:06 +01:00
th33xitus
cc27aaec7c readme: add prerequisites to readme (#309) 2023-03-08 20:07:00 +01:00
Quinn Damerell
1e9493461c feat: add OctoEverywhere for Klipper (#300)
Co-authored-by: th33xitus <th33xitus@googlemail.com>
2023-03-05 17:19:20 +01:00
th33xitus
31616ebad5 fix(crowsnest): silence grep error output in main menu
fixes #308

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

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

4
.github/FUNDING.yml vendored
View File

@@ -3,10 +3,10 @@
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username open_collective: # Replace with a single Open Collective username
ko_fi: th33xitus ko_fi: dw__0
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] custom: https://paypal.me/dwillner0

5
.gitignore vendored
View File

@@ -1 +1,4 @@
klipper_repos.txt .idea
.vscode
*.code-workspace
klipper_repos.txt

149
README.md
View File

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

View File

@@ -2,6 +2,75 @@
This document covers possible important changes to KIAUH. This document covers possible important changes to KIAUH.
### 2023-06-17
KIAUH has now added support for installing Mobileraker's companion!
Mobileraker is a free and Open Source Android and iOS App for Klipper, utilizing the Moonraker API, allowing you
to control your printer. Thank you to [Clon1998](https://github.com/Clon1998) for adding this feature!
### 2023-02-03
The installer for MJPG-Streamer got replaced by crowsnest. It is an improved webcam service, utilizing ustreamer.
Please have a look here for additional info about crowsnest and how to configure it: https://github.com/mainsail-crew/crowsnest \
It's unsure if the previous MJPG-Streamer installer will be updated and make its way back into KIAUH.
A big thanks to [KwadFan](https://github.com/KwadFan) for writing the crowsnest implementation.
### 2022-10-31
Some functions got updated, though not all of them.
The following functions are still currently unavailable:
- Installation of: MJPG-Streamer
- All backup functions and the Log-Upload
### 2022-10-20
KIAUH has now reached major version 5 !
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 ### 2022-08-15
Support for "Obico for Klipper" was added! Huge thanks to [kennethjiang](https://github.com/kennethjiang) for helping me with the implementation! Support for "Obico for Klipper" was added! Huge thanks to [kennethjiang](https://github.com/kennethjiang) for helping me with the implementation!

View File

@@ -41,7 +41,7 @@ Execute with:
`RUN_SHELL_COMMAND CMD=hello_world` `RUN_SHELL_COMMAND CMD=hello_world`
### Passing parameters: ### Passing parameters:
As of commit [f231fa9](https://github.com/th33xitus/kiauh/commit/f231fa9c69191f23277b4e3319f6b675bfa0ee42) it is also possible to pass optional parameters to a `gcode_shell_command`. As of commit [f231fa9](https://github.com/dw-0/kiauh/commit/f231fa9c69191f23277b4e3319f6b675bfa0ee42) it is also possible to pass optional parameters to a `gcode_shell_command`.
The following short example shows storing the extruder temperature into a variable, passing that value with a parameter to a `gcode_shell_command`, which then, The following short example shows storing the extruder temperature into a variable, passing that value with a parameter to a `gcode_shell_command`, which then,
once the gcode_macro runs and the gcode_shell_command gets called, executes the `script.sh`. The script then echoes a message to the console (if `verbose: True`) once the gcode_macro runs and the gcode_shell_command gets called, executes the `script.sh`. The script then echoes a message to the console (if `verbose: True`)
and writes the value of the parameter into a textfile called `test.txt` located in the home directory. and writes the value of the parameter into a textfile called `test.txt` located in the home directory.

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#

View File

@@ -1,7 +1,11 @@
[mcu] [mcu]
serial: /dev/serial/by-id/<your-mcu-id> serial: /dev/serial/by-id/<your-mcu-id>
[virtual_sdcard]
path: %GCODES_DIR%
on_error_gcode: CANCEL_PRINT
[printer] [printer]
kinematics: none kinematics: none
max_velocity: 1000 max_velocity: 1000
max_accel: 1000 max_accel: 1000

View File

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

1
resources/klipper.env Normal file
View File

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

View File

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

View File

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

View File

@@ -0,0 +1 @@
TELEGRAM_BOT_ARGS="%TELEGRAM_BOT_DIR%/bot/main.py -c %CFG% -l %LOG%"

View File

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

View File

@@ -1,7 +1,6 @@
[server] [server]
host: 0.0.0.0 host: 0.0.0.0
port: %PORT% port: %PORT%
enable_debug_logging: False
klippy_uds_address: %UDS% klippy_uds_address: %UDS%
[authorization] [authorization]
@@ -15,19 +14,12 @@ trusted_clients:
FE80::/10 FE80::/10
::1/128 ::1/128
cors_domains: cors_domains:
http://*.lan *.lan
http://*.local *.local
https://my.mainsail.xyz *://localhost
http://my.mainsail.xyz *://localhost:*
https://app.fluidd.xyz *://my.mainsail.xyz
http://app.fluidd.xyz *://app.fluidd.xyz
[database]
database_path: %DB%
[file_manager]
config_path: %CFG%
log_path: %LOG%
[octoprint_compat] [octoprint_compat]

1
resources/moonraker.env Normal file
View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -31,21 +31,30 @@ function backup_before_update() {
backup_"${1}" backup_"${1}"
} }
function backup_klipper_config_dir() { function backup_config_dir() {
check_for_backup_dir check_for_backup_dir
local current_date config_folder_name local current_date config_pathes
if [[ -d "${KLIPPER_CONFIG}" ]]; then config_pathes=$(get_config_folders)
if [[ -n "${config_pathes}" ]]; then
current_date=$(get_date) current_date=$(get_date)
config_folder_name="$(echo "${KLIPPER_CONFIG}" | rev | cut -d"/" -f1 | rev)"
status_msg "Timestamp: ${current_date}" status_msg "Timestamp: ${current_date}"
status_msg "Create backup of the Klipper config directory ..."
mkdir -p "${BACKUP_DIR}/${config_folder_name}/${current_date}" local i=0 folder folder_name target_dir
cp -r "${KLIPPER_CONFIG}" "${_}" for folder in ${config_pathes}; do
if [[ -d ${folder} ]]; then
print_confirm "Configuration directory backup complete!" status_msg "Create backup of ${folder} ..."
folder_name=$(echo "${folder}" | rev | cut -d"/" -f2 | rev)
target_dir="${BACKUP_DIR}/configs/${current_date}/${folder_name}"
mkdir -p "${target_dir}"
cp -r "${folder}" "${target_dir}"
i=$(( i + 1 ))
ok_msg "Backup created in:\n${target_dir}"
fi
done
else else
ok_msg "No config directory found! Skipping backup ..." ok_msg "No config directory found! Skipping backup ..."
fi fi
@@ -53,27 +62,29 @@ function backup_klipper_config_dir() {
function backup_moonraker_database() { function backup_moonraker_database() {
check_for_backup_dir check_for_backup_dir
local current_date databases target_dir regex=".moonraker_database(_[0-9a-zA-Z]+)?" local current_date db_pathes
databases=$(find "${HOME}" -maxdepth 1 -type d -regextype posix-extended -regex "${HOME}/${regex}" | sort)
if [[ -n ${databases} ]]; then db_pathes=$(get_instance_folder_path "database")
if [[ -n ${db_pathes} ]]; then
current_date=$(get_date) current_date=$(get_date)
target_dir="${BACKUP_DIR}/moonraker_database_backup/${current_date}"
status_msg "Timestamp: ${current_date}" status_msg "Timestamp: ${current_date}"
mkdir -p "${target_dir}"
for database in ${databases}; do local i=0 database folder_name target_dir
for database in ${db_pathes}; do
status_msg "Create backup of ${database} ..." status_msg "Create backup of ${database} ..."
cp -r "${database}" "${target_dir}"
ok_msg "Done!"
done
print_confirm "Moonraker database backup complete!" folder_name=$(echo "${database}" | rev | cut -d"/" -f2 | rev)
target_dir="${BACKUP_DIR}/moonraker_databases/${current_date}/${folder_name}"
mkdir -p "${target_dir}"
cp -r "${database}" "${target_dir}"
i=$(( i + 1 ))
ok_msg "Backup created in:\n${target_dir}"
done
else else
print_error "No Moonraker database found! Skipping backup ..." print_error "No Moonraker database found! Skipping backup ..."
fi fi
return
} }
function backup_klipper() { function backup_klipper() {
@@ -186,3 +197,19 @@ function backup_telegram_bot() {
print_error "Can't back up MoonrakerTelegramBot directory!\n Not found!" print_error "Can't back up MoonrakerTelegramBot directory!\n Not found!"
fi fi
} }
function backup_octoeverywhere() {
local current_date
if [[ -d ${OCTOEVERYWHERE_DIR} ]] ; then
status_msg "Creating OctoEverywhere backup ..."
check_for_backup_dir
current_date=$(get_date)
status_msg "Timestamp: ${current_date}"
mkdir -p "${BACKUP_DIR}/OctoEverywhere-backups/${current_date}"
cp -r "${OCTOEVERYWHERE_DIR}" "${_}" && cp -r "${OCTOEVERYWHERE_ENV}" "${_}"
print_confirm "OctoEverywhere backup complete!"
else
print_error "Can't back up OctoEverywhere directory!\n Not found!"
fi
}

235
scripts/crowsnest.sh Normal file
View File

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

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -52,16 +52,57 @@ function init_flash_process() {
esac esac
done done
### step 2: select how the mcu is connected to the host ### step 2: select how the mcu is flashed (flash/serialflash)
select_flash_command
### step 3: select how the mcu is connected to the host
select_mcu_connection select_mcu_connection
### step 3: select which detected mcu should be flashed ### step 4: select which detected mcu should be flashed
select_mcu_id "${method}" select_mcu_id "${method}"
} }
#================================================# #================================================#
#=================== STEP 2 =====================# #=================== STEP 2 =====================#
#================================================# #================================================#
function select_flash_command() {
unset flash_command
top_border
echo -e "| How to flash MCU? |"
echo -e "| 1) make flash (default) |"
echo -e "| 2) make serialflash (stm32flash) |"
blank_line
back_help_footer
local choice
while true; do
read -p "${cyan}###### Flashing command:${white} " -i "1" -e choice
case "${choice}" in
1)
select_msg "Selected 'make flash' command"
flash_command="flash"
break;;
2)
select_msg "Selected 'make serialflash' command"
flash_command="serialflash"
break;;
B|b)
advanced_menu
break;;
H|h)
clear && print_header
show_mcu_flash_command_help
break;;
*)
error_msg "Invalid command!";;
esac
done
}
#================================================#
#=================== STEP 3 =====================#
#================================================#
function select_mcu_connection() { function select_mcu_connection() {
top_border top_border
echo -e "| ${yellow}Make sure that the controller board is connected now!${white} |" echo -e "| ${yellow}Make sure that the controller board is connected now!${white} |"
@@ -70,6 +111,7 @@ function select_mcu_connection() {
echo -e "| How is the controller board connected to the host? |" echo -e "| How is the controller board connected to the host? |"
echo -e "| 1) USB |" echo -e "| 1) USB |"
echo -e "| 2) UART |" echo -e "| 2) UART |"
echo -e "| 3) USB (DFU mode) |"
blank_line blank_line
back_help_footer back_help_footer
@@ -85,6 +127,10 @@ function select_mcu_connection() {
status_msg "Identifying MCU possibly connected via UART ...\n" status_msg "Identifying MCU possibly connected via UART ...\n"
get_uart_id || true # continue even after exit code 1 get_uart_id || true # continue even after exit code 1
break;; break;;
3)
status_msg "Identifying MCU connected via USB in DFU mode ...\n"
get_dfu_id || true # continue even after exit code 1
break;;
B|b) B|b)
advanced_menu advanced_menu
break;; break;;
@@ -107,7 +153,6 @@ function print_detected_mcu_to_screen() {
fi fi
for mcu in "${mcu_list[@]}"; do for mcu in "${mcu_list[@]}"; do
mcu=$(echo "${mcu}" | rev | cut -d"/" -f1 | rev)
echo -e " ● MCU #${i}: ${cyan}${mcu}${white}" echo -e " ● MCU #${i}: ${cyan}${mcu}${white}"
i=$(( i + 1 )) i=$(( i + 1 ))
done done
@@ -115,7 +160,7 @@ function print_detected_mcu_to_screen() {
} }
#================================================# #================================================#
#=================== STEP 3 =====================# #=================== STEP 4 =====================#
#================================================# #================================================#
function select_mcu_id() { function select_mcu_id() {
local i=0 sel_index=0 method=${1} local i=0 sel_index=0 method=${1}
@@ -190,7 +235,7 @@ function start_flash_mcu() {
local device=${1} local device=${1}
do_action_service "stop" "klipper" do_action_service "stop" "klipper"
if make flash FLASH_DEVICE="${device}"; then if make ${flash_command} FLASH_DEVICE="${device}"; then
ok_msg "Flashing successfull!" ok_msg "Flashing successfull!"
else else
warn_msg "Flashing failed!" warn_msg "Flashing failed!"
@@ -329,6 +374,16 @@ function get_uart_id() {
done done
} }
function get_dfu_id() {
unset mcu_list
sleep 1
mcus=$(lsusb | grep "DFU" | cut -d " " -f 6 2>/dev/null)
for mcu in ${mcus}; do
mcu_list+=("${mcu}")
done
}
function show_flash_method_help() { function show_flash_method_help() {
top_border top_border
echo -e "| ~~~~~~~~ < ? > Help: Flash MCU < ? > ~~~~~~~~ |" echo -e "| ~~~~~~~~ < ? > Help: Flash MCU < ? > ~~~~~~~~ |"
@@ -372,6 +427,36 @@ function show_flash_method_help() {
done done
} }
function show_mcu_flash_command_help() {
top_border
echo -e "| ~~~~~~~~ < ? > Help: Flash MCU < ? > ~~~~~~~~ |"
hr
echo -e "| ${cyan}make flash:${white} |"
echo -e "| The default command to flash controller board, it |"
echo -e "| will detect selected microcontroller and use suitable |"
echo -e "| tool for flashing it. |"
blank_line
echo -e "| ${cyan}make serialflash:${white} |"
echo -e "| Special command to flash STM32 microcontrollers in |"
echo -e "| DFU mode but connected via serial. stm32flash command |"
echo -e "| will be used internally. |"
blank_line
back_footer
local choice
while true; do
read -p "${cyan}###### Please select:${white} " choice
case "${choice}" in
B|b)
clear && print_header
select_flash_command
break;;
*)
error_msg "Invalid command!";;
esac
done
}
function show_mcu_connection_help() { function show_mcu_connection_help() {
top_border top_border
echo -e "| ~~~~~~~~ < ? > Help: Flash MCU < ? > ~~~~~~~~ |" echo -e "| ~~~~~~~~ < ? > Help: Flash MCU < ? > ~~~~~~~~ |"
@@ -406,4 +491,4 @@ function show_mcu_connection_help() {
error_msg "Invalid command!";; error_msg "Invalid command!";;
esac esac
done done
} }

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -16,21 +16,35 @@ set -e
#===================================================# #===================================================#
function install_fluidd() { function install_fluidd() {
### exit early if moonraker not found
if [[ -z $(moonraker_systemd) ]]; then if [[ -z $(moonraker_systemd) ]]; then
local error="Moonraker not installed! Please install Moonraker first!" local error="Moonraker not installed! It's recommended to install Moonraker first!"
print_error "${error}" && return print_error "${error}"
while true; do
local yn
read -p "${cyan}###### Proceed to install Fluidd without installing Moonraker? (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 Fluidd setup ...\n"
return;;
*)
error_msg "Invalid Input!";;
esac
done
fi fi
### checking dependencies ### checking dependencies
local dep=(wget nginx) local dep=(wget nginx unzip)
dependency_check "${dep[@]}" dependency_check "${dep[@]}"
### detect conflicting Haproxy and Apache2 installations ### detect conflicting Haproxy and Apache2 installations
detect_conflicting_packages detect_conflicting_packages
status_msg "Initializing Fluidd installation ..." status_msg "Initializing Fluidd installation ..."
### first, we create a backup of the full klipper_config dir - safety first! ### first, we create a backup of the full klipper_config dir - safety first!
backup_klipper_config_dir backup_config_dir
### check for other enabled web interfaces ### check for other enabled web interfaces
unset SET_LISTEN_PORT unset SET_LISTEN_PORT
@@ -39,30 +53,6 @@ function install_fluidd() {
### check if another site already listens to port 80 ### check if another site already listens to port 80
fluidd_port_check fluidd_port_check
### ask user to install mjpg-streamer
local install_mjpg_streamer
if [[ ! -f "${SYSTEMD}/webcamd.service" ]]; then
while true; do
echo
top_border
echo -e "| Install MJPG-Streamer for webcam support? |"
bottom_border
read -p "${cyan}###### Please select (y/N):${white} " yn
case "${yn}" in
Y|y|Yes|yes)
select_msg "Yes"
install_mjpg_streamer="true"
break;;
N|n|No|no|"")
select_msg "No"
install_mjpg_streamer="false"
break;;
*)
error_msg "Invalid command!";;
esac
done
fi
### download fluidd ### download fluidd
download_fluidd download_fluidd
@@ -82,9 +72,6 @@ function install_fluidd() {
### add fluidd to the update manager in moonraker.conf ### add fluidd to the update manager in moonraker.conf
patch_fluidd_update_manager patch_fluidd_update_manager
### install mjpg-streamer
[[ ${install_mjpg_streamer} == "true" ]] && install_mjpg-streamer
fetch_webui_ports #WIP fetch_webui_ports #WIP
### confirm message ### confirm message
@@ -92,22 +79,21 @@ function install_fluidd() {
} }
function install_fluidd_macros() { function install_fluidd_macros() {
local yn
while true; do while true; do
echo echo
top_border top_border
echo -e "| It is recommended to have some important macros in |" echo -e "| It is recommended to use special macros in order to |"
echo -e "| your printer configuration to have Fluidd fully |" echo -e "| have Fluidd fully functional and working. |"
echo -e "| functional and working. |"
blank_line blank_line
echo -e "| The recommended macros for Fluidd can be found here: |" echo -e "| The recommended macros for Fluidd can be found here: |"
echo -e "| https://docs.fluidd.xyz/configuration/initial_setup |" echo -e "| https://github.com/fluidd-core/fluidd-config |"
blank_line blank_line
echo -e "| If you already have these macros in your config file, |" echo -e "| If you already use these macros skip this step. |"
echo -e "| skip this step and answer with 'no'. |"
echo -e "| Otherwise you should consider to answer with 'yes' to |" echo -e "| Otherwise you should consider to answer with 'yes' to |"
echo -e "| add the recommended example macros to your config. |" echo -e "| download the recommended macros. |"
bottom_border bottom_border
read -p "${cyan}###### Add the recommended macros? (Y/n):${white} " yn read -p "${cyan}###### Download the recommended macros? (Y/n):${white} " yn
case "${yn}" in case "${yn}" in
Y|y|Yes|yes|"") Y|y|Yes|yes|"")
select_msg "Yes" select_msg "Yes"
@@ -124,34 +110,64 @@ function install_fluidd_macros() {
} }
function download_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 ms_cfg_repo path configs regex line gcode_dir
local configs path
configs=$(find "${KLIPPER_CONFIG}" -type f -name "printer.cfg" | sort)
if [[ -n ${configs} ]]; then ms_cfg_repo="https://github.com/fluidd-core/fluidd-config.git"
for config in ${configs}; do regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/printer\.cfg"
path=$(echo "${config}" | rev | cut -d"/" -f2- | rev) configs=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ ! -f "${path}/fluidd.cfg" ]]; then
status_msg "Downloading fluidd.cfg to ${path} ..."
log_info "downloading fluidd.cfg to: ${path}"
wget "${fluidd_cfg}" -O "${path}/fluidd.cfg"
### replace user 'pi' with current username to prevent issues in cases where the user is not called 'pi' if [[ -z ${configs} ]]; then
log_info "modify fluidd.cfg" print_error "No printer.cfg found! Installation of Macros will be skipped ..."
sed -i "/^path: \/home\/pi\/gcode_files/ s/\/home\/pi/\/home\/${USER}/" "${path}/fluidd.cfg"
### write include to the very first line of the printer.cfg
if ! grep -Eq "^[include fluidd.cfg]$" "${path}/printer.cfg"; then
log_info "modify printer.cfg"
sed -i "1 i [include fluidd.cfg]" "${path}/printer.cfg"
fi
ok_msg "Done!"
fi
done
else
log_error "execution stopped! reason: no printer.cfg found" log_error "execution stopped! reason: no printer.cfg found"
return return
fi fi
status_msg "Cloning fluidd-config ..."
[[ -d "${HOME}/fluidd-config" ]] && rm -rf "${HOME}/fluidd-config"
if git clone --recurse-submodules "${ms_cfg_repo}" "${HOME}/fluidd-config"; then
for config in ${configs}; do
path=$(echo "${config}" | rev | cut -d"/" -f2- | rev)
if [[ -e "${path}/fluidd.cfg" && ! -h "${path}/fluidd.cfg" ]]; then
warn_msg "Attention! Existing fluidd.cfg detected!"
warn_msg "The file will be renamed to 'fluidd.bak.cfg' to be able to continue with the installation."
if ! mv "${path}/fluidd.cfg" "${path}/fluidd.bak.cfg"; then
error_msg "Renaming fluidd.cfg failed! Aborting installation ..."
return
fi
fi
if [[ -h "${path}/fluidd.cfg" ]]; then
warn_msg "Recreating symlink in ${path} ..."
rm -rf "${path}/fluidd.cfg"
fi
if ! ln -sf "${HOME}/fluidd-config/client.cfg" "${path}/fluidd.cfg"; then
error_msg "Creating symlink failed! Aborting installation ..."
return
fi
if ! grep -Eq "^\[include fluidd.cfg\]$" "${path}/printer.cfg"; then
log_info "${path}/printer.cfg"
sed -i "1 i [include fluidd.cfg]" "${path}/printer.cfg"
fi
line=$(($(grep -n "\[include fluidd.cfg\]" "${path}/printer.cfg" | tail -1 | cut -d: -f1) + 1))
gcode_dir=${path/config/gcodes}
if ! grep -Eq "^\[virtual_sdcard\]$" "${path}/printer.cfg"; then
log_info "${path}/printer.cfg"
sed -i "${line} i \[virtual_sdcard]\npath: ${gcode_dir}\non_error_gcode: CANCEL_PRINT\n" "${path}/printer.cfg"
fi
done
else
print_error "Cloning failed! Aborting installation ..."
log_error "execution stopped! reason: cloning failed"
return
fi
patch_fluidd_config_update_manager
ok_msg "Done!"
} }
function download_fluidd() { function download_fluidd() {
@@ -189,7 +205,7 @@ function remove_fluidd_dir() {
rm -rf "${FLUIDD_DIR}" && ok_msg "Directory removed!" rm -rf "${FLUIDD_DIR}" && ok_msg "Directory removed!"
} }
function remove_fluidd_config() { function remove_fluidd_nginx_config() {
if [[ -e "/etc/nginx/sites-available/fluidd" ]]; then if [[ -e "/etc/nginx/sites-available/fluidd" ]]; then
status_msg "Removing Fluidd configuration for Nginx ..." status_msg "Removing Fluidd configuration for Nginx ..."
sudo rm "/etc/nginx/sites-available/fluidd" && ok_msg "File removed!" sudo rm "/etc/nginx/sites-available/fluidd" && ok_msg "File removed!"
@@ -214,8 +230,10 @@ function remove_fluidd_logs() {
} }
function remove_fluidd_log_symlinks() { function remove_fluidd_log_symlinks() {
local files local files regex
files=$(find "${KLIPPER_LOGS}" -name "fluidd*" 2> /dev/null | sort)
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/logs\/fluidd-.*"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" 2> /dev/null | sort)
if [[ -n ${files} ]]; then if [[ -n ${files} ]]; then
for file in ${files}; do for file in ${files}; do
@@ -226,11 +244,34 @@ function remove_fluidd_log_symlinks() {
fi fi
} }
function remove_legacy_fluidd_log_symlinks() {
local files
files=$(find "${HOME}/klipper_logs" -name "fluidd*" 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_fluidd_config() {
if [[ -d "${HOME}/fluidd-config" ]]; then
status_msg "Removing ${HOME}/fluidd-config ..."
rm -rf "${HOME}/fluidd-config"
ok_msg "${HOME}/fluidd-config removed!"
print_confirm "Fluidd-Config successfully removed!"
fi
}
function remove_fluidd() { function remove_fluidd() {
remove_fluidd_dir remove_fluidd_dir
remove_fluidd_config remove_fluidd_nginx_config
remove_fluidd_logs remove_fluidd_logs
remove_fluidd_log_symlinks remove_fluidd_log_symlinks
remove_legacy_fluidd_log_symlinks
### remove fluidd_port from ~/.kiauh.ini ### remove fluidd_port from ~/.kiauh.ini
sed -i "/^fluidd_port=/d" "${INI_FILE}" sed -i "/^fluidd_port=/d" "${INI_FILE}"
@@ -276,19 +317,25 @@ function get_fluidd_status() {
} }
function get_local_fluidd_version() { function get_local_fluidd_version() {
[[ ! -f "${FLUIDD_DIR}/.version" ]] && return local versionfile="${FLUIDD_DIR}/.version"
local relinfofile="${FLUIDD_DIR}/release_info.json"
local version local version
version=$(head -n 1 "${FLUIDD_DIR}/.version")
if [[ -f ${relinfofile} ]]; then
version=$(grep -o '"version":"[^"]*' "${relinfofile}" | grep -o '[^"]*$')
elif [[ -f ${versionfile} ]]; then
version=$(head -n 1 "${versionfile}")
fi
echo "${version}" echo "${version}"
} }
function get_remote_fluidd_version() { function get_remote_fluidd_version() {
[[ ! $(dpkg-query -f'${Status}' --show curl 2>/dev/null) = *\ installed ]] && return [[ ! $(dpkg-query -f'${Status}' --show curl 2>/dev/null) = *\ installed ]] && return
local version local tags
version=$(get_fluidd_download_url | rev | cut -d"/" -f2 | rev) tags=$(curl -s "https://api.github.com/repos/fluidd-core/fluidd/tags" | grep "name" | cut -d'"' -f4)
echo "${version}" echo "${tags}" | head -1
} }
function compare_fluidd_versions() { function compare_fluidd_versions() {
@@ -314,25 +361,28 @@ function compare_fluidd_versions() {
#================================================# #================================================#
function get_fluidd_download_url() { function get_fluidd_download_url() {
local tags latest_tag latest_url stable_tag stable_url url local releases_by_tag tags tag unstable_url url
tags=$(curl -s "${FLUIDD_TAGS}" | grep "name" | cut -d'"' -f4)
### latest download url including pre-releases (alpha, beta, rc) ### latest stable download url
latest_tag=$(echo "${tags}" | head -1) url="https://github.com/fluidd-core/fluidd/releases/latest/download/fluidd.zip"
latest_url="https://github.com/fluidd-core/fluidd/releases/download/${latest_tag}/fluidd.zip"
### get stable fluidd download url
stable_tag=$(echo "${tags}" | grep -E "^v([0-9]+\.?){3}$" | head -1)
stable_url="https://github.com/fluidd-core/fluidd/releases/download/${stable_tag}/fluidd.zip"
read_kiauh_ini "${FUNCNAME[0]}" read_kiauh_ini "${FUNCNAME[0]}"
if [[ ${fluidd_install_unstable} == "true" ]]; then if [[ ${fluidd_install_unstable} == "true" ]]; then
url="${latest_url}" releases_by_tag="https://api.github.com/repos/fluidd-core/fluidd/tags"
echo "${url}" tags=$(curl -s "${releases_by_tag}" | grep "name" | cut -d'"' -f4)
else tag=$(echo "${tags}" | head -1)
url="${stable_url}"
echo "${url}" ### latest unstable download url including pre-releases (alpha, beta, rc)
unstable_url="https://github.com/fluidd-core/fluidd/releases/download/${tag}/fluidd.zip"
if [[ ${unstable_url} == *"download//"* ]]; then
warn_msg "Download URL broken! Falling back to URL of latest stable release!"
else
url=${unstable_url}
fi
fi fi
echo "${url}"
} }
function fluidd_port_check() { function fluidd_port_check() {
@@ -369,7 +419,7 @@ function select_fluidd_port() {
blank_line blank_line
[[ ${MAINSAIL_PORT} == "80" ]] && echo "| ● Mainsail |" [[ ${MAINSAIL_PORT} == "80" ]] && echo "| ● Mainsail |"
blank_line blank_line
echo -e "| Make sure you don't choose a port which is already |" echo -e "| Make sure you don't choose a port which was already |"
echo -e "| assigned to another webinterface! |" echo -e "| assigned to another webinterface! |"
blank_line blank_line
echo -e "| Be aware: there is ${red}NO${white} sanity check for the following |" echo -e "| Be aware: there is ${red}NO${white} sanity check for the following |"
@@ -395,12 +445,13 @@ function select_fluidd_port() {
} }
function patch_fluidd_update_manager() { function patch_fluidd_update_manager() {
local patched="false" local patched moonraker_configs regex
local moonraker_configs regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/moonraker\.conf"
moonraker_configs=$(find "${KLIPPER_CONFIG}" -type f -name "moonraker.conf" | sort) moonraker_configs=$(find "${HOME}" -maxdepth 3 -type f -regextype posix-extended -regex "${regex}" | sort)
patched="false"
for conf in ${moonraker_configs}; do for conf in ${moonraker_configs}; do
if ! grep -Eq "^\[update_manager fluidd\]$" "${conf}"; then if ! grep -Eq "^\[update_manager fluidd\]\s*$" "${conf}"; then
### add new line to conf if it doesn't end with one ### add new line to conf if it doesn't end with one
[[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}" [[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"
@@ -424,3 +475,36 @@ MOONRAKER_CONF
do_action_service "restart" "moonraker" do_action_service "restart" "moonraker"
fi fi
} }
function patch_fluidd_config_update_manager() {
local patched moonraker_configs regex
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/moonraker\.conf"
moonraker_configs=$(find "${HOME}" -maxdepth 3 -type f -regextype posix-extended -regex "${regex}" | sort)
patched="false"
for conf in ${moonraker_configs}; do
if ! grep -Eq "^\[update_manager fluidd-config\]\s*$" "${conf}"; then
### add new line to conf if it doesn't end with one
[[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"
### add Fluidds update manager section to moonraker.conf
status_msg "Adding Fluidd-Config to update manager in file:\n ${conf}"
/bin/sh -c "cat >> ${conf}" << MOONRAKER_CONF
[update_manager fluidd-config]
type: git_repo
primary_branch: master
path: ~/fluidd-config
origin: https://github.com/fluidd-core/fluidd-config.git
managed_services: klipper
MOONRAKER_CONF
fi
patched="true"
done
if [[ ${patched} == "true" ]]; then
do_action_service "restart" "moonraker"
fi
}

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -103,12 +103,13 @@ function install_gcode_shell_command() {
function create_example_shell_command() { function create_example_shell_command() {
### create a backup of the config folder ### create a backup of the config folder
backup_klipper_config_dir backup_config_dir
local printer_cfgs path local configs regex path
printer_cfgs=$(find "$(get_klipper_cfg_dir)" -type f -name "printer.cfg" | sort) regex="${HOME//\//\\/}\/([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) path=$(echo "${cfg}" | rev | cut -d"/" -f2- | rev)
if [[ ! -f "${path}/shell_command.cfg" ]]; then if [[ ! -f "${path}/shell_command.cfg" ]]; then
@@ -119,4 +120,4 @@ function create_example_shell_command() {
sed -i "1 i [include shell_command.cfg]" "${cfg}" sed -i "1 i [include shell_command.cfg]" "${cfg}"
fi fi
done done
} }

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -34,8 +34,6 @@ function set_globals() {
KLIPPY_ENV="${HOME}/klippy-env" KLIPPY_ENV="${HOME}/klippy-env"
KLIPPER_DIR="${HOME}/klipper" KLIPPER_DIR="${HOME}/klipper"
KLIPPER_REPO="https://github.com/Klipper3d/klipper.git" 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 ==================#
MOONRAKER_ENV="${HOME}/moonraker-env" MOONRAKER_ENV="${HOME}/moonraker-env"
@@ -44,13 +42,9 @@ function set_globals() {
#================= MAINSAIL ===================# #================= MAINSAIL ===================#
MAINSAIL_DIR="${HOME}/mainsail" MAINSAIL_DIR="${HOME}/mainsail"
MAINSAIL_REPO_API="https://api.github.com/repos/mainsail-crew/mainsail/releases"
MAINSAIL_TAGS="https://api.github.com/repos/mainsail-crew/mainsail/tags"
#================== FLUIDD ====================# #================== FLUIDD ====================#
FLUIDD_DIR="${HOME}/fluidd" FLUIDD_DIR="${HOME}/fluidd"
FLUIDD_REPO_API="https://api.github.com/repos/fluidd-core/fluidd/releases"
FLUIDD_TAGS="https://api.github.com/repos/fluidd-core/fluidd/tags"
#=============== KLIPPERSCREEN ================# #=============== KLIPPERSCREEN ================#
KLIPPERSCREEN_ENV="${HOME}/.KlipperScreen-env" KLIPPERSCREEN_ENV="${HOME}/.KlipperScreen-env"
@@ -74,4 +68,23 @@ function set_globals() {
#=============== MOONRAKER-OBICO ================# #=============== MOONRAKER-OBICO ================#
MOONRAKER_OBICO_DIR="${HOME}/moonraker-obico" MOONRAKER_OBICO_DIR="${HOME}/moonraker-obico"
MOONRAKER_OBICO_REPO="https://github.com/TheSpaghettiDetective/moonraker-obico.git" MOONRAKER_OBICO_REPO="https://github.com/TheSpaghettiDetective/moonraker-obico.git"
#=============== OCTOEVERYWHERE ================#
OCTOEVERYWHERE_ENV="${HOME}/octoeverywhere-env"
OCTOEVERYWHERE_DIR="${HOME}/octoeverywhere"
OCTOEVERYWHERE_REPO="https://github.com/QuinnDamerell/OctoPrint-OctoEverywhere.git"
#=============== Crowsnest ================#
CROWSNEST_DIR="${HOME}/crowsnest"
CROWSNEST_REPO="https://github.com/mainsail-crew/crowsnest.git"
#=============== Mobileraker ================#
MOBILERAKER_ENV="${HOME}/mobileraker-env"
MOBILERAKER_DIR="${HOME}/mobileraker_companion"
MOBILERAKER_REPO="https://github.com/Clon1998/mobileraker_companion.git"
#=============== OCTOAPP ================#
OCTOAPP_ENV="${HOME}/octoapp-env"
OCTOAPP_DIR="${HOME}/octoapp"
OCTOAPP_REPO="https://github.com/crysxd/OctoApp-Plugin.git"
} }

View File

@@ -1,52 +1,64 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
set -e set -e
#TODO (multi instance):
# if the klipper installer is started another time while other klipper
# instances are detected, ask if new instances should be added
#=================================================# #=================================================#
#================ INSTALL KLIPPER ================# #================ INSTALL KLIPPER ================#
#=================================================# #=================================================#
### check for existing klipper service installations ###
function klipper_initd() { # this function detects all installed klipper
local services # systemd instances and returns their absolute path
services=$(find "${INITD}" -maxdepth 1 -regextype posix-extended -regex "${INITD}/klipper(-[^0])?[0-9]*" | sort)
echo "${services}"
}
function klipper_systemd() { function klipper_systemd() {
local services local services
services=$(find "${SYSTEMD}" -maxdepth 1 -regextype posix-extended -regex "${SYSTEMD}/klipper(-[0-9a-zA-Z]+)?.service" | sort) local blacklist
local ignore
local match
###
# any service that uses "klipper" in its own name but isn't a full klipper service must be blacklisted using
# this variable, otherwise they will be falsely recognized as klipper instances. E.g. "klipper-mcu.service"
# is not a klipper service, but related to klippers linux mcu, which also requires its own service file, hence
# it must be blacklisted.
blacklist="mcu"
ignore="${SYSTEMD}/klipper-(${blacklist}).service"
match="${SYSTEMD}/klipper(-[0-9a-zA-Z]+)?.service"
services=$(find "${SYSTEMD}" -maxdepth 1 -regextype awk ! -regex "${ignore}" -regex "${match}" | sort)
echo "${services}" echo "${services}"
} }
function klipper_setup_dialog() { function start_klipper_setup() {
status_msg "Initializing Klipper installation ..."
local klipper_initd_service
local klipper_systemd_services local klipper_systemd_services
local python_version="${1}" user_input=() local python_version
local instance_count
local instance_names
local use_custom_names
local input
local regex
local blacklist
local error local error
klipper_initd_service=$(klipper_initd) status_msg "Initializing Klipper installation ...\n"
klipper_systemd_services=$(klipper_systemd)
user_input+=("${python_version}")
### return early if klipper already exists ### return early if klipper already exists
if [[ -n ${klipper_initd_service} ]]; then klipper_systemd_services=$(klipper_systemd)
error="Unsupported Klipper SysVinit service detected:"
error="${error}\n ➔ ${klipper_initd_service}" if [[ -n ${klipper_systemd_services} ]]; then
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:" error="At least one Klipper service is already installed:"
for s in ${klipper_systemd_services}; do for s in ${klipper_systemd_services}; do
@@ -54,10 +66,118 @@ function klipper_setup_dialog() {
error="${error}\n ➔ ${s}" error="${error}\n ➔ ${s}"
done done
fi fi
[[ -n ${error} ]] && print_error "${error}" && return [[ -n ${error} ]] && print_error "${error}" && return
### ask for amount of instances to create ### user selection for python version
print_dialog_user_select_python_version
while true; do
read -p "${cyan}###### Select Python version:${white} " -i "1" -e input
case "${input}" in
1)
select_msg "Python 3.x\n"
python_version=3
break;;
2)
select_msg "Python 2.7\n"
python_version=2
break;;
B|b)
clear; install_menu; break;;
*)
error_msg "Invalid Input!\n";;
esac
done && input=""
### user selection for instance count
print_dialog_user_select_instance_count
regex="^[1-9][0-9]*$"
while [[ ! ${input} =~ ${regex} ]]; do
read -p "${cyan}###### Number of Klipper instances to set up:${white} " -i "1" -e input
if [[ ${input} =~ ${regex} ]]; then
instance_count="${input}"
select_msg "Instance count: ${instance_count}\n"
break
elif [[ ${input} == "B" || ${input} == "b" ]]; then
install_menu
else
error_msg "Invalid Input!\n"
fi
done && input=""
### user selection for custom names
use_custom_names="false"
if (( instance_count > 1 )); then
print_dialog_user_select_custom_name_bool
while true; do
read -p "${cyan}###### Assign custom names? (y/N):${white} " input
case "${input}" in
Y|y|Yes|yes)
select_msg "Yes\n"
use_custom_names="true"
break;;
N|n|No|no|"")
select_msg "No\n"
break;;
B|b)
clear; install_menu; break;;
*)
error_msg "Invalid Input!\n";;
esac
done && input=""
else
instance_names+=("printer")
fi
### user selection for setting the actual custom names
shopt -s nocasematch
if (( instance_count > 1 )) && [[ ${use_custom_names} == "true" ]]; then
local i
i=1
regex="^[0-9a-zA-Z]+$"
blacklist="mcu"
while [[ ! ${input} =~ ${regex} || ${input} =~ ${blacklist} || ${i} -le ${instance_count} ]]; do
read -p "${cyan}###### Name for instance #${i}:${white} " input
if [[ ${input} =~ ${blacklist} ]]; then
error_msg "Name not allowed! You are trying to use a reserved name."
elif [[ ${input} =~ ${regex} && ! ${input} =~ ${blacklist} ]]; then
select_msg "Name: ${input}\n"
if [[ ${input} =~ ^[0-9]+$ ]]; then
instance_names+=("printer_${input}")
else
instance_names+=("${input}")
fi
i=$(( i + 1 ))
else
error_msg "Invalid Input!\n"
fi
done && input=""
elif (( instance_count > 1 )) && [[ ${use_custom_names} == "false" ]]; then
for (( i=1; i <= instance_count; i++ )); do
instance_names+=("printer_${i}")
done
fi
shopt -u nocasematch
(( instance_count > 1 )) && status_msg "Installing ${instance_count} Klipper instances ..."
(( instance_count == 1 )) && status_msg "Installing single Klipper instance ..."
run_klipper_setup "${python_version}" "${instance_names[@]}"
}
function print_dialog_user_select_python_version() {
top_border
echo -e "| Please select your preferred Python version. | "
echo -e "| The recommended version is Python 3.x. | "
hr
echo -e "| 1) [Python 3.x] (recommended) | "
echo -e "| 2) [Python 2.7] ${yellow}(legacy)${white} | "
back_footer
}
function print_dialog_user_select_instance_count() {
top_border top_border
echo -e "| Please select the number of Klipper instances to set |" echo -e "| Please select the number of Klipper instances to set |"
echo -e "| up. The number of Klipper instances will determine |" echo -e "| up. The number of Klipper instances will determine |"
@@ -65,187 +185,38 @@ function klipper_setup_dialog() {
blank_line blank_line
echo -e "| ${yellow}WARNING:${white} |" echo -e "| ${yellow}WARNING:${white} |"
echo -e "| ${yellow}Setting up too many instances may crash your system.${white} |" echo -e "| ${yellow}Setting up too many instances may crash your system.${white} |"
bottom_border back_footer
### ask for amount of instances
local klipper_count re="^[1-9][0-9]*$"
while [[ ! ${klipper_count} =~ ${re} ]]; do
read -p "${cyan}###### Number of Klipper instances to set up:${white} " -i "1" -e klipper_count
### break if input is valid
[[ ${klipper_count} =~ ${re} ]] && break
### error messages on invalid input
error_msg "Input not a number"
done && select_msg "${klipper_count}"
user_input+=("${klipper_count}")
### confirm instance amount
local yn
while true; do
read -p "${cyan}###### Install ${klipper_count} instance(s)? (Y/n):${white} " yn
case "${yn}" in
Y|y|Yes|yes|"")
select_msg "Yes"
break;;
N|n|No|no)
select_msg "No"
abort_msg "Exiting Klipper setup ...\n"
return;;
*)
error_msg "Invalid Input!";;
esac
done
### ask for custom names
if (( klipper_count > 1 )); then
local custom_names="false"
top_border
echo -e "| You can give each instance a custom name or skip. |"
echo -e "| If skipped, KIAUH will automatically assign an index |"
echo -e "| to each instance in ascending order, starting at '1'. |"
blank_line
echo -e "| Info: |"
echo -e "| Only alphanumeric characters will be allowed. |"
bottom_border
while true; do
read -p "${cyan}###### Use custom names? (y/N):${white} " yn
case "${yn}" in
Y|y|Yes|yes)
select_msg "Yes"
custom_names="true"
break;;
N|n|No|no|"")
select_msg "No"
break;;
*)
error_msg "Invalid Input!";;
esac
done
### get user input for custom names
if [[ ${custom_names} == "true" ]]; then
local i=1 name re="^[0-9a-zA-Z]+$"
while [[ ! ${name} =~ ${re} || ${i} -le ${klipper_count} ]]; do
read -p "${cyan}###### Name for instance #${i}:${white} " name
if [[ ${name} =~ ${re} ]]; then
select_msg "Name: ${name}"
user_input+=("${name}")
i=$(( i + 1 ))
else
error_msg "Invalid Input!"
fi
done
else
### if no custom names are used, add the respective amount of indices to the user_input array
for (( i=1; i <= klipper_count; i++ )); do
user_input+=("${i}")
done
fi
fi
(( klipper_count > 1 )) && status_msg "Installing ${klipper_count} Klipper instances ..."
(( klipper_count == 1 )) && status_msg "Installing single Klipper instance ..."
klipper_setup "${user_input[@]}"
} }
### function print_dialog_user_select_custom_name_bool() {
# extracts the required packages from the top_border
# install-debian.sh script and installs them echo -e "| You can now assign a custom name to each instance. |"
# echo -e "| If skipped, each instance will get an index assigned |"
# @param {string}: python_version - klipper-env python version echo -e "| in ascending order, starting at index '1'. |"
# blank_line
function install_klipper_packages() { echo -e "| Info: |"
local packages python_version="${1}" echo -e "| Only alphanumeric characters for names are allowed! |"
local install_script="${KLIPPER_DIR}/scripts/install-debian.sh" back_footer
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"
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
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 create_klipper_virtualenv() { function run_klipper_setup() {
local python_version="${1}"
[[ ${python_version} == "python2" ]] && \
status_msg "Installing $(python2 -V) virtual environment..."
[[ ${python_version} == "python3" ]] && \
status_msg "Installing $(python3 -V) virtual environment..."
### remove klippy-env if it already exists
[[ -d ${KLIPPY_ENV} ]] && rm -rf "${KLIPPY_ENV}"
if [[ ${python_version} == "python2" ]]; then
if virtualenv -p python2 "${KLIPPY_ENV}"; then
"${KLIPPY_ENV}"/bin/pip install -r "${KLIPPER_DIR}"/scripts/klippy-requirements.txt
else
log_error "failure while creating python2 klippy-env"
error_msg "Creation of Klipper virtualenv failed!"
exit 1
fi
fi
if [[ ${python_version} == "python3" ]]; then
if virtualenv -p python3 "${KLIPPY_ENV}"; then
"${KLIPPY_ENV}"/bin/pip install -U pip
"${KLIPPY_ENV}"/bin/pip install -r "${KLIPPER_DIR}"/scripts/klippy-requirements.txt
else
log_error "failure while creating python3 klippy-env"
error_msg "Creation of Klipper virtualenv failed!"
exit 1
fi
fi
return
}
function klipper_setup() {
read_kiauh_ini "${FUNCNAME[0]}" 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=${1}
local python_version="${user_input[0]}" && unset "user_input[0]" local instance_names
local instance_arr=("${user_input[@]}") && unset "user_input[@]" local confirm
local custom_repo="${custom_klipper_repo}" local custom_repo
local custom_branch="${custom_klipper_repo_branch}" local custom_branch
local dep
shift 1
read -r -a instance_names <<< "${@}"
custom_repo="${custom_klipper_repo}"
custom_branch="${custom_klipper_repo_branch}"
dep=(git)
### checking dependencies ### checking dependencies
local dep=(git)
dependency_check "${dep[@]}" dependency_check "${dep[@]}"
### step 1: clone klipper ### step 1: clone klipper
@@ -255,24 +226,25 @@ function klipper_setup() {
install_klipper_packages "${python_version}" install_klipper_packages "${python_version}"
create_klipper_virtualenv "${python_version}" create_klipper_virtualenv "${python_version}"
### step 3: create gcode_files and logs folder ### step 3: create klipper instances
[[ ! -d "${HOME}/gcode_files" ]] && mkdir -p "${HOME}/gcode_files" for instance in "${instance_names[@]}"; do
[[ ! -d ${KLIPPER_LOGS} ]] && mkdir -p "${KLIPPER_LOGS}" create_klipper_service "${instance}"
done
### step 4: create klipper instances ### step 4: enable and start all instances
create_klipper_service "${instance_arr[@]}"
### step 5: enable and start all instances
do_action_service "enable" "klipper" do_action_service "enable" "klipper"
do_action_service "start" "klipper" do_action_service "start" "klipper"
### step 6: check for dialout group membership ### step 5: check for dialout group membership
check_usergroups check_usergroups
### confirm message ### confirm message
local confirm="" (( ${#instance_names[@]} == 1 )) && confirm="Klipper has been set up!"
(( instance_arr[0] == 1 )) && confirm="Klipper has been set up!" (( ${#instance_names[@]} > 1 )) && confirm="${#instance_names[@]} Klipper instances have been set up!"
(( instance_arr[0] > 1 )) && confirm="${instance_arr[0]} Klipper instances have been set up!"
### finalizing the setup with writing instance names to the kiauh.ini
set_multi_instance_names
mask_disrupting_services
print_confirm "${confirm}" && return print_confirm "${confirm}" && return
} }
@@ -300,81 +272,129 @@ function clone_klipper() {
fi fi
} }
function write_klipper_service() { function create_klipper_virtualenv() {
local i=${1} cfg=${2} log=${3} printer=${4} uds=${5} service=${6} local python_version="${1}"
local service_template="${KIAUH_SRCDIR}/resources/klipper.service"
[[ -d ${KLIPPY_ENV} ]] && rm -rf "${KLIPPY_ENV}"
status_msg "Installing $("python${python_version}" -V) virtual environment..."
if virtualenv -p "python${python_version}" "${KLIPPY_ENV}"; then
(( python_version == 3 )) && "${KLIPPY_ENV}"/bin/pip install -U pip
"${KLIPPY_ENV}"/bin/pip install -r "${KLIPPER_DIR}"/scripts/klippy-requirements.txt
else
log_error "failure while creating python3 klippy-env"
error_msg "Creation of Klipper virtualenv failed!"
exit 1
fi
}
###
# 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 log_name="Klipper" python_version="${1}"
local install_script="${KLIPPER_DIR}/scripts/install-debian.sh"
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"
if (( python_version == 3 )); then
### replace python-dev with python3-dev if python3 was selected
packages="${packages//python-dev/python3-dev}"
elif (( python_version == 2 )); then
### package name 'python-dev' is deprecated (-> no installation candidate) on more modern linux distros
packages="${packages//python-dev/python2-dev}"
else
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 lists if stale
update_system_package_lists
### Install required packages
install_system_packages "${log_name}" "packages[@]"
}
function create_klipper_service() {
local instance_name=${1}
local printer_data
local cfg_dir
local gcodes_dir
local cfg
local log
local klippy_serial
local klippy_socket
local env_file
local service
local service_template
local env_template
local suffix
printer_data="${HOME}/${instance_name}_data"
cfg_dir="${printer_data}/config"
gcodes_dir="${printer_data}/gcodes"
cfg="${cfg_dir}/printer.cfg"
log="${printer_data}/logs/klippy.log"
klippy_serial="${printer_data}/comms/klippy.serial"
klippy_socket="${printer_data}/comms/klippy.sock"
env_file="${printer_data}/systemd/klipper.env"
if [[ ${instance_name} == "printer" ]]; then
suffix="${instance_name//printer/}"
else
suffix="-${instance_name//printer_/}"
fi
create_required_folders "${printer_data}"
service_template="${KIAUH_SRCDIR}/resources/klipper.service"
env_template="${KIAUH_SRCDIR}/resources/klipper.env"
service="${SYSTEMD}/klipper${suffix}.service"
### replace all placeholders
if [[ ! -f ${service} ]]; then if [[ ! -f ${service} ]]; then
status_msg "Creating Klipper Service ${i} ..." status_msg "Create Klipper service file ..."
sudo cp "${service_template}" "${service}" sudo cp "${service_template}" "${service}"
[[ -z ${i} ]] && sudo sed -i "s| for instance klipper-%INST%||" "${service}" sudo cp "${env_template}" "${env_file}"
[[ -n ${i} ]] && sudo sed -i "s|%INST%|${i}|" "${service}" sudo sed -i "s|%USER%|${USER}|g; s|%KLIPPER_DIR%|${KLIPPER_DIR}|; s|%ENV%|${KLIPPY_ENV}|; s|%ENV_FILE%|${env_file}|" "${service}"
sudo sed -i "s|%USER%|${USER}|; s|%ENV%|${KLIPPY_ENV}|; s|%DIR%|${KLIPPER_DIR}|" "${service}" sudo sed -i "s|%USER%|${USER}|; s|%KLIPPER_DIR%|${KLIPPER_DIR}|; s|%LOG%|${log}|; s|%CFG%|${cfg}|; s|%PRINTER%|${klippy_serial}|; s|%UDS%|${klippy_socket}|" "${env_file}"
sudo sed -i "s|%LOG%|${log}|; s|%CFG%|${cfg}|; s|%PRINTER%|${printer}|; s|%UDS%|${uds}|" "${service}"
ok_msg "Klipper service file created!"
fi
if [[ ! -f ${cfg} ]]; then
write_example_printer_cfg "${cfg}" "${gcodes_dir}"
fi fi
} }
function write_example_printer_cfg() { function write_example_printer_cfg() {
local cfg_dir=${1} cfg=${2} local cfg=${1}
local cfg_template="${KIAUH_SRCDIR}/resources/printer.cfg" local gcodes_dir=${2}
local cfg_template
### create a config directory if it doesn't exist cfg_template="${KIAUH_SRCDIR}/resources/example.printer.cfg"
if [[ ! -d ${cfg_dir} ]]; then
status_msg "Creating '${cfg_dir}' ..."
mkdir -p "${cfg_dir}"
fi
### create a minimal config if there is no printer.cfg
if [[ ! -f ${cfg} ]]; then
status_msg "Creating minimal example printer.cfg ..."
cp "${cfg_template}" "${cfg}"
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
status_msg "Creating minimal example printer.cfg ..."
if cp "${cfg_template}" "${cfg}"; then
sed -i "s|%GCODES_DIR%|${gcodes_dir}|" "${cfg}"
ok_msg "Minimal example printer.cfg created!"
else else
return 1 error_msg "Couldn't create minimal example printer.cfg!"
fi fi
} }
@@ -382,71 +402,53 @@ function create_klipper_service() {
#================ REMOVE KLIPPER ================# #================ REMOVE KLIPPER ================#
#================================================# #================================================#
function remove_klipper_sysvinit() { function remove_klipper_service() {
[[ ! -e "${INITD}/klipper" ]] && return
status_msg "Removing Klipper SysVinit service ..."
sudo systemctl stop klipper
sudo update-rc.d -f klipper remove
sudo rm -f "${INITD}/klipper" "${ETCDEF}/klipper"
ok_msg "Klipper SysVinit service removed!"
}
function remove_klipper_systemd() {
[[ -z $(klipper_systemd) ]] && return [[ -z $(klipper_systemd) ]] && return
status_msg "Removing Klipper Systemd Services ..." status_msg "Removing Klipper services ..."
for service in $(klipper_systemd | cut -d"/" -f5); do for service in $(klipper_systemd | cut -d"/" -f5); do
status_msg "Removing ${service} ..." status_msg "Removing ${service} ..."
sudo systemctl stop "${service}" sudo systemctl stop "${service}"
sudo systemctl disable "${service}" sudo systemctl disable "${service}"
sudo rm -f "${SYSTEMD}/${service}" sudo rm -f "${SYSTEMD}/${service}"
ok_msg "Done!" sudo systemctl daemon-reload
sudo systemctl reset-failed
done done
### reloading units ok_msg "All Klipper services removed!"
sudo systemctl daemon-reload
sudo systemctl reset-failed
ok_msg "Klipper Service removed!"
} }
function remove_klipper_logs() { function find_instance_files() {
local files regex="klippy(-[0-9a-zA-Z]+)?\.log(.*)?" local target_folder=${1}
files=$(find "${KLIPPER_LOGS}" -maxdepth 1 -regextype posix-extended -regex "${KLIPPER_LOGS}/${regex}" 2> /dev/null | sort) local target_name=${2}
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_klipper_uds() {
local files
files=$(find /tmp -maxdepth 1 -regextype posix-extended -regex "/tmp/klippy_uds(-[0-9a-zA-Z]+)?" | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_klipper_printer() {
local files local files
files=$(find /tmp -maxdepth 1 -regextype posix-extended -regex "/tmp/printer(-[0-9a-zA-Z]+)?" | sort) readarray -t files < <(find "${HOME}" -regex "${HOME}/[A-Za-z0-9_]+_data/${target_folder}/${target_name}" | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do echo -e "${files[@]}"
status_msg "Removing ${file} ..." }
rm -f "${file}"
ok_msg "${file} removed!" function find_legacy_klipper_logs() {
done local files
fi local regex="klippy(-[0-9a-zA-Z]+)?\.log(.*)?"
readarray -t files < <(find "${HOME}/klipper_logs" -maxdepth 1 -regextype posix-extended -regex "${HOME}/klipper_logs/${regex}" 2> /dev/null | sort)
echo -e "${files[@]}"
}
function find_legacy_klipper_uds() {
local files
readarray -t files < <(find /tmp -maxdepth 1 -regextype posix-extended -regex "/tmp/klippy_uds(-[0-9a-zA-Z]+)?" | sort)
echo -e "${files[@]}"
}
function find_legacy_klipper_printer() {
local files
readarray -t files < <(find /tmp -maxdepth 1 -regextype posix-extended -regex "/tmp/printer(-[0-9a-zA-Z]+)?" | sort)
echo -e "${files[@]}"
} }
function remove_klipper_dir() { function remove_klipper_dir() {
@@ -465,17 +467,38 @@ function remove_klipper_env() {
ok_msg "Directory removed!" ok_msg "Directory removed!"
} }
###
# takes in a string of space separated absolute
# filepaths and removes those files one after another
#
function remove_files() {
local files
read -r -a files <<< "${@}"
if (( ${#files[@]} > 0 )); then
for file in "${files[@]}"; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_klipper() { function remove_klipper() {
remove_klipper_sysvinit remove_klipper_service
remove_klipper_systemd remove_files "$(find_instance_files "systemd" "klipper.env")"
remove_klipper_logs remove_files "$(find_instance_files "logs" "klippy.log.*")"
remove_klipper_uds remove_files "$(find_instance_files "comms" "klippy.sock")"
remove_klipper_printer remove_files "$(find_instance_files "comms" "klippy.serial")"
remove_files "$(find_legacy_klipper_logs)"
remove_files "$(find_legacy_klipper_uds)"
remove_files "$(find_legacy_klipper_printer)"
remove_klipper_dir remove_klipper_dir
remove_klipper_env remove_klipper_env
local confirm="Klipper was successfully removed!" print_confirm "Klipper was successfully removed!" && return
print_confirm "${confirm}" && return
} }
#================================================# #================================================#
@@ -493,7 +516,7 @@ function update_klipper() {
local custom_repo="${custom_klipper_repo}" local custom_repo="${custom_klipper_repo}"
local custom_branch="${custom_klipper_repo_branch}" local custom_branch="${custom_klipper_repo_branch}"
py_ver="python$(get_klipper_python_ver)" py_ver=$(get_klipper_python_ver)
do_action_service "stop" "klipper" do_action_service "stop" "klipper"
@@ -522,12 +545,6 @@ function get_klipper_status() {
local sf_count status py_ver local sf_count status py_ver
sf_count="$(klipper_systemd | wc -w)" sf_count="$(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
sf_count=1
fi
py_ver=$(get_klipper_python_ver) py_ver=$(get_klipper_python_ver)
### remove the "SERVICE" entry from the data array if a klipper service is installed ### remove the "SERVICE" entry from the data array if a klipper service is installed
@@ -568,8 +585,14 @@ function get_remote_klipper_commit() {
[[ ! -d ${KLIPPER_DIR} || ! -d "${KLIPPER_DIR}/.git" ]] && return [[ ! -d ${KLIPPER_DIR} || ! -d "${KLIPPER_DIR}/.git" ]] && return
local commit local commit
local branch
read_kiauh_ini "${FUNCNAME[0]}"
branch="${custom_klipper_repo_branch}"
[[ -z ${branch} ]] && branch="master"
cd "${KLIPPER_DIR}" && git fetch origin -q cd "${KLIPPER_DIR}" && git fetch origin -q
commit=$(git describe origin/master --always --tags | cut -d "-" -f 1,2) commit=$(git describe "origin/${branch}" --always --tags | cut -d "-" -f 1,2)
echo "${commit}" echo "${commit}"
} }
@@ -595,19 +618,6 @@ function compare_klipper_versions() {
#=================== HELPERS ====================# #=================== 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}"
}
### ###
# reads the python version from the klipper virtual environment # reads the python version from the klipper virtual environment
# #
@@ -619,4 +629,35 @@ function get_klipper_python_ver() {
local version local version
version=$("${KLIPPY_ENV}"/bin/python --version 2>&1 | cut -d" " -f2 | cut -d"." -f1) version=$("${KLIPPY_ENV}"/bin/python --version 2>&1 | cut -d" " -f2 | cut -d"." -f1)
echo "${version}" echo "${version}"
} }
function mask_disrupting_services() {
local brltty="false"
local brltty_udev="false"
local modem_manager="false"
[[ $(dpkg -s brltty 2>/dev/null | grep "Status") = *\ installed ]] && brltty="true"
[[ $(dpkg -s brltty-udev 2>/dev/null | grep "Status") = *\ installed ]] && brltty_udev="true"
[[ $(dpkg -s ModemManager 2>/dev/null | grep "Status") = *\ installed ]] && modem_manager="true"
status_msg "Installed brltty package detected, masking brltty service ..."
if [[ ${brltty} == "true" ]]; then
sudo systemctl stop brltty
sudo systemctl mask brltty
fi
ok_msg "brltty service masked!"
status_msg "Installed brltty-udev package detected, masking brltty-udev service ..."
if [[ ${brltty_udev} == "true" ]]; then
sudo systemctl stop brltty-udev
sudo systemctl mask brltty-udev
fi
ok_msg "brltty-udev service masked!"
status_msg "Installed ModemManager package detected, masking ModemManager service ..."
if [[ ${modem_manager} == "true" ]]; then
sudo systemctl stop ModemManager
sudo systemctl mask ModemManager
fi
ok_msg "ModemManager service masked!"
}

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -30,7 +30,7 @@ function install_klipperscreen() {
fi fi
### first, we create a backup of the full klipper_config dir - safety first! ### first, we create a backup of the full klipper_config dir - safety first!
backup_klipper_config_dir backup_config_dir
### install KlipperScreen ### install KlipperScreen
klipperscreen_setup klipperscreen_setup
@@ -119,6 +119,8 @@ function update_klipperscreen() {
old_md5=$(md5sum "${KLIPPERSCREEN_DIR}/scripts/KlipperScreen-requirements.txt" | cut -d " " -f1) old_md5=$(md5sum "${KLIPPERSCREEN_DIR}/scripts/KlipperScreen-requirements.txt" | cut -d " " -f1)
do_action_service "stop" "KlipperScreen" do_action_service "stop" "KlipperScreen"
backup_before_update "klipperscreen"
cd "${KLIPPERSCREEN_DIR}" cd "${KLIPPERSCREEN_DIR}"
git pull origin master -q && ok_msg "Fetch successfull!" git pull origin master -q && ok_msg "Fetch successfull!"
git checkout -f master && ok_msg "Checkout successfull" git checkout -f master && ok_msg "Checkout successfull"
@@ -207,7 +209,7 @@ function patch_klipperscreen_update_manager() {
moonraker_configs=$(find "${KLIPPER_CONFIG}" -type f -name "moonraker.conf" | sort) moonraker_configs=$(find "${KLIPPER_CONFIG}" -type f -name "moonraker.conf" | sort)
for conf in ${moonraker_configs}; do for conf in ${moonraker_configs}; do
if ! grep -Eq "^\[update_manager KlipperScreen\]$" "${conf}"; then if ! grep -Eq "^\[update_manager KlipperScreen\]\s*$" "${conf}"; then
### add new line to conf if it doesn't end with one ### add new line to conf if it doesn't end with one
[[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}" [[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -16,21 +16,35 @@ set -e
#===================================================# #===================================================#
function install_mainsail() { function install_mainsail() {
### exit early if moonraker not found
if [[ -z $(moonraker_systemd) ]]; then if [[ -z $(moonraker_systemd) ]]; then
local error="Moonraker not installed! Please install Moonraker first!" local error="Moonraker not installed! It's recommended to install Moonraker first!"
print_error "${error}" && return print_error "${error}"
while true; do
local yn
read -p "${cyan}###### Proceed to install Mainsail without installing Moonraker? (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 Mainsail setup ...\n"
return;;
*)
error_msg "Invalid Input!";;
esac
done
fi fi
### checking dependencies ### checking dependencies
local dep=(wget nginx) local dep=(wget nginx unzip)
dependency_check "${dep[@]}" dependency_check "${dep[@]}"
### detect conflicting Haproxy and Apache2 installations ### detect conflicting Haproxy and Apache2 installations
detect_conflicting_packages detect_conflicting_packages
status_msg "Initializing Mainsail installation ..." status_msg "Initializing Mainsail installation ..."
### first, we create a backup of the full klipper_config dir - safety first! ### first, we create a backup of the full klipper_config dir - safety first!
backup_klipper_config_dir backup_config_dir
### check for other enabled web interfaces ### check for other enabled web interfaces
unset SET_LISTEN_PORT unset SET_LISTEN_PORT
@@ -39,30 +53,6 @@ function install_mainsail() {
### check if another site already listens to port 80 ### check if another site already listens to port 80
mainsail_port_check mainsail_port_check
### ask user to install mjpg-streamer
local install_mjpg_streamer
if [[ ! -f "${SYSTEMD}/webcamd.service" ]]; then
while true; do
echo
top_border
echo -e "| Install MJPG-Streamer for webcam support? |"
bottom_border
read -p "${cyan}###### Please select (y/N):${white} " yn
case "${yn}" in
Y|y|Yes|yes)
select_msg "Yes"
install_mjpg_streamer="true"
break;;
N|n|No|no|"")
select_msg "No"
install_mjpg_streamer="false"
break;;
*)
error_msg "Invalid command!";;
esac
done
fi
### download mainsail ### download mainsail
download_mainsail download_mainsail
@@ -82,9 +72,6 @@ function install_mainsail() {
### add mainsail to the update manager in moonraker.conf ### add mainsail to the update manager in moonraker.conf
patch_mainsail_update_manager patch_mainsail_update_manager
### install mjpg-streamer
[[ ${install_mjpg_streamer} == "true" ]] && install_mjpg-streamer
fetch_webui_ports #WIP fetch_webui_ports #WIP
### confirm message ### confirm message
@@ -92,22 +79,21 @@ function install_mainsail() {
} }
function install_mainsail_macros() { function install_mainsail_macros() {
local yn
while true; do while true; do
echo echo
top_border top_border
echo -e "| It is recommended to have some important macros in |" echo -e "| It is recommended to use special macros in order to |"
echo -e "| your printer configuration to have Mainsail fully |" echo -e "| have Mainsail fully functional and working. |"
echo -e "| functional and working. |"
blank_line blank_line
echo -e "| The recommended macros for Mainsail can be seen here: |" echo -e "| The recommended macros for Mainsail can be seen here: |"
echo -e "| https://docs.mainsail.xyz/configuration#macros |" echo -e "| https://github.com/mainsail-crew/mainsail-config |"
blank_line blank_line
echo -e "| If you already have these macros in your config file, |" echo -e "| If you already use these macros skip this step. |"
echo -e "| skip this step and answer with 'no'. |"
echo -e "| Otherwise you should consider to answer with 'yes' to |" echo -e "| Otherwise you should consider to answer with 'yes' to |"
echo -e "| add the recommended example macros to your config. |" echo -e "| download the recommended macros. |"
bottom_border bottom_border
read -p "${cyan}###### Add the recommended macros? (Y/n):${white} " yn read -p "${cyan}###### Download the recommended macros? (Y/n):${white} " yn
case "${yn}" in case "${yn}" in
Y|y|Yes|yes|"") Y|y|Yes|yes|"")
select_msg "Yes" select_msg "Yes"
@@ -124,37 +110,68 @@ function install_mainsail_macros() {
} }
function download_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 ms_cfg_repo path configs regex line gcode_dir
local configs path
configs=$(find "${KLIPPER_CONFIG}" -type f -name "printer.cfg" | sort)
if [[ -n ${configs} ]]; then ms_cfg_repo="https://github.com/mainsail-crew/mainsail-config.git"
for config in ${configs}; do regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/printer\.cfg"
path=$(echo "${config}" | rev | cut -d"/" -f2- | rev) configs=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ ! -f "${path}/mainsail.cfg" ]]; then
status_msg "Downloading mainsail.cfg to ${path} ..."
log_info "downloading mainsail.cfg to: ${path}"
wget "${ms_cfg}" -O "${path}/mainsail.cfg"
### replace user 'pi' with current username to prevent issues in cases where the user is not called 'pi' if [[ -z ${configs} ]]; then
log_info "modify mainsail.cfg" print_error "No printer.cfg found! Installation of Macros will be skipped ..."
sed -i "/^path: \/home\/pi\/gcode_files/ s/\/home\/pi/\/home\/${USER}/" "${path}/mainsail.cfg"
### write include to the very first line of the printer.cfg
if ! grep -Eq "^[include mainsail.cfg]$" "${path}/printer.cfg"; then
log_info "modify printer.cfg"
sed -i "1 i [include mainsail.cfg]" "${path}/printer.cfg"
fi
ok_msg "Done!"
fi
done
else
log_error "execution stopped! reason: no printer.cfg found" log_error "execution stopped! reason: no printer.cfg found"
return return
fi fi
status_msg "Cloning mainsail-config ..."
[[ -d "${HOME}/mainsail-config" ]] && rm -rf "${HOME}/mainsail-config"
if git clone "${ms_cfg_repo}" "${HOME}/mainsail-config"; then
for config in ${configs}; do
path=$(echo "${config}" | rev | cut -d"/" -f2- | rev)
if [[ -e "${path}/mainsail.cfg" && ! -h "${path}/mainsail.cfg" ]]; then
warn_msg "Attention! Existing mainsail.cfg detected!"
warn_msg "The file will be renamed to 'mainsail.bak.cfg' to be able to continue with the installation."
if ! mv "${path}/mainsail.cfg" "${path}/mainsail.bak.cfg"; then
error_msg "Renaming mainsail.cfg failed! Aborting installation ..."
return
fi
fi
if [[ -h "${path}/mainsail.cfg" ]]; then
warn_msg "Recreating symlink in ${path} ..."
rm -rf "${path}/mainsail.cfg"
fi
if ! ln -sf "${HOME}/mainsail-config/client.cfg" "${path}/mainsail.cfg"; then
error_msg "Creating symlink failed! Aborting installation ..."
return
fi
if ! grep -Eq "^\[include mainsail.cfg\]$" "${path}/printer.cfg"; then
log_info "${path}/printer.cfg"
sed -i "1 i [include mainsail.cfg]" "${path}/printer.cfg"
fi
line=$(($(grep -n "\[include mainsail.cfg\]" "${path}/printer.cfg" | tail -1 | cut -d: -f1) + 1))
gcode_dir=${path/config/gcodes}
if ! grep -Eq "^\[virtual_sdcard\]$" "${path}/printer.cfg"; then
log_info "${path}/printer.cfg"
sed -i "${line} i \[virtual_sdcard]\npath: ${gcode_dir}\non_error_gcode: CANCEL_PRINT\n" "${path}/printer.cfg"
fi
done
else
print_error "Cloning failed! Aborting installation ..."
log_error "execution stopped! reason: cloning failed"
return
fi
patch_mainsail_config_update_manager
ok_msg "Done!"
} }
function download_mainsail() { function download_mainsail() {
local services
local url local url
url=$(get_mainsail_download_url) url=$(get_mainsail_download_url)
@@ -177,8 +194,9 @@ function download_mainsail() {
exit 1 exit 1
fi fi
### check for moonraker multi-instance and if multi-instance was found, enable mainsails remoteMode ### check for moonraker multi-instance and if no-instance or multi-instance was found, enable mainsails remoteMode
if [[ $(moonraker_systemd | wc -w) -gt 1 ]]; then services=$(moonraker_systemd)
if [[ ( -z "${services}" ) || ( $(echo "${services}" | wc -w) -gt 1 ) ]]; then
enable_mainsail_remotemode enable_mainsail_remotemode
fi fi
} }
@@ -194,7 +212,7 @@ function remove_mainsail_dir() {
rm -rf "${MAINSAIL_DIR}" && ok_msg "Directory removed!" rm -rf "${MAINSAIL_DIR}" && ok_msg "Directory removed!"
} }
function remove_mainsail_config() { function remove_mainsail_nginx_config() {
if [[ -e "/etc/nginx/sites-available/mainsail" ]]; then if [[ -e "/etc/nginx/sites-available/mainsail" ]]; then
status_msg "Removing Mainsail configuration for Nginx ..." status_msg "Removing Mainsail configuration for Nginx ..."
sudo rm "/etc/nginx/sites-available/mainsail" && ok_msg "File removed!" sudo rm "/etc/nginx/sites-available/mainsail" && ok_msg "File removed!"
@@ -219,8 +237,10 @@ function remove_mainsail_logs() {
} }
function remove_mainsail_log_symlinks() { function remove_mainsail_log_symlinks() {
local files local files regex
files=$(find "${KLIPPER_LOGS}" -name "mainsail*" 2> /dev/null | sort)
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/logs\/mainsail-.*"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" 2> /dev/null | sort)
if [[ -n ${files} ]]; then if [[ -n ${files} ]]; then
for file in ${files}; do for file in ${files}; do
@@ -231,11 +251,34 @@ function remove_mainsail_log_symlinks() {
fi fi
} }
function remove_legacy_mainsail_log_symlinks() {
local files
files=$(find "${HOME}/klipper_logs" -name "mainsail*" 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_mainsail_config() {
if [[ -d "${HOME}/mainsail-config" ]]; then
status_msg "Removing ${HOME}/mainsail-config ..."
rm -rf "${HOME}/mainsail-config"
ok_msg "${HOME}/mainsail-config removed!"
print_confirm "Mainsail-Config successfully removed!"
fi
}
function remove_mainsail() { function remove_mainsail() {
remove_mainsail_dir remove_mainsail_dir
remove_mainsail_config remove_mainsail_nginx_config
remove_mainsail_logs remove_mainsail_logs
remove_mainsail_log_symlinks remove_mainsail_log_symlinks
remove_legacy_mainsail_log_symlinks
### remove mainsail_port from ~/.kiauh.ini ### remove mainsail_port from ~/.kiauh.ini
sed -i "/^mainsail_port=/d" "${INI_FILE}" sed -i "/^mainsail_port=/d" "${INI_FILE}"
@@ -281,19 +324,25 @@ function get_mainsail_status() {
} }
function get_local_mainsail_version() { function get_local_mainsail_version() {
[[ ! -f "${MAINSAIL_DIR}/.version" ]] && return local versionfile="${MAINSAIL_DIR}/.version"
local relinfofile="${MAINSAIL_DIR}/release_info.json"
local version local version
version=$(head -n 1 "${MAINSAIL_DIR}/.version")
if [[ -f ${relinfofile} ]]; then
version=$(grep -o '"version":"[^"]*' "${relinfofile}" | grep -o '[^"]*$')
elif [[ -f ${versionfile} ]]; then
version=$(head -n 1 "${versionfile}")
fi
echo "${version}" echo "${version}"
} }
function get_remote_mainsail_version() { function get_remote_mainsail_version() {
[[ ! $(dpkg-query -f'${Status}' --show curl 2>/dev/null) = *\ installed ]] && return [[ ! $(dpkg-query -f'${Status}' --show curl 2>/dev/null) = *\ installed ]] && return
local version local tags
version=$(get_mainsail_download_url | rev | cut -d"/" -f2 | rev) tags=$(curl -s "https://api.github.com/repos/mainsail-crew/mainsail/tags" | grep "name" | cut -d'"' -f4)
echo "${version}" echo "${tags}" | head -1
} }
function compare_mainsail_versions() { function compare_mainsail_versions() {
@@ -331,7 +380,7 @@ function print_theme_list() {
function ms_theme_installer_menu() { function ms_theme_installer_menu() {
local theme_list theme_author theme_repo theme_name theme_note theme_url local theme_list theme_author theme_repo theme_name theme_note theme_url
local theme_csv_url="https://raw.githubusercontent.com/mainsail-crew/docs/master/_data/themes.csv" local theme_csv_url="https://raw.githubusercontent.com/mainsail-crew/gb-docs/main/_data/themes.csv"
theme_list=$(curl -s -L "${theme_csv_url}") theme_list=$(curl -s -L "${theme_csv_url}")
top_border top_border
@@ -397,13 +446,13 @@ function ms_theme_install() {
for folder in "${folder_arr[@]}"; do for folder in "${folder_arr[@]}"; do
### instance names/identifier of only numbers need to be prefixed with 'printer_' ### instance names/identifier of only numbers need to be prefixed with 'printer_'
if [[ ${folder} =~ ^[0-9]+$ ]]; then if [[ ${folder} =~ ^[0-9]+$ ]]; then
target_folders+=("${KLIPPER_CONFIG}/printer_${folder}") target_folders+=("${HOME}/printer_${folder}_data/config")
else else
target_folders+=("${KLIPPER_CONFIG}/${folder}") target_folders+=("${HOME}/${folder}_data/config")
fi fi
done done
else else
target_folders+=("${KLIPPER_CONFIG}") target_folders+=("${HOME}/printer_data/config")
fi fi
if (( ${#target_folders[@]} > 1 )); then if (( ${#target_folders[@]} > 1 )); then
@@ -411,7 +460,7 @@ function ms_theme_install() {
echo -e "| Please select the printer you want to apply the theme |" echo -e "| Please select the printer you want to apply the theme |"
echo -e "| installation to: |" echo -e "| installation to: |"
for (( i=0; i < ${#target_folders[@]}; i++ )); do 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}" printf "|${cyan}%-55s${white}|\n" " ${i}) ${folder}"
done done
bottom_border bottom_border
@@ -440,8 +489,11 @@ function ms_theme_install() {
} }
function ms_theme_delete() { function ms_theme_delete() {
local theme_folders target_folders=() local regex theme_folders target_folders=()
theme_folders=$(find "${KLIPPER_CONFIG}" -mindepth 1 -type d -name ".theme" | sort)
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/\.theme"
theme_folders=$(find "${HOME}" -maxdepth 3 -type d -regextype posix-extended -regex "${regex}" | sort)
# theme_folders=$(find "${KLIPPER_CONFIG}" -mindepth 1 -type d -name ".theme" | sort)
### build target folder array ### build target folder array
for folder in ${theme_folders}; do for folder in ${theme_folders}; do
@@ -481,25 +533,28 @@ function ms_theme_delete() {
#================================================# #================================================#
function get_mainsail_download_url() { function get_mainsail_download_url() {
local tags latest_tag latest_url stable_tag stable_url url local releases_by_tag tags tag unstable_url url
tags=$(curl -s "${MAINSAIL_TAGS}" | grep "name" | cut -d'"' -f4)
### latest download url including pre-releases (alpha, beta, rc) ### latest stable download url
latest_tag=$(echo "${tags}" | head -1) url="https://github.com/mainsail-crew/mainsail/releases/latest/download/mainsail.zip"
latest_url="https://github.com/mainsail-crew/mainsail/releases/download/${latest_tag}/mainsail.zip"
### get stable mainsail download url
stable_tag=$(echo "${tags}" | grep -E "^v([0-9]+\.?){3}$" | head -1)
stable_url="https://github.com/mainsail-crew/mainsail/releases/download/${stable_tag}/mainsail.zip"
read_kiauh_ini "${FUNCNAME[0]}" read_kiauh_ini "${FUNCNAME[0]}"
if [[ ${mainsail_install_unstable} == "true" ]]; then if [[ ${mainsail_install_unstable} == "true" ]]; then
url="${latest_url}" releases_by_tag="https://api.github.com/repos/mainsail-crew/mainsail/tags"
echo "${url}" tags=$(curl -s "${releases_by_tag}" | grep "name" | cut -d'"' -f4)
else tag=$(echo "${tags}" | head -1)
url="${stable_url}"
echo "${url}" ### latest unstable download url including pre-releases (alpha, beta, rc)
unstable_url="https://github.com/mainsail-crew/mainsail/releases/download/${tag}/mainsail.zip"
if [[ ${unstable_url} == *"download//"* ]]; then
warn_msg "Download URL broken! Falling back to URL of latest stable release!"
else
url=${unstable_url}
fi
fi fi
echo "${url}"
} }
function mainsail_port_check() { function mainsail_port_check() {
@@ -570,12 +625,13 @@ function enable_mainsail_remotemode() {
} }
function patch_mainsail_update_manager() { function patch_mainsail_update_manager() {
local patched="false" local patched moonraker_configs regex
local moonraker_configs regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/moonraker\.conf"
moonraker_configs=$(find "${KLIPPER_CONFIG}" -type f -name "moonraker.conf" | sort) moonraker_configs=$(find "${HOME}" -maxdepth 3 -type f -regextype posix-extended -regex "${regex}" | sort)
patched="false"
for conf in ${moonraker_configs}; do for conf in ${moonraker_configs}; do
if ! grep -Eq "^\[update_manager mainsail\]$" "${conf}"; then if ! grep -Eq "^\[update_manager mainsail\]\s*$" "${conf}"; then
### add new line to conf if it doesn't end with one ### add new line to conf if it doesn't end with one
[[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}" [[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"
@@ -599,3 +655,36 @@ MOONRAKER_CONF
do_action_service "restart" "moonraker" do_action_service "restart" "moonraker"
fi fi
} }
function patch_mainsail_config_update_manager() {
local patched moonraker_configs regex
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/moonraker\.conf"
moonraker_configs=$(find "${HOME}" -maxdepth 3 -type f -regextype posix-extended -regex "${regex}" | sort)
patched="false"
for conf in ${moonraker_configs}; do
if ! grep -Eq "^\[update_manager mainsail-config\]\s*$" "${conf}"; then
### add new line to conf if it doesn't end with one
[[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"
### add Mainsails update manager section to moonraker.conf
status_msg "Adding Mainsail-Config to update manager in file:\n ${conf}"
/bin/sh -c "cat >> ${conf}" << MOONRAKER_CONF
[update_manager mainsail-config]
type: git_repo
primary_branch: master
path: ~/mainsail-config
origin: https://github.com/mainsail-crew/mainsail-config.git
managed_services: klipper
MOONRAKER_CONF
fi
patched="true"
done
if [[ ${patched} == "true" ]]; then
do_action_service "restart" "moonraker"
fi
}

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -190,4 +190,4 @@ function remove_mjpg-streamer() {
[[ -L "${KLIPPER_LOGS}/webcamd.log" ]] && rm -f "${KLIPPER_LOGS}/webcamd.log" [[ -L "${KLIPPER_LOGS}/webcamd.log" ]] && rm -f "${KLIPPER_LOGS}/webcamd.log"
print_confirm "MJPG-Streamer successfully removed!" print_confirm "MJPG-Streamer successfully removed!"
} }

247
scripts/mobileraker.sh Normal file
View File

@@ -0,0 +1,247 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/dw-0/kiauh #
# #
# This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================#
#
# This file is written and maintained by Patrick Schmidt author of Mobileraker
# It is based of the kliperscreen.sh install script!
set -e
#===================================================#
#========== INSTALL MOBILERAKER COMPANION ==========#
#===================================================#
function mobileraker_systemd() {
local services
services=$(find "${SYSTEMD}" -maxdepth 1 -regextype posix-extended -regex "${SYSTEMD}/mobileraker.service")
echo "${services}"
}
function install_mobileraker() {
### return early if python version check fails
if [[ $(python3_check) == "false" ]]; then
local error="Versioncheck failed! Python 3.7 or newer required!\n"
error="${error} Please upgrade Python."
print_error "${error}" && return
fi
### first, we create a backup of the full klipper_config dir - safety first!
backup_config_dir
### install Mobileraker's Companion
mobileraker_setup
### add Mobileraker's Companion to the update manager in moonraker.conf
patch_mobileraker_update_manager
do_action_service "restart" "mobileraker"
}
function mobileraker_setup() {
local dep=(wget curl unzip dfu-util)
dependency_check "${dep[@]}"
status_msg "Cloning Mobileraker's companion from ${MOBILERAKER_REPO} ..."
# force remove existing Mobileraker's companion dir
[[ -d ${MOBILERAKER_DIR} ]] && rm -rf "${MOBILERAKER_DIR}"
# clone into fresh Mobileraker's companion dir
cd "${HOME}" || exit 1
if ! git clone "${MOBILERAKER_REPO}" "${MOBILERAKER_DIR}"; then
print_error "Cloning mobileraker's companion from\n ${MOBILERAKER_REPO}\n failed!"
exit 1
fi
status_msg "Starting installer of Mobileraker's companion ..."
if "${MOBILERAKER_DIR}"/scripts/install.sh; then
ok_msg "Mobileraker's companion successfully installed!"
else
print_error "Mobileraker's companion installation failed!"
exit 1
fi
}
#===================================================#
#=========== REMOVE MOBILERAKER COMPANION ==========#
#===================================================#
function remove_mobileraker() {
### remove Mobileraker's companion dir
if [[ -d ${MOBILERAKER_DIR} ]]; then
status_msg "Removing Mobileraker's companion directory ..."
rm -rf "${MOBILERAKER_DIR}" && ok_msg "Directory removed!"
fi
### remove Mobileraker's companion VENV dir
if [[ -d ${MOBILERAKER_ENV} ]]; then
status_msg "Removing Mobileraker's companion VENV directory ..."
rm -rf "${MOBILERAKER_ENV}" && ok_msg "Directory removed!"
fi
### remove Mobileraker's companion service
if [[ -e "${SYSTEMD}/mobileraker.service" ]]; then
status_msg "Removing mobileraker service ..."
do_action_service "stop" "mobileraker"
do_action_service "disable" "mobileraker"
sudo rm -f "${SYSTEMD}/mobileraker.service"
###reloading units
sudo systemctl daemon-reload
sudo systemctl reset-failed
ok_msg "Mobileraker's companion Service removed!"
fi
remove_mobileraker_logs
print_confirm "Mobileraker's companion successfully removed!"
}
function remove_mobileraker_logs() {
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/logs\/mobileraker\.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
}
#===================================================#
#=========== UPDATE MOBILERAKER COMPANION ==========#
#===================================================#
function update_mobileraker() {
local old_md5
old_md5=$(md5sum "${MOBILERAKER_DIR}/scripts/mobileraker-requirements.txt" | cut -d " " -f1)
do_action_service "stop" "mobileraker"
cd "${MOBILERAKER_DIR}"
git pull origin main -q && ok_msg "Fetch successfull!"
git checkout -f main && ok_msg "Checkout successfull"
if [[ $(md5sum "${MOBILERAKER_DIR}/scripts/mobileraker-requirements.txt" | cut -d " " -f1) != "${old_md5}" ]]; then
status_msg "New dependecies detected..."
"${MOBILERAKER_ENV}"/bin/pip install -r "${MOBILERAKER_DIR}/scripts/mobileraker-requirements.txt"
ok_msg "Dependencies have been installed!"
fi
ok_msg "Update complete!"
do_action_service "start" "mobileraker"
}
#===================================================#
#=========== MOBILERAKER COMPANION STATUS ==========#
#===================================================#
function get_mobileraker_status() {
local sf_count status
sf_count="$(mobileraker_systemd | wc -w)"
### remove the "SERVICE" entry from the data array if a moonraker service is installed
local data_arr=(SERVICE "${MOBILERAKER_DIR}" "${MOBILERAKER_ENV}")
(( sf_count > 0 )) && unset "data_arr[0]"
### count+1 for each found data-item from array
local filecount=0
for data in "${data_arr[@]}"; do
[[ -e ${data} ]] && filecount=$(( filecount + 1 ))
done
if (( filecount == ${#data_arr[*]} )); then
status="Installed!"
elif (( filecount == 0 )); then
status="Not installed!"
else
status="Incomplete!"
fi
echo "${status}"
}
function get_local_mobileraker_commit() {
[[ ! -d ${MOBILERAKER_DIR} || ! -d "${MOBILERAKER_DIR}/.git" ]] && return
local commit
cd "${MOBILERAKER_DIR}"
commit="$(git describe HEAD --always --tags | cut -d "-" -f 1,2)"
echo "${commit}"
}
function get_remote_mobileraker_commit() {
[[ ! -d ${MOBILERAKER_DIR} || ! -d "${MOBILERAKER_DIR}/.git" ]] && return
local commit
cd "${MOBILERAKER_DIR}" && git fetch origin -q
commit=$(git describe origin/main --always --tags | cut -d "-" -f 1,2)
echo "${commit}"
}
function compare_mobileraker_versions() {
local versions local_ver remote_ver
local_ver="$(get_local_mobileraker_commit)"
remote_ver="$(get_remote_mobileraker_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 "mobileraker"
else
versions="${green}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
fi
echo "${versions}"
}
#================================================#
#=================== HELPERS ====================#
#================================================#
function patch_mobileraker_update_manager() {
local patched moonraker_configs regex
regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/moonraker\.conf"
moonraker_configs=$(find "${HOME}" -maxdepth 3 -type f -regextype posix-extended -regex "${regex}" | sort)
patched="false"
for conf in ${moonraker_configs}; do
if ! grep -Eq "^\[update_manager mobileraker\]\s*$" "${conf}"; then
### add new line to conf if it doesn't end with one
[[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"
### add Mobileraker's Companion update manager section to moonraker.conf
status_msg "Adding Mobileraker's Companion to update manager in file:\n ${conf}"
/bin/sh -c "cat >> ${conf}" << MOONRAKER_CONF
[update_manager mobileraker]
type: git_repo
path: ${HOME}/mobileraker_companion
origin: https://github.com/Clon1998/mobileraker_companion.git
primary_branch:main
managed_services: mobileraker
env: ${HOME}/mobileraker-env/bin/python
requirements: scripts/mobileraker-requirements.txt
install_script: scripts/install.sh
MOONRAKER_CONF
fi
patched="true"
done
if [[ ${patched} == "true" ]]; then
do_action_service "restart" "moonraker"
fi
}

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -33,7 +33,7 @@ function telegram_bot_setup_dialog() {
status_msg "Initializing Telegram Bot installation ..." status_msg "Initializing Telegram Bot installation ..."
### first, we create a backup of the full klipper_config dir - safety first! ### first, we create a backup of the full klipper_config dir - safety first!
backup_klipper_config_dir backup_config_dir
local moonraker_count user_input=() moonraker_names=() local moonraker_count user_input=() moonraker_names=()
moonraker_count=$(echo "${moonraker_services}" | wc -w ) moonraker_count=$(echo "${moonraker_services}" | wc -w )
@@ -110,7 +110,7 @@ function telegram_bot_setup_dialog() {
} }
function install_telegram_bot_dependencies() { function install_telegram_bot_dependencies() {
local packages local packages log_name="Telegram Bot"
local install_script="${TELEGRAM_BOT_DIR}/scripts/install.sh" local install_script="${TELEGRAM_BOT_DIR}/scripts/install.sh"
### read PKGLIST from official install-script ### read PKGLIST from official install-script
@@ -121,21 +121,11 @@ function install_telegram_bot_dependencies() {
echo "${cyan}${packages}${white}" | tr '[:space:]' '\n' echo "${cyan}${packages}${white}" | tr '[:space:]' '\n'
read -r -a packages <<< "${packages}" read -r -a packages <<< "${packages}"
### Update system package info ### Update system package lists if stale
status_msg "Updating package lists..." update_system_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 ### Install required packages
status_msg "Installing required packages..." install_system_packages "${log_name}" "packages[@]"
if ! sudo apt-get install --yes "${packages[@]}"; then
log_error "failure while installing required moonraker-telegram-bot packages"
error_msg "Installing required packages failed!"
exit 1
fi
} }
function create_telegram_bot_virtualenv() { function create_telegram_bot_virtualenv() {
@@ -203,29 +193,40 @@ function create_telegram_conf() {
local input=("${@}") local input=("${@}")
local telegram_bot_count=${input[0]} && unset "input[0]" local telegram_bot_count=${input[0]} && unset "input[0]"
local names=("${input[@]}") && unset "input[@]" local names=("${input[@]}") && unset "input[@]"
local log="${KLIPPER_LOGS}" local printer_data log_dir cfg cfg_dir
local cfg cfg_dir
if (( telegram_bot_count == 1 )); then if (( telegram_bot_count == 1 )); then
cfg_dir="${KLIPPER_CONFIG}" printer_data="${HOME}/printer_data"
log_dir="${printer_data}/logs"
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/telegram.conf" cfg="${cfg_dir}/telegram.conf"
### create required folder structure
create_required_folders "${printer_data}"
### write single instance config ### write single instance config
write_telegram_conf "${cfg_dir}" "${cfg}" "${log}" write_telegram_conf "${cfg_dir}" "${cfg}"
elif (( telegram_bot_count > 1 )); then elif (( telegram_bot_count > 1 )); then
local j=0 re="^[1-9][0-9]*$" local j=0 re="^[1-9][0-9]*$"
for (( i=1; i <= telegram_bot_count; i++ )); do for (( i=1; i <= telegram_bot_count; i++ )); do
### overwrite config folder if name is only a number
if [[ ${names[j]} =~ ${re} ]]; then printer_data="${HOME}/${names[${j}]}_data"
cfg_dir="${KLIPPER_CONFIG}/printer_${names[${j}]}" ### prefix instance name with "printer_" if it is only a number
else [[ ${names[j]} =~ ${re} ]] && printer_data="${HOME}/printer_${names[${j}]}_data"
cfg_dir="${KLIPPER_CONFIG}/${names[${j}]}"
fi
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/telegram.conf" cfg="${cfg_dir}/telegram.conf"
log_dir="${printer_data}/logs"
### create required folder structure
create_required_folders "${printer_data}"
### write multi instance config ### write multi instance config
write_telegram_conf "${cfg_dir}" "${cfg}" "${log}" write_telegram_conf "${cfg_dir}" "${cfg}"
j=$(( j + 1 )) j=$(( j + 1 ))
done && unset j done && unset j
@@ -235,17 +236,15 @@ function create_telegram_conf() {
} }
function write_telegram_conf() { function write_telegram_conf() {
local cfg_dir=${1} cfg=${2} log=${3} local cfg_dir=${1} cfg=${2}
local conf_template="${TELEGRAM_BOT_DIR}/scripts/base_install_template" local conf_template="${TELEGRAM_BOT_DIR}/scripts/base_install_template"
[[ ! -d ${cfg_dir} ]] && mkdir -p "${cfg_dir}"
if [[ ! -f ${cfg} ]]; then if [[ ! -f ${cfg} ]]; then
status_msg "Creating telegram.conf in ${cfg_dir} ..." status_msg "Creating telegram.conf in ${cfg_dir} ..."
cp "${conf_template}" "${cfg}" cp "${conf_template}" "${cfg}"
sed -i "s|some_log_path|${log}|g" "${cfg}"
ok_msg "telegram.conf created!" ok_msg "telegram.conf created!"
else else
status_msg "File '${cfg}' already exists!\nSkipping..." ok_msg "File '${cfg}' already exists! Skipping..."
fi fi
} }
@@ -253,16 +252,22 @@ function create_telegram_bot_service() {
local input=("${@}") local input=("${@}")
local instances=${input[0]} && unset "input[0]" local instances=${input[0]} && unset "input[0]"
local names=("${input[@]}") && unset "input[@]" local names=("${input[@]}") && unset "input[@]"
local cfg_dir cfg log service local printer_data cfg_dir cfg log service env_file
if (( instances == 1 )); then if (( instances == 1 )); then
cfg_dir="${KLIPPER_CONFIG}" printer_data="${HOME}/printer_data"
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/telegram.conf" cfg="${cfg_dir}/telegram.conf"
log="${KLIPPER_LOGS}/telegram.log" log="${printer_data}/logs/telegram.log"
service="${SYSTEMD}/moonraker-telegram-bot.service" service="${SYSTEMD}/moonraker-telegram-bot.service"
env_file="${printer_data}/systemd/moonraker-telegram-bot.env"
### create required folder structure
create_required_folders "${printer_data}"
### write single instance service ### write single instance service
write_telegram_bot_service "" "${cfg}" "${log}" "${service}" write_telegram_bot_service "" "${cfg}" "${log}" "${service}" "${env_file}"
ok_msg "Single Telegram Bot instance created!" ok_msg "Telegram Bot instance created!"
elif (( instances > 1 )); then elif (( instances > 1 )); then
local j=0 re="^[1-9][0-9]*$" local j=0 re="^[1-9][0-9]*$"
@@ -270,17 +275,27 @@ function create_telegram_bot_service() {
for (( i=1; i <= instances; i++ )); do for (( i=1; i <= instances; i++ )); do
### overwrite config folder if name is only a number ### overwrite config folder if name is only a number
if [[ ${names[j]} =~ ${re} ]]; then if [[ ${names[j]} =~ ${re} ]]; then
cfg_dir="${KLIPPER_CONFIG}/printer_${names[${j}]}" printer_data="${HOME}/printer_${names[${j}]}_data"
else else
cfg_dir="${KLIPPER_CONFIG}/${names[${j}]}" printer_data="${HOME}/${names[${j}]}_data"
fi fi
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/telegram.conf" cfg="${cfg_dir}/telegram.conf"
log="${KLIPPER_LOGS}/telegram-${names[${j}]}.log" log="${printer_data}/logs/telegram.log"
service="${SYSTEMD}/moonraker-telegram-bot-${names[${j}]}.service" service="${SYSTEMD}/moonraker-telegram-bot-${names[${j}]}.service"
env_file="${printer_data}/systemd/moonraker-telegram-bot.env"
### create required folder structure
create_required_folders "${printer_data}"
### write multi instance service ### write multi instance service
write_telegram_bot_service "${names[${j}]}" "${cfg}" "${log}" "${service}" if write_telegram_bot_service "${names[${j}]}" "${cfg}" "${log}" "${service}" "${env_file}"; then
ok_msg "Telegram Bot instance moonraker-telegram-bot-${names[${j}]} created!" ok_msg "Telegram Bot instance moonraker-telegram-bot-${names[${j}]} created!"
else
error_msg "An error occured during creation of instance moonraker-telegram-bot-${names[${j}]}!"
fi
j=$(( j + 1 )) j=$(( j + 1 ))
done && unset j done && unset j
@@ -290,17 +305,24 @@ function create_telegram_bot_service() {
} }
function write_telegram_bot_service() { function write_telegram_bot_service() {
local i=${1} cfg=${2} log=${3} service=${4} local i=${1} cfg=${2} log=${3} service=${4} env_file=${5}
local service_template="${KIAUH_SRCDIR}/resources/moonraker-telegram-bot.service" local service_template="${KIAUH_SRCDIR}/resources/moonraker-telegram-bot.service"
local env_template="${KIAUH_SRCDIR}/resources/moonraker-telegram-bot.env"
### replace all placeholders ### replace all placeholders
if [[ ! -f ${service} ]]; then if [[ ! -f ${service} ]]; then
status_msg "Creating Telegram Bot Service ${i} ..." status_msg "Creating service file for instance ${i} ..."
sudo cp "${service_template}" "${service}" sudo cp "${service_template}" "${service}"
[[ -z ${i} ]] && sudo sed -i "s|instance %INST% ||" "${service}" if [[ -z ${i} ]]; then
[[ -n ${i} ]] && sudo sed -i "s|%INST%|${i}|" "${service}" sudo sed -i "s| %INST%||" "${service}"
sudo sed -i "s|%USER%|${USER}|; s|%ENV%|${TELEGRAM_BOT_ENV}|; s|%DIR%|${TELEGRAM_BOT_DIR}|" "${service}" else
sudo sed -i "s|%CFG%|${cfg}|; s|%LOG%|${log}|" "${service}" sudo sed -i "s|%INST%|${i}|" "${service}"
fi
sudo sed -i "s|%USER%|${USER}|g; s|%TELEGRAM_BOT_DIR%|${TELEGRAM_BOT_DIR}|; s|%ENV%|${TELEGRAM_BOT_ENV}|; s|%ENV_FILE%|${env_file}|" "${service}"
status_msg "Creating environment file for instance ${i} ..."
cp "${env_template}" "${env_file}"
sed -i "s|%USER%|${USER}|; s|%TELEGRAM_BOT_DIR%|${TELEGRAM_BOT_DIR}|; s|%CFG%|${cfg}|; s|%LOG%|${log}|" "${env_file}"
fi fi
} }
@@ -343,9 +365,35 @@ function remove_telegram_bot_env() {
ok_msg "Directory removed!" ok_msg "Directory removed!"
} }
function remove_telegram_bot_env_file() {
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/systemd\/moonraker-telegram-bot\.env"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_telegram_bot_logs() { function remove_telegram_bot_logs() {
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/logs\/telegram\.log.*"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_legacy_telegram_bot_logs() {
local files regex="telegram(-[0-9a-zA-Z]+)?\.log(.*)?" local files regex="telegram(-[0-9a-zA-Z]+)?\.log(.*)?"
files=$(find "${KLIPPER_LOGS}" -maxdepth 1 -regextype posix-extended -regex "${KLIPPER_LOGS}/${regex}" | sort) files=$(find "${HOME}/klipper_logs" -maxdepth 1 -regextype posix-extended -regex "${HOME}/klipper_logs/${regex}" 2> /dev/null | sort)
if [[ -n ${files} ]]; then if [[ -n ${files} ]]; then
for file in ${files}; do for file in ${files}; do
@@ -360,7 +408,9 @@ function remove_telegram_bot() {
remove_telegram_bot_systemd remove_telegram_bot_systemd
remove_telegram_bot_dir remove_telegram_bot_dir
remove_telegram_bot_env remove_telegram_bot_env
remove_telegram_bot_env_file
remove_telegram_bot_logs remove_telegram_bot_logs
remove_legacy_telegram_bot_logs
local confirm="Moonraker-Telegram-Bot was successfully removed!" local confirm="Moonraker-Telegram-Bot was successfully removed!"
print_confirm "${confirm}" && return print_confirm "${confirm}" && return
@@ -458,12 +508,13 @@ function compare_telegram_bot_versions() {
#================================================# #================================================#
function patch_telegram_bot_update_manager() { function patch_telegram_bot_update_manager() {
local patched="false" local patched moonraker_configs regex
local moonraker_configs regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/moonraker\.conf"
moonraker_configs=$(find "${KLIPPER_CONFIG}" -type f -name "moonraker.conf" | sort) moonraker_configs=$(find "${HOME}" -maxdepth 3 -type f -regextype posix-extended -regex "${regex}" | sort)
patched="false"
for conf in ${moonraker_configs}; do for conf in ${moonraker_configs}; do
if ! grep -Eq "^\[update_manager moonraker-telegram-bot\]$" "${conf}"; then if ! grep -Eq "^\[update_manager moonraker-telegram-bot\]\s*$" "${conf}"; then
### add new line to conf if it doesn't end with one ### add new line to conf if it doesn't end with one
[[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}" [[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -141,7 +141,7 @@ function moonraker_setup_dialog() {
} }
function install_moonraker_dependencies() { function install_moonraker_dependencies() {
local packages local packages log_name="Moonraker"
local install_script="${MOONRAKER_DIR}/scripts/install-moonraker.sh" local install_script="${MOONRAKER_DIR}/scripts/install-moonraker.sh"
### read PKGLIST from official install-script ### read PKGLIST from official install-script
@@ -152,21 +152,11 @@ function install_moonraker_dependencies() {
echo "${cyan}${packages}${white}" | tr '[:space:]' '\n' echo "${cyan}${packages}${white}" | tr '[:space:]' '\n'
read -r -a packages <<< "${packages}" read -r -a packages <<< "${packages}"
### Update system package info ### Update system package lists if stale
status_msg "Updating package lists..." update_system_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 ### Install required packages
status_msg "Installing required packages..." install_system_packages "${log_name}" "packages[@]"
if ! sudo apt-get install --yes "${packages[@]}"; then
log_error "failure while installing required moonraker packages"
error_msg "Installing required packages failed!"
exit 1
fi
} }
function create_moonraker_virtualenv() { function create_moonraker_virtualenv() {
@@ -205,7 +195,7 @@ function moonraker_setup() {
create_moonraker_conf "${instance_arr[@]}" create_moonraker_conf "${instance_arr[@]}"
### step 4: create moonraker instances ### step 4: create moonraker instances
create_moonraker_service "${instance_arr[@]}" configure_moonraker_service "${instance_arr[@]}"
### step 5: create polkit rules for moonraker ### step 5: create polkit rules for moonraker
install_moonraker_polkit || true install_moonraker_polkit || true
@@ -240,18 +230,19 @@ function create_moonraker_conf() {
local input=("${@}") local input=("${@}")
local moonraker_count=${input[0]} && unset "input[0]" local moonraker_count=${input[0]} && unset "input[0]"
local names=("${input[@]}") && unset "input[@]" local names=("${input[@]}") && unset "input[@]"
local log="${KLIPPER_LOGS}" local port lan printer_data cfg_dir cfg uds
local lan
port=7125
lan="$(hostname -I | cut -d" " -f1 | cut -d"." -f1-2).0.0/16" 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 if (( moonraker_count == 1 )); then
cfg_dir="${KLIPPER_CONFIG}" printer_data="${HOME}/printer_data"
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/moonraker.conf" cfg="${cfg_dir}/moonraker.conf"
db="${HOME}/.moonraker_database" uds="${printer_data}/comms/klippy.sock"
uds="/tmp/klippy_uds"
### write single instance config ### 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 elif (( moonraker_count > 1 )); then
local j=0 re="^[1-9][0-9]*$" local j=0 re="^[1-9][0-9]*$"
@@ -259,16 +250,17 @@ function create_moonraker_conf() {
for (( i=1; i <= moonraker_count; i++ )); do for (( i=1; i <= moonraker_count; i++ )); do
### overwrite config folder if name is only a number ### overwrite config folder if name is only a number
if [[ ${names[j]} =~ ${re} ]]; then if [[ ${names[j]} =~ ${re} ]]; then
cfg_dir="${KLIPPER_CONFIG}/printer_${names[${j}]}" printer_data="${HOME}/printer_${names[${j}]}_data"
else else
cfg_dir="${KLIPPER_CONFIG}/${names[${j}]}" printer_data="${HOME}/${names[${j}]}_data"
fi fi
cfg_dir="${printer_data}/config"
cfg="${cfg_dir}/moonraker.conf" cfg="${cfg_dir}/moonraker.conf"
uds="/tmp/klippy_uds-${names[${j}]}" uds="${printer_data}/comms/klippy.sock"
db="${HOME}/.moonraker_database_${names[${j}]}"
### write multi instance config ### 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 )) port=$(( port + 1 ))
j=$(( j + 1 )) j=$(( j + 1 ))
done && unset j done && unset j
@@ -279,7 +271,7 @@ function create_moonraker_conf() {
} }
function write_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" local conf_template="${KIAUH_SRCDIR}/resources/moonraker.conf"
[[ ! -d ${cfg_dir} ]] && mkdir -p "${cfg_dir}" [[ ! -d ${cfg_dir} ]] && mkdir -p "${cfg_dir}"
@@ -287,8 +279,7 @@ function write_moonraker_conf() {
if [[ ! -f ${cfg} ]]; then if [[ ! -f ${cfg} ]]; then
status_msg "Creating moonraker.conf in ${cfg_dir} ..." status_msg "Creating moonraker.conf in ${cfg_dir} ..."
cp "${conf_template}" "${cfg}" cp "${conf_template}" "${cfg}"
sed -i "s|%USER%|${USER}|g" "${cfg}" sed -i "s|%USER%|${USER}|g; s|%PORT%|${port}|; s|%UDS%|${uds}|" "${cfg}"
sed -i "s|%CFG%|${cfg_dir}|; s|%PORT%|${port}|; s|%LOG%|${log}|; s|%DB%|${db}|; s|%UDS%|${uds}|" "${cfg}"
# if host ip is not in the default ip ranges replace placeholder, # if host ip is not in the default ip ranges replace placeholder,
# otherwise remove placeholder from config # otherwise remove placeholder from config
if ! grep -q "${lan}" "${cfg}"; then if ! grep -q "${lan}" "${cfg}"; then
@@ -302,20 +293,24 @@ function write_moonraker_conf() {
fi fi
} }
function create_moonraker_service() { function configure_moonraker_service() {
local input=("${@}") local input=("${@}")
local moonraker_count=${input[0]} && unset "input[0]" local moonraker_count=${input[0]} && unset "input[0]"
local names=("${input[@]}") && unset "input[@]" 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 if (( moonraker_count == 1 )) && [[ ${#names[@]} -eq 0 ]]; then
i="" i=""
cfg_dir="${KLIPPER_CONFIG}" printer_data="${HOME}/printer_data"
cfg="${cfg_dir}/moonraker.conf" cfg_dir="${printer_data}/config"
log="${KLIPPER_LOGS}/moonraker.log"
service="${SYSTEMD}/moonraker.service" 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 single instance service
write_moonraker_service "" "${cfg}" "${log}" "${service}" write_moonraker_service "" "${printer_data}" "${service}" "${env_file}"
ok_msg "Moonraker instance created!" ok_msg "Moonraker instance created!"
elif (( moonraker_count > 1 )) && [[ ${#names[@]} -gt 0 ]]; then elif (( moonraker_count > 1 )) && [[ ${#names[@]} -gt 0 ]]; then
@@ -324,16 +319,20 @@ function create_moonraker_service() {
for (( i=1; i <= moonraker_count; i++ )); do for (( i=1; i <= moonraker_count; i++ )); do
### overwrite config folder if name is only a number ### overwrite config folder if name is only a number
if [[ ${names[j]} =~ ${re} ]]; then if [[ ${names[j]} =~ ${re} ]]; then
cfg_dir="${KLIPPER_CONFIG}/printer_${names[${j}]}" printer_data="${HOME}/printer_${names[${j}]}_data"
else else
cfg_dir="${KLIPPER_CONFIG}/${names[${j}]}" printer_data="${HOME}/${names[${j}]}_data"
fi fi
cfg="${cfg_dir}/moonraker.conf" cfg_dir="${printer_data}/config"
log="${KLIPPER_LOGS}/moonraker-${names[${j}]}.log"
service="${SYSTEMD}/moonraker-${names[${j}]}.service" 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 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!" ok_msg "Moonraker instance 'moonraker-${names[${j}]}' created!"
j=$(( j + 1 )) j=$(( j + 1 ))
done && unset i done && unset i
@@ -349,18 +348,20 @@ function create_moonraker_service() {
} }
function write_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 service_template="${KIAUH_SRCDIR}/resources/moonraker.service"
local env_template="${KIAUH_SRCDIR}/resources/moonraker.env"
### replace all placeholders ### replace all placeholders
if [[ ! -f ${service} ]]; then if [[ ! -f ${service} ]]; then
status_msg "Creating Moonraker Service ${i} ..." status_msg "Creating Moonraker Service ${i} ..."
sudo cp "${service_template}" "${service}" 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}" [[ -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|%USER%|${USER}|g; s|%MOONRAKER_DIR%|${MOONRAKER_DIR}|; s|%ENV%|${MOONRAKER_ENV}|; s|%ENV_FILE%|${env_file}|" "${service}"
sudo sed -i "s|%CFG%|${cfg}|; s|%LOG%|${log}|" "${service}" sudo sed -i "s|%USER%|${USER}|; s|%MOONRAKER_DIR%|${MOONRAKER_DIR}|; s|%PRINTER_DATA%|${printer_data}|" "${env_file}"
fi fi
} }
@@ -453,9 +454,35 @@ function remove_moonraker_systemd() {
ok_msg "Moonraker Services removed!" ok_msg "Moonraker Services removed!"
} }
function remove_moonraker_env_file() {
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/systemd\/moonraker\.env"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_moonraker_logs() { function remove_moonraker_logs() {
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/logs\/moonraker\.log.*"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_legacy_moonraker_logs() {
local files regex="moonraker(-[0-9a-zA-Z]+)?\.log(.*)?" 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 if [[ -n ${files} ]]; then
for file in ${files}; do for file in ${files}; do
@@ -509,7 +536,9 @@ function remove_moonraker_polkit() {
function remove_moonraker() { function remove_moonraker() {
remove_moonraker_sysvinit remove_moonraker_sysvinit
remove_moonraker_systemd remove_moonraker_systemd
remove_moonraker_env_file
remove_moonraker_logs remove_moonraker_logs
remove_legacy_moonraker_logs
remove_moonraker_api_key remove_moonraker_api_key
remove_moonraker_polkit remove_moonraker_polkit
remove_moonraker_dir remove_moonraker_dir

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -74,23 +74,29 @@ function set_upstream_nginx_cfg() {
} }
function symlink_webui_nginx_log() { function symlink_webui_nginx_log() {
local interface=${1} path="${KLIPPER_LOGS}" local interface path access_log error_log regex logpaths
local access_log="/var/log/nginx/${interface}-access.log"
local error_log="/var/log/nginx/${interface}-error.log"
[[ ! -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//\//\\/}\/([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 for path in ${logpaths}; do
status_msg "Creating symlink for ${access_log} ..." [[ ! -d ${path} ]] && mkdir -p "${path}"
ln -s "${access_log}" "${path}"
ok_msg "Done!"
fi
if [[ -f ${error_log} && ! -L "${path}/${interface}-error.log" ]]; then if [[ -f ${access_log} && ! -L "${path}/${interface}-access.log" ]]; then
status_msg "Creating symlink for ${error_log} ..." status_msg "Creating symlink for ${access_log} ..."
ln -s "${error_log}" "${path}" ln -s "${access_log}" "${path}"
ok_msg "Done!" ok_msg "Symlink created: ${path}/${interface}-access.log"
fi 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() { function match_nginx_configs() {
@@ -351,4 +357,4 @@ function detect_enabled_sites() {
FLUIDD_PORT=$(read_listen_port "fluidd") FLUIDD_PORT=$(read_listen_port "fluidd")
fi fi
} }

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -24,7 +24,7 @@ function moonraker_obico_systemd() {
function moonraker_obico_config() { function moonraker_obico_config() {
local moonraker_cfg_dirs local moonraker_cfg_dirs
read -r -a moonraker_cfg_dirs <<< "$(get_config_folders)" read -r -a moonraker_cfg_dirs <<< "$(get_instance_folder_path "config")"
if (( ${#moonraker_cfg_dirs[@]} > 0 )); then if (( ${#moonraker_cfg_dirs[@]} > 0 )); then
echo "${moonraker_cfg_dirs[${1}]}/moonraker-obico.cfg" echo "${moonraker_cfg_dirs[${1}]}/moonraker-obico.cfg"
@@ -63,8 +63,7 @@ function obico_server_url_prompt() {
} }
function moonraker_obico_setup_dialog() { function moonraker_obico_setup_dialog() {
status_msg "Initializing Moonraker-obico installation ..." status_msg "Initializing Obico installation ..."
local moonraker_count local moonraker_count
local moonraker_names local moonraker_names
@@ -74,7 +73,7 @@ function moonraker_obico_setup_dialog() {
if (( moonraker_count == 0 )); then if (( moonraker_count == 0 )); then
### return early if moonraker is not installed ### return early if moonraker is not installed
local error="Moonraker not installed! Please install Moonraker first!" local error="Moonraker not installed! Please install Moonraker first!"
log_error "Moonraker-obico setup started without Moonraker being installed. Aborting setup." log_error "Obico setup started without Moonraker being installed. Aborting setup."
print_error "${error}" && return print_error "${error}" && return
elif (( moonraker_count > 1 )); then elif (( moonraker_count > 1 )); then
# moonraker_names is valid only in case of multi-instance # moonraker_names is valid only in case of multi-instance
@@ -86,6 +85,32 @@ function moonraker_obico_setup_dialog() {
moonraker_obico_services=$(moonraker_obico_systemd) moonraker_obico_services=$(moonraker_obico_systemd)
existing_moonraker_obico_count=$(echo "${moonraker_obico_services}" | wc -w ) existing_moonraker_obico_count=$(echo "${moonraker_obico_services}" | wc -w )
local allowed_moonraker_obico_count=$(( moonraker_count - existing_moonraker_obico_count )) local allowed_moonraker_obico_count=$(( moonraker_count - existing_moonraker_obico_count ))
# Allow user to reinstall an incomplete installation.
if (( allowed_moonraker_obico_count == 0 && moonraker_count > 0 )) && [[ $(get_moonraker_obico_status) != "Not linked!" ]]; then
local yn
while true; do
echo "${yellow}Obico is already installed.${white}"
echo "It is safe to run the install again to repair any issues."
echo ""
local question="Do you want to reinstall Obico?"
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 Obico installation...\n"
return;;
*)
error_msg "Invalid Input!";;
esac
done
# The user responded yes, allow the install to run again.
allowed_moonraker_obico_count=1
fi
if (( allowed_moonraker_obico_count > 0 )); then if (( allowed_moonraker_obico_count > 0 )); then
local new_moonraker_obico_count local new_moonraker_obico_count
@@ -101,32 +126,30 @@ function moonraker_obico_setup_dialog() {
done done
blank_line blank_line
if (( existing_moonraker_obico_count > 0 )); then if (( existing_moonraker_obico_count > 0 )); then
printf "|${green}%-55s${white}|\n" " ${existing_moonraker_obico_count} Moonraker-obico instances already installed!" printf "|${green}%-55s${white}|\n" " ${existing_moonraker_obico_count} Obico instances already installed!"
for svc in ${moonraker_obico_services}; do 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}")" printf "|${cyan}%-57s${white}|\n" " ● moonraker-obco-$(get_instance_name "${svc}")"
done done
fi fi
blank_line blank_line
echo -e "| The setup will apply the same names to |" echo -e "| The setup will apply the same names to Obico! |"
echo -e "| Moonraker-obico! |"
blank_line blank_line
echo -e "| Please select the number of Moonraker-obico instances |" echo -e "| Please select the number of Obico instances |"
echo -e "| to install. Usually one Moonraker-obico instance per |" echo -e "| to install. Usually one Obico instance per |"
echo -e "| Moonraker instance is required, but you may not |" echo -e "| Moonraker instance is required, but you may not |"
echo -e "| install more Moonraker-obico instances than available |" echo -e "| install more Obico instances than available |"
echo -e "| Moonraker instances. |" echo -e "| Moonraker instances. |"
bottom_border bottom_border
### ask for amount of instances ### ask for amount of instances
local re="^[1-9][0-9]*$" local re="^[1-9][0-9]*$"
while [[ ! ${new_moonraker_obico_count} =~ ${re} || ${new_moonraker_obico_count} -gt ${allowed_moonraker_obico_count} ]]; do 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 read -p "${cyan}###### Number of new Obico instances to set up:${white} " -i "${allowed_moonraker_obico_count}" -e new_moonraker_obico_count
### break if input is valid ### break if input is valid
[[ ${new_moonraker_obico_count} =~ ${re} && ${new_moonraker_obico_count} -le ${allowed_moonraker_obico_count} ]] && break [[ ${new_moonraker_obico_count} =~ ${re} && ${new_moonraker_obico_count} -le ${allowed_moonraker_obico_count} ]] && break
### conditional error messages ### conditional error messages
[[ ! ${new_moonraker_obico_count} =~ ${re} ]] && error_msg "Input not a number" [[ ! ${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" (( new_moonraker_obico_count > allowed_moonraker_obico_count )) && error_msg "Number of Obico instances larger than installed Moonraker instances"
done && select_msg "${new_moonraker_obico_count}" done && select_msg "${new_moonraker_obico_count}"
else else
log_error "Internal error. moonraker_count of '${moonraker_count}' not equal or grather than one!" log_error "Internal error. moonraker_count of '${moonraker_count}' not equal or grather than one!"
@@ -136,8 +159,8 @@ function moonraker_obico_setup_dialog() {
### Step 2: Confirm instance amount ### Step 2: Confirm instance amount
local yn local yn
while true; do while true; do
(( new_moonraker_obico_count == 1 )) && local question="Install Moonraker-obico?" (( new_moonraker_obico_count == 1 )) && local question="Install Obico?"
(( new_moonraker_obico_count > 1 )) && local question="Install ${new_moonraker_obico_count} Moonraker-obico instances?" (( new_moonraker_obico_count > 1 )) && local question="Install ${new_moonraker_obico_count} Obico instances?"
read -p "${cyan}###### ${question} (Y/n):${white} " yn read -p "${cyan}###### ${question} (Y/n):${white} " yn
case "${yn}" in case "${yn}" in
Y|y|Yes|yes|"") Y|y|Yes|yes|"")
@@ -145,7 +168,7 @@ function moonraker_obico_setup_dialog() {
break;; break;;
N|n|No|no) N|n|No|no)
select_msg "No" select_msg "No"
abort_msg "Exiting Moonraker-obico setup ...\n" abort_msg "Exiting Obico setup ...\n"
return;; return;;
*) *)
error_msg "Invalid Input!";; error_msg "Invalid Input!";;
@@ -167,29 +190,37 @@ function moonraker_obico_setup_dialog() {
fi fi
done done
(( new_moonraker_obico_count > 1 )) && status_msg "Installing ${new_moonraker_obico_count} Moonraker-obico instances ..." (( new_moonraker_obico_count > 1 )) && status_msg "Installing ${new_moonraker_obico_count} Obico instances ..."
(( new_moonraker_obico_count == 1 )) && status_msg "Installing Moonraker-obico ..." (( new_moonraker_obico_count == 1 )) && status_msg "Installing 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 ### Step 5: Clone the moonraker-obico repo
clone_moonraker_obico "${MOONRAKER_OBICO_REPO}" clone_moonraker_obico "${MOONRAKER_OBICO_REPO}"
### step 6: call moonrake-obico/install.sh with the correct params ### step 6: call moonrake-obico/install.sh with the correct params
local port=7125 local port=7125
local moonraker_cfg_dirs local instance_cfg_dirs
local instance_log_dirs
read -r -a moonraker_cfg_dirs <<< "$(get_config_folders)" read -r -a instance_cfg_dirs <<< "$(get_instance_folder_path "config")"
read -r -a instance_log_dirs <<< "$(get_instance_folder_path "logs")"
if (( moonraker_count == 1 )); then if (( moonraker_count == 1 )); then
"${MOONRAKER_OBICO_DIR}/install.sh" -C "${moonraker_cfg_dirs[0]}/moonraker.conf" -p "${port}" -H 127.0.0.1 -l "${KLIPPER_LOGS}" -s -L -S "${obico_server_url}" "${MOONRAKER_OBICO_DIR}/install.sh"\
-C "${instance_cfg_dirs[0]}/moonraker.conf"\
-p "${port}" -H 127.0.0.1 -l\
"${instance_log_dirs[0]}"\
-L -S "${obico_server_url}"
elif (( moonraker_count > 1 )); then elif (( moonraker_count > 1 )); then
local j=${existing_moonraker_obico_count} local j=${existing_moonraker_obico_count}
for (( i=1; i <= new_moonraker_obico_count; i++ )); do for (( i=1; i <= new_moonraker_obico_count; i++ )); do
"${MOONRAKER_OBICO_DIR}/install.sh" -n "${moonraker_names[${j}]}" -C "${moonraker_cfg_dirs[${j}]}/moonraker.conf" -p $((port+j)) -H 127.0.0.1 -l "${KLIPPER_LOGS}" -s -L -S "${obico_server_url}" "${MOONRAKER_OBICO_DIR}/install.sh"\
-n "${moonraker_names[${j}]}"\
-C "${instance_cfg_dirs[${j}]}/moonraker.conf"\
-p $((port+j))\
-H 127.0.0.1\
-l "${instance_log_dirs[${j}]}"\
-L -S "${obico_server_url}"
j=$(( j + 1 )) j=$(( j + 1 ))
done && unset j done && unset j
fi # (( moonraker_count == 1 )) fi # (( moonraker_count == 1 ))
@@ -212,17 +243,16 @@ function moonraker_obico_setup_dialog() {
if (( ${#not_linked_instances[@]} > 0 )); then if (( ${#not_linked_instances[@]} > 0 )); then
top_border top_border
if (( moonraker_count == 1 )); then if (( moonraker_count == 1 )); then
printf "|${green}%-55s${white}|\n" " Moonraker-obico not linked to the server!" printf "|${green}%-55s${white}|\n" " Obico not linked to the server!"
else else
printf "|${green}%-55s${white}|\n" " ${#not_linked_instances[@]} Moonraker-obico instances not linked to the server!" printf "|${green}%-55s${white}|\n" " ${#not_linked_instances[@]} Obico instances not linked to the server!"
for i in "${not_linked_instances[@]}"; do for i in "${not_linked_instances[@]}"; do
printf "|${cyan}%-57s${white}|\n" " ● moonraker-obico-${moonraker_names[${i}]}" printf "|${cyan}%-57s${white}|\n" " ● moonraker-obico-${moonraker_names[${i}]}"
done done
fi fi
blank_line blank_line
echo -e "| To link to your Obico Server account, you need to |" echo -e "| It will take only 10 seconds to link printer to Obico.|"
echo -e "| obtain the 6-digit verification code in the Obico |" echo -e "| For more information, visit: |"
echo -e "| mobile or web app. For more information, visit: |"
echo -e "| https://www.obico.io/docs/user-guides/klipper-setup/ |" echo -e "| https://www.obico.io/docs/user-guides/klipper-setup/ |"
blank_line blank_line
echo -e "| If you don't want to link the printer now, you can |" echo -e "| If you don't want to link the printer now, you can |"
@@ -240,7 +270,7 @@ function moonraker_obico_setup_dialog() {
break;; break;;
N|n|No|no) N|n|No|no)
select_msg "No" select_msg "No"
abort_msg "Exiting Moonraker-obico setup ...\n" abort_msg "Exiting Obico setup ...\n"
return;; return;;
*) *)
error_msg "Invalid Input!";; error_msg "Invalid Input!";;
@@ -263,13 +293,13 @@ function moonraker_obico_setup_dialog() {
function clone_moonraker_obico() { function clone_moonraker_obico() {
local repo=${1} local repo=${1}
status_msg "Cloning Moonraker-obico from ${repo} ..." status_msg "Cloning Obico from ${repo} ..."
### force remove existing Moonraker-obico dir ### force remove existing Obico dir
[[ -d "${MOONRAKER_OBICO_DIR}" ]] && rm -rf "${MOONRAKER_OBICO_DIR}" [[ -d "${MOONRAKER_OBICO_DIR}" ]] && rm -rf "${MOONRAKER_OBICO_DIR}"
cd "${HOME}" || exit 1 cd "${HOME}" || exit 1
if ! git clone "${repo}" "${MOONRAKER_OBICO_DIR}"; then if ! git clone "${repo}" "${MOONRAKER_OBICO_DIR}"; then
print_error "Cloning Moonraker-obico from\n ${repo}\n failed!" print_error "Cloning Obico from\n ${repo}\n failed!"
exit 1 exit 1
fi fi
} }
@@ -284,7 +314,7 @@ function moonraker_obico_install() {
function remove_moonraker_obico_systemd() { function remove_moonraker_obico_systemd() {
[[ -z $(moonraker_obico_systemd) ]] && return [[ -z $(moonraker_obico_systemd) ]] && return
status_msg "Removing Moonraker-obico Systemd Services ..." status_msg "Removing Obico Systemd Services ..."
for service in $(moonraker_obico_systemd | cut -d"/" -f5); do for service in $(moonraker_obico_systemd | cut -d"/" -f5); do
status_msg "Removing ${service} ..." status_msg "Removing ${service} ..."
@@ -297,12 +327,25 @@ function remove_moonraker_obico_systemd() {
### reloading units ### reloading units
sudo systemctl daemon-reload sudo systemctl daemon-reload
sudo systemctl reset-failed sudo systemctl reset-failed
ok_msg "Moonraker-obico Services removed!" ok_msg "Obico Services removed!"
} }
function remove_moonraker_obico_logs() { function remove_moonraker_obico_logs() {
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/logs\/moonraker-obico(-[0-9a-zA-Z]+)?\.log(.*)?"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_legacy_moonraker_obico_logs() {
local files regex="moonraker-obico(-[0-9a-zA-Z]+)?\.log(.*)?" local files regex="moonraker-obico(-[0-9a-zA-Z]+)?\.log(.*)?"
files=$(find "${KLIPPER_LOGS}" -maxdepth 1 -regextype posix-extended -regex "${KLIPPER_LOGS}/${regex}" 2> /dev/null | sort) files=$(find "${HOME}/klipper_logs" -maxdepth 1 -regextype posix-extended -regex "${HOME}/klipper_logs/${regex}" 2> /dev/null | sort)
if [[ -n ${files} ]]; then if [[ -n ${files} ]]; then
for file in ${files}; do for file in ${files}; do
@@ -316,7 +359,7 @@ function remove_moonraker_obico_logs() {
function remove_moonraker_obico_dir() { function remove_moonraker_obico_dir() {
[[ ! -d ${MOONRAKER_OBICO_DIR} ]] && return [[ ! -d ${MOONRAKER_OBICO_DIR} ]] && return
status_msg "Removing Moonraker-obico directory ..." status_msg "Removing Obico directory ..."
rm -rf "${MOONRAKER_OBICO_DIR}" rm -rf "${MOONRAKER_OBICO_DIR}"
ok_msg "Directory removed!" ok_msg "Directory removed!"
} }
@@ -335,7 +378,7 @@ function remove_moonraker_obico() {
remove_moonraker_obico_dir remove_moonraker_obico_dir
remove_moonraker_obico_env remove_moonraker_obico_env
print_confirm "Moonraker-obico was successfully removed!" print_confirm "Obico was successfully removed!"
return return
} }
@@ -349,10 +392,12 @@ function update_moonraker_obico() {
if [[ ! -d ${MOONRAKER_OBICO_DIR} ]]; then if [[ ! -d ${MOONRAKER_OBICO_DIR} ]]; then
clone_moonraker_obico "${MOONRAKER_OBICO_REPO}" clone_moonraker_obico "${MOONRAKER_OBICO_REPO}"
else else
status_msg "Updating Moonraker-obico ..." status_msg "Updating Obico ..."
cd "${MOONRAKER_OBICO_DIR}" && git pull cd "${MOONRAKER_OBICO_DIR}" && git pull
fi fi
"${MOONRAKER_OBICO_DIR}/install.sh" -U
ok_msg "Update complete!" ok_msg "Update complete!"
do_action_service "restart" "moonraker-obico" do_action_service "restart" "moonraker-obico"
} }
@@ -372,7 +417,7 @@ function get_moonraker_obico_status() {
is_linked="true" is_linked="true"
if [[ -n ${moonraker_obico_services} ]]; then if [[ -n ${moonraker_obico_services} ]]; then
for cfg_dir in $(get_config_folders); do for cfg_dir in $(get_instance_folder_path "config"); do
if moonraker_obico_needs_linking "${cfg_dir}/moonraker-obico.cfg"; then if moonraker_obico_needs_linking "${cfg_dir}/moonraker-obico.cfg"; then
is_linked="false" is_linked="false"
fi fi

369
scripts/octoapp.sh Normal file
View File

@@ -0,0 +1,369 @@
#!/usr/bin/env bash
#=======================================================================#
# Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# #
# This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/dw-0/kiauh #
# #
# This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================#
#
# This file is written and maintained by Christian Würthner from OctoApp
# Please contact me if you need any help!
# hello@octoapp.eu
#
set -e
#===================================================#
#============== Install ============#
#===================================================#
function octoapp_systemd() {
local services
services=$(find "${SYSTEMD}" -maxdepth 1 -regextype posix-extended -regex "${SYSTEMD}/octoapp(-[0-9a-zA-Z]+)?.service")
echo "${services}"
}
function octoapp_setup_dialog() {
status_msg "Initializing OctoApp for Klipper installation ..."
# First, check for moonraker service instances.
local moonraker_count
local moonraker_names
moonraker_count=$(moonraker_systemd | wc -w)
if (( moonraker_count == 0 )); then
### return early if moonraker is not installed
local error="Moonraker not installed! Please install Moonraker first!"
log_error "OctoApp setup started without Moonraker being installed. Aborting setup."
print_error "${error}" && return
elif (( moonraker_count > 1 )); then
# moonraker_names is valid only in case of multi-instance
read -r -a moonraker_names <<< "$(get_multi_instance_names)"
fi
# Next, check for any existing OctoApp services.
local octoapp_services
local existing_octoapp_count
octoapp_services=$(octoapp_systemd)
existing_octoapp_count=$(echo "${octoapp_services}" | wc -w )
# We need to make the moonraker instance count to the OctoApp service count.
local allowed_octoapp_count=$(( moonraker_count - existing_octoapp_count ))
if (( allowed_octoapp_count > 0 )); then
local new_octoapp_count
### Step 1: Ask for the number of OctoApp instances to install
if (( moonraker_count == 1 )); then
ok_msg "Moonraker installation found!\n"
new_octoapp_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_octoapp_count > 0 )); then
printf "|${green}%-55s${white}|\n" " ${existing_octoapp_count} OctoApp instances already installed!"
for svc in ${octoapp_services}; do
printf "|${cyan}%-57s${white}|\n" " ● octoapp-$(get_instance_name "${svc}")"
done
fi
blank_line
echo -e "| The setup will apply the same names to OctoApp |"
blank_line
echo -e "| Please select the number of OctoApp instances to |"
echo -e "| install. Usually one OctoApp instance per Moonraker |"
echo -e "| instance is required, but you may not install more |"
echo -e "| OctoApp instances than available Moonraker instances. |"
bottom_border
### ask for amount of instances
local re="^[1-9][0-9]*$"
while [[ ! ${new_octoapp_count} =~ ${re} || ${new_octoapp_count} -gt ${allowed_octoapp_count} ]]; do
read -p "${cyan}###### Number of new OctoApp instances to set up:${white} " -i "${allowed_octoapp_count}" -e new_octoapp_count
### break if input is valid
[[ ${new_octoapp_count} =~ ${re} && ${new_octoapp_count} -le ${allowed_octoapp_count} ]] && break
### conditional error messages
[[ ! ${new_octoapp_count} =~ ${re} ]] && error_msg "Input not a number"
(( new_octoapp_count > allowed_octoapp_count )) && error_msg "Number of OctoApp instances larger than installed Moonraker instances"
done && select_msg "${new_octoapp_count}"
else
log_error "Internal error. moonraker_count of '${moonraker_count}' not equal or grater than one!"
return 1
fi # (( moonraker_count == 1 ))
fi # (( allowed_octoapp_count > 0 ))
# Special case for one moonraker instance with OctoApp already installed.
# If the user selects the install option again, they might be trying to recover the install
# or complete a printer link they didn't finish in the past.
# So in this case, we will allow them to run the install script again, since it's safe to run
# if the service is already installed, it will repair any missing issues.
if (( allowed_octoapp_count == 0 && moonraker_count == 1 )); then
local yn
while true; do
echo "${yellow}OctoApp is already installed.${white}"
echo "It is safe to run the install again to repair any issues or if the printer isn't linked, run the printer linking logic again."
echo ""
local question="Do you want to run the OctoApp recovery or linking logic again?"
read -p "${cyan}###### ${question} (Y/n):${white} " yn
case "${yn}" in
Y|y|Yes|yes|"")
select_msg "Yes"
break;;
N|n|No|no)
select_msg "No"
abort_msg "Exiting OctoApp setup ...\n"
return;;
*)
error_msg "Invalid Input!";;
esac
done
# The user responded yes, allow the install to run again.
allowed_octoapp_count=1
fi
# If there's something to install, do it!
if (( allowed_octoapp_count > 0 )); then
(( new_octoapp_count > 1 )) && status_msg "Installing ${new_octoapp_count} OctoApp instances ..."
(( new_octoapp_count == 1 )) && status_msg "Installing OctoApp ..."
# Ensure the basic system dependencies are installed.
local dep=(git dfu-util virtualenv python3 python3-pip python3-venv)
dependency_check "${dep[@]}"
# Close the repo
clone_octoapp "${OCTOAPP_REPO}"
# Call install with the correct args.
local instance_cfg_dirs
read -r -a instance_cfg_dirs <<< "$(get_instance_folder_path "config")"
echo instance_cfg_dirs[0]
if (( moonraker_count == 1 )); then
"${OCTOAPP_DIR}/install.sh" "${instance_cfg_dirs[0]}/moonraker.conf"
elif (( moonraker_count > 1 )); then
local j=${existing_octoapp_count}
for (( i=1; i <= new_octoapp_count; i++ )); do
"${OCTOAPP_DIR}/install.sh" "${instance_cfg_dirs[${j}]}/moonraker.conf"
j=$(( j + 1 ))
done && unset j
fi # (( moonraker_count == 1 ))
fi # (( allowed_octoapp_count > 0 ))
}
function octoapp_install() {
"${OCTOAPP_DIR}/install.sh" "$@"
}
#===================================================#
#============= Remove ==============#
#===================================================#
function remove_octoapp_systemd() {
[[ -z $(octoapp_systemd) ]] && return
status_msg "Removing OctoApp Systemd Services ..."
for service in $(octoapp_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 "OctoApp Services removed!"
}
function remove_octoapp_logs() {
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/logs\/octoapp(-[0-9a-zA-Z]+)?\.log(.*)?"
files=$(find "${HOME}" -maxdepth 3 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_octoapp_dir() {
[[ ! -d ${OCTOAPP_DIR} ]] && return
status_msg "Removing OctoApp directory ..."
rm -rf "${OCTOAPP_DIR}"
ok_msg "Directory removed!"
}
function remove_octoapp_config() {
# Remove the system config but not the main config, so the printer id doesn't get lost.
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/config\/octoapp-system(-[0-9a-zA-Z]+)?\.cfg(.*)?"
files=$(find "${HOME}" -maxdepth 4 -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -f "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_octoapp_store_dir() {
local files regex="${HOME//\//\\/}\/([A-Za-z0-9_]+)\/octoapp-store"
files=$(find "${HOME}" -maxdepth 2 -type d -regextype posix-extended -regex "${regex}" | sort)
if [[ -n ${files} ]]; then
for file in ${files}; do
status_msg "Removing ${file} ..."
rm -rf "${file}"
ok_msg "${file} removed!"
done
fi
}
function remove_octoapp_env() {
[[ ! -d "${HOME}/octoapp-env" ]] && return
status_msg "Removing octoapp-env directory ..."
rm -rf "${HOME}/octoapp-env"
ok_msg "Directory removed!"
}
function remove_octoapp()
{
remove_octoapp_systemd
remove_octoapp_logs
remove_octoapp_dir
remove_octoapp_env
remove_octoapp_config
remove_octoapp_store_dir
print_confirm "OctoApp was successfully removed!"
return
}
#===================================================#
#============= UPDATE ==============#
#===================================================#
function update_octoapp() {
do_action_service "stop" "octoapp"
if [[ ! -d ${OCTOAPP_DIR} ]]; then
clone_octoapp "${OCTOAPP_REPO}"
else
backup_before_update "octoapp"
status_msg "Updating OctoApp for Klipper ..."
cd "${OCTOAPP_DIR}" && git pull
### read PKGLIST and install possible new dependencies
install_octoapp_dependencies
### install possible new python dependencies
"${OCTOAPP_ENV}"/bin/pip install -r "${OCTOAPP_DIR}/requirements.txt"
fi
ok_msg "Update complete!"
do_action_service "restart" "octoapp"
}
function clone_octoapp() {
local repo=${1}
status_msg "Cloning OctoApp from ${repo} ..."
### force remove existing octoapp dir and clone into fresh octoapp dir
[[ -d ${OCTOAPP_DIR} ]] && rm -rf "${OCTOAPP_DIR}"
cd "${HOME}" || exit 1
if ! git clone "${OCTOAPP_REPO}" "${OCTOAPP_DIR}"; then
print_error "Cloning OctoApp from\n ${repo}\n failed!"
exit 1
fi
}
function install_octoapp_dependencies() {
local packages log_name="OctoApp"
local install_script="${OCTOAPP_DIR}/install.sh"
### read PKGLIST from official install-script
status_msg "Reading dependencies..."
# shellcheck disable=SC2016
packages="$(grep "PKGLIST=" "${install_script}" | cut -d'"' -f2 | sed 's/\${PKGLIST}//g' | tr -d '\n')"
echo "${cyan}${packages}${white}" | tr '[:space:]' '\n'
read -r -a packages <<< "${packages}"
### Update system package lists if stale
update_system_package_lists
### Install required packages
install_system_packages "${log_name}" "packages[@]"
}
#===================================================#
#============= STATUS ==============#
#===================================================#
function get_octoapp_status() {
local status
local service_count
local octoapp_services
octoapp_services=$(octoapp_systemd)
service_count=$(echo "${octoapp_services}" | wc -w )
if (( service_count == 0 )); then
status="Not installed!"
elif [[ ! -d "${OCTOAPP_DIR}" ]]; then
status="Incomplete!"
else
status="Installed!"
fi
echo "${status}"
}
function get_local_octoapp_commit() {
[[ ! -d ${OCTOAPP_DIR} || ! -d "${OCTOAPP_DIR}/.git" ]] && return
local commit
cd "${OCTOAPP_DIR}"
commit="$(git describe HEAD --always --tags | cut -d "-" -f 1,2)"
echo "${commit}"
}
function get_remote_octoapp_commit() {
[[ ! -d ${OCTOAPP_DIR} || ! -d "${OCTOAPP_DIR}/.git" ]] && return
local commit
cd "${OCTOAPP_DIR}" && git fetch origin -q
commit=$(git describe origin/release --always --tags | cut -d "-" -f 1,2)
echo "${commit}"
}
function compare_octoapp_versions() {
local versions local_ver remote_ver
local_ver="$(get_local_octoapp_commit)"
remote_ver="$(get_remote_octoapp_commit)"
if [[ ${local_ver} != "${remote_ver}" ]]; then
versions="${yellow}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
# Add us to the update file, so if the user selects "update all" it includes us.
add_to_application_updates "octoapp"
else
versions="${green}$(printf " %-14s" "${local_ver}")${white}"
versions+="|${green}$(printf " %-13s" "${remote_ver}")${white}"
fi
echo "${versions}"
}

385
scripts/octoeverywhere.sh Normal file
View File

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

View File

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

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -38,7 +38,7 @@ function install_pgc_for_klipper() {
fi fi
sudo cp "${pgconfsrc}" "${pgconf}" sudo cp "${pgconfsrc}" "${pgconf}"
sudo sed -i "s|/home/pi/pgcode;|/home/${USER}/pgcode;|" "${pgconf}" sudo sed -i "s|/home/pi/pgcode;|${HOME}/pgcode;|" "${pgconf}"
### replace default port ### replace default port
if (( pgc_custom_port != pgc_default_port )); then if (( pgc_custom_port != pgc_default_port )); then
@@ -124,4 +124,4 @@ function compare_prettygcode_versions() {
fi fi
echo "${versions}" echo "${versions}"
} }

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -77,10 +77,12 @@ function change_klipper_repo_menu() {
error_msg "Invalid command!";; error_msg "Invalid command!";;
esac esac
done done
break
else else
status_msg "Set custom Klipper repository to:\n ● Repository: ${repos[${option}]}\n ● Branch: ${branches[${option}]}" status_msg "Set custom Klipper repository to:\n ● Repository: ${repos[${option}]}\n ● Branch: ${branches[${option}]}"
set_custom_klipper_repo "${repos[${option}]}" "${branches[${option}]}" set_custom_klipper_repo "${repos[${option}]}" "${branches[${option}]}"
ok_msg "This repo will now be used for new Klipper installations!\n" ok_msg "This repo will now be used for new Klipper installations!\n"
break
fi fi
elif [[ ${option} =~ ${back} ]]; then elif [[ ${option} =~ ${back} ]]; then
@@ -139,4 +141,4 @@ function show_custom_klipper_repo_help() {
deny_action "show_settings_help";; deny_action "show_settings_help";;
esac esac
done done
} }

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -66,4 +66,4 @@ function advanced_menu() {
esac esac
done done
advanced_menu advanced_menu
} }

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -20,12 +20,12 @@ function backup_ui() {
echo -e "| Klipper & API: | Touchscreen GUI: |" echo -e "| Klipper & API: | Touchscreen GUI: |"
echo -e "| 1) [Klipper] | 7) [KlipperScreen] |" echo -e "| 1) [Klipper] | 7) [KlipperScreen] |"
echo -e "| 2) [Moonraker] | |" echo -e "| 2) [Moonraker] | |"
echo -e "| 3) [Configuration Folder] | 3rd Party Webinterface: |" echo -e "| 3) [Config Folder] | 3rd Party Webinterface: |"
echo -e "| 4) [Moonraker Database] | 8) [OctoPrint] |" echo -e "| 4) [Moonraker Database] | 8) [OctoPrint] |"
echo -e "| | |" echo -e "| | |"
echo -e "| Klipper Webinterface: | Other: |" echo -e "| Klipper Webinterface: | Other: |"
echo -e "| 5) [Mainsail] | 9) [Telegram Bot] |" echo -e "| 5) [Mainsail] | 9) [Telegram Bot] |"
echo -e "| 6) [Fluidd] | |" echo -e "| 6) [Fluidd] | 10) [OctoEverywhere] |"
back_footer back_footer
} }
@@ -41,7 +41,7 @@ function backup_menu() {
2) 2)
do_action "backup_moonraker" "backup_ui";; do_action "backup_moonraker" "backup_ui";;
3) 3)
do_action "backup_klipper_config_dir" "backup_ui";; do_action "backup_config_dir" "backup_ui";;
4) 4)
do_action "backup_moonraker_database" "backup_ui";; do_action "backup_moonraker_database" "backup_ui";;
5) 5)
@@ -54,6 +54,8 @@ function backup_menu() {
do_action "backup_octoprint" "backup_ui";; do_action "backup_octoprint" "backup_ui";;
9) 9)
do_action "backup_telegram_bot" "backup_ui";; do_action "backup_telegram_bot" "backup_ui";;
10)
do_action "backup_octoeverywhere" "backup_ui";;
B|b) B|b)
clear; main_menu; break;; clear; main_menu; break;;
*) *)

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -26,14 +26,18 @@ function install_ui() {
echo -e "| Klipper Webinterface: | 7) [PrettyGCode] |" echo -e "| Klipper Webinterface: | 7) [PrettyGCode] |"
echo -e "| 3) [Mainsail] | 8) [Telegram Bot] |" echo -e "| 3) [Mainsail] | 8) [Telegram Bot] |"
echo -e "| 4) [Fluidd] | 9) $(obico_install_title) |" echo -e "| 4) [Fluidd] | 9) $(obico_install_title) |"
echo -e "| | |" echo -e "| | 10) [OctoEverywhere] |"
echo -e "| Touchscreen GUI: | Webcam Streamer: |" echo -e "| | 11) [Mobileraker] |"
echo -e "| 5) [KlipperScreen] | 10) [MJPG-Streamer] |" echo -e "| Touchscreen GUI: | 12) [OctoApp for Klipper] |"
echo -e "| 5) [KlipperScreen] | |"
echo -e "| | Webcam Streamer: |"
echo -e "| | 13) [Crowsnest] |"
back_footer back_footer
} }
function install_menu() { function install_menu() {
clear && print_header clear -x && sudo true && clear -x # (re)cache sudo credentials so password prompt doesn't bork ui
print_header
install_ui install_ui
### save all installed webinterface ports to the ini file ### save all installed webinterface ports to the ini file
@@ -47,7 +51,7 @@ function install_menu() {
read -p "${cyan}####### Perform action:${white} " action read -p "${cyan}####### Perform action:${white} " action
case "${action}" in case "${action}" in
1) 1)
do_action "select_klipper_python_version" "install_ui";; do_action "start_klipper_setup" "install_ui";;
2) 2)
do_action "moonraker_setup_dialog" "install_ui";; do_action "moonraker_setup_dialog" "install_ui";;
3) 3)
@@ -65,7 +69,13 @@ function install_menu() {
9) 9)
do_action "moonraker_obico_setup_dialog" "install_ui";; do_action "moonraker_obico_setup_dialog" "install_ui";;
10) 10)
do_action "install_mjpg-streamer" "install_ui";; do_action "octoeverywhere_setup_dialog" "install_ui";;
11)
do_action "install_mobileraker" "install_ui";;
12)
do_action "octoapp_setup_dialog" "install_ui";;
13)
do_action "install_crowsnest" "install_ui";;
B|b) B|b)
clear; main_menu; break;; clear; main_menu; break;;
*) *)
@@ -74,33 +84,3 @@ function install_menu() {
done done
install_menu install_menu
} }
function select_klipper_python_version() {
top_border
echo -e "| Please select the preferred Python version. | "
echo -e "| The recommended version is Python 2.7. | "
blank_line
echo -e "| Installing Klipper with Python 3 is officially not | "
echo -e "| recommended and should be considered as experimental. | "
hr
echo -e "| 1) [Python 2.7] (recommended) | "
echo -e "| 2) [Python 3.x] ${yellow}(experimental)${white} | "
back_footer
while true; do
read -p "${cyan}###### Select Python version:${white} " action
case "${action}" in
1)
select_msg "Python 2.7"
klipper_setup_dialog "python2"
break;;
2)
select_msg "Python 3.x"
klipper_setup_dialog "python3"
break;;
B|b)
clear; install_menu; break;;
*)
error_msg "Invalid Input!\n";;
esac
done
}

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -15,18 +15,24 @@ function main_ui() {
top_border top_border
echo -e "| $(title_msg "~~~~~~~~~~~~~~~ [ Main Menu ] ~~~~~~~~~~~~~~~") |" echo -e "| $(title_msg "~~~~~~~~~~~~~~~ [ Main Menu ] ~~~~~~~~~~~~~~~") |"
hr hr
echo -e "| 0) [Log-Upload] | Klipper: $(print_status "klipper")|" echo -e "| 0) [Log-Upload] | Klipper: $(print_status "klipper")|"
echo -e "| | Repo: $(print_klipper_repo)|" echo -e "| | Repo: $(print_klipper_repo)|"
echo -e "| 1) [Install] | |" echo -e "| 1) [Install] | |"
echo -e "| 2) [Update] | Moonraker: $(print_status "moonraker")|" echo -e "| 2) [Update] | Moonraker: $(print_status "moonraker")|"
echo -e "| 3) [Remove] | |" echo -e "| 3) [Remove] | |"
echo -e "| 4) [Advanced] | Mainsail: $(print_status "mainsail")|" echo -e "| 4) [Advanced] | Mainsail: $(print_status "mainsail")|"
echo -e "| 5) [Backup] | Fluidd: $(print_status "fluidd")|" echo -e "| 5) [Backup] | Fluidd: $(print_status "fluidd")|"
echo -e "| | KlipperScreen: $(print_status "klipperscreen")|" echo -e "| | KlipperScreen: $(print_status "klipperscreen")|"
echo -e "| 6) [Settings] | Telegram Bot: $(print_status "telegram_bot")|" echo -e "| 6) [Settings] | Telegram Bot: $(print_status "telegram_bot")|"
echo -e "| | Obico: $(print_status "moonraker_obico")|" echo -e "| | Crowsnest: $(print_status "crowsnest")|"
echo -e "| | |" echo -e "| | Obico: $(print_status "moonraker_obico")|"
echo -e "| $(print_kiauh_version)| Octoprint: $(print_status "octoprint")|" echo -e "| | OctoEverywhere: $(print_status "octoeverywhere")|"
echo -e "| | Mobileraker: $(print_status "mobileraker")|"
echo -e "| | OctoApp: $(print_status "octoapp")|"
echo -e "| | |"
echo -e "| | Octoprint: $(print_status "octoprint")|"
hr
echo -e "| $(print_kiauh_version)| Changelog: ${magenta}https://git.io/JnmlX${white} |"
quit_footer quit_footer
} }
@@ -39,7 +45,7 @@ function get_kiauh_version() {
function print_kiauh_version() { function print_kiauh_version() {
local version local version
version="$(printf "%-18s" "$(get_kiauh_version)")" version="$(printf "%-16s" "$(get_kiauh_version)")"
echo "${cyan}${version}${white}" echo "${cyan}${version}${white}"
} }
@@ -52,7 +58,7 @@ function print_status() {
elif [[ ${status} == "Incomplete!" ]]; then elif [[ ${status} == "Incomplete!" ]]; then
status="${yellow}${status}${white}" status="${yellow}${status}${white}"
elif [[ ${status} == "Not linked!" ]]; then elif [[ ${status} == "Not linked!" ]]; then
### "Not linked!" is only required for Moonraker-obico ### "Not linked!" is only required for Obico for Klipper
status="${yellow}${status}${white}" status="${yellow}${status}${white}"
else else
status="${green}${status}${white}" status="${green}${status}${white}"
@@ -83,7 +89,8 @@ function print_klipper_repo() {
function main_menu() { function main_menu() {
print_header && main_ui clear && print_header
main_ui
### initialize kiauh.ini ### initialize kiauh.ini
init_ini init_ini
@@ -101,10 +108,13 @@ function main_menu() {
"start octoprint") do_action_service "start" "octoprint"; main_ui;; "start octoprint") do_action_service "start" "octoprint"; main_ui;;
"stop octoprint") do_action_service "stop" "octoprint"; main_ui;; "stop octoprint") do_action_service "stop" "octoprint"; main_ui;;
"restart octoprint") do_action_service "restart" "octoprint"; main_ui;; "restart octoprint") do_action_service "restart" "octoprint"; main_ui;;
"start crowsnest") do_action_service "start" "crowsnest"; main_ui;;
"stop crowsnest") do_action_service "stop" "crowsnest"; main_ui;;
"restart crowsnest") do_action_service "restart" "crowsnest"; main_ui;;
update) do_action "update_kiauh" "main_ui";; update) do_action "update_kiauh" "main_ui";;
0)clear && print_header 0)clear && print_header
upload_selection upload_selection
break;; main_ui;;
1)clear && print_header 1)clear && print_header
install_menu install_menu
break;; break;;
@@ -119,7 +129,7 @@ function main_menu() {
break;; break;;
5)clear && print_header 5)clear && print_header
backup_menu backup_menu
break;; main_ui;;
6)clear && print_header 6)clear && print_header
settings_menu settings_menu
break;; break;;
@@ -130,5 +140,5 @@ function main_menu() {
deny_action "main_ui";; deny_action "main_ui";;
esac esac
done done
clear; main_menu main_menu
} }

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -18,16 +18,20 @@ function remove_ui() {
echo -e "| ${yellow}INFO: Configurations and/or any backups will be kept!${white} |" echo -e "| ${yellow}INFO: Configurations and/or any backups will be kept!${white} |"
hr hr
echo -e "| Firmware & API: | 3rd Party Webinterface: |" echo -e "| Firmware & API: | 3rd Party Webinterface: |"
echo -e "| 1) [Klipper] | 6) [OctoPrint] |" echo -e "| 1) [Klipper] | 8) [OctoPrint] |"
echo -e "| 2) [Moonraker] | |" echo -e "| 2) [Moonraker] | |"
echo -e "| | Webcam Streamer: |" echo -e "| | Webcam Streamer: |"
echo -e "| Klipper Webinterface: | 7) [MJPG-Streamer] |" echo -e "| Klipper Webinterface: | 9) [Crowsnest] |"
echo -e "| 3) [Mainsail] | |" echo -e "| 3) [Mainsail] | 10) [MJPG-Streamer] |"
echo -e "| 4) [Fluidd] | Other: |" echo -e "| 4) [Mainsail-Config] | |"
echo -e "| | 8) [PrettyGCode] |" echo -e "| 5) [Fluidd] | Other: |"
echo -e "| Touchscreen GUI: | 9) [Telegram Bot] |" echo -e "| 6) [Fluidd-Config] | 11) [PrettyGCode] |"
echo -e "| 5) [KlipperScreen] | 10) [Obico for Klipper] |" echo -e "| | 12) [Telegram Bot] |"
echo -e "| | 11) [NGINX] |" echo -e "| Touchscreen GUI: | 13) [Obico for Klipper] |"
echo -e "| 7) [KlipperScreen] | 14) [OctoEverywhere] |"
echo -e "| | 15) [Mobileraker] |"
echo -e "| | 16) [NGINX] |"
echo -e "| | 17) [OctoApp] |"
back_footer back_footer
} }
@@ -45,21 +49,33 @@ function remove_menu() {
3) 3)
do_action "remove_mainsail" "remove_ui";; do_action "remove_mainsail" "remove_ui";;
4) 4)
do_action "remove_fluidd" "remove_ui";; do_action "remove_mainsail_config" "remove_ui";;
5) 5)
do_action "remove_klipperscreen" "remove_ui";; do_action "remove_fluidd" "remove_ui";;
6) 6)
do_action "remove_octoprint" "remove_ui";; do_action "remove_fluidd_config" "remove_ui";;
7) 7)
do_action "remove_mjpg-streamer" "remove_ui";; do_action "remove_klipperscreen" "remove_ui";;
8) 8)
do_action "remove_prettygcode" "remove_ui";; do_action "remove_octoprint" "remove_ui";;
9) 9)
do_action "remove_telegram_bot" "remove_ui";; do_action "remove_crowsnest" "remove_ui";;
10) 10)
do_action "remove_moonraker_obico" "remove_ui";; do_action "remove_mjpg-streamer" "remove_ui";;
11) 11)
do_action "remove_prettygcode" "remove_ui";;
12)
do_action "remove_telegram_bot" "remove_ui";;
13)
do_action "remove_moonraker_obico" "remove_ui";;
14)
do_action "remove_octoeverywhere" "remove_ui";;
15)
do_action "remove_mobileraker" "remove_ui";;
16)
do_action "remove_nginx" "remove_ui";; do_action "remove_nginx" "remove_ui";;
17)
do_action "remove_octoapp" "remove_ui";;
B|b) B|b)
clear; main_menu; break;; clear; main_menu; break;;
*) *)

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -14,20 +14,12 @@ set -e
function settings_ui() { function settings_ui() {
read_kiauh_ini "${FUNCNAME[0]}" read_kiauh_ini "${FUNCNAME[0]}"
local custom_cfg_loc="${custom_klipper_cfg_loc}"
local custom_repo="${custom_klipper_repo}" local custom_repo="${custom_klipper_repo}"
local custom_branch="${custom_klipper_repo_branch}" local custom_branch="${custom_klipper_repo_branch}"
local ms_pre_rls="${mainsail_install_unstable}" local ms_pre_rls="${mainsail_install_unstable}"
local fl_pre_rls="${fluidd_install_unstable}" local fl_pre_rls="${fluidd_install_unstable}"
local bbu="${backup_before_update}" 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 repository
custom_repo=$(echo "${custom_repo}" | sed "s/https:\/\/github\.com\///" | sed "s/\.git$//" ) custom_repo=$(echo "${custom_repo}" | sed "s/https:\/\/github\.com\///" | sed "s/\.git$//" )
if [[ -z ${custom_repo} ]]; then if [[ -z ${custom_repo} ]]; then
@@ -67,8 +59,6 @@ function settings_ui() {
echo -e "| $(title_msg "~~~~~~~~~~~~ [ KIAUH Settings ] ~~~~~~~~~~~~~") |" echo -e "| $(title_msg "~~~~~~~~~~~~ [ KIAUH Settings ] ~~~~~~~~~~~~~") |"
hr hr
echo -e "| Klipper: |" echo -e "| Klipper: |"
echo -e "| ● Config folder: |"
printf "| %-60s|\n" "${custom_cfg_loc}"
echo -e "| ● Repository: |" echo -e "| ● Repository: |"
printf "| %-70s|\n" "${custom_repo} (${custom_branch})" printf "| %-70s|\n" "${custom_repo} (${custom_branch})"
hr hr
@@ -77,24 +67,23 @@ function settings_ui() {
hr hr
printf "| Backup before updating: %-42s|\n" "${bbu}" printf "| Backup before updating: %-42s|\n" "${bbu}"
hr hr
echo -e "| 1) Change Klipper config folder location |" echo -e "| 1) Set custom Klipper repository |"
echo -e "| 2) Set custom Klipper repository |"
blank_line blank_line
if [[ ${mainsail_install_unstable} == "false" ]]; then 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 else
echo -e "| 3) ${red}Disallow${white} unstable Mainsail releases |" echo -e "| 2) ${red}Disallow${white} unstable Mainsail releases |"
fi fi
if [[ ${fluidd_install_unstable} == "false" ]]; then 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 else
echo -e "| 4) ${red}Disallow${white} unstable Fluidd releases |" echo -e "| 3) ${red}Disallow${white} unstable Fluidd releases |"
fi fi
blank_line blank_line
if [[ ${backup_before_update} == "false" ]]; then 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 else
echo -e "| 5) ${red}Disable${white} automatic backups before updates |" echo -e "| 4) ${red}Disable${white} automatic backups before updates |"
fi fi
back_help_footer back_help_footer
} }
@@ -105,16 +94,6 @@ function show_settings_help() {
top_border top_border
echo -e "| ~~~~~~ < ? > Help: KIAUH Settings < ? > ~~~~~~ |" echo -e "| ~~~~~~ < ? > Help: KIAUH Settings < ? > ~~~~~~ |"
hr 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 "| ${cyan}Install unstable releases:${white} |"
echo -e "| If set to ${green}true${white}, KIAUH installs/updates the software |" echo -e "| If set to ${green}true${white}, KIAUH installs/updates the software |"
echo -e "| with the latest, currently available release. |" echo -e "| with the latest, currently available release. |"
@@ -160,20 +139,16 @@ function settings_menu() {
read -p "${cyan}####### Perform action:${white} " action read -p "${cyan}####### Perform action:${white} " action
case "${action}" in case "${action}" in
1) 1)
clear && print_header
change_klipper_cfg_folder
settings_ui;;
2)
clear && print_header clear && print_header
change_klipper_repo_menu change_klipper_repo_menu
settings_ui;; settings_ui;;
3) 2)
switch_mainsail_releasetype switch_mainsail_releasetype
settings_menu;; settings_menu;;
4) 3)
switch_fluidd_releasetype switch_fluidd_releasetype
settings_menu;; settings_menu;;
5) 4)
toggle_backup_before_update toggle_backup_before_update
settings_menu;; settings_menu;;
B|b) B|b)

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -32,12 +32,17 @@ function update_ui() {
echo -e "| 6) [PrettyGCode] |$(compare_prettygcode_versions)|" echo -e "| 6) [PrettyGCode] |$(compare_prettygcode_versions)|"
echo -e "| 7) [Telegram Bot] |$(compare_telegram_bot_versions)|" echo -e "| 7) [Telegram Bot] |$(compare_telegram_bot_versions)|"
echo -e "| 8) [Obico for Klipper]|$(compare_moonraker_obico_versions)|" echo -e "| 8) [Obico for Klipper]|$(compare_moonraker_obico_versions)|"
echo -e "| 9) [OctoEverywhere] |$(compare_octoeverywhere_versions)|"
echo -e "| 10) [Mobileraker] |$(compare_mobileraker_versions)|"
echo -e "| 11) [Crowsnest] |$(compare_crowsnest_versions)|"
echo -e "| 12) [OctoApp] |$(compare_octoapp_versions)|"
echo -e "| |------------------------------|" echo -e "| |------------------------------|"
echo -e "| 9) [System] | $(check_system_updates) |" echo -e "| 13) [System] | $(check_system_updates) |"
back_footer back_footer
} }
function update_menu() { function update_menu() {
clear -x && sudo true && clear -x # (re)cache sudo credentials so password prompt doesn't bork ui
do_action "" "update_ui" do_action "" "update_ui"
local action local action
@@ -63,7 +68,15 @@ function update_menu() {
8) 8)
do_action "update_moonraker_obico" "update_ui";; do_action "update_moonraker_obico" "update_ui";;
9) 9)
do_action "update_system" "update_ui";; do_action "update_octoeverywhere" "update_ui";;
10)
do_action "update_mobileraker" "update_ui";;
11)
do_action "update_crowsnest" "update_ui";;
12)
do_action "update_octoapp" "update_ui";;
13)
do_action "upgrade_system_packages" "update_ui";;
a) a)
do_action "update_all" "update_ui";; do_action "update_all" "update_ui";;
B|b) B|b)
@@ -114,6 +127,15 @@ function update_all() {
[[ "${update_arr[*]}" =~ "telegram_bot" ]] && \ [[ "${update_arr[*]}" =~ "telegram_bot" ]] && \
echo -e "| ${cyan}● MoonrakerTelegramBot${white} |" echo -e "| ${cyan}● MoonrakerTelegramBot${white} |"
[[ "${update_arr[*]}" =~ "octoeverywhere" ]] && \
echo -e "| ${cyan}● OctoEverywhere${white} |"
[[ "${update_arr[*]}" =~ "mobileraker" ]] && \
echo -e "| ${cyan}● Mobileraker${white} |"
[[ "${update_arr[*]}" =~ "octoapp" ]] && \
echo -e "| ${cyan}● OctoApp${white} |"
[[ "${update_arr[*]}" =~ "system" ]] && \ [[ "${update_arr[*]}" =~ "system" ]] && \
echo -e "| ${cyan}● System${white} |" echo -e "| ${cyan}● System${white} |"
@@ -123,8 +145,14 @@ function update_all() {
read -p "${cyan}###### Do you want to proceed? (Y/n):${white} " yn read -p "${cyan}###### Do you want to proceed? (Y/n):${white} " yn
case "${yn}" in case "${yn}" in
Y|y|Yes|yes|"") Y|y|Yes|yes|"")
for app in "${update_arr[@]}"; do local component
local update="update_${app}" local update
for component in "${update_arr[@]}"; do
if [[ ${component} == "system" ]]; then
update="upgrade_system_packages"
else
update="update_${component}"
fi
#shellcheck disable=SC2250 #shellcheck disable=SC2250
$update $update
done done

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -54,7 +54,6 @@ function upload_selection() {
[[ ${upload_agreed} == "false" ]] && accept_upload_conditions [[ ${upload_agreed} == "false" ]] && accept_upload_conditions
local logfiles local logfiles
local logs_dir="${KLIPPER_LOGS}"
local webif_logs="/var/log/nginx" local webif_logs="/var/log/nginx"
function find_logfile() { function find_logfile() {
@@ -64,14 +63,18 @@ function upload_selection() {
done done
} }
find_logfile "kiauh\.log" "/tmp" local logdir log_dirs
find_logfile "klippy(-[0-9a-zA-Z]+)?\.log" "${logs_dir}" log_dirs=$(get_instance_folder_path "logs")
find_logfile "moonraker(-[0-9a-zA-Z]+)?\.log" "${logs_dir}" for logdir in ${log_dirs}; do
find_logfile "telegram(-[0-9a-zA-Z]+)?\.log" "${logs_dir}" find_logfile "klippy(-[0-9a-zA-Z]+)?\.log" "${logdir}"
find_logfile "moonraker(-[0-9a-zA-Z]+)?\.log" "${logdir}"
find_logfile "telegram(-[0-9a-zA-Z]+)?\.log" "${logdir}"
done
find_logfile "mainsail.*" "${webif_logs}" find_logfile "mainsail.*" "${webif_logs}"
find_logfile "fluidd.*" "${webif_logs}" find_logfile "fluidd.*" "${webif_logs}"
find_logfile "KlipperScreen.log" "/tmp" find_logfile "KlipperScreen.log" "/tmp"
find_logfile "webcamd\.log(\.[0-9]+)?$" "/var/log" find_logfile "webcamd\.log(\.[0-9]+)?$" "/var/log"
find_logfile "kiauh\.log" "/tmp"
### draw interface ### draw interface
local i=0 local i=0

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#=======================================================================# #=======================================================================#
# Copyright (C) 2020 - 2022 Dominik Willner <th33xitus@gmail.com> # # Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# # # #
# This file is part of KIAUH - Klipper Installation And Update Helper # # This file is part of KIAUH - Klipper Installation And Update Helper #
# https://github.com/th33xitus/kiauh # # https://github.com/dw-0/kiauh #
# # # #
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
#=======================================================================# #=======================================================================#
@@ -20,6 +20,8 @@ function check_euid() {
echo -e "${red}" echo -e "${red}"
top_border top_border
echo -e "| !!! THIS SCRIPT MUST NOT RUN AS ROOT !!! |" echo -e "| !!! THIS SCRIPT MUST NOT RUN AS ROOT !!! |"
echo -e "| |"
echo -e "| It will ask for credentials as needed. |"
bottom_border bottom_border
echo -e "${white}" echo -e "${white}"
exit 1 exit 1
@@ -134,7 +136,7 @@ function init_ini() {
echo -e "# File creation date: $(date)" echo -e "# File creation date: $(date)"
echo -e "#=================================================#" echo -e "#=================================================#"
echo -e "# KIAUH - Klipper Installation And Update Helper #" echo -e "# KIAUH - Klipper Installation And Update Helper #"
echo -e "# https://github.com/th33xitus/kiauh #" echo -e "# https://github.com/dw-0/kiauh #"
echo -e "# DO NOT edit this file! #" echo -e "# DO NOT edit this file! #"
echo -e "#=================================================#" echo -e "#=================================================#"
echo -e "# KIAUH v4.0.0" echo -e "# KIAUH v4.0.0"
@@ -156,10 +158,6 @@ function init_ini() {
echo -e "\nlogupload_accepted=false\c" >> "${INI_FILE}" echo -e "\nlogupload_accepted=false\c" >> "${INI_FILE}"
fi 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 if ! grep -Eq "^custom_klipper_repo=" "${INI_FILE}"; then
echo -e "\ncustom_klipper_repo=\c" >> "${INI_FILE}" echo -e "\ncustom_klipper_repo=\c" >> "${INI_FILE}"
fi fi
@@ -184,157 +182,6 @@ function init_ini() {
sed -i "/^[[:blank:]]*$/ d" "${INI_FILE}" sed -i "/^[[:blank:]]*$/ d" "${INI_FILE}"
} }
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
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"
}
function switch_mainsail_releasetype() { function switch_mainsail_releasetype() {
read_kiauh_ini "${FUNCNAME[0]}" read_kiauh_ini "${FUNCNAME[0]}"
local state="${mainsail_install_unstable}" local state="${mainsail_install_unstable}"
@@ -440,7 +287,7 @@ function python3_check() {
function dependency_check() { function dependency_check() {
local dep=( "${@}" ) local dep=( "${@}" )
local packages local packages log_name="dependencies"
status_msg "Checking for the following dependencies:" status_msg "Checking for the following dependencies:"
#check if package is installed, if not write its name into array #check if package is installed, if not write its name into array
@@ -458,12 +305,12 @@ function dependency_check() {
done done
echo echo
if sudo apt-get update --allow-releaseinfo-change && sudo apt-get install "${packages[@]}" -y; then # update system package lists if stale
ok_msg "Dependencies installed!" update_system_package_lists
else
error_msg "Installing dependencies failed!" # install required packages
return 1 # exit kiauh install_system_packages "${log_name}" "packages[@]"
fi
else else
ok_msg "Dependencies already met!" ok_msg "Dependencies already met!"
return return
@@ -493,27 +340,98 @@ function fetch_webui_ports() {
#=================== SYSTEM =====================# #=================== SYSTEM =====================#
#================================================# #================================================#
function check_system_updates() { function create_required_folders() {
local updates_avail info_msg local printer_data=${1} folders
updates_avail=$(apt list --upgradeable 2>/dev/null | sed "1d") folders=("backup" "certs" "config" "database" "gcodes" "comms" "logs" "systemd")
if [[ -n ${updates_avail} ]]; then for folder in "${folders[@]}"; do
info_msg="${yellow}System upgrade available!${white}" local dir="${printer_data}/${folder}"
# add system to application_updates_available in kiauh.ini
add_to_application_updates "system"
else
info_msg="${green}System up to date! ${white}"
fi
echo "${info_msg}" ### 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 update_system() { function update_system_package_lists() {
status_msg "Updating System ..." local cache_mtime update_age update_interval silent
if sudo apt-get update --allow-releaseinfo-change && sudo apt-get upgrade -y; then
print_confirm "Update complete! Check the log above!\n ${yellow}KIAUH will not install any dist-upgrades or\n any packages which have been kept back!${green}" if [[ $1 == '--silent' ]]; then silent="true"; fi
if [[ -e /var/lib/apt/periodic/update-success-stamp ]]; then
cache_mtime="$(stat -c %Y /var/lib/apt/periodic/update-success-stamp)"
elif [[ -e /var/lib/apt/lists ]]; then
cache_mtime="$(stat -c %Y /var/lib/apt/lists)"
else else
print_error "System update failed! Please watch for any errors printed above!" log_warning "Failure determining package cache age, forcing update"
cache_mtime=0
fi
update_age="$(($(date +'%s') - cache_mtime))"
update_interval=$((48*60*60)) # 48hrs
# update if cache is greater than update_interval
if (( update_age > update_interval )); then
if [[ ! ${silent} == "true" ]]; then status_msg "Updating package lists..."; fi
if ! sudo apt-get update --allow-releaseinfo-change &>/dev/null; then
log_error "Failure while updating package lists!"
if [[ ! ${silent} == "true" ]]; then error_msg "Updating package lists failed!"; fi
return 1
else
log_info "Package lists updated successfully"
if [[ ! ${silent} == "true" ]]; then status_msg "Updated package lists."; fi
fi
else
log_info "Package lists updated recently, skipping update..."
fi
}
function check_system_updates() {
local updates_avail status
if ! update_system_package_lists --silent; then
status="${red}Update check failed! ${white}"
else
updates_avail="$(apt list --upgradeable 2>/dev/null | sed "1d")"
if [[ -n ${updates_avail} ]]; then
status="${yellow}System upgrade available!${white}"
# add system to application_updates_available in kiauh.ini
add_to_application_updates "system"
else
status="${green}System up to date! ${white}"
fi
fi
echo "${status}"
}
function upgrade_system_packages() {
status_msg "Upgrading System ..."
update_system_package_lists
if sudo apt-get upgrade -y; then
print_confirm "Upgrade complete! Check the log above!\n ${yellow}KIAUH will not install any dist-upgrades or\n any packages which have been held back!${green}"
else
print_error "System upgrade failed! Please look for any errors printed above!"
fi
}
function install_system_packages() {
local log_name="$1"
local packages=("${!2}")
status_msg "Installing packages..."
if sudo apt-get install -y "${packages[@]}"; then
ok_msg "${log_name^} packages installed!"
else
log_error "Failure while installing ${log_name,,} packages"
error_msg "Installing ${log_name} packages failed!"
exit 1 # exit kiauh
fi fi
} }
@@ -720,7 +638,9 @@ function set_multi_instance_names() {
local name local name
local names="" local names=""
local services=$(klipper_systemd) local services
services=$(klipper_systemd)
### ###
# if value of 'multi_instance_names' is not an empty # if value of 'multi_instance_names' is not an empty
@@ -780,16 +700,60 @@ function get_config_folders() {
# by KIAUH convention, all instance names of only numbers # by KIAUH convention, all instance names of only numbers
# need to be prefixed with 'printer_' # need to be prefixed with 'printer_'
if [[ ${name} =~ ^[0-9]+$ ]]; then if [[ ${name} =~ ^[0-9]+$ ]]; then
cfg_dirs+=("${KLIPPER_CONFIG}/printer_${name}") cfg_dirs+=("${HOME}/printer_${name}_data/config")
else else
cfg_dirs+=("${KLIPPER_CONFIG}/${name}") cfg_dirs+=("${HOME}/${name}_data/config")
fi fi
done done
elif [[ -z ${instance_names} && $(klipper_systemd | wc -w) -gt 0 ]]; then elif [[ -z ${instance_names} && $(klipper_systemd | wc -w) -gt 0 ]]; then
cfg_dirs+=("${KLIPPER_CONFIG}") cfg_dirs+=("${HOME}/printer_data/config")
else else
cfg_dirs=() cfg_dirs=()
fi fi
echo "${cfg_dirs[@]}" echo "${cfg_dirs[@]}"
} }
###
# helper function that returns all available absolute directory paths
# based on their instance name and specified target folder
#
# @param {string}: folder name - target instance folder name (e.g. config)
#
# => return an empty string if klipper is not installed
# => return space-separated string of absolute directory paths
#
function get_instance_folder_path() {
local folder_name=${1}
local folder_paths=()
local instance_names
local path
instance_names=$(get_multi_instance_names)
if [[ -n ${instance_names} ]]; then
for name in ${instance_names}; do
###
# by KIAUH convention, all instance names of only numbers
# need to be prefixed with 'printer_'
if [[ ${name} =~ ^[0-9]+$ ]]; then
path="${HOME}/printer_${name}_data/${folder_name}"
if [[ -d ${path} ]]; then
folder_paths+=("${path}")
fi
else
path="${HOME}/${name}_data/${folder_name}"
if [[ -d ${path} ]]; then
folder_paths+=("${path}")
fi
fi
done
elif [[ -z ${instance_names} && $(klipper_systemd | wc -w) -gt 0 ]]; then
path="${HOME}/printer_data/${folder_name}"
if [[ -d ${path} ]]; then
folder_paths+=("${path}")
fi
fi
echo "${folder_paths[@]}"
}