From 41d21477fd3001c66598e684c29baffdc29ee902 Mon Sep 17 00:00:00 2001 From: billz Date: Sat, 25 Mar 2023 17:49:52 +0100 Subject: [PATCH 1/6] Add -m --minwrite option and loader support --- installers/raspbian.sh | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/installers/raspbian.sh b/installers/raspbian.sh index 7df63832..d5efe387 100755 --- a/installers/raspbian.sh +++ b/installers/raspbian.sh @@ -20,10 +20,12 @@ # -t, --token Specify a GitHub token to access a private repository # -u, --upgrade Upgrades an existing installation to the latest release version # -i, --insiders Installs from the Insiders Edition (RaspAP/raspap-insiders) +# -m, --minwrite Configures a microSD card for minimum write operation # -v, --version Outputs release info and exits -# -n, --uninstall Loads and executes the uninstaller +# -n, --uninstall Loads and executes the uninstaller # -h, --help Outputs usage notes and exits # +# NOTE # Depending on options passed to the installer, ONE of the following # additional shell scripts will be downloaded and sourced: # @@ -31,6 +33,8 @@ # - or - # https://raw.githubusercontent.com/raspap/raspap-webgui/master/installers/mkcert.sh # - or - +# https://raw.githubusercontent.com/raspap/raspap-webgui/master/installers/minwrite.sh +# - or - # https://raw.githubusercontent.com/raspap/raspap-webgui/master/installers/uninstall.sh # # You are not obligated to bundle the LICENSE file with your RaspAP projects as long @@ -55,6 +59,7 @@ function _parse_params() { ovpn_option=1 adblock_option=1 insiders=0 + minwrite=0 acctoken="" while :; do @@ -92,6 +97,9 @@ function _parse_params() { -i|--insiders) insiders=1 ;; + -m|--minwrite) + minwrite=1 + ;; -t|--token) acctoken="$2" shift @@ -146,6 +154,7 @@ OPTIONS: -t, --token Specify a GitHub token to access a private repository -u, --upgrade Upgrades an existing installation to the latest release version -i, --insiders Installs from the Insiders Edition (RaspAP/raspap-insiders) +-m, --minwrite Configures a microSD card for minimum write operation -v, --version Outputs release info and exits -n, --uninstall Loads and executes the uninstaller -h, --help Outputs usage notes and exits @@ -203,7 +212,7 @@ function _get_release() { # Outputs a RaspAP Install log line function _install_log() { - echo -e "${ANSI_GREEN}RaspAP Install: $1${ANSI_RESET}" + echo -e "${ANSI_GREEN}RaspAP ${component}: $1${ANSI_RESET}" } # Outputs a RaspAP divider @@ -255,16 +264,25 @@ function _load_installer() { if [ "${install_cert:-}" = 1 ]; then source="mkcert" + component="mkcert" wget "${header[@]}" -q ${UPDATE_URL}installers/${source}.sh -O /tmp/raspap_${source}.sh source /tmp/raspap_${source}.sh && rm -f /tmp/raspap_${source}.sh _install_certificate || _install_status 1 "Unable to install certificate" + elif [ "${minwrite}" = 1 ]; then + source="minwrite" + component="Minwrite" + wget "${header[@]}" -q ${UPDATE_URL}installers/${source}.sh -O /tmp/raspap_${source}.sh + source /tmp/raspap_${source}.sh && rm -f /tmp/raspap_${source}.sh + _install_minwrite || _install_status 1 "Unable to execute minimal write install" elif [ "${uninstall}" = 1 ]; then source="uninstall" + component"Uninstall" wget "${header[@]}" -q ${UPDATE_URL}installers/${source}.sh -O /tmp/raspap_${source}.sh source /tmp/raspap_${source}.sh && rm -f /tmp/raspap_${source}.sh _remove_raspap || _install_status 1 "Unable to uninstall RaspAP" else source="common" + component="Install" wget "${header[@]}" -q ${UPDATE_URL}installers/${source}.sh -O /tmp/raspap_${source}.sh source /tmp/raspap_${source}.sh && rm -f /tmp/raspap_${source}.sh _install_raspap || _install_status 1 "Unable to install RaspAP" From 040160564fdecfc4c87220a62d6e9d1dc6c7c4cb Mon Sep 17 00:00:00 2001 From: billz Date: Sat, 25 Mar 2023 17:51:00 +0100 Subject: [PATCH 2/6] Create _install_minwrite() + functions --- installers/minwrite.sh | 169 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100755 installers/minwrite.sh diff --git a/installers/minwrite.sh b/installers/minwrite.sh new file mode 100755 index 00000000..590cde60 --- /dev/null +++ b/installers/minwrite.sh @@ -0,0 +1,169 @@ +#!/bin/bash +# +# RaspAP minimal microSD card write opartion +# Original author: @zbchristian +# Original source URI: https://github.com/RaspAP/raspap-tools +# Modified by: @billz +# License: GNU General Public License v3.0 +# License URI: https://github.com/raspap/raspap-webgui/blob/master/LICENSE +# +# Limits the microSD card write operation to a minimum by moving temporary and log files to RAM. +# Write access can be checked with "iotop -aoP". +# Remaining access originates mainly from the ext4 journal update (process jbd2). + +# Exit on error +set -o errexit +# Exit on error inside functions +set -o errtrace + +# Set defaults +readonly bootcmd="/boot/cmdline.txt" + +function _install_minwrite() { + _display_welcome + _begin_install + _remove_packages + _disable_services + _install_logger + _disable_swap + _move_directories + _install_complete +} + +function _dirs2tmpfs() { + for dir in "${dirs[@]}"; do + echo "Moving $dir to RAM" + if ! grep -q " $dir " /etc/fstab; then + echo "tmpfs $dir tmpfs nosuid,nodev 0 0" | sudo tee -a /etc/fstab + fi + done +} + +# Determines host Linux distribution details +function _get_linux_distro() { + if type lsb_release >/dev/null 2>&1; then # linuxbase.org + OS=$(lsb_release -si) + RELEASE=$(lsb_release -sr) + CODENAME=$(lsb_release -sc) + DESC=$(lsb_release -sd) + elif [ -f /etc/os-release ]; then # freedesktop.org + . /etc/os-release + OS=$ID + RELEASE=$VERSION_ID + CODENAME=$VERSION_CODENAME + DESC=$PRETTY_NAME + else + _install_status 1 "Unsupported Linux distribution" + fi +} + +function _begin_install() { + _install_log "Modify the OS to minimize microSD card write operation" + _get_linux_distro + echo "Detected OS: ${DESC}" +} + +function _remove_packages() { + _install_log "Removing packages" + echo -e "The following packages will be removed: ${ANSI_YELLOW}triggerhappy dphys-swapfile logrotate${ANSI_RESET}" + echo -n "Proceed? [Y/n]: " + if [ "$assume_yes" == 0 ]; then + read answer < /dev/tty + if [ "$answer" != "${answer#[Nn]}" ]; then + _install_status 0 "(Skipped)" + else + sudo apt -y remove --purge triggerhappy dphys-swapfile logrotate || _install_status 1 "Unable to remove packages" + sudo apt -y autoremove --purge || _install_status 1 "Unable to autoremove packages" + _install_status 0 + fi + else + echo "(Skipped)" + fi +} + +function _disable_services() { + _install_log "Disabling services" + echo -e "The following services will be disabled: ${ANSI_YELLOW}bootlogd.service bootlogs console-setup apt-daily${ANSI_RESET}" + echo -n "Proceed? [Y/n]: " + if [ "$assume_yes" == 0 ]; then + read answer < /dev/tty + if [ "$answer" != "${answer#[Nn]}" ]; then + _install_status 0 "(Skipped)" + else + sudo systemctl unmask bootlogd.service || _install_status 1 "Unable to disable bootlogd.service" + sudo systemctl disable bootlogs || _install_status 1 "Unable to disable bootlogs" + sudo systemctl disable console-setup || _install_status 1 "Unable to disable console-setup" + sudo systemctl disable apt-daily.service apt-daily.timer apt-daily-upgrade.timer apt-daily-upgrade.service || _install_status 1 "Unable to disable apt-daily" + _install_status 0 + fi + else + echo "(Skipped)" + fi +} + +function _install_logger() { + _install_log "Installing new logger" + echo -e "The new logger will be installed: ${ANSI_YELLOW}busybox-syslogd${ANSI_RESET}" + sudo apt-get -y install busybox-syslogd || _install_status 1 "Unable to install busybox-syslogd" + sudo dpkg --purge rsyslog || _install_status 1 "Unable to purge rsyslog" + _install_status 0 +} + +function _disable_swap() { + _install_log "Modifying boot options to disable swap and filesystem check" + echo "The noswap option will be written to ${bootcmd}" + echo -n "Proceed? [Y/n]: " + if [ "$assume_yes" == 0 ]; then + read answer < /dev/tty + if [ "$answer" != "${answer#[Nn]}" ]; then + _install_status 0 "(Skipped)" + else + # disable swap + if ! grep -q "noswap" $bootcmd; then + echo "Modified ${bootcmd} with noswap option" + sudo sed -i '1 s/$/ fsck.mode=skip noswap/' /boot/cmdline.txt || _install_status 1 "Unable to write to ${bootcmd}" + _install_status 0 + fi + fi + else + echo "(Skipped)" + fi +} + +function _move_directories() { + _install_log "Add tmpfs entries to /etc/fstab" + # move directories to RAM + dirs=( "/tmp" "/var/log" "/var/tmp" "/var/lib/misc" "/var/cache") + # special dirs used by vnstat and php + dirs+=( "/var/lib/vnstat" "/var/php/sessions" ) + echo "The following directories will be moved to RAM:" + echo -e "${ANSI_YELLOW}${dirs[*]}${ANSI_RESET}" + echo -n "Proceed? [Y/n]: " + if [ "$assume_yes" == 0 ]; then + read answer < /dev/tty + if [ "$answer" != "${answer#[Nn]}" ]; then + _install_status 0 "(Skipped)" + else + _dirs2tmpfs || _install_status 1 "Unable to call dirs2tmpfs" + _install_status 0 + fi + else + echo "(Skipped)" + fi +} + +function _install_complete() { + _install_log "Installation completed" + echo -e "${ANSI_RED}A system reboot should be performed now${ANSI_RESET}" + echo -n "Reboot now? [Y/n]: " + if [ "$assume_yes" == 0 ]; then + read answer < /dev/tty + if [ "$answer" != "${answer#[Nn]}" ]; then + echo "Installation reboot aborted." + exit 0 + fi + echo "Rebooting..." + sudo shutdown -r now || _install_status 1 "Unable to execute shutdown" + fi +} + From 33d99a01488a39d1b69efe54de97bcb9f5e6853d Mon Sep 17 00:00:00 2001 From: billz Date: Sat, 25 Mar 2023 18:09:41 +0100 Subject: [PATCH 3/6] Minor: comments --- installers/minwrite.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/installers/minwrite.sh b/installers/minwrite.sh index 590cde60..fbadbee7 100755 --- a/installers/minwrite.sh +++ b/installers/minwrite.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# RaspAP minimal microSD card write opartion +# RaspAP minimal microSD card write operation # Original author: @zbchristian # Original source URI: https://github.com/RaspAP/raspap-tools # Modified by: @billz @@ -8,6 +8,8 @@ # License URI: https://github.com/raspap/raspap-webgui/blob/master/LICENSE # # Limits the microSD card write operation to a minimum by moving temporary and log files to RAM. +# Several packages are removed and the default logging service is replaced. +# The file system is still in read/write mode, so RaspAP settings can be saved. # Write access can be checked with "iotop -aoP". # Remaining access originates mainly from the ext4 journal update (process jbd2). From 0ba78338040a268b58d12fb75ccc57a67c33b9da Mon Sep 17 00:00:00 2001 From: billz Date: Sun, 26 Mar 2023 10:08:01 +0200 Subject: [PATCH 4/6] Add proceed check to _install_logger() --- installers/minwrite.sh | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/installers/minwrite.sh b/installers/minwrite.sh index fbadbee7..ae1ef73e 100755 --- a/installers/minwrite.sh +++ b/installers/minwrite.sh @@ -7,7 +7,7 @@ # License: GNU General Public License v3.0 # License URI: https://github.com/raspap/raspap-webgui/blob/master/LICENSE # -# Limits the microSD card write operation to a minimum by moving temporary and log files to RAM. +# Limits microSD card write operation to a minimum by moving temporary and log files to RAM. # Several packages are removed and the default logging service is replaced. # The file system is still in read/write mode, so RaspAP settings can be saved. # Write access can be checked with "iotop -aoP". @@ -105,10 +105,20 @@ function _disable_services() { function _install_logger() { _install_log "Installing new logger" - echo -e "The new logger will be installed: ${ANSI_YELLOW}busybox-syslogd${ANSI_RESET}" - sudo apt-get -y install busybox-syslogd || _install_status 1 "Unable to install busybox-syslogd" - sudo dpkg --purge rsyslog || _install_status 1 "Unable to purge rsyslog" - _install_status 0 + echo -e "The following new logger will be installed: ${ANSI_YELLOW}busybox-syslogd${ANSI_RESET}" + echo -n "Proceed? [Y/n]: " + if [ "$assume_yes" == 0 ]; then + read answer < /dev/tty + if [ "$answer" != "${answer#[Nn]}" ]; then + _install_status 0 "(Skipped)" + else + sudo apt-get -y install busybox-syslogd || _install_status 1 "Unable to install busybox-syslogd" + sudo dpkg --purge rsyslog || _install_status 1 "Unable to purge rsyslog" + _install_status 0 + fi + else + echo "(Skipped)" + fi } function _disable_swap() { @@ -120,10 +130,9 @@ function _disable_swap() { if [ "$answer" != "${answer#[Nn]}" ]; then _install_status 0 "(Skipped)" else - # disable swap if ! grep -q "noswap" $bootcmd; then + sudo sed -i '1 s/$/ fsck.mode=skip noswap/' $bootcmd || _install_status 1 "Unable to write to ${bootcmd}" echo "Modified ${bootcmd} with noswap option" - sudo sed -i '1 s/$/ fsck.mode=skip noswap/' /boot/cmdline.txt || _install_status 1 "Unable to write to ${bootcmd}" _install_status 0 fi fi From b64faff248e1cd8914fc1ac04c82779b4d94d699 Mon Sep 17 00:00:00 2001 From: billz Date: Sun, 26 Mar 2023 12:01:38 +0200 Subject: [PATCH 5/6] Update w/ apt-get, install_status 2 (warning) on service disable --- installers/minwrite.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/installers/minwrite.sh b/installers/minwrite.sh index ae1ef73e..44b1ed74 100755 --- a/installers/minwrite.sh +++ b/installers/minwrite.sh @@ -74,8 +74,8 @@ function _remove_packages() { if [ "$answer" != "${answer#[Nn]}" ]; then _install_status 0 "(Skipped)" else - sudo apt -y remove --purge triggerhappy dphys-swapfile logrotate || _install_status 1 "Unable to remove packages" - sudo apt -y autoremove --purge || _install_status 1 "Unable to autoremove packages" + sudo apt-get -y remove --purge triggerhappy dphys-swapfile logrotate || _install_status 1 "Unable to remove packages" + sudo apt-get -y autoremove --purge || _install_status 1 "Unable to autoremove packages" _install_status 0 fi else @@ -92,10 +92,10 @@ function _disable_services() { if [ "$answer" != "${answer#[Nn]}" ]; then _install_status 0 "(Skipped)" else - sudo systemctl unmask bootlogd.service || _install_status 1 "Unable to disable bootlogd.service" - sudo systemctl disable bootlogs || _install_status 1 "Unable to disable bootlogs" - sudo systemctl disable console-setup || _install_status 1 "Unable to disable console-setup" - sudo systemctl disable apt-daily.service apt-daily.timer apt-daily-upgrade.timer apt-daily-upgrade.service || _install_status 1 "Unable to disable apt-daily" + sudo systemctl unmask bootlogd.service || _install_status 2 "Service bootlogd.service does not exist" + sudo systemctl disable bootlogs || _install_status 2 "Service bootlogs does not exist" + sudo systemctl disable console-setup || _install_status 2 "Service console-setup does not exist" + sudo systemctl disable apt-daily.service apt-daily.timer apt-daily-upgrade.timer apt-daily-upgrade.service || _install_status 2 "Service apt-daily does not exist" _install_status 0 fi else @@ -165,7 +165,7 @@ function _move_directories() { function _install_complete() { _install_log "Installation completed" - echo -e "${ANSI_RED}A system reboot should be performed now${ANSI_RESET}" + echo -e "${ANSI_RED}The system needs to be rebooted as a final step.${ANSI_RESET}" echo -n "Reboot now? [Y/n]: " if [ "$assume_yes" == 0 ]; then read answer < /dev/tty From 454e5d7ea8c5899bb24f02845df2ec6892528931 Mon Sep 17 00:00:00 2001 From: billz Date: Tue, 28 Mar 2023 18:43:36 +0200 Subject: [PATCH 6/6] Update remove_packages + disable_services --- installers/minwrite.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/installers/minwrite.sh b/installers/minwrite.sh index 44b1ed74..b4b2df21 100755 --- a/installers/minwrite.sh +++ b/installers/minwrite.sh @@ -67,14 +67,14 @@ function _begin_install() { function _remove_packages() { _install_log "Removing packages" - echo -e "The following packages will be removed: ${ANSI_YELLOW}triggerhappy dphys-swapfile logrotate${ANSI_RESET}" + echo -e "The following packages will be removed: ${ANSI_YELLOW}dphys-swapfile logrotate${ANSI_RESET}" echo -n "Proceed? [Y/n]: " if [ "$assume_yes" == 0 ]; then read answer < /dev/tty if [ "$answer" != "${answer#[Nn]}" ]; then _install_status 0 "(Skipped)" else - sudo apt-get -y remove --purge triggerhappy dphys-swapfile logrotate || _install_status 1 "Unable to remove packages" + sudo apt-get -y remove --purge dphys-swapfile logrotate || _install_status 1 "Unable to remove packages" sudo apt-get -y autoremove --purge || _install_status 1 "Unable to autoremove packages" _install_status 0 fi @@ -94,7 +94,6 @@ function _disable_services() { else sudo systemctl unmask bootlogd.service || _install_status 2 "Service bootlogd.service does not exist" sudo systemctl disable bootlogs || _install_status 2 "Service bootlogs does not exist" - sudo systemctl disable console-setup || _install_status 2 "Service console-setup does not exist" sudo systemctl disable apt-daily.service apt-daily.timer apt-daily-upgrade.timer apt-daily-upgrade.service || _install_status 2 "Service apt-daily does not exist" _install_status 0 fi @@ -174,7 +173,7 @@ function _install_complete() { exit 0 fi echo "Rebooting..." - sudo shutdown -r now || _install_status 1 "Unable to execute shutdown" + sudo reboot || _install_status 1 "Unable to execute reboot" fi }