docs: README with full command reference + platform design
Complete CLI reference for labctl covering: - Bastion (PXE provisioning) — implemented - Provisioning (install/reprovision/forget) — implemented - Server management (get/describe) — planned - Remote execution (exec) — planned - Kubernetes proxy (kubectl) — planned - Resource-scoped logs (server/app/pulumi/audit) — planned - Apps (Pulumi charts replacing Helm) — planned - RBAC (roles/permissions/deny rules) — planned - Infrastructure as Code (apply/plan/destroy) — planned Plus: partition layout, architecture diagram, tech stack, dev setup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
358
bastion/README.md
Normal file
358
bastion/README.md
Normal file
@@ -0,0 +1,358 @@
|
||||
# labctl
|
||||
|
||||
Infrastructure management platform for bare-metal servers, Kubernetes clusters, and cloud resources.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
# From Gitea packages (Fedora/RHEL)
|
||||
sudo dnf config-manager --add-repo https://mysources.co.uk/michal/-/packages/rpm/
|
||||
sudo dnf install labctl
|
||||
|
||||
# From source
|
||||
cd bastion && pnpm install && pnpm build
|
||||
bun build src/cli/src/index.ts --compile --outfile dist/labctl
|
||||
sudo cp dist/labctl /usr/bin/labctl
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Start the bastion (PXE provisioning server)
|
||||
sudo labctl init bastion standalone start
|
||||
|
||||
# PXE boot a machine — it gets discovered automatically
|
||||
labctl provision list
|
||||
|
||||
# Install Fedora on a discovered machine
|
||||
labctl provision install 78:55:36:08:35:14 labmaster --role infra
|
||||
|
||||
# Reprovision (SSH reboot into PXE, preserves /home /srv /var/lib/rancher)
|
||||
labctl provision reprovision 78:55:36:08:35:14 labmaster --role infra
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
### Bastion (PXE Provisioning)
|
||||
|
||||
```bash
|
||||
# Lifecycle
|
||||
sudo labctl init bastion standalone start # Start bastion (daemonized)
|
||||
sudo labctl init bastion standalone start --foreground # Start in foreground
|
||||
sudo labctl init bastion standalone stop # Stop bastion
|
||||
labctl init bastion standalone status # Show status, PID, machine count
|
||||
|
||||
# Options
|
||||
sudo labctl init bastion standalone start \
|
||||
--port 8080 \
|
||||
--dir /tmp/lab-bastion \
|
||||
--domain ad.itaz.eu \
|
||||
--dhcp-mode proxy \
|
||||
--fedora 43 \
|
||||
--timezone Europe/London
|
||||
```
|
||||
|
||||
### Provisioning
|
||||
|
||||
```bash
|
||||
# List all machines (discovered, queued, installing, installed)
|
||||
labctl provision list
|
||||
|
||||
# Queue a machine for Fedora install
|
||||
labctl provision install <mac> <hostname> --role worker # k3s worker (gets longhorn)
|
||||
labctl provision install <mac> <hostname> --role infra # infra node (gets k3s server + /var/lib/rancher)
|
||||
|
||||
# Reprovision — queues install, SSHes in, sets PXE boot, reboots
|
||||
labctl provision reprovision <mac> <hostname> --role infra
|
||||
|
||||
# Remove a machine from state
|
||||
labctl provision forget <mac>
|
||||
|
||||
# Options
|
||||
labctl provision install <mac> <hostname> \
|
||||
--role worker \
|
||||
--disk nvme0n1 \
|
||||
--port 8080
|
||||
```
|
||||
|
||||
### Server Management (planned)
|
||||
|
||||
```bash
|
||||
# List servers with filters
|
||||
labctl get servers
|
||||
labctl get servers --env production
|
||||
labctl get servers --cloud baremetal
|
||||
labctl get servers --cloud aws
|
||||
labctl get servers --label role=k3s-worker
|
||||
labctl get servers --label asg=web-servers
|
||||
|
||||
# Detailed server info
|
||||
labctl describe server/puppet
|
||||
labctl describe server/ser9
|
||||
```
|
||||
|
||||
### Remote Execution (planned)
|
||||
|
||||
```bash
|
||||
# Execute commands on servers (audited, RBAC-checked)
|
||||
labctl exec server/puppet -- whoami
|
||||
labctl exec server/puppet -- systemctl status k3s
|
||||
labctl exec server/puppet -it -- bash # interactive TTY
|
||||
labctl exec server/puppet --timeout 30s -- long-running-task
|
||||
```
|
||||
|
||||
### Kubernetes (planned)
|
||||
|
||||
```bash
|
||||
# Proxied kubectl — audited, RBAC-checked, no kubeconfig needed
|
||||
labctl kubectl --cluster lab get pods
|
||||
labctl kubectl --cluster lab get nodes
|
||||
labctl kubectl --cluster lab logs pod/nginx -f
|
||||
labctl kubectl --cluster lab exec pod/nginx -- bash
|
||||
labctl kubectl --cluster lab apply -f deployment.yaml
|
||||
labctl kubectl --cluster aws-prod get pods --namespace app
|
||||
|
||||
# Cluster management
|
||||
labctl clusters add lab --kubeconfig ~/.kube/config
|
||||
labctl clusters list
|
||||
labctl clusters remove staging
|
||||
```
|
||||
|
||||
### Logs (planned)
|
||||
|
||||
```bash
|
||||
# Server logs (journalctl passthrough via agent)
|
||||
labctl logs server/puppet # all journal
|
||||
labctl logs server/puppet -f # follow (live stream)
|
||||
labctl logs server/puppet -n 100 # last 100 lines
|
||||
labctl logs server/puppet -u k3s # specific unit
|
||||
labctl logs server/puppet -u sshd --since "1h ago" # time range
|
||||
labctl logs server/puppet --since "2026-03-17" --until "2026-03-18"
|
||||
labctl logs server/puppet -k # kernel only
|
||||
labctl logs server/puppet -p err # errors only
|
||||
labctl logs server/puppet --file /var/log/nginx/error.log # tail a file
|
||||
labctl logs server/puppet --file /var/log/nginx/error.log -n 50
|
||||
|
||||
# App logs (k8s pod logs)
|
||||
labctl logs app/bastion
|
||||
labctl logs app/bastion -f
|
||||
labctl logs app/labd --container postgres
|
||||
|
||||
# Pulumi execution logs
|
||||
labctl logs pulumi/run-abc123
|
||||
labctl logs pulumi/run-abc123 -f # follow active run
|
||||
|
||||
# Bastion logs
|
||||
labctl logs bastion/lab
|
||||
labctl logs bastion/lab --mac 78:55:36:08:35:14 # specific machine's install
|
||||
|
||||
# Agent daemon logs
|
||||
labctl logs agent/puppet
|
||||
|
||||
# Audit logs
|
||||
labctl logs audit
|
||||
labctl logs audit --user michal
|
||||
labctl logs audit --user michal --since "1h ago"
|
||||
labctl logs audit/michal-20260317-abc123 # specific session
|
||||
labctl logs audit --action kubectl --cluster lab
|
||||
labctl logs audit --action exec --server puppet
|
||||
```
|
||||
|
||||
### Apps (planned, replaces Helm)
|
||||
|
||||
```bash
|
||||
# Install Pulumi-based apps to Kubernetes
|
||||
labctl apps list # available apps
|
||||
labctl apps install bastion # deploy bastion
|
||||
labctl apps install bastion --set port=8080 # with overrides
|
||||
labctl apps install bastion -f values.yaml # from values file
|
||||
labctl apps install monitoring # Prometheus + Grafana
|
||||
|
||||
# Manage deployed apps
|
||||
labctl apps status bastion # health, version, config
|
||||
labctl apps upgrade bastion # rolling upgrade
|
||||
labctl apps history bastion # version history
|
||||
labctl apps rollback bastion 2 # rollback to version 2
|
||||
labctl apps uninstall bastion
|
||||
```
|
||||
|
||||
### Infrastructure as Code (planned)
|
||||
|
||||
```bash
|
||||
# Execute Pulumi programs via labd (RBAC-checked)
|
||||
labctl apply -f infra/k3s-cluster.ts --env lab
|
||||
labctl plan -f infra/k3s-cluster.ts --env lab # dry run
|
||||
labctl destroy -f infra/k3s-cluster.ts --env lab
|
||||
```
|
||||
|
||||
### RBAC (planned)
|
||||
|
||||
```bash
|
||||
# Roles and permissions
|
||||
labctl get roles
|
||||
labctl get users
|
||||
labctl create role viewer --allow "read:*:*:*"
|
||||
labctl create role lab-admin --allow "*:baremetal:lab:*" --deny "destroy:*:*:*"
|
||||
labctl bind role lab-admin --user michal
|
||||
labctl unbind role lab-admin --user michal
|
||||
|
||||
# Permission model: action:cloud:environment:server
|
||||
# read:*:*:* — read everything
|
||||
# exec:baremetal:lab:* — exec on any lab server
|
||||
# kubectl:*:*:* — kubectl on any cluster
|
||||
# *:baremetal:lab:puppet — full access to puppet only
|
||||
# manage:*:*:* — manage apps, clusters, tokens
|
||||
```
|
||||
|
||||
### Environments and Clouds (planned)
|
||||
|
||||
```bash
|
||||
labctl get environments
|
||||
labctl get clouds
|
||||
labctl create environment staging --cloud aws
|
||||
labctl create environment lab --cloud baremetal
|
||||
```
|
||||
|
||||
## Partition Layout
|
||||
|
||||
Machines installed by the bastion get this LVM layout:
|
||||
|
||||
### Worker role (k3s worker with Longhorn)
|
||||
```
|
||||
/boot/efi 600MB EFI
|
||||
/boot 3GB ext4
|
||||
── LVM VG: labvg ──
|
||||
swap 27GB (matches RAM)
|
||||
/ 33GB xfs
|
||||
/var 100GB xfs
|
||||
/var/log 10GB xfs
|
||||
/home 10GB xfs ← preserved on reprovision
|
||||
/srv 20GB xfs ← preserved on reprovision
|
||||
/tmp tmpfs 4GB
|
||||
/var/lib/longhorn rest xfs ← preserved on reprovision (Longhorn PVC storage)
|
||||
```
|
||||
|
||||
### Infra role (k3s server, labmaster)
|
||||
```
|
||||
/boot/efi 600MB EFI
|
||||
/boot 3GB ext4
|
||||
── LVM VG: labvg ──
|
||||
swap 27GB (matches RAM)
|
||||
/ 33GB xfs
|
||||
/var 100GB xfs
|
||||
/var/log 10GB xfs
|
||||
/home 10GB xfs ← preserved on reprovision
|
||||
/srv 20GB xfs ← preserved on reprovision
|
||||
/var/lib/rancher 20GB xfs ← preserved on reprovision (k3s etcd data)
|
||||
/tmp tmpfs 4GB
|
||||
```
|
||||
|
||||
On reprovision, OS partitions (`/`, `/var`, `/var/log`, `swap`) are wiped. Data partitions (`/home`, `/srv`, `/var/lib/longhorn`, `/var/lib/rancher`) are preserved.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ labctl CLI │
|
||||
│ init | provision | get | exec | logs | apply | apps | kubectl│
|
||||
└───────────────────────────┬──────────────────────────────────┘
|
||||
│ mTLS
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ labd (master daemon — stateless, on k3s) │
|
||||
│ ┌─────┐ ┌──────┐ ┌──────┐ ┌────────┐ ┌──────┐ ┌────────┐ │
|
||||
│ │ CA │ │ RBAC │ │ Logs │ │ Pulumi │ │ Apps │ │kubectl │ │
|
||||
│ │ │ │ │ │relay │ │executor│ │ │ │ proxy │ │
|
||||
│ └─────┘ └──────┘ └──────┘ └────────┘ └──────┘ └────────┘ │
|
||||
│ CockroachDB │
|
||||
└──────────────┬─────────────────────────┬─────────────────────┘
|
||||
│ mTLS │ mTLS
|
||||
┌──────────▼───────────┐ ┌──────────▼───────────┐
|
||||
│ lab-agent │ │ lab-agent │
|
||||
│ bare-metal server │ │ AWS EC2 / cloud VM │
|
||||
│ ┌────────────────┐ │ │ ┌────────────────┐ │
|
||||
│ │ heartbeat │ │ │ │ heartbeat │ │
|
||||
│ │ exec handler │ │ │ │ exec handler │ │
|
||||
│ │ log streamer │ │ │ │ log streamer │ │
|
||||
│ │ module runner │ │ │ │ module runner │ │
|
||||
│ └────────────────┘ │ │ └────────────────┘ │
|
||||
└──────────────────────┘ └──────────────────────┘
|
||||
```
|
||||
|
||||
## Technology Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|-----------|
|
||||
| Language | TypeScript (ESM) |
|
||||
| CLI | Commander.js |
|
||||
| HTTP Server | Fastify + WebSocket |
|
||||
| Database | CockroachDB (PostgreSQL compatible) |
|
||||
| ORM | Prisma |
|
||||
| IaC | Pulumi (TypeScript) |
|
||||
| k8s CNI | Cilium |
|
||||
| Auth | mTLS (built-in CA) |
|
||||
| Packaging | nfpm (RPM/DEB), bun compile |
|
||||
| Containers | Podman + podman-compose |
|
||||
| CI/CD | Gitea Actions |
|
||||
| Testing | Vitest |
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
cd bastion
|
||||
|
||||
# Install dependencies
|
||||
pnpm install
|
||||
|
||||
# Build all packages
|
||||
pnpm build
|
||||
|
||||
# Run tests (30 tests)
|
||||
pnpm test:run
|
||||
|
||||
# Type check
|
||||
pnpm typecheck
|
||||
|
||||
# Lint
|
||||
pnpm lint
|
||||
|
||||
# Generate shell completions
|
||||
pnpm completions:generate
|
||||
|
||||
# Build standalone binary
|
||||
bun build src/cli/src/index.ts --compile --outfile dist/labctl
|
||||
|
||||
# Build RPM/DEB packages (both architectures)
|
||||
bash scripts/build-rpm.sh --all
|
||||
|
||||
# Build Docker image
|
||||
bash scripts/build-bastion.sh
|
||||
|
||||
# Full release (build + publish + install)
|
||||
bash scripts/release.sh
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
bastion/
|
||||
├── src/
|
||||
│ ├── shared/ # @lab/shared — types, constants
|
||||
│ ├── bastion/ # @lab/bastion — PXE provisioning server
|
||||
│ ├── cli/ # @lab/cli — CLI binary (labctl)
|
||||
│ ├── labd/ # @lab/labd — master daemon (planned)
|
||||
│ └── agent/ # @lab/agent — server agent (planned)
|
||||
├── modules/ # Built-in configuration modules (planned)
|
||||
├── deploy/
|
||||
│ └── k3s/ # Kubernetes manifests
|
||||
├── stack/
|
||||
│ ├── Dockerfile
|
||||
│ └── docker-compose.yml
|
||||
├── scripts/ # Build, publish, release scripts
|
||||
├── completions/ # Generated shell completions
|
||||
└── ARCHITECTURE.md
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
Reference in New Issue
Block a user