From 56516173d069fa0bb2c488062d6b38db8275f681 Mon Sep 17 00:00:00 2001 From: yashsingh74 Date: Sat, 19 Apr 2025 10:48:37 +0530 Subject: [PATCH 01/11] fix: QF1002: could use tagged switch on host (staticcheck) Signed-off-by: yashsingh74 --- core/images/archive/importer.go | 7 ++++--- core/metadata/db.go | 5 +++-- core/remotes/docker/httpreadseeker.go | 5 +++-- core/remotes/docker/registry.go | 6 +++--- integration/remote/util/util_windows.go | 7 ++++--- plugins/snapshots/devmapper/snapshotter.go | 5 +++-- 6 files changed, 20 insertions(+), 15 deletions(-) diff --git a/core/images/archive/importer.go b/core/images/archive/importer.go index 64a1587f77..6cbd25c745 100644 --- a/core/images/archive/importer.go +++ b/core/images/archive/importer.go @@ -104,15 +104,16 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader, opt } hdrName := path.Clean(hdr.Name) - if hdrName == ocispec.ImageLayoutFile { + switch hdrName { + case ocispec.ImageLayoutFile: if err = onUntarJSON(tr, &ociLayout); err != nil { return ocispec.Descriptor{}, fmt.Errorf("untar oci layout %q: %w", hdr.Name, err) } - } else if hdrName == "manifest.json" { + case "manifest.json": if err = onUntarJSON(tr, &mfsts); err != nil { return ocispec.Descriptor{}, fmt.Errorf("untar manifest %q: %w", hdr.Name, err) } - } else { + default: dgst, err := onUntarBlob(ctx, tr, store, hdr.Size, "tar-"+hdrName) if err != nil { return ocispec.Descriptor{}, fmt.Errorf("failed to ingest %q: %w", hdr.Name, err) diff --git a/core/metadata/db.go b/core/metadata/db.go index 4a56b38736..960b40ab05 100644 --- a/core/metadata/db.go +++ b/core/metadata/db.go @@ -389,12 +389,13 @@ func (m *DB) GarbageCollect(ctx context.Context) (gc.Stats, error) { return nil } - if n.Type == ResourceSnapshot { + switch n.Type { + case ResourceSnapshot: if idx := strings.IndexRune(n.Key, '/'); idx > 0 { m.dirtySS[n.Key[:idx]] = struct{}{} } // queue event to publish after successful commit - } else if n.Type == ResourceContent || n.Type == ResourceIngest { + case ResourceContent, ResourceIngest: m.dirtyCS = true } diff --git a/core/remotes/docker/httpreadseeker.go b/core/remotes/docker/httpreadseeker.go index 6739e7904e..fa52aea647 100644 --- a/core/remotes/docker/httpreadseeker.go +++ b/core/remotes/docker/httpreadseeker.go @@ -59,7 +59,8 @@ func (hrs *httpReadSeeker) Read(p []byte) (n int, err error) { if n > 0 || err == nil { hrs.errsWithNoProgress = 0 } - if err == io.ErrUnexpectedEOF { + switch err { + case io.ErrUnexpectedEOF: // connection closed unexpectedly. try reconnecting. if n == 0 { hrs.errsWithNoProgress++ @@ -76,7 +77,7 @@ func (hrs *httpReadSeeker) Read(p []byte) (n int, err error) { if _, err2 := hrs.reader(); err2 == nil { return n, nil } - } else if err == io.EOF { + case io.EOF: // The CRI's imagePullProgressTimeout relies on responseBody.Close to // update the process monitor's status. If the err is io.EOF, close // the connection since there is no more available data. diff --git a/core/remotes/docker/registry.go b/core/remotes/docker/registry.go index bbae768b15..f26e98d984 100644 --- a/core/remotes/docker/registry.go +++ b/core/remotes/docker/registry.go @@ -212,10 +212,10 @@ func MatchAllHosts(string) (bool, error) { // Note: this does not handle matching of ip addresses in octal, // decimal or hex form. func MatchLocalhost(host string) (bool, error) { - switch { - case host == "::1": + switch host { + case "::1": return true, nil - case host == "[::1]": + case "[::1]": return true, nil } h, p, err := net.SplitHostPort(host) diff --git a/integration/remote/util/util_windows.go b/integration/remote/util/util_windows.go index 7ffee94760..a995c3a8ec 100644 --- a/integration/remote/util/util_windows.go +++ b/integration/remote/util/util_windows.go @@ -110,9 +110,10 @@ func parseEndpoint(endpoint string) (string, string, error) { return "", "", err } - if u.Scheme == "tcp" { + switch u.Scheme { + case "tcp": return "tcp", u.Host, nil - } else if u.Scheme == "npipe" { + case "npipe": if strings.HasPrefix(u.Path, "//./pipe") { return "npipe", u.Path, nil } @@ -123,7 +124,7 @@ func parseEndpoint(endpoint string) (string, string, error) { host = "." } return "npipe", fmt.Sprintf("//%s%s", host, u.Path), nil - } else if u.Scheme == "" { + case "": return "", "", fmt.Errorf("Using %q as endpoint is deprecated, please consider using full url format", endpoint) } return u.Scheme, "", fmt.Errorf("protocol %q not supported", u.Scheme) diff --git a/plugins/snapshots/devmapper/snapshotter.go b/plugins/snapshots/devmapper/snapshotter.go index 650b79de0f..5ec9baed8d 100644 --- a/plugins/snapshots/devmapper/snapshotter.go +++ b/plugins/snapshots/devmapper/snapshotter.go @@ -509,10 +509,11 @@ func (s *Snapshotter) getDevicePath(snap storage.Snapshot) string { func (s *Snapshotter) buildMounts(ctx context.Context, snap storage.Snapshot, fileSystemType fsType) []mount.Mount { var options []string - if fileSystemType == "" { + switch fileSystemType { + case "": log.G(ctx).Error("File system type cannot be empty") return nil - } else if fileSystemType == fsTypeXFS { + case fsTypeXFS: options = append(options, "nouuid") } if snap.Kind != snapshots.KindActive { From 1ff5900044c455284a3601df5a2d3272d33a4547 Mon Sep 17 00:00:00 2001 From: yashsingh74 Date: Sat, 19 Apr 2025 10:54:16 +0530 Subject: [PATCH 02/11] fix: QF1004: strings.ReplaceAll instead (staticcheck) Signed-off-by: yashsingh74 --- core/remotes/docker/config/config_windows.go | 4 ++-- core/remotes/docker/errcode.go | 2 +- integration/remote/util/util_windows.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/remotes/docker/config/config_windows.go b/core/remotes/docker/config/config_windows.go index 4697728b9c..3fd4775847 100644 --- a/core/remotes/docker/config/config_windows.go +++ b/core/remotes/docker/config/config_windows.go @@ -25,11 +25,11 @@ import ( func hostPaths(root, host string) (hosts []string) { ch := hostDirectory(host) if ch != host { - hosts = append(hosts, filepath.Join(root, strings.Replace(ch, ":", "", -1))) + hosts = append(hosts, filepath.Join(root, strings.ReplaceAll(ch, ":", ""))) } hosts = append(hosts, - filepath.Join(root, strings.Replace(host, ":", "", -1)), + filepath.Join(root, strings.ReplaceAll(host, ":", "")), filepath.Join(root, "_default"), ) diff --git a/core/remotes/docker/errcode.go b/core/remotes/docker/errcode.go index b62256f82a..8e1469d3e9 100644 --- a/core/remotes/docker/errcode.go +++ b/core/remotes/docker/errcode.go @@ -46,7 +46,7 @@ func (ec ErrorCode) ErrorCode() ErrorCode { // Error returns the ID/Value func (ec ErrorCode) Error() string { // NOTE(stevvooe): Cannot use message here since it may have unpopulated args. - return strings.ToLower(strings.Replace(ec.String(), "_", " ", -1)) + return strings.ToLower(strings.ReplaceAll(ec.String(), "_", " ")) } // Descriptor returns the descriptor for the error code. diff --git a/integration/remote/util/util_windows.go b/integration/remote/util/util_windows.go index a995c3a8ec..500a60b883 100644 --- a/integration/remote/util/util_windows.go +++ b/integration/remote/util/util_windows.go @@ -104,7 +104,7 @@ func npipeDial(ctx context.Context, addr string) (net.Conn, error) { func parseEndpoint(endpoint string) (string, string, error) { // url.Parse doesn't recognize \, so replace with / first. - endpoint = strings.Replace(endpoint, "\\", "/", -1) + endpoint = strings.ReplaceAll(endpoint, "\\", "/") u, err := url.Parse(endpoint) if err != nil { return "", "", err From b3eec6d8e95741aaf6f488ae528f6b8c50659b88 Mon Sep 17 00:00:00 2001 From: yashsingh74 Date: Sat, 19 Apr 2025 11:01:23 +0530 Subject: [PATCH 03/11] fix: ST1005: error strings should not end with punctuation or newlines Signed-off-by: yashsingh74 --- cmd/ctr/commands/run/run_windows.go | 2 +- core/mount/mount_idmapped_linux.go | 6 +++--- integration/remote/util/util_windows.go | 2 +- internal/cri/opts/spec_opts.go | 2 +- plugins/diff/windows/windows.go | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cmd/ctr/commands/run/run_windows.go b/cmd/ctr/commands/run/run_windows.go index f5c4f8f268..60c1f6b3a1 100644 --- a/cmd/ctr/commands/run/run_windows.go +++ b/cmd/ctr/commands/run/run_windows.go @@ -128,7 +128,7 @@ func NewContainer(ctx context.Context, client *containerd.Client, cliContext *cl opts = append(opts, oci.WithTTYSize(int(size.Width), int(size.Height))) } if cliContext.Bool("net-host") { - return nil, errors.New("Cannot use host mode networking with Windows containers") + return nil, errors.New("cannot use host mode networking with Windows containers") } if cliContext.Bool("cni") { ns, err := netns.NewNetNS("") diff --git a/core/mount/mount_idmapped_linux.go b/core/mount/mount_idmapped_linux.go index 2c9519fa8a..f8157a7ceb 100644 --- a/core/mount/mount_idmapped_linux.go +++ b/core/mount/mount_idmapped_linux.go @@ -95,16 +95,16 @@ func IDMapMountWithAttrs(source, target string, usernsFd int, attrSet uint64, at dFd, err := unix.OpenTree(-int(unix.EBADF), source, uint(unix.OPEN_TREE_CLONE|unix.OPEN_TREE_CLOEXEC|unix.AT_EMPTY_PATH)) if err != nil { - return fmt.Errorf("Unable to open tree for %s: %w", target, err) + return fmt.Errorf("unable to open tree for %s: %w", target, err) } defer unix.Close(dFd) if err = unix.MountSetattr(dFd, "", unix.AT_EMPTY_PATH, &attr); err != nil { - return fmt.Errorf("Unable to shift GID/UID or set mount attrs for %s: %w", target, err) + return fmt.Errorf("unable to shift GID/UID or set mount attrs for %s: %w", target, err) } if err = unix.MoveMount(dFd, "", -int(unix.EBADF), target, unix.MOVE_MOUNT_F_EMPTY_PATH); err != nil { - return fmt.Errorf("Unable to attach mount tree to %s: %w", target, err) + return fmt.Errorf("unable to attach mount tree to %s: %w", target, err) } return nil } diff --git a/integration/remote/util/util_windows.go b/integration/remote/util/util_windows.go index 500a60b883..23db774b1c 100644 --- a/integration/remote/util/util_windows.go +++ b/integration/remote/util/util_windows.go @@ -125,7 +125,7 @@ func parseEndpoint(endpoint string) (string, string, error) { } return "npipe", fmt.Sprintf("//%s%s", host, u.Path), nil case "": - return "", "", fmt.Errorf("Using %q as endpoint is deprecated, please consider using full url format", endpoint) + return "", "", fmt.Errorf("using %q as endpoint is deprecated, please consider using full url format", endpoint) } return u.Scheme, "", fmt.Errorf("protocol %q not supported", u.Scheme) } diff --git a/internal/cri/opts/spec_opts.go b/internal/cri/opts/spec_opts.go index 148026a526..bdab9e9c19 100644 --- a/internal/cri/opts/spec_opts.go +++ b/internal/cri/opts/spec_opts.go @@ -305,7 +305,7 @@ func WithoutNamespace(t runtimespec.LinuxNamespaceType) oci.SpecOpts { func WithNamespacePath(t runtimespec.LinuxNamespaceType, nsPath string) oci.SpecOpts { return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) error { if s.Linux == nil { - return fmt.Errorf("Linux spec is required") + return fmt.Errorf("linux spec is required") } for i, ns := range s.Linux.Namespaces { diff --git a/plugins/diff/windows/windows.go b/plugins/diff/windows/windows.go index 804e681c0c..613df25dea 100644 --- a/plugins/diff/windows/windows.go +++ b/plugins/diff/windows/windows.go @@ -361,7 +361,7 @@ func mountPairToLayerStack(lower, upper []mount.Mount) ([]string, error) { // May return an ErrNotImplemented, which will fall back to LCOW upperLayer, upperParentLayerPaths, err := mountsToLayerAndParents(upper) if err != nil { - return nil, fmt.Errorf("Upper mount invalid: %w", err) + return nil, fmt.Errorf("upper mount invalid: %w", err) } lowerLayer, lowerParentLayerPaths, err := mountsToLayerAndParents(lower) @@ -369,7 +369,7 @@ func mountPairToLayerStack(lower, upper []mount.Mount) ([]string, error) { // Upper was a windows-layer, lower is not. We can't handle that. return nil, fmt.Errorf("windowsDiff cannot diff a windows-layer against a non-windows-layer: %w", errdefs.ErrInvalidArgument) } else if err != nil { - return nil, fmt.Errorf("Lower mount invalid: %w", err) + return nil, fmt.Errorf("lower mount invalid: %w", err) } // Trivial case, diff-against-nothing From d93d18c857e0fd31feed4b3b8084d36d90f8beb7 Mon Sep 17 00:00:00 2001 From: yashsingh74 Date: Sat, 19 Apr 2025 11:05:13 +0530 Subject: [PATCH 04/11] fix: QF1001: could apply De Morgan's law (staticcheck) Signed-off-by: yashsingh74 --- internal/cri/opts/spec_opts.go | 2 +- internal/cri/opts/spec_windows_opts.go | 2 +- internal/cri/server/sandbox_stats_windows.go | 1 + pkg/archive/tar.go | 4 ++-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/cri/opts/spec_opts.go b/internal/cri/opts/spec_opts.go index bdab9e9c19..da540ca1f7 100644 --- a/internal/cri/opts/spec_opts.go +++ b/internal/cri/opts/spec_opts.go @@ -67,7 +67,7 @@ func WithProcessArgs(config *runtime.ContainerConfig, image *imagespec.ImageConf args = append([]string{}, image.Cmd...) } if command == nil { - if !(len(image.Entrypoint) == 1 && image.Entrypoint[0] == "") { + if len(image.Entrypoint) != 1 || image.Entrypoint[0] != "" { command = append([]string{}, image.Entrypoint...) } } diff --git a/internal/cri/opts/spec_windows_opts.go b/internal/cri/opts/spec_windows_opts.go index 01358b1158..6292cd1173 100644 --- a/internal/cri/opts/spec_windows_opts.go +++ b/internal/cri/opts/spec_windows_opts.go @@ -80,7 +80,7 @@ func parseMount(osi osinterface.OS, mount *runtime.Mount) (*runtimespec.Mount, e // drive (like Z:, E: etc.). Keeping this '.' in the path // causes incorrect parameter error when starting the // container on windows. Remove it here. - if !(len(dst) == 2 && dst[1] == ':') { + if len(dst) != 2 || dst[1] != ':' { dst = filepath.Clean(dst) if dst[0] == '\\' { dst = "C:" + dst diff --git a/internal/cri/server/sandbox_stats_windows.go b/internal/cri/server/sandbox_stats_windows.go index 83a9bcea04..28d97fd009 100644 --- a/internal/cri/server/sandbox_stats_windows.go +++ b/internal/cri/server/sandbox_stats_windows.go @@ -106,6 +106,7 @@ func convertMetricsToWindowsStats(metrics []*types.Metric, sandbox sandboxstore. // In the case of HostProcess sandbox container we will use the nil value for the statsmap which is used later // otherwise return an error since we should have gotten stats containerStats, ok := containerStatsData.(*wstats.Statistics) + //nolint:staticcheck // QF1001: could apply De Morgan's law (staticcheck) if !ok && !(isHostProcess && sandbox.ID == stat.ID) { return nil, fmt.Errorf("failed to extract metrics for container with id %s: %w", stat.ID, err) } diff --git a/pkg/archive/tar.go b/pkg/archive/tar.go index d4cb42213e..286a46c051 100644 --- a/pkg/archive/tar.go +++ b/pkg/archive/tar.go @@ -292,7 +292,7 @@ func applyNaive(ctx context.Context, root string, r io.Reader, options ApplyOpti // the layer is also a directory. Then we want to merge them (i.e. // just apply the metadata from the layer). if fi, err := os.Lstat(path); err == nil { - if !(fi.IsDir() && hdr.Typeflag == tar.TypeDir) { + if !fi.IsDir() || hdr.Typeflag != tar.TypeDir { if err := os.RemoveAll(path); err != nil { return 0, err } @@ -337,7 +337,7 @@ func createTarFile(ctx context.Context, path, extractDir string, hdr *tar.Header case tar.TypeDir: // Create directory unless it exists as a directory already. // In that case we just want to merge the two - if fi, err := os.Lstat(path); !(err == nil && fi.IsDir()) { + if fi, err := os.Lstat(path); err != nil || !fi.IsDir() { if err := mkdir(path, hdrInfo.Mode()); err != nil { return err } From 403f86ecc2dd886e5185db031ecb4e31718988be Mon Sep 17 00:00:00 2001 From: yashsingh74 Date: Sat, 19 Apr 2025 11:07:15 +0530 Subject: [PATCH 05/11] fix: QF1012: Use of fmt.Fprintln(...) Signed-off-by: yashsingh74 --- pkg/imageverifier/bindir/bindir.go | 2 +- pkg/shim/util_unix.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/imageverifier/bindir/bindir.go b/pkg/imageverifier/bindir/bindir.go index 198f7643a4..f9cca6cf2c 100644 --- a/pkg/imageverifier/bindir/bindir.go +++ b/pkg/imageverifier/bindir/bindir.go @@ -101,7 +101,7 @@ func (v *ImageVerifier) VerifyImage(ctx context.Context, name string, desc ocisp if i > 0 { reason.WriteString(", ") } - reason.WriteString(fmt.Sprintf("%v => %v", bin, vr)) + reason.WriteString(bin + " => " + vr) } return &imageverifier.Judgement{ diff --git a/pkg/shim/util_unix.go b/pkg/shim/util_unix.go index 61a8353fb2..874aaf5dda 100644 --- a/pkg/shim/util_unix.go +++ b/pkg/shim/util_unix.go @@ -208,7 +208,7 @@ func hybridVsockDialer(addr string, port uint64, timeout time.Duration) (net.Con if err != nil { return nil, err } - if _, err = conn.Write([]byte(fmt.Sprintf("CONNECT %d\n", port))); err != nil { + if _, err = fmt.Fprintln(conn, "CONNECT", port); err != nil { conn.Close() return nil, err } From b529973720bf9efa7588c86584e7c91c96126c73 Mon Sep 17 00:00:00 2001 From: yashsingh74 Date: Sat, 19 Apr 2025 11:12:52 +0530 Subject: [PATCH 06/11] fix: ST1019: removed the duplicate imports Signed-off-by: yashsingh74 --- core/runtime/v2/bridge.go | 9 ++++----- internal/cri/server/container_create.go | 3 +-- internal/cri/server/service.go | 7 +++---- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/core/runtime/v2/bridge.go b/core/runtime/v2/bridge.go index 6262e0efdd..8cce62fa9d 100644 --- a/core/runtime/v2/bridge.go +++ b/core/runtime/v2/bridge.go @@ -25,7 +25,6 @@ import ( "google.golang.org/protobuf/types/known/emptypb" v2 "github.com/containerd/containerd/api/runtime/task/v2" - v3 "github.com/containerd/containerd/api/runtime/task/v3" api "github.com/containerd/containerd/api/runtime/task/v3" // Current version used by TaskServiceClient ) @@ -70,7 +69,7 @@ func NewTaskClient(client interface{}, version int) (TaskServiceClient, error) { case 2: return &ttrpcV2Bridge{client: v2.NewTaskClient(c)}, nil case 3: - return v3.NewTTRPCTaskClient(c), nil + return api.NewTTRPCTaskClient(c), nil default: return nil, fmt.Errorf("containerd client supports only v2 and v3 TTRPC task client (got %d)", version) } @@ -80,7 +79,7 @@ func NewTaskClient(client interface{}, version int) (TaskServiceClient, error) { return nil, fmt.Errorf("containerd client supports only v3 GRPC task service (got %d)", version) } - return &grpcV3Bridge{v3.NewTaskClient(c)}, nil + return &grpcV3Bridge{api.NewTaskClient(c)}, nil default: return nil, fmt.Errorf("unsupported shim client type %T", c) } @@ -99,7 +98,7 @@ func (b *ttrpcV2Bridge) State(ctx context.Context, request *api.StateRequest) (* ExecID: request.GetExecID(), }) - return &v3.StateResponse{ + return &api.StateResponse{ ID: resp.GetID(), Bundle: resp.GetBundle(), Pid: resp.GetPid(), @@ -257,7 +256,7 @@ func (b *ttrpcV2Bridge) Shutdown(ctx context.Context, request *api.ShutdownReque // grpcV3Bridge implements task service client for v3 GRPC server. // GRPC uses same request/response structures as TTRPC, so it just wraps GRPC calls. type grpcV3Bridge struct { - client v3.TaskClient + client api.TaskClient } var _ TaskServiceClient = (*grpcV3Bridge)(nil) diff --git a/internal/cri/server/container_create.go b/internal/cri/server/container_create.go index efe333dc5a..49d5db61ef 100644 --- a/internal/cri/server/container_create.go +++ b/internal/cri/server/container_create.go @@ -43,7 +43,6 @@ import ( "github.com/containerd/typeurl/v2" "github.com/davecgh/go-spew/spew" imagespec "github.com/opencontainers/image-spec/specs-go/v1" - v1 "github.com/opencontainers/image-spec/specs-go/v1" runtimespec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/selinux/go-selinux" "github.com/opencontainers/selinux/go-selinux/label" @@ -210,7 +209,7 @@ type createContainerRequest struct { sandboxID string imageID string containerConfig *runtime.ContainerConfig - imageConfig *v1.ImageConfig + imageConfig *imagespec.ImageConfig podSandboxConfig *runtime.PodSandboxConfig sandboxRuntimeHandler string sandboxPid uint32 diff --git a/internal/cri/server/service.go b/internal/cri/server/service.go index d14b3698fd..a028794d96 100644 --- a/internal/cri/server/service.go +++ b/internal/cri/server/service.go @@ -39,7 +39,6 @@ import ( "github.com/containerd/containerd/v2/core/introspection" _ "github.com/containerd/containerd/v2/core/runtime" // for typeurl init "github.com/containerd/containerd/v2/core/sandbox" - "github.com/containerd/containerd/v2/internal/cri/config" criconfig "github.com/containerd/containerd/v2/internal/cri/config" "github.com/containerd/containerd/v2/internal/cri/nri" "github.com/containerd/containerd/v2/internal/cri/server/events" @@ -368,7 +367,7 @@ func (c *criService) IsInitialized() bool { return c.initialized.Load() } -func (c *criService) introspectRuntimeHandler(ctx context.Context, intro introspection.Service, name string, r config.Runtime) error { +func (c *criService) introspectRuntimeHandler(ctx context.Context, intro introspection.Service, name string, r criconfig.Runtime) error { h := &runtime.RuntimeHandler{ Name: name, } @@ -400,7 +399,7 @@ func (c *criService) introspectRuntimeHandler(ctx context.Context, intro introsp return nil } -func introspectRuntimeFeatures(ctx context.Context, intro introspection.Service, r config.Runtime) (*features.Features, error) { +func introspectRuntimeFeatures(ctx context.Context, intro introspection.Service, r criconfig.Runtime) (*features.Features, error) { if r.Type != plugins.RuntimeRuncV2 { return nil, fmt.Errorf("introspecting OCI runtime features needs the runtime type to be %q, got %q", plugins.RuntimeRuncV2, r.Type) @@ -413,7 +412,7 @@ func introspectRuntimeFeatures(ctx context.Context, intro introspection.Service, if r.Path != "" { rr.RuntimePath = r.Path // "/usr/local/bin/crun" } - options, err := config.GenerateRuntimeOptions(r) + options, err := criconfig.GenerateRuntimeOptions(r) if err != nil { return nil, err } From 4ba81d4296cbbea34bf69a3be436c95f7dee785a Mon Sep 17 00:00:00 2001 From: yashsingh74 Date: Sat, 19 Apr 2025 12:00:38 +0530 Subject: [PATCH 07/11] fix: ST1001: should not use dot imports (staticcheck) Signed-off-by: yashsingh74 --- integration/client/daemon.go | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/integration/client/daemon.go b/integration/client/daemon.go index fe57c6c7b4..573d43a149 100644 --- a/integration/client/daemon.go +++ b/integration/client/daemon.go @@ -28,9 +28,8 @@ import ( "syscall" "time" + "github.com/containerd/containerd/v2/client" "github.com/containerd/plugin" - - . "github.com/containerd/containerd/v2/client" ) type daemon struct { @@ -58,31 +57,31 @@ func (d *daemon) start(name, address string, args []string, stdout, stderr io.Wr return nil } -func (d *daemon) waitForStart(ctx context.Context) (*Client, error) { +func (d *daemon) waitForStart(ctx context.Context) (*client.Client, error) { var ( - client *Client - serving bool - err error - ticker = time.NewTicker(500 * time.Millisecond) + clientInstance *client.Client + serving bool + err error + ticker = time.NewTicker(500 * time.Millisecond) ) defer ticker.Stop() for { select { case <-ticker.C: - client, err = New(d.addr) + clientInstance, err = client.New(d.addr) if err != nil { continue } - serving, err = client.IsServing(ctx) + serving, err = clientInstance.IsServing(ctx) if !serving { - client.Close() + clientInstance.Close() if err == nil { err = errors.New("connection was successful but service is not available") } continue } - resp, perr := client.IntrospectionService().Plugins(ctx) + resp, perr := clientInstance.IntrospectionService().Plugins(ctx) if perr != nil { return nil, fmt.Errorf("failed to get plugin list: %w", perr) } @@ -97,7 +96,7 @@ func (d *daemon) waitForStart(ctx context.Context) (*Client, error) { return nil, loadErr } - return client, err + return clientInstance, err case <-ctx.Done(): return nil, fmt.Errorf("context deadline exceeded: %w", err) } From 03a44a2d7c54e23f303ad84adfe4ca3894cfe9ee Mon Sep 17 00:00:00 2001 From: yashsingh74 Date: Sat, 19 Apr 2025 12:04:32 +0530 Subject: [PATCH 08/11] fix: Used nolint to ignore the static checks Signed-off-by: yashsingh74 --- internal/cri/resourcequantity/quantity.go | 1 + internal/userns/idmap.go | 4 ++-- pkg/os/os_windows.go | 2 +- plugins/snapshots/erofs/erofs_linux.go | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/cri/resourcequantity/quantity.go b/internal/cri/resourcequantity/quantity.go index 2104a265e8..f11e449bd0 100644 --- a/internal/cri/resourcequantity/quantity.go +++ b/internal/cri/resourcequantity/quantity.go @@ -363,6 +363,7 @@ func ParseQuantity(str string) (Quantity, error) { } // So that no one but us has to think about suffixes, remove it. + //nolint:staticcheck if base == 10 { amount.SetScale(amount.Scale() + Scale(exponent).infScale()) } else if base == 2 { diff --git a/internal/userns/idmap.go b/internal/userns/idmap.go index 71d3bd89d5..aa8912f10b 100644 --- a/internal/userns/idmap.go +++ b/internal/userns/idmap.go @@ -35,7 +35,7 @@ var invalidUser = User{Uid: invalidID, Gid: invalidID} // User is a Uid and Gid pair of a user // -//nolint:revive +//nolint:revive,staticcheck type User struct { Uid uint32 Gid uint32 @@ -43,7 +43,7 @@ type User struct { // IDMap contains the mappings of Uids and Gids. // -//nolint:revive +//nolint:revive,staticcheck type IDMap struct { UidMap []specs.LinuxIDMapping `json:"UidMap"` GidMap []specs.LinuxIDMapping `json:"GidMap"` diff --git a/pkg/os/os_windows.go b/pkg/os/os_windows.go index 6047e2f59e..ef77d514c4 100644 --- a/pkg/os/os_windows.go +++ b/pkg/os/os_windows.go @@ -60,7 +60,7 @@ func openPath(path string) (windows.Handle, error) { // GetFinalPathNameByHandle flags. // -//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API. +//nolint:revive,staticcheck // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API. const ( cFILE_NAME_OPENED = 0x8 diff --git a/plugins/snapshots/erofs/erofs_linux.go b/plugins/snapshots/erofs/erofs_linux.go index 3993b32618..77266f2b3c 100644 --- a/plugins/snapshots/erofs/erofs_linux.go +++ b/plugins/snapshots/erofs/erofs_linux.go @@ -360,7 +360,7 @@ func (s *snapshotter) View(ctx context.Context, key, parent string, opts ...snap } func setImmutable(path string, enable bool) error { - //nolint:revive // silence "don't use ALL_CAPS in Go names; use CamelCase" + //nolint:revive,staticcheck // silence "don't use ALL_CAPS in Go names; use CamelCase" const ( FS_IMMUTABLE_FL = 0x10 ) From 19a7130613268c7fa170ca7beb5851ae4b4242d4 Mon Sep 17 00:00:00 2001 From: yashsingh74 Date: Wed, 11 Jun 2025 19:14:19 +0530 Subject: [PATCH 09/11] Disable QF1003: could use tagged switch on base (staticcheck) Signed-off-by: yashsingh74 --- core/transfer/local/pull.go | 1 + internal/cri/resourcequantity/quantity.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/core/transfer/local/pull.go b/core/transfer/local/pull.go index 2324b5361e..7660752069 100644 --- a/core/transfer/local/pull.go +++ b/core/transfer/local/pull.go @@ -299,6 +299,7 @@ func getSupportedPlatform(ctx context.Context, uc transfer.UnpackConfiguration, // use default Snapshotter if sp.Platform.Match(uc.Platform) { // Assume sp.SnapshotterKey is not empty + //nolint:staticcheck // QF1003: could use tagged switch on base (staticcheck) if uc.Snapshotter == sp.SnapshotterKey { return true, sp } else if uc.Snapshotter == "" { diff --git a/internal/cri/resourcequantity/quantity.go b/internal/cri/resourcequantity/quantity.go index f11e449bd0..47aca624a1 100644 --- a/internal/cri/resourcequantity/quantity.go +++ b/internal/cri/resourcequantity/quantity.go @@ -363,7 +363,7 @@ func ParseQuantity(str string) (Quantity, error) { } // So that no one but us has to think about suffixes, remove it. - //nolint:staticcheck + //nolint:staticcheck // QF1003: could use tagged switch on base (staticcheck) if base == 10 { amount.SetScale(amount.Scale() + Scale(exponent).infScale()) } else if base == 2 { From 37147b13a091150ef43c67c145da3202e05c01e3 Mon Sep 17 00:00:00 2001 From: yashsingh74 Date: Wed, 11 Jun 2025 19:14:51 +0530 Subject: [PATCH 10/11] Disable ST1003: struct field Uid should be UID (staticcheck) Signed-off-by: yashsingh74 --- internal/userns/idmap.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/userns/idmap.go b/internal/userns/idmap.go index aa8912f10b..8e4f37315c 100644 --- a/internal/userns/idmap.go +++ b/internal/userns/idmap.go @@ -35,7 +35,7 @@ var invalidUser = User{Uid: invalidID, Gid: invalidID} // User is a Uid and Gid pair of a user // -//nolint:revive,staticcheck +//nolint:revive,staticcheck // ST1003: struct field Uid should be UID (staticcheck) type User struct { Uid uint32 Gid uint32 @@ -43,7 +43,7 @@ type User struct { // IDMap contains the mappings of Uids and Gids. // -//nolint:revive,staticcheck +//nolint:revive,staticcheck // ST1003: struct field Uid should be UID (staticcheck) type IDMap struct { UidMap []specs.LinuxIDMapping `json:"UidMap"` GidMap []specs.LinuxIDMapping `json:"GidMap"` From ed7746656d98e9728f041e2a21b95a78f58b425c Mon Sep 17 00:00:00 2001 From: yashsingh74 Date: Wed, 11 Jun 2025 19:29:19 +0530 Subject: [PATCH 11/11] ci: bump golangci from 6.5.2 to 7.0.0 Signed-off-by: yashsingh74 --- .github/workflows/ci.yml | 4 +- .golangci.yml | 187 ++++++++++++++++++--------------- script/setup/install-dev-tools | 2 +- 3 files changed, 104 insertions(+), 89 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 549bffef85..1dcdd2fcd7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,9 +29,9 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: ./.github/actions/install-go - - uses: golangci/golangci-lint-action@55c2c1448f86e01eaae002a5a3a9624417608d84 # v6.5.2 + - uses: golangci/golangci-lint-action@1481404843c368bc19ca9406f87d6e0fc97bdcfd # v7.0.0 with: - version: v1.64.2 + version: v2.1.5 skip-cache: true args: --timeout=8m diff --git a/.golangci.yml b/.golangci.yml index 3bd723a8e8..07830dc9b2 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,98 +1,113 @@ +version: "2" linters: enable: - - depguard # Checks for dependencies that should not be (re)introduced. See "linter-settings" for further details. - copyloopvar # Checks for loop variable copies in Go 1.22+ - - gofmt - - goimports + - depguard # Checks for dependencies that should not be (re)introduced. See "settings" for further details. + - dupword # Checks for duplicate words in the source code - gosec - - ineffassign + - revive - misspell - nolintlint - - revive - - staticcheck - - tenv # Detects using os.Setenv instead of t.Setenv since Go 1.17 - unconvert - - unused - - govet - - dupword # Checks for duplicate words in the source code disable: - errcheck - + settings: + depguard: + rules: + main: + deny: + - pkg: github.com/opencontainers/runc + desc: We don't want to depend on runc (libcontainer), unless there is no other option; see https://github.com/opencontainers/runc/issues/3028. + forbidigo: + forbid: + - pkg: ^regexp$ + msg: Use internal/lazyregexp.New instead. + gosec: + # The following issues surfaced when `gosec` linter + # was enabled. They are temporarily excluded to unblock + # the existing workflow, but still to be addressed by + # future works. + excludes: + - G204 + - G305 + - G306 + - G402 + - G404 + - G115 + - G103 + - G104 + - G301 + - G302 + - G304 + staticcheck: + checks: + - all + - -QF1008 # Excludes QF1008 from staticcheck + - -ST1000 + - -ST1020 + - -ST1021 + revive: + rules: + - name: package-comments + severity: warning + disabled: true + exclude: [ "" ] + nolintlint: + allow-unused: true + exclusions: + generated: lax + rules: + - path: cmd[\\/]containerd[\\/]builtins[\\/] + text: 'blank-imports:' + - path: contrib[\\/]fuzz[\\/] + text: 'exported: func name will be used as fuzz.Fuzz' + - path: archive[\\/]tarheader[\\/] + # conversion is necessary on Linux, unnecessary on macOS + text: unnecessary conversion + - path: integration[\\/]client + text: 'dot-imports:' + - linters: + - revive + text: if-return + - linters: + - revive + text: empty-block + - linters: + - revive + text: superfluous-else + - linters: + - revive + text: unused-parameter + - linters: + - revive + text: unreachable-code + - linters: + - revive + text: redefines-builtin-id + - linters: + - forbidigo + text: 'use of `regexp.MustCompile` forbidden' + path: _test\.go + paths: + - api + - cluster + - docs + - docs/man + - releases + - test issues: - include: - - EXC0002 max-issues-per-linter: 0 max-same-issues: 0 - - exclude-dirs: - - api - - cluster - - docs - - docs/man - - releases - - test # e2e scripts - - # Only using / doesn't work due to https://github.com/golangci/golangci-lint/issues/1398. - exclude-rules: - - path: 'cmd[\\/]containerd[\\/]builtins[\\/]' - text: "blank-imports:" - - path: 'contrib[\\/]fuzz[\\/]' - text: "exported: func name will be used as fuzz.Fuzz" - - path: 'archive[\\/]tarheader[\\/]' - # conversion is necessary on Linux, unnecessary on macOS - text: "unnecessary conversion" - - path: 'integration[\\/]client' - text: "dot-imports:" - - linters: - - revive - text: "if-return" - - linters: - - revive - text: "empty-block" - - linters: - - revive - text: "superfluous-else" - - linters: - - revive - text: "unused-parameter" - - linters: - - revive - text: "unreachable-code" - - linters: - - revive - text: "redefines-builtin-id" - - linters: - - forbidigo - text: 'use of `regexp.MustCompile` forbidden' - path: _test\.go - -linters-settings: - depguard: - rules: - main: - deny: - - pkg: github.com/opencontainers/runc - desc: We don't want to depend on runc (libcontainer), unless there is no other option; see https://github.com/opencontainers/runc/issues/3028. - forbidigo: - forbid: - - pkg: ^regexp$ - p: ^regexp\.MustCompile - msg: Use internal/lazyregexp.New instead. - - gosec: - # The following issues surfaced when `gosec` linter - # was enabled. They are temporarily excluded to unblock - # the existing workflow, but still to be addressed by - # future works. - excludes: - - G204 - - G305 - - G306 - - G402 - - G404 - - G115 - nolintlint: - allow-unused: true - -run: - timeout: 8m +formatters: + enable: + - gofmt + - goimports + exclusions: + generated: strict + paths: + - api + - cluster + - docs + - docs/man + - releases + - test diff --git a/script/setup/install-dev-tools b/script/setup/install-dev-tools index aaf9953291..7af3fe38f4 100755 --- a/script/setup/install-dev-tools +++ b/script/setup/install-dev-tools @@ -23,7 +23,7 @@ set -eu -o pipefail go install github.com/containerd/protobuild@v0.3.0 go install github.com/containerd/protobuild/cmd/go-fix-acronym@v0.3.0 go install github.com/cpuguy83/go-md2man/v2@v2.0.2 -go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.60.1 +go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.5 go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2.0 go install github.com/containerd/ttrpc/cmd/protoc-gen-go-ttrpc@v1.2.5