-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathinstaller.sh
executable file
·980 lines (887 loc) · 37.6 KB
/
installer.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
#!/bin/bash
EDITOR=nano
PASSWD=/etc/passwd
clear
# function to display menus
show_menus() {
clear
echo '
/$$ /$$ /$$ /$$$$$$ /$$$$$$$ /$$$$$$$ /$$$$$$$$ /$$$$$$$ /$$$ /$$$$$$$ /$$ /$$ /$$$$$$ /$$$$$$
| $$ /$$/| $$ |_ $$_/| $$__ $$| $$__ $$| $$_____/| $$__ $$ /$$ $$ | $$__ $$| $$ /$ | $$ /$$__ $$ /$$__ $$
| $$ /$$/ | $$ | $$ | $$ \ $$| $$ \ $$| $$ | $$ \ $$ | $$$ | $$ \ $$| $$ /$$$| $$| $$ \__/|__/ \ $$
| $$$$$/ | $$ | $$ | $$$$$$$/| $$$$$$$/| $$$$$ | $$$$$$$/ /$$ $$/$$ | $$ | $$| $$/$$ $$ $$| $$ /$$$$$$/
| $$ $$ | $$ | $$ | $$____/ | $$____/ | $$__/ | $$__ $$ | $$ $$_/ | $$ | $$| $$$$_ $$$$| $$ /$$____/
| $$\ $$ | $$ | $$ | $$ | $$ | $$ | $$ \ $$ | $$\ $$ | $$ | $$| $$$/ \ $$$| $$ $$| $$
| $$ \ $$| $$$$$$$$ /$$$$$$| $$ | $$ | $$$$$$$$| $$ | $$ | $$$$/$$ | $$$$$$$/| $$/ \ $$| $$$$$$/| $$$$$$$$
|__/ \__/|________/|______/|__/ |__/ |________/|__/ |__/ \____/\_/ |_______/ |__/ \__/ \______/ |________/
/$$$$$$ /$$$$$$ /$$$$$$$$ /$$$$$$ /$$$$$$$ /$$$$$$$ /$$$$$$ /$$ /$$ /$$$$$$$$
/$$__ $$ /$$__ $$|__ $$__//$$__ $$| $$__ $$| $$__ $$|_ $$_/| $$$ | $$|__ $$__/
| $$ \ $$| $$ \__/ | $$ | $$ \ $$| $$ \ $$| $$ \ $$ | $$ | $$$$| $$ | $$
| $$ | $$| $$ | $$ | $$ | $$| $$$$$$$/| $$$$$$$/ | $$ | $$ $$ $$ | $$
| $$ | $$| $$ | $$ | $$ | $$| $$____/ | $$__ $$ | $$ | $$ $$$$ | $$
| $$ | $$| $$ $$ | $$ | $$ | $$| $$ | $$ \ $$ | $$ | $$\ $$$ | $$
| $$$$$$/| $$$$$$/ | $$ | $$$$$$/| $$ | $$ | $$ /$$$$$$| $$ \ $$ | $$
\______/ \______/ |__/ \______/ |__/ |__/ |__/|______/|__/ \__/ |__/
/$$$$$$ /$$ /$$ /$$$$$$ /$$$$$$$$ /$$$$$$ /$$ /$$ /$$$$$$$$ /$$$$$$$
|_ $$_/| $$$ | $$ /$$__ $$|__ $$__//$$__ $$| $$ | $$ | $$_____/| $$__ $$
| $$ | $$$$| $$| $$ \__/ | $$ | $$ \ $$| $$ | $$ | $$ | $$ \ $$
| $$ | $$ $$ $$| $$$$$$ | $$ | $$$$$$$$| $$ | $$ | $$$$$ | $$$$$$$/
| $$ | $$ $$$$ \____ $$ | $$ | $$__ $$| $$ | $$ | $$__/ | $$__ $$
| $$ | $$\ $$$ /$$ \ $$ | $$ | $$ | $$| $$ | $$ | $$ | $$ \ $$
/$$$$$$| $$ \ $$| $$$$$$/ | $$ | $$ | $$| $$$$$$$$| $$$$$$$$| $$$$$$$$| $$ | $$
|______/|__/ \__/ \______/ |__/ |__/ |__/|________/|________/|________/|__/ |__/
'
echo "=========================="
echo " INSTALL OR UPDATE "
echo " KLIPPER & DWC2 "
echo " OCTOPRINT "
echo " BY MANU7IRL "
echo "=========================="
echo "1. Install KLIPPER"
echo "2. Update KLIPPER"
echo "3. Flash your MCU"
echo "4. Install DWC2"
echo "5. Update DWC2"
echo "6. Install OCTOPRINT"
echo "7. Uninstall KLIPPER & DWC"
echo "8. Uninstall OCTOPRINT"
echo "9. Exit"
}
report_status()
{
echo -e "\n\n###### $1"
}
verify_ready()
{
if [ "$EUID" -eq 0 ]; then
report_status "This script must not run as root"
exit -1
fi
}
# Force script to exit if an error occurs
set -e
verify_ready
show_menus
pause(){
read -p "Press [Enter] to return to the main menu..." fackEnterKey
}
report_status "Welcome to my Klipper, DWC2 & Octoprint, global installer!"
sleep 1
report_status "Before we start it, some basic questions to get it running correctly..."
sleep 1
report_status "On Which user should the Installer be run on? watch out for typos!"
read userSelect
while true; do
read -p "###### This Installer will be launched for user: $userSelect, are you sure?[Y/N]" yn
case $yn in
[Yy]* ) break;;
[Nn]* ) report_status "On Which user should this install be run on? watch out for typos!"; read userSelect; continue;;
* ) report_status "Please answer by yes (Y/y) or no (N/n).";;
esac
done
# create some folders & variables
installLocation=/home/$userSelect
PrinterFarm=$installLocation/PrinterFarm
KlipperFarm=$PrinterFarm/KlipperFarm
OctoPrintFarm=$PrinterFarm/OctoPrintFarm
OCTOPRINT=$PrinterFarm/OctoPrintFarm/octoprint
KLIPPER=$PrinterFarm/KlipperFarm/klipper
GITSRC=$PrinterFarm/git_source
PYTHONDIR="$KLIPPER/klippy-env"
SYSTEMDDIR="/etc/systemd/system"
KLIPPER_USER=$userSelect
KLIPPER_GROUP=$userSelect
PRINTER_FOLDER=$KlipperFarm/printer-$printer_num
SDCARD=$PRINTER_FOLDER/sdcard
SERV_F=$GITSRC/service_files
while true
do
report_status "How many 3D-printers do you want to run on it?"
read printerCount
install_1=0
session_num=$(( printerCount-1 ))
if [ $(( session_num )) == $(( install_1 )) ]
then
read -p "###### You chose only $printerCount 3D-printer to install, are you sure?[Y/N]" yn
case $yn in
[Yy]* ) break;;
[Nn]* ) continue;;
* ) report_status "Please answer by yes (Y/y) or no (N/n).";;
esac
else
read -p "###### Ok, $printerCount 3D-printer(s) will be installed, are you sure?[Y/N]" yn
case $yn in
[Yy]* ) break;;
[Nn]* ) continue;;
* ) report_status "Please answer by yes (Y/y) or no (N/n).";;
esac
break
fi
done
report_status "Thanks! We collected enough information to launch the main menu!"
report_status "Creating some folders..."
[ ! -d $PrinterFarm ] && mkdir -p $PrinterFarm
report_status "Adding some dependencies, that might be need on some systems..."
klipper_install(){
if [ -d "$KLIPPER" ] || [ -f /ect/systemd/system/klipper-* ]
then
report_status "KLIPPER is already installed!"
sleep 2
report_status "Update is available in the menu, or remove it cleanly from it."
else
report_status "Starting KLIPPER install process..."
[ ! -d ${KlipperFarm} ] && mkdir -p $KlipperFarm
[ ! -d ${GITSRC} ] && mkdir -p $GITSRC
[ ! -d ${SERV_F} ] && mkdir -p $SERV_F
cd $GITSRC
report_status "Cloning the KLIPPER folder From GITHUB..."
sleep 2
[ ! -d ${GITSRC}/klipper ] && git clone https://github.com/KevinOConnor/klipper.git &> /dev/null
rsync -a ${GITSRC}/klipper $KlipperFarm &> /dev/null
sleep 2
report_status "There are sudo commands contained within, you will be asked for your sudo password in the next step"
sleep 5
report_status "Just preparing your system for install..."
# Step 1: Install system packages
install_packages()
{
# Packages for python cffi
PKGLIST="python-virtualenv virtualenv python-dev libffi-dev build-essential"
# kconfig requirements
PKGLIST="${PKGLIST} libncurses-dev"
# hub-ctrl
PKGLIST="${PKGLIST} libusb-dev"
# AVR chip installation and building
PKGLIST="${PKGLIST} avrdude gcc-avr binutils-avr avr-libc"
# ARM chip installation and building
PKGLIST="${PKGLIST} stm32flash libnewlib-arm-none-eabi"
PKGLIST="${PKGLIST} gcc-arm-none-eabi binutils-arm-none-eabi"
# Update system package info
report_status "Running package updater..."
sudo apt-get update &> /dev/null
# Install desired packages
report_status "Installing packages..."
sudo apt-get install --yes ${PKGLIST} &> /dev/null
# serial access perms for the chosen username
report_status "Check $userSelect permissions..."
sudo usermod -a -G tty $userSelect &> /dev/null
sudo usermod -a -G dialout $userSelect &> /dev/null
}
# Step 2: Create python virtual environment
create_virtualenv()
{
report_status "Updating python virtual environment..."
# Create virtualenv if it doesn't already exist
[ ! -d ${PYTHONDIR} ] && virtualenv ${PYTHONDIR} &> /dev/null
# Install/update dependencies
[ -d ${PYTHONDIR} ] && ${PYTHONDIR}/bin/pip2 install -r ${KLIPPER}/scripts/klippy-requirements.txt &> /dev/null
}
# Step 3: Install startup script
install_script()
{
# Create systemd service file
sudo systemctl daemon-reload
printer_num=0
while (( $printer_num <= $session_num ))
do
PRINTER_FOLDER=$KlipperFarm/printer-$printer_num
SDCARD=$PRINTER_FOLDER/sdcard
PRINTER_CFG=$PRINTER_FOLDER/printer-$printer_num.cfg
report_status "Creating a default printer-$printer_num_default.cfg under $PRINTER_CFG"
[ ! -d ${PRINTER_FOLDER} ] && mkdir -p $PRINTER_FOLDER
[ ! -d ${SDCARD} ] && mkdir -p $SDCARD
[ ! -f ${PRINTER_CFG} ] && cat &> /dev/null <<EXAMPLE > $PRINTER_FOLDER/printer-$printer_num.cfg
#this is an example config to start with,
#you will have to connect each printer separately first,
#to find the serial path of each one and configure this under:
[mcu]
serial: /dev/serial/by-id/myprinter-$printer_num
#enter in your terminal: ls /dev/serial/by-id
#and you will get the physical path to your printer,
#this path or id should be unique for each printer in order to run with the others without conflicts
EXAMPLE
if [ $session_num == 0 ]
then
[ -f ${installLocation}/printer.cfg ] && report_status "Moving and renaming your printer.cfg to the correct folder... under $PRINTER_FOLDER/" && sleep 3 && mv $installLocation/printer.cfg $PRINTER_FOLDER/printer-0.cfg
else
report_status "You do not a a printer.cfg file in $installLocation folder, do not forget to create one, and place it under $PRINTER_FOLDER/, in order to get the printer to work with klipper"
sleep 2
report_status "After you created a printer.cfg file move it to $PRINTER_FOLDER folder, and rename it printer-$printer_num.cfg"
sleep 2
fi
KLIPPER_LOG=/tmp/klippy-$printer_num.log
TMP_PRINTER=/tmp/printer-$printer_num
report_status "Installing systemd startup script klipper-$printer_num..."
cat &> /dev/null <<SERVICE > $KlipperFarm/klipper-$printer_num.service
#Systemd service file for klipper
[Unit]
Description=Starts klipper on startup
After=network.target
[Install]
WantedBy=multi-user.target
[Service]
Type=simple
User=$KLIPPER_USER
RemainAfterExit=yes
ExecStart=${PYTHONDIR}/bin/python ${KLIPPER}/klippy/klippy.py ${PRINTER_CFG} -I ${TMP_PRINTER} -l ${KLIPPER_LOG}
Restart=always
RestartSec=10
SERVICE
sudo mv $KlipperFarm/klipper-$printer_num.service $SYSTEMDDIR/ &> /dev/null
# Use systemctl to enable the klipper systemd service script
sudo systemctl enable klipper-$printer_num.service &> /dev/null
sudo systemctl start klipper-$printer_num &> /dev/null
sleep 5
report_status "Service klipper-$printer_num has been started!"
printer_num=$(( printer_num+1 ))
done
report_status "..."
sleep 5
report_status "Congradulations.... You should have $printerCount Klipper instance(s) running!"
}
# Run installation steps defined above
install_packages
create_virtualenv
install_script
fi
pause
}
klipper_update(){
report_status "This will upgrade $printerCount klipper instance(s)!"
printer_num=0
while (( $printer_num <= $session_num ))
do
report_status "Stopping klipper-$printer_num service..."
sudo systemctl stop klipper-$printer_num
printer_num=$(( printer_num+1 ))
done
cd $GITSRC/klipper
report_status "Updating the KLIPPER folder from github..."
git pull
report_status "Moving the current klipper folder to backup $KLIPPER.bak"
rsync -a $PYTHONDIR $KlipperFarm &> /dev/null
rsync -a $KLIPPER $KLIPPER.bak &> /dev/null && rm -fR $KLIPPER &> /dev/null
rm -Rf $KLIPPER &> /dev/null
rsync -a $GITSRC/klipper $KlipperFarm &> /dev/null
rsync -a $KlipperFarm/klippy-env $KLIPPER &> /dev/null
rm -Rf $KlipperFarm/klippy-env &> /dev/null
report_status "KLIPPER is up to date!"
sleep 1
printer_num=0
while (( $printer_num <= $session_num ))
do
[ -d ${SDCARD}/dwc2 ] && report_status "Also updating DWC2 in $SDCARD/, as it was installed previously" && dwc_update
printer_num=$(( printer_num+1 ))
done
sleep 1
report_status "You may need to reflash your MCU for the update into account"
sleep 2
printer_num=0
while (( $printer_num <= $session_num ))
do
report_status "Starting klipper-$printer_num service..."
sudo systemctl start klipper-$printer_num
printer_num=$(( printer_num+1 ))
done
pause
}
flash_mcu(){
printer_num=0
while (( $printer_num <= $session_num ))
do
report_status "Stopping klipper-$printer_num service..."
sudo systemctl stop klipper-$printer_num
printer_num=$(( printer_num+1 ))
done
cd $KLIPPER
report_status "please, connect only one MCU for each printer needed to flash"
sleep 2
report_status "Creating a new micro firmware for the MCU connected"
make clean
report_status "Opening menuconfig, choose your MCU type, then choose exit"
make menuconfig
report_status "Compiling the micro firmware..."
sleep 2
make
report_status "The firmware is ready! You also found it at $KLIPPER/src/klipper.elf.hex or $installLocation/PrinterFarm/klipper/out/klipper.bin"
sleep 3
cat << EOF
=================================
KLIPPER MICRO FIRMWARE FLASHING:
---------------------------------
Please choose the method needed:
(1)Flash your MCU via serial USB
(2)Flash your MCU via SDCARD
(Q)uit
---------------------------------
EOF
read -n1 -s
case "$REPLY" in
"1") report_status "Flashing the MCU with the new compiled micro firmware..."
sleep 3
report_status "Please connect your printer via USB cable"
read -n 1 -s -r -p "Press any key to continue"
mcu_add=$(ls -A /dev/serial/by-id/)
if [ $? != 0 ]
then
report_status "Please plug in your MCU via USB cable, prior trying to flash it!"
sleep 3
else
report_status "Flashing your MCU..."
make flash FLASH_DEVICE=/dev/serial/by-id/$mcu_add | tee -a flash.log
fi
if [ -f $KLIPPER/flash.log ]
then
report_status "Your MCU is flashed now"
sleep 2
else
report_status "You may have encountered a problem! Check your USB connection and try to flash it again..."
sleep 2
fi
while (( $printer_num <= $session_num ))
do
report_status "Starting klipper-$printer_num service..."
sudo systemctl start klipper-$printer_num
printer_num=$(( printer_num+1 ))
done
sleep 3
pause ;;
"2")
cd $KLIPPER
report_status "Renaming the klipper.elf.hex to firmware.bin..."
rsync -a $KLIPPER/out/klipper.bin $KLIPPER/out/firmware.bin
report_status "Please insert an SDCARD (min. 128MB)..."
read -n 1 -s -r -p "Press any key to continue"
sudo lsblk
sleep 5
report_status "What is your sdcard device name? type in the deivce name in /dev/"device" like /dev/"sdb", corresponding to your sdcard"
read DEVICE
check_sdcard=$(ls -A /dev/$DEVICE1)
if [ $? == 0 ]
then
report_status "There are sudo commands contained within, you will be asked for your sudo password in the next step"
sleep 2
report_status "mounting the SDCARD to /mnt/"
sudo mount /dev/$DEVICE1 /mnt/
report_status "Moving the micro firmware to the SDCARD..."
sudo rsync -va --no-owner --no-group --remove-fource-files $KLIPPER/out/firmware.bin /mnt/
ls -A /mnt/firmware.bin
sleep 2
report_status "Unmounting the SDCARD..."
sudo umount /mnt/
report_status "Now insert the SDCARD into your MCU, power it on and press the reset button"
sleep 3
report_status "Congrats you just flashed your MCU!"
sleep 2
else
report_status "Your SDCARD is not connected!"
sleep 3
fi
printer_num=0
while (( $printer_num <= $session_num ))
do
report_status "restarting klipper-$printer_num service..."
sudo systemctl restart klipper-$printer_num
printer_num=$(( printer_num+1 ))
done
sleep 3 ;;
"Q") pause ;;
"q") report_status "case sensitive!!" ;;
*) report_status "invalid option" ;;
esac
sleep 1
report_status "If you need to flash an other MCU, launch this script again!"
pause
}
dwc_install(){
report_status "Installing Duet Web Control web-UI, for your $printerCount Klipper instance(s)..."
sleep 2
cd $KlipperFarm
report_status "There are sudo commands contained within, you will be asked for your sudo password in the next step"
sleep 2
sudo apt install wget gzip tar -y &> /dev/null
printer_num=0
while (( $printer_num <= $session_num ))
do
report_status "Stopping klipper-$printer_num service..."
sudo systemctl stop klipper-$printer_num
printer_num=$(( printer_num+1 ))
done
if [ -d ${KLIPPER} ]
then
report_status "Adding some magic to make dwc2-for-klipper working..."
virtualenv $PYTHONDIR &> /dev/null
${PYTHONDIR}/bin/pip2 install tornado==5.1.1 &> /dev/null
report_status "Cloning the dwc2-for-klipper folder Stephan GITHUB..."
cd $GITSRC
[ ! -d $GITSRC/dwc2-for-klipper ] && git clone https://github.com/Stephan3/dwc2-for-klipper.git &> /dev/null
[ ! -d $KLIPPER/dwc2-for-klipper ] && rsync -a $GITSRC/dwc2-for-klipper $KLIPPER &> /dev/null
report_status "Making a magical change in web_dwc2.py to make multi-session possible..."
sed -i "s|'/tmp/printer'|config.get(\"serial_path\", \"/tmp/printer\")|g" $KLIPPER/dwc2-for-klipper/web_dwc2.py
report_status "Connecting dwc2-for-klipper as an extra module for klippy -> web_dwc2.py..."
web_dwc2=$KLIPPER/klippy/extras/web_dwc2.py
if [ -f ${web_dwc2} ]
then
report_status "$dwc2_module is already linked to KLIPPY"
sleep 2
else
user=$userSelect
ln -f $KLIPPER/dwc2-for-klipper/web_dwc2.py $KLIPPER/klippy/extras/web_dwc2.py
chown -h $userSelect:$userSelect $KLIPPER/klippy/extras/web_dwc2.py
dwc2_module=$(ls -A $KLIPPER/klippy/extras | grep -woh web_dwc2.py)
report_status "$dwc2_module is linked to KLIPPY"
sleep 2
fi
report_status "Creating a folder for nesting the DuetWebControl UI files"
report_status "Downloading the official latest DWC release, from Chrishamm GITHUB..."
cd $SERV_F
latest_DWC=`curl -s https://api.github.com/repositories/28820678/releases/latest | grep browser_download_url | cut -d '"' -f 4 | grep SD`
[ -f *.zip ] && rm $SERV_F/*.zip
wget $latest_DWC &> /dev/null
klipper_num=`find /etc/systemd/system -type f -name 'klipper-*' -printf x | wc -c`
session_num=$(( $klipper_num-1 ))
printer_num=0
PORT=4750
while (( $printer_num <= $session_num ))
do
PRINTER_FOLDER=$KlipperFarm/printer-$printer_num
SDCARD=$PRINTER_FOLDER/sdcard
[ ! -d ${SDCARD}/dwc2/web ] && mkdir -p $SDCARD/dwc2/web
[ ! -d ${SDCARD}/sys ] && mkdir -p $SDCARD/sys
[ -f $SDCARD/dwc2/web/*.zip ] && rm $SDCARD/dwc2/web/*.zip
[ ! -f $SDCARD/dwc2/web/*.zip ] && rsync -a $SERV_F/*.zip $SDCARD/dwc2/web
report_status "Installing the web server files on printer-$printer_num"
cd $SDCARD/dwc2/web
unzip *.zip && for f_ in $(find . | grep '.gz'); do gunzip ${f_}; done
rm $SDCARD/dwc2/web/*.zip
sleep 2
report_status "Creating the default sections [virtual_sdcard] and [web_dwc2], in your printer-$printer_num.cfg file, as describe in Stephan3 GITHUB"
sleep 5
[ -f ${PRINTER_CFG} ] && cat <<DWC2 >> $PRINTER_FOLDER/printer-$printer_num.cfg
#Move that entire bolck above the do not edit line if you have it!
#########################
# OPTIONAL DWC UI CONFIG
#########################
#you can also point all your printer to the same virtualSD
[virtual_sdcard]
path: $SDCARD
[web_dwc2]
# optional - defaulting to Klipper
printer_name: My-Printer-$printer_num
# optional - defaulting to 127.0.0.1
listen_adress: 0.0.0.0
# needed - use above 1024 as nonroot
listen_port: $(( ${PORT}+${printer_num} ))
# optional defaulting to dwc2/web. It's a folder relative to your $SDCARD path folder.
web_path: /dwc2/web
DWC2
sleep 3
new_port=$(( ${PORT}+${printer_num} ))
report_status "DWC2 server-$printer_num is running on http://$(hostname):$new_port or http://localhost:$new_port"
report_status "Linking $KLIPPER_LOG to $SDCARD/sys/klippy-$printer_num.log folder..."
KLIPPER_LOG=/tmp/klippy-$printer_num.log
ln -s $KLIPPER_LOG $SDCARD/sys/klippy-$printer_num.log
printer_num=$(( printer_num+1 ))
done
[ -f $SERV_F/*.zip ] && rm $SERV_F/*.zip
report_status "..."
sleep 5
report_status "Congradulations.... You should have $printerCount DWC2 server(s) running!"
printer_num=0
while (( $printer_num <= $session_num ))
do
report_status "Restarting klipper-$printer_num service..."
sudo systemctl restart klipper-$printer_num
printer_num=$(( printer_num+1 ))
done
else
report_status "Klipper is not installed please install it first!"
sleep 2
fi
pause
}
dwc_update(){
cd $GITSRC/dwc2-for-klipper
git pull
rm -vRf $KLIPPER/dwc2-for-klipper &> /dev/null
rsync -a $GITSRC/dwc2-for-klipper $KLIPPER
report_status "Making a magical change in web_dwc2.py to make multi-session possible..."
sed -i "s|'/tmp/printer'|config.get(\"serial_path\", \"/tmp/printer\")|g" $KLIPPER/dwc2-for-klipper/web_dwc2.py
report_status "Connecting dwc2-for-klipper as an extra module for klippy -> web_dwc2.py..."
web_dwc2=$KLIPPER/klippy/extras/web_dwc2.py
if [ -f ${web_dwc2} ]
then
report_status "$dwc2_module is already linked to KLIPPY"
sleep 2
else
user=$userSelect
ln -f $KLIPPER/dwc2-for-klipper/web_dwc2.py $KLIPPER/klippy/extras/web_dwc2.py
chown -h $userSelect:$userSelect $KLIPPER/klippy/extras/web_dwc2.py
dwc2_module=$(ls -A $KLIPPER/klippy/extras | grep -woh web_dwc2.py)
report_status "$dwc2_module is linked to KLIPPY"
sleep 2
fi
cd $SERV_F
latest_DWC=`curl -s https://api.github.com/repositories/28820678/releases/latest | grep browser_download_url | cut -d '"' -f 4 | grep SD`
wget $latest_DWC &> /dev/null
klipper_num=`find /etc/systemd/system -type f -name 'klipper-*' -printf x | wc -c`
session_num=$(( $klipper_num-1 ))
printer_num=0
PORT=4750
while (( $printer_num <= $session_num ))
do
PRINTER_FOLDER=$KlipperFarm/printer-$printer_num
SDCARD=$PRINTER_FOLDER/sdcard
report_status "removing the old web folder for DWC2, in $SDCARD/dwc2/..."
[ -d ${SDCARD}/dwc2/web ] && rm -vRf $SDCARD/dwc2/web &> /dev/null
[ ! -d ${SDCARD}/dwc2/web ] && mkdir -p $SDCARD/dwc2/web
[ ! -d ${SDCARD}/sys ] && mkdir -p $SDCARD/sys
[ -f ${SDCARD}/dwc2/web/*.zip ] && rm $SDCARD/dwc2/web/*.zip
rsync -a $SERV_F/*.zip $SDCARD/dwc2/web
report_status "Installing the web server files on printer-$printer_num"
cd $SDCARD/dwc2/web
unzip *.zip && for f_ in $(find . | grep '.gz'); do gunzip ${f_}; done
sleep 2
new_port=$(( ${PORT}+${printer_num} ))
report_status "DWC2 server-$printer_num is running on http://$(hostname):$new_port or http://localhost:$new_port"
printer_num=$(( printer_num+1 ))
done
rm $SERV_F/*.zip
report_status "..."
sleep 5
printer_num=0
while (( $printer_num <= $session_num ))
do
report_status "Restarting klipper-$printer_num service..."
sudo systemctl restart klipper-$printer_num
printer_num=$(( printer_num+1 ))
done
report_status "Congradulations... You should have $printerCount DWC2 server(s) updated!"
sleep 3
pause
}
octorprint_install(){
[ ! -d ${OctoPrintFarm} ] && mkdir -p $OctoPrintFarm
[ ! -d ${OCTOPRINT} ] && mkdir -p $OCTOPRINT
report_status "This will install OctoPrint on linux for you, as many times as you require."
while true
do
report_status "How many 3D-printer do you want to use with OctoPrint?"
read printerCount
install_1=0
session_num=$(( $printerCount-1 ))
if [ $(($printer_num)) == $((install_1)) ];
then
read -p "###### Only $octo_session main OctoPrint service will be installed without instances, are you sure?[Y/N]" yn
case $yn in
[Yy]* ) break;;
[Nn]* ) continue;;
* ) report_status "Please answer by yes (Y/y) or no (N/n).";;
esac
else
read -p "###### Only $printerCount OctoPrint instance(s) will be installed, are you sure?[Y/N]" yn
case $yn in
[Yy]* ) break;;
[Nn]* ) continue;;
* ) report_status "Please answer by yes (Y/y) or no (N/n).";;
esac
break
fi
done
report_status "Thanks! Full steam ahead to install $printerCount OctoPrint instance(s) in $OctoPrintFarm"
report_status "There are sudo commands contained within, you will be asked for your sudo password in the next step"
sleep 5
report_status "Just preparing your system for install"
sudo apt update &> /dev/null && sudo apt install git python-pip python-dev python-setuptools python-virtualenv git libyaml-dev build-essential -y &> /dev/null
report_status "Just making sure $userSelect has the correct permissions"
sudo usermod -a -G tty $userSelect &> /dev/null
sudo usermod -a -G dialout $userSelect &> /dev/null
report_status "Now I will handle $printerCount OctoPrint instance(s) install "
cd $OCTOPRINT &> /dev/null
report_status "Creating the virtualenv"
report_status "..."
virtualenv venv &> /dev/null
source venv/bin/activate &> /dev/null
report_status "Downloading Latest OctoPrint version from Github"
report_status "..."
pip install pip --upgrade &> /dev/null
pip install https://get.octoprint.org/latest &> /dev/null
[ ! -d ${SERV_F} ] && mkdir -p $SERV_F
cd $SERV_F
if [ ! -f ${SERV_F}/octoprint.init ]
then
report_status "Downloading init file...."
wget https://github.com/foosel/OctoPrint/raw/master/scripts/octoprint.init -P $SERV_F &> /dev/null
fi
if [ ! -f ${SERV_F}/octoprint.default ]
then
report_status "Downloading default file...."
wget https://github.com/foosel/OctoPrint/raw/master/scripts/octoprint.default -P $SERV_F &> /dev/null
fi
report_status "Now we need to create a system service for each instance. Two sec's I'll get on it!"
report_status "..."
sudo systemctl daemon-reload
PRT=5000
printer_num=0
octo_config=$OctoPrintFarm/.octoprint-$printer_num
while (( $printer_num <= $session_num ))
do
[ ! -d ${octo_config} ] && mkdir -p $octo_config
PORTcounter=$(( $PRT+$printer_num ))
cp $SERV_F/octoprint.init $OctoPrintFarm/octoprint.init
cp $SERV_F/octoprint.default $OctoPrintFarm/octoprint.default
sed -i "s/USER=pi/USER=$userSelect/g" $OctoPrintFarm/octoprint.default
sed -i "s/PORT=5000/PORT=$PORTcounter/g" $OctoPrintFarm/octoprint.default
sed -i "s+#DAEMON=/home/pi/OctoPrint/venv/bin/octoprint+DAEMON=$OCTOPRINT/venv/bin/octoprint+g" $OctoPrintFarm/octoprint.default
sed -i 's|#BASEDIR=/home/pi/.octoprint|BASEDIR='$OctoPrintFarm'/.octoprint-'$printer_num'|g' $OctoPrintFarm/octoprint.default
sed -i 's|#CONFIGFILE=/home/pi/.octoprint/config.yaml|CONFIGFILE='$OctoPrintFarm'/.octoprint-'$printer_num'/config.yaml|g' $OctoPrintFarm/octoprint.default
sed -i "s/UMASK=022/UMASK=022/g" $OctoPrintFarm/octoprint.default
sed -i "s+DESC=\"OctoPrint\" Daemon\"+DESC=\"OctoPrint-$printer_num Daemon\"+g" $OctoPrintFarm/octoprint.init
sed -i "s+NAME=\"OctoPrint\"+NAME=\"OctoPrint-$printer_num\"+g" $OctoPrintFarm/octoprint.init
sed -i "s/PKGNAME=octoprint/PKGNAME=octoprint-$printer_num/g" $OctoPrintFarm/octoprint.init
sudo mv $OctoPrintFarm/octoprint.init /etc/init.d/octoprint-$printer_num
sudo mv $OctoPrintFarm/octoprint.default /etc/default/octoprint-$printer_num
sudo chmod +x /etc/init.d/octoprint-$printer_num
sudo update-rc.d octoprint-$printer_num defaults
sudo systemctl daemon-reload
sudo service octoprint-$printer_num start
sleep 10
new_port=
report_status "Service octoprint-$printer_num has started on http://$(hostname):$PORTcounter or http://localhost:$PORTcounter"
printer_num=$(( printer_num+1 ))
done
report_status "..."
sleep 5
report_status "Congradulations.... You should have $printerCount OctoPrint instance(s) running!"
cd $SERV_F
report_status "Installing webcam support"
report_status "..."
sudo apt install subversion libjpeg-dev imagemagick ffmpeg libv4l-dev cmake -y &> /dev/null
[ -d ${SERV_F}/mjpg_streamer ] && rm -fR $SERV_F/mjpg_streamer &> /dev/null
git clone https://github.com/jacksonliam/mjpg-streamer.git &> /dev/null
cd $SERV_F/mjpg-streamer/mjpg-streamer-experimental/
mkdir build && cd build
cmake .. &> /dev/null
make &> /dev/null
sudo make install &> /dev/null
report_status "Creating webcam lauching scripts in $OctPrintFarm/octo-scripts"
report_status "..."
cd $OctoPrintFarm
[ ! -d ${OctoPrintFarm}/octo-scripts ] && mkdir -p $OctoPrintFarm/octo-scripts
[ -f ${OctoPrintFarm}/octo-scripts/webcam ] && rsync - a $OctoPrintFarm/octo-scripts/webcam $OctoPrintFarm/octo-scripts/webcam.bak &> /dev/null && rm $OctoPrintFarm/octo-scripts/webcam &> /dev/null
cat &> /dev/null <<WEBCAM > $OctoPrintFarm/octo-scripts/webcam
#!/bin/bash
# Start / stop streamer daemon
case "$1" in
start)
$installLocation/octo-scripts/webcamDaemon >/dev/null 2>&1 &
report_status "$0: started"
;;
stop)
pkill -x webcamDaemon
pkill -x mjpg_streamer
report_status "$0: stopped"
;;
restart)
pkill -x webcamDaemon
pkill -x mjpg_streamer
$installLocation/octo-scripts/webcamDaemon >/dev/null 2>&1 &
report_status "$0: restarted"
;;
*)
report_status "Usage: $0 {start|stop|restart}" >&2
;;
esac
WEBCAM
[ -f ${OctoPrintFarm}/octo-scripts/webcamDaemon ] && rsync -a $OctoPrintFarm/octo-scripts/webcamDaemon $OctoPrintFarm/octo-scripts/webcamDaemon.bak &> /dev/null && rm $OctoPrintFarm/octo-scripts/webcamDaemon &> /dev/null
cat &> /dev/null <<WEBCAMDAEMON > $OctoPrintFarm/octo-scripts/webcamDaemon
#!/bin/bash
MJPGSTREAMER_HOME=$installLocation/mjpg-ftreamer/mjpg-ftreamer-experimental
MJPGSTREAMER_INPUT_USB="input_uvc.so"
MJPGSTREAMER_INPUT_RASPICAM="input_raspicam.so"
# init configuration
camera="auto"
camera_usb_options="-r 640x480 -f 10"
camera_raspi_options="-fps 10"
if [ -e "/boot/octopi.txt" ]; then
source "/boot/octopi.txt"
fi
# runs MJPG Streamer, using the provided input plugin + configuration
function runMjpgStreamer {
input=$1
pushd $MJPGSTREAMER_HOME
report_status Running ./mjpg_streamer -o "output_http.so -w ./www" -i "$input"
LD_LIBRARY_PATH=. ./mjpg_streamer -o "output_http.so -w ./www" -i "$input"
popd
}
# starts up the RasPiCam
function startRaspi {
logger "Starting Raspberry Pi camera"
runMjpgStreamer "$MJPGSTREAMER_INPUT_RASPICAM $camera_raspi_options"
}
# starts up the USB webcam
function startUsb {
logger "Starting USB webcam"
runMjpgStreamer "$MJPGSTREAMER_INPUT_USB $camera_usb_options"
}
# we need this to prevent the later calls to vcgencmd from blocking
# I have no idea why, but that's how it is...
vcgencmd version
# report_status configuration
report_status camera: $camera
report_status usb options: $camera_usb_options
report_status raspi options: $camera_raspi_options
# keep mjpg streamer running if some camera is attached
while true; do
if [ -e "/dev/video0" ] && { [ "$camera" = "auto" ] || [ "$camera" = "usb" ] ; }; then
startUsb
elif [ "`vcgencmd get_camera`" = "supported=1 detected=1" ] && { [ "$camera" = "auto" ] || [ "$camera" = "raspi" ] ; }; then
startRaspi
fi
sleep 120
done
WEBCAMDAEMON
chmod +x $OctoPrintFarm/octo-scripts/webcam*
[ -f /etc/rc.local ] && sudo mv /etc/rc.local /etc/rc.local.bak &> /dev/null
cat &> /dev/null<<AUTOSTART | sudo tee -a /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
$OctoPrintFarm/octo-scripts/webcam start
exit0
AUTOSTART
sudo chmod +x /etc/rc.local
report_status "Adding new hostname octolinux"
report_status "..."
sudo apt install avahi-daemon -y &> /dev/null
[ -f /etc/hosts ] && sudo mv /etc/hosts /etc/hosts.bak &> /dev/null
cat &> /dev/null<<HOSTS | sudo tee -a /etc/hosts
127.0.0.1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
127.0.0.1 octolinux
HOSTS
report_status "Adding permission to Octoprint $userSelect user to reboot without password"
report_status "..."
[ -f /etc/sudoers.d/octoprint-shutdown ] && sudo mv /etc/sudoers.d/octoprint-shutdown /etc/sudoers.d/octoprint-shutdown.bak &> /dev/null
cat &> /dev/null<<SUDOER | sudo tee -a /etc/sudoers.d/octoprint-shutdown
$userSelect ALL=NOPASSWD: /sbin/shutdown
SUDOER
sudo apt install haproxy -y &> /dev/null
[ -f /etc/haproxy/haprox.cfg ] && sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
cat &> /dev/null<<PROXY | sudo tee -a /etc/haproxy/haproxy.cfg
global
maxconn 4096
user haproxy
group haproxy
daemon
log 127.0.0.1 local0 debug
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
option http-ferver-close
option forwardfor
maxconn 2000
timeout connect 5s
timeout client 15min
timeout server 15min
frontend public
bind :::80 v4v6
use_backend webcam if { path_beg /webcam/ }
default_backend octoprint
backend octoprint
reqrep ^([^\ :]*)\ /(.*) \1\ /\2
option forwardfor
server octoprint1 127.0.0.1:5000
backend webcam
reqrep ^([^\ :]*)\ /webcam/(.*) \1\ /\2
server webcam1 127.0.0.1:8080
PROXY
report_status "Remember to reboot the computer at least once to complete the $printCount Octoprint instance(s) to fully set up"
report_status "Everything is Done!"
pause
}
klipper_dwc_uninstall(){
report_status "Launching Klipper uninstall script..."
sleep 3
klipper_num=`find /etc/systemd/system -type f -name 'klipper-*' -printf x | wc -c`
session_num=$(( $klipper_num-1 ))
#sudo service klipper stop
printer_num=0
while (( $printer_num <= $session_num ))
do
report_status "Stopping klipper-$printer_num service..."
sudo systemctl stop klipper-$printer_num &> /dev/null
sleep 1
report_status "Disabling klipper-$printer_num service..."
sudo systemctl disable klipper-$printer_num &> /dev/null
sleep 1
report_status "Removing klipper-$printer_num service..."
sudo rm /etc/systemd/system/klipper-$printer_num.service &> /dev/null
sleep 1
report_status "Your config file, printer-$printer_num.cfg is still available, under $KlipperFarm/printer-$printer_num..."
sleep 3
report_status "Your $KlipperFarm/printer-$printer_num/sdcard folder is untouched..."
sleep 3
printer_num=$(( printer_num+1 ))
done
# Remove Klipper from Services
sleep 3
# Notify user of method to remove Klipper source code
sleep 3
report_status "The Klipper & DWC system files have been removed."
rm -vRf $KLIPPER
rm -vRf $SDCARD/dwc2
sleep 3
report_status "~/sdcard folder has not been removed"
sleep 3
pause
}
octoprint_uninstall(){
report_status "Not yet implemanted!"
pause
}
# read input from the keyboard and take a action
# invoke the one() when the user select 1 from the menu option.
# invoke the two() when the user select 2 from the menu option.
# Exit when user the user select 3 form the menu option.
read_options(){
local choice
read -p "Please choose what to do, then press [ENTER] [ 1 - 9 ] " choice
case $choice in
1) klipper_install ;;
2) klipper_update ;;
3) flash_mcu ;;
4) dwc_install ;;
5) dwc_update ;;
6) octorprint_install ;;
7) klipper_dwc_uninstall ;;
8) octoprint_uninstall ;;
9) exit 0 ;;
*) echo -e "${RED}${BG_WHITE}Error...${RESET}" && sleep 2
esac
}
trap '' SIGINT SIGQUIT SIGTSTP
while true
do
show_menus
read_options
done