257 lines
8.5 KiB
Bash
Executable File
257 lines
8.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# For audible sudo prompts:
|
|
unset sudoFlags
|
|
if [[ -x /etc/audibleprompt.sh ]]; then
|
|
export SUDO_ASKPASS=/etc/audibleprompt.sh
|
|
export sudoFlags=("-A")
|
|
fi
|
|
|
|
# shellcheck disable=SC2329
|
|
cleanup() {
|
|
popd &> /dev/null || true
|
|
if ! [[ -x /opt/configure-stormux/configure-stormux.sh ]]; then
|
|
echo "Initial setup is not complete."
|
|
echo "To continue setup, please run:"
|
|
echo "sudo configure-stormux"
|
|
fi
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
|
|
if [[ -x /opt/configure-stormux/configure-stormux.sh ]]; then
|
|
pushd /opt/configure-stormux || exit 1
|
|
./configure-stormux.sh
|
|
exit 0
|
|
fi
|
|
|
|
# Volume calibration is now handled in stormux_first_boot.sh
|
|
|
|
export DIALOGOPTS='--insecure --no-lines --visit-items'
|
|
i38StartAtBoot=0
|
|
firstBootSudoersFile="/etc/sudoers.d/zz-stormux-first-boot"
|
|
firstBootAutologinFile="/etc/systemd/system/getty@tty1.service.d/stormux-first-boot-autologin.conf"
|
|
firstBootAutologinDir="${firstBootAutologinFile%/*}"
|
|
|
|
read_yes_no() {
|
|
local answer
|
|
while true; do
|
|
echo "$1"
|
|
echo "Press y for yes or n for no followed by enter."
|
|
read -r answer
|
|
answer="${answer::1}"
|
|
case "${answer,,}" in
|
|
y)
|
|
return 0
|
|
;;
|
|
n)
|
|
return 1
|
|
;;
|
|
esac
|
|
echo "Please answer y or n."
|
|
done
|
|
}
|
|
|
|
cleanup_first_boot_access() {
|
|
rm -f "$firstBootSudoersFile" "$firstBootAutologinFile"
|
|
rmdir --ignore-fail-on-non-empty "$firstBootAutologinDir"
|
|
systemctl daemon-reload
|
|
}
|
|
|
|
configure_physical_screen() {
|
|
sudo "${sudoFlags[@]}" mkdir -p /etc/X11/xorg.conf.d
|
|
sudo "${sudoFlags[@]}" tee /etc/X11/xorg.conf.d/10-screendriver.conf > /dev/null << 'EOF'
|
|
Section "OutputClass"
|
|
Identifier "vc4"
|
|
MatchDriver "vc4"
|
|
Driver "modesetting"
|
|
Option "PrimaryGPU" "true"
|
|
EndSection
|
|
EOF
|
|
}
|
|
|
|
configure_headless_screen() {
|
|
sudo "${sudoFlags[@]}" mkdir -p /etc/X11/xorg.conf.d
|
|
sudo "${sudoFlags[@]}" tee /etc/X11/xorg.conf.d/10-screendriver.conf > /dev/null << 'EOF'
|
|
Section "Monitor"
|
|
Identifier "dummy_monitor"
|
|
HorizSync 28.0-80.0
|
|
VertRefresh 48.0-75.0
|
|
Modeline "1920x1080" 172.80 1920 2040 2248 2576 1080 1081 1084 1118
|
|
EndSection
|
|
|
|
Section "Device"
|
|
Identifier "dummy_card"
|
|
Driver "dummy"
|
|
VideoRam 256000
|
|
Option "UseFBDev" "false"
|
|
EndSection
|
|
|
|
Section "Screen"
|
|
Identifier "dummy_screen"
|
|
Device "dummy_card"
|
|
Monitor "dummy_monitor"
|
|
SubSection "Display"
|
|
Depth 24
|
|
Modes "1920x1080"
|
|
EndSubSection
|
|
EndSection
|
|
|
|
Section "ServerLayout"
|
|
Identifier "dummy_layout"
|
|
Screen 0 "dummy_screen"
|
|
EndSection
|
|
EOF
|
|
}
|
|
|
|
restart_fenrir_speech() {
|
|
if systemctl is-active --quiet fenrirscreenreader.service; then
|
|
killall speech-dispatcher 2>/dev/null || true
|
|
systemctl restart fenrirscreenreader.service
|
|
fi
|
|
}
|
|
|
|
set_timezone() {
|
|
# Get the list of timezones
|
|
mapfile -t regions < <(timedatectl --no-pager list-timezones | cut -d '/' -f1 | sort -u)
|
|
|
|
# Use the same text twice here and just hide the tag field.
|
|
# shellcheck disable=SC2046
|
|
region=$(dialog --backtitle "Please select your Region" \
|
|
--no-tags \
|
|
--menu "Use up and down arrows or page-up and page-down to navigate the list, and press 'Enter' to make your selection." 0 0 0 \
|
|
$(for i in "${regions[@]}" ; do echo "$i";echo "$i";done) --stdout)
|
|
|
|
|
|
mapfile -t cities < <(timedatectl --no-pager list-timezones | grep "$region" | cut -d '/' -f2 | sort -u)
|
|
|
|
# Use the same text twice here and just hide the tag field.
|
|
# shellcheck disable=SC2046
|
|
city=$(dialog --backtitle "Please select a city near you" \
|
|
--no-tags \
|
|
--menu "Use up and down arrow or page-up and page-down to navigate the list." 0 0 10 \
|
|
$(for i in "${cities[@]}" ; do echo "$i";echo "$i";done) --stdout)
|
|
|
|
# Set the timezone
|
|
if [[ -f /etc/localtime ]]; then
|
|
rm /etc/localtime
|
|
fi
|
|
ln -sf /usr/share/zoneinfo/"${region}"/"${city}" /etc/localtime
|
|
timedatectl set-ntp true
|
|
}
|
|
# Offer to switch fenrir layout.
|
|
if read_yes_no "Would you like to switch Fenrir to laptop layout?"; then
|
|
sed -i 's/=desktop/=laptop/' /etc/fenrirscreenreader/settings/settings.conf
|
|
clear
|
|
fi
|
|
restart_fenrir_speech
|
|
|
|
if command -v i3 > /dev/null 2>&1 && systemctl list-unit-files nodm.service > /dev/null 2>&1; then
|
|
if read_yes_no "Will this Pi be connected to a physical screen?"; then
|
|
configure_physical_screen
|
|
else
|
|
configure_headless_screen
|
|
fi
|
|
if read_yes_no "Should I38 start at boot?"; then
|
|
sudo "${sudoFlags[@]}" systemctl --quiet enable nodm.service
|
|
i38StartAtBoot=1
|
|
if read_yes_no "Should Fenrir run in the console at boot?"; then
|
|
sudo "${sudoFlags[@]}" systemctl --quiet enable fenrirscreenreader.service
|
|
else
|
|
sudo "${sudoFlags[@]}" systemctl --quiet disable fenrirscreenreader.service
|
|
fi
|
|
else
|
|
sudo "${sudoFlags[@]}" systemctl --quiet disable nodm.service
|
|
sudo "${sudoFlags[@]}" systemctl --quiet enable fenrirscreenreader.service
|
|
fi
|
|
fi
|
|
|
|
# Check for possible resize
|
|
diskSource="$(df --output='source' / | tail -1)"
|
|
diskSize="$(df -h --output='size' / | tail -1 | tr -cd '[:digit:].')"
|
|
diskSize=${diskSize%.*}
|
|
resizeThreshold=9
|
|
if [[ $diskSize -le $resizeThreshold ]]; then
|
|
if read_yes_no "$diskSource is only $diskSize gigs, which means it probably needs to be resized. Would you like to do this now?"; then
|
|
resizeLog="/tmp/stormux-resize.log"
|
|
# Extract base device name (handles mmcblk0p2, nvme0n1p2, sda2, etc.)
|
|
if [[ "$diskSource" =~ (.*[0-9]+)p[0-9]+$ ]]; then
|
|
# Handle mmcblk0p2, nvme0n1p2 style
|
|
diskDevice="${BASH_REMATCH[1]}"
|
|
else
|
|
# Handle sda2, sdb3 style
|
|
# shellcheck disable=SC2001
|
|
diskDevice="$(echo "$diskSource" | sed 's/[0-9]*$//')"
|
|
fi
|
|
echo "Resizing the filesystem. This may take a few minutes."
|
|
if { echo "Yes" | sudo "${sudoFlags[@]}" parted ---pretend-input-tty "$diskDevice" resizepart 2 100%; } > "$resizeLog" 2>&1 \
|
|
&& { sudo "${sudoFlags[@]}" resize2fs -f "$diskSource"; } >> "$resizeLog" 2>&1; then
|
|
echo "Resize complete."
|
|
else
|
|
echo "Resize failed. Details are in $resizeLog."
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if ! ping -c1 stormux.org &> /dev/null ; then
|
|
echo "No internet connection detected. Press enter to open NetworkManager."
|
|
read -r _
|
|
echo "setting set focus#highlight=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
|
nmtui-connect
|
|
echo "setting set focus#highlight=False" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
|
fi
|
|
# Check for internet connectivity
|
|
if ping -qc1 -W 1 stormux.org &> /dev/null; then
|
|
echo "Updating the clock to prevent certificate errors..."
|
|
# Get current date and time
|
|
date_time=$(curl -s http://worldtimeapi.org/api/ip | grep -oP '(?<="datetime":")[^"]*')
|
|
echo "Current date and time: $date_time"
|
|
# set date and time
|
|
date -s "$date_time"
|
|
echo "If your Pi does not have a CMOS battery and is powered off regularly, it may take a while for the time to be set correctly after boot."
|
|
echo "Stormux provides a service to sync the time after internet connection is established."
|
|
read -rp "Would you like the time to sync as soon as the Pi connects to the internet? " answer
|
|
answer="${answer:0:1}"
|
|
if [[ "${answer,,}" == "y" ]]; then
|
|
systemctl --quiet enable time_sync_at_boot.service
|
|
else
|
|
echo "Time sync at boot skipped."
|
|
echo "If you change your mind later, simply type:"
|
|
echo "sudo systemctl enable time_sync_at_boot.service"
|
|
fi
|
|
set_timezone
|
|
else
|
|
echo "Please connect to the internet and run ${0##*/} again."
|
|
exit 1
|
|
fi
|
|
echo "Installing configure-stormux..."
|
|
git -C /opt clone -q https://git.stormux.org/storm/configure-stormux || exit 1
|
|
|
|
echo
|
|
echo "Initial setup is complete."
|
|
echo
|
|
echo "The default passwords are stormux for the stormux user"
|
|
echo "and root for the root user. It is highly recommended to change them."
|
|
echo "To change the password for stormux, run:"
|
|
echo "passwd"
|
|
echo "To change the password for root, run:"
|
|
echo "sudo passwd"
|
|
echo
|
|
echo "For more configuration options, run configure-stormux,"
|
|
echo "or you may configure your system manually."
|
|
echo
|
|
echo "Thank you for choosing Stormux."
|
|
|
|
echo
|
|
read -rp "Press enter to continue."
|
|
|
|
cleanup_first_boot_access
|
|
|
|
if [[ $i38StartAtBoot -eq 1 ]]; then
|
|
echo
|
|
echo "Starting I38..."
|
|
sudo "${sudoFlags[@]}" systemctl --quiet start nodm.service
|
|
fi
|
|
|
|
exit 0
|