Created
October 11, 2018 09:21
-
-
Save rwos/d9c9af379c9be6d9d2ba43b874cd110e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/registry/storage/driver/gcs/gcs.go b/registry/storage/driver/gcs/gcs.go | |
index 86dc87f1..72bdf4ef 100644 | |
--- a/registry/storage/driver/gcs/gcs.go | |
+++ b/registry/storage/driver/gcs/gcs.go | |
@@ -10,7 +10,6 @@ | |
// Note that the contents of incomplete uploads are not accessible even though | |
// Stat returns their length | |
// | |
-// +build include_gcs | |
package gcs | |
@@ -39,6 +38,7 @@ import ( | |
"golang.org/x/oauth2/google" | |
"golang.org/x/oauth2/jwt" | |
"google.golang.org/api/googleapi" | |
+ storageapi "google.golang.org/api/storage/v1" | |
"google.golang.org/cloud" | |
"google.golang.org/cloud/storage" | |
) | |
@@ -67,6 +67,7 @@ type driverParameters struct { | |
client *http.Client | |
rootDirectory string | |
chunkSize int | |
+ projectID string | |
// maxConcurrency limits the number of concurrent driver operations | |
// to GCS, which ultimately increases reliability of many simultaneous | |
@@ -148,6 +149,9 @@ func FromParameters(parameters map[string]interface{}) (storagedriver.StorageDri | |
} | |
var ts oauth2.TokenSource | |
+ var key struct { | |
+ ProjectID string `json:"project_id"` | |
+ } | |
jwtConf := new(jwt.Config) | |
if keyfile, ok := parameters["keyfile"]; ok { | |
jsonKey, err := ioutil.ReadFile(fmt.Sprint(keyfile)) | |
@@ -158,6 +162,9 @@ func FromParameters(parameters map[string]interface{}) (storagedriver.StorageDri | |
if err != nil { | |
return nil, err | |
} | |
+ if err := json.Unmarshal(jsonKey, &key); err != nil { | |
+ return nil, err | |
+ } | |
ts = jwtConf.TokenSource(context.Background()) | |
} else if credentials, ok := parameters["credentials"]; ok { | |
credentialMap, ok := credentials.(map[interface{}]interface{}) | |
@@ -204,6 +211,7 @@ func FromParameters(parameters map[string]interface{}) (storagedriver.StorageDri | |
privateKey: jwtConf.PrivateKey, | |
client: oauth2.NewClient(context.Background(), ts), | |
chunkSize: chunkSize, | |
+ projectID: fmt.Sprint(key.ProjectID), | |
maxConcurrency: maxConcurrency, | |
} | |
@@ -219,6 +227,17 @@ func New(params driverParameters) (storagedriver.StorageDriver, error) { | |
if params.chunkSize <= 0 || params.chunkSize%minChunkSize != 0 { | |
return nil, fmt.Errorf("Invalid chunksize: %d is not a positive multiple of %d", params.chunkSize, minChunkSize) | |
} | |
+ | |
+ service, err := storageapi.New(params.client) | |
+ if err != nil { | |
+ return nil, err | |
+ } | |
+ if _, err := service.Buckets.Get(params.bucket).Do(); err != nil { | |
+ if _, err := service.Buckets.Insert(params.projectID, &storageapi.Bucket{Name: params.bucket}).Do(); err != nil { | |
+ return nil, err | |
+ } | |
+ } | |
+ | |
d := &driver{ | |
bucket: params.bucket, | |
rootDirectory: rootDirectory, | |
@@ -540,6 +559,9 @@ func (w *writer) Write(p []byte) (int, error) { | |
// Size returns the number of bytes written to this FileWriter. | |
func (w *writer) Size() int64 { | |
+ if !w.closed { | |
+ return w.offset + int64(w.buffSize) | |
+ } | |
return w.size | |
} | |
diff --git a/registry/storage/driver/gcs/gcs_test.go b/registry/storage/driver/gcs/gcs_test.go | |
index e58216be..daa0698f 100644 | |
--- a/registry/storage/driver/gcs/gcs_test.go | |
+++ b/registry/storage/driver/gcs/gcs_test.go | |
@@ -1,5 +1,3 @@ | |
-// +build include_gcs | |
- | |
package gcs | |
import ( | |
@@ -8,6 +6,8 @@ import ( | |
"os" | |
"testing" | |
+ "fmt" | |
+ ctx "github.com/docker/distribution/context" | |
dcontext "github.com/docker/distribution/context" | |
storagedriver "github.com/docker/distribution/registry/storage/driver" | |
"github.com/docker/distribution/registry/storage/driver/testsuites" | |
diff --git a/registry/storage/driver/s3-aws/s3.go b/registry/storage/driver/s3-aws/s3.go | |
index 800435d0..3b23f7d5 100644 | |
--- a/registry/storage/driver/s3-aws/s3.go | |
+++ b/registry/storage/driver/s3-aws/s3.go | |
@@ -460,6 +460,23 @@ func New(params DriverParameters) (*Driver, error) { | |
setv2Handlers(s3obj) | |
} | |
+ _, err = s3obj.CreateBucket(&s3.CreateBucketInput{ | |
+ Bucket: ¶ms.Bucket, | |
+ }) | |
+ if err != nil { | |
+ if s3err, ok := err.(awserr.Error); ok { | |
+ if s3err.Code() != "BucketAlreadyOwnedByYou" && s3err.Code() != "BucketAlreadyExists" { | |
+ return nil, err | |
+ } | |
+ } else { | |
+ return nil, err | |
+ } | |
+ } | |
+ | |
+ if err := s3obj.WaitUntilBucketExists(&s3.HeadBucketInput{Bucket: ¶ms.Bucket}); err != nil { | |
+ return nil, err | |
+ } | |
+ | |
// TODO Currently multipart uploads have no timestamps, so this would be unwise | |
// if you initiated a new s3driver while another one is running on the same bucket. | |
// multis, _, err := bucket.ListMulti("", "") | |
diff --git a/registry/storage/driver/storagedriver.go b/registry/storage/driver/storagedriver.go | |
index b220713f..aee67820 100644 | |
--- a/registry/storage/driver/storagedriver.go | |
+++ b/registry/storage/driver/storagedriver.go | |
@@ -116,7 +116,7 @@ type FileWriter interface { | |
// number of path components separated by slashes, where each component is | |
// restricted to alphanumeric characters or a period, underscore, or | |
// hyphen. | |
-var PathRegexp = regexp.MustCompile(`^(/[A-Za-z0-9._-]+)+$`) | |
+var PathRegexp = regexp.MustCompile(`^([A-Za-z0-9._:-]*(/[A-Za-z0-9._:-]+)*)+$`) | |
// ErrUnsupportedMethod may be returned in the case where a StorageDriver implementation does not support an optional method. | |
type ErrUnsupportedMethod struct { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment