blob: 531419b57e0fbfac850c50f798e440704b2d71b7 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cache
import (
"path/filepath"
"strings"
"v.io/jiri"
"v.io/jiri/collect"
"v.io/jiri/runutil"
)
// StoreGoogleStorageFile reads the given file from the given Google Storage
// location and stores it in the given cache location. It returns the cached
// file path.
func StoreGoogleStorageFile(jirix *jiri.X, cacheRoot, bucketRoot, filename string) (_ string, e error) {
s := jirix.NewSeq()
cachedFile := filepath.Join(cacheRoot, filename)
if _, err := s.Stat(cachedFile); err != nil {
if !runutil.IsNotExist(err) {
return "", err
}
// To avoid interference between concurrent requests, download data to a
// tmp dir, and move it to the final location.
tmpDir, err := s.TempDir(cacheRoot, "")
if err != nil {
return "", err
}
defer collect.Error(func() error { return jirix.NewSeq().RemoveAll(tmpDir).Done() }, &e)
if err := s.Last("gsutil", "-m", "-q", "cp", "-r", bucketRoot+"/"+filename, tmpDir); err != nil {
return "", err
}
if err := s.Rename(filepath.Join(tmpDir, filename), cachedFile).Done(); err != nil {
// If the target directory already exists, it must have been created by
// a concurrent request.
if !strings.Contains(err.Error(), "directory not empty") {
return "", err
}
}
}
return cachedFile, nil
}