Install under procd, so OpenWrt counts as a host too
The binary was already static and musl-clean; the only thing standing between Ham Lab and an OpenWrt box was that setup.go knew systemd and OpenRC and nothing else, so an install there ended at "nothing starts it at boot." Adds an embedded procd init script, detected on /sbin/procd + /etc/rc.common ahead of the OpenRC branch. Both backends write /etc/init.d/hamlab, so uninstall tells them apart by USE_PROCD=1 rather than by path. Verified on the new router: procd supervises the instance, S95/K10 symlinks land, and the hub drives its Docker and stacks like any other node. The Updates tab needed nothing — apk-tools 3 answers the same query Alpine's does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
4e3c817b2a
commit
4450f1285d
@@ -437,9 +437,16 @@ something long in one, switch away and back, refresh — it's all still there.
|
||||
replace, exec in place. Config default moved to `~/.config/hamlab` (existing
|
||||
`~/apps/hamlab` still found by the installer and the CLI). Tested in
|
||||
containers: Debian 12, Ubuntu 22.04, Fedora 40, Rocky 8, openSUSE Leap 15.5, Alpine
|
||||
3.18/3.20 (OpenRC + doas, non-root), plus the four lab hosts. Not done: an OpenRC
|
||||
backend for the Services tab; runit/s6/sysvinit service files; public hosting for
|
||||
`install.sh` (the Gitea repo is private, so the one-liner needs `HAMLAB_TOKEN`).
|
||||
3.18/3.20 (OpenRC + doas, non-root), plus the four lab hosts. **procd (OpenWrt) added
|
||||
2026-09-26** (`internal/setup/hamlab.procd`): detected on `/sbin/procd` + `/etc/rc.common`
|
||||
ahead of the OpenRC branch, installed to the same `/etc/init.d/hamlab` path and told apart
|
||||
from OpenRC at uninstall by `USE_PROCD=1` in the file. Verified on the new router
|
||||
(`gate`, OpenWrt 25.12.5, running as root): `S95`/`K10` symlinks, procd supervising the
|
||||
instance, Docker tab and stacks working through the hub. The Updates tab needed no change
|
||||
— apk-tools 3 answers `apk version -l '<'` the same way Alpine's does. Not done: an
|
||||
OpenRC or procd backend for the Services tab (it is systemd-only and says so cleanly);
|
||||
runit/s6/sysvinit service files; public hosting for `install.sh` (the Gitea repo is
|
||||
private, so the one-liner needs `HAMLAB_TOKEN`).
|
||||
- **Users, sessions and settings that follow the account** — **shipped 2026-09-22**
|
||||
(`internal/api/users.go`, `config.User`, `store.Session`/`UserState`, `Login.tsx`,
|
||||
`Users.tsx` — a hub-only **Users** tab in the rail, added the same day at Mitchell's
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Ham Lab web console (written by hamlab install)
|
||||
|
||||
USE_PROCD=1
|
||||
# after network and firewall, before the tail of the boot
|
||||
START=95
|
||||
STOP=10
|
||||
|
||||
start_service() {
|
||||
procd_open_instance hamlab
|
||||
procd_set_param command "@BIN@" serve
|
||||
procd_set_param env HAMLAB_CONFIG="@CONFIG@" HOME="@HOME@" USER="@USER@"
|
||||
procd_set_param user "@USER@"
|
||||
procd_set_param group "@GROUP@"
|
||||
procd_set_param pidfile /var/run/hamlab.pid
|
||||
# respawn: settle 3s, 5 retries inside that window, then give up counting
|
||||
procd_set_param respawn 3600 3 0
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger network
|
||||
}
|
||||
+25
-1
@@ -37,9 +37,14 @@ var systemdUnit string
|
||||
//go:embed hamlab.openrc
|
||||
var openrcScript string
|
||||
|
||||
//go:embed hamlab.procd
|
||||
var procdScript string
|
||||
|
||||
const (
|
||||
unitPath = "/etc/systemd/system/hamlab.service"
|
||||
openrcPath = "/etc/init.d/hamlab"
|
||||
// procd (OpenWrt) uses the same path as OpenRC; the two are told apart by content.
|
||||
procdPath = "/etc/init.d/hamlab"
|
||||
sudoersPath = "/etc/sudoers.d/hamlab-quiet"
|
||||
)
|
||||
|
||||
@@ -228,6 +233,19 @@ func Install(args []string, version string) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case exists("/sbin/procd") && exists("/etc/rc.common"):
|
||||
initSys = "procd"
|
||||
if err := os.WriteFile(procdPath, []byte(fill(procdScript, vars)), 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := run(procdPath, "enable"); err != nil {
|
||||
say("warning: %s enable: %v", procdPath, err)
|
||||
}
|
||||
if !o.noStart {
|
||||
if err := run(procdPath, "restart"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case exists("/sbin/openrc-run") || exists("/usr/sbin/openrc-run") || have("rc-service"):
|
||||
initSys = "OpenRC"
|
||||
if err := os.WriteFile(openrcPath, []byte(fill(openrcScript, vars)), 0o755); err != nil {
|
||||
@@ -258,7 +276,7 @@ func Install(args []string, version string) error {
|
||||
url := scheme + "://" + browseAddr(cfg.Listen)
|
||||
switch {
|
||||
case initSys == "":
|
||||
say("\nNo systemd or OpenRC here, so nothing starts it at boot.\nRun it under your own supervisor, as %s:\n HAMLAB_CONFIG=%s %s serve", acct.name, cfgPath, dest)
|
||||
say("\nNo systemd, procd or OpenRC here, so nothing starts it at boot.\nRun it under your own supervisor, as %s:\n HAMLAB_CONFIG=%s %s serve", acct.name, cfgPath, dest)
|
||||
case o.noStart:
|
||||
case healthy(cfg.Listen, cfg.TLS == "auto"):
|
||||
say("\nHam Lab is up: %s", url)
|
||||
@@ -294,9 +312,15 @@ func Uninstall(args []string) error {
|
||||
_ = run("systemctl", "daemon-reload")
|
||||
}
|
||||
if b, err := os.ReadFile(openrcPath); err == nil {
|
||||
if strings.Contains(string(b), "USE_PROCD=1") {
|
||||
dataDir = configDirFrom(string(b), "HAMLAB_CONFIG=")
|
||||
_ = run(procdPath, "stop")
|
||||
_ = run(procdPath, "disable")
|
||||
} else {
|
||||
dataDir = configDirFrom(string(b), "export HAMLAB_CONFIG=")
|
||||
_ = run("rc-service", "hamlab", "stop")
|
||||
_ = run("rc-update", "del", "hamlab", "default")
|
||||
}
|
||||
os.Remove(openrcPath)
|
||||
}
|
||||
os.Remove(sudoersPath)
|
||||
|
||||
Reference in New Issue
Block a user