From 3428b78e966954741325061800919984fb7257e9 Mon Sep 17 00:00:00 2001 From: Ying Li Date: Thu, 24 Aug 2017 15:42:11 -0700 Subject: [PATCH] Include whether the managers in the swarm are autolocked as part of `docker info`. Signed-off-by: Ying Li --- cli/command/system/info.go | 7 +- cli/command/system/info_test.go | 237 ++++++++++++++++++ .../testdata/docker-info-no-swarm.golden | 51 ++++ .../testdata/docker-info-warnings.golden | 11 + .../testdata/docker-info-with-swarm.golden | 73 ++++++ 5 files changed, 376 insertions(+), 3 deletions(-) create mode 100644 cli/command/system/info_test.go create mode 100644 cli/command/system/testdata/docker-info-no-swarm.golden create mode 100644 cli/command/system/testdata/docker-info-warnings.golden create mode 100644 cli/command/system/testdata/docker-info-with-swarm.golden diff --git a/cli/command/system/info.go b/cli/command/system/info.go index 73f1765435..e1b5b08c63 100644 --- a/cli/command/system/info.go +++ b/cli/command/system/info.go @@ -54,7 +54,7 @@ func runInfo(dockerCli *command.DockerCli, opts *infoOptions) error { } // nolint: gocyclo -func prettyPrintInfo(dockerCli *command.DockerCli, info types.Info) error { +func prettyPrintInfo(dockerCli command.Cli, info types.Info) error { fmt.Fprintf(dockerCli.Out(), "Containers: %d\n", info.Containers) fmt.Fprintf(dockerCli.Out(), " Running: %d\n", info.ContainersRunning) fmt.Fprintf(dockerCli.Out(), " Paused: %d\n", info.ContainersPaused) @@ -76,7 +76,7 @@ func prettyPrintInfo(dockerCli *command.DockerCli, info types.Info) error { fprintfIfNotEmpty(dockerCli.Out(), "Logging Driver: %s\n", info.LoggingDriver) fprintfIfNotEmpty(dockerCli.Out(), "Cgroup Driver: %s\n", info.CgroupDriver) - fmt.Fprintf(dockerCli.Out(), "Plugins: \n") + fmt.Fprintf(dockerCli.Out(), "Plugins:\n") fmt.Fprintf(dockerCli.Out(), " Volume:") fmt.Fprintf(dockerCli.Out(), " %s", strings.Join(info.Plugins.Volume, " ")) fmt.Fprintf(dockerCli.Out(), "\n") @@ -130,6 +130,7 @@ func prettyPrintInfo(dockerCli *command.DockerCli, info types.Info) error { fmt.Fprintf(dockerCli.Out(), " %s: %s\n", entry.Protocol, entry.URL) } } + fmt.Fprintf(dockerCli.Out(), " Autolock Managers: %v\n", info.Swarm.Cluster.Spec.EncryptionConfig.AutoLockManagers) fmt.Fprintf(dockerCli.Out(), " Root Rotation In Progress: %v\n", info.Swarm.Cluster.RootRotationInProgress) } fmt.Fprintf(dockerCli.Out(), " Node Address: %s\n", info.Swarm.NodeAddr) @@ -325,7 +326,7 @@ func prettyPrintInfo(dockerCli *command.DockerCli, info types.Info) error { return nil } -func printStorageDriverWarnings(dockerCli *command.DockerCli, info types.Info) { +func printStorageDriverWarnings(dockerCli command.Cli, info types.Info) { if info.DriverStatus == nil { return } diff --git a/cli/command/system/info_test.go b/cli/command/system/info_test.go new file mode 100644 index 0000000000..4291623d1a --- /dev/null +++ b/cli/command/system/info_test.go @@ -0,0 +1,237 @@ +package system + +import ( + "encoding/base64" + "net" + "testing" + "time" + + "github.com/docker/cli/internal/test" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/registry" + "github.com/docker/docker/api/types/swarm" + "github.com/gotestyourself/gotestyourself/golden" + "github.com/stretchr/testify/assert" +) + +// helper function that base64 decodes a string and ignores the error +func base64Decode(val string) []byte { + decoded, _ := base64.StdEncoding.DecodeString(val) + return decoded +} + +var sampleInfoNoSwarm = types.Info{ + 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: [][2]string{ + {"Root Dir", "/var/lib/docker/aufs"}, + {"Backing Filesystem", "extfs"}, + {"Dirs", "0"}, + {"Dirperm1 Supported", "true"}, + }, + SystemStatus: nil, + Plugins: types.PluginsInfo{ + Volume: []string{"local"}, + Network: []string{"bridge", "host", "macvlan", "null", "overlay"}, + Authorization: nil, + Log: []string{"awslogs", "fluentd", "gcplogs", "gelf", "journald", "json-file", "logentries", "splunk", "syslog"}, + }, + MemoryLimit: true, + SwapLimit: true, + KernelMemory: true, + 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: ®istry.ServiceConfig{ + AllowNondistributableArtifactsCIDRs: nil, + AllowNondistributableArtifactsHostnames: nil, + InsecureRegistryCIDRs: []*registry.NetIPNet{ + { + IP: net.ParseIP("127.0.0.0"), + Mask: net.IPv4Mask(255, 0, 0, 0), + }, + }, + IndexConfigs: map[string]*registry.IndexInfo{ + "docker.io": { + Name: "docker.io", + Mirrors: nil, + Secure: true, + Official: true, + }, + }, + Mirrors: nil, + }, + NCPU: 2, + MemTotal: 2097356800, + DockerRootDir: "/var/lib/docker", + HTTPProxy: "", + HTTPSProxy: "", + NoProxy: "", + Name: "system-sample", + Labels: []string{"provider=digitalocean"}, + ExperimentalBuild: false, + ServerVersion: "17.06.1-ce", + ClusterStore: "", + ClusterAdvertise: "", + Runtimes: map[string]types.Runtime{ + "runc": { + Path: "docker-runc", + Args: nil, + }, + }, + DefaultRuntime: "runc", + Swarm: swarm.Info{LocalNodeState: "inactive"}, + LiveRestoreEnabled: false, + Isolation: "", + InitBinary: "docker-init", + ContainerdCommit: types.Commit{ + ID: "6e23458c129b551d5c9871e5174f6b1b7f6d1170", + Expected: "6e23458c129b551d5c9871e5174f6b1b7f6d1170", + }, + RuncCommit: types.Commit{ + ID: "810190ceaa507aa2727d7ae6f4790c76ec150bd2", + Expected: "810190ceaa507aa2727d7ae6f4790c76ec150bd2", + }, + InitCommit: types.Commit{ + ID: "949e6fa", + Expected: "949e6fa", + }, + SecurityOptions: []string{"name=apparmor", "name=seccomp,profile=default"}, +} + +var sampleSwarmInfo = swarm.Info{ + NodeID: "qo2dfdig9mmxqkawulggepdih", + NodeAddr: "165.227.107.89", + LocalNodeState: "active", + ControlAvailable: true, + Error: "", + RemoteManagers: []swarm.Peer{ + { + NodeID: "qo2dfdig9mmxqkawulggepdih", + Addr: "165.227.107.89:2377", + }, + }, + Nodes: 1, + Managers: 1, + Cluster: &swarm.ClusterInfo{ + ID: "9vs5ygs0gguyyec4iqf2314c0", + Meta: swarm.Meta{ + Version: swarm.Version{Index: 11}, + CreatedAt: time.Date(2017, 8, 24, 17, 34, 19, 278062352, time.UTC), + UpdatedAt: time.Date(2017, 8, 24, 17, 34, 42, 398815481, time.UTC), + }, + Spec: swarm.Spec{ + Annotations: swarm.Annotations{ + Name: "default", + Labels: nil, + }, + Orchestration: swarm.OrchestrationConfig{ + TaskHistoryRetentionLimit: &[]int64{5}[0], + }, + Raft: swarm.RaftConfig{ + SnapshotInterval: 10000, + KeepOldSnapshots: &[]uint64{0}[0], + LogEntriesForSlowFollowers: 500, + ElectionTick: 3, + HeartbeatTick: 1, + }, + Dispatcher: swarm.DispatcherConfig{ + HeartbeatPeriod: 5000000000, + }, + CAConfig: swarm.CAConfig{ + NodeCertExpiry: 7776000000000000, + }, + TaskDefaults: swarm.TaskDefaults{}, + EncryptionConfig: swarm.EncryptionConfig{ + AutoLockManagers: true, + }, + }, + TLSInfo: swarm.TLSInfo{ + TrustRoot: ` +-----BEGIN CERTIFICATE----- +MIIBajCCARCgAwIBAgIUaFCW5xsq8eyiJ+Pmcv3MCflMLnMwCgYIKoZIzj0EAwIw +EzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMTcwODI0MTcyOTAwWhcNMzcwODE5MTcy +OTAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH +A0IABDy7NebyUJyUjWJDBUdnZoV6GBxEGKO4TZPNDwnxDxJcUdLVaB7WGa4/DLrW +UfsVgh1JGik2VTiLuTMA1tLlNPOjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MB0GA1UdDgQWBBQl16XFtaaXiUAwEuJptJlDjfKskDAKBggqhkjO +PQQDAgNIADBFAiEAo9fTQNM5DP9bHVcTJYfl2Cay1bFu1E+lnpmN+EYJfeACIGKH +1pCUkZ+D0IB6CiEZGWSHyLuXPM1rlP+I5KuS7sB8 +-----END CERTIFICATE----- +`, + CertIssuerSubject: base64Decode("MBMxETAPBgNVBAMTCHN3YXJtLWNh"), + CertIssuerPublicKey: base64Decode( + "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPLs15vJQnJSNYkMFR2dmhXoYHEQYo7hNk80PCfEPElxR0tVoHtYZrj8MutZR+xWCHUkaKTZVOIu5MwDW0uU08w=="), + }, + RootRotationInProgress: false, + }, +} + +func TestPrettyPrintInfo(t *testing.T) { + infoWithSwarm := sampleInfoNoSwarm + infoWithSwarm.Swarm = sampleSwarmInfo + + infoWithWarningsLinux := sampleInfoNoSwarm + infoWithWarningsLinux.MemoryLimit = false + infoWithWarningsLinux.SwapLimit = false + infoWithWarningsLinux.KernelMemory = false + infoWithWarningsLinux.OomKillDisable = false + infoWithWarningsLinux.CPUCfsQuota = false + infoWithWarningsLinux.CPUCfsPeriod = false + infoWithWarningsLinux.CPUShares = false + infoWithWarningsLinux.CPUSet = false + infoWithWarningsLinux.IPv4Forwarding = false + infoWithWarningsLinux.BridgeNfIptables = false + infoWithWarningsLinux.BridgeNfIP6tables = false + + for _, tc := range []struct { + dockerInfo types.Info + expectedGolden string + warningsGolden string + }{ + { + dockerInfo: sampleInfoNoSwarm, + expectedGolden: "docker-info-no-swarm", + }, + { + dockerInfo: infoWithSwarm, + expectedGolden: "docker-info-with-swarm", + }, + { + dockerInfo: infoWithWarningsLinux, + expectedGolden: "docker-info-no-swarm", + warningsGolden: "docker-info-warnings", + }, + } { + cli := test.NewFakeCli(&fakeClient{}) + assert.NoError(t, prettyPrintInfo(cli, tc.dockerInfo)) + golden.Assert(t, cli.OutBuffer().String(), tc.expectedGolden+".golden") + if tc.warningsGolden != "" { + golden.Assert(t, cli.ErrBuffer().String(), tc.warningsGolden+".golden") + } else { + assert.Equal(t, "", cli.ErrBuffer().String()) + } + } +} diff --git a/cli/command/system/testdata/docker-info-no-swarm.golden b/cli/command/system/testdata/docker-info-no-swarm.golden new file mode 100644 index 0000000000..7a3e966735 --- /dev/null +++ b/cli/command/system/testdata/docker-info-no-swarm.golden @@ -0,0 +1,51 @@ +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 +Security Options: + apparmor + seccomp + Profile: default +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 (client): false +Debug Mode (server): 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 + diff --git a/cli/command/system/testdata/docker-info-warnings.golden b/cli/command/system/testdata/docker-info-warnings.golden new file mode 100644 index 0000000000..a7a4d792b0 --- /dev/null +++ b/cli/command/system/testdata/docker-info-warnings.golden @@ -0,0 +1,11 @@ +WARNING: No memory limit support +WARNING: No swap limit support +WARNING: No kernel memory 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 diff --git a/cli/command/system/testdata/docker-info-with-swarm.golden b/cli/command/system/testdata/docker-info-with-swarm.golden new file mode 100644 index 0000000000..17bb70fa7f --- /dev/null +++ b/cli/command/system/testdata/docker-info-with-swarm.golden @@ -0,0 +1,73 @@ +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: active + NodeID: qo2dfdig9mmxqkawulggepdih + Is Manager: true + ClusterID: 9vs5ygs0gguyyec4iqf2314c0 + Managers: 1 + Nodes: 1 + Orchestration: + Task History Retention Limit: 5 + Raft: + Snapshot Interval: 10000 + Number of Old Snapshots to Retain: 0 + Heartbeat Tick: 1 + Election Tick: 3 + Dispatcher: + Heartbeat Period: 5 seconds + CA Configuration: + Expiry Duration: 3 months + Force Rotate: 0 + Autolock Managers: true + Root Rotation In Progress: false + Node Address: 165.227.107.89 + Manager Addresses: + 165.227.107.89:2377 +Runtimes: runc +Default Runtime: runc +Init Binary: docker-init +containerd version: 6e23458c129b551d5c9871e5174f6b1b7f6d1170 +runc version: 810190ceaa507aa2727d7ae6f4790c76ec150bd2 +init version: 949e6fa +Security Options: + apparmor + seccomp + Profile: default +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 (client): false +Debug Mode (server): 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 +