瀏覽代碼

Merge pull request #42445 from thaJeztah/bump_golang_ci

[testing] ~update~ fix linting issues found by golangci-lint v1.40.1
Sebastiaan van Stijn 4 年之前
父節點
當前提交
2773f81aa5
共有 44 個文件被更改,包括 120 次插入99 次删除
  1. 1 4
      builder/builder-next/adapters/snapshot/snapshot.go
  2. 1 1
      builder/builder-next/worker/gc_unix.go
  3. 5 4
      builder/dockerfile/builder.go
  4. 2 4
      client/request.go
  5. 1 0
      daemon/cluster/executor/container/adapter.go
  6. 4 4
      daemon/config/config_unix.go
  7. 2 1
      daemon/container.go
  8. 4 4
      daemon/daemon_unix.go
  9. 2 2
      daemon/graphdriver/copy/copy.go
  10. 2 2
      daemon/graphdriver/devmapper/deviceset.go
  11. 1 1
      daemon/graphdriver/devmapper/devmapper_test.go
  12. 2 2
      daemon/graphdriver/graphtest/graphtest_unix.go
  13. 1 1
      daemon/list.go
  14. 2 3
      daemon/logger/journald/read.go
  15. 2 1
      daemon/logger/local/local_test.go
  16. 2 1
      daemon/logger/splunk/splunk.go
  17. 5 5
      daemon/network.go
  18. 2 11
      daemon/stats/collector.go
  19. 1 1
      daemon/top_unix.go
  20. 3 1
      daemon/volumes_unix_test.go
  21. 2 1
      distribution/push_v2.go
  22. 18 3
      hack/validate/golangci-lint.yml
  23. 5 5
      integration-cli/docker_api_stats_test.go
  24. 11 11
      integration-cli/docker_cli_build_test.go
  25. 1 0
      integration/build/build_session_test.go
  26. 1 0
      integration/container/checkpoint_test.go
  27. 1 1
      integration/internal/network/network.go
  28. 1 0
      integration/network/service_test.go
  29. 2 2
      integration/plugin/graphdriver/external_test.go
  30. 1 0
      libcontainerd/remote/client.go
  31. 1 1
      oci/oci.go
  32. 2 2
      pkg/archive/archive_unix.go
  33. 1 1
      pkg/archive/archive_unix_test.go
  34. 10 0
      pkg/archive/copy.go
  35. 2 2
      pkg/devicemapper/devmapper.go
  36. 1 1
      pkg/jsonmessage/jsonmessage_test.go
  37. 1 1
      pkg/loopback/loopback.go
  38. 2 2
      pkg/namesgenerator/names-generator.go
  39. 5 5
      pkg/system/chtimes_linux_test.go
  40. 1 1
      pkg/system/stat_linux.go
  41. 1 4
      plugin/fetch_linux.go
  42. 3 1
      plugin/v2/plugin.go
  43. 1 1
      testutil/stringutils.go
  44. 1 1
      volume/drivers/extpoint.go

+ 1 - 4
builder/builder-next/adapters/snapshot/snapshot.go

@@ -383,10 +383,7 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap
 		if err != nil {
 			return err
 		}
-		if err := b.Put(keyIsCommitted, []byte{}); err != nil {
-			return err
-		}
-		return nil
+		return b.Put(keyIsCommitted, []byte{})
 	})
 }
 

+ 1 - 1
builder/builder-next/worker/gc_unix.go

@@ -11,7 +11,7 @@ func detectDefaultGCCap(root string) int64 {
 	if err := syscall.Statfs(root, &st); err != nil {
 		return defaultCap
 	}
-	diskSize := int64(st.Bsize) * int64(st.Blocks) // nolint unconvert
+	diskSize := int64(st.Bsize) * int64(st.Blocks) //nolint unconvert
 	avail := diskSize / 10
 	return (avail/(1<<30) + 1) * 1e9 // round up
 }

+ 5 - 4
builder/dockerfile/builder.go

@@ -254,10 +254,10 @@ func (b *Builder) dispatchDockerfileWithCancellation(parseResult []instructions.
 		totalCommands += len(stage.Commands)
 	}
 	shlex := shell.NewLex(escapeToken)
-	for _, meta := range metaArgs {
-		currentCommandIndex = printCommand(b.Stdout, currentCommandIndex, totalCommands, &meta)
+	for i := range metaArgs {
+		currentCommandIndex = printCommand(b.Stdout, currentCommandIndex, totalCommands, &metaArgs[i])
 
-		err := processMetaArg(meta, shlex, buildArgs)
+		err := processMetaArg(metaArgs[i], shlex, buildArgs)
 		if err != nil {
 			return nil, err
 		}
@@ -265,7 +265,8 @@ func (b *Builder) dispatchDockerfileWithCancellation(parseResult []instructions.
 
 	stagesResults := newStagesBuildResults()
 
-	for _, stage := range parseResult {
+	for _, s := range parseResult {
+		stage := s
 		if err := stagesResults.checkStageNameAvailable(stage.Name); err != nil {
 			return nil, err
 		}

+ 2 - 4
client/request.go

@@ -242,10 +242,8 @@ func (cli *Client) addHeaders(req *http.Request, headers headers) *http.Request
 		req.Header.Set(k, v)
 	}
 
-	if headers != nil {
-		for k, v := range headers {
-			req.Header[k] = v
-		}
+	for k, v := range headers {
+		req.Header[k] = v
 	}
 	return req
 }

+ 1 - 0
daemon/cluster/executor/container/adapter.go

@@ -431,6 +431,7 @@ func (c *containerAdapter) remove(ctx context.Context) error {
 func (c *containerAdapter) createVolumes(ctx context.Context) error {
 	// Create plugin volumes that are embedded inside a Mount
 	for _, mount := range c.container.task.Spec.GetContainer().Mounts {
+		mount := mount
 		if mount.Type != api.MountTypeVolume {
 			continue
 		}

+ 4 - 4
daemon/config/config_unix.go

@@ -74,14 +74,14 @@ func (conf *Config) IsSwarmCompatible() error {
 }
 
 func verifyDefaultIpcMode(mode string) error {
-	const hint = "Use \"shareable\" or \"private\"."
+	const hint = `use "shareable" or "private"`
 
 	dm := containertypes.IpcMode(mode)
 	if !dm.Valid() {
-		return fmt.Errorf("Default IPC mode setting (%v) is invalid. "+hint, dm)
+		return fmt.Errorf("default IPC mode setting (%v) is invalid; "+hint, dm)
 	}
 	if dm != "" && !dm.IsPrivate() && !dm.IsShareable() {
-		return fmt.Errorf("IPC mode \"%v\" is not supported as default value. "+hint, dm)
+		return fmt.Errorf(`IPC mode "%v" is not supported as default value; `+hint, dm)
 	}
 	return nil
 }
@@ -89,7 +89,7 @@ func verifyDefaultIpcMode(mode string) error {
 func verifyDefaultCgroupNsMode(mode string) error {
 	cm := containertypes.CgroupnsMode(mode)
 	if !cm.Valid() {
-		return fmt.Errorf("Default cgroup namespace mode (%v) is invalid. Use \"host\" or \"private\".", cm) // nolint: golint
+		return fmt.Errorf(`default cgroup namespace mode (%v) is invalid; use "host" or "private"`, cm)
 	}
 
 	return nil

+ 2 - 1
daemon/container.go

@@ -279,7 +279,8 @@ func validateHostConfig(hostConfig *containertypes.HostConfig, platform string)
 	}
 	// Validate mounts; check if host directories still exist
 	parser := volumemounts.NewParser(platform)
-	for _, cfg := range hostConfig.Mounts {
+	for _, c := range hostConfig.Mounts {
+		cfg := c
 		if err := parser.ValidateMountConfig(&cfg); err != nil {
 			return err
 		}

+ 4 - 4
daemon/daemon_unix.go

@@ -186,8 +186,8 @@ func getBlkioWeightDevices(config containertypes.Resources) ([]specs.LinuxWeight
 		weight := weightDevice.Weight
 		d := specs.LinuxWeightDevice{Weight: &weight}
 		// The type is 32bit on mips.
-		d.Major = int64(unix.Major(uint64(stat.Rdev))) // nolint: unconvert
-		d.Minor = int64(unix.Minor(uint64(stat.Rdev))) // nolint: unconvert
+		d.Major = int64(unix.Major(uint64(stat.Rdev))) //nolint: unconvert
+		d.Minor = int64(unix.Minor(uint64(stat.Rdev))) //nolint: unconvert
 		blkioWeightDevices = append(blkioWeightDevices, d)
 	}
 
@@ -258,8 +258,8 @@ func getBlkioThrottleDevices(devs []*blkiodev.ThrottleDevice) ([]specs.LinuxThro
 		}
 		d := specs.LinuxThrottleDevice{Rate: d.Rate}
 		// the type is 32bit on mips
-		d.Major = int64(unix.Major(uint64(stat.Rdev))) // nolint: unconvert
-		d.Minor = int64(unix.Minor(uint64(stat.Rdev))) // nolint: unconvert
+		d.Major = int64(unix.Major(uint64(stat.Rdev))) //nolint: unconvert
+		d.Minor = int64(unix.Minor(uint64(stat.Rdev))) //nolint: unconvert
 		throttleDevices = append(throttleDevices, d)
 	}
 

+ 2 - 2
daemon/graphdriver/copy/copy.go

@@ -144,7 +144,7 @@ func DirCopy(srcDir, dstDir string, copyMode Mode, copyXattrs bool) error {
 		switch mode := f.Mode(); {
 		case mode.IsRegular():
 			// the type is 32bit on mips
-			id := fileID{dev: uint64(stat.Dev), ino: stat.Ino} // nolint: unconvert
+			id := fileID{dev: uint64(stat.Dev), ino: stat.Ino} //nolint: unconvert
 			if copyMode == Hardlink {
 				isHardlink = true
 				if err2 := os.Link(srcPath, dstPath); err2 != nil {
@@ -223,7 +223,7 @@ func DirCopy(srcDir, dstDir string, copyMode Mode, copyXattrs bool) error {
 		}
 
 		// system.Chtimes doesn't support a NOFOLLOW flag atm
-		// nolint: unconvert
+		//nolint: unconvert
 		if f.IsDir() {
 			dirsToSetMtimes.PushFront(&dirMtimeInfo{dstPath: &dstPath, stat: stat})
 		} else if !isSymlink {

+ 2 - 2
daemon/graphdriver/devmapper/deviceset.go

@@ -1534,7 +1534,7 @@ func getDeviceMajorMinor(file *os.File) (uint64, uint64, error) {
 	}
 
 	// the type is 32bit on mips
-	dev := uint64(stat.Rdev) // nolint: unconvert
+	dev := uint64(stat.Rdev) //nolint: unconvert
 	majorNum := major(dev)
 	minorNum := minor(dev)
 
@@ -1746,7 +1746,7 @@ func (devices *DeviceSet) initDevmapper(doInit bool) (retErr error) {
 	//	- The target of this device is at major <maj> and minor <min>
 	//	- If <inode> is defined, use that file inside the device as a loopback image. Otherwise use the device itself.
 	// The type Dev in Stat_t is 32bit on mips.
-	devices.devicePrefix = fmt.Sprintf("docker-%d:%d-%d", major(uint64(st.Dev)), minor(uint64(st.Dev)), st.Ino) // nolint: unconvert
+	devices.devicePrefix = fmt.Sprintf("docker-%d:%d-%d", major(uint64(st.Dev)), minor(uint64(st.Dev)), st.Ino) //nolint: unconvert
 	logger.Debugf("Generated prefix: %s", devices.devicePrefix)
 
 	// Check for the existence of the thin-pool device

+ 1 - 1
daemon/graphdriver/devmapper/devmapper_test.go

@@ -41,7 +41,7 @@ func initLoopbacks() error {
 		// only create new loopback files if they don't exist
 		if _, err := os.Stat(loopPath); err != nil {
 			if mkerr := syscall.Mknod(loopPath,
-				uint32(statT.Mode|syscall.S_IFBLK), int((7<<8)|(i&0xff)|((i&0xfff00)<<12))); mkerr != nil { // nolint: unconvert
+				uint32(statT.Mode|syscall.S_IFBLK), int((7<<8)|(i&0xff)|((i&0xfff00)<<12))); mkerr != nil { //nolint: unconvert
 				return mkerr
 			}
 			os.Chown(loopPath, int(statT.Uid), int(statT.Gid))

+ 2 - 2
daemon/graphdriver/graphtest/graphtest_unix.go

@@ -302,10 +302,10 @@ func writeRandomFile(path string, size uint64) error {
 	}
 
 	// Cast to []byte
-	header := *(*reflect.SliceHeader)(unsafe.Pointer(&buf))
+	header := *(*reflect.SliceHeader)(unsafe.Pointer(&buf)) //nolint:govet // FIXME: unsafeptr: possible misuse of reflect.SliceHeader (govet) see https://github.com/moby/moby/issues/42444
 	header.Len *= 8
 	header.Cap *= 8
-	data := *(*[]byte)(unsafe.Pointer(&header))
+	data := *(*[]byte)(unsafe.Pointer(&header)) //nolint:govet // FIXME: unsafeptr: possible misuse of reflect.SliceHeader (govet) see https://github.com/moby/moby/issues/42444
 
 	return ioutil.WriteFile(path, data, 0700)
 }

+ 1 - 1
daemon/list.go

@@ -553,7 +553,7 @@ func includeContainerInList(container *container.Snapshot, ctx *listContext) ite
 
 	if len(ctx.expose) > 0 || len(ctx.publish) > 0 {
 		var (
-			shouldSkip    bool = true
+			shouldSkip    = true
 			publishedPort nat.Port
 			exposedPort   nat.Port
 		)

+ 2 - 3
daemon/logger/journald/read.go

@@ -125,10 +125,10 @@ func (s *journald) Close() error {
 	return nil
 }
 
-// convert error code returned from a sd_journal_* function
+// CErr converts error code returned from a sd_journal_* function
 // (which returns -errno) to a string
 func CErr(ret C.int) string {
-	return C.GoString(C.strerror(C.int(-ret)))
+	return C.GoString(C.strerror(-ret))
 }
 
 func (s *journald) drainJournal(logWatcher *logger.LogWatcher, j *C.sd_journal, oldCursor *C.char, untilUnixMicro uint64) (*C.char, bool, int) {
@@ -377,7 +377,6 @@ func (s *journald) readLogs(logWatcher *logger.LogWatcher, config logger.ReadCon
 	}
 
 	C.free(unsafe.Pointer(cursor))
-	return
 }
 
 func (s *journald) ReadLogs(config logger.ReadConfig) *logger.LogWatcher {

+ 2 - 1
daemon/logger/local/local_test.go

@@ -211,7 +211,8 @@ func copyLogMessage(src *logger.Message) *logger.Message {
 	dst.Err = src.Err
 	dst.Line = append(dst.Line, src.Line...)
 	if src.PLogMetaData != nil {
-		dst.PLogMetaData = &(*src.PLogMetaData)
+		lmd := *src.PLogMetaData
+		dst.PLogMetaData = &lmd
 	}
 	return dst
 }

+ 2 - 1
daemon/logger/splunk/splunk.go

@@ -170,7 +170,8 @@ func New(info logger.Info) (logger.Logger, error) {
 		return nil, fmt.Errorf("%s: %s is expected", driverName, splunkTokenKey)
 	}
 
-	tlsConfig := &tls.Config{}
+	// FIXME set minimum TLS version for splunk (see https://github.com/moby/moby/issues/42443)
+	tlsConfig := &tls.Config{} //nolint: gosec // G402: TLS MinVersion too low.
 
 	// Splunk is using autogenerated certificates by default,
 	// allow users to trust them with skipping verification

+ 5 - 5
daemon/network.go

@@ -155,7 +155,7 @@ var (
 func (daemon *Daemon) startIngressWorker() {
 	ingressJobsChannel = make(chan *ingressJob, 100)
 	go func() {
-		// nolint: gosimple
+		//nolint: gosimple
 		for {
 			select {
 			case r := <-ingressJobsChannel:
@@ -365,7 +365,7 @@ func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string
 	n, err := c.NewNetwork(driver, create.Name, id, nwOptions...)
 	if err != nil {
 		if _, ok := err.(libnetwork.ErrDataStoreNotInitialized); ok {
-			// nolint: golint
+			//nolint: golint
 			return nil, errors.New("This node is not a swarm manager. Use \"docker swarm init\" or \"docker swarm join\" to connect this node to swarm and try again.")
 		}
 		return nil, err
@@ -573,9 +573,9 @@ func (daemon *Daemon) GetNetworks(filter filters.Args, config types.NetworkListC
 	}
 
 	if config.Detailed {
-		for i, n := range list {
-			np := &n
-			buildDetailedNetworkResources(np, idx[n.ID], config.Verbose)
+		for i := range list {
+			np := &list[i]
+			buildDetailedNetworkResources(np, idx[np.ID], config.Verbose)
 			list[i] = *np
 		}
 	}

+ 2 - 11
daemon/stats/collector.go

@@ -7,6 +7,7 @@ import (
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/container"
+	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/pkg/pubsub"
 	"github.com/sirupsen/logrus"
 )
@@ -131,7 +132,7 @@ func (s *Collector) Run() {
 
 				pair.publisher.Publish(*stats)
 
-			case notRunningErr, notFoundErr:
+			case errdefs.ErrConflict, errdefs.ErrNotFound:
 				// publish empty stats containing only name and ID if not running or not found
 				pair.publisher.Publish(types.StatsJSON{
 					Name: pair.container.Name,
@@ -150,13 +151,3 @@ func (s *Collector) Run() {
 		time.Sleep(s.interval)
 	}
 }
-
-type notRunningErr interface {
-	error
-	Conflict()
-}
-
-type notFoundErr interface {
-	error
-	NotFound()
-}

+ 1 - 1
daemon/top_unix.go

@@ -20,7 +20,7 @@ func validatePSArgs(psArgs string) error {
 	// NOTE: \\s does not detect unicode whitespaces.
 	// So we use fieldsASCII instead of strings.Fields in parsePSOutput.
 	// See https://github.com/docker/docker/pull/24358
-	// nolint: gosimple
+	//nolint: gosimple
 	re := regexp.MustCompile("\\s+([^\\s]*)=\\s*(PID[^\\s]*)")
 	for _, group := range re.FindAllStringSubmatch(psArgs, -1) {
 		if len(group) >= 3 {

+ 3 - 1
daemon/volumes_unix_test.go

@@ -96,6 +96,8 @@ func TestBackportMountSpec(t *testing.T) {
 		return string(b)
 	}
 
+	mpc := *c.MountPoints["/jambolan"]
+
 	for _, x := range []expected{
 		{
 			mp: &volumemounts.MountPoint{
@@ -225,7 +227,7 @@ func TestBackportMountSpec(t *testing.T) {
 			comment: "partially configured named volume caused by #32613",
 		},
 		{
-			mp:      &(*c.MountPoints["/jambolan"]), // copy the mountpoint, expect no changes
+			mp:      &mpc,
 			comment: "volume defined in mounts API",
 		},
 		{

+ 2 - 1
distribution/push_v2.go

@@ -321,7 +321,8 @@ func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.
 	// Attempt to find another repository in the same registry to mount the layer from to avoid an unnecessary upload
 	candidates := getRepositoryMountCandidates(pd.repoInfo, pd.hmacKey, maxMountAttempts, v2Metadata)
 	isUnauthorizedError := false
-	for _, mountCandidate := range candidates {
+	for _, mc := range candidates {
+		mountCandidate := mc
 		logrus.Debugf("attempting to mount layer %s (%s) from %s", diffID, mountCandidate.Digest, mountCandidate.SourceRepository)
 		createOpts := []distribution.BlobCreateOption{}
 

+ 18 - 3
hack/validate/golangci-lint.yml

@@ -81,16 +81,25 @@ issues:
     - text: "(G201|G202): SQL string (formatting|concatenation)"
       linters:
         - gosec
+    # FIXME: evaluate these and fix where needed: G307: Deferring unsafe method "*os.File" on type "Close" (gosec)
+    - text: "G307: Deferring unsafe method"
+      linters:
+        - gosec
     # FIXME temporarily suppress these. See #39924
     - text: "SA1019: .*\\.Xattrs is deprecated: Use PAXRecords instead"
       linters:
         - staticcheck
     # FIXME temporarily suppress these. See #39926
-    - text: "SA1019: httputil.NewClientConn is deprecated"
+    - text: "SA1019: httputil.NewClientConn"
       linters:
         - staticcheck
     # FIXME temporarily suppress these (related to the ones above)
-    - text: "SA1019: httputil.ErrPersistEOF is deprecated"
+    - text: "SA1019: httputil.ErrPersistEOF"
+      linters:
+        - staticcheck
+    # FIXME temporarily suppress these for false positives in tests (see https://github.com/dominikh/go-tools/issues/1022)
+    - text: "SA5011"
+      path: _test\.go
       linters:
         - staticcheck
     # This code is doing some fun stuff with reflect and it trips up the linter.
@@ -105,4 +114,10 @@ issues:
       path: libnetwork/network.go
       linters:
         - structcheck
-        - unused
+        - unused
+
+  # Maximum issues count per one linter. Set to 0 to disable. Default is 50.
+  max-issues-per-linter: 0
+
+  # Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
+  max-same-issues: 0

+ 5 - 5
integration-cli/docker_api_stats_test.go

@@ -67,7 +67,7 @@ func (s *DockerSuite) TestAPIStatsStoppedContainerInGoroutines(c *testing.T) {
 	id := strings.TrimSpace(out)
 
 	getGoRoutines := func() int {
-		_, body, err := request.Get(fmt.Sprintf("/info"))
+		_, body, err := request.Get("/info")
 		assert.NilError(c, err)
 		info := types.Info{}
 		err = json.NewDecoder(body).Decode(&info)
@@ -78,7 +78,7 @@ func (s *DockerSuite) TestAPIStatsStoppedContainerInGoroutines(c *testing.T) {
 
 	// When the HTTP connection is closed, the number of goroutines should not increase.
 	routines := getGoRoutines()
-	_, body, err := request.Get(fmt.Sprintf("/containers/%s/stats", id))
+	_, body, err := request.Get("/containers/" + id + "/stats")
 	assert.NilError(c, err)
 	body.Close()
 
@@ -190,7 +190,7 @@ func (s *DockerSuite) TestAPIStatsNetworkStatsVersioning(c *testing.T) {
 func getNetworkStats(c *testing.T, id string) map[string]types.NetworkStats {
 	var st *types.StatsJSON
 
-	_, body, err := request.Get(fmt.Sprintf("/containers/%s/stats?stream=false", id))
+	_, body, err := request.Get("/containers/" + id + "/stats?stream=false")
 	assert.NilError(c, err)
 
 	err = json.NewDecoder(body).Decode(&st)
@@ -207,7 +207,7 @@ func getNetworkStats(c *testing.T, id string) map[string]types.NetworkStats {
 func getVersionedStats(c *testing.T, id string, apiVersion string) map[string]interface{} {
 	stats := make(map[string]interface{})
 
-	_, body, err := request.Get(fmt.Sprintf("/%s/containers/%s/stats?stream=false", apiVersion, id))
+	_, body, err := request.Get("/" + apiVersion + "/containers/" + id + "/stats?stream=false")
 	assert.NilError(c, err)
 	defer body.Close()
 
@@ -284,7 +284,7 @@ func (s *DockerSuite) TestAPIStatsNoStreamConnectedContainers(c *testing.T) {
 
 	ch := make(chan error, 1)
 	go func() {
-		resp, body, err := request.Get(fmt.Sprintf("/containers/%s/stats?stream=false", id2))
+		resp, body, err := request.Get("/containers/" + id2 + "/stats?stream=false")
 		defer body.Close()
 		if err != nil {
 			ch <- err

+ 11 - 11
integration-cli/docker_cli_build_test.go

@@ -4544,16 +4544,16 @@ func (s *DockerSuite) TestBuildBuildTimeArgEnv(c *testing.T) {
 	    `
 	result := buildImage("testbuildtimeargenv",
 		cli.WithFlags(
-			"--build-arg", fmt.Sprintf("FOO1=fromcmd"),
-			"--build-arg", fmt.Sprintf("FOO2="),
-			"--build-arg", fmt.Sprintf("FOO3"), // set in env
-			"--build-arg", fmt.Sprintf("FOO4"), // not set in env
-			"--build-arg", fmt.Sprintf("FOO5=fromcmd"),
+			"--build-arg", "FOO1=fromcmd",
+			"--build-arg", "FOO2=",
+			"--build-arg", "FOO3", // set in env
+			"--build-arg", "FOO4", // not set in env
+			"--build-arg", "FOO5=fromcmd",
 			// FOO6 is not set at all
-			"--build-arg", fmt.Sprintf("FOO7=fromcmd"), // should produce a warning
-			"--build-arg", fmt.Sprintf("FOO8="), // should produce a warning
-			"--build-arg", fmt.Sprintf("FOO9"), // should produce a warning
-			"--build-arg", fmt.Sprintf("FO10"), // not set in env, empty value
+			"--build-arg", "FOO7=fromcmd", // should produce a warning
+			"--build-arg", "FOO8=", // should produce a warning
+			"--build-arg", "FOO9", // should produce a warning
+			"--build-arg", "FO10", // not set in env, empty value
 		),
 		cli.WithEnvironmentVariables(append(os.Environ(),
 			"FOO1=fromenv",
@@ -4665,7 +4665,7 @@ func (s *DockerSuite) TestBuildMultiStageGlobalArg(c *testing.T) {
 
 	result := cli.BuildCmd(c, imgName,
 		build.WithDockerfile(dockerfile),
-		cli.WithFlags("--build-arg", fmt.Sprintf("tag=latest")))
+		cli.WithFlags("--build-arg", "tag=latest"))
 	result.Assert(c, icmd.Success)
 
 	result = cli.DockerCmd(c, "images", "-q", "-f", "label=multifromtest=1")
@@ -4687,7 +4687,7 @@ func (s *DockerSuite) TestBuildMultiStageUnusedArg(c *testing.T) {
 
 	result := cli.BuildCmd(c, imgName,
 		build.WithDockerfile(dockerfile),
-		cli.WithFlags("--build-arg", fmt.Sprintf("baz=abc")))
+		cli.WithFlags("--build-arg", "baz=abc"))
 	result.Assert(c, icmd.Success)
 	assert.Assert(c, strings.Contains(result.Combined(), "[Warning]"))
 	assert.Assert(c, strings.Contains(result.Combined(), "[baz] were not consumed"))

+ 1 - 0
integration/build/build_session_test.go

@@ -89,6 +89,7 @@ func TestBuildWithSession(t *testing.T) {
 	assert.Check(t, is.Equal(du.BuilderSize, int64(0)))
 }
 
+//nolint:unused // false positive: linter detects this as "unused"
 func testBuildWithSession(t *testing.T, client dclient.APIClient, daemonHost string, dir, dockerfile string) (outStr string) {
 	ctx := context.Background()
 	sess, err := session.NewSession(ctx, "foo1", "foo")

+ 1 - 0
integration/container/checkpoint_test.go

@@ -20,6 +20,7 @@ import (
 	"gotest.tools/v3/skip"
 )
 
+//nolint:unused // false positive: linter detects this as "unused"
 func containerExec(t *testing.T, client client.APIClient, cID string, cmd []string) {
 	t.Logf("Exec: %s", cmd)
 	ctx := context.Background()

+ 1 - 1
integration/internal/network/network.go

@@ -26,7 +26,7 @@ func Create(ctx context.Context, client client.APIClient, name string, ops ...fu
 }
 
 // CreateNoError creates a network with the specified options and verifies there were no errors
-func CreateNoError(ctx context.Context, t *testing.T, client client.APIClient, name string, ops ...func(*types.NetworkCreate)) string { // nolint: golint
+func CreateNoError(ctx context.Context, t *testing.T, client client.APIClient, name string, ops ...func(*types.NetworkCreate)) string { //nolint: golint
 	t.Helper()
 
 	name, err := createNetwork(ctx, client, name, ops...)

+ 1 - 0
integration/network/service_test.go

@@ -292,6 +292,7 @@ func TestServiceRemoveKeepsIngressNetwork(t *testing.T) {
 	assert.Assert(t, ok, "ingress-sbox not present in ingress network")
 }
 
+//nolint:unused // for some reason, the "unused" linter marks this function as "unused"
 func swarmIngressReady(client client.NetworkAPIClient) func(log poll.LogT) poll.Result {
 	return func(log poll.LogT) poll.Result {
 		netInfo, err := client.NetworkInspect(context.Background(), ingressNet, types.NetworkInspectOptions{

+ 2 - 2
integration/plugin/graphdriver/external_test.go

@@ -129,7 +129,7 @@ func setupPlugin(t *testing.T, ec map[string]*graphEventsCounter, ext string, mu
 		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
 		switch t := data.(type) {
 		case error:
-			fmt.Fprintln(w, fmt.Sprintf(`{"Err": %q}`, t.Error()))
+			fmt.Fprintf(w, "{\"Err\": %q}\n", t.Error())
 		case string:
 			fmt.Fprintln(w, t)
 		default:
@@ -318,7 +318,7 @@ func setupPlugin(t *testing.T, ec map[string]*graphEventsCounter, ext string, mu
 		parent := r.URL.Query().Get("parent")
 
 		if id == "" {
-			http.Error(w, fmt.Sprintf("missing id"), 409)
+			http.Error(w, "missing id", 409)
 		}
 
 		size, err := driver.ApplyDiff(id, parent, diff)

+ 1 - 0
libcontainerd/remote/client.go

@@ -568,6 +568,7 @@ func (c *client) CreateCheckpoint(ctx context.Context, containerID, checkpointDi
 
 	var cpDesc *v1.Descriptor
 	for _, m := range index.Manifests {
+		m := m
 		if m.MediaType == images.MediaTypeContainerd1Checkpoint {
 			cpDesc = &m // nolint:gosec
 			break

+ 1 - 1
oci/oci.go

@@ -13,7 +13,7 @@ import (
 //      that *only* passes `a` as value: `echo a > /sys/fs/cgroup/1/devices.allow, which would be
 //      the "implicit" equivalent of "a *:* rwm". Source-code also looks to confirm this, and returns
 //      early for "a" (all); https://github.com/torvalds/linux/blob/v5.10/security/device_cgroup.c#L614-L642
-// nolint: gosimple
+//nolint: gosimple
 var deviceCgroupRuleRegex = regexp.MustCompile("^([acb]) ([0-9]+|\\*):([0-9]+|\\*) ([rwm]{1,3})$")
 
 // SetCapabilities sets the provided capabilities on the spec

+ 2 - 2
pkg/archive/archive_unix.go

@@ -51,8 +51,8 @@ func setHeaderForSpecialDevice(hdr *tar.Header, name string, stat interface{}) (
 		// Currently go does not fill in the major/minors
 		if s.Mode&unix.S_IFBLK != 0 ||
 			s.Mode&unix.S_IFCHR != 0 {
-			hdr.Devmajor = int64(unix.Major(uint64(s.Rdev))) // nolint: unconvert
-			hdr.Devminor = int64(unix.Minor(uint64(s.Rdev))) // nolint: unconvert
+			hdr.Devmajor = int64(unix.Major(uint64(s.Rdev))) //nolint: unconvert
+			hdr.Devminor = int64(unix.Minor(uint64(s.Rdev))) //nolint: unconvert
 		}
 	}
 

+ 1 - 1
pkg/archive/archive_unix_test.go

@@ -186,7 +186,7 @@ func getNlink(path string) (uint64, error) {
 		return 0, fmt.Errorf("expected type *syscall.Stat_t, got %t", stat.Sys())
 	}
 	// We need this conversion on ARM64
-	// nolint: unconvert
+	//nolint: unconvert
 	return uint64(statT.Nlink), nil
 }
 

+ 10 - 0
pkg/archive/copy.go

@@ -354,6 +354,16 @@ func RebaseArchiveEntries(srcContent io.Reader, oldBase, newBase string) io.Read
 				return
 			}
 
+			// Ignoring GoSec G110. See https://github.com/securego/gosec/pull/433
+			// and https://cure53.de/pentest-report_opa.pdf, which recommends to
+			// replace io.Copy with io.CopyN7. The latter allows to specify the
+			// maximum number of bytes that should be read. By properly defining
+			// the limit, it can be assured that a GZip compression bomb cannot
+			// easily cause a Denial-of-Service.
+			// After reviewing with @tonistiigi and @cpuguy83, this should not
+			// affect us, because here we do not read into memory, hence should
+			// not be vulnerable to this code consuming memory.
+			//nolint:gosec // G110: Potential DoS vulnerability via decompression bomb (gosec)
 			if _, err = io.Copy(rebasedTar, srcTar); err != nil {
 				w.CloseWithError(err)
 				return

+ 2 - 2
pkg/devicemapper/devmapper.go

@@ -14,7 +14,7 @@ import (
 )
 
 // Same as DM_DEVICE_* enum values from libdevmapper.h
-// nolint: deadcode,unused,varcheck
+//nolint: deadcode,unused,varcheck
 const (
 	deviceCreate TaskType = iota
 	deviceReload
@@ -380,7 +380,7 @@ func CancelDeferredRemove(deviceName string) error {
 		return fmt.Errorf("devicemapper: Can't set sector %s", err)
 	}
 
-	if err := task.setMessage(fmt.Sprintf("@cancel_deferred_remove")); err != nil {
+	if err := task.setMessage("@cancel_deferred_remove"); err != nil {
 		return fmt.Errorf("devicemapper: Can't set message %s", err)
 	}
 

+ 1 - 1
pkg/jsonmessage/jsonmessage_test.go

@@ -252,7 +252,7 @@ func TestDisplayJSONMessagesStream(t *testing.T) {
 		// Without progress, with ID
 		"{ \"id\": \"ID\",\"status\": \"status\" }": {
 			"ID: status\n",
-			fmt.Sprintf("ID: status\n"),
+			"ID: status\n",
 		},
 		// With progress
 		"{ \"id\": \"ID\", \"status\": \"status\", \"progress\": \"ProgressMessage\" }": {

+ 1 - 1
pkg/loopback/loopback.go

@@ -38,7 +38,7 @@ func FindLoopDeviceFor(file *os.File) *os.File {
 	}
 	targetInode := stat.Ino
 	// the type is 32bit on mips
-	targetDevice := uint64(stat.Dev) // nolint: unconvert
+	targetDevice := uint64(stat.Dev) //nolint: unconvert
 
 	for i := 0; true; i++ {
 		path := fmt.Sprintf("/dev/loop%d", i)

+ 2 - 2
pkg/namesgenerator/names-generator.go

@@ -840,13 +840,13 @@ var (
 // integer between 0 and 10 will be added to the end of the name, e.g `focused_turing3`
 func GetRandomName(retry int) string {
 begin:
-	name := fmt.Sprintf("%s_%s", left[rand.Intn(len(left))], right[rand.Intn(len(right))])
+	name := fmt.Sprintf("%s_%s", left[rand.Intn(len(left))], right[rand.Intn(len(right))]) //nolint:gosec // G404: Use of weak random number generator (math/rand instead of crypto/rand)
 	if name == "boring_wozniak" /* Steve Wozniak is not boring */ {
 		goto begin
 	}
 
 	if retry > 0 {
-		name = fmt.Sprintf("%s%d", name, rand.Intn(10))
+		name = fmt.Sprintf("%s%d", name, rand.Intn(10)) //nolint:gosec // G404: Use of weak random number generator (math/rand instead of crypto/rand)
 	}
 	return name
 }

+ 5 - 5
pkg/system/chtimes_linux_test.go

@@ -26,7 +26,7 @@ func TestChtimesLinux(t *testing.T) {
 	}
 
 	stat := f.Sys().(*syscall.Stat_t)
-	aTime := time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)) // nolint: unconvert
+	aTime := time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)) //nolint: unconvert
 	if aTime != unixEpochTime {
 		t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
 	}
@@ -40,7 +40,7 @@ func TestChtimesLinux(t *testing.T) {
 	}
 
 	stat = f.Sys().(*syscall.Stat_t)
-	aTime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)) // nolint: unconvert
+	aTime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)) //nolint: unconvert
 	if aTime != unixEpochTime {
 		t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
 	}
@@ -54,7 +54,7 @@ func TestChtimesLinux(t *testing.T) {
 	}
 
 	stat = f.Sys().(*syscall.Stat_t)
-	aTime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)) // nolint: unconvert
+	aTime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)) //nolint: unconvert
 	if aTime != unixEpochTime {
 		t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
 	}
@@ -68,7 +68,7 @@ func TestChtimesLinux(t *testing.T) {
 	}
 
 	stat = f.Sys().(*syscall.Stat_t)
-	aTime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)) // nolint: unconvert
+	aTime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)) //nolint: unconvert
 	if aTime != afterUnixEpochTime {
 		t.Fatalf("Expected: %s, got: %s", afterUnixEpochTime, aTime)
 	}
@@ -82,7 +82,7 @@ func TestChtimesLinux(t *testing.T) {
 	}
 
 	stat = f.Sys().(*syscall.Stat_t)
-	aTime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)) // nolint: unconvert
+	aTime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)) //nolint: unconvert
 	if aTime.Truncate(time.Second) != unixMaxTime.Truncate(time.Second) {
 		t.Fatalf("Expected: %s, got: %s", unixMaxTime.Truncate(time.Second), aTime.Truncate(time.Second))
 	}

+ 1 - 1
pkg/system/stat_linux.go

@@ -9,7 +9,7 @@ func fromStatT(s *syscall.Stat_t) (*StatT, error) {
 		uid:  s.Uid,
 		gid:  s.Gid,
 		// the type is 32bit on mips
-		rdev: uint64(s.Rdev), // nolint: unconvert
+		rdev: uint64(s.Rdev), //nolint: unconvert
 		mtim: s.Mtim}, nil
 }
 

+ 1 - 4
plugin/fetch_linux.go

@@ -109,10 +109,7 @@ func (pm *Manager) fetch(ctx context.Context, ref reference.Named, auth *types.A
 
 	fp := withFetchProgress(pm.blobStore, out, ref)
 	handlers = append([]images.Handler{fp, remotes.FetchHandler(pm.blobStore, fetcher)}, handlers...)
-	if err := images.Dispatch(ctx, images.Handlers(handlers...), nil, desc); err != nil {
-		return err
-	}
-	return nil
+	return images.Dispatch(ctx, images.Handlers(handlers...), nil, desc)
 }
 
 // applyLayer makes an images.HandlerFunc which applies a fetched image rootfs layer to a directory.

+ 3 - 1
plugin/v2/plugin.go

@@ -126,7 +126,9 @@ func (p *Plugin) Set(args []string) error {
 	// TODO(vieux): lots of code duplication here, needs to be refactored.
 
 next:
-	for _, s := range sets {
+	for _, set := range sets {
+		s := set
+
 		// range over all the envs in the config
 		for _, env := range p.PluginObj.Config.Env {
 			// found the env in the config

+ 1 - 1
testutil/stringutils.go

@@ -8,7 +8,7 @@ func GenerateRandomAlphaOnlyString(n int) string {
 	letters := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
 	b := make([]byte, n)
 	for i := range b {
-		b[i] = letters[rand.Intn(len(letters))]
+		b[i] = letters[rand.Intn(len(letters))] //nolint: gosec // G404: Use of weak random number generator (math/rand instead of crypto/rand)
 	}
 	return string(b)
 }

+ 1 - 1
volume/drivers/extpoint.go

@@ -21,7 +21,7 @@ const extName = "VolumeDriver"
 // volumeDriver defines the available functions that volume plugins must implement.
 // This interface is only defined to generate the proxy objects.
 // It's not intended to be public or reused.
-// nolint: deadcode
+//nolint: deadcode
 type volumeDriver interface {
 	// Create a volume with the given name
 	Create(name string, opts map[string]string) (err error)