Skip to content

demos/counter: inline gVisor walkthrough and fix setup commands - #3498

Merged
Zoe Zhao (zoez7) merged 3 commits into
agent-substrate:mainfrom
moficodes:fix/3492-counter-demo-docs
Nov 2, 2026
Merged

Zoe Zhao (zoez7) merged 3 commits into
agent-substrate:mainfrom
moficodes:fix/3492-counter-demo-docs

Conversation

@moficodes

@moficodes Mofi Rahman (moficodes) commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

demos/counter/README.md hid every walkthrough command inside 16 collapsed <details> blocks (leaving <details> tags in the docsite's raw Markdown outputs) and had outdated or incomplete instructions across the default, external volume, and microVM flows:

  • Inline the default gvisor walkthrough commands in the numbered steps, note the default gvisor-default sandbox upfront, move actor deletion after ## Reaching a non-default port, and place the microVM and external CSI volume variants in dedicated sections at the end.
  • Document the atenet-router --ingress-allowed-spiffe-ids prerequisite for kubectl ate proxy actor, keeping ATE_INSTALL_KIND=true exported on kind, and point the Quickstart link to docs/get-started/quickstart.md.
  • Add the missing ExternalVolumes preview gate, ate-setup setup csi, delete demo counter and kubectl wait --for=delete namespace/ate-demo-counter before replacing the template, and kubectl ate --preview create actor steps for external volumes, and explain --validate-existing-file-path=/external-data/test.txt.
  • Add the create, proxy, suspend, and delete steps for microVM in ate-demo-counter-microvm (my-counter-1).
  • Document all three counters incremented by counter.go (preserved memory count, preserved file counter, and preserved rootfs counter) with expected curl output across suspend and resume.

Fixes #3492

AI use: AI-assisted, I reviewed and verified the changes on kind and Kubernetes clusters and built the docsite locally.

  • Tests pass: docs-only change (./hack/site.sh build, ./hack/verify/boilerplate.sh, and live walkthrough verification)
  • Docs updated

Comment thread demos/counter/README.md Resolved
Comment thread demos/counter/README.md Outdated
to forward additional ports. This proxy also takes port `8000`, so stop the
earlier one (such as the Quickstart's) first:
```bash
./hack/install-microvm-deps.sh --install

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script has been removed from #2092, please rebase and update the documentation.

Comment thread demos/counter/README.md Outdated
<details>
<summary>Delete from GVisor</summary>
# Local kind cluster (defaults KIND_CLUSTER_NAME to "kind"):
./hack/run-microvm-demo-kind.sh

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script will be removed in #3509 as well.

Comment thread demos/counter/README.md Outdated
- Builds the counter server image using `ko`.
- Applies [`counter.yaml.tmpl`](counter.yaml.tmpl) to create the `ate-demo-counter` namespace and the `counter` `WorkerPool`, then waits for the worker rollout.
- Creates the `ate-demo-counter` atespace.
- Creates the `counter` actor template through `kubectl ate create actor-template` from [`counter-template.yaml.tmpl`](counter-template.yaml.tmpl). The manifest uses the message's protojson form, which matches `kubectl ate get actor-template -o yaml`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 should-fix 🟡 – ate-setup deploy demo counter creates the template directly over gRPC (cmd/ate-setup/internal/steps/substrate.go:83) rather than running kubectl ate create actor-template. Also, kubectl ate get actor-template -o yaml without a template name and -a fails flag validation (and listing without a name wraps the output in actorTemplates:). Say that ate-setup creates the template through the Substrate API, and that the manifest matches kubectl ate get actor-template counter -a ate-demo-counter -o yaml.

Comment thread demos/counter/README.md Outdated
## How to Use

When you send an HTTP request through the proxy, `atenet-router` automatically activates (resumes) the actor onto an available worker pod and routes the traffic.
The actor resumes from its snapshot, potentially on a different worker pod, and all three counters continue from `1` to `2`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, probably out of scope for this PR: I think we should delete the hello from: 169.254.17.2 from the counter demo. It's ancient. It was used at the beginning of substrate to show that "Hey, the actor resumed on a different Pod whose IP is XXX", but now,
169.254.17.2 is the sandbox's fixed veth address (internal/ateworker/actornet/net.go:31), I think it's distracting in the counter demo.

Comment thread demos/counter/README.md Outdated
Comment on lines 122 to 126
4. Delete the actor when finished:

```bash
curl -X POST http://localhost:8000
kubectl ate delete actor my-counter-1 -a ate-demo-counter
```

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 should-fix 🟡 – Deleting my-counter-1 here causes the next section (## Reaching a non-default port, line 133) to fail when it proxies and curls my-counter-1. Move this delete step after ## Reaching a non-default port.

Comment thread demos/counter/README.md Outdated
Then send a request to local port `9090`:
## Attaching an External Volume

Pass `--with-external-volume` to attach a CSI-backed external volume mounted at `/external-data` and configure `counter.go` with `--validate-existing-file-path=/external-data/test.txt`. The e2e test harness uses this flag to verify a pre-seeded file on the volume, so on an empty volume `curl` returns `failed to read test file: open /external-data/test.txt: no such file or directory`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 should-fix 🟡 – The e2e suite does not use --with-external-volume (internal/e2e/suites/demo/demo_test.go:1639 builds a separate counter-ext-vol template with --file-counter-directory=/external-data, and updatetemplate_test.go:75 uses --validate-existing-file-path=/home/counter/a.txt). Drop the claim about the e2e test harness and state directly that --with-external-volume sets --validate-existing-file-path=/external-data/test.txt, so curl returns that error until /external-data/test.txt exists on the volume.

ningmingxiao (ningmingxiao) pushed a commit to ningmingxiao/substrate that referenced this pull request Oct 31, 2026
…t-substrate#3510)

<!-- The PR title becomes the release note. Write it for users. -->

Follow-up to
agent-substrate#3498 (comment).
Remove `hello from: %s` and `getCurrentIP()` from
`demos/counter/counter.go`.

Why? `counter.go` included `hello from: <ip>` in its response from early
dyas of Substrate to show that an actor resumed on a different worker
Pod IP. However, now every actor sandbox uses the fixed veth address
`169.254.17.2` (`ActorVethIP` in `internal/ateworker/actornet/net.go`),
so `getCurrentIP()` always returns `169.254.17.2` regardless of which
worker Pod hosts the actor.

Also updated documentations to remove mentioning of "the different
worker Pod IP replied by counter indicates it was resumed on another
pod".


<!-- e.g. "AI-assisted, I reviewed and tested it." No AI co-author
trailers. -->
AI use: AI-assisted to update the counter demo, docs, and tests; I
reviewed the diff.

<!-- Breaking change? Describe what users must do on upgrade and ask for
the `breaking-change` label. -->

- [x] Tests pass
- [x] Docs updated

---------

Signed-off-by: Zoe Zhao <[email protected]>
Hiding every walkthrough command inside 16 collapsed <details> blocks made the default gVisor flow hard to follow on GitHub and left <details> tags in the docsite's raw Markdown outputs. Inline the gVisor steps in the main walkthrough and move the microVM and external volume variants into dedicated sections at the end.

Several walkthrough commands also failed out of the box because Prerequisites omitted the atenet-router SPIFFE allowlist needed by kubectl ate proxy actor, the external volume steps omitted the ExternalVolumes preview gate and CSI driver setup, and the microVM instructions omitted required environment variables and --install on hack/install-microvm-deps.sh. Update those commands and document all three counters incremented by counter.go.

Signed-off-by: Mofi Rahman <[email protected]>
…eanup order

Note upfront that the main walkthrough deploys the default gvisor sandbox variant. State that ate-setup creates the counter template through the Substrate API and give the full kubectl ate get actor-template counter -a ate-demo-counter -o yaml command.

Move actor deletion after the non-default port section so my-counter-1 still exists when that section proxies to it, and explain directly that --with-external-volume sets --validate-existing-file-path=/external-data/test.txt on counter.go.

Signed-off-by: Mofi Rahman <[email protected]>
ate-setup delete demo counter returns before the ate-demo-counter namespace finishes terminating, so running deploy demo counter immediately afterward fails with a terminating-namespace error. Add kubectl wait --for=delete namespace/ate-demo-counter before redeploying with --with-external-volume.

Signed-off-by: Mofi Rahman <[email protected]>
@zoez7
Zoe Zhao (zoez7) added this pull request to the merge queue Nov 2, 2026
Dmitry Berkovich (dberkov) pushed a commit that referenced this pull request Nov 2, 2026
<!-- The PR title becomes the release note. Write it for users. -->

Follow-up to
#3498 (comment).
Remove `hello from: %s` and `getCurrentIP()` from
`demos/counter/counter.go`.

Why? `counter.go` included `hello from: <ip>` in its response from early
dyas of Substrate to show that an actor resumed on a different worker
Pod IP. However, now every actor sandbox uses the fixed veth address
`169.254.17.2` (`ActorVethIP` in `internal/ateworker/actornet/net.go`),
so `getCurrentIP()` always returns `169.254.17.2` regardless of which
worker Pod hosts the actor.

Also updated documentations to remove mentioning of "the different
worker Pod IP replied by counter indicates it was resumed on another
pod".

<!-- e.g. "AI-assisted, I reviewed and tested it." No AI co-author
trailers. -->
AI use: AI-assisted to update the counter demo, docs, and tests; I
reviewed the diff.

<!-- Breaking change? Describe what users must do on upgrade and ask for
the `breaking-change` label. -->

- [x] Tests pass
- [x] Docs updated

---------

Signed-off-by: Zoe Zhao <[email protected]>
(cherry picked from commit 659832f)
Signed-off-by: Eitan Yarmush <[email protected]>
Merged via the queue into agent-substrate:main with commit 30a0dea Nov 2, 2026
7 checks passed
Dmitry Berkovich (dberkov) pushed a commit that referenced this pull request Nov 3, 2026
Bring `release-1.0` up to `main` at
5a5b192 with the 19 changes merged
since the previous batch in #3536. The final tree matches that commit
exactly.

**Please use Rebase and merge to preserve the individual commits and
author attribution.** All 19 applied cleanly in upstream order. Original
authors, author dates, co-author and sign-off trailers, and `-x` source
references are retained.

Upgrade notes:

- #3533: old gVisor MEMORY snapshots, including goldens, no longer
restore. Recreate them after upgrading. MicroVM MEMORY snapshots still
resume with their old mounts until recreated. `/tmp` is now always
tmpfs; ROOTFS snapshots no longer preserve its contents, and
image-provided files there are hidden. MicroVM `/tmp` counts against
actor memory and is capped at half the guest's memory. gVisor `/dev/shm`
is now a 64 MiB tmpfs. Mount a `durableDir` at either path when
persistence or more space is needed. `/run` now comes from the image
rootfs.
- #3447: remove `--actor-jwt-jwks-file` from custom credential-exchange
sidecar configs. Set `--actor-jwt-issuer-ca-file` only when the issuer
uses a private CA other than the service DNS CA.

- #3450: do not reuse a deleted atespace name. See the updated atespace
name-reuse guidance.

Includes #3505, which overlaps the open backport in #3547. GKE
provisioning and teardown now live in
[substrate-gke](https://github.com/ai-on-gke/substrate-gke) rather than
this repository.

<details>
<summary>Included PRs, in cherry-pick order</summary>

1. #3500: demos/{sandbox,jupyter,multi-template}: fix tutorial
prerequisites, walkthroughs, and counter volume
2. #3498: demos/counter: inline gVisor walkthrough and fix setup
commands
3. #3511: e2e tests: Extend the existing tests to cover tag actor.
4. #2775: Generate API reference documentation and publish it on
Substrate website
5. #3119: Document how people, pods and CI jobs should authenticate to
ate-api
6. #3505: tools: remove setup-gcp and hack/teardown.sh
7. #3147: e2e: resume fidelity after SandboxConfig version edits
8. #3370: ate-setup: reconcile ate-api-server ConfigMaps and roll out on
config changes
9. #1607: hack: reject breaking proto changes across each proto package
10. #3415: docs: update and add security diagrams
11. #3485: Resuming a microVM actor on the same node no longer reads its
rootfs upper back from disk
12. #3447: Verify actor JWTs in the credential exchange through OIDC
discovery
13. #3533: ocispec: mount tmpfs at /dev/shm, and /tmp on both runtimes
14. #3450: docs: Document that atespace names must not be reused
15. #3410: Document using more than one egress credential provider
16. #3486: atelet: register the device plugin on a new socket each time
17. #3553: ate-setup: wait for the demo namespace in delete demo
18. #3560: Fix multiple issues in claude-code-multiplex demo
19. #3517: docs: remove inaccurate early-stage architecture
documentation

</details>

Validation: every intermediate tree matches its upstream source commit,
all 19 authorship records and original attribution trailers are
preserved, and `git diff --check` passes. The original 18 backport
commits are unchanged.

AI use: AI-assisted cherry-picking, attribution checks, and review.

- [ ] Tests pass
- [x] Docs updated

---------

Signed-off-by: Mofi Rahman <[email protected]>
Signed-off-by: Eitan Yarmush <[email protected]>
Signed-off-by: Nayana Bidari <[email protected]>
Signed-off-by: Julian Gutierrez Oschmann <[email protected]>
Signed-off-by: Max Thompson <[email protected]>
Signed-off-by: Steven Shriver <[email protected]>
Signed-off-by: Grant McCloskey <[email protected]>
Signed-off-by: Shrutiya <[email protected]>
Signed-off-by: Haiyan Meng <[email protected]>
Signed-off-by: Greg Castle <[email protected]>
Signed-off-by: Benjamin Elder <[email protected]>
Signed-off-by: Anish Ramasekar <[email protected]>
Signed-off-by: Shruti Nair <[email protected]>
Signed-off-by: Haven Xia <[email protected]>
Co-authored-by: Mofi Rahman <[email protected]>
Co-authored-by: nybidari <[email protected]>
Co-authored-by: Julian Gutierrez Oschmann <[email protected]>
Co-authored-by: Max Thompson <[email protected]>
Co-authored-by: Grant McCloskey <[email protected]>
Co-authored-by: Steven Shriver <[email protected]>
Co-authored-by: shrutiyam-glitch <[email protected]>
Co-authored-by: haiyanmeng <[email protected]>
Co-authored-by: Greg Castle <[email protected]>
Co-authored-by: Benjamin Elder <[email protected]>
Co-authored-by: Anish Ramasekar <[email protected]>
Co-authored-by: Shruti Nair <[email protected]>
Co-authored-by: Haven Xia <[email protected]>
Co-authored-by: Adam Wathieu <[email protected]>
Dmitry Berkovich (dberkov) pushed a commit that referenced this pull request Nov 3, 2026
`demos/counter/README.md` hid every walkthrough command inside 16
collapsed `<details>` blocks (leaving `<details>` tags in the docsite's
raw Markdown outputs) and had outdated or incomplete instructions across
the default, external volume, and microVM flows:

- Inline the default `gvisor` walkthrough commands in the numbered
steps, note the default `gvisor-default` sandbox upfront, move actor
deletion after `## Reaching a non-default port`, and place the `microVM`
and external CSI volume variants in dedicated sections at the end.
- Document the `atenet-router` `--ingress-allowed-spiffe-ids`
prerequisite for `kubectl ate proxy actor`, keeping
`ATE_INSTALL_KIND=true` exported on `kind`, and point the Quickstart
link to `docs/get-started/quickstart.md`.
- Add the missing `ExternalVolumes` preview gate, `ate-setup setup csi`,
`delete demo counter` and `kubectl wait --for=delete
namespace/ate-demo-counter` before replacing the template, and `kubectl
ate --preview create actor` steps for external volumes, and explain
`--validate-existing-file-path=/external-data/test.txt`.
- Add the `create`, `proxy`, `suspend`, and `delete` steps for `microVM`
in `ate-demo-counter-microvm` (`my-counter-1`).
- Document all three counters incremented by `counter.go` (`preserved
memory count`, `preserved file counter`, and `preserved rootfs counter`)
with expected `curl` output across suspend and resume.

Fixes #3492

AI use: AI-assisted, I reviewed and verified the changes on `kind` and
Kubernetes clusters and built the docsite locally.

- [x] Tests pass: docs-only change (`./hack/site.sh build`,
`./hack/verify/boilerplate.sh`, and live walkthrough verification)
- [x] Docs updated

---------

Signed-off-by: Mofi Rahman <[email protected]>
(cherry picked from commit 30a0dea)
Signed-off-by: Eitan Yarmush <[email protected]>
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.

demos/counter: inline gVisor walkthrough and fix external-volume, microVM, and 3-counter instructions

3 participants