Merge pull request #40 from vmarmol/switch-libcontainer

Switching from using Docker config to libcontainer config for ContainerSpec.
This commit is contained in:
monnand 2014-06-13 15:14:00 -04:00
commit 76b8af706e

View File

@ -24,9 +24,9 @@ import (
"strings" "strings"
"time" "time"
"github.com/docker/libcontainer"
"github.com/docker/libcontainer/cgroups" "github.com/docker/libcontainer/cgroups"
"github.com/docker/libcontainer/cgroups/fs" "github.com/docker/libcontainer/cgroups/fs"
"github.com/dotcloud/docker/nat"
"github.com/fsouza/go-dockerclient" "github.com/fsouza/go-dockerclient"
"github.com/google/cadvisor/container" "github.com/google/cadvisor/container"
"github.com/google/cadvisor/info" "github.com/google/cadvisor/info"
@ -85,96 +85,17 @@ func (self *dockerContainerHandler) isDockerContainer() bool {
return (!self.isDockerRoot()) && (!self.isRootContainer()) return (!self.isDockerRoot()) && (!self.isRootContainer())
} }
type dockerPortBinding struct { // TODO(vmarmol): Switch to getting this from libcontainer once we have a solid API.
HostIp string func readLibcontainerSpec(id string) (spec *libcontainer.Container, err error) {
HostPort string dir := "/var/lib/docker/execdriver/native"
} configPath := path.Join(dir, id, "container.json")
type dockerPort string
type dockerPortMap map[dockerPort][]dockerPortBinding
type dockerNetworkSettings struct {
IPAddress string
IPPrefixLen int
Gateway string
Bridge string
Ports dockerPortMap
}
type dockerContainerConfig struct {
Hostname string
Domainname string
User string
Memory int64 // Memory limit (in bytes)
MemorySwap int64 // Total memory usage (memory + swap); set `-1' to disable swap
CpuShares int64 // CPU shares (relative weight vs. other containers)
Cpuset string // Cpuset 0-2, 0,1
AttachStdin bool
AttachStdout bool
AttachStderr bool
PortSpecs []string // Deprecated - Can be in the format of 8080/tcp
ExposedPorts map[nat.Port]struct{}
Tty bool // Attach standard streams to a tty, including stdin if it is not closed.
OpenStdin bool // Open stdin
StdinOnce bool // If true, close stdin after the 1 attached client disconnects.
Env []string
Cmd []string
Image string // Name of the image as it was passed by the operator (eg. could be symbolic)
Volumes map[string]struct{}
WorkingDir string
Entrypoint []string
NetworkDisabled bool
OnBuild []string
}
type dockerState struct {
Running bool
Pid int
ExitCode int
StartedAt time.Time
FinishedAt time.Time
}
type dockerContainerSpec struct {
ID string
Created time.Time
Path string
Args []string
Config *dockerContainerConfig
State dockerState
Image string
NetworkSettings *dockerNetworkSettings
ResolvConfPath string
HostnamePath string
HostsPath string
Name string
Driver string
ExecDriver string
MountLabel, ProcessLabel string
Volumes map[string]string
// Store rw/ro in a separate structure to preserve reverse-compatibility on-disk.
// Easier than migrating older container configs :)
VolumesRW map[string]bool
// contains filtered or unexported fields
}
func readDockerSpec(id string) (spec *dockerContainerSpec, err error) {
dir := "/var/lib/docker/containers"
configPath := path.Join(dir, id, "config.json")
f, err := os.Open(configPath) f, err := os.Open(configPath)
if err != nil { if err != nil {
return return
} }
defer f.Close() defer f.Close()
d := json.NewDecoder(f) d := json.NewDecoder(f)
ret := new(dockerContainerSpec) ret := new(libcontainer.Container)
err = d.Decode(ret) err = d.Decode(ret)
if err != nil { if err != nil {
return return
@ -183,29 +104,30 @@ func readDockerSpec(id string) (spec *dockerContainerSpec, err error) {
return return
} }
func dockerConfigToContainerSpec(config *dockerContainerSpec, mi *info.MachineInfo) *info.ContainerSpec { func libcontainerConfigToContainerSpec(config *libcontainer.Container, mi *info.MachineInfo) *info.ContainerSpec {
spec := new(info.ContainerSpec) spec := new(info.ContainerSpec)
spec.Memory = new(info.MemorySpec) spec.Memory = new(info.MemorySpec)
spec.Memory.Limit = math.MaxUint64 spec.Memory.Limit = math.MaxUint64
spec.Memory.SwapLimit = math.MaxUint64 spec.Memory.SwapLimit = math.MaxUint64
if config.Config.Memory > 0 { if config.Cgroups.Memory > 0 {
spec.Memory.Limit = uint64(config.Config.Memory) spec.Memory.Limit = uint64(config.Cgroups.Memory)
} }
if config.Config.MemorySwap > 0 { if config.Cgroups.MemorySwap > 0 {
spec.Memory.SwapLimit = uint64(config.Config.MemorySwap - config.Config.Memory) spec.Memory.SwapLimit = uint64(config.Cgroups.MemorySwap)
} }
if mi != nil {
spec.Cpu = new(info.CpuSpec) // Get CPU info
spec.Cpu.Limit = math.MaxUint64 spec.Cpu = new(info.CpuSpec)
n := mi.NumCores / 64 spec.Cpu.Limit = 1024
if mi.NumCores%64 > 0 { if config.Cgroups.CpuShares != 0 {
n++ spec.Cpu.Limit = uint64(config.Cgroups.CpuShares)
}
spec.Cpu.Mask.Data = make([]uint64, n)
for i := 0; i < n; i++ {
spec.Cpu.Mask.Data[i] = math.MaxUint64
}
} }
n := (mi.NumCores + 63) / 64
spec.Cpu.Mask.Data = make([]uint64, n)
for i := 0; i < n; i++ {
spec.Cpu.Mask.Data[i] = math.MaxUint64
}
// TODO(vmarmol): Get CPUs from config.Cgroups.CpusetCpus
return spec return spec
} }
@ -222,12 +144,12 @@ func (self *dockerContainerHandler) GetSpec() (spec *info.ContainerSpec, err err
if err != nil { if err != nil {
return return
} }
dspec, err := readDockerSpec(id) libcontainerSpec, err := readLibcontainerSpec(id)
if err != nil { if err != nil {
return return
} }
spec = dockerConfigToContainerSpec(dspec, mi) spec = libcontainerConfigToContainerSpec(libcontainerSpec, mi)
return return
} }