|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +BPI Stack is a Python CLI tool for building, deploying, and managing software "stacks" — groups of containers defined in a component model similar to Docker Compose. It abstracts over Docker Compose and Kubernetes, allowing transparent deployment to either target. |
| 6 | + |
| 7 | +**Repository:** https://github.com/bozemanpass/stack |
| 8 | +**License:** AGPL-3.0 |
| 9 | + |
| 10 | +## Quick Reference |
| 11 | + |
| 12 | +- **Language:** Python 3.10+ |
| 13 | +- **CLI framework:** Click |
| 14 | +- **Entry point:** `src/stack/main.py` → `cli` group |
| 15 | +- **Package name:** `stack` (invoked as `stack` on the command line) |
| 16 | +- **Version:** defined in `pyproject.toml` |
| 17 | + |
| 18 | +## Development Setup |
| 19 | + |
| 20 | +```bash |
| 21 | +# Install dependencies (creates .venv via uv) |
| 22 | +./scripts/developer-mode-setup.sh |
| 23 | + |
| 24 | +# Run the CLI in dev mode |
| 25 | +uv run stack |
| 26 | + |
| 27 | +# Build a distributable zipapp |
| 28 | +./scripts/build_shiv_package.sh |
| 29 | +``` |
| 30 | + |
| 31 | +## Linting |
| 32 | + |
| 33 | +```bash |
| 34 | +uv run flake8 --config tox.ini |
| 35 | +``` |
| 36 | + |
| 37 | +Formatting uses `black` (available via `uv run black`). Linting config is in `tox.ini`. |
| 38 | + |
| 39 | +## Testing |
| 40 | + |
| 41 | +Tests are **bash shell scripts**, not pytest. They require Docker and/or Kubernetes (Kind) to be available. |
| 42 | + |
| 43 | +```bash |
| 44 | +# Smoke tests (basic CLI functionality) |
| 45 | +./tests/smoke-test/run-smoke-test.sh |
| 46 | + |
| 47 | +# Docker deployment tests |
| 48 | +./tests/deploy/run-deploy-test.sh |
| 49 | + |
| 50 | +# Kubernetes deployment tests |
| 51 | +./tests/k8s-deploy/run-k8s-deploy-test.sh |
| 52 | +``` |
| 53 | + |
| 54 | +The smoke tests require building a shiv package first (`./scripts/build_shiv_package.sh`). |
| 55 | + |
| 56 | +## Source Layout |
| 57 | + |
| 58 | +``` |
| 59 | +src/stack/ |
| 60 | +├── main.py # CLI entry point (Click commands) |
| 61 | +├── util.py # Shared utilities |
| 62 | +├── log.py # Logging (colored, timestamped) |
| 63 | +├── constants.py # Configuration constants |
| 64 | +├── deploy/ |
| 65 | +│ ├── stack.py # Stack model (parsed from stack.yml) |
| 66 | +│ ├── spec.py # Deployment specification (Spec, MergedSpec) |
| 67 | +│ ├── deployer.py # Abstract Deployer base class |
| 68 | +│ ├── deployer_factory.py # Factory: returns Docker or K8s deployer |
| 69 | +│ ├── deployment.py # Deployment orchestration |
| 70 | +│ ├── deployment_context.py # Tracks deployment directory/files |
| 71 | +│ ├── compose/ # Docker Compose deployer implementation |
| 72 | +│ │ └── deploy_docker.py |
| 73 | +│ └── k8s/ # Kubernetes deployer implementation |
| 74 | +│ ├── deploy_k8s.py |
| 75 | +│ ├── helpers.py |
| 76 | +│ └── cluster_info.py |
| 77 | +├── build/ # Container building and publishing |
| 78 | +├── repos/ # Git repository management |
| 79 | +├── config/ # Profile-based configuration |
| 80 | +├── init/ # Stack specification generation |
| 81 | +├── chart/ # Mermaid diagram generation |
| 82 | +├── webapp/ # Web application framework |
| 83 | +└── data/ # Embedded templates, K8s components |
| 84 | +``` |
| 85 | + |
| 86 | +## Key Abstractions |
| 87 | + |
| 88 | +- **Stack** (`deploy/stack.py`): Parsed from `stack.yml` files. Defines containers, pods, and their relationships. Supports "super stacks" (composition of stacks). |
| 89 | +- **Spec** (`deploy/spec.py`): Deployment specification — references a stack plus deployment config (target, volumes, resources, HTTP proxy). `MergedSpec` combines multiple specs. |
| 90 | +- **Deployer** (`deploy/deployer.py`): Abstract base with `up()`, `down()`, `ps()`, `logs()`, `execute()`, etc. Two implementations: |
| 91 | + - `DockerDeployer` — generates Docker Compose YAML, uses `python-on-whales` |
| 92 | + - `K8sDeployer` — uses the `kubernetes` Python client, supports Kind for local clusters |
| 93 | +- **DeployerFactory** (`deploy/deployer_factory.py`): Returns the correct deployer based on `deploy-to` field in the spec (`compose`, `k8s`, `k8s-kind`). |
| 94 | + |
| 95 | +## CLI Commands |
| 96 | + |
| 97 | +Core commands defined in `main.py`: |
| 98 | +- `deploy` — create a deployment from a spec file |
| 99 | +- `manage` — manage a running deployment (start, stop, logs, exec, status) |
| 100 | +- `build containers` — build container images |
| 101 | +- `fetch` — clone/fetch git repositories |
| 102 | +- `init` — generate a spec file |
| 103 | +- `prepare` — build/download containers |
| 104 | +- `list` — list available stacks |
| 105 | +- `config` — manage configuration profiles |
| 106 | +- `version` / `update` / `webapp` / `chart` |
| 107 | + |
| 108 | +Stacks can also provide custom subcommands loaded dynamically. |
| 109 | + |
| 110 | +## Key Dependencies |
| 111 | + |
| 112 | +- `click` — CLI framework |
| 113 | +- `python-on-whales` (pinned 0.63.0) — Docker client |
| 114 | +- `kubernetes` — K8s API client |
| 115 | +- `GitPython` — git operations |
| 116 | +- `PyYAML` / `ruamel.yaml.string` — YAML parsing |
| 117 | +- `humanfriendly` — human-readable resource sizes |
| 118 | + |
| 119 | +## Build & CI |
| 120 | + |
| 121 | +- Build backend: `uv_build` |
| 122 | +- CI runs on GitHub Actions (see `.github/workflows/`) |
| 123 | +- Workflows: `lint.yml`, `test.yml`, `test-deploy.yml`, `test-deploy-k8s.yml`, `test-database.yml`, `test-webapp.yml`, `publish.yml` |
0 commit comments