From c2ad55fd9e66f3e420e0d330c3a3502fc5aedf57 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Sun, 1 Mar 2026 21:53:10 +0100 Subject: [PATCH 1/2] chore(orch): move firecracker version feature flag --- .../internal/orchestrator/create_instance.go | 13 +-------- .../orchestrator/internal/server/sandboxes.go | 5 +++- packages/shared/pkg/feature-flags/context.go | 7 +++++ packages/shared/pkg/feature-flags/flags.go | 28 +++++++++++++++++++ 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/packages/api/internal/orchestrator/create_instance.go b/packages/api/internal/orchestrator/create_instance.go index d65ec4a36e..e5fde58d7e 100644 --- a/packages/api/internal/orchestrator/create_instance.go +++ b/packages/api/internal/orchestrator/create_instance.go @@ -7,7 +7,6 @@ import ( "net/http" "time" - "github.com/Masterminds/semver/v3" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" "go.uber.org/zap" @@ -71,16 +70,6 @@ func buildNetworkConfig(network *types.SandboxNetworkConfig, allowInternetAccess return orchNetwork } -func getFirecrackerVersion(ctx context.Context, featureFlags *feature_flags.Client, version semver.Version, fallback string) string { - firecrackerVersions := featureFlags.JSONFlag(ctx, feature_flags.FirecrackerVersions).AsValueMap() - fcVersion, ok := firecrackerVersions.Get(fmt.Sprintf("v%d.%d", version.Major(), version.Minor())).AsOptionalString().Get() - if !ok { - return fallback - } - - return fcVersion -} - func (o *Orchestrator) CreateSandbox( ctx context.Context, sandboxID, @@ -180,7 +169,7 @@ func (o *Orchestrator) CreateSandbox( } hasHugePages := fcSemver.HasHugePages() - firecrackerVersion := getFirecrackerVersion(ctx, o.featureFlagsClient, fcSemver.Version(), build.FirecrackerVersion) + firecrackerVersion := feature_flags.ResolveFirecrackerVersion(ctx, o.featureFlagsClient, build.FirecrackerVersion) telemetry.ReportEvent(ctx, "Got FC info") var sbxDomain *string diff --git a/packages/orchestrator/internal/server/sandboxes.go b/packages/orchestrator/internal/server/sandboxes.go index e2949395e0..ca7d0bd393 100644 --- a/packages/orchestrator/internal/server/sandboxes.go +++ b/packages/orchestrator/internal/server/sandboxes.go @@ -76,6 +76,7 @@ func (s *Server) Create(ctx context.Context, req *orchestrator.SandboxCreateRequ ldcontext.NewBuilder(req.GetSandbox().GetTeamId()). Kind(featureflags.TeamKind). Build(), + featureflags.VersionContext(s.info.ClientId, s.info.SourceCommit), ) maxRunningSandboxesPerNode := s.featureFlags.IntFlag(ctx, featureflags.MaxSandboxesPerNode) @@ -133,6 +134,8 @@ func (s *Server) Create(ctx context.Context, req *orchestrator.SandboxCreateRequ network.Egress.DeniedCidrs = []string{sandbox_network.AllInternetTrafficCIDR} } + resolvedFCVersion := featureflags.ResolveFirecrackerVersion(ctx, s.featureFlags, req.GetSandbox().GetFirecrackerVersion()) + sbx, err := s.sandboxFactory.ResumeSandbox( ctx, template, @@ -154,7 +157,7 @@ func (s *Server) Create(ctx context.Context, req *orchestrator.SandboxCreateRequ FirecrackerConfig: fc.Config{ KernelVersion: req.GetSandbox().GetKernelVersion(), - FirecrackerVersion: req.GetSandbox().GetFirecrackerVersion(), + FirecrackerVersion: resolvedFCVersion, }, VolumeMounts: createVolumeMountModelsFromAPI(req.GetSandbox().GetVolumeMounts()), diff --git a/packages/shared/pkg/feature-flags/context.go b/packages/shared/pkg/feature-flags/context.go index 1b3d3dc6d7..df8094f676 100644 --- a/packages/shared/pkg/feature-flags/context.go +++ b/packages/shared/pkg/feature-flags/context.go @@ -163,3 +163,10 @@ func TemplateContext(templateID string) ldcontext.Context { func VolumeContext(volumeName string) ldcontext.Context { return ldcontext.NewWithKind(VolumeKind, volumeName) } + +func VersionContext(orchestratorID, commit string) ldcontext.Context { + return ldcontext.NewBuilder(orchestratorID). + Kind(OrchestratorKind). + SetString(OrchestratorCommitAttribute, commit). + Build() +} diff --git a/packages/shared/pkg/feature-flags/flags.go b/packages/shared/pkg/feature-flags/flags.go index e5aab3344a..d24967a593 100644 --- a/packages/shared/pkg/feature-flags/flags.go +++ b/packages/shared/pkg/feature-flags/flags.go @@ -2,6 +2,8 @@ package feature_flags import ( "context" + "fmt" + "strings" "github.com/launchdarkly/go-sdk-common/v3/ldcontext" "github.com/launchdarkly/go-sdk-common/v3/ldvalue" @@ -24,6 +26,9 @@ const ( ServiceKind ldcontext.Kind = "service" TemplateKind ldcontext.Kind = "template" VolumeKind ldcontext.Kind = "volume" + + OrchestratorKind ldcontext.Kind = "orchestrator" + OrchestratorCommitAttribute string = "commit" ) // All flags must be defined here: https://app.launchdarkly.com/projects/default/flags/ @@ -211,6 +216,29 @@ var ( FirecrackerVersions = newJSONFlag("firecracker-versions", ldvalue.FromJSONMarshal(FirecrackerVersionMap)) ) +// ResolveFirecrackerVersion resolves the firecracker version using the FirecrackerVersions feature flag. +// The buildVersion format is "v1.12.1_a41d3fb" — we extract "v1.12" as the lookup key. +func ResolveFirecrackerVersion(ctx context.Context, ff *Client, buildVersion string) string { + parts := strings.Split(buildVersion, "_") + if len(parts) < 2 { + return buildVersion + } + + versionParts := strings.Split(strings.TrimPrefix(parts[0], "v"), ".") + if len(versionParts) < 2 { + return buildVersion + } + + key := fmt.Sprintf("v%s.%s", versionParts[0], versionParts[1]) + versions := ff.JSONFlag(ctx, FirecrackerVersions).AsValueMap() + + if resolved, ok := versions.Get(key).AsOptionalString().Get(); ok { + return resolved + } + + return buildVersion +} + // defaultTrackedTemplates is the default map of template aliases tracked for metrics. // This is used to reduce metric cardinality. // JSON format: {"base": true, "code-interpreter-v1": true, ...} From d252a5704779d1ecc56fbd17b8c26eb2e6224513 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 9 Mar 2026 19:50:17 +0000 Subject: [PATCH 2/2] chore: auto-commit generated changes --- packages/orchestrator/internal/server/sandboxes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/orchestrator/internal/server/sandboxes.go b/packages/orchestrator/internal/server/sandboxes.go index e14317e6db..542e2a22a8 100644 --- a/packages/orchestrator/internal/server/sandboxes.go +++ b/packages/orchestrator/internal/server/sandboxes.go @@ -142,7 +142,7 @@ func (s *Server) Create(ctx context.Context, req *orchestrator.SandboxCreateRequ resolvedFCVersion := featureflags.ResolveFirecrackerVersion(ctx, s.featureFlags, req.GetSandbox().GetFirecrackerVersion()) - volumeMounts, err := createVolumeMountModelsFromAPI(req.GetSandbox().GetVolumeMounts()) + volumeMounts, err := createVolumeMountModelsFromAPI(req.GetSandbox().GetVolumeMounts()) if err != nil { return nil, fmt.Errorf("failed to convert volume mounts: %w", err) }