Skip to content

feat: native dory backend for hops local#73

Merged
patrickleet merged 3 commits into
feat/cluster-backend-abstractionfrom
feat/dory-backend
Jul 11, 2026
Merged

feat: native dory backend for hops local#73
patrickleet merged 3 commits into
feat/cluster-backend-abstractionfrom
feat/dory-backend

Conversation

@patrickleet

@patrickleet patrickleet commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #70. Adds --backend dory: hops drives dory's built-in k3s headlessly through the dory CLI's new k8s lifecycle (see the paired dory-side change on the fork's feat/hops-local-integration branch, implementing the four upstream specs: extra port publishing, persistent registries.yaml, headless CLI, dory kubeconfig context).

How the registry plumbing works on dory

  • Trust (static): hops writes ~/.dory/k8s/registries.yaml before enable; dory bind-mounts it and k3s reads it at boot, aliasing both pull names (registry.crossplane-system.svc.cluster.local:5000, localhost:30500) to the Service hostname over HTTP.
  • Resolution (dynamic): wire_registry re-syncs hostname → ClusterIP in the node's /etc/hosts every start (in-place rewrite; it's a bind mount so sed -i can't rename over it).
  • Host reachability: dory k8s enable --publish 30500:30500 publishes the NodePort; the Dory app's port forwarder maps published container ports to host loopback (verified: it claimed 127.0.0.1:30500 within seconds of the port becoming free).

Also fixes helm repo update to target only crossplane-stable — a stale unrelated helm repo no longer fails start.

Test output (local end-to-end, macOS 26.4.1 arm64, Dory 0.2.0 + fork CLI)

  • hops local start --backend dory: k3s up in ~21s, Crossplane 2.3.3 + both providers healthy + registry Available
  • hops local doctor: all checks passed (context: dory)
  • Registry round-trip: docker push localhost:30500/smoke/busybox:ci (via engine socket), then pods pulling through both names reached Ready
  • hops local stop && hops local start (no flag — persisted backend): resume + hosts re-sync + doctor green
  • cargo test: 119 passed

🤖 Generated with Claude Code

https://claude.ai/code/session_011Ei12zcYdwvUoZ3jCbwiWf

Summary by CodeRabbit

  • New Features
    • Added support for the dory local backend, including cluster lifecycle actions and kubeconfig handling.
    • Expanded local cluster documentation to cover Dory setup, registry access, and Docker integration.
  • Bug Fixes
    • Kube-related environment settings are now exported earlier during install flows for more reliable cluster access.
    • Local startup now refreshes only the required Helm repository, avoiding failures from unrelated stale repos.

Backend::Dory drives dory's built-in k3s headlessly via the dory CLI
(k8s enable/disable/status) and the engine docker socket:

- start: writes ~/.dory/k8s/registries.yaml (k3s-native trust aliasing both
  registry pull names to the Service hostname over HTTP; read at boot via
  dory's bind mount), then 'dory k8s enable --publish 30500:30500'. The Dory
  app's port forwarder makes the published NodePort host-reachable.
- wire_registry: syncs hostname -> ClusterIP in the node's /etc/hosts per
  start (in-place rewrite — /etc/hosts is a bind mount, sed -i fails).
- stop/resume via docker stop/start of dory-k8s; destroy/reset via
  dory k8s disable (+ enable); sizing flags error (VM sized in the app).
- kube_context 'dory' (dory names its kubeconfig context that); hops
  prepends ~/.kube/dory-config to KUBECONFIG for its kubectl/helm children.
- detection order: colima > kind > dory.

Also: 'helm repo update crossplane-stable' instead of bare update — a stale
unrelated repo in the user's helm config no longer breaks start.

Verified end-to-end locally: start (Crossplane 2.3.3 + providers + registry),
doctor all green, registry round-trip through BOTH pull names to pod Ready,
stop/start resume, doctor green again.

Implements [[tasks/dory-native-backend]]
@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3ca309f9-66cb-4ec2-9b86-a45a100facc8

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/dory-backend

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@patrickleet

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

* fix: harden dory integration contract

[[tasks/rr-2-dory-contract]]

* fix: skip KUBECONFIG plumbing when dory context is already merged

Current dory merges the dory context into ~/.kube/config at enable time,
so hops no longer needs to mutate KUBECONFIG for child processes; the
side-file prepend remains as a fallback for pre-merge dory versions.

Implements [[tasks/dory-kubeconfig-merge]]

* fix: hold dory cluster through the app's engine provisioning window

Launching Dory.app re-provisions its engine for ~90s and restarts dockerd
in the VM at the end, SIGTERMing every container — a k3s node enabled
during that window reports Ready and then dies mid-bootstrap. The engine
socket's mtime marks the session start, so when it is younger than 180s,
start/reset now watch the node until the window passes and re-enable it
(up to 3x) if the engine restart takes it down. Steady-state starts pay
one container inspect.

Implements [[tasks/rr-2-dory-contract]]
[[tasks/rr-1-context-targeting]]
@patrickleet patrickleet merged commit 4297cd2 into feat/cluster-backend-abstraction Jul 11, 2026
1 check passed
patrickleet added a commit that referenced this pull request Jul 11, 2026
* feat: native dory backend for hops local

Backend::Dory drives dory's built-in k3s headlessly via the dory CLI
(k8s enable/disable/status) and the engine docker socket:

- start: writes ~/.dory/k8s/registries.yaml (k3s-native trust aliasing both
  registry pull names to the Service hostname over HTTP; read at boot via
  dory's bind mount), then 'dory k8s enable --publish 30500:30500'. The Dory
  app's port forwarder makes the published NodePort host-reachable.
- wire_registry: syncs hostname -> ClusterIP in the node's /etc/hosts per
  start (in-place rewrite — /etc/hosts is a bind mount, sed -i fails).
- stop/resume via docker stop/start of dory-k8s; destroy/reset via
  dory k8s disable (+ enable); sizing flags error (VM sized in the app).
- kube_context 'dory' (dory names its kubeconfig context that); hops
  prepends ~/.kube/dory-config to KUBECONFIG for its kubectl/helm children.
- detection order: colima > kind > dory.

Also: 'helm repo update crossplane-stable' instead of bare update — a stale
unrelated repo in the user's helm config no longer breaks start.

Verified end-to-end locally: start (Crossplane 2.3.3 + providers + registry),
doctor all green, registry round-trip through BOTH pull names to pod Ready,
stop/start resume, doctor green again.

Implements [[tasks/dory-native-backend]]

* fix: harden dory integration contract (#74)

* fix: harden dory integration contract

[[tasks/rr-2-dory-contract]]

* fix: skip KUBECONFIG plumbing when dory context is already merged

Current dory merges the dory context into ~/.kube/config at enable time,
so hops no longer needs to mutate KUBECONFIG for child processes; the
side-file prepend remains as a fallback for pre-merge dory versions.

Implements [[tasks/dory-kubeconfig-merge]]

* fix: hold dory cluster through the app's engine provisioning window

Launching Dory.app re-provisions its engine for ~90s and restarts dockerd
in the VM at the end, SIGTERMing every container — a k3s node enabled
during that window reports Ready and then dies mid-bootstrap. The engine
socket's mtime marks the session start, so when it is younger than 180s,
start/reset now watch the node until the window passes and re-enable it
(up to 3x) if the engine restart takes it down. Steady-state starts pay
one container inspect.

Implements [[tasks/rr-2-dory-contract]]

* fix: unify kube context/backend targeting (#75)

[[tasks/rr-1-context-targeting]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant