Repository navigation
Conversation
955e149 to
a314315
Compare
f75518e to
b196857
Compare
a314315 to
56a295d
Compare
b196857 to
66508e3
Compare
Every template-manager GetTemplate sandbox-manager issues now goes through one TemplateResolver, carried in SandboxManagerServiceOptions as template_resolver. That covers resolve_template_paths and resolve_template_paths_for_start, which serve create, start, wake, pool adoption and donor cloning, plus restore staging's parent-template lookup and the template network-policy cache. Both resolver methods take a tonic::Request<GetTemplateRequest> and return the tonic::Response, so request and response metadata cross the seam; callers call into_inner() as before. The default, HostTemplateManager, makes the same calls the callers made directly. get_template dials pplx_space_template_mgr_client::connect() for each call, and get_template_on_shared_channel uses the client crate's process-wide lazy() channel. Connect and RPC failures stay distinct (TemplateLookupError), so every caller keeps its error codes and messages. TemplateNetworkPolicyCache no longer has a Default constructor that bypassed the injected resolver. Tests substitute FakeTemplateResolver. It records each lookup's channel, request metadata and message, and returns a scripted answer: a response, a refusal, or a connect failure. - create_template_lookup_tests covers create's auto-lifecycle authority checks. Forwarded peers' Local authority, Unspecified and unknown authorities are refused before any lookup. Cluster authority from a forwarded peer, and Local from a local peer, send one dialed lookup for the requested template and surface its refusal as "GetTemplate failed:". An unreachable template-manager surfaces as Internal "cannot connect to template-manager:". No row is created, and node-manager, a refusing fake, receives no call. - The latest-alias start test and the orphaned-sandbox prepare test assert that no template lookup is sent. Previously they relied on an absent template-manager. - The network-policy cache tests build the cache with a refusing fake. The hint-admission and custom-override tests assert that no owner lookup is sent. - grpc_core's isolated_service, which lists every option, gets a FakeTemplateResolver that refuses every lookup, so those tests can no longer reach the fixed template-manager socket.
56a295d to
e1e9927
Compare
66508e3 to
17387b7
Compare
Review — 1 findingReviewed as the diff on top of PR #296's head Low
Verified against |
the-gigi-pplx
left a comment
There was a problem hiding this comment.
Approved. 1 non-blocking finding in the review comment above.
5547397
into
ac/sbxmgr-seam-node-manager-transport
Stacked on #296 (
ac/sbxmgr-seam-node-manager-transport). This PR's base is that branch, and its diff is only the template-manager seam.Summary
Every template-manager
GetTemplatethat sandbox-manager issues now goes through one injectedTemplateResolver. Production keeps today's exact client construction against the fixed template-manager socket. Tests can script the answer and observe each request.The seam
crates/libs/sbx/mgr/server/src/template_resolver.rsadds:TemplateResolver, anasync_traittrait with two methods. Both take atonic::Request<GetTemplateRequest>and return atonic::Response<GetTemplateResponse>, so request and response metadata cross the seam; callers callinto_inner()as before.get_template:GetTemplateon a client dialed for this call under the default connect-retry policy, aspplx_space_template_mgr_client::connect()does.get_template_on_shared_channel:GetTemplateon the client crate's process-widelazy()channel.TemplateLookupError, which keeps connect failures and RPC failures apart (Connect(ConnectError),Rpc(Status)), so each caller maps them to exactly the codes and messages it produced before.HostTemplateManager, the default. It callspplx_space_template_mgr_client::connect()andlazy(), which reachTEMPLATE_MANAGER_SOCKET.The resolver is a new field,
SandboxManagerServiceOptions::template_resolver: Arc<dyn TemplateResolver>, defaulting toHostTemplateManager. The service hands it to the template network-policy cache. Handlers pass it to:resolve_template_paths, and throughresolve_template_paths_for_start,template_source_for_sandbox_prepareandtemplate_runtime_defaults_for_sandbox_start(create_support), which serve create, start, wake (auth_lookup), and pool adoption and donor cloning (grpc_pool_wait_clone);snapshot_restore::ensure_local_template, throughrestore_pull_rootfsandprepare_restore_dir*.Production wiring is unchanged
resolve_template_pathsandensure_local_templatestill dial a fresh client withconnect()for each call.lazy()channel inside its existing timeout and admission bounds.cannot connect to template-manager: …andtmplmgr connect for GetTemplate(…): ….GetTemplate failed: …with the server's code,template_pull_error's mapping, andtemplate-manager GetTemplate(…) failed: ….tonic::Request::new, which is what the generated client'sIntoRequestdid for a bare message: no metadata, no extensions.TemplateNetworkPolicyCacheno longer has aDefaultconstructor that hard-wiredHostTemplateManager. Its only constructor takes the injected resolver.Call-site inventory, production code. Base is #296's head,
56a295d(the inventory was taken at its pre-rebase heada314315; the rebase changed no production code):pplx_space_template_mgr_client::connect()create_support::resolve_template_paths,snapshot_restore::ensure_local_templateHostTemplateManager::get_templatepplx_space_template_mgr_client::lazy()forGetTemplatenetwork_policy::fetch_template_default_network_policyHostTemplateManager::get_template_on_shared_channelgrpc_core), start ×3 (start), restore prepare (create), wake (auth_lookup), pool adoption and donor clone ×2 (grpc_pool_wait_clone), create_support ×2, the network-policy cache, restore stagingself.template_resolverCall sites left unrouted
grpc_core::list_templateskeepspplx_space_template_mgr_client::lazy()forListTemplates. It is a catalog passthrough for sandbox-manager's ownListTemplatesRPC, not a template resolution. Routing it would widen the resolver to a second RPC that no create, start or restore path uses...Default::default()still getHostTemplateManager, exactly as before. The network-policy cache's own tests now build the cache with a refusing fake (see below).Tests
FakeTemplateResolver(template_resolver/fake.rs, test-only) records each lookup and returns a scripted answer:Dialedforget_template,Sharedforget_template_on_shared_channel), the request metadata and the request message.ConnectError. A connect error reaches a shared-channel lookup asUnavailable, as a lazy channel reports it.New module
service/grpc_core/create_template_lookup_tests.rs. It is a separate file because #271, open when it was written and since merged, editedservice/grpc_core/tests.rs. It addscreate_checks_auto_lifecycle_authority_before_template_lookup, covering the create cases #271 deferred because a regression would have reached the fixed template-manager socket. Each case gets its ownFakeTemplateResolverand aFakeNodeManagerthat refuses everything. The test runs in an isolated child process, like #271's create tests. Every accepted case must send exactly one lookup, on the dialed channel, carrying no request metadata.Localauto-lifecycle authority from a forwarded peerPermissionDenied(authority=local requires a local operator peer)Unspecifiedauto-lifecycle authorityInvalidArgument(policy authority proto value is unspecified)99)InvalidArgument(policy authority proto value 99 is unknown)Clusterauto-lifecycle authority from a forwarded peer (accepting control)NotFound, message startingGetTemplate failed:and carrying the scripted refusalseedwith no hashLocalauto-lifecycle authority from a local peer (accepting control)NotFound, message startingGetTemplate failed:seedwith no hashClusterauthority with template-manager unreachable (scriptedConnectError)Internal, message startingcannot connect to template-manager:In every case no sandbox row is created and node-manager receives no call.
These cases cover the auto-lifecycle checks #271 deferred and stop at template lookup. Everything create does after lookup is still not covered by fake-backed tests: intent resolution, pool adoption, requested-id reuse and
create_with_id.Two existing tests call the start-path free functions directly, with no service. Each now passes a fake resolver and asserts that no lookup was sent. Previously they relied on template-manager being absent:
existing_sandbox_cannot_resolve_a_missing_artifact_by_latest_alias(create_support/tests.rs, callsresolve_template_paths_for_start)orphaned_sandbox_without_rootfs_start_prepare_does_not_fetch_template(service/tests.rs, callstemplate_source_for_sandbox_prepare)The network-policy cache's tests (
service/network_policy/tests.rs) now build their cache with a refusing fake instead of the removedDefault. Two of them reach the owner lookup throughrequire_hintwhen the cache misses or the admission lock is not honored, and both now assert that no lookup is sent:template_policy_hints_are_admission_requirements_not_cache_authoritycustom_policy_override_does_not_require_template_owner_progressservice/tests/node_manager_transport_tests.rs(from #296) gainsisolated_service, which takes both fakes. Itsservice_with_node_managernow refuses every template lookup.Mutation proof
Each mutation was applied, the named test was run with
--retries 0, and the file was restored. All lookups went to the fake.createskips the auto-lifecycle authority checkscreatelets a forwarded peer set aLocalauto-lifecycle authorityresolve_template_pathsdrops the requested template nameresolve_template_pathsturns a lookup refusal intoInternalresolve_template_pathsuses the shared lazy channel instead of a dialed clientShared≠Dialed)resolve_template_pathsdrops theGetTemplate failed:prefixresolve_template_pathsmaps a connect failure as an RPC failureThe other required seam check, a service built with
HostTemplateManagerin place of the fake, was not run. It would dial the fixed host socket, which the host-safety rule forbids even on a mutation's regression path. S1 proves the same dependence without contacting the host.Host safety
Unimplemented.enter_route_test_process) instead of reading the host's.Overlaps with open PRs
Rebased onto #296's rebased head
56a295d, on maina8b5df6, which merged #269, #271, #273, #275, #277, #278 and #302. Open PRs were re-checked against this head withgit merge-tree, plus a scan of each diff's added lines for the APIs this PR changes and forSandboxManagerServiceOptionsliterals:isolated_serviceinservice/grpc_core/tests.rslists everySandboxManagerServiceOptionsfield. sbx-mgr: inject the node-manager client transport and template-manager resolver #296 addednode_managerthere, an unbound connector on an absent socket. This PR addstemplate_resolver: Arc::new(FakeTemplateResolver::refusing(Status::unavailable("template-manager is outside this test"))), the same refusalservice_with_node_manageruses, so no sbx-mgr: characterize stop, delete and create core RPC paths (tests only) #271 test can reach the fixed template-manager socket. sbx-mgr: characterize stop, delete and create core RPC paths (tests only) #271's tests are otherwise unchanged. Its deferred auto-lifecycle create cases are covered by this PR'screate_template_lookup_tests.rs.template_resolver:line toruntime_liveness_optionsand one fake toorphaned_sandbox_without_rootfs_start_prepare_does_not_fetch_templateinservice/tests.rs, away from tests: keep three tests off host state they don't own #278's hunks.cache_cleanup/periodic/tests.rs, is also present against main.GetTemplatecall site this PR routes, which gives 14 conflict regions against this PR's head:auth_lookup2,create_support6,create_support/tests.rs2,grpc_core,grpc_pool_wait_clone,network_policyandsnapshot_restore. Preserve authenticated scope in cached template lookups #217 attaches a caller scope to thetonic::Request(scope.attach(&mut request)) and checks an acknowledgement on thetonic::Response(scope.require_acknowledgement(&resp)) beforeinto_inner(). Because the resolver takes and returns the tonic wrappers, Preserve authenticated scope in cached template lookups #217 can rebase by doing that around eachtemplates.get_template(…)call without changing the trait.watchdog.rs, from sbx-mgr: inject the node-manager client transport and template-manager resolver #296's change. This PR adds none.grpc_lifecycle.rsis also present against main. fix(sandbox): wait before retrying failed activations #3, [api] restore full snapshots only onto CPU-compatible hosts, behind a default-off gate #176, [sbx-mgr] record the capture host CPU on snapshots and publish it as a node label #203, Add an opt-in Firecracker balloon device per template #212 and [api] stop retrying restore pods whose snapshot the host CPU cannot load #221 already conflict with main; this PR adds no hunk to any of them.Validation
cargo fmt --all -- --check, at66508e3cargo clippy --workspace --locked --all-targets --all-features -- -D warnings, at66508e3check-rust-error-policy.sh,generate-env-contract.sh --check,source_guards/env_test_hook_boundary.py, at66508e3check_no_inline_rust_test_modules.pyandsource_guards/thin_service_mains.py, at66508e3a8b5df6; files not touched hereSPACE_CI_REQUIRE_TEST_DEPS=1 cargo nextest run --locked -p pplx-space-sbx-mgr --retries 0, two consecutive runs at66508e3(nextest's Postgres setup script passed)#[ignore]test not selected); 0 dependency-skip markersb196857b196857; not re-run after the rebasespace-localcluster per attempt on the current harness, built from #299's headb196857space-sbxmgr-svcsha2568e9ce23a…7090in both workerspace-sandbox-managerpods, before and after the suites, equals the staged artifact built from this checkout; the synced build source for sbx-mgr is identical tob196857; the binary contains thenode_manager_transportandtemplate_resolvermodule pathstilt get uiresources: 42/42ok, none pending or in errorsmoke-kind-e2e.shBOOTSTRAP_TIMEOUT=1800 DATA_PLANE_URL=http://127.0.0.1:8090smoke-kind-typed.sh all, attempt 1SKIP_BOOTSTRAP=1,SPACE_SMOKE_KIND_ADMIN_TOKEN_FILEandSPACE_SMOKE_KIND_COLD_RECEIPTSset as inkind-ci.yml, unshardedlocal.template_cache_lru_eviction_reclaimsfailed and the following scenarios were inconclusive. Docker's data disk (49 GB) reached 100%, so the Kind nodes' overlays could not write:os error 5under/space/cacheand Postgrescould not write init file. A rerun on that cluster could not start sandbox pods (pod_never_ready), so the cluster was torn downdocker builder prune -afanddocker image prune -fonlysmoke-kind-typed.sh all, rerun on a new clusterecw.cold_create_environment)The Kind rows above come from the pre-rebase head
b196857and were not re-run. Since then, the only changes to this PR are the newtemplate_resolverfield in #271's testisolated_service, and #296's test-only changes; main's merged PRs change no sbx-mgr production code.Follow-ups
service/grpc_core/tests.rs(for example onBARRIER_AUTHORITY) still say a lookup past the barrier would contact the fixed template-manager socket. With the refusing fake it would stop at the fake. They were left as they are, by design, because this change only adds the fields.service/tests/node_manager_transport_tests.rs's module doc should also list the template resolver among the host dependencies thatisolated_serviceredirects.🤖 Generated with Claude Code