From e96e17d1029dc5768ecf6bfb0da2f8aae1faa7f4 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 6 May 2022 16:15:20 +0200 Subject: [PATCH 1/2] info: improve handling of empty Info Before this change, the function could print an error in some cases, for example; ```bash docker -H tcp://127.0.0.1:2375 info --format '{{.LoggingDriver}}' template: :1:2: executing "" at <.LoggingDriver>: reflect: indirection through nil pointer to embedded struct field Info ``` With this patch applied, the error is handled gracefully, and when failing to connect with the daemon, the error is logged; ```bash docker -H tcp://127.0.0.1:2375 info --format '{{.LoggingDriver}}' Cannot connect to the Docker daemon at tcp://127.0.0.1:2375. Is the docker daemon running? docker -H tcp://127.0.0.1:2375 info --format '{{json .}}' Cannot connect to the Docker daemon at tcp://127.0.0.1:2375. Is the docker daemon running? {"ID":"","Containers":0,"..."}} ``` Note that the connection error is also included in the JSON `ServerErrors` field, so that the information does not get lost, even if STDERR would be redirected; ```bash docker -H tcp://127.0.0.1:2375 info --format '{{json .ServerErrors}}' 2> /dev/null ["Cannot connect to the Docker daemon at tcp://127.0.0.1:2375. Is the docker daemon running?"] ``` Signed-off-by: Sebastiaan van Stijn --- cli/command/system/info.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cli/command/system/info.go b/cli/command/system/info.go index ff2f79422158..f3ce01f86104 100644 --- a/cli/command/system/info.go +++ b/cli/command/system/info.go @@ -67,11 +67,12 @@ func NewInfoCommand(dockerCli command.Cli) *cobra.Command { } func runInfo(cmd *cobra.Command, dockerCli command.Cli, opts *infoOptions) error { - var info info - - info.ClientInfo = &clientInfo{ - Context: dockerCli.CurrentContext(), - Debug: debug.IsEnabled(), + info := info{ + ClientInfo: &clientInfo{ + Context: dockerCli.CurrentContext(), + Debug: debug.IsEnabled(), + }, + Info: &types.Info{}, } if plugins, err := pluginmanager.ListPlugins(dockerCli, cmd.Root()); err == nil { info.ClientInfo.Plugins = plugins @@ -84,6 +85,7 @@ func runInfo(cmd *cobra.Command, dockerCli command.Cli, opts *infoOptions) error if dinfo, err := dockerCli.Client().Info(ctx); err == nil { info.Info = &dinfo } else { + fmt.Fprintln(dockerCli.Err(), err) info.ServerErrors = append(info.ServerErrors, err.Error()) } } From 9dc54f3fbe5ff517bc0298aec56f9a6407cce74d Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 10 May 2022 12:13:03 +0200 Subject: [PATCH 2/2] info: don't print server info if we failed to connect Before this patch, the Server output would be printed even if we failed to connect (including WARNINGS): ```bash docker -H tcp://127.0.0.1:2375 info Cannot connect to the Docker daemon at tcp://127.0.0.1:2375. Is the docker daemon running? Client: Context: default Debug Mode: false Plugins: buildx: Docker Buildx (Docker Inc., v0.8.2) compose: Docker Compose (Docker Inc., v2.4.1) sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc., 0.6.0) scan: Docker Scan (Docker Inc., v0.17.0) Server: Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 0 Plugins: Volume: Network: Log: Swarm: NodeID: Is Manager: false Node Address: CPUs: 0 Total Memory: 0B Docker Root Dir: Debug Mode: false Experimental: false Live Restore Enabled: false WARNING: No memory limit support WARNING: No swap limit support WARNING: No oom kill disable support WARNING: No cpu cfs quota support WARNING: No cpu cfs period support WARNING: No cpu shares support WARNING: No cpuset support WARNING: IPv4 forwarding is disabled WARNING: bridge-nf-call-iptables is disabled WARNING: bridge-nf-call-ip6tables is disabled ERROR: Cannot connect to the Docker daemon at tcp://127.0.0.1:2375. Is the docker daemon running? errors pretty printing info ``` With this patch; ```bash docker -H tcp://127.0.0.1:2375 info Client: Context: default Debug Mode: false Plugins: buildx: Docker Buildx (Docker Inc., v0.8.2) compose: Docker Compose (Docker Inc., v2.4.1) sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc., 0.6.0) scan: Docker Scan (Docker Inc., v0.17.0) Server: ERROR: Cannot connect to the Docker daemon at tcp://127.0.0.1:2375. Is the docker daemon running? errors pretty printing info ``` And if a custom format is used: ```bash docker -H tcp://127.0.0.1:2375 info --format '{{.Containers}}' Cannot connect to the Docker daemon at tcp://127.0.0.1:2375. Is the docker daemon running? 0 ``` Signed-off-by: Sebastiaan van Stijn --- cli/command/system/info.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cli/command/system/info.go b/cli/command/system/info.go index f3ce01f86104..2a412c99fca3 100644 --- a/cli/command/system/info.go +++ b/cli/command/system/info.go @@ -85,8 +85,17 @@ func runInfo(cmd *cobra.Command, dockerCli command.Cli, opts *infoOptions) error if dinfo, err := dockerCli.Client().Info(ctx); err == nil { info.Info = &dinfo } else { - fmt.Fprintln(dockerCli.Err(), err) info.ServerErrors = append(info.ServerErrors, err.Error()) + if opts.format == "" { + // reset the server info to prevent printing "empty" Server info + // and warnings, but don't reset it if a custom format was specified + // to prevent errors from Go's template parsing during format. + info.Info = nil + } else { + // if a format is provided, print the error, as it may be hidden + // otherwise if the template doesn't include the ServerErrors field. + fmt.Fprintln(dockerCli.Err(), err) + } } }