2016-11-11 08:02:23 -08:00
// +build !windows
2018-02-05 16:05:59 -05:00
package daemon // import "github.com/docker/docker/daemon"
2016-11-11 08:02:23 -08:00
import (
2017-11-03 01:21:18 +01:00
"context"
2018-07-19 13:45:32 +02:00
"fmt"
2016-11-11 08:02:23 -08:00
"os/exec"
"strings"
"github.com/docker/docker/api/types"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/pkg/sysinfo"
2017-03-29 13:44:14 +02:00
"github.com/pkg/errors"
2017-07-26 14:42:13 -07:00
"github.com/sirupsen/logrus"
2016-11-11 08:02:23 -08:00
)
2018-07-13 13:14:45 +02:00
// fillPlatformInfo fills the platform related info.
func ( daemon * Daemon ) fillPlatformInfo ( v * types . Info , sysInfo * sysinfo . SysInfo ) {
2016-11-11 08:02:23 -08:00
v . MemoryLimit = sysInfo . MemoryLimit
v . SwapLimit = sysInfo . SwapLimit
v . KernelMemory = sysInfo . KernelMemory
2018-05-11 19:46:11 +00:00
v . KernelMemoryTCP = sysInfo . KernelMemoryTCP
2016-11-11 08:02:23 -08:00
v . OomKillDisable = sysInfo . OomKillDisable
v . CPUCfsPeriod = sysInfo . CPUCfsPeriod
v . CPUCfsQuota = sysInfo . CPUCfsQuota
v . CPUShares = sysInfo . CPUShares
v . CPUSet = sysInfo . Cpuset
v . Runtimes = daemon . configStore . GetAllRuntimes ( )
v . DefaultRuntime = daemon . configStore . GetDefaultRuntimeName ( )
v . InitBinary = daemon . configStore . GetInitPath ( )
2017-09-22 06:52:41 -07:00
defaultRuntimeBinary := daemon . configStore . GetRuntime ( v . DefaultRuntime ) . Path
2017-06-10 03:07:21 +02:00
if rv , err := exec . Command ( defaultRuntimeBinary , "--version" ) . Output ( ) ; err == nil {
2016-11-11 08:02:23 -08:00
parts := strings . Split ( strings . TrimSpace ( string ( rv ) ) , "\n" )
if len ( parts ) == 3 {
parts = strings . Split ( parts [ 1 ] , ": " )
if len ( parts ) == 2 {
v . RuncCommit . ID = strings . TrimSpace ( parts [ 1 ] )
}
}
if v . RuncCommit . ID == "" {
2017-06-06 19:36:24 +02:00
logrus . Warnf ( "failed to retrieve %s version: unknown output format: %s" , defaultRuntimeBinary , string ( rv ) )
2016-11-11 08:02:23 -08:00
v . RuncCommit . ID = "N/A"
}
} else {
2017-06-06 19:36:24 +02:00
logrus . Warnf ( "failed to retrieve %s version: %v" , defaultRuntimeBinary , err )
2016-11-11 08:02:23 -08:00
v . RuncCommit . ID = "N/A"
}
2018-10-04 23:17:13 +02:00
// runc is now shipped as a separate package. Set "expected" to same value
// as "ID" to prevent clients from reporting a version-mismatch
v . RuncCommit . Expected = v . RuncCommit . ID
2017-11-03 01:21:18 +01:00
if rv , err := daemon . containerd . Version ( context . Background ( ) ) ; err == nil {
v . ContainerdCommit . ID = rv . Revision
2017-09-22 06:52:41 -07:00
} else {
2017-11-03 01:21:18 +01:00
logrus . Warnf ( "failed to retrieve containerd version: %v" , err )
2017-09-22 06:52:41 -07:00
v . ContainerdCommit . ID = "N/A"
}
2018-10-04 23:17:13 +02:00
// containerd is now shipped as a separate package. Set "expected" to same
// value as "ID" to prevent clients from reporting a version-mismatch
v . ContainerdCommit . Expected = v . ContainerdCommit . ID
2017-06-06 19:36:24 +02:00
defaultInitBinary := daemon . configStore . GetInitPath ( )
if rv , err := exec . Command ( defaultInitBinary , "--version" ) . Output ( ) ; err == nil {
2017-03-29 13:44:14 +02:00
ver , err := parseInitVersion ( string ( rv ) )
2017-03-28 15:18:39 -07:00
2017-03-29 13:44:14 +02:00
if err != nil {
2017-06-06 19:36:24 +02:00
logrus . Warnf ( "failed to retrieve %s version: %s" , defaultInitBinary , err )
2016-11-11 08:02:23 -08:00
}
2017-03-29 13:44:14 +02:00
v . InitCommit = ver
2016-11-11 08:02:23 -08:00
} else {
2017-06-06 19:36:24 +02:00
logrus . Warnf ( "failed to retrieve %s version: %s" , defaultInitBinary , err )
2016-11-11 08:02:23 -08:00
v . InitCommit . ID = "N/A"
}
2018-07-19 13:45:32 +02:00
if ! v . MemoryLimit {
v . Warnings = append ( v . Warnings , "WARNING: No memory limit support" )
}
if ! v . SwapLimit {
v . Warnings = append ( v . Warnings , "WARNING: No swap limit support" )
}
if ! v . KernelMemory {
v . Warnings = append ( v . Warnings , "WARNING: No kernel memory limit support" )
}
2018-11-27 22:47:39 +01:00
if ! v . KernelMemoryTCP {
v . Warnings = append ( v . Warnings , "WARNING: No kernel memory TCP limit support" )
}
2018-07-19 13:45:32 +02:00
if ! v . OomKillDisable {
v . Warnings = append ( v . Warnings , "WARNING: No oom kill disable support" )
}
if ! v . CPUCfsQuota {
v . Warnings = append ( v . Warnings , "WARNING: No cpu cfs quota support" )
}
if ! v . CPUCfsPeriod {
v . Warnings = append ( v . Warnings , "WARNING: No cpu cfs period support" )
}
if ! v . CPUShares {
v . Warnings = append ( v . Warnings , "WARNING: No cpu shares support" )
}
if ! v . CPUSet {
v . Warnings = append ( v . Warnings , "WARNING: No cpuset support" )
}
if ! v . IPv4Forwarding {
v . Warnings = append ( v . Warnings , "WARNING: IPv4 forwarding is disabled" )
}
if ! v . BridgeNfIptables {
v . Warnings = append ( v . Warnings , "WARNING: bridge-nf-call-iptables is disabled" )
}
if ! v . BridgeNfIP6tables {
v . Warnings = append ( v . Warnings , "WARNING: bridge-nf-call-ip6tables is disabled" )
}
}
func fillDriverWarnings ( v * types . Info ) {
for _ , pair := range v . DriverStatus {
if pair [ 0 ] == "Data loop file" {
msg := fmt . Sprintf ( "WARNING: %s: usage of loopback devices is " +
"strongly discouraged for production use.\n " +
"Use `--storage-opt dm.thinpooldev` to specify a custom block storage device." , v . Driver )
v . Warnings = append ( v . Warnings , msg )
continue
}
if pair [ 0 ] == "Supports d_type" && pair [ 1 ] == "false" {
backingFs := getBackingFs ( v )
msg := fmt . Sprintf ( "WARNING: %s: the backing %s filesystem is formatted without d_type support, which leads to incorrect behavior.\n" , v . Driver , backingFs )
if backingFs == "xfs" {
msg += " Reformat the filesystem with ftype=1 to enable d_type support.\n"
}
msg += " Running without d_type support will not be supported in future releases."
v . Warnings = append ( v . Warnings , msg )
continue
}
}
}
func getBackingFs ( v * types . Info ) string {
for _ , pair := range v . DriverStatus {
if pair [ 0 ] == "Backing Filesystem" {
return pair [ 1 ]
}
}
return ""
2016-11-11 08:02:23 -08:00
}
2017-03-29 13:44:14 +02:00
// parseInitVersion parses a Tini version string, and extracts the version.
func parseInitVersion ( v string ) ( types . Commit , error ) {
version := types . Commit { ID : "" , Expected : dockerversion . InitCommitID }
parts := strings . Split ( strings . TrimSpace ( v ) , " - " )
if len ( parts ) >= 2 {
gitParts := strings . Split ( parts [ 1 ] , "." )
if len ( gitParts ) == 2 && gitParts [ 0 ] == "git" {
version . ID = gitParts [ 1 ]
version . Expected = dockerversion . InitCommitID [ 0 : len ( version . ID ) ]
}
}
if version . ID == "" && strings . HasPrefix ( parts [ 0 ] , "tini version " ) {
version . ID = "v" + strings . TrimPrefix ( parts [ 0 ] , "tini version " )
}
if version . ID == "" {
version . ID = "N/A"
return version , errors . Errorf ( "unknown output format: %s" , v )
}
return version , nil
}