about summary refs log tree commit diff
path: root/tools/nixery/storage
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2020-10-29T15·13+0100
committerVincent Ambo <mail@tazj.in>2020-10-29T16·07+0100
commitcc35bf0fc3a900dccf4f9edcc581cadb5956c439 (patch)
treeec23fc45ff5c0194e2bbb902d95f18c634c14c2b /tools/nixery/storage
parent8a5c446babbac860d6eaee6f7e0c5a5a8a6f4183 (diff)
feat(storage): Add support for content-types (GCS only)
Extends storage.Persist to accept a Content-Type argument, which in
the GCS backend is persisted with the object to ensure that the object
is served back with this content-type.

This is not yet implemented for the filesystem backend, where the
parameter is simply ignored.

This should help in the case of clients which expect the returned
objects to have content-types set when, for example, fetching layers
by digest.
Diffstat (limited to 'tools/nixery/storage')
-rw-r--r--tools/nixery/storage/filesystem.go3
-rw-r--r--tools/nixery/storage/gcs.go25
-rw-r--r--tools/nixery/storage/storage.go2
3 files changed, 25 insertions, 5 deletions
diff --git a/tools/nixery/storage/filesystem.go b/tools/nixery/storage/filesystem.go
index 926e9257a1..bd757587b4 100644
--- a/tools/nixery/storage/filesystem.go
+++ b/tools/nixery/storage/filesystem.go
@@ -49,7 +49,8 @@ func (b *FSBackend) Name() string {
 	return fmt.Sprintf("Filesystem (%s)", b.path)
 }
 
-func (b *FSBackend) Persist(ctx context.Context, key string, f Persister) (string, int64, error) {
+// TODO(tazjin): Implement support for persisting content-types for the filesystem backend.
+func (b *FSBackend) Persist(ctx context.Context, key, _type string, f Persister) (string, int64, error) {
 	full := path.Join(b.path, key)
 	dir := path.Dir(full)
 	err := os.MkdirAll(dir, 0755)
diff --git a/tools/nixery/storage/gcs.go b/tools/nixery/storage/gcs.go
index 61b5dea523..eac34461af 100644
--- a/tools/nixery/storage/gcs.go
+++ b/tools/nixery/storage/gcs.go
@@ -80,17 +80,36 @@ func (b *GCSBackend) Name() string {
 	return "Google Cloud Storage (" + b.bucket + ")"
 }
 
-func (b *GCSBackend) Persist(ctx context.Context, path string, f Persister) (string, int64, error) {
+func (b *GCSBackend) Persist(ctx context.Context, path, contentType string, f Persister) (string, int64, error) {
 	obj := b.handle.Object(path)
 	w := obj.NewWriter(ctx)
 
 	hash, size, err := f(w)
 	if err != nil {
-		log.WithError(err).WithField("path", path).Error("failed to upload to GCS")
+		log.WithError(err).WithField("path", path).Error("failed to write to GCS")
 		return hash, size, err
 	}
 
-	return hash, size, w.Close()
+	err = w.Close()
+	if err != nil {
+		log.WithError(err).WithField("path", path).Error("failed to complete GCS upload")
+		return hash, size, err
+	}
+
+	// GCS natively supports content types for objects, which will be
+	// used when serving them back.
+	if contentType != "" {
+		_, err = obj.Update(ctx, storage.ObjectAttrsToUpdate{
+			ContentType: contentType,
+		})
+
+		if err != nil {
+			log.WithError(err).WithField("path", path).Error("failed to update object attrs")
+			return hash, size, err
+		}
+	}
+
+	return hash, size, nil
 }
 
 func (b *GCSBackend) Fetch(ctx context.Context, path string) (io.ReadCloser, error) {
diff --git a/tools/nixery/storage/storage.go b/tools/nixery/storage/storage.go
index 4040ef08dc..fd496f440a 100644
--- a/tools/nixery/storage/storage.go
+++ b/tools/nixery/storage/storage.go
@@ -36,7 +36,7 @@ type Backend interface {
 	// It needs to return the SHA256 hash of the data written as
 	// well as the total number of bytes, as those are required
 	// for the image manifest.
-	Persist(context.Context, string, Persister) (string, int64, error)
+	Persist(ctx context.Context, path, contentType string, f Persister) (string, int64, error)
 
 	// Fetch retrieves data from the storage backend.
 	Fetch(ctx context.Context, path string) (io.ReadCloser, error)