Enable Go build tags

This enables go build tags so the GCS and OSS driver support is
available in the binary distributed via the image build by Dockerfile.

This led to quite a few fixes in the GCS and OSS packages raised as
warning by golang-ci linter.

Signed-off-by: Milos Gajdos <milosthegajdos@gmail.com>
(cherry picked from commit 6b388b1ba6)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Milos Gajdos 2023-06-28 11:41:22 +01:00 committed by Sebastiaan van Stijn
parent 8728c52ef2
commit 2548973b1d
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
6 changed files with 37 additions and 30 deletions

View file

@ -114,4 +114,4 @@ the registry binary generated in the "./bin" directory:
### Optional build tags ### Optional build tags
Optional [build tags](http://golang.org/pkg/go/build/) can be provided using Optional [build tags](http://golang.org/pkg/go/build/) can be provided using
the environment variable `DOCKER_BUILDTAGS`. the environment variable `BUILDTAGS`.

View file

@ -22,12 +22,12 @@ RUN --mount=target=. \
FROM base AS build FROM base AS build
ARG TARGETPLATFORM ARG TARGETPLATFORM
ARG LDFLAGS="-s -w" ARG LDFLAGS="-s -w"
ARG BUILDTAGS="include_oss include_gcs" ARG BUILDTAGS="include_oss,include_gcs"
RUN --mount=type=bind,target=/go/src/github.com/docker/distribution,rw \ RUN --mount=type=bind,target=/go/src/github.com/docker/distribution,rw \
--mount=type=cache,target=/root/.cache/go-build \ --mount=type=cache,target=/root/.cache/go-build \
--mount=target=/go/pkg/mod,type=cache \ --mount=target=/go/pkg/mod,type=cache \
--mount=type=bind,source=/tmp/.ldflags,target=/tmp/.ldflags,from=version \ --mount=type=bind,source=/tmp/.ldflags,target=/tmp/.ldflags,from=version \
set -x ; xx-go build -trimpath -ldflags "$(cat /tmp/.ldflags) ${LDFLAGS}" -tags="${BUILDTAGS}" -o /usr/bin/registry ./cmd/registry \ set -x ; xx-go build -tags "${BUILDTAGS}" -trimpath -ldflags "$(cat /tmp/.ldflags) ${LDFLAGS}" -o /usr/bin/registry ./cmd/registry \
&& xx-verify --static /usr/bin/registry && xx-verify --static /usr/bin/registry
FROM scratch AS binary FROM scratch AS binary

View file

@ -1,18 +1,17 @@
//go:build include_gcs
// +build include_gcs
// Package gcs provides a storagedriver.StorageDriver implementation to // Package gcs provides a storagedriver.StorageDriver implementation to
// store blobs in Google cloud storage. // store blobs in Google cloud storage.
// //
// This package leverages the google.golang.org/cloud/storage client library // This package leverages the google.golang.org/cloud/storage client library
//for interfacing with gcs. // for interfacing with gcs.
// //
// Because gcs is a key, value store the Stat call does not support last modification // Because gcs is a key, value store the Stat call does not support last modification
// time for directories (directories are an abstraction for key, value stores) // time for directories (directories are an abstraction for key, value stores)
// //
// Note that the contents of incomplete uploads are not accessible even though // Note that the contents of incomplete uploads are not accessible even though
// Stat returns their length // Stat returns their length
//
//go:build include_gcs
// +build include_gcs
package gcs package gcs
import ( import (
@ -62,7 +61,6 @@ var rangeHeader = regexp.MustCompile(`^bytes=([0-9])+-([0-9]+)$`)
// driverParameters is a struct that encapsulates all of the driver parameters after all values have been set // driverParameters is a struct that encapsulates all of the driver parameters after all values have been set
type driverParameters struct { type driverParameters struct {
bucket string bucket string
config *jwt.Config
email string email string
privateKey []byte privateKey []byte
client *http.Client client *http.Client
@ -88,6 +86,8 @@ func (factory *gcsDriverFactory) Create(parameters map[string]interface{}) (stor
return FromParameters(parameters) return FromParameters(parameters)
} }
var _ storagedriver.StorageDriver = &driver{}
// driver is a storagedriver.StorageDriver implementation backed by GCS // driver is a storagedriver.StorageDriver implementation backed by GCS
// Objects are stored at absolute keys in the provided bucket. // Objects are stored at absolute keys in the provided bucket.
type driver struct { type driver struct {
@ -298,7 +298,7 @@ func (d *driver) Reader(context context.Context, path string, offset int64) (io.
if err != nil { if err != nil {
return nil, err return nil, err
} }
if offset == int64(obj.Size) { if offset == obj.Size {
return ioutil.NopCloser(bytes.NewReader([]byte{})), nil return ioutil.NopCloser(bytes.NewReader([]byte{})), nil
} }
return nil, storagedriver.InvalidOffsetError{Path: path, Offset: offset} return nil, storagedriver.InvalidOffsetError{Path: path, Offset: offset}
@ -434,7 +434,6 @@ func putContentsClose(wc *storage.Writer, contents []byte) error {
} }
} }
if err != nil { if err != nil {
wc.CloseWithError(err)
return err return err
} }
return wc.Close() return wc.Close()
@ -614,10 +613,10 @@ func (d *driver) Stat(context context.Context, path string) (storagedriver.FileI
//try to get as folder //try to get as folder
dirpath := d.pathToDirKey(path) dirpath := d.pathToDirKey(path)
var query *storage.Query query := &storage.Query{
query = &storage.Query{} Prefix: dirpath,
query.Prefix = dirpath MaxResults: 1,
query.MaxResults = 1 }
objects, err := storageListObjects(gcsContext, d.bucket, query) objects, err := storageListObjects(gcsContext, d.bucket, query)
if err != nil { if err != nil {
@ -639,12 +638,12 @@ func (d *driver) Stat(context context.Context, path string) (storagedriver.FileI
} }
// List returns a list of the objects that are direct descendants of the // List returns a list of the objects that are direct descendants of the
//given path. // given path.
func (d *driver) List(context context.Context, path string) ([]string, error) { func (d *driver) List(context context.Context, path string) ([]string, error) {
var query *storage.Query query := &storage.Query{
query = &storage.Query{} Delimiter: "/",
query.Delimiter = "/" Prefix: d.pathToDirKey(path),
query.Prefix = d.pathToDirKey(path) }
list := make([]string, 0, 64) list := make([]string, 0, 64)
for { for {
objects, err := storageListObjects(d.context(context), d.bucket, query) objects, err := storageListObjects(d.context(context), d.bucket, query)

View file

@ -59,7 +59,7 @@ func init() {
panic(fmt.Sprintf("Error reading JWT config : %s", err)) panic(fmt.Sprintf("Error reading JWT config : %s", err))
} }
email = jwtConfig.Email email = jwtConfig.Email
privateKey = []byte(jwtConfig.PrivateKey) privateKey = jwtConfig.PrivateKey
if len(privateKey) == 0 { if len(privateKey) == 0 {
panic("Error reading JWT config : missing private_key property") panic("Error reading JWT config : missing private_key property")
} }
@ -260,6 +260,9 @@ func TestEmptyRootList(t *testing.T) {
} }
}() }()
keys, err := emptyRootDriver.List(ctx, "/") keys, err := emptyRootDriver.List(ctx, "/")
if err != nil {
t.Fatalf("unexpected error listing empty root content: %v", err)
}
for _, path := range keys { for _, path := range keys {
if !storagedriver.PathRegexp.MatchString(path) { if !storagedriver.PathRegexp.MatchString(path) {
t.Fatalf("unexpected string in path: %q != %q", path, storagedriver.PathRegexp) t.Fatalf("unexpected string in path: %q != %q", path, storagedriver.PathRegexp)
@ -267,6 +270,9 @@ func TestEmptyRootList(t *testing.T) {
} }
keys, err = slashRootDriver.List(ctx, "/") keys, err = slashRootDriver.List(ctx, "/")
if err != nil {
t.Fatalf("unexpected error listing slash root content: %v", err)
}
for _, path := range keys { for _, path := range keys {
if !storagedriver.PathRegexp.MatchString(path) { if !storagedriver.PathRegexp.MatchString(path) {
t.Fatalf("unexpected string in path: %q != %q", path, storagedriver.PathRegexp) t.Fatalf("unexpected string in path: %q != %q", path, storagedriver.PathRegexp)

View file

@ -1,3 +1,6 @@
//go:build include_oss
// +build include_oss
// Package oss provides a storagedriver.StorageDriver implementation to // Package oss provides a storagedriver.StorageDriver implementation to
// store blobs in Aliyun OSS cloud storage. // store blobs in Aliyun OSS cloud storage.
// //
@ -6,10 +9,6 @@
// //
// Because OSS is a key, value store the Stat call does not support last modification // Because OSS is a key, value store the Stat call does not support last modification
// time for directories (directories are an abstraction for key, value stores) // time for directories (directories are an abstraction for key, value stores)
//
//go:build include_oss
// +build include_oss
package oss package oss
import ( import (
@ -68,6 +67,8 @@ func (factory *ossDriverFactory) Create(parameters map[string]interface{}) (stor
return FromParameters(parameters) return FromParameters(parameters)
} }
var _ storagedriver.StorageDriver = &driver{}
type driver struct { type driver struct {
Client *oss.Client Client *oss.Client
Bucket *oss.Bucket Bucket *oss.Bucket
@ -498,11 +499,6 @@ func parseError(path string, err error) error {
return err return err
} }
func hasCode(err error, code string) bool {
ossErr, ok := err.(*oss.Error)
return ok && ossErr.Code == code
}
func (d *driver) getOptions() oss.Options { func (d *driver) getOptions() oss.Options {
return oss.Options{ServerSideEncryption: d.Encrypt} return oss.Options{ServerSideEncryption: d.Encrypt}
} }

View file

@ -128,6 +128,9 @@ func TestEmptyRootList(t *testing.T) {
defer rootedDriver.Delete(ctx, filename) defer rootedDriver.Delete(ctx, filename)
keys, err := emptyRootDriver.List(ctx, "/") keys, err := emptyRootDriver.List(ctx, "/")
if err != nil {
t.Fatalf("unexpected error listing empty root content: %v", err)
}
for _, path := range keys { for _, path := range keys {
if !storagedriver.PathRegexp.MatchString(path) { if !storagedriver.PathRegexp.MatchString(path) {
t.Fatalf("unexpected string in path: %q != %q", path, storagedriver.PathRegexp) t.Fatalf("unexpected string in path: %q != %q", path, storagedriver.PathRegexp)
@ -135,6 +138,9 @@ func TestEmptyRootList(t *testing.T) {
} }
keys, err = slashRootDriver.List(ctx, "/") keys, err = slashRootDriver.List(ctx, "/")
if err != nil {
t.Fatalf("unexpected error listing slash root content: %v", err)
}
for _, path := range keys { for _, path := range keys {
if !storagedriver.PathRegexp.MatchString(path) { if !storagedriver.PathRegexp.MatchString(path) {
t.Fatalf("unexpected string in path: %q != %q", path, storagedriver.PathRegexp) t.Fatalf("unexpected string in path: %q != %q", path, storagedriver.PathRegexp)