mirror of
https://github.com/linuxkit/linuxkit.git
synced 2026-04-04 16:46:49 +00:00
Update dependencies to use sirupsen not Sirupsen
That entailed a few other fixes, eg small Notary API changes. Signed-off-by: Justin Cormack <justin.cormack@docker.com>
This commit is contained in:
3
vendor/github.com/docker/distribution/README.md
generated
vendored
3
vendor/github.com/docker/distribution/README.md
generated
vendored
@@ -76,8 +76,7 @@ may be the better choice.
|
||||
For those who have previously deployed their own registry based on the Registry
|
||||
1.0 implementation and wish to deploy a Registry 2.0 while retaining images,
|
||||
data migration is required. A tool to assist with migration efforts has been
|
||||
created. For more information see [docker/migrator]
|
||||
(https://github.com/docker/migrator).
|
||||
created. For more information see [docker/migrator](https://github.com/docker/migrator).
|
||||
|
||||
## Contribute
|
||||
|
||||
|
||||
4
vendor/github.com/docker/distribution/blobs.go
generated
vendored
4
vendor/github.com/docker/distribution/blobs.go
generated
vendored
@@ -1,13 +1,13 @@
|
||||
package distribution
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/context"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
@@ -152,7 +152,7 @@ type BlobProvider interface {
|
||||
|
||||
// BlobServer can serve blobs via http.
|
||||
type BlobServer interface {
|
||||
// ServeBlob attempts to serve the blob, identifed by dgst, via http. The
|
||||
// ServeBlob attempts to serve the blob, identified by dgst, via http. The
|
||||
// service may decide to redirect the client elsewhere or serve the data
|
||||
// directly.
|
||||
//
|
||||
|
||||
85
vendor/github.com/docker/distribution/context/context.go
generated
vendored
85
vendor/github.com/docker/distribution/context/context.go
generated
vendored
@@ -1,85 +0,0 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/docker/distribution/uuid"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// Context is a copy of Context from the golang.org/x/net/context package.
|
||||
type Context interface {
|
||||
context.Context
|
||||
}
|
||||
|
||||
// instanceContext is a context that provides only an instance id. It is
|
||||
// provided as the main background context.
|
||||
type instanceContext struct {
|
||||
Context
|
||||
id string // id of context, logged as "instance.id"
|
||||
once sync.Once // once protect generation of the id
|
||||
}
|
||||
|
||||
func (ic *instanceContext) Value(key interface{}) interface{} {
|
||||
if key == "instance.id" {
|
||||
ic.once.Do(func() {
|
||||
// We want to lazy initialize the UUID such that we don't
|
||||
// call a random generator from the package initialization
|
||||
// code. For various reasons random could not be available
|
||||
// https://github.com/docker/distribution/issues/782
|
||||
ic.id = uuid.Generate().String()
|
||||
})
|
||||
return ic.id
|
||||
}
|
||||
|
||||
return ic.Context.Value(key)
|
||||
}
|
||||
|
||||
var background = &instanceContext{
|
||||
Context: context.Background(),
|
||||
}
|
||||
|
||||
// Background returns a non-nil, empty Context. The background context
|
||||
// provides a single key, "instance.id" that is globally unique to the
|
||||
// process.
|
||||
func Background() Context {
|
||||
return background
|
||||
}
|
||||
|
||||
// WithValue returns a copy of parent in which the value associated with key is
|
||||
// val. Use context Values only for request-scoped data that transits processes
|
||||
// and APIs, not for passing optional parameters to functions.
|
||||
func WithValue(parent Context, key, val interface{}) Context {
|
||||
return context.WithValue(parent, key, val)
|
||||
}
|
||||
|
||||
// stringMapContext is a simple context implementation that checks a map for a
|
||||
// key, falling back to a parent if not present.
|
||||
type stringMapContext struct {
|
||||
context.Context
|
||||
m map[string]interface{}
|
||||
}
|
||||
|
||||
// WithValues returns a context that proxies lookups through a map. Only
|
||||
// supports string keys.
|
||||
func WithValues(ctx context.Context, m map[string]interface{}) context.Context {
|
||||
mo := make(map[string]interface{}, len(m)) // make our own copy.
|
||||
for k, v := range m {
|
||||
mo[k] = v
|
||||
}
|
||||
|
||||
return stringMapContext{
|
||||
Context: ctx,
|
||||
m: mo,
|
||||
}
|
||||
}
|
||||
|
||||
func (smc stringMapContext) Value(key interface{}) interface{} {
|
||||
if ks, ok := key.(string); ok {
|
||||
if v, ok := smc.m[ks]; ok {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
return smc.Context.Value(key)
|
||||
}
|
||||
89
vendor/github.com/docker/distribution/context/doc.go
generated
vendored
89
vendor/github.com/docker/distribution/context/doc.go
generated
vendored
@@ -1,89 +0,0 @@
|
||||
// Package context provides several utilities for working with
|
||||
// golang.org/x/net/context in http requests. Primarily, the focus is on
|
||||
// logging relevant request information but this package is not limited to
|
||||
// that purpose.
|
||||
//
|
||||
// The easiest way to get started is to get the background context:
|
||||
//
|
||||
// ctx := context.Background()
|
||||
//
|
||||
// The returned context should be passed around your application and be the
|
||||
// root of all other context instances. If the application has a version, this
|
||||
// line should be called before anything else:
|
||||
//
|
||||
// ctx := context.WithVersion(context.Background(), version)
|
||||
//
|
||||
// The above will store the version in the context and will be available to
|
||||
// the logger.
|
||||
//
|
||||
// Logging
|
||||
//
|
||||
// The most useful aspect of this package is GetLogger. This function takes
|
||||
// any context.Context interface and returns the current logger from the
|
||||
// context. Canonical usage looks like this:
|
||||
//
|
||||
// GetLogger(ctx).Infof("something interesting happened")
|
||||
//
|
||||
// GetLogger also takes optional key arguments. The keys will be looked up in
|
||||
// the context and reported with the logger. The following example would
|
||||
// return a logger that prints the version with each log message:
|
||||
//
|
||||
// ctx := context.Context(context.Background(), "version", version)
|
||||
// GetLogger(ctx, "version").Infof("this log message has a version field")
|
||||
//
|
||||
// The above would print out a log message like this:
|
||||
//
|
||||
// INFO[0000] this log message has a version field version=v2.0.0-alpha.2.m
|
||||
//
|
||||
// When used with WithLogger, we gain the ability to decorate the context with
|
||||
// loggers that have information from disparate parts of the call stack.
|
||||
// Following from the version example, we can build a new context with the
|
||||
// configured logger such that we always print the version field:
|
||||
//
|
||||
// ctx = WithLogger(ctx, GetLogger(ctx, "version"))
|
||||
//
|
||||
// Since the logger has been pushed to the context, we can now get the version
|
||||
// field for free with our log messages. Future calls to GetLogger on the new
|
||||
// context will have the version field:
|
||||
//
|
||||
// GetLogger(ctx).Infof("this log message has a version field")
|
||||
//
|
||||
// This becomes more powerful when we start stacking loggers. Let's say we
|
||||
// have the version logger from above but also want a request id. Using the
|
||||
// context above, in our request scoped function, we place another logger in
|
||||
// the context:
|
||||
//
|
||||
// ctx = context.WithValue(ctx, "http.request.id", "unique id") // called when building request context
|
||||
// ctx = WithLogger(ctx, GetLogger(ctx, "http.request.id"))
|
||||
//
|
||||
// When GetLogger is called on the new context, "http.request.id" will be
|
||||
// included as a logger field, along with the original "version" field:
|
||||
//
|
||||
// INFO[0000] this log message has a version field http.request.id=unique id version=v2.0.0-alpha.2.m
|
||||
//
|
||||
// Note that this only affects the new context, the previous context, with the
|
||||
// version field, can be used independently. Put another way, the new logger,
|
||||
// added to the request context, is unique to that context and can have
|
||||
// request scoped varaibles.
|
||||
//
|
||||
// HTTP Requests
|
||||
//
|
||||
// This package also contains several methods for working with http requests.
|
||||
// The concepts are very similar to those described above. We simply place the
|
||||
// request in the context using WithRequest. This makes the request variables
|
||||
// available. GetRequestLogger can then be called to get request specific
|
||||
// variables in a log line:
|
||||
//
|
||||
// ctx = WithRequest(ctx, req)
|
||||
// GetRequestLogger(ctx).Infof("request variables")
|
||||
//
|
||||
// Like above, if we want to include the request data in all log messages in
|
||||
// the context, we push the logger to a new context and use that one:
|
||||
//
|
||||
// ctx = WithLogger(ctx, GetRequestLogger(ctx))
|
||||
//
|
||||
// The concept is fairly powerful and ensures that calls throughout the stack
|
||||
// can be traced in log messages. Using the fields like "http.request.id", one
|
||||
// can analyze call flow for a particular request with a simple grep of the
|
||||
// logs.
|
||||
package context
|
||||
366
vendor/github.com/docker/distribution/context/http.go
generated
vendored
366
vendor/github.com/docker/distribution/context/http.go
generated
vendored
@@ -1,366 +0,0 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/docker/distribution/uuid"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// Common errors used with this package.
|
||||
var (
|
||||
ErrNoRequestContext = errors.New("no http request in context")
|
||||
ErrNoResponseWriterContext = errors.New("no http response in context")
|
||||
)
|
||||
|
||||
func parseIP(ipStr string) net.IP {
|
||||
ip := net.ParseIP(ipStr)
|
||||
if ip == nil {
|
||||
log.Warnf("invalid remote IP address: %q", ipStr)
|
||||
}
|
||||
return ip
|
||||
}
|
||||
|
||||
// RemoteAddr extracts the remote address of the request, taking into
|
||||
// account proxy headers.
|
||||
func RemoteAddr(r *http.Request) string {
|
||||
if prior := r.Header.Get("X-Forwarded-For"); prior != "" {
|
||||
proxies := strings.Split(prior, ",")
|
||||
if len(proxies) > 0 {
|
||||
remoteAddr := strings.Trim(proxies[0], " ")
|
||||
if parseIP(remoteAddr) != nil {
|
||||
return remoteAddr
|
||||
}
|
||||
}
|
||||
}
|
||||
// X-Real-Ip is less supported, but worth checking in the
|
||||
// absence of X-Forwarded-For
|
||||
if realIP := r.Header.Get("X-Real-Ip"); realIP != "" {
|
||||
if parseIP(realIP) != nil {
|
||||
return realIP
|
||||
}
|
||||
}
|
||||
|
||||
return r.RemoteAddr
|
||||
}
|
||||
|
||||
// RemoteIP extracts the remote IP of the request, taking into
|
||||
// account proxy headers.
|
||||
func RemoteIP(r *http.Request) string {
|
||||
addr := RemoteAddr(r)
|
||||
|
||||
// Try parsing it as "IP:port"
|
||||
if ip, _, err := net.SplitHostPort(addr); err == nil {
|
||||
return ip
|
||||
}
|
||||
|
||||
return addr
|
||||
}
|
||||
|
||||
// WithRequest places the request on the context. The context of the request
|
||||
// is assigned a unique id, available at "http.request.id". The request itself
|
||||
// is available at "http.request". Other common attributes are available under
|
||||
// the prefix "http.request.". If a request is already present on the context,
|
||||
// this method will panic.
|
||||
func WithRequest(ctx Context, r *http.Request) Context {
|
||||
if ctx.Value("http.request") != nil {
|
||||
// NOTE(stevvooe): This needs to be considered a programming error. It
|
||||
// is unlikely that we'd want to have more than one request in
|
||||
// context.
|
||||
panic("only one request per context")
|
||||
}
|
||||
|
||||
return &httpRequestContext{
|
||||
Context: ctx,
|
||||
startedAt: time.Now(),
|
||||
id: uuid.Generate().String(),
|
||||
r: r,
|
||||
}
|
||||
}
|
||||
|
||||
// GetRequest returns the http request in the given context. Returns
|
||||
// ErrNoRequestContext if the context does not have an http request associated
|
||||
// with it.
|
||||
func GetRequest(ctx Context) (*http.Request, error) {
|
||||
if r, ok := ctx.Value("http.request").(*http.Request); r != nil && ok {
|
||||
return r, nil
|
||||
}
|
||||
return nil, ErrNoRequestContext
|
||||
}
|
||||
|
||||
// GetRequestID attempts to resolve the current request id, if possible. An
|
||||
// error is return if it is not available on the context.
|
||||
func GetRequestID(ctx Context) string {
|
||||
return GetStringValue(ctx, "http.request.id")
|
||||
}
|
||||
|
||||
// WithResponseWriter returns a new context and response writer that makes
|
||||
// interesting response statistics available within the context.
|
||||
func WithResponseWriter(ctx Context, w http.ResponseWriter) (Context, http.ResponseWriter) {
|
||||
if closeNotifier, ok := w.(http.CloseNotifier); ok {
|
||||
irwCN := &instrumentedResponseWriterCN{
|
||||
instrumentedResponseWriter: instrumentedResponseWriter{
|
||||
ResponseWriter: w,
|
||||
Context: ctx,
|
||||
},
|
||||
CloseNotifier: closeNotifier,
|
||||
}
|
||||
|
||||
return irwCN, irwCN
|
||||
}
|
||||
|
||||
irw := instrumentedResponseWriter{
|
||||
ResponseWriter: w,
|
||||
Context: ctx,
|
||||
}
|
||||
return &irw, &irw
|
||||
}
|
||||
|
||||
// GetResponseWriter returns the http.ResponseWriter from the provided
|
||||
// context. If not present, ErrNoResponseWriterContext is returned. The
|
||||
// returned instance provides instrumentation in the context.
|
||||
func GetResponseWriter(ctx Context) (http.ResponseWriter, error) {
|
||||
v := ctx.Value("http.response")
|
||||
|
||||
rw, ok := v.(http.ResponseWriter)
|
||||
if !ok || rw == nil {
|
||||
return nil, ErrNoResponseWriterContext
|
||||
}
|
||||
|
||||
return rw, nil
|
||||
}
|
||||
|
||||
// getVarsFromRequest let's us change request vars implementation for testing
|
||||
// and maybe future changes.
|
||||
var getVarsFromRequest = mux.Vars
|
||||
|
||||
// WithVars extracts gorilla/mux vars and makes them available on the returned
|
||||
// context. Variables are available at keys with the prefix "vars.". For
|
||||
// example, if looking for the variable "name", it can be accessed as
|
||||
// "vars.name". Implementations that are accessing values need not know that
|
||||
// the underlying context is implemented with gorilla/mux vars.
|
||||
func WithVars(ctx Context, r *http.Request) Context {
|
||||
return &muxVarsContext{
|
||||
Context: ctx,
|
||||
vars: getVarsFromRequest(r),
|
||||
}
|
||||
}
|
||||
|
||||
// GetRequestLogger returns a logger that contains fields from the request in
|
||||
// the current context. If the request is not available in the context, no
|
||||
// fields will display. Request loggers can safely be pushed onto the context.
|
||||
func GetRequestLogger(ctx Context) Logger {
|
||||
return GetLogger(ctx,
|
||||
"http.request.id",
|
||||
"http.request.method",
|
||||
"http.request.host",
|
||||
"http.request.uri",
|
||||
"http.request.referer",
|
||||
"http.request.useragent",
|
||||
"http.request.remoteaddr",
|
||||
"http.request.contenttype")
|
||||
}
|
||||
|
||||
// GetResponseLogger reads the current response stats and builds a logger.
|
||||
// Because the values are read at call time, pushing a logger returned from
|
||||
// this function on the context will lead to missing or invalid data. Only
|
||||
// call this at the end of a request, after the response has been written.
|
||||
func GetResponseLogger(ctx Context) Logger {
|
||||
l := getLogrusLogger(ctx,
|
||||
"http.response.written",
|
||||
"http.response.status",
|
||||
"http.response.contenttype")
|
||||
|
||||
duration := Since(ctx, "http.request.startedat")
|
||||
|
||||
if duration > 0 {
|
||||
l = l.WithField("http.response.duration", duration.String())
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// httpRequestContext makes information about a request available to context.
|
||||
type httpRequestContext struct {
|
||||
Context
|
||||
|
||||
startedAt time.Time
|
||||
id string
|
||||
r *http.Request
|
||||
}
|
||||
|
||||
// Value returns a keyed element of the request for use in the context. To get
|
||||
// the request itself, query "request". For other components, access them as
|
||||
// "request.<component>". For example, r.RequestURI
|
||||
func (ctx *httpRequestContext) Value(key interface{}) interface{} {
|
||||
if keyStr, ok := key.(string); ok {
|
||||
if keyStr == "http.request" {
|
||||
return ctx.r
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(keyStr, "http.request.") {
|
||||
goto fallback
|
||||
}
|
||||
|
||||
parts := strings.Split(keyStr, ".")
|
||||
|
||||
if len(parts) != 3 {
|
||||
goto fallback
|
||||
}
|
||||
|
||||
switch parts[2] {
|
||||
case "uri":
|
||||
return ctx.r.RequestURI
|
||||
case "remoteaddr":
|
||||
return RemoteAddr(ctx.r)
|
||||
case "method":
|
||||
return ctx.r.Method
|
||||
case "host":
|
||||
return ctx.r.Host
|
||||
case "referer":
|
||||
referer := ctx.r.Referer()
|
||||
if referer != "" {
|
||||
return referer
|
||||
}
|
||||
case "useragent":
|
||||
return ctx.r.UserAgent()
|
||||
case "id":
|
||||
return ctx.id
|
||||
case "startedat":
|
||||
return ctx.startedAt
|
||||
case "contenttype":
|
||||
ct := ctx.r.Header.Get("Content-Type")
|
||||
if ct != "" {
|
||||
return ct
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fallback:
|
||||
return ctx.Context.Value(key)
|
||||
}
|
||||
|
||||
type muxVarsContext struct {
|
||||
Context
|
||||
vars map[string]string
|
||||
}
|
||||
|
||||
func (ctx *muxVarsContext) Value(key interface{}) interface{} {
|
||||
if keyStr, ok := key.(string); ok {
|
||||
if keyStr == "vars" {
|
||||
return ctx.vars
|
||||
}
|
||||
|
||||
if strings.HasPrefix(keyStr, "vars.") {
|
||||
keyStr = strings.TrimPrefix(keyStr, "vars.")
|
||||
}
|
||||
|
||||
if v, ok := ctx.vars[keyStr]; ok {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
return ctx.Context.Value(key)
|
||||
}
|
||||
|
||||
// instrumentedResponseWriterCN provides response writer information in a
|
||||
// context. It implements http.CloseNotifier so that users can detect
|
||||
// early disconnects.
|
||||
type instrumentedResponseWriterCN struct {
|
||||
instrumentedResponseWriter
|
||||
http.CloseNotifier
|
||||
}
|
||||
|
||||
// instrumentedResponseWriter provides response writer information in a
|
||||
// context. This variant is only used in the case where CloseNotifier is not
|
||||
// implemented by the parent ResponseWriter.
|
||||
type instrumentedResponseWriter struct {
|
||||
http.ResponseWriter
|
||||
Context
|
||||
|
||||
mu sync.Mutex
|
||||
status int
|
||||
written int64
|
||||
}
|
||||
|
||||
func (irw *instrumentedResponseWriter) Write(p []byte) (n int, err error) {
|
||||
n, err = irw.ResponseWriter.Write(p)
|
||||
|
||||
irw.mu.Lock()
|
||||
irw.written += int64(n)
|
||||
|
||||
// Guess the likely status if not set.
|
||||
if irw.status == 0 {
|
||||
irw.status = http.StatusOK
|
||||
}
|
||||
|
||||
irw.mu.Unlock()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (irw *instrumentedResponseWriter) WriteHeader(status int) {
|
||||
irw.ResponseWriter.WriteHeader(status)
|
||||
|
||||
irw.mu.Lock()
|
||||
irw.status = status
|
||||
irw.mu.Unlock()
|
||||
}
|
||||
|
||||
func (irw *instrumentedResponseWriter) Flush() {
|
||||
if flusher, ok := irw.ResponseWriter.(http.Flusher); ok {
|
||||
flusher.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
func (irw *instrumentedResponseWriter) Value(key interface{}) interface{} {
|
||||
if keyStr, ok := key.(string); ok {
|
||||
if keyStr == "http.response" {
|
||||
return irw
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(keyStr, "http.response.") {
|
||||
goto fallback
|
||||
}
|
||||
|
||||
parts := strings.Split(keyStr, ".")
|
||||
|
||||
if len(parts) != 3 {
|
||||
goto fallback
|
||||
}
|
||||
|
||||
irw.mu.Lock()
|
||||
defer irw.mu.Unlock()
|
||||
|
||||
switch parts[2] {
|
||||
case "written":
|
||||
return irw.written
|
||||
case "status":
|
||||
return irw.status
|
||||
case "contenttype":
|
||||
contentType := irw.Header().Get("Content-Type")
|
||||
if contentType != "" {
|
||||
return contentType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fallback:
|
||||
return irw.Context.Value(key)
|
||||
}
|
||||
|
||||
func (irw *instrumentedResponseWriterCN) Value(key interface{}) interface{} {
|
||||
if keyStr, ok := key.(string); ok {
|
||||
if keyStr == "http.response" {
|
||||
return irw
|
||||
}
|
||||
}
|
||||
|
||||
return irw.instrumentedResponseWriter.Value(key)
|
||||
}
|
||||
116
vendor/github.com/docker/distribution/context/logger.go
generated
vendored
116
vendor/github.com/docker/distribution/context/logger.go
generated
vendored
@@ -1,116 +0,0 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Logger provides a leveled-logging interface.
|
||||
type Logger interface {
|
||||
// standard logger methods
|
||||
Print(args ...interface{})
|
||||
Printf(format string, args ...interface{})
|
||||
Println(args ...interface{})
|
||||
|
||||
Fatal(args ...interface{})
|
||||
Fatalf(format string, args ...interface{})
|
||||
Fatalln(args ...interface{})
|
||||
|
||||
Panic(args ...interface{})
|
||||
Panicf(format string, args ...interface{})
|
||||
Panicln(args ...interface{})
|
||||
|
||||
// Leveled methods, from logrus
|
||||
Debug(args ...interface{})
|
||||
Debugf(format string, args ...interface{})
|
||||
Debugln(args ...interface{})
|
||||
|
||||
Error(args ...interface{})
|
||||
Errorf(format string, args ...interface{})
|
||||
Errorln(args ...interface{})
|
||||
|
||||
Info(args ...interface{})
|
||||
Infof(format string, args ...interface{})
|
||||
Infoln(args ...interface{})
|
||||
|
||||
Warn(args ...interface{})
|
||||
Warnf(format string, args ...interface{})
|
||||
Warnln(args ...interface{})
|
||||
}
|
||||
|
||||
// WithLogger creates a new context with provided logger.
|
||||
func WithLogger(ctx Context, logger Logger) Context {
|
||||
return WithValue(ctx, "logger", logger)
|
||||
}
|
||||
|
||||
// GetLoggerWithField returns a logger instance with the specified field key
|
||||
// and value without affecting the context. Extra specified keys will be
|
||||
// resolved from the context.
|
||||
func GetLoggerWithField(ctx Context, key, value interface{}, keys ...interface{}) Logger {
|
||||
return getLogrusLogger(ctx, keys...).WithField(fmt.Sprint(key), value)
|
||||
}
|
||||
|
||||
// GetLoggerWithFields returns a logger instance with the specified fields
|
||||
// without affecting the context. Extra specified keys will be resolved from
|
||||
// the context.
|
||||
func GetLoggerWithFields(ctx Context, fields map[interface{}]interface{}, keys ...interface{}) Logger {
|
||||
// must convert from interface{} -> interface{} to string -> interface{} for logrus.
|
||||
lfields := make(logrus.Fields, len(fields))
|
||||
for key, value := range fields {
|
||||
lfields[fmt.Sprint(key)] = value
|
||||
}
|
||||
|
||||
return getLogrusLogger(ctx, keys...).WithFields(lfields)
|
||||
}
|
||||
|
||||
// GetLogger returns the logger from the current context, if present. If one
|
||||
// or more keys are provided, they will be resolved on the context and
|
||||
// included in the logger. While context.Value takes an interface, any key
|
||||
// argument passed to GetLogger will be passed to fmt.Sprint when expanded as
|
||||
// a logging key field. If context keys are integer constants, for example,
|
||||
// its recommended that a String method is implemented.
|
||||
func GetLogger(ctx Context, keys ...interface{}) Logger {
|
||||
return getLogrusLogger(ctx, keys...)
|
||||
}
|
||||
|
||||
// GetLogrusLogger returns the logrus logger for the context. If one more keys
|
||||
// are provided, they will be resolved on the context and included in the
|
||||
// logger. Only use this function if specific logrus functionality is
|
||||
// required.
|
||||
func getLogrusLogger(ctx Context, keys ...interface{}) *logrus.Entry {
|
||||
var logger *logrus.Entry
|
||||
|
||||
// Get a logger, if it is present.
|
||||
loggerInterface := ctx.Value("logger")
|
||||
if loggerInterface != nil {
|
||||
if lgr, ok := loggerInterface.(*logrus.Entry); ok {
|
||||
logger = lgr
|
||||
}
|
||||
}
|
||||
|
||||
if logger == nil {
|
||||
fields := logrus.Fields{}
|
||||
|
||||
// Fill in the instance id, if we have it.
|
||||
instanceID := ctx.Value("instance.id")
|
||||
if instanceID != nil {
|
||||
fields["instance.id"] = instanceID
|
||||
}
|
||||
|
||||
fields["go.version"] = runtime.Version()
|
||||
// If no logger is found, just return the standard logger.
|
||||
logger = logrus.StandardLogger().WithFields(fields)
|
||||
}
|
||||
|
||||
fields := logrus.Fields{}
|
||||
for _, key := range keys {
|
||||
v := ctx.Value(key)
|
||||
if v != nil {
|
||||
fields[fmt.Sprint(key)] = v
|
||||
}
|
||||
}
|
||||
|
||||
return logger.WithFields(fields)
|
||||
}
|
||||
104
vendor/github.com/docker/distribution/context/trace.go
generated
vendored
104
vendor/github.com/docker/distribution/context/trace.go
generated
vendored
@@ -1,104 +0,0 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/uuid"
|
||||
)
|
||||
|
||||
// WithTrace allocates a traced timing span in a new context. This allows a
|
||||
// caller to track the time between calling WithTrace and the returned done
|
||||
// function. When the done function is called, a log message is emitted with a
|
||||
// "trace.duration" field, corresponding to the elapsed time and a
|
||||
// "trace.func" field, corresponding to the function that called WithTrace.
|
||||
//
|
||||
// The logging keys "trace.id" and "trace.parent.id" are provided to implement
|
||||
// dapper-like tracing. This function should be complemented with a WithSpan
|
||||
// method that could be used for tracing distributed RPC calls.
|
||||
//
|
||||
// The main benefit of this function is to post-process log messages or
|
||||
// intercept them in a hook to provide timing data. Trace ids and parent ids
|
||||
// can also be linked to provide call tracing, if so required.
|
||||
//
|
||||
// Here is an example of the usage:
|
||||
//
|
||||
// func timedOperation(ctx Context) {
|
||||
// ctx, done := WithTrace(ctx)
|
||||
// defer done("this will be the log message")
|
||||
// // ... function body ...
|
||||
// }
|
||||
//
|
||||
// If the function ran for roughly 1s, such a usage would emit a log message
|
||||
// as follows:
|
||||
//
|
||||
// INFO[0001] this will be the log message trace.duration=1.004575763s trace.func=github.com/docker/distribution/context.traceOperation trace.id=<id> ...
|
||||
//
|
||||
// Notice that the function name is automatically resolved, along with the
|
||||
// package and a trace id is emitted that can be linked with parent ids.
|
||||
func WithTrace(ctx Context) (Context, func(format string, a ...interface{})) {
|
||||
if ctx == nil {
|
||||
ctx = Background()
|
||||
}
|
||||
|
||||
pc, file, line, _ := runtime.Caller(1)
|
||||
f := runtime.FuncForPC(pc)
|
||||
ctx = &traced{
|
||||
Context: ctx,
|
||||
id: uuid.Generate().String(),
|
||||
start: time.Now(),
|
||||
parent: GetStringValue(ctx, "trace.id"),
|
||||
fnname: f.Name(),
|
||||
file: file,
|
||||
line: line,
|
||||
}
|
||||
|
||||
return ctx, func(format string, a ...interface{}) {
|
||||
GetLogger(ctx,
|
||||
"trace.duration",
|
||||
"trace.id",
|
||||
"trace.parent.id",
|
||||
"trace.func",
|
||||
"trace.file",
|
||||
"trace.line").
|
||||
Debugf(format, a...)
|
||||
}
|
||||
}
|
||||
|
||||
// traced represents a context that is traced for function call timing. It
|
||||
// also provides fast lookup for the various attributes that are available on
|
||||
// the trace.
|
||||
type traced struct {
|
||||
Context
|
||||
id string
|
||||
parent string
|
||||
start time.Time
|
||||
fnname string
|
||||
file string
|
||||
line int
|
||||
}
|
||||
|
||||
func (ts *traced) Value(key interface{}) interface{} {
|
||||
switch key {
|
||||
case "trace.start":
|
||||
return ts.start
|
||||
case "trace.duration":
|
||||
return time.Since(ts.start)
|
||||
case "trace.id":
|
||||
return ts.id
|
||||
case "trace.parent.id":
|
||||
if ts.parent == "" {
|
||||
return nil // must return nil to signal no parent.
|
||||
}
|
||||
|
||||
return ts.parent
|
||||
case "trace.func":
|
||||
return ts.fnname
|
||||
case "trace.file":
|
||||
return ts.file
|
||||
case "trace.line":
|
||||
return ts.line
|
||||
}
|
||||
|
||||
return ts.Context.Value(key)
|
||||
}
|
||||
24
vendor/github.com/docker/distribution/context/util.go
generated
vendored
24
vendor/github.com/docker/distribution/context/util.go
generated
vendored
@@ -1,24 +0,0 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Since looks up key, which should be a time.Time, and returns the duration
|
||||
// since that time. If the key is not found, the value returned will be zero.
|
||||
// This is helpful when inferring metrics related to context execution times.
|
||||
func Since(ctx Context, key interface{}) time.Duration {
|
||||
if startedAt, ok := ctx.Value(key).(time.Time); ok {
|
||||
return time.Since(startedAt)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// GetStringValue returns a string value from the context. The empty string
|
||||
// will be returned if not found.
|
||||
func GetStringValue(ctx Context, key interface{}) (value string) {
|
||||
if valuev, ok := ctx.Value(key).(string); ok {
|
||||
value = valuev
|
||||
}
|
||||
return value
|
||||
}
|
||||
16
vendor/github.com/docker/distribution/context/version.go
generated
vendored
16
vendor/github.com/docker/distribution/context/version.go
generated
vendored
@@ -1,16 +0,0 @@
|
||||
package context
|
||||
|
||||
// WithVersion stores the application version in the context. The new context
|
||||
// gets a logger to ensure log messages are marked with the application
|
||||
// version.
|
||||
func WithVersion(ctx Context, version string) Context {
|
||||
ctx = WithValue(ctx, "version", version)
|
||||
// push a new logger onto the stack
|
||||
return WithLogger(ctx, GetLogger(ctx, "version"))
|
||||
}
|
||||
|
||||
// GetVersion returns the application version from the context. An empty
|
||||
// string may returned if the version was not set on the context.
|
||||
func GetVersion(ctx Context) string {
|
||||
return GetStringValue(ctx, "version")
|
||||
}
|
||||
2
vendor/github.com/docker/distribution/errors.go
generated
vendored
2
vendor/github.com/docker/distribution/errors.go
generated
vendored
@@ -77,7 +77,7 @@ func (err ErrManifestUnknownRevision) Error() string {
|
||||
type ErrManifestUnverified struct{}
|
||||
|
||||
func (ErrManifestUnverified) Error() string {
|
||||
return fmt.Sprintf("unverified manifest")
|
||||
return "unverified manifest"
|
||||
}
|
||||
|
||||
// ErrManifestVerification provides a type to collect errors encountered
|
||||
|
||||
2
vendor/github.com/docker/distribution/manifests.go
generated
vendored
2
vendor/github.com/docker/distribution/manifests.go
generated
vendored
@@ -1,10 +1,10 @@
|
||||
package distribution
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"mime"
|
||||
|
||||
"github.com/docker/distribution/context"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
|
||||
2
vendor/github.com/docker/distribution/reference/reference.go
generated
vendored
2
vendor/github.com/docker/distribution/reference/reference.go
generated
vendored
@@ -15,7 +15,7 @@
|
||||
// tag := /[\w][\w.-]{0,127}/
|
||||
//
|
||||
// digest := digest-algorithm ":" digest-hex
|
||||
// digest-algorithm := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]
|
||||
// digest-algorithm := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]*
|
||||
// digest-algorithm-separator := /[+.-_]/
|
||||
// digest-algorithm-component := /[A-Za-z][A-Za-z0-9]*/
|
||||
// digest-hex := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
|
||||
|
||||
18
vendor/github.com/docker/distribution/registry.go
generated
vendored
18
vendor/github.com/docker/distribution/registry.go
generated
vendored
@@ -1,7 +1,8 @@
|
||||
package distribution
|
||||
|
||||
import (
|
||||
"github.com/docker/distribution/context"
|
||||
"context"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
)
|
||||
|
||||
@@ -72,6 +73,21 @@ func (o WithTagOption) Apply(m ManifestService) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithManifestMediaTypes lists the media types the client wishes
|
||||
// the server to provide.
|
||||
func WithManifestMediaTypes(mediaTypes []string) ManifestServiceOption {
|
||||
return WithManifestMediaTypesOption{mediaTypes}
|
||||
}
|
||||
|
||||
// WithManifestMediaTypesOption holds a list of accepted media types
|
||||
type WithManifestMediaTypesOption struct{ MediaTypes []string }
|
||||
|
||||
// Apply conforms to the ManifestServiceOption interface
|
||||
func (o WithManifestMediaTypesOption) Apply(m ManifestService) error {
|
||||
// no implementation
|
||||
return nil
|
||||
}
|
||||
|
||||
// Repository is a named collection of manifests and layers.
|
||||
type Repository interface {
|
||||
// Named returns the name of the repository.
|
||||
|
||||
6
vendor/github.com/docker/distribution/registry/api/errcode/handler.go
generated
vendored
6
vendor/github.com/docker/distribution/registry/api/errcode/handler.go
generated
vendored
@@ -36,9 +36,5 @@ func ServeJSON(w http.ResponseWriter, err error) error {
|
||||
|
||||
w.WriteHeader(sc)
|
||||
|
||||
if err := json.NewEncoder(w).Encode(err); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return json.NewEncoder(w).Encode(err)
|
||||
}
|
||||
|
||||
116
vendor/github.com/docker/distribution/registry/api/v2/urls.go
generated
vendored
116
vendor/github.com/docker/distribution/registry/api/v2/urls.go
generated
vendored
@@ -1,10 +1,9 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"net"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
@@ -48,66 +47,42 @@ func NewURLBuilderFromString(root string, relative bool) (*URLBuilder, error) {
|
||||
// NewURLBuilderFromRequest uses information from an *http.Request to
|
||||
// construct the root url.
|
||||
func NewURLBuilderFromRequest(r *http.Request, relative bool) *URLBuilder {
|
||||
var scheme string
|
||||
|
||||
forwardedProto := r.Header.Get("X-Forwarded-Proto")
|
||||
// TODO: log the error
|
||||
forwardedHeader, _, _ := parseForwardedHeader(r.Header.Get("Forwarded"))
|
||||
|
||||
switch {
|
||||
case len(forwardedProto) > 0:
|
||||
scheme = forwardedProto
|
||||
case len(forwardedHeader["proto"]) > 0:
|
||||
scheme = forwardedHeader["proto"]
|
||||
case r.TLS != nil:
|
||||
scheme = "https"
|
||||
case len(r.URL.Scheme) > 0:
|
||||
scheme = r.URL.Scheme
|
||||
default:
|
||||
var (
|
||||
scheme = "http"
|
||||
host = r.Host
|
||||
)
|
||||
|
||||
if r.TLS != nil {
|
||||
scheme = "https"
|
||||
} else if len(r.URL.Scheme) > 0 {
|
||||
scheme = r.URL.Scheme
|
||||
}
|
||||
|
||||
host := r.Host
|
||||
|
||||
if forwardedHost := r.Header.Get("X-Forwarded-Host"); len(forwardedHost) > 0 {
|
||||
// According to the Apache mod_proxy docs, X-Forwarded-Host can be a
|
||||
// comma-separated list of hosts, to which each proxy appends the
|
||||
// requested host. We want to grab the first from this comma-separated
|
||||
// list.
|
||||
hosts := strings.SplitN(forwardedHost, ",", 2)
|
||||
host = strings.TrimSpace(hosts[0])
|
||||
} else if addr, exists := forwardedHeader["for"]; exists {
|
||||
host = addr
|
||||
} else if h, exists := forwardedHeader["host"]; exists {
|
||||
host = h
|
||||
}
|
||||
|
||||
portLessHost, port := host, ""
|
||||
if !isIPv6Address(portLessHost) {
|
||||
// with go 1.6, this would treat the last part of IPv6 address as a port
|
||||
portLessHost, port, _ = net.SplitHostPort(host)
|
||||
}
|
||||
if forwardedPort := r.Header.Get("X-Forwarded-Port"); len(port) == 0 && len(forwardedPort) > 0 {
|
||||
ports := strings.SplitN(forwardedPort, ",", 2)
|
||||
forwardedPort = strings.TrimSpace(ports[0])
|
||||
if _, err := strconv.ParseInt(forwardedPort, 10, 32); err == nil {
|
||||
port = forwardedPort
|
||||
// Handle fowarded headers
|
||||
// Prefer "Forwarded" header as defined by rfc7239 if given
|
||||
// see https://tools.ietf.org/html/rfc7239
|
||||
if forwarded := r.Header.Get("Forwarded"); len(forwarded) > 0 {
|
||||
forwardedHeader, _, err := parseForwardedHeader(forwarded)
|
||||
if err == nil {
|
||||
if fproto := forwardedHeader["proto"]; len(fproto) > 0 {
|
||||
scheme = fproto
|
||||
}
|
||||
if fhost := forwardedHeader["host"]; len(fhost) > 0 {
|
||||
host = fhost
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(portLessHost) > 0 {
|
||||
host = portLessHost
|
||||
}
|
||||
if len(port) > 0 {
|
||||
// remove enclosing brackets of ipv6 address otherwise they will be duplicated
|
||||
if len(host) > 1 && host[0] == '[' && host[len(host)-1] == ']' {
|
||||
host = host[1 : len(host)-1]
|
||||
} else {
|
||||
if forwardedProto := r.Header.Get("X-Forwarded-Proto"); len(forwardedProto) > 0 {
|
||||
scheme = forwardedProto
|
||||
}
|
||||
if forwardedHost := r.Header.Get("X-Forwarded-Host"); len(forwardedHost) > 0 {
|
||||
// According to the Apache mod_proxy docs, X-Forwarded-Host can be a
|
||||
// comma-separated list of hosts, to which each proxy appends the
|
||||
// requested host. We want to grab the first from this comma-separated
|
||||
// list.
|
||||
hosts := strings.SplitN(forwardedHost, ",", 2)
|
||||
host = strings.TrimSpace(hosts[0])
|
||||
}
|
||||
// JoinHostPort properly encloses ipv6 addresses in square brackets
|
||||
host = net.JoinHostPort(host, port)
|
||||
} else if isIPv6Address(host) && host[0] != '[' {
|
||||
// ipv6 needs to be enclosed in square brackets in urls
|
||||
host = "[" + host + "]"
|
||||
}
|
||||
|
||||
basePath := routeDescriptorsMap[RouteNameBase].Path
|
||||
@@ -175,6 +150,8 @@ func (ub *URLBuilder) BuildManifestURL(ref reference.Named) (string, error) {
|
||||
tagOrDigest = v.Tag()
|
||||
case reference.Digested:
|
||||
tagOrDigest = v.Digest().String()
|
||||
default:
|
||||
return "", fmt.Errorf("reference must have a tag or digest")
|
||||
}
|
||||
|
||||
manifestURL, err := route.URL("name", ref.Name(), "reference", tagOrDigest)
|
||||
@@ -287,28 +264,3 @@ func appendValues(u string, values ...url.Values) string {
|
||||
|
||||
return appendValuesURL(up, values...).String()
|
||||
}
|
||||
|
||||
// isIPv6Address returns true if given string is a valid IPv6 address. No port is allowed. The address may be
|
||||
// enclosed in square brackets.
|
||||
func isIPv6Address(host string) bool {
|
||||
if len(host) > 1 && host[0] == '[' && host[len(host)-1] == ']' {
|
||||
host = host[1 : len(host)-1]
|
||||
}
|
||||
// The IPv6 scoped addressing zone identifier starts after the last percent sign.
|
||||
if i := strings.LastIndexByte(host, '%'); i > 0 {
|
||||
host = host[:i]
|
||||
}
|
||||
ip := net.ParseIP(host)
|
||||
if ip == nil {
|
||||
return false
|
||||
}
|
||||
if ip.To16() == nil {
|
||||
return false
|
||||
}
|
||||
if ip.To4() == nil {
|
||||
return true
|
||||
}
|
||||
// dot can be present in ipv4-mapped address, it needs to come after a colon though
|
||||
i := strings.IndexAny(host, ":.")
|
||||
return i >= 0 && host[i] == ':'
|
||||
}
|
||||
|
||||
33
vendor/github.com/docker/distribution/registry/client/auth/session.go
generated
vendored
33
vendor/github.com/docker/distribution/registry/client/auth/session.go
generated
vendored
@@ -10,7 +10,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/distribution/registry/client"
|
||||
"github.com/docker/distribution/registry/client/auth/challenge"
|
||||
"github.com/docker/distribution/registry/client/transport"
|
||||
@@ -135,6 +134,8 @@ type tokenHandler struct {
|
||||
tokenLock sync.Mutex
|
||||
tokenCache string
|
||||
tokenExpiration time.Time
|
||||
|
||||
logger Logger
|
||||
}
|
||||
|
||||
// Scope is a type which is serializable to a string
|
||||
@@ -176,6 +177,18 @@ func (rs RegistryScope) String() string {
|
||||
return fmt.Sprintf("registry:%s:%s", rs.Name, strings.Join(rs.Actions, ","))
|
||||
}
|
||||
|
||||
// Logger defines the injectable logging interface, used on TokenHandlers.
|
||||
type Logger interface {
|
||||
Debugf(format string, args ...interface{})
|
||||
}
|
||||
|
||||
func logDebugf(logger Logger, format string, args ...interface{}) {
|
||||
if logger == nil {
|
||||
return
|
||||
}
|
||||
logger.Debugf(format, args...)
|
||||
}
|
||||
|
||||
// TokenHandlerOptions is used to configure a new token handler
|
||||
type TokenHandlerOptions struct {
|
||||
Transport http.RoundTripper
|
||||
@@ -185,6 +198,7 @@ type TokenHandlerOptions struct {
|
||||
ForceOAuth bool
|
||||
ClientID string
|
||||
Scopes []Scope
|
||||
Logger Logger
|
||||
}
|
||||
|
||||
// An implementation of clock for providing real time data.
|
||||
@@ -220,6 +234,7 @@ func NewTokenHandlerWithOptions(options TokenHandlerOptions) AuthenticationHandl
|
||||
clientID: options.ClientID,
|
||||
scopes: options.Scopes,
|
||||
clock: realClock{},
|
||||
logger: options.Logger,
|
||||
}
|
||||
|
||||
return handler
|
||||
@@ -264,6 +279,9 @@ func (th *tokenHandler) getToken(params map[string]string, additionalScopes ...s
|
||||
}
|
||||
var addedScopes bool
|
||||
for _, scope := range additionalScopes {
|
||||
if hasScope(scopes, scope) {
|
||||
continue
|
||||
}
|
||||
scopes = append(scopes, scope)
|
||||
addedScopes = true
|
||||
}
|
||||
@@ -287,6 +305,15 @@ func (th *tokenHandler) getToken(params map[string]string, additionalScopes ...s
|
||||
return th.tokenCache, nil
|
||||
}
|
||||
|
||||
func hasScope(scopes []string, scope string) bool {
|
||||
for _, s := range scopes {
|
||||
if s == scope {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type postTokenResponse struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
@@ -348,7 +375,7 @@ func (th *tokenHandler) fetchTokenWithOAuth(realm *url.URL, refreshToken, servic
|
||||
if tr.ExpiresIn < minimumTokenLifetimeSeconds {
|
||||
// The default/minimum lifetime.
|
||||
tr.ExpiresIn = minimumTokenLifetimeSeconds
|
||||
logrus.Debugf("Increasing token expiration to: %d seconds", tr.ExpiresIn)
|
||||
logDebugf(th.logger, "Increasing token expiration to: %d seconds", tr.ExpiresIn)
|
||||
}
|
||||
|
||||
if tr.IssuedAt.IsZero() {
|
||||
@@ -439,7 +466,7 @@ func (th *tokenHandler) fetchTokenWithBasicAuth(realm *url.URL, service string,
|
||||
if tr.ExpiresIn < minimumTokenLifetimeSeconds {
|
||||
// The default/minimum lifetime.
|
||||
tr.ExpiresIn = minimumTokenLifetimeSeconds
|
||||
logrus.Debugf("Increasing token expiration to: %d seconds", tr.ExpiresIn)
|
||||
logDebugf(th.logger, "Increasing token expiration to: %d seconds", tr.ExpiresIn)
|
||||
}
|
||||
|
||||
if tr.IssuedAt.IsZero() {
|
||||
|
||||
2
vendor/github.com/docker/distribution/registry/client/blob_writer.go
generated
vendored
2
vendor/github.com/docker/distribution/registry/client/blob_writer.go
generated
vendored
@@ -2,6 +2,7 @@ package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@@ -9,7 +10,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/context"
|
||||
)
|
||||
|
||||
type httpBlobUpload struct {
|
||||
|
||||
51
vendor/github.com/docker/distribution/registry/client/repository.go
generated
vendored
51
vendor/github.com/docker/distribution/registry/client/repository.go
generated
vendored
@@ -2,6 +2,7 @@ package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -14,7 +15,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/context"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/docker/distribution/registry/api/v2"
|
||||
"github.com/docker/distribution/registry/client/transport"
|
||||
@@ -62,7 +62,7 @@ func checkHTTPRedirect(req *http.Request, via []*http.Request) error {
|
||||
}
|
||||
|
||||
// NewRegistry creates a registry namespace which can be used to get a listing of repositories
|
||||
func NewRegistry(ctx context.Context, baseURL string, transport http.RoundTripper) (Registry, error) {
|
||||
func NewRegistry(baseURL string, transport http.RoundTripper) (Registry, error) {
|
||||
ub, err := v2.NewURLBuilderFromString(baseURL, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -75,9 +75,8 @@ func NewRegistry(ctx context.Context, baseURL string, transport http.RoundTrippe
|
||||
}
|
||||
|
||||
return ®istry{
|
||||
client: client,
|
||||
ub: ub,
|
||||
context: ctx,
|
||||
client: client,
|
||||
ub: ub,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -133,7 +132,7 @@ func (r *registry) Repositories(ctx context.Context, entries []string, last stri
|
||||
}
|
||||
|
||||
// NewRepository creates a new Repository for the given repository name and base URL.
|
||||
func NewRepository(ctx context.Context, name reference.Named, baseURL string, transport http.RoundTripper) (distribution.Repository, error) {
|
||||
func NewRepository(name reference.Named, baseURL string, transport http.RoundTripper) (distribution.Repository, error) {
|
||||
ub, err := v2.NewURLBuilderFromString(baseURL, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -146,10 +145,9 @@ func NewRepository(ctx context.Context, name reference.Named, baseURL string, tr
|
||||
}
|
||||
|
||||
return &repository{
|
||||
client: client,
|
||||
ub: ub,
|
||||
name: name,
|
||||
context: ctx,
|
||||
client: client,
|
||||
ub: ub,
|
||||
name: name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -190,19 +188,17 @@ func (r *repository) Manifests(ctx context.Context, options ...distribution.Mani
|
||||
|
||||
func (r *repository) Tags(ctx context.Context) distribution.TagService {
|
||||
return &tags{
|
||||
client: r.client,
|
||||
ub: r.ub,
|
||||
context: r.context,
|
||||
name: r.Named(),
|
||||
client: r.client,
|
||||
ub: r.ub,
|
||||
name: r.Named(),
|
||||
}
|
||||
}
|
||||
|
||||
// tags implements remote tagging operations.
|
||||
type tags struct {
|
||||
client *http.Client
|
||||
ub *v2.URLBuilder
|
||||
context context.Context
|
||||
name reference.Named
|
||||
client *http.Client
|
||||
ub *v2.URLBuilder
|
||||
name reference.Named
|
||||
}
|
||||
|
||||
// All returns all tags
|
||||
@@ -321,7 +317,8 @@ func (t *tags) Get(ctx context.Context, tag string) (distribution.Descriptor, er
|
||||
defer resp.Body.Close()
|
||||
|
||||
switch {
|
||||
case resp.StatusCode >= 200 && resp.StatusCode < 400:
|
||||
case resp.StatusCode >= 200 && resp.StatusCode < 400 && len(resp.Header.Get("Docker-Content-Digest")) > 0:
|
||||
// if the response is a success AND a Docker-Content-Digest can be retrieved from the headers
|
||||
return descriptorFromResponse(resp)
|
||||
default:
|
||||
// if the response is an error - there will be no body to decode.
|
||||
@@ -421,18 +418,22 @@ func (ms *manifests) Get(ctx context.Context, dgst digest.Digest, options ...dis
|
||||
ref reference.Named
|
||||
err error
|
||||
contentDgst *digest.Digest
|
||||
mediaTypes []string
|
||||
)
|
||||
|
||||
for _, option := range options {
|
||||
if opt, ok := option.(distribution.WithTagOption); ok {
|
||||
switch opt := option.(type) {
|
||||
case distribution.WithTagOption:
|
||||
digestOrTag = opt.Tag
|
||||
ref, err = reference.WithTag(ms.name, opt.Tag)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if opt, ok := option.(contentDigestOption); ok {
|
||||
case contentDigestOption:
|
||||
contentDgst = opt.digest
|
||||
} else {
|
||||
case distribution.WithManifestMediaTypesOption:
|
||||
mediaTypes = opt.MediaTypes
|
||||
default:
|
||||
err := option.Apply(ms)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -448,6 +449,10 @@ func (ms *manifests) Get(ctx context.Context, dgst digest.Digest, options ...dis
|
||||
}
|
||||
}
|
||||
|
||||
if len(mediaTypes) == 0 {
|
||||
mediaTypes = distribution.ManifestMediaTypes()
|
||||
}
|
||||
|
||||
u, err := ms.ub.BuildManifestURL(ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -458,7 +463,7 @@ func (ms *manifests) Get(ctx context.Context, dgst digest.Digest, options ...dis
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, t := range distribution.ManifestMediaTypes() {
|
||||
for _, t := range mediaTypes {
|
||||
req.Header.Add("Accept", t)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"github.com/docker/distribution/context"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"context"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// Metrics is used to hold metric counters
|
||||
@@ -16,12 +16,20 @@ type Metrics struct {
|
||||
Misses uint64
|
||||
}
|
||||
|
||||
// Logger can be provided on the MetricsTracker to log errors.
|
||||
//
|
||||
// Usually, this is just a proxy to dcontext.GetLogger.
|
||||
type Logger interface {
|
||||
Errorf(format string, args ...interface{})
|
||||
}
|
||||
|
||||
// MetricsTracker represents a metric tracker
|
||||
// which simply counts the number of hits and misses.
|
||||
type MetricsTracker interface {
|
||||
Hit()
|
||||
Miss()
|
||||
Metrics() Metrics
|
||||
Logger(context.Context) Logger
|
||||
}
|
||||
|
||||
type cachedBlobStatter struct {
|
||||
@@ -53,7 +61,7 @@ func (cbds *cachedBlobStatter) Stat(ctx context.Context, dgst digest.Digest) (di
|
||||
desc, err := cbds.cache.Stat(ctx, dgst)
|
||||
if err != nil {
|
||||
if err != distribution.ErrBlobUnknown {
|
||||
context.GetLogger(ctx).Errorf("error retrieving descriptor from cache: %v", err)
|
||||
logErrorf(ctx, cbds.tracker, "error retrieving descriptor from cache: %v", err)
|
||||
}
|
||||
|
||||
goto fallback
|
||||
@@ -73,7 +81,7 @@ fallback:
|
||||
}
|
||||
|
||||
if err := cbds.cache.SetDescriptor(ctx, dgst, desc); err != nil {
|
||||
context.GetLogger(ctx).Errorf("error adding descriptor %v to cache: %v", desc.Digest, err)
|
||||
logErrorf(ctx, cbds.tracker, "error adding descriptor %v to cache: %v", desc.Digest, err)
|
||||
}
|
||||
|
||||
return desc, err
|
||||
@@ -95,7 +103,19 @@ func (cbds *cachedBlobStatter) Clear(ctx context.Context, dgst digest.Digest) er
|
||||
|
||||
func (cbds *cachedBlobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error {
|
||||
if err := cbds.cache.SetDescriptor(ctx, dgst, desc); err != nil {
|
||||
context.GetLogger(ctx).Errorf("error adding descriptor %v to cache: %v", desc.Digest, err)
|
||||
logErrorf(ctx, cbds.tracker, "error adding descriptor %v to cache: %v", desc.Digest, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func logErrorf(ctx context.Context, tracker MetricsTracker, format string, args ...interface{}) {
|
||||
if tracker == nil {
|
||||
return
|
||||
}
|
||||
|
||||
logger := tracker.Logger(ctx)
|
||||
if logger == nil {
|
||||
return
|
||||
}
|
||||
logger.Errorf(format, args...)
|
||||
}
|
||||
|
||||
2
vendor/github.com/docker/distribution/registry/storage/cache/memory/memory.go
generated
vendored
2
vendor/github.com/docker/distribution/registry/storage/cache/memory/memory.go
generated
vendored
@@ -1,10 +1,10 @@
|
||||
package memory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/context"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/docker/distribution/registry/storage/cache"
|
||||
"github.com/opencontainers/go-digest"
|
||||
|
||||
2
vendor/github.com/docker/distribution/tags.go
generated
vendored
2
vendor/github.com/docker/distribution/tags.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
package distribution
|
||||
|
||||
import (
|
||||
"github.com/docker/distribution/context"
|
||||
"context"
|
||||
)
|
||||
|
||||
// TagService provides access to information about tagged objects.
|
||||
|
||||
18
vendor/github.com/docker/distribution/vendor.conf
generated
vendored
18
vendor/github.com/docker/distribution/vendor.conf
generated
vendored
@@ -1,19 +1,21 @@
|
||||
github.com/Azure/azure-sdk-for-go c6f0533defaaaa26ea4dff3c9774e36033088112
|
||||
github.com/Sirupsen/logrus d26492970760ca5d33129d2d799e34be5c4782eb
|
||||
github.com/Azure/azure-sdk-for-go 088007b3b08cc02b27f2eadfdcd870958460ce7e
|
||||
github.com/Azure/go-autorest ec5f4903f77ed9927ac95b19ab8e44ada64c1356
|
||||
github.com/sirupsen/logrus 3d4380f53a34dcdc95f0c1db702615992b38d9a4
|
||||
github.com/aws/aws-sdk-go c6fc52983ea2375810aa38ddb5370e9cdf611716
|
||||
github.com/bshuster-repo/logrus-logstash-hook 5f729f2fb50a301153cae84ff5c58981d51c095a
|
||||
github.com/bshuster-repo/logrus-logstash-hook d2c0ecc1836d91814e15e23bb5dc309c3ef51f4a
|
||||
github.com/bugsnag/bugsnag-go b1d153021fcd90ca3f080db36bec96dc690fb274
|
||||
github.com/bugsnag/osext 0dd3f918b21bec95ace9dc86c7e70266cfc5c702
|
||||
github.com/bugsnag/panicwrap e2c28503fcd0675329da73bf48b33404db873782
|
||||
github.com/denverdino/aliyungo afedced274aa9a7fcdd47ac97018f0f8db4e5de2
|
||||
github.com/dgrijalva/jwt-go a601269ab70c205d26370c16f7c81e9017c14e04
|
||||
github.com/docker/goamz f0a21f5b2e12f83a505ecf79b633bb2035cf6f85
|
||||
github.com/docker/libtrust fa567046d9b14f6aa788882a950d69651d230b21
|
||||
github.com/garyburd/redigo 535138d7bcd717d6531c701ef5933d98b1866257
|
||||
github.com/go-ini/ini 2ba15ac2dc9cdf88c110ec2dc0ced7fa45f5678c
|
||||
github.com/golang/protobuf/proto 8d92cf5fc15a4382f8964b08e1f42a75c0591aa3
|
||||
github.com/golang/protobuf 8d92cf5fc15a4382f8964b08e1f42a75c0591aa3
|
||||
github.com/gorilla/context 14f550f51af52180c2eefed15e5fd18d63c0a64a
|
||||
github.com/gorilla/handlers 60c7bfde3e33c201519a200a4507a158cc03a17b
|
||||
github.com/gorilla/mux e444e69cbd2e2e3e0749a2f3c717cec491552bbf
|
||||
github.com/gorilla/mux 599cba5e7b6137d46ddf58fb1765f5d928e69604
|
||||
github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
|
||||
github.com/jmespath/go-jmespath bd40a432e4c76585ef6b72d3fd96fb9b6dc7b68d
|
||||
github.com/miekg/dns 271c58e0c14f552178ea321a545ff9af38930f39
|
||||
@@ -21,15 +23,15 @@ github.com/mitchellh/mapstructure 482a9fd5fa83e8c4e7817413b80f3eb8feec03ef
|
||||
github.com/ncw/swift b964f2ca856aac39885e258ad25aec08d5f64ee6
|
||||
github.com/spf13/cobra 312092086bed4968099259622145a0c9ae280064
|
||||
github.com/spf13/pflag 5644820622454e71517561946e3d94b9f9db6842
|
||||
github.com/stevvooe/resumable 51ad44105773cafcbe91927f70ac68e1bf78f8b4
|
||||
github.com/xenolf/lego/acme a9d8cec0e6563575e5868a005359ac97911b5985
|
||||
github.com/stevvooe/resumable 2aaf90b2ceea5072cb503ef2a620b08ff3119870
|
||||
github.com/xenolf/lego a9d8cec0e6563575e5868a005359ac97911b5985
|
||||
github.com/yvasiyarov/go-metrics 57bccd1ccd43f94bb17fdd8bf3007059b802f85e
|
||||
github.com/yvasiyarov/gorelic a9bba5b9ab508a086f9a12b8c51fab68478e2128
|
||||
github.com/yvasiyarov/newrelic_platform_go b21fdbd4370f3717f3bbd2bf41c223bc273068e6
|
||||
golang.org/x/crypto c10c31b5e94b6f7a0283272dc2bb27163dcea24b
|
||||
golang.org/x/net 4876518f9e71663000c348837735820161a42df7
|
||||
golang.org/x/oauth2 045497edb6234273d67dbc25da3f2ddbc4c4cacf
|
||||
golang.org/x/time/rate a4bde12657593d5e90d0533a3e4fd95e635124cb
|
||||
golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb
|
||||
google.golang.org/api 9bf6e6e569ff057f75d9604a46c52928f17d2b54
|
||||
google.golang.org/appengine 12d5545dc1cfa6047a286d5e853841b6471f4c19
|
||||
google.golang.org/cloud 975617b05ea8a58727e6c1a06b6161ff4185a9f2
|
||||
|
||||
Reference in New Issue
Block a user