301 lines
7.2 KiB
Bash
Executable File
301 lines
7.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
#toolName=mytool
|
|
toolDownSite="https://raspi.debian.net/tested-images"
|
|
toolDownUrl=
|
|
toolDownFile=
|
|
|
|
toolEssentialDeps="vim bash-completion man-db locales wget"
|
|
|
|
SDDEV=
|
|
SDBOOT=
|
|
SDBOOTPUUID=
|
|
SDROOT=
|
|
SDROOTDEV=
|
|
SDROOTPUUID=
|
|
|
|
# Get script working directory
|
|
# (when called from a different directory)
|
|
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
|
APTOPT=
|
|
CONFIG=0
|
|
SCRIPT_NAME=$(basename -- $0)
|
|
SCRIPT_NAME=${SCRIPT_NAME%%.*}
|
|
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
|
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
|
|
|
step_config() {
|
|
[ $QUIET -ne 0 ] && APTOPT="-y"
|
|
return 0
|
|
}
|
|
|
|
step_1_info() {
|
|
echo "Download latest xz-compressed image [IMAGE FILE URL] [SD CARD DEVICE]"
|
|
echoinfo "$toolDownSite"
|
|
}
|
|
step_1_alias() { ALIAS="install"; }
|
|
step_1() {
|
|
shift
|
|
SDDEV="$2"
|
|
if [ -z "$1" ] && [ $QUIET -eq 0 ] ; then
|
|
read -p "Provide image download url from $toolDownSite: " toolDownUrl
|
|
elif [ ! -z "$1" ] ; then
|
|
toolDownUrl="$1"
|
|
else
|
|
echoerr " [E] No image file provided for download"
|
|
exit 1
|
|
fi
|
|
|
|
toolDownFile="/tmp/${toolDownUrl//*\//}"
|
|
local downSha256="${toolDownUrl%.img.xz}.xz.sha256"
|
|
local downShaFile="${toolDownFile%.img.xz}.xz.sha256"
|
|
|
|
echo Url: ${toolDownUrl}
|
|
echo Sha256: $downSha256
|
|
echo "Files: $toolDownFile"
|
|
echo " $downShaFile"
|
|
|
|
if [ ! -f "$downShaFile" ] ; then
|
|
exe wget -O "$downShaFile" "$downSha256"
|
|
endReturn -o $? "Error downloading $downShaFile"
|
|
fi
|
|
|
|
if [ ! -f "$toolDownFile" ] ; then
|
|
exe wget -O "$toolDownFile" "$toolDownUrl"
|
|
endReturn -o $? "Error downloading $downDownFile"
|
|
fi
|
|
|
|
echoseq " [I] Checking SHA256 checksum"
|
|
exe cd $(dirname "$toolDownFile")
|
|
exe sha256sum -c "$downShaFile" >>/dev/null
|
|
endReturn -o $? "SHA256 checksum error"
|
|
}
|
|
|
|
step_2_info() { echo "Write image to device [DEVICE]"; }
|
|
step_2() {
|
|
shift
|
|
if [ -z "$SDDEV" ] ; then
|
|
SDDEV="$1"
|
|
fi
|
|
read_sd_dev "$SDDEV"
|
|
# check if device was confirmed
|
|
endReturn -o $? "SD card device not found"
|
|
|
|
echoseq " [I] Writing $(basename "$toolDownFile")"
|
|
exep "xzcat \"$toolDownFile\" | dd of=$SDDEV bs=64k oflag=dsync status=progress"
|
|
exe sync
|
|
}
|
|
|
|
step_3_info() { echo "Prepare SD card for first run"; }
|
|
step_3() {
|
|
outColor green
|
|
cat <<PREPARE_EOF
|
|
[I] Setup static IP
|
|
[etc/network/interfaces.d/eth0]
|
|
#iface eth0 inet dhcp
|
|
|
|
iface eth0 inet static
|
|
address 192.168.0.38/24
|
|
gateway 192.168.0.1
|
|
|
|
iface eth0 inet6 static
|
|
address fd00::38/72
|
|
gateway fd00::1/64
|
|
|
|
[I] Disable ipv6
|
|
[etc/sysctl.conf]
|
|
net.ipv6.conf.eth0.disable_ipv6 = 1
|
|
|
|
[I] Setup dns nameserver
|
|
[etc/resolv.conf]
|
|
nameserver 192.168.0.1
|
|
nameserver fd00::1
|
|
|
|
[I] Setup root ssh access
|
|
[etc/ssh/sshd_config]
|
|
PermitRootLogin yes
|
|
|
|
[root/.ssh/authorized_keys]
|
|
# Root login only possible with an ssh key
|
|
|
|
PREPARE_EOF
|
|
}
|
|
|
|
step_10_info() { echo "Essential debian setup"; }
|
|
step_10_alias() { ALIAS="setup"; }
|
|
step_10() {
|
|
if [ -z "$(ls /etc/default | grep raspi)" ] ; then
|
|
echoerr " [E] Not on a Raspberry pi"
|
|
return 1
|
|
fi
|
|
|
|
exe apt update
|
|
exe apt full-upgrade $APTOPT
|
|
exe apt install $toolEssentialDeps $APTOPT
|
|
}
|
|
|
|
step_11_info() { echo "Set timezone"; }
|
|
step_11() {
|
|
exe dpkg-reconfigure tzdata
|
|
}
|
|
|
|
step_12_info() { echo "Setup locales to en_US.UTF-8"; }
|
|
step_12() {
|
|
local localUs="en_US.UTF-8"
|
|
local localUsDefault="$localUs UTF-8"
|
|
if [ ! -f "$localesConfigLoc" ] ; then
|
|
echoerr " [E] Install packages locales first"
|
|
exit 1
|
|
fi
|
|
|
|
exe sed -i "s/#[[:space:]]*\($localUsDefault\)/\1/" "$localesConfigLoc"
|
|
endReturn -o $? "Changing locales failed"
|
|
exe locale-gen
|
|
exe update-locale LANG=$localUs
|
|
echoseq " [I] Logout and login for changes to be active"
|
|
}
|
|
localesConfigLoc="/etc/locale.gen"
|
|
|
|
step_14_info() { echo "Change hostname [HOSTNAME]"; }
|
|
step_14_alias() { ALIAS="hostname"; }
|
|
step_14() {
|
|
shift
|
|
local localHostname=$1
|
|
endCheckEmpty localHostname "No hostname provided"
|
|
if [ $(grep -r "$localHostname" "$hostsLoc">>/dev/null; echo $?) -eq 0 ] ; then
|
|
echoseq " [I] Hostname $localHostname already defined"
|
|
return 0
|
|
fi
|
|
exe hostnamectl set-hostname "$localHostname"
|
|
endReturn -o $? "Couldn't set hostname"
|
|
exe sed -i "s/^\(127\.0\.0\.1[[:space:]]*\)\(localhost.*\)/\1\2\n\1$localHostname/" "$hostsLoc"
|
|
}
|
|
hostsLoc="/etc/hosts"
|
|
|
|
step_16_info() { echo "Install cifs mounting requirements"; }
|
|
step_16_alias() { ALIAS="cifs"; }
|
|
step_16() {
|
|
exe apt install cifs-utils $APTOPT
|
|
}
|
|
|
|
step_17_info() { echo "Cifs notes"; }
|
|
step_17() {
|
|
outColor green
|
|
cat <<CIFS_EOF
|
|
# Example fstab entry
|
|
[/etc/fstab]
|
|
//192.168.0.10/Qdownload /mnt/Qdownload cifs vers=1.0,credentials=/root/.smbpasswd,uid=username,gid=groupname,file_mode=0775,dir_mode=0775 0 0
|
|
|
|
# Mounting during boot may fail on Rpi4. This changes the entry to automount
|
|
(note "_netdev" and "comment=systemd.automount")
|
|
//192.168.0.10/Qdownload /mnt/Qdownload cifs _netdev,vers=2.0,credentials=/root/.smbpasswd,uid=username,gid=groupname,file_mode=0775,dir_mode=0775,comment=systemd.automount 0 0
|
|
|
|
## Alternatively this options were reported to work
|
|
auto,x-systemd.automount
|
|
|
|
# Example .smbpasswd
|
|
Don't forget to chown 600 this file.
|
|
[/root/.smbpasswd]
|
|
username=REMOTEUSER
|
|
password=REMOTEPASSWORD
|
|
|
|
CIFS_EOF
|
|
}
|
|
|
|
step_19_info() { echo "Setup notes"; }
|
|
step_19_alias() { ALIAS="setupnotes"; }
|
|
step_19() {
|
|
outColor green
|
|
cat <<SETUPNOTES_EOF
|
|
# Secure root with a password
|
|
passwd
|
|
|
|
# Create a regular user
|
|
adduser USERNAME
|
|
|
|
SETUPNOTES_EOF
|
|
}
|
|
|
|
step_40_info() { echo "Boot from HD notes"; }
|
|
step_40_alias() { ALIAS="hdboot"; }
|
|
step_40() {
|
|
outColor green
|
|
cat <<HDBOOT_EOF
|
|
[I] Raspberry pi 4 boots from USB automatically if there is no SD available
|
|
(needs boot loader version September 3rd)
|
|
|
|
[I] Adding a swap partition
|
|
|
|
* [RASPIROOTSSD/etc/fstab]
|
|
LABEL=RASPISWAP none swap sw 0 3
|
|
* Debian enables a swap partition automatically
|
|
because by default there is no swap file
|
|
|
|
[I] Procedure for raspi 3 is similar to the one for raspbian
|
|
(boot on SD and root on SSD)
|
|
|
|
* Clone RAPSIROOT from SD to SSD
|
|
rsync -axHAX RASPIROOT/ RASPIROOTSSD/
|
|
* [/boot/firmware/cmdline.txt]
|
|
root=LABEL=RASPIROOTSSD
|
|
* [RASPIROOTSSD/etc/fstab]
|
|
LABEL=RASPIROOTSSD / ...
|
|
|
|
HDBOOT_EOF
|
|
}
|
|
|
|
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
|
|
VERSION_SEQREV=12
|
|
. /usr/local/bin/sequencer.sh
|