Merge pull request #489 from vmarmol/create
Add container creation time to ContainerSpec.
This commit is contained in:
commit
238a761ffc
@ -23,6 +23,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/libcontainer"
|
||||
"github.com/docker/libcontainer/cgroups"
|
||||
@ -68,6 +69,9 @@ type dockerContainerHandler struct {
|
||||
usesAufsDriver bool
|
||||
fsInfo fs.FsInfo
|
||||
storageDirs []string
|
||||
|
||||
// Time at which this container was created.
|
||||
creationTime time.Time
|
||||
}
|
||||
|
||||
func DockerStateDir() string {
|
||||
@ -119,6 +123,7 @@ func newDockerContainerHandler(
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to inspect container %q: %v", id, err)
|
||||
}
|
||||
handler.creationTime = ctnr.Created
|
||||
|
||||
// Add the name and bare ID as aliases of the container.
|
||||
handler.aliases = append(handler.aliases, strings.TrimPrefix(ctnr.Name, "/"))
|
||||
@ -235,23 +240,23 @@ func libcontainerConfigToContainerSpec(config *libcontainer.Config, mi *info.Mac
|
||||
return spec
|
||||
}
|
||||
|
||||
func (self *dockerContainerHandler) GetSpec() (spec info.ContainerSpec, err error) {
|
||||
func (self *dockerContainerHandler) GetSpec() (info.ContainerSpec, error) {
|
||||
mi, err := self.machineInfoFactory.GetMachineInfo()
|
||||
if err != nil {
|
||||
return
|
||||
return info.ContainerSpec{}, err
|
||||
}
|
||||
libcontainerConfig, err := self.readLibcontainerConfig()
|
||||
if err != nil {
|
||||
return
|
||||
return info.ContainerSpec{}, err
|
||||
}
|
||||
|
||||
spec = libcontainerConfigToContainerSpec(libcontainerConfig, mi)
|
||||
|
||||
spec := libcontainerConfigToContainerSpec(libcontainerConfig, mi)
|
||||
spec.CreationTime = self.creationTime
|
||||
if self.usesAufsDriver {
|
||||
spec.HasFilesystem = true
|
||||
}
|
||||
|
||||
return
|
||||
return spec, err
|
||||
}
|
||||
|
||||
func (self *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error {
|
||||
|
@ -18,9 +18,11 @@ package raw
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.google.com/p/go.exp/inotify"
|
||||
dockerlibcontainer "github.com/docker/libcontainer"
|
||||
@ -180,6 +182,20 @@ func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) {
|
||||
|
||||
// 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 {
|
||||
|
@ -40,6 +40,9 @@ type MemorySpec struct {
|
||||
}
|
||||
|
||||
type ContainerSpec struct {
|
||||
// Time at which the container was created.
|
||||
CreationTime time.Time `json:"creation_time,omitempty"`
|
||||
|
||||
HasCpu bool `json:"has_cpu"`
|
||||
Cpu CpuSpec `json:"cpu,omitempty"`
|
||||
|
||||
@ -88,6 +91,7 @@ type ContainerInfo struct {
|
||||
Stats []*ContainerStats `json:"stats,omitempty"`
|
||||
}
|
||||
|
||||
// TODO(vmarmol): Refactor to not need this equality comparison.
|
||||
// ContainerInfo may be (un)marshaled by json or other en/decoder. In that
|
||||
// case, the Timestamp field in each stats/sample may not be precisely
|
||||
// en/decoded. This will lead to small but acceptable differences between a
|
||||
@ -111,7 +115,7 @@ func (self *ContainerInfo) Eq(b *ContainerInfo) bool {
|
||||
if !reflect.DeepEqual(self.Subcontainers, b.Subcontainers) {
|
||||
return false
|
||||
}
|
||||
if !reflect.DeepEqual(self.Spec, b.Spec) {
|
||||
if !self.Spec.Eq(&b.Spec) {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -125,6 +129,37 @@ func (self *ContainerInfo) Eq(b *ContainerInfo) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *ContainerSpec) Eq(b *ContainerSpec) bool {
|
||||
// Creation within 1s of each other.
|
||||
diff := self.CreationTime.Sub(b.CreationTime)
|
||||
if (diff > time.Second) || (diff < -time.Second) {
|
||||
return false
|
||||
}
|
||||
|
||||
if self.HasCpu != b.HasCpu {
|
||||
return false
|
||||
}
|
||||
if !reflect.DeepEqual(self.Cpu, b.Cpu) {
|
||||
return false
|
||||
}
|
||||
if self.HasMemory != b.HasMemory {
|
||||
return false
|
||||
}
|
||||
if !reflect.DeepEqual(self.Memory, b.Memory) {
|
||||
return false
|
||||
}
|
||||
if self.HasNetwork != b.HasNetwork {
|
||||
return false
|
||||
}
|
||||
if self.HasFilesystem != b.HasFilesystem {
|
||||
return false
|
||||
}
|
||||
if self.HasDiskIo != b.HasDiskIo {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *ContainerInfo) StatsAfter(ref time.Time) []*ContainerStats {
|
||||
n := len(self.Stats) + 1
|
||||
for i, s := range self.Stats {
|
||||
|
@ -51,8 +51,9 @@ func GenerateRandomStats(numStats, numCores int, duration time.Duration) []*info
|
||||
|
||||
func GenerateRandomContainerSpec(numCores int) info.ContainerSpec {
|
||||
ret := info.ContainerSpec{
|
||||
Cpu: info.CpuSpec{},
|
||||
Memory: info.MemorySpec{},
|
||||
CreationTime: time.Now(),
|
||||
Cpu: info.CpuSpec{},
|
||||
Memory: info.MemorySpec{},
|
||||
}
|
||||
ret.Cpu.Limit = uint64(1000 + rand.Int63n(2000))
|
||||
ret.Cpu.MaxLimit = uint64(1000 + rand.Int63n(2000))
|
||||
|
Loading…
Reference in New Issue
Block a user