added sas to both images. A few minor updates to image generation for pi images.

This commit is contained in:
Storm Dragon
2026-06-04 23:52:44 -04:00
parent c94a71e0d6
commit f6e2e2f4c8
10 changed files with 431 additions and 1242 deletions
+141
View File
@@ -0,0 +1,141 @@
#!/usr/bin/env bash
set -euo pipefail
readonly repoName="stormux"
readonly repoKeyUrl="https://packages.stormux.org/stormux_repo.pub"
readonly repoKeyId="52ADA49000F1FF0456F8AEEFB4CDE1CD56EF8E82"
readonly pacmanConf="${STORMUX_PACMAN_CONF:-/etc/pacman.conf}"
readonly osRelease="${STORMUX_OS_RELEASE:-/etc/os-release}"
readonly effectiveUid="${STORMUX_TEST_EUID:-${EUID}}"
keyFile=""
cleanup() {
if [[ -n "$keyFile" && -f "$keyFile" ]]; then
rm -f "$keyFile"
fi
}
die() {
printf 'Error: %s\n' "$1" >&2
exit 1
}
require_root() {
[[ "$effectiveUid" == "0" ]] || die "This script must be run as root."
}
require_command() {
local commandName="$1"
command -v "$commandName" >/dev/null 2>&1 || die "Required command not found: ${commandName}"
}
is_arch_based_system() {
local osId=""
local osIdLike=""
[[ -f "$osRelease" ]] || return 1
while IFS='=' read -r keyName keyValue; do
keyValue="${keyValue%\"}"
keyValue="${keyValue#\"}"
case "$keyName" in
ID)
osId="$keyValue"
;;
ID_LIKE)
osIdLike="$keyValue"
;;
esac
done < "$osRelease"
[[ "$osId" == "arch" || "$osId" == "archarm" || " ${osIdLike} " == *" arch "* ]]
}
check_prerequisites() {
require_root
require_command curl
require_command pacman
require_command pacman-key
is_arch_based_system || die "This script supports Arch-based pacman systems only."
[[ -f "$pacmanConf" ]] || die "pacman.conf not found: ${pacmanConf}"
}
download_and_trust_key() {
keyFile="$(mktemp)"
trap cleanup EXIT
printf 'Downloading Stormux repository key...\n'
curl -fsSL "$repoKeyUrl" > "$keyFile"
printf 'Adding Stormux repository key to pacman keyring...\n'
pacman-key --add "$keyFile"
printf 'Locally signing Stormux repository key...\n'
pacman-key --lsign-key "$repoKeyId"
}
update_pacman_conf() {
local tempConf
tempConf="$(mktemp)"
awk -v repoName="$repoName" '
function print_repo_block() {
print "[" repoName "]"
print "SigLevel = Required DatabaseOptional"
print "Server = https://packages.stormux.org/$arch"
}
/^\[stormux\][[:space:]]*$/ {
inStormux = 1
next
}
inStormux && /^\[[^]]+\][[:space:]]*$/ {
inStormux = 0
}
inStormux {
next
}
!inserted && /^\[core\][[:space:]]*$/ {
print_repo_block()
print ""
inserted = 1
}
{
print
}
END {
if (!inserted) {
print ""
print_repo_block()
}
}
' "$pacmanConf" > "$tempConf"
cat "$tempConf" > "$pacmanConf"
rm -f "$tempConf"
}
refresh_databases() {
printf 'Refreshing package databases...\n'
pacman -Sy
}
main() {
check_prerequisites
download_and_trust_key
update_pacman_conf
refresh_databases
printf 'Stormux repository is configured.\n'
}
main "$@"
+230
View File
@@ -0,0 +1,230 @@
#!/usr/bin/env bash
set -euo pipefail
shopt -s nullglob
repoDir="/var/www/packages.stormux.org"
aurRpcUrl="https://aur.archlinux.org/rpc/v5/info"
exclude=("gzdoom")
require_cmd() {
local cmd="$1"
if ! command -v "$cmd" >/dev/null 2>&1; then
printf 'Required command not found: %s\n' "$cmd" >&2
exit 1
fi
}
is_excluded() {
local packageName="$1"
local excludedPackage
for excludedPackage in "${exclude[@]}"; do
if [[ "$excludedPackage" == "$packageName" ]]; then
return 0
fi
done
return 1
}
record_local_package_version() {
local packageName="$1"
local packageVersion="$2"
local packageMapName="$3"
local -n packageMapRef="$packageMapName"
local existingVersion="${packageMapRef[$packageName]:-}"
if [[ -z "$existingVersion" ]] || (( $(vercmp "$packageVersion" "$existingVersion") > 0 )); then
packageMapRef["$packageName"]="$packageVersion"
fi
}
read_package_metadata() {
local packageFile="$1"
pacman -Qip "$packageFile" | parse_pacman_info
}
parse_pacman_info() {
awk '
/^Name[[:space:]]*:/ {
packageName=$0
sub(/^Name[[:space:]]*:[[:space:]]*/, "", packageName)
}
/^Version[[:space:]]*:/ {
packageVersion=$0
sub(/^Version[[:space:]]*:[[:space:]]*/, "", packageVersion)
}
END {
if (packageName == "" || packageVersion == "") {
exit 1
}
printf "%s\t%s\n", packageName, packageVersion
}
'
}
collect_local_packages() {
local packageMapName="$1"
# shellcheck disable=SC2178
local -n packageMapRef="$packageMapName"
local archDir packageFile metadata packageName packageVersion
local -a archDirs=("$repoDir/x86_64" "$repoDir/aarch64")
for archDir in "${archDirs[@]}"; do
if [[ ! -d "$archDir" ]]; then
continue
fi
for packageFile in "$archDir"/*.pkg.tar.zst "$archDir"/*.pkg.tar.xz; do
metadata="$(read_package_metadata "$packageFile")" || {
printf 'Unable to read package metadata: %s\n' "$packageFile" >&2
exit 1
}
packageName="${metadata%%$'\t'*}"
packageVersion="${metadata#*$'\t'}"
record_local_package_version "$packageName" "$packageVersion" "$packageMapName"
done
done
}
extract_aur_version_from_json() {
local packageName="$1"
jq -r --arg packageName "$packageName" '
.results[]
| select(.Name == $packageName)
| .Version
' | head -n1
}
fetch_aur_version() {
local packageName="$1"
curl -fsS --get \
--data-urlencode "arg[]=${packageName}" \
"$aurRpcUrl" |
extract_aur_version_from_json "$packageName"
}
print_outdated_packages() {
local packageMapName="$1"
# shellcheck disable=SC2178
local -n packageMapRef="$packageMapName"
local packageName localVersion aurVersion
local -a packageNames=()
mapfile -t packageNames < <(printf '%s\n' "${!packageMapRef[@]}" | sort)
for packageName in "${packageNames[@]}"; do
if is_excluded "$packageName"; then
continue
fi
localVersion="${packageMapRef[$packageName]}"
aurVersion="$(fetch_aur_version "$packageName" || true)"
if [[ -z "$aurVersion" ]]; then
continue
fi
if (( $(vercmp "$localVersion" "$aurVersion") < 0 )); then
printf '%s %s\n' "$packageName" "$aurVersion"
fi
done
}
assert_equals() {
local expected="$1"
local actual="$2"
local message="$3"
if [[ "$expected" != "$actual" ]]; then
printf 'FAIL: %s\nExpected: %s\nActual: %s\n' "$message" "$expected" "$actual" >&2
exit 1
fi
}
assert_success() {
local message="$1"
shift
if ! "$@"; then
printf 'FAIL: %s\n' "$message" >&2
exit 1
fi
}
assert_failure() {
local message="$1"
shift
if "$@"; then
printf 'FAIL: %s\n' "$message" >&2
exit 1
fi
}
main() {
if [[ "${1:-}" == "--self-test" ]]; then
run_self_tests
return
fi
require_cmd "curl"
require_cmd "jq"
require_cmd "pacman"
require_cmd "vercmp"
if [[ ! -d "$repoDir" ]]; then
printf 'Repo dir does not exist: %s\n' "$repoDir" >&2
exit 1
fi
# shellcheck disable=SC2034
declare -A localPackages=()
collect_local_packages localPackages
print_outdated_packages localPackages
}
run_self_tests() {
declare -A packageMap=()
local exactMatchJson noMatchJson
local extractedVersion=""
local pacmanInfo=""
assert_success "excluded package should match" is_excluded "gzdoom"
assert_failure "non-excluded package should not match" is_excluded "fenrir"
record_local_package_version "fenrir" "1:2026.01.20-1" packageMap
record_local_package_version "fenrir" "1:2026.01.28-1" packageMap
record_local_package_version "fenrir" "1:2026.01.10-1" packageMap
assert_equals "1:2026.01.28-1" "${packageMap[fenrir]}" "newest local version should win"
exactMatchJson='{"results":[{"Name":"fenrir-git","Version":"1:r3322.4672592d-1"},{"Name":"fenrir","Version":"1:2026.01.28-1"}]}'
extractedVersion="$(printf '%s\n' "$exactMatchJson" | extract_aur_version_from_json "fenrir")"
assert_equals "1:2026.01.28-1" "$extractedVersion" "exact package name should be selected from AUR JSON"
noMatchJson='{"results":[{"Name":"fenrir-git","Version":"1:r3322.4672592d-1"}]}'
extractedVersion="$(printf '%s\n' "$noMatchJson" | extract_aur_version_from_json "fenrir")"
assert_equals "" "$extractedVersion" "missing exact AUR match should stay empty"
pacmanInfo='Name : fenrir
Version : 1:2026.01.28-1
Description : A user space console screen reader written in python3'
extractedVersion="$(printf '%s\n' "$pacmanInfo" | parse_pacman_info)"
assert_equals $'fenrir\t1:2026.01.28-1' "$extractedVersion" "pacman metadata parsing should return name and version"
if (( $(vercmp "1:2026.01.20-1" "1:2026.01.28-1") >= 0 )); then
printf 'FAIL: older local version should compare lower than AUR version\n' >&2
exit 1
fi
printf 'Self-test passed\n'
}
main "$@"