Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env bash
- # Adapted from Adafruit read-only script:
- # https://learn.adafruit.com/read-only-raspberry-pi/
- #
- # Make DreamPi run read-only
- #
- # Tested with DreamPi 1.7
- #
- if [ $(id -u) -ne 0 ]; then
- echo "Installer must be run as root."
- echo "Try 'sudo bash $0'"
- exit 1
- fi
- clear
- echo "This script configures a Raspberry Pi"
- echo "SD card to boot into read-only mode,"
- echo "obviating need for clean shutdown."
- echo "NO FILES ON THE CARD CAN BE CHANGED"
- echo "WHEN PI IS BOOTED IN THIS STATE. Either"
- echo "the filesystems must be remounted in"
- echo "read/write mode, card must be mounted"
- echo "R/W on another system, or an optional"
- echo "jumper can be used to enable read/write"
- echo "on boot."
- echo
- echo "Links to original tutorials are in"
- echo "script source. This script doesn't offer"
- echo "an uninstall option. ALL other system"
- echo "config should be complete before using"
- echo "this script. (Setup wifi, enable SSH, etc)."
- echo
- echo "Run time ~3.5 minutes. Reboot required."
- echo
- echo -n "CONTINUE? [y/N] "
- read
- if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
- echo "Canceled."
- exit 0
- fi
- # FEATURE PROMPTS ----------------------------------------------------------
- # Installation doesn't begin until after all user input is taken.
- INSTALL_RW_JUMPER=0
- INSTALL_HALT=0
- SYS_TYPES=(Pi\ 3\ /\ Pi\ Zero\ W All\ other\ models)
- OPTION_NAMES=(NO YES)
- # Display pinout
- echo -e "\
- \033[1;36m 3V3\033[0m (1)\033[0m (2) \033[0m \033[1;31m5V \033[0m\n\
- \033[1;32m GPIO2\033[0m (3)\033[0m (4) \033[0m \033[1;31m5V \033[0m\n\
- \033[1;32m GPIO3\033[0m (5)\033[0m (6) \033[0m \033[1;30mGND \033[0m\n\
- \033[1;32m GPIO4\033[0m (7)\033[0m (8) \033[0m \033[1;32mGPIO14\033[0m\n\
- \033[1;30m GND\033[0m (9)\033[0m (10)\033[0m \033[1;32mGPIO15\033[0m\n\
- \033[1;32mGPIO17\033[0m (11)\033[0m (12)\033[0m \033[1;32mGPIO18\033[0m\n\
- \033[1;32mGPIO27\033[0m (13)\033[0m (14)\033[0m \033[1;30mGND \033[0m\n\
- \033[1;32mGPIO22\033[0m (15)\033[0m (16)\033[0m \033[1;32mGPIO23\033[0m\n\
- \033[1;36m 3V3\033[0m (17)\033[0m (18)\033[0m \033[1;32mGPIO24\033[0m\n\
- \033[1;32mGPIO10\033[0m (19)\033[0m (20)\033[0m \033[1;30mGND \033[0m\n\
- \033[1;32m GPIO9\033[0m (21)\033[0m (22)\033[0m \033[1;32mGPIO25\033[0m\n\
- \033[1;32mGPIO11\033[0m (23)\033[0m (24)\033[0m \033[1;32mGPIO8 \033[0m\n\
- \033[1;30m GND\033[0m (25)\033[0m (26)\033[0m \033[1;32mGPIO7 \033[0m\n\
- \033[1;32m GPIO0\033[0m (27)\033[0m (28)\033[0m \033[1;32mGPIO1 \033[0m\n\
- \033[1;32m GPIO5\033[0m (29)\033[0m (30)\033[0m \033[1;30mGND \033[0m\n\
- \033[1;32m GPIO6\033[0m (31)\033[0m (32)\033[0m \033[1;32mGPIO12\033[0m\n\
- \033[1;32mGPIO13\033[0m (33)\033[0m (34)\033[0m \033[1;30mGND \033[0m\n\
- \033[1;32mGPIO19\033[0m (35)\033[0m (36)\033[0m \033[1;32mGPIO16\033[0m\n\
- \033[1;32mGPIO26\033[0m (37)\033[0m (38)\033[0m \033[1;32mGPIO20\033[0m\n\
- \033[1;30m GND\033[0m (39)\033[0m (40)\033[0m \033[1;32mGPIO21\033[0m\n"
- echo -n "Enable boot-time read/write jumper? [y/N] "
- read
- if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then
- INSTALL_RW_JUMPER=1
- echo -n "GPIO pin for R/W jumper [Suggested: 21]: "
- read
- RW_PIN=$REPLY
- fi
- echo -n "Install GPIO-halt utility? [y/N] "
- read
- if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then
- INSTALL_HALT=1
- echo -n "GPIO pin for halt button [Suggested: 16]: "
- read
- HALT_PIN=$REPLY
- fi
- # VERIFY SELECTIONS BEFORE CONTINUING --------------------------------------
- echo
- if [ $INSTALL_RW_JUMPER -eq 1 ]; then
- echo "Boot-time R/W jumper: YES (GPIO$RW_PIN)"
- else
- echo "Boot-time R/W jumper: NO"
- fi
- if [ $INSTALL_HALT -eq 1 ]; then
- echo "Install GPIO-halt: YES (GPIO$HALT_PIN)"
- else
- echo "Install GPIO-halt: NO"
- fi
- echo
- echo -n "CONTINUE? [y/N] "
- read
- if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
- echo "Canceled."
- exit 0
- fi
- # START INSTALL ------------------------------------------------------------
- # All selections have been validated at this point...
- # Given a filename, a regex pattern to match and a replacement string:
- # Replace string if found, else no change.
- # (# $1 = filename, $2 = pattern to match, $3 = replacement)
- replace() {
- grep $2 $1 >/dev/null
- if [ $? -eq 0 ]; then
- # Pattern found; replace in file
- sed -i "s/$2/$3/g" $1 >/dev/null
- fi
- }
- # Given a filename, a regex pattern to match and a string:
- # If found, no change, else append file with string on new line.
- append1() {
- grep $2 $1 >/dev/null
- if [ $? -ne 0 ]; then
- # Not found; append on new line (silently)
- echo $3 | sudo tee -a $1 >/dev/null
- fi
- }
- # Given a filename, a regex pattern to match and a string:
- # If found, no change, else append space + string to last line --
- # this is used for the single-line /boot/cmdline.txt file.
- append2() {
- grep $2 $1 >/dev/null
- if [ $? -ne 0 ]; then
- # Not found; insert in file before EOF
- sed -i "s/\'/ $3/g" $1 >/dev/null
- fi
- }
- echo
- echo "Starting installation..."
- echo "Updating package index files..."
- apt-get update
- echo "Removing packages no longer required..."
- apt-get -y autoremove --purge
- echo "Configuring system..."
- # START readonlyboot
- # Create rc.local replacement, /home/pi/dreampi/readonlyboot
- echo "#!/bin/bash" > /home/pi/dreampi/readonlyboot
- echo "" >> /home/pi/dreampi/readonlyboot
- echo "exit 0" >> /home/pi/dreampi/readonlyboot
- chown pi:pi /home/pi/dreampi/readonlyboot
- chmod 755 /home/pi/dreampi/readonlyboot
- # Install boot-time R/W jumper test if requested
- GPIOTEST="echo 'Checking GPIO $RW_PIN'\n\
- gpio -g mode $RW_PIN up\n\
- if [ \`gpio -g read $RW_PIN\` -eq 0 ] ; then\n\
- \techo 'GPIO $RW_PIN grounded. Remounting system RW.'\n\
- \tmount -o remount,rw \/\n\
- \tmount -o remount,rw \/boot\n\
- \tumount \/var\/log\n\
- \tumount \/var\/tmp\n\
- \tumount \/tmp\n\
- \tumount \/etc\/ppp\n\
- else\n\
- \techo 'GPIO $RW_PIN open. Leaving system RO.'\n\
- fi\n"
- if [ $INSTALL_RW_JUMPER -ne 0 ]; then
- apt-get install -y wiringpi
- # Insert before final 'exit 0'
- echo "Setting up boot-time R/W jumper..."
- sed -i "s/^exit\ 0/$GPIOTEST\\nexit\ 0/g" /home/pi/dreampi/readonlyboot >/dev/null
- fi
- # Install gpio-halt if requested
- if [ $INSTALL_HALT -ne 0 ]; then
- if [ $INSTALL_RW_JUMPER -eq 0 ]; then
- apt-get install -y wiringpi
- fi
- echo "Installing gpio-halt in /usr/local/bin..."
- cd /tmp
- curl -LO https://github.com/adafruit/Adafruit-GPIO-Halt/archive/master.zip
- unzip master.zip
- cd Adafruit-GPIO-Halt-master
- make
- mv gpio-halt /usr/local/bin/
- cd ..
- rm -rf Adafruit-GPIO-Halt-master
- rm -rf /tmp/master.zip
- # Add and enable gpio-halt.service to systemd/system/dreampi
- echo "Adding gpio-halt.service to systemd..."
- echo -ne "[Unit]\n\
- Description=Short GPIO $HALT_PIN to ground to shutdown the Pi\n\
- After=multi-user.target\n\
- \n\
- [Service]\n\
- Type=idle\n\
- ExecStart=/usr/local/bin/gpio-halt $HALT_PIN &\n\
- \n\
- [Install]\n\
- WantedBy=multi-user.target" > /etc/systemd/system/gpio-halt.service
- systemctl enable gpio-halt.service
- fi
- # Add tmpfs /etc/ppp population
- mkdir /etc/ppp_ro
- cp -R /etc/ppp/* /etc/ppp_ro/
- ETCPPP="if [ ! -f \/etc\/ppp\/options ]; then \n\
- \techo 'Populating tmpfs \/etc\/ppp'\n\
- \tcp -R \/etc\/ppp_ro\/\* \/etc\/ppp\/ \n\
- fi\n"
- sed -i "s/^exit\ 0/$ETCPPP\\nexit\ 0/g" /home/pi/dreampi/readonlyboot >/dev/null
- # Create readonlyboot.service and enable
- echo -ne "[Unit]\n\
- Description=ReadOnly-Boot Service\n\
- After=network.target etc-ppp.mount var-log.mount var-tmp.mount tmp.mount\n\
- \n\
- [Service]\n\
- Type=simple\n\
- ExecStart=/usr/local/bin/readonlyboot\n\
- \n\
- [Install]\n\
- WantedBy=multi-user.target\n" > /home/pi/dreampi/etc/systemd/system/readonlyboot.service
- ln -s /home/pi/dreampi/readonlyboot /usr/local/bin/readonlyboot
- ln -s /home/pi/dreampi/etc/systemd/system/readonlyboot.service /etc/systemd/system/readonlyboot.service
- systemctl enable readonlyboot.service
- # END readonlyboot
- # Update dreampi.service to run after readonlyboot
- sed -i "s/^After=network.*$/After=network.target\ readonlyboot.service/g" /home/pi/dreampi/etc/systemd/system/dreampi.service >/dev/null
- # Add fastboot, noswap and/or ro to end of /boot/cmdline.txt
- append2 /boot/cmdline.txt fastboot fastboot
- append2 /boot/cmdline.txt noswap noswap
- append2 /boot/cmdline.txt ro^o^t ro
- # Move /var/spool to /tmp
- rm -rf /var/spool
- ln -s /tmp /var/spool
- # Change spool permissions in var.conf (rondie/Margaret fix)
- replace /usr/lib/tmpfiles.d/var.conf "spool\s*0755" "spool 1777"
- # Move dhcpd.resolv.conf to tmpfs
- touch /tmp/dhcpcd.resolv.conf
- rm /etc/resolv.conf
- ln -s /tmp/dhcpcd.resolv.conf /etc/resolv.conf
- # Make edits to fstab
- # make / and /boot ro
- # mount /var/log, /var/tmp, /tmp, /etc/ppp to RAM
- replace /etc/fstab "vfat\s*defaults\s" "vfat defaults,ro "
- replace /etc/fstab "ext4\s*defaults,noatime\s" "ext4 defaults,noatime,ro "
- append1 /etc/fstab "/var/log" "tmpfs /var/log tmpfs nodev,nosuid,noatime,size=100m 0 0"
- append1 /etc/fstab "/var/tmp" "tmpfs /var/tmp tmpfs nodev,nosuid,noatime,size=30m 0 0"
- append1 /etc/fstab "\s/tmp" "tmpfs /tmp tmpfs nodev,nosuid,noatime,size=100m 0 0"
- append1 /etc/fstab "/etc/ppp" "tmpfs /etc/ppp tmpfs nodev,nosuid,noatime,size=120k 0 0"
- # PROMPT FOR REBOOT --------------------------------------------------------
- echo "Done."
- echo
- echo "Settings take effect on next boot."
- echo
- echo -n "REBOOT NOW? [y/N] "
- read
- if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
- echo "Exiting without reboot."
- exit 0
- fi
- echo "Reboot started..."
- reboot
- exit 0
Add Comment
Please, Sign In to add comment