Repository navigation
Actors can reach the network while they boot, before their wakeup probe passes - #2117
Conversation
f788639 to
8151b8d
Compare
8151b8d to
de5bd12
Compare
|
Quentin Bisson (@QuentinBisson) I think this doesn't do anything without #2159 allowing for policies to be applied to goldens |
|
You're totally right. I forgot to link it here. I did not want to make the other PR bigger |
de5bd12 to
d689539
Compare
|
To clarify my earlier reply: the two PRs are complementary. #2159 gives the golden actor a policy, and this PR turns egress on before readyz, so the golden's boot fetch needs both. This one also helps any actor that already has a policy and fetches while booting or restoring. I've linked #2159 in the description. |
d689539 to
a45ab26
Compare
Allow substrate egress for `RESUMING` actors as well as `RUNNING` actors, so workloads can fetch what they need while booting or restoring, before the wakeup probe passes. This supports agent-substrate/substrate#2117. The actor's egress policy still applies. All 91 Substrate integration tests pass with `cargo test -p agentgateway --test integration tests::substrate::`, including coverage for resuming actors, rejected states, and policy enforcement. Formatting checks pass. AI assistance was used for the implementation, tests, and this description. - [ ] As required by the [Code of Conduct](https://github.com/agentgateway/agentgateway/blob/main/CODE_OF_CONDUCT.md#generative-ai-policy), the description, docs, and comments (words meant for humans) are written by a human, not by an LLM. Signed-off-by: Eitan Yarmush <[email protected]>
|
Quentin Bisson (@QuentinBisson) this release will have the fix for agw so you don't need conditional logic: https://github.com/agentgateway/agentgateway/actions/runs/37940656707 |
|
Thanks Eitan Yarmush (@EItanya) I'll take a look on monday |
sounds good, btw I brought this whole issue up in the community meeting and we're doing our best to get it done for GA |
60dd5ab to
df525eb
Compare
|
Eitan Yarmush (@EItanya) sorry, i got sick yesterday and had to postpone the fix. Do you know when GA is coming? |
eef5295 to
5bf56a7
Compare
|
Eitan Yarmush (@EItanya) would you have some capacity to review this one ? |
5bf56a7 to
ddb320f
Compare
A memory restore resumes past the probe's boot fetch. The boot-fetch probe now fails its wakeup probe until the restored actor has fetched again as itself, so a restore that tunnels egress only after the wakeup probe fails the test.
abb2ed5 to
3a06d83
Compare
|
🤖 AI-generated comment. To clarify the remaining golden-policy comment: |
The fixture template sets goldenEgressPolicy, so the controller creates the golden actor's EgressPolicy before it resumes the actor. This drops WithGoldenEgressPolicy and the boot fetch retries that covered a policy landing after the golden boot started. The test needs the GoldenEgressPolicy preview gate. Signed-off-by: QuentinBisson <[email protected]>
|
Thanks, addressed in 37d3df4: the template now sets On |
Eitan Yarmush (EItanya)
left a comment
There was a problem hiding this comment.
🤖 AI-generated review.
One remaining restore retry issue to fix before approval, plus a small, nonblocking test-command correction.
| // processes. | ||
| // As in coldBootActor: egress before the VM restores, ingress after the | ||
| // wakeup probe. | ||
| if err := s.tunnel.ActivateEgress(p.attribution(), egress); err != nil { |
There was a problem hiding this comment.
With egress active before Resume, a restored background task can complete an external POST while dialAgentRetry or reseedGuestCRNG subsequently fails. Both still go through restoreGuestReadyError, which returns Unavailable. Atelet preserves that status, so a retry restores the same snapshot and can repeat the POST. The helper's retry rationale explicitly relies on outbound TCP being blocked until activation, which is no longer true.
Can we keep early egress but stop classifying these failures as safe to retry once the guest may have run, and add a regression test for that transition?
There was a problem hiding this comment.
Fixed, a bit differently from what you suggested. A restore from a memory snapshot now gets egress after the CRNG reseed, just before the wakeup probe, instead of before Resume.
Why: before the reseed, every clone restored from the same snapshot has the same frozen "random" state. Opening egress then could let those identical values leave the host, which is what the reseed is there to prevent. It also means a failure during Resume, the agent dial or the reseed happens before any egress, so retrying it can't resend a request and the existing retry stays. Making those failures non-retryable instead would have crashed the actor on any short host stall. The restored workload is already past its boot, so it only needs egress once the probe starts.
A wake cut short during the probe can still be retried from the snapshot. The api-guide now says requests made while waking may be sent again. The run command now names the GoldenEgressPolicy gate.
| // policy before the controller resumes it. An actor restored from that snapshot then has to fetch again | ||
| // as itself before its wakeup probe passes, which covers the restore paths. | ||
| // | ||
| // hack/run-e2e-kind.sh ./internal/e2e/suites/egressmitm -run TestGoldenBootEgress -v -args --no-color |
There was a problem hiding this comment.
Small nit: can we add --preview=GoldenEgressPolicy to this command? RequirePreview skips the test without it, so copying the documented command doesn't exercise golden boot egress. The cluster also needs that gate enabled.
|
Sure I'm on it |
Egress opened before Resume let a restored guest send traffic drawn from CRNG state it shares with the snapshot's other clones, and let a request complete before a failure that atelet retries from the same snapshot. A memory restore is past the workload's boot, so it gets egress after the reseed, just before the wakeup probe; cold boots and gVisor restores keep egress before the workload starts. The api-guide says a wake retried after egress was active can resend outbound requests. atunnel's per-connection drop logs move to Debug with the actor UID, since renewal already warns once. The fixture render test fails on a placeholder left unfilled, and the boot egress test's run command names the GoldenEgressPolicy preview gate.
Lior Lieberman (LiorLieberman)
left a comment
There was a problem hiding this comment.
LGTM overall, some nits
| // appRestore time the cold start that stands in for the restore. activate sums | ||
| // the tunnel's egress half, armed before the containers restore, and its | ||
| // ingress half, after the wakeup probe. |
There was a problem hiding this comment.
nit: can we humanize this comment just a bit?
There was a problem hiding this comment.
What do you think about:
| // appRestore time the cold start that stands in for the restore. activate sums | |
| // the tunnel's egress half, armed before the containers restore, and its | |
| // ingress half, after the wakeup probe. | |
| // appRestore time the cold start that stands in for the restore. activate is | |
| // the total time spent activating the tunnel: egress is activated before the | |
| // containers restore and ingress after the wakeup probe, and both are counted. |
| // From inside the sandbox this is a connection that opens and closes at | ||
| // once, indistinguishable from a network failure. Debug, since the actor | ||
| // sets the rate and an actor without a gateway gets here on every |
There was a problem hiding this comment.
can we humanize this comment a bit?
There was a problem hiding this comment.
| // From inside the sandbox this is a connection that opens and closes at | |
| // once, indistinguishable from a network failure. Debug, since the actor | |
| // sets the rate and an actor without a gateway gets here on every | |
| // The actor sees this as a connection that closes right away, like a | |
| // network failure. This logs at Debug because an actor without an | |
| // egress gateway hits this on every outbound connection. |
|
cla is failing |
|
Also:
|
Co-authored-by: Lior Lieberman <[email protected]>
Co-authored-by: Lior Lieberman <[email protected]>
f948134 to
089f0fa
Compare
|
fixed CLA |
The origin's certificate covers only <name>.<namespace>.svc, which the actor resolves through its search path. The DNS relay answers only names the EgressPolicy lists, so the golden and restored actors' policies also list the .svc.cluster.local name the search path expands to.
|
Can you take another look? |
| if err := reseedThenActivateEgress(ctx, guestAC, func() error { | ||
| return s.tunnel.ActivateEgress(p.attribution(), egress) | ||
| }); err != nil { |
There was a problem hiding this comment.
nit: Why does this need to be a callback with this, feels like claude trying to inject a test seam
Eitan Yarmush (EItanya)
left a comment
There was a problem hiding this comment.
once you fix that test seam issue i think I'm good with this
|
It was added so we could test that a failed reseed leaves egress off in the unit test but it's a seam that only exists for tests so lets remove it |
|
🎉 Thank you |
An actor's egress was turned on only after every container answered its wakeup probe, so a workload that downloads what it needs to become ready (a model, a Git repository) could not start. atunnel closed the connection inside the sandbox before it reached the gateway. Egress is now turned on before the first container starts, on both sandbox classes and for both run and restore; ingress still waits for the probe. The atenet gateway admits
RESUMINGactors as well asRUNNINGones, and atunnel and the gateway now log the connections they refuse.The actor's EgressPolicy still applies. The new e2e test gives the golden actor its policy through the template's
goldenEgressPolicy(#2159), so it runs only with theGoldenEgressPolicypreview gate. A restored actor's wakeup probe also waits for a fresh fetch as itself, which covers the restore paths. agentgateway moves tov0.0.0-alpha.9d36620d, which admitsRESUMINGactors too (agentgateway/agentgateway#3882), so the test runs on both dataplanes.Tested on kind with gVisor on both dataplanes, before the move to
goldenEgressPolicy: the test passed with this change and failed without it (on agentgateway, against the previous pin). The rest of the gVisor e2e suite also passes on the agentgateway lane, apart from the external-volume tests, which could not mount NFS on my rootless setup.Part of #1543