Skip to content
Closed
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
5 changes: 4 additions & 1 deletion packages/orchestrator/cmd/show-build-diff/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ func main() {
)
}

mergedHeader := header.MergeMappings(baseHeader.Mapping, onlyDiffMappings)
mergedHeader, err := header.MergeMappings(baseHeader.Mapping, onlyDiffMappings)
if err != nil {
log.Fatalf("merge mappings: %v", err)
}

fmt.Printf("\n\nMERGED METADATA\n")
fmt.Printf("========\n")
Expand Down
4 changes: 2 additions & 2 deletions packages/shared/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ require (
github.com/hashicorp/go-retryablehttp v0.7.7
github.com/hashicorp/nomad/api v0.0.0-20251216171439-1dee0671280e
github.com/jellydator/ttlcache/v3 v3.4.0
github.com/klauspost/compress v1.18.2
github.com/launchdarkly/go-sdk-common/v3 v3.3.0
github.com/launchdarkly/go-server-sdk/v7 v7.13.0
github.com/ngrok/firewall_toolkit v0.0.18
github.com/oapi-codegen/runtime v1.1.1
github.com/orcaman/concurrent-map/v2 v2.0.1
github.com/pierrec/lz4/v4 v4.1.22
github.com/redis/go-redis/extra/redisotel/v9 v9.17.3
github.com/redis/go-redis/v9 v9.17.3
github.com/stretchr/testify v1.11.1
Expand Down Expand Up @@ -229,7 +231,6 @@ require (
github.com/json-iterator/go v1.1.12 // indirect
github.com/julienschmidt/httprouter v1.3.0 // indirect
github.com/kamstrup/intmap v0.5.1 // indirect
github.com/klauspost/compress v1.18.2 // indirect
github.com/klauspost/cpuid/v2 v2.2.11 // indirect
github.com/knadh/koanf/maps v0.1.2 // indirect
github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
Expand Down Expand Up @@ -281,7 +282,6 @@ require (
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pierrec/lz4/v4 v4.1.22 // indirect
github.com/pires/go-proxyproto v0.7.0 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
Expand Down
8 changes: 8 additions & 0 deletions packages/shared/pkg/featureflags/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,14 @@ func VolumeContext(volumeName string) ldcontext.Context {
return ldcontext.NewWithKind(VolumeKind, volumeName)
}

func CompressFileTypeContext(fileType string) ldcontext.Context {
return ldcontext.NewWithKind(CompressFileTypeKind, fileType)
}

func CompressUseCaseContext(useCase string) ldcontext.Context {
return ldcontext.NewWithKind(CompressUseCaseKind, useCase)
}

func VersionContext(orchestratorID, commit string) ldcontext.Context {
return ldcontext.NewBuilder(orchestratorID).
Kind(OrchestratorKind).
Expand Down
31 changes: 23 additions & 8 deletions packages/shared/pkg/featureflags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ const (
SandboxKernelVersionAttribute string = "kernel-version"
SandboxFirecrackerVersionAttribute string = "firecracker-version"

TeamKind ldcontext.Kind = "team"
UserKind ldcontext.Kind = "user"
ClusterKind ldcontext.Kind = "cluster"
deploymentKind ldcontext.Kind = "deployment"
TierKind ldcontext.Kind = "tier"
ServiceKind ldcontext.Kind = "service"
TemplateKind ldcontext.Kind = "template"
VolumeKind ldcontext.Kind = "volume"
TeamKind ldcontext.Kind = "team"
UserKind ldcontext.Kind = "user"
ClusterKind ldcontext.Kind = "cluster"
deploymentKind ldcontext.Kind = "deployment"
TierKind ldcontext.Kind = "tier"
ServiceKind ldcontext.Kind = "service"
TemplateKind ldcontext.Kind = "template"
VolumeKind ldcontext.Kind = "volume"
CompressFileTypeKind ldcontext.Kind = "compress-file-type"
CompressUseCaseKind ldcontext.Kind = "compress-use-case"

OrchestratorKind ldcontext.Kind = "orchestrator"
OrchestratorCommitAttribute string = "commit"
Expand Down Expand Up @@ -326,6 +328,19 @@ var ChunkerConfigFlag = newJSONFlag("chunker-config", ldvalue.FromJSONMarshal(ma
"minReadBatchSizeKB": 16,
}))

// CompressConfigFlag controls compression during template builds.
// When compressBuilds is true, builds upload exclusively compressed data
// (no uncompressed fallback). When false, exclusively uncompressed with V3 headers.
var CompressConfigFlag = newJSONFlag("compress-config", ldvalue.FromJSONMarshal(map[string]any{
"compressBuilds": false,
"compressionType": "zstd",
"compressionLevel": 2,
"frameSizeKB": 2048,
"targetPartSizeMB": 50,
"frameEncodeWorkers": 4,
"encoderConcurrency": 1,
}))

// TCPFirewallEgressThrottleConfig controls per-sandbox egress throttling via Firecracker's
// VMM-level token bucket rate limiters on the network interface.
// Structure mirrors the Firecracker RateLimiter API: two independent token buckets.
Expand Down
131 changes: 131 additions & 0 deletions packages/shared/pkg/storage/compress_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package storage

import (
"context"
"fmt"

"github.com/e2b-dev/infra/packages/shared/pkg/featureflags"
)

// CompressConfig is the base compression configuration, loaded from environment
// variables at startup. Feature flags can override individual fields at runtime
// via ResolveCompressConfig.
type CompressConfig struct {
Enabled bool `env:"COMPRESS_ENABLED" envDefault:"false"`
Type string `env:"COMPRESS_TYPE" envDefault:"zstd"`
Level int `env:"COMPRESS_LEVEL" envDefault:"2"`
FrameSizeKB int `env:"COMPRESS_FRAME_SIZE_KB" envDefault:"2048"`
TargetPartSizeMB int `env:"COMPRESS_TARGET_PART_SIZE_MB" envDefault:"50"`
FrameEncodeWorkers int `env:"COMPRESS_FRAME_ENCODE_WORKERS" envDefault:"4"`
EncoderConcurrency int `env:"COMPRESS_ENCODER_CONCURRENCY" envDefault:"1"`
}
Comment on lines +13 to +21
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

isn't this defined by the feature flags already?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

we need to override the FF settings for the integration tests, and also to configure the service in the future without FF


// CompressionType returns the parsed CompressionType.
func (c *CompressConfig) CompressionType() CompressionType {
if c == nil {
return CompressionNone
}

return ParseCompressionType(c.Type)
}

// FrameSize returns the frame size in bytes.
func (c *CompressConfig) FrameSize() int {
if c == nil || c.FrameSizeKB <= 0 {
return DefaultCompressFrameSize
}

return c.FrameSizeKB * 1024
}

// TargetPartSize returns the target part size in bytes.
func (c *CompressConfig) TargetPartSize() int64 {
if c == nil || c.TargetPartSizeMB <= 0 {
return int64(gcpMultipartUploadChunkSize)
}

return int64(c.TargetPartSizeMB) * (1 << 20)
}

// IsEnabled reports whether compression is configured and active.
func (c *CompressConfig) IsEnabled() bool {
return c != nil && c.Enabled && c.CompressionType() != CompressionNone
}

// Validate checks that the config is internally consistent.
func (c *CompressConfig) Validate() error {
if c == nil || !c.IsEnabled() {
return nil
}

fs := c.FrameSize()
if fs <= 0 {
return fmt.Errorf("frame size must be positive, got %d KB", c.FrameSizeKB)
}
if MemoryChunkSize%fs != 0 && fs%MemoryChunkSize != 0 {
return fmt.Errorf("frame size (%d) must be a divisor or multiple of MemoryChunkSize (%d)", fs, MemoryChunkSize)
}

return nil
}

// Resolve returns a pointer to this config if compression is enabled, or nil.
// Callers use nil to mean "no compression".
func (c *CompressConfig) Resolve() *CompressConfig {
if c == nil || !c.IsEnabled() {
return nil
}

return c
}

// CompressConfigFromLDValue parses the LaunchDarkly CompressConfigFlag JSON
// into a CompressConfig. Returns nil if the flag disables compression.
func CompressConfigFromLDValue(ctx context.Context, ff *featureflags.Client) *CompressConfig {
if ff == nil {
return nil
}

v := ff.JSONFlag(ctx, featureflags.CompressConfigFlag).AsValueMap()

if !v.Get("compressBuilds").BoolValue() {
return nil
}

ct := v.Get("compressionType").StringValue()
if ParseCompressionType(ct) == CompressionNone {
return nil
}

return &CompressConfig{
Enabled: true,
Type: ct,
Level: v.Get("compressionLevel").IntValue(),
FrameSizeKB: v.Get("frameSizeKB").IntValue(),
TargetPartSizeMB: v.Get("targetPartSizeMB").IntValue(),
FrameEncodeWorkers: v.Get("frameEncodeWorkers").IntValue(),
EncoderConcurrency: v.Get("encoderConcurrency").IntValue(),
}
}

// ResolveCompressConfig returns the effective compression config for a given
// file type and use case. Feature flags override the base config when active.
// Returns nil when compression is disabled.
//
// fileType and useCase are added to the LD evaluation context so that
// LaunchDarkly targeting rules can differentiate (e.g. compress memfile
// but not rootfs, or compress builds but not pauses).
func ResolveCompressConfig(ctx context.Context, base CompressConfig, ff *featureflags.Client, fileType, useCase string) *CompressConfig {
if ff != nil {
ctx = featureflags.AddToContext(ctx,
featureflags.CompressFileTypeContext(fileType),
featureflags.CompressUseCaseContext(useCase),
)

if override := CompressConfigFromLDValue(ctx, ff); override != nil {
return override
}
}

return base.Resolve()
}
Loading
Loading