chore(maestro): retarget installer, e2e harness, and docs at unified maestro binary (NAP-245)
- Installer: one `cargo install maestro` instead of two; ExecStart becomes `~/.cargo/bin/maestro daemon`; user unit renamed `maestrod.service` → `maestro.service`; configure step is `maestro daemon configure`. - E2E harness: both `Daemon` and `Registry` subprocess wrappers shell out to the unified `maestro` binary with the appropriate subcommand. - State dir: `~/.local/state/maestrod` → `~/.local/state/maestro`. - Docs: CLAUDE.md repo layout, design spec repo layout + "Daemon (`maestro daemon`)" heading, INSTALL.md (full rewrite of CLI references + new thin-builds section).
This commit is contained in:
+49
-31
@@ -13,13 +13,13 @@ The repo is private, so grab `install.sh` while signed in to gitea, then run it:
|
||||
```
|
||||
|
||||
The bootstrap script builds `maestro-installer` into a temp directory, runs the
|
||||
wizard, and cleans up — only `maestrod` and `maestro` end up persisted in
|
||||
wizard, and cleans up — only the unified `maestro` binary ends up persisted in
|
||||
`~/.cargo/bin`.
|
||||
|
||||
**Updating is the same command.** Re-running `./install.sh` detects an
|
||||
existing `[daemon]` section in `~/.config/maestro/config.toml` and an
|
||||
existing systemd unit, skips the configure prompt, refreshes the unit, and
|
||||
runs `systemctl --user restart maestrod` instead of `start`. No `--update`
|
||||
runs `systemctl --user restart maestro` instead of `start`. No `--update`
|
||||
flag needed.
|
||||
|
||||
Inside the script, `cargo install --git https://git.naps.pt/naps62/maestro …`
|
||||
@@ -38,20 +38,39 @@ Pass flags through to the wizard after `./install.sh`:
|
||||
|
||||
The wizard:
|
||||
|
||||
1. Runs `cargo install` for `maestro-daemon` and `maestro-cli` (pinned to the
|
||||
committed `Cargo.lock` via `--locked`).
|
||||
2. Optionally runs `maestrod configure` to populate `~/.config/maestro/config.toml`
|
||||
(one shared TOML for `maestrod`, `maestro-registry`, and the `maestro` CLI).
|
||||
1. Runs `cargo install` for the unified `maestro` crate (pinned to the
|
||||
committed `Cargo.lock` via `--locked`). The same binary hosts the CLI,
|
||||
the per-host daemon (`maestro daemon`), and the always-on registry
|
||||
(`maestro registry`), gated by Cargo features.
|
||||
2. Optionally runs `maestro daemon configure` to populate `~/.config/maestro/config.toml`
|
||||
(one shared TOML for the CLI, daemon, registry, and web).
|
||||
3. On systemd hosts, optionally writes a user unit at
|
||||
`~/.config/systemd/user/maestrod.service`, reloads systemd, and offers to
|
||||
`~/.config/systemd/user/maestro.service`, reloads systemd, and offers to
|
||||
enable + start it.
|
||||
|
||||
Both binaries land in `~/.cargo/bin` — make sure that's on your `$PATH`.
|
||||
The binary lands in `~/.cargo/bin/maestro` — make sure that's on your `$PATH`.
|
||||
|
||||
## Thin builds for single-role hosts
|
||||
|
||||
The default install pulls in everything. Registry-only and daemon-only hosts
|
||||
can opt out of unused dependencies:
|
||||
|
||||
```sh
|
||||
# Registry server — no tmux/PTY/jwt-verifier code:
|
||||
cargo install --git https://git.naps.pt/naps62/maestro \
|
||||
--no-default-features --features registry --locked maestro
|
||||
|
||||
# Daemon-only host — no embedded web assets, no registry HTTP surface:
|
||||
cargo install --git https://git.naps.pt/naps62/maestro \
|
||||
--no-default-features --features daemon --locked maestro
|
||||
```
|
||||
|
||||
The wizard always installs the default-feature build.
|
||||
|
||||
## Adding the browser UI (optional)
|
||||
|
||||
`maestro-web` is a separate binary that serves the SPA bundle and reverse-
|
||||
proxies API calls to a co-located `maestrod`.
|
||||
proxies API calls to a co-located `maestro daemon`.
|
||||
|
||||
**Interactive install (default path).** The wizard now offers it as an
|
||||
optional step right after the daemon flow:
|
||||
@@ -63,7 +82,7 @@ Install maestro-web? [Y/n]
|
||||
|
||||
Press `Y` and it `cargo install`s `maestro-web`, drops a
|
||||
`~/.config/systemd/user/maestro-web.service` unit (ordered after
|
||||
`maestrod.service`), reloads systemd, and offers to enable + start it. Re-runs
|
||||
`maestro.service`), reloads systemd, and offers to enable + start it. Re-runs
|
||||
of `./install.sh` detect the existing unit and refresh + restart silently.
|
||||
|
||||
Pass `--no-web` to skip the prompt entirely (headless hosts), or `--yes`
|
||||
@@ -100,18 +119,18 @@ where you want browser access answer yes — both binaries end up in
|
||||
|---|---|
|
||||
| `--git <url>` | Install from a different git repo (default: this one). |
|
||||
| `--branch <name>` | Pin a branch with `--git`. |
|
||||
| `--path <dir>` | Install from a local workspace checkout (`--path` + `-p <crate>`). |
|
||||
| `--path <dir>` | Install from a local workspace checkout (`--path` + `-p maestro`). |
|
||||
| `--no-locked` | Drop `--locked` from `cargo install` (resolves a fresh dep tree). |
|
||||
| `--exec-start <path>` | Override the systemd unit's `ExecStart` (default `~/.cargo/bin/maestrod`). |
|
||||
| `--exec-start <path>` | Override the systemd unit's `ExecStart` (default `~/.cargo/bin/maestro daemon`). |
|
||||
| `--no-systemd` | Skip the systemd step even if detected. |
|
||||
| `--no-configure` | Skip the `maestrod configure` step. |
|
||||
| `--no-configure` | Skip the `maestro daemon configure` step. |
|
||||
| `--no-web` | Skip the optional `maestro-web` install step. |
|
||||
| `--web-exec-start <path>` | Override the web unit's `ExecStart` (default `~/.cargo/bin/maestro-web`). |
|
||||
| `-y`, `--yes` | Non-interactive: install binaries + drop systemd unit + reload + enable, but **don't** auto-run `configure` or auto-start the unit (those need real config). Also skips the web step unless an existing `maestro-web.service` is being refreshed. |
|
||||
|
||||
## Where tmux sockets land
|
||||
|
||||
`maestrod` defaults `TMUX_TMPDIR` to `$XDG_RUNTIME_DIR` (= `/run/user/$UID`)
|
||||
`maestro daemon` defaults `TMUX_TMPDIR` to `$XDG_RUNTIME_DIR` (= `/run/user/$UID`)
|
||||
so a plain `tmux ls` in your shell — which typically uses the same env var
|
||||
— sees maestro-managed sessions. Override in
|
||||
`~/.config/maestro/config.toml`:
|
||||
@@ -129,13 +148,13 @@ precedence over the file.
|
||||
## Hot-reloading policy
|
||||
|
||||
`[daemon.policy].allow_inbound` (the list of peer daemons allowed to broker-
|
||||
attach into this one) can be changed without restarting `maestrod` — restarting
|
||||
would kill every live session. Two ways to apply an edit:
|
||||
attach into this one) can be changed without restarting the daemon — restarting
|
||||
would kill every live session. Three ways to apply an edit:
|
||||
|
||||
```sh
|
||||
maestro policy reload # POSTs to the local daemon's /api/policy/reload
|
||||
maestro policy show # prints the current effective list
|
||||
kill -HUP <maestrod-pid> # equivalent; what `systemctl --user reload` does
|
||||
kill -HUP <maestro-pid> # equivalent; what `systemctl --user reload` does
|
||||
```
|
||||
|
||||
Only newly-arriving attach attempts see the change — sessions already
|
||||
@@ -143,18 +162,18 @@ attached stay attached. To boot a live attacher out, kill the session.
|
||||
|
||||
## What the systemd unit looks like
|
||||
|
||||
The wizard writes a *user* unit (`systemctl --user`), since `maestrod` runs
|
||||
per-user and uses tmux sockets under `$XDG_RUNTIME_DIR`. Body:
|
||||
The wizard writes a *user* unit (`systemctl --user`), since `maestro daemon`
|
||||
runs per-user and uses tmux sockets under `$XDG_RUNTIME_DIR`. Body:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Maestro per-host daemon (maestrod)
|
||||
Description=Maestro per-host daemon
|
||||
Documentation=https://git.naps.pt/naps62/maestro
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=%h/.cargo/bin/maestrod
|
||||
ExecStart=%h/.cargo/bin/maestro daemon
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
@@ -166,8 +185,8 @@ WantedBy=default.target
|
||||
Check status / logs:
|
||||
|
||||
```sh
|
||||
systemctl --user status maestrod
|
||||
journalctl --user -u maestrod -f
|
||||
systemctl --user status maestro
|
||||
journalctl --user -u maestro -f
|
||||
```
|
||||
|
||||
## Running the wizard without the bootstrap script
|
||||
@@ -185,15 +204,14 @@ script avoids that by installing to a scratch dir.
|
||||
## Fully manual install (no wizard)
|
||||
|
||||
```sh
|
||||
cargo install --git https://git.naps.pt/naps62/maestro --locked maestro-daemon
|
||||
cargo install --git https://git.naps.pt/naps62/maestro --locked maestro-cli
|
||||
maestrod configure
|
||||
maestrod # foreground; or wire your own service manager
|
||||
cargo install --git https://git.naps.pt/naps62/maestro --locked maestro
|
||||
maestro daemon configure
|
||||
maestro daemon # foreground; or wire your own service manager
|
||||
```
|
||||
|
||||
## Non-Linux hosts
|
||||
|
||||
The wizard works on macOS for the `cargo install` + `maestrod configure` parts.
|
||||
The systemd step is automatically skipped (probe of `/run/systemd/system`).
|
||||
launchd integration is not yet supported — start `maestrod` from your shell or
|
||||
your own service manager.
|
||||
The wizard works on macOS for the `cargo install` + `maestro daemon configure`
|
||||
parts. The systemd step is automatically skipped (probe of
|
||||
`/run/systemd/system`). launchd integration is not yet supported — start
|
||||
`maestro daemon` from your shell or your own service manager.
|
||||
|
||||
Reference in New Issue
Block a user