This changeset integrates context with the storage package. Debug messages have
been added to exported methods. Existing log messages will now include
contextual details through logger fields to aid in debugging. This integration
focuses on logging and may be followed up with a metric-oriented change in the
future.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
This changeset integrates contextual logging into the registry web application.
Idiomatic context use is attempted within the current webapp layout. The
functionality is centered around making lifecycle objects (application and
request context) into contexts themselves. Relevant data has been moved into
the context where appropriate. We still have some work to do to factor out the
registry.Context object and the dispatching functionality to remove some
awkward portions.
The api tests were slightly refactored to use a test environment to eliminate
common code.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
The new context package supports context-aware logging, integrating with
logrus. Several utilities are provided to associate http requests with a
context, ensuring that one can trace log messages all the way through a
context-aware call stack.
A full description of this functionality is available in doc.go.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
This dependency added a method to access the current standard logger. This is
required to properly configure the logger for context awareness. The plan is to
have all loggers descend from the standard logger.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
There don't seem to be any major changes but we'll update this while we're at
it. This dependency is pretty important for coming changes.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
A nice set of common default targets have been added to the Makefile to make
running tests and building binaries more straightforward. Running the Makefile
before committing should make build failures less common.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
This allows wrappers of LayerUpload to implement io.ReadFrom, which
prevents io.Copy on LayerUpload implementations from using repeated 32kB
Writes.
This has a huge performance implication, especially for s3/azure storage
drivers.
The auth package has been updated to use "golang.org/x/net/context" for
passing information between the application and the auth backend.
AccessControllers should now set a "auth.user" context value to a AuthUser
struct containing a single "Name" field for now with possible, optional, values
in the future.
The "silly" auth backend always sets the name to "silly", while the "token" auth
backend will set the name to match the "subject" claim of the JWT.
Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
This changeset moves common checks from driver implementations into base
package. The Base type can be embedded in a driver implementation, ensuring
that incoming arguments are checked for validity.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
To clarify the role of actor, the request data that initiates an event has been
separated. The ActorRecord is pared down to just the username. This eliminates
confusion about where event related data should be added.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
Endpoints are now created at applications startup time, using notification
configuration. The instances are then added to a Broadcaster instance, which
becomes the main event sink for the application. At request time, an event
bridge is configured to listen to repository method calls. The actor and source
of the eventBridge are created from the requeest context and application,
respectively. The result is notifications are dispatched with calls to the
context's Repository instance and are queued to each endpoint via the
broadcaster.
This commit also adds the concept of a RequestID and App.InstanceID. The
request id uniquely identifies each request and the InstanceID uniquely
identifies a run of the registry. These identifiers can be used in the future
to correlate log messages with generated events to support rich debugging.
The fields of the app were slightly reorganized for clarity and a few horrid
util functions have been removed.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
If configured, a debug http server will be started to serve default registered
endpoints, such as pprof and expvar. The endpoint should be secured carefully
and not available to external traffic. It is disabled by default but the
development config has been modified to make it available on localhost.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
After implementing notifications end to end, it was found that decorating
repositories was more straightforward that previously thought. It's unfortunate
to can this package, but it led to the techniques employed in
storage/notifications/listeners.go. The ultimate result turned out much better.
This changeset implements webhook notification endpoints for dispatching
registry events. Repository instances can be decorated by a listener that
converts calls into context-aware events, using a bridge. Events generated in
the bridge are written to a sink. Implementations of sink include a broadcast
and endpoint sink which can be used to configure event dispatch. Endpoints
represent a webhook notification target, with queueing and retries built in.
They can be added to a Broadcaster, which is a simple sink that writes a block
of events to several sinks, to provide a complete dispatch mechanism.
The main caveat to the current approach is that all unsent notifications are
inmemory. Best effort is made to ensure that notifications are not dropped, to
the point where queues may back up on faulty endpoints. If the endpoint is
fixed, the events will be retried and all messages will go through.
Internally, this functionality is all made up of Sink objects. The queuing
functionality is implemented with an eventQueue sink and retries are
implemented with retryingSink. Replacing the inmemory queuing with something
persistent should be as simple as replacing broadcaster with a remote queue and
that sets up the sinks to be local workers listening to that remote queue.
Metrics are kept for each endpoint and exported via expvar. This may not be a
permanent appraoch but should provide enough information for troubleshooting
notification problems.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
To provide easier access to digestible content, the paylaod has been made
accessible on the signed manifest type. This hides the specifics of the
interaction with libtrust with the caveat that signatures may be parsed twice.
We'll have to have a future look at the interface for manifest as we may be
making problematic architectural decisions. We'll visit this after the initial
release.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit defines the message format used to notify external parties of
activity within a registry instance. The event includes information about which
action was taken on which registry object, including what user created the
action and which instance generated the event.
Message instances can be sent throughout an application or transmitted
externally. An envelope format along with a custom media type is defined along
with tests to detect changes to the wire format.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
To address the possibility of confusing registry name components with
repository paths, path components that abut user provided repository names are
escaped with a prefixed underscore. This works because repository name
components are no allowed to start with underscores. The requirements on
backend driver path names have been relaxed greatly to support this use case.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
This changeset provides simple tls support for a registry instance. Simply
providing a cert and key file are enough to get a tls registry running. If the
certs are trusted by the client, tls can be used throughout the push and pull
process.
If more complex TLS options are required, it is recommend that a proxy be used.
Contributions will be accepted to add more features, if necessary.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
* Result of regexp.FindStringSubmatch must be checked to be not nil.
Otherwise it leads to `index out of range`.
* Range header regexp is compiled only once to speedup (5x) the header parsing.
Signed-off-by: Anton Tiurin <noxiouz@yandex.ru>
Several API tests were added to ensure correct acceptance of zero-size and
empty tar files. This led to several changes in the storage backend around the
guarantees of remote file reading, which backs the layer and layer upload type.
In support of these changes, zero-length and empty checks have been added to
the digest package. These provide a sanity check against upstream tarsum
changes. The fileReader has been modified to be more robust when reading and
seeking on zero-length or non-existent files. The file no longer needs to exist
for the reader to be created. Seeks can now move beyond the end of the file,
causing reads to issue an io.EOF. This eliminates errors during certain race
conditions for reading files which should be detected by stat calls. As a part
of this, a few error types were factored out and the read buffer size was
increased to something more reasonable.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
Handles an issue where mux.Route does not set the desired scheme
when building a url and always uses `http`.
Now uses X-Forwarded-Proto when creating a URLBuilder from a request.
Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
This changeset addresses intermittent internal server errors encountered during
pushes. The root cause has been isolated to layers that result in identical,
empty filesystems but may have some path declarations (imaginge "./"),
resulting in different tarsums. The main error message reported during these
upload problems was a 500 error, which was not correct. Further investigation
showed the errors to be rooted in digest verification when finishing uploads.
Inspection of the surrounding code also identified a few issues. PutLayerChunk
was slightly refactered into PutLayerUploadComplete. Helper methods were
avoided to make handler less confusing. This simplification leveraged an
earlier change in the spec that moved non-complete chunk uploads to the PATCH
method. Simple logging was also added in the unknown error case that should
help to avoid mysterious 500 errors in the future.
At the same time, the glaring omission of a proper layer upload cancel method
was rectified. This has been added in this change so it is not missed in the
future.
In the future, we may want to refactor the handler code to be more
straightforward, hopefully letting us avoid these problems in the future.
Added test cases that reproduce these errors and drove these changes include
the following:
1. Push a layer with an empty body results in invalid blob upload.
2. Push a layer with a different tarsum (in this case, empty tar)
3. Deleting a layer upload works.
4. Getting status on a deleted layer upload returns 404.
Common functionality was grouped into shared functions to remove repitition.
The API tests will still require future love.
Signed-off-by: Stephen J Day <stephen.day@docker.com>