Implement GeSpec() in the simple raw driver.

This commit is contained in:
Victor Marmol 2014-07-22 08:44:32 -07:00
parent 03def6fff0
commit e951d03be6
3 changed files with 89 additions and 16 deletions

View File

@ -52,7 +52,7 @@ func main() {
}
// Register the raw driver.
if err := raw.Register(); err != nil {
if err := raw.Register(containerManager); err != nil {
log.Fatalf("raw registration failed: %v.", err)
}

View File

@ -20,15 +20,21 @@ import (
"github.com/docker/libcontainer/cgroups"
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/info"
)
type cgroupSubsystems struct {
// Cgroup subsystem mounts.
mounts []cgroups.Mount
// Cgroup subsystem to their mount location.
mountPoints map[string]string
}
type rawFactory struct {
cgroupSubsystems *cgroupSubsystems
// Factory for machine information.
machineInfoFactory info.MachineInfoFactory
cgroupSubsystems *cgroupSubsystems
}
func (self *rawFactory) String() string {
@ -36,7 +42,7 @@ func (self *rawFactory) String() string {
}
func (self *rawFactory) NewContainerHandler(name string) (container.ContainerHandler, error) {
return newRawContainerHandler(name, self.cgroupSubsystems)
return newRawContainerHandler(name, self.cgroupSubsystems, self.machineInfoFactory)
}
// The raw factory can handle any container.
@ -44,7 +50,7 @@ func (self *rawFactory) CanHandle(name string) bool {
return true
}
func Register() error {
func Register(machineInfoFactory info.MachineInfoFactory) error {
// Get all cgroup mounts.
allCgroups, err := cgroups.GetCgroupMounts()
if err != nil {
@ -56,10 +62,12 @@ func Register() error {
// Trim the mounts to only the subsystems we care about.
supportedCgroups := make([]cgroups.Mount, 0, len(allCgroups))
mountPoints := make(map[string]string, len(allCgroups))
for _, mount := range allCgroups {
for _, subsystem := range mount.Subsystems {
if _, ok := supportedSubsystems[subsystem]; ok {
supportedCgroups = append(supportedCgroups, mount)
mountPoints[subsystem] = mount.Mountpoint
}
}
}
@ -69,8 +77,10 @@ func Register() error {
log.Printf("Registering Raw factory")
factory := &rawFactory{
machineInfoFactory: machineInfoFactory,
cgroupSubsystems: &cgroupSubsystems{
mounts: supportedCgroups,
mounts: supportedCgroups,
mountPoints: mountPoints,
},
}
container.RegisterContainerHandlerFactory(factory)

View File

@ -16,23 +16,30 @@ package raw
import (
"io/ioutil"
"log"
"math"
"path/filepath"
"strconv"
"strings"
"github.com/docker/libcontainer/cgroups"
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/info"
"github.com/google/cadvisor/utils"
)
type rawContainerHandler struct {
name string
cgroupSubsystems *cgroupSubsystems
name string
cgroupSubsystems *cgroupSubsystems
machineInfoFactory info.MachineInfoFactory
}
func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems) (container.ContainerHandler, error) {
func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, machineInfoFactory info.MachineInfoFactory) (container.ContainerHandler, error) {
return &rawContainerHandler{
name: name,
cgroupSubsystems: cgroupSubsystems,
name: name,
cgroupSubsystems: cgroupSubsystems,
machineInfoFactory: machineInfoFactory,
}, nil
}
@ -43,13 +50,69 @@ func (self *rawContainerHandler) ContainerReference() (info.ContainerReference,
}, nil
}
func (self *rawContainerHandler) GetSpec() (*info.ContainerSpec, error) {
ret := new(info.ContainerSpec)
ret.Cpu = new(info.CpuSpec)
ret.Memory = new(info.MemorySpec)
func readInt64(path string, file string) uint64 {
cgroupFile := filepath.Join(path, file)
// TODO(vmarmol): Implement
return ret, nil
// Ignore non-existent files
if !utils.FileExists(cgroupFile) {
return 0
}
// Read
out, err := ioutil.ReadFile(cgroupFile)
if err != nil {
log.Printf("raw driver: Failed to read %q: %s", cgroupFile, err)
return 0
}
val, err := strconv.ParseUint(strings.TrimSpace(string(out)), 10, 64)
if err != nil {
log.Printf("raw driver: Failed to parse in %q from file %q: %s", string(out), cgroupFile, err)
return 0
}
return val
}
func (self *rawContainerHandler) GetSpec() (*info.ContainerSpec, error) {
spec := new(info.ContainerSpec)
// The raw driver assumes unified hierarchy containers.
// CPU.
cpuRoot, ok := self.cgroupSubsystems.mountPoints["cpu"]
if ok {
cpuRoot = filepath.Join(cpuRoot, self.name)
if utils.FileExists(cpuRoot) {
// Get machine info.
mi, err := self.machineInfoFactory.GetMachineInfo()
if err != nil {
return nil, err
}
spec.Cpu = new(info.CpuSpec)
spec.Cpu.Limit = readInt64(cpuRoot, "cpu.shares")
// TODO(vmarmol): Get CPUs from config.Cgroups.CpusetCpus
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
}
}
}
// Memory.
memoryRoot, ok := self.cgroupSubsystems.mountPoints["memory"]
if ok {
memoryRoot = filepath.Join(memoryRoot, self.name)
if utils.FileExists(memoryRoot) {
spec.Memory = new(info.MemorySpec)
spec.Memory.Limit = readInt64(memoryRoot, "memory.limit_in_bytes")
spec.Memory.SwapLimit = readInt64(memoryRoot, "memory.limit_in_bytes")
}
}
return spec, nil
}
func (self *rawContainerHandler) GetStats() (stats *info.ContainerStats, err error) {