123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- package daemon // import "github.com/docker/docker/daemon"
- import (
- "fmt"
- "net/url"
- "os"
- "runtime"
- "strings"
- "time"
- "github.com/docker/docker/api"
- "github.com/docker/docker/api/types"
- "github.com/docker/docker/cli/debug"
- "github.com/docker/docker/daemon/logger"
- "github.com/docker/docker/dockerversion"
- "github.com/docker/docker/pkg/fileutils"
- "github.com/docker/docker/pkg/parsers/kernel"
- "github.com/docker/docker/pkg/parsers/operatingsystem"
- "github.com/docker/docker/pkg/platform"
- "github.com/docker/docker/pkg/sysinfo"
- "github.com/docker/docker/pkg/system"
- "github.com/docker/docker/registry"
- "github.com/docker/go-connections/sockets"
- "github.com/sirupsen/logrus"
- )
- // SystemInfo returns information about the host server the daemon is running on.
- func (daemon *Daemon) SystemInfo() (*types.Info, error) {
- sysInfo := sysinfo.New(true)
- cRunning, cPaused, cStopped := stateCtr.get()
- v := &types.Info{
- ID: daemon.ID,
- Containers: cRunning + cPaused + cStopped,
- ContainersRunning: cRunning,
- ContainersPaused: cPaused,
- ContainersStopped: cStopped,
- Images: daemon.imageService.CountImages(),
- IPv4Forwarding: !sysInfo.IPv4ForwardingDisabled,
- BridgeNfIptables: !sysInfo.BridgeNFCallIPTablesDisabled,
- BridgeNfIP6tables: !sysInfo.BridgeNFCallIP6TablesDisabled,
- Debug: debug.IsEnabled(),
- Name: hostName(),
- NFd: fileutils.GetTotalUsedFds(),
- NGoroutines: runtime.NumGoroutine(),
- SystemTime: time.Now().Format(time.RFC3339Nano),
- LoggingDriver: daemon.defaultLogConfig.Type,
- CgroupDriver: daemon.getCgroupDriver(),
- NEventsListener: daemon.EventsService.SubscribersCount(),
- KernelVersion: kernelVersion(),
- OperatingSystem: operatingSystem(),
- IndexServerAddress: registry.IndexServer,
- OSType: platform.OSType,
- Architecture: platform.Architecture,
- RegistryConfig: daemon.RegistryService.ServiceConfig(),
- NCPU: sysinfo.NumCPU(),
- MemTotal: memInfo().MemTotal,
- GenericResources: daemon.genericResources,
- DockerRootDir: daemon.configStore.Root,
- Labels: daemon.configStore.Labels,
- ExperimentalBuild: daemon.configStore.Experimental,
- ServerVersion: dockerversion.Version,
- ClusterStore: daemon.configStore.ClusterStore,
- ClusterAdvertise: daemon.configStore.ClusterAdvertise,
- HTTPProxy: maskCredentials(sockets.GetProxyEnv("http_proxy")),
- HTTPSProxy: maskCredentials(sockets.GetProxyEnv("https_proxy")),
- NoProxy: sockets.GetProxyEnv("no_proxy"),
- LiveRestoreEnabled: daemon.configStore.LiveRestoreEnabled,
- Isolation: daemon.defaultIsolation,
- }
- daemon.fillAPIInfo(v)
- // Retrieve platform specific info
- daemon.fillPlatformInfo(v, sysInfo)
- daemon.fillDriverInfo(v)
- daemon.fillPluginsInfo(v)
- daemon.fillSecurityOptions(v, sysInfo)
- daemon.fillLicense(v)
- return v, nil
- }
- // SystemVersion returns version information about the daemon.
- func (daemon *Daemon) SystemVersion() types.Version {
- kernelVersion := kernelVersion()
- v := types.Version{
- Components: []types.ComponentVersion{
- {
- Name: "Engine",
- Version: dockerversion.Version,
- Details: map[string]string{
- "GitCommit": dockerversion.GitCommit,
- "ApiVersion": api.DefaultVersion,
- "MinAPIVersion": api.MinVersion,
- "GoVersion": runtime.Version(),
- "Os": runtime.GOOS,
- "Arch": runtime.GOARCH,
- "BuildTime": dockerversion.BuildTime,
- "KernelVersion": kernelVersion,
- "Experimental": fmt.Sprintf("%t", daemon.configStore.Experimental),
- },
- },
- },
- // Populate deprecated fields for older clients
- Version: dockerversion.Version,
- GitCommit: dockerversion.GitCommit,
- APIVersion: api.DefaultVersion,
- MinAPIVersion: api.MinVersion,
- GoVersion: runtime.Version(),
- Os: runtime.GOOS,
- Arch: runtime.GOARCH,
- BuildTime: dockerversion.BuildTime,
- KernelVersion: kernelVersion,
- Experimental: daemon.configStore.Experimental,
- }
- v.Platform.Name = dockerversion.PlatformName
- return v
- }
- func (daemon *Daemon) fillDriverInfo(v *types.Info) {
- var ds [][2]string
- drivers := ""
- statuses := daemon.imageService.LayerStoreStatus()
- for os, gd := range daemon.graphDrivers {
- ds = append(ds, statuses[os]...)
- drivers += gd
- if len(daemon.graphDrivers) > 1 {
- drivers += fmt.Sprintf(" (%s) ", os)
- }
- switch gd {
- case "devicemapper", "overlay":
- v.Warnings = append(v.Warnings, fmt.Sprintf("WARNING: the %s storage-driver is deprecated, and will be removed in a future release.", gd))
- }
- }
- drivers = strings.TrimSpace(drivers)
- v.Driver = drivers
- v.DriverStatus = ds
- fillDriverWarnings(v)
- }
- func (daemon *Daemon) fillPluginsInfo(v *types.Info) {
- v.Plugins = types.PluginsInfo{
- Volume: daemon.volumes.GetDriverList(),
- Network: daemon.GetNetworkDriverList(),
- // The authorization plugins are returned in the order they are
- // used as they constitute a request/response modification chain.
- Authorization: daemon.configStore.AuthorizationPlugins,
- Log: logger.ListDrivers(),
- }
- }
- func (daemon *Daemon) fillSecurityOptions(v *types.Info, sysInfo *sysinfo.SysInfo) {
- var securityOptions []string
- if sysInfo.AppArmor {
- securityOptions = append(securityOptions, "name=apparmor")
- }
- if sysInfo.Seccomp && supportsSeccomp {
- profile := daemon.seccompProfilePath
- if profile == "" {
- profile = "default"
- }
- securityOptions = append(securityOptions, fmt.Sprintf("name=seccomp,profile=%s", profile))
- }
- if selinuxEnabled() {
- securityOptions = append(securityOptions, "name=selinux")
- }
- if rootIDs := daemon.idMapping.RootPair(); rootIDs.UID != 0 || rootIDs.GID != 0 {
- securityOptions = append(securityOptions, "name=userns")
- }
- v.SecurityOptions = securityOptions
- }
- func (daemon *Daemon) fillAPIInfo(v *types.Info) {
- const warn string = `
- Access to the remote API is equivalent to root access on the host. Refer
- to the 'Docker daemon attack surface' section in the documentation for
- more information: https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface`
- cfg := daemon.configStore
- for _, host := range cfg.Hosts {
- // cnf.Hosts is normalized during startup, so should always have a scheme/proto
- h := strings.SplitN(host, "://", 2)
- proto := h[0]
- addr := h[1]
- if proto != "tcp" {
- continue
- }
- if !cfg.TLS {
- v.Warnings = append(v.Warnings, fmt.Sprintf("WARNING: API is accessible on http://%s without encryption.%s", addr, warn))
- continue
- }
- if !cfg.TLSVerify {
- v.Warnings = append(v.Warnings, fmt.Sprintf("WARNING: API is accessible on https://%s without TLS client verification.%s", addr, warn))
- continue
- }
- }
- }
- func hostName() string {
- hostname := ""
- if hn, err := os.Hostname(); err != nil {
- logrus.Warnf("Could not get hostname: %v", err)
- } else {
- hostname = hn
- }
- return hostname
- }
- func kernelVersion() string {
- var kernelVersion string
- if kv, err := kernel.GetKernelVersion(); err != nil {
- logrus.Warnf("Could not get kernel version: %v", err)
- } else {
- kernelVersion = kv.String()
- }
- return kernelVersion
- }
- func memInfo() *system.MemInfo {
- memInfo, err := system.ReadMemInfo()
- if err != nil {
- logrus.Errorf("Could not read system memory info: %v", err)
- memInfo = &system.MemInfo{}
- }
- return memInfo
- }
- func operatingSystem() string {
- var operatingSystem string
- if s, err := operatingsystem.GetOperatingSystem(); err != nil {
- logrus.Warnf("Could not get operating system name: %v", err)
- } else {
- operatingSystem = s
- }
- // Don't do containerized check on Windows
- if runtime.GOOS != "windows" {
- if inContainer, err := operatingsystem.IsContainerized(); err != nil {
- logrus.Errorf("Could not determine if daemon is containerized: %v", err)
- operatingSystem += " (error determining if containerized)"
- } else if inContainer {
- operatingSystem += " (containerized)"
- }
- }
- return operatingSystem
- }
- func maskCredentials(rawURL string) string {
- parsedURL, err := url.Parse(rawURL)
- if err != nil || parsedURL.User == nil {
- return rawURL
- }
- parsedURL.User = url.UserPassword("xxxxx", "xxxxx")
- maskedURL := parsedURL.String()
- return maskedURL
- }
|