Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/on-pr-colima-smoke.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: colima backend smoke

# End-to-end check of `hops local` on the colima backend on macOS.
# Mirrors on-pr-kind-smoke.yaml with --backend colima and kubectl --context colima.
# Mirrors on-pr-kind-smoke.yaml with colima as both providers and kubectl --context colima.
#
# Runner constraints:
# - Colima needs nested virtualization (Lima VM). Pin macos-15-intel — that
Expand All @@ -12,7 +12,7 @@ name: colima backend smoke
# (macOS 15 Local Network Privacy can block non-root VM-IP access).
#
# Install: brew provides colima/docker/kubectl/helm only. Do not pre-start
# colima here — hops local start --backend colima owns cluster bring-up.
# colima here — hops local start with colima providers owns cluster bring-up.
#
# Sizing: hops defaults (8 CPU / 16 GiB / 60 GiB) exceed standard
# macos-15-intel runners (~4 CPU / ~14 GiB). Pass explicit smaller sizes
Expand Down Expand Up @@ -57,14 +57,14 @@ jobs:
sysctl hw.memsize
df -h /

- name: hops local start --backend colima
- name: hops local start with colima providers
run: |
set -euxo pipefail
# Fit macos-15-intel (~4 CPU / ~14 GiB RAM). Defaults (8/16/60) OOM VZ.
# Memory 10 (not 8): at 8Gi CoreDNS/metrics-server thrash and smoke pods
# sit in ContainerCreating without IPs even after images pull. Leave ~4Gi
# for host macOS + VZ. Disk 40: registry PVC requests 20Gi.
./target/debug/hops-cli local start --backend colima \
./target/debug/hops-cli local start --cluster-provider colima --docker-provider colima \
--cpus 3 --memory 10 --disk 40

- name: hops local doctor
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/on-pr-dory-smoke.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,11 @@ jobs:
# DOCKER_HOST + KUBECONFIG already in env from prior step
dory readiness || true

- name: hops local start --backend dory
- name: hops local start with Dory providers
run: |
set -euxo pipefail
# HOPS_DORY_DESKTOP=0 → env session only (no global context changes)
./target/debug/hops-cli local start --backend dory
./target/debug/hops-cli local start --cluster-provider dory --docker-provider dory

- name: hops local doctor
run: |
Expand Down Expand Up @@ -290,7 +290,7 @@ jobs:
test -d "$FIXTURE"
test -f "$FIXTURE/upbound.yaml"

./target/debug/hops-cli config install --path "$FIXTURE" --backend dory
./target/debug/hops-cli config install --path "$FIXTURE" --cluster-provider dory --docker-provider dory

# Wait for Configuration package Healthy.
for i in $(seq 1 90); do
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/on-pr-kind-smoke.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ jobs:
- name: Build hops
run: cargo build

- name: hops local start --backend kind
run: ./target/debug/hops-cli local start --backend kind
- name: hops local start with kind + Docker
run: ./target/debug/hops-cli local start --cluster-provider kind --docker-provider docker

- name: hops local doctor
run: ./target/debug/hops-cli local doctor
Expand Down Expand Up @@ -84,7 +84,7 @@ jobs:
test -d "$FIXTURE"
test -f "$FIXTURE/upbound.yaml"

./target/debug/hops-cli config install --path "$FIXTURE" --backend kind
./target/debug/hops-cli config install --path "$FIXTURE" --cluster-provider kind --docker-provider docker

for i in $(seq 1 90); do
healthy="$(kubectl --context kind-hops get configuration.pkg.crossplane.io hops-ops-config-smoke \
Expand Down
57 changes: 26 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,13 @@ hops xr --help
Multi-workspace local GitOps on the laptop control plane:

```bash
# once
hops local start
# shared control-plane tree (terminal 1)
hops local gitops cluster ./gitops/cluster \
--cluster-provider kind --docker-provider dory --cluster-name hops

# daily
hops local up ./gitops/env/local
hops local status
hops local open
hops local down
# per-workspace tree (terminal 2)
hops local gitops worktree ./gitops/envs/local --name alice \
--cluster-provider kind --docker-provider dory --cluster-name hops
```

Use `--name` for concurrent worktrees (`<name>` namespaces). Full guide: [skills/claude/references/local-workbench.md](skills/claude/references/local-workbench.md).
Expand Down Expand Up @@ -208,9 +207,8 @@ Examples:
## Create a Local Control Plane

```bash
# 1) Install the backend (via Homebrew). Defaults to colima on macOS;
# pass --backend kind to use kind on any docker daemon.
hops local install
# 1) Install/select the cluster and Docker providers.
hops local install --cluster-provider kind --docker-provider dory

# 2) Start local k8s + Crossplane + providers + local registry
hops local start
Expand All @@ -228,9 +226,9 @@ hops local zitadel --source-context pat-local --domain auth.ops.com.ai
hops config install --repo hops-ops/aws-auto-eks-cluster --version v0.11.0
```

### Cluster backends
### Cluster and Docker providers

`hops local` supports three backends behind the same commands:
`hops local` separates Kubernetes node provisioning from the Docker engine:

- **colima** — a VM running dockerd + k3s. macOS/Linux; supports `--cpus`,
`--memory`, `--disk`, and `hops local resize`.
Expand All @@ -247,17 +245,14 @@ hops config install --repo hops-ops/aws-auto-eks-cluster --version v0.11.0
dockerd runs *inside* the engine — Mac `localhost` is the wrong plane. The
VM is sized in the Dory app, so hops sizing flags don't apply.

Select with the global `--backend` flag:
Select both dimensions explicitly:

```bash
hops local start --backend kind
hops local start --cluster-provider kind --docker-provider dory --cluster-name hops
```

The chosen backend is persisted to `~/.hops/local/backend` on a successful
start, so later commands (`stop`, `destroy`, `doctor`, package installs)
target the same cluster without the flag. Resolution order: `--backend` flag >
persisted choice > existing cluster detection (colima wins) > platform
default (macOS: colima, otherwise kind).
The chosen pair is persisted to `~/.hops/local/providers.json` on a successful
start, so later commands can target the same cluster without repeating flags.

Unless `--context` is given, kubectl commands automatically use the backend's
kubeconfig context (`colima`, `kind-hops`, or `hops-dory`), regardless of your
Expand All @@ -273,7 +268,7 @@ fork of Dory required.
# 2. Enable Kubernetes in the app; wait until the cluster is running
# (product container is usually named dory-k8s)
# 3. Bootstrap Crossplane + local package registry
hops local start --backend dory
hops local start --cluster-provider dory --docker-provider dory
```

On start/activate, hops:
Expand All @@ -283,8 +278,8 @@ On start/activate, hops:
- runs `kubectl config use-context hops-dory`
- creates/uses a docker context of the same name → `unix://$HOME/.dory/dory.sock`

`--dory-name` is intentionally **not** `--name`. Workspace commands use `--name` for the
Kubernetes namespace (`hops local up|down|status|open|gitops worktree --name alice`).
`--dory-name` is intentionally **not** `--name`. Workspace GitOps uses `--name`
for the Kubernetes namespace.

So you should **not** need:

Expand All @@ -294,22 +289,22 @@ export DOCKER_HOST=unix://$HOME/.dory/dory.sock
```

```bash
hops local start --backend dory # dory name defaults to hops-dory
hops local start --backend dory --dory-name mine # custom kube+docker context name
hops local up ./gitops/envs/local --name alice # workspace ns only; does not rename Dory
hops local start --cluster-provider dory --docker-provider dory
hops local start --cluster-provider dory --docker-provider dory --dory-name mine
hops local gitops worktree ./gitops/envs/local --name alice

kubectl get nodes # context hops-dory
docker info # context hops-dory
hops local doctor
hops local github -o hops-ops
hops config install --path … --backend dory
hops config install --path … --cluster-provider dory --docker-provider dory
```

Alternatively, use kind on Dory's docker socket (no product k3s):

```bash
docker context use dory # product context from Dory.app
hops local start --backend kind
hops local start --cluster-provider kind --docker-provider dory --cluster-name hops
```

**CI:** `.github/workflows/on-pr-dory-smoke.yaml` runs on a **self-hosted**
Expand Down Expand Up @@ -397,7 +392,7 @@ k3s is product-owned. hops does not run `dory k8s enable`.
1. Install the Kubernetes component if needed: `dory component install kubernetes`
2. Enable Kubernetes in the Dory app UI
3. Wait until a `dory-k8s` container is running: `docker ps` (with context hops-dory)
4. Re-run `hops local start --backend dory`
4. Re-run `hops local start --cluster-provider dory --docker-provider dory`

**`k ctx` has no dory / hops-dory entry**

Expand All @@ -406,7 +401,7 @@ merges that into `~/.kube/config` as **`hops-dory`** on activate/start. If the
merge is missing:

```bash
hops local doctor --backend dory
hops local doctor --cluster-provider dory --docker-provider dory
kubectl config get-contexts # expect hops-dory
kubectl config use-context hops-dory
```
Expand All @@ -423,7 +418,7 @@ Crossplane always pulls packages with HTTPS. The local registry must be TLS
```bash
kubectl -n crossplane-system delete deploy registry
kubectl -n crossplane-system delete secret hops-local-registry-tls
hops local start --backend dory # recreates TLS secret + registry + CA patch
hops local start --cluster-provider dory --docker-provider dory
```

**docker push to localhost:30500 fails (connection refused / HTTPS to HTTP)**
Expand Down Expand Up @@ -458,7 +453,7 @@ Avoid raw `kill` of dockerd inside the guest unless you are prepared to wait for
```bash
dory doctor
dory readiness
hops local doctor --backend dory
hops local doctor --cluster-provider dory --docker-provider dory
docker context show
kubectl config current-context
kubectl get configuration,provider -A
Expand Down
3 changes: 2 additions & 1 deletion skills/claude/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ For detailed reference on each area, see the bundled references:
## Local control plane + platform packages (dogfood)

```bash
hops local start --backend dory --gitops ./gitops/cluster
hops local start --cluster-provider kind --docker-provider dory \
--cluster-name hops --gitops ./gitops/cluster
# bootstrap writes helm/k8s providers + ProviderConfigs (default) into the tree,
# then runs cluster gitops (apply + watch)

Expand Down
4 changes: 2 additions & 2 deletions skills/claude/references/config-install.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ gitops (not only as one-shot kubectl applies).

```bash
# 1. Bootstrap CP (creates helm/k8s ProviderConfigs named "default")
hops local start --backend dory
hops local start --cluster-provider kind --docker-provider dory --cluster-name hops

# 2. Install published stacks + write package YAML under gitops/cluster
hops config install --repo hops-ops/psql-stack --version v0.9.1 \
Expand All @@ -76,7 +76,7 @@ hops config install --repo hops-ops/auth-stack --version v1.6.0 \

# 3. Day-to-day: apply/watch the tree (packages + XRs)
hops local gitops cluster ./gitops/cluster
# or: hops local start --backend dory --gitops ./gitops/cluster
# or: hops local start --cluster-provider kind --docker-provider dory --cluster-name hops --gitops ./gitops/cluster
```

| Flag | Effect |
Expand Down
7 changes: 4 additions & 3 deletions skills/claude/references/local-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

```bash
# 1. Start local k8s + Crossplane + providers + registry
# (backend preference is user-local: ~/.hops/local/backend)
hops local start --backend dory
# (provider selection is user-local: ~/.hops/local/providers.json)
hops local start --cluster-provider kind --docker-provider dory --cluster-name hops

# 2. Install platform packages into the CP *and* pin them in cluster gitops
hops config install --repo hops-ops/psql-stack --version v0.9.1 \
Expand Down Expand Up @@ -45,7 +45,8 @@ With **`--gitops PATH`** (e.g. `./gitops/cluster`):
2. Runs `hops local gitops cluster PATH` (apply + watch) so day-to-day CP state is gitops-owned

```bash
hops local start --backend dory --gitops ./gitops/cluster
hops local start --cluster-provider kind --docker-provider dory \
--cluster-name hops --gitops ./gitops/cluster
```

**Version bumps:** Renovate owns these pins (`cli/renovate.json` customManagers →
Expand Down
3 changes: 2 additions & 1 deletion skills/claude/references/local-source-packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ providers that Configurations depend on.
## Prerequisites

```bash
hops local start --backend dory --gitops ./gitops/cluster
hops local start --cluster-provider kind --docker-provider dory \
--cluster-name hops --gitops ./gitops/cluster
# Creates: Crossplane, helm/k8s providers (pinned), ProviderConfigs named "default",
# local OCI registry, and writes bootstrap YAML under gitops/cluster/
```
Expand Down
41 changes: 14 additions & 27 deletions skills/claude/references/local-workbench.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ tree copy). You do not need to learn volume types.

```bash
# Dory app running (engine healthy). Product Dory Kubernetes is optional.
# hops points kind at ~/.dory/dory.sock when present.
hops local start --backend kind --gitops ./gitops/cluster
hops local start --cluster-provider kind --docker-provider dory \
--cluster-name hops --gitops ./gitops/cluster
```

Context is typically `kind-hops`. Confirm mounts:
Expand All @@ -25,17 +25,19 @@ Context is typically `kind-hops`. Confirm mounts:
hops local doctor # "kind node projects-root mount (hostPath capable)"
```

**Changing mounts:** recreate the kind cluster — `hops local reset --backend kind`
**Changing mounts:** recreate the kind cluster —
`hops local reset --cluster-provider kind --docker-provider dory --cluster-name hops`
(or destroy + start). Existing clusters created without mounts will not pick up
home mounts until reset.

### Alternative: product Dory Kubernetes

Stock Dory k8s (`--backend dory`) is fine for platform experiments but usually
Stock Dory k8s (`--cluster-provider dory --docker-provider dory`) is fine for platform experiments but usually
**cannot** hostPath-mount Mac paths into the node; delivery falls back to sync.

```bash
hops local start --backend dory --gitops ./gitops/cluster
hops local start --cluster-provider dory --docker-provider dory \
--gitops ./gitops/cluster
```

## Daily loop
Expand All @@ -47,16 +49,7 @@ hops local gitops cluster ./gitops/cluster
# Per-worktree apps (Application YAMLs → namespace = --name) — watches by default
hops local gitops worktree ./gitops/envs/local --name dogfood

# See workspaces and app URLs
hops local status

# Open the UI in a browser
hops local open

# When finished
hops local down
# Optional: delete the namespace too
hops local down --purge
# Stop either watcher with Ctrl+C.
```

Watch is the default for both gitops commands. Use `--once` for a single reconcile (CI/scripts).
Expand All @@ -72,25 +65,19 @@ hops local gitops worktree ./gitops/envs/local --name alice
# Terminal B
hops local gitops worktree ./gitops/envs/local --name bob

hops local status
hops local down --name alice
hops local down --name bob
```

Each name maps to namespace `<name>` and gets its own access URLs.
Each name maps to namespace `<name>`.

## Dogfood: e2e-ui

```bash
cd distributed/tests/e2e-ui
# Prefer kind-on-Dory for hostPath HMR (see One-time prerequisite)
hops local start --backend kind --gitops ./gitops/cluster
hops local start --cluster-provider kind --docker-provider dory \
--cluster-name hops --gitops ./gitops/cluster
hops local gitops cluster ./gitops/cluster
hops local gitops worktree ./gitops/envs/local --name dogfood
# or: hops local up ./gitops/envs/local --name dogfood
hops local status
hops local open
hops local down --name dogfood --purge
```

Charts live under `api/.gitops/deploy` and `ui/.gitops/deploy`. You can also render them without hops:
Expand All @@ -108,7 +95,7 @@ host `make run` you invent.

**When the dogfood site is broken:**

1. **Confirm runtime first** (`KUBECONFIG` = dory, e.g. `~/.kube/dory-config`):
1. **Confirm runtime first** (`kubectl --context kind-hops`):
```bash
kubectl -n dogfood get pods
kubectl -n dogfood logs deploy/e2e-ui-api --tail=40
Expand Down Expand Up @@ -139,8 +126,8 @@ host `make run` you invent.
experiments, or long GraphQL protocol essays when the pod never finished
building. **Do not** declare success without curling the live UI paths.

**Kubeconfig:** prefer `~/.kube/dory-config` for dory; map host access uses
cluster FQDNs (`*.svc.cluster.local`), not `localhost` alone.
**Kube context:** use `kind-hops`; map host access uses cluster FQDNs
(`*.svc.cluster.local`), not `localhost` alone.

## Layout

Expand Down
Loading
Loading