Skip to content

Commit 9b2f831

Browse files
committed
cli-plugins/manager: ignore broken symlinks
Before this patch, a broken symlink would print a warning; docker info > /dev/null WARNING: Plugin "/Users/thajeztah/.docker/cli-plugins/docker-feedback" is not valid: failed to fetch metadata: fork/exec /Users/thajeztah/.docker/cli-plugins/docker-feedback: no such file or directory After this patch, such symlinks are ignored: docker info > /dev/null With debug enabled, we don't ignore the faulty plugin, which will make the warning shown on docker info; mkdir -p ~/.docker/cli-plugins ln -s nosuchplugin ~/.docker/cli-plugins/docker-brokenplugin docker --debug info Client: Version: 29.0.0-dev Context: default Debug Mode: true Plugins: buildx: Docker Buildx (Docker Inc.) Version: v0.25.0 Path: /usr/libexec/docker/cli-plugins/docker-buildx WARNING: Plugin "/Users/thajeztah/.docker/cli-plugins/docker-brokenplugin" is not valid: failed to fetch metadata: fork/exec /Users/thajeztah/.docker/cli-plugins/docker-brokenplugin: no such file or directory # ... We should als consider passing a "seen" map to de-duplicate entries. Entries can be either a direct symlink or in a symlinked path (for which we can filepath.EvalSymlinks). We need to benchmark the overhead of resolving the symlink vs possibly calling the plugin (to get their metadata) further down the line. Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent c8600e1 commit 9b2f831

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

cli-plugins/manager/manager.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package manager
22

33
import (
44
"context"
5+
"errors"
56
"os"
67
"os/exec"
78
"path/filepath"
@@ -13,6 +14,7 @@ import (
1314
"github.com/docker/cli/cli-plugins/metadata"
1415
"github.com/docker/cli/cli/config"
1516
"github.com/docker/cli/cli/config/configfile"
17+
"github.com/docker/cli/cli/debug"
1618
"github.com/fvbommel/sortorder"
1719
"github.com/spf13/cobra"
1820
"golang.org/x/sync/errgroup"
@@ -57,9 +59,17 @@ func addPluginCandidatesFromDir(res map[string][]string, d string) {
5759
return
5860
}
5961
for _, dentry := range dentries {
60-
switch dentry.Type() & os.ModeType { //nolint:exhaustive,nolintlint // no need to include all possible file-modes in this list
61-
case 0, os.ModeSymlink:
62-
// Regular file or symlink, keep going
62+
switch mode := dentry.Type() & os.ModeType; mode { //nolint:exhaustive,nolintlint // no need to include all possible file-modes in this list
63+
case os.ModeSymlink:
64+
if !debug.IsEnabled() {
65+
// Skip broken symlinks unless debug is enabled. With debug
66+
// enabled, this will print a warning in "docker info".
67+
if _, err := os.Stat(filepath.Join(d, dentry.Name())); errors.Is(err, os.ErrNotExist) {
68+
continue
69+
}
70+
}
71+
case 0:
72+
// Regular file, keep going
6373
default:
6474
// Something else, ignore.
6575
continue

cli-plugins/manager/manager_test.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func TestListPluginCandidates(t *testing.T) {
3838
"plugins3-target", // Will be referenced as a symlink from below
3939
fs.WithFile("docker-plugin1", ""),
4040
fs.WithDir("ignored3"),
41-
fs.WithSymlink("docker-brokensymlink", "broken"), // A broken symlink is still a candidate (but would fail tests later)
41+
fs.WithSymlink("docker-brokensymlink", "broken"), // A broken symlink is ignored
4242
fs.WithFile("non-plugin-symlinked", ""), // This shouldn't appear, but ...
4343
fs.WithSymlink("docker-symlinked", "non-plugin-symlinked"), // ... this link to it should.
4444
),
@@ -72,9 +72,6 @@ func TestListPluginCandidates(t *testing.T) {
7272
"hardlink2": {
7373
dir.Join("plugins2", "docker-hardlink2"),
7474
},
75-
"brokensymlink": {
76-
dir.Join("plugins3", "docker-brokensymlink"),
77-
},
7875
"symlinked": {
7976
dir.Join("plugins3", "docker-symlinked"),
8077
},

0 commit comments

Comments
 (0)