If this slice ends up empty after parsing the HTTP response body, it
means the body is not well-formed. We've probably encountered an error
message produced by something that uses a different JSON schema, or
an error that just happens to validate as JSON.
An empty errcode.Errors slice is not a very useful thing to return,
since its Error() output is just `<nil>`. Detect this case, and instend
return an UnexpectedHTTPResponseError.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Updates registry storage code to use this for better resumable writes.
Implements this interface for the following drivers:
+ Inmemory
+ Filesystem
+ S3
+ Azure
Signed-off-by: Brian Bland <brian.bland@docker.com>
It is possible for a middlebox to lowercase the URL at somepoint causing a
lookup in the auth challenges table to fail. Lowercase hostname before
using as keys to challenge map.
Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
Cross repository push tokens were not being cached and could not be used,
now any returned token will be used and the caching is hidden in the getToken function.
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
Login needs to add an offline token flag to ensure a refresh token is returned by the token endpoint.
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
The Move operation is only used to move uploaded blobs
to their final destination. There is no point in implementing
Move on "folders". Apart from simplifying the code, this also
saves an HTTP request.
Signed-off-by: Arthur Baars <arthur@semmle.com>
- Includes a change in the command to run the registry. The registry
server itself is now started up as a subcommand.
- Includes changes to the high level interfaces to support enumeration
of various registry objects.
Signed-off-by: Andrew T Nguyen <andrew.nguyen@docker.com>
Ensure Accept headers are sent with TagService.Get (which hits manifest
endpoints). Add support for remote Get and Put for the proxied blobstore.
Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
Middleware code may perform additional checks on blobs written. Allow it
to return access denied errors that will result in 403 Forbidden.
Signed-off-by: Michal Minar <miminar@redhat.com>
Offset can be more than CurrentSize as long as this case is checked
by DriverSuite.testContinueStreamAppend.
Signed-off-by: Anton Tiurin <noxiouz@yandex.ru>
Fixes bug in TestStorageClass for s3aws driver where the "standard" file
was checked for reduced-redundnancy storage.
Signed-off-by: Brian Bland <brian.bland@docker.com>
challenges with the upstream until any proxied data is found not to be local.
Implement auth challenges behind an interface and add to unit tests. Also,
remove a non-sensical unit test.
Signed-off-by: Richard Scothern <richard.scothern@docker.com>
Keeps old s3 driver, renames to s3goamz, registers new s3 driver as both
"s3" and "s3aws"
Changes cloudfront middleware to use aws-sdk-go
Signed-off-by: Brian Bland <brian.bland@docker.com>
Making this an exported error value will allow users of the
registry/client/auth module to have consistent behavior between
authentication failures and cases where no credentials are provided.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Add option for specifying trust key for signing schema1 manifests.
Since schema1 signature key identifiers are not verified anywhere and deprecated, storing signatures is no longer a requirement.
Furthermore in schema2 there is no signature, requiring the registry to already add signatures to generated schema1 manifests.
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
When schema2 manifests are rewritten as schema1 currently the etag and docker content digest header keep the value for the schema2 manifest.
Fixes#1444
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
Treats nil parameters the same as unprovided parameters (fixes issues
where certain parameters are printed to "<nil>").
Accepts "true" and "false" string values for boolean parameters.
Signed-off-by: Brian Bland <brian.bland@docker.com>
A changeset under consideration for Go 1.7 would automatically copy
headers on redirect. This change future-proofs our code so we won't make
duplicate copies of the headers if net/http does it automatically in the
future.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Uses docker/goamz instead of AdRoll/goamz
Adds a registry UA string param to the storage parameters when
constructing the storage driver for the registry App.
This could be used by other storage drivers as well
Signed-off-by: Brian Bland <brian.bland@docker.com>
Prevent using strings throughout the code to reference a string key defined in the auth package.
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
Since RawMessage json receivers take a pointer type, the Header structure should use points in order to call the json.RawMessage marshal and unmarshal functions
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
Most places in the registry were using string types to refer to
repository names. This changes them to use reference.Named, so the type
system can enforce validation of the naming rules.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This is needed for compatibility with some third-party registries that
send an inappropriate Content-Type header such as text/html.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
https://github.com/docker/distribution/pull/1249 changed token fetching
to parse HTTP error response bodies as serialized errcodes. However,
Docker Hub's authentication endpoint does not return error bodies in
this format. To work around this, convert its format into
ErrCodeUnauthorized or ErrCodeUnknown.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Verify that the file(s) have been deleted after calling Delete,
and retry if this is not the case. Furthermore, report the error
if a Delete operation fails.
Signed-off-by: Arthur Baars <arthur@semmle.com>
The Payload function for schema1 currently returns a signed manifest,
but indicates the content type is that of a manifest that isn't signed.
Note that this breaks compatibility with Registry 2.3 alpha 1 and
Docker 1.10-rc1, because they use the incorrect content type.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
For compatibility with other registries that don't use this exact
variant of the Content-Type header, we need to be more flexible about
what we accept. Any form of "application/json" should be allowed. The
charset should not be included in the comparison.
See docker/docker#19400.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Accidentally checked for err != nil instead of err == nil :/
Also now ensures that only a non-nil option is appended to the create
options slice
Signed-off-by: Brian Bland <brian.bland@docker.com>
Remove the requirement of file system access to run GCS unit tests. Deconstruct
the input parameters to take the private key and email which can be specified on
the build system via environment variables.
Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
Removes the Mount operation and instead implements this behavior as part
of Create a From option is provided, which in turn returns a rich
ErrBlobMounted indicating that a blob upload session was not initiated,
but instead the blob was mounted from another repository
Signed-off-by: Brian Bland <brian.bland@docker.com>
When an auth request provides the "from" query parameter, the token
handler will add a "pull" scope for the provided repository, refreshing
the token if the overall scope has increased
Signed-off-by: Brian Bland <brian.bland@docker.com>
This makes content type sniffing cleaner. The document just needs to be
decoded into a manifest.Versioned structure. It's no longer a two-step
process.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Create signedManifestHandler and schema2ManifestHandler. Use these to
unmarshal and put the respective types of manifests from manifestStore.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
When a manifest is deleted by digest, look up the referenced tags in the tag
store and remove all associations.
Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
Add a generic Manifest interface to represent manifests in the registry and
remove references to schema specific manifests.
Add a ManifestBuilder to construct Manifest objects. Concrete manifest builders
will exist for each manifest type and implementations will contain manifest
specific data used to build a manifest.
Remove Signatures() from Repository interface.
Signatures are relevant only to schema1 manifests. Move access to the signature
store inside the schema1 manifestStore. Add some API tests to verify
signature roundtripping.
schema1
-------
Change the way data is stored in schema1.Manifest to enable Payload() to be used
to return complete Manifest JSON from the HTTP handler without knowledge of the
schema1 protocol.
tags
----
Move tag functionality to a seperate TagService and update ManifestService
to use the new interfaces. Implement a driver based tagService to be backward
compatible with the current tag service.
Add a proxyTagService to enable the registry to get a digest for remote manifests
from a tag.
manifest store
--------------
Remove revision store and move all signing functionality into the signed manifeststore.
manifest registration
---------------------
Add a mechanism to register manifest media types and to allow different manifest
types to be Unmarshalled correctly.
client
------
Add ManifestServiceOptions to client functions to allow tags to be passed into Put and
Get for building correct registry URLs. Change functional arguments to be an interface type
to allow passing data without mutating shared state.
Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
Signed-off-by: Richard Scothern <richard.scothern@docker.com>
tarsum is not actually used by the registry. Remove support for it.
Convert numerous uses in unit tests to SHA256.
Update docs to remove mentions of tarsums (which were often inaccurate).
Remove tarsum dependency.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
The current implementation of digest.FromBytes returns an error. This
error can never be non-nil, but its presence in the function signature
means each call site needs error handling code for an error that is
always nil.
I verified that none of the hash.Hash implementations in the standard
library can return an error on Write. Nor can any of the hash.Hash
implementations vendored in distribution.
This commit changes digest.FromBytes not to return an error. If Write
returns an error, it will panic, but as discussed above, this should
never happen.
This commit also avoids using a bytes.Reader to feed data into the hash
function in FromBytes. This makes the hypothetical case that would panic
a bit more explicit, and should also be more performant.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This calls Stat before Open, which should be unnecessary because Open
can handle the case of a nonexistent blob. Removing the Stat saves a
round trip.
This is similar to the removal of stat in Open in #1226.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This fixes both the s3 driver and the oss driver to return the unmunged path
when returning errors.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
Swift returns an empty object list when trying to read a non-existing object path, treat it as a
PathNotFoundError when trying to list a non existing virtual directory.
Signed-off-by: David li <wenquan.li@hpe.com>
RADOS returns a -EIO when trying to read a non-existing OMAP, treat it as a
PathNotFoundError when trying to list a non existing virtual directory.
Signed-off-by: Vincent Giersch <vincent@giersch.fr>
Issue #1186 describes a condition where a null tags response is returned when
using the s3 driver. The issue seems to be related to a missing
PathNotFoundError in s3. This change adds a test for that to get an idea of the
lack of compliance across storage drivers. If the failures are manageable,
we'll add this test condition and fix the s3 driver.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
This change removes the sort() from the Repositories() function since
we're now guaranteed to have a lexigraphically sorted walk.
Signed-off-by: Patrick Devine <patrick.devine@docker.com>
Without this commit, three round-trips are required to fetch a blob with
a progress bar. The first is a call to Stat (HEAD request), to determine
the size. Then Open is called, which also calls Stat, and finally
performs a GET request.
Only the GET request is actually needed. The size of the blob can be
sniffed from Content-Length in the GET response.
This commit changes HTTPReadSeeker to automatically detect the size from
Content-Length instead of requiring it to be passed in. The Stat call is
removed from Open because it is no longer necessary.
HTTPReadSeeker now takes an additional errorHandler callback argument which
translates an unsuccessful HTTP response into an appropriate API-level
error. Using a callback for this makes it possible to avoid leaking the
repsonse body to Read's caller, which would make lifecycle management
problematic.
Fixes#1223
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
The Delete method lists objects under the given path and tries to delete
all of them with a bulk delete request. If the path has no objects
underneath it, the body of this request will be empty, which causes
HTTP-level issues. Specifically, Go's HTTP client senses the empty
request buffer and doesn't include a Content-Length, which causes the
Swift server to fail the request.
This commit fixes the problem by avoiding sending empty bulk delete
requests. This is the correct thing to do anyway, since there's no
reason to request deletion of zero objects.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Previously, this error message would stringify as a pointer address,
which isn't particularly helpful.
This change breaks out the elements of the challenge object such that
the error is appropriately represented.
Signed-off-by: Ted Reed <ted.reed@gmail.com>
contains equal length History and FSLayer arrays.
This is required to prevent malformed manifests being put to the registry and
failing external verification checks.
Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
Errors thrown by storage drivers don't have the name of the driver, causing user
confusion about whether the error is coming from Docker or from a storage driver.
This change adds the storage driver name to each error message.
This required changing ErrUnsupportedDriver to a type, leading to code changes
whenever ErrUnsupportedDriver is used. The tests check whether the driver name
appears in the error message.
Signed-off-by: Amit Shukla <amit.shukla@docker.com>
This extends the specification for the Bearer token response to include
information pertaining to when an issued Bearer token will expire.
This also allows the client to accept `access_token` as an alias for `token`.
Signed-off-by: Matt Moore <mattmoor@google.com>
The proxy scheduler implemented its own timer state machine. It's
simpler and more efficient to leverage the Go runtime's timer heap by
using time.AfterFunc.
This commit adds a time.Timer to each scheduler entry, and starts and
stops those timers as necessary. Then the mainloop goroutine and its
associated logic are not needed.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
To ensure that we only unmarshal the verified payload into the contained
manifest, we first copy the entire incoming buffer into Raw and then unmarshal
only the Payload portion of the incoming bytes. If the contents is later
verified, the caller can then be sure that the contents of the Manifest fields
can be trusted.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
There seems to be a need for a type that represents a way of pointing
to an image, irrespective of the implementation.
This patch defines a Reference interface and provides 3 implementations:
- TagReference: when only a tag is provided
- DigestReference: when a digest (according to the digest package) is
provided, can include optional tag as well
Validation of references are purely syntactic.
There is also a strong type for tags, analogous to digests, as well
as a strong type for Repository from which clients can access the
hostname alone, or the repository name without the hostname, or both
together via the String() method.
For Repository, the files names.go and names_test.go were moved from
the v2 package.
Signed-off-by: Tibor Vass <tibor@docker.com>
of readers joining current downloads. Concurrent requests for the same blob
will not block, but only the first instance will be comitted locally.
Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
Fixes https://github.com/docker/distribution/issues/1062
This relaxes the naming restrictions places on Docker images to permit
valid hostnames according to [RFC-2396](https://www.ietf.org/rfc/rfc2396.txt).
It deviates from the RFC in the following ways:
1) Allow underscores where we allow hyphens (hostnames don't allow
underscores, which we must for backwards compatibility).
2) Leave "top-level" name segments unrestricted (domains require an
alpha character to begin a top-level domain, e.g. "com").
3) DO NOT allow a trailing dot, as permitted by FQDNs.
Signed-off-by: Matt Moore <mattmoor@google.com>
This allows the administrator to specify an externally-reachable URL for
the registry. It takes precedence over the X-Forwarded-Proto and
X-Forwarded-Host headers, and the hostname in the request.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Associate HTTP 401s with Authentication errors rather than Authorization
errors. Changes the meaning of the UNAUTHORIZED error to be authentication
specific.
Defines DENIED error code to be associated with authorization
errors which result in HTTP 403 responses.
Add 'No Such Repository' errors to more endpoints.
Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
The "testing" package adds some flags in its init function, so utilities
that import distribution code may print a page of extra testing flags in
their help output.
This commit solves the issue by moving an import of "testing" in the
registry/storage/cache package to a new
registry/storage/cache/cachecheck package, which is only imported by
tests.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Add "readonly" under the storage/maintenance section. When this is set
to true, uploads and deletions will return 503 Service Unavailable
errors.
Document the parameter and add some unit testing.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
In the S3 storage driver there is currently an initial access permission check by listing the bucket. If this check fails, registry will panic and exit.
However, this check is broken in two ways. First of all it strips the final slash from the root directory path, meaning that any access permissions which limit access to a single directory will fail, because S3 treats the path as strict prefix match. Secondly it fails to strip any leading slash that might be present, unlike the other access places, which means that the path used is different as a leading slash is allowed and significant in a filename in S3.
Since there is also a periodic health check which correctly checks access permissions and shows the error more cleanly, the best solution seems to be to just remove this initial access check.
Signed-off-by: Nuutti Kotivuori <nuutti.kotivuori@poplatek.fi>
By adding WithVersion to the context package, we can simplify context setup in
the application. This avoids some odd bugs where instantiation order can lead
to missing instance.id or version from log messages.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
This solves a issue from #909 where instance.id was not printed in logs,
because this file was using the background context from
golang.org/x/net/context instead of
github.com/docker/distribution/context.
It's cleaner to standardize on one package, so this commit removes the
import of golang.org/x/net/context entirely. The Context interfaces
defined in both packages are the same, so other code using
golang.org/x/net/context can still pass its context to NewRegistry.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Use this command in cmd/registry/main.go.
Move debug server to the main command, and change Serve to be a
ListenAndServe function.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
As we begin our march towards multi-arch, we must prepare for the reality of
multiple manifest schemas. This is the beginning of a set of changes to
facilitate this. We are both moving this package into its target position where
it may live peacefully next to other manfiest versions.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
To bring ErrorCode into liine with Go conventions, ErrorCode.Error() now
returns the "nice" value of the error code. This ensures error message assembly
works similar to commonly used Go conventions when directly using ErrorCode as
an error.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
Also, add timeout and status code parameters to the HTTP checker, and
remove the threshold parameter for the file checker.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Update docs.
Change health_test.go tests to create their own registries and register
the checks there. The tests now call CheckStatus directly instead of
polling the HTTP handler, which returns results from the default
registry.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Add default storagedriver health check to example configuration files
with parameters matching the previous hardcoded configuration.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Add a section to the config file called "health". Within this section,
"filecheckers" and "httpcheckers" list checks to run. Each check
specifies a file or URI, a time interval for the check, and a threshold
specifying how many times the check must fail to reach an unhealthy
state.
Document the new options in docs/configuration.md.
Add unit testing for both types of checkers. Add an UnregisterAll
function in the health package to support the unit tests, and an
Unregister function for consistency with Register.
Fix a string conversion problem in the health package's HTTP checker.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Clean up calling convention for NewRegistryWithDriver to use functional
arguments.
This is a first step towards the refactor described in #215. I plan to
add additional options in the process of moving configurable items from
the App structure to the registry structure.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
A change in #763 to address review comments caused problems. Originally,
instrumentedResponseWriter implemented the CloseNotifier interface, and
would panic if it was wrapping something that did not implement that
interface. This was split into a separate instrumentedResponseWriterCN
type that implements CloseNotifier, so there's a fallback if
instrumentedResponseWriter ever needs to wrap something that does not
implement this interface.
instrumentedResponseWriter's Value method would end up upcasting either
type back to instrumentedResponseWriter, which does not implement the
interface. In effect, instrumentedResponseWriterCN was never visible to
the handler.
This fixes the problem by implementing a wrapper Value method for
instrumentedResponseWriterCN.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Change checkResponse to only expect the configured
X-Content-Type-Options header if it doesn't receive a 405 error, which
means the handler isn't registered for that method.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
The use of the pathMapper is no longer needed the way we have organized the
code base. The extra level of indirection has proved unnecessary and confusing
so we've opted to clean it up. In the future, we may require more flexibility,
but now it is simply not required.
Signed-off-by: Stephen J Day <stephen.day@docker.com>