From 355fe3f5ec05c3c698ea3ba21a5d57454daeceef Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Thu, 3 Oct 2019 11:23:04 +0100 Subject: feat(server): Reintroduce manifest caching to GCS The new builder now caches and reads cached manifests to/from GCS. The in-memory cache is disabled, as manifests are no longer written to local file and the caching of file paths does not work (unless we reintroduce reading/writing from temp files as part of the local cache). --- tools/nixery/server/builder/builder.go | 15 +++++++++--- tools/nixery/server/builder/cache.go | 43 ++++++++++++++-------------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/tools/nixery/server/builder/builder.go b/tools/nixery/server/builder/builder.go index d0650648fbcb..f3342f9918f8 100644 --- a/tools/nixery/server/builder/builder.go +++ b/tools/nixery/server/builder/builder.go @@ -366,7 +366,14 @@ func uploadHashLayer(ctx context.Context, s *State, key string, data io.Reader) } func BuildImage(ctx context.Context, s *State, image *Image) (*BuildResult, error) { - // TODO(tazjin): Use the build cache + key := s.Cfg.Pkgs.CacheKey(image.Packages, image.Tag) + if key != "" { + if m, c := manifestFromCache(ctx, s, key); c { + return &BuildResult{ + Manifest: m, + }, nil + } + } imageResult, err := prepareImage(s, image) if err != nil { @@ -410,10 +417,12 @@ func BuildImage(ctx context.Context, s *State, image *Image) (*BuildResult, erro return nil, err } + if key != "" { + go cacheManifest(ctx, s, key, m) + } + result := BuildResult{ Manifest: m, } - // TODO: cache manifest - return &result, nil } diff --git a/tools/nixery/server/builder/cache.go b/tools/nixery/server/builder/cache.go index 582e28d81abc..a5cbbf6ce469 100644 --- a/tools/nixery/server/builder/cache.go +++ b/tools/nixery/server/builder/cache.go @@ -18,8 +18,8 @@ import ( "context" "encoding/json" "io" + "io/ioutil" "log" - "os" "sync" ) @@ -86,57 +86,48 @@ func (c *LocalCache) localCacheBuild(key string, b Build) { // Retrieve a manifest from the cache(s). First the local cache is // checked, then the GCS-bucket cache. -func manifestFromCache(ctx context.Context, s *State, key string) (string, bool) { - path, cached := s.Cache.manifestFromLocalCache(key) - if cached { - return path, true - } +func manifestFromCache(ctx context.Context, s *State, key string) (json.RawMessage, bool) { + // path, cached := s.Cache.manifestFromLocalCache(key) + // if cached { + // return path, true + // } + // TODO: local cache? obj := s.Bucket.Object("manifests/" + key) // Probe whether the file exists before trying to fetch it. _, err := obj.Attrs(ctx) if err != nil { - return "", false + return nil, false } r, err := obj.NewReader(ctx) if err != nil { log.Printf("Failed to retrieve manifest '%s' from cache: %s\n", key, err) - return "", false + return nil, false } defer r.Close() - path = os.TempDir() + "/" + key - f, _ := os.Create(path) - defer f.Close() - - _, err = io.Copy(f, r) + m, err := ioutil.ReadAll(r) if err != nil { log.Printf("Failed to read cached manifest for '%s': %s\n", key, err) } + // TODO: locally cache manifest, but the cache needs to be changed log.Printf("Retrieved manifest for sha1:%s from GCS\n", key) - go s.Cache.localCacheManifest(key, path) - - return path, true + return json.RawMessage(m), true } // Add a manifest to the bucket & local caches -func cacheManifest(ctx context.Context, s *State, key, path string) { - go s.Cache.localCacheManifest(key, path) +func cacheManifest(ctx context.Context, s *State, key string, m json.RawMessage) { + // go s.Cache.localCacheManifest(key, path) + // TODO local cache obj := s.Bucket.Object("manifests/" + key) w := obj.NewWriter(ctx) + r := bytes.NewReader([]byte(m)) - f, err := os.Open(path) - if err != nil { - log.Printf("failed to open manifest sha1:%s for cache upload: %s\n", key, err) - return - } - defer f.Close() - - size, err := io.Copy(w, f) + size, err := io.Copy(w, r) if err != nil { log.Printf("failed to cache manifest sha1:%s: %s\n", key, err) return -- cgit 1.4.1