1
0
mirror of https://github.com/docker/cli.git synced 2026-01-06 05:41:44 +03:00

cli/command/image: use stdlib errors

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-09-08 19:26:40 +02:00
parent f10041c724
commit 179dc0228c
8 changed files with 48 additions and 46 deletions

View File

@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"os"
@@ -26,7 +27,6 @@ import (
"github.com/moby/moby/api/types/container"
registrytypes "github.com/moby/moby/api/types/registry"
"github.com/moby/moby/client"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -212,7 +212,7 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
if options.imageIDFile != "" {
// Avoid leaving a stale file if we eventually fail
if err := os.Remove(options.imageIDFile); err != nil && !os.IsNotExist(err) {
return errors.Wrap(err, "Removing image ID file")
return fmt.Errorf("removing image ID file: %w", err)
}
}
@@ -226,13 +226,13 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
case build.ContextTypeLocal:
contextDir, relDockerfile, err = build.GetContextFromLocalDir(options.context, options.dockerfileName)
if err != nil {
return errors.Errorf("unable to prepare context: %s", err)
return fmt.Errorf("unable to prepare context: %s", err)
}
if strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
// Dockerfile is outside of build-context; read the Dockerfile and pass it as dockerfileCtx
// Dockerfile is outside build-context; read the Dockerfile and pass it as dockerfileCtx
dockerfileCtx, err = os.Open(options.dockerfileName)
if err != nil {
return errors.Errorf("unable to open Dockerfile: %v", err)
return fmt.Errorf("unable to open Dockerfile: %w", err)
}
defer dockerfileCtx.Close()
}
@@ -240,7 +240,7 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
var tempDir string
tempDir, relDockerfile, err = build.GetContextFromGitURL(options.context, options.dockerfileName)
if err != nil {
return errors.Errorf("unable to prepare context: %s", err)
return fmt.Errorf("unable to prepare context: %w", err)
}
defer func() {
_ = os.RemoveAll(tempDir)
@@ -252,7 +252,7 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
_, _ = fmt.Fprintln(dockerCli.Err(), progBuff)
}
default:
return errors.Errorf("unable to prepare context: path %q not found", options.context)
return fmt.Errorf("unable to prepare context: path %q not found", options.context)
}
// read from a directory into tar archive
@@ -263,7 +263,7 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
}
if err := build.ValidateContextDirectory(contextDir, excludes); err != nil {
return errors.Wrap(err, "error checking context")
return fmt.Errorf("error checking context: %w", err)
}
// And canonicalize dockerfile name to a platform-independent one
@@ -370,7 +370,7 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
if options.imageIDFile != "" {
if imageID == "" {
return errors.Errorf("Server did not provide an image ID. Cannot write %s", options.imageIDFile)
return fmt.Errorf("server did not provide an image ID. Cannot write %s", options.imageIDFile)
}
if err := os.WriteFile(options.imageIDFile, []byte(imageID), 0o666); err != nil {
return err

View File

@@ -6,6 +6,7 @@ import (
"bytes"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
"net/http"
@@ -22,7 +23,6 @@ import (
"github.com/moby/moby/api/pkg/progress"
"github.com/moby/moby/api/pkg/streamformatter"
"github.com/moby/patternmatcher"
"github.com/pkg/errors"
)
const (
@@ -49,10 +49,10 @@ func ValidateContextDirectory(srcPath string, excludes []string) error {
return filepath.Walk(contextRoot, func(filePath string, f os.FileInfo, err error) error {
if err != nil {
if os.IsPermission(err) {
return errors.Errorf("can't stat '%s'", filePath)
return fmt.Errorf("can't stat '%s'", filePath)
}
if os.IsNotExist(err) {
return errors.Errorf("file ('%s') not found or excluded by .dockerignore", filePath)
return fmt.Errorf("file ('%s') not found or excluded by .dockerignore", filePath)
}
return err
}
@@ -78,7 +78,7 @@ func ValidateContextDirectory(srcPath string, excludes []string) error {
if !f.IsDir() {
currentFile, err := os.Open(filePath)
if err != nil && os.IsPermission(err) {
return errors.Errorf("no permission to read from '%s'", filePath)
return fmt.Errorf("no permission to read from '%s'", filePath)
}
currentFile.Close()
}
@@ -105,7 +105,7 @@ func DetectArchiveReader(input io.ReadCloser) (rc io.ReadCloser, isArchive bool,
magic, err := buf.Peek(archiveHeaderSize * 2)
if err != nil && err != io.EOF {
return nil, false, errors.Errorf("failed to peek context header from STDIN: %v", err)
return nil, false, fmt.Errorf("failed to peek context header from STDIN: %w", err)
}
return newReadCloserWrapper(buf, func() error { return input.Close() }), IsArchive(magic), nil
@@ -118,7 +118,7 @@ func WriteTempDockerfile(rc io.ReadCloser) (dockerfileDir string, err error) {
// err is a named return value, due to the defer call below.
dockerfileDir, err = os.MkdirTemp("", "docker-build-tempdockerfile-")
if err != nil {
return "", errors.Errorf("unable to create temporary context directory: %v", err)
return "", fmt.Errorf("unable to create temporary context directory: %w", err)
}
defer func() {
if err != nil {
@@ -194,11 +194,11 @@ func IsArchive(header []byte) bool {
// success.
func GetContextFromGitURL(gitURL, dockerfileName string) (string, string, error) {
if _, err := exec.LookPath("git"); err != nil {
return "", "", errors.Wrapf(err, "unable to find 'git'")
return "", "", fmt.Errorf("unable to find 'git': %w", err)
}
absContextDir, err := git.Clone(gitURL)
if err != nil {
return "", "", errors.Wrapf(err, "unable to 'git clone' to temporary context directory")
return "", "", fmt.Errorf("unable to 'git clone' to temporary context directory: %w", err)
}
absContextDir, err = ResolveAndValidateContextPath(absContextDir)
@@ -207,7 +207,7 @@ func GetContextFromGitURL(gitURL, dockerfileName string) (string, string, error)
}
relDockerfile, err := getDockerfileRelPath(absContextDir, dockerfileName)
if err == nil && strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
return "", "", errors.Errorf("the Dockerfile (%s) must be within the build context", dockerfileName)
return "", "", fmt.Errorf("the Dockerfile (%s) must be within the build context", dockerfileName)
}
return absContextDir, relDockerfile, err
@@ -220,7 +220,7 @@ func GetContextFromGitURL(gitURL, dockerfileName string) (string, string, error)
func GetContextFromURL(out io.Writer, remoteURL, dockerfileName string) (io.ReadCloser, string, error) {
response, err := getWithStatusError(remoteURL)
if err != nil {
return nil, "", errors.Errorf("unable to download remote context %s: %v", remoteURL, err)
return nil, "", fmt.Errorf("unable to download remote context %s: %w", remoteURL, err)
}
progressOutput := streamformatter.NewProgressOutput(out)
@@ -244,9 +244,9 @@ func getWithStatusError(url string) (resp *http.Response, err error) {
body, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return nil, errors.Wrapf(err, "%s: error reading body", msg)
return nil, fmt.Errorf("%s: error reading body: %w", msg, err)
}
return nil, errors.Errorf("%s: %s", msg, bytes.TrimSpace(body))
return nil, fmt.Errorf("%s: %s", msg, bytes.TrimSpace(body))
}
// GetContextFromLocalDir uses the given local directory as context for a
@@ -264,7 +264,7 @@ func GetContextFromLocalDir(localDir, dockerfileName string) (string, string, er
// current directory and not the context directory.
if dockerfileName != "" && dockerfileName != "-" {
if dockerfileName, err = filepath.Abs(dockerfileName); err != nil {
return "", "", errors.Errorf("unable to get absolute path to Dockerfile: %v", err)
return "", "", fmt.Errorf("unable to get absolute path to Dockerfile: %w", err)
}
}
@@ -277,7 +277,7 @@ func GetContextFromLocalDir(localDir, dockerfileName string) (string, string, er
func ResolveAndValidateContextPath(givenContextDir string) (string, error) {
absContextDir, err := filepath.Abs(givenContextDir)
if err != nil {
return "", errors.Errorf("unable to get absolute context directory of given context directory %q: %v", givenContextDir, err)
return "", fmt.Errorf("unable to get absolute context directory of given context directory %q: %w", givenContextDir, err)
}
// The context dir might be a symbolic link, so follow it to the actual
@@ -290,17 +290,17 @@ func ResolveAndValidateContextPath(givenContextDir string) (string, error) {
if !isUNC(absContextDir) {
absContextDir, err = filepath.EvalSymlinks(absContextDir)
if err != nil {
return "", errors.Errorf("unable to evaluate symlinks in context path: %v", err)
return "", fmt.Errorf("unable to evaluate symlinks in context path: %w", err)
}
}
stat, err := os.Lstat(absContextDir)
if err != nil {
return "", errors.Errorf("unable to stat context directory %q: %v", absContextDir, err)
return "", fmt.Errorf("unable to stat context directory %q: %w", absContextDir, err)
}
if !stat.IsDir() {
return "", errors.Errorf("context must be a directory: %s", absContextDir)
return "", fmt.Errorf("context must be a directory: %s", absContextDir)
}
return absContextDir, err
}
@@ -345,20 +345,20 @@ func getDockerfileRelPath(absContextDir, givenDockerfile string) (string, error)
if !isUNC(absDockerfile) {
absDockerfile, err = filepath.EvalSymlinks(absDockerfile)
if err != nil {
return "", errors.Errorf("unable to evaluate symlinks in Dockerfile path: %v", err)
return "", fmt.Errorf("unable to evaluate symlinks in Dockerfile path: %w", err)
}
}
if _, err := os.Lstat(absDockerfile); err != nil {
if os.IsNotExist(err) {
return "", errors.Errorf("Cannot locate Dockerfile: %q", absDockerfile)
return "", fmt.Errorf("cannot locate Dockerfile: %q", absDockerfile)
}
return "", errors.Errorf("unable to stat Dockerfile: %v", err)
return "", fmt.Errorf("unable to stat Dockerfile: %w", err)
}
relDockerfile, err := filepath.Rel(absContextDir, absDockerfile)
if err != nil {
return "", errors.Errorf("unable to get relative Dockerfile path: %v", err)
return "", fmt.Errorf("unable to get relative Dockerfile path: %w", err)
}
return relDockerfile, nil
@@ -443,7 +443,7 @@ func Compress(buildCtx io.ReadCloser) (io.ReadCloser, error) {
defer buildCtx.Close()
if _, err := io.Copy(compressWriter, buildCtx); err != nil {
pipeWriter.CloseWithError(errors.Wrap(err, "failed to compress context"))
pipeWriter.CloseWithError(fmt.Errorf("failed to compress context: %w", err))
compressWriter.Close()
return
}

View File

@@ -2,6 +2,7 @@ package image
import (
"context"
"fmt"
"github.com/containerd/platforms"
"github.com/docker/cli/cli"
@@ -10,7 +11,6 @@ import (
"github.com/docker/cli/cli/command/formatter"
flagsHelper "github.com/docker/cli/cli/flags"
"github.com/moby/moby/client"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -61,7 +61,7 @@ func runHistory(ctx context.Context, dockerCli command.Cli, opts historyOptions)
if opts.platform != "" {
p, err := platforms.Parse(opts.platform)
if err != nil {
return errors.Wrap(err, "invalid platform")
return fmt.Errorf("invalid platform: %w", err)
}
options = append(options, client.ImageHistoryWithPlatform(p))
}

View File

@@ -2,6 +2,8 @@ package image
import (
"context"
"errors"
"fmt"
"io"
"github.com/containerd/platforms"
@@ -12,7 +14,6 @@ import (
"github.com/moby/moby/client"
"github.com/moby/sys/sequential"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -60,7 +61,7 @@ func runLoad(ctx context.Context, dockerCli command.Cli, opts loadOptions) error
// To avoid getting stuck, verify that a tar file is given either in
// the input flag or through stdin and if not display an error message and exit.
if dockerCli.In().IsTerminal() {
return errors.Errorf("requested load from stdin, but stdin is empty")
return errors.New("requested load from stdin, but stdin is empty")
}
default:
// We use sequential.Open to use sequential file access on Windows, avoiding
@@ -82,7 +83,7 @@ func runLoad(ctx context.Context, dockerCli command.Cli, opts loadOptions) error
for _, p := range opts.platform {
pp, err := platforms.Parse(p)
if err != nil {
return errors.Wrap(err, "invalid platform")
return fmt.Errorf("invalid platform: %w", err)
}
platformList = append(platformList, pp)
}

View File

@@ -2,6 +2,7 @@ package image
import (
"context"
"errors"
"fmt"
"strconv"
"strings"
@@ -12,7 +13,6 @@ import (
"github.com/docker/cli/internal/prompt"
"github.com/docker/cli/opts"
"github.com/docker/go-units"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)

View File

@@ -6,6 +6,7 @@ package image
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
@@ -23,7 +24,6 @@ import (
"github.com/moby/moby/client"
"github.com/morikuni/aec"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)

View File

@@ -2,6 +2,8 @@ package image
import (
"context"
"errors"
"fmt"
"io"
"github.com/containerd/platforms"
@@ -11,7 +13,6 @@ import (
"github.com/moby/moby/client"
"github.com/moby/sys/atomicwriter"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -58,7 +59,7 @@ func runSave(ctx context.Context, dockerCLI command.Cli, opts saveOptions) error
for _, p := range opts.platform {
pp, err := platforms.Parse(p)
if err != nil {
return errors.Wrap(err, "invalid platform")
return fmt.Errorf("invalid platform: %w", err)
}
platformList = append(platformList, pp)
}
@@ -75,7 +76,7 @@ func runSave(ctx context.Context, dockerCLI command.Cli, opts saveOptions) error
} else {
writer, err := atomicwriter.New(opts.output, 0o600)
if err != nil {
return errors.Wrap(err, "failed to save image")
return fmt.Errorf("failed to save image: %w", err)
}
defer writer.Close()
output = writer

View File

@@ -3,6 +3,7 @@ package image
import (
"context"
"encoding/hex"
"errors"
"fmt"
"io"
@@ -16,7 +17,6 @@ import (
registrytypes "github.com/moby/moby/api/types/registry"
"github.com/moby/moby/client"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
notaryclient "github.com/theupdateframework/notary/client"
"github.com/theupdateframework/notary/tuf/data"
@@ -102,7 +102,7 @@ func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.Image
func getTrustedPullTargets(cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth) ([]target, error) {
notaryRepo, err := newNotaryClient(cli, imgRefAndAuth)
if err != nil {
return nil, errors.Wrap(err, "error establishing connection to trust repository")
return nil, fmt.Errorf("error establishing connection to trust repository: %w", err)
}
ref := imgRefAndAuth.Reference()
@@ -128,7 +128,7 @@ func getTrustedPullTargets(cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth)
refs = append(refs, t)
}
if len(refs) == 0 {
return nil, trust.NotaryError(ref.Name(), errors.Errorf("No trusted tags for %s", ref.Name()))
return nil, trust.NotaryError(ref.Name(), fmt.Errorf("no trusted tags for %s", ref.Name()))
}
return refs, nil
}
@@ -140,7 +140,7 @@ func getTrustedPullTargets(cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth)
// Only get the tag if it's in the top level targets role or the releases delegation role
// ignore it if it's in any other delegation roles
if t.Role != trust.ReleasesRole && t.Role != data.CanonicalTargetsRole {
return nil, trust.NotaryError(ref.Name(), errors.Errorf("No trust data for %s", tagged.Tag()))
return nil, trust.NotaryError(ref.Name(), fmt.Errorf("no trust data for %s", tagged.Tag()))
}
logrus.Debugf("retrieving target for %s role", t.Role)
@@ -181,7 +181,7 @@ func TrustedReference(ctx context.Context, cli command.Cli, ref reference.NamedT
notaryRepo, err := newNotaryClient(cli, imgRefAndAuth)
if err != nil {
return nil, errors.Wrap(err, "error establishing connection to trust repository")
return nil, fmt.Errorf("error establishing connection to trust repository: %w", err)
}
t, err := notaryRepo.GetTargetByName(ref.Tag(), trust.ReleasesRole, data.CanonicalTargetsRole)