9p: remove daemon subcommands, simplify to foreground-only

Drop start/fgstart/stop/status subcommands. olliesrv now runs
directly in the foreground; lifecycle managed by the supervisor
(systemd, openrc, or xdg-autostart). Keep mount as a convenience
subcommand for mounting remote 9P servers via 9pfuse.

- Remove daemonize(), stopServer(), isRunning(), pid file management
- runServer() no longer takes pidPath
- Move desktop file to main repo services/xdg-autostart/
- Update README examples
This commit is contained in:
lkn 2026-07-25 18:20:14 +02:00
parent af7363cb1d
commit cbd249e5f9
3 changed files with 14 additions and 107 deletions

View File

@ -75,10 +75,8 @@ Installs `olliesrv` to `$HOME/bin`.
## Usage
```sh
olliesrv start # start daemon (backgrounds itself)
olliesrv fgstart # start in foreground
olliesrv stop # stop daemon
olliesrv status # check if running
olliesrv # start the server (foreground)
olliesrv mount <addr> [mnt] # mount a remote 9P server via 9pfuse
olliesrv mount <addr> [mnt] # mount a remote 9P server via 9pfuse
```
@ -97,9 +95,9 @@ The server listens on a Unix socket in the Plan 9 namespace (`$NAMESPACE/ollie`)
| `-nodbus` | Disable the embedded D-Bus adapter (implied by `-tcp`). |
```sh
olliesrv start -strict # tools only, sandboxed
olliesrv start -yolo # arbitrary code, no sandbox
olliesrv start -strict -yolo # tools only, no sandbox
olliesrv -strict # tools only, sandboxed
olliesrv -yolo # arbitrary code, no sandbox
olliesrv -strict -yolo # tools only, no sandbox
```
## Remote Access
@ -110,7 +108,7 @@ olliesrv start -strict -yolo # tools only, no sandbox
```sh
# On the remote host:
olliesrv start -tcp :9564
olliesrv -tcp :9564
# Locally:
olliesrv mount remotehost:9564 ~/mnt/remotehost

96
main.go
View File

@ -87,15 +87,10 @@ func (c *ModelCache) Invalidate() {
}
func main() {
if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, "usage: olliesrv <start|fgstart|stop|status|mount>")
os.Exit(1)
}
subcmd := os.Args[1]
flag.CommandLine.Parse(os.Args[2:]) //nolint:errcheck
flag.CommandLine.Parse(os.Args[1:]) //nolint:errcheck
switch subcmd {
case "mount":
// Handle mount subcommand (kept as a convenience)
if flag.NArg() > 0 && flag.Arg(0) == "mount" {
cmdMount()
return
}
@ -107,34 +102,7 @@ func main() {
}
sockPath := filepath.Join(ns, serviceName)
pidPath := filepath.Join(ns, serviceName+".pid")
switch subcmd {
case "start":
if isRunning(sockPath) {
fmt.Println("olliesrv already running")
os.Exit(0)
}
daemonize(pidPath)
case "fgstart":
if isRunning(sockPath) {
fmt.Println("olliesrv already running")
os.Exit(0)
}
runServer(sockPath, pidPath)
case "stop":
stopServer(sockPath, pidPath)
case "status":
if isRunning(sockPath) {
fmt.Println("olliesrv running")
} else {
fmt.Println("olliesrv not running")
os.Exit(1)
}
default:
fmt.Fprintln(os.Stderr, "usage: olliesrv <start|fgstart|stop|status|mount>")
os.Exit(1)
}
runServer(sockPath)
}
func cmdMount() {
@ -167,59 +135,13 @@ func cmdMount() {
fmt.Printf("mounted %s at %s (pid %d)\n", addr, mnt, cmd.Process.Pid)
}
func isRunning(sockPath string) bool {
conn, err := net.Dial("unix", sockPath)
if err == nil {
conn.Close()
return true
}
return false
}
func daemonize(pidPath string) {
exe, _ := os.Executable()
args := []string{"fgstart"}
if *tcpAddr != "" {
args = append(args, "-tcp", *tcpAddr)
}
if *strict {
args = append(args, "-strict")
}
if *yolo {
args = append(args, "-yolo")
}
if *nodbus {
args = append(args, "-nodbus")
}
if *no9p {
args = append(args, "-no9p")
}
cmd := exec.Command(exe, args...)
cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true}
if err := cmd.Start(); err != nil {
fmt.Fprintf(os.Stderr, "failed to start: %v\n", err)
os.Exit(1)
}
fmt.Printf("olliesrv started (pid %d)\n", cmd.Process.Pid)
}
func stopServer(sockPath, pidPath string) {
data, err := os.ReadFile(pidPath)
if err != nil {
fmt.Println("olliesrv not running")
return
}
var pid int
fmt.Sscanf(string(data), "%d", &pid)
if pid > 0 {
syscall.Kill(pid, syscall.SIGTERM) //nolint:errcheck
}
os.Remove(sockPath) //nolint:errcheck
os.Remove(pidPath) //nolint:errcheck
fmt.Println("olliesrv stopped")
}
func runServer(sockPath, pidPath string) {
func runServer(sockPath string) {
env.EnsureDefaults()
// -no9p requires D-Bus (otherwise there's no interface at all)
@ -236,7 +158,6 @@ func runServer(sockPath, pidPath string) {
}
// Write PID file
os.WriteFile(pidPath, []byte(fmt.Sprintf("%d", os.Getpid())), fs.Perms[fs.PathRoot].FileMode) //nolint:errcheck
sink := olog.NewSink(os.Stdout, os.Stderr, olog.ParseLevel(os.Getenv("OLLIE_LOG"), olog.LevelWarn))
@ -371,7 +292,6 @@ func runServer(sockPath, pidPath string) {
if !*no9p {
os.Remove(sockPath)
}
os.Remove(pidPath)
sink.Flush()
}

View File

@ -1,11 +0,0 @@
[Desktop Entry]
Type=Application
Name=Ollie Server
GenericName=AI Agent 9P Server
Comment=9P server for Ollie AI agent sessions (includes embedded D-Bus adapter)
Exec=sh -c 'olliesrv start; sleep 3; ollie-remount'
Icon=ollie
Terminal=false
Categories=Utility;
X-DBUS-StartupType=unique
X-DBUS-ServiceName=org.ollie.SessionManager