Rewrite README to match current state
Build now uses scripts/build.sh (Docker cross-compile, no Go install needed). Add Prereqs, docker-compose dev section, Architecture notes, and a list of intentional MVP stubs so reviewers know what's still scaffolded vs what's real.
This commit is contained in:
@@ -2,64 +2,110 @@
|
|||||||
|
|
||||||
Internal deployment platform for Backend/QA. Lets a developer deploy a feature
|
Internal deployment platform for Backend/QA. Lets a developer deploy a feature
|
||||||
branch into an isolated sandbox, with the API Gateway routing selected
|
branch into an isolated sandbox, with the API Gateway routing selected
|
||||||
services to the sandbox and the rest to OCP. See [REQUIREMENTS.md](REQUIREMENTS.md)
|
services to the sandbox and the rest to OCP. See
|
||||||
for the full spec.
|
[REQUIREMENTS.md](REQUIREMENTS.md) for the full spec.
|
||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
```
|
```
|
||||||
.
|
.
|
||||||
├── protocol/ # shared wire types (Event, DeployRequest)
|
├── protocol/ # shared wire types (Event, DeployRequest)
|
||||||
├── control-plane/ # Go. HTTP API + WS hub + SQLite/.log persistence
|
├── control-plane/ # Go. HTTP API + WS hub + SQLite/.log persistence
|
||||||
├── agent-micro/ # Go. Runs on 172.18.136.92, deploys Go microservices
|
├── agent-micro/ # Go. Runs on 172.18.136.92, deploys Go microservices
|
||||||
├── agent-gateway/ # Go. Runs on 172.18.139.186, deploys the API Gateway
|
├── agent-gateway/ # Go. Runs on 172.18.139.186, deploys the API Gateway
|
||||||
├── dashboard/ # NextJS static export, served by nginx
|
├── dashboard/ # NextJS static export, served by nginx
|
||||||
└── nginx/ # reverse proxy + try_files for the dashboard
|
├── nginx/ # reverse proxy + try_files for the dashboard
|
||||||
|
├── scripts/ # build, deploy, ssh wrappers, nginx patch
|
||||||
|
├── docker-compose.yml # all three services on alpine:latest
|
||||||
|
├── go.work # Go workspace — one build, four modules
|
||||||
|
└── bin/ # build output (gitignored)
|
||||||
```
|
```
|
||||||
|
|
||||||
## End-to-end smoke (manual)
|
## Prerequisites
|
||||||
|
|
||||||
Prereqs: Go 1.22+, Node 18+, Docker on each agent VM, alpine:3.20 loaded
|
- Docker (for the build container)
|
||||||
locally (`docker load -i alpine.tar`).
|
- Node 18+ (for the dashboard)
|
||||||
|
- `sshpass` (for the deploy scripts: `brew install sshpass`)
|
||||||
|
|
||||||
1. Build everything:
|
No Go install needed locally — `scripts/build.sh` cross-compiles inside
|
||||||
```bash
|
`golang:1.23-alpine`.
|
||||||
cd protocol && go build ./...
|
|
||||||
cd ../control-plane && go build -o bin/control-plane ./cmd/control-plane
|
|
||||||
cd ../agent-micro && go build -o bin/agent-micro ./cmd/agent-micro
|
|
||||||
cd ../agent-gateway && go build -o bin/agent-gateway ./cmd/agent-gateway
|
|
||||||
cd ../dashboard && npm install && npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Start the control plane:
|
## Build
|
||||||
```bash
|
|
||||||
./control-plane/bin/control-plane -addr :8080 -data ./data
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Start the micro agent on 172.18.136.92:
|
```bash
|
||||||
```bash
|
./scripts/build.sh
|
||||||
SDP_CP_URL=ws://172.18.139.186:8080/ws/agent SDP_NODE_ID=micro \
|
```
|
||||||
./agent-micro/bin/agent-micro
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Start the gateway agent on 172.18.139.186:
|
Outputs:
|
||||||
```bash
|
- `bin/control-plane`, `bin/agent-micro`, `bin/agent-gateway` (Linux/amd64 ELF)
|
||||||
SDP_CP_URL=ws://172.18.139.186:8080/ws/agent SDP_NODE_ID=gateway \
|
- `dashboard/out/` (NextJS static export)
|
||||||
./agent-gateway/bin/agent-gateway
|
|
||||||
```
|
|
||||||
|
|
||||||
5. Point nginx at the dashboard build (`dashboard/out/`) and the control
|
The script verifies each binary with `file` to catch a missing
|
||||||
plane (`:8080`). See `nginx/nginx.conf`.
|
`GOOS`/`GOARCH`.
|
||||||
|
|
||||||
6. Open `http://<nginx-host>/`, sign in with any Bitbucket creds, pick
|
## Deploy
|
||||||
`account` → `feature/login-error`, click Deploy. Watch the stage
|
|
||||||
checkmarks and the log stream.
|
|
||||||
|
|
||||||
## Notes
|
```bash
|
||||||
|
./scripts/deploy.sh
|
||||||
|
```
|
||||||
|
|
||||||
- Credentials are passed per-operation to the agent and never persisted
|
This script:
|
||||||
on the agent longer than the operation.
|
1. SSHs to **172.18.136.92** (`administrator`) and pushes `bin/agent-micro`
|
||||||
- The runtime model is `alpine:3.20` + bind-mounted repo + exec'd binary.
|
to `~/SDP/bin/`
|
||||||
No Dockerfile build step on the agent.
|
2. SSHs to **172.18.139.186** (`administrator`) and pushes
|
||||||
- Logs persist to `<data>/logs/<deploymentId>.log`. SQLite holds progress
|
`bin/control-plane`, `bin/agent-gateway`, and `dashboard/out/` to
|
||||||
snapshots and final state.
|
`~/SDP/`
|
||||||
|
3. Idempotently splices the SDP location block into
|
||||||
|
`/etc/nginx/sites-available/default` on 186 and reloads nginx
|
||||||
|
|
||||||
|
Override the creds via `SDP_92_PASS` / `SDP_186_PASS` env vars.
|
||||||
|
|
||||||
|
## Local dev (docker compose)
|
||||||
|
|
||||||
|
For dev on a single host (e.g. a laptop with Docker):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/build.sh
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Three services come up on `alpine:latest`:
|
||||||
|
- `control-plane` → `:8080`
|
||||||
|
- `agent-micro` (connects to control plane, has docker socket + repos mounted)
|
||||||
|
- `agent-gateway` (same shape)
|
||||||
|
|
||||||
|
## Architecture notes
|
||||||
|
|
||||||
|
- **Pass-through creds.** Bitbucket credentials travel with each deploy
|
||||||
|
request from control plane to agent, are used once for `git fetch`/`checkout`/
|
||||||
|
`pull`, and are never logged or persisted on the agent.
|
||||||
|
- **No Dockerfile build on the agent.** Each agent does `go build` on the
|
||||||
|
host, then `docker run alpine:3.20` with the host repo bind-mounted at
|
||||||
|
`/src` and the binary exec'd as the container command.
|
||||||
|
- **No internet on the VMs.** `alpine:3.20` is pre-loaded via
|
||||||
|
`docker load`. The dashboard is a static export, no runtime fetches.
|
||||||
|
- **Persistence.** Deployment progress goes to SQLite (`<data>/sdp.db`).
|
||||||
|
Log lines go to append-only `<data>/logs/<deploymentId>.log`. SQLite
|
||||||
|
uses `modernc.org/sqlite` (pure Go, no cgo) so the control plane binary
|
||||||
|
stays statically linkable.
|
||||||
|
- **Realtime transport.** WebSocket end-to-end. Agents connect to
|
||||||
|
`/ws/agent` on the control plane; the dashboard subscribes to
|
||||||
|
`/ws/deployments/{id}`.
|
||||||
|
|
||||||
|
## MVP stubs (intentional)
|
||||||
|
|
||||||
|
These are marked with `ponytail:` comments in the code and will be
|
||||||
|
replaced before production:
|
||||||
|
|
||||||
|
- `validateViaAgent` (login) — accepts any creds if an agent is
|
||||||
|
connected. Real impl does a `git ls-remote` probe frame.
|
||||||
|
- `handleListRepos` / `handleListBranches` — hardcoded fixtures.
|
||||||
|
Real impl forwards to the connected agent.
|
||||||
|
- `handleListDeployments` (GET) — returns `[]`. Real impl reads SQLite.
|
||||||
|
- WS auth on `/ws/deployments/*` — open. Real impl checks session token.
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [REQUIREMENTS.md](REQUIREMENTS.md) — full spec, infra, MVP success criteria
|
||||||
|
- [nginx/nginx.conf](nginx/nginx.conf) — reference nginx config
|
||||||
|
- [docker-compose.yml](docker-compose.yml) — three-service dev stack
|
||||||
|
|||||||
Reference in New Issue
Block a user