diff --git a/go.mod b/go.mod index fa338fcf..04cbac4b 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/containerd/typeurl/v2 v2.1.1 github.com/creack/pty v1.1.18 github.com/distribution/reference v0.5.0 - github.com/docker/cli v26.0.1-0.20240401150816-155dc5e4e406+incompatible + github.com/docker/cli v26.0.1-0.20240410153731-b6c552212837+incompatible // v26.1.0-dev github.com/docker/cli-docs-tool v0.7.0 github.com/docker/docker v26.0.0+incompatible github.com/docker/go-units v0.5.0 diff --git a/go.sum b/go.sum index 1a1ed75d..06309566 100644 --- a/go.sum +++ b/go.sum @@ -121,8 +121,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v26.0.1-0.20240401150816-155dc5e4e406+incompatible h1:+BQSfkbpbEDXXfHmFfmbfstUBFjhffsTkfa0iudOFLc= -github.com/docker/cli v26.0.1-0.20240401150816-155dc5e4e406+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v26.0.1-0.20240410153731-b6c552212837+incompatible h1:KTmSJjZSQM+cpaczHecGsBNlgJtRccef/62pCOeiA9o= +github.com/docker/cli v26.0.1-0.20240410153731-b6c552212837+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli-docs-tool v0.7.0 h1:M2Da98Unz2kz3A5d4yeSGbhyOge2mfYSNjAFt01Rw0M= github.com/docker/cli-docs-tool v0.7.0/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= diff --git a/vendor/github.com/docker/cli/cli-plugins/plugin/plugin.go b/vendor/github.com/docker/cli/cli-plugins/plugin/plugin.go index 54471b41..c04edbb5 100644 --- a/vendor/github.com/docker/cli/cli-plugins/plugin/plugin.go +++ b/vendor/github.com/docker/cli/cli-plugins/plugin/plugin.go @@ -12,15 +12,17 @@ import ( "github.com/docker/cli/cli-plugins/socket" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/connhelper" + "github.com/docker/cli/cli/debug" "github.com/docker/docker/client" "github.com/spf13/cobra" + "go.opentelemetry.io/otel" ) // PersistentPreRunE must be called by any plugin command (or // subcommand) which uses the cobra `PersistentPreRun*` hook. Plugins // which do not make use of `PersistentPreRun*` do not need to call // this (although it remains safe to do so). Plugins are recommended -// to use `PersistenPreRunE` to enable the error to be +// to use `PersistentPreRunE` to enable the error to be // returned. Should not be called outside of a command's // PersistentPreRunE hook and must not be run unless Run has been // called. @@ -66,6 +68,8 @@ 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) { + otel.SetErrorHandler(debug.OTELErrorHandler) + dockerCli, err := command.NewDockerCli() if err != nil { fmt.Fprintln(os.Stderr, err) diff --git a/vendor/github.com/docker/cli/cli/command/telemetry.go b/vendor/github.com/docker/cli/cli/command/telemetry.go index e10571e3..92e80420 100644 --- a/vendor/github.com/docker/cli/cli/command/telemetry.go +++ b/vendor/github.com/docker/cli/cli/command/telemetry.go @@ -110,7 +110,7 @@ func (r *telemetryResource) init() { return } - opts := append(r.defaultOptions(), r.opts...) + opts := append(defaultResourceOptions(), r.opts...) res, err := resource.New(context.Background(), opts...) if err != nil { otel.Handle(err) @@ -122,7 +122,7 @@ func (r *telemetryResource) init() { r.opts = nil } -func (r *telemetryResource) defaultOptions() []resource.Option { +func defaultResourceOptions() []resource.Option { return []resource.Option{ resource.WithDetectors(serviceNameDetector{}), resource.WithAttributes( diff --git a/vendor/github.com/docker/cli/cli/command/telemetry_utils.go b/vendor/github.com/docker/cli/cli/command/telemetry_utils.go index 034fa1f0..5749b4f1 100644 --- a/vendor/github.com/docker/cli/cli/command/telemetry_utils.go +++ b/vendor/github.com/docker/cli/cli/command/telemetry_utils.go @@ -3,23 +3,22 @@ package command import ( "context" "fmt" - "strconv" "strings" "time" "github.com/docker/cli/cli/version" + "github.com/moby/term" "github.com/pkg/errors" "github.com/spf13/cobra" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" ) -// BaseMetricAttributes returns an attribute.Set containing attributes to attach to metrics/traces -func BaseMetricAttributes(cmd *cobra.Command) attribute.Set { - attrList := []attribute.KeyValue{ +// BaseCommandAttributes returns an attribute.Set containing attributes to attach to metrics/traces +func BaseCommandAttributes(cmd *cobra.Command, streams Streams) []attribute.KeyValue { + return append([]attribute.KeyValue{ attribute.String("command.name", getCommandName(cmd)), - } - return attribute.NewSet(attrList...) + }, stdioAttributes(streams)...) } // InstrumentCobraCommands wraps all cobra commands' RunE funcs to set a command duration metric using otel. @@ -27,7 +26,7 @@ func BaseMetricAttributes(cmd *cobra.Command) attribute.Set { // Note: this should be the last func to wrap/modify the PersistentRunE/RunE funcs before command execution. // // can also be used for spans! -func InstrumentCobraCommands(cmd *cobra.Command, mp metric.MeterProvider) { +func (cli *DockerCli) InstrumentCobraCommands(cmd *cobra.Command, mp metric.MeterProvider) { meter := getDefaultMeter(mp) // If PersistentPreRunE is nil, make it execute PersistentPreRun and return nil by default ogPersistentPreRunE := cmd.PersistentPreRunE @@ -56,7 +55,8 @@ func InstrumentCobraCommands(cmd *cobra.Command, mp metric.MeterProvider) { } cmd.RunE = func(cmd *cobra.Command, args []string) error { // start the timer as the first step of every cobra command - stopCobraCmdTimer := startCobraCommandTimer(cmd, meter) + baseAttrs := BaseCommandAttributes(cmd, cli) + stopCobraCmdTimer := startCobraCommandTimer(cmd, meter, baseAttrs) cmdErr := ogRunE(cmd, args) stopCobraCmdTimer(cmdErr) return cmdErr @@ -66,9 +66,8 @@ func InstrumentCobraCommands(cmd *cobra.Command, mp metric.MeterProvider) { } } -func startCobraCommandTimer(cmd *cobra.Command, meter metric.Meter) func(err error) { +func startCobraCommandTimer(cmd *cobra.Command, meter metric.Meter, attrs []attribute.KeyValue) func(err error) { ctx := cmd.Context() - baseAttrs := BaseMetricAttributes(cmd) durationCounter, _ := meter.Float64Counter( "command.time", metric.WithDescription("Measures the duration of the cobra command"), @@ -80,12 +79,22 @@ func startCobraCommandTimer(cmd *cobra.Command, meter metric.Meter) func(err err duration := float64(time.Since(start)) / float64(time.Millisecond) cmdStatusAttrs := attributesFromError(err) durationCounter.Add(ctx, duration, - metric.WithAttributeSet(baseAttrs), - metric.WithAttributeSet(attribute.NewSet(cmdStatusAttrs...)), + metric.WithAttributes(attrs...), + metric.WithAttributes(cmdStatusAttrs...), ) } } +func stdioAttributes(streams Streams) []attribute.KeyValue { + // we don't wrap stderr, but we do wrap in/out + _, stderrTty := term.GetFdInfo(streams.Err()) + return []attribute.KeyValue{ + attribute.Bool("command.stdin.isatty", streams.In().IsTerminal()), + attribute.Bool("command.stdout.isatty", streams.Out().IsTerminal()), + attribute.Bool("command.stderr.isatty", stderrTty), + } +} + func attributesFromError(err error) []attribute.KeyValue { attrs := []attribute.KeyValue{} exitCode := 0 @@ -100,7 +109,7 @@ func attributesFromError(err error) []attribute.KeyValue { } attrs = append(attrs, attribute.String("command.error.type", otelErrorType(err))) } - attrs = append(attrs, attribute.String("command.status.code", strconv.Itoa(exitCode))) + attrs = append(attrs, attribute.Int("command.status.code", exitCode)) return attrs } diff --git a/vendor/github.com/docker/cli/cli/command/utils.go b/vendor/github.com/docker/cli/cli/command/utils.go index df1f876f..d7184f8c 100644 --- a/vendor/github.com/docker/cli/cli/command/utils.go +++ b/vendor/github.com/docker/cli/cli/command/utils.go @@ -19,6 +19,7 @@ import ( "github.com/docker/docker/api/types/filters" mounttypes "github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/versions" + "github.com/docker/docker/errdefs" "github.com/moby/sys/sequential" "github.com/pkg/errors" "github.com/spf13/pflag" @@ -75,9 +76,7 @@ func PrettyPrint(i any) string { } } -type PromptError error - -var ErrPromptTerminated = PromptError(errors.New("prompt terminated")) +var ErrPromptTerminated = errdefs.Cancelled(errors.New("prompt terminated")) // PromptForConfirmation requests and checks confirmation from the user. // This will display the provided message followed by ' [y/N] '. If the user @@ -123,6 +122,8 @@ func PromptForConfirmation(ctx context.Context, ins io.Reader, outs io.Writer, m select { case <-notifyCtx.Done(): + // print a newline on termination + _, _ = fmt.Fprintln(outs, "") return false, ErrPromptTerminated case r := <-result: return r, nil diff --git a/vendor/github.com/docker/cli/cli/debug/debug.go b/vendor/github.com/docker/cli/cli/debug/debug.go index b00ea63a..1a9a46ab 100644 --- a/vendor/github.com/docker/cli/cli/debug/debug.go +++ b/vendor/github.com/docker/cli/cli/debug/debug.go @@ -4,6 +4,7 @@ import ( "os" "github.com/sirupsen/logrus" + "go.opentelemetry.io/otel" ) // Enable sets the DEBUG env var to true @@ -24,3 +25,13 @@ func Disable() { func IsEnabled() bool { return os.Getenv("DEBUG") != "" } + +// OTELErrorHandler is an error handler for OTEL that +// uses the CLI debug package to log messages when an error +// occurs. +// +// The default is to log to the debug level which is only +// enabled when debugging is enabled. +var OTELErrorHandler otel.ErrorHandler = otel.ErrorHandlerFunc(func(err error) { + logrus.WithError(err).Debug("otel error") +}) diff --git a/vendor/modules.txt b/vendor/modules.txt index f54b97b6..e3fd16d9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -215,7 +215,7 @@ github.com/davecgh/go-spew/spew # github.com/distribution/reference v0.5.0 ## explicit; go 1.20 github.com/distribution/reference -# github.com/docker/cli v26.0.1-0.20240401150816-155dc5e4e406+incompatible +# github.com/docker/cli v26.0.1-0.20240410153731-b6c552212837+incompatible ## explicit github.com/docker/cli/cli github.com/docker/cli/cli-plugins/hooks