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>
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>
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>
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>
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>
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>
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>
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 example configuration files add X-Content-Type-Options: nosniff.
Add coverage in existing registry/handlers unit tests.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
distribution errors. Fill in missing checks for mutations on a registry pull-through
cache. Add unit tests and update documentation.
Also, give v2.ErrorCodeUnsupported an HTTP status code, previously it was
defaulting to 500, now its 405 Method Not Allowed.
Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
Several error codes are generally useful but tied to the v2 specification
definitions. This change moves these error code definitions into the common
package for use by the health package, which is not tied to the v2 API.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
To ensure the ensure the web application is properly operating, we've added a
periodic health check for the storage driver. If the health check fails three
times in a row, the registry will serve 503 response status for any request
until the condition is resolved. The condition is reported in the response body
and via the /debug/health endpoint.
To ensure that all drivers will properly operate with this health check, a
function has been added to the driver testsuite.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
Instead, provide a variant of instrumentedResponseWriter that does not
implement CloseNotifier, and use that when necessary. In
copyFullPayload, log instead of panicing when we encounter something
that doesn't implement CloseNotifier.
This is more complicated than I'd like, but it's necessary because
instrumentedResponseWriter must not embed CloseNotifier unless there's
really a CloseNotifier to embed.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
with a new `proxy` section in the configuration file.
Create a new registry type which delegates storage to a proxyBlobStore
and proxyManifestStore. These stores will pull through data if not present
locally. proxyBlobStore takes care not to write duplicate data to disk.
Add a scheduler to cleanup expired content. The scheduler runs as a background
goroutine. When a blob or manifest is pulled through from the remote registry,
an entry is added to the scheduler with a TTL. When the TTL expires the
scheduler calls a pre-specified function to remove the fetched resource.
Add token authentication to the registry middleware. Get a token at startup
and preload the credential store with the username and password supplied in the
config file.
Allow resumable digest functionality to be disabled at runtime and disable
it when the registry is a pull through cache.
Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
The response code isn't actually sent to the client, because the
connection has already closed by this point. But it causes the status
code to appear as 499 in the logs instead of 0.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
When a client disconnects without completing a HTTP request, we were
attempting to process the partial request, which usually leads to a 400
error. These errors can pollute the logs and make it more difficult to
track down real bugs.
This change uses CloseNotifier to detect disconnects. In combination
with checking Content-Length, we can detect a disconnect before sending
the full payload, and avoid logging a 400 error.
This logic is only applied to PUT, POST, and PATCH endpoints, as these
are the places where disconnects during a request are most likely to
happen.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
includes the http response.
When debugging non-successful registry requests this will place
the error details and http status fields in the same log line
giving easier visibility to what error occured in the request.
Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
Log a warning if the registry generates its own secret.
Update configuration doc, and remove the default secret from the
development config file.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This passed in the #744 before merge, but apparently the test changed
since the PR was created in ways that led to a new failures.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Storage drivers can implement a method called URLFor which can return a direct
url for a given path. The functionality allows the registry to direct clients
to download content directly from the backend storage. This is commonly used
with s3 and cloudfront. Under certain conditions, such as when the registry is
not local to the backend, these redirects can hurt performance and waste
incoming bandwidth on pulls. This feature addition allows one to disable this
feature, if required.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
Conflicts:
configuration/configuration.go
registry/handlers/app.go
registry/storage/catalog_test.go
registry/storage/manifeststore_test.go
registry/storage/registry.go
Implement the delete API by implementing soft delete for layers
and blobs by removing link files and updating the blob descriptor
cache. Deletion is configurable - if it is disabled API calls
will return an unsupported error.
We invalidate the blob descriptor cache by changing the linkedBlobStore's
blobStatter to a blobDescriptorService and naming it blobAccessController.
Delete() is added throughout the relevant API to support this functionality.
Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
Because the logger was incorrectly replaced while adding hooks, log output did
not include the version and instance ids. The main issue was the the
logrus.Entry was replaced with the logger, which included no context. Replacing
the logger on the context is not necessary when configuring hooks since we are
configuring the contexts logger directly.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
This removes the erroneous http.Handler interface in favor a simple SetHeaders
method that only operattes on the response. Several unnecessary uses of pointer
types were also fixed up.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
This change removes the Catalog Service and replaces it with a more
simplistic Repositories() method for obtaining a catalog of all
repositories. The Repositories method takes a pre-allocated slice
and fills it up to the size of the slice and returns the amount
filled. The catalog is returned lexicographically and will start
being filled from the last entry passed to Repositories(). If there
are no more entries to fill, io.EOF will be returned.
Signed-off-by: Patrick Devine <patrick.devine@docker.com>
Conflicts:
registry/client/repository.go
registry/handlers/api_test.go
This change adds a basic catalog endpoint to the API, which returns a list,
or partial list, of all of the repositories contained in the registry. Calls
to this endpoint are somewhat expensive, as every call requires walking a
large part of the registry.
Instead, to maintain a list of repositories, you would first call the catalog
endpoint to get an initial list, and then use the events API to maintain
any future repositories.
Signed-off-by: Patrick Devine <patrick.devine@docker.com>