mirror of
				https://github.com/billz/raspap-webgui.git
				synced 2025-03-01 10:31:47 +00:00 
			
		
		
		
	Merge pull request #1319 from RaspAP/feat/minwrite
Adds minimal SD card write support to installer
This commit is contained in:
		
							
								
								
									
										179
									
								
								installers/minwrite.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										179
									
								
								installers/minwrite.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,179 @@ | ||||
| #!/bin/bash | ||||
| # | ||||
| # RaspAP minimal microSD card write operation | ||||
| # Original author: @zbchristian | ||||
| # Original source URI: https://github.com/RaspAP/raspap-tools | ||||
| # Modified by: @billz <billzimmerman@gmail.com> | ||||
| # License: GNU General Public License v3.0 | ||||
| # License URI: https://github.com/raspap/raspap-webgui/blob/master/LICENSE | ||||
| # | ||||
| # 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". | ||||
| # 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}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 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 | ||||
|         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 2 "Service bootlogd.service does not exist" | ||||
|             sudo systemctl disable bootlogs || _install_status 2 "Service bootlogs 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 | ||||
|         echo "(Skipped)" | ||||
|     fi | ||||
| } | ||||
|  | ||||
| function _install_logger() { | ||||
|     _install_log "Installing new logger" | ||||
|     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() { | ||||
|     _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 | ||||
|             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" | ||||
|                 _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}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 | ||||
|         if [ "$answer" != "${answer#[Nn]}" ]; then | ||||
|             echo "Installation reboot aborted." | ||||
|             exit 0 | ||||
|         fi | ||||
|         echo "Rebooting..." | ||||
|         sudo reboot || _install_status 1 "Unable to execute reboot" | ||||
|     fi | ||||
| } | ||||
|  | ||||
| @@ -20,10 +20,12 @@ | ||||
| # -t, --token <accesstoken>         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 <accesstoken>           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" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user