Skip to content
Open
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
13 changes: 1 addition & 12 deletions packages/api/internal/orchestrator/create_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion packages/orchestrator/internal/server/sandboxes.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,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)
Expand Down Expand Up @@ -139,6 +140,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())
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolvedFCVersion may differ from req.GetSandbox().GetFirecrackerVersion() when node-specific overrides are active. However, SandboxFirecrackerVersionAttribute in the LD multi-context was already set to the incoming (API-resolved) version at line 74, before this resolution. Any other feature flags in this request that target on the sandbox's firecracker-version attribute will evaluate against the pre-orchestrator-resolved value rather than the version that will actually be used.


volumeMounts, err := createVolumeMountModelsFromAPI(req.GetSandbox().GetVolumeMounts())
if err != nil {
return nil, fmt.Errorf("failed to convert volume mounts: %w", err)
Expand All @@ -165,7 +168,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: volumeMounts,
Expand Down
7 changes: 7 additions & 0 deletions packages/shared/pkg/feature-flags/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
28 changes: 28 additions & 0 deletions packages/shared/pkg/feature-flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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/
Expand Down Expand Up @@ -224,6 +229,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, ...}
Expand Down