From 58ef35edcb98eac07c221ae4d83374b162b8bf8e Mon Sep 17 00:00:00 2001 From: Kathryn Baldauf Date: Fri, 11 Oct 2019 15:53:21 -0700 Subject: [PATCH] update getPropertiesV2 with ability to get container stats for LCOW Signed-off-by: Kathryn Baldauf --- go.mod | 2 +- go.sum | 2 ++ internal/runtime/hcsv2/container.go | 18 ++++++++++++++ service/gcs/bridge/bridge_v2.go | 38 +++++++++++++++++++++-------- service/gcs/prot/protocol.go | 6 +++++ 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 24ac2cec..f3e860cd 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.12 require ( github.com/Microsoft/go-winio v0.4.12 github.com/Microsoft/hcsshim v0.0.0-20190404205635-cf1c2137fae1 - github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f + github.com/containerd/cgroups v0.0.0-20191011165608-5fbad35c2a7e github.com/containerd/containerd v1.3.0 github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02 // indirect github.com/docker/docker v0.0.0-20190404075923-dbe4a30928d4 diff --git a/go.sum b/go.sum index b13e3e15..9e2ca4ca 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,8 @@ github.com/Microsoft/hcsshim v0.0.0-20190404205635-cf1c2137fae1/go.mod h1:Op3hHs github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s= github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= +github.com/containerd/cgroups v0.0.0-20191011165608-5fbad35c2a7e h1:3bt+8T1I/CuYx+a5ww32+UT4fc9x8iRiXrhfduFTlBU= +github.com/containerd/cgroups v0.0.0-20191011165608-5fbad35c2a7e/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= github.com/containerd/containerd v1.3.0 h1:xjvXQWABwS2uiv3TWgQt5Uth60Gu86LTGZXMJkjc7rY= github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02 h1:tN9D97v5A5QuKdcKHKt+UMKrkQ5YXUnD8iM7IAAjEfI= diff --git a/internal/runtime/hcsv2/container.go b/internal/runtime/hcsv2/container.go index 690cd4d6..dc7c0e99 100644 --- a/internal/runtime/hcsv2/container.go +++ b/internal/runtime/hcsv2/container.go @@ -12,7 +12,10 @@ import ( "github.com/Microsoft/opengcs/service/gcs/runtime" "github.com/Microsoft/opengcs/service/gcs/stdio" "github.com/Microsoft/opengcs/service/gcs/transport" + "github.com/containerd/cgroups" + v1 "github.com/containerd/cgroups/stats/v1" oci "github.com/opencontainers/runtime-spec/specs-go" + "github.com/pkg/errors" "go.opencensus.io/trace" ) @@ -137,3 +140,18 @@ func (c *Container) setExitType(signal syscall.Signal) { c.exitType = prot.NtForcedExit } } + +// GetStats returns the cgroup metrics for the container. +func (c *Container) GetStats(ctx context.Context) (*v1.Metrics, error) { + _, span := trace.StartSpan(ctx, "opengcs::Container::GetStats") + defer span.End() + span.AddAttributes(trace.StringAttribute("cid", c.id)) + + cgroupPath := c.spec.Linux.CgroupsPath + cg, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(cgroupPath)) + if err != nil { + return nil, errors.Errorf("failed to get container stats for %v: %v", c.id, err) + } + + return cg.Stat(cgroups.IgnoreNotExist) +} diff --git a/service/gcs/bridge/bridge_v2.go b/service/gcs/bridge/bridge_v2.go index f05d5c8d..bc55e483 100644 --- a/service/gcs/bridge/bridge_v2.go +++ b/service/gcs/bridge/bridge_v2.go @@ -324,24 +324,42 @@ func (b *Bridge) getPropertiesV2(r *Request) (_ RequestResponse, err error) { return nil, errors.Wrapf(err, "failed to unmarshal JSON in message \"%s\"", r.Message) } - var properties *prot.Properties + properties := &prot.PropertiesV2{} + + var query prot.PropertyQuery + if len(request.Query) != 0 { + if err := json.Unmarshal([]byte(request.Query), &query); err != nil { + e := gcserr.WrapHresult(err, gcserr.HrVmcomputeInvalidJSON) + return nil, errors.Wrapf(e, "The query could not be unmarshaled: '%s'", query) + } + } + if request.ContainerID == hcsv2.UVMContainerID { return nil, errors.New("getPropertiesV2 is not supported against the UVM") } + c, err := b.hostState.GetContainer(request.ContainerID) if err != nil { return nil, err } - pids, err := c.GetAllProcessPids(ctx) - if err != nil { - return nil, err - } - properties = &prot.Properties{ - ProcessList: make([]prot.ProcessDetails, len(pids)), - } - for i, pid := range pids { - properties.ProcessList[i].ProcessID = uint32(pid) + for _, requestedProperty := range query.PropertyTypes { + if requestedProperty == prot.PtProcessList { + pids, err := c.GetAllProcessPids(ctx) + if err != nil { + return nil, err + } + properties.ProcessList = make([]prot.ProcessDetails, len(pids)) + for i, pid := range pids { + properties.ProcessList[i].ProcessID = uint32(pid) + } + } else if requestedProperty == prot.PtStatistics { + cgroupMetrics, err := c.GetStats(ctx) + if err != nil { + return nil, err + } + properties.Metrics = cgroupMetrics + } } propertyJSON := []byte("{}") diff --git a/service/gcs/prot/protocol.go b/service/gcs/prot/protocol.go index e65fc1a9..3a1033fe 100644 --- a/service/gcs/prot/protocol.go +++ b/service/gcs/prot/protocol.go @@ -8,6 +8,7 @@ import ( "strconv" "github.com/Microsoft/opengcs/service/libs/commonutils" + v1 "github.com/containerd/cgroups/stats/v1" oci "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" ) @@ -932,3 +933,8 @@ type PropertyQuery struct { type Properties struct { ProcessList []ProcessDetails `json:",omitempty"` } + +type PropertiesV2 struct { + ProcessList []ProcessDetails `json:"ProcessList,omitempty"` + Metrics *v1.Metrics `json:"LCOWMetrics,omitempty"` +}