github.com/DaoCloud/dao@v0.0.0-20161212064103-c3dbfd13ee36/api/client/info.go (about) 1 package client 2 3 import ( 4 "fmt" 5 "strings" 6 "time" 7 8 "golang.org/x/net/context" 9 10 Cli "github.com/docker/docker/cli" 11 "github.com/docker/docker/pkg/ioutils" 12 flag "github.com/docker/docker/pkg/mflag" 13 "github.com/docker/docker/utils" 14 "github.com/docker/engine-api/types/swarm" 15 "github.com/docker/go-units" 16 ) 17 18 // CmdInfo displays system-wide information. 19 // 20 // Usage: docker info 21 func (cli *DockerCli) CmdInfo(args ...string) error { 22 cmd := Cli.Subcmd("info", nil, Cli.DockerCommands["info"].Description, true) 23 cmd.Require(flag.Exact, 0) 24 25 cmd.ParseFlags(args, true) 26 27 ctx := context.Background() 28 info, err := cli.client.Info(ctx) 29 if err != nil { 30 return err 31 } 32 33 fmt.Fprintf(cli.out, "容器数: %d\n", info.Containers) 34 fmt.Fprintf(cli.out, " 运行: %d\n", info.ContainersRunning) 35 fmt.Fprintf(cli.out, " 暂停: %d\n", info.ContainersPaused) 36 fmt.Fprintf(cli.out, " 停止: %d\n", info.ContainersStopped) 37 fmt.Fprintf(cli.out, "镜像数: %d\n", info.Images) 38 ioutils.FprintfIfNotEmpty(cli.out, "Docker引擎版本: %s\n", info.ServerVersion) 39 ioutils.FprintfIfNotEmpty(cli.out, "存储驱动: %s\n", info.Driver) 40 if info.DriverStatus != nil { 41 for _, pair := range info.DriverStatus { 42 fmt.Fprintf(cli.out, " %s: %s\n", pair[0], pair[1]) 43 44 // print a warning if devicemapper is using a loopback file 45 if pair[0] == "Data loop file" { 46 fmt.Fprintln(cli.err, " 警告: 环回设备loopback严重不建议在生产环境中使用。详见 `--storage-opt dm.thinpooldev` 来指定一个自定义的块存储设备。") 47 } 48 } 49 50 } 51 if info.SystemStatus != nil { 52 for _, pair := range info.SystemStatus { 53 fmt.Fprintf(cli.out, "%s: %s\n", pair[0], pair[1]) 54 } 55 } 56 ioutils.FprintfIfNotEmpty(cli.out, "日志驱动: %s\n", info.LoggingDriver) 57 ioutils.FprintfIfNotEmpty(cli.out, "Cgroup 驱动: %s\n", info.CgroupDriver) 58 59 fmt.Fprintf(cli.out, "插件:\n") 60 fmt.Fprintf(cli.out, " 存储卷:") 61 fmt.Fprintf(cli.out, " %s", strings.Join(info.Plugins.Volume, " ")) 62 fmt.Fprintf(cli.out, "\n") 63 fmt.Fprintf(cli.out, " 网络:") 64 fmt.Fprintf(cli.out, " %s", strings.Join(info.Plugins.Network, " ")) 65 fmt.Fprintf(cli.out, "\n") 66 67 if len(info.Plugins.Authorization) != 0 { 68 fmt.Fprintf(cli.out, " 认证:") 69 fmt.Fprintf(cli.out, " %s", strings.Join(info.Plugins.Authorization, " ")) 70 fmt.Fprintf(cli.out, "\n") 71 } 72 73 fmt.Fprintf(cli.out, "Swarm集群: %v\n", info.Swarm.LocalNodeState) 74 if info.Swarm.LocalNodeState != swarm.LocalNodeStateInactive { 75 fmt.Fprintf(cli.out, " 节点ID: %s\n", info.Swarm.NodeID) 76 if info.Swarm.Error != "" { 77 fmt.Fprintf(cli.out, " 错误: %v\n", info.Swarm.Error) 78 } 79 fmt.Fprintf(cli.out, " 是否是管理者: %v\n", info.Swarm.ControlAvailable) 80 if info.Swarm.ControlAvailable { 81 fmt.Fprintf(cli.out, " 集群ID: %s\n", info.Swarm.Cluster.ID) 82 fmt.Fprintf(cli.out, " 管理者数量: %d\n", info.Swarm.Managers) 83 fmt.Fprintf(cli.out, " 节点数: %d\n", info.Swarm.Nodes) 84 fmt.Fprintf(cli.out, " 编排:\n") 85 fmt.Fprintf(cli.out, " 历史任务保留上线: %d\n", info.Swarm.Cluster.Spec.Orchestration.TaskHistoryRetentionLimit) 86 fmt.Fprintf(cli.out, " Raft:\n") 87 fmt.Fprintf(cli.out, " 快照间隔: %d\n", info.Swarm.Cluster.Spec.Raft.SnapshotInterval) 88 fmt.Fprintf(cli.out, " 心跳时钟: %d\n", info.Swarm.Cluster.Spec.Raft.HeartbeatTick) 89 fmt.Fprintf(cli.out, " 选举时钟: %d\n", info.Swarm.Cluster.Spec.Raft.ElectionTick) 90 fmt.Fprintf(cli.out, " 分发器:\n") 91 fmt.Fprintf(cli.out, " 心跳周期: %s\n", units.HumanDuration(time.Duration(info.Swarm.Cluster.Spec.Dispatcher.HeartbeatPeriod))) 92 fmt.Fprintf(cli.out, " CA配置:\n") 93 fmt.Fprintf(cli.out, " 过期周期: %s\n", units.HumanDuration(info.Swarm.Cluster.Spec.CAConfig.NodeCertExpiry)) 94 if len(info.Swarm.Cluster.Spec.CAConfig.ExternalCAs) > 0 { 95 fmt.Fprintf(cli.out, " 外部CAs:\n") 96 for _, entry := range info.Swarm.Cluster.Spec.CAConfig.ExternalCAs { 97 fmt.Fprintf(cli.out, " %s: %s\n", entry.Protocol, entry.URL) 98 } 99 } 100 } 101 fmt.Fprintf(cli.out, " 节点地址: %s\n", info.Swarm.NodeAddr) 102 } 103 104 if len(info.Runtimes) > 0 { 105 fmt.Fprintf(cli.out, "运行时:") 106 for name := range info.Runtimes { 107 fmt.Fprintf(cli.out, " %s", name) 108 } 109 fmt.Fprint(cli.out, "\n") 110 fmt.Fprintf(cli.out, "默认运行时: %s\n", info.DefaultRuntime) 111 } 112 113 fmt.Fprintf(cli.out, "安全选项:") 114 ioutils.FprintfIfNotEmpty(cli.out, " %s", strings.Join(info.SecurityOptions, " ")) 115 fmt.Fprintf(cli.out, "\n") 116 117 ioutils.FprintfIfNotEmpty(cli.out, "内核版本: %s\n", info.KernelVersion) 118 ioutils.FprintfIfNotEmpty(cli.out, "操作系统: %s\n", info.OperatingSystem) 119 ioutils.FprintfIfNotEmpty(cli.out, "操作系统类型: %s\n", info.OSType) 120 ioutils.FprintfIfNotEmpty(cli.out, "机器架构: %s\n", info.Architecture) 121 fmt.Fprintf(cli.out, "CPU数量: %d\n", info.NCPU) 122 fmt.Fprintf(cli.out, "内存总数: %s\n", units.BytesSize(float64(info.MemTotal))) 123 ioutils.FprintfIfNotEmpty(cli.out, "名称: %s\n", info.Name) 124 ioutils.FprintfIfNotEmpty(cli.out, "ID: %s\n", info.ID) 125 fmt.Fprintf(cli.out, "Docker引擎根目录: %s\n", info.DockerRootDir) 126 fmt.Fprintf(cli.out, "调试模式(客户端): %v\n", utils.IsDebugEnabled()) 127 fmt.Fprintf(cli.out, "调试模式(服务端): %v\n", info.Debug) 128 129 if info.Debug { 130 fmt.Fprintf(cli.out, " 文件描述符个数: %d\n", info.NFd) 131 fmt.Fprintf(cli.out, " Go协程综述: %d\n", info.NGoroutines) 132 fmt.Fprintf(cli.out, " 系统时间: %s\n", info.SystemTime) 133 fmt.Fprintf(cli.out, " 事件监听者总数: %d\n", info.NEventsListener) 134 } 135 136 ioutils.FprintfIfNotEmpty(cli.out, "Http代理: %s\n", info.HTTPProxy) 137 ioutils.FprintfIfNotEmpty(cli.out, "Https代理: %s\n", info.HTTPSProxy) 138 ioutils.FprintfIfNotEmpty(cli.out, "No Proxy: %s\n", info.NoProxy) 139 140 if info.IndexServerAddress != "" { 141 u := cli.configFile.AuthConfigs[info.IndexServerAddress].Username 142 if len(u) > 0 { 143 fmt.Fprintf(cli.out, "用户名: %v\n", u) 144 } 145 fmt.Fprintf(cli.out, "镜像仓库: %v\n", info.IndexServerAddress) 146 } 147 148 // Only output these warnings if the server does not support these features 149 if info.OSType != "windows" { 150 if !info.MemoryLimit { 151 fmt.Fprintln(cli.err, "警告: 不支持内存限制") 152 } 153 if !info.SwapLimit { 154 fmt.Fprintln(cli.err, "警告: 不支持交换区内存限制") 155 } 156 if !info.KernelMemory { 157 fmt.Fprintln(cli.err, "警告: 不支持内核内存限制") 158 } 159 if !info.OomKillDisable { 160 fmt.Fprintln(cli.err, "警告: 不支持oom kill 禁用") 161 } 162 if !info.CPUCfsQuota { 163 fmt.Fprintln(cli.err, "警告: 不支持 cpu cfs 限额 ") 164 } 165 if !info.CPUCfsPeriod { 166 fmt.Fprintln(cli.err, "警告: 不支持 cpu cfs 周期 ") 167 } 168 if !info.CPUShares { 169 fmt.Fprintln(cli.err, "警告: 不支持 cpu 时间") 170 } 171 if !info.CPUSet { 172 fmt.Fprintln(cli.err, "警告: 不支持 cpuset") 173 } 174 if !info.IPv4Forwarding { 175 fmt.Fprintln(cli.err, "警告: IPv4转发功能已禁用") 176 } 177 if !info.BridgeNfIptables { 178 fmt.Fprintln(cli.err, "警告: bridge-nf-call-iptables已禁用") 179 } 180 if !info.BridgeNfIP6tables { 181 fmt.Fprintln(cli.err, "警告: bridge-nf-call-ip6tables已禁用") 182 } 183 } 184 185 if info.Labels != nil { 186 fmt.Fprintln(cli.out, "标签:") 187 for _, attribute := range info.Labels { 188 fmt.Fprintf(cli.out, " %s\n", attribute) 189 } 190 } 191 192 ioutils.FprintfIfTrue(cli.out, "试验版: %v\n", info.ExperimentalBuild) 193 if info.ClusterStore != "" { 194 fmt.Fprintf(cli.out, "集群存储: %s\n", info.ClusterStore) 195 } 196 197 if info.ClusterAdvertise != "" { 198 fmt.Fprintf(cli.out, "集群广播地址: %s\n", info.ClusterAdvertise) 199 } 200 201 if info.RegistryConfig != nil && (len(info.RegistryConfig.InsecureRegistryCIDRs) > 0 || len(info.RegistryConfig.IndexConfigs) > 0) { 202 fmt.Fprintln(cli.out, "不受信的镜像仓库:") 203 for _, registry := range info.RegistryConfig.IndexConfigs { 204 if registry.Secure == false { 205 fmt.Fprintf(cli.out, " %s\n", registry.Name) 206 } 207 } 208 209 for _, registry := range info.RegistryConfig.InsecureRegistryCIDRs { 210 mask, _ := registry.Mask.Size() 211 fmt.Fprintf(cli.out, " %s/%d\n", registry.IP.String(), mask) 212 } 213 } 214 return nil 215 }