diff --git a/cli-plugins/examples/helloworld/main.go b/cli-plugins/examples/helloworld/main.go index d91e1185fa..fecb18325c 100644 --- a/cli-plugins/examples/helloworld/main.go +++ b/cli-plugins/examples/helloworld/main.go @@ -5,7 +5,7 @@ import ( "fmt" "os" - "github.com/docker/cli/cli-plugins/manager" + "github.com/docker/cli/cli-plugins/metadata" "github.com/docker/cli/cli-plugins/plugin" "github.com/docker/cli/cli/command" "github.com/spf13/cobra" @@ -97,7 +97,7 @@ func main() { cmd.AddCommand(goodbye, apiversion, exitStatus2) return cmd }, - manager.Metadata{ + metadata.Metadata{ SchemaVersion: "0.1.0", Vendor: "Docker Inc.", Version: "testing", diff --git a/cli-plugins/manager/annotations.go b/cli-plugins/manager/annotations.go new file mode 100644 index 0000000000..8fc76b73c9 --- /dev/null +++ b/cli-plugins/manager/annotations.go @@ -0,0 +1,30 @@ +package manager + +import "github.com/docker/cli/cli-plugins/metadata" + +const ( + // CommandAnnotationPlugin is added to every stub command added by + // AddPluginCommandStubs with the value "true" and so can be + // used to distinguish plugin stubs from regular commands. + CommandAnnotationPlugin = metadata.CommandAnnotationPlugin + + // CommandAnnotationPluginVendor is added to every stub command + // added by AddPluginCommandStubs and contains the vendor of + // that plugin. + CommandAnnotationPluginVendor = metadata.CommandAnnotationPluginVendor + + // CommandAnnotationPluginVersion is added to every stub command + // added by AddPluginCommandStubs and contains the version of + // that plugin. + CommandAnnotationPluginVersion = metadata.CommandAnnotationPluginVersion + + // CommandAnnotationPluginInvalid is added to any stub command + // added by AddPluginCommandStubs for an invalid command (that + // is, one which failed it's candidate test) and contains the + // reason for the failure. + CommandAnnotationPluginInvalid = metadata.CommandAnnotationPluginInvalid + + // CommandAnnotationPluginCommandPath is added to overwrite the + // command path for a plugin invocation. + CommandAnnotationPluginCommandPath = metadata.CommandAnnotationPluginCommandPath +) diff --git a/cli-plugins/manager/candidate.go b/cli-plugins/manager/candidate.go index e65ac1a54f..d809926cf6 100644 --- a/cli-plugins/manager/candidate.go +++ b/cli-plugins/manager/candidate.go @@ -1,6 +1,10 @@ package manager -import "os/exec" +import ( + "os/exec" + + "github.com/docker/cli/cli-plugins/metadata" +) // Candidate represents a possible plugin candidate, for mocking purposes type Candidate interface { @@ -17,5 +21,5 @@ func (c *candidate) Path() string { } func (c *candidate) Metadata() ([]byte, error) { - return exec.Command(c.path, MetadataSubcommandName).Output() // #nosec G204 -- ignore "Subprocess launched with a potential tainted input or cmd arguments" + return exec.Command(c.path, metadata.MetadataSubcommandName).Output() // #nosec G204 -- ignore "Subprocess launched with a potential tainted input or cmd arguments" } diff --git a/cli-plugins/manager/candidate_test.go b/cli-plugins/manager/candidate_test.go index acf52e54ff..dc0e960f63 100644 --- a/cli-plugins/manager/candidate_test.go +++ b/cli-plugins/manager/candidate_test.go @@ -6,6 +6,7 @@ import ( "strings" "testing" + "github.com/docker/cli/cli-plugins/metadata" "github.com/spf13/cobra" "gotest.tools/v3/assert" "gotest.tools/v3/assert/cmp" @@ -30,10 +31,10 @@ func (c *fakeCandidate) Metadata() ([]byte, error) { func TestValidateCandidate(t *testing.T) { const ( - goodPluginName = NamePrefix + "goodplugin" + goodPluginName = metadata.NamePrefix + "goodplugin" - builtinName = NamePrefix + "builtin" - builtinAlias = NamePrefix + "alias" + builtinName = metadata.NamePrefix + "builtin" + builtinAlias = metadata.NamePrefix + "alias" badPrefixPath = "/usr/local/libexec/cli-plugins/wobble" badNamePath = "/usr/local/libexec/cli-plugins/docker-123456" @@ -43,9 +44,9 @@ func TestValidateCandidate(t *testing.T) { fakeroot := &cobra.Command{Use: "docker"} fakeroot.AddCommand(&cobra.Command{ - Use: strings.TrimPrefix(builtinName, NamePrefix), + Use: strings.TrimPrefix(builtinName, metadata.NamePrefix), Aliases: []string{ - strings.TrimPrefix(builtinAlias, NamePrefix), + strings.TrimPrefix(builtinAlias, metadata.NamePrefix), }, }) @@ -59,7 +60,7 @@ func TestValidateCandidate(t *testing.T) { }{ /* Each failing one of the tests */ {name: "empty path", c: &fakeCandidate{path: ""}, err: "plugin candidate path cannot be empty"}, - {name: "bad prefix", c: &fakeCandidate{path: badPrefixPath}, err: fmt.Sprintf("does not have %q prefix", NamePrefix)}, + {name: "bad prefix", c: &fakeCandidate{path: badPrefixPath}, err: fmt.Sprintf("does not have %q prefix", metadata.NamePrefix)}, {name: "bad path", c: &fakeCandidate{path: badNamePath}, invalid: "did not match"}, {name: "builtin command", c: &fakeCandidate{path: builtinName}, invalid: `plugin "builtin" duplicates builtin command`}, {name: "builtin alias", c: &fakeCandidate{path: builtinAlias}, invalid: `plugin "alias" duplicates an alias of builtin command "builtin"`}, @@ -84,7 +85,7 @@ func TestValidateCandidate(t *testing.T) { assert.ErrorContains(t, p.Err, tc.invalid) default: assert.NilError(t, err) - assert.Equal(t, NamePrefix+p.Name, goodPluginName) + assert.Equal(t, metadata.NamePrefix+p.Name, goodPluginName) assert.Equal(t, p.SchemaVersion, "0.1.0") assert.Equal(t, p.Vendor, "e2e-testing") } diff --git a/cli-plugins/manager/cobra.go b/cli-plugins/manager/cobra.go index 756ede944d..ddf067be1d 100644 --- a/cli-plugins/manager/cobra.go +++ b/cli-plugins/manager/cobra.go @@ -5,37 +5,11 @@ import ( "os" "sync" + "github.com/docker/cli/cli-plugins/metadata" "github.com/docker/cli/cli/config" "github.com/spf13/cobra" ) -const ( - // CommandAnnotationPlugin is added to every stub command added by - // AddPluginCommandStubs with the value "true" and so can be - // used to distinguish plugin stubs from regular commands. - CommandAnnotationPlugin = "com.docker.cli.plugin" - - // CommandAnnotationPluginVendor is added to every stub command - // added by AddPluginCommandStubs and contains the vendor of - // that plugin. - CommandAnnotationPluginVendor = "com.docker.cli.plugin.vendor" - - // CommandAnnotationPluginVersion is added to every stub command - // added by AddPluginCommandStubs and contains the version of - // that plugin. - CommandAnnotationPluginVersion = "com.docker.cli.plugin.version" - - // CommandAnnotationPluginInvalid is added to any stub command - // added by AddPluginCommandStubs for an invalid command (that - // is, one which failed it's candidate test) and contains the - // reason for the failure. - CommandAnnotationPluginInvalid = "com.docker.cli.plugin-invalid" - - // CommandAnnotationPluginCommandPath is added to overwrite the - // command path for a plugin invocation. - CommandAnnotationPluginCommandPath = "com.docker.cli.plugin.command_path" -) - var pluginCommandStubsOnce sync.Once // AddPluginCommandStubs adds a stub cobra.Commands for each valid and invalid @@ -54,12 +28,12 @@ func AddPluginCommandStubs(dockerCLI config.Provider, rootCmd *cobra.Command) (e vendor = "unknown" } annotations := map[string]string{ - CommandAnnotationPlugin: "true", - CommandAnnotationPluginVendor: vendor, - CommandAnnotationPluginVersion: p.Version, + metadata.CommandAnnotationPlugin: "true", + metadata.CommandAnnotationPluginVendor: vendor, + metadata.CommandAnnotationPluginVersion: p.Version, } if p.Err != nil { - annotations[CommandAnnotationPluginInvalid] = p.Err.Error() + annotations[metadata.CommandAnnotationPluginInvalid] = p.Err.Error() } rootCmd.AddCommand(&cobra.Command{ Use: p.Name, diff --git a/cli-plugins/manager/manager.go b/cli-plugins/manager/manager.go index 0f15daa29d..4b553eae79 100644 --- a/cli-plugins/manager/manager.go +++ b/cli-plugins/manager/manager.go @@ -9,6 +9,7 @@ import ( "strings" "sync" + "github.com/docker/cli/cli-plugins/metadata" "github.com/docker/cli/cli/config" "github.com/docker/cli/cli/config/configfile" "github.com/fvbommel/sortorder" @@ -21,7 +22,7 @@ const ( // used to originally invoke the docker CLI when executing a // plugin. Assuming $PATH and $CWD remain unchanged this should allow // the plugin to re-execute the original CLI. - ReexecEnvvar = "DOCKER_CLI_PLUGIN_ORIGINAL_CLI_COMMAND" + ReexecEnvvar = metadata.ReexecEnvvar // ResourceAttributesEnvvar is the name of the envvar that includes additional // resource attributes for OTEL. @@ -92,10 +93,10 @@ func addPluginCandidatesFromDir(res map[string][]string, d string) { continue } name := dentry.Name() - if !strings.HasPrefix(name, NamePrefix) { + if !strings.HasPrefix(name, metadata.NamePrefix) { continue } - name = strings.TrimPrefix(name, NamePrefix) + name = strings.TrimPrefix(name, metadata.NamePrefix) var err error if name, err = trimExeSuffix(name); err != nil { continue @@ -200,7 +201,7 @@ func PluginRunCommand(dockerCli config.Provider, name string, rootcmd *cobra.Com // fallback to their "invalid" command path. return nil, errPluginNotFound(name) } - exename := addExeSuffix(NamePrefix + name) + exename := addExeSuffix(metadata.NamePrefix + name) pluginDirs, err := getPluginDirs(dockerCli.ConfigFile()) if err != nil { return nil, err @@ -237,7 +238,7 @@ func PluginRunCommand(dockerCli config.Provider, name string, rootcmd *cobra.Com cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr - cmd.Env = append(cmd.Environ(), ReexecEnvvar+"="+os.Args[0]) + cmd.Env = append(cmd.Environ(), metadata.ReexecEnvvar+"="+os.Args[0]) cmd.Env = appendPluginResourceAttributesEnvvar(cmd.Env, rootcmd, plugin) return cmd, nil @@ -247,5 +248,5 @@ func PluginRunCommand(dockerCli config.Provider, name string, rootcmd *cobra.Com // IsPluginCommand checks if the given cmd is a plugin-stub. func IsPluginCommand(cmd *cobra.Command) bool { - return cmd.Annotations[CommandAnnotationPlugin] == "true" + return cmd.Annotations[metadata.CommandAnnotationPlugin] == "true" } diff --git a/cli-plugins/manager/metadata.go b/cli-plugins/manager/metadata.go index f7aac06fe9..9bddb12142 100644 --- a/cli-plugins/manager/metadata.go +++ b/cli-plugins/manager/metadata.go @@ -1,30 +1,23 @@ package manager +import ( + "github.com/docker/cli/cli-plugins/metadata" +) + const ( // NamePrefix is the prefix required on all plugin binary names - NamePrefix = "docker-" + NamePrefix = metadata.NamePrefix // MetadataSubcommandName is the name of the plugin subcommand // which must be supported by every plugin and returns the // plugin metadata. - MetadataSubcommandName = "docker-cli-plugin-metadata" + MetadataSubcommandName = metadata.MetadataSubcommandName // HookSubcommandName is the name of the plugin subcommand // which must be implemented by plugins declaring support // for hooks in their metadata. - HookSubcommandName = "docker-cli-plugin-hooks" + HookSubcommandName = metadata.HookSubcommandName ) // Metadata provided by the plugin. -type Metadata struct { - // SchemaVersion describes the version of this struct. Mandatory, must be "0.1.0" - SchemaVersion string `json:",omitempty"` - // Vendor is the name of the plugin vendor. Mandatory - Vendor string `json:",omitempty"` - // Version is the optional version of this plugin. - Version string `json:",omitempty"` - // ShortDescription should be suitable for a single line help message. - ShortDescription string `json:",omitempty"` - // URL is a pointer to the plugin's homepage. - URL string `json:",omitempty"` -} +type Metadata = metadata.Metadata diff --git a/cli-plugins/manager/plugin.go b/cli-plugins/manager/plugin.go index 5576ef4301..e73d535d51 100644 --- a/cli-plugins/manager/plugin.go +++ b/cli-plugins/manager/plugin.go @@ -9,6 +9,7 @@ import ( "regexp" "strings" + "github.com/docker/cli/cli-plugins/metadata" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -17,7 +18,7 @@ var pluginNameRe = regexp.MustCompile("^[a-z][a-z0-9]*$") // Plugin represents a potential plugin with all it's metadata. type Plugin struct { - Metadata + metadata.Metadata Name string `json:",omitempty"` Path string `json:",omitempty"` @@ -50,12 +51,12 @@ func newPlugin(c Candidate, cmds []*cobra.Command) (Plugin, error) { if fullname, err = trimExeSuffix(fullname); err != nil { return Plugin{}, errors.Wrapf(err, "plugin candidate %q", path) } - if !strings.HasPrefix(fullname, NamePrefix) { - return Plugin{}, errors.Errorf("plugin candidate %q: does not have %q prefix", path, NamePrefix) + if !strings.HasPrefix(fullname, metadata.NamePrefix) { + return Plugin{}, errors.Errorf("plugin candidate %q: does not have %q prefix", path, metadata.NamePrefix) } p := Plugin{ - Name: strings.TrimPrefix(fullname, NamePrefix), + Name: strings.TrimPrefix(fullname, metadata.NamePrefix), Path: path, } @@ -112,9 +113,9 @@ func (p *Plugin) RunHook(ctx context.Context, hookData HookPluginData) ([]byte, return nil, wrapAsPluginError(err, "failed to marshall hook data") } - pCmd := exec.CommandContext(ctx, p.Path, p.Name, HookSubcommandName, string(hDataBytes)) // #nosec G204 -- ignore "Subprocess launched with a potential tainted input or cmd arguments" + pCmd := exec.CommandContext(ctx, p.Path, p.Name, metadata.HookSubcommandName, string(hDataBytes)) // #nosec G204 -- ignore "Subprocess launched with a potential tainted input or cmd arguments" pCmd.Env = os.Environ() - pCmd.Env = append(pCmd.Env, ReexecEnvvar+"="+os.Args[0]) + pCmd.Env = append(pCmd.Env, metadata.ReexecEnvvar+"="+os.Args[0]) hookCmdOutput, err := pCmd.Output() if err != nil { return nil, wrapAsPluginError(err, "failed to execute plugin hook subcommand") diff --git a/cli-plugins/manager/telemetry.go b/cli-plugins/manager/telemetry.go index 3382d4d8d2..ab3dace414 100644 --- a/cli-plugins/manager/telemetry.go +++ b/cli-plugins/manager/telemetry.go @@ -5,6 +5,7 @@ import ( "os" "strings" + "github.com/docker/cli/cli-plugins/metadata" "github.com/spf13/cobra" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" @@ -26,7 +27,7 @@ const ( ) func getPluginResourceAttributes(cmd *cobra.Command, plugin Plugin) attribute.Set { - commandPath := cmd.Annotations[CommandAnnotationPluginCommandPath] + commandPath := cmd.Annotations[metadata.CommandAnnotationPluginCommandPath] if commandPath == "" { commandPath = fmt.Sprintf("%s %s", cmd.CommandPath(), plugin.Name) } diff --git a/cli-plugins/metadata/annotations.go b/cli-plugins/metadata/annotations.go new file mode 100644 index 0000000000..1c7c6d1874 --- /dev/null +++ b/cli-plugins/metadata/annotations.go @@ -0,0 +1,28 @@ +package metadata + +const ( + // CommandAnnotationPlugin is added to every stub command added by + // AddPluginCommandStubs with the value "true" and so can be + // used to distinguish plugin stubs from regular commands. + CommandAnnotationPlugin = "com.docker.cli.plugin" + + // CommandAnnotationPluginVendor is added to every stub command + // added by AddPluginCommandStubs and contains the vendor of + // that plugin. + CommandAnnotationPluginVendor = "com.docker.cli.plugin.vendor" + + // CommandAnnotationPluginVersion is added to every stub command + // added by AddPluginCommandStubs and contains the version of + // that plugin. + CommandAnnotationPluginVersion = "com.docker.cli.plugin.version" + + // CommandAnnotationPluginInvalid is added to any stub command + // added by AddPluginCommandStubs for an invalid command (that + // is, one which failed it's candidate test) and contains the + // reason for the failure. + CommandAnnotationPluginInvalid = "com.docker.cli.plugin-invalid" + + // CommandAnnotationPluginCommandPath is added to overwrite the + // command path for a plugin invocation. + CommandAnnotationPluginCommandPath = "com.docker.cli.plugin.command_path" +) diff --git a/cli-plugins/metadata/metadata.go b/cli-plugins/metadata/metadata.go new file mode 100644 index 0000000000..9d408c00b3 --- /dev/null +++ b/cli-plugins/metadata/metadata.go @@ -0,0 +1,36 @@ +package metadata + +const ( + // NamePrefix is the prefix required on all plugin binary names + NamePrefix = "docker-" + + // MetadataSubcommandName is the name of the plugin subcommand + // which must be supported by every plugin and returns the + // plugin metadata. + MetadataSubcommandName = "docker-cli-plugin-metadata" + + // HookSubcommandName is the name of the plugin subcommand + // which must be implemented by plugins declaring support + // for hooks in their metadata. + HookSubcommandName = "docker-cli-plugin-hooks" + + // ReexecEnvvar is the name of an ennvar which is set to the command + // used to originally invoke the docker CLI when executing a + // plugin. Assuming $PATH and $CWD remain unchanged this should allow + // the plugin to re-execute the original CLI. + ReexecEnvvar = "DOCKER_CLI_PLUGIN_ORIGINAL_CLI_COMMAND" +) + +// Metadata provided by the plugin. +type Metadata struct { + // SchemaVersion describes the version of this struct. Mandatory, must be "0.1.0" + SchemaVersion string `json:",omitempty"` + // Vendor is the name of the plugin vendor. Mandatory + Vendor string `json:",omitempty"` + // Version is the optional version of this plugin. + Version string `json:",omitempty"` + // ShortDescription should be suitable for a single line help message. + ShortDescription string `json:",omitempty"` + // URL is a pointer to the plugin's homepage. + URL string `json:",omitempty"` +} diff --git a/cli-plugins/plugin/plugin.go b/cli-plugins/plugin/plugin.go index cf57aad5e1..08bdf73614 100644 --- a/cli-plugins/plugin/plugin.go +++ b/cli-plugins/plugin/plugin.go @@ -9,7 +9,7 @@ import ( "sync" "github.com/docker/cli/cli" - "github.com/docker/cli/cli-plugins/manager" + "github.com/docker/cli/cli-plugins/metadata" "github.com/docker/cli/cli-plugins/socket" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/connhelper" @@ -30,7 +30,7 @@ import ( var PersistentPreRunE func(*cobra.Command, []string) error // RunPlugin executes the specified plugin command -func RunPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta manager.Metadata) error { +func RunPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta metadata.Metadata) error { tcmd := newPluginCommand(dockerCli, plugin, meta) var persistentPreRunOnce sync.Once @@ -81,7 +81,7 @@ func RunPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta manager } // Run is the top-level entry point to the CLI plugin framework. It should be called from your plugin's `main()` function. -func Run(makeCmd func(command.Cli) *cobra.Command, meta manager.Metadata) { +func Run(makeCmd func(command.Cli) *cobra.Command, meta metadata.Metadata) { otel.SetErrorHandler(debug.OTELErrorHandler) dockerCli, err := command.NewDockerCli() @@ -111,7 +111,7 @@ func Run(makeCmd func(command.Cli) *cobra.Command, meta manager.Metadata) { func withPluginClientConn(name string) command.CLIOption { return command.WithInitializeClient(func(dockerCli *command.DockerCli) (client.APIClient, error) { cmd := "docker" - if x := os.Getenv(manager.ReexecEnvvar); x != "" { + if x := os.Getenv(metadata.ReexecEnvvar); x != "" { cmd = x } var flags []string @@ -140,9 +140,9 @@ func withPluginClientConn(name string) command.CLIOption { }) } -func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta manager.Metadata) *cli.TopLevelCommand { +func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta metadata.Metadata) *cli.TopLevelCommand { name := plugin.Name() - fullname := manager.NamePrefix + name + fullname := metadata.NamePrefix + name cmd := &cobra.Command{ Use: fmt.Sprintf("docker [OPTIONS] %s [ARG...]", name), @@ -177,12 +177,12 @@ func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta return cli.NewTopLevelCommand(cmd, dockerCli, opts, cmd.Flags()) } -func newMetadataSubcommand(plugin *cobra.Command, meta manager.Metadata) *cobra.Command { +func newMetadataSubcommand(plugin *cobra.Command, meta metadata.Metadata) *cobra.Command { if meta.ShortDescription == "" { meta.ShortDescription = plugin.Short } cmd := &cobra.Command{ - Use: manager.MetadataSubcommandName, + Use: metadata.MetadataSubcommandName, Hidden: true, // Suppress the global/parent PersistentPreRunE, which // needlessly initializes the client and tries to @@ -200,8 +200,8 @@ func newMetadataSubcommand(plugin *cobra.Command, meta manager.Metadata) *cobra. // RunningStandalone tells a CLI plugin it is run standalone by direct execution func RunningStandalone() bool { - if os.Getenv(manager.ReexecEnvvar) != "" { + if os.Getenv(metadata.ReexecEnvvar) != "" { return false } - return len(os.Args) < 2 || os.Args[1] != manager.MetadataSubcommandName + return len(os.Args) < 2 || os.Args[1] != metadata.MetadataSubcommandName } diff --git a/cli/cobra.go b/cli/cobra.go index aa7dbef44c..9cfcc616d6 100644 --- a/cli/cobra.go +++ b/cli/cobra.go @@ -7,7 +7,7 @@ import ( "sort" "strings" - pluginmanager "github.com/docker/cli/cli-plugins/manager" + "github.com/docker/cli/cli-plugins/metadata" "github.com/docker/cli/cli/command" cliflags "github.com/docker/cli/cli/flags" "github.com/docker/docker/pkg/homedir" @@ -252,7 +252,7 @@ func hasAdditionalHelp(cmd *cobra.Command) bool { } func isPlugin(cmd *cobra.Command) bool { - return pluginmanager.IsPluginCommand(cmd) + return cmd.Annotations[metadata.CommandAnnotationPlugin] == "true" } func hasAliases(cmd *cobra.Command) bool { @@ -356,9 +356,9 @@ func decoratedName(cmd *cobra.Command) string { } func vendorAndVersion(cmd *cobra.Command) string { - if vendor, ok := cmd.Annotations[pluginmanager.CommandAnnotationPluginVendor]; ok && isPlugin(cmd) { + if vendor, ok := cmd.Annotations[metadata.CommandAnnotationPluginVendor]; ok && isPlugin(cmd) { version := "" - if v, ok := cmd.Annotations[pluginmanager.CommandAnnotationPluginVersion]; ok && v != "" { + if v, ok := cmd.Annotations[metadata.CommandAnnotationPluginVersion]; ok && v != "" { version = ", " + v } return fmt.Sprintf("(%s%s)", vendor, version) @@ -417,7 +417,7 @@ func invalidPlugins(cmd *cobra.Command) []*cobra.Command { } func invalidPluginReason(cmd *cobra.Command) string { - return cmd.Annotations[pluginmanager.CommandAnnotationPluginInvalid] + return cmd.Annotations[metadata.CommandAnnotationPluginInvalid] } const usageTemplate = `Usage: diff --git a/cli/cobra_test.go b/cli/cobra_test.go index 4e0ea8e3e4..e1d4bcb2d2 100644 --- a/cli/cobra_test.go +++ b/cli/cobra_test.go @@ -3,7 +3,7 @@ package cli import ( "testing" - pluginmanager "github.com/docker/cli/cli-plugins/manager" + "github.com/docker/cli/cli-plugins/metadata" "github.com/google/go-cmp/cmp/cmpopts" "github.com/spf13/cobra" "gotest.tools/v3/assert" @@ -49,9 +49,9 @@ func TestVendorAndVersion(t *testing.T) { cmd := &cobra.Command{ Use: "test", Annotations: map[string]string{ - pluginmanager.CommandAnnotationPlugin: "true", - pluginmanager.CommandAnnotationPluginVendor: tc.vendor, - pluginmanager.CommandAnnotationPluginVersion: tc.version, + metadata.CommandAnnotationPlugin: "true", + metadata.CommandAnnotationPluginVendor: tc.vendor, + metadata.CommandAnnotationPluginVersion: tc.version, }, } assert.Equal(t, vendorAndVersion(cmd), tc.expected) @@ -69,8 +69,8 @@ func TestInvalidPlugin(t *testing.T) { assert.Assert(t, is.Len(invalidPlugins(root), 0)) sub1.Annotations = map[string]string{ - pluginmanager.CommandAnnotationPlugin: "true", - pluginmanager.CommandAnnotationPluginInvalid: "foo", + metadata.CommandAnnotationPlugin: "true", + metadata.CommandAnnotationPluginInvalid: "foo", } root.AddCommand(sub1, sub2) sub1.AddCommand(sub1sub1, sub1sub2) @@ -100,6 +100,6 @@ func TestDecoratedName(t *testing.T) { topLevelCommand := &cobra.Command{Use: "pluginTopLevelCommand"} root.AddCommand(topLevelCommand) assert.Equal(t, decoratedName(topLevelCommand), "pluginTopLevelCommand ") - topLevelCommand.Annotations = map[string]string{pluginmanager.CommandAnnotationPlugin: "true"} + topLevelCommand.Annotations = map[string]string{metadata.CommandAnnotationPlugin: "true"} assert.Equal(t, decoratedName(topLevelCommand), "pluginTopLevelCommand*") } diff --git a/cli/command/system/info_test.go b/cli/command/system/info_test.go index e8cecc63bf..5ff0787422 100644 --- a/cli/command/system/info_test.go +++ b/cli/command/system/info_test.go @@ -7,6 +7,7 @@ import ( "time" pluginmanager "github.com/docker/cli/cli-plugins/manager" + "github.com/docker/cli/cli-plugins/metadata" "github.com/docker/cli/internal/test" registrytypes "github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/swarm" @@ -201,7 +202,7 @@ var samplePluginsInfo = []pluginmanager.Plugin{ { Name: "goodplugin", Path: "/path/to/docker-goodplugin", - Metadata: pluginmanager.Metadata{ + Metadata: metadata.Metadata{ SchemaVersion: "0.1.0", ShortDescription: "unit test is good", Vendor: "ACME Corp", @@ -211,7 +212,7 @@ var samplePluginsInfo = []pluginmanager.Plugin{ { Name: "unversionedplugin", Path: "/path/to/docker-unversionedplugin", - Metadata: pluginmanager.Metadata{ + Metadata: metadata.Metadata{ SchemaVersion: "0.1.0", ShortDescription: "this plugin has no version", Vendor: "ACME Corp", diff --git a/cmd/docker/builder.go b/cmd/docker/builder.go index ecb73264e0..bf1ed5e23a 100644 --- a/cmd/docker/builder.go +++ b/cmd/docker/builder.go @@ -8,6 +8,7 @@ import ( "strings" pluginmanager "github.com/docker/cli/cli-plugins/manager" + "github.com/docker/cli/cli-plugins/metadata" "github.com/docker/cli/cli/command" "github.com/docker/docker/api/types" "github.com/pkg/errors" @@ -127,7 +128,7 @@ func processBuilder(dockerCli command.Cli, cmd *cobra.Command, args, osargs []st } // overwrite the command path for this plugin using the alias name. - cmd.Annotations[pluginmanager.CommandAnnotationPluginCommandPath] = strings.Join(append([]string{cmd.CommandPath()}, fwcmdpath...), " ") + cmd.Annotations[metadata.CommandAnnotationPluginCommandPath] = strings.Join(append([]string{cmd.CommandPath()}, fwcmdpath...), " ") return fwargs, fwosargs, envs, nil } diff --git a/e2e/cli-plugins/dial_test.go b/e2e/cli-plugins/dial_test.go index 87ae6eb488..c66fb9ce9d 100644 --- a/e2e/cli-plugins/dial_test.go +++ b/e2e/cli-plugins/dial_test.go @@ -5,7 +5,7 @@ import ( "path/filepath" "testing" - "github.com/docker/cli/cli-plugins/manager" + "github.com/docker/cli/cli-plugins/metadata" "gotest.tools/v3/icmd" ) @@ -21,7 +21,7 @@ func TestCLIPluginDialStdio(t *testing.T) { // the connhelper stuff. helloworld := filepath.Join(os.Getenv("DOCKER_CLI_E2E_PLUGINS_EXTRA_DIRS"), "docker-helloworld") cmd := icmd.Command(helloworld, "--config=blah", "--log-level", "debug", "helloworld", "--who=foo") - res := icmd.RunCmd(cmd, icmd.WithEnv(manager.ReexecEnvvar+"=/bin/true")) + res := icmd.RunCmd(cmd, icmd.WithEnv(metadata.ReexecEnvvar+"=/bin/true")) res.Assert(t, icmd.Expected{ ExitCode: 0, Err: `msg="commandconn: starting /bin/true with [--config=blah --log-level debug system dial-stdio]"`, diff --git a/e2e/cli-plugins/plugins/badmeta/main.go b/e2e/cli-plugins/plugins/badmeta/main.go index 10bd0eff72..8b93c7ab8b 100644 --- a/e2e/cli-plugins/plugins/badmeta/main.go +++ b/e2e/cli-plugins/plugins/badmeta/main.go @@ -7,11 +7,11 @@ import ( "fmt" "os" - "github.com/docker/cli/cli-plugins/manager" + "github.com/docker/cli/cli-plugins/metadata" ) func main() { - if len(os.Args) == 2 && os.Args[1] == manager.MetadataSubcommandName { + if len(os.Args) == 2 && os.Args[1] == metadata.MetadataSubcommandName { fmt.Println(`{invalid-json}`) os.Exit(0) } diff --git a/e2e/cli-plugins/plugins/nopersistentprerun/main.go b/e2e/cli-plugins/plugins/nopersistentprerun/main.go index b90cc67aee..35163d7a72 100644 --- a/e2e/cli-plugins/plugins/nopersistentprerun/main.go +++ b/e2e/cli-plugins/plugins/nopersistentprerun/main.go @@ -3,7 +3,7 @@ package main import ( "fmt" - "github.com/docker/cli/cli-plugins/manager" + "github.com/docker/cli/cli-plugins/metadata" "github.com/docker/cli/cli-plugins/plugin" "github.com/docker/cli/cli/command" "github.com/spf13/cobra" @@ -26,7 +26,7 @@ func main() { }, } }, - manager.Metadata{ + metadata.Metadata{ SchemaVersion: "0.1.0", Vendor: "Docker Inc.", Version: "testing", diff --git a/e2e/cli-plugins/plugins/presocket/main.go b/e2e/cli-plugins/plugins/presocket/main.go index 9a695f1883..d1a4b35011 100644 --- a/e2e/cli-plugins/plugins/presocket/main.go +++ b/e2e/cli-plugins/plugins/presocket/main.go @@ -7,14 +7,14 @@ import ( "syscall" "time" - "github.com/docker/cli/cli-plugins/manager" + "github.com/docker/cli/cli-plugins/metadata" "github.com/docker/cli/cli-plugins/plugin" "github.com/docker/cli/cli/command" "github.com/spf13/cobra" ) func main() { - plugin.Run(RootCmd, manager.Metadata{ + plugin.Run(RootCmd, metadata.Metadata{ SchemaVersion: "0.1.0", Vendor: "Docker Inc.", Version: "test",