From ae0361e6c838e9a198e582eee4666bfb77c311a7 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Sun, 21 Jun 2026 08:47:07 +0000 Subject: [PATCH 1/4] feat(featureflags): add envd-version to LaunchDarkly sandbox context Enables targeting freeze-user-cgroup and other sandbox flags by the guest envd version. Set on the sandbox context in create/pause/ checkpoint; propagates to the reclaim freeze eval via ctx. --- packages/orchestrator/pkg/server/sandboxes.go | 38 +++++++++++-------- packages/shared/pkg/featureflags/flags.go | 1 + 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/packages/orchestrator/pkg/server/sandboxes.go b/packages/orchestrator/pkg/server/sandboxes.go index 08d4b8df44..534c17791e 100644 --- a/packages/orchestrator/pkg/server/sandboxes.go +++ b/packages/orchestrator/pkg/server/sandboxes.go @@ -112,6 +112,7 @@ func (s *Server) Create(ctx context.Context, req *orchestrator.SandboxCreateRequ SetString(featureflags.SandboxTemplateAttribute, req.GetSandbox().GetTemplateId()). SetString(featureflags.SandboxKernelVersionAttribute, req.GetSandbox().GetKernelVersion()). SetString(featureflags.SandboxFirecrackerVersionAttribute, req.GetSandbox().GetFirecrackerVersion()). + SetString(featureflags.SandboxEnvdVersionAttribute, req.GetSandbox().GetEnvdVersion()). Build(), ldcontext.NewBuilder(req.GetSandbox().GetTeamId()). Kind(featureflags.TeamKind). @@ -585,14 +586,6 @@ func (s *Server) Pause(ctx context.Context, in *orchestrator.SandboxPauseRequest telemetry.WithBuildID(in.GetBuildId()), ) - ctx = featureflags.AddToContext( - ctx, - ldcontext.NewBuilder(in.GetSandboxId()). - Kind(featureflags.SandboxKind). - SetString(featureflags.SandboxTemplateAttribute, in.GetTemplateId()). - Build(), - ) - sbx, ok := s.sandboxFactory.Sandboxes.Get(in.GetSandboxId()) if !ok { telemetry.ReportCriticalError(ctx, "sandbox not found", nil, telemetry.WithSandboxID(in.GetSandboxId())) @@ -600,6 +593,17 @@ func (s *Server) Pause(ctx context.Context, in *orchestrator.SandboxPauseRequest return nil, status.Error(codes.NotFound, "sandbox not found") } + ctx = featureflags.AddToContext( + ctx, + ldcontext.NewBuilder(in.GetSandboxId()). + Kind(featureflags.SandboxKind). + SetString(featureflags.SandboxTemplateAttribute, sbx.Runtime.TemplateID). + SetString(featureflags.SandboxKernelVersionAttribute, sbx.Config.FirecrackerConfig.KernelVersion). + SetString(featureflags.SandboxFirecrackerVersionAttribute, sbx.Config.FirecrackerConfig.FirecrackerVersion). + SetString(featureflags.SandboxEnvdVersionAttribute, sbx.Config.Envd.Version). + Build(), + ) + childSpan.SetAttributes( telemetry.WithTeamID(sbx.Runtime.TeamID), telemetry.WithFirecrackerVersion(sbx.Config.FirecrackerConfig.FirecrackerVersion), @@ -667,13 +671,6 @@ func (s *Server) Checkpoint(ctx context.Context, in *orchestrator.SandboxCheckpo telemetry.WithBuildID(in.GetBuildId()), ) - ctx = featureflags.AddToContext( - ctx, - ldcontext.NewBuilder(in.GetSandboxId()). - Kind(featureflags.SandboxKind). - Build(), - ) - sbx, ok := s.sandboxFactory.Sandboxes.Get(in.GetSandboxId()) if !ok { telemetry.ReportCriticalError(ctx, "sandbox not found", nil, telemetry.WithSandboxID(in.GetSandboxId())) @@ -681,6 +678,17 @@ func (s *Server) Checkpoint(ctx context.Context, in *orchestrator.SandboxCheckpo return nil, status.Errorf(codes.NotFound, "sandbox '%s' not found", in.GetSandboxId()) } + ctx = featureflags.AddToContext( + ctx, + ldcontext.NewBuilder(in.GetSandboxId()). + Kind(featureflags.SandboxKind). + SetString(featureflags.SandboxTemplateAttribute, sbx.Runtime.TemplateID). + SetString(featureflags.SandboxKernelVersionAttribute, sbx.Config.FirecrackerConfig.KernelVersion). + SetString(featureflags.SandboxFirecrackerVersionAttribute, sbx.Config.FirecrackerConfig.FirecrackerVersion). + SetString(featureflags.SandboxEnvdVersionAttribute, sbx.Config.Envd.Version). + Build(), + ) + childSpan.SetAttributes( telemetry.WithTeamID(sbx.Runtime.TeamID), telemetry.WithTemplateID(sbx.Runtime.TemplateID), diff --git a/packages/shared/pkg/featureflags/flags.go b/packages/shared/pkg/featureflags/flags.go index a181bde3a7..6b80a58a29 100644 --- a/packages/shared/pkg/featureflags/flags.go +++ b/packages/shared/pkg/featureflags/flags.go @@ -18,6 +18,7 @@ const ( SandboxTemplateAttribute string = "template-id" SandboxKernelVersionAttribute string = "kernel-version" SandboxFirecrackerVersionAttribute string = "firecracker-version" + SandboxEnvdVersionAttribute string = "envd-version" // SandboxTypeAttribute distinguishes "sandbox" from "build" runs. SandboxTypeAttribute string = "sandbox-type" From 5b1e6afd700b0fb02ee35bfdf967f3f19d8bcd06 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Sun, 21 Jun 2026 09:11:27 +0000 Subject: [PATCH 2/4] feat(orchestrator): carry envd-version on build-path sandbox LD context Drive the envd-version attribute off Config.Envd.Version in the shared sandboxLDContext helper so it is present on both regular and build sandboxes (envd version is resolved during build). Switch the freeze-user-cgroup and reclaim-config evals to this helper so they no longer depend on server-side ctx propagation, which the build path does not run. --- packages/orchestrator/pkg/sandbox/reclaim.go | 6 ++++-- packages/orchestrator/pkg/sandbox/sandbox.go | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/orchestrator/pkg/sandbox/reclaim.go b/packages/orchestrator/pkg/sandbox/reclaim.go index 270be40e8d..92c60e14fb 100644 --- a/packages/orchestrator/pkg/sandbox/reclaim.go +++ b/packages/orchestrator/pkg/sandbox/reclaim.go @@ -62,14 +62,16 @@ func (s *Sandbox) bestEffortReclaim(ctx context.Context) { ctx, span := tracer.Start(ctx, "envd-reclaim") defer span.End() + sbxCtx := sandboxLDContext(s.Runtime, s.Config) + cfg := featureflags.GetReclaimConfig(ctx, s.featureFlags, - featureflags.SandboxContext(s.Runtime.SandboxID), + sbxCtx, featureflags.TeamContext(s.Runtime.TeamID), featureflags.TemplateContext(s.Runtime.TemplateID), ) if s.featureFlags.BoolFlag(ctx, featureflags.FreezeUserCgroupFlag, - featureflags.SandboxContext(s.Runtime.SandboxID), + sbxCtx, featureflags.TeamContext(s.Runtime.TeamID), featureflags.TemplateContext(s.Runtime.TemplateID), ) { diff --git a/packages/orchestrator/pkg/sandbox/sandbox.go b/packages/orchestrator/pkg/sandbox/sandbox.go index 8101f91400..63e7254955 100644 --- a/packages/orchestrator/pkg/sandbox/sandbox.go +++ b/packages/orchestrator/pkg/sandbox/sandbox.go @@ -183,7 +183,7 @@ type RuntimeMetadata struct { SandboxType SandboxType } -// sandboxLDContext builds an LD context with kernel/FC-version attributes for +// sandboxLDContext builds an LD context with envd/kernel/FC-version attributes for // per-sandbox flag targeting. Team/template targeting comes from the team and // template contexts the caller embeds in ctx. func sandboxLDContext(runtime RuntimeMetadata, config *Config) ldcontext.Context { @@ -192,6 +192,7 @@ func sandboxLDContext(runtime RuntimeMetadata, config *Config) ldcontext.Context SetString(featureflags.SandboxTemplateAttribute, runtime.TemplateID). SetString(featureflags.SandboxKernelVersionAttribute, config.FirecrackerConfig.KernelVersion). SetString(featureflags.SandboxFirecrackerVersionAttribute, config.FirecrackerConfig.FirecrackerVersion). + SetString(featureflags.SandboxEnvdVersionAttribute, config.Envd.Version). SetString(featureflags.SandboxTypeAttribute, runtime.SandboxType.String()). Build() } From 012302ef101e00d663c924c4dfa18d73073a7362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Nov=C3=A1k?= Date: Sun, 21 Jun 2026 02:56:41 -0700 Subject: [PATCH 3/4] Apply suggestion from @arkamar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Petr Vaněk --- packages/orchestrator/pkg/sandbox/reclaim.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/orchestrator/pkg/sandbox/reclaim.go b/packages/orchestrator/pkg/sandbox/reclaim.go index 572283be3b..92f485db59 100644 --- a/packages/orchestrator/pkg/sandbox/reclaim.go +++ b/packages/orchestrator/pkg/sandbox/reclaim.go @@ -101,7 +101,7 @@ func (s *Sandbox) bestEffortReclaim(ctx context.Context) { } if s.featureFlags.BoolFlag(ctx, featureflags.CollapseEnvdHeapFlag, - featureflags.SandboxContext(s.Runtime.SandboxID), + sbxCtx, featureflags.TeamContext(s.Runtime.TeamID), featureflags.TemplateContext(s.Runtime.TemplateID), ) { From 77c53721184dd316522b26ae99d5acb78695d58e Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Sun, 21 Jun 2026 10:17:13 +0000 Subject: [PATCH 4/4] simplify --- packages/orchestrator/pkg/sandbox/reclaim.go | 26 ++++++-------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/packages/orchestrator/pkg/sandbox/reclaim.go b/packages/orchestrator/pkg/sandbox/reclaim.go index 92f485db59..2d65b8cd5a 100644 --- a/packages/orchestrator/pkg/sandbox/reclaim.go +++ b/packages/orchestrator/pkg/sandbox/reclaim.go @@ -84,30 +84,22 @@ func (s *Sandbox) bestEffortReclaim(ctx context.Context) { ctx, span := tracer.Start(ctx, "envd-reclaim") defer span.End() - sbxCtx := sandboxLDContext(s.Runtime, s.Config) - - cfg := featureflags.GetReclaimConfig(ctx, s.featureFlags, - sbxCtx, + ctx = featureflags.AddToContext( + ctx, + sandboxLDContext(s.Runtime, s.Config), featureflags.TeamContext(s.Runtime.TeamID), featureflags.TemplateContext(s.Runtime.TemplateID), ) - if s.featureFlags.BoolFlag(ctx, featureflags.FreezeUserCgroupFlag, - sbxCtx, - featureflags.TeamContext(s.Runtime.TeamID), - featureflags.TemplateContext(s.Runtime.TemplateID), - ) { + if s.featureFlags.BoolFlag(ctx, featureflags.FreezeUserCgroupFlag) { s.bestEffortFreeze(ctx) } - if s.featureFlags.BoolFlag(ctx, featureflags.CollapseEnvdHeapFlag, - sbxCtx, - featureflags.TeamContext(s.Runtime.TeamID), - featureflags.TemplateContext(s.Runtime.TemplateID), - ) { + if s.featureFlags.BoolFlag(ctx, featureflags.CollapseEnvdHeapFlag) { s.bestEffortCollapse(ctx) } + cfg := featureflags.GetReclaimConfig(ctx, s.featureFlags) script, timeout := s.buildReclaimScript(cfg) if script == "" { return @@ -310,11 +302,7 @@ func (s *Sandbox) bestEffortCollapse(ctx context.Context) { // Timeout comes straight from the flag, whose fallback (10s) is returned // whenever LD is unavailable or the flag is unset — so there is no separate // local default to keep in sync. - timeout := time.Duration(s.featureFlags.IntFlag(ctx, featureflags.CollapseEnvdHeapTimeoutMsFlag, - featureflags.SandboxContext(s.Runtime.SandboxID), - featureflags.TeamContext(s.Runtime.TeamID), - featureflags.TemplateContext(s.Runtime.TemplateID), - )) * time.Millisecond + timeout := time.Duration(s.featureFlags.IntFlag(ctx, featureflags.CollapseEnvdHeapTimeoutMsFlag)) * time.Millisecond start := time.Now() stats, err := s.callEnvdCollapse(ctx, timeout)