From c9e60ae17a118555196ab827f366629c4884bbb6 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 24 Jan 2019 14:22:55 +0000 Subject: [PATCH] Allow `prettyPrintInfo` to return multiple errors This allows it to print what it can, rather than aborting half way when a bad security context is hit. Signed-off-by: Ian Campbell --- cli/command/system/info.go | 34 ++++++------ cli/command/system/info_test.go | 14 +++++ .../system/testdata/docker-info-badsec.golden | 54 +++++++++++++++++++ .../testdata/docker-info-badsec.json.golden | 1 + 4 files changed, 87 insertions(+), 16 deletions(-) create mode 100644 cli/command/system/testdata/docker-info-badsec.golden create mode 100644 cli/command/system/testdata/docker-info-badsec.json.golden diff --git a/cli/command/system/info.go b/cli/command/system/info.go index 4c65cfeaef..2ec94db0fa 100644 --- a/cli/command/system/info.go +++ b/cli/command/system/info.go @@ -94,7 +94,7 @@ func prettyPrintInfo(dockerCli command.Cli, info info) error { fmt.Fprintln(dockerCli.Out(), "Server") fmt.Fprintln(dockerCli.Out(), "------") if info.Info != nil { - if err := prettyPrintServerInfo(dockerCli, *info.Info); err != nil { + for _, err := range prettyPrintServerInfo(dockerCli, *info.Info) { info.ServerErrors = append(info.ServerErrors, err.Error()) } } @@ -119,7 +119,9 @@ func prettyPrintClientInfo(dockerCli command.Cli, info clientInfo) error { } // nolint: gocyclo -func prettyPrintServerInfo(dockerCli command.Cli, info types.Info) error { +func prettyPrintServerInfo(dockerCli command.Cli, info types.Info) []error { + var errs []error + fmt.Fprintln(dockerCli.Out(), "Containers:", info.Containers) fmt.Fprintln(dockerCli.Out(), " Running:", info.ContainersRunning) fmt.Fprintln(dockerCli.Out(), " Paused:", info.ContainersPaused) @@ -180,20 +182,20 @@ func prettyPrintServerInfo(dockerCli command.Cli, info types.Info) error { fmt.Fprint(dockerCli.Out(), "\n") } if len(info.SecurityOptions) != 0 { - kvs, err := types.DecodeSecurityOptions(info.SecurityOptions) - if err != nil { - return err - } - fmt.Fprintln(dockerCli.Out(), "Security Options:") - for _, so := range kvs { - fmt.Fprintln(dockerCli.Out(), " "+so.Name) - for _, o := range so.Options { - switch o.Key { - case "profile": - if o.Value != "default" { - fmt.Fprintln(dockerCli.Err(), " WARNING: You're not using the default seccomp profile") + if kvs, err := types.DecodeSecurityOptions(info.SecurityOptions); err != nil { + errs = append(errs, err) + } else { + fmt.Fprintln(dockerCli.Out(), "Security Options:") + for _, so := range kvs { + fmt.Fprintln(dockerCli.Out(), " "+so.Name) + for _, o := range so.Options { + switch o.Key { + case "profile": + if o.Value != "default" { + fmt.Fprintln(dockerCli.Err(), " WARNING: You're not using the default seccomp profile") + } + fmt.Fprintln(dockerCli.Out(), " Profile:", o.Value) } - fmt.Fprintln(dockerCli.Out(), " Profile:", o.Value) } } } @@ -274,7 +276,7 @@ func prettyPrintServerInfo(dockerCli command.Cli, info types.Info) error { fmt.Fprint(dockerCli.Out(), "\n") printServerWarnings(dockerCli, info) - return nil + return errs } // nolint: gocyclo diff --git a/cli/command/system/info_test.go b/cli/command/system/info_test.go index 5b44935c2f..d3bcd7e02a 100644 --- a/cli/command/system/info_test.go +++ b/cli/command/system/info_test.go @@ -224,6 +224,9 @@ func TestPrettyPrintInfo(t *testing.T) { "WARNING: bridge-nf-call-ip6tables is disabled", } + sampleInfoBadSecurity := sampleInfoNoSwarm + sampleInfoBadSecurity.SecurityOptions = []string{"foo="} + for _, tc := range []struct { doc string dockerInfo info @@ -280,6 +283,17 @@ func TestPrettyPrintInfo(t *testing.T) { jsonGolden: "docker-info-errors", expectedError: "errors pretty printing info", }, + { + doc: "bad security info", + dockerInfo: info{ + Info: &sampleInfoBadSecurity, + ServerErrors: []string{"an error happened"}, + ClientInfo: &clientInfo{Debug: false}, + }, + prettyGolden: "docker-info-badsec", + jsonGolden: "docker-info-badsec", + expectedError: "errors pretty printing info", + }, } { t.Run(tc.doc, func(t *testing.T) { cli := test.NewFakeCli(&fakeClient{}) diff --git a/cli/command/system/testdata/docker-info-badsec.golden b/cli/command/system/testdata/docker-info-badsec.golden new file mode 100644 index 0000000000..337991ca74 --- /dev/null +++ b/cli/command/system/testdata/docker-info-badsec.golden @@ -0,0 +1,54 @@ +Client +------ +Debug Mode: false + +Server +------ +Containers: 0 + Running: 0 + Paused: 0 + Stopped: 0 +Images: 0 +Server Version: 17.06.1-ce +Storage Driver: aufs + Root Dir: /var/lib/docker/aufs + Backing Filesystem: extfs + Dirs: 0 + Dirperm1 Supported: true +Logging Driver: json-file +Cgroup Driver: cgroupfs +Plugins: + Volume: local + Network: bridge host macvlan null overlay + Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog +Swarm: inactive +Runtimes: runc +Default Runtime: runc +Init Binary: docker-init +containerd version: 6e23458c129b551d5c9871e5174f6b1b7f6d1170 +runc version: 810190ceaa507aa2727d7ae6f4790c76ec150bd2 +init version: 949e6fa +Kernel Version: 4.4.0-87-generic +Operating System: Ubuntu 16.04.3 LTS +OSType: linux +Architecture: x86_64 +CPUs: 2 +Total Memory: 1.953GiB +Name: system-sample +ID: EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX +Docker Root Dir: /var/lib/docker +Debug Mode: true + File Descriptors: 33 + Goroutines: 135 + System Time: 2017-08-24T17:44:34.077811894Z + EventsListeners: 0 +Registry: https://index.docker.io/v1/ +Labels: + provider=digitalocean +Experimental: false +Insecure Registries: + 127.0.0.0/8 +Live Restore Enabled: false + +ERROR: an error happened +ERROR: invalid empty security option diff --git a/cli/command/system/testdata/docker-info-badsec.json.golden b/cli/command/system/testdata/docker-info-badsec.json.golden new file mode 100644 index 0000000000..4b15ac0222 --- /dev/null +++ b/cli/command/system/testdata/docker-info-badsec.json.golden @@ -0,0 +1 @@ +{"ID":"EKHL:QDUU:QZ7U:MKGD:VDXK:S27Q:GIPU:24B7:R7VT:DGN6:QCSF:2UBX","Containers":0,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":0,"Images":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Backing Filesystem","extfs"],["Dirs","0"],["Dirperm1 Supported","true"]],"SystemStatus":null,"Plugins":{"Volume":["local"],"Network":["bridge","host","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"KernelMemoryTCP":false,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":33,"OomKillDisable":true,"NGoroutines":135,"SystemTime":"2017-08-24T17:44:34.077811894Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"4.4.0-87-generic","OperatingSystem":"Ubuntu 16.04.3 LTS","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":null,"Secure":true,"Official":true}},"Mirrors":null},"NCPU":2,"MemTotal":2097356800,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"system-sample","Labels":["provider=digitalocean"],"ExperimentalBuild":false,"ServerVersion":"17.06.1-ce","ClusterStore":"","ClusterAdvertise":"","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"6e23458c129b551d5c9871e5174f6b1b7f6d1170","Expected":"6e23458c129b551d5c9871e5174f6b1b7f6d1170"},"RuncCommit":{"ID":"810190ceaa507aa2727d7ae6f4790c76ec150bd2","Expected":"810190ceaa507aa2727d7ae6f4790c76ec150bd2"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["foo="],"Warnings":null,"ServerErrors":["an error happened"],"ClientInfo":{"Debug":false,"Warnings":null}}