67 lines
3.7 KiB
Markdown
67 lines
3.7 KiB
Markdown
# Pegasus Monitor
|
|
|
|
Native macOS SwiftUI menu-bar health monitor for Pegasus.
|
|
|
|
## Setup on Pegasus (Ubuntu)
|
|
|
|
The existing `/usr/local/bin/pegasus-health` must support `--verbose` and use the updated checks (no Time Machine, Domino at `192.168.1.50`, Cockpit at `192.168.1.2`, and `saturn.absdev.net`). The adapter does **not** replace or modify that existing script.
|
|
|
|
Copy `server/pegasus-health-json` to Pegasus then install:
|
|
|
|
```bash
|
|
sudo install -o root -g root -m 755 pegasus-health-json /usr/local/bin/pegasus-health-json
|
|
sudo /usr/local/bin/pegasus-health-json | python3 -m json.tool | head -30
|
|
```
|
|
|
|
For the app to poll automatically, configure **restricted passwordless sudo** for the JSON command only. Run `sudo visudo -f /etc/sudoers.d/pegasus-health-monitor` and enter:
|
|
|
|
```
|
|
mag ALL=(root) NOPASSWD: /usr/local/bin/pegasus-health-json
|
|
```
|
|
|
|
Both `/usr/local/bin/pegasus-health-json` and `/usr/local/bin/pegasus-health` must be root-owned and not writable by `mag` or any other non-root user. **Do not** grant `NOPASSWD` to arbitrary commands or to `python3` globally. The adapter executes only the fixed health command and accepts no user-controlled command strings.
|
|
|
|
From your Mac confirm:
|
|
|
|
```bash
|
|
ssh -o BatchMode=yes mag@192.168.1.2 'sudo -n /usr/local/bin/pegasus-health-json' | python3 -m json.tool | head -35
|
|
```
|
|
|
|
Use SSH keys and trust the host key from an interactive SSH login before first running the app. The macOS app uses `BatchMode=yes` and `StrictHostKeyChecking=yes`, and will not present password prompts.
|
|
|
|
## Build on macOS
|
|
|
|
Open `PegasusMonitor.xcodeproj` in Xcode and choose the PegasusMonitor scheme. Set your signing team as appropriate, then Build & Run. The app requires macOS 14.0 or newer. No third-party dependencies are required.
|
|
|
|
The app appears as a status icon in the macOS menu bar, not the Dock. It polls every five minutes by default (configurable), shows 14 aggregated categories and per-check diagnostics, and sends notifications when a previously healthy server becomes unhealthy. The server JSON adapter is read-only; it never restarts services.
|
|
|
|
## Diagnostics
|
|
|
|
- `ssh -v mag@192.168.1.2`: confirm SSH key authentication.
|
|
- `sudo -n /usr/local/bin/pegasus-health-json`: confirm restricted sudo.
|
|
- A non-zero SSH command exit code of 1/2 can indicate warnings/failures; the tool still emits JSON.
|
|
- A missing required check is classified as **fail**, not green.
|
|
- VM NRPC checks confirm TCP reachability; backup checks do not validate Borg archive integrity.
|
|
|
|
## Design
|
|
|
|
`PegasusMonitorApp.swift`: `MenuBarExtra` entry and Settings scene.
|
|
`ServerMonitor.swift`: async SSH runner, JSON decoding, polling and notifications.
|
|
`MonitorMenuView.swift`: summary and drill-down details.
|
|
`SettingsView.swift`: SSH configuration and interval.
|
|
`server/pegasus-health-json`: read-only JSON adapter for the existing health script.
|
|
|
|
## Build and release scripts
|
|
|
|
Run from the project root:
|
|
|
|
```zsh
|
|
./Scripts/build.sh # Debug build; launches the app
|
|
LAUNCH_AFTER_BUILD=0 ./Scripts/build.sh # Debug build without launching
|
|
./Scripts/release.sh # Signed Release DMG in dist/
|
|
NOTARY_PROFILE=your-profile ./Scripts/release.sh # Notarize + staple DMG
|
|
ALLOW_UNSIGNED=1 ./Scripts/release.sh # Local testing only
|
|
```
|
|
|
|
Release automatically selects the first `Developer ID Application` identity from the login keychain, or honors `SIGNING_IDENTITY`. It requires an identity unless `ALLOW_UNSIGNED=1`. Signing and notarization do **not** happen in `build.sh`. Script-built artifacts are written to `.build/` and `dist/`. The DMG is assembled after successful compilation and signing. These scripts do not change Xcode project version numbers; change `MARKETING_VERSION` and `CURRENT_PROJECT_VERSION` in Xcode before a release.
|