352 lines
13 KiB
Bash
Executable File
352 lines
13 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
new_instance() {
|
|
#reset detection info
|
|
UDEV=''
|
|
TEMPUSB=''
|
|
USB=''
|
|
|
|
#It is possible to not create an instance after preparing,so check if this is the first
|
|
if [ -f /etc/octodocker_instances ]; then
|
|
firstrun=false
|
|
else
|
|
firstrun=true
|
|
fi
|
|
|
|
#We can also pass this directly, from prepare.sh
|
|
firstrun=$1
|
|
TEMPLATE=''
|
|
|
|
get_settings
|
|
|
|
if [ $SUDO_USER ]; then user=$SUDO_USER; fi
|
|
SCRIPTDIR=$(dirname $(readlink -f $0))
|
|
|
|
while true; do
|
|
echo "${green}Enter the name for new printer/instance (no spaces):${white}"
|
|
read INSTANCE
|
|
if [ -z "$INSTANCE" ]; then
|
|
echo "Please provide an instance name"
|
|
continue
|
|
fi
|
|
|
|
if ! has-space "$INSTANCE"; then
|
|
break
|
|
else
|
|
echo "Instance names must not have spaces"
|
|
fi
|
|
done
|
|
|
|
if [ "$firstrun" != "true" ]; then
|
|
if [ -d "/opt/octoprint/$INSTANCE" ]; then
|
|
echo "Already have an entry for $INSTANCE. Exiting."
|
|
main_menu
|
|
fi
|
|
|
|
#Choose if should use an instance as template here
|
|
echo
|
|
echo
|
|
echo
|
|
echo "Using a template instance allows you to copy config settings"
|
|
echo "and gcode files from one instance to your new instance."
|
|
if prompt_confirm "Use an existing instance as a template?"; then
|
|
PS3="${cyan}Select template instance: ${white}"
|
|
get_instances true
|
|
select opt in "${INSTANCE_ARR[@]}"
|
|
do
|
|
if [ "$opt" == Quit ]; then
|
|
main_menu
|
|
fi
|
|
|
|
TEMPLATE=$opt
|
|
echo "Using $opt as template."
|
|
break
|
|
done
|
|
PS3="${cyan}Select what components of the template to copy: ${white}"
|
|
options=("Config Only" "Config and Gcode")
|
|
select opt in "${options[@]}"
|
|
do
|
|
case $opt in
|
|
"Config Only")
|
|
COPY=1
|
|
break
|
|
;;
|
|
"Config and Gcode")
|
|
COPY=2
|
|
break
|
|
;;*) echo "invalid option $REPLY";;
|
|
esac
|
|
done
|
|
|
|
else
|
|
TEMPLATE=''
|
|
fi
|
|
fi
|
|
|
|
if prompt_confirm "Ready to begin instance creation?"; then
|
|
PORT=5000
|
|
PORTS_INUSE=$(join_by , $(cat /etc/octodocker_instances 2>/dev/null | sed -n -e 's/^.*\(port:\)\(.*\) udev:.*/\2/p'))
|
|
until [[ "${PORTS_INUSE}" != *"${PORT}"* ]]; do ((PORT++)); done
|
|
|
|
echo Selected port is: $PORT
|
|
OCTOCONFIG="/opt/octoprint"
|
|
|
|
echo "Your new OctoPrint instance will be installed at ${cyan}/opt/octoprint/$INSTANCE${white}"
|
|
echo
|
|
echo
|
|
else
|
|
if [ "$firstrun" == "true" ]; then
|
|
echo "${red}You will need to restart your installation.${white}"
|
|
echo "${red}Answer Y and re-run octodocker_deploy${white}"
|
|
remove_everything
|
|
exit
|
|
else
|
|
main_menu
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$TEMPLATE" ]; then
|
|
BFOLD="/opt/octoprint/$INSTANCE$TEMPLATE"
|
|
#check to make sure first run is complete
|
|
if grep -q 'firstRun: true' $BFOLD/config.yaml; then
|
|
echo "Template profile and admin user will have to be setup."
|
|
main_menu
|
|
fi
|
|
fi
|
|
|
|
echo "Printer auto-detection must be completed before an instance can be created."
|
|
if prompt_confirm "Begin printer auto-detection for udev entry?"; then
|
|
detect_printer
|
|
else
|
|
if [ "$firstrun" == "true" ]; then
|
|
echo "${magenta}First instance setup in progress, continuing${white}"
|
|
|
|
else
|
|
echo "${magenta}Instance has not been created. Restart and do detection when you are ready.${white}"
|
|
main_menu
|
|
fi
|
|
fi
|
|
|
|
#Detection phase
|
|
printer_udev false
|
|
|
|
#USB cameras
|
|
if [ "$firstrun" != "true" ]; then
|
|
if prompt_confirm "Would you like to auto detect an associated USB camera?"; then
|
|
add_camera
|
|
fi
|
|
fi
|
|
|
|
if prompt_confirm "Ready to write all changes. Do you want to proceed?"; then
|
|
|
|
mkdir $OCTOCONFIG/$INSTANCE
|
|
|
|
cat $SCRIPTDIR/docker-compose.yml | \
|
|
sed -e "s/NEWINSTANCE/$INSTANCE/" \
|
|
-e "s/CAMPORT/$CAMPORT/" > \
|
|
-e "s/NEWPORT/$PORT/" > $OCTOCONFIG/$INSTANCE/docker-compose.yml
|
|
|
|
#write phase
|
|
if [ -n "$UDEV" ] || [ -n "$USB" ]; then
|
|
printer_udev true
|
|
fi
|
|
|
|
#Append instance name to list for removal tool
|
|
if [ -z "$UDEV" ] && [ -z "$USB" ]; then
|
|
echo "instance:$INSTANCE port:$PORT udev:false" >> /etc/octodocker_instances
|
|
else
|
|
echo "instance:$INSTANCE port:$PORT udev:true" >> /etc/octodocker_instances
|
|
fi
|
|
|
|
if [ -n "$TEMPLATE" ]; then
|
|
echo "${magenta}Copying template files....${white}"
|
|
if [ $COPY -eq 1 ]; then
|
|
rsync -r \
|
|
--exclude 'timelapse' \
|
|
--exclude 'uploads' \
|
|
--exclude 'logs' \
|
|
$BFOLD/* $OCTOCONFIG/$INSTANCE/octoprint/
|
|
fi
|
|
if [ $COPY -eq 2 ]; then
|
|
rsync -r \
|
|
--exclude 'timelapse' \
|
|
--exclude 'logs' \
|
|
$BFOLD/* $OCTOCONFIG/$INSTANCE/octoprint/
|
|
fi
|
|
fi
|
|
|
|
#build docker
|
|
docker compose -f $OCTOCONFIG/$INSTANCE/docker-compose.yml up -d
|
|
|
|
#uniquify instances
|
|
echo 'Uniquifying instance...'
|
|
BASE=$OCTOCONFIG/$INSTANCE
|
|
docker exec -it $INSTANCE $OCTOEXEC --basedir $BASE config set appearance.name $INSTANCE
|
|
docker exec -it $INSTANCE $OCTOEXEC --basedir $BASE config set server.commands.serverRestartCommand "sudo systemctl restart $INSTANCE"
|
|
docker exec -it $INSTANCE $OCTOEXEC --basedir $BASE config set server.commands.systemRestartCommand "sudo reboot"
|
|
docker exec -it $INSTANCE $OCTOEXEC --basedir $BASE config set plugins.discovery.upnpUuid $(uuidgen)
|
|
docker exec -it $INSTANCE $OCTOEXEC --basedir $BASE config set plugins.errortracking.unique_id $(uuidgen)
|
|
docker exec -it $INSTANCE $OCTOEXEC --basedir $BASE config set plugins.tracking.unique_id $(uuidgen)
|
|
docker exec -it $INSTANCE $OCTOEXEC --basedir $BASE config set serial.port /dev/octo_$INSTANCE
|
|
#clear additional ports
|
|
docker exec -it $INSTANCE $OCTOEXEC --basedir $BASE config remove serial.additionalPorts
|
|
docker exec -it $INSTANCE $OCTOEXEC --basedir $BASE config append_value serial.additionalPorts "/dev/octo_$INSTANCE"
|
|
docker exec -it $INSTANCE $OCTOEXEC --basedir $BASE config set feature.modelSizeDetection false --bool
|
|
docker exec -it $INSTANCE $OCTOEXEC --basedir $BASE config set webcam.ffmpeg /usr/bin/ffmpeg
|
|
|
|
if [ "$HAPROXY" == true ]; then
|
|
HAversion=$(haproxy -v | sed -n 's/^.*version \([0-9]\).*/\1/p')
|
|
SEDREPLACE="#$INSTANCE start\n\
|
|
acl is_$INSTANCE url_beg /$INSTANCE\n\
|
|
http-request redirect scheme http drop-query append-slash if is_$INSTANCE ! { path_beg /$INSTANCE/ }\n\
|
|
use_backend $INSTANCE if { path_beg /$INSTANCE/ }\n\
|
|
#$INSTANCE stop"
|
|
|
|
sed -i "/option forwardfor except 127.0.0.1/a $SEDREPLACE" /etc/haproxy/haproxy.cfg
|
|
echo "#$INSTANCE start" >> /etc/haproxy/haproxy.cfg
|
|
echo "backend $INSTANCE" >> /etc/haproxy/haproxy.cfg
|
|
if [ $HAversion -gt 1 ]; then
|
|
echo " http-request replace-path /$INSTANCE/(.*) /\1" >> /etc/haproxy/haproxy.cfg
|
|
echo " acl needs_scheme req.hdr_cnt(X-Scheme) eq 0" >> /etc/haproxy/haproxy.cfg
|
|
echo " http-request add-header X-Scheme https if needs_scheme { ssl_fc }" >> /etc/haproxy/haproxy.cfg
|
|
echo " http-request add-header X-Scheme http if needs_scheme !{ ssl_fc }" >> /etc/haproxy/haproxy.cfg
|
|
echo " http-request add-header X-Script-Name /$INSTANCE" >> /etc/haproxy/haproxy.cfg
|
|
echo " server octoprint1 127.0.0.1:$PORT" >> /etc/haproxy/haproxy.cfg
|
|
echo " option forwardfor" >> /etc/haproxy/haproxy.cfg
|
|
else
|
|
echo " reqrep ^([^\ :]*)\ /$INSTANCE/(.*) \1\ /\2" >> /etc/haproxy/haproxy.cfg
|
|
echo " server octoprint1 127.0.0.1:$PORT" >> /etc/haproxy/haproxy.cfg
|
|
echo " option forwardfor" >> /etc/haproxy/haproxy.cfg
|
|
echo " acl needs_scheme req.hdr_cnt(X-Scheme) eq 0" >> /etc/haproxy/haproxy.cfg
|
|
echo " reqadd X-Scheme:\ https if needs_scheme { ssl_fc }" >> /etc/haproxy/haproxy.cfg
|
|
echo " reqadd X-Scheme:\ http if needs_scheme !{ ssl_fc }" >> /etc/haproxy/haproxy.cfg
|
|
echo " reqadd X-Script-Name:\ /$INSTANCE" >> /etc/haproxy/haproxy.cfg
|
|
fi
|
|
|
|
echo "#$INSTANCE stop" >> /etc/haproxy/haproxy.cfg
|
|
|
|
#restart haproxy
|
|
sudo systemctl restart haproxy.service
|
|
|
|
fi
|
|
|
|
if [[ -n $CAM || -n $USBCAM ]]; then
|
|
write_camera
|
|
fi
|
|
|
|
#Reset udev
|
|
udevadm control --reload-rules
|
|
udevadm trigger
|
|
systemctl daemon-reload
|
|
sleep 1
|
|
|
|
#restart docker
|
|
docker restart $INSTANCE
|
|
systemctl enable $INSTANCE.service
|
|
if [[ -n $CAM || -n $USBCAM || -n $BYIDCAM ]]; then
|
|
systemctl start cam_$INSTANCE.service
|
|
systemctl enable cam_$INSTANCE.service
|
|
fi
|
|
else
|
|
main_menu
|
|
fi
|
|
|
|
if [ "$firstrun" == "true" ]; then
|
|
firstrun_install
|
|
else
|
|
main_menu
|
|
fi
|
|
|
|
}
|
|
|
|
detect_printer() {
|
|
echo
|
|
echo
|
|
dmesg -C
|
|
echo "Plug your printer in via USB now (detection time-out in 1 min)"
|
|
counter=0
|
|
while [[ -z "$UDEV" ]] && [[ $counter -lt 60 ]]; do
|
|
TEMPUSB=$(dmesg | sed -n -e 's/^.*\(cdc_acm\|ftdi_sio\|ch341\|cp210x\|ch34x\) \([0-9].*[0-9]\): \(tty.*\|FTD.*\|ch341-uart.*\|cp210x\|ch34x\).*/\2/p')
|
|
UDEV=$(dmesg | sed -n -e 's/^.*SerialNumber: //p')
|
|
counter=$(( $counter + 1 ))
|
|
if [[ -n "$TEMPUSB" ]] && [[ -z "$UDEV" ]]; then
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
dmesg -C
|
|
}
|
|
|
|
printer_udev() {
|
|
write=$1
|
|
if [ "$write" == true ]; then
|
|
#Printer udev identifier technique - either Serial number or USB port
|
|
#Serial Number
|
|
if [ -n "$UDEV" ]; then
|
|
echo SUBSYSTEM==\"tty\", ATTRS{serial}==\"$UDEV\", SYMLINK+=\"octo_$INSTANCE\" >> /etc/udev/rules.d/99-octoprint.rules
|
|
fi
|
|
|
|
#USB port
|
|
if [ -n "$USB" ]; then
|
|
echo KERNELS==\"$USB\",SUBSYSTEM==\"tty\",SYMLINK+=\"octo_$INSTANCE\" >> /etc/udev/rules.d/99-octoprint.rules
|
|
fi
|
|
else
|
|
#No serial number
|
|
if [ -z "$UDEV" ] && [ -n "$TEMPUSB" ]; then
|
|
echo "Printer Serial Number not detected."
|
|
echo "The physical USB port will be used."
|
|
echo "USB hubs and printers detected this way must stay plugged into the same USB positions on your machine."
|
|
echo
|
|
USB=$TEMPUSB
|
|
echo "Your printer will be setup at the following usb address: ${cyan}$USB${white}"
|
|
echo
|
|
else
|
|
echo -e "Serial number detected as: ${cyan}$UDEV${white}"
|
|
check_sn "$UDEV"
|
|
echo
|
|
fi
|
|
#Failed state. Nothing detected
|
|
if [ -z "$UDEV" ] && [ -z "$TEMPUSB" ]; then
|
|
if [ "$firstrun" == "false" ]; then
|
|
echo
|
|
echo "${red}No printer was detected during the detection period.${white}"
|
|
echo "Check your USB cable (power only?) and try again."
|
|
echo
|
|
echo
|
|
main_menu
|
|
else
|
|
echo "You can add a udev rule later from the Utilities menu."
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
remove_instance() {
|
|
opt=$1
|
|
#stop and remove docker
|
|
if [ "$(docker ps -a | grep $opt)" ]; then
|
|
docker stop $opt
|
|
docker rm $opt
|
|
fi
|
|
|
|
#Get all cameras associated with this instance.
|
|
#Is this right?
|
|
get_cameras
|
|
for camera in "${CAMERA_ARR[@]}"; do
|
|
remove_camera $camera
|
|
done
|
|
|
|
#remove udev entry
|
|
sed -i "/$opt/d" /etc/udev/rules.d/99-octoprint.rules
|
|
#remove files
|
|
rm -rf /opt/octoprint/s$opt
|
|
#remove from octoprint_instances
|
|
sed -i "/$opt/d" /etc/octodocker_instances
|
|
#remove haproxy entry
|
|
if [ "$HAPROXY" == true ]; then
|
|
sed -i "/use_backend $opt/d" /etc/haproxy/haproxy.cfg
|
|
sed -i "/#$opt start/,/#$opt stop/d" /etc/haproxy/haproxy.cfg
|
|
systemctl restart haproxy.service
|
|
fi
|
|
|
|
} |