Merge pull request #220 from vmarmol/coreos
Fix name resolution in Systemd systems
This commit is contained in:
commit
1ed9d122c1
@ -17,7 +17,6 @@ package docker
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -77,11 +76,12 @@ func (self *dockerFactory) CanHandle(name string) (bool, error) {
|
|||||||
} else if !strings.HasPrefix(name, "/docker/") {
|
} else if !strings.HasPrefix(name, "/docker/") {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the container is known to docker and it is active.
|
// Check if the container is known to docker and it is active.
|
||||||
id := path.Base(name)
|
id := containerNameToDockerId(name, self.useSystemd)
|
||||||
ctnr, err := self.client.InspectContainer(id)
|
|
||||||
// We assume that if Inspect fails then the container is not known to docker.
|
// We assume that if Inspect fails then the container is not known to docker.
|
||||||
// TODO(vishh): Detect lxc containers and avoid handling them.
|
ctnr, err := self.client.InspectContainer(id)
|
||||||
if err != nil || !ctnr.State.Running {
|
if err != nil || !ctnr.State.Running {
|
||||||
return false, fmt.Errorf("error inspecting container: %v", err)
|
return false, fmt.Errorf("error inspecting container: %v", err)
|
||||||
}
|
}
|
||||||
@ -156,7 +156,6 @@ func Register(factory info.MachineInfoFactory) error {
|
|||||||
if f.useSystemd {
|
if f.useSystemd {
|
||||||
glog.Infof("System is using systemd")
|
glog.Infof("System is using systemd")
|
||||||
}
|
}
|
||||||
glog.Infof("Registering Docker factory")
|
|
||||||
container.RegisterContainerHandlerFactory(f)
|
container.RegisterContainerHandlerFactory(f)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -42,12 +42,12 @@ var fileNotFound = errors.New("file not found")
|
|||||||
type dockerContainerHandler struct {
|
type dockerContainerHandler struct {
|
||||||
client *docker.Client
|
client *docker.Client
|
||||||
name string
|
name string
|
||||||
parent string
|
|
||||||
id string
|
id string
|
||||||
aliases []string
|
aliases []string
|
||||||
machineInfoFactory info.MachineInfoFactory
|
machineInfoFactory info.MachineInfoFactory
|
||||||
useSystemd bool
|
useSystemd bool
|
||||||
libcontainerStateDir string
|
libcontainerStateDir string
|
||||||
|
cgroup cgroups.Cgroup
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDockerContainerHandler(
|
func newDockerContainerHandler(
|
||||||
@ -63,12 +63,15 @@ func newDockerContainerHandler(
|
|||||||
machineInfoFactory: machineInfoFactory,
|
machineInfoFactory: machineInfoFactory,
|
||||||
useSystemd: useSystemd,
|
useSystemd: useSystemd,
|
||||||
libcontainerStateDir: path.Join(dockerRootDir, pathToLibcontainerState),
|
libcontainerStateDir: path.Join(dockerRootDir, pathToLibcontainerState),
|
||||||
|
cgroup: cgroups.Cgroup{
|
||||||
|
Parent: "/",
|
||||||
|
Name: name,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
if handler.isDockerRoot() {
|
if handler.isDockerRoot() {
|
||||||
return handler, nil
|
return handler, nil
|
||||||
}
|
}
|
||||||
id := path.Base(name)
|
id := containerNameToDockerId(name, useSystemd)
|
||||||
handler.parent = path.Dir(name)
|
|
||||||
handler.id = id
|
handler.id = id
|
||||||
ctnr, err := client.InspectContainer(id)
|
ctnr, err := client.InspectContainer(id)
|
||||||
// We assume that if Inspect fails then the container is not known to docker.
|
// We assume that if Inspect fails then the container is not known to docker.
|
||||||
@ -79,6 +82,25 @@ func newDockerContainerHandler(
|
|||||||
return handler, nil
|
return handler, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func containerNameToDockerId(name string, useSystemd bool) string {
|
||||||
|
id := path.Base(name)
|
||||||
|
|
||||||
|
// Turn systemd cgroup name into Docker ID.
|
||||||
|
if useSystemd {
|
||||||
|
const systemdDockerPrefix = "docker-"
|
||||||
|
if strings.HasPrefix(id, systemdDockerPrefix) {
|
||||||
|
id = id[len(systemdDockerPrefix):]
|
||||||
|
}
|
||||||
|
|
||||||
|
const systemdScopeSuffix = ".scope"
|
||||||
|
if strings.HasSuffix(id, systemdScopeSuffix) {
|
||||||
|
id = id[:len(id)-len(systemdScopeSuffix)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
func (self *dockerContainerHandler) ContainerReference() (info.ContainerReference, error) {
|
func (self *dockerContainerHandler) ContainerReference() (info.ContainerReference, error) {
|
||||||
return info.ContainerReference{
|
return info.ContainerReference{
|
||||||
Name: self.name,
|
Name: self.name,
|
||||||
@ -112,8 +134,7 @@ func (self *dockerContainerHandler) readLibcontainerConfig() (config *libcontain
|
|||||||
config = retConfig
|
config = retConfig
|
||||||
|
|
||||||
// Replace cgroup parent and name with our own since we may be running in a different context.
|
// Replace cgroup parent and name with our own since we may be running in a different context.
|
||||||
config.Cgroups.Parent = self.parent
|
*config.Cgroups = self.cgroup
|
||||||
config.Cgroups.Name = self.id
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -199,14 +220,6 @@ func (self *dockerContainerHandler) GetStats() (stats *info.ContainerStats, err
|
|||||||
if self.isDockerRoot() {
|
if self.isDockerRoot() {
|
||||||
return &info.ContainerStats{}, nil
|
return &info.ContainerStats{}, nil
|
||||||
}
|
}
|
||||||
config, err := self.readLibcontainerConfig()
|
|
||||||
if err != nil {
|
|
||||||
if err == fileNotFound {
|
|
||||||
glog.Errorf("Libcontainer config not found for container %q", self.name)
|
|
||||||
return &info.ContainerStats{}, nil
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
state, err := self.readLibcontainerState()
|
state, err := self.readLibcontainerState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == fileNotFound {
|
if err == fileNotFound {
|
||||||
@ -216,7 +229,7 @@ func (self *dockerContainerHandler) GetStats() (stats *info.ContainerStats, err
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return containerLibcontainer.GetStats(config, state)
|
return containerLibcontainer.GetStats(&self.cgroup, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *dockerContainerHandler) ListContainers(listType container.ListType) ([]info.ContainerReference, error) {
|
func (self *dockerContainerHandler) ListContainers(listType container.ListType) ([]info.ContainerReference, error) {
|
||||||
@ -258,11 +271,7 @@ func (self *dockerContainerHandler) ListThreads(listType container.ListType) ([]
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *dockerContainerHandler) ListProcesses(listType container.ListType) ([]int, error) {
|
func (self *dockerContainerHandler) ListProcesses(listType container.ListType) ([]int, error) {
|
||||||
c := &cgroups.Cgroup{
|
return fs.GetPids(&self.cgroup)
|
||||||
Parent: self.parent,
|
|
||||||
Name: self.id,
|
|
||||||
}
|
|
||||||
return fs.GetPids(c)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *dockerContainerHandler) WatchSubcontainers(events chan container.SubcontainerEvent) error {
|
func (self *dockerContainerHandler) WatchSubcontainers(events chan container.SubcontainerEvent) error {
|
||||||
|
@ -20,17 +20,23 @@ import (
|
|||||||
"github.com/docker/libcontainer"
|
"github.com/docker/libcontainer"
|
||||||
"github.com/docker/libcontainer/cgroups"
|
"github.com/docker/libcontainer/cgroups"
|
||||||
cgroupfs "github.com/docker/libcontainer/cgroups/fs"
|
cgroupfs "github.com/docker/libcontainer/cgroups/fs"
|
||||||
|
"github.com/docker/libcontainer/network"
|
||||||
"github.com/google/cadvisor/info"
|
"github.com/google/cadvisor/info"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Get stats of the specified container
|
// Get stats of the specified container
|
||||||
func GetStats(config *libcontainer.Config, state *libcontainer.State) (*info.ContainerStats, error) {
|
func GetStats(cgroup *cgroups.Cgroup, state *libcontainer.State) (*info.ContainerStats, error) {
|
||||||
// TODO(vmarmol): Use libcontainer's Stats() in the new API when that is ready.
|
// TODO(vmarmol): Use libcontainer's Stats() in the new API when that is ready.
|
||||||
libcontainerStats, err := libcontainer.GetStats(config, state)
|
stats := &libcontainer.ContainerStats{}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
stats.CgroupStats, err = cgroupfs.GetStats(cgroup)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return &info.ContainerStats{}, err
|
||||||
}
|
}
|
||||||
return toContainerStats(libcontainerStats), nil
|
|
||||||
|
stats.NetworkStats, err = network.GetStats(&state.NetworkState)
|
||||||
|
return toContainerStats(stats), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetStatsCgroupOnly(cgroup *cgroups.Cgroup) (*info.ContainerStats, error) {
|
func GetStatsCgroupOnly(cgroup *cgroups.Cgroup) (*info.ContainerStats, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user