Merge pull request #489 from vmarmol/create

Add container creation time to ContainerSpec.
This commit is contained in:
Rohit Jnagal 2015-02-05 10:38:59 -08:00
commit 238a761ffc
4 changed files with 66 additions and 9 deletions

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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))