mirror of https://github.com/docker/cli.git
cli/command/system: add utilities for printing
Adding some utilities to print the output, to keep the linters happier without having to either suppress errors, or ignore them. Perhaps we should consider adding utilities for this on the "command.Streams" outputs. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
1e89037d72
commit
155f7d9e2b
|
@ -108,7 +108,7 @@ func runInfo(cmd *cobra.Command, dockerCli command.Cli, opts *infoOptions) error
|
||||||
} else {
|
} else {
|
||||||
// if a format is provided, print the error, as it may be hidden
|
// if a format is provided, print the error, as it may be hidden
|
||||||
// otherwise if the template doesn't include the ServerErrors field.
|
// otherwise if the template doesn't include the ServerErrors field.
|
||||||
fmt.Fprintln(dockerCli.Err(), err)
|
fprintln(dockerCli.Err(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ func runInfo(cmd *cobra.Command, dockerCli command.Cli, opts *infoOptions) error
|
||||||
info.ClientInfo.APIVersion = dockerCli.CurrentVersion()
|
info.ClientInfo.APIVersion = dockerCli.CurrentVersion()
|
||||||
return prettyPrintInfo(dockerCli, info)
|
return prettyPrintInfo(dockerCli, info)
|
||||||
}
|
}
|
||||||
return formatInfo(dockerCli, info, opts.format)
|
return formatInfo(dockerCli.Out(), info, opts.format)
|
||||||
}
|
}
|
||||||
|
|
||||||
// placeHolders does a rudimentary match for possible placeholders in a
|
// placeHolders does a rudimentary match for possible placeholders in a
|
||||||
|
@ -163,26 +163,26 @@ func needsServerInfo(template string, info info) bool {
|
||||||
func prettyPrintInfo(streams command.Streams, info info) error {
|
func prettyPrintInfo(streams command.Streams, info info) error {
|
||||||
// Only append the platform info if it's not empty, to prevent printing a trailing space.
|
// Only append the platform info if it's not empty, to prevent printing a trailing space.
|
||||||
if p := info.clientPlatform(); p != "" {
|
if p := info.clientPlatform(); p != "" {
|
||||||
_, _ = fmt.Fprintln(streams.Out(), "Client:", p)
|
fprintln(streams.Out(), "Client:", p)
|
||||||
} else {
|
} else {
|
||||||
_, _ = fmt.Fprintln(streams.Out(), "Client:")
|
fprintln(streams.Out(), "Client:")
|
||||||
}
|
}
|
||||||
if info.ClientInfo != nil {
|
if info.ClientInfo != nil {
|
||||||
prettyPrintClientInfo(streams, *info.ClientInfo)
|
prettyPrintClientInfo(streams, *info.ClientInfo)
|
||||||
}
|
}
|
||||||
for _, err := range info.ClientErrors {
|
for _, err := range info.ClientErrors {
|
||||||
fmt.Fprintln(streams.Err(), "ERROR:", err)
|
fprintln(streams.Err(), "ERROR:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(streams.Out())
|
fprintln(streams.Out())
|
||||||
fmt.Fprintln(streams.Out(), "Server:")
|
fprintln(streams.Out(), "Server:")
|
||||||
if info.Info != nil {
|
if info.Info != nil {
|
||||||
for _, err := range prettyPrintServerInfo(streams, &info) {
|
for _, err := range prettyPrintServerInfo(streams, &info) {
|
||||||
info.ServerErrors = append(info.ServerErrors, err.Error())
|
info.ServerErrors = append(info.ServerErrors, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, err := range info.ServerErrors {
|
for _, err := range info.ServerErrors {
|
||||||
fmt.Fprintln(streams.Err(), "ERROR:", err)
|
fprintln(streams.Err(), "ERROR:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(info.ServerErrors) > 0 || len(info.ClientErrors) > 0 {
|
if len(info.ServerErrors) > 0 || len(info.ClientErrors) > 0 {
|
||||||
|
@ -192,18 +192,17 @@ func prettyPrintInfo(streams command.Streams, info info) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func prettyPrintClientInfo(streams command.Streams, info clientInfo) {
|
func prettyPrintClientInfo(streams command.Streams, info clientInfo) {
|
||||||
output := streams.Out()
|
fprintlnNonEmpty(streams.Out(), " Version: ", info.Version)
|
||||||
fprintlnNonEmpty(output, " Version: ", info.Version)
|
fprintln(streams.Out(), " Context: ", info.Context)
|
||||||
fmt.Fprintln(output, " Context: ", info.Context)
|
fprintln(streams.Out(), " Debug Mode:", info.Debug)
|
||||||
fmt.Fprintln(output, " Debug Mode:", info.Debug)
|
|
||||||
|
|
||||||
if len(info.Plugins) > 0 {
|
if len(info.Plugins) > 0 {
|
||||||
fmt.Fprintln(output, " Plugins:")
|
fprintln(streams.Out(), " Plugins:")
|
||||||
for _, p := range info.Plugins {
|
for _, p := range info.Plugins {
|
||||||
if p.Err == nil {
|
if p.Err == nil {
|
||||||
fmt.Fprintf(output, " %s: %s (%s)\n", p.Name, p.ShortDescription, p.Vendor)
|
fprintf(streams.Out(), " %s: %s (%s)\n", p.Name, p.ShortDescription, p.Vendor)
|
||||||
fprintlnNonEmpty(output, " Version: ", p.Version)
|
fprintlnNonEmpty(streams.Out(), " Version: ", p.Version)
|
||||||
fprintlnNonEmpty(output, " Path: ", p.Path)
|
fprintlnNonEmpty(streams.Out(), " Path: ", p.Path)
|
||||||
} else {
|
} else {
|
||||||
info.Warnings = append(info.Warnings, fmt.Sprintf("WARNING: Plugin %q is not valid: %s", p.Path, p.Err))
|
info.Warnings = append(info.Warnings, fmt.Sprintf("WARNING: Plugin %q is not valid: %s", p.Path, p.Err))
|
||||||
}
|
}
|
||||||
|
@ -211,7 +210,7 @@ func prettyPrintClientInfo(streams command.Streams, info clientInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(info.Warnings) > 0 {
|
if len(info.Warnings) > 0 {
|
||||||
fmt.Fprintln(streams.Err(), strings.Join(info.Warnings, "\n"))
|
fprintln(streams.Err(), strings.Join(info.Warnings, "\n"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,38 +219,38 @@ func prettyPrintServerInfo(streams command.Streams, info *info) []error {
|
||||||
var errs []error
|
var errs []error
|
||||||
output := streams.Out()
|
output := streams.Out()
|
||||||
|
|
||||||
fmt.Fprintln(output, " Containers:", info.Containers)
|
fprintln(output, " Containers:", info.Containers)
|
||||||
fmt.Fprintln(output, " Running:", info.ContainersRunning)
|
fprintln(output, " Running:", info.ContainersRunning)
|
||||||
fmt.Fprintln(output, " Paused:", info.ContainersPaused)
|
fprintln(output, " Paused:", info.ContainersPaused)
|
||||||
fmt.Fprintln(output, " Stopped:", info.ContainersStopped)
|
fprintln(output, " Stopped:", info.ContainersStopped)
|
||||||
fmt.Fprintln(output, " Images:", info.Images)
|
fprintln(output, " Images:", info.Images)
|
||||||
fprintlnNonEmpty(output, " Server Version:", info.ServerVersion)
|
fprintlnNonEmpty(output, " Server Version:", info.ServerVersion)
|
||||||
fprintlnNonEmpty(output, " Storage Driver:", info.Driver)
|
fprintlnNonEmpty(output, " Storage Driver:", info.Driver)
|
||||||
if info.DriverStatus != nil {
|
if info.DriverStatus != nil {
|
||||||
for _, pair := range info.DriverStatus {
|
for _, pair := range info.DriverStatus {
|
||||||
fmt.Fprintf(output, " %s: %s\n", pair[0], pair[1])
|
fprintf(output, " %s: %s\n", pair[0], pair[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if info.SystemStatus != nil {
|
if info.SystemStatus != nil {
|
||||||
for _, pair := range info.SystemStatus {
|
for _, pair := range info.SystemStatus {
|
||||||
fmt.Fprintf(output, " %s: %s\n", pair[0], pair[1])
|
fprintf(output, " %s: %s\n", pair[0], pair[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintlnNonEmpty(output, " Logging Driver:", info.LoggingDriver)
|
fprintlnNonEmpty(output, " Logging Driver:", info.LoggingDriver)
|
||||||
fprintlnNonEmpty(output, " Cgroup Driver:", info.CgroupDriver)
|
fprintlnNonEmpty(output, " Cgroup Driver:", info.CgroupDriver)
|
||||||
fprintlnNonEmpty(output, " Cgroup Version:", info.CgroupVersion)
|
fprintlnNonEmpty(output, " Cgroup Version:", info.CgroupVersion)
|
||||||
|
|
||||||
fmt.Fprintln(output, " Plugins:")
|
fprintln(output, " Plugins:")
|
||||||
fmt.Fprintln(output, " Volume:", strings.Join(info.Plugins.Volume, " "))
|
fprintln(output, " Volume:", strings.Join(info.Plugins.Volume, " "))
|
||||||
fmt.Fprintln(output, " Network:", strings.Join(info.Plugins.Network, " "))
|
fprintln(output, " Network:", strings.Join(info.Plugins.Network, " "))
|
||||||
|
|
||||||
if len(info.Plugins.Authorization) != 0 {
|
if len(info.Plugins.Authorization) != 0 {
|
||||||
fmt.Fprintln(output, " Authorization:", strings.Join(info.Plugins.Authorization, " "))
|
fprintln(output, " Authorization:", strings.Join(info.Plugins.Authorization, " "))
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(output, " Log:", strings.Join(info.Plugins.Log, " "))
|
fprintln(output, " Log:", strings.Join(info.Plugins.Log, " "))
|
||||||
|
|
||||||
fmt.Fprintln(output, " Swarm:", info.Swarm.LocalNodeState)
|
fprintln(output, " Swarm:", info.Swarm.LocalNodeState)
|
||||||
printSwarmInfo(output, *info.Info)
|
printSwarmInfo(output, *info.Info)
|
||||||
|
|
||||||
if len(info.Runtimes) > 0 {
|
if len(info.Runtimes) > 0 {
|
||||||
|
@ -259,12 +258,12 @@ func prettyPrintServerInfo(streams command.Streams, info *info) []error {
|
||||||
for name := range info.Runtimes {
|
for name := range info.Runtimes {
|
||||||
names = append(names, name)
|
names = append(names, name)
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output, " Runtimes:", strings.Join(names, " "))
|
fprintln(output, " Runtimes:", strings.Join(names, " "))
|
||||||
fmt.Fprintln(output, " Default Runtime:", info.DefaultRuntime)
|
fprintln(output, " Default Runtime:", info.DefaultRuntime)
|
||||||
}
|
}
|
||||||
|
|
||||||
if info.OSType == "linux" {
|
if info.OSType == "linux" {
|
||||||
fmt.Fprintln(output, " Init Binary:", info.InitBinary)
|
fprintln(output, " Init Binary:", info.InitBinary)
|
||||||
|
|
||||||
for _, ci := range []struct {
|
for _, ci := range []struct {
|
||||||
Name string
|
Name string
|
||||||
|
@ -274,23 +273,23 @@ func prettyPrintServerInfo(streams command.Streams, info *info) []error {
|
||||||
{"runc", info.RuncCommit},
|
{"runc", info.RuncCommit},
|
||||||
{"init", info.InitCommit},
|
{"init", info.InitCommit},
|
||||||
} {
|
} {
|
||||||
fmt.Fprintf(output, " %s version: %s", ci.Name, ci.Commit.ID)
|
fprintf(output, " %s version: %s", ci.Name, ci.Commit.ID)
|
||||||
if ci.Commit.ID != ci.Commit.Expected {
|
if ci.Commit.ID != ci.Commit.Expected {
|
||||||
fmt.Fprintf(output, " (expected: %s)", ci.Commit.Expected)
|
fprintf(output, " (expected: %s)", ci.Commit.Expected)
|
||||||
}
|
}
|
||||||
fmt.Fprint(output, "\n")
|
fprintln(output)
|
||||||
}
|
}
|
||||||
if len(info.SecurityOptions) != 0 {
|
if len(info.SecurityOptions) != 0 {
|
||||||
if kvs, err := types.DecodeSecurityOptions(info.SecurityOptions); err != nil {
|
if kvs, err := types.DecodeSecurityOptions(info.SecurityOptions); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintln(output, " Security Options:")
|
fprintln(output, " Security Options:")
|
||||||
for _, so := range kvs {
|
for _, so := range kvs {
|
||||||
fmt.Fprintln(output, " "+so.Name)
|
fprintln(output, " "+so.Name)
|
||||||
for _, o := range so.Options {
|
for _, o := range so.Options {
|
||||||
switch o.Key {
|
switch o.Key {
|
||||||
case "profile":
|
case "profile":
|
||||||
fmt.Fprintln(output, " Profile:", o.Value)
|
fprintln(output, " Profile:", o.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -300,25 +299,25 @@ func prettyPrintServerInfo(streams command.Streams, info *info) []error {
|
||||||
|
|
||||||
// Isolation only has meaning on a Windows daemon.
|
// Isolation only has meaning on a Windows daemon.
|
||||||
if info.OSType == "windows" {
|
if info.OSType == "windows" {
|
||||||
fmt.Fprintln(output, " Default Isolation:", info.Isolation)
|
fprintln(output, " Default Isolation:", info.Isolation)
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintlnNonEmpty(output, " Kernel Version:", info.KernelVersion)
|
fprintlnNonEmpty(output, " Kernel Version:", info.KernelVersion)
|
||||||
fprintlnNonEmpty(output, " Operating System:", info.OperatingSystem)
|
fprintlnNonEmpty(output, " Operating System:", info.OperatingSystem)
|
||||||
fprintlnNonEmpty(output, " OSType:", info.OSType)
|
fprintlnNonEmpty(output, " OSType:", info.OSType)
|
||||||
fprintlnNonEmpty(output, " Architecture:", info.Architecture)
|
fprintlnNonEmpty(output, " Architecture:", info.Architecture)
|
||||||
fmt.Fprintln(output, " CPUs:", info.NCPU)
|
fprintln(output, " CPUs:", info.NCPU)
|
||||||
fmt.Fprintln(output, " Total Memory:", units.BytesSize(float64(info.MemTotal)))
|
fprintln(output, " Total Memory:", units.BytesSize(float64(info.MemTotal)))
|
||||||
fprintlnNonEmpty(output, " Name:", info.Name)
|
fprintlnNonEmpty(output, " Name:", info.Name)
|
||||||
fprintlnNonEmpty(output, " ID:", info.ID)
|
fprintlnNonEmpty(output, " ID:", info.ID)
|
||||||
fmt.Fprintln(output, " Docker Root Dir:", info.DockerRootDir)
|
fprintln(output, " Docker Root Dir:", info.DockerRootDir)
|
||||||
fmt.Fprintln(output, " Debug Mode:", info.Debug)
|
fprintln(output, " Debug Mode:", info.Debug)
|
||||||
|
|
||||||
if info.Debug {
|
if info.Debug {
|
||||||
fmt.Fprintln(output, " File Descriptors:", info.NFd)
|
fprintln(output, " File Descriptors:", info.NFd)
|
||||||
fmt.Fprintln(output, " Goroutines:", info.NGoroutines)
|
fprintln(output, " Goroutines:", info.NGoroutines)
|
||||||
fmt.Fprintln(output, " System Time:", info.SystemTime)
|
fprintln(output, " System Time:", info.SystemTime)
|
||||||
fmt.Fprintln(output, " EventsListeners:", info.NEventsListener)
|
fprintln(output, " EventsListeners:", info.NEventsListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintlnNonEmpty(output, " HTTP Proxy:", info.HTTPProxy)
|
fprintlnNonEmpty(output, " HTTP Proxy:", info.HTTPProxy)
|
||||||
|
@ -326,48 +325,48 @@ func prettyPrintServerInfo(streams command.Streams, info *info) []error {
|
||||||
fprintlnNonEmpty(output, " No Proxy:", info.NoProxy)
|
fprintlnNonEmpty(output, " No Proxy:", info.NoProxy)
|
||||||
fprintlnNonEmpty(output, " Username:", info.UserName)
|
fprintlnNonEmpty(output, " Username:", info.UserName)
|
||||||
if len(info.Labels) > 0 {
|
if len(info.Labels) > 0 {
|
||||||
fmt.Fprintln(output, " Labels:")
|
fprintln(output, " Labels:")
|
||||||
for _, lbl := range info.Labels {
|
for _, lbl := range info.Labels {
|
||||||
fmt.Fprintln(output, " "+lbl)
|
fprintln(output, " "+lbl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(output, " Experimental:", info.ExperimentalBuild)
|
fprintln(output, " Experimental:", info.ExperimentalBuild)
|
||||||
|
|
||||||
if info.RegistryConfig != nil && (len(info.RegistryConfig.InsecureRegistryCIDRs) > 0 || len(info.RegistryConfig.IndexConfigs) > 0) {
|
if info.RegistryConfig != nil && (len(info.RegistryConfig.InsecureRegistryCIDRs) > 0 || len(info.RegistryConfig.IndexConfigs) > 0) {
|
||||||
fmt.Fprintln(output, " Insecure Registries:")
|
fprintln(output, " Insecure Registries:")
|
||||||
for _, reg := range info.RegistryConfig.IndexConfigs {
|
for _, registryConfig := range info.RegistryConfig.IndexConfigs {
|
||||||
if !reg.Secure {
|
if !registryConfig.Secure {
|
||||||
fmt.Fprintln(output, " "+reg.Name)
|
fprintln(output, " "+registryConfig.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, reg := range info.RegistryConfig.InsecureRegistryCIDRs {
|
for _, registryConfig := range info.RegistryConfig.InsecureRegistryCIDRs {
|
||||||
mask, _ := reg.Mask.Size()
|
mask, _ := registryConfig.Mask.Size()
|
||||||
fmt.Fprintf(output, " %s/%d\n", reg.IP.String(), mask)
|
fprintf(output, " %s/%d\n", registryConfig.IP.String(), mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if info.RegistryConfig != nil && len(info.RegistryConfig.Mirrors) > 0 {
|
if info.RegistryConfig != nil && len(info.RegistryConfig.Mirrors) > 0 {
|
||||||
fmt.Fprintln(output, " Registry Mirrors:")
|
fprintln(output, " Registry Mirrors:")
|
||||||
for _, mirror := range info.RegistryConfig.Mirrors {
|
for _, mirror := range info.RegistryConfig.Mirrors {
|
||||||
fmt.Fprintln(output, " "+mirror)
|
fprintln(output, " "+mirror)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(output, " Live Restore Enabled:", info.LiveRestoreEnabled)
|
fprintln(output, " Live Restore Enabled:", info.LiveRestoreEnabled)
|
||||||
if info.ProductLicense != "" {
|
if info.ProductLicense != "" {
|
||||||
fmt.Fprintln(output, " Product License:", info.ProductLicense)
|
fprintln(output, " Product License:", info.ProductLicense)
|
||||||
}
|
}
|
||||||
|
|
||||||
if info.DefaultAddressPools != nil && len(info.DefaultAddressPools) > 0 {
|
if info.DefaultAddressPools != nil && len(info.DefaultAddressPools) > 0 {
|
||||||
fmt.Fprintln(output, " Default Address Pools:")
|
fprintln(output, " Default Address Pools:")
|
||||||
for _, pool := range info.DefaultAddressPools {
|
for _, pool := range info.DefaultAddressPools {
|
||||||
fmt.Fprintf(output, " Base: %s, Size: %d\n", pool.Base, pool.Size)
|
fprintf(output, " Base: %s, Size: %d\n", pool.Base, pool.Size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprint(output, "\n")
|
fprintln(output)
|
||||||
printServerWarnings(streams.Err(), info)
|
printServerWarnings(streams.Err(), info)
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
@ -377,67 +376,67 @@ func printSwarmInfo(output io.Writer, info types.Info) {
|
||||||
if info.Swarm.LocalNodeState == swarm.LocalNodeStateInactive || info.Swarm.LocalNodeState == swarm.LocalNodeStateLocked {
|
if info.Swarm.LocalNodeState == swarm.LocalNodeStateInactive || info.Swarm.LocalNodeState == swarm.LocalNodeStateLocked {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output, " NodeID:", info.Swarm.NodeID)
|
fprintln(output, " NodeID:", info.Swarm.NodeID)
|
||||||
if info.Swarm.Error != "" {
|
if info.Swarm.Error != "" {
|
||||||
fmt.Fprintln(output, " Error:", info.Swarm.Error)
|
fprintln(output, " Error:", info.Swarm.Error)
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output, " Is Manager:", info.Swarm.ControlAvailable)
|
fprintln(output, " Is Manager:", info.Swarm.ControlAvailable)
|
||||||
if info.Swarm.Cluster != nil && info.Swarm.ControlAvailable && info.Swarm.Error == "" && info.Swarm.LocalNodeState != swarm.LocalNodeStateError {
|
if info.Swarm.Cluster != nil && info.Swarm.ControlAvailable && info.Swarm.Error == "" && info.Swarm.LocalNodeState != swarm.LocalNodeStateError {
|
||||||
fmt.Fprintln(output, " ClusterID:", info.Swarm.Cluster.ID)
|
fprintln(output, " ClusterID:", info.Swarm.Cluster.ID)
|
||||||
fmt.Fprintln(output, " Managers:", info.Swarm.Managers)
|
fprintln(output, " Managers:", info.Swarm.Managers)
|
||||||
fmt.Fprintln(output, " Nodes:", info.Swarm.Nodes)
|
fprintln(output, " Nodes:", info.Swarm.Nodes)
|
||||||
var strAddrPool strings.Builder
|
var strAddrPool strings.Builder
|
||||||
if info.Swarm.Cluster.DefaultAddrPool != nil {
|
if info.Swarm.Cluster.DefaultAddrPool != nil {
|
||||||
for _, p := range info.Swarm.Cluster.DefaultAddrPool {
|
for _, p := range info.Swarm.Cluster.DefaultAddrPool {
|
||||||
strAddrPool.WriteString(p + " ")
|
strAddrPool.WriteString(p + " ")
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output, " Default Address Pool:", strAddrPool.String())
|
fprintln(output, " Default Address Pool:", strAddrPool.String())
|
||||||
fmt.Fprintln(output, " SubnetSize:", info.Swarm.Cluster.SubnetSize)
|
fprintln(output, " SubnetSize:", info.Swarm.Cluster.SubnetSize)
|
||||||
}
|
}
|
||||||
if info.Swarm.Cluster.DataPathPort > 0 {
|
if info.Swarm.Cluster.DataPathPort > 0 {
|
||||||
fmt.Fprintln(output, " Data Path Port:", info.Swarm.Cluster.DataPathPort)
|
fprintln(output, " Data Path Port:", info.Swarm.Cluster.DataPathPort)
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output, " Orchestration:")
|
fprintln(output, " Orchestration:")
|
||||||
|
|
||||||
taskHistoryRetentionLimit := int64(0)
|
taskHistoryRetentionLimit := int64(0)
|
||||||
if info.Swarm.Cluster.Spec.Orchestration.TaskHistoryRetentionLimit != nil {
|
if info.Swarm.Cluster.Spec.Orchestration.TaskHistoryRetentionLimit != nil {
|
||||||
taskHistoryRetentionLimit = *info.Swarm.Cluster.Spec.Orchestration.TaskHistoryRetentionLimit
|
taskHistoryRetentionLimit = *info.Swarm.Cluster.Spec.Orchestration.TaskHistoryRetentionLimit
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output, " Task History Retention Limit:", taskHistoryRetentionLimit)
|
fprintln(output, " Task History Retention Limit:", taskHistoryRetentionLimit)
|
||||||
fmt.Fprintln(output, " Raft:")
|
fprintln(output, " Raft:")
|
||||||
fmt.Fprintln(output, " Snapshot Interval:", info.Swarm.Cluster.Spec.Raft.SnapshotInterval)
|
fprintln(output, " Snapshot Interval:", info.Swarm.Cluster.Spec.Raft.SnapshotInterval)
|
||||||
if info.Swarm.Cluster.Spec.Raft.KeepOldSnapshots != nil {
|
if info.Swarm.Cluster.Spec.Raft.KeepOldSnapshots != nil {
|
||||||
fmt.Fprintf(output, " Number of Old Snapshots to Retain: %d\n", *info.Swarm.Cluster.Spec.Raft.KeepOldSnapshots)
|
fprintf(output, " Number of Old Snapshots to Retain: %d\n", *info.Swarm.Cluster.Spec.Raft.KeepOldSnapshots)
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output, " Heartbeat Tick:", info.Swarm.Cluster.Spec.Raft.HeartbeatTick)
|
fprintln(output, " Heartbeat Tick:", info.Swarm.Cluster.Spec.Raft.HeartbeatTick)
|
||||||
fmt.Fprintln(output, " Election Tick:", info.Swarm.Cluster.Spec.Raft.ElectionTick)
|
fprintln(output, " Election Tick:", info.Swarm.Cluster.Spec.Raft.ElectionTick)
|
||||||
fmt.Fprintln(output, " Dispatcher:")
|
fprintln(output, " Dispatcher:")
|
||||||
fmt.Fprintln(output, " Heartbeat Period:", units.HumanDuration(info.Swarm.Cluster.Spec.Dispatcher.HeartbeatPeriod))
|
fprintln(output, " Heartbeat Period:", units.HumanDuration(info.Swarm.Cluster.Spec.Dispatcher.HeartbeatPeriod))
|
||||||
fmt.Fprintln(output, " CA Configuration:")
|
fprintln(output, " CA Configuration:")
|
||||||
fmt.Fprintln(output, " Expiry Duration:", units.HumanDuration(info.Swarm.Cluster.Spec.CAConfig.NodeCertExpiry))
|
fprintln(output, " Expiry Duration:", units.HumanDuration(info.Swarm.Cluster.Spec.CAConfig.NodeCertExpiry))
|
||||||
fmt.Fprintln(output, " Force Rotate:", info.Swarm.Cluster.Spec.CAConfig.ForceRotate)
|
fprintln(output, " Force Rotate:", info.Swarm.Cluster.Spec.CAConfig.ForceRotate)
|
||||||
if caCert := strings.TrimSpace(info.Swarm.Cluster.Spec.CAConfig.SigningCACert); caCert != "" {
|
if caCert := strings.TrimSpace(info.Swarm.Cluster.Spec.CAConfig.SigningCACert); caCert != "" {
|
||||||
fmt.Fprintf(output, " Signing CA Certificate: \n%s\n\n", caCert)
|
fprintf(output, " Signing CA Certificate: \n%s\n\n", caCert)
|
||||||
}
|
}
|
||||||
if len(info.Swarm.Cluster.Spec.CAConfig.ExternalCAs) > 0 {
|
if len(info.Swarm.Cluster.Spec.CAConfig.ExternalCAs) > 0 {
|
||||||
fmt.Fprintln(output, " External CAs:")
|
fprintln(output, " External CAs:")
|
||||||
for _, entry := range info.Swarm.Cluster.Spec.CAConfig.ExternalCAs {
|
for _, entry := range info.Swarm.Cluster.Spec.CAConfig.ExternalCAs {
|
||||||
fmt.Fprintf(output, " %s: %s\n", entry.Protocol, entry.URL)
|
fprintf(output, " %s: %s\n", entry.Protocol, entry.URL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output, " Autolock Managers:", info.Swarm.Cluster.Spec.EncryptionConfig.AutoLockManagers)
|
fprintln(output, " Autolock Managers:", info.Swarm.Cluster.Spec.EncryptionConfig.AutoLockManagers)
|
||||||
fmt.Fprintln(output, " Root Rotation In Progress:", info.Swarm.Cluster.RootRotationInProgress)
|
fprintln(output, " Root Rotation In Progress:", info.Swarm.Cluster.RootRotationInProgress)
|
||||||
}
|
}
|
||||||
fmt.Fprintln(output, " Node Address:", info.Swarm.NodeAddr)
|
fprintln(output, " Node Address:", info.Swarm.NodeAddr)
|
||||||
if len(info.Swarm.RemoteManagers) > 0 {
|
if len(info.Swarm.RemoteManagers) > 0 {
|
||||||
managers := []string{}
|
managers := []string{}
|
||||||
for _, entry := range info.Swarm.RemoteManagers {
|
for _, entry := range info.Swarm.RemoteManagers {
|
||||||
managers = append(managers, entry.Addr)
|
managers = append(managers, entry.Addr)
|
||||||
}
|
}
|
||||||
sort.Strings(managers)
|
sort.Strings(managers)
|
||||||
fmt.Fprintln(output, " Manager Addresses:")
|
fprintln(output, " Manager Addresses:")
|
||||||
for _, entry := range managers {
|
for _, entry := range managers {
|
||||||
fmt.Fprintf(output, " %s\n", entry)
|
fprintf(output, " %s\n", entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -447,7 +446,7 @@ func printServerWarnings(stdErr io.Writer, info *info) {
|
||||||
printSecurityOptionsWarnings(stdErr, *info.Info)
|
printSecurityOptionsWarnings(stdErr, *info.Info)
|
||||||
}
|
}
|
||||||
if len(info.Warnings) > 0 {
|
if len(info.Warnings) > 0 {
|
||||||
fmt.Fprintln(stdErr, strings.Join(info.Warnings, "\n"))
|
fprintln(stdErr, strings.Join(info.Warnings, "\n"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// daemon didn't return warnings. Fallback to old behavior
|
// daemon didn't return warnings. Fallback to old behavior
|
||||||
|
@ -487,38 +486,38 @@ func printServerWarningsLegacy(stdErr io.Writer, info types.Info) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !info.MemoryLimit {
|
if !info.MemoryLimit {
|
||||||
fmt.Fprintln(stdErr, "WARNING: No memory limit support")
|
fprintln(stdErr, "WARNING: No memory limit support")
|
||||||
}
|
}
|
||||||
if !info.SwapLimit {
|
if !info.SwapLimit {
|
||||||
fmt.Fprintln(stdErr, "WARNING: No swap limit support")
|
fprintln(stdErr, "WARNING: No swap limit support")
|
||||||
}
|
}
|
||||||
if !info.OomKillDisable && info.CgroupVersion != "2" {
|
if !info.OomKillDisable && info.CgroupVersion != "2" {
|
||||||
fmt.Fprintln(stdErr, "WARNING: No oom kill disable support")
|
fprintln(stdErr, "WARNING: No oom kill disable support")
|
||||||
}
|
}
|
||||||
if !info.CPUCfsQuota {
|
if !info.CPUCfsQuota {
|
||||||
fmt.Fprintln(stdErr, "WARNING: No cpu cfs quota support")
|
fprintln(stdErr, "WARNING: No cpu cfs quota support")
|
||||||
}
|
}
|
||||||
if !info.CPUCfsPeriod {
|
if !info.CPUCfsPeriod {
|
||||||
fmt.Fprintln(stdErr, "WARNING: No cpu cfs period support")
|
fprintln(stdErr, "WARNING: No cpu cfs period support")
|
||||||
}
|
}
|
||||||
if !info.CPUShares {
|
if !info.CPUShares {
|
||||||
fmt.Fprintln(stdErr, "WARNING: No cpu shares support")
|
fprintln(stdErr, "WARNING: No cpu shares support")
|
||||||
}
|
}
|
||||||
if !info.CPUSet {
|
if !info.CPUSet {
|
||||||
fmt.Fprintln(stdErr, "WARNING: No cpuset support")
|
fprintln(stdErr, "WARNING: No cpuset support")
|
||||||
}
|
}
|
||||||
if !info.IPv4Forwarding {
|
if !info.IPv4Forwarding {
|
||||||
fmt.Fprintln(stdErr, "WARNING: IPv4 forwarding is disabled")
|
fprintln(stdErr, "WARNING: IPv4 forwarding is disabled")
|
||||||
}
|
}
|
||||||
if !info.BridgeNfIptables {
|
if !info.BridgeNfIptables {
|
||||||
fmt.Fprintln(stdErr, "WARNING: bridge-nf-call-iptables is disabled")
|
fprintln(stdErr, "WARNING: bridge-nf-call-iptables is disabled")
|
||||||
}
|
}
|
||||||
if !info.BridgeNfIP6tables {
|
if !info.BridgeNfIP6tables {
|
||||||
fmt.Fprintln(stdErr, "WARNING: bridge-nf-call-ip6tables is disabled")
|
fprintln(stdErr, "WARNING: bridge-nf-call-ip6tables is disabled")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatInfo(dockerCli command.Cli, info info, format string) error {
|
func formatInfo(output io.Writer, info info, format string) error {
|
||||||
if format == formatter.JSONFormatKey {
|
if format == formatter.JSONFormatKey {
|
||||||
format = formatter.JSONFormat
|
format = formatter.JSONFormat
|
||||||
}
|
}
|
||||||
|
@ -535,13 +534,21 @@ func formatInfo(dockerCli command.Cli, info info, format string) error {
|
||||||
Status: "template parsing error: " + err.Error(),
|
Status: "template parsing error: " + err.Error(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = tmpl.Execute(dockerCli.Out(), info)
|
err = tmpl.Execute(output, info)
|
||||||
dockerCli.Out().Write([]byte{'\n'})
|
fprintln(output)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fprintf(w io.Writer, format string, a ...any) {
|
||||||
|
_, _ = fmt.Fprintf(w, format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fprintln(w io.Writer, a ...any) {
|
||||||
|
_, _ = fmt.Fprintln(w, a...)
|
||||||
|
}
|
||||||
|
|
||||||
func fprintlnNonEmpty(w io.Writer, label, value string) {
|
func fprintlnNonEmpty(w io.Writer, label, value string) {
|
||||||
if value != "" {
|
if value != "" {
|
||||||
fmt.Fprintln(w, label, value)
|
_, _ = fmt.Fprintln(w, label, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -406,12 +406,12 @@ func TestPrettyPrintInfo(t *testing.T) {
|
||||||
|
|
||||||
if tc.jsonGolden != "" {
|
if tc.jsonGolden != "" {
|
||||||
cli = test.NewFakeCli(&fakeClient{})
|
cli = test.NewFakeCli(&fakeClient{})
|
||||||
assert.NilError(t, formatInfo(cli, tc.dockerInfo, "{{json .}}"))
|
assert.NilError(t, formatInfo(cli.Out(), tc.dockerInfo, "{{json .}}"))
|
||||||
golden.Assert(t, cli.OutBuffer().String(), tc.jsonGolden+".json.golden")
|
golden.Assert(t, cli.OutBuffer().String(), tc.jsonGolden+".json.golden")
|
||||||
assert.Check(t, is.Equal("", cli.ErrBuffer().String()))
|
assert.Check(t, is.Equal("", cli.ErrBuffer().String()))
|
||||||
|
|
||||||
cli = test.NewFakeCli(&fakeClient{})
|
cli = test.NewFakeCli(&fakeClient{})
|
||||||
assert.NilError(t, formatInfo(cli, tc.dockerInfo, "json"))
|
assert.NilError(t, formatInfo(cli.Out(), tc.dockerInfo, "json"))
|
||||||
golden.Assert(t, cli.OutBuffer().String(), tc.jsonGolden+".json.golden")
|
golden.Assert(t, cli.OutBuffer().String(), tc.jsonGolden+".json.golden")
|
||||||
assert.Check(t, is.Equal("", cli.ErrBuffer().String()))
|
assert.Check(t, is.Equal("", cli.ErrBuffer().String()))
|
||||||
}
|
}
|
||||||
|
@ -473,7 +473,7 @@ func TestFormatInfo(t *testing.T) {
|
||||||
Info: &sampleInfoNoSwarm,
|
Info: &sampleInfoNoSwarm,
|
||||||
ClientInfo: &clientInfo{Debug: true},
|
ClientInfo: &clientInfo{Debug: true},
|
||||||
}
|
}
|
||||||
err := formatInfo(cli, info, tc.template)
|
err := formatInfo(cli.Out(), info, tc.template)
|
||||||
if tc.expectedOut != "" {
|
if tc.expectedOut != "" {
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, cli.OutBuffer().String(), tc.expectedOut)
|
assert.Equal(t, cli.OutBuffer().String(), tc.expectedOut)
|
||||||
|
|
Loading…
Reference in New Issue