diff --git a/README-PiGen.md b/README-pigen.md similarity index 100% rename from README-PiGen.md rename to README-pigen.md diff --git a/README.md b/README.md index b1c00f9..1bc6980 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,16 @@ # Raspberry Pi OctoPrint Kiosk This repository contains the source for building an OctoPrint kiosk. +## Highlights +- Lightweight graphical frontend using Surf to display OctoPrint +- Easy to use TUI installer +- Built for security + +## Screenshots +TODO + ## Installation -Download the latest image from the Releases section and flash it onto a microSD card with at least 4GB of storage +[Download the latest image from the releases section](/releases) and flash it onto a microSD card with at least 4GB of storage. ## Requirements ### Minimum: diff --git a/TODO.md b/TODO.md index 9adeb9a..29703b1 100644 --- a/TODO.md +++ b/TODO.md @@ -3,10 +3,13 @@ ## First time/Octo-Config - Change OctoPrint listening address and port - Change frontend listening address and port -- Add plugin menu +- Add network configuration (replace nmtui) +- Add hostname configuration (replace nmtui) +- Consolidate shared functions into a single file ## Frontend - Autodetect OctoPrint port if hosted locally +- Add on screen keyboard to Openbox autostart ## Misc - 64 bit builds diff --git a/stage1/01-sys-tweaks/00-run.sh b/stage1/01-sys-tweaks/00-run.sh index 5331560..feca584 100755 --- a/stage1/01-sys-tweaks/00-run.sh +++ b/stage1/01-sys-tweaks/00-run.sh @@ -5,6 +5,7 @@ install -m 644 files/noclear.conf "${ROOTFS_DIR}/etc/systemd/system/getty@tty1.s install -v -m 644 files/fstab "${ROOTFS_DIR}/etc/fstab" install -m 755 files/.xprofile "${ROOTFS_DIR}/etc/skel/.xprofile" install -m 755 files/.browser.sh "${ROOTFS_DIR}/etc/skel/.browser.sh" +install -m 644 files/.dialogrc "${ROOTFS_DIR}/etc/skel/.dialogrc" mkdir -p "${ROOTFS_DIR}/etc/skel/.config/openbox" install -m 644 files/autostart "${ROOTFS_DIR}/etc/skel/.config/openbox/autostart" @@ -13,9 +14,9 @@ if ! id -u ${FIRST_USER_NAME} >/dev/null 2>&1; then adduser --disabled-password --gecos "" ${FIRST_USER_NAME} fi if ! id -u octoprint >/dev/null 2>&1; then - adduser --system --shell /usr/sbin/nologin --disabled-password --gecos "" octoprint + adduser --system --shell /usr/sbin/nologin --group --disabled-password --gecos "" octoprint fi echo "${FIRST_USER_NAME}:${FIRST_USER_PASS}" | chpasswd -echo "octoprint:$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c20)" | chpasswd -echo "root:$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c20)" | chpasswd +echo "octoprint:$(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/.dialogrc b/stage1/01-sys-tweaks/files/.dialogrc new file mode 100644 index 0000000..2e864fe --- /dev/null +++ b/stage1/01-sys-tweaks/files/.dialogrc @@ -0,0 +1 @@ +screen_color = (CYAN,BLACK,ON) diff --git a/stage2/01-sys-tweaks/00-packages b/stage2/01-sys-tweaks/00-packages index 0a000aa..c9d9a1b 100644 --- a/stage2/01-sys-tweaks/00-packages +++ b/stage2/01-sys-tweaks/00-packages @@ -51,3 +51,4 @@ rpi-eeprom raspinfo unattended-upgrades apt-listchanges +dialog diff --git a/stage2/04-octoprint/01-run.sh b/stage2/04-octoprint/01-run.sh index 7663e86..47df47a 100755 --- a/stage2/04-octoprint/01-run.sh +++ b/stage2/04-octoprint/01-run.sh @@ -4,15 +4,13 @@ install -m 644 files/octoprint.service ${ROOTFS_DIR}/etc/systemd/system/octoprin on_chroot << EOF if ! pip list | grep -F octoprint; then - if [ -d /home/octoprint ]; then - cd /home/octoprint || exit 1 - if [[ ! -d OctoPrint ]]; then mkdir OctoPrint; fi || exit 1 - cd OctoPrint || exit 1 - virtualenv venv || exit 1 - source venv/bin/activate || exit 1 - pip install pip --upgrade || exit 1 - pip install octoprint || exit 1 - pip install "https://github.com/BillyBlaze/OctoPrint-TouchUI/archive/master.zip" || exit 1 - fi + if [[ ! -d /srv/octoprint ]]; then mkdir -p /srv/octoprint; fi + cd /srv/octoprint || exit 1 + chown octoprint:octoprint /srv/octoprint || exit 1 + virtualenv venv || exit 1 + source venv/bin/activate || exit 1 + pip install pip --upgrade + pip install octoprint || exit 1 + chown -R octoprint:octoprint /srv/octoprint fi EOF diff --git a/stage2/04-octoprint/files/octoprint.service b/stage2/04-octoprint/files/octoprint.service index 2be41af..e60bf95 100644 --- a/stage2/04-octoprint/files/octoprint.service +++ b/stage2/04-octoprint/files/octoprint.service @@ -4,7 +4,8 @@ Description=OctoPrint Daemon [Service] Type=simple User=octoprint -ExecStart=/home/octoprint/OctoPrint/venv/bin/octoprint serve +Group=octoprint +ExecStart=/srv/octoprint/venv/bin/octoprint serve [Install] WantedBy=multi-user.target diff --git a/stage2/05-utils/files/first-time.sh b/stage2/05-utils/files/first-time.sh index ecc1955..0912e1f 100755 --- a/stage2/05-utils/files/first-time.sh +++ b/stage2/05-utils/files/first-time.sh @@ -7,18 +7,18 @@ if [ "$EUID" -ne 0 ]; then fi change_password () { - local PASSWORD="$(whiptail --title "Change Password" --nocancel --passwordbox "Enter new password for user \"pi\"" 10 50 3>&1 1>&2 2>&3)" + local PASSWORD="$(dialog --title "Change Password" --nocancel --insecure --passwordbox "Enter new password for user \"pi\"" 10 50 3>&1 1>&2 2>&3)" if [[ $? != 0 ]]; then change_password; return 0; fi if [[ "$PASSWORD" == "raspberry" ]]; then - whiptail --title "Change Password" --nocancel --msgbox "That password sucks. Please use a different one :)" 10 50 + dialog --title "Change Password" --nocancel --msgbox "That password sucks. Please use a different one :)" 10 50 change_password return 0 fi - if [[ "$(whiptail --nocancel --passwordbox "Confirm new password for user \"pi\"" 10 50 3>&1 1>&2 2>&3)" == "$PASSWORD" ]]; then + if [[ "$(dialog --nocancel --insecure --passwordbox "Confirm new password for user \"pi\"" 10 50 3>&1 1>&2 2>&3)" == "$PASSWORD" ]]; then if [[ $? != 0 ]]; then return 1; fi echo -e "pi:$PASSWORD" | chpasswd else - whiptail --title "Change Password" --nocancel --msgbox "Passwords did not match!" 10 50 + dialog --title "Change Password" --nocancel --msgbox "Passwords did not match!" 10 50 change_password return 0 fi @@ -32,7 +32,7 @@ change_password () { } service_select () { - local SERVICE_MENU=$(whiptail --separate-output --nocancel --title "Select services" --checklist "Enable/disable services" 0 0 0 \ + local SERVICE_MENU=$(dialog --nocancel --title "Select services" --checklist "Enable/disable services" 0 0 0 \ "1" "OctoPrint" ON \ "2" "GUI" ON \ "3" "SSH" OFF 3>&1 1>&2 2>&3) @@ -50,7 +50,7 @@ service_select () { } screen_timeout() { - local TIMEOUT=$(whiptail --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." 11 60 "0" 3>&1 1>&2 2>&3) + 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." 11 60 "off" 3>&1 1>&2 2>&3) cat > /home/pi/.xprofile << EOF xset s ${TIMEOUT} xset -dpms @@ -58,28 +58,71 @@ screen_timeout() { EOF } -<< 'EOF' -main_menu () { - local MAINMENU=$(whiptail --separate-output --nocancel --title "Pi Setup" --menu "" 10 50 0 \ - "1" "Setup Networking" \ - "2" "Configure services" \ - "3" "Configure screen timeout" \ - "4" "Exit" 3>&1 1>&2 2>&3) - - case $MAINMENU in - "1") nmtui; main_menu; return 0;; - "2") service_select; main_menu; return 0;; - "3") screen_timeout; main_menu; return 0;; - "4") return 0;; - esac +install_package () { + echo "==========Installing $1==========" >>/home/pi/install.log + cd /srv/octoprint/ || return 1 + source venv/bin/activate || return 1 + pip install $1 2>&1 >>/home/pi/install.log || return 1 } -EOF +error_install () { + dialog --title "ERROR" --msgbox "Error installing $1!" 10 50 +} + +recommended_menu () { + local RECOMMEND_MENU=$(dialog --nocancel --title "Plugin Manager | Recommended Plugins" --checklist "Check plugins that you wish to install" 0 0 0 \ + "OctoPrint-Dashboard" "Adds a nice dashboard to OctoPrint" ON \ + "ExcludeRegion" "Select regions of the bed where you don't want to print" ON \ + "NavbarTemp" "Shows the temperature of the Pi, extruder(s) and bed in the navigation bar" ON \ + "PrintTimeGenius" "Provides more accurate print time estimates" ON \ + "HeaterTimeout" "Turns off the hotend and bed after a set amount of time" ON \ + "Themeify" "Adds theming supports and a few themes to OctoPrint" ON 3>&1 1>&2 2>&3) + + RECOMMEND_MENU=($RECOMMEND_MENU) + + for ((i = 0; i < ${#RECOMMEND_MENU[@]}; i++)); do + echo $(( $i * 100 / ${#RECOMMEND_MENU[@]} )) | dialog --title "Plugin Manager" --gauge "Installing ${RECOMMEND_MENU[$i]}" 10 50 + case ${RECOMMEND_MENU[$i]} in + "OctoPrint-Dashboard") install_package "https://github.com/StefanCohen/OctoPrint-Dashboard/archive/master.zip" || error_install "OctoPrint-Dashboard"; install_package "https://github.com/OllisGit/OctoPrint-DisplayLayerProgress/releases/latest/download/master.zip" || error_install "OctoPrint-Dashboard";; + "ExcludeRegion") install_package "https://github.com/bradcfisher/OctoPrint-ExcludeRegionPlugin/archive/master.zip" || error_install "ExcludeRegion";; + "NavbarTemp") install_package "https://github.com/imrahil/OctoPrint-NavbarTemp/archive/master.zip" || error_install "NavbarTemp";; + "PrintTimeGenius") install_package "https://github.com/eyal0/OctoPrint-PrintTimeGenius/archive/master.zip" || error_install "PrintTimeGenius";; + "HeaterTimeout") install_package "https://github.com/google/OctoPrint-HeaterTimeout/archive/master.zip" || error_install "HeaterTimeout";; + "Themeify") install_package "https://github.com/birkbjo/OctoPrint-Themeify/archive/master.zip" || error_install "Themeify";; + esac + done +} + +suggested_menu () { + local SUGGEST_MENU=$(dialog --nocancel --title "Plugin Manager | Suggested Plugins" --checklist "Check plugins that you wish to install" 0 0 0 \ + "TouchUI" "Makes the UI easier to use on touchscreens" OFF \ + "Preheat" "Adds a preheat button to preheat the bed and extruder to the temperature set in the selected gcode file" OFF \ + "ConsolidatedTabs" "Allows you to combine several tabs into one larger tab with draggable and resizable panels" OFF \ + "DetailedProgress" "Sends commands to your printer to display current printing progress" OFF 3>&1 1>&2 2>&3) + + SUGGEST_MENU=($SUGGEST_MENU) + + for ((i = 0; i < ${#SUGGEST_MENU[@]}; i++)); do + echo $(( $i * 100 / ${#SUGGEST_MENU[@]} )) | dialog --title "Plugin Manager" --gauge "Installing ${SUGGEST_MENU[$i]}" 10 50 + case ${SUGGEST_MENU[$i]} in + "TouchUI") install_package "https://github.com/BillyBlaze/OctoPrint-TouchUI/archive/master.zip" || error_install "TouchUI";; + "Preheat") install_package "https://github.com/marian42/octoprint-preheat/archive/master.zip" || error_install "Preheat";; + "ConsolidatedTabs") install_package "https://github.com/jneilliii/OctoPrint-ConsolidatedTabs/archive/master.zip" || error_install "ConsolidatedTabs";; + "DetailedProgress") install_package "https://github.com/tpmullan/OctoPrint-DetailedProgress/archive/master.zip" || error_install "DetailedProgress";; + esac + done +} + +dialog --title "NOTICE" --nocancel --colors --msgbox "This collection of software is currently in alpha. It is lacking several critical features. \Zb\Z1DO NOT\Zn use this in a production environment. This image has been provided for testing purposes only." 10 50 change_password || return 1 -whiptail --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 +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 service_select || return 1 screen_timeout || return 1 +if dialog --title "Plugin Manager" --yesno "Do you wish to preinstall some suggested plugins?" 10 60; then + recommended_menu || return 1 + suggested_menu || return 1 +fi rm /etc/systemd/system/getty@tty1.service.d/override.conf rm /etc/profile.d/first-time.sh reboot diff --git a/stage2/05-utils/files/octo-config b/stage2/05-utils/files/octo-config index 11730dd..8c3d80d 100755 --- a/stage2/05-utils/files/octo-config +++ b/stage2/05-utils/files/octo-config @@ -7,26 +7,26 @@ fi change_password () { - local PASSWORD="$(whiptail --title "Change Password" --nocancel --passwordbox "Enter new password for user \"pi\"" 10 50 3>&1 1>&2 2>&3)" - if [[ $? -eq 0 ]] || [[ $PASSWORD == "" ]]; then return 1; fi + local PASSWORD="$(dialog --title "Change Password" --nocancel --insecure --passwordbox "Enter new password for user \"pi\"" 10 50 3>&1 1>&2 2>&3)" + if [[ $? -ne 0 ]] || [[ $PASSWORD == "" ]]; then return 1; fi if [[ "$PASSWORD" == "raspberry" ]]; then - whiptail --title "Change Password" --nocancel --msgbox "That password sucks. Please use a different one :)" 10 50 + dialog --title "Change Password" --nocancel --msgbox "That password sucks. Please use a different one :)" 10 50 change_password return 0 fi - if [[ "$(whiptail --nocancel --passwordbox "Confirm new password for user \"pi\"" 10 50 3>&1 1>&2 2>&3)" == "$PASSWORD" ]]; then + if [[ "$(dialog --nocancel --insecure --passwordbox "Confirm new password for user \"pi\"" 10 50 3>&1 1>&2 2>&3)" == "$PASSWORD" ]]; then if [[ $? != 0 ]]; then return 1; fi echo -e "pi:$PASSWORD" | chpasswd else - whiptail --title "Change Password" --nocancel --msgbox "Passwords did not match!" 10 50 + dialog --title "Change Password" --nocancel --msgbox "Passwords did not match!" 10 50 change_password return 0 fi - unset $PASSWORD + unset PASSWORD } service_select () { - local SERVICE_MENU=$(whiptail --separate-output --nocancel --title "Select services" --checklist "Enable/disable services" 0 0 0 \ + 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) \ "2" "GUI" $(if [[ $(systemctl get-default) == "graphical.target" ]]; then echo "ON"; else echo "OFF"; fi) \ "3" "SSH" $(if [[ -f /etc/systemd/system/multi-user.target.wants/ssh.service ]]; then echo "ON"; else echo "OFF"; fi) 3>&1 1>&2 2>&3) @@ -86,7 +86,7 @@ EOF } screen_timeout() { - local TIMEOUT=$(whiptail --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." 11 60 "0" 3>&1 1>&2 2>&3) + 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." 11 60 "0" 3>&1 1>&2 2>&3) cat > /home/pi/.xprofile << EOF xset s ${TIMEOUT} xset -dpms @@ -95,7 +95,7 @@ EOF } main_menu () { - local MAINMENU=$(whiptail --separate-output --nocancel --title "Pi Setup" --menu "" 10 50 0 \ + local MAINMENU=$(dialog --nocancel --title "Pi Setup" --menu "" 10 50 0 \ "1" "Configure Networking" \ "2" "Change password for pi" \ "3" "Configure services" \ @@ -112,6 +112,6 @@ main_menu () { } main_menu -if whiptail --title "Reboot Confirmation" --yesno "Some changes require a reboot to take effect.\nDo you want to reboot now?" 10 50; then +if dialog --title "Reboot Confirmation" --yesno "Some changes require a reboot to take effect.\nDo you want to reboot now?" 10 50; then reboot fi