From efa24b6c3cd946d4386134f8fefb9b4e3a2a342b Mon Sep 17 00:00:00 2001 From: Denis Kurilov Date: Wed, 8 May 2024 02:32:49 +0400 Subject: [PATCH] Alpine go bump to fix the build; Transactional filestore add method; --- Dockerfile | 2 +- storage/gcsemu/filestore.go | 39 ++++++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index 61c7793..0d2b7ad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.17-alpine As builder +FROM golang:1.20-alpine As builder MAINTAINER Fullstory Engineering # create non-privileged group and user diff --git a/storage/gcsemu/filestore.go b/storage/gcsemu/filestore.go index f2999d2..3a343d6 100644 --- a/storage/gcsemu/filestore.go +++ b/storage/gcsemu/filestore.go @@ -86,18 +86,25 @@ func (fs *filestore) GetMeta(baseUrl HttpBaseUrl, bucket string, filename string } func (fs *filestore) Add(bucket string, filename string, contents []byte, meta *storage.Object) error { - f := fs.filename(bucket, filename) - if err := os.MkdirAll(filepath.Dir(f), 0777); err != nil { - return fmt.Errorf("could not create dirs for: %s: %w", f, err) + fName := fs.filename(bucket, filename) + fPath := filepath.Dir(fName) + + if err := os.MkdirAll(fPath, 0777); err != nil { + return fmt.Errorf("could not create dirs for: %s: %w", fName, err) + } + + fTmp, err := os.CreateTemp(fPath, "tmp-*") + if err != nil { + return fmt.Errorf("could not create temp file name: %s: %w", fName, err) } - if err := ioutil.WriteFile(f, contents, 0666); err != nil { - return fmt.Errorf("could not write: %s: %w", f, err) + if err := ioutil.WriteFile(fTmp.Name(), contents, 0666); err != nil { + return fmt.Errorf("could not write: %s: %w", fTmp.Name(), err) } // Force a new modification time, since this is what Generation is based on. now := time.Now().UTC() - _ = os.Chtimes(f, now, now) + _ = os.Chtimes(fTmp.Name(), now, now) InitScrubbedMeta(meta, filename) meta.Metageneration = 1 @@ -105,9 +112,23 @@ func (fs *filestore) Add(bucket string, filename string, contents []byte, meta * meta.TimeCreated = now.UTC().Format(time.RFC3339Nano) } - fMeta := metaFilename(f) - if err := ioutil.WriteFile(fMeta, mustJson(meta), 0666); err != nil { - return fmt.Errorf("could not write metadata file: %s: %w", fMeta, err) + fMetaTmp, err := os.CreateTemp(fPath, "tmp-meta-*") + if err != nil { + return fmt.Errorf("could not create temp meta file name: %s: %w", fName, err) + } + + if err := ioutil.WriteFile(fMetaTmp.Name(), mustJson(meta), 0666); err != nil { + return fmt.Errorf("could not write metadata file: %s: %w", fMetaTmp.Name(), err) + } + + if err := os.Rename(fTmp.Name(), fName); err != nil { + return fmt.Errorf("could not commit: %s to %s: %w", fTmp.Name(), fName, err) + } + + fMetaName := metaFilename(fName) + + if err := os.Rename(fMetaTmp.Name(), fMetaName); err != nil { + return fmt.Errorf("could not commit: %s to %s: %w", fMetaTmp.Name(), fMetaName, err) } return nil