Repository navigation
[api] restore full snapshots only onto CPU-compatible hosts, behind a default-off gate - #176
Draft
the-gigi-pplx wants to merge 1 commit into
Draft
the-gigi-pplx wants to merge 1 commit into
the-gigi-pplx wants to merge 1 commit into
Conversation
the-gigi-pplx
force-pushed
the
gigi/pla-6559-cross-cpu-snapshot-restore
branch
from
October 8, 2026 02:20
1ac1216 to
7128c34
Compare
the-gigi-pplx
marked this pull request as ready for review
October 8, 2026 04:11
kumarpallav-pplx
requested review from
mabdelraouf-pplx and
nikhilbirmiwal-pplx
October 8, 2026 04:11
nikhilbirmiwal-pplx
left a comment
Member
There was a problem hiding this comment.
A few suggestions:
- This is a non-trivial patch touching a critical feature, I would suggest we split it into a logical stack: RFC -> Protobuf Changes -> NodeChanges. ->K8s Changes.
- I don't see mention of testing on a cluster with mixed nodes, is that something we can do?
- Do we have any feature flags or env-gates to ensure smooth rollout?
Member
There was a problem hiding this comment.
Is there value in checking in these svgs / pngs / mmds into git history? I am thinking they will accumulate and bit rot over time.
Collaborator
Author
There was a problem hiding this comment.
They reflect the history. If they are not useful I can just drop them.
| static CURRENT: OnceLock<Option<HostCpu>> = OnceLock::new(); | ||
| CURRENT | ||
| .get_or_init(|| { | ||
| std::fs::read_to_string("/proc/cpuinfo") |
Member
There was a problem hiding this comment.
Does this make Linux based assumptions? I think in Rust there are flags which allow us to compile features based on target system, did we do that there?
the-gigi-pplx
marked this pull request as draft
October 8, 2026 17:38
7 tasks done
the-gigi-pplx
force-pushed
the
gigi/pla-6559-cross-cpu-snapshot-restore
branch
from
October 9, 2026 05:54
e48d65b to
898bee9
Compare
the-gigi-pplx
changed the base branch from
main
to
gigi/pla-6578-stamp-capture-cpu-and-host-cpu-label
October 9, 2026 05:54
the-gigi-pplx
force-pushed
the
gigi/pla-6559-cross-cpu-snapshot-restore
branch
from
October 9, 2026 05:56
898bee9 to
a355022
Compare
the-gigi-pplx
force-pushed
the
gigi/pla-6578-stamp-capture-cpu-and-host-cpu-label
branch
2 times, most recently
from
October 9, 2026 06:07
59ec91e to
61a1a11
Compare
the-gigi-pplx
force-pushed
the
gigi/pla-6559-cross-cpu-snapshot-restore
branch
from
October 9, 2026 06:11
a355022 to
32fdd59
Compare
Base automatically changed from
gigi/pla-6578-stamp-capture-cpu-and-host-cpu-label
to
gigi/pla-6576-record-capture-host-cpu
October 9, 2026 16:03
the-gigi-pplx
force-pushed
the
gigi/pla-6576-record-capture-host-cpu
branch
3 times, most recently
from
October 11, 2026 03:04
8a75ec2 to
b1d0990
Compare
This was referenced Oct 12, 2026
Merged
the-gigi-pplx
force-pushed
the
gigi/pla-6576-record-capture-host-cpu
branch
from
October 15, 2026 02:32
b1d0990 to
d410682
Compare
the-gigi-pplx
force-pushed
the
gigi/pla-6576-record-capture-host-cpu
branch
from
October 17, 2026 02:21
d410682 to
835e318
Compare
Base automatically changed from
gigi/pla-6576-record-capture-host-cpu
to
main
October 17, 2026 03:07
the-gigi-pplx
force-pushed
the
gigi/pla-6559-cross-cpu-snapshot-restore
branch
from
October 26, 2026 23:56
32fdd59 to
87d695a
Compare
… default-off gate
the-gigi-pplx
force-pushed
the
gigi/pla-6559-cross-cpu-snapshot-restore
branch
from
October 27, 2026 00:04
87d695a to
6780a61
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Restores of a full snapshot can now be kept off hosts whose CPU can't load the snapshot's vCPU state. A snapshot captured on one CPU model can fail Firecracker's
PUT /snapshot/loadon another (Failed to set all KVM MSRs), and a restore placed on such a host fails on every retry. Everything here sits behindSPACE_SANDBOX_RESTORE_HOST_CPU_PLACEMENT_ENABLED, which defaults to off. With it off, placement is exactly as onmain.This is the Kubernetes layer. The capture CPU recorded on suspend snapshots and the
space.pplx.net/host-cpunode label come from PR #203.What changed
With the gate on:
space.pplx.net/host-cpu NotIn [...]term listing every published CPU that can't load it. The term goes into every required node-selector term, so it can't be escaped through the source-node shortlist.NotInleaves unlabeled nodes eligible.Unschedulable.host_cpu. A snapshot with no recorded CPU falls back to the live label of the node that uploaded it, but only when that Node object is older than the snapshot, since a replacement instance can reuse the name. A label that isn't in canonical form reads as unlabeled, which matches how kube-scheduler compares it.SPACE_SANDBOX_RESTORE_SOURCE_NODE_HARD_PIN) drops fallbacks labeled with an excluded CPU. When the source's own CPU is excluded, the node-services readiness filter isn't allowed to leave it with no compatible fallback.restoringrow, no full snapshot postdates the restore's start.SPACE_SANDBOX_RESTORE_HOST_CPU_COMPATIBILITYtakes comma-separated one-waycapture=>loaderpairs, letting a known-compatible pair share restores. An invalid value fails startup.Gate-independent:
Code:
crates/libs/api/src/controllers/substrate/kubernetes/pod_ops/host_cpu.rs(requirement, exclusions, redirect);store/snapshot_capture.rs(capture-CPU evidence queries);pod_ops/{create_request,ensure_pod,redrive,restore}.rs;mod.rs;crates/libs/common/core/src/k8s.rs.Known limits:
Test plan
cargo fmt --all -- --checkcargo clippy --workspace --all-targets --locked -- -D warningscargo nextest run --workspaceon a Linux build host, including the Postgres-backed testsrestore_requires_the_capture_cpu_only_when_a_schedulable_host_has_it, including the gate-off casea_restore_stranded_on_an_incompatible_cpu_restores_from_its_snapshot, including the gate-off caserestore_requirement_counts_only_hosts_inside_the_node_grouprestore_requirement_counts_only_hosts_whose_taints_the_pod_toleratesevacuation_requirement_counts_only_hosts_in_the_target_cohortrestore_requirement_falls_back_to_the_capturing_nodes_labela_listed_compatible_cpu_takes_the_restorerestore_shortlist_drops_fallbacks_on_another_cpua_non_canonical_host_cpu_label_reads_as_unlabeledtaint_toleration_matching_follows_kubernetes_rulessandbox_pod_restore_host_cpu_shortlistandsandbox_pod_restore_host_cpu_storage_onlyDocs
docs/configuration.md:SPACE_SANDBOX_RESTORE_HOST_CPU_PLACEMENT_ENABLED(including the unpublished-CPU limit) andSPACE_SANDBOX_RESTORE_HOST_CPU_COMPATIBILITY.