vendor: update buildx to latest docker/cli

This version of docker/cli has changes to remove compose-cli wrapper and
move all CLI metrics to OTEL.

Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
This commit is contained in:
Jonathan A. Sternberg
2024-05-16 12:07:13 -05:00
parent afcb609966
commit 4fc4bc07ae
15 changed files with 204 additions and 107 deletions
+69 -30
View File
@@ -14,31 +14,42 @@ import (
// that plugins declaring support for hooks get passed when
// being invoked following a CLI command execution.
type HookPluginData struct {
RootCmd string
Flags map[string]string
// RootCmd is a string representing the matching hook configuration
// which is currently being invoked. If a hook for `docker context` is
// configured and the user executes `docker context ls`, the plugin will
// be invoked with `context`.
RootCmd string
Flags map[string]string
CommandError string
}
// RunPluginHooks calls the hook subcommand for all present
// CLI plugins that declare support for hooks in their metadata
// and parses/prints their responses.
func RunPluginHooks(dockerCli command.Cli, rootCmd, subCommand *cobra.Command, plugin string, args []string) error {
subCmdName := subCommand.Name()
if plugin != "" {
subCmdName = plugin
}
var flags map[string]string
if plugin == "" {
flags = getCommandFlags(subCommand)
} else {
flags = getNaiveFlags(args)
}
nextSteps := invokeAndCollectHooks(dockerCli, rootCmd, subCommand, subCmdName, flags)
// RunCLICommandHooks is the entrypoint into the hooks execution flow after
// a main CLI command was executed. It calls the hook subcommand for all
// present CLI plugins that declare support for hooks in their metadata and
// parses/prints their responses.
func RunCLICommandHooks(dockerCli command.Cli, rootCmd, subCommand *cobra.Command, cmdErrorMessage string) {
commandName := strings.TrimPrefix(subCommand.CommandPath(), rootCmd.Name()+" ")
flags := getCommandFlags(subCommand)
runHooks(dockerCli, rootCmd, subCommand, commandName, flags, cmdErrorMessage)
}
// RunPluginHooks is the entrypoint for the hooks execution flow
// after a plugin command was just executed by the CLI.
func RunPluginHooks(dockerCli command.Cli, rootCmd, subCommand *cobra.Command, args []string) {
commandName := strings.Join(args, " ")
flags := getNaiveFlags(args)
runHooks(dockerCli, rootCmd, subCommand, commandName, flags, "")
}
func runHooks(dockerCli command.Cli, rootCmd, subCommand *cobra.Command, invokedCommand string, flags map[string]string, cmdErrorMessage string) {
nextSteps := invokeAndCollectHooks(dockerCli, rootCmd, subCommand, invokedCommand, flags, cmdErrorMessage)
hooks.PrintNextSteps(dockerCli.Err(), nextSteps)
return nil
}
func invokeAndCollectHooks(dockerCli command.Cli, rootCmd, subCmd *cobra.Command, hookCmdName string, flags map[string]string) []string {
func invokeAndCollectHooks(dockerCli command.Cli, rootCmd, subCmd *cobra.Command, subCmdStr string, flags map[string]string, cmdErrorMessage string) []string {
pluginsCfg := dockerCli.ConfigFile().Plugins
if pluginsCfg == nil {
return nil
@@ -46,7 +57,8 @@ func invokeAndCollectHooks(dockerCli command.Cli, rootCmd, subCmd *cobra.Command
nextSteps := make([]string, 0, len(pluginsCfg))
for pluginName, cfg := range pluginsCfg {
if !registersHook(cfg, hookCmdName) {
match, ok := pluginMatch(cfg, subCmdStr)
if !ok {
continue
}
@@ -55,7 +67,11 @@ func invokeAndCollectHooks(dockerCli command.Cli, rootCmd, subCmd *cobra.Command
continue
}
hookReturn, err := p.RunHook(hookCmdName, flags)
hookReturn, err := p.RunHook(HookPluginData{
RootCmd: match,
Flags: flags,
CommandError: cmdErrorMessage,
})
if err != nil {
// skip misbehaving plugins, but don't halt execution
continue
@@ -76,23 +92,46 @@ func invokeAndCollectHooks(dockerCli command.Cli, rootCmd, subCmd *cobra.Command
if err != nil {
continue
}
nextSteps = append(nextSteps, processedHook)
nextSteps = append(nextSteps, processedHook...)
}
return nextSteps
}
func registersHook(pluginCfg map[string]string, subCmdName string) bool {
hookCmdStr, ok := pluginCfg["hooks"]
if !ok {
return false
// pluginMatch takes a plugin configuration and a string representing the
// command being executed (such as 'image ls' the root 'docker' is omitted)
// and, if the configuration includes a hook for the invoked command, returns
// the configured hook string.
func pluginMatch(pluginCfg map[string]string, subCmd string) (string, bool) {
configuredPluginHooks, ok := pluginCfg["hooks"]
if !ok || configuredPluginHooks == "" {
return "", false
}
commands := strings.Split(hookCmdStr, ",")
commands := strings.Split(configuredPluginHooks, ",")
for _, hookCmd := range commands {
if hookCmd == subCmdName {
return true
if hookMatch(hookCmd, subCmd) {
return hookCmd, true
}
}
return false
return "", false
}
func hookMatch(hookCmd, subCmd string) bool {
hookCmdTokens := strings.Split(hookCmd, " ")
subCmdTokens := strings.Split(subCmd, " ")
if len(hookCmdTokens) > len(subCmdTokens) {
return false
}
for i, v := range hookCmdTokens {
if v != subCmdTokens[i] {
return false
}
}
return true
}
func getCommandFlags(cmd *cobra.Command) map[string]string {
+1 -2
View File
@@ -240,8 +240,7 @@ func PluginRunCommand(dockerCli command.Cli, name string, rootcmd *cobra.Command
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, ReexecEnvvar+"="+os.Args[0])
cmd.Env = append(cmd.Environ(), ReexecEnvvar+"="+os.Args[0])
cmd.Env = appendPluginResourceAttributesEnvvar(cmd.Env, rootcmd, plugin)
return cmd, nil
+7 -6
View File
@@ -2,6 +2,7 @@ package manager
import (
"encoding/json"
"os"
"os/exec"
"path/filepath"
"regexp"
@@ -104,16 +105,16 @@ func newPlugin(c Candidate, cmds []*cobra.Command) (Plugin, error) {
// RunHook executes the plugin's hooks command
// and returns its unprocessed output.
func (p *Plugin) RunHook(cmdName string, flags map[string]string) ([]byte, error) {
hDataBytes, err := json.Marshal(HookPluginData{
RootCmd: cmdName,
Flags: flags,
})
func (p *Plugin) RunHook(hookData HookPluginData) ([]byte, error) {
hDataBytes, err := json.Marshal(hookData)
if err != nil {
return nil, wrapAsPluginError(err, "failed to marshall hook data")
}
hookCmdOutput, err := exec.Command(p.Path, p.Name, HookSubcommandName, string(hDataBytes)).Output()
pCmd := exec.Command(p.Path, p.Name, HookSubcommandName, string(hDataBytes))
pCmd.Env = os.Environ()
pCmd.Env = append(pCmd.Env, ReexecEnvvar+"="+os.Args[0])
hookCmdOutput, err := pCmd.Output()
if err != nil {
return nil, wrapAsPluginError(err, "failed to execute plugin hook subcommand")
}