Merge pull request #3385 from wy65701436/release/2.7-ci
enable ci for release/2.7
This commit is contained in:
commit
51636a6711
77 changed files with 167 additions and 366 deletions
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
|
@ -2,11 +2,7 @@ name: CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
|
@ -34,7 +30,7 @@ jobs:
|
||||||
- name: Dependencies
|
- name: Dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -q update
|
sudo apt-get -q update
|
||||||
sudo -E apt-get -yq --no-install-suggests --no-install-recommends install python-minimal
|
sudo -E apt-get -yq --no-install-suggests --no-install-recommends install python2-minimal
|
||||||
cd /tmp && go get -u github.com/vbatts/git-validation
|
cd /tmp && go get -u github.com/vbatts/git-validation
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
|
|
20
.golangci.yml
Normal file
20
.golangci.yml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
linters:
|
||||||
|
enable:
|
||||||
|
- structcheck
|
||||||
|
- varcheck
|
||||||
|
- staticcheck
|
||||||
|
- unconvert
|
||||||
|
- gofmt
|
||||||
|
- goimports
|
||||||
|
- golint
|
||||||
|
- ineffassign
|
||||||
|
- vet
|
||||||
|
- unused
|
||||||
|
- misspell
|
||||||
|
disable:
|
||||||
|
- errcheck
|
||||||
|
|
||||||
|
run:
|
||||||
|
deadline: 2m
|
||||||
|
skip-dirs:
|
||||||
|
- vendor
|
|
@ -1,15 +0,0 @@
|
||||||
{
|
|
||||||
"Vendor": true,
|
|
||||||
"Deadline": "2m",
|
|
||||||
"Sort": ["linter", "severity", "path", "line"],
|
|
||||||
"EnableGC": true,
|
|
||||||
"Enable": [
|
|
||||||
"structcheck",
|
|
||||||
"unconvert",
|
|
||||||
|
|
||||||
"gofmt",
|
|
||||||
"goimports",
|
|
||||||
"golint",
|
|
||||||
"vet"
|
|
||||||
]
|
|
||||||
}
|
|
51
.travis.yml
51
.travis.yml
|
@ -1,51 +0,0 @@
|
||||||
dist: trusty
|
|
||||||
sudo: required
|
|
||||||
# setup travis so that we can run containers for integration tests
|
|
||||||
services:
|
|
||||||
- docker
|
|
||||||
|
|
||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- "1.11.x"
|
|
||||||
|
|
||||||
go_import_path: github.com/docker/distribution
|
|
||||||
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- python-minimal
|
|
||||||
|
|
||||||
|
|
||||||
env:
|
|
||||||
- TRAVIS_GOOS=linux DOCKER_BUILDTAGS="include_oss include_gcs" TRAVIS_CGO_ENABLED=1
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- uname -r
|
|
||||||
- sudo apt-get -q update
|
|
||||||
|
|
||||||
install:
|
|
||||||
- go get -u github.com/vbatts/git-validation
|
|
||||||
# TODO: Add enforcement of license
|
|
||||||
# - go get -u github.com/kunalkushwaha/ltag
|
|
||||||
- cd $TRAVIS_BUILD_DIR
|
|
||||||
|
|
||||||
script:
|
|
||||||
- export GOOS=$TRAVIS_GOOS
|
|
||||||
- export CGO_ENABLED=$TRAVIS_CGO_ENABLED
|
|
||||||
- DCO_VERBOSITY=-q script/validate/dco
|
|
||||||
- GOOS=linux script/setup/install-dev-tools
|
|
||||||
- script/validate/vendor
|
|
||||||
- go build -i .
|
|
||||||
- make check
|
|
||||||
- make build
|
|
||||||
- make binaries
|
|
||||||
# Currently takes too long
|
|
||||||
#- if [ "$GOOS" = "linux" ]; then make test-race ; fi
|
|
||||||
- if [ "$GOOS" = "linux" ]; then make coverage ; fi
|
|
||||||
|
|
||||||
after_success:
|
|
||||||
- bash <(curl -s https://codecov.io/bash) -F linux
|
|
||||||
|
|
||||||
before_deploy:
|
|
||||||
# Run tests with storage driver configurations
|
|
2
Makefile
2
Makefile
|
@ -50,7 +50,7 @@ version/version.go:
|
||||||
|
|
||||||
check: ## run all linters (TODO: enable "unused", "varcheck", "ineffassign", "unconvert", "staticheck", "goimports", "structcheck")
|
check: ## run all linters (TODO: enable "unused", "varcheck", "ineffassign", "unconvert", "staticheck", "goimports", "structcheck")
|
||||||
@echo "$(WHALE) $@"
|
@echo "$(WHALE) $@"
|
||||||
gometalinter --config .gometalinter.json ./...
|
golangci-lint run
|
||||||
|
|
||||||
test: ## run tests, except integration test with test.short
|
test: ## run tests, except integration test with test.short
|
||||||
@echo "$(WHALE) $@"
|
@echo "$(WHALE) $@"
|
||||||
|
|
2
blobs.go
2
blobs.go
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/docker/distribution/registry/api/errcode"
|
"github.com/docker/distribution/registry/api/errcode"
|
||||||
"github.com/docker/distribution/registry/api/v2"
|
v2 "github.com/docker/distribution/registry/api/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var spaceRegex = regexp.MustCompile(`\n\s*`)
|
var spaceRegex = regexp.MustCompile(`\n\s*`)
|
||||||
|
|
|
@ -388,7 +388,7 @@ func (loglevel *Loglevel) UnmarshalYAML(unmarshal func(interface{}) error) error
|
||||||
switch loglevelString {
|
switch loglevelString {
|
||||||
case "error", "warn", "info", "debug":
|
case "error", "warn", "info", "debug":
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Invalid loglevel %s Must be one of [error, warn, info, debug]", loglevelString)
|
return fmt.Errorf("invalid loglevel %s Must be one of [error, warn, info, debug]", loglevelString)
|
||||||
}
|
}
|
||||||
|
|
||||||
*loglevel = Loglevel(loglevelString)
|
*loglevel = Loglevel(loglevelString)
|
||||||
|
@ -463,7 +463,7 @@ func (storage *Storage) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(types) > 1 {
|
if len(types) > 1 {
|
||||||
return fmt.Errorf("Must provide exactly one storage type. Provided: %v", types)
|
return fmt.Errorf("must provide exactly one storage type. Provided: %v", types)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*storage = storageMap
|
*storage = storageMap
|
||||||
|
@ -665,11 +665,11 @@ func Parse(rd io.Reader) (*Configuration, error) {
|
||||||
v0_1.Loglevel = Loglevel("")
|
v0_1.Loglevel = Loglevel("")
|
||||||
}
|
}
|
||||||
if v0_1.Storage.Type() == "" {
|
if v0_1.Storage.Type() == "" {
|
||||||
return nil, errors.New("No storage configuration provided")
|
return nil, errors.New("no storage configuration provided")
|
||||||
}
|
}
|
||||||
return (*Configuration)(v0_1), nil
|
return (*Configuration)(v0_1), nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("Expected *v0_1Configuration, received %#v", c)
|
return nil, fmt.Errorf("expected *v0_1Configuration, received %#v", c)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -540,9 +540,7 @@ func copyConfig(config Configuration) *Configuration {
|
||||||
}
|
}
|
||||||
|
|
||||||
configCopy.Notifications = Notifications{Endpoints: []Endpoint{}}
|
configCopy.Notifications = Notifications{Endpoints: []Endpoint{}}
|
||||||
for _, v := range config.Notifications.Endpoints {
|
configCopy.Notifications.Endpoints = append(configCopy.Notifications.Endpoints, config.Notifications.Endpoints...)
|
||||||
configCopy.Notifications.Endpoints = append(configCopy.Notifications.Endpoints, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
configCopy.HTTP.Headers = make(http.Header)
|
configCopy.HTTP.Headers = make(http.Header)
|
||||||
for k, v := range config.HTTP.Headers {
|
for k, v := range config.HTTP.Headers {
|
||||||
|
|
|
@ -122,7 +122,7 @@ func (p *Parser) Parse(in []byte, v interface{}) error {
|
||||||
|
|
||||||
parseInfo, ok := p.mapping[versionedStruct.Version]
|
parseInfo, ok := p.mapping[versionedStruct.Version]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Unsupported version: %q", versionedStruct.Version)
|
return fmt.Errorf("unsupported version: %q", versionedStruct.Version)
|
||||||
}
|
}
|
||||||
|
|
||||||
parseAs := reflect.New(parseInfo.ParseAs)
|
parseAs := reflect.New(parseInfo.ParseAs)
|
||||||
|
|
|
@ -14,7 +14,7 @@ var (
|
||||||
// DownHandler registers a manual_http_status that always returns an Error
|
// DownHandler registers a manual_http_status that always returns an Error
|
||||||
func DownHandler(w http.ResponseWriter, r *http.Request) {
|
func DownHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method == "POST" {
|
if r.Method == "POST" {
|
||||||
updater.Update(errors.New("Manual Check"))
|
updater.Update(errors.New("manual Check"))
|
||||||
} else {
|
} else {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
"github.com/docker/distribution/manifest"
|
"github.com/docker/distribution/manifest"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -163,7 +163,7 @@ func FromDescriptorsWithMediaType(descriptors []ManifestDescriptor, mediaType st
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Manifests = make([]ManifestDescriptor, len(descriptors), len(descriptors))
|
m.Manifests = make([]ManifestDescriptor, len(descriptors))
|
||||||
copy(m.Manifests, descriptors)
|
copy(m.Manifests, descriptors)
|
||||||
|
|
||||||
deserialized := DeserializedManifestList{
|
deserialized := DeserializedManifestList{
|
||||||
|
@ -177,7 +177,7 @@ func FromDescriptorsWithMediaType(descriptors []ManifestDescriptor, mediaType st
|
||||||
|
|
||||||
// UnmarshalJSON populates a new ManifestList struct from JSON data.
|
// UnmarshalJSON populates a new ManifestList struct from JSON data.
|
||||||
func (m *DeserializedManifestList) UnmarshalJSON(b []byte) error {
|
func (m *DeserializedManifestList) UnmarshalJSON(b []byte) error {
|
||||||
m.canonical = make([]byte, len(b), len(b))
|
m.canonical = make([]byte, len(b))
|
||||||
// store manifest list in canonical
|
// store manifest list in canonical
|
||||||
copy(m.canonical, b)
|
copy(m.canonical, b)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var expectedManifestListSerialization = []byte(`{
|
var expectedManifestListSerialization = []byte(`{
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
"github.com/docker/distribution/manifest"
|
"github.com/docker/distribution/manifest"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Builder is a type for constructing manifests.
|
// Builder is a type for constructing manifests.
|
||||||
|
@ -48,7 +48,7 @@ func NewManifestBuilder(bs distribution.BlobService, configJSON []byte, annotati
|
||||||
// valid media type for oci image manifests currently: "" or "application/vnd.oci.image.manifest.v1+json"
|
// valid media type for oci image manifests currently: "" or "application/vnd.oci.image.manifest.v1+json"
|
||||||
func (mb *Builder) SetMediaType(mediaType string) error {
|
func (mb *Builder) SetMediaType(mediaType string) error {
|
||||||
if mediaType != "" && mediaType != v1.MediaTypeImageManifest {
|
if mediaType != "" && mediaType != v1.MediaTypeImageManifest {
|
||||||
return errors.New("Invalid media type for OCI image manifest")
|
return errors.New("invalid media type for OCI image manifest")
|
||||||
}
|
}
|
||||||
|
|
||||||
mb.mediaType = mediaType
|
mb.mediaType = mediaType
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mockBlobService struct {
|
type mockBlobService struct {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
"github.com/docker/distribution/manifest"
|
"github.com/docker/distribution/manifest"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -87,7 +87,7 @@ func FromStruct(m Manifest) (*DeserializedManifest, error) {
|
||||||
|
|
||||||
// UnmarshalJSON populates a new Manifest struct from JSON data.
|
// UnmarshalJSON populates a new Manifest struct from JSON data.
|
||||||
func (m *DeserializedManifest) UnmarshalJSON(b []byte) error {
|
func (m *DeserializedManifest) UnmarshalJSON(b []byte) error {
|
||||||
m.canonical = make([]byte, len(b), len(b))
|
m.canonical = make([]byte, len(b))
|
||||||
// store manifest in canonical
|
// store manifest in canonical
|
||||||
copy(m.canonical, b)
|
copy(m.canonical, b)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
"github.com/docker/distribution/manifest"
|
"github.com/docker/distribution/manifest"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var expectedManifestSerialization = []byte(`{
|
var expectedManifestSerialization = []byte(`{
|
||||||
|
|
|
@ -108,7 +108,7 @@ type SignedManifest struct {
|
||||||
|
|
||||||
// UnmarshalJSON populates a new SignedManifest struct from JSON data.
|
// UnmarshalJSON populates a new SignedManifest struct from JSON data.
|
||||||
func (sm *SignedManifest) UnmarshalJSON(b []byte) error {
|
func (sm *SignedManifest) UnmarshalJSON(b []byte) error {
|
||||||
sm.all = make([]byte, len(b), len(b))
|
sm.all = make([]byte, len(b))
|
||||||
// store manifest and signatures in all
|
// store manifest and signatures in all
|
||||||
copy(sm.all, b)
|
copy(sm.all, b)
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ func (sm *SignedManifest) UnmarshalJSON(b []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// sm.Canonical stores the canonical manifest JSON
|
// sm.Canonical stores the canonical manifest JSON
|
||||||
sm.Canonical = make([]byte, len(bytes), len(bytes))
|
sm.Canonical = make([]byte, len(bytes))
|
||||||
copy(sm.Canonical, bytes)
|
copy(sm.Canonical, bytes)
|
||||||
|
|
||||||
// Unmarshal canonical JSON into Manifest object
|
// Unmarshal canonical JSON into Manifest object
|
||||||
|
|
|
@ -58,7 +58,7 @@ func (mb *referenceManifestBuilder) Build(ctx context.Context) (distribution.Man
|
||||||
func (mb *referenceManifestBuilder) AppendReference(d distribution.Describable) error {
|
func (mb *referenceManifestBuilder) AppendReference(d distribution.Describable) error {
|
||||||
r, ok := d.(Reference)
|
r, ok := d.(Reference)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Unable to add non-reference type to v1 builder")
|
return fmt.Errorf("unable to add non-reference type to v1 builder")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entries need to be prepended
|
// Entries need to be prepended
|
||||||
|
|
|
@ -106,7 +106,7 @@ func FromStruct(m Manifest) (*DeserializedManifest, error) {
|
||||||
|
|
||||||
// UnmarshalJSON populates a new Manifest struct from JSON data.
|
// UnmarshalJSON populates a new Manifest struct from JSON data.
|
||||||
func (m *DeserializedManifest) UnmarshalJSON(b []byte) error {
|
func (m *DeserializedManifest) UnmarshalJSON(b []byte) error {
|
||||||
m.canonical = make([]byte, len(b), len(b))
|
m.canonical = make([]byte, len(b))
|
||||||
// store manifest in canonical
|
// store manifest in canonical
|
||||||
copy(m.canonical, b)
|
copy(m.canonical, b)
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ func ManifestMediaTypes() (mediaTypes []string) {
|
||||||
// UnmarshalFunc implements manifest unmarshalling a given MediaType
|
// UnmarshalFunc implements manifest unmarshalling a given MediaType
|
||||||
type UnmarshalFunc func([]byte) (Manifest, Descriptor, error)
|
type UnmarshalFunc func([]byte) (Manifest, Descriptor, error)
|
||||||
|
|
||||||
var mappings = make(map[string]UnmarshalFunc, 0)
|
var mappings = make(map[string]UnmarshalFunc)
|
||||||
|
|
||||||
// UnmarshalManifest looks up manifest unmarshal functions based on
|
// UnmarshalManifest looks up manifest unmarshal functions based on
|
||||||
// MediaType
|
// MediaType
|
||||||
|
|
|
@ -125,15 +125,6 @@ func (b *bridge) RepoDeleted(repo reference.Named) error {
|
||||||
return b.sink.Write(*event)
|
return b.sink.Write(*event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bridge) createManifestEventAndWrite(action string, repo reference.Named, sm distribution.Manifest) error {
|
|
||||||
manifestEvent, err := b.createManifestEvent(action, repo, sm)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return b.sink.Write(*manifestEvent)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bridge) createManifestDeleteEventAndWrite(action string, repo reference.Named, dgst digest.Digest) error {
|
func (b *bridge) createManifestDeleteEventAndWrite(action string, repo reference.Named, dgst digest.Digest) error {
|
||||||
event := b.createEvent(action)
|
event := b.createEvent(action)
|
||||||
event.Target.Repository = repo.Name()
|
event.Target.Repository = repo.Name()
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
"github.com/docker/distribution/manifest/schema1"
|
"github.com/docker/distribution/manifest/schema1"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/docker/distribution/registry/api/v2"
|
v2 "github.com/docker/distribution/registry/api/v2"
|
||||||
"github.com/docker/distribution/uuid"
|
"github.com/docker/distribution/uuid"
|
||||||
"github.com/docker/libtrust"
|
"github.com/docker/libtrust"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
|
|
|
@ -114,8 +114,7 @@ func TestEventEnvelopeJSONFormat(t *testing.T) {
|
||||||
prototype.Request.UserAgent = "test/0.1"
|
prototype.Request.UserAgent = "test/0.1"
|
||||||
prototype.Source.Addr = "hostname.local:port"
|
prototype.Source.Addr = "hostname.local:port"
|
||||||
|
|
||||||
var manifestPush Event
|
var manifestPush = prototype
|
||||||
manifestPush = prototype
|
|
||||||
manifestPush.ID = "asdf-asdf-asdf-asdf-0"
|
manifestPush.ID = "asdf-asdf-asdf-asdf-0"
|
||||||
manifestPush.Target.Digest = "sha256:0123456789abcdef0"
|
manifestPush.Target.Digest = "sha256:0123456789abcdef0"
|
||||||
manifestPush.Target.Length = 1
|
manifestPush.Target.Length = 1
|
||||||
|
@ -124,8 +123,7 @@ func TestEventEnvelopeJSONFormat(t *testing.T) {
|
||||||
manifestPush.Target.Repository = "library/test"
|
manifestPush.Target.Repository = "library/test"
|
||||||
manifestPush.Target.URL = "http://example.com/v2/library/test/manifests/latest"
|
manifestPush.Target.URL = "http://example.com/v2/library/test/manifests/latest"
|
||||||
|
|
||||||
var layerPush0 Event
|
var layerPush0 = prototype
|
||||||
layerPush0 = prototype
|
|
||||||
layerPush0.ID = "asdf-asdf-asdf-asdf-1"
|
layerPush0.ID = "asdf-asdf-asdf-asdf-1"
|
||||||
layerPush0.Target.Digest = "sha256:3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5"
|
layerPush0.Target.Digest = "sha256:3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5"
|
||||||
layerPush0.Target.Length = 2
|
layerPush0.Target.Length = 2
|
||||||
|
@ -134,8 +132,7 @@ func TestEventEnvelopeJSONFormat(t *testing.T) {
|
||||||
layerPush0.Target.Repository = "library/test"
|
layerPush0.Target.Repository = "library/test"
|
||||||
layerPush0.Target.URL = "http://example.com/v2/library/test/manifests/latest"
|
layerPush0.Target.URL = "http://example.com/v2/library/test/manifests/latest"
|
||||||
|
|
||||||
var layerPush1 Event
|
var layerPush1 = prototype
|
||||||
layerPush1 = prototype
|
|
||||||
layerPush1.ID = "asdf-asdf-asdf-asdf-2"
|
layerPush1.ID = "asdf-asdf-asdf-asdf-2"
|
||||||
layerPush1.Target.Digest = "sha256:3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d6"
|
layerPush1.Target.Digest = "sha256:3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d6"
|
||||||
layerPush1.Target.Length = 3
|
layerPush1.Target.Length = 3
|
||||||
|
|
|
@ -133,8 +133,7 @@ type headerRoundTripper struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hrt *headerRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
func (hrt *headerRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
var nreq http.Request
|
var nreq = *req
|
||||||
nreq = *req
|
|
||||||
nreq.Header = make(http.Header)
|
nreq.Header = make(http.Header)
|
||||||
|
|
||||||
merge := func(headers http.Header) {
|
merge := func(headers http.Header) {
|
||||||
|
|
|
@ -136,11 +136,10 @@ func checkExerciseRepository(t *testing.T, repository distribution.Repository, r
|
||||||
var blobDigests []digest.Digest
|
var blobDigests []digest.Digest
|
||||||
blobs := repository.Blobs(ctx)
|
blobs := repository.Blobs(ctx)
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
rs, ds, err := testutil.CreateRandomTarFile()
|
rs, dgst, err := testutil.CreateRandomTarFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error creating test layer: %v", err)
|
t.Fatalf("error creating test layer: %v", err)
|
||||||
}
|
}
|
||||||
dgst := digest.Digest(ds)
|
|
||||||
blobDigests = append(blobDigests, dgst)
|
blobDigests = append(blobDigests, dgst)
|
||||||
|
|
||||||
wr, err := blobs.Create(ctx)
|
wr, err := blobs.Create(ctx)
|
||||||
|
|
|
@ -284,11 +284,6 @@ type retryingSink struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type retryingSinkListener interface {
|
|
||||||
active(events ...Event)
|
|
||||||
retry(events ...Event)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(stevvooe): We are using circuit break here, which actually doesn't
|
// TODO(stevvooe): We are using circuit break here, which actually doesn't
|
||||||
// make a whole lot of sense for this use case, since we always retry. Move
|
// make a whole lot of sense for this use case, since we always retry. Move
|
||||||
// this to use bounded exponential backoff.
|
// this to use bounded exponential backoff.
|
||||||
|
|
|
@ -205,7 +205,7 @@ func Parse(s string) (Reference, error) {
|
||||||
var repo repository
|
var repo repository
|
||||||
|
|
||||||
nameMatch := anchoredNameRegexp.FindStringSubmatch(matches[1])
|
nameMatch := anchoredNameRegexp.FindStringSubmatch(matches[1])
|
||||||
if nameMatch != nil && len(nameMatch) == 3 {
|
if len(nameMatch) == 3 {
|
||||||
repo.domain = nameMatch[1]
|
repo.domain = nameMatch[1]
|
||||||
repo.path = nameMatch[2]
|
repo.path = nameMatch[2]
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -639,7 +639,7 @@ func TestParseNamed(t *testing.T) {
|
||||||
failf("error parsing name: %s", err)
|
failf("error parsing name: %s", err)
|
||||||
continue
|
continue
|
||||||
} else if err == nil && testcase.err != nil {
|
} else if err == nil && testcase.err != nil {
|
||||||
failf("parsing succeded: expected error %v", testcase.err)
|
failf("parsing succeeded: expected error %v", testcase.err)
|
||||||
continue
|
continue
|
||||||
} else if err != testcase.err {
|
} else if err != testcase.err {
|
||||||
failf("unexpected error %v, expected %v", err, testcase.err)
|
failf("unexpected error %v, expected %v", err, testcase.err)
|
||||||
|
|
|
@ -207,11 +207,11 @@ func (errs Errors) MarshalJSON() ([]byte, error) {
|
||||||
for _, daErr := range errs {
|
for _, daErr := range errs {
|
||||||
var err Error
|
var err Error
|
||||||
|
|
||||||
switch daErr.(type) {
|
switch daErr := daErr.(type) {
|
||||||
case ErrorCode:
|
case ErrorCode:
|
||||||
err = daErr.(ErrorCode).WithDetail(nil)
|
err = daErr.WithDetail(nil)
|
||||||
case Error:
|
case Error:
|
||||||
err = daErr.(Error)
|
err = daErr
|
||||||
default:
|
default:
|
||||||
err = ErrorCodeUnknown.WithDetail(daErr)
|
err = ErrorCodeUnknown.WithDetail(daErr)
|
||||||
|
|
||||||
|
|
|
@ -252,15 +252,3 @@ func appendValuesURL(u *url.URL, values ...url.Values) *url.URL {
|
||||||
u.RawQuery = merged.Encode()
|
u.RawQuery = merged.Encode()
|
||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
// appendValues appends the parameters to the url. Panics if the string is not
|
|
||||||
// a url.
|
|
||||||
func appendValues(u string, values ...url.Values) string {
|
|
||||||
up, err := url.Parse(u)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic(err) // should never happen
|
|
||||||
}
|
|
||||||
|
|
||||||
return appendValuesURL(up, values...).String()
|
|
||||||
}
|
|
||||||
|
|
|
@ -182,11 +182,6 @@ func TestURLBuilderWithPrefix(t *testing.T) {
|
||||||
doTest(false)
|
doTest(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
type builderFromRequestTestCase struct {
|
|
||||||
request *http.Request
|
|
||||||
base string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBuilderFromRequest(t *testing.T) {
|
func TestBuilderFromRequest(t *testing.T) {
|
||||||
u, err := url.Parse("http://example.com")
|
u, err := url.Parse("http://example.com")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -117,8 +117,8 @@ func init() {
|
||||||
var t octetType
|
var t octetType
|
||||||
isCtl := c <= 31 || c == 127
|
isCtl := c <= 31 || c == 127
|
||||||
isChar := 0 <= c && c <= 127
|
isChar := 0 <= c && c <= 127
|
||||||
isSeparator := strings.IndexRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) >= 0
|
isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c))
|
||||||
if strings.IndexRune(" \t\r\n", rune(c)) >= 0 {
|
if strings.ContainsRune(" \t\r\n", rune(c)) {
|
||||||
t |= isSpace
|
t |= isSpace
|
||||||
}
|
}
|
||||||
if isChar && !isCtl && !isSeparator {
|
if isChar && !isCtl && !isSeparator {
|
||||||
|
|
|
@ -466,7 +466,7 @@ func TestEndpointAuthorizeTokenBasic(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
authenicate1 := fmt.Sprintf("Basic realm=localhost")
|
authenicate1 := "Basic realm=localhost"
|
||||||
basicCheck := func(a string) bool {
|
basicCheck := func(a string) bool {
|
||||||
return a == fmt.Sprintf("Basic %s", basicAuth(username, password))
|
return a == fmt.Sprintf("Basic %s", basicAuth(username, password))
|
||||||
}
|
}
|
||||||
|
@ -546,7 +546,7 @@ func TestEndpointAuthorizeTokenBasicWithExpiresIn(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
authenicate1 := fmt.Sprintf("Basic realm=localhost")
|
authenicate1 := "Basic realm=localhost"
|
||||||
tokenExchanges := 0
|
tokenExchanges := 0
|
||||||
basicCheck := func(a string) bool {
|
basicCheck := func(a string) bool {
|
||||||
tokenExchanges = tokenExchanges + 1
|
tokenExchanges = tokenExchanges + 1
|
||||||
|
@ -706,7 +706,7 @@ func TestEndpointAuthorizeTokenBasicWithExpiresInAndIssuedAt(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
authenicate1 := fmt.Sprintf("Basic realm=localhost")
|
authenicate1 := "Basic realm=localhost"
|
||||||
tokenExchanges := 0
|
tokenExchanges := 0
|
||||||
basicCheck := func(a string) bool {
|
basicCheck := func(a string) bool {
|
||||||
tokenExchanges = tokenExchanges + 1
|
tokenExchanges = tokenExchanges + 1
|
||||||
|
@ -835,7 +835,7 @@ func TestEndpointAuthorizeBasic(t *testing.T) {
|
||||||
|
|
||||||
username := "user1"
|
username := "user1"
|
||||||
password := "funSecretPa$$word"
|
password := "funSecretPa$$word"
|
||||||
authenicate := fmt.Sprintf("Basic realm=localhost")
|
authenicate := "Basic realm=localhost"
|
||||||
validCheck := func(a string) bool {
|
validCheck := func(a string) bool {
|
||||||
return a == fmt.Sprintf("Basic %s", basicAuth(username, password))
|
return a == fmt.Sprintf("Basic %s", basicAuth(username, password))
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
"github.com/docker/distribution/registry/api/errcode"
|
"github.com/docker/distribution/registry/api/errcode"
|
||||||
"github.com/docker/distribution/registry/api/v2"
|
v2 "github.com/docker/distribution/registry/api/v2"
|
||||||
"github.com/docker/distribution/testutil"
|
"github.com/docker/distribution/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/docker/distribution/registry/api/v2"
|
v2 "github.com/docker/distribution/registry/api/v2"
|
||||||
"github.com/docker/distribution/registry/client/transport"
|
"github.com/docker/distribution/registry/client/transport"
|
||||||
"github.com/docker/distribution/registry/storage/cache"
|
"github.com/docker/distribution/registry/storage/cache"
|
||||||
"github.com/docker/distribution/registry/storage/cache/memory"
|
"github.com/docker/distribution/registry/storage/cache/memory"
|
||||||
|
|
|
@ -22,7 +22,7 @@ import (
|
||||||
"github.com/docker/distribution/manifest/schema1"
|
"github.com/docker/distribution/manifest/schema1"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/docker/distribution/registry/api/errcode"
|
"github.com/docker/distribution/registry/api/errcode"
|
||||||
"github.com/docker/distribution/registry/api/v2"
|
v2 "github.com/docker/distribution/registry/api/v2"
|
||||||
"github.com/docker/distribution/testutil"
|
"github.com/docker/distribution/testutil"
|
||||||
"github.com/docker/distribution/uuid"
|
"github.com/docker/distribution/uuid"
|
||||||
"github.com/docker/libtrust"
|
"github.com/docker/libtrust"
|
||||||
|
@ -152,7 +152,7 @@ func TestBlobFetch(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if bytes.Compare(b, b1) != 0 {
|
if !bytes.Equal(b, b1) {
|
||||||
t.Fatalf("Wrong bytes values fetched: [%d]byte != [%d]byte", len(b), len(b1))
|
t.Fatalf("Wrong bytes values fetched: [%d]byte != [%d]byte", len(b), len(b1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ import (
|
||||||
"github.com/docker/distribution/manifest/schema2"
|
"github.com/docker/distribution/manifest/schema2"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/docker/distribution/registry/api/errcode"
|
"github.com/docker/distribution/registry/api/errcode"
|
||||||
"github.com/docker/distribution/registry/api/v2"
|
v2 "github.com/docker/distribution/registry/api/v2"
|
||||||
storagedriver "github.com/docker/distribution/registry/storage/driver"
|
storagedriver "github.com/docker/distribution/registry/storage/driver"
|
||||||
"github.com/docker/distribution/registry/storage/driver/factory"
|
"github.com/docker/distribution/registry/storage/driver/factory"
|
||||||
_ "github.com/docker/distribution/registry/storage/driver/testdriver"
|
_ "github.com/docker/distribution/registry/storage/driver/testdriver"
|
||||||
|
@ -959,7 +959,6 @@ func testManifestWithStorageError(t *testing.T, env *testEnv, imageName referenc
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
checkResponse(t, "getting non-existent manifest", resp, expectedStatusCode)
|
checkResponse(t, "getting non-existent manifest", resp, expectedStatusCode)
|
||||||
checkBodyHasErrorCodes(t, "getting non-existent manifest", resp, expectedErrorCode)
|
checkBodyHasErrorCodes(t, "getting non-existent manifest", resp, expectedErrorCode)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testManifestAPISchema1(t *testing.T, env *testEnv, imageName reference.Named) manifestArgs {
|
func testManifestAPISchema1(t *testing.T, env *testEnv, imageName reference.Named) manifestArgs {
|
||||||
|
@ -1066,12 +1065,11 @@ func testManifestAPISchema1(t *testing.T, env *testEnv, imageName reference.Name
|
||||||
expectedLayers := make(map[digest.Digest]io.ReadSeeker)
|
expectedLayers := make(map[digest.Digest]io.ReadSeeker)
|
||||||
|
|
||||||
for i := range unsignedManifest.FSLayers {
|
for i := range unsignedManifest.FSLayers {
|
||||||
rs, dgstStr, err := testutil.CreateRandomTarFile()
|
rs, dgst, err := testutil.CreateRandomTarFile()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error creating random layer %d: %v", i, err)
|
t.Fatalf("error creating random layer %d: %v", i, err)
|
||||||
}
|
}
|
||||||
dgst := digest.Digest(dgstStr)
|
|
||||||
|
|
||||||
expectedLayers[dgst] = rs
|
expectedLayers[dgst] = rs
|
||||||
unsignedManifest.FSLayers[i].BlobSum = dgst
|
unsignedManifest.FSLayers[i].BlobSum = dgst
|
||||||
|
@ -1405,12 +1403,11 @@ func testManifestAPISchema2(t *testing.T, env *testEnv, imageName reference.Name
|
||||||
expectedLayers := make(map[digest.Digest]io.ReadSeeker)
|
expectedLayers := make(map[digest.Digest]io.ReadSeeker)
|
||||||
|
|
||||||
for i := range manifest.Layers {
|
for i := range manifest.Layers {
|
||||||
rs, dgstStr, err := testutil.CreateRandomTarFile()
|
rs, dgst, err := testutil.CreateRandomTarFile()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error creating random layer %d: %v", i, err)
|
t.Fatalf("error creating random layer %d: %v", i, err)
|
||||||
}
|
}
|
||||||
dgst := digest.Digest(dgstStr)
|
|
||||||
|
|
||||||
expectedLayers[dgst] = rs
|
expectedLayers[dgst] = rs
|
||||||
manifest.Layers[i].Digest = dgst
|
manifest.Layers[i].Digest = dgst
|
||||||
|
@ -2357,7 +2354,7 @@ func checkBodyHasErrorCodes(t *testing.T, msg string, resp *http.Response, error
|
||||||
// Ensure that counts of expected errors were all non-zero
|
// Ensure that counts of expected errors were all non-zero
|
||||||
for code := range expected {
|
for code := range expected {
|
||||||
if counts[code] == 0 {
|
if counts[code] == 0 {
|
||||||
t.Fatalf("expected error code %v not encounterd during %s: %s", code, msg, string(p))
|
t.Fatalf("expected error code %v not encountered during %s: %s", code, msg, string(p))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2432,11 +2429,10 @@ func createRepository(env *testEnv, t *testing.T, imageName string, tag string)
|
||||||
expectedLayers := make(map[digest.Digest]io.ReadSeeker)
|
expectedLayers := make(map[digest.Digest]io.ReadSeeker)
|
||||||
|
|
||||||
for i := range unsignedManifest.FSLayers {
|
for i := range unsignedManifest.FSLayers {
|
||||||
rs, dgstStr, err := testutil.CreateRandomTarFile()
|
rs, dgst, err := testutil.CreateRandomTarFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error creating random layer %d: %v", i, err)
|
t.Fatalf("error creating random layer %d: %v", i, err)
|
||||||
}
|
}
|
||||||
dgst := digest.Digest(dgstStr)
|
|
||||||
|
|
||||||
expectedLayers[dgst] = rs
|
expectedLayers[dgst] = rs
|
||||||
unsignedManifest.FSLayers[i].BlobSum = dgst
|
unsignedManifest.FSLayers[i].BlobSum = dgst
|
||||||
|
|
|
@ -24,7 +24,7 @@ import (
|
||||||
"github.com/docker/distribution/notifications"
|
"github.com/docker/distribution/notifications"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/docker/distribution/registry/api/errcode"
|
"github.com/docker/distribution/registry/api/errcode"
|
||||||
"github.com/docker/distribution/registry/api/v2"
|
v2 "github.com/docker/distribution/registry/api/v2"
|
||||||
"github.com/docker/distribution/registry/auth"
|
"github.com/docker/distribution/registry/auth"
|
||||||
registrymiddleware "github.com/docker/distribution/registry/middleware/registry"
|
registrymiddleware "github.com/docker/distribution/registry/middleware/registry"
|
||||||
repositorymiddleware "github.com/docker/distribution/registry/middleware/repository"
|
repositorymiddleware "github.com/docker/distribution/registry/middleware/repository"
|
||||||
|
@ -753,20 +753,18 @@ func (app *App) logError(ctx context.Context, errors errcode.Errors) {
|
||||||
for _, e1 := range errors {
|
for _, e1 := range errors {
|
||||||
var c context.Context
|
var c context.Context
|
||||||
|
|
||||||
switch e1.(type) {
|
switch e := e1.(type) {
|
||||||
case errcode.Error:
|
case errcode.Error:
|
||||||
e, _ := e1.(errcode.Error)
|
|
||||||
c = context.WithValue(ctx, errCodeKey{}, e.Code)
|
c = context.WithValue(ctx, errCodeKey{}, e.Code)
|
||||||
c = context.WithValue(c, errMessageKey{}, e.Message)
|
c = context.WithValue(c, errMessageKey{}, e.Message)
|
||||||
c = context.WithValue(c, errDetailKey{}, e.Detail)
|
c = context.WithValue(c, errDetailKey{}, e.Detail)
|
||||||
case errcode.ErrorCode:
|
case errcode.ErrorCode:
|
||||||
e, _ := e1.(errcode.ErrorCode)
|
|
||||||
c = context.WithValue(ctx, errCodeKey{}, e)
|
c = context.WithValue(ctx, errCodeKey{}, e)
|
||||||
c = context.WithValue(c, errMessageKey{}, e.Message())
|
c = context.WithValue(c, errMessageKey{}, e.Message())
|
||||||
default:
|
default:
|
||||||
// just normal go 'error'
|
// just normal go 'error'
|
||||||
c = context.WithValue(ctx, errCodeKey{}, errcode.ErrorCodeUnknown)
|
c = context.WithValue(ctx, errCodeKey{}, errcode.ErrorCodeUnknown)
|
||||||
c = context.WithValue(c, errMessageKey{}, e1.Error())
|
c = context.WithValue(c, errMessageKey{}, e.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
c = dcontext.WithLogger(c, dcontext.GetLogger(c,
|
c = dcontext.WithLogger(c, dcontext.GetLogger(c,
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/docker/distribution/configuration"
|
"github.com/docker/distribution/configuration"
|
||||||
"github.com/docker/distribution/context"
|
"github.com/docker/distribution/context"
|
||||||
"github.com/docker/distribution/registry/api/errcode"
|
"github.com/docker/distribution/registry/api/errcode"
|
||||||
"github.com/docker/distribution/registry/api/v2"
|
v2 "github.com/docker/distribution/registry/api/v2"
|
||||||
"github.com/docker/distribution/registry/auth"
|
"github.com/docker/distribution/registry/auth"
|
||||||
_ "github.com/docker/distribution/registry/auth/silly"
|
_ "github.com/docker/distribution/registry/auth/silly"
|
||||||
"github.com/docker/distribution/registry/storage"
|
"github.com/docker/distribution/registry/storage"
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
"github.com/docker/distribution/context"
|
"github.com/docker/distribution/context"
|
||||||
"github.com/docker/distribution/registry/api/errcode"
|
"github.com/docker/distribution/registry/api/errcode"
|
||||||
"github.com/docker/distribution/registry/api/v2"
|
v2 "github.com/docker/distribution/registry/api/v2"
|
||||||
"github.com/gorilla/handlers"
|
"github.com/gorilla/handlers"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
dcontext "github.com/docker/distribution/context"
|
dcontext "github.com/docker/distribution/context"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/docker/distribution/registry/api/errcode"
|
"github.com/docker/distribution/registry/api/errcode"
|
||||||
"github.com/docker/distribution/registry/api/v2"
|
v2 "github.com/docker/distribution/registry/api/v2"
|
||||||
"github.com/docker/distribution/registry/storage"
|
"github.com/docker/distribution/registry/storage"
|
||||||
"github.com/gorilla/handlers"
|
"github.com/gorilla/handlers"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
|
@ -172,7 +172,7 @@ func (buh *blobUploadHandler) PatchBlobData(w http.ResponseWriter, r *http.Reque
|
||||||
|
|
||||||
ct := r.Header.Get("Content-Type")
|
ct := r.Header.Get("Content-Type")
|
||||||
if ct != "" && ct != "application/octet-stream" {
|
if ct != "" && ct != "application/octet-stream" {
|
||||||
buh.Errors = append(buh.Errors, errcode.ErrorCodeUnknown.WithDetail(fmt.Errorf("Bad Content-Type")))
|
buh.Errors = append(buh.Errors, errcode.ErrorCodeUnknown.WithDetail(fmt.Errorf("bad Content-Type")))
|
||||||
// TODO(dmcgowan): encode error
|
// TODO(dmcgowan): encode error
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
dcontext "github.com/docker/distribution/context"
|
dcontext "github.com/docker/distribution/context"
|
||||||
"github.com/docker/distribution/registry/api/errcode"
|
"github.com/docker/distribution/registry/api/errcode"
|
||||||
"github.com/docker/distribution/registry/api/v2"
|
v2 "github.com/docker/distribution/registry/api/v2"
|
||||||
"github.com/docker/distribution/registry/auth"
|
"github.com/docker/distribution/registry/auth"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,7 +20,7 @@ type logHook struct {
|
||||||
func (hook *logHook) Fire(entry *logrus.Entry) error {
|
func (hook *logHook) Fire(entry *logrus.Entry) error {
|
||||||
addr := strings.Split(hook.Mail.Addr, ":")
|
addr := strings.Split(hook.Mail.Addr, ":")
|
||||||
if len(addr) != 2 {
|
if len(addr) != 2 {
|
||||||
return errors.New("Invalid Mail Address")
|
return errors.New("invalid Mail Address")
|
||||||
}
|
}
|
||||||
host := addr[0]
|
host := addr[0]
|
||||||
subject := fmt.Sprintf("[%s] %s: %s", entry.Level, host, entry.Message)
|
subject := fmt.Sprintf("[%s] %s: %s", entry.Level, host, entry.Message)
|
||||||
|
@ -37,7 +37,7 @@ func (hook *logHook) Fire(entry *logrus.Entry) error {
|
||||||
if err := t.Execute(b, entry); err != nil {
|
if err := t.Execute(b, entry); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
body := fmt.Sprintf("%s", b)
|
body := b.String()
|
||||||
|
|
||||||
return hook.Mail.sendMail(subject, body)
|
return hook.Mail.sendMail(subject, body)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ type mailer struct {
|
||||||
func (mail *mailer) sendMail(subject, message string) error {
|
func (mail *mailer) sendMail(subject, message string) error {
|
||||||
addr := strings.Split(mail.Addr, ":")
|
addr := strings.Split(mail.Addr, ":")
|
||||||
if len(addr) != 2 {
|
if len(addr) != 2 {
|
||||||
return errors.New("Invalid Mail Address")
|
return errors.New("invalid Mail Address")
|
||||||
}
|
}
|
||||||
host := addr[0]
|
host := addr[0]
|
||||||
msg := []byte("To:" + strings.Join(mail.To, ";") +
|
msg := []byte("To:" + strings.Join(mail.To, ";") +
|
||||||
|
|
|
@ -14,11 +14,11 @@ import (
|
||||||
"github.com/docker/distribution/manifest/schema2"
|
"github.com/docker/distribution/manifest/schema2"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/docker/distribution/registry/api/errcode"
|
"github.com/docker/distribution/registry/api/errcode"
|
||||||
"github.com/docker/distribution/registry/api/v2"
|
v2 "github.com/docker/distribution/registry/api/v2"
|
||||||
"github.com/docker/distribution/registry/auth"
|
"github.com/docker/distribution/registry/auth"
|
||||||
"github.com/gorilla/handlers"
|
"github.com/gorilla/handlers"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// These constants determine which architecture and OS to choose from a
|
// These constants determine which architecture and OS to choose from a
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
"github.com/docker/distribution/registry/api/errcode"
|
"github.com/docker/distribution/registry/api/errcode"
|
||||||
"github.com/docker/distribution/registry/api/v2"
|
v2 "github.com/docker/distribution/registry/api/v2"
|
||||||
"github.com/gorilla/handlers"
|
"github.com/gorilla/handlers"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/docker/distribution"
|
"github.com/docker/distribution"
|
||||||
dcontext "github.com/docker/distribution/context"
|
dcontext "github.com/docker/distribution/context"
|
||||||
|
@ -15,9 +14,6 @@ import (
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
)
|
)
|
||||||
|
|
||||||
// todo(richardscothern): from cache control header or config file
|
|
||||||
const blobTTL = 24 * 7 * time.Hour
|
|
||||||
|
|
||||||
type proxyBlobStore struct {
|
type proxyBlobStore struct {
|
||||||
localStore distribution.BlobStore
|
localStore distribution.BlobStore
|
||||||
remoteStore distribution.BlobService
|
remoteStore distribution.BlobService
|
||||||
|
|
|
@ -193,7 +193,7 @@ func makeTestEnv(t *testing.T, name string) *testEnv {
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeBlob(size int) []byte {
|
func makeBlob(size int) []byte {
|
||||||
blob := make([]byte, size, size)
|
blob := make([]byte, size)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
blob[i] = byte('A' + rand.Int()%48)
|
blob[i] = byte('A' + rand.Int()%48)
|
||||||
}
|
}
|
||||||
|
@ -204,16 +204,6 @@ func init() {
|
||||||
rand.Seed(42)
|
rand.Seed(42)
|
||||||
}
|
}
|
||||||
|
|
||||||
func perm(m []distribution.Descriptor) []distribution.Descriptor {
|
|
||||||
for i := 0; i < len(m); i++ {
|
|
||||||
j := rand.Intn(i + 1)
|
|
||||||
tmp := m[i]
|
|
||||||
m[i] = m[j]
|
|
||||||
m[j] = tmp
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func populate(t *testing.T, te *testEnv, blobCount, size, numUnique int) {
|
func populate(t *testing.T, te *testEnv, blobCount, size, numUnique int) {
|
||||||
var inRemote []distribution.Descriptor
|
var inRemote []distribution.Descriptor
|
||||||
|
|
||||||
|
|
|
@ -165,11 +165,10 @@ func populateRepo(ctx context.Context, t *testing.T, repository distribution.Rep
|
||||||
t.Fatalf("unexpected error creating test upload: %v", err)
|
t.Fatalf("unexpected error creating test upload: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rs, ts, err := testutil.CreateRandomTarFile()
|
rs, dgst, err := testutil.CreateRandomTarFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error generating test layer file")
|
t.Fatalf("unexpected error generating test layer file")
|
||||||
}
|
}
|
||||||
dgst := digest.Digest(ts)
|
|
||||||
if _, err := io.Copy(wr, rs); err != nil {
|
if _, err := io.Copy(wr, rs); err != nil {
|
||||||
t.Fatalf("unexpected error copying to upload: %v", err)
|
t.Fatalf("unexpected error copying to upload: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ func (ttles *TTLExpirationScheduler) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ttles.stopped {
|
if !ttles.stopped {
|
||||||
return fmt.Errorf("Scheduler already started")
|
return fmt.Errorf("scheduler already started")
|
||||||
}
|
}
|
||||||
|
|
||||||
dcontext.GetLogger(ttles.ctx).Infof("Starting cached object TTL expiration scheduler...")
|
dcontext.GetLogger(ttles.ctx).Infof("Starting cached object TTL expiration scheduler...")
|
||||||
|
@ -126,7 +126,7 @@ func (ttles *TTLExpirationScheduler) Start() error {
|
||||||
|
|
||||||
// Start timer for each deserialized entry
|
// Start timer for each deserialized entry
|
||||||
for _, entry := range ttles.entries {
|
for _, entry := range ttles.entries {
|
||||||
entry.timer = ttles.startTimer(entry, entry.Expiry.Sub(time.Now()))
|
entry.timer = ttles.startTimer(entry, time.Until(entry.Expiry))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start a ticker to periodically save the entries index
|
// Start a ticker to periodically save the entries index
|
||||||
|
@ -164,7 +164,7 @@ func (ttles *TTLExpirationScheduler) add(r reference.Reference, ttl time.Duratio
|
||||||
Expiry: time.Now().Add(ttl),
|
Expiry: time.Now().Add(ttl),
|
||||||
EntryType: eType,
|
EntryType: eType,
|
||||||
}
|
}
|
||||||
dcontext.GetLogger(ttles.ctx).Infof("Adding new scheduler entry for %s with ttl=%s", entry.Key, entry.Expiry.Sub(time.Now()))
|
dcontext.GetLogger(ttles.ctx).Infof("Adding new scheduler entry for %s with ttl=%s", entry.Key, time.Until(entry.Expiry))
|
||||||
if oldEntry, present := ttles.entries[entry.Key]; present && oldEntry.timer != nil {
|
if oldEntry, present := ttles.entries[entry.Key]; present && oldEntry.timer != nil {
|
||||||
oldEntry.timer.Stop()
|
oldEntry.timer.Stop()
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,8 @@ import (
|
||||||
|
|
||||||
"rsc.io/letsencrypt"
|
"rsc.io/letsencrypt"
|
||||||
|
|
||||||
"github.com/Shopify/logrus-bugsnag"
|
logrus_bugsnag "github.com/Shopify/logrus-bugsnag"
|
||||||
|
|
||||||
logstash "github.com/bshuster-repo/logrus-logstash-hook"
|
logstash "github.com/bshuster-repo/logrus-logstash-hook"
|
||||||
"github.com/bugsnag/bugsnag-go"
|
"github.com/bugsnag/bugsnag-go"
|
||||||
"github.com/docker/distribution/configuration"
|
"github.com/docker/distribution/configuration"
|
||||||
|
@ -185,7 +186,7 @@ func (registry *Registry) ListenAndServe() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ok := pool.AppendCertsFromPEM(caPem); !ok {
|
if ok := pool.AppendCertsFromPEM(caPem); !ok {
|
||||||
return fmt.Errorf("Could not add CA to pool")
|
return fmt.Errorf("could not add CA to pool")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -418,7 +418,7 @@ func TestBlobMount(t *testing.T) {
|
||||||
|
|
||||||
bs := repository.Blobs(ctx)
|
bs := repository.Blobs(ctx)
|
||||||
// Test destination for existence.
|
// Test destination for existence.
|
||||||
statDesc, err = bs.Stat(ctx, desc.Digest)
|
_, err = bs.Stat(ctx, desc.Digest)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("unexpected non-error stating unmounted blob: %v", desc)
|
t.Fatalf("unexpected non-error stating unmounted blob: %v", desc)
|
||||||
}
|
}
|
||||||
|
@ -478,12 +478,12 @@ func TestBlobMount(t *testing.T) {
|
||||||
t.Fatalf("Unexpected error deleting blob")
|
t.Fatalf("Unexpected error deleting blob")
|
||||||
}
|
}
|
||||||
|
|
||||||
d, err := bs.Stat(ctx, desc.Digest)
|
_, err = bs.Stat(ctx, desc.Digest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error stating blob deleted from source repository: %v", err)
|
t.Fatalf("unexpected error stating blob deleted from source repository: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d, err = sbs.Stat(ctx, desc.Digest)
|
d, err := sbs.Stat(ctx, desc.Digest)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("unexpected non-error stating deleted blob: %v", d)
|
t.Fatalf("unexpected non-error stating deleted blob: %v", d)
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,16 +152,6 @@ func (bs *blobStore) readlink(ctx context.Context, path string) (digest.Digest,
|
||||||
return linked, nil
|
return linked, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve reads the digest link at path and returns the blob store path.
|
|
||||||
func (bs *blobStore) resolve(ctx context.Context, path string) (string, error) {
|
|
||||||
dgst, err := bs.readlink(ctx, path)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return bs.path(dgst)
|
|
||||||
}
|
|
||||||
|
|
||||||
type blobStatter struct {
|
type blobStatter struct {
|
||||||
driver driver.StorageDriver
|
driver driver.StorageDriver
|
||||||
}
|
}
|
||||||
|
|
3
registry/storage/cache/cachecheck/suite.go
vendored
3
registry/storage/cache/cachecheck/suite.go
vendored
|
@ -173,8 +173,7 @@ func checkBlobDescriptorCacheClear(ctx context.Context, t *testing.T, provider c
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
desc, err = cache.Stat(ctx, localDigest)
|
if _, err = cache.Stat(ctx, localDigest); err == nil {
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("expected error statting deleted blob: %v", err)
|
t.Fatalf("expected error statting deleted blob: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,17 +55,17 @@ func (factory *azureDriverFactory) Create(parameters map[string]interface{}) (st
|
||||||
func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
accountName, ok := parameters[paramAccountName]
|
accountName, ok := parameters[paramAccountName]
|
||||||
if !ok || fmt.Sprint(accountName) == "" {
|
if !ok || fmt.Sprint(accountName) == "" {
|
||||||
return nil, fmt.Errorf("No %s parameter provided", paramAccountName)
|
return nil, fmt.Errorf("no %s parameter provided", paramAccountName)
|
||||||
}
|
}
|
||||||
|
|
||||||
accountKey, ok := parameters[paramAccountKey]
|
accountKey, ok := parameters[paramAccountKey]
|
||||||
if !ok || fmt.Sprint(accountKey) == "" {
|
if !ok || fmt.Sprint(accountKey) == "" {
|
||||||
return nil, fmt.Errorf("No %s parameter provided", paramAccountKey)
|
return nil, fmt.Errorf("no %s parameter provided", paramAccountKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
container, ok := parameters[paramContainer]
|
container, ok := parameters[paramContainer]
|
||||||
if !ok || fmt.Sprint(container) == "" {
|
if !ok || fmt.Sprint(container) == "" {
|
||||||
return nil, fmt.Errorf("No %s parameter provided", paramContainer)
|
return nil, fmt.Errorf("no %s parameter provided", paramContainer)
|
||||||
}
|
}
|
||||||
|
|
||||||
realm, ok := parameters[paramRealm]
|
realm, ok := parameters[paramRealm]
|
||||||
|
|
|
@ -36,7 +36,7 @@ func init() {
|
||||||
func TestFromParametersImpl(t *testing.T) {
|
func TestFromParametersImpl(t *testing.T) {
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
params map[string]interface{} // techincally the yaml can contain anything
|
params map[string]interface{} // technically the yaml can contain anything
|
||||||
expected DriverParameters
|
expected DriverParameters
|
||||||
pass bool
|
pass bool
|
||||||
}{
|
}{
|
||||||
|
|
|
@ -252,20 +252,6 @@ func (d *dir) delete(p string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// dump outputs a primitive directory structure to stdout.
|
|
||||||
func (d *dir) dump(indent string) {
|
|
||||||
fmt.Println(indent, d.name()+"/")
|
|
||||||
|
|
||||||
for _, child := range d.children {
|
|
||||||
if child.isdir() {
|
|
||||||
child.(*dir).dump(indent + "\t")
|
|
||||||
} else {
|
|
||||||
fmt.Println(indent, child.name())
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *dir) String() string {
|
func (d *dir) String() string {
|
||||||
return fmt.Sprintf("&dir{path: %v, children: %v}", d.p, d.children)
|
return fmt.Sprintf("&dir{path: %v, children: %v}", d.p, d.children)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
"github.com/aws/aws-sdk-go/service/cloudfront/sign"
|
"github.com/aws/aws-sdk-go/service/cloudfront/sign"
|
||||||
dcontext "github.com/docker/distribution/context"
|
dcontext "github.com/docker/distribution/context"
|
||||||
storagedriver "github.com/docker/distribution/registry/storage/driver"
|
storagedriver "github.com/docker/distribution/registry/storage/driver"
|
||||||
"github.com/docker/distribution/registry/storage/driver/middleware"
|
storagemiddleware "github.com/docker/distribution/registry/storage/driver/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
// cloudFrontStorageMiddleware provides a simple implementation of layerHandler that
|
// cloudFrontStorageMiddleware provides a simple implementation of layerHandler that
|
||||||
|
|
|
@ -188,19 +188,19 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
|
|
||||||
regionName := parameters["region"]
|
regionName := parameters["region"]
|
||||||
if regionName == nil || fmt.Sprint(regionName) == "" {
|
if regionName == nil || fmt.Sprint(regionName) == "" {
|
||||||
return nil, fmt.Errorf("No region parameter provided")
|
return nil, fmt.Errorf("no region parameter provided")
|
||||||
}
|
}
|
||||||
region := fmt.Sprint(regionName)
|
region := fmt.Sprint(regionName)
|
||||||
// Don't check the region value if a custom endpoint is provided.
|
// Don't check the region value if a custom endpoint is provided.
|
||||||
if regionEndpoint == "" {
|
if regionEndpoint == "" {
|
||||||
if _, ok := validRegions[region]; !ok {
|
if _, ok := validRegions[region]; !ok {
|
||||||
return nil, fmt.Errorf("Invalid region provided: %v", region)
|
return nil, fmt.Errorf("invalid region provided: %v", region)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bucket := parameters["bucket"]
|
bucket := parameters["bucket"]
|
||||||
if bucket == nil || fmt.Sprint(bucket) == "" {
|
if bucket == nil || fmt.Sprint(bucket) == "" {
|
||||||
return nil, fmt.Errorf("No bucket parameter provided")
|
return nil, fmt.Errorf("no bucket parameter provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptBool := false
|
encryptBool := false
|
||||||
|
@ -209,7 +209,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
case string:
|
case string:
|
||||||
b, err := strconv.ParseBool(encrypt)
|
b, err := strconv.ParseBool(encrypt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("The encrypt parameter should be a boolean")
|
return nil, fmt.Errorf("the encrypt parameter should be a boolean")
|
||||||
}
|
}
|
||||||
encryptBool = b
|
encryptBool = b
|
||||||
case bool:
|
case bool:
|
||||||
|
@ -217,7 +217,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
case nil:
|
case nil:
|
||||||
// do nothing
|
// do nothing
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("The encrypt parameter should be a boolean")
|
return nil, fmt.Errorf("the encrypt parameter should be a boolean")
|
||||||
}
|
}
|
||||||
|
|
||||||
secureBool := true
|
secureBool := true
|
||||||
|
@ -226,7 +226,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
case string:
|
case string:
|
||||||
b, err := strconv.ParseBool(secure)
|
b, err := strconv.ParseBool(secure)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("The secure parameter should be a boolean")
|
return nil, fmt.Errorf("the secure parameter should be a boolean")
|
||||||
}
|
}
|
||||||
secureBool = b
|
secureBool = b
|
||||||
case bool:
|
case bool:
|
||||||
|
@ -234,7 +234,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
case nil:
|
case nil:
|
||||||
// do nothing
|
// do nothing
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("The secure parameter should be a boolean")
|
return nil, fmt.Errorf("the secure parameter should be a boolean")
|
||||||
}
|
}
|
||||||
|
|
||||||
skipVerifyBool := false
|
skipVerifyBool := false
|
||||||
|
@ -243,7 +243,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
case string:
|
case string:
|
||||||
b, err := strconv.ParseBool(skipVerify)
|
b, err := strconv.ParseBool(skipVerify)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("The skipVerify parameter should be a boolean")
|
return nil, fmt.Errorf("the skipVerify parameter should be a boolean")
|
||||||
}
|
}
|
||||||
skipVerifyBool = b
|
skipVerifyBool = b
|
||||||
case bool:
|
case bool:
|
||||||
|
@ -251,7 +251,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
case nil:
|
case nil:
|
||||||
// do nothing
|
// do nothing
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("The skipVerify parameter should be a boolean")
|
return nil, fmt.Errorf("the skipVerify parameter should be a boolean")
|
||||||
}
|
}
|
||||||
|
|
||||||
v4Bool := true
|
v4Bool := true
|
||||||
|
@ -260,7 +260,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
case string:
|
case string:
|
||||||
b, err := strconv.ParseBool(v4auth)
|
b, err := strconv.ParseBool(v4auth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("The v4auth parameter should be a boolean")
|
return nil, fmt.Errorf("the v4auth parameter should be a boolean")
|
||||||
}
|
}
|
||||||
v4Bool = b
|
v4Bool = b
|
||||||
case bool:
|
case bool:
|
||||||
|
@ -268,7 +268,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
case nil:
|
case nil:
|
||||||
// do nothing
|
// do nothing
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("The v4auth parameter should be a boolean")
|
return nil, fmt.Errorf("the v4auth parameter should be a boolean")
|
||||||
}
|
}
|
||||||
|
|
||||||
keyID := parameters["keyid"]
|
keyID := parameters["keyid"]
|
||||||
|
@ -306,7 +306,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
if storageClassParam != nil {
|
if storageClassParam != nil {
|
||||||
storageClassString, ok := storageClassParam.(string)
|
storageClassString, ok := storageClassParam.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("The storageclass parameter must be one of %v, %v invalid",
|
return nil, fmt.Errorf("the storageclass parameter must be one of %v, %v invalid",
|
||||||
[]string{s3.StorageClassStandard, s3.StorageClassReducedRedundancy}, storageClassParam)
|
[]string{s3.StorageClassStandard, s3.StorageClassReducedRedundancy}, storageClassParam)
|
||||||
}
|
}
|
||||||
// All valid storage class parameters are UPPERCASE, so be a bit more flexible here
|
// All valid storage class parameters are UPPERCASE, so be a bit more flexible here
|
||||||
|
@ -314,7 +314,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
if storageClassString != noStorageClass &&
|
if storageClassString != noStorageClass &&
|
||||||
storageClassString != s3.StorageClassStandard &&
|
storageClassString != s3.StorageClassStandard &&
|
||||||
storageClassString != s3.StorageClassReducedRedundancy {
|
storageClassString != s3.StorageClassReducedRedundancy {
|
||||||
return nil, fmt.Errorf("The storageclass parameter must be one of %v, %v invalid",
|
return nil, fmt.Errorf("the storageclass parameter must be one of %v, %v invalid",
|
||||||
[]string{noStorageClass, s3.StorageClassStandard, s3.StorageClassReducedRedundancy}, storageClassParam)
|
[]string{noStorageClass, s3.StorageClassStandard, s3.StorageClassReducedRedundancy}, storageClassParam)
|
||||||
}
|
}
|
||||||
storageClass = storageClassString
|
storageClass = storageClassString
|
||||||
|
@ -330,11 +330,11 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
if objectACLParam != nil {
|
if objectACLParam != nil {
|
||||||
objectACLString, ok := objectACLParam.(string)
|
objectACLString, ok := objectACLParam.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("Invalid value for objectacl parameter: %v", objectACLParam)
|
return nil, fmt.Errorf("invalid value for objectacl parameter: %v", objectACLParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok = validObjectACLs[objectACLString]; !ok {
|
if _, ok = validObjectACLs[objectACLString]; !ok {
|
||||||
return nil, fmt.Errorf("Invalid value for objectacl parameter: %v", objectACLParam)
|
return nil, fmt.Errorf("invalid value for objectacl parameter: %v", objectACLParam)
|
||||||
}
|
}
|
||||||
objectACL = objectACLString
|
objectACL = objectACLString
|
||||||
}
|
}
|
||||||
|
@ -366,7 +366,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
return New(params)
|
return New(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getParameterAsInt64 converts paramaters[name] to an int64 value (using
|
// getParameterAsInt64 converts parameters[name] to an int64 value (using
|
||||||
// defaultt if nil), verifies it is no smaller than min, and returns it.
|
// defaultt if nil), verifies it is no smaller than min, and returns it.
|
||||||
func getParameterAsInt64(parameters map[string]interface{}, name string, defaultt int64, min int64, max int64) (int64, error) {
|
func getParameterAsInt64(parameters map[string]interface{}, name string, defaultt int64, min int64, max int64) (int64, error) {
|
||||||
rv := defaultt
|
rv := defaultt
|
||||||
|
@ -389,7 +389,7 @@ func getParameterAsInt64(parameters map[string]interface{}, name string, default
|
||||||
}
|
}
|
||||||
|
|
||||||
if rv < min || rv > max {
|
if rv < min || rv > max {
|
||||||
return 0, fmt.Errorf("The %s %#v parameter should be a number between %d and %d (inclusive)", name, rv, min, max)
|
return 0, fmt.Errorf("the %s %#v parameter should be a number between %d and %d (inclusive)", name, rv, min, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv, nil
|
return rv, nil
|
||||||
|
@ -401,7 +401,7 @@ func New(params DriverParameters) (*Driver, error) {
|
||||||
if !params.V4Auth &&
|
if !params.V4Auth &&
|
||||||
(params.RegionEndpoint == "" ||
|
(params.RegionEndpoint == "" ||
|
||||||
strings.Contains(params.RegionEndpoint, "s3.amazonaws.com")) {
|
strings.Contains(params.RegionEndpoint, "s3.amazonaws.com")) {
|
||||||
return nil, fmt.Errorf("On Amazon S3 this storage driver can only be used with v4 authentication")
|
return nil, fmt.Errorf("on Amazon S3 this storage driver can only be used with v4 authentication")
|
||||||
}
|
}
|
||||||
|
|
||||||
awsConfig := aws.NewConfig()
|
awsConfig := aws.NewConfig()
|
||||||
|
@ -878,7 +878,7 @@ func (d *driver) URLFor(ctx context.Context, path string, options map[string]int
|
||||||
if ok {
|
if ok {
|
||||||
et, ok := expires.(time.Time)
|
et, ok := expires.(time.Time)
|
||||||
if ok {
|
if ok {
|
||||||
expiresIn = et.Sub(time.Now())
|
expiresIn = time.Until(et)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,12 +39,6 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
signatureVersion = "2"
|
|
||||||
signatureMethod = "HmacSHA1"
|
|
||||||
timeFormat = "2006-01-02T15:04:05Z"
|
|
||||||
)
|
|
||||||
|
|
||||||
type signer struct {
|
type signer struct {
|
||||||
// Values that must be populated from the request
|
// Values that must be populated from the request
|
||||||
Request *http.Request
|
Request *http.Request
|
||||||
|
|
|
@ -160,23 +160,23 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.Username == "" {
|
if params.Username == "" {
|
||||||
return nil, fmt.Errorf("No username parameter provided")
|
return nil, fmt.Errorf("no username parameter provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.Password == "" {
|
if params.Password == "" {
|
||||||
return nil, fmt.Errorf("No password parameter provided")
|
return nil, fmt.Errorf("no password parameter provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.AuthURL == "" {
|
if params.AuthURL == "" {
|
||||||
return nil, fmt.Errorf("No authurl parameter provided")
|
return nil, fmt.Errorf("no authurl parameter provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.Container == "" {
|
if params.Container == "" {
|
||||||
return nil, fmt.Errorf("No container parameter provided")
|
return nil, fmt.Errorf("no container parameter provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.ChunkSize < minChunkSize {
|
if params.ChunkSize < minChunkSize {
|
||||||
return nil, fmt.Errorf("The chunksize %#v parameter should be a number that is larger than or equal to %d", params.ChunkSize, minChunkSize)
|
return nil, fmt.Errorf("the chunksize %#v parameter should be a number that is larger than or equal to %d", params.ChunkSize, minChunkSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
return New(params)
|
return New(params)
|
||||||
|
@ -211,15 +211,15 @@ func New(params Parameters) (*Driver, error) {
|
||||||
}
|
}
|
||||||
err := ct.Authenticate()
|
err := ct.Authenticate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Swift authentication failed: %s", err)
|
return nil, fmt.Errorf("swift authentication failed: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, _, err := ct.Container(params.Container); err == swift.ContainerNotFound {
|
if _, _, err := ct.Container(params.Container); err == swift.ContainerNotFound {
|
||||||
if err := ct.ContainerCreate(params.Container, nil); err != nil {
|
if err := ct.ContainerCreate(params.Container, nil); err != nil {
|
||||||
return nil, fmt.Errorf("Failed to create container %s (%s)", params.Container, err)
|
return nil, fmt.Errorf("failed to create container %s (%s)", params.Container, err)
|
||||||
}
|
}
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to retrieve info about container %s (%s)", params.Container, err)
|
return nil, fmt.Errorf("failed to retrieve info about container %s (%s)", params.Container, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := &driver{
|
d := &driver{
|
||||||
|
@ -258,7 +258,7 @@ func New(params Parameters) (*Driver, error) {
|
||||||
if d.TempURLContainerKey {
|
if d.TempURLContainerKey {
|
||||||
_, containerHeaders, err := d.Conn.Container(d.Container)
|
_, containerHeaders, err := d.Conn.Container(d.Container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to fetch container info %s (%s)", d.Container, err)
|
return nil, fmt.Errorf("failed to fetch container info %s (%s)", d.Container, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SecretKey = containerHeaders["X-Container-Meta-Temp-Url-Key"]
|
d.SecretKey = containerHeaders["X-Container-Meta-Temp-Url-Key"]
|
||||||
|
@ -273,7 +273,7 @@ func New(params Parameters) (*Driver, error) {
|
||||||
// Use the account secret key
|
// Use the account secret key
|
||||||
_, accountHeaders, err := d.Conn.Account()
|
_, accountHeaders, err := d.Conn.Account()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to fetch account info (%s)", err)
|
return nil, fmt.Errorf("failed to fetch account info (%s)", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SecretKey = accountHeaders["X-Account-Meta-Temp-Url-Key"]
|
d.SecretKey = accountHeaders["X-Account-Meta-Temp-Url-Key"]
|
||||||
|
@ -350,7 +350,7 @@ func (d *driver) Reader(ctx context.Context, path string, offset int64) (io.Read
|
||||||
}
|
}
|
||||||
if isDLO && size == 0 {
|
if isDLO && size == 0 {
|
||||||
if time.Now().Add(waitingTime).After(endTime) {
|
if time.Now().Add(waitingTime).After(endTime) {
|
||||||
return nil, fmt.Errorf("Timeout expired while waiting for segments of %s to show up", path)
|
return nil, fmt.Errorf("timeout expired while waiting for segments of %s to show up", path)
|
||||||
}
|
}
|
||||||
time.Sleep(waitingTime)
|
time.Sleep(waitingTime)
|
||||||
waitingTime *= 2
|
waitingTime *= 2
|
||||||
|
@ -456,7 +456,7 @@ func (d *driver) Stat(ctx context.Context, path string) (storagedriver.FileInfo,
|
||||||
_, isDLO := headers["X-Object-Manifest"]
|
_, isDLO := headers["X-Object-Manifest"]
|
||||||
if isDLO && info.Bytes == 0 {
|
if isDLO && info.Bytes == 0 {
|
||||||
if time.Now().Add(waitingTime).After(endTime) {
|
if time.Now().Add(waitingTime).After(endTime) {
|
||||||
return nil, fmt.Errorf("Timeout expired while waiting for segments of %s to show up", path)
|
return nil, fmt.Errorf("timeout expired while waiting for segments of %s to show up", path)
|
||||||
}
|
}
|
||||||
time.Sleep(waitingTime)
|
time.Sleep(waitingTime)
|
||||||
waitingTime *= 2
|
waitingTime *= 2
|
||||||
|
@ -755,7 +755,7 @@ func chunkFilenames(slice []string, maxSize int) (chunks [][]string, err error)
|
||||||
chunks = append(chunks, slice[offset:offset+chunkSize])
|
chunks = append(chunks, slice[offset:offset+chunkSize])
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("Max chunk size must be > 0")
|
return nil, fmt.Errorf("max chunk size must be > 0")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -894,7 +894,7 @@ func (w *writer) waitForSegmentsToShowUp() error {
|
||||||
if info.Bytes == w.size {
|
if info.Bytes == w.size {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
err = fmt.Errorf("Timeout expired while waiting for segments of %s to show up", w.path)
|
err = fmt.Errorf("timeout expired while waiting for segments of %s to show up", w.path)
|
||||||
}
|
}
|
||||||
if time.Now().Add(waitingTime).After(endTime) {
|
if time.Now().Add(waitingTime).After(endTime) {
|
||||||
break
|
break
|
||||||
|
|
|
@ -98,7 +98,6 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
// In certain situations such as unfinished uploads, deleting all
|
// In certain situations such as unfinished uploads, deleting all
|
||||||
// tags in S3 or removing the _manifests folder manually, this
|
// tags in S3 or removing the _manifests folder manually, this
|
||||||
// error may be of type PathNotFound.
|
// error may be of type PathNotFound.
|
||||||
|
@ -107,7 +106,6 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
|
||||||
if _, ok := err.(driver.PathNotFoundError); ok {
|
if _, ok := err.(driver.PathNotFoundError); ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
|
|
|
@ -27,13 +27,12 @@ func TestLinkedBlobStoreCreateWithMountFrom(t *testing.T) {
|
||||||
// readseekers for upload later.
|
// readseekers for upload later.
|
||||||
testLayers := map[digest.Digest]io.ReadSeeker{}
|
testLayers := map[digest.Digest]io.ReadSeeker{}
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
rs, ds, err := testutil.CreateRandomTarFile()
|
rs, dgst, err := testutil.CreateRandomTarFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error generating test layer file")
|
t.Fatalf("unexpected error generating test layer file")
|
||||||
}
|
}
|
||||||
dgst := digest.Digest(ds)
|
|
||||||
|
|
||||||
testLayers[digest.Digest(dgst)] = rs
|
testLayers[dgst] = rs
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload the layers to foo/bar
|
// upload the layers to foo/bar
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"github.com/docker/distribution/manifest/schema1"
|
"github.com/docker/distribution/manifest/schema1"
|
||||||
"github.com/docker/distribution/manifest/schema2"
|
"github.com/docker/distribution/manifest/schema2"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A ManifestHandler gets and puts manifests of a particular type.
|
// A ManifestHandler gets and puts manifests of a particular type.
|
||||||
|
|
|
@ -19,7 +19,7 @@ import (
|
||||||
"github.com/docker/distribution/testutil"
|
"github.com/docker/distribution/testutil"
|
||||||
"github.com/docker/libtrust"
|
"github.com/docker/libtrust"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type manifestStoreTestEnv struct {
|
type manifestStoreTestEnv struct {
|
||||||
|
@ -91,13 +91,12 @@ func testManifestStorage(t *testing.T, schema1Enabled bool, options ...RegistryO
|
||||||
// readseekers for upload later.
|
// readseekers for upload later.
|
||||||
testLayers := map[digest.Digest]io.ReadSeeker{}
|
testLayers := map[digest.Digest]io.ReadSeeker{}
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
rs, ds, err := testutil.CreateRandomTarFile()
|
rs, dgst, err := testutil.CreateRandomTarFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error generating test layer file")
|
t.Fatalf("unexpected error generating test layer file")
|
||||||
}
|
}
|
||||||
dgst := digest.Digest(ds)
|
|
||||||
|
|
||||||
testLayers[digest.Digest(dgst)] = rs
|
testLayers[dgst] = rs
|
||||||
m.FSLayers = append(m.FSLayers, schema1.FSLayer{
|
m.FSLayers = append(m.FSLayers, schema1.FSLayer{
|
||||||
BlobSum: dgst,
|
BlobSum: dgst,
|
||||||
})
|
})
|
||||||
|
@ -414,11 +413,10 @@ func testOCIManifestStorage(t *testing.T, testname string, includeMediaTypes boo
|
||||||
|
|
||||||
// Add some layers
|
// Add some layers
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
rs, ds, err := testutil.CreateRandomTarFile()
|
rs, dgst, err := testutil.CreateRandomTarFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("%s: unexpected error generating test layer file", testname)
|
t.Fatalf("%s: unexpected error generating test layer file", testname)
|
||||||
}
|
}
|
||||||
dgst := digest.Digest(ds)
|
|
||||||
|
|
||||||
wr, err := env.repository.Blobs(env.ctx).Create(env.ctx)
|
wr, err := env.repository.Blobs(env.ctx).Create(env.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
dcontext "github.com/docker/distribution/context"
|
dcontext "github.com/docker/distribution/context"
|
||||||
"github.com/docker/distribution/manifest/ocischema"
|
"github.com/docker/distribution/manifest/ocischema"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
//ocischemaManifestHandler is a ManifestHandler that covers ocischema manifests.
|
//ocischemaManifestHandler is a ManifestHandler that covers ocischema manifests.
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/docker/distribution/manifest"
|
"github.com/docker/distribution/manifest"
|
||||||
"github.com/docker/distribution/manifest/ocischema"
|
"github.com/docker/distribution/manifest/ocischema"
|
||||||
"github.com/docker/distribution/registry/storage/driver/inmemory"
|
"github.com/docker/distribution/registry/storage/driver/inmemory"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestVerifyOCIManifestNonDistributableLayer(t *testing.T) {
|
func TestVerifyOCIManifestNonDistributableLayer(t *testing.T) {
|
||||||
|
|
|
@ -133,10 +133,7 @@ func pathFor(spec pathSpec) (string, error) {
|
||||||
|
|
||||||
return path.Join(append(append(repoPrefix, v.name, "_manifests", "revisions"), components...)...), nil
|
return path.Join(append(append(repoPrefix, v.name, "_manifests", "revisions"), components...)...), nil
|
||||||
case manifestRevisionLinkPathSpec:
|
case manifestRevisionLinkPathSpec:
|
||||||
root, err := pathFor(manifestRevisionPathSpec{
|
root, err := pathFor(manifestRevisionPathSpec(v))
|
||||||
name: v.name,
|
|
||||||
revision: v.revision,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -156,10 +153,7 @@ func pathFor(spec pathSpec) (string, error) {
|
||||||
|
|
||||||
return path.Join(root, v.tag), nil
|
return path.Join(root, v.tag), nil
|
||||||
case manifestTagCurrentPathSpec:
|
case manifestTagCurrentPathSpec:
|
||||||
root, err := pathFor(manifestTagPathSpec{
|
root, err := pathFor(manifestTagPathSpec(v))
|
||||||
name: v.name,
|
|
||||||
tag: v.tag,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -167,10 +161,7 @@ func pathFor(spec pathSpec) (string, error) {
|
||||||
|
|
||||||
return path.Join(root, "current", "link"), nil
|
return path.Join(root, "current", "link"), nil
|
||||||
case manifestTagIndexPathSpec:
|
case manifestTagIndexPathSpec:
|
||||||
root, err := pathFor(manifestTagPathSpec{
|
root, err := pathFor(manifestTagPathSpec(v))
|
||||||
name: v.name,
|
|
||||||
tag: v.tag,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -178,11 +169,7 @@ func pathFor(spec pathSpec) (string, error) {
|
||||||
|
|
||||||
return path.Join(root, "index"), nil
|
return path.Join(root, "index"), nil
|
||||||
case manifestTagIndexEntryLinkPathSpec:
|
case manifestTagIndexEntryLinkPathSpec:
|
||||||
root, err := pathFor(manifestTagIndexEntryPathSpec{
|
root, err := pathFor(manifestTagIndexEntryPathSpec(v))
|
||||||
name: v.name,
|
|
||||||
tag: v.tag,
|
|
||||||
revision: v.revision,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
|
|
@ -10,7 +10,6 @@ func TestPathMapper(t *testing.T) {
|
||||||
for _, testcase := range []struct {
|
for _, testcase := range []struct {
|
||||||
spec pathSpec
|
spec pathSpec
|
||||||
expected string
|
expected string
|
||||||
err error
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
spec: manifestRevisionPathSpec{
|
spec: manifestRevisionPathSpec{
|
||||||
|
|
|
@ -59,7 +59,7 @@ func PurgeUploads(ctx context.Context, driver storageDriver.StorageDriver, older
|
||||||
// file, so gather files by UUID with a date from startedAt.
|
// file, so gather files by UUID with a date from startedAt.
|
||||||
func getOutstandingUploads(ctx context.Context, driver storageDriver.StorageDriver) (map[string]uploadData, []error) {
|
func getOutstandingUploads(ctx context.Context, driver storageDriver.StorageDriver) (map[string]uploadData, []error) {
|
||||||
var errors []error
|
var errors []error
|
||||||
uploads := make(map[string]uploadData, 0)
|
uploads := make(map[string]uploadData)
|
||||||
|
|
||||||
inUploadDir := false
|
inUploadDir := false
|
||||||
root, err := pathFor(repositoriesRootPathSpec{})
|
root, err := pathFor(repositoriesRootPathSpec{})
|
||||||
|
|
|
@ -118,7 +118,7 @@ func TestPurgeOnlyUploads(t *testing.T) {
|
||||||
t.Fatalf(err.Error())
|
t.Fatalf(err.Error())
|
||||||
}
|
}
|
||||||
nonUploadPath := strings.Replace(dataPath, "_upload", "_important", -1)
|
nonUploadPath := strings.Replace(dataPath, "_upload", "_important", -1)
|
||||||
if strings.Index(nonUploadPath, "_upload") != -1 {
|
if strings.Contains(nonUploadPath, "_upload") {
|
||||||
t.Fatalf("Non-upload path not created correctly")
|
t.Fatalf("Non-upload path not created correctly")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ func TestPurgeOnlyUploads(t *testing.T) {
|
||||||
t.Error("Unexpected errors", errs)
|
t.Error("Unexpected errors", errs)
|
||||||
}
|
}
|
||||||
for _, file := range deleted {
|
for _, file := range deleted {
|
||||||
if strings.Index(file, "_upload") == -1 {
|
if !strings.Contains(file, "_upload") {
|
||||||
t.Errorf("Non-upload file deleted")
|
t.Errorf("Non-upload file deleted")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errUnexpectedURL = errors.New("unexpected URL on layer")
|
|
||||||
errMissingURL = errors.New("missing URL on layer")
|
errMissingURL = errors.New("missing URL on layer")
|
||||||
errInvalidURL = errors.New("invalid URL on layer")
|
errInvalidURL = errors.New("invalid URL on layer")
|
||||||
)
|
)
|
||||||
|
@ -93,7 +92,7 @@ func (ms *schema2ManifestHandler) verifyManifest(ctx context.Context, mnfst sche
|
||||||
switch descriptor.MediaType {
|
switch descriptor.MediaType {
|
||||||
case schema2.MediaTypeForeignLayer:
|
case schema2.MediaTypeForeignLayer:
|
||||||
// Clients download this layer from an external URL, so do not check for
|
// Clients download this layer from an external URL, so do not check for
|
||||||
// its presense.
|
// its presence.
|
||||||
if len(descriptor.URLs) == 0 {
|
if len(descriptor.URLs) == 0 {
|
||||||
err = errMissingURL
|
err = errMissingURL
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,25 +50,6 @@ func (ts *tagStore) All(ctx context.Context) ([]string, error) {
|
||||||
return tags, nil
|
return tags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// exists returns true if the specified manifest tag exists in the repository.
|
|
||||||
func (ts *tagStore) exists(ctx context.Context, tag string) (bool, error) {
|
|
||||||
tagPath, err := pathFor(manifestTagCurrentPathSpec{
|
|
||||||
name: ts.repository.Named().Name(),
|
|
||||||
tag: tag,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
exists, err := exists(ctx, ts.blobStore.driver, tagPath)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return exists, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tag tags the digest with the given tag, updating the the store to point at
|
// Tag tags the digest with the given tag, updating the the store to point at
|
||||||
// the current tag. The digest must point to a manifest.
|
// the current tag. The digest must point to a manifest.
|
||||||
func (ts *tagStore) Tag(ctx context.Context, tag string, desc distribution.Descriptor) error {
|
func (ts *tagStore) Tag(ctx context.Context, tag string, desc distribution.Descriptor) error {
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/docker/distribution/registry/storage/driver"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Exists provides a utility method to test whether or not a path exists in
|
|
||||||
// the given driver.
|
|
||||||
func exists(ctx context.Context, drv driver.StorageDriver, path string) (bool, error) {
|
|
||||||
if _, err := drv.Stat(ctx, path); err != nil {
|
|
||||||
switch err := err.(type) {
|
|
||||||
case driver.PathNotFoundError:
|
|
||||||
return false, nil
|
|
||||||
default:
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
|
@ -1,11 +1,12 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
GOLANGCI_LINT_VERSION="v1.27.0"
|
||||||
|
|
||||||
#
|
#
|
||||||
# Install developer tools to $GOBIN (or $GOPATH/bin if unset)
|
# Install developer tools to $GOBIN (or $GOPATH/bin if unset)
|
||||||
#
|
#
|
||||||
set -eu -o pipefail
|
set -eu -o pipefail
|
||||||
|
|
||||||
go get -u github.com/alecthomas/gometalinter
|
cd /tmp
|
||||||
gometalinter --install >/dev/null
|
|
||||||
go get -u github.com/LK4D4/vndr
|
go get -u github.com/LK4D4/vndr
|
||||||
go get -u github.com/cpuguy83/go-md2man
|
go get "github.com/golangci/golangci-lint/cmd/golangci-lint@${GOLANGCI_LINT_VERSION}"
|
||||||
|
|
|
@ -9,4 +9,4 @@ if ! command -v git-validation; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
verbosity="${DCO_VERBOSITY--v}"
|
verbosity="${DCO_VERBOSITY--v}"
|
||||||
GIT_CHECK_EXCLUDE="./vendor:./script/validate/template" git-validation "$verbosity" -range "$COMMIT_RANGE" -run DCO,short-subject,dangling-whitespace
|
GIT_CHECK_EXCLUDE="./vendor:./script/validate/template" git-validation "$verbosity" -range "5b98226afefa11a06ef0c652af4995177c0efda0..HEAD" -run DCO,short-subject,dangling-whitespace
|
Loading…
Reference in a new issue