From 55edeed22b8bfe1e71d68b5c75cf434f5be647b6 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Thu, 23 May 2024 17:25:45 -0700 Subject: [PATCH] allow controlling detected platforms cache timeout Because detecting emulator changes can be relatively expensive, avoid doing it very frequently. A new config parameter allows controlling if users prefer more or less frequent updates or want to disable detecting changes completely and only rely on emultor configuration at boot time. Signed-off-by: Tonis Tiigi --- cmd/buildkitd/config/config.go | 8 ++++++++ cmd/buildkitd/main.go | 6 ++++++ util/archutil/detect.go | 13 ++++++++++--- worker/base/worker.go | 8 ++++++-- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/cmd/buildkitd/config/config.go b/cmd/buildkitd/config/config.go index 28c11acb983ed..d8da19ecafec3 100644 --- a/cmd/buildkitd/config/config.go +++ b/cmd/buildkitd/config/config.go @@ -38,6 +38,14 @@ type Config struct { Dockerfile DockerfileFrontendConfig `toml:"dockerfile.v0"` Gateway GatewayFrontendConfig `toml:"gateway.v0"` } `toml:"frontend"` + + System *SystemConfig `toml:"system"` +} + +type SystemConfig struct { + // PlatformCacheMaxAge controls how often supported platforms + // are refreshed by rescanning the system. + PlatformsCacheMaxAge *Duration `toml:"platformsCacheMaxAge"` } type LogConfig struct { diff --git a/cmd/buildkitd/main.go b/cmd/buildkitd/main.go index d254b7ce1d959..d57defa53826e 100644 --- a/cmd/buildkitd/main.go +++ b/cmd/buildkitd/main.go @@ -262,6 +262,12 @@ func main() { logrus.SetLevel(logrus.TraceLevel) } + if sc := cfg.System; sc != nil { + if v := sc.PlatformsCacheMaxAge; v != nil { + archutil.CacheMaxAge = v.Duration + } + } + if cfg.GRPC.DebugAddress != "" { if err := setupDebugHandlers(cfg.GRPC.DebugAddress); err != nil { return err diff --git a/util/archutil/detect.go b/util/archutil/detect.go index 5808333f91b5f..b52a77adee09f 100644 --- a/util/archutil/detect.go +++ b/util/archutil/detect.go @@ -4,21 +4,28 @@ import ( "sort" "strings" "sync" + "time" "github.com/containerd/containerd/platforms" "github.com/moby/buildkit/util/bklog" ocispecs "github.com/opencontainers/image-spec/specs-go/v1" ) -var mu sync.Mutex -var arr []ocispecs.Platform +var CacheMaxAge time.Duration = 20 * time.Second + +var ( + mu sync.Mutex + arr []ocispecs.Platform + lastRefresh time.Time +) func SupportedPlatforms(noCache bool) []ocispecs.Platform { mu.Lock() defer mu.Unlock() - if !noCache && arr != nil { + if arr != nil && (!noCache || CacheMaxAge < 0 || time.Since(lastRefresh) < CacheMaxAge) { return arr } + defer func() { lastRefresh = time.Now() }() def := nativePlatform() arr = append([]ocispecs.Platform{}, def) diff --git a/worker/base/worker.go b/worker/base/worker.go index de8c1d5774732..78cd6fef85c8a 100644 --- a/worker/base/worker.go +++ b/worker/base/worker.go @@ -245,10 +245,14 @@ func (w *Worker) Labels() map[string]string { func (w *Worker) Platforms(noCache bool) []ocispecs.Platform { if noCache { + matchers := make([]platforms.MatchComparer, len(w.WorkerOpt.Platforms)) + for i, p := range w.WorkerOpt.Platforms { + matchers[i] = platforms.Only(p) + } for _, p := range archutil.SupportedPlatforms(noCache) { exists := false - for _, pp := range w.WorkerOpt.Platforms { - if platforms.Only(pp).Match(p) { + for _, m := range matchers { + if m.Match(p) { exists = true break }