Updates to the x86_64 image creation.

This commit is contained in:
Storm Dragon
2025-12-17 16:09:22 -05:00
parent 3f2dc0b492
commit f4e91f7ee2
9 changed files with 524 additions and 3 deletions

View File

@@ -850,7 +850,7 @@ install_base_system() {
# Add desktop-specific packages
case "$desktopEnvironment" in
i3)
allPackages+=(i3-wm orca lxterminal pluma)
allPackages+=(i3-wm orca python-psutil lxterminal pluma)
allPackages+=(discount jq libnotify xfce4-notifyd pamixer playerctl)
allPackages+=(python-i3ipc python-wxpython sox yad)
allPackages+=(lxsession magic-wormhole pcmanfm)
@@ -860,7 +860,7 @@ install_base_system() {
stormuxPackages+=(xlibre-xserver xlibre-input-libinput nodm-dgw brave-bin)
;;
mate)
allPackages+=(mate mate-extra orca)
allPackages+=(mate mate-extra orca python-psutil)
# Add Stormux-specific MATE packages
stormuxPackages+=(xlibre-xserver xlibre-input-libinput nodm-dgw brave-bin)
;;
@@ -1017,6 +1017,37 @@ EOF
log_info "Audio configuration installed"
}
#
# SSH login monitor installation (script + service)
#
install_ssh_login_monitor() {
log_info "=== Installing SSH Login Monitor ==="
local srcScript="/usr/share/fenrirscreenreader/scripts/ssh-login-monitor.sh"
local srcService="/etc/systemd/system/ssh-login-monitor.service"
if [[ ! -f "$srcScript" ]]; then
log_error "Source script not found: $srcScript"
return 1
fi
if [[ ! -f "$srcService" ]]; then
log_error "Source service not found: $srcService"
return 1
fi
mkdir -p "$mountPoint/usr/share/fenrirscreenreader/scripts"
mkdir -p "$mountPoint/etc/systemd/system"
cp "$srcScript" "$mountPoint/usr/share/fenrirscreenreader/scripts/ssh-login-monitor.sh"
chmod 755 "$mountPoint/usr/share/fenrirscreenreader/scripts/ssh-login-monitor.sh"
cp "$srcService" "$mountPoint/etc/systemd/system/ssh-login-monitor.service"
chmod 644 "$mountPoint/etc/systemd/system/ssh-login-monitor.service"
log_info "SSH login monitor installed to target system"
}
#
# System configuration in chroot
#
@@ -1156,6 +1187,7 @@ systemctl enable NetworkManager.service
systemctl enable brltty.path
systemctl enable fenrirscreenreader.service
systemctl enable cronie.service
systemctl enable ssh-login-monitor.service
# Enable bluetooth if present
systemctl enable bluetooth.service 2>/dev/null || true
@@ -1588,6 +1620,13 @@ if ! install_audio_configs; then
exit 1
fi
# Install SSH login monitor files (script + service)
if ! install_ssh_login_monitor; then
log_error "SSH login monitor installation failed"
cleanup_and_unmount
exit 1
fi
# Configure system
if ! configure_system; then
log_error "System configuration failed"

View File

@@ -0,0 +1 @@
sas.sh

View File

@@ -0,0 +1,258 @@
#!/usr/bin/env bash
# Stormux Assistance System (SAS) - Client
# Simple command for users to request remote assistance
# Usage: sas
set -euo pipefail
# Configuration
serverHost="assistance.stormux.org"
serverPort=22
serverUser="stormux-assist"
tunnelPort=2222
configFile="/etc/stormux-assist/client.conf"
logFile="/var/log/sas.log"
logDir="${HOME}/stormux-assist-logs"
sessionTimeout=14400 # 4 hours
# Session variables
sessionId=""
tunnelPid=""
# Speech feedback function
speak() {
spd-say -w "$1" 2>/dev/null || true
}
# Logging function (format: "Message [timestamp]")
logMessage() {
local message="$1"
local timestamp
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "${message} [${timestamp}]" >> "${logFile}"
}
# Error handler with speech
errorExit() {
local message="$1"
speak "Error: ${message}"
logMessage "ERROR: ${message}"
cleanup
exit 1
}
# Load configuration if it exists
loadConfig() {
if [[ -f "${configFile}" ]]; then
# Source config file values (simple INI parsing)
while IFS='=' read -r key value; do
# Skip comments and empty lines
[[ "${key}" =~ ^[[:space:]]*# ]] && continue
[[ -z "${key}" ]] && continue
# Trim whitespace
key=$(echo "${key}" | xargs)
value=$(echo "${value}" | xargs)
case "${key}" in
host) serverHost="${value}" ;;
ssh_port) serverPort="${value}" ;;
ssh_user) serverUser="${value}" ;;
tunnel_port) tunnelPort="${value}" ;;
timeout) sessionTimeout="${value}" ;;
log_file) logFile="${value}" ;;
log_dir) logDir="${value}" ;;
esac
done < "${configFile}"
logMessage "Configuration loaded from ${configFile}"
else
logMessage "No config file found, using defaults"
fi
}
# Check network connectivity
checkNetwork() {
speak "Checking network connection"
logMessage "Checking network connectivity to ${serverHost}"
if ! ping -c 1 -W 5 "${serverHost}" &>/dev/null; then
errorExit "No network connection detected. Please connect to the internet and try again."
fi
logMessage "Network connectivity verified"
}
# Check SSH client is installed
checkSsh() {
if ! command -v ssh &>/dev/null; then
errorExit "SSH client not found. Please install openssh."
fi
if ! command -v autossh &>/dev/null; then
errorExit "autossh not found. Please install autossh package."
fi
logMessage "SSH and autossh verified"
}
# Create log directory
createLogDir() {
if [[ ! -d "${logDir}" ]]; then
mkdir -p "${logDir}" || errorExit "Failed to create log directory ${logDir}"
logMessage "Created log directory ${logDir}"
fi
}
# Generate session ID
generateSessionId() {
sessionId=$(date '+%Y%m%d-%H%M%S')-$(hostname -s)
logMessage "Generated session ID: ${sessionId}"
}
# Establish SSH reverse tunnel
establishTunnel() {
speak "Establishing connection to assistance server"
logMessage "Establishing SSH reverse tunnel to ${serverHost}:${serverPort}"
# Use autossh for auto-reconnection
# -M 0: disable autossh monitoring port (use ServerAliveInterval instead)
# -N: no remote command
# -R 2222:localhost:22: reverse tunnel from server port 2222 to local port 22
# ServerAliveInterval: keep connection alive
# ServerAliveCountMax: max failed keepalives before disconnect
# ExitOnForwardFailure: exit if tunnel cannot be established
autossh -M 0 \
-o "ServerAliveInterval=30" \
-o "ServerAliveCountMax=3" \
-o "ExitOnForwardFailure=yes" \
-o "StrictHostKeyChecking=accept-new" \
-N \
-R "${tunnelPort}:localhost:22" \
-p "${serverPort}" \
"${serverUser}@${serverHost}" &
tunnelPid=$!
# Wait a moment for tunnel to establish
sleep 3
# Check if tunnel is still running
if ! kill -0 "${tunnelPid}" 2>/dev/null; then
errorExit "Failed to establish SSH tunnel. Please check your SSH keys and server accessibility."
fi
logMessage "SSH tunnel established (PID: ${tunnelPid})"
}
# Wait for user to quit or timeout
waitForQuit() {
speak "Connection established. Support staff have been notified via IRC. Press Q to quit or wait for support to connect."
logMessage "Session active, waiting for Q keypress or timeout"
echo ""
echo "════════════════════════════════════════════════"
echo " Stormux Assistance System - Session Active"
echo "════════════════════════════════════════════════"
echo ""
echo "Support staff have been notified via IRC."
echo "They will connect shortly to help you."
echo ""
echo "Session ID: ${sessionId}"
echo "Session timeout: 4 hours"
echo ""
echo "Press 'Q' to end the session early"
echo ""
echo "════════════════════════════════════════════════"
echo ""
local startTime
startTime=$(date +%s)
while true; do
# Check for timeout
local currentTime
currentTime=$(date +%s)
local elapsed=$((currentTime - startTime))
if [[ ${elapsed} -ge ${sessionTimeout} ]]; then
speak "Session has timed out after 4 hours"
logMessage "Session timed out after ${sessionTimeout} seconds"
break
fi
# Check for Q keypress (with timeout)
if read -r -t 1 -n 1 key; then
if [[ "${key}" == "q" ]] || [[ "${key}" == "Q" ]]; then
speak "Ending assistance session"
logMessage "User requested session termination"
break
fi
fi
# Check if tunnel is still alive
if ! kill -0 "${tunnelPid}" 2>/dev/null; then
speak "Connection lost. Session ended."
logMessage "Tunnel process died unexpectedly"
break
fi
done
}
# Cleanup and exit
cleanup() {
logMessage "Starting cleanup"
# Kill tunnel if running
if [[ -n "${tunnelPid}" ]] && kill -0 "${tunnelPid}" 2>/dev/null; then
kill "${tunnelPid}" 2>/dev/null || true
logMessage "Tunnel process terminated"
fi
logMessage "Cleanup complete"
}
# End-of-session patronage message
patronageMessage() {
speak "Assistance session ended. Thank you for using Stormux Live Assistance."
sleep 2
speak "This service is made possible by supporters like you. Consider becoming a patron at patreon dot com slash stormux to help keep this service running."
logMessage "Session ended, patronage message delivered"
}
# Main execution
main() {
speak "Starting Stormux assistance request"
logMessage "=== SAS Client Started ==="
# Ensure we clean up on exit
trap cleanup EXIT INT TERM
# Load configuration
loadConfig
# Create log directory
createLogDir
# Pre-flight checks
checkNetwork
checkSsh
# Generate session ID
generateSessionId
# Establish tunnel
establishTunnel
# Wait for quit or timeout
waitForQuit
# End session
patronageMessage
logMessage "=== SAS Client Ended ==="
}
# Run main
main "$@"