diff --git a/packages/api/internal/template-manager/cache_scope.go b/packages/api/internal/template-manager/cache_scope.go new file mode 100644 index 0000000000..524a5ee800 --- /dev/null +++ b/packages/api/internal/template-manager/cache_scope.go @@ -0,0 +1,38 @@ +package template_manager + +import ( + "os" + "sync" + + "github.com/google/uuid" +) + +// templateCacheScopeEnv, when set to a non-empty value, overrides the per-team +// layer cache scope with a single shared scope so that identical content- +// addressed layers (and the buildID-keyed memfile/rootfs they resolve to) are +// stored and reused across teams instead of once per team. +// +// Default (unset): the scope is the teamID, preserving upstream per-team cache +// isolation. Only set this in a single trusted organization / self-hosted +// deployment where cross-team cache sharing is acceptable: a shared scope lets +// any team hit (and thus prove the existence of, and reuse) another team's +// cached layers. +const templateCacheScopeEnv = "TEMPLATE_CACHE_SCOPE" + +var ( + cacheScopeOnce sync.Once + cacheScopeShared string +) + +// cacheScopeFor returns the layer cache scope for a build owned by teamID. +// If TEMPLATE_CACHE_SCOPE is set it returns that shared scope for every team +// (cross-team dedup); otherwise it returns the teamID (per-team isolation). +func cacheScopeFor(teamID uuid.UUID) string { + cacheScopeOnce.Do(func() { + cacheScopeShared = os.Getenv(templateCacheScopeEnv) + }) + if cacheScopeShared != "" { + return cacheScopeShared + } + return teamID.String() +} diff --git a/packages/api/internal/template-manager/create_template.go b/packages/api/internal/template-manager/create_template.go index 66e38301a5..ff00927282 100644 --- a/packages/api/internal/template-manager/create_template.go +++ b/packages/api/internal/template-manager/create_template.go @@ -157,7 +157,7 @@ func (tm *TemplateManager) CreateTemplate( _, err = client.Template.TemplateCreate( ctx, &templatemanagergrpc.TemplateCreateRequest{ Template: template, - CacheScope: new(teamID.String()), + CacheScope: new(cacheScopeFor(teamID)), Version: &version, }, ) diff --git a/packages/api/internal/template-manager/upload_template_layer_files.go b/packages/api/internal/template-manager/upload_template_layer_files.go index 13e3c08fee..d60c755fd5 100644 --- a/packages/api/internal/template-manager/upload_template_layer_files.go +++ b/packages/api/internal/template-manager/upload_template_layer_files.go @@ -18,7 +18,7 @@ func (tm *TemplateManager) InitLayerFileUpload(ctx context.Context, clusterID uu resp, err := client.Template.InitLayerFileUpload( ctx, &templatemanager.InitLayerFileUploadRequest{ - CacheScope: new(teamID.String()), + CacheScope: new(cacheScopeFor(teamID)), TemplateID: templateID, Hash: hash, },