diff --git a/pkg/libcontainer/cgroups/fs/cpu.go b/pkg/libcontainer/cgroups/fs/cpu.go index 1c266f4a10..2e9d588f4f 100644 --- a/pkg/libcontainer/cgroups/fs/cpu.go +++ b/pkg/libcontainer/cgroups/fs/cpu.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "strconv" + "syscall" "github.com/dotcloud/docker/pkg/libcontainer/cgroups" ) @@ -49,6 +50,9 @@ func (s *cpuGroup) GetStats(d *data, stats *cgroups.Stats) error { f, err := os.Open(filepath.Join(path, "cpu.stat")) if err != nil { + if pathErr, ok := err.(*os.PathError); ok && pathErr.Err == syscall.ENOENT { + return nil + } return err } defer f.Close() diff --git a/pkg/libcontainer/nsinit/nsinit/main.go b/pkg/libcontainer/nsinit/nsinit/main.go index b076b5c55c..5d968375ed 100644 --- a/pkg/libcontainer/nsinit/nsinit/main.go +++ b/pkg/libcontainer/nsinit/nsinit/main.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "fmt" "io/ioutil" "log" "os" @@ -11,6 +12,7 @@ import ( "strconv" "github.com/dotcloud/docker/pkg/libcontainer" + "github.com/dotcloud/docker/pkg/libcontainer/cgroups/fs" "github.com/dotcloud/docker/pkg/libcontainer/nsinit" ) @@ -67,6 +69,26 @@ func main() { if err := nsinit.Init(container, rootfs, console, syncPipe, os.Args[2:]); err != nil { log.Fatalf("unable to initialize for container: %s", err) } + case "stats": + // returns the stats of the current container. + stats, err := getContainerStats(container) + if err != nil { + log.Printf("Failed to get stats - %v\n", err) + os.Exit(1) + } + fmt.Printf("Stats:\n%v\n", stats) + os.Exit(0) + + case "spec": + // returns the spec of the current container. + spec, err := getContainerSpec(container) + if err != nil { + log.Printf("Failed to get spec - %v\n", err) + os.Exit(1) + } + fmt.Printf("Spec:\n%v\n", spec) + os.Exit(0) + default: log.Fatalf("command not supported for nsinit %s", os.Args[0]) } @@ -125,3 +147,25 @@ func startContainer(container *libcontainer.Container, term nsinit.Terminal, dat return nsinit.Exec(container, term, "", dataPath, args, createCommand, startCallback) } + +// returns the container stats in json format. +func getContainerStats(container *libcontainer.Container) (string, error) { + stats, err := fs.GetStats(container.Cgroups) + if err != nil { + return "", err + } + out, err := json.MarshalIndent(stats, "", "\t") + if err != nil { + return "", err + } + return string(out), nil +} + +// returns the container spec in json format. +func getContainerSpec(container *libcontainer.Container) (string, error) { + spec, err := json.MarshalIndent(container, "", "\t") + if err != nil { + return "", err + } + return string(spec), nil +}