Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions crates/fakecloud-ec2/src/service/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,13 @@ pub(crate) async fn reboot_instances(
}
}
}
// A reboot can change the instance's IP (k8s Pod recreate), which
// leaves a stale /32 in every peer's security-group rules until an
// unrelated reconcile fires. Re-apply the firewall now (#1745;
// bug-hunt 2026-06-18 finding 4.2). No-op when enforcement is off.
if rt.network_isolation_enforced() {
super::firewall_model::reconcile(&svc_state, &rt).await;
}
});
}
Ok(Ec2Service::respond(
Expand Down
23 changes: 22 additions & 1 deletion crates/fakecloud-ec2/src/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1016,10 +1016,11 @@ impl Ec2Service {
"recovering backing containers for persisted ec2 instances",
);

let mut handles = Vec::new();
for p in pending {
let runtime = runtime.clone();
let state = self.state.clone();
tokio::spawn(async move {
handles.push(tokio::spawn(async move {
let running = runtime
.run_instance(&p.id, p.user_data.as_deref(), &p.tags, p.network.as_ref())
.await;
Expand Down Expand Up @@ -1063,6 +1064,26 @@ impl Ec2Service {
if reap {
runtime.terminate_instance(&p.id).await;
}
}));
}

// Once every instance is back up, (re)apply the security-group
// firewall. The startup reaper cleared the previous process's nft
// table / NetworkPolicies, and the per-instance recovery tasks above
// don't reconcile — without this, recovered instances would run
// unfiltered until some unrelated later op happened to trigger a
// reconcile (#1745; bug-hunt 2026-06-18 finding 4.1). No-op when
// enforcement is disabled.
{
let runtime = runtime.clone();
let state = self.state.clone();
tokio::spawn(async move {
for h in handles {
let _ = h.await;
}
if runtime.network_isolation_enforced() {
firewall_model::reconcile(&state, &runtime).await;
}
});
}
}
Expand Down
Loading