feat: replace github.com/pkg/errors to errors
Signed-off-by: haoyun <yun.hao@daocloud.io> Co-authored-by: zounengren <zouyee1989@gmail.com>
This commit is contained in:
@@ -19,6 +19,8 @@ package auth
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
@@ -27,7 +29,6 @@ import (
|
||||
"github.com/containerd/containerd/log"
|
||||
remoteserrors "github.com/containerd/containerd/remotes/errors"
|
||||
"github.com/containerd/containerd/version"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context/ctxhttp"
|
||||
)
|
||||
|
||||
@@ -46,7 +47,7 @@ func GenerateTokenOptions(ctx context.Context, host, username, secret string, c
|
||||
|
||||
realmURL, err := url.Parse(realm)
|
||||
if err != nil {
|
||||
return TokenOptions{}, errors.Wrap(err, "invalid token auth challenge realm")
|
||||
return TokenOptions{}, fmt.Errorf("invalid token auth challenge realm: %w", err)
|
||||
}
|
||||
|
||||
to := TokenOptions{
|
||||
@@ -133,18 +134,18 @@ func FetchTokenWithOAuth(ctx context.Context, client *http.Client, headers http.
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 400 {
|
||||
return nil, errors.WithStack(remoteserrors.NewUnexpectedStatusErr(resp))
|
||||
return nil, remoteserrors.NewUnexpectedStatusErr(resp)
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(resp.Body)
|
||||
|
||||
var tr OAuthTokenResponse
|
||||
if err = decoder.Decode(&tr); err != nil {
|
||||
return nil, errors.Wrap(err, "unable to decode token response")
|
||||
return nil, fmt.Errorf("unable to decode token response: %w", err)
|
||||
}
|
||||
|
||||
if tr.AccessToken == "" {
|
||||
return nil, errors.WithStack(ErrNoToken)
|
||||
return nil, ErrNoToken
|
||||
}
|
||||
|
||||
return &tr, nil
|
||||
@@ -200,14 +201,14 @@ func FetchToken(ctx context.Context, client *http.Client, headers http.Header, t
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 400 {
|
||||
return nil, errors.WithStack(remoteserrors.NewUnexpectedStatusErr(resp))
|
||||
return nil, remoteserrors.NewUnexpectedStatusErr(resp)
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(resp.Body)
|
||||
|
||||
var tr FetchTokenResponse
|
||||
if err = decoder.Decode(&tr); err != nil {
|
||||
return nil, errors.Wrap(err, "unable to decode token response")
|
||||
return nil, fmt.Errorf("unable to decode token response: %w", err)
|
||||
}
|
||||
|
||||
// `access_token` is equivalent to `token` and if both are specified
|
||||
@@ -218,7 +219,7 @@ func FetchToken(ctx context.Context, client *http.Client, headers http.Header, t
|
||||
}
|
||||
|
||||
if tr.Token == "" {
|
||||
return nil, errors.WithStack(ErrNoToken)
|
||||
return nil, ErrNoToken
|
||||
}
|
||||
|
||||
return &tr, nil
|
||||
|
@@ -19,6 +19,7 @@ package docker
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -28,7 +29,6 @@ import (
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/remotes/docker/auth"
|
||||
remoteerrors "github.com/containerd/containerd/remotes/errors"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@@ -205,7 +205,7 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
|
||||
}
|
||||
}
|
||||
}
|
||||
return errors.Wrap(errdefs.ErrNotImplemented, "failed to find supported auth scheme")
|
||||
return fmt.Errorf("failed to find supported auth scheme: %w", errdefs.ErrNotImplemented)
|
||||
}
|
||||
|
||||
// authResult is used to control limit rate.
|
||||
@@ -252,7 +252,7 @@ func (ah *authHandler) authorize(ctx context.Context) (string, string, error) {
|
||||
case auth.BearerAuth:
|
||||
return ah.doBearerAuth(ctx)
|
||||
default:
|
||||
return "", "", errors.Wrapf(errdefs.ErrNotImplemented, "failed to find supported auth scheme: %s", string(ah.scheme))
|
||||
return "", "", fmt.Errorf("failed to find supported auth scheme: %s: %w", string(ah.scheme), errdefs.ErrNotImplemented)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,7 +298,9 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (token, refreshToken st
|
||||
// fetch token for the resource scope
|
||||
if to.Secret != "" {
|
||||
defer func() {
|
||||
err = errors.Wrap(err, "failed to fetch oauth token")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to fetch oauth token: %w", err)
|
||||
}
|
||||
}()
|
||||
// credential information is provided, use oauth POST endpoint
|
||||
// TODO: Allow setting client_id
|
||||
@@ -328,7 +330,7 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (token, refreshToken st
|
||||
// do request anonymously
|
||||
resp, err := auth.FetchToken(ctx, ah.client, ah.header, to)
|
||||
if err != nil {
|
||||
return "", "", errors.Wrap(err, "failed to fetch anonymous token")
|
||||
return "", "", fmt.Errorf("failed to fetch anonymous token: %w", err)
|
||||
}
|
||||
return resp.Token, resp.RefreshToken, nil
|
||||
}
|
||||
@@ -344,7 +346,7 @@ func invalidAuthorization(c auth.Challenge, responses []*http.Response) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.Wrapf(ErrInvalidAuthorization, "server message: %s", errStr)
|
||||
return fmt.Errorf("server message: %s: %w", errStr, ErrInvalidAuthorization)
|
||||
}
|
||||
|
||||
func sameRequest(r1, r2 *http.Request) bool {
|
||||
|
@@ -20,6 +20,8 @@ package config
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -34,7 +36,6 @@ import (
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/remotes/docker"
|
||||
"github.com/pelletier/go-toml"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// UpdateClientFunc is a function that lets you to amend http Client behavior used by registry clients.
|
||||
@@ -166,17 +167,17 @@ func ConfigureHosts(ctx context.Context, options HostOptions) docker.RegistryHos
|
||||
if tlsConfig.RootCAs == nil {
|
||||
rootPool, err := rootSystemPool()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to initialize cert pool")
|
||||
return nil, fmt.Errorf("unable to initialize cert pool: %w", err)
|
||||
}
|
||||
tlsConfig.RootCAs = rootPool
|
||||
}
|
||||
for _, f := range host.caCerts {
|
||||
data, err := os.ReadFile(f)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to read CA cert %q", f)
|
||||
return nil, fmt.Errorf("unable to read CA cert %q: %w", f, err)
|
||||
}
|
||||
if !tlsConfig.RootCAs.AppendCertsFromPEM(data) {
|
||||
return nil, errors.Errorf("unable to load CA cert %q", f)
|
||||
return nil, fmt.Errorf("unable to load CA cert %q", f)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,13 +186,13 @@ func ConfigureHosts(ctx context.Context, options HostOptions) docker.RegistryHos
|
||||
for _, pair := range host.clientPairs {
|
||||
certPEMBlock, err := os.ReadFile(pair[0])
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to read CERT file %q", pair[0])
|
||||
return nil, fmt.Errorf("unable to read CERT file %q: %w", pair[0], err)
|
||||
}
|
||||
var keyPEMBlock []byte
|
||||
if pair[1] != "" {
|
||||
keyPEMBlock, err = os.ReadFile(pair[1])
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to read CERT file %q", pair[1])
|
||||
return nil, fmt.Errorf("unable to read CERT file %q: %w", pair[1], err)
|
||||
}
|
||||
} else {
|
||||
// Load key block from same PEM file
|
||||
@@ -199,7 +200,7 @@ func ConfigureHosts(ctx context.Context, options HostOptions) docker.RegistryHos
|
||||
}
|
||||
cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to load X509 key pair")
|
||||
return nil, fmt.Errorf("failed to load X509 key pair: %w", err)
|
||||
}
|
||||
|
||||
tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
|
||||
@@ -315,7 +316,7 @@ type hostFileConfig struct {
|
||||
func parseHostsFile(baseDir string, b []byte) ([]hostConfig, error) {
|
||||
tree, err := toml.LoadBytes(b)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse TOML")
|
||||
return nil, fmt.Errorf("failed to parse TOML: %w", err)
|
||||
}
|
||||
|
||||
// HACK: we want to keep toml parsing structures private in this package, however go-toml ignores private embedded types.
|
||||
@@ -377,7 +378,7 @@ func parseHostConfig(server string, baseDir string, config hostFileConfig) (host
|
||||
}
|
||||
u, err := url.Parse(server)
|
||||
if err != nil {
|
||||
return hostConfig{}, errors.Wrapf(err, "unable to parse server %v", server)
|
||||
return hostConfig{}, fmt.Errorf("unable to parse server %v: %w", server, err)
|
||||
}
|
||||
result.scheme = u.Scheme
|
||||
result.host = u.Host
|
||||
@@ -404,7 +405,7 @@ func parseHostConfig(server string, baseDir string, config hostFileConfig) (host
|
||||
case "push":
|
||||
result.capabilities |= docker.HostCapabilityPush
|
||||
default:
|
||||
return hostConfig{}, errors.Errorf("unknown capability %v", c)
|
||||
return hostConfig{}, fmt.Errorf("unknown capability %v", c)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -423,7 +424,7 @@ func parseHostConfig(server string, baseDir string, config hostFileConfig) (host
|
||||
return hostConfig{}, err
|
||||
}
|
||||
default:
|
||||
return hostConfig{}, errors.Errorf("invalid type %v for \"ca\"", cert)
|
||||
return hostConfig{}, fmt.Errorf("invalid type %v for \"ca\"", cert)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,18 +446,18 @@ func parseHostConfig(server string, baseDir string, config hostFileConfig) (host
|
||||
return hostConfig{}, err
|
||||
}
|
||||
if len(slice) != 2 {
|
||||
return hostConfig{}, errors.Errorf("invalid pair %v for \"client\"", p)
|
||||
return hostConfig{}, fmt.Errorf("invalid pair %v for \"client\"", p)
|
||||
}
|
||||
|
||||
var pair [2]string
|
||||
copy(pair[:], slice)
|
||||
result.clientPairs = append(result.clientPairs, pair)
|
||||
default:
|
||||
return hostConfig{}, errors.Errorf("invalid type %T for \"client\"", p)
|
||||
return hostConfig{}, fmt.Errorf("invalid type %T for \"client\"", p)
|
||||
}
|
||||
}
|
||||
default:
|
||||
return hostConfig{}, errors.Errorf("invalid type %v for \"client\"", client)
|
||||
return hostConfig{}, fmt.Errorf("invalid type %v for \"client\"", client)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,7 +473,7 @@ func parseHostConfig(server string, baseDir string, config hostFileConfig) (host
|
||||
return hostConfig{}, err
|
||||
}
|
||||
default:
|
||||
return hostConfig{}, errors.Errorf("invalid type %v for header %q", ty, key)
|
||||
return hostConfig{}, fmt.Errorf("invalid type %v for header %q", ty, key)
|
||||
}
|
||||
}
|
||||
result.header = header
|
||||
@@ -508,7 +509,7 @@ func makeStringSlice(slice []interface{}, cb func(string) string) ([]string, err
|
||||
for i, value := range slice {
|
||||
str, ok := value.(string)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("unable to cast %v to string", value)
|
||||
return nil, fmt.Errorf("unable to cast %v to string", value)
|
||||
}
|
||||
|
||||
if cb != nil {
|
||||
|
@@ -28,7 +28,6 @@ import (
|
||||
"github.com/containerd/containerd/remotes"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// LegacyConfigMediaType should be replaced by OCI image spec.
|
||||
@@ -52,12 +51,12 @@ func ConvertManifest(ctx context.Context, store content.Store, desc ocispec.Desc
|
||||
// read manifest data
|
||||
mb, err := content.ReadBlob(ctx, store, desc)
|
||||
if err != nil {
|
||||
return ocispec.Descriptor{}, errors.Wrap(err, "failed to read index data")
|
||||
return ocispec.Descriptor{}, fmt.Errorf("failed to read index data: %w", err)
|
||||
}
|
||||
|
||||
var manifest ocispec.Manifest
|
||||
if err := json.Unmarshal(mb, &manifest); err != nil {
|
||||
return ocispec.Descriptor{}, errors.Wrap(err, "failed to unmarshal data into manifest")
|
||||
return ocispec.Descriptor{}, fmt.Errorf("failed to unmarshal data into manifest: %w", err)
|
||||
}
|
||||
|
||||
// check config media type
|
||||
@@ -68,7 +67,7 @@ func ConvertManifest(ctx context.Context, store content.Store, desc ocispec.Desc
|
||||
manifest.Config.MediaType = images.MediaTypeDockerSchema2Config
|
||||
data, err := json.MarshalIndent(manifest, "", " ")
|
||||
if err != nil {
|
||||
return ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal manifest")
|
||||
return ocispec.Descriptor{}, fmt.Errorf("failed to marshal manifest: %w", err)
|
||||
}
|
||||
|
||||
// update manifest with gc labels
|
||||
@@ -82,7 +81,7 @@ func ConvertManifest(ctx context.Context, store content.Store, desc ocispec.Desc
|
||||
|
||||
ref := remotes.MakeRefKey(ctx, desc)
|
||||
if err := content.WriteBlob(ctx, store, ref, bytes.NewReader(data), desc, content.WithLabels(labels)); err != nil {
|
||||
return ocispec.Descriptor{}, errors.Wrap(err, "failed to update content")
|
||||
return ocispec.Descriptor{}, fmt.Errorf("failed to update content: %w", err)
|
||||
}
|
||||
return desc, nil
|
||||
}
|
||||
|
@@ -19,6 +19,7 @@ package docker
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -29,7 +30,6 @@ import (
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/log"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type dockerFetcher struct {
|
||||
@@ -41,7 +41,7 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R
|
||||
|
||||
hosts := r.filterHosts(HostCapabilityPull)
|
||||
if len(hosts) == 0 {
|
||||
return nil, errors.Wrap(errdefs.ErrNotFound, "no pull hosts")
|
||||
return nil, fmt.Errorf("no pull hosts: %w", errdefs.ErrNotFound)
|
||||
}
|
||||
|
||||
ctx, err := ContextWithRepositoryScope(ctx, r.refspec, false)
|
||||
@@ -141,9 +141,9 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R
|
||||
}
|
||||
|
||||
if errdefs.IsNotFound(firstErr) {
|
||||
firstErr = errors.Wrapf(errdefs.ErrNotFound,
|
||||
"could not fetch content descriptor %v (%v) from remote",
|
||||
desc.Digest, desc.MediaType)
|
||||
firstErr = fmt.Errorf("could not fetch content descriptor %v (%v) from remote: %w",
|
||||
desc.Digest, desc.MediaType, errdefs.ErrNotFound,
|
||||
)
|
||||
}
|
||||
|
||||
return nil, firstErr
|
||||
@@ -178,19 +178,19 @@ func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string,
|
||||
// implementation.
|
||||
|
||||
if resp.StatusCode == http.StatusNotFound {
|
||||
return nil, errors.Wrapf(errdefs.ErrNotFound, "content at %v not found", req.String())
|
||||
return nil, fmt.Errorf("content at %v not found: %w", req.String(), errdefs.ErrNotFound)
|
||||
}
|
||||
var registryErr Errors
|
||||
if err := json.NewDecoder(resp.Body).Decode(®istryErr); err != nil || registryErr.Len() < 1 {
|
||||
return nil, errors.Errorf("unexpected status code %v: %v", req.String(), resp.Status)
|
||||
return nil, fmt.Errorf("unexpected status code %v: %v", req.String(), resp.Status)
|
||||
}
|
||||
return nil, errors.Errorf("unexpected status code %v: %s - Server message: %s", req.String(), resp.Status, registryErr.Error())
|
||||
return nil, fmt.Errorf("unexpected status code %v: %s - Server message: %s", req.String(), resp.Status, registryErr.Error())
|
||||
}
|
||||
if offset > 0 {
|
||||
cr := resp.Header.Get("content-range")
|
||||
if cr != "" {
|
||||
if !strings.HasPrefix(cr, fmt.Sprintf("bytes %d-", offset)) {
|
||||
return nil, errors.Errorf("unhandled content range in response: %v", cr)
|
||||
return nil, fmt.Errorf("unhandled content range in response: %v", cr)
|
||||
|
||||
}
|
||||
} else {
|
||||
@@ -202,7 +202,7 @@ func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string,
|
||||
// Could use buffer pool here but this case should be rare
|
||||
n, err := io.Copy(io.Discard, io.LimitReader(resp.Body, offset))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to discard to offset")
|
||||
return nil, fmt.Errorf("failed to discard to offset: %w", err)
|
||||
}
|
||||
if n != offset {
|
||||
return nil, errors.New("unable to discard to offset")
|
||||
|
@@ -27,7 +27,6 @@ import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
@@ -200,9 +199,9 @@ func TestDockerFetcherOpen(t *testing.T) {
|
||||
if tt.wantErr {
|
||||
var expectedError error
|
||||
if tt.wantServerMessageError {
|
||||
expectedError = errors.Errorf("unexpected status code %v/ns: %v %s - Server message: %s", s.URL, tt.mockedStatus, http.StatusText(tt.mockedStatus), tt.mockedErr.Error())
|
||||
expectedError = fmt.Errorf("unexpected status code %v/ns: %v %s - Server message: %s", s.URL, tt.mockedStatus, http.StatusText(tt.mockedStatus), tt.mockedErr.Error())
|
||||
} else if tt.wantPlainError {
|
||||
expectedError = errors.Errorf("unexpected status code %v/ns: %v %s", s.URL, tt.mockedStatus, http.StatusText(tt.mockedStatus))
|
||||
expectedError = fmt.Errorf("unexpected status code %v/ns: %v %s", s.URL, tt.mockedStatus, http.StatusText(tt.mockedStatus))
|
||||
}
|
||||
assert.Equal(t, expectedError.Error(), err.Error())
|
||||
|
||||
|
@@ -18,11 +18,11 @@ package docker
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const maxRetry = 3
|
||||
@@ -94,7 +94,7 @@ func (hrs *httpReadSeeker) Close() error {
|
||||
|
||||
func (hrs *httpReadSeeker) Seek(offset int64, whence int) (int64, error) {
|
||||
if hrs.closed {
|
||||
return 0, errors.Wrap(errdefs.ErrUnavailable, "Fetcher.Seek: closed")
|
||||
return 0, fmt.Errorf("Fetcher.Seek: closed: %w", errdefs.ErrUnavailable)
|
||||
}
|
||||
|
||||
abs := hrs.offset
|
||||
@@ -105,15 +105,15 @@ func (hrs *httpReadSeeker) Seek(offset int64, whence int) (int64, error) {
|
||||
abs += offset
|
||||
case io.SeekEnd:
|
||||
if hrs.size == -1 {
|
||||
return 0, errors.Wrap(errdefs.ErrUnavailable, "Fetcher.Seek: unknown size, cannot seek from end")
|
||||
return 0, fmt.Errorf("Fetcher.Seek: unknown size, cannot seek from end: %w", errdefs.ErrUnavailable)
|
||||
}
|
||||
abs = hrs.size + offset
|
||||
default:
|
||||
return 0, errors.Wrap(errdefs.ErrInvalidArgument, "Fetcher.Seek: invalid whence")
|
||||
return 0, fmt.Errorf("Fetcher.Seek: invalid whence: %w", errdefs.ErrInvalidArgument)
|
||||
}
|
||||
|
||||
if abs < 0 {
|
||||
return 0, errors.Wrapf(errdefs.ErrInvalidArgument, "Fetcher.Seek: negative offset")
|
||||
return 0, fmt.Errorf("Fetcher.Seek: negative offset: %w", errdefs.ErrInvalidArgument)
|
||||
}
|
||||
|
||||
if abs != hrs.offset {
|
||||
@@ -140,12 +140,12 @@ func (hrs *httpReadSeeker) reader() (io.Reader, error) {
|
||||
// only try to reopen the body request if we are seeking to a value
|
||||
// less than the actual size.
|
||||
if hrs.open == nil {
|
||||
return nil, errors.Wrapf(errdefs.ErrNotImplemented, "cannot open")
|
||||
return nil, fmt.Errorf("cannot open: %w", errdefs.ErrNotImplemented)
|
||||
}
|
||||
|
||||
rc, err := hrs.open(hrs.offset)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "httpReadSeeker: failed open")
|
||||
return nil, fmt.Errorf("httpReadSeeker: failed open: %w", err)
|
||||
}
|
||||
|
||||
if hrs.rc != nil {
|
||||
|
@@ -18,6 +18,8 @@ package docker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -32,7 +34,6 @@ import (
|
||||
remoteserrors "github.com/containerd/containerd/remotes/errors"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type dockerPusher struct {
|
||||
@@ -55,7 +56,7 @@ func (p dockerPusher) Writer(ctx context.Context, opts ...content.WriterOpt) (co
|
||||
}
|
||||
}
|
||||
if wOpts.Ref == "" {
|
||||
return nil, errors.Wrap(errdefs.ErrInvalidArgument, "ref must not be empty")
|
||||
return nil, fmt.Errorf("ref must not be empty: %w", errdefs.ErrInvalidArgument)
|
||||
}
|
||||
return p.push(ctx, wOpts.Desc, wOpts.Ref, true)
|
||||
}
|
||||
@@ -76,22 +77,22 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str
|
||||
status, err := p.tracker.GetStatus(ref)
|
||||
if err == nil {
|
||||
if status.Committed && status.Offset == status.Total {
|
||||
return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "ref %v", ref)
|
||||
return nil, fmt.Errorf("ref %v: %w", ref, errdefs.ErrAlreadyExists)
|
||||
}
|
||||
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")
|
||||
return nil, fmt.Errorf("push is on-going: %w", errdefs.ErrUnavailable)
|
||||
}
|
||||
// TODO: Handle incomplete status
|
||||
} else if !errdefs.IsNotFound(err) {
|
||||
return nil, errors.Wrap(err, "failed to get status")
|
||||
return nil, fmt.Errorf("failed to get status: %w", err)
|
||||
}
|
||||
|
||||
hosts := p.filterHosts(HostCapabilityPush)
|
||||
if len(hosts) == 0 {
|
||||
return nil, errors.Wrap(errdefs.ErrNotFound, "no push hosts")
|
||||
return nil, fmt.Errorf("no push hosts: %w", errdefs.ErrNotFound)
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -143,7 +144,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str
|
||||
},
|
||||
})
|
||||
resp.Body.Close()
|
||||
return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest)
|
||||
return nil, fmt.Errorf("content %v on remote: %w", desc.Digest, errdefs.ErrAlreadyExists)
|
||||
}
|
||||
} else if resp.StatusCode != http.StatusNotFound {
|
||||
err := remoteserrors.NewUnexpectedStatusErr(resp)
|
||||
@@ -205,7 +206,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str
|
||||
Offset: desc.Size,
|
||||
},
|
||||
})
|
||||
return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest)
|
||||
return nil, fmt.Errorf("content %v on remote: %w", desc.Digest, errdefs.ErrAlreadyExists)
|
||||
default:
|
||||
err := remoteserrors.NewUnexpectedStatusErr(resp)
|
||||
log.G(ctx).WithField("resp", resp).WithField("body", string(err.(remoteserrors.ErrUnexpectedStatus).Body)).Debug("unexpected response")
|
||||
@@ -221,7 +222,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str
|
||||
if strings.HasPrefix(location, "/") {
|
||||
lurl, err = url.Parse(lhost.Scheme + "://" + lhost.Host + location)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to parse location %v", location)
|
||||
return nil, fmt.Errorf("unable to parse location %v: %w", location, err)
|
||||
}
|
||||
} else {
|
||||
if !strings.Contains(location, "://") {
|
||||
@@ -229,7 +230,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str
|
||||
}
|
||||
lurl, err = url.Parse(location)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to parse location %v", location)
|
||||
return nil, fmt.Errorf("unable to parse location %v: %w", location, err)
|
||||
}
|
||||
|
||||
if lurl.Host != lhost.Host || lhost.Scheme != lurl.Scheme {
|
||||
@@ -374,7 +375,7 @@ func (pw *pushWriter) Digest() digest.Digest {
|
||||
func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
|
||||
// Check whether read has already thrown an error
|
||||
if _, err := pw.pipe.Write([]byte{}); err != nil && err != io.ErrClosedPipe {
|
||||
return errors.Wrap(err, "pipe error before commit")
|
||||
return fmt.Errorf("pipe error before commit: %w", err)
|
||||
}
|
||||
|
||||
if err := pw.pipe.Close(); err != nil {
|
||||
@@ -397,11 +398,11 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
|
||||
|
||||
status, err := pw.tracker.GetStatus(pw.ref)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get status")
|
||||
return fmt.Errorf("failed to get status: %w", err)
|
||||
}
|
||||
|
||||
if size > 0 && size != status.Offset {
|
||||
return errors.Errorf("unexpected size %d, expected %d", status.Offset, size)
|
||||
return fmt.Errorf("unexpected size %d, expected %d", status.Offset, size)
|
||||
}
|
||||
|
||||
if expected == "" {
|
||||
@@ -410,11 +411,11 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
|
||||
|
||||
actual, err := digest.Parse(resp.Header.Get("Docker-Content-Digest"))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "invalid content digest in response")
|
||||
return fmt.Errorf("invalid content digest in response: %w", err)
|
||||
}
|
||||
|
||||
if actual != expected {
|
||||
return errors.Errorf("got digest %s, expected %s", actual, expected)
|
||||
return fmt.Errorf("got digest %s, expected %s", actual, expected)
|
||||
}
|
||||
|
||||
status.Committed = true
|
||||
|
@@ -17,10 +17,9 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// HostCapabilities represent the capabilities of the registry
|
||||
|
@@ -18,6 +18,7 @@ package docker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -34,7 +35,6 @@ import (
|
||||
"github.com/containerd/containerd/version"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context/ctxhttp"
|
||||
)
|
||||
@@ -254,7 +254,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
|
||||
|
||||
hosts := base.filterHosts(caps)
|
||||
if len(hosts) == 0 {
|
||||
return "", ocispec.Descriptor{}, errors.Wrap(errdefs.ErrNotFound, "no resolve hosts")
|
||||
return "", ocispec.Descriptor{}, fmt.Errorf("no resolve hosts: %w", errdefs.ErrNotFound)
|
||||
}
|
||||
|
||||
ctx, err = ContextWithRepositoryScope(ctx, refspec, false)
|
||||
@@ -279,7 +279,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
|
||||
resp, err := req.doWithRetries(ctx, nil)
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrInvalidAuthorization) {
|
||||
err = errors.Wrapf(err, "pull access denied, repository does not exist or may require authorization")
|
||||
err = fmt.Errorf("pull access denied, repository does not exist or may require authorization: %w", err)
|
||||
}
|
||||
// Store the error for referencing later
|
||||
if firstErr == nil {
|
||||
@@ -298,11 +298,11 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
|
||||
if resp.StatusCode > 399 {
|
||||
// Set firstErr when encountering the first non-404 status code.
|
||||
if firstErr == nil {
|
||||
firstErr = errors.Errorf("pulling from host %s failed with status code %v: %v", host.Host, u, resp.Status)
|
||||
firstErr = fmt.Errorf("pulling from host %s failed with status code %v: %v", host.Host, u, resp.Status)
|
||||
}
|
||||
continue // try another host
|
||||
}
|
||||
return "", ocispec.Descriptor{}, errors.Errorf("pulling from host %s failed with unexpected status code %v: %v", host.Host, u, resp.Status)
|
||||
return "", ocispec.Descriptor{}, fmt.Errorf("pulling from host %s failed with unexpected status code %v: %v", host.Host, u, resp.Status)
|
||||
}
|
||||
size := resp.ContentLength
|
||||
contentType := getManifestMediaType(resp)
|
||||
@@ -318,7 +318,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
|
||||
|
||||
if dgstHeader != "" && size != -1 {
|
||||
if err := dgstHeader.Validate(); err != nil {
|
||||
return "", ocispec.Descriptor{}, errors.Wrapf(err, "%q in header not a valid digest", dgstHeader)
|
||||
return "", ocispec.Descriptor{}, fmt.Errorf("%q in header not a valid digest: %w", dgstHeader, err)
|
||||
}
|
||||
dgst = dgstHeader
|
||||
}
|
||||
@@ -366,7 +366,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
|
||||
// Prevent resolving to excessively large manifests
|
||||
if size > MaxManifestSize {
|
||||
if firstErr == nil {
|
||||
firstErr = errors.Wrapf(errdefs.ErrNotFound, "rejecting %d byte manifest for %s", size, ref)
|
||||
firstErr = fmt.Errorf("rejecting %d byte manifest for %s: %w", size, ref, errdefs.ErrNotFound)
|
||||
}
|
||||
continue
|
||||
}
|
||||
@@ -387,7 +387,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
|
||||
// means that either no registries were given or each registry returned 404.
|
||||
|
||||
if firstErr == nil {
|
||||
firstErr = errors.Wrap(errdefs.ErrNotFound, ref)
|
||||
firstErr = fmt.Errorf("%s: %w", ref, errdefs.ErrNotFound)
|
||||
}
|
||||
|
||||
return "", ocispec.Descriptor{}, firstErr
|
||||
@@ -547,7 +547,7 @@ func (r *request) do(ctx context.Context) (*http.Response, error) {
|
||||
ctx = log.WithLogger(ctx, log.G(ctx).WithField("url", u))
|
||||
log.G(ctx).WithFields(requestFields(req)).Debug("do request")
|
||||
if err := r.authorize(ctx, req); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to authorize")
|
||||
return nil, fmt.Errorf("failed to authorize: %w", err)
|
||||
}
|
||||
|
||||
var client = &http.Client{}
|
||||
@@ -559,13 +559,16 @@ func (r *request) do(ctx context.Context) (*http.Response, error) {
|
||||
if len(via) >= 10 {
|
||||
return errors.New("stopped after 10 redirects")
|
||||
}
|
||||
return errors.Wrap(r.authorize(ctx, req), "failed to authorize redirect")
|
||||
if err := r.authorize(ctx, req); err != nil {
|
||||
return fmt.Errorf("failed to authorize redirect: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := ctxhttp.Do(ctx, client, req)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to do request")
|
||||
return nil, fmt.Errorf("failed to do request: %w", err)
|
||||
}
|
||||
log.G(ctx).WithFields(responseFields(resp)).Debug("fetch response received")
|
||||
return resp, nil
|
||||
|
@@ -21,6 +21,7 @@ import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -35,7 +36,6 @@ import (
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
specs "github.com/opencontainers/image-spec/specs-go"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func TestHTTPResolver(t *testing.T) {
|
||||
@@ -588,7 +588,7 @@ func testFetch(ctx context.Context, f remotes.Fetcher, desc ocispec.Descriptor)
|
||||
dgstr := desc.Digest.Algorithm().Digester()
|
||||
io.Copy(dgstr.Hash(), r)
|
||||
if dgstr.Digest() != desc.Digest {
|
||||
return errors.Errorf("content mismatch: %s != %s", dgstr.Digest(), desc.Digest)
|
||||
return fmt.Errorf("content mismatch: %s != %s", dgstr.Digest(), desc.Digest)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -597,14 +597,14 @@ func testFetch(ctx context.Context, f remotes.Fetcher, desc ocispec.Descriptor)
|
||||
func testocimanifest(ctx context.Context, f remotes.Fetcher, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
||||
r, err := f.Fetch(ctx, desc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to fetch %s", desc.Digest)
|
||||
return nil, fmt.Errorf("failed to fetch %s: %w", desc.Digest, err)
|
||||
}
|
||||
p, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dgst := desc.Digest.Algorithm().FromBytes(p); dgst != desc.Digest {
|
||||
return nil, errors.Errorf("digest mismatch: %s != %s", dgst, desc.Digest)
|
||||
return nil, fmt.Errorf("digest mismatch: %s != %s", dgst, desc.Digest)
|
||||
}
|
||||
|
||||
var manifest ocispec.Manifest
|
||||
|
@@ -21,6 +21,7 @@ import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
@@ -28,8 +29,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/containerd/containerd/archive/compression"
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
@@ -39,7 +38,7 @@ import (
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
specs "github.com/opencontainers/image-spec/specs-go"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -158,12 +157,12 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De
|
||||
|
||||
history, diffIDs, err := c.schema1ManifestHistory()
|
||||
if err != nil {
|
||||
return ocispec.Descriptor{}, errors.Wrap(err, "schema 1 conversion failed")
|
||||
return ocispec.Descriptor{}, fmt.Errorf("schema 1 conversion failed: %w", err)
|
||||
}
|
||||
|
||||
var img ocispec.Image
|
||||
if err := json.Unmarshal([]byte(c.pulledManifest.History[0].V1Compatibility), &img); err != nil {
|
||||
return ocispec.Descriptor{}, errors.Wrap(err, "failed to unmarshal image from schema 1 history")
|
||||
return ocispec.Descriptor{}, fmt.Errorf("failed to unmarshal image from schema 1 history: %w", err)
|
||||
}
|
||||
|
||||
img.History = history
|
||||
@@ -174,7 +173,7 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De
|
||||
|
||||
b, err := json.MarshalIndent(img, "", " ")
|
||||
if err != nil {
|
||||
return ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal image")
|
||||
return ocispec.Descriptor{}, fmt.Errorf("failed to marshal image: %w", err)
|
||||
}
|
||||
|
||||
config := ocispec.Descriptor{
|
||||
@@ -198,7 +197,7 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De
|
||||
|
||||
mb, err := json.MarshalIndent(manifest, "", " ")
|
||||
if err != nil {
|
||||
return ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal image")
|
||||
return ocispec.Descriptor{}, fmt.Errorf("failed to marshal image: %w", err)
|
||||
}
|
||||
|
||||
desc := ocispec.Descriptor{
|
||||
@@ -215,12 +214,12 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De
|
||||
|
||||
ref := remotes.MakeRefKey(ctx, desc)
|
||||
if err := content.WriteBlob(ctx, c.contentStore, ref, bytes.NewReader(mb), desc, content.WithLabels(labels)); err != nil {
|
||||
return ocispec.Descriptor{}, errors.Wrap(err, "failed to write image manifest")
|
||||
return ocispec.Descriptor{}, fmt.Errorf("failed to write image manifest: %w", err)
|
||||
}
|
||||
|
||||
ref = remotes.MakeRefKey(ctx, config)
|
||||
if err := content.WriteBlob(ctx, c.contentStore, ref, bytes.NewReader(b), config); err != nil {
|
||||
return ocispec.Descriptor{}, errors.Wrap(err, "failed to write image config")
|
||||
return ocispec.Descriptor{}, fmt.Errorf("failed to write image config: %w", err)
|
||||
}
|
||||
|
||||
return desc, nil
|
||||
@@ -349,7 +348,7 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
|
||||
if desc.Size == -1 {
|
||||
info, err := c.contentStore.Info(ctx, desc.Digest)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get blob info")
|
||||
return fmt.Errorf("failed to get blob info: %w", err)
|
||||
}
|
||||
desc.Size = info.Size
|
||||
}
|
||||
@@ -370,7 +369,7 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
|
||||
}
|
||||
|
||||
if _, err := c.contentStore.Update(ctx, cinfo, "labels.containerd.io/uncompressed", fmt.Sprintf("labels.%s", labelDockerSchema1EmptyLayer)); err != nil {
|
||||
return errors.Wrap(err, "failed to update uncompressed label")
|
||||
return fmt.Errorf("failed to update uncompressed label: %w", err)
|
||||
}
|
||||
|
||||
c.mu.Lock()
|
||||
@@ -384,7 +383,7 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
|
||||
func (c *Converter) reuseLabelBlobState(ctx context.Context, desc ocispec.Descriptor) (bool, error) {
|
||||
cinfo, err := c.contentStore.Info(ctx, desc.Digest)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "failed to get blob info")
|
||||
return false, fmt.Errorf("failed to get blob info: %w", err)
|
||||
}
|
||||
desc.Size = cinfo.Size
|
||||
|
||||
@@ -441,7 +440,7 @@ func (c *Converter) schema1ManifestHistory() ([]ocispec.History, []digest.Digest
|
||||
for i := range m.History {
|
||||
var h v1History
|
||||
if err := json.Unmarshal([]byte(m.History[i].V1Compatibility), &h); err != nil {
|
||||
return nil, nil, errors.Wrap(err, "failed to unmarshal history")
|
||||
return nil, nil, fmt.Errorf("failed to unmarshal history: %w", err)
|
||||
}
|
||||
|
||||
blobSum := m.FSLayers[i].BlobSum
|
||||
@@ -553,7 +552,7 @@ func stripSignature(b []byte) ([]byte, error) {
|
||||
}
|
||||
pb, err := joseBase64UrlDecode(sig.Signatures[0].Protected)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not decode %s", sig.Signatures[0].Protected)
|
||||
return nil, fmt.Errorf("could not decode %s: %w", sig.Signatures[0].Protected, err)
|
||||
}
|
||||
|
||||
var protected protectedBlock
|
||||
@@ -567,7 +566,7 @@ func stripSignature(b []byte) ([]byte, error) {
|
||||
|
||||
tail, err := joseBase64UrlDecode(protected.Tail)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "invalid tail base 64 value")
|
||||
return nil, fmt.Errorf("invalid tail base 64 value: %w", err)
|
||||
}
|
||||
|
||||
return append(b[:protected.Length], tail...), nil
|
||||
|
@@ -17,12 +17,12 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/moby/locker"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Status of a content operation
|
||||
@@ -67,7 +67,7 @@ func (t *memoryStatusTracker) GetStatus(ref string) (Status, error) {
|
||||
defer t.m.Unlock()
|
||||
status, ok := t.statuses[ref]
|
||||
if !ok {
|
||||
return Status{}, errors.Wrapf(errdefs.ErrNotFound, "status for ref %v", ref)
|
||||
return Status{}, fmt.Errorf("status for ref %v: %w", ref, errdefs.ErrNotFound)
|
||||
}
|
||||
return status, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user