diff --git a/.golangci.yml b/.golangci.yml index 7d28e1d72c..eb58d4fe1a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -21,6 +21,7 @@ linters: - dogsled # Detects assignments with too many blank identifiers. - dupword # Detects duplicate words. - durationcheck # Detect cases where two time.Duration values are being multiplied in possibly erroneous ways. + - errorlint # Detects code that will cause problems with the error wrapping scheme introduced in Go 1.13. - errchkjson # Detects unsupported types passed to json encoding functions and reports if checks for the returned error can be omitted. - exhaustive # Detects missing options in enum switch statements. - exptostd # Detects functions from golang.org/x/exp/ that can be replaced by std functions. @@ -75,6 +76,13 @@ linters: - "false" # some tests use this as expected output - "root" # for tests using "ls" output with files owned by "root:root" + errorlint: + # Check whether fmt.Errorf uses the %w verb for formatting errors. + # See the https://github.com/polyfloyd/go-errorlint for caveats. + errorf: false + # Check for plain type assertions and type switches. + asserts: false + exhaustive: # Program elements to check for exhaustiveness. # Default: [ switch ] diff --git a/api/server/httputils/httputils.go b/api/server/httputils/httputils.go index b2dccfd3e2..451d54e4f3 100644 --- a/api/server/httputils/httputils.go +++ b/api/server/httputils/httputils.go @@ -74,7 +74,7 @@ func ReadJSON(r *http.Request, out interface{}) error { err = dec.Decode(out) defer r.Body.Close() if err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { return errdefs.InvalidParameter(errors.New("invalid JSON: got EOF while reading request body")) } return errdefs.InvalidParameter(errors.Wrap(err, "invalid JSON")) diff --git a/api/server/router/distribution/distribution_routes.go b/api/server/router/distribution/distribution_routes.go index 16963925b5..03e69238fb 100644 --- a/api/server/router/distribution/distribution_routes.go +++ b/api/server/router/distribution/distribution_routes.go @@ -108,14 +108,14 @@ func (dr *distributionRouter) fetchManifest(ctx context.Context, distrepo distri } mnfst, err := mnfstsrvc.Get(ctx, distributionInspect.Descriptor.Digest) if err != nil { - switch err { - case reference.ErrReferenceInvalidFormat, - reference.ErrTagInvalidFormat, - reference.ErrDigestInvalidFormat, - reference.ErrNameContainsUppercase, - reference.ErrNameEmpty, - reference.ErrNameTooLong, - reference.ErrNameNotCanonical: + switch { + case errors.Is(err, reference.ErrReferenceInvalidFormat), + errors.Is(err, reference.ErrTagInvalidFormat), + errors.Is(err, reference.ErrDigestInvalidFormat), + errors.Is(err, reference.ErrNameContainsUppercase), + errors.Is(err, reference.ErrNameEmpty), + errors.Is(err, reference.ErrNameTooLong), + errors.Is(err, reference.ErrNameNotCanonical): return registry.DistributionInspect{}, errdefs.InvalidParameter(err) } return registry.DistributionInspect{}, err diff --git a/builder/remotecontext/remote.go b/builder/remotecontext/remote.go index 7258a9b010..67c878a42d 100644 --- a/builder/remotecontext/remote.go +++ b/builder/remotecontext/remote.go @@ -96,7 +96,7 @@ func inspectResponse(ct string, r io.Reader, clen int64) (string, io.Reader, err if rlen == 0 { return ct, r, errors.New("empty response") } - if err != nil && err != io.EOF { + if err != nil && !errors.Is(err, io.EOF) { return ct, r, err } diff --git a/client/container_logs_test.go b/client/container_logs_test.go index 1b0fb7252a..b18eecda69 100644 --- a/client/container_logs_test.go +++ b/client/container_logs_test.go @@ -3,6 +3,7 @@ package client import ( "bytes" "context" + "errors" "fmt" "io" "log" @@ -167,7 +168,7 @@ func ExampleClient_ContainerLogs_withTimeout() { } _, err = io.Copy(os.Stdout, reader) - if err != nil && err != io.EOF { + if err != nil && !errors.Is(err, io.EOF) { log.Fatal(err) } } diff --git a/client/events_test.go b/client/events_test.go index b699ea28c8..84042c7522 100644 --- a/client/events_test.go +++ b/client/events_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "io" "net/http" @@ -143,7 +144,7 @@ func TestEvents(t *testing.T) { for { select { case err := <-errs: - if err != nil && err != io.EOF { + if err != nil && !errors.Is(err, io.EOF) { t.Fatal(err) } diff --git a/client/service_logs_test.go b/client/service_logs_test.go index a670cbd132..e4d79af11e 100644 --- a/client/service_logs_test.go +++ b/client/service_logs_test.go @@ -3,6 +3,7 @@ package client import ( "bytes" "context" + "errors" "fmt" "io" "log" @@ -138,7 +139,7 @@ func ExampleClient_ServiceLogs_withTimeout() { } _, err = io.Copy(os.Stdout, reader) - if err != nil && err != io.EOF { + if err != nil && !errors.Is(err, io.EOF) { log.Fatal(err) } } diff --git a/cmd/docker-proxy/udp_proxy_linux.go b/cmd/docker-proxy/udp_proxy_linux.go index 560d893d7e..7253d30632 100644 --- a/cmd/docker-proxy/udp_proxy_linux.go +++ b/cmd/docker-proxy/udp_proxy_linux.go @@ -121,7 +121,7 @@ func (proxy *UDPProxy) replyLoop(cte *connTrackEntry, serverAddr net.IP, clientA again: read, err := cte.conn.Read(readBuf) if err != nil { - if err, ok := err.(*net.OpError); ok && err.Err == syscall.ECONNREFUSED { + if err, ok := err.(*net.OpError); ok && errors.Is(err.Err, syscall.ECONNREFUSED) { // This will happen if the last write failed // (e.g: nothing is actually listening on the // proxied port on the container), ignore it diff --git a/container/stream/attach.go b/container/stream/attach.go index 87f8d89df1..abf78b5d38 100644 --- a/container/stream/attach.go +++ b/container/stream/attach.go @@ -86,7 +86,7 @@ func (c *Config) CopyStreams(ctx context.Context, cfg *AttachConfig) <-chan erro } else { _, err = pools.Copy(cfg.CStdin, cfg.Stdin) } - if err == io.ErrClosedPipe { + if errors.Is(err, io.ErrClosedPipe) { err = nil } if err != nil { @@ -109,7 +109,7 @@ func (c *Config) CopyStreams(ctx context.Context, cfg *AttachConfig) <-chan erro }() _, err := pools.Copy(stream, streamPipe) - if err == io.ErrClosedPipe { + if errors.Is(err, io.ErrClosedPipe) { err = nil } if err != nil { diff --git a/container/stream/bytespipe/buffer_test.go b/container/stream/bytespipe/buffer_test.go index 2a849029ce..3567bc5e5d 100644 --- a/container/stream/bytespipe/buffer_test.go +++ b/container/stream/bytespipe/buffer_test.go @@ -2,6 +2,7 @@ package bytespipe import ( "bytes" + "errors" "testing" ) @@ -42,7 +43,7 @@ func TestFixedBufferLen(t *testing.T) { if n != 0 { t.Fatalf("expected no bytes to be written to buffer, got %d", n) } - if err != errBufferFull { + if !errors.Is(err, errBufferFull) { t.Fatalf("expected errBufferFull, got %v", err) } @@ -99,7 +100,7 @@ func TestFixedBufferWrite(t *testing.T) { if n != 59 { t.Fatalf("expected 59 bytes written before buffer is full, got %d", n) } - if err != errBufferFull { + if !errors.Is(err, errBufferFull) { t.Fatalf("expected errBufferFull, got %v - %v", err, buf.buf[:64]) } } diff --git a/container/stream/bytespipe/bytespipe.go b/container/stream/bytespipe/bytespipe.go index 4577a0c3a9..b0956b581c 100644 --- a/container/stream/bytespipe/bytespipe.go +++ b/container/stream/bytespipe/bytespipe.go @@ -71,7 +71,7 @@ loop0: bp.bufLen += n // errBufferFull is an error we expect to get if the buffer is full - if err != nil && err != errBufferFull { + if err != nil && !errors.Is(err, errBufferFull) { bp.wait.Broadcast() return written, err } diff --git a/daemon/cluster/cluster.go b/daemon/cluster/cluster.go index b5d4092b08..2b1fa2bde8 100644 --- a/daemon/cluster/cluster.go +++ b/daemon/cluster/cluster.go @@ -354,7 +354,7 @@ func (c *Cluster) errNoManager(st nodeState) error { if errors.Is(st.err, errSwarmLocked) { return errSwarmLocked } - if st.err == errSwarmCertificatesExpired { + if errors.Is(st.err, errSwarmCertificatesExpired) { return errSwarmCertificatesExpired } return errors.WithStack(notAvailableError(`This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.`)) @@ -426,7 +426,7 @@ func managerStats(client swarmapi.ControlClient, currentNodeID string) (current } func detectLockedError(err error) error { - if err == swarmnode.ErrInvalidUnlockKey { + if errors.Is(err, swarmnode.ErrInvalidUnlockKey) { return errors.WithStack(errSwarmLocked) } return err diff --git a/daemon/cluster/controllers/plugin/controller_test.go b/daemon/cluster/controllers/plugin/controller_test.go index 68c0af6bce..28ca16fa97 100644 --- a/daemon/cluster/controllers/plugin/controller_test.go +++ b/daemon/cluster/controllers/plugin/controller_test.go @@ -117,7 +117,7 @@ func TestWaitCancel(t *testing.T) { cancel() select { case err := <-chErr: - if err != context.Canceled { + if !errors.Is(err, context.Canceled) { t.Fatal(err) } case <-time.After(10 * time.Second): diff --git a/daemon/cluster/convert/service_test.go b/daemon/cluster/convert/service_test.go index 9ed25cc684..b45f0103f2 100644 --- a/daemon/cluster/convert/service_test.go +++ b/daemon/cluster/convert/service_test.go @@ -1,6 +1,7 @@ package convert import ( + "errors" "testing" containertypes "github.com/docker/docker/api/types/container" @@ -148,7 +149,7 @@ func TestServiceConvertToGRPCGenericRuntimeCustom(t *testing.T) { }, } - if _, err := ServiceSpecToGRPC(s); err != ErrUnsupportedRuntime { + if _, err := ServiceSpecToGRPC(s); !errors.Is(err, ErrUnsupportedRuntime) { t.Fatal(err) } } @@ -409,7 +410,7 @@ func TestServiceConvertToGRPCNetworkAttachmentRuntime(t *testing.T) { if err == nil { t.Fatalf("expected error %v but got no error", ErrUnsupportedRuntime) } - if err != ErrUnsupportedRuntime { + if !errors.Is(err, ErrUnsupportedRuntime) { t.Fatalf("expected error %v but got error %v", ErrUnsupportedRuntime, err) } } @@ -436,7 +437,7 @@ func TestServiceConvertToGRPCMismatchedRuntime(t *testing.T) { } s.TaskTemplate.Runtime = rt - if _, err := ServiceSpecToGRPC(s); err != ErrMismatchedRuntime { + if _, err := ServiceSpecToGRPC(s); !errors.Is(err, ErrMismatchedRuntime) { t.Fatalf("expected %v got %v", ErrMismatchedRuntime, err) } } diff --git a/daemon/cluster/executor/container/controller.go b/daemon/cluster/executor/container/controller.go index 080b75efcd..4f4dc0939d 100644 --- a/daemon/cluster/executor/container/controller.go +++ b/daemon/cluster/executor/container/controller.go @@ -305,7 +305,7 @@ func (r *controller) Wait(pctx context.Context) error { go func() { ectx, cancel := context.WithCancel(ctx) // cancel event context on first event defer cancel() - if err := r.checkHealth(ectx); err == ErrContainerUnhealthy { + if err := r.checkHealth(ectx); errors.Is(err, ErrContainerUnhealthy) { healthErr <- ErrContainerUnhealthy if err := r.Shutdown(ectx); err != nil { log.G(ectx).WithError(err).Debug("shutdown failed on unhealthy") diff --git a/daemon/cluster/executor/container/health_test.go b/daemon/cluster/executor/container/health_test.go index f1e191062f..0c317e1bd1 100644 --- a/daemon/cluster/executor/container/health_test.go +++ b/daemon/cluster/executor/container/health_test.go @@ -4,6 +4,7 @@ package container import ( "context" + "errors" "testing" "time" @@ -80,7 +81,7 @@ func TestHealthStates(t *testing.T) { select { case err := <-errChan: - if err != expectedErr { + if !errors.Is(err, expectedErr) { t.Fatalf("expect error %v, but get %v", expectedErr, err) } case <-timer.C: diff --git a/daemon/cluster/listen_addr.go b/daemon/cluster/listen_addr.go index 425d779e96..000fb739d9 100644 --- a/daemon/cluster/listen_addr.go +++ b/daemon/cluster/listen_addr.go @@ -1,6 +1,7 @@ package cluster import ( + "errors" "fmt" "net" "strings" @@ -26,7 +27,7 @@ func resolveListenAddr(specifiedAddr string) (string, string, error) { // system? If so, use the address from that interface. specifiedIP, err := resolveInputIPAddr(specifiedHost, true) if err != nil { - if err == errBadNetworkIdentifier { + if errors.Is(err, errBadNetworkIdentifier) { err = errBadListenAddr } return "", "", err @@ -57,7 +58,7 @@ func (c *Cluster) resolveAdvertiseAddr(advertiseAddr, listenAddrPort string) (st // system? If so, use the address from that interface. advertiseIP, err := resolveInputIPAddr(advertiseHost, false) if err != nil { - if err == errBadNetworkIdentifier { + if errors.Is(err, errBadNetworkIdentifier) { err = errBadAdvertiseAddr } return "", "", err @@ -72,7 +73,7 @@ func (c *Cluster) resolveAdvertiseAddr(advertiseAddr, listenAddrPort string) (st // that interface. defaultAdvertiseIP, err := resolveInputIPAddr(c.config.DefaultAdvertiseAddr, false) if err != nil { - if err == errBadNetworkIdentifier { + if errors.Is(err, errBadNetworkIdentifier) { err = errBadDefaultAdvertiseAddr } return "", "", err @@ -151,7 +152,7 @@ func resolveDataPathAddr(dataPathAddr string) (string, error) { // If a data path flag is specified try to resolve the IP address. dataPathIP, err := resolveInputIPAddr(dataPathAddr, false) if err != nil { - if err == errBadNetworkIdentifier { + if errors.Is(err, errBadNetworkIdentifier) { err = errBadDataPathAddr } return "", err @@ -216,7 +217,7 @@ func resolveInputIPAddr(input string, isUnspecifiedValid bool) (net.IP, error) { return interfaceAddr, nil } // String matched interface but there is a potential ambiguity to be resolved - if err != errNoSuchInterface { + if !errors.Is(err, errNoSuchInterface) { return nil, err } diff --git a/daemon/cluster/services.go b/daemon/cluster/services.go index 6f48475025..a45f9fcd94 100644 --- a/daemon/cluster/services.go +++ b/daemon/cluster/services.go @@ -513,7 +513,7 @@ func (c *Cluster) ServiceLogs(ctx context.Context, selector *backend.LogSelector default: } subscribeMsg, err := stream.Recv() - if err == io.EOF { + if errors.Is(err, io.EOF) { return } // if we're not io.EOF, push the message in and return diff --git a/daemon/cluster/swarm.go b/daemon/cluster/swarm.go index 51582e47cf..87400b82c3 100644 --- a/daemon/cluster/swarm.go +++ b/daemon/cluster/swarm.go @@ -314,7 +314,7 @@ func (c *Cluster) UnlockSwarm(req types.UnlockRequest) error { if !state.IsActiveManager() { // when manager is not active, // unless it is locked, otherwise return error. - if err := c.errNoManager(state); err != errSwarmLocked { + if err := c.errNoManager(state); !errors.Is(err, errSwarmLocked) { c.mu.RUnlock() return err } diff --git a/daemon/container_operations_unix.go b/daemon/container_operations_unix.go index 7c519364ed..f6d9449609 100644 --- a/daemon/container_operations_unix.go +++ b/daemon/container_operations_unix.go @@ -462,7 +462,7 @@ func killProcessDirectly(ctr *container.Container) error { } if err := unix.Kill(pid, syscall.SIGKILL); err != nil { - if err != unix.ESRCH { + if !errors.Is(err, unix.ESRCH) { return errdefs.System(err) } err = errNoSuchProcess{pid, syscall.SIGKILL} diff --git a/daemon/containerd/cache.go b/daemon/containerd/cache.go index fa7c7a5dff..242a0047a4 100644 --- a/daemon/containerd/cache.go +++ b/daemon/containerd/cache.go @@ -102,7 +102,7 @@ func (c cacheAdaptor) Get(id image.ID) (*image.Image, error) { } return nil }) - if err != nil && err != errFound { + if err != nil && !errors.Is(err, errFound) { return nil, err } @@ -217,7 +217,7 @@ func findContentByUncompressedDigest(ctx context.Context, cs content.Manager, un return errStopWalk }, `labels."containerd.io/uncompressed"==`+uncompressed.String()) - if err != nil && err != errStopWalk { + if err != nil && !errors.Is(err, errStopWalk) { return out, err } if out.Digest == "" { diff --git a/daemon/containerd/image_list.go b/daemon/containerd/image_list.go index 734bfb1ec8..6de698fbe9 100644 --- a/daemon/containerd/image_list.go +++ b/daemon/containerd/image_list.go @@ -699,7 +699,7 @@ func setupLabelFilter(ctx context.Context, store content.Store, fltrs filters.Ar return nil, errFoundConfig })), nil, image.Target) - if err == errFoundConfig { + if errors.Is(err, errFoundConfig) { return true } if err != nil { diff --git a/daemon/containerd/image_manifest.go b/daemon/containerd/image_manifest.go index f7ac8580a0..2e59ffacec 100644 --- a/daemon/containerd/image_manifest.go +++ b/daemon/containerd/image_manifest.go @@ -31,7 +31,7 @@ func (i *ImageService) walkImageManifests(ctx context.Context, img c8dimages.Ima handleManifest := func(ctx context.Context, d ocispec.Descriptor) error { platformImg, err := i.NewImageManifest(ctx, img, d) if err != nil { - if err == errNotManifest { + if errors.Is(err, errNotManifest) { return nil } return err @@ -59,7 +59,7 @@ func (i *ImageService) walkReachableImageManifests(ctx context.Context, img c8di handleManifest := func(ctx context.Context, d ocispec.Descriptor) error { platformImg, err := i.NewImageManifest(ctx, img, d) if err != nil { - if err == errNotManifest { + if errors.Is(err, errNotManifest) { return nil } return err diff --git a/daemon/graphdriver/copy/copy.go b/daemon/graphdriver/copy/copy.go index 89a3cebc41..a6c89cf204 100644 --- a/daemon/graphdriver/copy/copy.go +++ b/daemon/graphdriver/copy/copy.go @@ -49,7 +49,7 @@ func copyRegular(srcPath, dstPath string, fileinfo os.FileInfo, copyWithFileRang } *copyWithFileClone = false - if err == unix.EXDEV { + if errors.Is(err, unix.EXDEV) { *copyWithFileRange = false } } @@ -57,7 +57,7 @@ func copyRegular(srcPath, dstPath string, fileinfo os.FileInfo, copyWithFileRang err = doCopyWithFileRange(srcFile, dstFile, fileinfo) // Trying the file_clone may not have caught the exdev case // as the ioctl may not have been available (therefore EINVAL) - if err == unix.EXDEV || err == unix.ENOSYS { + if errors.Is(err, unix.EXDEV) || errors.Is(err, unix.ENOSYS) { *copyWithFileRange = false } else { return err diff --git a/daemon/graphdriver/driver.go b/daemon/graphdriver/driver.go index 08bb5a5bcd..3e7093de33 100644 --- a/daemon/graphdriver/driver.go +++ b/daemon/graphdriver/driver.go @@ -269,7 +269,7 @@ func isEmptyDir(name string) bool { } defer f.Close() - if _, err = f.Readdirnames(1); err == io.EOF { + if _, err = f.Readdirnames(1); errors.Is(err, io.EOF) { return true } return false diff --git a/daemon/graphdriver/graphtest/graphtest_unix.go b/daemon/graphdriver/graphtest/graphtest_unix.go index 7ca5487e42..936491ae5f 100644 --- a/daemon/graphdriver/graphtest/graphtest_unix.go +++ b/daemon/graphdriver/graphtest/graphtest_unix.go @@ -5,6 +5,7 @@ package graphtest import ( "bytes" "crypto/rand" + "errors" "os" "path" "testing" @@ -312,7 +313,7 @@ func DriverTestSetQuota(t *testing.T, drivername string, required bool) { createOpts.StorageOpt = make(map[string]string, 1) createOpts.StorageOpt["size"] = "50M" layerName := drivername + "Test" - if err := driver.CreateReadWrite(layerName, "Base", createOpts); err == quota.ErrQuotaNotSupported && !required { + if err := driver.CreateReadWrite(layerName, "Base", createOpts); errors.Is(err, quota.ErrQuotaNotSupported) && !required { t.Skipf("Quota not supported on underlying filesystem: %v", err) } else if err != nil { t.Fatal(err) @@ -337,7 +338,7 @@ func DriverTestSetQuota(t *testing.T, drivername string, required bool) { if err == nil { t.Fatalf("expected write to fail(), instead had success") } - if pathError, ok := err.(*os.PathError); ok && pathError.Err != unix.EDQUOT && pathError.Err != unix.ENOSPC { + if pathError, ok := err.(*os.PathError); ok && !errors.Is(pathError.Err, unix.EDQUOT) && !errors.Is(pathError.Err, unix.ENOSPC) { os.Remove(path.Join(mountPath, "bigfile")) t.Fatalf("expect write() to fail with %v or %v, got %v", unix.EDQUOT, unix.ENOSPC, pathError.Err) } diff --git a/daemon/graphdriver/overlay2/check.go b/daemon/graphdriver/overlay2/check.go index e702390e92..d9fd65ddd8 100644 --- a/daemon/graphdriver/overlay2/check.go +++ b/daemon/graphdriver/overlay2/check.go @@ -106,7 +106,7 @@ func doesSupportNativeDiff(d string) error { // rename "d1" to "d2" if err := os.Rename(filepath.Join(td, mergedDirName, "d1"), filepath.Join(td, mergedDirName, "d2")); err != nil { // if rename failed with syscall.EXDEV, the kernel doesn't have CONFIG_OVERLAY_FS_REDIRECT_DIR enabled - if err.(*os.LinkError).Err == syscall.EXDEV { + if errors.Is(err.(*os.LinkError).Err, syscall.EXDEV) { return nil } return errors.Wrap(err, "failed to rename dir in merged directory") diff --git a/daemon/graphdriver/vfs/quota_linux.go b/daemon/graphdriver/vfs/quota_linux.go index 2b1cf904b3..5ef8cd64c4 100644 --- a/daemon/graphdriver/vfs/quota_linux.go +++ b/daemon/graphdriver/vfs/quota_linux.go @@ -2,6 +2,7 @@ package vfs import ( "context" + "errors" "github.com/containerd/log" "github.com/docker/docker/quota" @@ -15,7 +16,7 @@ type driverQuota struct { func setupDriverQuota(driver *Driver) { if quotaCtl, err := quota.NewControl(driver.home); err == nil { driver.quotaCtl = quotaCtl - } else if err != quota.ErrQuotaNotSupported { + } else if !errors.Is(err, quota.ErrQuotaNotSupported) { log.G(context.TODO()).Warnf("Unable to setup quota: %v\n", err) } } diff --git a/daemon/list.go b/daemon/list.go index 3c140ae391..1bf3811500 100644 --- a/daemon/list.go +++ b/daemon/list.go @@ -524,7 +524,7 @@ func includeContainerInList(container *container.Snapshot, filter *listContext) } return nil }) - if err != volumeExist { + if !errors.Is(err, volumeExist) { return excludeContainer } } @@ -560,7 +560,7 @@ func includeContainerInList(container *container.Snapshot, filter *listContext) } return nil }) - if err != networkExist { + if !errors.Is(err, networkExist) { return excludeContainer } } diff --git a/daemon/logger/adapter.go b/daemon/logger/adapter.go index 16a73f0314..b865858286 100644 --- a/daemon/logger/adapter.go +++ b/daemon/logger/adapter.go @@ -107,7 +107,7 @@ func (a *pluginAdapterWithRead) ReadLogs(ctx context.Context, config ReadConfig) var buf logdriver.LogEntry if err := dec.Decode(&buf); err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { return } watcher.Err <- errors.Wrap(err, "error decoding log message") diff --git a/daemon/logger/adapter_test.go b/daemon/logger/adapter_test.go index 9617e4b1af..d9db7f7fc8 100644 --- a/daemon/logger/adapter_test.go +++ b/daemon/logger/adapter_test.go @@ -3,6 +3,7 @@ package logger import ( "context" "encoding/binary" + "errors" "io" "sync" "testing" @@ -118,7 +119,7 @@ func (l *mockLoggingPlugin) waitLen(i int) { } func (l *mockLoggingPlugin) check(t *testing.T) { - if l.err != nil && l.err != io.EOF { + if l.err != nil && !errors.Is(l.err, io.EOF) { t.Fatal(l.err) } } diff --git a/daemon/logger/awslogs/cloudwatchlogs.go b/daemon/logger/awslogs/cloudwatchlogs.go index 116e38e1ca..372a483c9d 100644 --- a/daemon/logger/awslogs/cloudwatchlogs.go +++ b/daemon/logger/awslogs/cloudwatchlogs.go @@ -431,7 +431,7 @@ func (l *logStream) Log(msg *logger.Message) error { // (i.e. returns false) in this case. ctx := context.TODO() if err := l.messages.Enqueue(ctx, msg); err != nil { - if err == loggerutils.ErrQueueClosed { + if errors.Is(err, loggerutils.ErrQueueClosed) { return errClosed } return err diff --git a/daemon/logger/gcplogs/gcplogging.go b/daemon/logger/gcplogs/gcplogging.go index 0261a0ff60..529ac93fad 100644 --- a/daemon/logger/gcplogs/gcplogging.go +++ b/daemon/logger/gcplogs/gcplogging.go @@ -2,6 +2,7 @@ package gcplogs import ( "context" + "errors" "fmt" "sync" "sync/atomic" @@ -187,7 +188,7 @@ func New(info logger.Info) (logger.Logger, error) { // without overly spamming /var/log/docker.log so we log the first time // we overflow and every 1000th time after. c.OnError = func(err error) { - if err == logging.ErrOverflow { + if errors.Is(err, logging.ErrOverflow) { if i := droppedLogs.Add(1); i%1000 == 1 { log.G(context.TODO()).Errorf("gcplogs driver has dropped %v logs", i) } diff --git a/daemon/logger/jsonfilelog/read_test.go b/daemon/logger/jsonfilelog/read_test.go index b25ca16692..327cdda52c 100644 --- a/daemon/logger/jsonfilelog/read_test.go +++ b/daemon/logger/jsonfilelog/read_test.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "context" + "errors" "fmt" "io" "os" @@ -104,7 +105,7 @@ func TestEncodeDecode(t *testing.T) { assert.Assert(t, string(msg.Line) == "hello 3\n") _, err = dec.Decode() - assert.Assert(t, err == io.EOF) + assert.Assert(t, errors.Is(err, io.EOF)) } func TestReadLogs(t *testing.T) { diff --git a/daemon/logger/local/read.go b/daemon/logger/local/read.go index 14771a52db..186b4d6114 100644 --- a/daemon/logger/local/read.go +++ b/daemon/logger/local/read.go @@ -46,7 +46,7 @@ func getTailReader(ctx context.Context, r loggerutils.SizeReaderAt, req int) (lo } n, err := r.ReadAt(buf, offset-encodeBinaryLen64) - if err != nil && err != io.EOF { + if err != nil && !errors.Is(err, io.EOF) { return nil, 0, errors.Wrap(err, "error reading log message footer") } @@ -57,7 +57,7 @@ func getTailReader(ctx context.Context, r loggerutils.SizeReaderAt, req int) (lo msgLen := binary.BigEndian.Uint32(buf) n, err = r.ReadAt(buf, offset-encodeBinaryLen64-encodeBinaryLen64-int64(msgLen)) - if err != nil && err != io.EOF { + if err != nil && !errors.Is(err, io.EOF) { return nil, 0, errors.Wrap(err, "error reading log message header") } diff --git a/daemon/logger/ring_test.go b/daemon/logger/ring_test.go index df61315e07..f90ef839d2 100644 --- a/daemon/logger/ring_test.go +++ b/daemon/logger/ring_test.go @@ -2,6 +2,7 @@ package logger import ( "context" + "errors" "strconv" "testing" "time" @@ -97,7 +98,7 @@ func TestRingClose(t *testing.T) { t.Fatal(err) } r.Close() - if err := r.Enqueue(&Message{}); err != errClosed { + if err := r.Enqueue(&Message{}); !errors.Is(err, errClosed) { t.Fatalf("expected errClosed, got: %v", err) } if len(r.queue) != 1 { diff --git a/daemon/monitor.go b/daemon/monitor.go index 2e7750c50a..f18d5692e8 100644 --- a/daemon/monitor.go +++ b/daemon/monitor.go @@ -153,7 +153,7 @@ func (daemon *Daemon) handleContainerExit(c *container.Container, e *libcontaine c.CheckpointTo(context.TODO(), daemon.containersReplica) c.Unlock() defer daemon.autoRemove(&cfg.Config, c) - if waitErr != restartmanager.ErrRestartCanceled { + if !errors.Is(waitErr, restartmanager.ErrRestartCanceled) { log.G(ctx).Errorf("restartmanger wait error: %+v", waitErr) } } diff --git a/distribution/errors.go b/distribution/errors.go index b8340b00d7..9d761e2a63 100644 --- a/distribution/errors.go +++ b/distribution/errors.go @@ -164,15 +164,15 @@ func retryOnError(err error) error { return xfer.DoNotRetry{Err: err} } case *url.Error: - switch v.Err { - case auth.ErrNoBasicAuthCredentials, auth.ErrNoToken: + switch { + case errors.Is(v.Err, auth.ErrNoBasicAuthCredentials), errors.Is(v.Err, auth.ErrNoToken): return xfer.DoNotRetry{Err: v.Err} } return retryOnError(v.Err) case *client.UnexpectedHTTPResponseError, unsupportedMediaTypeError: return xfer.DoNotRetry{Err: err} case error: - if err == distribution.ErrBlobUnknown { + if errors.Is(err, distribution.ErrBlobUnknown) { return xfer.DoNotRetry{Err: err} } if strings.Contains(err.Error(), strings.ToLower(syscall.ENOSPC.Error())) { diff --git a/distribution/pull.go b/distribution/pull.go index d09782b8da..022d5f4dce 100644 --- a/distribution/pull.go +++ b/distribution/pull.go @@ -65,7 +65,7 @@ func addDigestReference(store refstore.Store, ref reference.Named, dgst digest.D log.G(context.TODO()).Errorf("Image ID for digest %s changed from %s to %s, cannot update", dgst.String(), oldTagID, id) } return nil - } else if err != refstore.ErrDoesNotExist { + } else if !errors.Is(err, refstore.ErrDoesNotExist) { return err } diff --git a/distribution/pull_v2.go b/distribution/pull_v2.go index 378908847c..a960938088 100644 --- a/distribution/pull_v2.go +++ b/distribution/pull_v2.go @@ -248,7 +248,7 @@ func (ld *layerDescriptor) Download(ctx context.Context, progressOutput progress _, err = io.Copy(tmpFile, io.TeeReader(reader, ld.verifier)) if err != nil { - if err == transport.ErrWrongCodeForByteRange { + if errors.Is(err, transport.ErrWrongCodeForByteRange) { if err := ld.truncateDownloadFile(); err != nil { return nil, 0, xfer.DoNotRetry{Err: err} } @@ -421,7 +421,7 @@ func (p *puller) pullTag(ctx context.Context, ref reference.Named, platform *oci if oldTagID == id { return false, addDigestReference(p.config.ReferenceStore, ref, manifestDigest, id) } - } else if err != refstore.ErrDoesNotExist { + } else if !errors.Is(err, refstore.ErrDoesNotExist) { return false, err } diff --git a/distribution/push_v2.go b/distribution/push_v2.go index e3c6b6f013..473147a2f9 100644 --- a/distribution/push_v2.go +++ b/distribution/push_v2.go @@ -525,8 +525,8 @@ attempts: var err error desc, err = pd.repo.Blobs(ctx).Stat(ctx, dgst) pd.checkedDigests[meta.Digest] = struct{}{} - switch err { - case nil: + switch { + case err == nil: if m, ok := digestToMetadata[desc.Digest]; !ok || m.SourceRepository != pd.repoName.Name() || !metadata.CheckV2MetadataHMAC(m, pd.hmacKey) { // cache mapping from this layer's DiffID to the blobsum if err := pd.metadataService.TagAndAdd(diffID, pd.hmacKey, metadata.V2Metadata{ @@ -539,7 +539,7 @@ attempts: desc.MediaType = schema2.MediaTypeLayer exists = true break attempts - case distribution.ErrBlobUnknown: + case errors.Is(err, distribution.ErrBlobUnknown): if meta.SourceRepository == pd.repoName.Name() { // remove the mapping to the target repository if err := pd.metadataService.Remove(*meta); err != nil { diff --git a/distribution/xfer/download_test.go b/distribution/xfer/download_test.go index 4fc89c98ad..39a1a8c25e 100644 --- a/distribution/xfer/download_test.go +++ b/distribution/xfer/download_test.go @@ -351,7 +351,7 @@ func TestCancelledDownload(t *testing.T) { descriptors := downloadDescriptors(nil) _, _, err := ldm.Download(ctx, *image.NewRootFS(), descriptors, progress.ChanOutput(progressChan)) - if err != context.Canceled { + if !errors.Is(err, context.Canceled) { close(progressChan) t.Fatal("expected download to be cancelled") } diff --git a/distribution/xfer/upload_test.go b/distribution/xfer/upload_test.go index b47bef1a80..44798051a9 100644 --- a/distribution/xfer/upload_test.go +++ b/distribution/xfer/upload_test.go @@ -125,7 +125,7 @@ func TestCancelledUpload(t *testing.T) { descriptors := uploadDescriptors(nil) err := lum.Upload(ctx, descriptors, progress.ChanOutput(progressChan)) - if err != context.Canceled { + if !errors.Is(err, context.Canceled) { t.Fatal("expected upload to be cancelled") } diff --git a/errdefs/helpers_test.go b/errdefs/helpers_test.go index 8d1ba1dc36..f813f0fd79 100644 --- a/errdefs/helpers_test.go +++ b/errdefs/helpers_test.go @@ -22,7 +22,7 @@ func TestNotFound(t *testing.T) { if !cerrdefs.IsNotFound(e) { t.Fatalf("expected not found error, got: %T", e) } - if cause := e.(wrapped).Unwrap(); cause != errTest { + if cause := e.(wrapped).Unwrap(); cause != errTest { //nolint:errorlint // not using errors.Is, as this tests for the unwrapped error. t.Fatalf("causual should be errTest, got: %v", cause) } if !errors.Is(e, errTest) { @@ -43,7 +43,7 @@ func TestConflict(t *testing.T) { if !cerrdefs.IsConflict(e) { t.Fatalf("expected conflict error, got: %T", e) } - if cause := e.(wrapped).Unwrap(); cause != errTest { + if cause := e.(wrapped).Unwrap(); cause != errTest { //nolint:errorlint // not using errors.Is, as this tests for the unwrapped error. t.Fatalf("causual should be errTest, got: %v", cause) } if !errors.Is(e, errTest) { @@ -64,7 +64,7 @@ func TestForbidden(t *testing.T) { if !cerrdefs.IsPermissionDenied(e) { t.Fatalf("expected forbidden error, got: %T", e) } - if cause := e.(wrapped).Unwrap(); cause != errTest { + if cause := e.(wrapped).Unwrap(); cause != errTest { //nolint:errorlint // not using errors.Is, as this tests for the unwrapped error. t.Fatalf("causual should be errTest, got: %v", cause) } if !errors.Is(e, errTest) { @@ -85,7 +85,7 @@ func TestInvalidParameter(t *testing.T) { if !cerrdefs.IsInvalidArgument(e) { t.Fatalf("expected invalid argument error, got %T", e) } - if cause := e.(wrapped).Unwrap(); cause != errTest { + if cause := e.(wrapped).Unwrap(); cause != errTest { //nolint:errorlint // not using errors.Is, as this tests for the unwrapped error. t.Fatalf("causual should be errTest, got: %v", cause) } if !errors.Is(e, errTest) { @@ -106,7 +106,7 @@ func TestNotImplemented(t *testing.T) { if !cerrdefs.IsNotImplemented(e) { t.Fatalf("expected not implemented error, got %T", e) } - if cause := e.(wrapped).Unwrap(); cause != errTest { + if cause := e.(wrapped).Unwrap(); cause != errTest { //nolint:errorlint // not using errors.Is, as this tests for the unwrapped error. t.Fatalf("causual should be errTest, got: %v", cause) } if !errors.Is(e, errTest) { @@ -127,7 +127,7 @@ func TestNotModified(t *testing.T) { if !cerrdefs.IsNotModified(e) { t.Fatalf("expected not modified error, got %T", e) } - if cause := e.(wrapped).Unwrap(); cause != errTest { + if cause := e.(wrapped).Unwrap(); cause != errTest { //nolint:errorlint // not using errors.Is, as this tests for the unwrapped error. t.Fatalf("causual should be errTest, got: %v", cause) } if !errors.Is(e, errTest) { @@ -148,7 +148,7 @@ func TestUnauthorized(t *testing.T) { if !cerrdefs.IsUnauthorized(e) { t.Fatalf("expected unauthorized error, got %T", e) } - if cause := e.(wrapped).Unwrap(); cause != errTest { + if cause := e.(wrapped).Unwrap(); cause != errTest { //nolint:errorlint // not using errors.Is, as this tests for the unwrapped error. t.Fatalf("causual should be errTest, got: %v", cause) } if !errors.Is(e, errTest) { @@ -169,7 +169,7 @@ func TestUnknown(t *testing.T) { if !cerrdefs.IsUnknown(e) { t.Fatalf("expected unknown error, got %T", e) } - if cause := e.(wrapped).Unwrap(); cause != errTest { + if cause := e.(wrapped).Unwrap(); cause != errTest { //nolint:errorlint // not using errors.Is, as this tests for the unwrapped error. t.Fatalf("causual should be errTest, got: %v", cause) } if !errors.Is(e, errTest) { @@ -190,7 +190,7 @@ func TestCancelled(t *testing.T) { if !cerrdefs.IsCanceled(e) { t.Fatalf("expected cancelled error, got %T", e) } - if cause := e.(wrapped).Unwrap(); cause != errTest { + if cause := e.(wrapped).Unwrap(); cause != errTest { //nolint:errorlint // not using errors.Is, as this tests for the unwrapped error. t.Fatalf("causual should be errTest, got: %v", cause) } if !errors.Is(e, errTest) { @@ -211,7 +211,7 @@ func TestDeadline(t *testing.T) { if !cerrdefs.IsDeadlineExceeded(e) { t.Fatalf("expected deadline error, got %T", e) } - if cause := e.(wrapped).Unwrap(); cause != errTest { + if cause := e.(wrapped).Unwrap(); cause != errTest { //nolint:errorlint // not using errors.Is, as this tests for the unwrapped error. t.Fatalf("causual should be errTest, got: %v", cause) } if !errors.Is(e, errTest) { @@ -232,7 +232,7 @@ func TestDataLoss(t *testing.T) { if !cerrdefs.IsDataLoss(e) { t.Fatalf("expected data loss error, got %T", e) } - if cause := e.(wrapped).Unwrap(); cause != errTest { + if cause := e.(wrapped).Unwrap(); cause != errTest { //nolint:errorlint // not using errors.Is, as this tests for the unwrapped error. t.Fatalf("causual should be errTest, got: %v", cause) } if !errors.Is(e, errTest) { @@ -253,7 +253,7 @@ func TestUnavailable(t *testing.T) { if !cerrdefs.IsUnavailable(e) { t.Fatalf("expected unavaillable error, got %T", e) } - if cause := e.(wrapped).Unwrap(); cause != errTest { + if cause := e.(wrapped).Unwrap(); cause != errTest { //nolint:errorlint // not using errors.Is, as this tests for the unwrapped error. t.Fatalf("causual should be errTest, got: %v", cause) } if !errors.Is(e, errTest) { @@ -274,7 +274,7 @@ func TestSystem(t *testing.T) { if !cerrdefs.IsInternal(e) { t.Fatalf("expected system error, got %T", e) } - if cause := e.(wrapped).Unwrap(); cause != errTest { + if cause := e.(wrapped).Unwrap(); cause != errTest { //nolint:errorlint // not using errors.Is, as this tests for the unwrapped error. t.Fatalf("causual should be errTest, got: %v", cause) } if !errors.Is(e, errTest) { diff --git a/image/store.go b/image/store.go index eac157de48..cf5683c8c9 100644 --- a/image/store.go +++ b/image/store.go @@ -199,7 +199,7 @@ func (imageNotFoundError) NotFound() {} func (is *store) Search(term string) (ID, error) { dgst, err := is.digestSet.Lookup(term) if err != nil { - if err == digestset.ErrDigestNotFound { + if errors.Is(err, digestset.ErrDigestNotFound) { err = imageNotFoundError(term) } return "", errors.WithStack(err) diff --git a/integration-cli/docker_api_exec_resize_test.go b/integration-cli/docker_api_exec_resize_test.go index f5f500be58..cc5fe3447b 100644 --- a/integration-cli/docker_api_exec_resize_test.go +++ b/integration-cli/docker_api_exec_resize_test.go @@ -71,7 +71,7 @@ func (s *DockerAPISuite) TestExecResizeImmediatelyAfterExecStart(c *testing.T) { _, rc, err := request.Post(testutil.GetContext(c), fmt.Sprintf("/exec/%s/resize?h=24&w=80", execID), request.ContentType("text/plain")) if err != nil { // It's probably a panic of the daemon if io.ErrUnexpectedEOF is returned. - if err == io.ErrUnexpectedEOF { + if errors.Is(err, io.ErrUnexpectedEOF) { return errors.New("the daemon might have crashed") } // Other error happened, should be reported. diff --git a/integration-cli/docker_cli_daemon_plugins_test.go b/integration-cli/docker_cli_daemon_plugins_test.go index 838a353fc2..60e0443bff 100644 --- a/integration-cli/docker_cli_daemon_plugins_test.go +++ b/integration-cli/docker_cli_daemon_plugins_test.go @@ -3,6 +3,7 @@ package main import ( + "errors" "strings" "testing" @@ -143,7 +144,7 @@ func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *testing.T) { } for { - if err := unix.Kill(s.d.Pid(), 0); err == unix.ESRCH { + if err := unix.Kill(s.d.Pid(), 0); errors.Is(err, unix.ESRCH) { break } } diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 1721dfdaff..4aef4dacd4 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "io" "net" @@ -2190,7 +2191,7 @@ func (s *DockerCLIRunSuite) TestRunVolumesCleanPaths(c *testing.T) { cli.DockerCmd(c, "run", "-v", prefix+"/foo", "-v", prefix+"/bar/", "--name", "dark_helmet", "run_volumes_clean_paths") out, err := inspectMountSourceField("dark_helmet", prefix+slash+"foo"+slash) - if err != errMountNotFound { + if !errors.Is(err, errMountNotFound) { c.Fatalf("Found unexpected volume entry for '%s/foo/' in volumes\n%q", prefix, out) } @@ -2201,7 +2202,7 @@ func (s *DockerCLIRunSuite) TestRunVolumesCleanPaths(c *testing.T) { } out, err = inspectMountSourceField("dark_helmet", prefix+slash+"bar"+slash) - if err != errMountNotFound { + if !errors.Is(err, errMountNotFound) { c.Fatalf("Found unexpected volume entry for '%s/bar/' in volumes\n%q", prefix, out) } diff --git a/integration/build/build_test.go b/integration/build/build_test.go index f8caf14965..d5d8463260 100644 --- a/integration/build/build_test.go +++ b/integration/build/build_test.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "io" "os" @@ -780,7 +781,7 @@ func TestBuildEmitsImageCreateEvent(t *testing.T) { imageCreateEvts++ } case err := <-errs: - assert.Check(t, err == nil || err == io.EOF) + assert.Check(t, err == nil || errors.Is(err, io.EOF)) finished = true } } diff --git a/integration/container/copy_test.go b/integration/container/copy_test.go index 5d59d252ca..b2acd9bec7 100644 --- a/integration/container/copy_test.go +++ b/integration/container/copy_test.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "io" "os" "path/filepath" @@ -335,7 +336,7 @@ func TestCopyFromContainer(t *testing.T) { tr := tar.NewReader(rdr) for numFound < len(x.expect) { h, err := tr.Next() - if err == io.EOF { + if errors.Is(err, io.EOF) { break } assert.NilError(t, err) diff --git a/integration/container/pause_test.go b/integration/container/pause_test.go index 0b9d0e19cb..6c1c1e781d 100644 --- a/integration/container/pause_test.go +++ b/integration/container/pause_test.go @@ -1,6 +1,7 @@ package container import ( + "errors" "io" "testing" @@ -80,7 +81,7 @@ func getEventActions(t *testing.T, messages <-chan events.Message, errs <-chan e for { select { case err := <-errs: - assert.Check(t, err == nil || err == io.EOF) + assert.Check(t, err == nil || errors.Is(err, io.EOF)) return actions case e := <-messages: actions = append(actions, e.Action) diff --git a/integration/plugin/authz/authz_plugin_test.go b/integration/plugin/authz/authz_plugin_test.go index e1fde67df2..b77b2de31a 100644 --- a/integration/plugin/authz/authz_plugin_test.go +++ b/integration/plugin/authz/authz_plugin_test.go @@ -4,6 +4,7 @@ package authz import ( "context" + "errors" "fmt" "io" "net" @@ -255,7 +256,7 @@ func TestAuthZPluginAllowEventStream(t *testing.T) { } } case err := <-errs: - if err == io.EOF { + if errors.Is(err, io.EOF) { t.Fatal("premature end of event stream") } assert.NilError(t, err) diff --git a/integration/system/event_test.go b/integration/system/event_test.go index 9efcc33ff7..0d2970acd5 100644 --- a/integration/system/event_test.go +++ b/integration/system/event_test.go @@ -136,7 +136,7 @@ func TestEventsVolumeCreate(t *testing.T) { case m := <-messages: evts = append(evts, m) case err := <-errs: - if err == io.EOF { + if errors.Is(err, io.EOF) { return evts, nil } return nil, err diff --git a/internal/containerfs/rm.go b/internal/containerfs/rm.go index abced3f5e9..22a39453fa 100644 --- a/internal/containerfs/rm.go +++ b/internal/containerfs/rm.go @@ -61,7 +61,7 @@ func EnsureRemoveAll(dir string) error { continue } - if pe.Err != syscall.EBUSY { + if !errors.Is(pe.Err, syscall.EBUSY) { return err } diff --git a/libnetwork/bitmap/sequence_test.go b/libnetwork/bitmap/sequence_test.go index afc5fa29fd..5db3870fc3 100644 --- a/libnetwork/bitmap/sequence_test.go +++ b/libnetwork/bitmap/sequence_test.go @@ -1,6 +1,7 @@ package bitmap import ( + "errors" "math/rand" "testing" "time" @@ -677,13 +678,13 @@ func TestSetUnset(t *testing.T) { t.Fatal(err) } } - if _, err := hnd.SetAny(false); err != ErrNoBitAvailable { + if _, err := hnd.SetAny(false); !errors.Is(err, ErrNoBitAvailable) { t.Fatal("Expected error. Got success") } - if _, err := hnd.SetAnyInRange(10, 20, false); err != ErrNoBitAvailable { + if _, err := hnd.SetAnyInRange(10, 20, false); !errors.Is(err, ErrNoBitAvailable) { t.Fatal("Expected error. Got success") } - if err := hnd.Set(50); err != ErrBitAllocated { + if err := hnd.Set(50); !errors.Is(err, ErrBitAllocated) { t.Fatalf("Expected error. Got %v: %s", err, hnd) } i := uint64(0) @@ -706,11 +707,11 @@ func TestOffsetSetUnset(t *testing.T) { } } - if _, err := hnd.SetAny(false); err != ErrNoBitAvailable { + if _, err := hnd.SetAny(false); !errors.Is(err, ErrNoBitAvailable) { t.Fatal("Expected error. Got success") } - if _, err := hnd.SetAnyInRange(10, 20, false); err != ErrNoBitAvailable { + if _, err := hnd.SetAnyInRange(10, 20, false); !errors.Is(err, ErrNoBitAvailable) { t.Fatal("Expected error. Got success") } @@ -812,7 +813,7 @@ func TestSetInRange(t *testing.T) { if err == nil { t.Fatalf("Expected failure. Got success with ordinal:%d", o) } - if err != ErrNoBitAvailable { + if !errors.Is(err, ErrNoBitAvailable) { t.Fatalf("Unexpected error: %v", err) } @@ -829,7 +830,7 @@ func TestSetInRange(t *testing.T) { if err == nil { t.Fatalf("Expected failure. Got success with ordinal:%d", o) } - if err != ErrNoBitAvailable { + if !errors.Is(err, ErrNoBitAvailable) { t.Fatalf("Unexpected error: %v", err) } @@ -844,7 +845,7 @@ func TestSetInRange(t *testing.T) { if err == nil { t.Fatalf("Expected failure. Got success with ordinal:%d", o) } - if err != ErrNoBitAvailable { + if !errors.Is(err, ErrNoBitAvailable) { t.Fatalf("Unexpected error: %v", err) } } diff --git a/libnetwork/cnmallocator/networkallocator.go b/libnetwork/cnmallocator/networkallocator.go index 9eb1c77511..861d06ba60 100644 --- a/libnetwork/cnmallocator/networkallocator.go +++ b/libnetwork/cnmallocator/networkallocator.go @@ -591,7 +591,7 @@ func (na *cnmNetworkAllocator) allocateVIP(vip *api.Endpoint_VirtualIP) error { for _, poolID := range localNet.pools { ip, _, err := ipam.RequestAddress(poolID, addr, opts) - if err != nil && err != ipamapi.ErrNoAvailableIPs && err != ipamapi.ErrIPOutOfRange { + if err != nil && !errors.Is(err, ipamapi.ErrNoAvailableIPs) && !errors.Is(err, ipamapi.ErrIPOutOfRange) { return errors.Wrap(err, "could not allocate VIP from IPAM") } @@ -682,7 +682,7 @@ func (na *cnmNetworkAllocator) allocateNetworkIPs(nAttach *api.NetworkAttachment var err error ip, _, err = ipam.RequestAddress(poolID, addr, opts) - if err != nil && err != ipamapi.ErrNoAvailableIPs && err != ipamapi.ErrIPOutOfRange { + if err != nil && !errors.Is(err, ipamapi.ErrNoAvailableIPs) && !errors.Is(err, ipamapi.ErrIPOutOfRange) { return errors.Wrap(err, "could not allocate IP from IPAM") } diff --git a/libnetwork/controller.go b/libnetwork/controller.go index 14858c7881..88309a2a57 100644 --- a/libnetwork/controller.go +++ b/libnetwork/controller.go @@ -1076,7 +1076,7 @@ func (c *Controller) loadDriver(networkType string) error { } if err != nil { - if errors.Cause(err) == plugins.ErrNotFound { + if errors.Is(err, plugins.ErrNotFound) { return types.NotFoundErrorf("%v", err) } return err @@ -1095,7 +1095,7 @@ func (c *Controller) loadIPAMDriver(name string) error { } if err != nil { - if errors.Cause(err) == plugins.ErrNotFound { + if errors.Is(err, plugins.ErrNotFound) { return types.NotFoundErrorf("%v", err) } return err diff --git a/libnetwork/datastore/cache.go b/libnetwork/datastore/cache.go index e64e1cf399..a421cc176c 100644 --- a/libnetwork/datastore/cache.go +++ b/libnetwork/datastore/cache.go @@ -1,6 +1,7 @@ package datastore import ( + "errors" "fmt" "sync" @@ -35,7 +36,7 @@ func (c *cache) kmap(kvObject KVObject) (kvMap, error) { kvList, err := c.ds.List(keyPrefix) if err != nil { - if err == store.ErrKeyNotFound { + if errors.Is(err, store.ErrKeyNotFound) { // If the store doesn't have anything then there is nothing to // populate in the cache. Just bail out. goto out diff --git a/libnetwork/datastore/datastore.go b/libnetwork/datastore/datastore.go index 3e5da5637a..3b9a762814 100644 --- a/libnetwork/datastore/datastore.go +++ b/libnetwork/datastore/datastore.go @@ -121,7 +121,7 @@ func (ds *Store) PutObjectAtomic(kvObject KVObject) error { pair, err := ds.store.AtomicPut(Key(kvObject.Key()...), kvObjValue, previous) if err != nil { - if err == store.ErrKeyExists { + if errors.Is(err, store.ErrKeyExists) { return ErrKeyModified } return err @@ -245,7 +245,7 @@ func (ds *Store) DeleteObjectAtomic(kvObject KVObject) error { if !kvObject.Skip() { if err := ds.store.AtomicDelete(Key(kvObject.Key()...), previous); err != nil { - if err == store.ErrKeyExists { + if errors.Is(err, store.ErrKeyExists) { return ErrKeyModified } return err diff --git a/libnetwork/drivers/bridge/bridge_linux.go b/libnetwork/drivers/bridge/bridge_linux.go index 1dc331ffef..19fcf43337 100644 --- a/libnetwork/drivers/bridge/bridge_linux.go +++ b/libnetwork/drivers/bridge/bridge_linux.go @@ -956,7 +956,7 @@ func (d *driver) deleteNetwork(nid string) error { // it's not in d.networks. To prevent the driver's state from getting out of step // with its parent, make sure it's not in the store before reporting that it does // not exist. - if err := d.storeDelete(&networkConfiguration{ID: nid}); err != nil && err != datastore.ErrKeyNotFound { + if err := d.storeDelete(&networkConfiguration{ID: nid}); err != nil && !errors.Is(err, datastore.ErrKeyNotFound) { log.G(context.TODO()).WithFields(log.Fields{ "error": err, "network": nid, diff --git a/libnetwork/drivers/bridge/bridge_store.go b/libnetwork/drivers/bridge/bridge_store.go index 0e03c9f86e..1cb682fe13 100644 --- a/libnetwork/drivers/bridge/bridge_store.go +++ b/libnetwork/drivers/bridge/bridge_store.go @@ -5,6 +5,7 @@ package bridge import ( "context" "encoding/json" + "errors" "fmt" "net" "strings" @@ -43,12 +44,12 @@ func (d *driver) initStore() error { func (d *driver) populateNetworks() error { kvol, err := d.store.List(&networkConfiguration{}) - if err != nil && err != datastore.ErrKeyNotFound { - return fmt.Errorf("failed to get bridge network configurations from store: %v", err) + if err != nil && !errors.Is(err, datastore.ErrKeyNotFound) { + return fmt.Errorf("failed to get bridge network configurations from store: %w", err) } // It's normal for network configuration state to be empty. Just return. - if err == datastore.ErrKeyNotFound { + if errors.Is(err, datastore.ErrKeyNotFound) { return nil } @@ -68,11 +69,11 @@ func (d *driver) populateNetworks() error { func (d *driver) populateEndpoints() error { kvol, err := d.store.List(&bridgeEndpoint{}) - if err != nil && err != datastore.ErrKeyNotFound { - return fmt.Errorf("failed to get bridge endpoints from store: %v", err) + if err != nil && !errors.Is(err, datastore.ErrKeyNotFound) { + return fmt.Errorf("failed to get bridge endpoints from store: %w", err) } - if err == datastore.ErrKeyNotFound { + if errors.Is(err, datastore.ErrKeyNotFound) { return nil } diff --git a/libnetwork/drivers/ipvlan/ipvlan_store.go b/libnetwork/drivers/ipvlan/ipvlan_store.go index c35f48ec29..33e0101a8d 100644 --- a/libnetwork/drivers/ipvlan/ipvlan_store.go +++ b/libnetwork/drivers/ipvlan/ipvlan_store.go @@ -5,6 +5,7 @@ package ipvlan import ( "context" "encoding/json" + "errors" "fmt" "net" @@ -56,11 +57,11 @@ func (d *driver) initStore() error { // populateNetworks is invoked at driver init to recreate persistently stored networks func (d *driver) populateNetworks() error { kvol, err := d.store.List(&configuration{}) - if err != nil && err != datastore.ErrKeyNotFound { - return fmt.Errorf("failed to get ipvlan network configurations from store: %v", err) + if err != nil && !errors.Is(err, datastore.ErrKeyNotFound) { + return fmt.Errorf("failed to get ipvlan network configurations from store: %w", err) } // If empty it simply means no ipvlan networks have been created yet - if err == datastore.ErrKeyNotFound { + if errors.Is(err, datastore.ErrKeyNotFound) { return nil } for _, kvo := range kvol { @@ -75,11 +76,11 @@ func (d *driver) populateNetworks() error { func (d *driver) populateEndpoints() error { kvol, err := d.store.List(&endpoint{}) - if err != nil && err != datastore.ErrKeyNotFound { - return fmt.Errorf("failed to get ipvlan endpoints from store: %v", err) + if err != nil && !errors.Is(err, datastore.ErrKeyNotFound) { + return fmt.Errorf("failed to get ipvlan endpoints from store: %w", err) } - if err == datastore.ErrKeyNotFound { + if errors.Is(err, datastore.ErrKeyNotFound) { return nil } diff --git a/libnetwork/drivers/macvlan/macvlan_store.go b/libnetwork/drivers/macvlan/macvlan_store.go index a542fdc017..884fc75cee 100644 --- a/libnetwork/drivers/macvlan/macvlan_store.go +++ b/libnetwork/drivers/macvlan/macvlan_store.go @@ -5,6 +5,7 @@ package macvlan import ( "context" "encoding/json" + "errors" "fmt" "net" @@ -55,11 +56,11 @@ func (d *driver) initStore() error { // populateNetworks is invoked at driver init to recreate persistently stored networks func (d *driver) populateNetworks() error { kvol, err := d.store.List(&configuration{}) - if err != nil && err != datastore.ErrKeyNotFound { - return fmt.Errorf("failed to get macvlan network configurations from store: %v", err) + if err != nil && !errors.Is(err, datastore.ErrKeyNotFound) { + return fmt.Errorf("failed to get macvlan network configurations from store: %w", err) } // If empty it simply means no macvlan networks have been created yet - if err == datastore.ErrKeyNotFound { + if errors.Is(err, datastore.ErrKeyNotFound) { return nil } for _, kvo := range kvol { @@ -74,11 +75,11 @@ func (d *driver) populateNetworks() error { func (d *driver) populateEndpoints() error { kvol, err := d.store.List(&endpoint{}) - if err != nil && err != datastore.ErrKeyNotFound { - return fmt.Errorf("failed to get macvlan endpoints from store: %v", err) + if err != nil && !errors.Is(err, datastore.ErrKeyNotFound) { + return fmt.Errorf("failed to get macvlan endpoints from store: %w", err) } - if err == datastore.ErrKeyNotFound { + if errors.Is(err, datastore.ErrKeyNotFound) { return nil } diff --git a/libnetwork/drivers/overlay/encryption.go b/libnetwork/drivers/overlay/encryption.go index e81623da73..67eaf7d7e4 100644 --- a/libnetwork/drivers/overlay/encryption.go +++ b/libnetwork/drivers/overlay/encryption.go @@ -7,6 +7,7 @@ import ( "context" "encoding/binary" "encoding/hex" + "errors" "fmt" "hash/fnv" "net" @@ -431,10 +432,10 @@ func programSP(fSA *netlink.XfrmState, rSA *netlink.XfrmState, add bool) error { func saExists(sa *netlink.XfrmState) (bool, error) { _, err := ns.NlHandle().XfrmStateGet(sa) - switch err { - case nil: + switch { + case err == nil: return true, nil - case syscall.ESRCH: + case errors.Is(err, syscall.ESRCH): return false, nil default: err = fmt.Errorf("Error while checking for SA existence: %v", err) @@ -445,10 +446,10 @@ func saExists(sa *netlink.XfrmState) (bool, error) { func spExists(sp *netlink.XfrmPolicy) (bool, error) { _, err := ns.NlHandle().XfrmPolicyGet(sp) - switch err { - case nil: + switch { + case err == nil: return true, nil - case syscall.ENOENT: + case errors.Is(err, syscall.ENOENT): return false, nil default: err = fmt.Errorf("Error while checking for SP existence: %v", err) diff --git a/libnetwork/drivers/remote/driver_test.go b/libnetwork/drivers/remote/driver_test.go index 767414b8f7..4dcc886136 100644 --- a/libnetwork/drivers/remote/driver_test.go +++ b/libnetwork/drivers/remote/driver_test.go @@ -28,7 +28,7 @@ func handle(t *testing.T, mux *http.ServeMux, method string, h func(map[string]i mux.HandleFunc(fmt.Sprintf("/%s.%s", driverapi.NetworkPluginEndpointType, method), func(w http.ResponseWriter, r *http.Request) { var ask map[string]interface{} err := json.NewDecoder(r.Body).Decode(&ask) - if err != nil && err != io.EOF { + if err != nil && !errors.Is(err, io.EOF) { t.Fatal(err) } answer := h(ask) diff --git a/libnetwork/endpoint.go b/libnetwork/endpoint.go index 085f719046..5d94efd444 100644 --- a/libnetwork/endpoint.go +++ b/libnetwork/endpoint.go @@ -6,6 +6,7 @@ package libnetwork import ( "context" "encoding/json" + "errors" "fmt" "net" "net/netip" @@ -1334,7 +1335,7 @@ func (ep *Endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error { ep.mu.Unlock() return nil } - if err != ipamapi.ErrNoAvailableIPs || progAdd != nil { + if !errors.Is(err, ipamapi.ErrNoAvailableIPs) || progAdd != nil { return err } } diff --git a/libnetwork/ipams/defaultipam/allocator_test.go b/libnetwork/ipams/defaultipam/allocator_test.go index 12d254217d..fc273abb93 100644 --- a/libnetwork/ipams/defaultipam/allocator_test.go +++ b/libnetwork/ipams/defaultipam/allocator_test.go @@ -2,6 +2,7 @@ package defaultipam import ( "context" + "errors" "flag" "fmt" "math/rand" @@ -404,7 +405,7 @@ func TestRequestReleaseAddressFromSubPool(t *testing.T) { ip = c } } - if err != ipamapi.ErrNoAvailableIPs { + if !errors.Is(err, ipamapi.ErrNoAvailableIPs) { t.Fatal(err) } if !types.CompareIPNet(expected, ip) { @@ -436,7 +437,7 @@ func TestRequestReleaseAddressFromSubPool(t *testing.T) { ip = c } } - if err != ipamapi.ErrNoAvailableIPs { + if !errors.Is(err, ipamapi.ErrNoAvailableIPs) { t.Fatal(err) } if !types.CompareIPNet(expected, ip) { @@ -528,7 +529,7 @@ func TestSerializeRequestReleaseAddressFromSubPool(t *testing.T) { ip = c } } - if err != ipamapi.ErrNoAvailableIPs { + if !errors.Is(err, ipamapi.ErrNoAvailableIPs) { t.Fatal(err) } if !types.CompareIPNet(expected, ip) { @@ -560,7 +561,7 @@ func TestSerializeRequestReleaseAddressFromSubPool(t *testing.T) { ip = c } } - if err != ipamapi.ErrNoAvailableIPs { + if !errors.Is(err, ipamapi.ErrNoAvailableIPs) { t.Fatal(err) } if !types.CompareIPNet(expected, ip) { @@ -853,7 +854,7 @@ func TestUnusualSubnets(t *testing.T) { for _, outside := range outsideTheRangeAddresses { _, _, errx := allocator.RequestAddress(alloc.PoolID, net.ParseIP(outside.address), nil) - if errx != ipamapi.ErrIPOutOfRange { + if !errors.Is(errx, ipamapi.ErrIPOutOfRange) { t.Fatalf("Address %s failed to throw expected error: %s", outside.address, errx.Error()) } } @@ -873,7 +874,7 @@ func TestUnusualSubnets(t *testing.T) { } _, _, err = allocator.RequestAddress(alloc.PoolID, nil, nil) - if err != ipamapi.ErrNoAvailableIPs { + if !errors.Is(err, ipamapi.ErrNoAvailableIPs) { t.Fatal("Did not get expected error when pool is exhausted.") } } @@ -890,7 +891,7 @@ func TestRelease(t *testing.T) { } // Allocate all addresses - for err != ipamapi.ErrNoAvailableIPs { + for !errors.Is(err, ipamapi.ErrNoAvailableIPs) { _, _, err = a.RequestAddress(alloc.PoolID, nil, nil) } @@ -948,7 +949,7 @@ func assertGetAddress(t *testing.T, subnet string) { start := time.Now() run := 0 - for err != ipamapi.ErrNoAvailableIPs { + for !errors.Is(err, ipamapi.ErrNoAvailableIPs) { _, err = getAddress(sub, bm, netip.Addr{}, netip.Prefix{}, false) run++ } @@ -997,7 +998,7 @@ func assertNRequests(t *testing.T, subnet string, numReq int, lastExpectedIP str func benchmarkRequest(b *testing.B, a *Allocator, subnet string) { alloc, err := a.RequestPool(ipamapi.PoolRequest{AddressSpace: localAddressSpace, Pool: subnet}) - for err != ipamapi.ErrNoAvailableIPs { + for !errors.Is(err, ipamapi.ErrNoAvailableIPs) { _, _, err = a.RequestAddress(alloc.PoolID, nil, nil) } } diff --git a/libnetwork/ipams/remote/remote_test.go b/libnetwork/ipams/remote/remote_test.go index b3ec7739d2..a47b6099c6 100644 --- a/libnetwork/ipams/remote/remote_test.go +++ b/libnetwork/ipams/remote/remote_test.go @@ -2,6 +2,7 @@ package remote import ( "encoding/json" + "errors" "fmt" "io" "net" @@ -22,7 +23,7 @@ func handle(t *testing.T, mux *http.ServeMux, method string, h func(map[string]i mux.HandleFunc(fmt.Sprintf("/%s.%s", ipamapi.PluginEndpointType, method), func(w http.ResponseWriter, r *http.Request) { var ask map[string]interface{} err := json.NewDecoder(r.Body).Decode(&ask) - if err != nil && err != io.EOF { + if err != nil && !errors.Is(err, io.EOF) { t.Fatal(err) } answer := h(ask) diff --git a/libnetwork/network.go b/libnetwork/network.go index 96b6cf4949..eabb1c3646 100644 --- a/libnetwork/network.go +++ b/libnetwork/network.go @@ -1619,7 +1619,7 @@ func (n *Network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error { return types.ForbiddenErrorf("auxiliary address: (%s:%s) must belong to the master pool: %s", k, v, d.Pool) } // Attempt reservation in the container addressable pool, silent the error if address does not belong to that pool - if d.IPAMData.AuxAddresses[k], _, err = ipam.RequestAddress(d.PoolID, ip, nil); err != nil && err != ipamapi.ErrIPOutOfRange { + if d.IPAMData.AuxAddresses[k], _, err = ipam.RequestAddress(d.PoolID, ip, nil); err != nil && !errors.Is(err, ipamapi.ErrIPOutOfRange) { return types.InternalErrorf("failed to allocate secondary ip address (%s:%s): %v", k, v, err) } } @@ -1673,7 +1673,7 @@ func (n *Network) ipamReleaseVersion(ipVer int, ipam ipamapi.Ipam) { if d.IPAMData.AuxAddresses != nil { for k, nw := range d.IPAMData.AuxAddresses { if d.Pool.Contains(nw.IP) { - if err := ipam.ReleaseAddress(d.PoolID, nw.IP); err != nil && err != ipamapi.ErrIPOutOfRange { + if err := ipam.ReleaseAddress(d.PoolID, nw.IP); err != nil && !errors.Is(err, ipamapi.ErrIPOutOfRange) { log.G(context.TODO()).Warnf("Failed to release secondary ip address %s (%v) on delete of network %s (%s): %v", k, nw.IP, n.Name(), n.ID(), err) } } diff --git a/libnetwork/portallocator/portallocator_test.go b/libnetwork/portallocator/portallocator_test.go index ed661851e3..90c7b0a96c 100644 --- a/libnetwork/portallocator/portallocator_test.go +++ b/libnetwork/portallocator/portallocator_test.go @@ -93,7 +93,7 @@ func TestReleaseUnreadledPort(t *testing.T) { func TestUnknowProtocol(t *testing.T) { p := newInstance() - if _, err := p.RequestPort(net.IPv4zero, "tcpp", 0); err != errUnknownProtocol { + if _, err := p.RequestPort(net.IPv4zero, "tcpp", 0); !errors.Is(err, errUnknownProtocol) { t.Fatalf("Expected error %s got %s", errUnknownProtocol, err) } } @@ -112,7 +112,7 @@ func TestAllocateAllPorts(t *testing.T) { } } - if _, err := p.RequestPort(net.IPv4zero, "tcp", 0); err != errAllPortsAllocated { + if _, err := p.RequestPort(net.IPv4zero, "tcp", 0); !errors.Is(err, errAllPortsAllocated) { t.Fatalf("Expected error %s got %s", errAllPortsAllocated, err) } @@ -281,7 +281,7 @@ func TestPortAllocationWithCustomRange(t *testing.T) { t.Fatal("Allocated the same port from a custom range") } // request 3rd port from the range of 2 - if _, err := p.RequestPortInRange(net.IPv4zero, "tcp", start, end); err != errAllPortsAllocated { + if _, err := p.RequestPortInRange(net.IPv4zero, "tcp", start, end); !errors.Is(err, errAllPortsAllocated) { t.Fatalf("Expected error %s got %s", errAllPortsAllocated, err) } } diff --git a/libnetwork/resolver_test.go b/libnetwork/resolver_test.go index e60fa0b7ea..936d1f2e36 100644 --- a/libnetwork/resolver_test.go +++ b/libnetwork/resolver_test.go @@ -125,7 +125,7 @@ func waitForLocalDNSServer(t *testing.T) { if err != nil { if oerr, ok := err.(*net.OpError); ok { // server is probably initializing - if oerr.Err == syscall.ECONNREFUSED { + if errors.Is(oerr.Err, syscall.ECONNREFUSED) { continue } } else { diff --git a/libnetwork/sandbox_store.go b/libnetwork/sandbox_store.go index 83d60d5e36..01879e7305 100644 --- a/libnetwork/sandbox_store.go +++ b/libnetwork/sandbox_store.go @@ -3,6 +3,7 @@ package libnetwork import ( "context" "encoding/json" + "errors" "fmt" "github.com/containerd/log" @@ -147,7 +148,7 @@ retry: } err := sb.controller.updateToStore(ctx, sbs) - if err == datastore.ErrKeyModified { + if errors.Is(err, datastore.ErrKeyModified) { // When we get ErrKeyModified it is sufficient to just // go back and retry. No need to get the object from // the store because we always regenerate the store @@ -171,7 +172,7 @@ func (sb *Sandbox) storeDelete() error { func (c *Controller) sandboxRestore(activeSandboxes map[string]interface{}) error { sandboxStates, err := c.store.List(&sbState{c: c}) if err != nil { - if err == datastore.ErrKeyNotFound { + if errors.Is(err, datastore.ErrKeyNotFound) { // It's normal for no sandboxes to be found. Just bail out. return nil } diff --git a/libnetwork/service_linux.go b/libnetwork/service_linux.go index 207c926e06..31975c09a8 100644 --- a/libnetwork/service_linux.go +++ b/libnetwork/service_linux.go @@ -2,6 +2,7 @@ package libnetwork import ( "context" + "errors" "fmt" "io" "net" @@ -138,7 +139,7 @@ func (n *Network) addLBBackend(ip net.IP, lb *loadBalancer) { return } - if err := i.NewService(s); err != nil && err != syscall.EEXIST { + if err := i.NewService(s); err != nil && !errors.Is(err, syscall.EEXIST) { log.G(context.TODO()).Errorf("Failed to create a new service for vip %s fwmark %d in sbox %.7s (%.7s): %v", lb.vip, lb.fwMark, sb.ID(), sb.ContainerID(), err) return } @@ -158,7 +159,7 @@ func (n *Network) addLBBackend(ip net.IP, lb *loadBalancer) { Weight: 1, ConnectionFlags: flags, }) - if err != nil && err != syscall.EEXIST { + if err != nil && !errors.Is(err, syscall.EEXIST) { log.G(context.TODO()).Errorf("Failed to create real server %s for vip %s fwmark %d in sbox %.7s (%.7s): %v", ip, lb.vip, lb.fwMark, sb.ID(), sb.ContainerID(), err) } @@ -208,19 +209,19 @@ func (n *Network) rmLBBackend(ip net.IP, lb *loadBalancer, rmService bool, fullR } if fullRemove { - if err := i.DelDestination(s, d); err != nil && err != syscall.ENOENT { + if err := i.DelDestination(s, d); err != nil && !errors.Is(err, syscall.ENOENT) { log.G(context.TODO()).Errorf("Failed to delete real server %s for vip %s fwmark %d in sbox %.7s (%.7s): %v", ip, lb.vip, lb.fwMark, sb.ID(), sb.ContainerID(), err) } } else { d.Weight = 0 - if err := i.UpdateDestination(s, d); err != nil && err != syscall.ENOENT { + if err := i.UpdateDestination(s, d); err != nil && !errors.Is(err, syscall.ENOENT) { log.G(context.TODO()).Errorf("Failed to set LB weight of real server %s to 0 for vip %s fwmark %d in sbox %.7s (%.7s): %v", ip, lb.vip, lb.fwMark, sb.ID(), sb.ContainerID(), err) } } if rmService { s.SchedName = ipvs.RoundRobin - if err := i.DelService(s); err != nil && err != syscall.ENOENT { + if err := i.DelService(s); err != nil && !errors.Is(err, syscall.ENOENT) { log.G(context.TODO()).Errorf("Failed to delete service for vip %s fwmark %d in sbox %.7s (%.7s): %v", lb.vip, lb.fwMark, sb.ID(), sb.ContainerID(), err) } diff --git a/libnetwork/store.go b/libnetwork/store.go index e751e2dda9..f048b4f742 100644 --- a/libnetwork/store.go +++ b/libnetwork/store.go @@ -2,6 +2,7 @@ package libnetwork import ( "context" + "errors" "fmt" "github.com/containerd/log" @@ -23,7 +24,7 @@ func (c *Controller) getNetworks() ([]*Network, error) { var nl []*Network kvol, err := c.store.List(&Network{ctrlr: c}) - if err != nil && err != datastore.ErrKeyNotFound { + if err != nil && !errors.Is(err, datastore.ErrKeyNotFound) { return nil, fmt.Errorf("failed to get networks: %w", err) } @@ -45,7 +46,7 @@ func (c *Controller) getNetworksFromStore(ctx context.Context) []*Network { // F kvol, err := c.store.List(&Network{ctrlr: c}) if err != nil { - if err != datastore.ErrKeyNotFound { + if !errors.Is(err, datastore.ErrKeyNotFound) { log.G(ctx).Debugf("failed to get networks from store: %v", err) } return nil @@ -80,7 +81,7 @@ func (n *Network) getEndpointsFromStore() ([]*Endpoint, error) { kvol, err := n.getController().store.List(&Endpoint{network: n}) if err != nil { - if err != datastore.ErrKeyNotFound { + if !errors.Is(err, datastore.ErrKeyNotFound) { return nil, fmt.Errorf("failed to get endpoints for network %s: %w", n.Name(), err) } @@ -101,7 +102,7 @@ func (c *Controller) updateToStore(ctx context.Context, kvObject datastore.KVObj defer span.End() if err := c.store.PutObjectAtomic(kvObject); err != nil { - if err == datastore.ErrKeyModified { + if errors.Is(err, datastore.ErrKeyModified) { return err } return fmt.Errorf("failed to update store for object type %T: %v", kvObject, err) @@ -113,7 +114,7 @@ func (c *Controller) updateToStore(ctx context.Context, kvObject datastore.KVObj func (c *Controller) deleteFromStore(kvObject datastore.KVObject) error { retry: if err := c.store.DeleteObjectAtomic(kvObject); err != nil { - if err == datastore.ErrKeyModified { + if errors.Is(err, datastore.ErrKeyModified) { if err := c.store.GetObject(kvObject); err != nil { return fmt.Errorf("could not update the kvobject to latest when trying to delete: %v", err) } diff --git a/oci/devices_linux.go b/oci/devices_linux.go index 92f8708432..7c09d6e4d7 100644 --- a/oci/devices_linux.go +++ b/oci/devices_linux.go @@ -1,6 +1,7 @@ package oci import ( + "errors" "fmt" "os" "path/filepath" @@ -40,7 +41,7 @@ func DevicesFromPath(pathOnHost, pathInContainer, cgroupPermissions string) (dev // if the device is not a device node // try to see if it's a directory holding many devices - if err == coci.ErrNotADevice { + if errors.Is(err, coci.ErrNotADevice) { // check if it is a directory if src, e := os.Stat(resolvedPathOnHost); e == nil && src.IsDir() { // mount the internal devices recursively diff --git a/pkg/ioutils/readers_test.go b/pkg/ioutils/readers_test.go index 4ab2adfa9c..90b4ec0bc8 100644 --- a/pkg/ioutils/readers_test.go +++ b/pkg/ioutils/readers_test.go @@ -46,7 +46,7 @@ func TestCancelReadCloser(t *testing.T) { for { var buf [128]byte _, err := crc.Read(buf[:]) - if err == context.DeadlineExceeded { + if errors.Is(err, context.DeadlineExceeded) { break } else if err != nil { t.Fatalf("got unexpected error: %v", err) diff --git a/pkg/process/process_unix.go b/pkg/process/process_unix.go index baa1693a24..13298bbdcc 100644 --- a/pkg/process/process_unix.go +++ b/pkg/process/process_unix.go @@ -4,6 +4,7 @@ package process import ( "bytes" + "errors" "fmt" "os" "path/filepath" @@ -33,7 +34,7 @@ func Alive(pid int) bool { // Either the PID was found (no error) or we get an EPERM, which means // the PID exists, but we don't have permissions to signal it. - return err == nil || err == unix.EPERM + return err == nil || errors.Is(err, unix.EPERM) default: _, err := os.Stat(filepath.Join("/proc", strconv.Itoa(pid))) return err == nil @@ -51,7 +52,7 @@ func Kill(pid int) error { return fmt.Errorf("invalid PID (%d): only positive PIDs are allowed", pid) } err := unix.Kill(pid, unix.SIGKILL) - if err != nil && err != unix.ESRCH { + if err != nil && !errors.Is(err, unix.ESRCH) { return err } return nil diff --git a/pkg/stdcopy/stdcopy.go b/pkg/stdcopy/stdcopy.go index cf9368aa4e..611432a626 100644 --- a/pkg/stdcopy/stdcopy.go +++ b/pkg/stdcopy/stdcopy.go @@ -107,7 +107,7 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, _ error) { var nr2 int nr2, err = src.Read(buf[nr:]) nr += nr2 - if err == io.EOF { + if errors.Is(err, io.EOF) { if nr < stdWriterPrefixLen { return written, nil } @@ -153,7 +153,7 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, _ error) { var nr2 int nr2, err = src.Read(buf[nr:]) nr += nr2 - if err == io.EOF { + if errors.Is(err, io.EOF) { if nr < frameSize+stdWriterPrefixLen { return written, nil } diff --git a/pkg/stdcopy/stdcopy_test.go b/pkg/stdcopy/stdcopy_test.go index 014e58ba44..14ea60ea53 100644 --- a/pkg/stdcopy/stdcopy_test.go +++ b/pkg/stdcopy/stdcopy_test.go @@ -67,7 +67,7 @@ func TestWriteWithWriterError(t *testing.T) { }, Stdout) data := []byte("This won't get written, sigh") n, err := writer.Write(data) - if err != expectedError { + if !errors.Is(err, expectedError) { t.Fatalf("Didn't get expected error.") } if n != expectedReturnedBytes { @@ -139,7 +139,7 @@ func TestStdCopyReturnsErrorReadingHeader(t *testing.T) { if written != 0 { t.Fatalf("Expected 0 bytes read, got %d", written) } - if err != expectedError { + if !errors.Is(err, expectedError) { t.Fatalf("Didn't get expected error") } } @@ -162,7 +162,7 @@ func TestStdCopyReturnsErrorReadingFrame(t *testing.T) { if written != 0 { t.Fatalf("Expected 0 bytes read, got %d", written) } - if err != expectedError { + if !errors.Is(err, expectedError) { t.Fatalf("Didn't get expected error") } } @@ -226,7 +226,7 @@ func TestStdCopyReturnsWriteErrors(t *testing.T) { if written != 0 { t.Fatalf("StdCopy should have written 0, but has written %d", written) } - if err != expectedError { + if !errors.Is(err, expectedError) { t.Fatalf("Didn't get expected error, got %v", err) } } @@ -244,7 +244,7 @@ func TestStdCopyDetectsNotFullyWrittenFrames(t *testing.T) { if written != 0 { t.Fatalf("StdCopy should have return 0 written bytes, but returned %d", written) } - if err != io.ErrShortWrite { + if !errors.Is(err, io.ErrShortWrite) { t.Fatalf("Didn't get expected io.ErrShortWrite error") } } diff --git a/pkg/system/utimes_unix.go b/pkg/system/utimes_unix.go index dbb7d97cd4..ebde64dd43 100644 --- a/pkg/system/utimes_unix.go +++ b/pkg/system/utimes_unix.go @@ -3,6 +3,7 @@ package system import ( + "errors" "syscall" "golang.org/x/sys/unix" @@ -16,7 +17,7 @@ func LUtimesNano(path string, ts []syscall.Timespec) error { unix.NsecToTimespec(syscall.TimespecToNsec(ts[1])), } err := unix.UtimesNanoAt(unix.AT_FDCWD, path, uts, unix.AT_SYMLINK_NOFOLLOW) - if err != nil && err != unix.ENOSYS { + if err != nil && !errors.Is(err, unix.ENOSYS) { return err } diff --git a/pkg/system/xattrs_linux.go b/pkg/system/xattrs_linux.go index 8ca94b75d8..ba4e9b3e1c 100644 --- a/pkg/system/xattrs_linux.go +++ b/pkg/system/xattrs_linux.go @@ -1,6 +1,8 @@ package system import ( + "errors" + "golang.org/x/sys/unix" ) @@ -16,7 +18,7 @@ func Lgetxattr(path string, attr string) ([]byte, error) { dest := make([]byte, 128) sz, errno := unix.Lgetxattr(path, attr, dest) - for errno == unix.ERANGE { + for errors.Is(errno, unix.ERANGE) { // Buffer too small, use zero-sized buffer to get the actual size sz, errno = unix.Lgetxattr(path, attr, []byte{}) if errno != nil { @@ -27,7 +29,7 @@ func Lgetxattr(path string, attr string) ([]byte, error) { } switch { - case errno == unix.ENODATA: + case errors.Is(errno, unix.ENODATA): return nil, nil case errno != nil: return sysErr(errno) diff --git a/pkg/tailfile/tailfile.go b/pkg/tailfile/tailfile.go index 27f6a7f311..a77435030f 100644 --- a/pkg/tailfile/tailfile.go +++ b/pkg/tailfile/tailfile.go @@ -189,7 +189,7 @@ func (s *scanner) Scan(ctx context.Context) bool { offset := s.pos - int64(readSize) n, err := s.r.ReadAt(s.buf[:readSize], offset) - if err != nil && err != io.EOF { + if err != nil && !errors.Is(err, io.EOF) { s.err = err return false } diff --git a/pkg/tailfile/tailfile_test.go b/pkg/tailfile/tailfile_test.go index ff5fbb21ed..a9add26795 100644 --- a/pkg/tailfile/tailfile_test.go +++ b/pkg/tailfile/tailfile_test.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "context" + "errors" "fmt" "io" "os" @@ -130,10 +131,10 @@ truncated line`) if _, err := f.Seek(0, io.SeekStart); err != nil { t.Fatal(err) } - if _, err := TailFile(f, -1); err != ErrNonPositiveLinesNumber { + if _, err := TailFile(f, -1); !errors.Is(err, ErrNonPositiveLinesNumber) { t.Fatalf("Expected ErrNonPositiveLinesNumber, got %v", err) } - if _, err := TailFile(f, 0); err != ErrNonPositiveLinesNumber { + if _, err := TailFile(f, 0); !errors.Is(err, ErrNonPositiveLinesNumber) { t.Fatalf("Expected ErrNonPositiveLinesNumber, got %s", err) } } @@ -255,7 +256,7 @@ func TestNewTailReader(t *testing.T) { return } if len(test.data) == 0 { - assert.Assert(t, err == ErrNonPositiveLinesNumber, err) + assert.Assert(t, errors.Is(err, ErrNonPositiveLinesNumber), err) return } @@ -285,7 +286,7 @@ func TestNewTailReader(t *testing.T) { assert.Check(t, string(data) == "b", string(data)) _, _, err = rdr.ReadLine() - assert.Assert(t, err == io.EOF, err) + assert.Assert(t, errors.Is(err, io.EOF), err) }) }) t.Run("truncated last line", func(t *testing.T) { @@ -304,7 +305,7 @@ func TestNewTailReader(t *testing.T) { assert.Check(t, string(data) == "b", string(data)) _, _, err = rdr.ReadLine() - assert.Assert(t, err == io.EOF, err) + assert.Assert(t, errors.Is(err, io.EOF), err) }) }) @@ -320,7 +321,7 @@ func TestNewTailReader(t *testing.T) { assert.Check(t, string(data) == "b", string(data)) _, _, err = rdr.ReadLine() - assert.Assert(t, err == io.EOF, err) + assert.Assert(t, errors.Is(err, io.EOF), err) }) }) } diff --git a/pkg/tarsum/tarsum.go b/pkg/tarsum/tarsum.go index 45d31b30aa..86768fe78d 100644 --- a/pkg/tarsum/tarsum.go +++ b/pkg/tarsum/tarsum.go @@ -208,7 +208,7 @@ func (ts *tarSum) Read(buf []byte) (int, error) { n, err := ts.tarR.Read(buf2) if err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { if _, err := ts.h.Write(buf2[:n]); err != nil { return 0, err } diff --git a/pkg/tarsum/tarsum_test.go b/pkg/tarsum/tarsum_test.go index 18bf7ca833..1169fc453b 100644 --- a/pkg/tarsum/tarsum_test.go +++ b/pkg/tarsum/tarsum_test.go @@ -10,6 +10,7 @@ import ( "crypto/sha256" "crypto/sha512" "encoding/hex" + "errors" "fmt" "io" "os" @@ -545,7 +546,7 @@ func renderSumForHeader(v Version, h *tar.Header, data []byte) (string, error) { tr := tar.NewReader(ts) for { hdr, err := tr.Next() - if hdr == nil || err == io.EOF { + if hdr == nil || errors.Is(err, io.EOF) { // Signals the end of the archive. break } diff --git a/pkg/tarsum/versioning_test.go b/pkg/tarsum/versioning_test.go index 4d2b2a2d5e..da7946f636 100644 --- a/pkg/tarsum/versioning_test.go +++ b/pkg/tarsum/versioning_test.go @@ -2,6 +2,7 @@ package tarsum import ( "archive/tar" + "errors" "fmt" "strings" "testing" @@ -74,7 +75,7 @@ func TestGetVersion(t *testing.T) { // test one that does not exist, to ensure it errors str := "weak+md5:abcdeabcde" _, err := GetVersionFromTarsum(str) - if err != ErrNotVersion { + if !errors.Is(err, ErrNotVersion) { t.Fatalf("%q : %s", err, str) } } diff --git a/plugin/v2/settable_test.go b/plugin/v2/settable_test.go index b55252e35f..ac0c6f6853 100644 --- a/plugin/v2/settable_test.go +++ b/plugin/v2/settable_test.go @@ -1,6 +1,7 @@ package v2 import ( + "errors" "reflect" "testing" ) @@ -23,7 +24,7 @@ func TestNewSettable(t *testing.T) { for _, c := range contexts { s, err := newSettable(c.arg) - if err != c.err { + if !errors.Is(err, c.err) { t.Fatalf("expected error to be %v, got %v", c.err, err) } @@ -61,7 +62,7 @@ func TestIsSettable(t *testing.T) { for _, c := range contexts { if res, err := c.set.isSettable(c.allowedSettableFields, c.settable); res != c.result { t.Fatalf("expected result to be %t, got %t", c.result, res) - } else if err != c.err { + } else if !errors.Is(err, c.err) { t.Fatalf("expected error to be %v, got %v", c.err, err) } } diff --git a/quota/projectquota.go b/quota/projectquota.go index b41b5f2031..f27bc02872 100644 --- a/quota/projectquota.go +++ b/quota/projectquota.go @@ -413,11 +413,11 @@ func makeBackingFsDev(home string) (string, error) { // Re-create just in case someone copied the home directory over to a new device unix.Unlink(backingFsBlockDev) err := unix.Mknod(backingFsBlockDev, unix.S_IFBLK|0o600, int(stat.Dev)) - switch err { - case nil: + switch { + case err == nil: return backingFsBlockDev, nil - case unix.ENOSYS, unix.EPERM: + case errors.Is(err, unix.ENOSYS), errors.Is(err, unix.EPERM): return "", ErrQuotaNotSupported default: diff --git a/quota/projectquota_test.go b/quota/projectquota_test.go index 8fe8904c72..ae96684ae6 100644 --- a/quota/projectquota_test.go +++ b/quota/projectquota_test.go @@ -3,6 +3,7 @@ package quota import ( + "errors" "io" "os" "path/filepath" @@ -62,7 +63,7 @@ func testBiggerThanQuota(t *testing.T, ctrl *Control, homeDir, testDir, testSubD biggerThanQuotaFile := filepath.Join(testSubDir, "bigger-than-quota") err := os.WriteFile(biggerThanQuotaFile, make([]byte, testQuotaSize+1), 0o644) assert.ErrorContains(t, err, "") - if err == io.ErrShortWrite { + if errors.Is(err, io.ErrShortWrite) { assert.NilError(t, os.Remove(biggerThanQuotaFile)) } } diff --git a/reference/store_test.go b/reference/store_test.go index 5f5e8a67f1..1bb3df6977 100644 --- a/reference/store_test.go +++ b/reference/store_test.go @@ -2,6 +2,7 @@ package reference import ( "bytes" + "errors" "os" "path/filepath" "testing" @@ -228,7 +229,7 @@ func TestAddDeleteGet(t *testing.T) { if err != nil { t.Fatalf("could not parse reference: %v", err) } - if _, err = store.Get(nonExistRepo); err != ErrDoesNotExist { + if _, err = store.Get(nonExistRepo); !errors.Is(err, ErrDoesNotExist) { t.Fatal("Expected ErrDoesNotExist from Get") } @@ -237,7 +238,7 @@ func TestAddDeleteGet(t *testing.T) { if err != nil { t.Fatalf("could not parse reference: %v", err) } - if _, err = store.Get(nonExistTag); err != ErrDoesNotExist { + if _, err = store.Get(nonExistTag); !errors.Is(err, ErrDoesNotExist) { t.Fatal("Expected ErrDoesNotExist from Get") } @@ -289,12 +290,12 @@ func TestAddDeleteGet(t *testing.T) { } // Delete should return ErrDoesNotExist for a nonexistent repo - if _, err = store.Delete(nonExistRepo); err != ErrDoesNotExist { + if _, err = store.Delete(nonExistRepo); !errors.Is(err, ErrDoesNotExist) { t.Fatal("Expected ErrDoesNotExist from Delete") } // Delete should return ErrDoesNotExist for a nonexistent tag - if _, err = store.Delete(nonExistTag); err != ErrDoesNotExist { + if _, err = store.Delete(nonExistTag); !errors.Is(err, ErrDoesNotExist) { t.Fatal("Expected ErrDoesNotExist from Delete") } @@ -302,19 +303,19 @@ func TestAddDeleteGet(t *testing.T) { if deleted, err := store.Delete(ref1); err != nil || !deleted { t.Fatal("Delete failed") } - if _, err := store.Get(ref1); err != ErrDoesNotExist { + if _, err := store.Get(ref1); !errors.Is(err, ErrDoesNotExist) { t.Fatal("Expected ErrDoesNotExist from Get") } if deleted, err := store.Delete(ref5); err != nil || !deleted { t.Fatal("Delete failed") } - if _, err := store.Get(ref5); err != ErrDoesNotExist { + if _, err := store.Get(ref5); !errors.Is(err, ErrDoesNotExist) { t.Fatal("Expected ErrDoesNotExist from Get") } if deleted, err := store.Delete(nameOnly); err != nil || !deleted { t.Fatal("Delete failed") } - if _, err := store.Get(nameOnly); err != ErrDoesNotExist { + if _, err := store.Get(nameOnly); !errors.Is(err, ErrDoesNotExist) { t.Fatal("Expected ErrDoesNotExist from Get") } } diff --git a/registry/resumable/resumablerequestreader.go b/registry/resumable/resumablerequestreader.go index 70471d578c..9ccee1e439 100644 --- a/registry/resumable/resumablerequestreader.go +++ b/registry/resumable/resumablerequestreader.go @@ -2,6 +2,7 @@ package resumable import ( "context" + "errors" "fmt" "io" "net/http" @@ -77,7 +78,7 @@ func (r *requestReader) Read(p []byte) (n int, _ error) { if err != nil { r.cleanUpResponse() } - if err != nil && err != io.EOF { + if err != nil && !errors.Is(err, io.EOF) { log.G(context.TODO()).Infof("encountered error during pull and clearing it before resume: %s", err) err = nil } diff --git a/testutil/daemon/daemon.go b/testutil/daemon/daemon.go index a83ccddac6..97158f9685 100644 --- a/testutil/daemon/daemon.go +++ b/testutil/daemon/daemon.go @@ -693,7 +693,7 @@ func (d *Daemon) Stop(t testing.TB) { t.Helper() err := d.StopWithError() if err != nil { - if err != errDaemonNotStarted { + if !errors.Is(err, errDaemonNotStarted) { t.Fatalf("[%s] error while stopping the daemon: %v", d.id, err) } else { t.Logf("[%s] daemon is not started", d.id) diff --git a/testutil/daemon/daemon_linux.go b/testutil/daemon/daemon_linux.go index 4d1415b18b..70a4fa1588 100644 --- a/testutil/daemon/daemon_linux.go +++ b/testutil/daemon/daemon_linux.go @@ -1,6 +1,7 @@ package daemon import ( + "errors" "fmt" "os" "path/filepath" @@ -19,7 +20,7 @@ func cleanupNetworkNamespace(t testing.TB, d *Daemon) { // cleaned up when a new daemon is instantiated with a // new exec root. filepath.WalkDir(filepath.Join(d.execRoot, "netns"), func(path string, _ os.DirEntry, _ error) error { - if err := unix.Unmount(path, unix.MNT_DETACH); err != nil && err != unix.EINVAL && err != unix.ENOENT { + if err := unix.Unmount(path, unix.MNT_DETACH); err != nil && !errors.Is(err, unix.EINVAL) && !errors.Is(err, unix.ENOENT) { t.Logf("[%s] unmount of %s failed: %v", d.id, path, err) } os.Remove(path) diff --git a/volume/service/errors.go b/volume/service/errors.go index 48b28e011a..3356c9c59f 100644 --- a/volume/service/errors.go +++ b/volume/service/errors.go @@ -1,6 +1,7 @@ package service import ( + "errors" "strings" ) @@ -101,5 +102,5 @@ func isErr(err error, expected error) bool { } return false } - return err == expected + return errors.Is(err, expected) } diff --git a/volume/service/restore.go b/volume/service/restore.go index ab1cdf4e82..9518dd35a3 100644 --- a/volume/service/restore.go +++ b/volume/service/restore.go @@ -2,6 +2,7 @@ package service import ( "context" + "errors" "sync" "github.com/containerd/log" @@ -35,7 +36,7 @@ func (s *VolumeStore) restore() { var err error if meta.Driver != "" { v, err = lookupVolume(ctx, s.drivers, meta.Driver, meta.Name) - if err != nil && err != errNoSuchVolume { + if err != nil && !errors.Is(err, errNoSuchVolume) { log.G(ctx).WithError(err).WithField("driver", meta.Driver).WithField("volume", meta.Name).Warn("Error restoring volume") return } @@ -47,7 +48,7 @@ func (s *VolumeStore) restore() { } else { v, err = s.getVolume(ctx, meta.Name, meta.Driver) if err != nil { - if err == errNoSuchVolume { + if errors.Is(err, errNoSuchVolume) { chRemove <- &meta } return