Merge pull request #1287 from crosbymichael/cgroups

Use type alias from containerd for cgroup metric types
This commit is contained in:
Lantao Liu 2019-09-24 17:34:49 -07:00 committed by GitHub
commit 2eba67a7ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 360 additions and 207 deletions

View File

@ -19,8 +19,8 @@ limitations under the License.
package server package server
import ( import (
"github.com/containerd/cgroups"
"github.com/containerd/containerd/api/types" "github.com/containerd/containerd/api/types"
v1 "github.com/containerd/containerd/metrics/types/v1"
"github.com/containerd/typeurl" "github.com/containerd/typeurl"
"github.com/pkg/errors" "github.com/pkg/errors"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
@ -61,7 +61,7 @@ func (c *criService) containerMetrics(
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to extract container metrics") return nil, errors.Wrap(err, "failed to extract container metrics")
} }
metrics := s.(*cgroups.Metrics) metrics := s.(*v1.Metrics)
if metrics.CPU != nil && metrics.CPU.Usage != nil { if metrics.CPU != nil && metrics.CPU.Usage != nil {
cs.Cpu = &runtime.CpuUsage{ cs.Cpu = &runtime.CpuUsage{
Timestamp: stats.Timestamp.UnixNano(), Timestamp: stats.Timestamp.UnixNano(),
@ -84,7 +84,7 @@ func (c *criService) containerMetrics(
// getWorkingSet calculates workingset memory from cgroup memory stats. // getWorkingSet calculates workingset memory from cgroup memory stats.
// The caller should make sure memory is not nil. // The caller should make sure memory is not nil.
// workingset = usage - total_inactive_file // workingset = usage - total_inactive_file
func getWorkingSet(memory *cgroups.MemoryStat) uint64 { func getWorkingSet(memory *v1.MemoryStat) uint64 {
if memory.Usage == nil { if memory.Usage == nil {
return 0 return 0
} }

View File

@ -44,7 +44,7 @@ github.com/containerd/ttrpc 92c8520ef9f86600c650dd540266a007bf03670f
github.com/containerd/go-runc 9007c2405372fe28918845901a3276c0915689a1 github.com/containerd/go-runc 9007c2405372fe28918845901a3276c0915689a1
github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13 github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
github.com/containerd/continuity f2a389ac0a02ce21c09edd7344677a601970f41c github.com/containerd/continuity f2a389ac0a02ce21c09edd7344677a601970f41c
github.com/containerd/containerd 59a625defb21c958c25424fa5cc806167e22382e github.com/containerd/containerd ed16170c4c399c57f25d6aa1e97b345ed6ab96cb
github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
github.com/containerd/cgroups c4b9ac5c7601384c965b9646fc515884e091ebb9 github.com/containerd/cgroups c4b9ac5c7601384c965b9646fc515884e091ebb9
github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9 github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9

View File

@ -70,6 +70,17 @@ func App() *cli.App {
app.Name = "containerd" app.Name = "containerd"
app.Version = version.Version app.Version = version.Version
app.Usage = usage app.Usage = usage
app.Description = `
containerd is a high performance container runtime whose daemon can be started
by using this command. If none of the *config*, *publish*, or *help* commands
are specified, the default action of the **containerd** command is to start the
containerd daemon in the foreground.
A default configuration is used if no TOML configuration is specified or located
at the default file location. The *containerd config* command can be used to
generate the default configuration for containerd. The output of that command
can be used and modified as necessary as a custom configuration.`
app.Flags = []cli.Flag{ app.Flags = []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "config,c", Name: "config,c",

View File

@ -88,11 +88,11 @@ type StreamProcessor interface {
} }
func compressedHandler(ctx context.Context, mediaType string) (StreamProcessorInit, bool) { func compressedHandler(ctx context.Context, mediaType string) (StreamProcessorInit, bool) {
compressed, err := images.IsCompressedDiff(ctx, mediaType) compressed, err := images.DiffCompression(ctx, mediaType)
if err != nil { if err != nil {
return nil, false return nil, false
} }
if compressed { if compressed != "" {
return func(ctx context.Context, stream StreamProcessor, payloads map[string]*types.Any) (StreamProcessor, error) { return func(ctx context.Context, stream StreamProcessor, payloads map[string]*types.Any) (StreamProcessor, error) {
ds, err := compression.DecompressStream(stream) ds, err := compression.DecompressStream(stream)
if err != nil { if err != nil {

View File

@ -20,7 +20,6 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"sort" "sort"
"strings"
"time" "time"
"github.com/containerd/containerd/content" "github.com/containerd/containerd/content"
@ -358,16 +357,11 @@ func Children(ctx context.Context, provider content.Provider, desc ocispec.Descr
} }
descs = append(descs, index.Manifests...) descs = append(descs, index.Manifests...)
case MediaTypeDockerSchema2Layer, MediaTypeDockerSchema2LayerGzip,
MediaTypeDockerSchema2LayerEnc, MediaTypeDockerSchema2LayerGzipEnc,
MediaTypeDockerSchema2LayerForeign, MediaTypeDockerSchema2LayerForeignGzip,
MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig,
ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerGzip,
ocispec.MediaTypeImageLayerNonDistributable, ocispec.MediaTypeImageLayerNonDistributableGzip,
MediaTypeContainerd1Checkpoint, MediaTypeContainerd1CheckpointConfig:
// childless data types.
return nil, nil
default: default:
if IsLayerType(desc.MediaType) || IsKnownConfig(desc.MediaType) {
// childless data types.
return nil, nil
}
log.G(ctx).Warnf("encountered unknown type %v; children may not be fetched", desc.MediaType) log.G(ctx).Warnf("encountered unknown type %v; children may not be fetched", desc.MediaType)
} }
@ -390,72 +384,3 @@ func RootFS(ctx context.Context, provider content.Provider, configDesc ocispec.D
} }
return config.RootFS.DiffIDs, nil return config.RootFS.DiffIDs, nil
} }
// IsCompressedDiff returns true if mediaType is a known compressed diff media type.
// It returns false if the media type is a diff, but not compressed. If the media type
// is not a known diff type, it returns errdefs.ErrNotImplemented
func IsCompressedDiff(ctx context.Context, mediaType string) (bool, error) {
switch mediaType {
case ocispec.MediaTypeImageLayer, MediaTypeDockerSchema2Layer:
case ocispec.MediaTypeImageLayerGzip, MediaTypeDockerSchema2LayerGzip:
return true, nil
default:
// Still apply all generic media types *.tar[.+]gzip and *.tar
if strings.HasSuffix(mediaType, ".tar.gzip") || strings.HasSuffix(mediaType, ".tar+gzip") {
return true, nil
} else if !strings.HasSuffix(mediaType, ".tar") {
return false, errdefs.ErrNotImplemented
}
}
return false, nil
}
// GetImageLayerDescriptors gets the image layer Descriptors of an image; the array contains
// a list of Descriptors belonging to one platform followed by lists of other platforms
func GetImageLayerDescriptors(ctx context.Context, cs content.Store, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
var lis []ocispec.Descriptor
ds := platforms.DefaultSpec()
platform := &ds
switch desc.MediaType {
case MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex,
MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
children, err := Children(ctx, cs, desc)
if err != nil {
if errdefs.IsNotFound(err) {
return []ocispec.Descriptor{}, nil
}
return []ocispec.Descriptor{}, err
}
if desc.Platform != nil {
platform = desc.Platform
}
for _, child := range children {
var tmp []ocispec.Descriptor
switch child.MediaType {
case MediaTypeDockerSchema2LayerGzip, MediaTypeDockerSchema2Layer,
ocispec.MediaTypeImageLayerGzip, ocispec.MediaTypeImageLayer,
MediaTypeDockerSchema2LayerGzipEnc, MediaTypeDockerSchema2LayerEnc:
tdesc := child
tdesc.Platform = platform
tmp = append(tmp, tdesc)
default:
tmp, err = GetImageLayerDescriptors(ctx, cs, child)
}
if err != nil {
return []ocispec.Descriptor{}, err
}
lis = append(lis, tmp...)
}
case MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig:
default:
return nil, errors.Wrapf(errdefs.ErrInvalidArgument, "GetImageLayerInfo: unhandled media type %s", desc.MediaType)
}
return lis, nil
}

View File

@ -16,16 +16,23 @@
package images package images
import (
"context"
"sort"
"strings"
"github.com/containerd/containerd/errdefs"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// mediatype definitions for image components handled in containerd. // mediatype definitions for image components handled in containerd.
// //
// oci components are generally referenced directly, although we may centralize // oci components are generally referenced directly, although we may centralize
// here for clarity. // here for clarity.
const ( const (
MediaTypeDockerSchema2Layer = "application/vnd.docker.image.rootfs.diff.tar" MediaTypeDockerSchema2Layer = "application/vnd.docker.image.rootfs.diff.tar"
MediaTypeDockerSchema2LayerEnc = "application/vnd.docker.image.rootfs.diff.tar+enc"
MediaTypeDockerSchema2LayerForeign = "application/vnd.docker.image.rootfs.foreign.diff.tar" MediaTypeDockerSchema2LayerForeign = "application/vnd.docker.image.rootfs.foreign.diff.tar"
MediaTypeDockerSchema2LayerGzip = "application/vnd.docker.image.rootfs.diff.tar.gzip" MediaTypeDockerSchema2LayerGzip = "application/vnd.docker.image.rootfs.diff.tar.gzip"
MediaTypeDockerSchema2LayerGzipEnc = "application/vnd.docker.image.rootfs.diff.tar.gzip+enc"
MediaTypeDockerSchema2LayerForeignGzip = "application/vnd.docker.image.rootfs.foreign.diff.tar.gzip" MediaTypeDockerSchema2LayerForeignGzip = "application/vnd.docker.image.rootfs.foreign.diff.tar.gzip"
MediaTypeDockerSchema2Config = "application/vnd.docker.container.image.v1+json" MediaTypeDockerSchema2Config = "application/vnd.docker.container.image.v1+json"
MediaTypeDockerSchema2Manifest = "application/vnd.docker.distribution.manifest.v2+json" MediaTypeDockerSchema2Manifest = "application/vnd.docker.distribution.manifest.v2+json"
@ -42,3 +49,78 @@ const (
// Legacy Docker schema1 manifest // Legacy Docker schema1 manifest
MediaTypeDockerSchema1Manifest = "application/vnd.docker.distribution.manifest.v1+prettyjws" MediaTypeDockerSchema1Manifest = "application/vnd.docker.distribution.manifest.v1+prettyjws"
) )
// DiffCompression returns the compression as defined by the layer diff media
// type. For Docker media types without compression, "unknown" is returned to
// indicate that the media type may be compressed. If the media type is not
// recognized as a layer diff, then it returns errdefs.ErrNotImplemented
func DiffCompression(ctx context.Context, mediaType string) (string, error) {
base, ext := parseMediaTypes(mediaType)
switch base {
case MediaTypeDockerSchema2Layer, MediaTypeDockerSchema2LayerForeign:
if len(ext) > 0 {
// Type is wrapped
return "", nil
}
// These media types may have been compressed but failed to
// use the correct media type. The decompression function
// should detect and handle this case.
return "unknown", nil
case MediaTypeDockerSchema2LayerGzip, MediaTypeDockerSchema2LayerForeignGzip:
if len(ext) > 0 {
// Type is wrapped
return "", nil
}
return "gzip", nil
case ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerNonDistributable:
if len(ext) > 0 {
switch ext[len(ext)-1] {
case "gzip":
return "gzip", nil
}
}
return "", nil
default:
return "", errdefs.ErrNotImplemented
}
}
// parseMediaTypes splits the media type into the base type and
// an array of sorted extensions
func parseMediaTypes(mt string) (string, []string) {
if mt == "" {
return "", []string{}
}
s := strings.Split(mt, "+")
ext := s[1:]
sort.Strings(ext)
return s[0], ext
}
// IsLayerTypes returns true if the media type is a layer
func IsLayerType(mt string) bool {
if strings.HasPrefix(mt, "application/vnd.oci.image.layer.") {
return true
}
// Parse Docker media types, strip off any + suffixes first
base, _ := parseMediaTypes(mt)
switch base {
case MediaTypeDockerSchema2Layer, MediaTypeDockerSchema2LayerGzip,
MediaTypeDockerSchema2LayerForeign, MediaTypeDockerSchema2LayerForeignGzip:
return true
}
return false
}
// IsKnownConfig returns true if the media type is a known config type
func IsKnownConfig(mt string) bool {
switch mt {
case MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig,
MediaTypeContainerd1Checkpoint, MediaTypeContainerd1CheckpointConfig:
return true
}
return false
}

View File

@ -21,7 +21,7 @@ package cgroups
import ( import (
"strconv" "strconv"
"github.com/containerd/cgroups" v1 "github.com/containerd/containerd/metrics/types/v1"
metrics "github.com/docker/go-metrics" metrics "github.com/docker/go-metrics"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -33,7 +33,7 @@ var blkioMetrics = []*metric{
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"op", "device", "major", "minor"}, labels: []string{"op", "device", "major", "minor"},
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Blkio == nil { if stats.Blkio == nil {
return nil return nil
} }
@ -46,7 +46,7 @@ var blkioMetrics = []*metric{
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"op", "device", "major", "minor"}, labels: []string{"op", "device", "major", "minor"},
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Blkio == nil { if stats.Blkio == nil {
return nil return nil
} }
@ -59,7 +59,7 @@ var blkioMetrics = []*metric{
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"op", "device", "major", "minor"}, labels: []string{"op", "device", "major", "minor"},
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Blkio == nil { if stats.Blkio == nil {
return nil return nil
} }
@ -72,7 +72,7 @@ var blkioMetrics = []*metric{
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"op", "device", "major", "minor"}, labels: []string{"op", "device", "major", "minor"},
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Blkio == nil { if stats.Blkio == nil {
return nil return nil
} }
@ -85,7 +85,7 @@ var blkioMetrics = []*metric{
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"op", "device", "major", "minor"}, labels: []string{"op", "device", "major", "minor"},
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Blkio == nil { if stats.Blkio == nil {
return nil return nil
} }
@ -98,7 +98,7 @@ var blkioMetrics = []*metric{
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"op", "device", "major", "minor"}, labels: []string{"op", "device", "major", "minor"},
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Blkio == nil { if stats.Blkio == nil {
return nil return nil
} }
@ -111,7 +111,7 @@ var blkioMetrics = []*metric{
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"op", "device", "major", "minor"}, labels: []string{"op", "device", "major", "minor"},
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Blkio == nil { if stats.Blkio == nil {
return nil return nil
} }
@ -120,7 +120,7 @@ var blkioMetrics = []*metric{
}, },
} }
func blkioValues(l []*cgroups.BlkIOEntry) []value { func blkioValues(l []*v1.BlkIOEntry) []value {
var out []value var out []value
for _, e := range l { for _, e := range l {
out = append(out, value{ out = append(out, value{

View File

@ -21,7 +21,7 @@ package cgroups
import ( import (
"strconv" "strconv"
"github.com/containerd/cgroups" v1 "github.com/containerd/containerd/metrics/types/v1"
metrics "github.com/docker/go-metrics" metrics "github.com/docker/go-metrics"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -32,7 +32,7 @@ var cpuMetrics = []*metric{
help: "The total cpu time", help: "The total cpu time",
unit: metrics.Nanoseconds, unit: metrics.Nanoseconds,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.CPU == nil { if stats.CPU == nil {
return nil return nil
} }
@ -48,7 +48,7 @@ var cpuMetrics = []*metric{
help: "The total kernel cpu time", help: "The total kernel cpu time",
unit: metrics.Nanoseconds, unit: metrics.Nanoseconds,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.CPU == nil { if stats.CPU == nil {
return nil return nil
} }
@ -64,7 +64,7 @@ var cpuMetrics = []*metric{
help: "The total user cpu time", help: "The total user cpu time",
unit: metrics.Nanoseconds, unit: metrics.Nanoseconds,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.CPU == nil { if stats.CPU == nil {
return nil return nil
} }
@ -81,7 +81,7 @@ var cpuMetrics = []*metric{
unit: metrics.Nanoseconds, unit: metrics.Nanoseconds,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"cpu"}, labels: []string{"cpu"},
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.CPU == nil { if stats.CPU == nil {
return nil return nil
} }
@ -100,7 +100,7 @@ var cpuMetrics = []*metric{
help: "The total cpu throttle periods", help: "The total cpu throttle periods",
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.CPU == nil { if stats.CPU == nil {
return nil return nil
} }
@ -116,7 +116,7 @@ var cpuMetrics = []*metric{
help: "The total cpu throttled periods", help: "The total cpu throttled periods",
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.CPU == nil { if stats.CPU == nil {
return nil return nil
} }
@ -132,7 +132,7 @@ var cpuMetrics = []*metric{
help: "The total cpu throttled time", help: "The total cpu throttled time",
unit: metrics.Nanoseconds, unit: metrics.Nanoseconds,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.CPU == nil { if stats.CPU == nil {
return nil return nil
} }

View File

@ -19,7 +19,7 @@
package cgroups package cgroups
import ( import (
"github.com/containerd/cgroups" v1 "github.com/containerd/containerd/metrics/types/v1"
metrics "github.com/docker/go-metrics" metrics "github.com/docker/go-metrics"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -31,7 +31,7 @@ var hugetlbMetrics = []*metric{
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"page"}, labels: []string{"page"},
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Hugetlb == nil { if stats.Hugetlb == nil {
return nil return nil
} }
@ -51,7 +51,7 @@ var hugetlbMetrics = []*metric{
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"page"}, labels: []string{"page"},
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Hugetlb == nil { if stats.Hugetlb == nil {
return nil return nil
} }
@ -71,7 +71,7 @@ var hugetlbMetrics = []*metric{
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"page"}, labels: []string{"page"},
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Hugetlb == nil { if stats.Hugetlb == nil {
return nil return nil
} }

View File

@ -19,7 +19,7 @@
package cgroups package cgroups
import ( import (
"github.com/containerd/cgroups" v1 "github.com/containerd/containerd/metrics/types/v1"
metrics "github.com/docker/go-metrics" metrics "github.com/docker/go-metrics"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -30,7 +30,7 @@ var memoryMetrics = []*metric{
help: "The cache amount used", help: "The cache amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -46,7 +46,7 @@ var memoryMetrics = []*metric{
help: "The rss amount used", help: "The rss amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -62,7 +62,7 @@ var memoryMetrics = []*metric{
help: "The rss_huge amount used", help: "The rss_huge amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -78,7 +78,7 @@ var memoryMetrics = []*metric{
help: "The mapped_file amount used", help: "The mapped_file amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -94,7 +94,7 @@ var memoryMetrics = []*metric{
help: "The dirty amount", help: "The dirty amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -110,7 +110,7 @@ var memoryMetrics = []*metric{
help: "The writeback amount", help: "The writeback amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -126,7 +126,7 @@ var memoryMetrics = []*metric{
help: "The pgpgin amount", help: "The pgpgin amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -142,7 +142,7 @@ var memoryMetrics = []*metric{
help: "The pgpgout amount", help: "The pgpgout amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -158,7 +158,7 @@ var memoryMetrics = []*metric{
help: "The pgfault amount", help: "The pgfault amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -174,7 +174,7 @@ var memoryMetrics = []*metric{
help: "The pgmajfault amount", help: "The pgmajfault amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -190,7 +190,7 @@ var memoryMetrics = []*metric{
help: "The inactive_anon amount", help: "The inactive_anon amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -206,7 +206,7 @@ var memoryMetrics = []*metric{
help: "The active_anon amount", help: "The active_anon amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -222,7 +222,7 @@ var memoryMetrics = []*metric{
help: "The inactive_file amount", help: "The inactive_file amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -238,7 +238,7 @@ var memoryMetrics = []*metric{
help: "The active_file amount", help: "The active_file amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -254,7 +254,7 @@ var memoryMetrics = []*metric{
help: "The unevictable amount", help: "The unevictable amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -270,7 +270,7 @@ var memoryMetrics = []*metric{
help: "The hierarchical_memory_limit amount", help: "The hierarchical_memory_limit amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -286,7 +286,7 @@ var memoryMetrics = []*metric{
help: "The hierarchical_memsw_limit amount", help: "The hierarchical_memsw_limit amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -302,7 +302,7 @@ var memoryMetrics = []*metric{
help: "The total_cache amount used", help: "The total_cache amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -318,7 +318,7 @@ var memoryMetrics = []*metric{
help: "The total_rss amount used", help: "The total_rss amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -334,7 +334,7 @@ var memoryMetrics = []*metric{
help: "The total_rss_huge amount used", help: "The total_rss_huge amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -350,7 +350,7 @@ var memoryMetrics = []*metric{
help: "The total_mapped_file amount used", help: "The total_mapped_file amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -366,7 +366,7 @@ var memoryMetrics = []*metric{
help: "The total_dirty amount", help: "The total_dirty amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -382,7 +382,7 @@ var memoryMetrics = []*metric{
help: "The total_writeback amount", help: "The total_writeback amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -398,7 +398,7 @@ var memoryMetrics = []*metric{
help: "The total_pgpgin amount", help: "The total_pgpgin amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -414,7 +414,7 @@ var memoryMetrics = []*metric{
help: "The total_pgpgout amount", help: "The total_pgpgout amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -430,7 +430,7 @@ var memoryMetrics = []*metric{
help: "The total_pgfault amount", help: "The total_pgfault amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -446,7 +446,7 @@ var memoryMetrics = []*metric{
help: "The total_pgmajfault amount", help: "The total_pgmajfault amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -462,7 +462,7 @@ var memoryMetrics = []*metric{
help: "The total_inactive_anon amount", help: "The total_inactive_anon amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -478,7 +478,7 @@ var memoryMetrics = []*metric{
help: "The total_active_anon amount", help: "The total_active_anon amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -494,7 +494,7 @@ var memoryMetrics = []*metric{
help: "The total_inactive_file amount", help: "The total_inactive_file amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -510,7 +510,7 @@ var memoryMetrics = []*metric{
help: "The total_active_file amount", help: "The total_active_file amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -526,7 +526,7 @@ var memoryMetrics = []*metric{
help: "The total_unevictable amount", help: "The total_unevictable amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -542,7 +542,7 @@ var memoryMetrics = []*metric{
help: "The usage failcnt", help: "The usage failcnt",
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -558,7 +558,7 @@ var memoryMetrics = []*metric{
help: "The memory limit", help: "The memory limit",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -574,7 +574,7 @@ var memoryMetrics = []*metric{
help: "The memory maximum usage", help: "The memory maximum usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -590,7 +590,7 @@ var memoryMetrics = []*metric{
help: "The memory usage", help: "The memory usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -606,7 +606,7 @@ var memoryMetrics = []*metric{
help: "The swap failcnt", help: "The swap failcnt",
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -622,7 +622,7 @@ var memoryMetrics = []*metric{
help: "The swap limit", help: "The swap limit",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -638,7 +638,7 @@ var memoryMetrics = []*metric{
help: "The swap maximum usage", help: "The swap maximum usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -654,7 +654,7 @@ var memoryMetrics = []*metric{
help: "The swap usage", help: "The swap usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -670,7 +670,7 @@ var memoryMetrics = []*metric{
help: "The kernel failcnt", help: "The kernel failcnt",
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -686,7 +686,7 @@ var memoryMetrics = []*metric{
help: "The kernel limit", help: "The kernel limit",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -702,7 +702,7 @@ var memoryMetrics = []*metric{
help: "The kernel maximum usage", help: "The kernel maximum usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -718,7 +718,7 @@ var memoryMetrics = []*metric{
help: "The kernel usage", help: "The kernel usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -734,7 +734,7 @@ var memoryMetrics = []*metric{
help: "The kerneltcp failcnt", help: "The kerneltcp failcnt",
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -750,7 +750,7 @@ var memoryMetrics = []*metric{
help: "The kerneltcp limit", help: "The kerneltcp limit",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -766,7 +766,7 @@ var memoryMetrics = []*metric{
help: "The kerneltcp maximum usage", help: "The kerneltcp maximum usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -782,7 +782,7 @@ var memoryMetrics = []*metric{
help: "The kerneltcp usage", help: "The kerneltcp usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }

View File

@ -19,7 +19,7 @@
package cgroups package cgroups
import ( import (
"github.com/containerd/cgroups" v1 "github.com/containerd/containerd/metrics/types/v1"
metrics "github.com/docker/go-metrics" metrics "github.com/docker/go-metrics"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -36,7 +36,7 @@ type metric struct {
vt prometheus.ValueType vt prometheus.ValueType
labels []string labels []string
// getValues returns the value and labels for the data // getValues returns the value and labels for the data
getValues func(stats *cgroups.Metrics) []value getValues func(stats *v1.Metrics) []value
} }
func (m *metric) desc(ns *metrics.Namespace) *prometheus.Desc { func (m *metric) desc(ns *metrics.Namespace) *prometheus.Desc {
@ -44,7 +44,7 @@ func (m *metric) desc(ns *metrics.Namespace) *prometheus.Desc {
return ns.NewDesc(m.name, m.help, m.unit, append([]string{"container_id", "namespace"}, m.labels...)...) return ns.NewDesc(m.name, m.help, m.unit, append([]string{"container_id", "namespace"}, m.labels...)...)
} }
func (m *metric) collect(id, namespace string, stats *cgroups.Metrics, ns *metrics.Namespace, ch chan<- prometheus.Metric, block bool) { func (m *metric) collect(id, namespace string, stats *v1.Metrics, ns *metrics.Namespace, ch chan<- prometheus.Metric, block bool) {
values := m.getValues(stats) values := m.getValues(stats)
for _, v := range values { for _, v := range values {
// block signals to block on the sending the metrics so none are missed // block signals to block on the sending the metrics so none are missed

View File

@ -25,6 +25,7 @@ import (
"github.com/containerd/cgroups" "github.com/containerd/cgroups"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
v1 "github.com/containerd/containerd/metrics/types/v1"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/runtime" "github.com/containerd/containerd/runtime"
"github.com/containerd/typeurl" "github.com/containerd/typeurl"
@ -114,7 +115,7 @@ func (c *collector) collect(t runtime.Task, ch chan<- prometheus.Metric, block b
log.L.WithError(err).Errorf("unmarshal stats for %s", t.ID()) log.L.WithError(err).Errorf("unmarshal stats for %s", t.ID())
return return
} }
s, ok := data.(*cgroups.Metrics) s, ok := data.(*v1.Metrics)
if !ok { if !ok {
log.L.WithError(err).Errorf("invalid metric type for %s", t.ID()) log.L.WithError(err).Errorf("invalid metric type for %s", t.ID())
return return

View File

@ -19,7 +19,7 @@
package cgroups package cgroups
import ( import (
"github.com/containerd/cgroups" v1 "github.com/containerd/containerd/metrics/types/v1"
metrics "github.com/docker/go-metrics" metrics "github.com/docker/go-metrics"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -30,7 +30,7 @@ var pidMetrics = []*metric{
help: "The limit to the number of pids allowed", help: "The limit to the number of pids allowed",
unit: metrics.Unit("limit"), unit: metrics.Unit("limit"),
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Pids == nil { if stats.Pids == nil {
return nil return nil
} }
@ -46,7 +46,7 @@ var pidMetrics = []*metric{
help: "The current number of pids", help: "The current number of pids",
unit: metrics.Unit("current"), unit: metrics.Unit("current"),
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Metrics) []value { getValues: func(stats *v1.Metrics) []value {
if stats.Pids == nil { if stats.Pids == nil {
return nil return nil
} }

View File

@ -0,0 +1,44 @@
// +build linux
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import "github.com/containerd/cgroups"
type (
// Metrics alias
Metrics = cgroups.Metrics
// BlkIOEntry alias
BlkIOEntry = cgroups.BlkIOEntry
// MemoryStat alias
MemoryStat = cgroups.MemoryStat
// CPUStat alias
CPUStat = cgroups.CPUStat
// CPUUsage alias
CPUUsage = cgroups.CPUUsage
// BlkIOStat alias
BlkIOStat = cgroups.BlkIOStat
// PidsStat alias
PidsStat = cgroups.PidsStat
// RdmaStat alias
RdmaStat = cgroups.RdmaStat
// RdmaEntry alias
RdmaEntry = cgroups.RdmaEntry
// HugetlbStat alias
HugetlbStat = cgroups.HugetlbStat
)

View File

@ -17,6 +17,7 @@
package oci package oci
import ( import (
"bufio"
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
@ -1200,3 +1201,49 @@ func WithLinuxDevice(path, permissions string) SpecOpts {
return nil return nil
} }
} }
// WithEnvFile adds environment variables from a file to the container's spec
func WithEnvFile(path string) SpecOpts {
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
var vars []string
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
sc := bufio.NewScanner(f)
for sc.Scan() {
if sc.Err() != nil {
return sc.Err()
}
vars = append(vars, sc.Text())
}
return WithEnv(vars)(nil, nil, nil, s)
}
}
// ErrNoShmMount is returned when there is no /dev/shm mount specified in the config
// and an Opts was trying to set a configuration value on the mount.
var ErrNoShmMount = errors.New("no /dev/shm mount specified")
// WithDevShmSize sets the size of the /dev/shm mount for the container.
//
// The size value is specified in kb, kilobytes.
func WithDevShmSize(kb int64) SpecOpts {
return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {
for _, m := range s.Mounts {
if m.Source == "shm" && m.Type == "tmpfs" {
for i, o := range m.Options {
if strings.HasPrefix(o, "size=") {
m.Options[i] = fmt.Sprintf("size=%dk", kb)
return nil
}
}
m.Options = append(m.Options, fmt.Sprintf("size=%dk", kb))
return nil
}
}
return ErrNoShmMount
}
}

View File

@ -28,7 +28,7 @@ func isLinuxOS(os string) bool {
return os == "linux" return os == "linux"
} }
// These function are generated from from https://golang.org/src/go/build/syslist.go. // These function are generated from https://golang.org/src/go/build/syslist.go.
// //
// We use switch statements because they are slightly faster than map lookups // We use switch statements because they are slightly faster than map lookups
// and use a little less memory. // and use a little less memory.
@ -38,7 +38,7 @@ func isLinuxOS(os string) bool {
// The OS value should be normalized before calling this function. // The OS value should be normalized before calling this function.
func isKnownOS(os string) bool { func isKnownOS(os string) bool {
switch os { switch os {
case "android", "darwin", "dragonfly", "freebsd", "linux", "nacl", "netbsd", "openbsd", "plan9", "solaris", "windows", "zos": case "aix", "android", "darwin", "dragonfly", "freebsd", "hurd", "illumos", "js", "linux", "nacl", "netbsd", "openbsd", "plan9", "solaris", "windows", "zos":
return true return true
} }
return false return false
@ -60,7 +60,7 @@ func isArmArch(arch string) bool {
// The arch value should be normalized before being passed to this function. // The arch value should be normalized before being passed to this function.
func isKnownArch(arch string) bool { func isKnownArch(arch string) bool {
switch arch { switch arch {
case "386", "amd64", "amd64p32", "arm", "armbe", "arm64", "arm64be", "ppc64", "ppc64le", "mips", "mipsle", "mips64", "mips64le", "mips64p32", "mips64p32le", "ppc", "s390", "s390x", "sparc", "sparc64": case "386", "amd64", "amd64p32", "arm", "armbe", "arm64", "arm64be", "ppc64", "ppc64le", "mips", "mipsle", "mips64", "mips64le", "mips64p32", "mips64p32le", "ppc", "riscv", "riscv64", "s390", "s390x", "sparc", "sparc64", "wasm":
return true return true
} }
return false return false

View File

@ -51,19 +51,25 @@ func contextWithRepositoryScope(ctx context.Context, refspec reference.Spec, pus
if err != nil { if err != nil {
return nil, err return nil, err
} }
return context.WithValue(ctx, tokenScopesKey{}, []string{s}), nil return WithScope(ctx, s), nil
}
// WithScope appends a custom registry auth scope to the context.
func WithScope(ctx context.Context, scope string) context.Context {
var scopes []string
if v := ctx.Value(tokenScopesKey{}); v != nil {
scopes = v.([]string)
scopes = append(scopes, scope)
} else {
scopes = []string{scope}
}
return context.WithValue(ctx, tokenScopesKey{}, scopes)
} }
// contextWithAppendPullRepositoryScope is used to append repository pull // contextWithAppendPullRepositoryScope is used to append repository pull
// scope into existing scopes indexed by the tokenScopesKey{}. // scope into existing scopes indexed by the tokenScopesKey{}.
func contextWithAppendPullRepositoryScope(ctx context.Context, repo string) context.Context { func contextWithAppendPullRepositoryScope(ctx context.Context, repo string) context.Context {
var scopes []string return WithScope(ctx, fmt.Sprintf("repository:%s:pull", repo))
if v := ctx.Value(tokenScopesKey{}); v != nil {
scopes = append(scopes, v.([]string)...)
}
scopes = append(scopes, fmt.Sprintf("repository:%s:pull", repo))
return context.WithValue(ctx, tokenScopesKey{}, scopes)
} }
// getTokenScopes returns deduplicated and sorted scopes from ctx.Value(tokenScopesKey{}) and common scopes. // getTokenScopes returns deduplicated and sorted scopes from ctx.Value(tokenScopesKey{}) and common scopes.

View File

@ -33,28 +33,46 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
type refKeyPrefix struct{}
// WithMediaTypeKeyPrefix adds a custom key prefix for a media type which is used when storing
// data in the content store from the FetchHandler.
//
// Used in `MakeRefKey` to determine what the key prefix should be.
func WithMediaTypeKeyPrefix(ctx context.Context, mediaType, prefix string) context.Context {
var values map[string]string
if v := ctx.Value(refKeyPrefix{}); v != nil {
values = v.(map[string]string)
} else {
values = make(map[string]string)
}
values[mediaType] = prefix
return context.WithValue(ctx, refKeyPrefix{}, values)
}
// MakeRefKey returns a unique reference for the descriptor. This reference can be // MakeRefKey returns a unique reference for the descriptor. This reference can be
// used to lookup ongoing processes related to the descriptor. This function // used to lookup ongoing processes related to the descriptor. This function
// may look to the context to namespace the reference appropriately. // may look to the context to namespace the reference appropriately.
func MakeRefKey(ctx context.Context, desc ocispec.Descriptor) string { func MakeRefKey(ctx context.Context, desc ocispec.Descriptor) string {
// TODO(stevvooe): Need better remote key selection here. Should be a if v := ctx.Value(refKeyPrefix{}); v != nil {
// product of the context, which may include information about the ongoing values := v.(map[string]string)
// fetch process. if prefix := values[desc.MediaType]; prefix != "" {
switch desc.MediaType { return prefix + "-" + desc.Digest.String()
case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest: }
}
switch mt := desc.MediaType; {
case mt == images.MediaTypeDockerSchema2Manifest || mt == ocispec.MediaTypeImageManifest:
return "manifest-" + desc.Digest.String() return "manifest-" + desc.Digest.String()
case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: case mt == images.MediaTypeDockerSchema2ManifestList || mt == ocispec.MediaTypeImageIndex:
return "index-" + desc.Digest.String() return "index-" + desc.Digest.String()
case images.MediaTypeDockerSchema2Layer, images.MediaTypeDockerSchema2LayerGzip, case images.IsLayerType(mt):
images.MediaTypeDockerSchema2LayerForeign, images.MediaTypeDockerSchema2LayerForeignGzip,
ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerGzip,
ocispec.MediaTypeImageLayerNonDistributable, ocispec.MediaTypeImageLayerNonDistributableGzip,
images.MediaTypeDockerSchema2LayerEnc, images.MediaTypeDockerSchema2LayerGzipEnc:
return "layer-" + desc.Digest.String() return "layer-" + desc.Digest.String()
case images.MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig: case images.IsKnownConfig(mt):
return "config-" + desc.Digest.String() return "config-" + desc.Digest.String()
default: default:
log.G(ctx).Warnf("reference for unknown type: %s", desc.MediaType) log.G(ctx).Warnf("reference for unknown type: %s", mt)
return "unknown-" + desc.Digest.String() return "unknown-" + desc.Digest.String()
} }
} }

View File

@ -74,7 +74,7 @@ func (b *binary) Start(ctx context.Context, opts *types.Any, onClose func()) (_
if err != nil { if err != nil {
return nil, err return nil, err
} }
f, err := openShimLog(ctx, b.bundle) f, err := openShimLog(ctx, b.bundle, client.AnonDialer)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "open shim log pipe") return nil, errors.Wrap(err, "open shim log pipe")
} }

View File

@ -67,7 +67,7 @@ func loadShim(ctx context.Context, bundle *Bundle, events *exchange.Exchange, rt
if err != nil { if err != nil {
return nil, err return nil, err
} }
conn, err := client.Connect(address, client.AnonDialer) conn, err := client.Connect(address, client.AnonReconnectDialer)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -76,7 +76,7 @@ func loadShim(ctx context.Context, bundle *Bundle, events *exchange.Exchange, rt
conn.Close() conn.Close()
} }
}() }()
f, err := openShimLog(ctx, bundle) f, err := openShimLog(ctx, bundle, client.AnonReconnectDialer)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "open shim log pipe") return nil, errors.Wrap(err, "open shim log pipe")
} }

View File

@ -78,6 +78,10 @@ func AnonDialer(address string, timeout time.Duration) (net.Conn, error) {
return net.DialTimeout("unix", "\x00"+address, timeout) return net.DialTimeout("unix", "\x00"+address, timeout)
} }
func AnonReconnectDialer(address string, timeout time.Duration) (net.Conn, error) {
return AnonDialer(address, timeout)
}
// NewSocket returns a new socket // NewSocket returns a new socket
func NewSocket(address string) (*net.UnixListener, error) { func NewSocket(address string) (*net.UnixListener, error) {
if len(address) > 106 { if len(address) > 106 {

View File

@ -33,6 +33,22 @@ func getSysProcAttr() *syscall.SysProcAttr {
return nil return nil
} }
// AnonReconnectDialer returns a dialer for an existing npipe on containerd reconnection
func AnonReconnectDialer(address string, timeout time.Duration) (net.Conn, error) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
c, err := winio.DialPipeContext(ctx, address)
if os.IsNotExist(err) {
return nil, errors.Wrap(os.ErrNotExist, "npipe not found on reconnect")
} else if err == context.DeadlineExceeded {
return nil, errors.Wrapf(err, "timed out waiting for npipe %s", address)
} else if err != nil {
return nil, err
}
return c, nil
}
// AnonDialer returns a dialer for a npipe // AnonDialer returns a dialer for a npipe
func AnonDialer(address string, timeout time.Duration) (net.Conn, error) { func AnonDialer(address string, timeout time.Duration) (net.Conn, error) {
ctx, cancel := context.WithTimeout(context.Background(), timeout) ctx, cancel := context.WithTimeout(context.Background(), timeout)

View File

@ -21,13 +21,15 @@ package v2
import ( import (
"context" "context"
"io" "io"
"net"
"path/filepath" "path/filepath"
"time"
"github.com/containerd/fifo" "github.com/containerd/fifo"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
func openShimLog(ctx context.Context, bundle *Bundle) (io.ReadCloser, error) { func openShimLog(ctx context.Context, bundle *Bundle, _ func(string, time.Duration) (net.Conn, error)) (io.ReadCloser, error) {
return fifo.OpenFifo(ctx, filepath.Join(bundle.Path, "log"), unix.O_RDONLY|unix.O_CREAT|unix.O_NONBLOCK, 0700) return fifo.OpenFifo(ctx, filepath.Join(bundle.Path, "log"), unix.O_RDONLY|unix.O_CREAT|unix.O_NONBLOCK, 0700)
} }

View File

@ -26,7 +26,6 @@ import (
"time" "time"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
client "github.com/containerd/containerd/runtime/v2/shim"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -64,7 +63,7 @@ func (dpc *deferredPipeConnection) Close() error {
// openShimLog on Windows acts as the client of the log pipe. In this way the // openShimLog on Windows acts as the client of the log pipe. In this way the
// containerd daemon can reconnect to the shim log stream if it is restarted. // containerd daemon can reconnect to the shim log stream if it is restarted.
func openShimLog(ctx context.Context, bundle *Bundle) (io.ReadCloser, error) { func openShimLog(ctx context.Context, bundle *Bundle, dialer func(string, time.Duration) (net.Conn, error)) (io.ReadCloser, error) {
ns, err := namespaces.NamespaceRequired(ctx) ns, err := namespaces.NamespaceRequired(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
@ -74,7 +73,7 @@ func openShimLog(ctx context.Context, bundle *Bundle) (io.ReadCloser, error) {
} }
dpc.wg.Add(1) dpc.wg.Add(1)
go func() { go func() {
c, conerr := client.AnonDialer( c, conerr := dialer(
fmt.Sprintf("\\\\.\\pipe\\containerd-shim-%s-%s-log", ns, bundle.ID), fmt.Sprintf("\\\\.\\pipe\\containerd-shim-%s-%s-log", ns, bundle.ID),
time.Second*10, time.Second*10,
) )

View File

@ -204,12 +204,12 @@ func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(im
// one manifest to handle, and manifest list can be // one manifest to handle, and manifest list can be
// safely skipped. // safely skipped.
// TODO: support multi-platform unpack. // TODO: support multi-platform unpack.
switch desc.MediaType { switch mt := desc.MediaType; {
case images.MediaTypeDockerSchema1Manifest: case mt == images.MediaTypeDockerSchema1Manifest:
lock.Lock() lock.Lock()
schema1 = true schema1 = true
lock.Unlock() lock.Unlock()
case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest: case mt == images.MediaTypeDockerSchema2Manifest || mt == ocispec.MediaTypeImageManifest:
lock.Lock() lock.Lock()
for _, child := range children { for _, child := range children {
if child.MediaType == images.MediaTypeDockerSchema2Config || if child.MediaType == images.MediaTypeDockerSchema2Config ||
@ -219,7 +219,7 @@ func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(im
layers = append(layers, child) layers = append(layers, child)
} }
lock.Unlock() lock.Unlock()
case images.MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig: case mt == images.MediaTypeDockerSchema2Config || mt == ocispec.MediaTypeImageConfig:
lock.Lock() lock.Lock()
l := append([]ocispec.Descriptor{}, layers...) l := append([]ocispec.Descriptor{}, layers...)
lock.Unlock() lock.Unlock()
@ -229,11 +229,7 @@ func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(im
return u.unpack(uctx, desc, l) return u.unpack(uctx, desc, l)
}) })
} }
case images.MediaTypeDockerSchema2Layer, images.MediaTypeDockerSchema2LayerGzip, case images.IsLayerType(mt):
images.MediaTypeDockerSchema2LayerForeign, images.MediaTypeDockerSchema2LayerForeignGzip,
ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerGzip,
ocispec.MediaTypeImageLayerNonDistributable, ocispec.MediaTypeImageLayerNonDistributableGzip,
images.MediaTypeDockerSchema2LayerEnc, images.MediaTypeDockerSchema2LayerGzipEnc:
lock.Lock() lock.Lock()
update := !schema1 update := !schema1
lock.Unlock() lock.Unlock()

View File

@ -1,4 +1,4 @@
github.com/containerd/go-runc 9007c2405372fe28918845901a3276c0915689a1 github.com/containerd/go-runc e029b79d8cda8374981c64eba71f28ec38e5526f
github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
github.com/containerd/cgroups c4b9ac5c7601384c965b9646fc515884e091ebb9 github.com/containerd/cgroups c4b9ac5c7601384c965b9646fc515884e091ebb9
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40 github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
@ -23,7 +23,7 @@ github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4
github.com/opencontainers/runc f4982d86f7fde0b6f953cc62ccc4022c519a10a9 # v1.0.0-rc8-32-gf4982d86 github.com/opencontainers/runc f4982d86f7fde0b6f953cc62ccc4022c519a10a9 # v1.0.0-rc8-32-gf4982d86
github.com/konsorten/go-windows-terminal-sequences v1.0.1 github.com/konsorten/go-windows-terminal-sequences v1.0.1
github.com/sirupsen/logrus v1.4.1 github.com/sirupsen/logrus v1.4.1
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c github.com/urfave/cli v1.22.0
golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3 golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3
google.golang.org/grpc 6eaf6f47437a6b4e2153a190160ef39a92c7eceb # v1.23.0 google.golang.org/grpc 6eaf6f47437a6b4e2153a190160ef39a92c7eceb # v1.23.0
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
@ -47,9 +47,11 @@ github.com/hashicorp/go-multierror v1.0.0
github.com/hashicorp/golang-lru v0.5.3 github.com/hashicorp/golang-lru v0.5.3
go.opencensus.io v0.22.0 go.opencensus.io v0.22.0
github.com/imdario/mergo v0.3.7 github.com/imdario/mergo v0.3.7
github.com/cpuguy83/go-md2man v1.0.10
github.com/russross/blackfriday v1.5.2
# cri dependencies # cri dependencies
github.com/containerd/cri 0165d516161e25e52b4ab52a404a00823f8f0ef6 # master github.com/containerd/cri f4d75d321c89b8d89bae570a7d2da1b3846c096f # release/1.3
github.com/containerd/go-cni 49fbd9b210f3c8ee3b7fd3cd797aabaf364627c1 github.com/containerd/go-cni 49fbd9b210f3c8ee3b7fd3cd797aabaf364627c1
github.com/containernetworking/cni v0.7.1 github.com/containernetworking/cni v0.7.1
github.com/containernetworking/plugins v0.7.6 github.com/containernetworking/plugins v0.7.6