diff --git a/TODO.md b/TODO.md
index a5e7c96..d15d3bb 100644
--- a/TODO.md
+++ b/TODO.md
@@ -3,12 +3,6 @@
## First time/Octo-Config
- Add network configuration (replace nmtui)
- Add hostname configuration (replace nmtui)
-- Better service configuration (deeper menu)
-- System check
-- Touch screen calibration
-
-## Frontend
-- Separate frontend from pi account
## Nginx
- Add HTTP basic auth (especially to MJPG)
diff --git a/stage1/01-sys-tweaks/00-run.sh b/stage1/01-sys-tweaks/00-run.sh
index 51331c7..4225fe8 100755
--- a/stage1/01-sys-tweaks/00-run.sh
+++ b/stage1/01-sys-tweaks/00-run.sh
@@ -9,6 +9,7 @@ install -m 644 files/.dialogrc "${ROOTFS_DIR}/etc/skel/.dialogrc"
install -m 644 files/.dialogrc "${ROOTFS_DIR}/root/.dialogrc"
mkdir -p "${ROOTFS_DIR}/etc/skel/.config/openbox"
install -m 644 files/autostart "${ROOTFS_DIR}/etc/skel/.config/openbox/autostart"
+install -m 644 files/menu.xml "${ROOTFS_DIR}/etc/skel/.config/openbox/menu.xml"
on_chroot << EOF
if ! id -u ${FIRST_USER_NAME} >/dev/null 2>&1; then
@@ -17,7 +18,10 @@ fi
if ! id -u octoprint >/dev/null 2>&1; then
adduser --system --shell /usr/sbin/nologin --group --disabled-password --gecos "" octoprint
fi
+if ! id -u kiosk >/dev/null 2>&1; then
+ adduser --disabled-password --shell /usr/sbin/nologin --gecos "" kiosk
+fi
echo "${FIRST_USER_NAME}:${FIRST_USER_PASS}" | chpasswd
-echo "octoprint:$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c40)" | chpasswd
+echo "kiosk:$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c40)" | chpasswd
echo "root:$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c40)" | chpasswd
EOF
diff --git a/stage1/01-sys-tweaks/files/.browser.sh b/stage1/01-sys-tweaks/files/.browser.sh
index 01dd8fe..c1ebadb 100644
--- a/stage1/01-sys-tweaks/files/.browser.sh
+++ b/stage1/01-sys-tweaks/files/.browser.sh
@@ -1,25 +1,25 @@
#!/bin/bash
# Grabs the port (and IP) out of the nginx config
-LISTEN=$(grep -i listen /etc/nginx/listen.conf | awk '{gsub(";",""); print $2}')
+LISTEN=$(awk '/listen/{gsub(";",""); print $2}' /etc/nginx/listen.conf)
# If the value we just grabbed doesn't contain an IP, prepend localhost
if ! echo $LISTEN | grep ":" 2>&1; then
- ADDRESS="localhost:$LISTEN"
+ ADDRESS="https://localhost:$LISTEN"
else
- ADDRESS=$LISTEN
+ ADDRESS="https://$LISTEN"
fi
# Override the automatically detected address if the user wants to
if [[ -f ~/.overrideurl.sh ]]; then source ~/.overrideurl.sh; fi
# Wait until Nginx/override comes up
-while ! curl "$ADDRESS" 2>&1 >/dev/null; do
+while ! curl -f -k -s -I "$ADDRESS" 2>&1 >/dev/null; do
sleep 1
done
# Wait until OctoPrint comes up if it is enabled
-while [[ -f /etc/systemd/system/multi-user.target.wants/octoprint.service ]] && ! curl "localhost:5000"; do
+while [[ -f /etc/systemd/system/multi-user.target.wants/octoprint.service ]] && ! curl -f -s -I "localhost:5000"; do
sleep 1
done
@@ -31,4 +31,4 @@ done
# -K | Enable kiosk mode (doesn't seem to do anything?)
# -n | Disable web inspector
# -p | Disable plugins
-surf -t -F -g -K -n -p "https://$ADDRESS"
+surf -t -F -g -K -n -p "$ADDRESS"
diff --git a/stage1/01-sys-tweaks/files/menu.xml b/stage1/01-sys-tweaks/files/menu.xml
new file mode 100644
index 0000000..60e591c
--- /dev/null
+++ b/stage1/01-sys-tweaks/files/menu.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/stage2/01-sys-tweaks/01-run.sh b/stage2/01-sys-tweaks/01-run.sh
index 5cb650a..c5f1ff6 100755
--- a/stage2/01-sys-tweaks/01-run.sh
+++ b/stage2/01-sys-tweaks/01-run.sh
@@ -46,6 +46,9 @@ done
for GRP in dialout plugdev video users; do
adduser octoprint \$GRP
done
+for GRP in users; do
+ adduser kiosk \$GRP
+done
EOF
on_chroot << EOF
diff --git a/stage2/06-utils/files/first-time.sh b/stage2/06-utils/files/first-time.sh
index 7efe87e..11aea05 100755
--- a/stage2/06-utils/files/first-time.sh
+++ b/stage2/06-utils/files/first-time.sh
@@ -67,7 +67,10 @@ suggested_menu () {
dialog --title "NOTICE" --nocancel --colors --msgbox "This collection of software is currently in beta. It is lacking several critical features. \Zb\Z1DO NOT\Zn use this in a production environment." 10 50
# Force the user to change the pi user's password before the RPi gets botnetted
-change_password
+change_password
+# Randomize the root and frontend password
+echo "kiosk:$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c40)" | chpasswd
+echo "root:$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c40)" | chpasswd
dialog --title "Network Configuration" --nocancel --msgbox "Setup will now open nmtui, a program to help configure your ethernet/wireless interfaces. Hit Quit when you are done." 10 50
nmtui
@@ -76,10 +79,14 @@ nmtui
dpkg-reconfigure tzdata
# Enable/disable OctoPrint, GUI, MJPG and SSH
-service_select
+service_toggle
screen_timeout
+if ( udevadm info --export-db | grep ID_INPUT_TOUCHSCREEN=1 >/dev/null ) && dialog --title "Touchscreen Calibration" --defaultno --yesno "Do you wish to calibrate your touchscreen?\nMost touchscreens are calibrated out of the factory, so this is usually not needed." 10 60; then
+ startx $(which xinput_calibrator) --no-timeout --output-filename /etc/X11/xorg.conf.d/99-calibration.conf
+fi
+
# Makes a certificate and key for Nginx HTTPS
openssl req -x509 -nodes -days 36500 -newkey rsa:4096 -subj "/C=/ST=/L=/O=/OU=/CN=*/emailAddress=" -out /etc/ssl/certs/nginx-octoprint.crt -keyout /etc/ssl/private/nginx-octoprint.key
@@ -90,6 +97,7 @@ fi
# If MJPG service is enabled, ask user which video device to use
if [[ -f /etc/systemd/system/multi-user.target.wants/mjpg-streamer.service ]]; then
+ video_select
video_config
fi
diff --git a/stage2/06-utils/files/octo-config b/stage2/06-utils/files/octo-config
index 43f1dbb..8525c74 100755
--- a/stage2/06-utils/files/octo-config
+++ b/stage2/06-utils/files/octo-config
@@ -9,26 +9,77 @@ fi
source /usr/local/lib/octo-lib.sh
main_menu () {
- local MAINMENU=$(dialog --nocancel --title "Pi Setup" --menu "" 10 50 0 \
+ local MAINMENU=$(dialog --nocancel --title "TouchPrint Setup" --menu "" 10 50 0 \
"1" "Configure networking" \
"2" "Change password for pi" \
"3" "Configure services" \
"4" "Configure screen timeout" \
- "5" "Configure Nginx" \
- "6" "Configure MJPG" \
- "7" "Exit" 3>&1 1>&2 2>&3)
+ "5" "Calibrate touchscreen" \
+ "6" "Exit" 3>&1 1>&2 2>&3)
case $MAINMENU in
"1") nmtui; main_menu; return 0;;
"2") change_password; main_menu; return 0;;
- "3") service_select; main_menu; return 0;;
+ "3") services_menu; main_menu; return 0;;
"4") screen_timeout; main_menu; return 0;;
- "5") nginx_config; main_menu; return 0;;
- "6") video_config; main_menu; return 0;;
- "7") return 0;;
+ "5") dialog --title "Touchscreen Calibration" --infobox "Waiting for touchscreen calibrator to close..." 3 50; DISPLAY=:0 xinput_calibrator --no-timeout --output-filename /etc/X11/xorg.conf.d/99-calibration.conf; main_menu; return 0;;
+ "6") return 0;;
esac
}
+services_menu () {
+ local SERVICESMENU=$(dialog --nocancel --title "Services Select" --menu "" 10 50 0 \
+ "1" "Enable/disable services" \
+ "2" "Service health check" \
+ "3" "Configure Nginx" \
+ "4" "Configure MJPG" \
+ "5" "Go Back" 3>&1 1>&2 2>&3)
+
+ case $SERVICESMENU in
+ "1") service_toggle; services_menu; return 0;;
+ "2") service_health; services_menu; return 0;;
+ "3") nginx_config; services_menu; return 0;;
+ "4") video_menu; services_menu; return 0;;
+ "5") return 0;;
+ esac
+}
+
+service_health () {
+ # Grab listening address/port from Nginx config
+ if [[ -f /etc/nginx/listen.conf ]]; then
+ LISTEN=$(awk '/listen/{gsub(";",""); print $2}' /etc/nginx/listen.conf)
+ else
+ LISTEN="443"
+ fi
+
+ # If Nginx config didn't contain a port, assume localhost
+ if ! echo $LISTEN | grep ":" 2>&1; then
+ ADDRESS="localhost:$LISTEN"
+ else
+ ADDRESS=$LISTEN
+ fi
+
+ # I hate bash, and soon you will too
+ dialog --colors --title "Service Health" --msgbox "\
+\ZnOctoPrint: \Zb$(if curl -s -I 127.0.0.1:5000 >/dev/null; then echo '\Z2Online'; elif [[ ! -f /etc/systemd/system/multi-user.target.wants/octoprint.service ]]; then echo "Disabled"; else echo '\Z1Offline'; fi)
+\ZnMJPG: \Zb$(if curl -s -I 127.0.0.1:9000 >/dev/null; then echo '\Z2Online'; elif [[ ! -f /etc/systemd/system/multi-user.target.wants/mjpg-streamer.service ]]; then echo "Disabled"; else echo '\Z1Offline'; fi)
+\ZnNginx: \Zb$(if curl -k -s -I https://$ADDRESS >/dev/null; then echo '\Z2Online'; elif [[ ! -f /etc/systemd/system/multi-user.target.wants/nginx.service ]]; then echo "Disabled"; else echo '\Z1Offline'; fi)
+\ZnSSH: \Zb$(if pgrep sshd >/dev/null; then echo '\Z2Online'; elif [[ ! -f /etc/systemd/system/multi-user.target.wants/sshd.service ]]; then echo "Disabled"; else echo '\Z1Offline'; fi)" 0 0
+}
+
+video_menu () {
+ local VIDEOMENU=$(dialog --title "MJPG Config" --menu "" 10 50 0 \
+ "1" "Camera Selection" \
+ "2" "Video Settings" \
+ "3" "Go Back" 3>&1 1>&2 2>&3)
+
+ case $VIDEOMENU in
+ "1") video_select; video_menu; return 0;;
+ "2") video_config; video_menu; return 0;;
+ "3") return 0;;
+ esac
+}
+
main_menu
if dialog --title "Reboot Confirmation" --yesno "Some changes require a reboot to take effect.\nDo you want to reboot now?" 10 50; then
reboot
diff --git a/stage2/06-utils/files/octo-lib.sh b/stage2/06-utils/files/octo-lib.sh
index 77305d0..a17c087 100644
--- a/stage2/06-utils/files/octo-lib.sh
+++ b/stage2/06-utils/files/octo-lib.sh
@@ -19,7 +19,7 @@ change_password () {
unset PASSWORD
}
-service_select () {
+service_toggle () {
# Toggle the checkboxes if the service is active or not
local SERVICE_MENU=$(dialog --separate-output --nocancel --title "Select services" --checklist "Enable/disable services" 0 0 0 \
"1" "OctoPrint" $(if [[ -f /etc/systemd/system/multi-user.target.wants/octoprint.service ]]; then echo "ON"; else echo "OFF"; fi) \
@@ -69,7 +69,6 @@ service_select () {
systemctl disable ssh
fi
-
<< 'EOF'
for ((i = 0; i <= 3; i++)); do
for n in "${SERVICE_MENU[@]}"; do
@@ -91,9 +90,12 @@ service_select () {
EOF
}
-screen_timeout() {
+screen_timeout () {
local TIMEOUT=$(dialog --nocancel --title "Screen Timeout" --inputbox "Input your desired screen timeout in seconds.\nEnter \"off\" to disable the screen timeout.\n\nAdding a screen timeout can reduce screen burn in.\n\nDefault: off" 12 60 "off" 3>&1 1>&2 2>&3)
- cat > /home/pi/.xtimeout << EOF
+
+ [[ "$TIMEOUT" == "" ]] && return 0
+
+ cat > /home/kiosk/.xtimeout << EOF
xset s ${TIMEOUT}
xset -dpms
EOF
@@ -104,24 +106,29 @@ nginx_config () {
# Grab the variable from the nginx conf if it exists, otherwise use default
if [[ -f /etc/nginx/listen.conf ]]; then
- LISTEN=$(grep -i listen /etc/nginx/listen.conf | awk '{gsub(";",""); print $2}')
+ LISTEN=$(awk '/listen/{gsub(";",""); print $2}' /etc/nginx/listen.conf)
else
LISTEN="443"
fi
LISTEN=$(dialog --title "Nginx Config" --nocancel --inputbox "Configure what port and IP Nginx should listen on.\nTo listen on all IPs, just enter the port.\nDefault: 443" 11 50 "$LISTEN" 3>&1 1>&2 2>&3)
+ [[ "$LISTEN" == "" ]] && return 0
+
# Write new value to nginx
echo "listen $LISTEN;" > /etc/nginx/listen.conf
}
-video_config () {
+video_select () {
# In the unlikely event that there are no video devices, don't continue
if ! ls /dev/video* 2>&1 >/dev/null; then
dialog --title "Error" --msgbox "No video devices detected!" 10 50
return 1
fi
+ # Grab config values
+ source /usr/local/etc/mjpg-server/config.sh
+
# Grab all video devices
local DEVICES=($(ls /dev/video*))
@@ -129,13 +136,41 @@ video_config () {
# Generate a menu from said video devices
for ((i = 0; i < ${#DEVICES[@]}; i++)); do
- DEVICELIST+="${DEVICES[$i]} $i OFF "
+ if [[ "$VIDEO_DEVICE" == ${DEVICES[$i]} ]]; then
+ DEVICELIST+="${DEVICES[$i]} $i ON "
+ else
+ DEVICELIST+="${DEVICES[$i]} $i OFF "
+ fi
done
- local DEVICE_MENU=$(dialog --title "Video Config" --nocancel --radiolist "Choose which video device you wish to use for MJPG-Streamer" 10 50 0 $DEVICELIST 3>&1 1>&2 2>&3)
+ local DEVICE_MENU=$(dialog --title "MJPG Config" --nocancel --radiolist "Choose which video device you wish to use for MJPG-Streamer" 10 50 0 $DEVICELIST 3>&1 1>&2 2>&3)
[[ "$DEVICE_MENU" == "" ]] && return 0
- # Write selected value to startup script
- echo -e '#!/bin/bash'"\n/usr/local/bin/mjpeg-server -a 127.0.0.1:9000 -- ffmpeg -i $DEVICE_MENU -f v4l2 -f mpjpeg -" > /usr/local/bin/start-mjpg
+ # Write selected value to config file
+ echo -e "VIDEO_DEVICE=$DEVICE_MENU\nVIDEO_SIZE=$VIDEO_SIZE\nFRAMERATE=$FRAMERATE" > /usr/local/etc/mjpg-server/config.sh
+}
+
+video_config () {
+ # Include config values
+ source /usr/local/etc/mjpg-server/config.sh
+
+ # Set video device to a resonable default if it isn't set for some reason
+ if [[ "$VIDEO_DEVICE" == "" ]]; then
+ VIDEO_DEVICE="/dev/video0"
+ fi
+
+ local VIDEOCONFIG_MENU=$(dialog --nocancel --title "MJPG Config" --form "Choose desired camera resolution and framerate." 10 50 0\
+ "Resolution: " 1 1 "$VIDEO_SIZE" 1 13 10 0 \
+ "Framerate: " 2 1 "$FRAMERATE" 2 12 3 0 3>&1 1>&2 2>&3)
+ VIDEOCONFIG_MENU=($VIDEOCONFIG_MENU)
+
+ if [[ "$VIDEOCONFIG_MENU[0]" == "" ]] || [[ "$VIDEOCONFIG_MENU[1]" == "" ]]; then
+ dialog --title "Error" --msgbox "Invalid input!" 10 50
+ video_config
+ return 0
+ fi
+
+ # Write values to config file
+ echo -e "VIDEO_DEVICE=$VIDEO_DEVICE\nVIDEO_SIZE=${VIDEOCONFIG_MENU[0]}\nFRAMERATE=${VIDEOCONFIG_MENU[1]}" > /usr/local/etc/mjpg-server/config.sh
}
diff --git a/stage3/00-install-packages/01-run.sh b/stage3/00-install-packages/01-run.sh
index 4adb563..6654d2d 100755
--- a/stage3/00-install-packages/01-run.sh
+++ b/stage3/00-install-packages/01-run.sh
@@ -1,41 +1,7 @@
#!/bin/bash -e
-#echo -n -e "NODM_USER=${FIRST_USER_NAME}\nNODM_XSESSION=/home/${FIRST_USER_NAME}/.xprofile" > ${ROOTFS_DIR}/etc/nodm.conf
-
-cat > ${ROOTFS_DIR}/etc/default/nodm << EOF
-# nodm configuration
-
-# Set NODM_ENABLED to something different than 'false' to enable nodm
-NODM_ENABLED=true
-
-# User to autologin for
-NODM_USER=${FIRST_USER_NAME}
-
-# First vt to try when looking for free VTs
-NODM_FIRST_VT=7
-
-# X session
-NODM_XSESSION=/home/${FIRST_USER_NAME}/.xprofile
-
-# Options for nodm itself
-NODM_OPTIONS=
-
-# Options for the X server.
-#
-# Format: [/usr/bin/] [:]
-#
-# The Xserver executable and the display name can be omitted, but should
-# be placed in front, if nodm's defaults shall be overridden.
-NODM_X_OPTIONS='-nolisten tcp'
-
-# If an X session will run for less than this time in seconds, nodm will wait an
-# increasing bit of time before restarting the session.
-NODM_MIN_SESSION_TIME=60
-
-# Timeout (in seconds) to wait for X to be ready to accept connections. If X is
-# not ready before this timeout, it is killed and restarted.
-NODM_X_TIMEOUT=300
-EOF
+mkdir -p ${ROOTFS_DIR}/etc/default
+install -m 644 files/nodm ${ROOTFS_DIR}/etc/default/nodm
# Probably not needed
on_chroot << EOF
diff --git a/stage3/00-install-packages/files/nodm b/stage3/00-install-packages/files/nodm
new file mode 100644
index 0000000..b254e2b
--- /dev/null
+++ b/stage3/00-install-packages/files/nodm
@@ -0,0 +1,33 @@
+# nodm configuration
+
+# Set NODM_ENABLED to something different than 'false' to enable nodm
+NODM_ENABLED=true
+
+# User to autologin for
+NODM_USER=kiosk
+
+# First vt to try when looking for free VTs
+NODM_FIRST_VT=7
+
+# X session
+NODM_XSESSION=/home/kiosk/.xprofile
+
+# Options for nodm itself
+NODM_OPTIONS=
+
+# Options for the X server.
+#
+# Format: [/usr/bin/] [:]
+#
+# The Xserver executable and the display name can be omitted, but should
+# be placed in front, if nodm's defaults shall be overridden.
+NODM_X_OPTIONS='-nolisten tcp'
+
+# If an X session will run for less than this time in seconds, nodm will wait an
+# increasing bit of time before restarting the session.
+NODM_MIN_SESSION_TIME=60
+
+# Timeout (in seconds) to wait for X to be ready to accept connections. If X is
+# not ready before this timeout, it is killed and restarted.
+NODM_X_TIMEOUT=300
+