2014-08-08 07:01:55 +04:00
|
|
|
package daemon
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"runtime"
|
2015-03-10 21:25:47 +03:00
|
|
|
"time"
|
2014-08-08 07:01:55 +04:00
|
|
|
|
2015-03-27 01:22:04 +03:00
|
|
|
"github.com/Sirupsen/logrus"
|
2015-04-10 20:26:30 +03:00
|
|
|
"github.com/docker/docker/api/types"
|
2015-02-05 00:22:38 +03:00
|
|
|
"github.com/docker/docker/autogen/dockerversion"
|
2015-09-11 01:01:18 +03:00
|
|
|
"github.com/docker/docker/context"
|
2015-03-30 00:17:23 +03:00
|
|
|
"github.com/docker/docker/pkg/fileutils"
|
2014-08-08 07:01:55 +04:00
|
|
|
"github.com/docker/docker/pkg/parsers/kernel"
|
|
|
|
"github.com/docker/docker/pkg/parsers/operatingsystem"
|
2015-08-06 14:54:48 +03:00
|
|
|
"github.com/docker/docker/pkg/sysinfo"
|
2014-10-25 02:48:23 +04:00
|
|
|
"github.com/docker/docker/pkg/system"
|
2014-08-08 07:01:55 +04:00
|
|
|
"github.com/docker/docker/registry"
|
|
|
|
"github.com/docker/docker/utils"
|
|
|
|
)
|
|
|
|
|
2015-07-31 00:01:53 +03:00
|
|
|
// SystemInfo returns information about the host server the daemon is running on.
|
2015-09-11 01:01:18 +03:00
|
|
|
func (daemon *Daemon) SystemInfo(ctx context.Context) (*types.Info, error) {
|
2015-09-29 20:40:17 +03:00
|
|
|
images := daemon.Graph(ctx).Map()
|
2014-08-08 07:01:55 +04:00
|
|
|
var imgcount int
|
|
|
|
if images == nil {
|
|
|
|
imgcount = 0
|
|
|
|
} else {
|
|
|
|
imgcount = len(images)
|
|
|
|
}
|
|
|
|
kernelVersion := "<unknown>"
|
|
|
|
if kv, err := kernel.GetKernelVersion(); err == nil {
|
|
|
|
kernelVersion = kv.String()
|
|
|
|
}
|
|
|
|
|
|
|
|
operatingSystem := "<unknown>"
|
|
|
|
if s, err := operatingsystem.GetOperatingSystem(); err == nil {
|
|
|
|
operatingSystem = s
|
|
|
|
}
|
2015-04-27 18:38:01 +03:00
|
|
|
|
|
|
|
// 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)"
|
|
|
|
}
|
2014-08-08 07:01:55 +04:00
|
|
|
}
|
|
|
|
|
2014-10-25 02:48:23 +04:00
|
|
|
meminfo, err := system.ReadMemInfo()
|
|
|
|
if err != nil {
|
2015-03-27 01:22:04 +03:00
|
|
|
logrus.Errorf("Could not read system memory info: %v", err)
|
2014-10-25 02:48:23 +04:00
|
|
|
}
|
|
|
|
|
2015-07-31 00:01:53 +03:00
|
|
|
// if we still have the original dockerinit binary from before
|
|
|
|
// we copied it locally, let's return the path to that, since
|
|
|
|
// that's more intuitive (the copied path is trivial to derive
|
|
|
|
// by hand given VERSION)
|
2014-08-08 07:01:55 +04:00
|
|
|
initPath := utils.DockerInitPath("")
|
|
|
|
if initPath == "" {
|
|
|
|
// if that fails, we'll just return the path from the daemon
|
2015-07-31 00:01:53 +03:00
|
|
|
initPath = daemon.systemInitPath()
|
2014-08-08 07:01:55 +04:00
|
|
|
}
|
|
|
|
|
2015-08-06 14:54:48 +03:00
|
|
|
sysInfo := sysinfo.New(false)
|
|
|
|
|
2015-04-10 20:26:30 +03:00
|
|
|
v := &types.Info{
|
|
|
|
ID: daemon.ID,
|
2015-09-29 20:40:17 +03:00
|
|
|
Containers: len(daemon.List(ctx)),
|
2015-04-10 20:26:30 +03:00
|
|
|
Images: imgcount,
|
2015-09-29 20:40:17 +03:00
|
|
|
Driver: daemon.GraphDriver(ctx).String(),
|
|
|
|
DriverStatus: daemon.GraphDriver(ctx).Status(),
|
2015-08-06 14:54:48 +03:00
|
|
|
IPv4Forwarding: !sysInfo.IPv4ForwardingDisabled,
|
|
|
|
BridgeNfIptables: !sysInfo.BridgeNfCallIptablesDisabled,
|
2015-07-23 12:40:54 +03:00
|
|
|
BridgeNfIP6tables: !sysInfo.BridgeNfCallIP6tablesDisabled,
|
2015-04-10 20:26:30 +03:00
|
|
|
Debug: os.Getenv("DEBUG") != "",
|
|
|
|
NFd: fileutils.GetTotalUsedFds(),
|
|
|
|
NGoroutines: runtime.NumGoroutine(),
|
|
|
|
SystemTime: time.Now().Format(time.RFC3339Nano),
|
2015-09-29 20:40:17 +03:00
|
|
|
ExecutionDriver: daemon.ExecutionDriver(ctx).Name(),
|
2015-04-10 20:26:30 +03:00
|
|
|
LoggingDriver: daemon.defaultLogConfig.Type,
|
|
|
|
NEventsListener: daemon.EventsService.SubscribersCount(),
|
|
|
|
KernelVersion: kernelVersion,
|
|
|
|
OperatingSystem: operatingSystem,
|
2015-07-21 22:40:36 +03:00
|
|
|
IndexServerAddress: registry.IndexServer,
|
2015-04-10 20:26:30 +03:00
|
|
|
RegistryConfig: daemon.RegistryService.Config,
|
|
|
|
InitSha1: dockerversion.INITSHA1,
|
|
|
|
InitPath: initPath,
|
|
|
|
NCPU: runtime.NumCPU(),
|
|
|
|
MemTotal: meminfo.MemTotal,
|
2015-07-31 00:01:53 +03:00
|
|
|
DockerRootDir: daemon.config().Root,
|
|
|
|
Labels: daemon.config().Labels,
|
2015-05-20 01:09:58 +03:00
|
|
|
ExperimentalBuild: utils.ExperimentalBuild(),
|
2015-09-21 07:23:54 +03:00
|
|
|
ServerVersion: dockerversion.VERSION,
|
2015-09-11 02:12:00 +03:00
|
|
|
ClusterStore: daemon.config().ClusterStore,
|
2015-04-10 20:26:30 +03:00
|
|
|
}
|
|
|
|
|
2015-07-10 02:37:54 +03:00
|
|
|
// TODO Windows. Refactor this more once sysinfo is refactored into
|
|
|
|
// platform specific code. On Windows, sysinfo.cgroupMemInfo and
|
|
|
|
// sysinfo.cgroupCpuInfo will be nil otherwise and cause a SIGSEGV if
|
|
|
|
// an attempt is made to access through them.
|
|
|
|
if runtime.GOOS != "windows" {
|
2015-08-06 14:54:48 +03:00
|
|
|
v.MemoryLimit = sysInfo.MemoryLimit
|
|
|
|
v.SwapLimit = sysInfo.SwapLimit
|
|
|
|
v.OomKillDisable = sysInfo.OomKillDisable
|
2015-07-23 12:40:54 +03:00
|
|
|
v.CPUCfsPeriod = sysInfo.CPUCfsPeriod
|
|
|
|
v.CPUCfsQuota = sysInfo.CPUCfsQuota
|
2015-07-10 02:37:54 +03:00
|
|
|
}
|
|
|
|
|
2015-03-26 04:40:23 +03:00
|
|
|
if httpProxy := os.Getenv("http_proxy"); httpProxy != "" {
|
2015-07-23 12:40:54 +03:00
|
|
|
v.HTTPProxy = httpProxy
|
2015-03-03 06:15:17 +03:00
|
|
|
}
|
2015-03-26 04:40:23 +03:00
|
|
|
if httpsProxy := os.Getenv("https_proxy"); httpsProxy != "" {
|
2015-07-23 12:40:54 +03:00
|
|
|
v.HTTPSProxy = httpsProxy
|
2015-03-03 06:15:17 +03:00
|
|
|
}
|
2015-03-26 04:40:23 +03:00
|
|
|
if noProxy := os.Getenv("no_proxy"); noProxy != "" {
|
2015-04-10 20:26:30 +03:00
|
|
|
v.NoProxy = noProxy
|
2015-03-03 06:15:17 +03:00
|
|
|
}
|
2014-11-17 22:23:41 +03:00
|
|
|
if hostname, err := os.Hostname(); err == nil {
|
2015-04-10 20:26:30 +03:00
|
|
|
v.Name = hostname
|
2014-11-17 22:23:41 +03:00
|
|
|
}
|
2015-04-10 20:26:30 +03:00
|
|
|
|
|
|
|
return v, nil
|
2014-08-08 07:01:55 +04:00
|
|
|
}
|