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 +} +