Skip to content
This repository has been archived by the owner on Oct 19, 2021. It is now read-only.

Implement GSP-93, GSP-109 and GSP-117 #35

Merged
merged 5 commits into from
Jun 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
494 changes: 281 additions & 213 deletions generated.go

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ go 1.15

require (
cloud.google.com/go/storage v1.15.0
github.com/beyondstorage/go-integration-test/v4 v4.0.0
github.com/beyondstorage/go-storage/v4 v4.0.1-0.20210530044854-1c928ddbe52d
github.com/beyondstorage/go-integration-test/v4 v4.1.1
github.com/beyondstorage/go-storage/v4 v4.2.0
github.com/google/uuid v1.2.0
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
google.golang.org/api v0.47.0
Expand Down
25 changes: 14 additions & 11 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,12 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Xuanwo/templateutils v0.1.0 h1:WpkWOqQtIQ2vAIpJLa727DdN8WtxhUkkbDGa6UhntJY=
github.com/Xuanwo/templateutils v0.1.0/go.mod h1:OdE0DJ+CJxDBq6psX5DPV+gOZi8bhuHuVUpPCG++Wb8=
github.com/beyondstorage/go-integration-test/v4 v4.0.0 h1:tdXQV9yxQ3Q6p9xfyQKzK3MEo9r9j9g3uT5+3sbVtnQ=
github.com/beyondstorage/go-integration-test/v4 v4.0.0/go.mod h1:26/JF4b0XxRN0pL4kihpnVNhbbw+QWvmmvgxfnFJDfA=
github.com/beyondstorage/go-storage/v4 v4.0.0/go.mod h1:oa2dYco+xplPj99WSBnYVw/xXvRkIKWSSVDQKNZ5Kz8=
github.com/beyondstorage/go-storage/v4 v4.0.1-0.20210530044854-1c928ddbe52d h1:s9t6VNNRDqmg+PXyXtVEsxIM7xZQIJOYlma28IpkbNQ=
github.com/beyondstorage/go-storage/v4 v4.0.1-0.20210530044854-1c928ddbe52d/go.mod h1:kXMu07IDZaKtxbqI1ufuhqo0FjYe0nH7zPCbBanln/Y=
github.com/beyondstorage/specs/go v0.0.0-20210521044836-3d41c1d9c97f/go.mod h1:f5VvmLHc/dNJwl+/yAv/TOHdev3phvuEswx8DIXiSQQ=
github.com/beyondstorage/specs/go v0.0.0-20210530044123-3ff75e192bc9 h1:YSiF27cAHlDZk9q+oaEHQbA8dH8XTvYxeTOoPzNCwOQ=
github.com/beyondstorage/specs/go v0.0.0-20210530044123-3ff75e192bc9/go.mod h1:f5VvmLHc/dNJwl+/yAv/TOHdev3phvuEswx8DIXiSQQ=
github.com/beyondstorage/go-integration-test/v4 v4.1.1 h1:9bSXKbr6hLb4+ZsmAhWE32fvqhyrpub4U4qgBGeth4A=
github.com/beyondstorage/go-integration-test/v4 v4.1.1/go.mod h1:ihtCaOJvaHGE0v+IhY6ZUF5NU1IND6xmdrJI9Lq/jhc=
github.com/beyondstorage/go-storage/v4 v4.2.0 h1:J0xqqy4qEQRtIS2zUWMA5wRXVHx/cxX5fHsU2ezA3+I=
github.com/beyondstorage/go-storage/v4 v4.2.0/go.mod h1:rUNzOXcikYk5w0ewvNsKbztg7ndQDyDvjDuP0bznSLU=
github.com/beyondstorage/specs/go v0.0.0-20210623065218-d1c2d7d81259 h1:mW9XpHLc6pdXBRnsha1VlqF0rNsB/Oc+8l+5UYngmRA=
github.com/beyondstorage/specs/go v0.0.0-20210623065218-d1c2d7d81259/go.mod h1:vF/Q0P1tCvhVAUrxg7i6NvrARRMQVTAuQdDNqpSzR1w=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
Expand All @@ -65,8 +63,9 @@ github.com/dave/gopackages v0.0.0-20170318123100-46e7023ec56e/go.mod h1:i00+b/gK
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
github.com/dave/kerr v0.0.0-20170318121727-bc25dd6abe8e/go.mod h1:qZqlPyPvfsDJt+3wHJ1EvSXDuVjFTK0j2p/ca+gtsb8=
github.com/dave/rebecca v0.9.1/go.mod h1:N6XYdMD/OKw3lkF3ywh8Z6wPGuwNFDNtWYEMFWEmXBA=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
Expand Down Expand Up @@ -166,19 +165,22 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pelletier/go-toml v1.9.1 h1:a6qW1EVNZWH9WGI6CsYdD8WAylkoXBS5yv0XHlh17Tc=
github.com/pelletier/go-toml v1.9.1/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
Expand Down Expand Up @@ -312,6 +314,7 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
16 changes: 16 additions & 0 deletions service.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,32 @@ name = "gcs"
required = ["credential", "project_id"]
optional = ["service_features", "default_service_pairs", "http_client_options"]

[namespace.storage]
features = ["virtual_dir"]
implement = ["direr"]

[namespace.storage.new]
required = ["name"]
optional = ["storage_features", "default_storage_pairs", "work_dir"]

[namespace.storage.op.create]
optional = ["object_mode"]

[namespace.storage.op.create_dir]
optional = ["storage_class"]

[namespace.storage.op.delete]
optional = ["object_mode"]

[namespace.storage.op.list]
optional = ["list_mode"]

[namespace.storage.op.read]
optional = ["offset", "io_callback", "size", "encryption_key"]

[namespace.storage.op.stat]
optional = ["object_mode"]

[namespace.storage.op.write]
optional = ["content_md5", "content_type", "io_callback", "storage_class", "encryption_key", "kms_key_name"]

Expand Down
81 changes: 77 additions & 4 deletions storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,76 @@ import (
gs "cloud.google.com/go/storage"
"google.golang.org/api/iterator"

ps "github.com/beyondstorage/go-storage/v4/pairs"
"github.com/beyondstorage/go-storage/v4/pkg/iowrap"
"github.com/beyondstorage/go-storage/v4/services"
. "github.com/beyondstorage/go-storage/v4/types"
)

func (s *Storage) create(path string, opt pairStorageCreate) (o *Object) {
o = s.newObject(false)
o.Mode = ModeRead
o.ID = s.getAbsPath(path)
rp := s.getAbsPath(path)

if opt.HasObjectMode && opt.ObjectMode.IsDir() {
if !s.features.VirtualDir {
return
}
// Add `/` at the end of path to simulate a directory.
rp += "/"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we need a comment to describe why we need to add a / here?

o = s.newObject(true)
o.Mode = ModeDir
} else {
o = s.newObject(false)
o.Mode = ModeRead
}

o.ID = rp
o.Path = path
return o
}

func (s *Storage) createDir(ctx context.Context, path string, opt pairStorageCreateDir) (o *Object, err error) {
if !s.features.VirtualDir {
err = NewOperationNotImplementedError("create_dir")
return
}

rp := s.getAbsPath(path)

// Add `/` at the end of `path` to simulate a directory.
// ref: https://cloud.google.com/storage/docs/naming-objects
rp += "/"

object := s.bucket.Object(rp)
w := object.NewWriter(ctx)
w.Size = 0
if opt.HasStorageClass {
w.StorageClass = opt.StorageClass
}

cerr := w.Close()
if cerr != nil {
err = cerr
}

o = s.newObject(true)
o.ID = rp
o.Path = path
o.Mode |= ModeDir
return
}

func (s *Storage) delete(ctx context.Context, path string, opt pairStorageDelete) (err error) {
rp := s.getAbsPath(path)

if opt.HasObjectMode && opt.ObjectMode.IsDir() {
if !s.features.VirtualDir {
err = services.PairUnsupportedError{Pair: ps.WithObjectMode(opt.ObjectMode)}
return
}

rp += "/"
}

err = s.bucket.Object(rp).Delete(ctx)
if err != nil && errors.Is(err, gs.ErrObjectNotExist) {
// Omit `ErrObjectNotExist` error here.
Expand Down Expand Up @@ -168,12 +222,31 @@ func (s *Storage) read(ctx context.Context, path string, w io.Writer, opt pairSt
func (s *Storage) stat(ctx context.Context, path string, opt pairStorageStat) (o *Object, err error) {
rp := s.getAbsPath(path)

if opt.HasObjectMode && opt.ObjectMode.IsDir() {
if !s.features.VirtualDir {
err = services.PairUnsupportedError{Pair: ps.WithObjectMode(opt.ObjectMode)}
return
}

rp += "/"
}

attr, err := s.bucket.Object(rp).Attrs(ctx)
if err != nil {
return nil, err
}

return s.formatFileObject(attr)
o, err = s.formatFileObject(attr)
if err != nil {
return nil, err
}

if opt.HasObjectMode && opt.ObjectMode.IsDir() {
o.Path = path
o.Mode.Add(ModeDir)
}

return o, nil
}

func (s *Storage) write(ctx context.Context, path string, r io.Reader, size int64, opt pairStorageWrite) (n int64, err error) {
Expand Down
7 changes: 7 additions & 0 deletions tests/storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,10 @@ func TestStorage(t *testing.T) {
}
tests.TestStorager(t, setupTest(t))
}

func TestDirer(t *testing.T) {
if os.Getenv("STORAGE_GCS_INTEGRATION_TEST") != "on" {
t.Skipf("STORAGE_GCS_INTEGRATION_TEST is not 'on', skipped")
}
tests.TestDirer(t, setupTest(t))
}
3 changes: 3 additions & 0 deletions tests/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ func setupTest(t *testing.T) types.Storager {
ps.WithName(os.Getenv("STORAGE_GCS_NAME")),
ps.WithWorkDir("/"+uuid.New().String()+"/"),
gcs.WithProjectID(os.Getenv("STORAGE_GCS_PROJECT_ID")),
gcs.WithStorageFeatures(gcs.StorageFeatures{
VirtualDir: true,
}),
)
if err != nil {
t.Errorf("new storager: %v", err)
Expand Down
5 changes: 3 additions & 2 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type Storage struct {
features StorageFeatures

typ.UnimplementedStorager
typ.UnimplementedDirer
}

// String implements Storager.String
Expand Down Expand Up @@ -276,14 +277,14 @@ func (s *Storage) formatFileObject(v *gs.ObjectAttrs) (o *typ.Object, err error)
o.SetContentMd5(base64.StdEncoding.EncodeToString(v.MD5))
}

var sm ObjectMetadata
var sm ObjectSystemMetadata
if value := v.StorageClass; value != "" {
sm.StorageClass = value
}
if value := v.CustomerKeySHA256; value != "" {
sm.EncryptionKeySha256 = value
}
o.SetServiceMetadata(sm)
o.SetSystemMetadata(sm)

return
}
Expand Down