func libcontainerConfigToContainerSpec(config *libcontainerConfigs.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 { spec.Memory.Limit = uint64(config.Cgroups.Memory) } if config.Cgroups.MemorySwap > 0 { spec.Memory.SwapLimit = uint64(config.Cgroups.MemorySwap) } // Get CPU info spec.HasCpu = true spec.Cpu.Limit = 1024 if config.Cgroups.CpuShares != 0 { spec.Cpu.Limit = uint64(config.Cgroups.CpuShares) } spec.Cpu.Mask = utils.FixCpuMask(config.Cgroups.CpusetCpus, mi.NumCores) spec.HasNetwork = true spec.HasDiskIo = true return spec }
func (self *hyperContainerHandler) GetSpec() (info.ContainerSpec, error) { var spec info.ContainerSpec podInfo, err := self.client.GetPod(self.podID) if err != nil { return spec, err } startedAt, err := parseTimeString(podInfo.Status.StartTime) if err != nil { return spec, err } spec.CreationTime = startedAt spec.Cpu = info.CpuSpec{Limit: uint64(1024 * podInfo.Spec.Vcpu)} spec.HasCpu = true spec.Memory = info.MemorySpec{Limit: uint64(1024 * 1024 * podInfo.Spec.Memory)} spec.HasMemory = true spec.HasDiskIo = true spec.HasNetwork = true spec.HasCustomMetrics = false spec.Labels = podInfo.Spec.Labels return spec, nil }
func libcontainerConfigToContainerSpec(config *libcontainerConfigs.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 { spec.Memory.Limit = uint64(config.Cgroups.Memory) } if config.Cgroups.MemorySwap > 0 { spec.Memory.SwapLimit = uint64(config.Cgroups.MemorySwap) } // Get CPU info spec.HasCpu = true spec.Cpu.Limit = 1024 if config.Cgroups.CpuShares != 0 { spec.Cpu.Limit = uint64(config.Cgroups.CpuShares) } spec.Cpu.Mask = utils.FixCpuMask(config.Cgroups.CpusetCpus, mi.NumCores) // Docker reports a loop device for containers with --net=host. Ignore // those too. networkCount := 0 for _, n := range config.Networks { if n.Type != "loopback" { networkCount += 1 } } spec.HasNetwork = networkCount > 0 || hasNetNs(config.Namespaces) spec.HasDiskIo = true return spec }
// cmeFactory generates a complete ContainerMetricElement with fuzzed data. // CMEs created by cmeFactory contain partially fuzzed stats, aside from hardcoded values for Memory usage. // The timestamp of the CME is rouded to the current minute and offset by a random number of hours. func cmeFactory() *cache.ContainerMetricElement { f := fuzz.New().NilChance(0).NumElements(1, 1) containerSpec := cadvisor.ContainerSpec{ CreationTime: time.Now(), HasCpu: true, HasMemory: true, HasNetwork: true, HasFilesystem: true, HasDiskIo: true, } containerSpec.Cpu.Limit = 1024 containerSpec.Memory.Limit = 10000000 // Create a fuzzed ContainerStats struct var containerStats cadvisor.ContainerStats f.Fuzz(&containerStats) // Standardize timestamp to the current minute plus a random number of hours ([1, 10]) now_time := time.Now().Round(time.Minute) new_time := now_time for new_time == now_time { new_time = now_time.Add(time.Duration(rand.Intn(10)) * 5 * time.Minute) } containerStats.Timestamp = new_time containerSpec.CreationTime = new_time.Add(-time.Hour) // Standardize memory usage and limit to test aggregation containerStats.Memory.Usage = uint64(5000) containerStats.Memory.WorkingSet = uint64(602) // Standardize the device name, usage and limit new_fs := cadvisor.FsStats{} f.Fuzz(&new_fs) new_fs.Device = "/dev/device1" new_fs.Usage = 50000 new_fs.Limit = 100000 containerStats.Filesystem = []cadvisor.FsStats{new_fs} return &cache.ContainerMetricElement{ Spec: &containerSpec, Stats: &containerStats, } }
func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) { var spec info.ContainerSpec // The raw driver assumes unified hierarchy containers. // Get the lowest creation time from all hierarchies as the container creation time. now := time.Now() lowestTime := now for _, cgroupPath := range self.cgroupPaths { // The modified time of the cgroup directory is when the container was created. fi, err := os.Stat(cgroupPath) if err == nil && fi.ModTime().Before(lowestTime) { lowestTime = fi.ModTime() } } if lowestTime != now { spec.CreationTime = lowestTime } // Get machine info. mi, err := self.machineInfoFactory.GetMachineInfo() if err != nil { return spec, err } // CPU. cpuRoot, ok := self.cgroupPaths["cpu"] if ok { if utils.FileExists(cpuRoot) { spec.HasCpu = true spec.Cpu.Limit = readInt64(cpuRoot, "cpu.shares") } } // Cpu Mask. // This will fail for non-unified hierarchies. We'll return the whole machine mask in that case. cpusetRoot, ok := self.cgroupPaths["cpuset"] if ok { if utils.FileExists(cpusetRoot) { spec.HasCpu = true mask := readString(cpusetRoot, "cpuset.cpus") spec.Cpu.Mask = utils.FixCpuMask(mask, mi.NumCores) } } // Memory. memoryRoot, ok := self.cgroupPaths["memory"] if ok { if utils.FileExists(memoryRoot) { spec.HasMemory = true spec.Memory.Limit = readInt64(memoryRoot, "memory.limit_in_bytes") spec.Memory.SwapLimit = readInt64(memoryRoot, "memory.memsw.limit_in_bytes") } } // Fs. if self.name == "/" || self.externalMounts != nil { spec.HasFilesystem = true } //Network spec.HasNetwork = self.hasNetwork // DiskIo. if blkioRoot, ok := self.cgroupPaths["blkio"]; ok && utils.FileExists(blkioRoot) { spec.HasDiskIo = true } // Check physical network devices for root container. nd, err := self.GetRootNetworkDevices() if err != nil { return spec, err } if len(nd) != 0 { spec.HasNetwork = true } return spec, nil }
func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) { var spec info.ContainerSpec // The raw driver assumes unified hierarchy containers. // Get the lowest creation time from all hierarchies as the container creation time. now := time.Now() lowestTime := now for _, cgroupPath := range self.cgroupPaths { // The modified time of the cgroup directory changes whenever a subcontainer is created. // eg. /docker will have creation time matching the creation of latest docker container. // Use clone_children as a workaround as it isn't usually modified. It is only likely changed // immediately after creating a container. cgroupPath = path.Join(cgroupPath, "cgroup.clone_children") fi, err := os.Stat(cgroupPath) if err == nil && fi.ModTime().Before(lowestTime) { lowestTime = fi.ModTime() } } if lowestTime != now { spec.CreationTime = lowestTime } // Get machine info. mi, err := self.machineInfoFactory.GetMachineInfo() if err != nil { return spec, err } // CPU. cpuRoot, ok := self.cgroupPaths["cpu"] if ok { if utils.FileExists(cpuRoot) { spec.HasCpu = true spec.Cpu.Limit = readInt64(cpuRoot, "cpu.shares") } } // Cpu Mask. // This will fail for non-unified hierarchies. We'll return the whole machine mask in that case. cpusetRoot, ok := self.cgroupPaths["cpuset"] if ok { if utils.FileExists(cpusetRoot) { spec.HasCpu = true mask := readString(cpusetRoot, "cpuset.cpus") spec.Cpu.Mask = utils.FixCpuMask(mask, mi.NumCores) } } // Memory if self.name == "/" { // Get memory and swap limits of the running machine memLimit, err := machine.GetMachineMemoryCapacity() if err != nil { glog.Warningf("failed to obtain memory limit for machine container") spec.HasMemory = false } else { spec.Memory.Limit = uint64(memLimit) // Spec is marked to have memory only if the memory limit is set spec.HasMemory = true } swapLimit, err := machine.GetMachineSwapCapacity() if err != nil { glog.Warningf("failed to obtain swap limit for machine container") } else { spec.Memory.SwapLimit = uint64(swapLimit) } } else { memoryRoot, ok := self.cgroupPaths["memory"] if ok { if utils.FileExists(memoryRoot) { spec.HasMemory = true spec.Memory.Limit = readInt64(memoryRoot, "memory.limit_in_bytes") spec.Memory.SwapLimit = readInt64(memoryRoot, "memory.memsw.limit_in_bytes") } } } // Fs. if self.name == "/" || self.externalMounts != nil { spec.HasFilesystem = true } //Network spec.HasNetwork = self.hasNetwork // DiskIo. if blkioRoot, ok := self.cgroupPaths["blkio"]; ok && utils.FileExists(blkioRoot) { spec.HasDiskIo = true } // Check physical network devices for root container. nd, err := self.GetRootNetworkDevices() if err != nil { return spec, err } if len(nd) != 0 { spec.HasNetwork = true } return spec, nil }
func GetSpec(cgroupPaths map[string]string, machineInfoFactory info.MachineInfoFactory, hasNetwork, hasFilesystem bool) (info.ContainerSpec, error) { var spec info.ContainerSpec // Assume unified hierarchy containers. // Get the lowest creation time from all hierarchies as the container creation time. now := time.Now() lowestTime := now for _, cgroupPath := range cgroupPaths { // The modified time of the cgroup directory changes whenever a subcontainer is created. // eg. /docker will have creation time matching the creation of latest docker container. // Use clone_children as a workaround as it isn't usually modified. It is only likely changed // immediately after creating a container. cgroupPath = path.Join(cgroupPath, "cgroup.clone_children") fi, err := os.Stat(cgroupPath) if err == nil && fi.ModTime().Before(lowestTime) { lowestTime = fi.ModTime() } } if lowestTime != now { spec.CreationTime = lowestTime } // Get machine info. mi, err := machineInfoFactory.GetMachineInfo() if err != nil { return spec, err } // CPU. cpuRoot, ok := cgroupPaths["cpu"] if ok { if utils.FileExists(cpuRoot) { spec.HasCpu = true spec.Cpu.Limit = readUInt64(cpuRoot, "cpu.shares") spec.Cpu.Period = readUInt64(cpuRoot, "cpu.cfs_period_us") quota := readString(cpuRoot, "cpu.cfs_quota_us") if quota != "" && quota != "-1" { val, err := strconv.ParseUint(quota, 10, 64) if err != nil { glog.Errorf("GetSpec: Failed to parse CPUQuota from %q: %s", path.Join(cpuRoot, "cpu.cfs_quota_us"), err) } spec.Cpu.Quota = val } } } // Cpu Mask. // This will fail for non-unified hierarchies. We'll return the whole machine mask in that case. cpusetRoot, ok := cgroupPaths["cpuset"] if ok { if utils.FileExists(cpusetRoot) { spec.HasCpu = true mask := readString(cpusetRoot, "cpuset.cpus") spec.Cpu.Mask = utils.FixCpuMask(mask, mi.NumCores) } } // Memory memoryRoot, ok := cgroupPaths["memory"] if ok { if utils.FileExists(memoryRoot) { spec.HasMemory = true spec.Memory.Limit = readUInt64(memoryRoot, "memory.limit_in_bytes") spec.Memory.SwapLimit = readUInt64(memoryRoot, "memory.memsw.limit_in_bytes") } } spec.HasNetwork = hasNetwork spec.HasFilesystem = hasFilesystem if blkioRoot, ok := cgroupPaths["blkio"]; ok && utils.FileExists(blkioRoot) { spec.HasDiskIo = true } return spec, nil }
func GetSpec(handler AbstractContainerHandler) (info.ContainerSpec, error) { cgroupPaths := handler.GetCgroupPaths() machineInfoFactory := handler.GetMachineInfoFactory() name := handler.GetName() externalMounts := handler.GetExternalMounts() var spec info.ContainerSpec // The raw driver assumes unified hierarchy containers. // Get the lowest creation time from all hierarchies as the container creation time. now := time.Now() lowestTime := now for _, cgroupPath := range cgroupPaths { // The modified time of the cgroup directory changes whenever a subcontainer is created. // eg. /docker will have creation time matching the creation of latest docker container. // Use clone_children as a workaround as it isn't usually modified. It is only likely changed // immediately after creating a container. cgroupPath = path.Join(cgroupPath, "cgroup.clone_children") fi, err := os.Stat(cgroupPath) if err == nil && fi.ModTime().Before(lowestTime) { lowestTime = fi.ModTime() } } if lowestTime != now { spec.CreationTime = lowestTime } // Get machine info. mi, err := machineInfoFactory.GetMachineInfo() if err != nil { return spec, err } // CPU. cpuRoot, ok := cgroupPaths["cpu"] if ok { if utils.FileExists(cpuRoot) { spec.HasCpu = true spec.Cpu.Limit = readUInt64(cpuRoot, "cpu.shares") spec.Cpu.Period = readUInt64(cpuRoot, "cpu.cfs_period_us") quota := readString(cpuRoot, "cpu.cfs_quota_us") if quota != "" && quota != "-1" { val, err := strconv.ParseUint(quota, 10, 64) if err != nil { glog.Errorf("GetSpec: Failed to parse CPUQuota from %q: %s", path.Join(cpuRoot, "cpu.cfs_quota_us"), err) } spec.Cpu.Quota = val } } } // Cpu Mask. // This will fail for non-unified hierarchies. We'll return the whole machine mask in that case. cpusetRoot, ok := cgroupPaths["cpuset"] if ok { if utils.FileExists(cpusetRoot) { spec.HasCpu = true mask := readString(cpusetRoot, "cpuset.cpus") spec.Cpu.Mask = utils.FixCpuMask(mask, mi.NumCores) } } // Memory if name == "/" { // Get memory and swap limits of the running machine memLimit, err := machine.GetMachineMemoryCapacity() if err != nil { glog.Warningf("failed to obtain memory limit for machine container") spec.HasMemory = false } else { spec.Memory.Limit = uint64(memLimit) // Spec is marked to have memory only if the memory limit is set spec.HasMemory = true } swapLimit, err := machine.GetMachineSwapCapacity() if err != nil { glog.Warningf("failed to obtain swap limit for machine container") } else { spec.Memory.SwapLimit = uint64(swapLimit) } } else { memoryRoot, ok := cgroupPaths["memory"] if ok { if utils.FileExists(memoryRoot) { spec.HasMemory = true spec.Memory.Limit = readUInt64(memoryRoot, "memory.limit_in_bytes") spec.Memory.SwapLimit = readUInt64(memoryRoot, "memory.memsw.limit_in_bytes") } } } spec.HasFilesystem = name == "/" || externalMounts != nil || handler.HasFilesystem() spec.HasNetwork = handler.HasNetwork() if blkioRoot, ok := cgroupPaths["blkio"]; ok && utils.FileExists(blkioRoot) { spec.HasDiskIo = true } // Check physical network devices for root container. nd, err := handler.GetRootNetworkDevices() if err != nil { return spec, err } spec.HasNetwork = spec.HasNetwork || len(nd) != 0 return spec, nil }