Skip to content

Commit

Permalink
Merge pull request kubernetes#489 from vmarmol/create
Browse files Browse the repository at this point in the history
Add container creation time to ContainerSpec.
  • Loading branch information
rjnagal committed Feb 5, 2015
2 parents 5e61b39 + 45ba276 commit 238a761
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 9 deletions.
17 changes: 11 additions & 6 deletions container/docker/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"os"
"path"
"strings"
"time"

"github.com/docker/libcontainer"
"github.com/docker/libcontainer/cgroups"
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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, "/"))
Expand Down Expand Up @@ -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 {
Expand Down
16 changes: 16 additions & 0 deletions container/raw/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 {
Expand Down
37 changes: 36 additions & 1 deletion info/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`

Expand Down Expand Up @@ -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
Expand All @@ -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
}

Expand All @@ -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 {
Expand Down
5 changes: 3 additions & 2 deletions info/test/datagen.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down

0 comments on commit 238a761

Please sign in to comment.