mirror of
https://github.com/basnijholt/compose-farm.git
synced 2026-02-03 14:13:26 +00:00
cli: Add list command with ls alias (#158)
This commit is contained in:
@@ -17,7 +17,7 @@ src/compose_farm/
|
|||||||
│ ├── config.py # Config subcommand (init, show, path, validate, edit, symlink)
|
│ ├── config.py # Config subcommand (init, show, path, validate, edit, symlink)
|
||||||
│ ├── lifecycle.py # up, down, stop, pull, restart, update, apply, compose commands
|
│ ├── lifecycle.py # up, down, stop, pull, restart, update, apply, compose commands
|
||||||
│ ├── management.py # refresh, check, init-network, traefik-file commands
|
│ ├── management.py # refresh, check, init-network, traefik-file commands
|
||||||
│ ├── monitoring.py # logs, ps, stats commands
|
│ ├── monitoring.py # logs, ps, stats, list commands
|
||||||
│ ├── ssh.py # SSH key management (setup, status, keygen)
|
│ ├── ssh.py # SSH key management (setup, status, keygen)
|
||||||
│ └── web.py # Web UI server command
|
│ └── web.py # Web UI server command
|
||||||
├── compose.py # Compose file parsing (.env, ports, volumes, networks)
|
├── compose.py # Compose file parsing (.env, ports, volumes, networks)
|
||||||
@@ -157,6 +157,7 @@ CLI available as `cf` or `compose-farm`.
|
|||||||
| `logs` | Show stack logs |
|
| `logs` | Show stack logs |
|
||||||
| `ps` | Show status of all stacks |
|
| `ps` | Show status of all stacks |
|
||||||
| `stats` | Show overview (hosts, stacks, pending migrations; `--live` for container counts) |
|
| `stats` | Show overview (hosts, stacks, pending migrations; `--live` for container counts) |
|
||||||
|
| `list` | List stacks and hosts (`--simple` for scripting, `--host` to filter) |
|
||||||
| `refresh` | Update state from reality: discover running stacks, capture image digests |
|
| `refresh` | Update state from reality: discover running stacks, capture image digests |
|
||||||
| `check` | Validate config, traefik labels, mounts, networks; show host compatibility |
|
| `check` | Validate config, traefik labels, mounts, networks; show host compatibility |
|
||||||
| `init-network` | Create Docker network on hosts with consistent subnet/gateway |
|
| `init-network` | Create Docker network on hosts with consistent subnet/gateway |
|
||||||
|
|||||||
37
README.md
37
README.md
@@ -395,6 +395,7 @@ Multi-host orchestration that Docker Compose can't do:
|
|||||||
| `cf traefik-file` | Generate Traefik file-provider config |
|
| `cf traefik-file` | Generate Traefik file-provider config |
|
||||||
| `cf config` | Manage config files (init, show, validate, edit, symlink) |
|
| `cf config` | Manage config files (init, show, validate, edit, symlink) |
|
||||||
| `cf ssh` | Manage SSH keys (setup, status, keygen) |
|
| `cf ssh` | Manage SSH keys (setup, status, keygen) |
|
||||||
|
| `cf list` | List all stacks and their assigned hosts |
|
||||||
|
|
||||||
### Aliases
|
### Aliases
|
||||||
|
|
||||||
@@ -403,10 +404,11 @@ Short aliases for frequently used commands:
|
|||||||
| Alias | Command | Alias | Command |
|
| Alias | Command | Alias | Command |
|
||||||
|-------|---------|-------|---------|
|
|-------|---------|-------|---------|
|
||||||
| `cf a` | `apply` | `cf s` | `stats` |
|
| `cf a` | `apply` | `cf s` | `stats` |
|
||||||
| `cf l` | `logs` | `cf c` | `compose` |
|
| `cf l` | `logs` | `cf ls` | `list` |
|
||||||
| `cf r` | `restart` | `cf rf` | `refresh` |
|
| `cf r` | `restart` | `cf rf` | `refresh` |
|
||||||
| `cf u` | `update` | `cf ck` | `check` |
|
| `cf u` | `update` | `cf ck` | `check` |
|
||||||
| `cf p` | `pull` | `cf tf` | `traefik-file` |
|
| `cf p` | `pull` | `cf tf` | `traefik-file` |
|
||||||
|
| `cf c` | `compose` | | |
|
||||||
|
|
||||||
Each command replaces: look up host → SSH → find compose file → run `ssh host "cd /opt/compose/plex && docker compose up -d"`.
|
Each command replaces: look up host → SSH → find compose file → run `ssh host "cd /opt/compose/plex && docker compose up -d"`.
|
||||||
|
|
||||||
@@ -511,6 +513,7 @@ Full `--help` output for each command. See the [Usage](#usage) table above for a
|
|||||||
│ service. │
|
│ service. │
|
||||||
│ ps Show status of stacks. │
|
│ ps Show status of stacks. │
|
||||||
│ stats Show overview statistics for hosts and stacks. │
|
│ stats Show overview statistics for hosts and stacks. │
|
||||||
|
│ list List all stacks and their assigned hosts. │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||||
╭─ Server ─────────────────────────────────────────────────────────────────────╮
|
╭─ Server ─────────────────────────────────────────────────────────────────────╮
|
||||||
│ web Start the web UI server. │
|
│ web Start the web UI server. │
|
||||||
@@ -1191,6 +1194,38 @@ Full `--help` output for each command. See the [Usage](#usage) table above for a
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>See the output of <code>cf list --help</code></summary>
|
||||||
|
|
||||||
|
<!-- CODE:BASH:START -->
|
||||||
|
<!-- echo '```yaml' -->
|
||||||
|
<!-- export NO_COLOR=1 -->
|
||||||
|
<!-- export TERM=dumb -->
|
||||||
|
<!-- export TERMINAL_WIDTH=90 -->
|
||||||
|
<!-- cf list --help -->
|
||||||
|
<!-- echo '```' -->
|
||||||
|
<!-- CODE:END -->
|
||||||
|
<!-- OUTPUT:START -->
|
||||||
|
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||||
|
```yaml
|
||||||
|
|
||||||
|
Usage: cf list [OPTIONS]
|
||||||
|
|
||||||
|
List all stacks and their assigned hosts.
|
||||||
|
|
||||||
|
╭─ Options ────────────────────────────────────────────────────────────────────╮
|
||||||
|
│ --host -H TEXT Filter to stacks on this host │
|
||||||
|
│ --simple -s Plain output (one stack per line, for scripting) │
|
||||||
|
│ --config -c PATH Path to config file │
|
||||||
|
│ --help -h Show this message and exit. │
|
||||||
|
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- OUTPUT:END -->
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
**Server**
|
**Server**
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ Commands are either **Docker Compose wrappers** (`up`, `down`, `stop`, `restart`
|
|||||||
| **Monitoring** | `ps` | Show stack status |
|
| **Monitoring** | `ps` | Show stack status |
|
||||||
| | `logs` | Show stack logs |
|
| | `logs` | Show stack logs |
|
||||||
| | `stats` | Show overview statistics |
|
| | `stats` | Show overview statistics |
|
||||||
|
| | `list` | List stacks and hosts |
|
||||||
| **Configuration** | `check` | Validate config and mounts |
|
| **Configuration** | `check` | Validate config and mounts |
|
||||||
| | `refresh` | Sync state from reality |
|
| | `refresh` | Sync state from reality |
|
||||||
| | `init-network` | Create Docker network |
|
| | `init-network` | Create Docker network |
|
||||||
@@ -45,10 +46,11 @@ Short aliases for frequently used commands:
|
|||||||
| Alias | Command | Alias | Command |
|
| Alias | Command | Alias | Command |
|
||||||
|-------|---------|-------|---------|
|
|-------|---------|-------|---------|
|
||||||
| `cf a` | `apply` | `cf s` | `stats` |
|
| `cf a` | `apply` | `cf s` | `stats` |
|
||||||
| `cf l` | `logs` | `cf c` | `compose` |
|
| `cf l` | `logs` | `cf ls` | `list` |
|
||||||
| `cf r` | `restart` | `cf rf` | `refresh` |
|
| `cf r` | `restart` | `cf rf` | `refresh` |
|
||||||
| `cf u` | `update` | `cf ck` | `check` |
|
| `cf u` | `update` | `cf ck` | `check` |
|
||||||
| `cf p` | `pull` | `cf tf` | `traefik-file` |
|
| `cf p` | `pull` | `cf tf` | `traefik-file` |
|
||||||
|
| `cf c` | `compose` | | |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -466,6 +468,40 @@ cf stats --live
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### cf list
|
||||||
|
|
||||||
|
List all stacks and their assigned hosts.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cf list [OPTIONS]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Options:**
|
||||||
|
|
||||||
|
| Option | Description |
|
||||||
|
|--------|-------------|
|
||||||
|
| `--host, -H TEXT` | Filter to stacks on this host |
|
||||||
|
| `--simple, -s` | Plain output for scripting (one stack per line) |
|
||||||
|
| `--config, -c PATH` | Path to config file |
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List all stacks
|
||||||
|
cf list
|
||||||
|
|
||||||
|
# Filter by host
|
||||||
|
cf list --host nas
|
||||||
|
|
||||||
|
# Plain output for scripting
|
||||||
|
cf list --simple
|
||||||
|
|
||||||
|
# Combine: list stack names on a specific host
|
||||||
|
cf list --host nuc --simple
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Configuration Commands
|
## Configuration Commands
|
||||||
|
|
||||||
### cf check
|
### cf check
|
||||||
|
|||||||
@@ -203,6 +203,43 @@ def stats(
|
|||||||
console.print(_build_summary_table(cfg, state, pending))
|
console.print(_build_summary_table(cfg, state, pending))
|
||||||
|
|
||||||
|
|
||||||
|
@app.command("list", rich_help_panel="Monitoring")
|
||||||
|
def list_(
|
||||||
|
host: HostOption = None,
|
||||||
|
simple: Annotated[
|
||||||
|
bool,
|
||||||
|
typer.Option("--simple", "-s", help="Plain output (one stack per line, for scripting)"),
|
||||||
|
] = False,
|
||||||
|
config: ConfigOption = None,
|
||||||
|
) -> None:
|
||||||
|
"""List all stacks and their assigned hosts."""
|
||||||
|
cfg = load_config_or_exit(config)
|
||||||
|
|
||||||
|
stacks: list[tuple[str, str | list[str]]] = list(cfg.stacks.items())
|
||||||
|
if host:
|
||||||
|
stacks = [(s, h) for s, h in stacks if str(h) == host or host in str(h).split(",")]
|
||||||
|
|
||||||
|
if simple:
|
||||||
|
for stack, _ in sorted(stacks):
|
||||||
|
console.print(stack)
|
||||||
|
else:
|
||||||
|
# Assign colors to hosts for visual grouping
|
||||||
|
host_colors = ["magenta", "cyan", "green", "yellow", "blue", "red"]
|
||||||
|
unique_hosts = sorted({str(h) for _, h in stacks})
|
||||||
|
host_color_map = {h: host_colors[i % len(host_colors)] for i, h in enumerate(unique_hosts)}
|
||||||
|
|
||||||
|
table = Table(title="Stacks", show_header=True, header_style="bold cyan")
|
||||||
|
table.add_column("Stack")
|
||||||
|
table.add_column("Host")
|
||||||
|
|
||||||
|
for stack, host_val in sorted(stacks):
|
||||||
|
color = host_color_map.get(str(host_val), "white")
|
||||||
|
table.add_row(f"[{color}]{stack}[/]", f"[{color}]{host_val}[/]")
|
||||||
|
|
||||||
|
console.print(table)
|
||||||
|
|
||||||
|
|
||||||
# Aliases (hidden from help)
|
# Aliases (hidden from help)
|
||||||
app.command("l", hidden=True)(logs) # cf l = cf logs
|
app.command("l", hidden=True)(logs) # cf l = cf logs
|
||||||
|
app.command("ls", hidden=True)(list_) # cf ls = cf list
|
||||||
app.command("s", hidden=True)(stats) # cf s = cf stats
|
app.command("s", hidden=True)(stats) # cf s = cf stats
|
||||||
|
|||||||
Reference in New Issue
Block a user