Initial build setup for x86_64 Stormux.
This commit is contained in:
141
x86_64/airootfs/usr/local/bin/configure-stormux
Executable file
141
x86_64/airootfs/usr/local/bin/configure-stormux
Executable file
@@ -0,0 +1,141 @@
|
||||
#!/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
|
||||
|
||||
trap cleanup EXIT
|
||||
cleanup() {
|
||||
popd &> /dev/null
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
if [[ -x /opt/configure-stormux/configure-stormux.sh ]]; then
|
||||
pushd /opt/configure-stormux
|
||||
./configure-stormux.sh
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Volume calibration is now handled in stormux_first_boot.sh
|
||||
|
||||
export DIALOGOPTS='--insecure --no-lines --visit-items'
|
||||
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
echo "Would you like to switch Fenrir to laptop layout?"
|
||||
echo "Press y for yes or n for no followed by enter."
|
||||
read -r continue
|
||||
continue="${continue::1}"
|
||||
if [[ "${continue,}" == "y" ]];then
|
||||
sed -i 's/=desktop/=laptop/' /etc/fenrirscreenreader/settings/settings.conf
|
||||
clear
|
||||
systemctl restart fenrirscreenreader.service
|
||||
fi
|
||||
|
||||
# Check for possible resize
|
||||
diskSource="$(df --output='source' / | tail -1)"
|
||||
diskSize="$(df -h --output='size' / | tail -1 | tr -cd '[:digit:].')"
|
||||
diskSize=${diskSize%.*}
|
||||
if [[ $diskSize -le 7 ]]; then
|
||||
echo "$diskSource is only $diskSize gigs, which means it probably needs to be resized. Would you like to do this now?"
|
||||
echo "Press y for yes or n for no followed by enter."
|
||||
read -r continue
|
||||
continue="${continue::1}"
|
||||
if [[ "${continue,}" == "y" ]];then
|
||||
# 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
|
||||
diskDevice="$(echo "$diskSource" | sed 's/[0-9]*$//')"
|
||||
fi
|
||||
echo "Yes" | sudo "${sudoFlags[@]}" parted ---pretend-input-tty "$diskDevice" resizepart 2 100%
|
||||
sudo "${sudoFlags[@]}" resize2fs -f "$diskSource"
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! ping -c1 stormux.org &> /dev/null ; then
|
||||
echo "No internet connection detected. Press enter to open NetworkManager."
|
||||
read -r continue
|
||||
echo "setting set focus#highlight=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
||||
nmtui-connect
|
||||
echo "setting set focus#highlight=False" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.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 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."
|
||||
|
||||
|
||||
exit 0
|
||||
21
x86_64/airootfs/usr/local/bin/init-pipewire-sound.sh
Executable file
21
x86_64/airootfs/usr/local/bin/init-pipewire-sound.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
# Initialize pipewire audio by attempting to play sound until it succeeds
|
||||
# This ensures pipewire is fully ready before fenrir starts
|
||||
|
||||
maxAttempts=30
|
||||
attempt=0
|
||||
|
||||
while [[ $attempt -lt $maxAttempts ]]; do
|
||||
# Try to play a silent sound using sox
|
||||
if play -qnV0 synth .1 whi norm -100 2>/dev/null; then
|
||||
# Success! Pipewire is working
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Wait a moment before trying again
|
||||
sleep 1
|
||||
((attempt++))
|
||||
done
|
||||
|
||||
# Even if we failed, exit successfully so we don't block boot
|
||||
exit 0
|
||||
24
x86_64/airootfs/usr/local/bin/livecd-sound
Executable file
24
x86_64/airootfs/usr/local/bin/livecd-sound
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
# Configure audio for Stormux live environment
|
||||
# Ensures pipewire is running and audio is properly configured
|
||||
|
||||
# Start pipewire for the stormux user if not already running
|
||||
if id stormux &>/dev/null; then
|
||||
# Enable linger for stormux user
|
||||
loginctl enable-linger stormux 2>/dev/null || true
|
||||
|
||||
# Start pipewire user services
|
||||
stormux_uid="$(id -u stormux)"
|
||||
sudo -u stormux XDG_RUNTIME_DIR="/run/user/${stormux_uid}" systemctl --user enable --now pipewire.service pipewire-pulse.service wireplumber.service 2>/dev/null || true
|
||||
|
||||
# Wait for pipewire to initialize
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
# Unmute and set reasonable volumes
|
||||
amixer -q set Master 70% unmute 2>/dev/null || true
|
||||
amixer -q set PCM 70% unmute 2>/dev/null || true
|
||||
amixer -q set Speaker 70% unmute 2>/dev/null || true
|
||||
amixer -q set Headphone 70% unmute 2>/dev/null || true
|
||||
|
||||
exit 0
|
||||
22
x86_64/airootfs/usr/local/bin/setup-pipewire-live.sh
Executable file
22
x86_64/airootfs/usr/local/bin/setup-pipewire-live.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
# Setup Pipewire for the live environment
|
||||
# This ensures pipewire is running before Fenrir starts
|
||||
|
||||
# Note: Do not use set -e - we want this to succeed even if commands fail
|
||||
|
||||
# Enable user linger for the stormux user (allows user services to run without login)
|
||||
if [ -d /var/lib/systemd/linger ]; then
|
||||
touch /var/lib/systemd/linger/stormux
|
||||
fi
|
||||
|
||||
# Start pipewire for the stormux user
|
||||
if id stormux &>/dev/null; then
|
||||
# Use machinectl to start user services in the user's session
|
||||
machinectl shell stormux@ /usr/bin/systemctl --user enable pipewire.service pipewire-pulse.service wireplumber.service 2>/dev/null || true
|
||||
machinectl shell stormux@ /usr/bin/systemctl --user start pipewire.service pipewire-pulse.service wireplumber.service 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Wait a moment for pipewire to initialize
|
||||
sleep 2
|
||||
|
||||
exit 0
|
||||
73
x86_64/airootfs/usr/local/bin/stormux-setup.sh
Executable file
73
x86_64/airootfs/usr/local/bin/stormux-setup.sh
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Customize the airootfs after package installation
|
||||
# This script runs in the chroot environment after packages are installed
|
||||
|
||||
set -e -u
|
||||
|
||||
# Copy custom skel files, overwriting package defaults
|
||||
if [ -d /etc/skel.custom ]; then
|
||||
echo "Installing custom skel files..."
|
||||
cp -f /etc/skel.custom/.* /etc/skel/ 2>/dev/null || true
|
||||
rm -rf /etc/skel.custom
|
||||
fi
|
||||
|
||||
# Set the distribution name
|
||||
echo 'Stormux \r (\l)' > /etc/issue
|
||||
echo >> /etc/issue
|
||||
|
||||
# Create realtime group if it doesn't exist
|
||||
if ! getent group realtime > /dev/null 2>&1; then
|
||||
echo "Creating realtime group..."
|
||||
groupadd -r realtime
|
||||
fi
|
||||
|
||||
# Create stormux user with groups matching Pi build
|
||||
echo "Creating stormux user..."
|
||||
useradd -m -g users -G wheel,realtime,audio,video,network,brlapi -s /bin/bash stormux
|
||||
|
||||
# Set passwords
|
||||
echo -e "root\nroot" | passwd "root"
|
||||
echo -e "stormux\nstormux" | passwd "stormux"
|
||||
|
||||
# Configure git for stormux user
|
||||
sudo -iu stormux bash -c 'git config --global init.defaultBranch master'
|
||||
|
||||
# Create user directories
|
||||
sudo -iu stormux xdg-user-dirs-update
|
||||
|
||||
# Enable linger so that sound will start at login
|
||||
mkdir -p /var/lib/systemd/linger
|
||||
touch /var/lib/systemd/linger/stormux
|
||||
|
||||
# Enable pipewire globally
|
||||
# Pipewire configuration for fenrir is pre-installed in airootfs
|
||||
systemctl --global enable pipewire.service pipewire-pulse.service
|
||||
|
||||
# Configure sudo for wheel group
|
||||
echo '%wheel ALL=(ALL) ALL' > /etc/sudoers.d/wheel
|
||||
|
||||
# Set hostname
|
||||
echo stormux > /etc/hostname
|
||||
|
||||
# Disable systemd-networkd in favor of NetworkManager
|
||||
systemctl disable systemd-networkd.service systemd-networkd.socket 2>/dev/null || true
|
||||
|
||||
# Enable services
|
||||
services=(
|
||||
brltty.path
|
||||
fenrirscreenreader.service
|
||||
NetworkManager.service
|
||||
stormux-audio-setup.service
|
||||
)
|
||||
|
||||
for service in "${services[@]}"; do
|
||||
echo "Enabling $service..."
|
||||
if systemctl enable "$service"; then
|
||||
echo " $service: OK"
|
||||
else
|
||||
echo " $service: FAILED"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Airootfs customization complete"
|
||||
4
x86_64/airootfs/usr/local/bin/sync_time.sh
Executable file
4
x86_64/airootfs/usr/local/bin/sync_time.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
date_time=$(curl -s http://worldtimeapi.org/api/ip | grep -oP '(?<="datetime":")[^"]*')
|
||||
date -s "$date_time"
|
||||
Reference in New Issue
Block a user