Compare commits

..

17 Commits

Author SHA1 Message Date
Jack Kingsman c7248222dd Updating changelog + build for 3.10.0 2026-04-10 11:16:16 -07:00
Jack Kingsman 1e18a91f12 Merge pull request #172 from YourSandwich/aur-install-instructions
Add Arch Linux (AUR) packaging infrastructure
2026-04-10 10:54:49 -07:00
Jack Kingsman 18db6e4dd8 Make test script executable 2026-04-10 10:49:49 -07:00
Jack Kingsman 2393dadf1b Unload the service on uninstall 2026-04-10 10:48:38 -07:00
Jack Kingsman fd26576e0d Use correct email 2026-04-10 10:47:21 -07:00
Sandwich cb5a76eb5f Replace manual user/group creation with sysusers.d and tmpfiles.d 2026-04-10 19:23:01 +02:00
Jack Kingsman 7f5dde119f Update AGENTS.md 2026-04-10 00:15:57 -07:00
Jack Kingsman 799a721761 Be more defensive about systemd detection 2026-04-10 00:10:53 -07:00
Jack Kingsman 152a584f35 Fix TCP host 2026-04-10 00:10:41 -07:00
Jack Kingsman 5cc0476426 Fix port numbering 2026-04-10 00:06:22 -07:00
Jack Kingsman e468c6c161 Change command palette shortcut 2026-04-09 23:45:16 -07:00
Jack Kingsman e33537018b Fix AUR username 2026-04-09 23:11:02 -07:00
Jack Kingsman 0727793560 Add test script 2026-04-09 23:08:32 -07:00
Jack Kingsman 5c4e04e024 Skip daemon reload if systemctl isn't around 2026-04-09 23:08:26 -07:00
Jack Kingsman 967269ef7d Initial AUR work 2026-04-09 23:08:22 -07:00
Jack Kingsman 1903797d0d Fix broken statistics pane e2e test 2026-04-09 22:30:12 -07:00
Sandwich 424da7e232 Add Arch Linux (AUR) install instructions to README
Adds "Install Path 3: Arch Linux (AUR)" section covering both AUR
helper and manual makepkg installation, linking to the published
remoteterm-meshcore AUR package.

Closes #171
2026-04-09 03:51:39 +02:00
18 changed files with 59 additions and 41 deletions
+3 -1
View File
@@ -56,8 +56,10 @@ jobs:
assets: | assets: |
pkg/aur/remoteterm-meshcore.install pkg/aur/remoteterm-meshcore.install
pkg/aur/remoteterm-meshcore.service pkg/aur/remoteterm-meshcore.service
pkg/aur/remoteterm-meshcore.sysusers
pkg/aur/remoteterm-meshcore.tmpfiles
pkg/aur/remoteterm.env pkg/aur/remoteterm.env
commit_username: jkingsman commit_username: jackkingsman
commit_email: ${{ secrets.AUR_COMMIT_EMAIL }} commit_email: ${{ secrets.AUR_COMMIT_EMAIL }}
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }} ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
commit_message: "Update to ${{ steps.version.outputs.version }}" commit_message: "Update to ${{ steps.version.outputs.version }}"
+3 -1
View File
@@ -209,6 +209,7 @@ This message-layer echo/path handling is independent of raw-packet storage dedup
│ │ ├── MapView.tsx # Leaflet map showing node locations │ │ ├── MapView.tsx # Leaflet map showing node locations
│ │ └── ... │ │ └── ...
│ └── vite.config.ts │ └── vite.config.ts
├── pkg/aur/ # AUR package files (PKGBUILD, systemd service, env, install hooks)
├── scripts/ # Quality / release helpers (listing below is representative, not exhaustive) ├── scripts/ # Quality / release helpers (listing below is representative, not exhaustive)
│ ├── build/ │ ├── build/
│ │ ├── collect_licenses.sh # Gather third-party license attributions │ │ ├── collect_licenses.sh # Gather third-party license attributions
@@ -216,7 +217,8 @@ This message-layer echo/path handling is independent of raw-packet storage dedup
│ ├── quality/ │ ├── quality/
│ │ ├── all_quality.sh # Repo-standard autofix + validate gate │ │ ├── all_quality.sh # Repo-standard autofix + validate gate
│ │ ├── e2e.sh # End-to-end test runner │ │ ├── e2e.sh # End-to-end test runner
│ │ ── extended_quality.sh # Quality gate plus e2e and Docker matrix │ │ ── extended_quality.sh # Quality gate plus e2e and Docker matrix
│ │ └── test_aur_package.sh # Build + install AUR package in Arch Docker containers
│ └── setup/ │ └── setup/
│ ├── fetch_prebuilt_frontend.py # Download release frontend fallback │ ├── fetch_prebuilt_frontend.py # Download release frontend fallback
│ └── install_service.sh # Install/configure Linux systemd service │ └── install_service.sh # Install/configure Linux systemd service
+9
View File
@@ -1,3 +1,12 @@
## [3.10.0] - 2026-04-10
* Feature: Add Arch AUR package
* Feature: 72hr packet density view in statistics
* Feature: Add warnings for event loop selection for MQTT on Windows startup
* Bufix: Bump Apprise to 1.9.9 to fix Matrix bug
* Misc: More memory-conscious on recent contact fetch
* Misc: Fix statistics pane e2e test
## [3.9.0] - 2026-04-06 ## [3.9.0] - 2026-04-06
* Feature: Add hop counts to hop-width selection options * Feature: Add hop counts to hop-width selection options
+2 -2
View File
@@ -56,7 +56,7 @@ SOFTWARE.
</details> </details>
### apprise (1.9.7) — BSD-2-Clause ### apprise (1.9.9) — BSD-2-Clause
<details> <details>
<summary>Full license text</summary> <summary>Full license text</summary>
@@ -64,7 +64,7 @@ SOFTWARE.
``` ```
BSD 2-Clause License BSD 2-Clause License
Copyright (c) 2025, Chris Caron <lead2gold@gmail.com> Copyright (c) 2026, Chris Caron <lead2gold@gmail.com>
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
+1 -1
View File
@@ -31,7 +31,7 @@ services:
# TCP # TCP
# MESHCORE_TCP_HOST: 192.168.1.100 # MESHCORE_TCP_HOST: 192.168.1.100
# MESHCORE_TCP_PORT: 4000 # MESHCORE_TCP_PORT: 5000
# BLE # BLE
# BLE in Docker usually needs additional manual compose changes such as # BLE in Docker usually needs additional manual compose changes such as
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "remoteterm-meshcore-frontend", "name": "remoteterm-meshcore-frontend",
"private": true, "private": true,
"version": "3.9.0", "version": "3.10.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
+4 -4
View File
@@ -7,7 +7,7 @@ import {
Radio, Radio,
Route, Route,
Search, Search,
Sparkles, Star,
User, User,
Waypoints, Waypoints,
} from 'lucide-react'; } from 'lucide-react';
@@ -296,7 +296,7 @@ export function CommandPalette({
> >
<Hash className="text-muted-foreground" /> <Hash className="text-muted-foreground" />
<span>{ch.name}</span> <span>{ch.name}</span>
<Sparkles className="ml-auto h-3 w-3 text-yellow-500" /> <Star className="ml-auto h-3 w-3 text-favorite" />
</CommandItem> </CommandItem>
))} ))}
</CommandGroup> </CommandGroup>
@@ -384,7 +384,7 @@ function ContactGroup({
> >
<Icon className="text-muted-foreground" /> <Icon className="text-muted-foreground" />
<span>{displayName}</span> <span>{displayName}</span>
{showStar && <Sparkles className="ml-auto h-3 w-3 text-yellow-500" />} {showStar && <Star className="ml-auto h-3 w-3 text-favorite" />}
</CommandItem> </CommandItem>
))} ))}
</CommandGroup> </CommandGroup>
@@ -419,7 +419,7 @@ function RepeaterGroup({
> >
<Waypoints className="text-muted-foreground" /> <Waypoints className="text-muted-foreground" />
<span>{displayName}</span> <span>{displayName}</span>
{showStar && <Sparkles className="ml-auto h-3 w-3 text-yellow-500" />} {showStar && <Star className="ml-auto h-3 w-3 text-favorite" />}
</CommandItem>, </CommandItem>,
<CommandItem <CommandItem
key={`${c.public_key}-acl`} key={`${c.public_key}-acl`}
+11 -1
View File
@@ -1,4 +1,4 @@
# Maintainer: Jack Kingsman <jack.kingsman@gmail.com> # Maintainer: Jack Kingsman <jack@jackkingsman.me>
pkgname=remoteterm-meshcore pkgname=remoteterm-meshcore
# pkgver is rewritten by .github/workflows/publish-aur.yml on each release. # pkgver is rewritten by .github/workflows/publish-aur.yml on each release.
@@ -23,11 +23,15 @@ source=(
"$pkgname-$pkgver.tar.gz::https://github.com/jkingsman/Remote-Terminal-for-MeshCore/archive/refs/tags/$pkgver.tar.gz" "$pkgname-$pkgver.tar.gz::https://github.com/jkingsman/Remote-Terminal-for-MeshCore/archive/refs/tags/$pkgver.tar.gz"
"remoteterm-meshcore.service" "remoteterm-meshcore.service"
"remoteterm.env" "remoteterm.env"
"remoteterm-meshcore.sysusers"
"remoteterm-meshcore.tmpfiles"
) )
# sha256sums are recomputed by `updpkgsums` in the publish workflow before # sha256sums are recomputed by `updpkgsums` in the publish workflow before
# the PKGBUILD is pushed to AUR. The committed values are intentionally SKIP # the PKGBUILD is pushed to AUR. The committed values are intentionally SKIP
# so the file is honest about not tracking real hashes in this repo. # so the file is honest about not tracking real hashes in this repo.
sha256sums=('SKIP' sha256sums=('SKIP'
'SKIP'
'SKIP'
'SKIP' 'SKIP'
'SKIP') 'SKIP')
@@ -111,6 +115,12 @@ package() {
install -Dm640 "$srcdir/remoteterm.env" \ install -Dm640 "$srcdir/remoteterm.env" \
"$pkgdir/etc/remoteterm-meshcore/remoteterm.env" "$pkgdir/etc/remoteterm-meshcore/remoteterm.env"
# System user and data directory
install -Dm644 "$srcdir/remoteterm-meshcore.sysusers" \
"$pkgdir/usr/lib/sysusers.d/remoteterm-meshcore.conf"
install -Dm644 "$srcdir/remoteterm-meshcore.tmpfiles" \
"$pkgdir/usr/lib/tmpfiles.d/remoteterm-meshcore.conf"
# License # License
install -Dm644 LICENSE.md \ install -Dm644 LICENSE.md \
"$pkgdir/usr/share/licenses/$pkgname/LICENSE" "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
+7 -16
View File
@@ -1,14 +1,3 @@
pre_install() {
getent group remoteterm > /dev/null || groupadd -r remoteterm
getent passwd remoteterm > /dev/null || \
useradd -r -g remoteterm -d /var/lib/remoteterm-meshcore -s /sbin/nologin \
-c "RemoteTerm for MeshCore" remoteterm
}
pre_upgrade() {
pre_install
}
post_install() { post_install() {
echo "==> Set your radio connection (serial, TCP, or BLE) in" echo "==> Set your radio connection (serial, TCP, or BLE) in"
echo "==> /etc/remoteterm-meshcore/remoteterm.env" echo "==> /etc/remoteterm-meshcore/remoteterm.env"
@@ -20,22 +9,24 @@ post_upgrade() {
# Clean orphaned __pycache__ dirs left by the previous Python version # Clean orphaned __pycache__ dirs left by the previous Python version
find /opt/remoteterm-meshcore -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true find /opt/remoteterm-meshcore -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
if command -v systemctl &>/dev/null && systemctl --version &>/dev/null 2>&1; then # Skip systemd operations in chroots/containers where the binary may exist
systemctl daemon-reload # but PID 1 is not systemd.
if [ -d /run/systemd/system ] && command -v systemctl &>/dev/null; then
systemctl daemon-reload || true
if systemctl is-active --quiet remoteterm-meshcore; then if systemctl is-active --quiet remoteterm-meshcore; then
systemctl restart remoteterm-meshcore systemctl restart remoteterm-meshcore || true
fi fi
fi fi
} }
pre_remove() { pre_remove() {
if command -v systemctl &>/dev/null && systemctl --version &>/dev/null 2>&1; then if [ -d /run/systemd/system ] && command -v systemctl &>/dev/null; then
systemctl disable --now remoteterm-meshcore 2>/dev/null || true systemctl disable --now remoteterm-meshcore 2>/dev/null || true
fi fi
} }
post_remove() { post_remove() {
if command -v systemctl &>/dev/null && systemctl --version &>/dev/null 2>&1; then if [ -d /run/systemd/system ] && command -v systemctl &>/dev/null; then
systemctl daemon-reload systemctl daemon-reload
fi fi
+1
View File
@@ -0,0 +1 @@
u remoteterm - "RemoteTerm for MeshCore" /var/lib/remoteterm-meshcore
+1
View File
@@ -0,0 +1 @@
d /var/lib/remoteterm-meshcore 0750 remoteterm remoteterm
+1 -1
View File
@@ -10,7 +10,7 @@
# TCP # TCP
#MESHCORE_TCP_HOST=192.168.1.100 #MESHCORE_TCP_HOST=192.168.1.100
#MESHCORE_TCP_PORT=4000 #MESHCORE_TCP_PORT=5000
# BLE (also requires the optional `bluez` package) # BLE (also requires the optional `bluez` package)
#MESHCORE_BLE_ADDRESS=AA:BB:CC:DD:EE:FF #MESHCORE_BLE_ADDRESS=AA:BB:CC:DD:EE:FF
+1 -1
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "remoteterm-meshcore" name = "remoteterm-meshcore"
version = "3.9.0" version = "3.10.0"
description = "RemoteTerm - Web interface for MeshCore radio mesh networks" description = "RemoteTerm - Web interface for MeshCore radio mesh networks"
readme = "README.md" readme = "README.md"
requires-python = ">=3.11" requires-python = ">=3.11"
+7 -5
View File
@@ -53,7 +53,8 @@ echo "builder ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
BUILD_DIR=/home/builder/build BUILD_DIR=/home/builder/build
mkdir -p "$BUILD_DIR" mkdir -p "$BUILD_DIR"
cp /pkg/PKGBUILD /pkg/remoteterm-meshcore.install \ cp /pkg/PKGBUILD /pkg/remoteterm-meshcore.install \
/pkg/remoteterm-meshcore.service /pkg/remoteterm.env "$BUILD_DIR/" /pkg/remoteterm-meshcore.service /pkg/remoteterm-meshcore.sysusers \
/pkg/remoteterm-meshcore.tmpfiles /pkg/remoteterm.env "$BUILD_DIR/"
chown -R builder:builder "$BUILD_DIR" chown -R builder:builder "$BUILD_DIR"
echo "Building package..." echo "Building package..."
@@ -84,13 +85,14 @@ docker run -d \
archlinux:latest bash -c ' archlinux:latest bash -c '
set -euo pipefail set -euo pipefail
# Install the package (triggers pre_install which creates the remoteterm user) # Install the package (sysusers.d creates the remoteterm user, tmpfiles.d creates the data dir)
pacman -Syu --noconfirm >/dev/null 2>&1 pacman -Syu --noconfirm >/dev/null 2>&1
pacman -U --noconfirm /pkg/*.pkg.tar.zst pacman -U --noconfirm /pkg/*.pkg.tar.zst
# Create the state directory (systemd StateDirectory= would do this on a real host) # In a container there is no systemd to trigger sysusers/tmpfiles automatically,
mkdir -p /var/lib/remoteterm-meshcore # so run them manually.
chown remoteterm:remoteterm /var/lib/remoteterm-meshcore systemd-sysusers
systemd-tmpfiles --create
echo "============================================" echo "============================================"
echo " RemoteTerm installed — starting server" echo " RemoteTerm installed — starting server"
+3 -3
View File
@@ -35,7 +35,7 @@ SERIAL_HOST_PATH="/dev/ttyACM0"
SERIAL_COMPOSE_HOST_PATH="/dev/ttyACM0" SERIAL_COMPOSE_HOST_PATH="/dev/ttyACM0"
SERIAL_CONTAINER_PATH="/dev/meshcore-radio" SERIAL_CONTAINER_PATH="/dev/meshcore-radio"
TCP_HOST="" TCP_HOST=""
TCP_PORT="4000" TCP_PORT="5000"
BLE_ADDRESS="" BLE_ADDRESS=""
BLE_PIN="" BLE_PIN=""
ENABLE_BOTS="N" ENABLE_BOTS="N"
@@ -311,8 +311,8 @@ case "$TRANSPORT_CHOICE" in
echo -e "${RED}TCP host is required.${NC}" echo -e "${RED}TCP host is required.${NC}"
read -r -p "TCP host: " TCP_HOST read -r -p "TCP host: " TCP_HOST
done done
read -r -p "TCP port (default: 4000): " TCP_PORT read -r -p "TCP port (default: 5000): " TCP_PORT
TCP_PORT="${TCP_PORT:-4000}" TCP_PORT="${TCP_PORT:-5000}"
echo -e "${GREEN}TCP: ${TCP_HOST}:${TCP_PORT}${NC}" echo -e "${GREEN}TCP: ${TCP_HOST}:${TCP_PORT}${NC}"
;; ;;
3) 3)
+2 -2
View File
@@ -114,8 +114,8 @@ case "$TRANSPORT_CHOICE" in
echo -e "${RED}TCP host is required.${NC}" echo -e "${RED}TCP host is required.${NC}"
read -rp "TCP host: " TCP_HOST read -rp "TCP host: " TCP_HOST
done done
read -rp "TCP port (default: 4000): " TCP_PORT read -rp "TCP port (default: 5000): " TCP_PORT
TCP_PORT="${TCP_PORT:-4000}" TCP_PORT="${TCP_PORT:-5000}"
echo -e "${GREEN}TCP: ${TCP_HOST}:${TCP_PORT}${NC}" echo -e "${GREEN}TCP: ${TCP_HOST}:${TCP_PORT}${NC}"
;; ;;
4) 4)
+1 -1
View File
@@ -15,6 +15,6 @@ test.describe('Statistics page', () => {
await expect(page.locator('h4').getByText('Network')).toBeVisible({ timeout: 10_000 }); await expect(page.locator('h4').getByText('Network')).toBeVisible({ timeout: 10_000 });
await expect(page.getByText('Contacts', { exact: true }).first()).toBeVisible(); await expect(page.getByText('Contacts', { exact: true }).first()).toBeVisible();
await expect(page.getByText('Channels', { exact: true }).first()).toBeVisible(); await expect(page.getByText('Channels', { exact: true }).first()).toBeVisible();
await expect(page.locator('h4').getByText('Packets')).toBeVisible(); await expect(page.locator('h4').getByText('Packets', { exact: true })).toBeVisible();
}); });
}); });
Generated
+1 -1
View File
@@ -983,7 +983,7 @@ wheels = [
[[package]] [[package]]
name = "remoteterm-meshcore" name = "remoteterm-meshcore"
version = "3.9.0" version = "3.10.0"
source = { virtual = "." } source = { virtual = "." }
dependencies = [ dependencies = [
{ name = "aiomqtt" }, { name = "aiomqtt" },