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 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 (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(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 }