Merge pull request #7215 from tiborvass/add-os-to-docker-info

Add OS to docker info
This commit is contained in:
unclejack 2014-07-30 18:02:45 +03:00
commit c18b38f912
6 changed files with 193 additions and 19 deletions

View File

@ -493,6 +493,7 @@ func (cli *DockerCli) CmdInfo(args ...string) error {
}
fmt.Fprintf(cli.out, "Execution Driver: %s\n", remoteInfo.Get("ExecutionDriver"))
fmt.Fprintf(cli.out, "Kernel Version: %s\n", remoteInfo.Get("KernelVersion"))
fmt.Fprintf(cli.out, "Operating System: %s\n", remoteInfo.Get("OperatingSystem"))
if remoteInfo.GetBool("Debug") || os.Getenv("DEBUG") != "" {
fmt.Fprintf(cli.out, "Debug mode (server): %v\n", remoteInfo.GetBool("Debug"))

View File

@ -29,18 +29,14 @@ There are no available options.
Here is a sample output:
# docker info
Containers: 18
Images: 95
Storage Driver: devicemapper
Pool Name: docker-8:1-170408448-pool
Data file: /var/lib/docker/devicemapper/devicemapper/data
Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata
Data Space Used: 9946.3 Mb
Data Space Total: 102400.0 Mb
Metadata Space Used: 9.9 Mb
Metadata Space Total: 2048.0 Mb
Execution Driver: native-0.1
Kernel Version: 3.10.0-116.el7.x86_64
Containers: 14
Images: 52
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Dirs: 80
Execution Driver: native-0.2
Kernel Version: 3.13.0-24-generic
Operating System: Ubuntu 14.04 LTS
# HISTORY
April 2014, Originally compiled by William Henry (whenry at redhat dot com)

View File

@ -605,18 +605,19 @@ tar, then the ownerships might not get preserved.
For example:
$ sudo docker -D info
Containers: 16
Images: 2138
Containers: 14
Images: 52
Storage Driver: btrfs
Execution Driver: native-0.1
Kernel Version: 3.12.0-1-amd64
Execution Driver: native-0.2
Kernel Version: 3.13.0-24-generic
Operating System: Ubuntu 14.04 LTS
Debug mode (server): false
Debug mode (client): true
Fds: 16
Goroutines: 104
Fds: 10
Goroutines: 9
EventsListeners: 0
Init Path: /usr/bin/docker
Sockets: [unix:///var/run/docker.sock tcp://0.0.0.0:4243]
Sockets: [unix:///var/run/docker.sock]
Username: svendowideit
Registry: [https://index.docker.io/v1/]

View File

@ -0,0 +1,40 @@
package operatingsystem
import (
"bytes"
"errors"
"io/ioutil"
)
var (
// file to use to detect if the daemon is running in a container
proc1Cgroup = "/proc/1/cgroup"
// file to check to determine Operating System
etcOsRelease = "/etc/os-release"
)
func GetOperatingSystem() (string, error) {
b, err := ioutil.ReadFile(etcOsRelease)
if err != nil {
return "", err
}
if i := bytes.Index(b, []byte("PRETTY_NAME")); i >= 0 {
b = b[i+13:]
return string(b[:bytes.IndexByte(b, '"')]), nil
}
return "", errors.New("PRETTY_NAME not found")
}
func IsContainerized() (bool, error) {
b, err := ioutil.ReadFile(proc1Cgroup)
if err != nil {
return false, err
}
for _, line := range bytes.Split(b, []byte{'\n'}) {
if len(line) > 0 && !bytes.HasSuffix(line, []byte{'/'}) {
return true, nil
}
}
return false, nil
}

View File

@ -0,0 +1,123 @@
package operatingsystem
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
)
func TestGetOperatingSystem(t *testing.T) {
var (
backup = etcOsRelease
ubuntuTrusty = []byte(`NAME="Ubuntu"
VERSION="14.04, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 14.04 LTS"
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`)
gentoo = []byte(`NAME=Gentoo
ID=gentoo
PRETTY_NAME="Gentoo/Linux"
ANSI_COLOR="1;32"
HOME_URL="http://www.gentoo.org/"
SUPPORT_URL="http://www.gentoo.org/main/en/support.xml"
BUG_REPORT_URL="https://bugs.gentoo.org/"
`)
noPrettyName = []byte(`NAME="Ubuntu"
VERSION="14.04, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`)
)
dir := os.TempDir()
defer func() {
etcOsRelease = backup
os.RemoveAll(dir)
}()
etcOsRelease = filepath.Join(dir, "etcOsRelease")
for expect, osRelease := range map[string][]byte{
"Ubuntu 14.04 LTS": ubuntuTrusty,
"Gentoo/Linux": gentoo,
"": noPrettyName,
} {
if err := ioutil.WriteFile(etcOsRelease, osRelease, 0600); err != nil {
t.Fatalf("failed to write to %s: %v", etcOsRelease, err)
}
s, err := GetOperatingSystem()
if s != expect {
if expect == "" {
t.Fatalf("Expected error 'PRETTY_NAME not found', but got %v", err)
} else {
t.Fatalf("Expected '%s', but got '%s'. Err=%v", expect, s, err)
}
}
}
}
func TestIsContainerized(t *testing.T) {
var (
backup = proc1Cgroup
nonContainerizedProc1Cgroup = []byte(`14:name=systemd:/
13:hugetlb:/
12:net_prio:/
11:perf_event:/
10:bfqio:/
9:blkio:/
8:net_cls:/
7:freezer:/
6:devices:/
5:memory:/
4:cpuacct:/
3:cpu:/
2:cpuset:/
`)
containerizedProc1Cgroup = []byte(`9:perf_event:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
8:blkio:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
7:net_cls:/
6:freezer:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
5:devices:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
4:memory:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
3:cpuacct:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
2:cpu:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
1:cpuset:/`)
)
dir := os.TempDir()
defer func() {
proc1Cgroup = backup
os.RemoveAll(dir)
}()
proc1Cgroup = filepath.Join(dir, "proc1Cgroup")
if err := ioutil.WriteFile(proc1Cgroup, nonContainerizedProc1Cgroup, 0600); err != nil {
t.Fatalf("failed to write to %s: %v", proc1Cgroup, err)
}
inContainer, err := IsContainerized()
if err != nil {
t.Fatal(err)
}
if inContainer {
t.Fatal("Wrongly assuming containerized")
}
if err := ioutil.WriteFile(proc1Cgroup, containerizedProc1Cgroup, 0600); err != nil {
t.Fatalf("failed to write to %s: %v", proc1Cgroup, err)
}
inContainer, err = IsContainerized()
if err != nil {
t.Fatal(err)
}
if !inContainer {
t.Fatal("Wrongly assuming non-containerized")
}
}

View File

@ -57,6 +57,7 @@ import (
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/parsers/filters"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/docker/pkg/parsers/operatingsystem"
"github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/tailfile"
"github.com/docker/docker/registry"
@ -795,6 +796,17 @@ func (srv *Server) DockerInfo(job *engine.Job) engine.Status {
kernelVersion = kv.String()
}
operatingSystem := "<unknown>"
if s, err := operatingsystem.GetOperatingSystem(); err == nil {
operatingSystem = s
}
if inContainer, err := operatingsystem.IsContainerized(); err != nil {
utils.Errorf("Could not determine if daemon is containerized: %v", err)
operatingSystem += " (error determining if containerized)"
} else if inContainer {
operatingSystem += " (containerized)"
}
// 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)
initPath := utils.DockerInitPath("")
if initPath == "" {
@ -816,6 +828,7 @@ func (srv *Server) DockerInfo(job *engine.Job) engine.Status {
v.Set("ExecutionDriver", srv.daemon.ExecutionDriver().Name())
v.SetInt("NEventsListener", srv.eventPublisher.SubscribersCount())
v.Set("KernelVersion", kernelVersion)
v.Set("OperatingSystem", operatingSystem)
v.Set("IndexServerAddress", registry.IndexServerAddress())
v.Set("InitSha1", dockerversion.INITSHA1)
v.Set("InitPath", initPath)