2015-03-25 03:57:23 +00:00
package client
import (
"fmt"
2015-12-29 21:10:23 +00:00
"strings"
2015-03-25 03:57:23 +00:00
2016-03-16 19:19:22 +00:00
"golang.org/x/net/context"
2015-05-05 04:18:28 +00:00
Cli "github.com/docker/docker/cli"
2015-05-29 23:48:02 +00:00
"github.com/docker/docker/pkg/ioutils"
2015-03-25 03:57:23 +00:00
flag "github.com/docker/docker/pkg/mflag"
2016-02-01 23:09:25 +00:00
"github.com/docker/docker/utils"
2015-12-16 17:26:49 +00:00
"github.com/docker/go-units"
2015-03-25 03:57:23 +00:00
)
2015-03-25 17:34:41 +00:00
// CmdInfo displays system-wide information.
//
// Usage: docker info
2015-03-25 03:57:23 +00:00
func ( cli * DockerCli ) CmdInfo ( args ... string ) error {
2015-10-08 12:46:21 +00:00
cmd := Cli . Subcmd ( "info" , nil , Cli . DockerCommands [ "info" ] . Description , true )
2015-03-25 03:57:23 +00:00
cmd . Require ( flag . Exact , 0 )
2015-07-03 09:26:09 +00:00
2015-05-23 15:57:50 +00:00
cmd . ParseFlags ( args , true )
2015-03-25 03:57:23 +00:00
2016-03-16 19:19:22 +00:00
info , err := cli . client . Info ( context . Background ( ) )
2015-03-25 03:57:23 +00:00
if err != nil {
return err
}
2015-04-10 17:26:30 +00:00
fmt . Fprintf ( cli . out , "Containers: %d\n" , info . Containers )
2015-10-27 20:12:33 +00:00
fmt . Fprintf ( cli . out , " Running: %d\n" , info . ContainersRunning )
fmt . Fprintf ( cli . out , " Paused: %d\n" , info . ContainersPaused )
fmt . Fprintf ( cli . out , " Stopped: %d\n" , info . ContainersStopped )
2015-04-10 17:26:30 +00:00
fmt . Fprintf ( cli . out , "Images: %d\n" , info . Images )
2015-10-15 00:24:13 +00:00
ioutils . FprintfIfNotEmpty ( cli . out , "Server Version: %s\n" , info . ServerVersion )
2015-05-29 23:48:02 +00:00
ioutils . FprintfIfNotEmpty ( cli . out , "Storage Driver: %s\n" , info . Driver )
2015-04-10 17:26:30 +00:00
if info . DriverStatus != nil {
for _ , pair := range info . DriverStatus {
2015-03-25 03:57:23 +00:00
fmt . Fprintf ( cli . out , " %s: %s\n" , pair [ 0 ] , pair [ 1 ] )
2015-12-10 07:58:02 +00:00
// print a warning if devicemapper is using a loopback file
if pair [ 0 ] == "Data loop file" {
2015-12-11 19:23:16 +00:00
fmt . Fprintln ( cli . err , " WARNING: Usage of loopback devices is strongly discouraged for production use. Either use `--storage-opt dm.thinpooldev` or use `--storage-opt dm.no_warn_on_loop_devices=true` to suppress this warning." )
2015-12-10 07:58:02 +00:00
}
2015-03-25 03:57:23 +00:00
}
2015-12-10 07:58:02 +00:00
2015-03-25 03:57:23 +00:00
}
2016-01-24 21:30:21 +00:00
if info . SystemStatus != nil {
for _ , pair := range info . SystemStatus {
fmt . Fprintf ( cli . out , "%s: %s\n" , pair [ 0 ] , pair [ 1 ] )
}
}
2015-05-29 23:48:02 +00:00
ioutils . FprintfIfNotEmpty ( cli . out , "Execution Driver: %s\n" , info . ExecutionDriver )
ioutils . FprintfIfNotEmpty ( cli . out , "Logging Driver: %s\n" , info . LoggingDriver )
2016-02-18 10:10:31 +00:00
ioutils . FprintfIfNotEmpty ( cli . out , "Cgroup Driver: %s\n" , info . CgroupDriver )
2015-10-23 06:08:26 +00:00
fmt . Fprintf ( cli . out , "Plugins: \n" )
fmt . Fprintf ( cli . out , " Volume:" )
2015-12-29 21:10:23 +00:00
fmt . Fprintf ( cli . out , " %s" , strings . Join ( info . Plugins . Volume , " " ) )
2015-10-23 06:08:26 +00:00
fmt . Fprintf ( cli . out , "\n" )
fmt . Fprintf ( cli . out , " Network:" )
2015-12-29 21:10:23 +00:00
fmt . Fprintf ( cli . out , " %s" , strings . Join ( info . Plugins . Network , " " ) )
2015-10-23 06:08:26 +00:00
fmt . Fprintf ( cli . out , "\n" )
2015-12-29 21:10:23 +00:00
if len ( info . Plugins . Authorization ) != 0 {
fmt . Fprintf ( cli . out , " Authorization:" )
fmt . Fprintf ( cli . out , " %s" , strings . Join ( info . Plugins . Authorization , " " ) )
fmt . Fprintf ( cli . out , "\n" )
}
2015-05-29 23:48:02 +00:00
ioutils . FprintfIfNotEmpty ( cli . out , "Kernel Version: %s\n" , info . KernelVersion )
ioutils . FprintfIfNotEmpty ( cli . out , "Operating System: %s\n" , info . OperatingSystem )
2015-06-13 07:39:19 +00:00
ioutils . FprintfIfNotEmpty ( cli . out , "OSType: %s\n" , info . OSType )
ioutils . FprintfIfNotEmpty ( cli . out , "Architecture: %s\n" , info . Architecture )
2015-04-10 17:26:30 +00:00
fmt . Fprintf ( cli . out , "CPUs: %d\n" , info . NCPU )
fmt . Fprintf ( cli . out , "Total Memory: %s\n" , units . BytesSize ( float64 ( info . MemTotal ) ) )
2015-05-29 23:48:02 +00:00
ioutils . FprintfIfNotEmpty ( cli . out , "Name: %s\n" , info . Name )
ioutils . FprintfIfNotEmpty ( cli . out , "ID: %s\n" , info . ID )
2016-02-04 02:10:48 +00:00
fmt . Fprintf ( cli . out , "Docker Root Dir: %s\n" , info . DockerRootDir )
2016-03-28 07:46:53 +00:00
fmt . Fprintf ( cli . out , "Debug Mode (client): %v\n" , utils . IsDebugEnabled ( ) )
fmt . Fprintf ( cli . out , "Debug Mode (server): %v\n" , info . Debug )
2016-02-01 23:09:25 +00:00
2015-03-31 20:49:41 +00:00
if info . Debug {
2015-09-19 02:36:10 +00:00
fmt . Fprintf ( cli . out , " File Descriptors: %d\n" , info . NFd )
fmt . Fprintf ( cli . out , " Goroutines: %d\n" , info . NGoroutines )
fmt . Fprintf ( cli . out , " System Time: %s\n" , info . SystemTime )
fmt . Fprintf ( cli . out , " EventsListeners: %d\n" , info . NEventsListener )
2015-03-25 03:57:23 +00:00
}
2015-04-10 17:26:30 +00:00
2015-07-23 09:40:54 +00:00
ioutils . FprintfIfNotEmpty ( cli . out , "Http Proxy: %s\n" , info . HTTPProxy )
ioutils . FprintfIfNotEmpty ( cli . out , "Https Proxy: %s\n" , info . HTTPSProxy )
2015-05-29 23:48:02 +00:00
ioutils . FprintfIfNotEmpty ( cli . out , "No Proxy: %s\n" , info . NoProxy )
2015-04-10 17:26:30 +00:00
if info . IndexServerAddress != "" {
2015-04-01 22:39:37 +00:00
u := cli . configFile . AuthConfigs [ info . IndexServerAddress ] . Username
2015-03-25 03:57:23 +00:00
if len ( u ) > 0 {
fmt . Fprintf ( cli . out , "Username: %v\n" , u )
}
2016-03-04 20:00:18 +00:00
fmt . Fprintf ( cli . out , "Registry: %v\n" , info . IndexServerAddress )
2015-03-25 03:57:23 +00:00
}
2015-09-19 02:36:10 +00:00
// Only output these warnings if the server does not support these features
2015-12-03 22:20:46 +00:00
if info . OSType != "windows" {
if ! info . MemoryLimit {
2015-12-11 19:23:16 +00:00
fmt . Fprintln ( cli . err , "WARNING: No memory limit support" )
2015-12-03 22:20:46 +00:00
}
if ! info . SwapLimit {
2015-12-11 19:23:16 +00:00
fmt . Fprintln ( cli . err , "WARNING: No swap limit support" )
2015-12-03 22:20:46 +00:00
}
2016-03-02 13:35:17 +00:00
if ! info . KernelMemory {
fmt . Fprintln ( cli . err , "WARNING: No kernel memory limit support" )
}
2015-12-03 22:20:46 +00:00
if ! info . OomKillDisable {
2015-12-11 19:23:16 +00:00
fmt . Fprintln ( cli . err , "WARNING: No oom kill disable support" )
2015-12-03 22:20:46 +00:00
}
if ! info . CPUCfsQuota {
2015-12-11 19:23:16 +00:00
fmt . Fprintln ( cli . err , "WARNING: No cpu cfs quota support" )
2015-12-03 22:20:46 +00:00
}
if ! info . CPUCfsPeriod {
2015-12-11 19:23:16 +00:00
fmt . Fprintln ( cli . err , "WARNING: No cpu cfs period support" )
2015-12-03 22:20:46 +00:00
}
if ! info . CPUShares {
2015-12-11 19:23:16 +00:00
fmt . Fprintln ( cli . err , "WARNING: No cpu shares support" )
2015-12-03 22:20:46 +00:00
}
if ! info . CPUSet {
2015-12-11 19:23:16 +00:00
fmt . Fprintln ( cli . err , "WARNING: No cpuset support" )
2015-12-03 22:20:46 +00:00
}
if ! info . IPv4Forwarding {
2015-12-11 19:23:16 +00:00
fmt . Fprintln ( cli . err , "WARNING: IPv4 forwarding is disabled" )
2015-12-03 22:20:46 +00:00
}
if ! info . BridgeNfIptables {
2015-12-11 19:23:16 +00:00
fmt . Fprintln ( cli . err , "WARNING: bridge-nf-call-iptables is disabled" )
2015-12-03 22:20:46 +00:00
}
if ! info . BridgeNfIP6tables {
2015-12-11 19:23:16 +00:00
fmt . Fprintln ( cli . err , "WARNING: bridge-nf-call-ip6tables is disabled" )
2015-07-10 02:05:50 +00:00
}
2015-06-17 01:19:11 +00:00
}
2015-07-10 02:05:50 +00:00
2015-04-10 17:26:30 +00:00
if info . Labels != nil {
2015-03-25 03:57:23 +00:00
fmt . Fprintln ( cli . out , "Labels:" )
2015-04-10 17:26:30 +00:00
for _ , attribute := range info . Labels {
2015-03-25 03:57:23 +00:00
fmt . Fprintf ( cli . out , " %s\n" , attribute )
}
}
2015-05-21 17:48:36 +00:00
2015-09-19 02:36:10 +00:00
ioutils . FprintfIfTrue ( cli . out , "Experimental: %v\n" , info . ExperimentalBuild )
2015-09-10 23:12:00 +00:00
if info . ClusterStore != "" {
2016-03-28 07:46:53 +00:00
fmt . Fprintf ( cli . out , "Cluster Store: %s\n" , info . ClusterStore )
2015-09-10 23:12:00 +00:00
}
2015-03-25 03:57:23 +00:00
2015-10-26 00:12:22 +00:00
if info . ClusterAdvertise != "" {
2016-03-28 07:46:53 +00:00
fmt . Fprintf ( cli . out , "Cluster Advertise: %s\n" , info . ClusterAdvertise )
2015-10-26 00:12:22 +00:00
}
2016-02-16 22:45:48 +00:00
if info . RegistryConfig != nil && ( len ( info . RegistryConfig . InsecureRegistryCIDRs ) > 0 || len ( info . RegistryConfig . IndexConfigs ) > 0 ) {
2016-04-25 10:40:24 +00:00
fmt . Fprintln ( cli . out , "Insecure Registries:" )
2016-02-16 22:45:48 +00:00
for _ , registry := range info . RegistryConfig . IndexConfigs {
if registry . Secure == false {
fmt . Fprintf ( cli . out , " %s\n" , registry . Name )
}
}
for _ , registry := range info . RegistryConfig . InsecureRegistryCIDRs {
mask , _ := registry . Mask . Size ( )
fmt . Fprintf ( cli . out , " %s/%d\n" , registry . IP . String ( ) , mask )
}
}
2015-03-25 03:57:23 +00:00
return nil
}