1package daemon // import "github.com/docker/docker/daemon" 2 3import ( 4 "fmt" 5 "os" 6 "runtime" 7 "strings" 8 "time" 9 10 "github.com/docker/docker/api" 11 "github.com/docker/docker/api/types" 12 "github.com/docker/docker/cli/debug" 13 "github.com/docker/docker/daemon/logger" 14 "github.com/docker/docker/dockerversion" 15 "github.com/docker/docker/pkg/fileutils" 16 "github.com/docker/docker/pkg/parsers/kernel" 17 "github.com/docker/docker/pkg/parsers/operatingsystem" 18 "github.com/docker/docker/pkg/platform" 19 "github.com/docker/docker/pkg/sysinfo" 20 "github.com/docker/docker/pkg/system" 21 "github.com/docker/docker/registry" 22 "github.com/docker/go-connections/sockets" 23 "github.com/sirupsen/logrus" 24) 25 26// SystemInfo returns information about the host server the daemon is running on. 27func (daemon *Daemon) SystemInfo() (*types.Info, error) { 28 kernelVersion := "<unknown>" 29 if kv, err := kernel.GetKernelVersion(); err != nil { 30 logrus.Warnf("Could not get kernel version: %v", err) 31 } else { 32 kernelVersion = kv.String() 33 } 34 35 operatingSystem := "<unknown>" 36 if s, err := operatingsystem.GetOperatingSystem(); err != nil { 37 logrus.Warnf("Could not get operating system name: %v", err) 38 } else { 39 operatingSystem = s 40 } 41 42 // Don't do containerized check on Windows 43 if runtime.GOOS != "windows" { 44 if inContainer, err := operatingsystem.IsContainerized(); err != nil { 45 logrus.Errorf("Could not determine if daemon is containerized: %v", err) 46 operatingSystem += " (error determining if containerized)" 47 } else if inContainer { 48 operatingSystem += " (containerized)" 49 } 50 } 51 52 meminfo, err := system.ReadMemInfo() 53 if err != nil { 54 logrus.Errorf("Could not read system memory info: %v", err) 55 meminfo = &system.MemInfo{} 56 } 57 58 sysInfo := sysinfo.New(true) 59 cRunning, cPaused, cStopped := stateCtr.get() 60 61 securityOptions := []string{} 62 if sysInfo.AppArmor { 63 securityOptions = append(securityOptions, "name=apparmor") 64 } 65 if sysInfo.Seccomp && supportsSeccomp { 66 profile := daemon.seccompProfilePath 67 if profile == "" { 68 profile = "default" 69 } 70 securityOptions = append(securityOptions, fmt.Sprintf("name=seccomp,profile=%s", profile)) 71 } 72 if selinuxEnabled() { 73 securityOptions = append(securityOptions, "name=selinux") 74 } 75 rootIDs := daemon.idMappings.RootPair() 76 if rootIDs.UID != 0 || rootIDs.GID != 0 { 77 securityOptions = append(securityOptions, "name=userns") 78 } 79 80 var ds [][2]string 81 drivers := "" 82 statuses := daemon.imageService.LayerStoreStatus() 83 for os, gd := range daemon.graphDrivers { 84 ds = append(ds, statuses[os]...) 85 drivers += gd 86 if len(daemon.graphDrivers) > 1 { 87 drivers += fmt.Sprintf(" (%s) ", os) 88 } 89 } 90 drivers = strings.TrimSpace(drivers) 91 92 v := &types.Info{ 93 ID: daemon.ID, 94 Containers: cRunning + cPaused + cStopped, 95 ContainersRunning: cRunning, 96 ContainersPaused: cPaused, 97 ContainersStopped: cStopped, 98 Images: daemon.imageService.CountImages(), 99 Driver: drivers, 100 DriverStatus: ds, 101 Plugins: daemon.showPluginsInfo(), 102 IPv4Forwarding: !sysInfo.IPv4ForwardingDisabled, 103 BridgeNfIptables: !sysInfo.BridgeNFCallIPTablesDisabled, 104 BridgeNfIP6tables: !sysInfo.BridgeNFCallIP6TablesDisabled, 105 Debug: debug.IsEnabled(), 106 NFd: fileutils.GetTotalUsedFds(), 107 NGoroutines: runtime.NumGoroutine(), 108 SystemTime: time.Now().Format(time.RFC3339Nano), 109 LoggingDriver: daemon.defaultLogConfig.Type, 110 CgroupDriver: daemon.getCgroupDriver(), 111 NEventsListener: daemon.EventsService.SubscribersCount(), 112 KernelVersion: kernelVersion, 113 OperatingSystem: operatingSystem, 114 IndexServerAddress: registry.IndexServer, 115 OSType: platform.OSType, 116 Architecture: platform.Architecture, 117 RegistryConfig: daemon.RegistryService.ServiceConfig(), 118 NCPU: sysinfo.NumCPU(), 119 MemTotal: meminfo.MemTotal, 120 GenericResources: daemon.genericResources, 121 DockerRootDir: daemon.configStore.Root, 122 Labels: daemon.configStore.Labels, 123 ExperimentalBuild: daemon.configStore.Experimental, 124 ServerVersion: dockerversion.Version, 125 ClusterStore: daemon.configStore.ClusterStore, 126 ClusterAdvertise: daemon.configStore.ClusterAdvertise, 127 HTTPProxy: sockets.GetProxyEnv("http_proxy"), 128 HTTPSProxy: sockets.GetProxyEnv("https_proxy"), 129 NoProxy: sockets.GetProxyEnv("no_proxy"), 130 LiveRestoreEnabled: daemon.configStore.LiveRestoreEnabled, 131 SecurityOptions: securityOptions, 132 Isolation: daemon.defaultIsolation, 133 } 134 135 // Retrieve platform specific info 136 daemon.FillPlatformInfo(v, sysInfo) 137 138 hostname := "" 139 if hn, err := os.Hostname(); err != nil { 140 logrus.Warnf("Could not get hostname: %v", err) 141 } else { 142 hostname = hn 143 } 144 v.Name = hostname 145 146 return v, nil 147} 148 149// SystemVersion returns version information about the daemon. 150func (daemon *Daemon) SystemVersion() types.Version { 151 kernelVersion := "<unknown>" 152 if kv, err := kernel.GetKernelVersion(); err != nil { 153 logrus.Warnf("Could not get kernel version: %v", err) 154 } else { 155 kernelVersion = kv.String() 156 } 157 158 v := types.Version{ 159 Components: []types.ComponentVersion{ 160 { 161 Name: "Engine", 162 Version: dockerversion.Version, 163 Details: map[string]string{ 164 "GitCommit": dockerversion.GitCommit, 165 "ApiVersion": api.DefaultVersion, 166 "MinAPIVersion": api.MinVersion, 167 "GoVersion": runtime.Version(), 168 "Os": runtime.GOOS, 169 "Arch": runtime.GOARCH, 170 "BuildTime": dockerversion.BuildTime, 171 "KernelVersion": kernelVersion, 172 "Experimental": fmt.Sprintf("%t", daemon.configStore.Experimental), 173 }, 174 }, 175 }, 176 177 // Populate deprecated fields for older clients 178 Version: dockerversion.Version, 179 GitCommit: dockerversion.GitCommit, 180 APIVersion: api.DefaultVersion, 181 MinAPIVersion: api.MinVersion, 182 GoVersion: runtime.Version(), 183 Os: runtime.GOOS, 184 Arch: runtime.GOARCH, 185 BuildTime: dockerversion.BuildTime, 186 KernelVersion: kernelVersion, 187 Experimental: daemon.configStore.Experimental, 188 } 189 190 v.Platform.Name = dockerversion.PlatformName 191 192 return v 193} 194 195func (daemon *Daemon) showPluginsInfo() types.PluginsInfo { 196 var pluginsInfo types.PluginsInfo 197 198 pluginsInfo.Volume = daemon.volumes.GetDriverList() 199 pluginsInfo.Network = daemon.GetNetworkDriverList() 200 // The authorization plugins are returned in the order they are 201 // used as they constitute a request/response modification chain. 202 pluginsInfo.Authorization = daemon.configStore.AuthorizationPlugins 203 pluginsInfo.Log = logger.ListDrivers() 204 205 return pluginsInfo 206} 207