docs: add group deployment support to homelab-deploy plan
All checks were successful
Run nix flake check / flake-check (push) Successful in 2m3s
All checks were successful
Run nix flake check / flake-check (push) Successful in 2m3s
Support deploying to all hosts in a tier or all hosts with a role: - deploy.<tier>.all - broadcast to all hosts in tier - deploy.<tier>.role.<role> - broadcast to hosts with matching role MCP can deploy to all test hosts at once, admin can deploy to any group. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -74,8 +74,10 @@ homelab-deploy listener --hostname ns1 --nats-url nats://nats1:4222
|
|||||||
homelab-deploy mcp --nats-url nats://nats1:4222
|
homelab-deploy mcp --nats-url nats://nats1:4222
|
||||||
|
|
||||||
# CLI commands for manual use
|
# CLI commands for manual use
|
||||||
homelab-deploy deploy ns1 --branch feature-x --action switch
|
homelab-deploy deploy ns1 --branch feature-x --action switch # single host
|
||||||
homelab-deploy deploy --all --action boot
|
homelab-deploy deploy --tier test --all --action boot # all test hosts
|
||||||
|
homelab-deploy deploy --tier prod --all --action boot # all prod hosts (admin only)
|
||||||
|
homelab-deploy deploy --tier prod --role dns --action switch # all prod dns hosts
|
||||||
homelab-deploy status
|
homelab-deploy status
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -84,11 +86,28 @@ homelab-deploy status
|
|||||||
### Listener Mode
|
### Listener Mode
|
||||||
|
|
||||||
A systemd service on each host that:
|
A systemd service on each host that:
|
||||||
- Subscribes to `deploy.<tier>.<hostname>` and `deploy.<tier>.all` subjects
|
- Subscribes to multiple subjects for targeted and group deployments
|
||||||
- Validates incoming messages (revision, action)
|
- Validates incoming messages (revision, action)
|
||||||
- Executes `nixos-rebuild` with specified parameters
|
- Executes `nixos-rebuild` with specified parameters
|
||||||
- Reports status back via NATS
|
- Reports status back via NATS
|
||||||
|
|
||||||
|
**Subject structure:**
|
||||||
|
```
|
||||||
|
deploy.<tier>.<hostname> # specific host (e.g., deploy.prod.ns1)
|
||||||
|
deploy.<tier>.all # all hosts in tier (e.g., deploy.test.all)
|
||||||
|
deploy.<tier>.role.<role> # all hosts with role in tier (e.g., deploy.prod.role.dns)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Listener subscriptions** (based on `homelab.host` config):
|
||||||
|
- `deploy.<tier>.<hostname>` - direct messages to this host
|
||||||
|
- `deploy.<tier>.all` - broadcast to all hosts in tier
|
||||||
|
- `deploy.<tier>.role.<role>` - broadcast to hosts with matching role (if role is set)
|
||||||
|
|
||||||
|
Example: ns1 with `tier=prod, role=dns` subscribes to:
|
||||||
|
- `deploy.prod.ns1`
|
||||||
|
- `deploy.prod.all`
|
||||||
|
- `deploy.prod.role.dns`
|
||||||
|
|
||||||
**NixOS module configuration:**
|
**NixOS module configuration:**
|
||||||
```nix
|
```nix
|
||||||
services.homelab-deploy.listener = {
|
services.homelab-deploy.listener = {
|
||||||
@@ -97,7 +116,7 @@ services.homelab-deploy.listener = {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
The listener reads its tier from `config.homelab.host.tier` (see Host Metadata below) and subscribes to tier-specific subjects (e.g., `deploy.prod.ns1` and `deploy.prod.all`).
|
The listener reads tier and role from `config.homelab.host` (see Host Metadata below).
|
||||||
|
|
||||||
**Request message format:**
|
**Request message format:**
|
||||||
```json
|
```json
|
||||||
@@ -133,11 +152,16 @@ This provides immediate feedback on validation errors (bad revision, already run
|
|||||||
### MCP Mode
|
### MCP Mode
|
||||||
|
|
||||||
Runs as an MCP server providing tools for Claude Code:
|
Runs as an MCP server providing tools for Claude Code:
|
||||||
- `deploy` - Deploy to specific host(s) with optional revision
|
- `deploy` - Deploy to specific host, all hosts in tier, or all hosts with a role
|
||||||
- `deploy_status` - Check deployment status/history
|
- `deploy_status` - Check deployment status/history
|
||||||
- `list_hosts` - List available deployment targets
|
- `list_hosts` - List available deployment targets
|
||||||
|
|
||||||
The MCP server runs with limited credentials (test-tier only), so Claude can deploy to test hosts but not production.
|
The MCP server runs with limited credentials (test-tier only), so Claude can:
|
||||||
|
- Deploy to individual test hosts
|
||||||
|
- Deploy to all test hosts at once (`deploy.test.all`)
|
||||||
|
- Deploy to test hosts by role (`deploy.test.role.<role>`)
|
||||||
|
|
||||||
|
Production deployments require admin credentials.
|
||||||
|
|
||||||
### Tiered Permissions
|
### Tiered Permissions
|
||||||
|
|
||||||
@@ -183,11 +207,15 @@ accounts = {
|
|||||||
| test | template1, nix-cache01, future test hosts |
|
| test | template1, nix-cache01, future test hosts |
|
||||||
| prod | ns1, ns2, ha1, monitoring01, http-proxy, etc. |
|
| prod | ns1, ns2, ha1, monitoring01, http-proxy, etc. |
|
||||||
|
|
||||||
**How it works:**
|
**Example deployment scenarios:**
|
||||||
1. MCP tries to deploy to ns1 → publishes to `deploy.prod.ns1`
|
|
||||||
2. NATS server rejects publish (mcp-deployer lacks `deploy.prod.>` permission)
|
| Command | Subject | MCP | Admin |
|
||||||
3. MCP tries to deploy to template1 → publishes to `deploy.test.template1`
|
|---------|---------|-----|-------|
|
||||||
4. NATS allows it, listener receives and executes
|
| Deploy to ns1 | `deploy.prod.ns1` | ❌ | ✅ |
|
||||||
|
| Deploy to template1 | `deploy.test.template1` | ✅ | ✅ |
|
||||||
|
| Deploy to all test hosts | `deploy.test.all` | ✅ | ✅ |
|
||||||
|
| Deploy to all prod hosts | `deploy.prod.all` | ❌ | ✅ |
|
||||||
|
| Deploy to all DNS servers | `deploy.prod.role.dns` | ❌ | ✅ |
|
||||||
|
|
||||||
All NKeys stored in Vault - MCP gets limited credentials, admin CLI gets full-access credentials.
|
All NKeys stored in Vault - MCP gets limited credentials, admin CLI gets full-access credentials.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user