mirror of
https://gitea.com/Lydanne/buildx.git
synced 2026-01-13 09:24:12 +08:00
vendor: update buildkit to opentelemetry support
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
50
vendor/github.com/containerd/containerd/remotes/docker/pusher.go
generated
vendored
50
vendor/github.com/containerd/containerd/remotes/docker/pusher.go
generated
vendored
@@ -44,17 +44,47 @@ type dockerPusher struct {
|
||||
tracker StatusTracker
|
||||
}
|
||||
|
||||
// Writer implements Ingester API of content store. This allows the client
|
||||
// to receive ErrUnavailable when there is already an on-going upload.
|
||||
// Note that the tracker MUST implement StatusTrackLocker interface to avoid
|
||||
// race condition on StatusTracker.
|
||||
func (p dockerPusher) Writer(ctx context.Context, opts ...content.WriterOpt) (content.Writer, error) {
|
||||
var wOpts content.WriterOpts
|
||||
for _, opt := range opts {
|
||||
if err := opt(&wOpts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if wOpts.Ref == "" {
|
||||
return nil, errors.Wrap(errdefs.ErrInvalidArgument, "ref must not be empty")
|
||||
}
|
||||
return p.push(ctx, wOpts.Desc, wOpts.Ref, true)
|
||||
}
|
||||
|
||||
func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (content.Writer, error) {
|
||||
return p.push(ctx, desc, remotes.MakeRefKey(ctx, desc), false)
|
||||
}
|
||||
|
||||
func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref string, unavailableOnFail bool) (content.Writer, error) {
|
||||
if l, ok := p.tracker.(StatusTrackLocker); ok {
|
||||
l.Lock(ref)
|
||||
defer l.Unlock(ref)
|
||||
}
|
||||
ctx, err := ContextWithRepositoryScope(ctx, p.refspec, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ref := remotes.MakeRefKey(ctx, desc)
|
||||
status, err := p.tracker.GetStatus(ref)
|
||||
if err == nil {
|
||||
if status.Offset == status.Total {
|
||||
if status.Committed && status.Offset == status.Total {
|
||||
return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "ref %v", ref)
|
||||
}
|
||||
if unavailableOnFail {
|
||||
// Another push of this ref is happening elsewhere. The rest of function
|
||||
// will continue only when `errdefs.IsNotFound(err) == true` (i.e. there
|
||||
// is no actively-tracked ref already).
|
||||
return nil, errors.Wrap(errdefs.ErrUnavailable, "push is on-going")
|
||||
}
|
||||
// TODO: Handle incomplete status
|
||||
} else if !errdefs.IsNotFound(err) {
|
||||
return nil, errors.Wrap(err, "failed to get status")
|
||||
@@ -105,8 +135,11 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
|
||||
|
||||
if exists {
|
||||
p.tracker.SetStatus(ref, Status{
|
||||
Committed: true,
|
||||
Status: content.Status{
|
||||
Ref: ref,
|
||||
Ref: ref,
|
||||
Total: desc.Size,
|
||||
Offset: desc.Size,
|
||||
// TODO: Set updated time?
|
||||
},
|
||||
})
|
||||
@@ -162,8 +195,11 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
|
||||
case http.StatusOK, http.StatusAccepted, http.StatusNoContent:
|
||||
case http.StatusCreated:
|
||||
p.tracker.SetStatus(ref, Status{
|
||||
Committed: true,
|
||||
Status: content.Status{
|
||||
Ref: ref,
|
||||
Ref: ref,
|
||||
Total: desc.Size,
|
||||
Offset: desc.Size,
|
||||
},
|
||||
})
|
||||
return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest)
|
||||
@@ -341,8 +377,6 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
|
||||
if err := pw.pipe.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO: Update status to determine committing
|
||||
|
||||
// TODO: timeout waiting for response
|
||||
resp := <-pw.responseC
|
||||
if resp.err != nil {
|
||||
@@ -379,6 +413,10 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
|
||||
return errors.Errorf("got digest %s, expected %s", actual, expected)
|
||||
}
|
||||
|
||||
status.Committed = true
|
||||
status.UpdatedAt = time.Now()
|
||||
pw.tracker.SetStatus(pw.ref, status)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
42
vendor/github.com/containerd/containerd/remotes/docker/registry.go
generated
vendored
42
vendor/github.com/containerd/containerd/remotes/docker/registry.go
generated
vendored
@@ -17,7 +17,10 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// HostCapabilities represent the capabilities of the registry
|
||||
@@ -202,12 +205,41 @@ func MatchAllHosts(string) (bool, error) {
|
||||
|
||||
// MatchLocalhost is a host match function which returns true for
|
||||
// localhost.
|
||||
//
|
||||
// Note: this does not handle matching of ip addresses in octal,
|
||||
// decimal or hex form.
|
||||
func MatchLocalhost(host string) (bool, error) {
|
||||
for _, s := range []string{"localhost", "127.0.0.1", "[::1]"} {
|
||||
if len(host) >= len(s) && host[0:len(s)] == s && (len(host) == len(s) || host[len(s)] == ':') {
|
||||
return true, nil
|
||||
}
|
||||
switch {
|
||||
case host == "::1":
|
||||
return true, nil
|
||||
case host == "[::1]":
|
||||
return true, nil
|
||||
}
|
||||
return host == "::1", nil
|
||||
h, p, err := net.SplitHostPort(host)
|
||||
|
||||
// addrError helps distinguish between errors of form
|
||||
// "no colon in address" and "too many colons in address".
|
||||
// The former is fine as the host string need not have a
|
||||
// port. Latter needs to be handled.
|
||||
addrError := &net.AddrError{
|
||||
Err: "missing port in address",
|
||||
Addr: host,
|
||||
}
|
||||
if err != nil {
|
||||
if err.Error() != addrError.Error() {
|
||||
return false, err
|
||||
}
|
||||
// host string without any port specified
|
||||
h = host
|
||||
} else if len(p) == 0 {
|
||||
return false, errors.New("invalid host name format")
|
||||
}
|
||||
|
||||
// use ipv4 dotted decimal for further checking
|
||||
if h == "localhost" {
|
||||
h = "127.0.0.1"
|
||||
}
|
||||
ip := net.ParseIP(h)
|
||||
|
||||
return ip.IsLoopback(), nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/containerd/containerd/remotes/docker/resolver.go
generated
vendored
2
vendor/github.com/containerd/containerd/remotes/docker/resolver.go
generated
vendored
@@ -286,12 +286,14 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
|
||||
if lastErr == nil {
|
||||
lastErr = err
|
||||
}
|
||||
log.G(ctx).WithError(err).Info("trying next host")
|
||||
continue // try another host
|
||||
}
|
||||
resp.Body.Close() // don't care about body contents.
|
||||
|
||||
if resp.StatusCode > 299 {
|
||||
if resp.StatusCode == http.StatusNotFound {
|
||||
log.G(ctx).Info("trying next host - response was http.StatusNotFound")
|
||||
continue
|
||||
}
|
||||
return "", ocispec.Descriptor{}, errors.Errorf("unexpected status code %v: %v", u, resp.Status)
|
||||
|
||||
22
vendor/github.com/containerd/containerd/remotes/docker/status.go
generated
vendored
22
vendor/github.com/containerd/containerd/remotes/docker/status.go
generated
vendored
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/moby/locker"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -28,6 +29,8 @@ import (
|
||||
type Status struct {
|
||||
content.Status
|
||||
|
||||
Committed bool
|
||||
|
||||
// UploadUUID is used by the Docker registry to reference blob uploads
|
||||
UploadUUID string
|
||||
}
|
||||
@@ -38,15 +41,24 @@ type StatusTracker interface {
|
||||
SetStatus(string, Status)
|
||||
}
|
||||
|
||||
// StatusTrackLocker to track status of operations with lock
|
||||
type StatusTrackLocker interface {
|
||||
StatusTracker
|
||||
Lock(string)
|
||||
Unlock(string)
|
||||
}
|
||||
|
||||
type memoryStatusTracker struct {
|
||||
statuses map[string]Status
|
||||
m sync.Mutex
|
||||
locker *locker.Locker
|
||||
}
|
||||
|
||||
// NewInMemoryTracker returns a StatusTracker that tracks content status in-memory
|
||||
func NewInMemoryTracker() StatusTracker {
|
||||
func NewInMemoryTracker() StatusTrackLocker {
|
||||
return &memoryStatusTracker{
|
||||
statuses: map[string]Status{},
|
||||
locker: locker.New(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,3 +77,11 @@ func (t *memoryStatusTracker) SetStatus(ref string, status Status) {
|
||||
t.statuses[ref] = status
|
||||
t.m.Unlock()
|
||||
}
|
||||
|
||||
func (t *memoryStatusTracker) Lock(ref string) {
|
||||
t.locker.Lock(ref)
|
||||
}
|
||||
|
||||
func (t *memoryStatusTracker) Unlock(ref string) {
|
||||
t.locker.Unlock(ref)
|
||||
}
|
||||
|
||||
35
vendor/github.com/containerd/containerd/remotes/handlers.go
generated
vendored
35
vendor/github.com/containerd/containerd/remotes/handlers.go
generated
vendored
@@ -31,6 +31,7 @@ import (
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sync/semaphore"
|
||||
)
|
||||
|
||||
type refKeyPrefix struct{}
|
||||
@@ -55,25 +56,32 @@ func WithMediaTypeKeyPrefix(ctx context.Context, mediaType, prefix string) conte
|
||||
// used to lookup ongoing processes related to the descriptor. This function
|
||||
// may look to the context to namespace the reference appropriately.
|
||||
func MakeRefKey(ctx context.Context, desc ocispec.Descriptor) string {
|
||||
key := desc.Digest.String()
|
||||
if desc.Annotations != nil {
|
||||
if name, ok := desc.Annotations[ocispec.AnnotationRefName]; ok {
|
||||
key = fmt.Sprintf("%s@%s", name, desc.Digest.String())
|
||||
}
|
||||
}
|
||||
|
||||
if v := ctx.Value(refKeyPrefix{}); v != nil {
|
||||
values := v.(map[string]string)
|
||||
if prefix := values[desc.MediaType]; prefix != "" {
|
||||
return prefix + "-" + desc.Digest.String()
|
||||
return prefix + "-" + key
|
||||
}
|
||||
}
|
||||
|
||||
switch mt := desc.MediaType; {
|
||||
case mt == images.MediaTypeDockerSchema2Manifest || mt == ocispec.MediaTypeImageManifest:
|
||||
return "manifest-" + desc.Digest.String()
|
||||
return "manifest-" + key
|
||||
case mt == images.MediaTypeDockerSchema2ManifestList || mt == ocispec.MediaTypeImageIndex:
|
||||
return "index-" + desc.Digest.String()
|
||||
return "index-" + key
|
||||
case images.IsLayerType(mt):
|
||||
return "layer-" + desc.Digest.String()
|
||||
return "layer-" + key
|
||||
case images.IsKnownConfig(mt):
|
||||
return "config-" + desc.Digest.String()
|
||||
return "config-" + key
|
||||
default:
|
||||
log.G(ctx).Warnf("reference for unknown type: %s", mt)
|
||||
return "unknown-" + desc.Digest.String()
|
||||
return "unknown-" + key
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +165,15 @@ func PushHandler(pusher Pusher, provider content.Provider) images.HandlerFunc {
|
||||
func push(ctx context.Context, provider content.Provider, pusher Pusher, desc ocispec.Descriptor) error {
|
||||
log.G(ctx).Debug("push")
|
||||
|
||||
cw, err := pusher.Push(ctx, desc)
|
||||
var (
|
||||
cw content.Writer
|
||||
err error
|
||||
)
|
||||
if cs, ok := pusher.(content.Ingester); ok {
|
||||
cw, err = content.OpenWriter(ctx, cs, content.WithRef(MakeRefKey(ctx, desc)), content.WithDescriptor(desc))
|
||||
} else {
|
||||
cw, err = pusher.Push(ctx, desc)
|
||||
}
|
||||
if err != nil {
|
||||
if !errdefs.IsAlreadyExists(err) {
|
||||
return err
|
||||
@@ -181,7 +197,8 @@ func push(ctx context.Context, provider content.Provider, pusher Pusher, desc oc
|
||||
//
|
||||
// Base handlers can be provided which will be called before any push specific
|
||||
// handlers.
|
||||
func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, store content.Store, platform platforms.MatchComparer, wrapper func(h images.Handler) images.Handler) error {
|
||||
func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, store content.Store, limiter *semaphore.Weighted, platform platforms.MatchComparer, wrapper func(h images.Handler) images.Handler) error {
|
||||
|
||||
var m sync.Mutex
|
||||
manifestStack := []ocispec.Descriptor{}
|
||||
|
||||
@@ -213,7 +230,7 @@ func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, st
|
||||
handler = wrapper(handler)
|
||||
}
|
||||
|
||||
if err := images.Dispatch(ctx, handler, nil, desc); err != nil {
|
||||
if err := images.Dispatch(ctx, handler, limiter, desc); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/containerd/containerd/remotes/resolver.go
generated
vendored
2
vendor/github.com/containerd/containerd/remotes/resolver.go
generated
vendored
@@ -45,6 +45,8 @@ type Resolver interface {
|
||||
Fetcher(ctx context.Context, ref string) (Fetcher, error)
|
||||
|
||||
// Pusher returns a new pusher for the provided reference
|
||||
// The returned Pusher should satisfy content.Ingester and concurrent attempts
|
||||
// to push the same blob using the Ingester API should result in ErrUnavailable.
|
||||
Pusher(ctx context.Context, ref string) (Pusher, error)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user