Flatten ContainerSpec.

This commit is contained in:
Victor Marmol 2014-09-19 10:14:22 -07:00
parent 7c59947ee8
commit e22831f1bd
10 changed files with 73 additions and 69 deletions

View File

@ -41,7 +41,7 @@ type SubcontainerEvent struct {
// Interface for container operation handlers.
type ContainerHandler interface {
ContainerReference() (info.ContainerReference, error)
GetSpec() (*info.ContainerSpec, error)
GetSpec() (info.ContainerSpec, error)
GetStats() (*info.ContainerStats, error)
ListContainers(listType ListType) ([]info.ContainerReference, error)
ListThreads(listType ListType) ([]int, error)

View File

@ -149,9 +149,9 @@ func (self *dockerContainerHandler) readLibcontainerState() (state *libcontainer
return
}
func libcontainerConfigToContainerSpec(config *libcontainer.Config, mi *info.MachineInfo) *info.ContainerSpec {
spec := new(info.ContainerSpec)
spec.Memory = new(info.MemorySpec)
func libcontainerConfigToContainerSpec(config *libcontainer.Config, mi *info.MachineInfo) info.ContainerSpec {
var spec info.ContainerSpec
spec.HasMemory = true
spec.Memory.Limit = math.MaxUint64
spec.Memory.SwapLimit = math.MaxUint64
if config.Cgroups.Memory > 0 {
@ -162,7 +162,7 @@ func libcontainerConfigToContainerSpec(config *libcontainer.Config, mi *info.Mac
}
// Get CPU info
spec.Cpu = new(info.CpuSpec)
spec.HasCpu = true
spec.Cpu.Limit = 1024
if config.Cgroups.CpuShares != 0 {
spec.Cpu.Limit = uint64(config.Cgroups.CpuShares)
@ -173,12 +173,14 @@ func libcontainerConfigToContainerSpec(config *libcontainer.Config, mi *info.Mac
} else {
spec.Cpu.Mask = config.Cgroups.CpusetCpus
}
spec.HasNetwork = true
return spec
}
func (self *dockerContainerHandler) GetSpec() (spec *info.ContainerSpec, err error) {
func (self *dockerContainerHandler) GetSpec() (spec info.ContainerSpec, err error) {
if self.isDockerRoot() {
return &info.ContainerSpec{}, nil
return info.ContainerSpec{}, nil
}
mi, err := self.machineInfoFactory.GetMachineInfo()
if err != nil {

View File

@ -44,9 +44,9 @@ func (self *MockContainerHandler) ContainerReference() (info.ContainerReference,
return args.Get(0).(info.ContainerReference), args.Error(1)
}
func (self *MockContainerHandler) GetSpec() (*info.ContainerSpec, error) {
func (self *MockContainerHandler) GetSpec() (info.ContainerSpec, error) {
args := self.Called()
return args.Get(0).(*info.ContainerSpec), args.Error(1)
return args.Get(0).(info.ContainerSpec), args.Error(1)
}
func (self *MockContainerHandler) GetStats() (*info.ContainerStats, error) {

View File

@ -92,15 +92,15 @@ func readInt64(dirpath string, file string) uint64 {
return val
}
func (self *rawContainerHandler) GetSpec() (*info.ContainerSpec, error) {
spec := new(info.ContainerSpec)
func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) {
var spec info.ContainerSpec
// The raw driver assumes unified hierarchy containers.
// Get machine info.
mi, err := self.machineInfoFactory.GetMachineInfo()
if err != nil {
return nil, err
return spec, err
}
// CPU.
@ -108,7 +108,7 @@ func (self *rawContainerHandler) GetSpec() (*info.ContainerSpec, error) {
if ok {
cpuRoot = path.Join(cpuRoot, self.name)
if utils.FileExists(cpuRoot) {
spec.Cpu = new(info.CpuSpec)
spec.HasCpu = true
spec.Cpu.Limit = readInt64(cpuRoot, "cpu.shares")
}
}
@ -117,11 +117,9 @@ func (self *rawContainerHandler) GetSpec() (*info.ContainerSpec, error) {
// This will fail for non-unified hierarchies. We'll return the whole machine mask in that case.
cpusetRoot, ok := self.cgroupSubsystems.mountPoints["cpuset"]
if ok {
if spec.Cpu == nil {
spec.Cpu = new(info.CpuSpec)
}
cpusetRoot = path.Join(cpusetRoot, self.name)
if utils.FileExists(cpusetRoot) {
spec.HasCpu = true
spec.Cpu.Mask = readString(cpusetRoot, "cpuset.cpus")
if spec.Cpu.Mask == "" {
spec.Cpu.Mask = fmt.Sprintf("0-%d", mi.NumCores-1)
@ -134,7 +132,7 @@ func (self *rawContainerHandler) GetSpec() (*info.ContainerSpec, error) {
if ok {
memoryRoot = path.Join(memoryRoot, self.name)
if utils.FileExists(memoryRoot) {
spec.Memory = new(info.MemorySpec)
spec.HasMemory = true
spec.Memory.Limit = readInt64(memoryRoot, "memory.limit_in_bytes")
spec.Memory.SwapLimit = readInt64(memoryRoot, "memory.memsw.limit_in_bytes")
}

View File

@ -40,8 +40,13 @@ type MemorySpec struct {
}
type ContainerSpec struct {
Cpu *CpuSpec `json:"cpu,omitempty"`
Memory *MemorySpec `json:"memory,omitempty"`
HasCpu bool `json:"has_cpu"`
Cpu CpuSpec `json:"cpu,omitempty"`
HasMemory bool `json:"has_memory"`
Memory MemorySpec `json:"memory,omitempty"`
HasNetwork bool `json:"has_network"`
}
// Container reference contains enough information to uniquely identify a container
@ -66,7 +71,7 @@ type ContainerInfo struct {
Subcontainers []ContainerReference `json:"subcontainers,omitempty"`
// The isolation used in the container.
Spec *ContainerSpec `json:"spec,omitempty"`
Spec ContainerSpec `json:"spec,omitempty"`
// Historical statistics gathered from the container.
Stats []*ContainerStats `json:"stats,omitempty"`

View File

@ -51,10 +51,10 @@ func GenerateRandomStats(numStats, numCores int, duration time.Duration) []*info
return ret
}
func GenerateRandomContainerSpec(numCores int) *info.ContainerSpec {
ret := &info.ContainerSpec{
Cpu: &info.CpuSpec{},
Memory: &info.MemorySpec{},
func GenerateRandomContainerSpec(numCores int) info.ContainerSpec {
ret := info.ContainerSpec{
Cpu: info.CpuSpec{},
Memory: info.MemorySpec{},
}
ret.Cpu.Limit = uint64(1000 + rand.Int63n(2000))
ret.Cpu.MaxLimit = uint64(1000 + rand.Int63n(2000))

View File

@ -41,7 +41,7 @@ type containerStat struct {
type containerInfo struct {
info.ContainerReference
Subcontainers []info.ContainerReference
Spec *info.ContainerSpec
Spec info.ContainerSpec
}
type containerData struct {
@ -166,7 +166,6 @@ func (c *containerData) housekeeping() {
time.Sleep(nextHousekeeping.Sub(time.Now()))
}
lastHousekeeping = nextHousekeeping
}
}

View File

@ -166,7 +166,7 @@ func (self *manager) containerDataToContainerInfo(cont *containerData, query *in
}
// Set default value to an actual value
if ret.Spec.Memory != nil {
if ret.Spec.HasMemory {
// Memory.Limit is 0 means there's no limit
if ret.Spec.Memory.Limit == 0 {
ret.Spec.Memory.Limit = uint64(self.machineInfo.MemoryCapacity)

View File

@ -108,7 +108,7 @@ type pageData struct {
ContainerName string
ParentContainers []info.ContainerReference
Subcontainers []info.ContainerReference
Spec *info.ContainerSpec
Spec info.ContainerSpec
Stats []*info.ContainerStats
MachineInfo *info.MachineInfo
ResourcesAvailable bool
@ -300,14 +300,6 @@ func ServerContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL)
}
}
networkStatsAvailable := false
for _, stat := range cont.Stats {
if stat.Network != nil {
networkStatsAvailable = true
break
}
}
data := &pageData{
ContainerName: displayName,
// TODO(vmarmol): Only use strings for this.
@ -316,10 +308,10 @@ func ServerContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL)
Spec: cont.Spec,
Stats: cont.Stats,
MachineInfo: machineInfo,
ResourcesAvailable: cont.Spec.Cpu != nil || cont.Spec.Memory != nil,
CpuAvailable: cont.Spec.Cpu != nil,
MemoryAvailable: cont.Spec.Memory != nil,
NetworkAvailable: networkStatsAvailable,
ResourcesAvailable: cont.Spec.HasCpu || cont.Spec.HasMemory || cont.Spec.HasNetwork,
CpuAvailable: cont.Spec.HasCpu,
MemoryAvailable: cont.Spec.HasMemory,
NetworkAvailable: cont.Spec.HasNetwork,
}
err = pageTemplate.Execute(w, data)
if err != nil {

View File

@ -142,7 +142,7 @@ function getStats(containerName, callback) {
// Draw the graph for CPU usage.
function drawCpuTotalUsage(elementId, machineInfo, stats) {
if (!hasResource(stats, "cpu")) {
if (stats.spec.has_cpu && !hasResource(stats, "cpu")) {
return;
}
@ -163,7 +163,7 @@ function drawCpuTotalUsage(elementId, machineInfo, stats) {
// Draw the graph for per-core CPU usage.
function drawCpuPerCoreUsage(elementId, machineInfo, stats) {
if (!hasResource(stats, "cpu")) {
if (stats.spec.has_cpu && !hasResource(stats, "cpu")) {
return;
}
@ -190,7 +190,7 @@ function drawCpuPerCoreUsage(elementId, machineInfo, stats) {
// Draw the graph for CPU usage breakdown.
function drawCpuUsageBreakdown(elementId, containerInfo) {
if (!hasResource(containerInfo, "cpu")) {
if (containerInfo.spec.has_cpu && !hasResource(containerInfo, "cpu")) {
return;
}
@ -215,7 +215,7 @@ function drawOverallUsage(elementId, machineInfo, containerInfo) {
var cur = containerInfo.stats[containerInfo.stats.length - 1];
var cpuUsage = 0;
if (containerInfo.spec.cpu && containerInfo.stats.length >= 2) {
if (containerInfo.spec.has_cpu && containerInfo.stats.length >= 2) {
var prev = containerInfo.stats[containerInfo.stats.length - 2];
var rawUsage = cur.cpu.usage.total - prev.cpu.usage.total;
var intervalInNs = getInterval(cur.timestamp, prev.timestamp);
@ -228,7 +228,7 @@ function drawOverallUsage(elementId, machineInfo, containerInfo) {
}
var memoryUsage = 0;
if (containerInfo.spec.memory) {
if (containerInfo.spec.has_memory) {
// Saturate to the machine size.
var limit = containerInfo.spec.memory.limit;
if (limit > machineInfo.memory_capacity) {
@ -244,7 +244,7 @@ function drawOverallUsage(elementId, machineInfo, containerInfo) {
var oneMegabyte = 1024 * 1024;
function drawMemoryUsage(elementId, containerInfo) {
if (!hasResource(containerInfo, "memory")) {
if (containerInfo.spec.has_memory && !hasResource(containerInfo, "memory")) {
return;
}
@ -264,7 +264,7 @@ function drawMemoryUsage(elementId, containerInfo) {
// Draw the graph for network tx/rx bytes.
function drawNetworkBytes(elementId, machineInfo, stats) {
if (!hasResource(stats, "network")) {
if (stats.spec.has_network && !hasResource(stats, "network")) {
return;
}
@ -286,7 +286,7 @@ function drawNetworkBytes(elementId, machineInfo, stats) {
// Draw the graph for network errors
function drawNetworkErrors(elementId, machineInfo, stats) {
if (!hasResource(stats, "network")) {
if (stats.spec.has_network && !hasResource(stats, "network")) {
return;
}
@ -328,33 +328,41 @@ function stepExecute(steps) {
function drawCharts(machineInfo, containerInfo) {
var steps = [];
steps.push(function() {
drawOverallUsage("usage-gauge", machineInfo, containerInfo)
});
if (containerInfo.spec.has_cpu || containerInfo.spec.has_memory) {
steps.push(function() {
drawOverallUsage("usage-gauge", machineInfo, containerInfo)
});
}
// CPU.
steps.push(function() {
drawCpuTotalUsage("cpu-total-usage-chart", machineInfo, containerInfo);
});
steps.push(function() {
drawCpuPerCoreUsage("cpu-per-core-usage-chart", machineInfo, containerInfo);
});
steps.push(function() {
drawCpuUsageBreakdown("cpu-usage-breakdown-chart", containerInfo);
});
if (containerInfo.spec.has_cpu) {
steps.push(function() {
drawCpuTotalUsage("cpu-total-usage-chart", machineInfo, containerInfo);
});
steps.push(function() {
drawCpuPerCoreUsage("cpu-per-core-usage-chart", machineInfo, containerInfo);
});
steps.push(function() {
drawCpuUsageBreakdown("cpu-usage-breakdown-chart", containerInfo);
});
}
// Memory.
steps.push(function() {
drawMemoryUsage("memory-usage-chart", containerInfo);
});
if (containerInfo.spec.has_memory) {
steps.push(function() {
drawMemoryUsage("memory-usage-chart", containerInfo);
});
}
// Network.
steps.push(function() {
drawNetworkBytes("network-bytes-chart", machineInfo, containerInfo);
});
steps.push(function() {
drawNetworkErrors("network-errors-chart", machineInfo, containerInfo);
});
if (containerInfo.spec.has_network) {
steps.push(function() {
drawNetworkBytes("network-bytes-chart", machineInfo, containerInfo);
});
steps.push(function() {
drawNetworkErrors("network-errors-chart", machineInfo, containerInfo);
});
}
stepExecute(steps);
}