Lots of reorganization. Added stormux package repository. Removed unneeded packages. Switched to systemd management of logging to ram. Use existing tools to resize the image to fill the device, no more growpartfs. No packages installed from AUR any more.
This commit is contained in:
@@ -50,9 +50,8 @@ help() {
|
||||
declare -A command=(
|
||||
[h]="This help screen."
|
||||
[l:]="Language default is en_US."
|
||||
[n:]="Image name, default is stormux-pi<32|64>-<yyyy-mm-dd>.img"
|
||||
[s:]="image size in GB, default is 4."
|
||||
[v:]="Version of the Raspberry Pi for which you are building. (32|64) default is 64."
|
||||
[n:]="Image name, default is stormux-pi4-aarch64-<yyyy-mm-dd>.img"
|
||||
[s:]="image size in GB, default is 6."
|
||||
)
|
||||
|
||||
# Convert the keys of the associative array to a format usable by getopts
|
||||
@@ -75,14 +74,6 @@ while getopts "${args}" i ; do
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
v)
|
||||
if [[ "${OPTARG}" =~ ^32|64$ ]]; then
|
||||
imageVersion="${OPTARG}"
|
||||
else
|
||||
echo "Image version must be 32 for 32 bit (armv7h), or 64 for 64 bit (aarch64 default)."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
;;
|
||||
@@ -90,11 +81,8 @@ while getopts "${args}" i ; do
|
||||
done
|
||||
|
||||
# make sure variables are set, or use defaults.
|
||||
export imageVersion="${imageVersion:-64}"
|
||||
export imageSize="${imageSize:-6G}"
|
||||
imageName="${imageName:-stormux-pi4-${imageVersion}-$(date '+%Y-%m-%d').img}"
|
||||
imageName="${imageName/-64-/-aarch64-}"
|
||||
imageName="${imageName/-32-/-armv7h-}"
|
||||
imageName="${imageName:-stormux-pi4-aarch64-$(date '+%Y-%m-%d').img}"
|
||||
export imageName
|
||||
export imageLanguage="${imageLanguage:-en_US.UTF-8}"
|
||||
|
||||
@@ -129,9 +117,8 @@ for i in arch-install-scripts dosfstools parted wget ; do
|
||||
done
|
||||
|
||||
|
||||
# Url for the image to be downloaded.
|
||||
url[32]="http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-armv7-latest.tar.gz"
|
||||
url[64]="http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-aarch64-latest.tar.gz"
|
||||
# Url for the aarch64 image to be downloaded.
|
||||
imageUrl="http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-aarch64-latest.tar.gz"
|
||||
|
||||
fallocate -l "$imageSize" "$imageName"
|
||||
loopdev="$(losetup --find --show "${imageName}")"
|
||||
@@ -144,72 +131,122 @@ mount "${loopdev}p1" /mnt/boot
|
||||
# Things are mounted now, so set mounted to 0 (bash true)
|
||||
mounted=0
|
||||
imageFileName=$(mktemp)
|
||||
wget "${url[$imageVersion]}" -O "${imageFileName}"
|
||||
if [[ $imageVersion -eq 32 ]]; then
|
||||
# Workaround for bsdtar errors when extracting 32 bit image.
|
||||
set +e
|
||||
fi
|
||||
wget "${imageUrl}" -O "${imageFileName}"
|
||||
bsdtar -xpf "${imageFileName}" -C /mnt
|
||||
# Set -e in case it got unset for 32 bit image
|
||||
set -e
|
||||
|
||||
# Copy override files into place before chroot (except skel to avoid conflicts)
|
||||
cp -rv ../files/boot/* /mnt/boot
|
||||
cp -rv ../files/var/* /mnt/var
|
||||
cp -rv ../files/usr/* /mnt/usr
|
||||
# Copy etc files but exclude skel directory to avoid package conflicts
|
||||
find ../files/etc -mindepth 1 -maxdepth 1 ! -name skel -exec cp -rv {} /mnt/etc/ \;
|
||||
|
||||
PS1="(Chroot) [\u@\h \W] \$" arch-chroot /mnt << EOF
|
||||
echo "Chroot started."
|
||||
# set up pacman
|
||||
pacman-key --init
|
||||
pacman-key --populate archlinuxarm
|
||||
pacman -Syy
|
||||
# Change kernels for aarch64
|
||||
if [[ "$imageVersion" == "64" ]]; then
|
||||
pacman -R --noconfirm linux-aarch64 uboot-raspberrypi
|
||||
pacman -S --noconfirm linux-rpi
|
||||
|
||||
# Add stormux repository
|
||||
echo "Downloading stormux repository key..."
|
||||
curl -s https://packages.stormux.org/stormux_repo.pub > /tmp/stormux_repo.pub
|
||||
echo "Adding key to pacman keyring..."
|
||||
pacman-key --add /tmp/stormux_repo.pub
|
||||
echo "Locally signing key..."
|
||||
pacman-key --lsign-key 52ADA49000F1FF0456F8AEEFB4CDE1CD56EF8E82
|
||||
rm /tmp/stormux_repo.pub
|
||||
# Add repository before core in pacman.conf
|
||||
sed -i '/^\[core\]/i[stormux]\nSigLevel = Required DatabaseOptional\nServer = https://packages.stormux.org/\$arch\n' /etc/pacman.conf
|
||||
|
||||
# Test mirrors and configure based on responsiveness
|
||||
echo "Testing mirror responsiveness..."
|
||||
mirrors=(
|
||||
"mirror.archlinuxarm.org"
|
||||
"fl.us.mirror.archlinuxarm.org"
|
||||
"il.us.mirror.archlinuxarm.org"
|
||||
"tx.us.mirror.archlinuxarm.org"
|
||||
"nj.us.mirror.archlinuxarm.org"
|
||||
)
|
||||
|
||||
working_mirrors=()
|
||||
for mirror in "\${mirrors[@]}"; do
|
||||
echo "Testing \$mirror..."
|
||||
if curl -m 5 -f -s "http://\$mirror/aarch64/core/core.db" > /dev/null 2>&1; then
|
||||
echo " \$mirror: OK"
|
||||
working_mirrors+=("\$mirror")
|
||||
else
|
||||
echo " \$mirror: FAILED"
|
||||
fi
|
||||
done
|
||||
|
||||
# Create mirrorlist with working mirrors first, then fallback to all mirrors
|
||||
> /etc/pacman.d/mirrorlist
|
||||
if [[ \${#working_mirrors[@]} -gt 0 ]]; then
|
||||
echo "Using \${#working_mirrors[@]} working mirrors"
|
||||
for mirror in "\${working_mirrors[@]}"; do
|
||||
echo "Server = http://\$mirror/\\\$arch/\\\$repo" >> /etc/pacman.d/mirrorlist
|
||||
done
|
||||
else
|
||||
echo "No mirrors responded, using all mirrors as fallback"
|
||||
for mirror in "\${mirrors[@]}"; do
|
||||
echo "Server = http://\$mirror/\\\$arch/\\\$repo" >> /etc/pacman.d/mirrorlist
|
||||
done
|
||||
fi
|
||||
|
||||
# Install packages
|
||||
pacman -Su --needed --noconfirm \
|
||||
alsa-firmware \
|
||||
alsa-utils \
|
||||
base \
|
||||
base-devel \
|
||||
bash-completion \
|
||||
bluez \
|
||||
bluez-utils \
|
||||
brltty \
|
||||
cloud-utils \
|
||||
cronie \
|
||||
espeak-ng \
|
||||
fake-hwclock \
|
||||
firmware-raspberrypi \
|
||||
git \
|
||||
go \
|
||||
magic-wormhole \
|
||||
man \
|
||||
man-pages \
|
||||
networkmanager \
|
||||
pipewire \
|
||||
pipewire-alsa \
|
||||
pipewire-jack \
|
||||
pipewire-pulse \
|
||||
poppler \
|
||||
python-pyudev \
|
||||
python-daemonize \
|
||||
python-evdev \
|
||||
python-dbus \
|
||||
python-pyenchant \
|
||||
python-pyte \
|
||||
socat \
|
||||
raspberrypi-utils \
|
||||
realtime-privileges \
|
||||
rhvoice-voice-bdl \
|
||||
rng-tools \
|
||||
rsync \
|
||||
screen \
|
||||
sox \
|
||||
w3m \
|
||||
wget \
|
||||
wireless-regdb \
|
||||
wireplumber \
|
||||
xdg-user-dirs \
|
||||
pacman -Syy
|
||||
# Change to the Pi kernel for aarch64
|
||||
pacman -R --noconfirm linux-aarch64 uboot-raspberrypi
|
||||
pacman -S --noconfirm linux-rpi
|
||||
|
||||
# Install all packages (stormux repo has priority since it's listed first)
|
||||
packages=(
|
||||
alsa-firmware
|
||||
alsa-utils
|
||||
base
|
||||
base-devel
|
||||
bash-completion
|
||||
bluez
|
||||
bluez-utils
|
||||
brltty
|
||||
cronie
|
||||
espeak-ng
|
||||
fake-hwclock
|
||||
fenrir
|
||||
firmware-raspberrypi
|
||||
git
|
||||
magic-wormhole
|
||||
man
|
||||
man-pages
|
||||
networkmanager
|
||||
parted
|
||||
pipewire
|
||||
pipewire-alsa
|
||||
pipewire-jack
|
||||
pipewire-pulse
|
||||
poppler
|
||||
python-dbus
|
||||
python-pyenchant
|
||||
python-pyte
|
||||
python-setuptools-scm
|
||||
python-pyperclip
|
||||
raspberrypi-utils
|
||||
socat
|
||||
realtime-privileges
|
||||
rhvoice-voice-bdl
|
||||
rng-tools
|
||||
rsync
|
||||
screen
|
||||
sox
|
||||
w3m-git
|
||||
wget
|
||||
wireless-regdb
|
||||
wireplumber
|
||||
xdg-user-dirs
|
||||
xdg-utils
|
||||
yay
|
||||
)
|
||||
|
||||
pacman -Su --needed --noconfirm "\${packages[@]}"
|
||||
|
||||
# Restart gpg agents.
|
||||
gpgconf --kill all
|
||||
@@ -231,35 +268,14 @@ echo 'stormux ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers.d/wheel
|
||||
echo -e "root\nroot" | passwd "root"
|
||||
# Set the password for the stormux user
|
||||
echo -e "stormux\nstormux" | passwd "stormux"
|
||||
# Change to the stormux user and install some packages
|
||||
|
||||
# Change to the stormux user for user configuration
|
||||
sudo -iu stormux
|
||||
# suppress git spam about default branch name
|
||||
git config --global init.defaultBranch master
|
||||
# Create desktop, downloads, music, and other directories.
|
||||
xdg-user-dirs-update
|
||||
# Build AUR packages
|
||||
export aurPackages=(fenrir \
|
||||
growpartfs \
|
||||
log2ram \
|
||||
python-pythondialog \
|
||||
yay)
|
||||
export PKGDEST=~/packages
|
||||
for p in "\${aurPackages[@]}" ; do
|
||||
git clone https://aur.archlinux.org/\${p}.git
|
||||
cd ~/\${p}
|
||||
if [[ "\${p}" == "python-pythondialog" ]]; then
|
||||
gpg --import keys/pgp/*.asc
|
||||
fi
|
||||
makepkg -A
|
||||
cd ~
|
||||
rm -rf \${p}
|
||||
done
|
||||
exit
|
||||
# Install built packages
|
||||
for p in /home/stormux/packages/* ; do
|
||||
pacman -U --noconfirm \${p}
|
||||
done
|
||||
rm -rf /home/stormux/packages/
|
||||
# Enable linger so that hopefully sound will start at login.
|
||||
mkdir -p /var/lib/systemd/linger
|
||||
touch /var/lib/systemd/linger/stormux
|
||||
@@ -272,20 +288,32 @@ echo '%wheel ALL=(ALL) ALL' > /etc/sudoers.d/wheel
|
||||
echo stormux > /etc/hostname
|
||||
# Configure services
|
||||
systemctl disable systemd-networkd.service systemd-networkd.socket
|
||||
systemctl enable brltty.path cronie.service fake-hwclock.service fenrirscreenreader.service log2ram.service NetworkManager.service
|
||||
# Enable services
|
||||
services=(
|
||||
brltty.path
|
||||
cronie.service
|
||||
fake-hwclock.service
|
||||
fenrirscreenreader.service
|
||||
log-to-ram-setup.service
|
||||
log-to-ram-sync.timer
|
||||
log-to-ram-shutdown.service
|
||||
NetworkManager.service
|
||||
)
|
||||
|
||||
for service in "\${services[@]}"; do
|
||||
echo "Enabling \$service..."
|
||||
if systemctl enable "\$service"; then
|
||||
echo " \$service: OK"
|
||||
else
|
||||
echo " \$service: FAILED"
|
||||
fi
|
||||
done
|
||||
# Cleanup packages
|
||||
pacman -Sc --noconfirm
|
||||
pacman -R --noconfirm go
|
||||
|
||||
# Update fstab for Raspberry Pi 4. Not needed until linux-aarch64 works.
|
||||
# [[ $imageVersion -eq 4 ]] && sed -i 's/mmcblk0/mmcblk1/g' /etc/fstab
|
||||
EOF
|
||||
|
||||
# Copy override files into place.
|
||||
cp -rv ../files/boot/* /mnt/boot
|
||||
cp -rv ../files/etc/* /mnt/etc
|
||||
cp -rv ../files/var/* /mnt/var
|
||||
cp -rv ../files/usr/* /mnt/usr
|
||||
# Copy skel files to stormux user home (after user rename in chroot)
|
||||
find ../files/etc/skel/ -mindepth 1 -exec cp -rv "{}" /mnt/home/stormux/ \;
|
||||
|
||||
# Exiting calls the cleanup function to unmount.
|
||||
|
@@ -4,3 +4,4 @@
|
||||
# <file system> <dir> <type> <options> <dump> <pass>
|
||||
LABEL=STRMX_BOOT /boot vfat defaults 0 1
|
||||
LABEL=STRMX_ROOT / ext4 defaults,noatime 0 1
|
||||
tmpfs /var/log tmpfs defaults,noatime,nosuid,nodev,noexec,mode=0755,size=128M 0 0
|
||||
|
@@ -1,37 +0,0 @@
|
||||
# Configuration file for Log2Ram (https://github.com/azlux/log2ram) under MIT license.
|
||||
# This configuration file is read by the log2ram service
|
||||
|
||||
# Size for the ram folder, it defines the size the log folder will reserve into the RAM.
|
||||
# If it's not enough, log2ram will not be able to use ram. Check you /var/log size folder.
|
||||
# The default is 40M and is basically enough for a lot of applications.
|
||||
# You will need to increase it if you have a server and a lot of log for example.
|
||||
SIZE=128M
|
||||
|
||||
# This variable can be set to true if you prefer "rsync" rather than "cp".
|
||||
# I use the command cp -u and rsync -X, so I don't copy the all folder every time for optimization.
|
||||
# You can choose which one you want. Be sure rsync is installed if you use it.
|
||||
USE_RSYNC=true
|
||||
|
||||
# If there are some errors with available RAM space, a system mail will be send
|
||||
# Change it to false and you will have only a log if there is no place on RAM anymore.
|
||||
MAIL=false
|
||||
|
||||
# Variable for folders to put in RAM. You need to specify the real folder `/path/folder` , the `/path/hdd.folder` will be automatically created. Multiple path can be separeted by `;`. Do not add the final `/` !
|
||||
# example : PATH_DISK="/var/log;/home/test/FolderInRam"
|
||||
PATH_DISK="/var/log"
|
||||
|
||||
# **************** Zram backing conf *************************************************
|
||||
|
||||
# ZL2R Zram Log 2 Ram enables a zram drive when ZL2R=true ZL2R=false is mem only tmpfs
|
||||
ZL2R=false
|
||||
# COMP_ALG this is any compression algorithm listed in /proc/crypto
|
||||
# lz4 is fastest with lightest load but deflate (zlib) and Zstandard (zstd) give far better compression ratios
|
||||
# lzo is very close to lz4 and may with some binaries have better optimisation
|
||||
# COMP_ALG=lz4 for speed or Zstd for compression, lzo or zlib if optimisation or availabilty is a problem
|
||||
COMP_ALG=lz4
|
||||
# LOG_DISK_SIZE is the uncompressed disk size. Note zram uses about 0.1% of the size of the disk when not in use
|
||||
# LOG_DISK_SIZE is expected compression ratio of alg chosen multiplied by log SIZE
|
||||
# lzo/lz4=2.1:1 compression ratio zlib=2.7:1 zstandard=2.9:1
|
||||
# Really a guestimate of a bit bigger than compression ratio whilst minimising 0.1% mem usage of disk size
|
||||
LOG_DISK_SIZE=100M
|
||||
|
16
pi4/files/etc/systemd/system/log-to-ram-setup.service
Normal file
16
pi4/files/etc/systemd/system/log-to-ram-setup.service
Normal file
@@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=Setup RAM logging and restore logs from disk
|
||||
DefaultDependencies=false
|
||||
After=local-fs.target
|
||||
Before=sysinit.target
|
||||
RequiresMountsFor=/var
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStartPre=/bin/mkdir -p /var/log.hdd
|
||||
ExecStartPre=/bin/sh -c 'if [ -d /var/log.hdd ] && [ "$(ls -A /var/log.hdd 2>/dev/null)" ]; then cp -au /var/log.hdd/* /var/log/ 2>/dev/null || true; fi'
|
||||
ExecStart=/bin/true
|
||||
|
||||
[Install]
|
||||
WantedBy=sysinit.target
|
14
pi4/files/etc/systemd/system/log-to-ram-shutdown.service
Normal file
14
pi4/files/etc/systemd/system/log-to-ram-shutdown.service
Normal file
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Sync logs to disk before shutdown
|
||||
DefaultDependencies=false
|
||||
Before=shutdown.target reboot.target halt.target
|
||||
Conflicts=shutdown.target reboot.target halt.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=true
|
||||
ExecStart=/bin/sh -c 'rsync -aXv --delete --exclude="*.hdd" /var/log/ /var/log.hdd/ 2>/dev/null || true'
|
||||
TimeoutStopSec=30
|
||||
|
||||
[Install]
|
||||
WantedBy=shutdown.target reboot.target halt.target
|
8
pi4/files/etc/systemd/system/log-to-ram-sync.service
Normal file
8
pi4/files/etc/systemd/system/log-to-ram-sync.service
Normal file
@@ -0,0 +1,8 @@
|
||||
[Unit]
|
||||
Description=Sync logs from RAM to disk
|
||||
After=local-fs.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStartPre=/bin/mkdir -p /var/log.hdd
|
||||
ExecStart=/bin/sh -c 'rsync -aXv --delete --exclude="*.hdd" /var/log/ /var/log.hdd/ 2>/dev/null || true'
|
11
pi4/files/etc/systemd/system/log-to-ram-sync.timer
Normal file
11
pi4/files/etc/systemd/system/log-to-ram-sync.timer
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Sync logs from RAM to disk every hour
|
||||
Requires=log-to-ram-sync.service
|
||||
|
||||
[Timer]
|
||||
OnBootSec=15min
|
||||
OnUnitActiveSec=1h
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
@@ -24,29 +24,33 @@ if [[ -x /opt/configure-stormux/configure-stormux.sh ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# make sure the system is at a decent volume
|
||||
# Wait for pipewire to become available and set volume
|
||||
echo "Waiting for audio system to initialize..."
|
||||
volume=50
|
||||
wait=0
|
||||
|
||||
# Wait for pipewire to become available
|
||||
while [[ $wait -lt 30 ]]; do
|
||||
if pgrep pipewire &> /dev/null ; then
|
||||
wait=30 # We don't want to continue the loop
|
||||
echo "Audio system ready. Setting up volume..."
|
||||
break
|
||||
else
|
||||
sleep 1
|
||||
continue
|
||||
((wait++))
|
||||
fi
|
||||
done
|
||||
|
||||
# Volume calibration - this should be the first interactive part
|
||||
while [[ $volume -le 130 ]]; do
|
||||
clear
|
||||
echo "Volume calibration (current: ${volume}%)"
|
||||
pactl set-sink-volume @DEFAULT_SINK@ "${volume}%" 2>/dev/null
|
||||
spd-say "If this is loud enough, press enter."
|
||||
if read -t4 ; then
|
||||
echo "Volume set to ${volume}%"
|
||||
break
|
||||
else
|
||||
((volume+=5))
|
||||
fi
|
||||
while [[ $volume -le 130 ]]; do
|
||||
clear
|
||||
spd-say "If this is loud enough, press enter."
|
||||
if read -t4 ; then
|
||||
break
|
||||
else
|
||||
((volume+=5))
|
||||
fi
|
||||
pactl set-sink-volume @DEFAULT_SINK@ "${volume}%"
|
||||
done
|
||||
((wait++))
|
||||
done
|
||||
|
||||
export DIALOGOPTS='--insecure --no-lines --visit-items'
|
||||
@@ -98,7 +102,16 @@ if [[ $diskSize -le 7 ]]; then
|
||||
read -r continue
|
||||
continue="${continue::1}"
|
||||
if [[ "${continue,}" == "y" ]];then
|
||||
sudo "${sudoFlags[@]}" growpartfs $diskSource
|
||||
# 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
|
||||
sudo "${sudoFlags[@]}" parted "$diskDevice" resizepart 2 100%
|
||||
sudo "${sudoFlags[@]}" resize2fs "$diskSource"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
Reference in New Issue
Block a user