Files
tsunagi/dist/arch/build-pkg.sh
T
Aleksandr BogomiakovandClaude c62d29fa14 Arch package: start the service and let the GUI reach the agent
The control socket is now opened to the tsunagi group (unit), the Arch
package enables and starts the service on install, adds the installing user
to the group, restarts a running agent on upgrade, and depends on the
libraries the tray loads at run time. The tray looks for the agent's socket
again on every poll instead of once at start, and a missing indicator
library is reported instead of panicking. Repository URLs unified.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-02 23:29:51 +01:00

149 lines
5.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Assemble an Arch Linux package (.pkg.tar.zst) from prebuilt tsunagi binaries,
# using only bsdtar + zstd on a non-Arch host — no makepkg, no Arch container.
#
# Usage: build-pkg.sh <binary> <arch> <version> <output.pkg.tar.zst> [tray_binary]
# <binary> path to the built tsunagi (agent/CLI) executable
# <arch> pacman architecture: x86_64 or aarch64
# <version> package version (the tag without its leading v)
# <output> path to write the package to
# [tray_binary] optional tsunagi-tray GUI executable; when given, the package
# also installs the tray and a desktop launcher and is named
# tsunagi-gui (conflicting with the headless tsunagi).
#
# Needs bsdtar (libarchive-tools) and zstd on the builder.
set -euo pipefail
binary="$1"
arch="$2"
version="$3"
output="$4"
tray="${5:-}"
here="$(cd "$(dirname "$0")" && pwd)"
root="$(mktemp -d)"
trap 'rm -rf "$root"' EXIT
# pacman pkgver may not contain '-', so a prerelease tag like 0.1.0-rc.9 becomes
# 0.1.0_rc.9.
pkgver="$(printf '%s' "$version" | tr '-' '_')"
pkgrel=1
# Payload. Arch keeps units under /usr/lib/systemd/system and installs to
# /usr/bin, so the service's ExecStart is rewritten to match.
install -D -m 0755 "$binary" "$root/usr/bin/tsunagi"
mkdir -p "$root/usr/lib/systemd/system"
sed 's#/usr/local/bin/tsunagi#/usr/bin/tsunagi#' \
"$here/../linux/tsunagi.service" > "$root/usr/lib/systemd/system/tsunagi.service"
chmod 0644 "$root/usr/lib/systemd/system/tsunagi.service"
install -D -m 0644 "$here/../linux/50-tsunagi-resolved.rules" \
"$root/usr/share/polkit-1/rules.d/50-tsunagi-resolved.rules"
install -D -m 0644 "$here/../../README.md" "$root/usr/share/doc/tsunagi/README.md"
install -D -m 0644 "$here/../linux/README.md" "$root/usr/share/doc/tsunagi/INSTALL.md"
pkgname=tsunagi
pkgdesc="Serverless private mesh networking agent"
relations=""
if [ -n "$tray" ]; then
pkgname=tsunagi-gui
pkgdesc="Serverless private mesh networking agent, with the tray GUI"
relations=$'conflict = tsunagi\nprovides = tsunagi\nreplaces = tsunagi\n'
# What the tray and its window load at run time; none of it is linked in
# statically, so pacman has to be told.
for dep in gtk3 libayatana-appindicator xdotool libxkbcommon wayland libx11 libglvnd; do
relations+="depend = ${dep}"$'\n'
done
install -D -m 0755 "$tray" "$root/usr/bin/tsunagi-tray"
install -D -m 0644 "$here/../linux/tsunagi-tray.desktop" \
"$root/usr/share/applications/tsunagi-tray.desktop"
install -D -m 0644 "$here/../linux/tsunagi.svg" \
"$root/usr/share/icons/hicolor/scalable/apps/tsunagi.svg"
fi
# Installed size (payload only), before the metadata files are written.
size="$(du -sb "$root" | cut -f1)"
cat > "$root/.PKGINFO" <<PKGINFO
pkgname = ${pkgname}
pkgver = ${pkgver}-${pkgrel}
pkgdesc = ${pkgdesc}
url = https://github.com/house-of-vanity/tsunagi
builddate = $(date +%s)
packager = AB <ab@hexor.cy>
size = ${size}
arch = ${arch}
${relations}license = WTFPL
PKGINFO
# Scriptlet: create the dedicated system user the service runs as, start the
# service, and let whoever ran pacman use it. The control socket belongs to the
# `tsunagi` group, so the tray and the CLI work for any member of it; the
# person installing is added, since the package cannot know anyone else.
cat > "$root/.INSTALL" <<'INSTALL'
post_install() {
getent group tsunagi >/dev/null 2>&1 || groupadd -r tsunagi
getent passwd tsunagi >/dev/null 2>&1 || \
useradd -r -g tsunagi -d /var/lib/tsunagi -s /usr/bin/nologin -c "tsunagi agent" tsunagi
command -v update-desktop-database >/dev/null 2>&1 && \
update-desktop-database -q /usr/share/applications >/dev/null 2>&1 || true
command -v gtk-update-icon-cache >/dev/null 2>&1 && \
gtk-update-icon-cache -q -t /usr/share/icons/hicolor >/dev/null 2>&1 || true
# Whoever ran pacman through sudo or pkexec (an AUR helper does too).
installer="${SUDO_USER:-}"
if [ -z "$installer" ] && [ -n "${PKEXEC_UID:-}" ]; then
installer="$(getent passwd "$PKEXEC_UID" | cut -d: -f1)"
fi
if [ -n "$installer" ] && [ "$installer" != root ] && id "$installer" >/dev/null 2>&1; then
usermod -aG tsunagi "$installer" >/dev/null 2>&1 || true
echo ":: $installer was added to the tsunagi group; log out and in again so the"
echo " tray and the CLI can reach the agent without sudo."
else
echo ":: add yourself to the tsunagi group to use the tray and the CLI without"
echo " sudo: sudo usermod -aG tsunagi \$USER, then log out and in again."
fi
if [ -d /run/systemd/system ]; then
systemctl daemon-reload >/dev/null 2>&1 || true
systemctl enable --now tsunagi.service >/dev/null 2>&1 || \
echo ":: could not start tsunagi.service; see: systemctl status tsunagi"
fi
}
post_upgrade() {
# Not enabled again: it may have been turned off on purpose. A running
# agent is restarted, because the control protocol changes between builds
# and a new client cannot talk to an old agent.
command -v update-desktop-database >/dev/null 2>&1 && \
update-desktop-database -q /usr/share/applications >/dev/null 2>&1 || true
if [ -d /run/systemd/system ]; then
systemctl daemon-reload >/dev/null 2>&1 || true
systemctl try-restart tsunagi.service >/dev/null 2>&1 || true
fi
}
pre_remove() {
systemctl disable --now tsunagi.service >/dev/null 2>&1 || true
}
post_remove() {
systemctl daemon-reload >/dev/null 2>&1 || true
}
INSTALL
# .MTREE over the metadata and payload (not over itself), gzip-compressed, as
# pacman expects.
(
cd "$root"
LANG=C bsdtar -czf .MTREE --format=mtree \
--options='!all,use-set,type,uid,gid,mode,time,size,md5,sha256,link' \
.PKGINFO .INSTALL usr
)
# Pack with .PKGINFO first, then the rest, and zstd-compress.
(
cd "$root"
bsdtar -cf - .PKGINFO .MTREE .INSTALL usr
) | zstd -c -19 -T0 > "$output"
echo "built $output"