Flatten ContainerSpec.
This commit is contained in:
parent
7c59947ee8
commit
e22831f1bd
@ -41,7 +41,7 @@ type SubcontainerEvent struct {
|
|||||||
// Interface for container operation handlers.
|
// Interface for container operation handlers.
|
||||||
type ContainerHandler interface {
|
type ContainerHandler interface {
|
||||||
ContainerReference() (info.ContainerReference, error)
|
ContainerReference() (info.ContainerReference, error)
|
||||||
GetSpec() (*info.ContainerSpec, error)
|
GetSpec() (info.ContainerSpec, error)
|
||||||
GetStats() (*info.ContainerStats, error)
|
GetStats() (*info.ContainerStats, error)
|
||||||
ListContainers(listType ListType) ([]info.ContainerReference, error)
|
ListContainers(listType ListType) ([]info.ContainerReference, error)
|
||||||
ListThreads(listType ListType) ([]int, error)
|
ListThreads(listType ListType) ([]int, error)
|
||||||
|
@ -149,9 +149,9 @@ func (self *dockerContainerHandler) readLibcontainerState() (state *libcontainer
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func libcontainerConfigToContainerSpec(config *libcontainer.Config, mi *info.MachineInfo) *info.ContainerSpec {
|
func libcontainerConfigToContainerSpec(config *libcontainer.Config, mi *info.MachineInfo) info.ContainerSpec {
|
||||||
spec := new(info.ContainerSpec)
|
var spec info.ContainerSpec
|
||||||
spec.Memory = new(info.MemorySpec)
|
spec.HasMemory = true
|
||||||
spec.Memory.Limit = math.MaxUint64
|
spec.Memory.Limit = math.MaxUint64
|
||||||
spec.Memory.SwapLimit = math.MaxUint64
|
spec.Memory.SwapLimit = math.MaxUint64
|
||||||
if config.Cgroups.Memory > 0 {
|
if config.Cgroups.Memory > 0 {
|
||||||
@ -162,7 +162,7 @@ func libcontainerConfigToContainerSpec(config *libcontainer.Config, mi *info.Mac
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get CPU info
|
// Get CPU info
|
||||||
spec.Cpu = new(info.CpuSpec)
|
spec.HasCpu = true
|
||||||
spec.Cpu.Limit = 1024
|
spec.Cpu.Limit = 1024
|
||||||
if config.Cgroups.CpuShares != 0 {
|
if config.Cgroups.CpuShares != 0 {
|
||||||
spec.Cpu.Limit = uint64(config.Cgroups.CpuShares)
|
spec.Cpu.Limit = uint64(config.Cgroups.CpuShares)
|
||||||
@ -173,12 +173,14 @@ func libcontainerConfigToContainerSpec(config *libcontainer.Config, mi *info.Mac
|
|||||||
} else {
|
} else {
|
||||||
spec.Cpu.Mask = config.Cgroups.CpusetCpus
|
spec.Cpu.Mask = config.Cgroups.CpusetCpus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spec.HasNetwork = true
|
||||||
return spec
|
return spec
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *dockerContainerHandler) GetSpec() (spec *info.ContainerSpec, err error) {
|
func (self *dockerContainerHandler) GetSpec() (spec info.ContainerSpec, err error) {
|
||||||
if self.isDockerRoot() {
|
if self.isDockerRoot() {
|
||||||
return &info.ContainerSpec{}, nil
|
return info.ContainerSpec{}, nil
|
||||||
}
|
}
|
||||||
mi, err := self.machineInfoFactory.GetMachineInfo()
|
mi, err := self.machineInfoFactory.GetMachineInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -44,9 +44,9 @@ func (self *MockContainerHandler) ContainerReference() (info.ContainerReference,
|
|||||||
return args.Get(0).(info.ContainerReference), args.Error(1)
|
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()
|
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) {
|
func (self *MockContainerHandler) GetStats() (*info.ContainerStats, error) {
|
||||||
|
@ -92,15 +92,15 @@ func readInt64(dirpath string, file string) uint64 {
|
|||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *rawContainerHandler) GetSpec() (*info.ContainerSpec, error) {
|
func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) {
|
||||||
spec := new(info.ContainerSpec)
|
var spec info.ContainerSpec
|
||||||
|
|
||||||
// The raw driver assumes unified hierarchy containers.
|
// The raw driver assumes unified hierarchy containers.
|
||||||
|
|
||||||
// Get machine info.
|
// Get machine info.
|
||||||
mi, err := self.machineInfoFactory.GetMachineInfo()
|
mi, err := self.machineInfoFactory.GetMachineInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return spec, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CPU.
|
// CPU.
|
||||||
@ -108,7 +108,7 @@ func (self *rawContainerHandler) GetSpec() (*info.ContainerSpec, error) {
|
|||||||
if ok {
|
if ok {
|
||||||
cpuRoot = path.Join(cpuRoot, self.name)
|
cpuRoot = path.Join(cpuRoot, self.name)
|
||||||
if utils.FileExists(cpuRoot) {
|
if utils.FileExists(cpuRoot) {
|
||||||
spec.Cpu = new(info.CpuSpec)
|
spec.HasCpu = true
|
||||||
spec.Cpu.Limit = readInt64(cpuRoot, "cpu.shares")
|
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.
|
// This will fail for non-unified hierarchies. We'll return the whole machine mask in that case.
|
||||||
cpusetRoot, ok := self.cgroupSubsystems.mountPoints["cpuset"]
|
cpusetRoot, ok := self.cgroupSubsystems.mountPoints["cpuset"]
|
||||||
if ok {
|
if ok {
|
||||||
if spec.Cpu == nil {
|
|
||||||
spec.Cpu = new(info.CpuSpec)
|
|
||||||
}
|
|
||||||
cpusetRoot = path.Join(cpusetRoot, self.name)
|
cpusetRoot = path.Join(cpusetRoot, self.name)
|
||||||
if utils.FileExists(cpusetRoot) {
|
if utils.FileExists(cpusetRoot) {
|
||||||
|
spec.HasCpu = true
|
||||||
spec.Cpu.Mask = readString(cpusetRoot, "cpuset.cpus")
|
spec.Cpu.Mask = readString(cpusetRoot, "cpuset.cpus")
|
||||||
if spec.Cpu.Mask == "" {
|
if spec.Cpu.Mask == "" {
|
||||||
spec.Cpu.Mask = fmt.Sprintf("0-%d", mi.NumCores-1)
|
spec.Cpu.Mask = fmt.Sprintf("0-%d", mi.NumCores-1)
|
||||||
@ -134,7 +132,7 @@ func (self *rawContainerHandler) GetSpec() (*info.ContainerSpec, error) {
|
|||||||
if ok {
|
if ok {
|
||||||
memoryRoot = path.Join(memoryRoot, self.name)
|
memoryRoot = path.Join(memoryRoot, self.name)
|
||||||
if utils.FileExists(memoryRoot) {
|
if utils.FileExists(memoryRoot) {
|
||||||
spec.Memory = new(info.MemorySpec)
|
spec.HasMemory = true
|
||||||
spec.Memory.Limit = readInt64(memoryRoot, "memory.limit_in_bytes")
|
spec.Memory.Limit = readInt64(memoryRoot, "memory.limit_in_bytes")
|
||||||
spec.Memory.SwapLimit = readInt64(memoryRoot, "memory.memsw.limit_in_bytes")
|
spec.Memory.SwapLimit = readInt64(memoryRoot, "memory.memsw.limit_in_bytes")
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,13 @@ type MemorySpec struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ContainerSpec struct {
|
type ContainerSpec struct {
|
||||||
Cpu *CpuSpec `json:"cpu,omitempty"`
|
HasCpu bool `json:"has_cpu"`
|
||||||
Memory *MemorySpec `json:"memory,omitempty"`
|
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
|
// Container reference contains enough information to uniquely identify a container
|
||||||
@ -66,7 +71,7 @@ type ContainerInfo struct {
|
|||||||
Subcontainers []ContainerReference `json:"subcontainers,omitempty"`
|
Subcontainers []ContainerReference `json:"subcontainers,omitempty"`
|
||||||
|
|
||||||
// The isolation used in the container.
|
// The isolation used in the container.
|
||||||
Spec *ContainerSpec `json:"spec,omitempty"`
|
Spec ContainerSpec `json:"spec,omitempty"`
|
||||||
|
|
||||||
// Historical statistics gathered from the container.
|
// Historical statistics gathered from the container.
|
||||||
Stats []*ContainerStats `json:"stats,omitempty"`
|
Stats []*ContainerStats `json:"stats,omitempty"`
|
||||||
|
@ -51,10 +51,10 @@ func GenerateRandomStats(numStats, numCores int, duration time.Duration) []*info
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateRandomContainerSpec(numCores int) *info.ContainerSpec {
|
func GenerateRandomContainerSpec(numCores int) info.ContainerSpec {
|
||||||
ret := &info.ContainerSpec{
|
ret := info.ContainerSpec{
|
||||||
Cpu: &info.CpuSpec{},
|
Cpu: info.CpuSpec{},
|
||||||
Memory: &info.MemorySpec{},
|
Memory: info.MemorySpec{},
|
||||||
}
|
}
|
||||||
ret.Cpu.Limit = uint64(1000 + rand.Int63n(2000))
|
ret.Cpu.Limit = uint64(1000 + rand.Int63n(2000))
|
||||||
ret.Cpu.MaxLimit = uint64(1000 + rand.Int63n(2000))
|
ret.Cpu.MaxLimit = uint64(1000 + rand.Int63n(2000))
|
||||||
|
@ -41,7 +41,7 @@ type containerStat struct {
|
|||||||
type containerInfo struct {
|
type containerInfo struct {
|
||||||
info.ContainerReference
|
info.ContainerReference
|
||||||
Subcontainers []info.ContainerReference
|
Subcontainers []info.ContainerReference
|
||||||
Spec *info.ContainerSpec
|
Spec info.ContainerSpec
|
||||||
}
|
}
|
||||||
|
|
||||||
type containerData struct {
|
type containerData struct {
|
||||||
@ -166,7 +166,6 @@ func (c *containerData) housekeeping() {
|
|||||||
time.Sleep(nextHousekeeping.Sub(time.Now()))
|
time.Sleep(nextHousekeeping.Sub(time.Now()))
|
||||||
}
|
}
|
||||||
lastHousekeeping = nextHousekeeping
|
lastHousekeeping = nextHousekeeping
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ func (self *manager) containerDataToContainerInfo(cont *containerData, query *in
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set default value to an actual value
|
// 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
|
// Memory.Limit is 0 means there's no limit
|
||||||
if ret.Spec.Memory.Limit == 0 {
|
if ret.Spec.Memory.Limit == 0 {
|
||||||
ret.Spec.Memory.Limit = uint64(self.machineInfo.MemoryCapacity)
|
ret.Spec.Memory.Limit = uint64(self.machineInfo.MemoryCapacity)
|
||||||
|
@ -108,7 +108,7 @@ type pageData struct {
|
|||||||
ContainerName string
|
ContainerName string
|
||||||
ParentContainers []info.ContainerReference
|
ParentContainers []info.ContainerReference
|
||||||
Subcontainers []info.ContainerReference
|
Subcontainers []info.ContainerReference
|
||||||
Spec *info.ContainerSpec
|
Spec info.ContainerSpec
|
||||||
Stats []*info.ContainerStats
|
Stats []*info.ContainerStats
|
||||||
MachineInfo *info.MachineInfo
|
MachineInfo *info.MachineInfo
|
||||||
ResourcesAvailable bool
|
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{
|
data := &pageData{
|
||||||
ContainerName: displayName,
|
ContainerName: displayName,
|
||||||
// TODO(vmarmol): Only use strings for this.
|
// 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,
|
Spec: cont.Spec,
|
||||||
Stats: cont.Stats,
|
Stats: cont.Stats,
|
||||||
MachineInfo: machineInfo,
|
MachineInfo: machineInfo,
|
||||||
ResourcesAvailable: cont.Spec.Cpu != nil || cont.Spec.Memory != nil,
|
ResourcesAvailable: cont.Spec.HasCpu || cont.Spec.HasMemory || cont.Spec.HasNetwork,
|
||||||
CpuAvailable: cont.Spec.Cpu != nil,
|
CpuAvailable: cont.Spec.HasCpu,
|
||||||
MemoryAvailable: cont.Spec.Memory != nil,
|
MemoryAvailable: cont.Spec.HasMemory,
|
||||||
NetworkAvailable: networkStatsAvailable,
|
NetworkAvailable: cont.Spec.HasNetwork,
|
||||||
}
|
}
|
||||||
err = pageTemplate.Execute(w, data)
|
err = pageTemplate.Execute(w, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -142,7 +142,7 @@ function getStats(containerName, callback) {
|
|||||||
|
|
||||||
// Draw the graph for CPU usage.
|
// Draw the graph for CPU usage.
|
||||||
function drawCpuTotalUsage(elementId, machineInfo, stats) {
|
function drawCpuTotalUsage(elementId, machineInfo, stats) {
|
||||||
if (!hasResource(stats, "cpu")) {
|
if (stats.spec.has_cpu && !hasResource(stats, "cpu")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ function drawCpuTotalUsage(elementId, machineInfo, stats) {
|
|||||||
|
|
||||||
// Draw the graph for per-core CPU usage.
|
// Draw the graph for per-core CPU usage.
|
||||||
function drawCpuPerCoreUsage(elementId, machineInfo, stats) {
|
function drawCpuPerCoreUsage(elementId, machineInfo, stats) {
|
||||||
if (!hasResource(stats, "cpu")) {
|
if (stats.spec.has_cpu && !hasResource(stats, "cpu")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ function drawCpuPerCoreUsage(elementId, machineInfo, stats) {
|
|||||||
|
|
||||||
// Draw the graph for CPU usage breakdown.
|
// Draw the graph for CPU usage breakdown.
|
||||||
function drawCpuUsageBreakdown(elementId, containerInfo) {
|
function drawCpuUsageBreakdown(elementId, containerInfo) {
|
||||||
if (!hasResource(containerInfo, "cpu")) {
|
if (containerInfo.spec.has_cpu && !hasResource(containerInfo, "cpu")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ function drawOverallUsage(elementId, machineInfo, containerInfo) {
|
|||||||
var cur = containerInfo.stats[containerInfo.stats.length - 1];
|
var cur = containerInfo.stats[containerInfo.stats.length - 1];
|
||||||
|
|
||||||
var cpuUsage = 0;
|
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 prev = containerInfo.stats[containerInfo.stats.length - 2];
|
||||||
var rawUsage = cur.cpu.usage.total - prev.cpu.usage.total;
|
var rawUsage = cur.cpu.usage.total - prev.cpu.usage.total;
|
||||||
var intervalInNs = getInterval(cur.timestamp, prev.timestamp);
|
var intervalInNs = getInterval(cur.timestamp, prev.timestamp);
|
||||||
@ -228,7 +228,7 @@ function drawOverallUsage(elementId, machineInfo, containerInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var memoryUsage = 0;
|
var memoryUsage = 0;
|
||||||
if (containerInfo.spec.memory) {
|
if (containerInfo.spec.has_memory) {
|
||||||
// Saturate to the machine size.
|
// Saturate to the machine size.
|
||||||
var limit = containerInfo.spec.memory.limit;
|
var limit = containerInfo.spec.memory.limit;
|
||||||
if (limit > machineInfo.memory_capacity) {
|
if (limit > machineInfo.memory_capacity) {
|
||||||
@ -244,7 +244,7 @@ function drawOverallUsage(elementId, machineInfo, containerInfo) {
|
|||||||
var oneMegabyte = 1024 * 1024;
|
var oneMegabyte = 1024 * 1024;
|
||||||
|
|
||||||
function drawMemoryUsage(elementId, containerInfo) {
|
function drawMemoryUsage(elementId, containerInfo) {
|
||||||
if (!hasResource(containerInfo, "memory")) {
|
if (containerInfo.spec.has_memory && !hasResource(containerInfo, "memory")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ function drawMemoryUsage(elementId, containerInfo) {
|
|||||||
|
|
||||||
// Draw the graph for network tx/rx bytes.
|
// Draw the graph for network tx/rx bytes.
|
||||||
function drawNetworkBytes(elementId, machineInfo, stats) {
|
function drawNetworkBytes(elementId, machineInfo, stats) {
|
||||||
if (!hasResource(stats, "network")) {
|
if (stats.spec.has_network && !hasResource(stats, "network")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,7 +286,7 @@ function drawNetworkBytes(elementId, machineInfo, stats) {
|
|||||||
|
|
||||||
// Draw the graph for network errors
|
// Draw the graph for network errors
|
||||||
function drawNetworkErrors(elementId, machineInfo, stats) {
|
function drawNetworkErrors(elementId, machineInfo, stats) {
|
||||||
if (!hasResource(stats, "network")) {
|
if (stats.spec.has_network && !hasResource(stats, "network")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,11 +328,14 @@ function stepExecute(steps) {
|
|||||||
function drawCharts(machineInfo, containerInfo) {
|
function drawCharts(machineInfo, containerInfo) {
|
||||||
var steps = [];
|
var steps = [];
|
||||||
|
|
||||||
|
if (containerInfo.spec.has_cpu || containerInfo.spec.has_memory) {
|
||||||
steps.push(function() {
|
steps.push(function() {
|
||||||
drawOverallUsage("usage-gauge", machineInfo, containerInfo)
|
drawOverallUsage("usage-gauge", machineInfo, containerInfo)
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// CPU.
|
// CPU.
|
||||||
|
if (containerInfo.spec.has_cpu) {
|
||||||
steps.push(function() {
|
steps.push(function() {
|
||||||
drawCpuTotalUsage("cpu-total-usage-chart", machineInfo, containerInfo);
|
drawCpuTotalUsage("cpu-total-usage-chart", machineInfo, containerInfo);
|
||||||
});
|
});
|
||||||
@ -342,19 +345,24 @@ function drawCharts(machineInfo, containerInfo) {
|
|||||||
steps.push(function() {
|
steps.push(function() {
|
||||||
drawCpuUsageBreakdown("cpu-usage-breakdown-chart", containerInfo);
|
drawCpuUsageBreakdown("cpu-usage-breakdown-chart", containerInfo);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Memory.
|
// Memory.
|
||||||
|
if (containerInfo.spec.has_memory) {
|
||||||
steps.push(function() {
|
steps.push(function() {
|
||||||
drawMemoryUsage("memory-usage-chart", containerInfo);
|
drawMemoryUsage("memory-usage-chart", containerInfo);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Network.
|
// Network.
|
||||||
|
if (containerInfo.spec.has_network) {
|
||||||
steps.push(function() {
|
steps.push(function() {
|
||||||
drawNetworkBytes("network-bytes-chart", machineInfo, containerInfo);
|
drawNetworkBytes("network-bytes-chart", machineInfo, containerInfo);
|
||||||
});
|
});
|
||||||
steps.push(function() {
|
steps.push(function() {
|
||||||
drawNetworkErrors("network-errors-chart", machineInfo, containerInfo);
|
drawNetworkErrors("network-errors-chart", machineInfo, containerInfo);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
stepExecute(steps);
|
stepExecute(steps);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user