Skip to content

Commit 0cc2375

Browse files
committed
feat: agent runs as system service via kardianos/service
Integrate github.com/kardianos/service so the Go agent can install itself as a system service (launchd on macOS, systemd on Linux, Windows service). Three CLI modes: - No args: interactive setup wizard that registers, installs, and starts the service — the friend-friendly double-click path - --run: foreground mode for Docker/service manager/development - --service <action>: power-user install/uninstall/start/stop/restart/status Automatically requests sudo when elevation is needed. Bakes PLOW_DATA_DIR into the service env so the daemon finds credentials generated by the installing user. Clears stale service state before reinstalling to avoid launchd throttle errors from prior crash loops.
1 parent 8540332 commit 0cc2375

9 files changed

Lines changed: 639 additions & 125 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ dist/
1010
src/where_the_plow/static/changelog.html
1111
tmp
1212
agent/plow-agent
13+
.DS_Store

agent/Dockerfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
FROM golang:1.22-alpine AS builder
1+
FROM golang:1.25-alpine AS builder
22
WORKDIR /build
3-
COPY go.mod ./
3+
COPY go.mod go.sum ./
44
RUN go mod download
55
COPY *.go ./
66
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /plow-agent .
77

88
FROM scratch
99
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
1010
COPY --from=builder /plow-agent /plow-agent
11-
ENTRYPOINT ["/plow-agent"]
11+
ENTRYPOINT ["/plow-agent", "--run"]

agent/README.md

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,55 @@ The city publishes real-time plow locations on their [AVL map](https://map.stjoh
1515

1616
Your credentials are stored locally and reused on subsequent runs. The agent uses minimal resources and runs quietly in the background.
1717

18-
## Running
18+
## Quick start (recommended)
1919

20-
### Binary
20+
Download the latest release for your platform, then just run it:
2121

22-
Download the latest release for your platform, then:
22+
```
23+
./plow-agent
24+
```
25+
26+
This launches an interactive setup wizard that:
27+
1. Asks for the server URL (defaults to `https://plow.jackharrhy.dev`)
28+
2. Prompts for a name to identify your agent (e.g. "alice-laptop")
29+
3. Generates your cryptographic keypair
30+
4. Registers with the server
31+
5. Installs itself as a **system service** (systemd on Linux, launchd on macOS, Windows service)
32+
6. Starts the service automatically
33+
34+
After setup, the agent runs in the background and survives reboots. You don't need to keep a terminal open.
35+
36+
**Note:** Installing a system service usually requires administrator/root privileges. On Linux, run with `sudo`. On macOS, you may get a permissions prompt. On Windows, run as Administrator.
37+
38+
## Running interactively
39+
40+
If you prefer not to install a service (or for Docker/development use):
41+
42+
```
43+
./plow-agent --run --server https://plow.jackharrhy.dev
44+
```
45+
46+
This runs the agent in the foreground. Press Ctrl+C to stop.
47+
48+
## Managing the service
49+
50+
Once installed, you can control the service with:
2351

2452
```
25-
./plow-agent --server https://plow.jackharrhy.dev
53+
plow-agent --service status # Check if running
54+
plow-agent --service stop # Stop the service
55+
plow-agent --service start # Start the service
56+
plow-agent --service restart # Restart the service
57+
plow-agent --service uninstall # Remove the service
2658
```
2759

28-
On first run it will ask for a name to identify your agent (e.g. "alice-laptop"). The keypair and name are saved to `~/.config/plow-agent/` so you only do this once.
60+
### Viewing logs
2961

30-
That's it. Leave it running and the server operator will approve you.
62+
- **Linux (systemd):** `journalctl -u plow-agent -f`
63+
- **macOS (launchd):** `log show --predicate 'process == "plow-agent"' --last 1h`
64+
- **Windows:** Event Viewer > Application logs
3165

32-
### Docker
66+
## Docker
3367

3468
```
3569
docker run -d \
@@ -48,7 +82,7 @@ To build the image yourself:
4882
docker build -t plow-agent agent/
4983
```
5084

51-
### Kubernetes
85+
## Kubernetes
5286

5387
A ready-made manifest is included at [`k8s.yaml`](k8s.yaml). Edit `PLOW_NAME` to your name, then:
5488

@@ -62,9 +96,11 @@ This creates a small PVC for key persistence and a Deployment running the agent.
6296

6397
| Flag / Env Var | Required | Description |
6498
|---|---|---|
65-
| `--server` / `PLOW_SERVER` | Yes | Plow server URL |
99+
| `--server` / `PLOW_SERVER` | Yes (for `--run`) | Plow server URL |
100+
| `--run` | No | Run in foreground instead of installing as service |
101+
| `--service <action>` | No | Control installed service: install, uninstall, start, stop, restart, status |
66102
| `PLOW_NAME` | Docker/K8s only | Agent name (binary prompts interactively) |
67-
| `PLOW_DATA_DIR` | No | Override config directory (default: `~/.config/plow-agent/`, or `/data` when `PLOW_DATA_DIR` is set) |
103+
| `PLOW_DATA_DIR` | No | Override config directory (default: `~/.config/plow-agent/`, or `/data` when set) |
68104

69105
## What gets stored locally
70106

agent/go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
module github.com/jackharrhy/plow-agent
22

33
go 1.25.6
4+
5+
require (
6+
github.com/kardianos/service v1.2.4 // indirect
7+
golang.org/x/sys v0.34.0 // indirect
8+
)

agent/go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
github.com/kardianos/service v1.2.4 h1:XNlGtZOYNx2u91urOdg/Kfmc+gfmuIo1Dd3rEi2OgBk=
2+
github.com/kardianos/service v1.2.4/go.mod h1:E4V9ufUuY82F7Ztlu1eN9VXWIQxg8NoLQlmFe0MtrXc=
3+
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
4+
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=

agent/k8s.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ spec:
2727
containers:
2828
- name: plow-agent
2929
image: ghcr.io/jackharrhy/plow-agent:latest
30-
args: ["--server", "https://plow.jackharrhy.dev"]
30+
args: ["--run", "--server", "https://plow.jackharrhy.dev"]
3131
env:
3232
- name: PLOW_NAME
3333
value: "your-name-here"

0 commit comments

Comments
 (0)