#!/bin/bash # Collection of setup steps for a new raspberry pi # (e.g. boot from HD, disable swap file, ...) # Get script working directory # (when called from a different directory) WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )" #CONFIG_FILE="$WDIR/${toolName}.cfg" #CONFIG_FILE_DEFAULT="${CONFIG_FILE}.example" osName= distName= step_config() { if [ "$(which lsb_release)" == "" ] ; then echoerr " [W] Cannot detect OS. Assuming Ubuntu" osName="Ubuntu" else osName=$(lsb_release -is) distName=$(lsb_release -cs) fi if [ "$osName" == "" ] ; then echoerr " [W] Error dedecting OS. Assuming Ubuntu" osName="Ubuntu" fi echo " [I] Detected OS: $osName $distName" } SDDEV= SDBOOT= SDBOOTPUUID= SDROOT= SDROOTDEV= SDROOTPUUID= HDDEV= HDROOT= HDROOTPUUID= HDSWAP= HDSWAPPUUID= step_1_info() { echo "Download latest Raspberry Pi OS lite image from" echoinfo "$downUrl"; } step_1_alias() { ALIAS="setup"; } step_1() { if [ ! -f "$downLoc" ] ; then exe wget "$downUrl" -O "$downLoc" echo -ne " [I] sha256 sum of download:\n " exe sha256sum "$downLoc" fi downImgName="${downDir}/$(zipinfo -1 "$downLoc")" if [ ! -f "$downImgName" ] ; then exe unzip "$downLoc" -d "$downDir" endReturn -o $? "Unzip raspios image failed" fi } downUrl="https://downloads.raspberrypi.org/raspios_lite_armhf_latest" downImgName="" downDay=$(date +%Y%m%d) downDir="/tmp" downLoc="${downDir}/raspios_$downDay.zip" step_2_info() { echo -n "Write Raspberry Pi OS image to SD card " if [ -z $2 ] ; then echo "[SD CARD DEVICE]"; else echo "$2"; fi echoinfo "This operation will delete all data previously on the SD card!" } step_2_alias() { ALIAS="writesd"; } step_2() { if [ "$downImgName" == "" ] ; then # called again to make sure $downImgName is populated step setup fi if [ ! -f "$downImgName" ] ; then endReturn -o 1 "No raspios image found" fi if [ $(id -u) -ne 0 ] ; then endReturn -o 1 "No root" fi read_sd_dev "$2" # check if device was confirmed if [ $? -ne 0 ] ; then endReturn -o 1 "SD card device not found" fi # write image exe dd bs=4M if="$downImgName" of="$SDDEV" conv=fsync endReturn -o "$?" "Writing image to $SDDEV failed" exe sync # SD partitions will have new informations now # Leave SD card device intact for next step SDBOOT="" SDROOT="" # TODO ? automatic remount echoerr " [W] Please remove SD now and plug it back in." exe read -p " Press enter to contiue." } step_3_info() { echo "Prepare SD for first run [SD CARD DEVICE]"; } step_3() { if [ -z $2 ] && [ ! -z $SDDEV ] ; then if [ $QUIET -ne 0 ] ; then answer="n" else exe lsblk -p "$SDDEV" echo exe read -p "Is $SDDEV still the SD card (y/[n])? " answer fi case $answer in [yY]) # Nothing todo ;; *) SDDEV="" ;; esac fi read_sd_dev "$2" endReturn -o $? "SD card device not found" if [ ! -w "$SDBOOT" ] ; then echoerr " [E] SD card boot partion not writeable" return 1 fi # enable systemd ssh service echo " [I] Enable SSH access" exe touch "$SDBOOT"/ssh # save SD boot settings for easy emergency start from SD echo " [I] Save SD card boot information for later use" exe cp -ar "$SDBOOT"/cmdline.txt "$SDBOOT"/cmdline.txt.sd exe cp -ar "$SDROOT"/etc/fstab "$SDROOT"/etc/fstab.sd } step_4_info() { local sd="[SD CARD DEVICE]" local hd="[HD DEVICE]" if [ ! -z $2 ] ; then sd="SD: \"$2\"" fi if [ ! -z $3 ] ; then hd="HD: \"$3\"" fi echo "Prepare $sd to boot from $hd" } step_4_alias() { ALIAS="hdboot"; } step_4() { read_sd_dev "$2" endReturn -o $? "SD detection error $?" read_hd_dev "$3" endReturn -o $? "HD detection error" echo " [I] SD: $SDDEV" echo " $SDBOOT [$SDBOOTPUUID]" echo " $SDROOT [$SDROOTPUUID]" echo " [I] HD: $HDDEV" echo " $HDROOT [$HDROOTPUUID]" echo " $HDSWAP [$HDSWAPPUUID]" echo # Point boot command line to SSD echo -n " [I] modify PARTUUID of $SDBOOT/cmdline.txt" if [ ! -z $HDROOTPUUID ] ; then exe sed -i -E "s/root=PARTUUID=[a-f0-9-]+/root=PARTUUID=${HDROOTPUUID}/" "$SDBOOT/cmdline.txt" if [ $? -eq 0 ] ; then echo " ... Ok" else echo -e "\n Failed! Replace PARTUUID manually" fi else echo " Replace \"root=PARTUUID=******00-01\" manually" fi # Disable initial resizing of the second partition echo -n " [I] remove \"init=/usr/lib/raspi-config/init_resize.sh\"" exe sed -i -E "s/[ ]*init=.*\/init_resize\.sh//" "$SDBOOT/cmdline.txt" if [ $? -eq 0 ] ; then echo " ... Ok" else echo -e "\n Failed! Remove init=... manually" fi # Save modifications for HD boot exe cp -ar "$SDBOOT"/cmdline.txt "$SDBOOT"/cmdline.txt.hd echo # Resize second partition of SD to max. possible size echo " [I] Resize root partion of SD: ${SDROOT} " step resizesd "$SDDEV" if [ $? -ne 0 ] ; then echoerr " [W] Something seems to have failed during resize" else # Disable init script to resize SD echo -n " [I] remove \"init=\" part from $SDBOOT/cmdline.txt.sd" exe sed -i -E "s/[ ]*init=.*\/init_resize\.sh//" "$SDBOOT/cmdline.txt.sd" if [ $? -eq 0 ] ; then echo " ... Ok" else echo -e "\n Failed! Remove init=... manually" fi fi } step_5_info() { local sd="[SD CARD DEVICE]" local hd="[HD DEVICE]" if [ ! -z $2 ] ; then sd="SD: \"$2\"" fi if [ ! -z $3 ] ; then hd="HD: \"$3\"" fi echo "Prepare HD for boot $sd $hd (TODO)" } step_5() { #TODO echoerr " [E] Not ready yet...TODO" #return 1 read_sd_dev "$2" endReturn -o $? "SD detection error $?" read_hd_dev "$3" endReturn -o $? "HD detection error" echo " [I] SD: $SDDEV" echo " $SDBOOT [$SDBOOTPUUID]" echo " $SDROOT [$SDROOTPUUID]" echo " [I] HD: $HDDEV" echo " $HDROOT [$HDROOTPUUID]" echo " $HDSWAP [$HDSWAPPUUID]" echo # TODO how to partition HD echo " [I] $HDDEV is expected to be partitioned with root and swap" echo " TODO create a step for partitioning script support?!" echo # Initial rsync of system to HD echo " [I] Clone SD root to HD root:" echo " rsync -avxHAX --numeric-ids --info=stats2 $SDROOT/ $HDROOT/" echo # Modify fstab on HD for root and swap on HD echo " [I] modify $HDROOT/etc/fstab" echo " PARTUUID=$SDBOOTPUUID /boot vfat ro,defaults 0 2" echo " PARTUUID=$SDROOTPUUID /backup ext4 ro,defaults,noatime 0 2" echo " PARTUUID=$HDROOTPUUID / ext4 defaults,noatime 0 1" echo " PARTUUID=$HDSWAPPUUID none swap sw 0 0" echo # etc echo " [I] modify $HDROOT/etc/dhcpcd.conf for static IPs" } step_20_info() { echo "Disable swap file and remove it"; } step_20_alias() { ALIAS="disableswap"; } step_20() { exe swapoff -a exe systemctl disable dphys-swapfile exe rm -rf "$rpiSwapFile" echoerr " [W] Reboot to apply changes" if [ $QUIET -eq 0 ] ; then exe read -p " Reboot now ([n]/y)? " answer case $answer in [yY]) echoerr " [I] Rebooting now ..." exe reboot ;; *) ;; esac fi } rpiSwapFile="/var/swap" step_22_info() { echo "Resize second SD card partition [SD CARD DEVICE]"; } step_22_alias() { ALIAS="resizesd"; } step_22() { shift read_sd_dev "$1" if [ -z $SDDEV ] || [ "$SDDEV" = "" ] || [ "$SDROOT" == "/" ] ; then echoerr " [E] No SD found" return 1 fi echo " [I] Device to be resized: $SDROOTDEV" exe umount -q "$SDROOT" exe parted -s "$SDDEV" "resizepart $SDROOTPARTNO -1" quit saveReturn $? exe e2fsck -f "$SDROOTDEV" saveReturn $? exe resize2fs "$SDROOTDEV" saveReturn $? if [ -z $SDROOT ] ; then read -p "Please provide a mountpoint: " SDROOT exe mkdir -p "$SDROOT" fi exe mount "$SDROOTDEV" "$SDROOT" saveReturn $? getReturn return $? } step_24_info() { echo "Turn off power LED [OPTION]" echoinfo " [OPTION]" echoinfo " -p : Turn off permanentely (/etc/rc.local)" } step_24_alias() { ALIAS="powerledoff"; } step_24() { exep "${ledOffCmd}" if [ ! -z $2 ] ; then exep "grep \"$ledPowerBright\" $startScript >>/dev/null" if [ $? -eq 0 ] ; then echo " [I] Power LED brightness already used. Please check $startScript manually for:" echo " $ledOffCmd" return 1 fi exe sed -i "s/^exit 0/# Turn off power LED/" "$startScript" exep "echo \"${ledOffCmd}\" >> $startScript" exep "echo -e \"\nexit 0\" >> $startScript" fi } startScript="/etc/rc.local" ledPowerBright="/sys/class/leds/led1/brightness" ledOffCmd="sudo sh -c 'echo 0 > ${ledPowerBright}'" step_26_info() { echo "Restart network without reboot"; } step_26_alias() { ALIAS="netrestart"; } step_26() { exep "sudo ip link set eth0 down && sudo ip link set eth0 up" } read_sd_dev() { local partExt="" if [ ! -z "$1" ] ; then SDBOOT= SDROOT= SDROOTDEV= SDROOTPUUID= SDBOOTPUUID= SDDEV="$1" elif [ -z $SDDEV ] || [ ! -b "$SDDEV" ] ; then SDDEV= SDBOOT= SDROOT= SDROOTDEV= SDBOOTPUUID= SDROOTPUUID= echo " [I] Available devices:" echo exe lsblk -p echo exe read -p "Provide SD card device (e.g. /dev/sdb): " SDDEV fi if [ ! -b "$SDDEV" ] ; then echoerr " [I] $SDDEV not a block device" SDDEV= return 1 fi if [[ "$SDDEV" =~ .*blk.* ]] ; then partExt="p" fi if [ -z $SDBOOT ] ; then SDBOOT=$(findmnt -no TARGET "${SDDEV}${partExt}${SDBOOTPARTNO}") fi if [ -z $SDBOOTPUUID ] ; then IFS=\" read -r _ vPARTUUID _ < <(blkid "${SDDEV}${partExt}${SDBOOTPARTNO}" -s PARTUUID) SDBOOTPUUID=$vPARTUUID fi SDROOTDEV=${SDDEV}${partExt}${SDROOTPARTNO} if [ -z $SDROOT ] ; then SDROOT=$(findmnt -no TARGET "${SDROOTDEV}") fi if [ -z $SDROOTPUUID ] ; then SDROOTPUUID=$(findmnt -no PARTUUID "${SDROOTDEV}") fi return 0 } SDBOOTPARTNO=1 SDROOTPARTNO=2 read_hd_dev() { if [ ! -z "$1" ] ; then HDROOT= HDROOTPUUID= HDSWAPPUUID= HDDEV="$1" elif [ -z $HDDEV ] || [ ! -b "$HDDEV" ] ; then HDROOT= HDROOTPUUID= HDSWAPPUUID= echo " [I] Available devices:" echo exe lsblk -p echo exe read -p "Provide HD device (e.g. /dev/sdf): " HDDEV fi if [ ! -b "$HDDEV" ] ; then HDDEV= return 1 fi if [ -z $HDROOT ] ; then HDROOT=$(findmnt -no TARGET "${HDDEV}1") fi if [ -z $HDROOTPUUID ] ; then IFS=\" read -r _ vPARTUUID _ < <(blkid "${HDDEV}1" -s PARTUUID) HDROOTPUUID=$vPARTUUID fi if [ -z $HDSWAPPUUID ] ; then IFS=\" read -r _ vPARTUUID _ < <(blkid "${HDDEV}2" -s PARTUUID) HDSWAPPUUID=$vPARTUUID HDSWAP="${HDDEV}2" fi return 0 } VERSION_SEQREV=9 . /usr/local/bin/sequencer.sh