Skip to content

Simplify docs, add Docker support, improve Kubernetes discovery - #20

Merged
rishibaghel25 merged 7 commits into
mainfrom
claude/infracanvas-repo-review-1y9wjl
Sep 24, 2026
Merged

rishibaghel25 merged 7 commits into
mainfrom
claude/infracanvas-repo-review-1y9wjl

Conversation

@rishibaghel25

Copy link
Copy Markdown
Member

What does this PR do?

This PR restructures the documentation, adds Docker container support, and improves Kubernetes discovery robustness. The main changes are:

  1. Documentation overhaul: Consolidates scattered README sections into focused docs (install.md, security.md, multi-machine.md). The README now leads with a clear value proposition and quick-start examples instead of lengthy explanations.

  2. Docker support: Adds a Dockerfile for containerized deployment with embedded UI, and updates CI/release notes to build and document the Docker image.

  3. Kubernetes discovery improvements:

    • Changes IsAvailable() to use /version endpoint instead of listing nodes, so read-only or namespace-scoped credentials don't incorrectly mark a working cluster as unavailable
    • Adds Skipped() method to track resource kinds the credential lacks RBAC access to, allowing discovery to continue with partial access instead of failing entirely
    • Adds comprehensive unit tests for these scenarios
  4. Agent resilience:

    • Moves discovery into a separate goroutine to prevent terminal input from stalling during discovery passes
    • Adds ResumeSecret and OnResumeSecret to WSConfig so virtual cluster agents can persist session identity across restarts
    • Adds discoverMu to serialize discovery passes
  5. Cluster manager improvements:

    • Adds pingCluster() to validate connectivity before persisting a cluster entry
    • Deduplicates clusters by context (re-adding the same context updates in place)
    • Persists cluster resume secrets so reconnects work correctly
  6. UI and server:

    • Adds DISCOVERY_ERROR message type so agents can report discovery failures before producing a canvas
    • Frontend displays discovery errors with retry information
    • Adds cluster auth tests to ensure join tokens don't leak to kubeconfig routes
  7. Testing: Adds unit tests for audit logging, runstate persistence, redaction, cluster manager, and Kubernetes discovery edge cases.

Type of change

  • New feature (Docker support, discovery error reporting)
  • Refactor (discovery goroutine, cluster deduplication)
  • Documentation
  • CI / tooling (Docker build, release notes)

Testing

  • make test passes (new tests added for audit, runstate, redaction, clustermgr, k8s discovery)
  • make lint passes
  • npm run build passes (frontend builds with new discovery error UI)
  • Docker image builds successfully with embedded UI

Related issues

Addresses robustness of Kubernetes discovery with limited credentials, Docker deployment, and documentation clarity.

https://claude.ai/code/session_01W4DmTTCv9UQim4aBJ6oGKH

…surface discovery errors

- Kubernetes discovery pinged the API server by listing Nodes and failed the
  whole pass on the first forbidden list call. Credentials without
  cluster-wide access to nodes, secrets, PVs or storageclasses always showed
  "error". Ping now hits /version, and 403/404 on a resource kind is skipped
  and reported in snapshot permission_issues (#7).
- Adding a cluster now checks the API server is reachable before saving, and
  re-adding the same server+context updates the existing entry instead of
  creating a duplicate (#6).
- Cluster virtual agents lost their relay resume secret on restart, so after
  the first disconnect every reconnect was rejected as a hijack attempt. The
  manager now keeps each cluster's secret across agent restarts.
- If an agent's first discovery failed, later successful passes only sent
  diffs, which browsers drop without a snapshot, so the canvas stayed on
  "Discovering infrastructure…" forever. The agent now sends a snapshot on
  the first success and a DISCOVERY_ERROR before that, which the relay
  caches and the dashboard shows with the reason (#14).
The agent ran each periodic discovery pass inside the same select loop that
reads commands from the relay. A pass takes seconds, and for that long
EXEC_INPUT messages sat in the queue, then reached the PTY all at once. This
is the "input freezes, then dumps buffered text" behavior in #5.

- Periodic discovery now runs in its own goroutine; discovery passes are
  serialized with a mutex since the "refresh" command can overlap it.
- Terminal input is written by one goroutine per session instead of one
  goroutine per keystroke, so characters can't be reordered.
Multi-stage build (Next.js export, Go binary with embedded UI, Alpine
runtime). Releases push ghcr.io/bytestrix/infracanvas for amd64 and arm64,
tagged with the version and latest. CI builds the image on every PR so the
Dockerfile can't silently break.
…f read-only mode

Previewing or connecting a cluster runs the kubeconfig's auth, including any
exec: credential plugin, on the hub.

- /api/clusters, /api/clusters/preview and /api/clusters/{id} now require
  the UI token. They also accepted the agent join token, which every joined
  VM holds, and nothing but the dashboard calls them.
- Cluster preview is now blocked in --read-only mode, like connect already
  was.
…s the invoking user

- serve now reads INFRACANVAS_TUNNEL and INFRACANVAS_PRIVATE (explicit flags
  still win), and the installer no longer bakes --no-tunnel/--private into
  the systemd ExecStart. Before, editing those lines in config.env and
  restarting did nothing, although the README said it would.
- serve --private now implies --no-tunnel, as the installer and docs already
  described. Before, serve --private alone still opened the public tunnel.
- When a normal user runs `curl ... | bash` without sudo, the service now
  runs as that user instead of the first /home user the script found.
…o docs/

- README leads with a canvas screenshot linked to the live demo, then three
  install paths (local binary, Docker, VM with --private), what it shows,
  a comparison table and a short security summary.
- Install options, flags, reverse proxy setup and service management move
  to docs/install.md; the security model to docs/security.md; VMs and
  clusters to docs/multi-machine.md.
- Corrected statements that didn't match the code: token is 24 hex
  characters, Go 1.25+ is required, "binds localhost by default" was only
  true with the tunnel, and which user the service runs as.
- ARCHITECTURE.md rewritten for the open-source binary. The old version
  described the hosted product and included internal host details.
These three handle secrets, credentials on disk and the audit trail and had
no tests. Covers key-name and pattern redaction, command-line masking,
state round-trip and 0700/0600 permissions, audit ordering, on-disk format
and reload after restart.
@rishibaghel25
rishibaghel25 force-pushed the claude/infracanvas-repo-review-1y9wjl branch from ed49c75 to 1df2a27 Compare September 24, 2026 19:56
@rishibaghel25
rishibaghel25 merged commit bc161ca into main Sep 24, 2026
5 checks passed
rishibaghel25 added a commit that referenced this pull request Oct 17, 2026
Mirrors SaaS PR #20.

    Kubernetes                    (big node, helm logo)
    |- Cluster  |- CronJobs  |- Deployments  |- Namespaces
    |                                         |- cert-manager
    |                                         |   |- cert-manager
    |                                         |   |- cert-manager-webhook
    |                                         |- cs
    |                                             |- manager-*, az-*

Three earlier attempts each got half of it wrong: grouping by type alone
destroyed parentage, a free radial layout destroyed grouping (identical
discs, undifferentiable), labelled blocks kept grouping but had no
hierarchy inside them.

- `hierarchyMap.ts` — synthesises platform roots, resource-type nodes and
  containment edges; layout centres each node over its children and
  grid-wraps wide fan-outs
- `MapHierarchyNodes.tsx` — root node with the Kubernetes helm / Docker
  marks, and type nodes (`Pods 44`)

Namespaced resources are drawn under their namespace so the parentage is
real; the type node still links to them so "Pods" reaches its pods.

Two layout bugs fixed: `cy` was computed once and never advanced per row
so wrapped grids stacked on one line (91 overlapping pairs), and column
count came from child count alone which made the tree 6000px wide
(aspect 4.21 -> 1.17).
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