add local support for introspection service
Signed-off-by: Kathryn Baldauf <kabaldau@microsoft.com>
This commit is contained in:
4
vendor/github.com/containerd/cgroups/README.md
generated
vendored
4
vendor/github.com/containerd/cgroups/README.md
generated
vendored
@@ -112,6 +112,10 @@ err := control.MoveTo(destination)
|
||||
subCgroup, err := control.New("child", resources)
|
||||
```
|
||||
|
||||
### Attention
|
||||
|
||||
All static path should not include `/sys/fs/cgroup/` prefix, it should start with your own cgroups name
|
||||
|
||||
## Project details
|
||||
|
||||
Cgroups is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE).
|
||||
|
||||
1
vendor/github.com/containerd/cgroups/cgroup.go
generated
vendored
1
vendor/github.com/containerd/cgroups/cgroup.go
generated
vendored
@@ -67,6 +67,7 @@ func New(hierarchy Hierarchy, path Path, resources *specs.LinuxResources, opts .
|
||||
}
|
||||
|
||||
// Load will load an existing cgroup and allow it to be controlled
|
||||
// All static path should not include `/sys/fs/cgroup/` prefix, it should start with your own cgroups name
|
||||
func Load(hierarchy Hierarchy, path Path, opts ...InitOpts) (Cgroup, error) {
|
||||
config := newInitConfig()
|
||||
for _, o := range opts {
|
||||
|
||||
5
vendor/github.com/containerd/cgroups/go.mod
generated
vendored
5
vendor/github.com/containerd/cgroups/go.mod
generated
vendored
@@ -3,11 +3,14 @@ module github.com/containerd/cgroups
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/cilium/ebpf v0.0.0-20191113100448-d9fb101ca1fb
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e
|
||||
github.com/docker/go-units v0.4.0
|
||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e
|
||||
github.com/gogo/protobuf v1.2.1
|
||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700
|
||||
github.com/pkg/errors v0.8.1
|
||||
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/urfave/cli v1.22.1
|
||||
golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea
|
||||
)
|
||||
|
||||
584
vendor/github.com/containerd/cgroups/stats/v1/metrics.pb.go
generated
vendored
584
vendor/github.com/containerd/cgroups/stats/v1/metrics.pb.go
generated
vendored
@@ -32,6 +32,7 @@ type Metrics struct {
|
||||
Blkio *BlkIOStat `protobuf:"bytes,5,opt,name=blkio,proto3" json:"blkio,omitempty"`
|
||||
Rdma *RdmaStat `protobuf:"bytes,6,opt,name=rdma,proto3" json:"rdma,omitempty"`
|
||||
Network []*NetworkStat `protobuf:"bytes,7,rep,name=network,proto3" json:"network,omitempty"`
|
||||
CgroupStats *CgroupStats `protobuf:"bytes,8,opt,name=cgroup_stats,json=cgroupStats,proto3" json:"cgroup_stats,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
@@ -608,6 +609,55 @@ func (m *NetworkStat) XXX_DiscardUnknown() {
|
||||
|
||||
var xxx_messageInfo_NetworkStat proto.InternalMessageInfo
|
||||
|
||||
// CgroupStats exports per-cgroup statistics.
|
||||
type CgroupStats struct {
|
||||
// number of tasks sleeping
|
||||
NrSleeping uint64 `protobuf:"varint,1,opt,name=nr_sleeping,json=nrSleeping,proto3" json:"nr_sleeping,omitempty"`
|
||||
// number of tasks running
|
||||
NrRunning uint64 `protobuf:"varint,2,opt,name=nr_running,json=nrRunning,proto3" json:"nr_running,omitempty"`
|
||||
// number of tasks in stopped state
|
||||
NrStopped uint64 `protobuf:"varint,3,opt,name=nr_stopped,json=nrStopped,proto3" json:"nr_stopped,omitempty"`
|
||||
// number of tasks in uninterruptible state
|
||||
NrUninterruptible uint64 `protobuf:"varint,4,opt,name=nr_uninterruptible,json=nrUninterruptible,proto3" json:"nr_uninterruptible,omitempty"`
|
||||
// number of tasks waiting on IO
|
||||
NrIoWait uint64 `protobuf:"varint,5,opt,name=nr_io_wait,json=nrIoWait,proto3" json:"nr_io_wait,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CgroupStats) Reset() { *m = CgroupStats{} }
|
||||
func (*CgroupStats) ProtoMessage() {}
|
||||
func (*CgroupStats) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_a17b2d87c332bfaa, []int{13}
|
||||
}
|
||||
func (m *CgroupStats) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *CgroupStats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_CgroupStats.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalTo(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *CgroupStats) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CgroupStats.Merge(m, src)
|
||||
}
|
||||
func (m *CgroupStats) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *CgroupStats) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CgroupStats.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_CgroupStats proto.InternalMessageInfo
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Metrics)(nil), "io.containerd.cgroups.v1.Metrics")
|
||||
proto.RegisterType((*HugetlbStat)(nil), "io.containerd.cgroups.v1.HugetlbStat")
|
||||
@@ -622,6 +672,7 @@ func init() {
|
||||
proto.RegisterType((*RdmaStat)(nil), "io.containerd.cgroups.v1.RdmaStat")
|
||||
proto.RegisterType((*RdmaEntry)(nil), "io.containerd.cgroups.v1.RdmaEntry")
|
||||
proto.RegisterType((*NetworkStat)(nil), "io.containerd.cgroups.v1.NetworkStat")
|
||||
proto.RegisterType((*CgroupStats)(nil), "io.containerd.cgroups.v1.CgroupStats")
|
||||
}
|
||||
|
||||
func init() {
|
||||
@@ -629,105 +680,112 @@ func init() {
|
||||
}
|
||||
|
||||
var fileDescriptor_a17b2d87c332bfaa = []byte{
|
||||
// 1558 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x57, 0xcf, 0x73, 0x13, 0x39,
|
||||
0x16, 0xc6, 0xb1, 0x13, 0xbb, 0x9f, 0x93, 0x90, 0x28, 0x10, 0x3a, 0x01, 0xe2, 0xe0, 0x24, 0xbb,
|
||||
0xd9, 0xa5, 0xca, 0x29, 0xd8, 0x2d, 0x6a, 0x61, 0xa1, 0xb6, 0x70, 0x80, 0x82, 0xda, 0xcd, 0x62,
|
||||
0xda, 0x49, 0xb1, 0x7b, 0xea, 0x92, 0xdb, 0xa2, 0xad, 0xc4, 0x6e, 0x35, 0x6a, 0xb5, 0xe3, 0xcc,
|
||||
0x69, 0x0e, 0x53, 0x35, 0xa7, 0xf9, 0x67, 0xe6, 0xaf, 0xe0, 0x38, 0x97, 0xa9, 0x9a, 0xb9, 0xa4,
|
||||
0x06, 0xff, 0x25, 0x53, 0x92, 0xfa, 0x87, 0x0c, 0x84, 0x8c, 0x6f, 0x2d, 0xe9, 0xfb, 0xbe, 0xf7,
|
||||
0xf4, 0xfa, 0x53, 0xeb, 0x35, 0xfc, 0xdd, 0xa7, 0xa2, 0x17, 0x77, 0x1a, 0x1e, 0x1b, 0xec, 0x79,
|
||||
0x2c, 0x10, 0x98, 0x06, 0x84, 0x77, 0xf7, 0x3c, 0x9f, 0xb3, 0x38, 0x8c, 0xf6, 0x22, 0x81, 0x45,
|
||||
0xb4, 0x37, 0xbc, 0xb7, 0x37, 0x20, 0x82, 0x53, 0x2f, 0x6a, 0x84, 0x9c, 0x09, 0x86, 0x6c, 0xca,
|
||||
0x1a, 0x39, 0xba, 0x91, 0xa0, 0x1b, 0xc3, 0x7b, 0xeb, 0xd7, 0x7c, 0xe6, 0x33, 0x05, 0xda, 0x93,
|
||||
0x4f, 0x1a, 0x5f, 0xff, 0xb1, 0x08, 0xe5, 0x03, 0xad, 0x80, 0xfe, 0x05, 0xe5, 0x5e, 0xec, 0x13,
|
||||
0xd1, 0xef, 0xd8, 0x85, 0xcd, 0xe2, 0x6e, 0xf5, 0xfe, 0x4e, 0xe3, 0x22, 0xb5, 0xc6, 0x4b, 0x0d,
|
||||
0x6c, 0x0b, 0x2c, 0x9c, 0x94, 0x85, 0x1e, 0x40, 0x29, 0xa4, 0xdd, 0xc8, 0x9e, 0xd9, 0x2c, 0xec,
|
||||
0x56, 0xef, 0xd7, 0x2f, 0x66, 0xb7, 0x68, 0x37, 0x52, 0x54, 0x85, 0x47, 0x8f, 0xa1, 0xe8, 0x85,
|
||||
0xb1, 0x5d, 0x54, 0xb4, 0x3b, 0x17, 0xd3, 0xf6, 0x5b, 0x47, 0x92, 0xd5, 0x2c, 0x8f, 0xcf, 0x6b,
|
||||
0xc5, 0xfd, 0xd6, 0x91, 0x23, 0x69, 0xe8, 0x31, 0xcc, 0x0d, 0xc8, 0x80, 0xf1, 0x33, 0xbb, 0xa4,
|
||||
0x04, 0xb6, 0x2f, 0x16, 0x38, 0x50, 0x38, 0x15, 0x39, 0xe1, 0xa0, 0x87, 0x30, 0xdb, 0xe9, 0x9f,
|
||||
0x50, 0x66, 0xcf, 0x2a, 0xf2, 0xd6, 0xc5, 0xe4, 0x66, 0xff, 0xe4, 0xd5, 0x6b, 0xc5, 0xd5, 0x0c,
|
||||
0xb9, 0x5d, 0xde, 0x1d, 0x60, 0x7b, 0xee, 0xb2, 0xed, 0x3a, 0xdd, 0x01, 0xd6, 0xdb, 0x95, 0x78,
|
||||
0x59, 0xe7, 0x80, 0x88, 0x53, 0xc6, 0x4f, 0xec, 0xf2, 0x65, 0x75, 0xfe, 0xaf, 0x06, 0xea, 0x3a,
|
||||
0x27, 0xac, 0xfa, 0x09, 0x54, 0x8d, 0xfa, 0xa3, 0x6b, 0x30, 0x1b, 0x47, 0xd8, 0x27, 0x76, 0x61,
|
||||
0xb3, 0xb0, 0x5b, 0x72, 0xf4, 0x00, 0x2d, 0x41, 0x71, 0x80, 0x47, 0xea, 0x5d, 0x94, 0x1c, 0xf9,
|
||||
0x88, 0x6c, 0x28, 0xbf, 0xc3, 0xb4, 0xef, 0x05, 0x42, 0x95, 0xba, 0xe4, 0xa4, 0x43, 0xb4, 0x0e,
|
||||
0x95, 0x10, 0xfb, 0x24, 0xa2, 0xdf, 0x10, 0x55, 0x44, 0xcb, 0xc9, 0xc6, 0xf5, 0x47, 0x50, 0x49,
|
||||
0x5f, 0x97, 0x54, 0xf0, 0x62, 0xce, 0x49, 0x20, 0x92, 0x58, 0xe9, 0x50, 0xe6, 0xd0, 0xa7, 0x03,
|
||||
0x2a, 0x92, 0x78, 0x7a, 0x50, 0xff, 0xbe, 0x00, 0xe5, 0xe4, 0xa5, 0xa1, 0x7f, 0x98, 0x59, 0x7e,
|
||||
0xb5, 0x5c, 0xfb, 0xad, 0xa3, 0x23, 0x89, 0x4c, 0x77, 0xd2, 0x04, 0x10, 0x3d, 0xce, 0x84, 0xe8,
|
||||
0xd3, 0xc0, 0xbf, 0xdc, 0x5c, 0x87, 0x1a, 0x4b, 0x1c, 0x83, 0x55, 0x7f, 0x0f, 0x95, 0x54, 0x56,
|
||||
0xe6, 0x2a, 0x98, 0xc0, 0xfd, 0xb4, 0x5e, 0x6a, 0x80, 0x56, 0x61, 0xee, 0x84, 0xf0, 0x80, 0xf4,
|
||||
0x93, 0x2d, 0x24, 0x23, 0x84, 0xa0, 0x14, 0x47, 0x84, 0x27, 0x25, 0x53, 0xcf, 0x68, 0x0b, 0xca,
|
||||
0x21, 0xe1, 0xae, 0x34, 0x6d, 0x69, 0xb3, 0xb8, 0x5b, 0x6a, 0xc2, 0xf8, 0xbc, 0x36, 0xd7, 0x22,
|
||||
0x5c, 0x9a, 0x72, 0x2e, 0x24, 0x7c, 0x3f, 0x8c, 0xeb, 0x23, 0xa8, 0xa4, 0xa9, 0xc8, 0xc2, 0x85,
|
||||
0x84, 0x53, 0xd6, 0x8d, 0xd2, 0xc2, 0x25, 0x43, 0x74, 0x17, 0x96, 0x93, 0x34, 0x49, 0xd7, 0x4d,
|
||||
0x31, 0x3a, 0x83, 0xa5, 0x6c, 0xa1, 0x95, 0x80, 0x77, 0x60, 0x31, 0x07, 0x0b, 0x3a, 0x20, 0x49,
|
||||
0x56, 0x0b, 0xd9, 0xec, 0x21, 0x1d, 0x90, 0xfa, 0xaf, 0x55, 0x80, 0xdc, 0xea, 0x72, 0xbf, 0x1e,
|
||||
0xf6, 0x7a, 0x99, 0x3f, 0xd4, 0x00, 0xad, 0x41, 0x91, 0x47, 0x49, 0x28, 0x7d, 0xa2, 0x9c, 0x76,
|
||||
0xdb, 0x91, 0x73, 0xe8, 0x4f, 0x50, 0xe1, 0x51, 0xe4, 0xca, 0x63, 0xad, 0x03, 0x34, 0xab, 0xe3,
|
||||
0xf3, 0x5a, 0xd9, 0x69, 0xb7, 0xa5, 0xed, 0x9c, 0x32, 0x8f, 0x22, 0xf9, 0x80, 0x6a, 0x50, 0x1d,
|
||||
0xe0, 0x30, 0x24, 0x5d, 0xf7, 0x1d, 0xed, 0x6b, 0xe7, 0x94, 0x1c, 0xd0, 0x53, 0x2f, 0x68, 0x5f,
|
||||
0x55, 0xba, 0x4b, 0xb9, 0x38, 0x53, 0x87, 0xab, 0xe4, 0xe8, 0x01, 0xba, 0x05, 0xd6, 0x29, 0xa7,
|
||||
0x82, 0x74, 0xb0, 0x77, 0xa2, 0x0e, 0x4f, 0xc9, 0xc9, 0x27, 0x90, 0x0d, 0x95, 0xd0, 0x77, 0x43,
|
||||
0xdf, 0xa5, 0x81, 0x5d, 0xd6, 0x6f, 0x22, 0xf4, 0x5b, 0xfe, 0xab, 0x00, 0xad, 0x83, 0xa5, 0x57,
|
||||
0x58, 0x2c, 0xec, 0x4a, 0x52, 0x46, 0xbf, 0xe5, 0xbf, 0x8e, 0x05, 0x5a, 0x53, 0xac, 0x77, 0x38,
|
||||
0xee, 0x0b, 0xdb, 0x4a, 0x97, 0x5e, 0xc8, 0x21, 0xda, 0x84, 0xf9, 0xd0, 0x77, 0x07, 0xf8, 0x38,
|
||||
0x59, 0x06, 0x9d, 0x66, 0xe8, 0x1f, 0xe0, 0x63, 0x8d, 0xd8, 0x82, 0x05, 0x1a, 0x60, 0x4f, 0xd0,
|
||||
0x21, 0x71, 0x71, 0xc0, 0x02, 0xbb, 0xaa, 0x20, 0xf3, 0xe9, 0xe4, 0xd3, 0x80, 0x05, 0x72, 0xb3,
|
||||
0x26, 0x64, 0x5e, 0xab, 0x18, 0x00, 0x53, 0x45, 0xd5, 0x63, 0x61, 0x52, 0x45, 0x55, 0x24, 0x57,
|
||||
0x51, 0x90, 0x45, 0x53, 0x45, 0x01, 0x36, 0xa1, 0x1a, 0x07, 0x64, 0x48, 0x3d, 0x81, 0x3b, 0x7d,
|
||||
0x62, 0x5f, 0x55, 0x00, 0x73, 0x0a, 0x3d, 0x82, 0xb5, 0x1e, 0x25, 0x1c, 0x73, 0xaf, 0x47, 0x3d,
|
||||
0xdc, 0x77, 0xf5, 0x87, 0xcc, 0xd5, 0xc7, 0x6f, 0x49, 0xe1, 0x6f, 0x98, 0x00, 0xed, 0x84, 0xff,
|
||||
0xc8, 0x65, 0xf4, 0x00, 0x26, 0x96, 0xdc, 0xe8, 0x14, 0x87, 0x09, 0x73, 0x59, 0x31, 0xaf, 0x9b,
|
||||
0xcb, 0xed, 0x53, 0x1c, 0x6a, 0x5e, 0x0d, 0xaa, 0xea, 0x94, 0xb8, 0xda, 0x48, 0x48, 0xa7, 0xad,
|
||||
0xa6, 0xf6, 0x95, 0x9b, 0xfe, 0x02, 0x96, 0x06, 0x48, 0x4f, 0xad, 0x28, 0xcf, 0xcc, 0x8f, 0xcf,
|
||||
0x6b, 0x95, 0x43, 0x39, 0x29, 0x8d, 0x55, 0x51, 0xcb, 0x4e, 0x14, 0xa1, 0x07, 0xb0, 0x98, 0x41,
|
||||
0xb5, 0xc7, 0xae, 0x29, 0xfc, 0xd2, 0xf8, 0xbc, 0x36, 0x9f, 0xe2, 0x95, 0xd1, 0xe6, 0x53, 0x8e,
|
||||
0x72, 0xdb, 0x5f, 0x61, 0x59, 0xf3, 0x4c, 0xcf, 0x5d, 0x57, 0x99, 0x5c, 0x55, 0x0b, 0x07, 0xb9,
|
||||
0xf1, 0xb2, 0x7c, 0xb5, 0xfd, 0x56, 0x8d, 0x7c, 0x9f, 0x29, 0x0f, 0xfe, 0x19, 0x34, 0xc7, 0xcd,
|
||||
0x9d, 0x78, 0x43, 0x81, 0x74, 0x6e, 0x6f, 0x33, 0x3b, 0x6e, 0xa5, 0xd9, 0x66, 0xa6, 0xb4, 0xf5,
|
||||
0x2b, 0x51, 0xb3, 0x2d, 0xed, 0xcc, 0x9d, 0x54, 0x2d, 0xf7, 0xe7, 0x9a, 0x7e, 0xf9, 0x19, 0x4a,
|
||||
0x9a, 0x74, 0xdb, 0xd0, 0xd2, 0x5e, 0x5c, 0x9f, 0x40, 0x69, 0x37, 0xde, 0x05, 0x94, 0xa1, 0x72,
|
||||
0xd7, 0xde, 0x34, 0x36, 0xda, 0xca, 0xad, 0xdb, 0x80, 0x15, 0x0d, 0x9e, 0x34, 0xf0, 0x2d, 0x85,
|
||||
0xd6, 0xf5, 0x7a, 0x65, 0xba, 0x38, 0x2b, 0xa2, 0x89, 0xbe, 0x6d, 0x68, 0x3f, 0xcd, 0xb1, 0x9f,
|
||||
0x6b, 0xab, 0x92, 0x6f, 0x7c, 0x41, 0x5b, 0x15, 0xfd, 0x53, 0x6d, 0x85, 0xae, 0x7d, 0xa6, 0xad,
|
||||
0xb0, 0x77, 0x53, 0xac, 0x69, 0xf6, 0xcd, 0xe4, 0xb3, 0x27, 0x17, 0x8e, 0x0c, 0xc7, 0xff, 0x33,
|
||||
0xbd, 0x3a, 0xee, 0xa8, 0x6f, 0xff, 0xce, 0x65, 0x17, 0xfc, 0xf3, 0x40, 0xf0, 0xb3, 0xf4, 0xf6,
|
||||
0x78, 0x08, 0x25, 0xe9, 0x72, 0xbb, 0x3e, 0x0d, 0x57, 0x51, 0xd0, 0x93, 0xec, 0x4a, 0xd8, 0x9a,
|
||||
0x86, 0x9c, 0xde, 0x1c, 0x6d, 0x00, 0xfd, 0xe4, 0x0a, 0x2f, 0xb4, 0xb7, 0xa7, 0x90, 0x68, 0x2e,
|
||||
0x8c, 0xcf, 0x6b, 0xd6, 0xbf, 0x15, 0xf9, 0x70, 0xbf, 0xe5, 0x58, 0x5a, 0xe7, 0xd0, 0x0b, 0xeb,
|
||||
0x04, 0xaa, 0x06, 0x30, 0xbf, 0x77, 0x0b, 0xc6, 0xbd, 0x9b, 0x77, 0x04, 0x33, 0x5f, 0xe8, 0x08,
|
||||
0x8a, 0x5f, 0xec, 0x08, 0x4a, 0x13, 0x1d, 0x41, 0xfd, 0xe7, 0x59, 0xb0, 0xb2, 0x86, 0x07, 0x61,
|
||||
0x58, 0xa7, 0xcc, 0x8d, 0x08, 0x1f, 0x52, 0x8f, 0xb8, 0x9d, 0x33, 0x41, 0x22, 0x97, 0x13, 0x2f,
|
||||
0xe6, 0x11, 0x1d, 0x92, 0xa4, 0x59, 0xdc, 0xbe, 0xa4, 0x73, 0xd2, 0xb5, 0xb9, 0x41, 0x59, 0x5b,
|
||||
0xcb, 0x34, 0xa5, 0x8a, 0x93, 0x8a, 0xa0, 0xff, 0xc1, 0xf5, 0x3c, 0x44, 0xd7, 0x50, 0x9f, 0x99,
|
||||
0x42, 0x7d, 0x25, 0x53, 0xef, 0xe6, 0xca, 0x87, 0xb0, 0x42, 0x99, 0xfb, 0x3e, 0x26, 0xf1, 0x84,
|
||||
0x6e, 0x71, 0x0a, 0xdd, 0x65, 0xca, 0xde, 0x28, 0x7e, 0xae, 0xea, 0xc2, 0x9a, 0x51, 0x12, 0x79,
|
||||
0x17, 0x1b, 0xda, 0xa5, 0x29, 0xb4, 0x57, 0xb3, 0x9c, 0xe5, 0xdd, 0x9d, 0x07, 0xf8, 0x3f, 0xac,
|
||||
0x52, 0xe6, 0x9e, 0x62, 0x2a, 0x3e, 0x55, 0x9f, 0x9d, 0xae, 0x22, 0x6f, 0x31, 0x15, 0x93, 0xd2,
|
||||
0xba, 0x22, 0x03, 0xc2, 0xfd, 0x89, 0x8a, 0xcc, 0x4d, 0x57, 0x91, 0x03, 0xc5, 0xcf, 0x55, 0x5b,
|
||||
0xb0, 0x4c, 0xd9, 0xa7, 0xb9, 0x96, 0xa7, 0xd0, 0xbc, 0x4a, 0xd9, 0x64, 0x9e, 0x6f, 0x60, 0x39,
|
||||
0x22, 0x9e, 0x60, 0xdc, 0x74, 0x5b, 0x65, 0x0a, 0xc5, 0xa5, 0x84, 0x9e, 0x49, 0xd6, 0x87, 0x00,
|
||||
0xf9, 0x3a, 0x5a, 0x84, 0x19, 0x16, 0xaa, 0xa3, 0x63, 0x39, 0x33, 0x2c, 0x94, 0x3d, 0x60, 0x57,
|
||||
0x7e, 0x76, 0xf4, 0xc1, 0xb1, 0x9c, 0x64, 0x24, 0xcf, 0xd3, 0x00, 0x1f, 0xb3, 0xb4, 0x09, 0xd4,
|
||||
0x03, 0x35, 0x4b, 0x03, 0xc6, 0x93, 0xb3, 0xa3, 0x07, 0x72, 0x76, 0x88, 0xfb, 0x31, 0x49, 0x7b,
|
||||
0x1e, 0x35, 0xa8, 0x7f, 0x57, 0x80, 0x4a, 0xfa, 0x1b, 0x80, 0x9e, 0x98, 0x6d, 0x74, 0xf1, 0xeb,
|
||||
0x7f, 0x1d, 0x92, 0xa4, 0x37, 0x93, 0xf5, 0xda, 0x0f, 0xf3, 0x5e, 0xfb, 0x0f, 0x93, 0x93, 0x86,
|
||||
0x9c, 0x80, 0x95, 0xcd, 0x19, 0xbb, 0x2d, 0x4c, 0xec, 0xb6, 0x06, 0xd5, 0x9e, 0x87, 0xdd, 0x1e,
|
||||
0x0e, 0xba, 0x7d, 0xa2, 0x3b, 0xc4, 0x05, 0x07, 0x7a, 0x1e, 0x7e, 0xa9, 0x67, 0x52, 0x00, 0xeb,
|
||||
0x1c, 0x13, 0x4f, 0x44, 0xaa, 0x28, 0x1a, 0xf0, 0x5a, 0xcf, 0xd4, 0x7f, 0x98, 0x81, 0xaa, 0xf1,
|
||||
0xe7, 0x22, 0x7b, 0xe8, 0x00, 0x0f, 0xd2, 0x38, 0xea, 0x59, 0x76, 0x6c, 0x7c, 0xa4, 0xbf, 0x25,
|
||||
0xc9, 0x67, 0xaa, 0xcc, 0x47, 0xea, 0xa3, 0x80, 0x6e, 0x03, 0xf0, 0x91, 0x1b, 0x62, 0xef, 0x84,
|
||||
0x24, 0xf2, 0x25, 0xc7, 0xe2, 0xa3, 0x96, 0x9e, 0x40, 0x37, 0xc1, 0xe2, 0x23, 0x97, 0x70, 0xce,
|
||||
0x78, 0x94, 0xd4, 0xbe, 0xc2, 0x47, 0xcf, 0xd5, 0x38, 0xe1, 0x76, 0x39, 0x93, 0xbd, 0x40, 0xf2,
|
||||
0x0e, 0x2c, 0x3e, 0x7a, 0xa6, 0x27, 0x64, 0x54, 0x91, 0x46, 0xd5, 0xad, 0x67, 0x59, 0xe4, 0x51,
|
||||
0x45, 0x1e, 0x55, 0xb7, 0x9e, 0x96, 0x30, 0xa3, 0x8a, 0x2c, 0xaa, 0xee, 0x3e, 0x2b, 0xc2, 0x88,
|
||||
0x2a, 0xf2, 0xa8, 0x56, 0xca, 0x4d, 0xa2, 0x36, 0xed, 0x0f, 0x1f, 0x37, 0xae, 0xfc, 0xf2, 0x71,
|
||||
0xe3, 0xca, 0xb7, 0xe3, 0x8d, 0xc2, 0x87, 0xf1, 0x46, 0xe1, 0xa7, 0xf1, 0x46, 0xe1, 0xb7, 0xf1,
|
||||
0x46, 0xa1, 0x33, 0xa7, 0x7e, 0xc3, 0xff, 0xf6, 0x7b, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2f, 0xc0,
|
||||
0x49, 0x92, 0xee, 0x0f, 0x00, 0x00,
|
||||
// 1669 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x58, 0x4f, 0x73, 0x1b, 0xb7,
|
||||
0x15, 0x0f, 0xc5, 0x95, 0xc8, 0x7d, 0x94, 0x6c, 0x09, 0xfe, 0xb7, 0x52, 0x1c, 0x51, 0xa1, 0xec,
|
||||
0xd6, 0xad, 0xa7, 0xd2, 0x24, 0xed, 0x78, 0xea, 0x34, 0x99, 0x4e, 0xa4, 0x24, 0x63, 0x4f, 0xab,
|
||||
0x9a, 0x59, 0x4a, 0x93, 0xf6, 0xb4, 0x03, 0x2e, 0xe1, 0x25, 0xac, 0xe5, 0x62, 0x83, 0xc5, 0x52,
|
||||
0x74, 0x4f, 0x3d, 0x74, 0xa6, 0xa7, 0x7e, 0xa0, 0x7e, 0x83, 0x1c, 0x7b, 0xe9, 0x4c, 0x7b, 0xd1,
|
||||
0x34, 0xfc, 0x1c, 0x3d, 0x74, 0x80, 0x87, 0xfd, 0x43, 0xc7, 0xb2, 0xc2, 0xdb, 0xe2, 0xe1, 0xf7,
|
||||
0x7e, 0xef, 0xe1, 0xe1, 0x07, 0xe0, 0x91, 0xf0, 0xab, 0x88, 0xab, 0x71, 0x3e, 0x3c, 0x08, 0xc5,
|
||||
0xe4, 0x30, 0x14, 0x89, 0xa2, 0x3c, 0x61, 0x72, 0x74, 0x18, 0x46, 0x52, 0xe4, 0x69, 0x76, 0x98,
|
||||
0x29, 0xaa, 0xb2, 0xc3, 0xe9, 0x47, 0x87, 0x13, 0xa6, 0x24, 0x0f, 0xb3, 0x83, 0x54, 0x0a, 0x25,
|
||||
0x88, 0xc7, 0xc5, 0x41, 0x85, 0x3e, 0xb0, 0xe8, 0x83, 0xe9, 0x47, 0x3b, 0xb7, 0x23, 0x11, 0x09,
|
||||
0x03, 0x3a, 0xd4, 0x5f, 0x88, 0xef, 0xfd, 0xaf, 0x09, 0xad, 0x13, 0x64, 0x20, 0xbf, 0x85, 0xd6,
|
||||
0x38, 0x8f, 0x98, 0x8a, 0x87, 0x5e, 0x63, 0xaf, 0xf9, 0xa8, 0xf3, 0xf1, 0xc3, 0x83, 0xab, 0xd8,
|
||||
0x0e, 0x9e, 0x21, 0x70, 0xa0, 0xa8, 0xf2, 0x0b, 0x2f, 0xf2, 0x04, 0x9c, 0x94, 0x8f, 0x32, 0x6f,
|
||||
0x65, 0xaf, 0xf1, 0xa8, 0xf3, 0x71, 0xef, 0x6a, 0xef, 0x3e, 0x1f, 0x65, 0xc6, 0xd5, 0xe0, 0xc9,
|
||||
0xa7, 0xd0, 0x0c, 0xd3, 0xdc, 0x6b, 0x1a, 0xb7, 0x0f, 0xaf, 0x76, 0x3b, 0xee, 0x9f, 0x69, 0xaf,
|
||||
0xa3, 0xd6, 0xfc, 0xb2, 0xdb, 0x3c, 0xee, 0x9f, 0xf9, 0xda, 0x8d, 0x7c, 0x0a, 0x6b, 0x13, 0x36,
|
||||
0x11, 0xf2, 0xb5, 0xe7, 0x18, 0x82, 0x07, 0x57, 0x13, 0x9c, 0x18, 0x9c, 0x89, 0x6c, 0x7d, 0xc8,
|
||||
0x53, 0x58, 0x1d, 0xc6, 0xe7, 0x5c, 0x78, 0xab, 0xc6, 0x79, 0xff, 0x6a, 0xe7, 0xa3, 0xf8, 0xfc,
|
||||
0xf9, 0x0b, 0xe3, 0x8b, 0x1e, 0x7a, 0xb9, 0x72, 0x34, 0xa1, 0xde, 0xda, 0x75, 0xcb, 0xf5, 0x47,
|
||||
0x13, 0x8a, 0xcb, 0xd5, 0x78, 0x5d, 0xe7, 0x84, 0xa9, 0x0b, 0x21, 0xcf, 0xbd, 0xd6, 0x75, 0x75,
|
||||
0xfe, 0x03, 0x02, 0xb1, 0xce, 0xd6, 0x8b, 0x3c, 0x83, 0x75, 0x84, 0x04, 0x46, 0x05, 0x5e, 0xdb,
|
||||
0x24, 0xf0, 0x0e, 0x96, 0x63, 0xf3, 0xa9, 0x49, 0x32, 0xbf, 0x13, 0x56, 0x83, 0xde, 0x39, 0x74,
|
||||
0x6a, 0x3b, 0x49, 0x6e, 0xc3, 0x6a, 0x9e, 0xd1, 0x88, 0x79, 0x8d, 0xbd, 0xc6, 0x23, 0xc7, 0xc7,
|
||||
0x01, 0xd9, 0x84, 0xe6, 0x84, 0xce, 0xcc, 0xae, 0x3a, 0xbe, 0xfe, 0x24, 0x1e, 0xb4, 0x5e, 0x52,
|
||||
0x1e, 0x87, 0x89, 0x32, 0x9b, 0xe6, 0xf8, 0xc5, 0x90, 0xec, 0x40, 0x3b, 0xa5, 0x11, 0xcb, 0xf8,
|
||||
0x9f, 0x99, 0xd9, 0x0e, 0xd7, 0x2f, 0xc7, 0xbd, 0x4f, 0xa0, 0x5d, 0x6c, 0xbc, 0x66, 0x08, 0x73,
|
||||
0x29, 0x59, 0xa2, 0x6c, 0xac, 0x62, 0xa8, 0x73, 0x88, 0xf9, 0x84, 0x2b, 0x1b, 0x0f, 0x07, 0xbd,
|
||||
0xbf, 0x35, 0xa0, 0x65, 0xb7, 0x9f, 0xfc, 0xba, 0x9e, 0xe5, 0x3b, 0x0b, 0x7f, 0xdc, 0x3f, 0x3b,
|
||||
0xd3, 0xc8, 0x62, 0x25, 0x47, 0x00, 0x6a, 0x2c, 0x85, 0x52, 0x31, 0x4f, 0xa2, 0xeb, 0x65, 0x7a,
|
||||
0x8a, 0x58, 0xe6, 0xd7, 0xbc, 0x7a, 0xdf, 0x42, 0xbb, 0xa0, 0xd5, 0xb9, 0x2a, 0xa1, 0x68, 0x5c,
|
||||
0xd4, 0xcb, 0x0c, 0xc8, 0x5d, 0x58, 0x3b, 0x67, 0x32, 0x61, 0xb1, 0x5d, 0x82, 0x1d, 0x11, 0x02,
|
||||
0x4e, 0x9e, 0x31, 0x69, 0x4b, 0x66, 0xbe, 0xc9, 0x3e, 0xb4, 0x52, 0x26, 0x03, 0x2d, 0x7f, 0x67,
|
||||
0xaf, 0xf9, 0xc8, 0x39, 0x82, 0xf9, 0x65, 0x77, 0xad, 0xcf, 0xa4, 0x96, 0xf7, 0x5a, 0xca, 0xe4,
|
||||
0x71, 0x9a, 0xf7, 0x66, 0xd0, 0x2e, 0x52, 0xd1, 0x85, 0x4b, 0x99, 0xe4, 0x62, 0x94, 0x15, 0x85,
|
||||
0xb3, 0x43, 0xf2, 0x18, 0xb6, 0x6c, 0x9a, 0x6c, 0x14, 0x14, 0x18, 0xcc, 0x60, 0xb3, 0x9c, 0xe8,
|
||||
0x5b, 0xf0, 0x43, 0xb8, 0x51, 0x81, 0x15, 0x9f, 0x30, 0x9b, 0xd5, 0x46, 0x69, 0x3d, 0xe5, 0x13,
|
||||
0xd6, 0xfb, 0x4f, 0x07, 0xa0, 0x3a, 0x34, 0x7a, 0xbd, 0x21, 0x0d, 0xc7, 0xa5, 0x3e, 0xcc, 0x80,
|
||||
0x6c, 0x43, 0x53, 0x66, 0x36, 0x14, 0x9e, 0x4d, 0x7f, 0x30, 0xf0, 0xb5, 0x8d, 0xfc, 0x04, 0xda,
|
||||
0x32, 0xcb, 0x02, 0x7d, 0x41, 0x60, 0x80, 0xa3, 0xce, 0xfc, 0xb2, 0xdb, 0xf2, 0x07, 0x03, 0x2d,
|
||||
0x3b, 0xbf, 0x25, 0xb3, 0x4c, 0x7f, 0x90, 0x2e, 0x74, 0x26, 0x34, 0x4d, 0xd9, 0x28, 0x78, 0xc9,
|
||||
0x63, 0x54, 0x8e, 0xe3, 0x03, 0x9a, 0xbe, 0xe2, 0xb1, 0xa9, 0xf4, 0x88, 0x4b, 0xf5, 0xda, 0x1c,
|
||||
0x53, 0xc7, 0xc7, 0x01, 0xb9, 0x0f, 0xee, 0x85, 0xe4, 0x8a, 0x0d, 0x69, 0x78, 0x6e, 0x8e, 0xa1,
|
||||
0xe3, 0x57, 0x06, 0xe2, 0x41, 0x3b, 0x8d, 0x82, 0x34, 0x0a, 0x78, 0xe2, 0xb5, 0x70, 0x27, 0xd2,
|
||||
0xa8, 0x1f, 0x3d, 0x4f, 0xc8, 0x0e, 0xb8, 0x38, 0x23, 0x72, 0x65, 0x4e, 0x8f, 0x2e, 0x63, 0xd4,
|
||||
0x8f, 0x5e, 0xe4, 0x8a, 0x6c, 0x1b, 0xaf, 0x97, 0x34, 0x8f, 0x95, 0xe7, 0x16, 0x53, 0x5f, 0xe9,
|
||||
0x21, 0xd9, 0x83, 0xf5, 0x34, 0x0a, 0x26, 0xf4, 0x95, 0x9d, 0x06, 0x4c, 0x33, 0x8d, 0x4e, 0xe8,
|
||||
0x2b, 0x44, 0xec, 0xc3, 0x06, 0x4f, 0x68, 0xa8, 0xf8, 0x94, 0x05, 0x34, 0x11, 0x89, 0xd7, 0x31,
|
||||
0x90, 0xf5, 0xc2, 0xf8, 0x79, 0x22, 0x12, 0xbd, 0xd8, 0x3a, 0x64, 0x1d, 0x59, 0x6a, 0x80, 0x3a,
|
||||
0x8b, 0xa9, 0xc7, 0xc6, 0x22, 0x8b, 0xa9, 0x48, 0xc5, 0x62, 0x20, 0x37, 0xea, 0x2c, 0x06, 0xb0,
|
||||
0x07, 0x9d, 0x3c, 0x61, 0x53, 0x1e, 0x2a, 0x3a, 0x8c, 0x99, 0x77, 0xd3, 0x00, 0xea, 0x26, 0xf2,
|
||||
0x09, 0x6c, 0x8f, 0x39, 0x93, 0x54, 0x86, 0x63, 0x1e, 0xd2, 0x38, 0xc0, 0x2b, 0x31, 0xc0, 0xe3,
|
||||
0xb7, 0x69, 0xf0, 0xf7, 0xea, 0x00, 0x54, 0xc2, 0xef, 0xf5, 0x34, 0x79, 0x02, 0x0b, 0x53, 0x41,
|
||||
0x76, 0x41, 0x53, 0xeb, 0xb9, 0x65, 0x3c, 0xef, 0xd4, 0xa7, 0x07, 0x17, 0x34, 0x45, 0xbf, 0x2e,
|
||||
0x74, 0xcc, 0x29, 0x09, 0x50, 0x48, 0x04, 0xd3, 0x36, 0xa6, 0x63, 0xa3, 0xa6, 0x9f, 0x81, 0x8b,
|
||||
0x00, 0xad, 0xa9, 0x5b, 0x46, 0x33, 0xeb, 0xf3, 0xcb, 0x6e, 0xfb, 0x54, 0x1b, 0xb5, 0xb0, 0xda,
|
||||
0x66, 0xda, 0xcf, 0x32, 0xf2, 0x04, 0x6e, 0x94, 0x50, 0xd4, 0xd8, 0x6d, 0x83, 0xdf, 0x9c, 0x5f,
|
||||
0x76, 0xd7, 0x0b, 0xbc, 0x11, 0xda, 0x7a, 0xe1, 0x63, 0xd4, 0xf6, 0x73, 0xd8, 0x42, 0xbf, 0xba,
|
||||
0xe6, 0xee, 0x98, 0x4c, 0x6e, 0x9a, 0x89, 0x93, 0x4a, 0x78, 0x65, 0xbe, 0x28, 0xbf, 0xbb, 0xb5,
|
||||
0x7c, 0xbf, 0x30, 0x1a, 0xfc, 0x29, 0xa0, 0x4f, 0x50, 0x29, 0xf1, 0x9e, 0x01, 0x61, 0x6e, 0xdf,
|
||||
0x94, 0x72, 0xdc, 0x2f, 0xb2, 0x2d, 0x45, 0xe9, 0xe1, 0x96, 0x18, 0x6b, 0x1f, 0x95, 0xf9, 0xb0,
|
||||
0x60, 0xab, 0xf4, 0xb9, 0x8d, 0x9b, 0x5f, 0xa2, 0xb4, 0x48, 0x1f, 0xd4, 0xb8, 0x50, 0x8b, 0x3b,
|
||||
0x0b, 0x28, 0x54, 0xe3, 0x63, 0x20, 0x25, 0xaa, 0x52, 0xed, 0xfb, 0xb5, 0x85, 0xf6, 0x2b, 0xe9,
|
||||
0x1e, 0xc0, 0x2d, 0x04, 0x2f, 0x0a, 0xf8, 0xbe, 0x41, 0x63, 0xbd, 0x9e, 0xd7, 0x55, 0x5c, 0x16,
|
||||
0xb1, 0x8e, 0xfe, 0xa0, 0xc6, 0xfd, 0x79, 0x85, 0xfd, 0x21, 0xb7, 0x29, 0xf9, 0xee, 0x5b, 0xb8,
|
||||
0x4d, 0xd1, 0xdf, 0xe4, 0x36, 0xe8, 0xee, 0x0f, 0xb8, 0x0d, 0xf6, 0x71, 0x81, 0xad, 0x8b, 0x7d,
|
||||
0xcf, 0x5e, 0x7b, 0x7a, 0xe2, 0xac, 0xa6, 0xf8, 0xdf, 0x14, 0x4f, 0xc7, 0x87, 0xd7, 0x3d, 0x99,
|
||||
0xa8, 0xf5, 0x2f, 0x13, 0x25, 0x5f, 0x17, 0xaf, 0xc7, 0x53, 0x70, 0xb4, 0xca, 0xbd, 0xde, 0x32,
|
||||
0xbe, 0xc6, 0x85, 0x7c, 0x56, 0x3e, 0x09, 0xfb, 0xcb, 0x38, 0x17, 0x2f, 0xc7, 0x00, 0x00, 0xbf,
|
||||
0x02, 0x15, 0xa6, 0xde, 0x83, 0x25, 0x28, 0x8e, 0x36, 0xe6, 0x97, 0x5d, 0xf7, 0x77, 0xc6, 0xf9,
|
||||
0xf4, 0xb8, 0xef, 0xbb, 0xc8, 0x73, 0x1a, 0xa6, 0x3d, 0x06, 0x9d, 0x1a, 0xb0, 0x7a, 0x77, 0x1b,
|
||||
0xb5, 0x77, 0xb7, 0xea, 0x08, 0x56, 0xde, 0xd2, 0x11, 0x34, 0xdf, 0xda, 0x11, 0x38, 0x0b, 0x1d,
|
||||
0x41, 0xef, 0x5f, 0xab, 0xe0, 0x96, 0xad, 0x13, 0xa1, 0xb0, 0xc3, 0x45, 0x90, 0x31, 0x39, 0xe5,
|
||||
0x21, 0x0b, 0x86, 0xaf, 0x15, 0xcb, 0x02, 0xc9, 0xc2, 0x5c, 0x66, 0x7c, 0xca, 0x6c, 0xdb, 0xf9,
|
||||
0xe0, 0x9a, 0x1e, 0x0c, 0x6b, 0x73, 0x8f, 0x8b, 0x01, 0xd2, 0x1c, 0x69, 0x16, 0xbf, 0x20, 0x21,
|
||||
0x7f, 0x84, 0x3b, 0x55, 0x88, 0x51, 0x8d, 0x7d, 0x65, 0x09, 0xf6, 0x5b, 0x25, 0xfb, 0xa8, 0x62,
|
||||
0x3e, 0x85, 0x5b, 0x5c, 0x04, 0xdf, 0xe6, 0x2c, 0x5f, 0xe0, 0x6d, 0x2e, 0xc1, 0xbb, 0xc5, 0xc5,
|
||||
0xd7, 0xc6, 0xbf, 0x62, 0x0d, 0x60, 0xbb, 0x56, 0x12, 0xfd, 0x16, 0xd7, 0xb8, 0x9d, 0x25, 0xb8,
|
||||
0xef, 0x96, 0x39, 0xeb, 0xb7, 0xbb, 0x0a, 0xf0, 0x27, 0xb8, 0xcb, 0x45, 0x70, 0x41, 0xb9, 0x7a,
|
||||
0x93, 0x7d, 0x75, 0xb9, 0x8a, 0x7c, 0x43, 0xb9, 0x5a, 0xa4, 0xc6, 0x8a, 0x4c, 0x98, 0x8c, 0x16,
|
||||
0x2a, 0xb2, 0xb6, 0x5c, 0x45, 0x4e, 0x8c, 0x7f, 0xc5, 0xda, 0x87, 0x2d, 0x2e, 0xde, 0xcc, 0xb5,
|
||||
0xb5, 0x04, 0xe7, 0x4d, 0x2e, 0x16, 0xf3, 0xfc, 0x1a, 0xb6, 0x32, 0x16, 0x2a, 0x21, 0xeb, 0x6a,
|
||||
0x6b, 0x2f, 0xc1, 0xb8, 0x69, 0xdd, 0x4b, 0xca, 0xde, 0x14, 0xa0, 0x9a, 0x27, 0x37, 0x60, 0x45,
|
||||
0xa4, 0xe6, 0xe8, 0xb8, 0xfe, 0x8a, 0x48, 0x75, 0x0f, 0x38, 0xd2, 0xd7, 0x0e, 0x1e, 0x1c, 0xd7,
|
||||
0xb7, 0x23, 0x7d, 0x9e, 0x26, 0xf4, 0x95, 0x28, 0x9a, 0x40, 0x1c, 0x18, 0x2b, 0x4f, 0x84, 0xb4,
|
||||
0x67, 0x07, 0x07, 0xda, 0x3a, 0xa5, 0x71, 0xce, 0x8a, 0x9e, 0xc7, 0x0c, 0x7a, 0x7f, 0x6d, 0x40,
|
||||
0xbb, 0xf8, 0x41, 0x41, 0x3e, 0xab, 0xb7, 0xd1, 0xcd, 0x77, 0xff, 0x7e, 0xd1, 0x4e, 0xb8, 0x98,
|
||||
0xb2, 0xd7, 0x7e, 0x5a, 0xf5, 0xda, 0x3f, 0xda, 0xd9, 0x36, 0xe4, 0x0c, 0xdc, 0xd2, 0x56, 0x5b,
|
||||
0x6d, 0x63, 0x61, 0xb5, 0x5d, 0xe8, 0x8c, 0x43, 0x1a, 0x8c, 0x69, 0x32, 0x8a, 0x19, 0x76, 0x88,
|
||||
0x1b, 0x3e, 0x8c, 0x43, 0xfa, 0x0c, 0x2d, 0x05, 0x40, 0x0c, 0x5f, 0xb1, 0x50, 0x65, 0xa6, 0x28,
|
||||
0x08, 0x78, 0x81, 0x96, 0xde, 0xdf, 0x57, 0xa0, 0x53, 0xfb, 0x0d, 0xa4, 0x7b, 0xe8, 0x84, 0x4e,
|
||||
0x8a, 0x38, 0xe6, 0x5b, 0x77, 0x6c, 0x72, 0x86, 0x77, 0x89, 0xbd, 0xa6, 0x5a, 0x72, 0x66, 0x2e,
|
||||
0x05, 0xf2, 0x01, 0x80, 0x9c, 0x05, 0x29, 0x0d, 0xcf, 0x99, 0xa5, 0x77, 0x7c, 0x57, 0xce, 0xfa,
|
||||
0x68, 0x20, 0xef, 0x83, 0x2b, 0x67, 0x01, 0x93, 0x52, 0xc8, 0xcc, 0xd6, 0xbe, 0x2d, 0x67, 0x5f,
|
||||
0x9a, 0xb1, 0xf5, 0x1d, 0x49, 0xa1, 0x7b, 0x01, 0xbb, 0x07, 0xae, 0x9c, 0x7d, 0x81, 0x06, 0x1d,
|
||||
0x55, 0x15, 0x51, 0xb1, 0xf5, 0x6c, 0xa9, 0x2a, 0xaa, 0xaa, 0xa2, 0x62, 0xeb, 0xe9, 0xaa, 0x7a,
|
||||
0x54, 0x55, 0x46, 0xc5, 0xee, 0xb3, 0xad, 0x6a, 0x51, 0x55, 0x15, 0xd5, 0x2d, 0x7c, 0x6d, 0xd4,
|
||||
0xde, 0x3f, 0x1a, 0xd0, 0xa9, 0xfd, 0x9a, 0xd3, 0x05, 0x4c, 0x64, 0x90, 0xc5, 0x8c, 0xa5, 0xfa,
|
||||
0x27, 0x0d, 0xde, 0xdd, 0x90, 0xc8, 0x81, 0xb5, 0x68, 0xbe, 0x44, 0x06, 0x32, 0x4f, 0x92, 0xe2,
|
||||
0x27, 0x8f, 0xe3, 0xbb, 0x89, 0xf4, 0xd1, 0x60, 0xa7, 0x33, 0x85, 0xe1, 0x9a, 0xc5, 0xf4, 0x00,
|
||||
0x0d, 0xe4, 0x17, 0x40, 0x12, 0x19, 0xe4, 0x09, 0x4f, 0x14, 0x93, 0x32, 0x4f, 0x15, 0x1f, 0x96,
|
||||
0xed, 0xf9, 0x56, 0x22, 0xcf, 0x16, 0x27, 0xc8, 0x7d, 0xc3, 0x66, 0x2f, 0x1b, 0x5b, 0xb2, 0x76,
|
||||
0x22, 0x9f, 0x9b, 0x9b, 0xe3, 0xc8, 0xfb, 0xee, 0xfb, 0xdd, 0xf7, 0xfe, 0xfd, 0xfd, 0xee, 0x7b,
|
||||
0x7f, 0x99, 0xef, 0x36, 0xbe, 0x9b, 0xef, 0x36, 0xfe, 0x39, 0xdf, 0x6d, 0xfc, 0x77, 0xbe, 0xdb,
|
||||
0x18, 0xae, 0x99, 0x3f, 0x23, 0x7e, 0xf9, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb9, 0x78, 0x66,
|
||||
0x06, 0xf4, 0x10, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *Metrics) Marshal() (dAtA []byte, err error) {
|
||||
@@ -819,6 +877,16 @@ func (m *Metrics) MarshalTo(dAtA []byte) (int, error) {
|
||||
i += n
|
||||
}
|
||||
}
|
||||
if m.CgroupStats != nil {
|
||||
dAtA[i] = 0x42
|
||||
i++
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(m.CgroupStats.Size()))
|
||||
n6, err := m.CgroupStats.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n6
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
i += copy(dAtA[i:], m.XXX_unrecognized)
|
||||
}
|
||||
@@ -917,21 +985,21 @@ func (m *CPUStat) MarshalTo(dAtA []byte) (int, error) {
|
||||
dAtA[i] = 0xa
|
||||
i++
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(m.Usage.Size()))
|
||||
n6, err := m.Usage.MarshalTo(dAtA[i:])
|
||||
n7, err := m.Usage.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n6
|
||||
i += n7
|
||||
}
|
||||
if m.Throttling != nil {
|
||||
dAtA[i] = 0x12
|
||||
i++
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(m.Throttling.Size()))
|
||||
n7, err := m.Throttling.MarshalTo(dAtA[i:])
|
||||
n8, err := m.Throttling.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n7
|
||||
i += n8
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
i += copy(dAtA[i:], m.XXX_unrecognized)
|
||||
@@ -970,21 +1038,21 @@ func (m *CPUUsage) MarshalTo(dAtA []byte) (int, error) {
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(m.User))
|
||||
}
|
||||
if len(m.PerCPU) > 0 {
|
||||
dAtA9 := make([]byte, len(m.PerCPU)*10)
|
||||
var j8 int
|
||||
dAtA10 := make([]byte, len(m.PerCPU)*10)
|
||||
var j9 int
|
||||
for _, num := range m.PerCPU {
|
||||
for num >= 1<<7 {
|
||||
dAtA9[j8] = uint8(uint64(num)&0x7f | 0x80)
|
||||
dAtA10[j9] = uint8(uint64(num)&0x7f | 0x80)
|
||||
num >>= 7
|
||||
j8++
|
||||
j9++
|
||||
}
|
||||
dAtA9[j8] = uint8(num)
|
||||
j8++
|
||||
dAtA10[j9] = uint8(num)
|
||||
j9++
|
||||
}
|
||||
dAtA[i] = 0x22
|
||||
i++
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(j8))
|
||||
i += copy(dAtA[i:], dAtA9[:j8])
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(j9))
|
||||
i += copy(dAtA[i:], dAtA10[:j9])
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
i += copy(dAtA[i:], m.XXX_unrecognized)
|
||||
@@ -1243,11 +1311,11 @@ func (m *MemoryStat) MarshalTo(dAtA []byte) (int, error) {
|
||||
dAtA[i] = 0x2
|
||||
i++
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(m.Usage.Size()))
|
||||
n10, err := m.Usage.MarshalTo(dAtA[i:])
|
||||
n11, err := m.Usage.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n10
|
||||
i += n11
|
||||
}
|
||||
if m.Swap != nil {
|
||||
dAtA[i] = 0x92
|
||||
@@ -1255,11 +1323,11 @@ func (m *MemoryStat) MarshalTo(dAtA []byte) (int, error) {
|
||||
dAtA[i] = 0x2
|
||||
i++
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(m.Swap.Size()))
|
||||
n11, err := m.Swap.MarshalTo(dAtA[i:])
|
||||
n12, err := m.Swap.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n11
|
||||
i += n12
|
||||
}
|
||||
if m.Kernel != nil {
|
||||
dAtA[i] = 0x9a
|
||||
@@ -1267,11 +1335,11 @@ func (m *MemoryStat) MarshalTo(dAtA []byte) (int, error) {
|
||||
dAtA[i] = 0x2
|
||||
i++
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(m.Kernel.Size()))
|
||||
n12, err := m.Kernel.MarshalTo(dAtA[i:])
|
||||
n13, err := m.Kernel.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n12
|
||||
i += n13
|
||||
}
|
||||
if m.KernelTCP != nil {
|
||||
dAtA[i] = 0xa2
|
||||
@@ -1279,11 +1347,11 @@ func (m *MemoryStat) MarshalTo(dAtA []byte) (int, error) {
|
||||
dAtA[i] = 0x2
|
||||
i++
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(m.KernelTCP.Size()))
|
||||
n13, err := m.KernelTCP.MarshalTo(dAtA[i:])
|
||||
n14, err := m.KernelTCP.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n13
|
||||
i += n14
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
i += copy(dAtA[i:], m.XXX_unrecognized)
|
||||
@@ -1646,6 +1714,52 @@ func (m *NetworkStat) MarshalTo(dAtA []byte) (int, error) {
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (m *CgroupStats) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *CgroupStats) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.NrSleeping != 0 {
|
||||
dAtA[i] = 0x8
|
||||
i++
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(m.NrSleeping))
|
||||
}
|
||||
if m.NrRunning != 0 {
|
||||
dAtA[i] = 0x10
|
||||
i++
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(m.NrRunning))
|
||||
}
|
||||
if m.NrStopped != 0 {
|
||||
dAtA[i] = 0x18
|
||||
i++
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(m.NrStopped))
|
||||
}
|
||||
if m.NrUninterruptible != 0 {
|
||||
dAtA[i] = 0x20
|
||||
i++
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(m.NrUninterruptible))
|
||||
}
|
||||
if m.NrIoWait != 0 {
|
||||
dAtA[i] = 0x28
|
||||
i++
|
||||
i = encodeVarintMetrics(dAtA, i, uint64(m.NrIoWait))
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
i += copy(dAtA[i:], m.XXX_unrecognized)
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func encodeVarintMetrics(dAtA []byte, offset int, v uint64) int {
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
@@ -1693,6 +1807,10 @@ func (m *Metrics) Size() (n int) {
|
||||
n += 1 + l + sovMetrics(uint64(l))
|
||||
}
|
||||
}
|
||||
if m.CgroupStats != nil {
|
||||
l = m.CgroupStats.Size()
|
||||
n += 1 + l + sovMetrics(uint64(l))
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
}
|
||||
@@ -2134,6 +2252,33 @@ func (m *NetworkStat) Size() (n int) {
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *CgroupStats) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.NrSleeping != 0 {
|
||||
n += 1 + sovMetrics(uint64(m.NrSleeping))
|
||||
}
|
||||
if m.NrRunning != 0 {
|
||||
n += 1 + sovMetrics(uint64(m.NrRunning))
|
||||
}
|
||||
if m.NrStopped != 0 {
|
||||
n += 1 + sovMetrics(uint64(m.NrStopped))
|
||||
}
|
||||
if m.NrUninterruptible != 0 {
|
||||
n += 1 + sovMetrics(uint64(m.NrUninterruptible))
|
||||
}
|
||||
if m.NrIoWait != 0 {
|
||||
n += 1 + sovMetrics(uint64(m.NrIoWait))
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovMetrics(x uint64) (n int) {
|
||||
for {
|
||||
n++
|
||||
@@ -2159,6 +2304,7 @@ func (this *Metrics) String() string {
|
||||
`Blkio:` + strings.Replace(fmt.Sprintf("%v", this.Blkio), "BlkIOStat", "BlkIOStat", 1) + `,`,
|
||||
`Rdma:` + strings.Replace(fmt.Sprintf("%v", this.Rdma), "RdmaStat", "RdmaStat", 1) + `,`,
|
||||
`Network:` + strings.Replace(fmt.Sprintf("%v", this.Network), "NetworkStat", "NetworkStat", 1) + `,`,
|
||||
`CgroupStats:` + strings.Replace(fmt.Sprintf("%v", this.CgroupStats), "CgroupStats", "CgroupStats", 1) + `,`,
|
||||
`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
@@ -2366,6 +2512,21 @@ func (this *NetworkStat) String() string {
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *CgroupStats) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&CgroupStats{`,
|
||||
`NrSleeping:` + fmt.Sprintf("%v", this.NrSleeping) + `,`,
|
||||
`NrRunning:` + fmt.Sprintf("%v", this.NrRunning) + `,`,
|
||||
`NrStopped:` + fmt.Sprintf("%v", this.NrStopped) + `,`,
|
||||
`NrUninterruptible:` + fmt.Sprintf("%v", this.NrUninterruptible) + `,`,
|
||||
`NrIoWait:` + fmt.Sprintf("%v", this.NrIoWait) + `,`,
|
||||
`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func valueToStringMetrics(v interface{}) string {
|
||||
rv := reflect.ValueOf(v)
|
||||
if rv.IsNil() {
|
||||
@@ -2651,6 +2812,42 @@ func (m *Metrics) Unmarshal(dAtA []byte) error {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 8:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CgroupStats", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowMetrics
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthMetrics
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthMetrics
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.CgroupStats == nil {
|
||||
m.CgroupStats = &CgroupStats{}
|
||||
}
|
||||
if err := m.CgroupStats.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipMetrics(dAtA[iNdEx:])
|
||||
@@ -5256,6 +5453,155 @@ func (m *NetworkStat) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *CgroupStats) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowMetrics
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: CgroupStats: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: CgroupStats: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field NrSleeping", wireType)
|
||||
}
|
||||
m.NrSleeping = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowMetrics
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.NrSleeping |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field NrRunning", wireType)
|
||||
}
|
||||
m.NrRunning = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowMetrics
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.NrRunning |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field NrStopped", wireType)
|
||||
}
|
||||
m.NrStopped = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowMetrics
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.NrStopped |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 4:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field NrUninterruptible", wireType)
|
||||
}
|
||||
m.NrUninterruptible = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowMetrics
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.NrUninterruptible |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 5:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field NrIoWait", wireType)
|
||||
}
|
||||
m.NrIoWait = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowMetrics
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.NrIoWait |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipMetrics(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthMetrics
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
return ErrInvalidLengthMetrics
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipMetrics(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
|
||||
15
vendor/github.com/containerd/cgroups/stats/v1/metrics.proto
generated
vendored
15
vendor/github.com/containerd/cgroups/stats/v1/metrics.proto
generated
vendored
@@ -12,6 +12,7 @@ message Metrics {
|
||||
BlkIOStat blkio = 5;
|
||||
RdmaStat rdma = 6;
|
||||
repeated NetworkStat network = 7;
|
||||
CgroupStats cgroup_stats = 8;
|
||||
}
|
||||
|
||||
message HugetlbStat {
|
||||
@@ -134,3 +135,17 @@ message NetworkStat {
|
||||
uint64 tx_errors = 8;
|
||||
uint64 tx_dropped = 9;
|
||||
}
|
||||
|
||||
// CgroupStats exports per-cgroup statistics.
|
||||
message CgroupStats {
|
||||
// number of tasks sleeping
|
||||
uint64 nr_sleeping = 1;
|
||||
// number of tasks running
|
||||
uint64 nr_running = 2;
|
||||
// number of tasks in stopped state
|
||||
uint64 nr_stopped = 3;
|
||||
// number of tasks in uninterruptible state
|
||||
uint64 nr_uninterruptible = 4;
|
||||
// number of tasks waiting on IO
|
||||
uint64 nr_io_wait = 5;
|
||||
}
|
||||
|
||||
48
vendor/github.com/containerd/cgroups/utils.go
generated
vendored
48
vendor/github.com/containerd/cgroups/utils.go
generated
vendored
@@ -25,13 +25,59 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
units "github.com/docker/go-units"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var isUserNS = runningInUserNS()
|
||||
var (
|
||||
isUserNS = runningInUserNS()
|
||||
checkMode sync.Once
|
||||
cgMode CGMode
|
||||
)
|
||||
|
||||
const unifiedMountpoint = "/sys/fs/cgroup"
|
||||
|
||||
// CGMode is the cgroups mode of the host system
|
||||
type CGMode int
|
||||
|
||||
const (
|
||||
// Unavailable cgroup mountpoint
|
||||
Unavailable CGMode = iota
|
||||
// Legacy cgroups v1
|
||||
Legacy
|
||||
// Hybrid with cgroups v1 and v2 controllers mounted
|
||||
Hybrid
|
||||
// Unified with only cgroups v2 mounted
|
||||
Unified
|
||||
)
|
||||
|
||||
// Mode returns the cgroups mode running on the host
|
||||
func Mode() CGMode {
|
||||
checkMode.Do(func() {
|
||||
var st unix.Statfs_t
|
||||
if err := unix.Statfs(unifiedMountpoint, &st); err != nil {
|
||||
cgMode = Unavailable
|
||||
return
|
||||
}
|
||||
switch st.Type {
|
||||
case unix.CGROUP2_SUPER_MAGIC:
|
||||
cgMode = Unified
|
||||
default:
|
||||
cgMode = Legacy
|
||||
if err := unix.Statfs(filepath.Join(unifiedMountpoint, "unified"), &st); err != nil {
|
||||
return
|
||||
}
|
||||
if st.Type == unix.CGROUP2_SUPER_MAGIC {
|
||||
cgMode = Hybrid
|
||||
}
|
||||
}
|
||||
})
|
||||
return cgMode
|
||||
}
|
||||
|
||||
// runningInUserNS detects whether we are currently running in a user namespace.
|
||||
// Copied from github.com/lxc/lxd/shared/util.go
|
||||
|
||||
52
vendor/github.com/containerd/cgroups/v2/cpu.go
generated
vendored
Normal file
52
vendor/github.com/containerd/cgroups/v2/cpu.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
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 v2
|
||||
|
||||
type CPU struct {
|
||||
Weight *uint64
|
||||
Max *uint64
|
||||
Cpus string
|
||||
Mems string
|
||||
}
|
||||
|
||||
func (r *CPU) Values() (o []Value) {
|
||||
if r.Weight != nil {
|
||||
o = append(o, Value{
|
||||
filename: "cpu.weight",
|
||||
value: *r.Weight,
|
||||
})
|
||||
}
|
||||
if r.Max != nil {
|
||||
o = append(o, Value{
|
||||
filename: "cpu.max",
|
||||
value: *r.Max,
|
||||
})
|
||||
}
|
||||
if r.Cpus != "" {
|
||||
o = append(o, Value{
|
||||
filename: "cpuset.cpus",
|
||||
value: r.Cpus,
|
||||
})
|
||||
}
|
||||
if r.Mems != "" {
|
||||
o = append(o, Value{
|
||||
filename: "cpuset.mems",
|
||||
value: r.Mems,
|
||||
})
|
||||
}
|
||||
return o
|
||||
}
|
||||
199
vendor/github.com/containerd/cgroups/v2/devicefilter.go
generated
vendored
Normal file
199
vendor/github.com/containerd/cgroups/v2/devicefilter.go
generated
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// Devicefilter containes eBPF device filter program
|
||||
//
|
||||
// The implementation is based on https://github.com/containers/crun/blob/0.10.2/src/libcrun/ebpf.c
|
||||
//
|
||||
// Although ebpf.c is originally licensed under LGPL-3.0-or-later, the author (Giuseppe Scrivano)
|
||||
// agreed to relicense the file in Apache License 2.0: https://github.com/opencontainers/runc/issues/2144#issuecomment-543116397
|
||||
//
|
||||
// This particular Go implementation based on runc version
|
||||
// https://github.com/opencontainers/runc/blob/master/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go
|
||||
package v2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/cilium/ebpf/asm"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
// license string format is same as kernel MODULE_LICENSE macro
|
||||
license = "Apache"
|
||||
)
|
||||
|
||||
// DeviceFilter returns eBPF device filter program and its license string
|
||||
func DeviceFilter(devices []specs.LinuxDeviceCgroup) (asm.Instructions, string, error) {
|
||||
p := &program{}
|
||||
p.init()
|
||||
for i := len(devices) - 1; i >= 0; i-- {
|
||||
if err := p.appendDevice(devices[i]); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
}
|
||||
insts, err := p.finalize()
|
||||
return insts, license, err
|
||||
}
|
||||
|
||||
type program struct {
|
||||
insts asm.Instructions
|
||||
hasWildCard bool
|
||||
blockID int
|
||||
}
|
||||
|
||||
func (p *program) init() {
|
||||
// struct bpf_cgroup_dev_ctx: https://elixir.bootlin.com/linux/v5.3.6/source/include/uapi/linux/bpf.h#L3423
|
||||
/*
|
||||
u32 access_type
|
||||
u32 major
|
||||
u32 minor
|
||||
*/
|
||||
// R2 <- type (lower 16 bit of u32 access_type at R1[0])
|
||||
p.insts = append(p.insts,
|
||||
asm.LoadMem(asm.R2, asm.R1, 0, asm.Half))
|
||||
|
||||
// R3 <- access (upper 16 bit of u32 access_type at R1[0])
|
||||
p.insts = append(p.insts,
|
||||
asm.LoadMem(asm.R3, asm.R1, 0, asm.Word),
|
||||
// RSh: bitwise shift right
|
||||
asm.RSh.Imm32(asm.R3, 16))
|
||||
|
||||
// R4 <- major (u32 major at R1[4])
|
||||
p.insts = append(p.insts,
|
||||
asm.LoadMem(asm.R4, asm.R1, 4, asm.Word))
|
||||
|
||||
// R5 <- minor (u32 minor at R1[8])
|
||||
p.insts = append(p.insts,
|
||||
asm.LoadMem(asm.R5, asm.R1, 8, asm.Word))
|
||||
}
|
||||
|
||||
// appendDevice needs to be called from the last element of OCI linux.resources.devices to the head element.
|
||||
func (p *program) appendDevice(dev specs.LinuxDeviceCgroup) error {
|
||||
if p.blockID < 0 {
|
||||
return errors.New("the program is finalized")
|
||||
}
|
||||
if p.hasWildCard {
|
||||
// All entries after wildcard entry are ignored
|
||||
return nil
|
||||
}
|
||||
|
||||
bpfType := int32(-1)
|
||||
hasType := true
|
||||
switch dev.Type {
|
||||
case string('c'):
|
||||
bpfType = int32(unix.BPF_DEVCG_DEV_CHAR)
|
||||
case string('b'):
|
||||
bpfType = int32(unix.BPF_DEVCG_DEV_BLOCK)
|
||||
case string('a'):
|
||||
hasType = false
|
||||
default:
|
||||
// if not specified in OCI json, typ is set to DeviceTypeAll
|
||||
return errors.Errorf("invalid DeviceType %q", dev.Type)
|
||||
}
|
||||
if *dev.Major > math.MaxUint32 {
|
||||
return errors.Errorf("invalid major %d", *dev.Major)
|
||||
}
|
||||
if *dev.Minor > math.MaxUint32 {
|
||||
return errors.Errorf("invalid minor %d", *dev.Major)
|
||||
}
|
||||
hasMajor := *dev.Major >= 0 // if not specified in OCI json, major is set to -1
|
||||
hasMinor := *dev.Minor >= 0
|
||||
bpfAccess := int32(0)
|
||||
for _, r := range dev.Access {
|
||||
switch r {
|
||||
case 'r':
|
||||
bpfAccess |= unix.BPF_DEVCG_ACC_READ
|
||||
case 'w':
|
||||
bpfAccess |= unix.BPF_DEVCG_ACC_WRITE
|
||||
case 'm':
|
||||
bpfAccess |= unix.BPF_DEVCG_ACC_MKNOD
|
||||
default:
|
||||
return errors.Errorf("unknown device access %v", r)
|
||||
}
|
||||
}
|
||||
// If the access is rwm, skip the check.
|
||||
hasAccess := bpfAccess != (unix.BPF_DEVCG_ACC_READ | unix.BPF_DEVCG_ACC_WRITE | unix.BPF_DEVCG_ACC_MKNOD)
|
||||
|
||||
blockSym := fmt.Sprintf("block-%d", p.blockID)
|
||||
nextBlockSym := fmt.Sprintf("block-%d", p.blockID+1)
|
||||
prevBlockLastIdx := len(p.insts) - 1
|
||||
if hasType {
|
||||
p.insts = append(p.insts,
|
||||
// if (R2 != bpfType) goto next
|
||||
asm.JNE.Imm(asm.R2, bpfType, nextBlockSym),
|
||||
)
|
||||
}
|
||||
if hasAccess {
|
||||
p.insts = append(p.insts,
|
||||
// if (R3 & bpfAccess == 0 /* use R1 as a temp var */) goto next
|
||||
asm.Mov.Reg32(asm.R1, asm.R3),
|
||||
asm.And.Imm32(asm.R1, bpfAccess),
|
||||
asm.JEq.Imm(asm.R1, 0, nextBlockSym),
|
||||
)
|
||||
}
|
||||
if hasMajor {
|
||||
p.insts = append(p.insts,
|
||||
// if (R4 != major) goto next
|
||||
asm.JNE.Imm(asm.R4, int32(*dev.Major), nextBlockSym),
|
||||
)
|
||||
}
|
||||
if hasMinor {
|
||||
p.insts = append(p.insts,
|
||||
// if (R5 != minor) goto next
|
||||
asm.JNE.Imm(asm.R5, int32(*dev.Minor), nextBlockSym),
|
||||
)
|
||||
}
|
||||
if !hasType && !hasAccess && !hasMajor && !hasMinor {
|
||||
p.hasWildCard = true
|
||||
}
|
||||
p.insts = append(p.insts, acceptBlock(dev.Allow)...)
|
||||
// set blockSym to the first instruction we added in this iteration
|
||||
p.insts[prevBlockLastIdx+1] = p.insts[prevBlockLastIdx+1].Sym(blockSym)
|
||||
p.blockID++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *program) finalize() (asm.Instructions, error) {
|
||||
if p.hasWildCard {
|
||||
// acceptBlock with asm.Return() is already inserted
|
||||
return p.insts, nil
|
||||
}
|
||||
blockSym := fmt.Sprintf("block-%d", p.blockID)
|
||||
p.insts = append(p.insts,
|
||||
// R0 <- 0
|
||||
asm.Mov.Imm32(asm.R0, 0).Sym(blockSym),
|
||||
asm.Return(),
|
||||
)
|
||||
p.blockID = -1
|
||||
return p.insts, nil
|
||||
}
|
||||
|
||||
func acceptBlock(accept bool) asm.Instructions {
|
||||
v := int32(0)
|
||||
if accept {
|
||||
v = 1
|
||||
}
|
||||
return []asm.Instruction{
|
||||
// R0 <- v
|
||||
asm.Mov.Imm32(asm.R0, v),
|
||||
asm.Return(),
|
||||
}
|
||||
}
|
||||
83
vendor/github.com/containerd/cgroups/v2/ebpf.go
generated
vendored
Normal file
83
vendor/github.com/containerd/cgroups/v2/ebpf.go
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
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 v2
|
||||
|
||||
import (
|
||||
"github.com/cilium/ebpf"
|
||||
"github.com/cilium/ebpf/asm"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// LoadAttachCgroupDeviceFilter installs eBPF device filter program to /sys/fs/cgroup/<foo> directory.
|
||||
//
|
||||
// Requires the system to be running in cgroup2 unified-mode with kernel >= 4.15 .
|
||||
//
|
||||
// https://github.com/torvalds/linux/commit/ebc614f687369f9df99828572b1d85a7c2de3d92
|
||||
func LoadAttachCgroupDeviceFilter(insts asm.Instructions, license string, dirFD int) (func() error, error) {
|
||||
nilCloser := func() error {
|
||||
return nil
|
||||
}
|
||||
spec := &ebpf.ProgramSpec{
|
||||
Type: ebpf.CGroupDevice,
|
||||
Instructions: insts,
|
||||
License: license,
|
||||
}
|
||||
prog, err := ebpf.NewProgram(spec)
|
||||
if err != nil {
|
||||
return nilCloser, err
|
||||
}
|
||||
if err := prog.Attach(dirFD, ebpf.AttachCGroupDevice, unix.BPF_F_ALLOW_MULTI); err != nil {
|
||||
return nilCloser, errors.Wrap(err, "failed to call BPF_PROG_ATTACH (BPF_CGROUP_DEVICE, BPF_F_ALLOW_MULTI)")
|
||||
}
|
||||
closer := func() error {
|
||||
if err := prog.Detach(dirFD, ebpf.AttachCGroupDevice, unix.BPF_F_ALLOW_MULTI); err != nil {
|
||||
return errors.Wrap(err, "failed to call BPF_PROG_DETACH (BPF_CGROUP_DEVICE, BPF_F_ALLOW_MULTI)")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return closer, nil
|
||||
}
|
||||
|
||||
func isRWM(cgroupPermissions string) bool {
|
||||
r := false
|
||||
w := false
|
||||
m := false
|
||||
for _, rn := range cgroupPermissions {
|
||||
switch rn {
|
||||
case 'r':
|
||||
r = true
|
||||
case 'w':
|
||||
w = true
|
||||
case 'm':
|
||||
m = true
|
||||
}
|
||||
}
|
||||
return r && w && m
|
||||
}
|
||||
|
||||
// the logic is from runc
|
||||
// https://github.com/opencontainers/runc/blob/master/libcontainer/cgroups/fs/devices_v2.go#L44
|
||||
func canSkipEBPFError(devices []specs.LinuxDeviceCgroup) bool {
|
||||
for _, dev := range devices {
|
||||
if dev.Allow || !isRWM(dev.Access) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
50
vendor/github.com/containerd/cgroups/v2/errors.go
generated
vendored
Normal file
50
vendor/github.com/containerd/cgroups/v2/errors.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
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 v2
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidPid = errors.New("cgroups: pid must be greater than 0")
|
||||
ErrMountPointNotExist = errors.New("cgroups: cgroup mountpoint does not exist")
|
||||
ErrInvalidFormat = errors.New("cgroups: parsing file with invalid format failed")
|
||||
ErrFreezerNotSupported = errors.New("cgroups: freezer cgroup (v2) not supported on this system")
|
||||
ErrMemoryNotSupported = errors.New("cgroups: memory cgroup (v2) not supported on this system")
|
||||
ErrPidsNotSupported = errors.New("cgroups: pids cgroup (v2) not supported on this system")
|
||||
ErrCPUNotSupported = errors.New("cgroups: cpu cgroup (v2) not supported on this system")
|
||||
ErrCgroupDeleted = errors.New("cgroups: cgroup deleted")
|
||||
ErrNoCgroupMountDestination = errors.New("cgroups: cannot find cgroup mount destination")
|
||||
ErrInvalidGroupPath = errors.New("cgroups: invalid group path")
|
||||
)
|
||||
|
||||
// ErrorHandler is a function that handles and acts on errors
|
||||
type ErrorHandler func(err error) error
|
||||
|
||||
// IgnoreNotExist ignores any errors that are for not existing files
|
||||
func IgnoreNotExist(err error) error {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func errPassthrough(err error) error {
|
||||
return err
|
||||
}
|
||||
64
vendor/github.com/containerd/cgroups/v2/io.go
generated
vendored
Normal file
64
vendor/github.com/containerd/cgroups/v2/io.go
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
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 v2
|
||||
|
||||
import "fmt"
|
||||
|
||||
type IOType string
|
||||
|
||||
const (
|
||||
ReadBPS IOType = "rbps"
|
||||
WriteBPS IOType = "wbps"
|
||||
ReadIOPS IOType = "riops"
|
||||
WriteIOPS IOType = "wiops"
|
||||
)
|
||||
|
||||
type BFQ struct {
|
||||
Weight uint16
|
||||
}
|
||||
|
||||
type Entry struct {
|
||||
Type IOType
|
||||
Major int64
|
||||
Minor int64
|
||||
Rate uint64
|
||||
}
|
||||
|
||||
func (e Entry) String() string {
|
||||
return fmt.Sprintf("%d:%d %s=%d", e.Major, e.Minor, e.Type, e.Rate)
|
||||
}
|
||||
|
||||
type IO struct {
|
||||
BFQ BFQ
|
||||
Max []Entry
|
||||
}
|
||||
|
||||
func (i *IO) Values() (o []Value) {
|
||||
if i.BFQ.Weight != 0 {
|
||||
o = append(o, Value{
|
||||
filename: "io.bfq.weight",
|
||||
value: i.BFQ.Weight,
|
||||
})
|
||||
}
|
||||
for _, e := range i.Max {
|
||||
o = append(o, Value{
|
||||
filename: "io.max",
|
||||
value: e.String(),
|
||||
})
|
||||
}
|
||||
return o
|
||||
}
|
||||
552
vendor/github.com/containerd/cgroups/v2/manager.go
generated
vendored
Normal file
552
vendor/github.com/containerd/cgroups/v2/manager.go
generated
vendored
Normal file
@@ -0,0 +1,552 @@
|
||||
/*
|
||||
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 v2
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/containerd/cgroups/v2/stats"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
subtreeControl = "cgroup.subtree_control"
|
||||
controllersFile = "cgroup.controllers"
|
||||
)
|
||||
|
||||
type cgValuer interface {
|
||||
Values() []Value
|
||||
}
|
||||
|
||||
type Event struct {
|
||||
Low uint64
|
||||
High uint64
|
||||
Max uint64
|
||||
OOM uint64
|
||||
OOMKill uint64
|
||||
}
|
||||
|
||||
// Resources for a cgroups v2 unified hierarchy
|
||||
type Resources struct {
|
||||
CPU *CPU
|
||||
Memory *Memory
|
||||
Pids *Pids
|
||||
IO *IO
|
||||
RDMA *RDMA
|
||||
// When len(Devices) is zero, devices are not controlled
|
||||
Devices []specs.LinuxDeviceCgroup
|
||||
}
|
||||
|
||||
// Values returns the raw filenames and values that
|
||||
// can be written to the unified hierarchy
|
||||
func (r *Resources) Values() (o []Value) {
|
||||
values := []cgValuer{
|
||||
r.CPU,
|
||||
r.Memory,
|
||||
r.Pids,
|
||||
r.IO,
|
||||
r.RDMA,
|
||||
}
|
||||
for _, v := range values {
|
||||
if v == nil {
|
||||
continue
|
||||
}
|
||||
o = append(o, v.Values()...)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// Value of a cgroup setting
|
||||
type Value struct {
|
||||
filename string
|
||||
value interface{}
|
||||
}
|
||||
|
||||
// write the value to the full, absolute path, of a unified hierarchy
|
||||
func (c *Value) write(path string, perm os.FileMode) error {
|
||||
var data []byte
|
||||
switch t := c.value.(type) {
|
||||
case uint64:
|
||||
data = []byte(strconv.FormatUint(t, 10))
|
||||
case uint16:
|
||||
data = []byte(strconv.FormatUint(uint64(t), 10))
|
||||
case int64:
|
||||
data = []byte(strconv.FormatInt(t, 10))
|
||||
case []byte:
|
||||
data = t
|
||||
case string:
|
||||
data = []byte(t)
|
||||
default:
|
||||
return ErrInvalidFormat
|
||||
}
|
||||
return ioutil.WriteFile(
|
||||
filepath.Join(path, c.filename),
|
||||
data,
|
||||
perm,
|
||||
)
|
||||
}
|
||||
|
||||
func writeValues(path string, values []Value) error {
|
||||
for _, o := range values {
|
||||
if err := o.write(path, defaultFilePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewManager(mountpoint string, group string, resources *Resources) (*Manager, error) {
|
||||
if err := VerifyGroupPath(group); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
path := filepath.Join(mountpoint, group)
|
||||
if err := os.MkdirAll(path, defaultDirPerm); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := setResources(path, resources); err != nil {
|
||||
// clean up cgroup dir on failure
|
||||
os.Remove(path)
|
||||
return nil, err
|
||||
}
|
||||
return &Manager{
|
||||
unifiedMountpoint: mountpoint,
|
||||
path: path,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func LoadManager(mountpoint string, group string) (*Manager, error) {
|
||||
if err := VerifyGroupPath(group); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
path := filepath.Join(mountpoint, group)
|
||||
return &Manager{
|
||||
unifiedMountpoint: mountpoint,
|
||||
path: path,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type Manager struct {
|
||||
unifiedMountpoint string
|
||||
path string
|
||||
}
|
||||
|
||||
func setResources(path string, resources *Resources) error {
|
||||
if resources != nil {
|
||||
if err := writeValues(path, resources.Values()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setDevices(path, resources.Devices); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Manager) RootControllers() ([]string, error) {
|
||||
b, err := ioutil.ReadFile(filepath.Join(c.unifiedMountpoint, controllersFile))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return strings.Fields(string(b)), nil
|
||||
}
|
||||
|
||||
func (c *Manager) Controllers() ([]string, error) {
|
||||
b, err := ioutil.ReadFile(filepath.Join(c.path, controllersFile))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return strings.Fields(string(b)), nil
|
||||
}
|
||||
|
||||
type ControllerToggle int
|
||||
|
||||
const (
|
||||
Enable ControllerToggle = iota + 1
|
||||
Disable
|
||||
)
|
||||
|
||||
func toggleFunc(controllers []string, prefix string) []string {
|
||||
out := make([]string, len(controllers))
|
||||
for i, c := range controllers {
|
||||
out[i] = prefix + c
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (c *Manager) ToggleControllers(controllers []string, t ControllerToggle) error {
|
||||
// when c.path is like /foo/bar/baz, the following files need to be written:
|
||||
// * /sys/fs/cgroup/cgroup.subtree_control
|
||||
// * /sys/fs/cgroup/foo/cgroup.subtree_control
|
||||
// * /sys/fs/cgroup/foo/bar/cgroup.subtree_control
|
||||
// Note that /sys/fs/cgroup/foo/bar/baz/cgroup.subtree_control does not need to be written.
|
||||
split := strings.Split(c.path, "/")
|
||||
var lastErr error
|
||||
for i, _ := range split {
|
||||
f := strings.Join(split[:i], "/")
|
||||
if !strings.HasPrefix(f, c.unifiedMountpoint) || f == c.path {
|
||||
continue
|
||||
}
|
||||
filePath := filepath.Join(f, subtreeControl)
|
||||
if err := c.writeSubtreeControl(filePath, controllers, t); err != nil {
|
||||
// When running as rootless, the user may face EPERM on parent groups, but it is neglible when the
|
||||
// controller is already written.
|
||||
// So we only return the last error.
|
||||
lastErr = errors.Wrapf(err, "failed to write subtree controllers %+v to %q", controllers, filePath)
|
||||
}
|
||||
}
|
||||
return lastErr
|
||||
}
|
||||
|
||||
func (c *Manager) writeSubtreeControl(filePath string, controllers []string, t ControllerToggle) error {
|
||||
f, err := os.OpenFile(filePath, os.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
switch t {
|
||||
case Enable:
|
||||
controllers = toggleFunc(controllers, "+")
|
||||
case Disable:
|
||||
controllers = toggleFunc(controllers, "-")
|
||||
}
|
||||
_, err = f.WriteString(strings.Join(controllers, " "))
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Manager) NewChild(name string, resources *Resources) (*Manager, error) {
|
||||
if strings.HasPrefix(name, "/") {
|
||||
return nil, errors.New("name must be relative")
|
||||
}
|
||||
path := filepath.Join(c.path, name)
|
||||
if err := os.MkdirAll(path, defaultDirPerm); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := setResources(path, resources); err != nil {
|
||||
// clean up cgroup dir on failure
|
||||
os.Remove(path)
|
||||
return nil, err
|
||||
}
|
||||
return &Manager{
|
||||
unifiedMountpoint: c.unifiedMountpoint,
|
||||
path: path,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Manager) AddProc(pid uint64) error {
|
||||
v := Value{
|
||||
filename: cgroupProcs,
|
||||
value: pid,
|
||||
}
|
||||
return writeValues(c.path, []Value{v})
|
||||
}
|
||||
|
||||
func (c *Manager) Delete() error {
|
||||
return remove(c.path)
|
||||
}
|
||||
|
||||
func (c *Manager) Procs(recursive bool) ([]uint64, error) {
|
||||
var processes []uint64
|
||||
err := filepath.Walk(c.path, func(p string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !recursive && info.IsDir() {
|
||||
if p == c.path {
|
||||
return nil
|
||||
}
|
||||
return filepath.SkipDir
|
||||
}
|
||||
_, name := filepath.Split(p)
|
||||
if name != cgroupProcs {
|
||||
return nil
|
||||
}
|
||||
procs, err := parseCgroupProcsFile(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
processes = append(processes, procs...)
|
||||
return nil
|
||||
})
|
||||
return processes, err
|
||||
}
|
||||
|
||||
var singleValueFiles = []string{
|
||||
"pids.current",
|
||||
"pids.max",
|
||||
}
|
||||
|
||||
func (c *Manager) Stat() (*stats.Metrics, error) {
|
||||
controllers, err := c.Controllers()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make(map[string]interface{})
|
||||
for _, controller := range controllers {
|
||||
filename := fmt.Sprintf("%s.stat", controller)
|
||||
if err := readStatsFile(c.path, filename, out); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
for _, name := range singleValueFiles {
|
||||
if err := readSingleFile(c.path, name, out); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var metrics stats.Metrics
|
||||
|
||||
metrics.Pids = &stats.PidsStat{
|
||||
Current: getPidValue("pids.current", out),
|
||||
Limit: getPidValue("pids.max", out),
|
||||
}
|
||||
metrics.CPU = &stats.CPUStat{
|
||||
UsageUsec: getUint64Value("usage_usec", out),
|
||||
UserUsec: getUint64Value("user_usec", out),
|
||||
SystemUsec: getUint64Value("system_usec", out),
|
||||
NrPeriods: getUint64Value("nr_periods", out),
|
||||
NrThrottled: getUint64Value("nr_throttled", out),
|
||||
ThrottledUsec: getUint64Value("throttled_usec", out),
|
||||
}
|
||||
metrics.Memory = &stats.MemoryStat{
|
||||
Anon: getUint64Value("anon", out),
|
||||
File: getUint64Value("file", out),
|
||||
KernelStack: getUint64Value("kernel_stack", out),
|
||||
Slab: getUint64Value("slab", out),
|
||||
Sock: getUint64Value("sock", out),
|
||||
Shmem: getUint64Value("shmem", out),
|
||||
FileMapped: getUint64Value("file_mapped", out),
|
||||
FileDirty: getUint64Value("file_dirty", out),
|
||||
FileWriteback: getUint64Value("file_writeback", out),
|
||||
AnonThp: getUint64Value("anon_thp", out),
|
||||
InactiveAnon: getUint64Value("inactive_anon", out),
|
||||
ActiveAnon: getUint64Value("active_anon", out),
|
||||
InactiveFile: getUint64Value("inactive_file", out),
|
||||
ActiveFile: getUint64Value("active_file", out),
|
||||
Unevictable: getUint64Value("unevictable", out),
|
||||
SlabReclaimable: getUint64Value("slab_reclaimable", out),
|
||||
SlabUnreclaimable: getUint64Value("slab_unreclaimable", out),
|
||||
Pgfault: getUint64Value("pgfault", out),
|
||||
Pgmajfault: getUint64Value("pgmajfault", out),
|
||||
WorkingsetRefault: getUint64Value("workingset_refault", out),
|
||||
WorkingsetActivate: getUint64Value("workingset_activate", out),
|
||||
WorkingsetNodereclaim: getUint64Value("workingset_nodereclaim", out),
|
||||
Pgrefill: getUint64Value("pgrefill", out),
|
||||
Pgscan: getUint64Value("pgscan", out),
|
||||
Pgsteal: getUint64Value("pgsteal", out),
|
||||
Pgactivate: getUint64Value("pgactivate", out),
|
||||
Pgdeactivate: getUint64Value("pgdeactivate", out),
|
||||
Pglazyfree: getUint64Value("pglazyfree", out),
|
||||
Pglazyfreed: getUint64Value("pglazyfreed", out),
|
||||
ThpFaultAlloc: getUint64Value("thp_fault_alloc", out),
|
||||
ThpCollapseAlloc: getUint64Value("thp_collapse_alloc", out),
|
||||
Usage: getStatFileContentUint64(filepath.Join(c.path, "memory.current")),
|
||||
UsageLimit: getStatFileContentUint64(filepath.Join(c.path, "memory.max")),
|
||||
SwapUsage: getStatFileContentUint64(filepath.Join(c.path, "memory.swap.current")),
|
||||
SwapLimit: getStatFileContentUint64(filepath.Join(c.path, "memory.swap.max")),
|
||||
}
|
||||
|
||||
metrics.Rdma = &stats.RdmaStat{
|
||||
Current: rdmaStats(filepath.Join(c.path, "rdma.current")),
|
||||
Limit: rdmaStats(filepath.Join(c.path, "rdma.max")),
|
||||
}
|
||||
|
||||
return &metrics, nil
|
||||
}
|
||||
|
||||
func getUint64Value(key string, out map[string]interface{}) uint64 {
|
||||
v, ok := out[key]
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
switch t := v.(type) {
|
||||
case uint64:
|
||||
return t
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func getPidValue(key string, out map[string]interface{}) uint64 {
|
||||
v, ok := out[key]
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
switch t := v.(type) {
|
||||
case uint64:
|
||||
return t
|
||||
case string:
|
||||
if t == "max" {
|
||||
return math.MaxUint64
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func readSingleFile(path string, file string, out map[string]interface{}) error {
|
||||
f, err := os.Open(filepath.Join(path, file))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
data, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s := strings.TrimSpace(string(data))
|
||||
v, err := parseUint(s, 10, 64)
|
||||
if err != nil {
|
||||
// if we cannot parse as a uint, parse as a string
|
||||
out[file] = s
|
||||
return nil
|
||||
}
|
||||
out[file] = v
|
||||
return nil
|
||||
}
|
||||
|
||||
func readStatsFile(path string, file string, out map[string]interface{}) error {
|
||||
f, err := os.Open(filepath.Join(path, file))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
s := bufio.NewScanner(f)
|
||||
for s.Scan() {
|
||||
if err := s.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
name, value, err := parseKV(s.Text())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out[name] = value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Manager) Freeze() error {
|
||||
return c.freeze(c.path, Frozen)
|
||||
}
|
||||
|
||||
func (c *Manager) Thaw() error {
|
||||
return c.freeze(c.path, Thawed)
|
||||
}
|
||||
|
||||
func (c *Manager) freeze(path string, state State) error {
|
||||
values := state.Values()
|
||||
for {
|
||||
if err := writeValues(path, values); err != nil {
|
||||
return err
|
||||
}
|
||||
current, err := fetchState(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if current == state {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(1 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Manager) MemoryEventFD() (uintptr, error) {
|
||||
fpath := filepath.Join(c.path, "memory.events")
|
||||
fd, err := syscall.InotifyInit()
|
||||
if err != nil {
|
||||
return 0, errors.Errorf("Failed to create inotify fd")
|
||||
}
|
||||
defer syscall.Close(fd)
|
||||
wd, err := syscall.InotifyAddWatch(fd, fpath, unix.IN_MODIFY)
|
||||
if wd < 0 {
|
||||
return 0, errors.Errorf("Failed to add inotify watch for %q", fpath)
|
||||
}
|
||||
defer syscall.InotifyRmWatch(fd, uint32(wd))
|
||||
|
||||
return uintptr(fd), nil
|
||||
}
|
||||
|
||||
func (c *Manager) EventChan() (<-chan Event, <-chan error) {
|
||||
ec := make(chan Event)
|
||||
errCh := make(chan error)
|
||||
go c.waitForEvents(ec, errCh)
|
||||
|
||||
return ec, nil
|
||||
}
|
||||
|
||||
func (c *Manager) waitForEvents(ec chan<- Event, errCh chan<- error) {
|
||||
fd, err := c.MemoryEventFD()
|
||||
if err != nil {
|
||||
errCh <- errors.Errorf("Failed to create memory event fd")
|
||||
}
|
||||
for {
|
||||
buffer := make([]byte, syscall.SizeofInotifyEvent*10)
|
||||
bytesRead, err := syscall.Read(int(fd), buffer)
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
}
|
||||
var out map[string]interface{}
|
||||
if bytesRead >= syscall.SizeofInotifyEvent {
|
||||
if err := readStatsFile(c.path, "memory.events", out); err != nil {
|
||||
e := Event{
|
||||
High: out["high"].(uint64),
|
||||
Low: out["low"].(uint64),
|
||||
Max: out["max"].(uint64),
|
||||
OOM: out["oom"].(uint64),
|
||||
OOMKill: out["oom_kill"].(uint64),
|
||||
}
|
||||
ec <- e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setDevices(path string, devices []specs.LinuxDeviceCgroup) error {
|
||||
if len(devices) == 0 {
|
||||
return nil
|
||||
}
|
||||
insts, license, err := DeviceFilter(devices)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dirFD, err := unix.Open(path, unix.O_DIRECTORY|unix.O_RDONLY, 0600)
|
||||
if err != nil {
|
||||
return errors.Errorf("cannot get dir FD for %s", path)
|
||||
}
|
||||
defer unix.Close(dirFD)
|
||||
if _, err := LoadAttachCgroupDeviceFilter(insts, license, dirFD); err != nil {
|
||||
if !canSkipEBPFError(devices) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
52
vendor/github.com/containerd/cgroups/v2/memory.go
generated
vendored
Normal file
52
vendor/github.com/containerd/cgroups/v2/memory.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
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 v2
|
||||
|
||||
type Memory struct {
|
||||
Swap *int64
|
||||
Max *int64
|
||||
Low *int64
|
||||
High *int64
|
||||
}
|
||||
|
||||
func (r *Memory) Values() (o []Value) {
|
||||
if r.Swap != nil {
|
||||
o = append(o, Value{
|
||||
filename: "memory.swap.max",
|
||||
value: *r.Swap,
|
||||
})
|
||||
}
|
||||
if r.Max != nil {
|
||||
o = append(o, Value{
|
||||
filename: "memory.max",
|
||||
value: *r.Max,
|
||||
})
|
||||
}
|
||||
if r.Low != nil {
|
||||
o = append(o, Value{
|
||||
filename: "memory.low",
|
||||
value: *r.Low,
|
||||
})
|
||||
}
|
||||
if r.High != nil {
|
||||
o = append(o, Value{
|
||||
filename: "memory.high",
|
||||
value: *r.High,
|
||||
})
|
||||
}
|
||||
return o
|
||||
}
|
||||
60
vendor/github.com/containerd/cgroups/v2/paths.go
generated
vendored
Normal file
60
vendor/github.com/containerd/cgroups/v2/paths.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
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 v2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// NestedGroupPath will nest the cgroups based on the calling processes cgroup
|
||||
// placing its child processes inside its own path
|
||||
func NestedGroupPath(suffix string) (string, error) {
|
||||
path, err := parseCgroupFile("/proc/self/cgroup")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(string(path), suffix), nil
|
||||
}
|
||||
|
||||
// PidGroupPath will return the correct cgroup paths for an existing process running inside a cgroup
|
||||
// This is commonly used for the Load function to restore an existing container
|
||||
func PidGroupPath(pid int) (string, error) {
|
||||
p := fmt.Sprintf("/proc/%d/cgroup", pid)
|
||||
return parseCgroupFile(p)
|
||||
}
|
||||
|
||||
// VerifyGroupPath verifies the format of group path string g.
|
||||
// The format is same as the third field in /proc/PID/cgroup.
|
||||
// e.g. "/user.slice/user-1001.slice/session-1.scope"
|
||||
//
|
||||
// g must be a "clean" absolute path starts with "/", and must not contain "/sys/fs/cgroup" prefix.
|
||||
//
|
||||
// VerifyGroupPath doesn't verify whether g actually exists on the system.
|
||||
func VerifyGroupPath(g string) error {
|
||||
if !strings.HasPrefix(g, "/") {
|
||||
return ErrInvalidGroupPath
|
||||
}
|
||||
if filepath.Clean(g) != g {
|
||||
return ErrInvalidGroupPath
|
||||
}
|
||||
if strings.HasPrefix(g, "/sys/fs/cgroup") {
|
||||
return ErrInvalidGroupPath
|
||||
}
|
||||
return nil
|
||||
}
|
||||
37
vendor/github.com/containerd/cgroups/v2/pids.go
generated
vendored
Normal file
37
vendor/github.com/containerd/cgroups/v2/pids.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
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 v2
|
||||
|
||||
import "strconv"
|
||||
|
||||
type Pids struct {
|
||||
Max int64
|
||||
}
|
||||
|
||||
func (r *Pids) Values() (o []Value) {
|
||||
if r.Max != 0 {
|
||||
limit := "max"
|
||||
if r.Max > 0 {
|
||||
limit = strconv.FormatInt(r.Max, 10)
|
||||
}
|
||||
o = append(o, Value{
|
||||
filename: "pids.max",
|
||||
value: limit,
|
||||
})
|
||||
}
|
||||
return o
|
||||
}
|
||||
46
vendor/github.com/containerd/cgroups/v2/rdma.go
generated
vendored
Normal file
46
vendor/github.com/containerd/cgroups/v2/rdma.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
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 v2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type RDMA struct {
|
||||
Limit []RDMAEntry
|
||||
}
|
||||
|
||||
type RDMAEntry struct {
|
||||
Device string
|
||||
HcaHandles uint32
|
||||
HcaObjects uint32
|
||||
}
|
||||
|
||||
func (r RDMAEntry) String() string {
|
||||
return fmt.Sprintf("%s hca_handle=%d hca_object=%d", r.Device, r.HcaHandles, r.HcaObjects)
|
||||
}
|
||||
|
||||
func (r *RDMA) Values() (o []Value) {
|
||||
for _, e := range r.Limit {
|
||||
o = append(o, Value{
|
||||
filename: "rdma.max",
|
||||
value: e.String(),
|
||||
})
|
||||
}
|
||||
|
||||
return o
|
||||
}
|
||||
65
vendor/github.com/containerd/cgroups/v2/state.go
generated
vendored
Normal file
65
vendor/github.com/containerd/cgroups/v2/state.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
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 v2
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// State is a type that represents the state of the current cgroup
|
||||
type State string
|
||||
|
||||
const (
|
||||
Unknown State = ""
|
||||
Thawed State = "thawed"
|
||||
Frozen State = "frozen"
|
||||
Deleted State = "deleted"
|
||||
|
||||
cgroupFreeze = "cgroup.freeze"
|
||||
)
|
||||
|
||||
func (s State) Values() []Value {
|
||||
v := Value{
|
||||
filename: cgroupFreeze,
|
||||
}
|
||||
switch s {
|
||||
case Frozen:
|
||||
v.value = "1"
|
||||
case Thawed:
|
||||
v.value = "0"
|
||||
}
|
||||
return []Value{
|
||||
v,
|
||||
}
|
||||
}
|
||||
|
||||
func fetchState(path string) (State, error) {
|
||||
current, err := ioutil.ReadFile(filepath.Join(path, cgroupFreeze))
|
||||
if err != nil {
|
||||
return Unknown, err
|
||||
}
|
||||
switch strings.TrimSpace(string(current)) {
|
||||
case "1":
|
||||
return Frozen, nil
|
||||
case "0":
|
||||
return Thawed, nil
|
||||
default:
|
||||
return Unknown, nil
|
||||
}
|
||||
}
|
||||
17
vendor/github.com/containerd/cgroups/v2/stats/doc.go
generated
vendored
Normal file
17
vendor/github.com/containerd/cgroups/v2/stats/doc.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
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 stats
|
||||
2759
vendor/github.com/containerd/cgroups/v2/stats/metrics.pb.go
generated
vendored
Normal file
2759
vendor/github.com/containerd/cgroups/v2/stats/metrics.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
78
vendor/github.com/containerd/cgroups/v2/stats/metrics.proto
generated
vendored
Normal file
78
vendor/github.com/containerd/cgroups/v2/stats/metrics.proto
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package io.containerd.cgroups.v2;
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
|
||||
message Metrics {
|
||||
PidsStat pids = 1;
|
||||
CPUStat cpu = 2 [(gogoproto.customname) = "CPU"];
|
||||
MemoryStat memory = 4;
|
||||
RdmaStat rdma = 5;
|
||||
}
|
||||
|
||||
message PidsStat {
|
||||
uint64 current = 1;
|
||||
uint64 limit = 2;
|
||||
}
|
||||
|
||||
message CPUStat {
|
||||
uint64 usage_usec = 1;
|
||||
uint64 user_usec = 2;
|
||||
uint64 system_usec = 3;
|
||||
uint64 nr_periods = 4;
|
||||
uint64 nr_throttled = 5;
|
||||
uint64 throttled_usec = 6;
|
||||
}
|
||||
|
||||
message MemoryStat {
|
||||
uint64 anon = 1;
|
||||
uint64 file = 2;
|
||||
uint64 kernel_stack = 3;
|
||||
uint64 slab = 4;
|
||||
uint64 sock = 5;
|
||||
uint64 shmem = 6;
|
||||
uint64 file_mapped = 7;
|
||||
uint64 file_dirty = 8;
|
||||
uint64 file_writeback = 9;
|
||||
uint64 anon_thp = 10;
|
||||
uint64 inactive_anon = 11;
|
||||
uint64 active_anon = 12;
|
||||
uint64 inactive_file = 13;
|
||||
uint64 active_file = 14;
|
||||
uint64 unevictable = 15;
|
||||
uint64 slab_reclaimable = 16;
|
||||
uint64 slab_unreclaimable = 17;
|
||||
uint64 pgfault = 18;
|
||||
uint64 pgmajfault = 19;
|
||||
uint64 workingset_refault = 20;
|
||||
uint64 workingset_activate = 21;
|
||||
uint64 workingset_nodereclaim = 22;
|
||||
uint64 pgrefill = 23;
|
||||
uint64 pgscan = 24;
|
||||
uint64 pgsteal = 25;
|
||||
uint64 pgactivate = 26;
|
||||
uint64 pgdeactivate = 27;
|
||||
uint64 pglazyfree = 28;
|
||||
uint64 pglazyfreed = 29;
|
||||
uint64 thp_fault_alloc = 30;
|
||||
uint64 thp_collapse_alloc = 31;
|
||||
uint64 usage = 32;
|
||||
uint64 usage_limit = 33;
|
||||
uint64 swap_usage = 34;
|
||||
uint64 swap_limit = 35;
|
||||
}
|
||||
|
||||
message RdmaStat {
|
||||
repeated RdmaEntry current = 1;
|
||||
repeated RdmaEntry limit = 2;
|
||||
}
|
||||
|
||||
message RdmaEntry {
|
||||
string device = 1;
|
||||
uint32 hca_handles = 2;
|
||||
uint32 hca_objects = 3;
|
||||
}
|
||||
|
||||
// iostat
|
||||
// fmt: 230:0 rbytes=394211328 wbytes=65044480 rios=16313 wios=2006 dbytes=0 dios=0
|
||||
304
vendor/github.com/containerd/cgroups/v2/utils.go
generated
vendored
Normal file
304
vendor/github.com/containerd/cgroups/v2/utils.go
generated
vendored
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
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 v2
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/cgroups/v2/stats"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
cgroupProcs = "cgroup.procs"
|
||||
defaultDirPerm = 0755
|
||||
)
|
||||
|
||||
// defaultFilePerm is a var so that the test framework can change the filemode
|
||||
// of all files created when the tests are running. The difference between the
|
||||
// tests and real world use is that files like "cgroup.procs" will exist when writing
|
||||
// to a read cgroup filesystem and do not exist prior when running in the tests.
|
||||
// this is set to a non 0 value in the test code
|
||||
var defaultFilePerm = os.FileMode(0)
|
||||
|
||||
// remove will remove a cgroup path handling EAGAIN and EBUSY errors and
|
||||
// retrying the remove after a exp timeout
|
||||
func remove(path string) error {
|
||||
var err error
|
||||
delay := 10 * time.Millisecond
|
||||
for i := 0; i < 5; i++ {
|
||||
if i != 0 {
|
||||
time.Sleep(delay)
|
||||
delay *= 2
|
||||
}
|
||||
if err = os.RemoveAll(path); err == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return errors.Wrapf(err, "cgroups: unable to remove path %q", path)
|
||||
}
|
||||
|
||||
// parseCgroupProcsFile parses /sys/fs/cgroup/$GROUPPATH/cgroup.procs
|
||||
func parseCgroupProcsFile(path string) ([]uint64, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
var (
|
||||
out []uint64
|
||||
s = bufio.NewScanner(f)
|
||||
)
|
||||
for s.Scan() {
|
||||
if t := s.Text(); t != "" {
|
||||
pid, err := strconv.ParseUint(t, 10, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, pid)
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func parseKV(raw string) (string, interface{}, error) {
|
||||
parts := strings.Fields(raw)
|
||||
switch len(parts) {
|
||||
case 2:
|
||||
v, err := parseUint(parts[1], 10, 64)
|
||||
if err != nil {
|
||||
// if we cannot parse as a uint, parse as a string
|
||||
return parts[0], parts[1], nil
|
||||
}
|
||||
return parts[0], v, nil
|
||||
default:
|
||||
return "", 0, ErrInvalidFormat
|
||||
}
|
||||
}
|
||||
|
||||
func readUint(path string) (uint64, error) {
|
||||
v, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return parseUint(strings.TrimSpace(string(v)), 10, 64)
|
||||
}
|
||||
|
||||
func parseUint(s string, base, bitSize int) (uint64, error) {
|
||||
v, err := strconv.ParseUint(s, base, bitSize)
|
||||
if err != nil {
|
||||
intValue, intErr := strconv.ParseInt(s, base, bitSize)
|
||||
// 1. Handle negative values greater than MinInt64 (and)
|
||||
// 2. Handle negative values lesser than MinInt64
|
||||
if intErr == nil && intValue < 0 {
|
||||
return 0, nil
|
||||
} else if intErr != nil &&
|
||||
intErr.(*strconv.NumError).Err == strconv.ErrRange &&
|
||||
intValue < 0 {
|
||||
return 0, nil
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// parseCgroupFile parses /proc/PID/cgroup file and return string
|
||||
func parseCgroupFile(path string) (string, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
return parseCgroupFromReader(f)
|
||||
}
|
||||
|
||||
func parseCgroupFromReader(r io.Reader) (string, error) {
|
||||
var (
|
||||
s = bufio.NewScanner(r)
|
||||
)
|
||||
for s.Scan() {
|
||||
if err := s.Err(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
var (
|
||||
text = s.Text()
|
||||
parts = strings.SplitN(text, ":", 3)
|
||||
)
|
||||
if len(parts) < 3 {
|
||||
return "", fmt.Errorf("invalid cgroup entry: %q", text)
|
||||
}
|
||||
// text is like "0::/user.slice/user-1001.slice/session-1.scope"
|
||||
if parts[0] == "0" && parts[1] == "" {
|
||||
return parts[2], nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("cgroup path not found")
|
||||
}
|
||||
|
||||
// ToResources converts the oci LinuxResources struct into a
|
||||
// v2 Resources type for use with this package.
|
||||
//
|
||||
// converting cgroups configuration from v1 to v2
|
||||
// ref: https://github.com/containers/crun/blob/master/crun.1.md#cgroup-v2
|
||||
func ToResources(spec *specs.LinuxResources) *Resources {
|
||||
var resources Resources
|
||||
if cpu := spec.CPU; cpu != nil {
|
||||
resources.CPU = &CPU{
|
||||
Cpus: cpu.Cpus,
|
||||
Mems: cpu.Mems,
|
||||
}
|
||||
if shares := cpu.Shares; shares != nil {
|
||||
convertedWeight := (1 + ((*shares-2)*9999)/262142)
|
||||
resources.CPU.Weight = &convertedWeight
|
||||
}
|
||||
if period := cpu.Period; period != nil {
|
||||
resources.CPU.Max = period
|
||||
}
|
||||
}
|
||||
if mem := spec.Memory; mem != nil {
|
||||
resources.Memory = &Memory{}
|
||||
if swap := mem.Swap; swap != nil {
|
||||
resources.Memory.Swap = swap
|
||||
}
|
||||
if l := mem.Limit; l != nil {
|
||||
resources.Memory.Max = l
|
||||
}
|
||||
if l := mem.Reservation; l != nil {
|
||||
resources.Memory.Low = l
|
||||
}
|
||||
}
|
||||
if pids := spec.Pids; pids != nil {
|
||||
resources.Pids = &Pids{
|
||||
Max: pids.Limit,
|
||||
}
|
||||
}
|
||||
if i := spec.BlockIO; i != nil {
|
||||
resources.IO = &IO{}
|
||||
if i.Weight != nil {
|
||||
resources.IO.BFQ.Weight = *i.Weight
|
||||
}
|
||||
for t, devices := range map[IOType][]specs.LinuxThrottleDevice{
|
||||
ReadBPS: i.ThrottleReadBpsDevice,
|
||||
WriteBPS: i.ThrottleWriteBpsDevice,
|
||||
ReadIOPS: i.ThrottleReadIOPSDevice,
|
||||
WriteIOPS: i.ThrottleWriteIOPSDevice,
|
||||
} {
|
||||
for _, d := range devices {
|
||||
resources.IO.Max = append(resources.IO.Max, Entry{
|
||||
Type: t,
|
||||
Major: d.Major,
|
||||
Minor: d.Minor,
|
||||
Rate: d.Rate,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
if i := spec.Rdma; i != nil {
|
||||
resources.RDMA = &RDMA{}
|
||||
for device, value := range spec.Rdma {
|
||||
if device != "" && (value.HcaHandles != nil || value.HcaObjects != nil) {
|
||||
resources.RDMA.Limit = append(resources.RDMA.Limit, RDMAEntry{
|
||||
Device: device,
|
||||
HcaHandles: *value.HcaHandles,
|
||||
HcaObjects: *value.HcaObjects,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &resources
|
||||
}
|
||||
|
||||
// Gets uint64 parsed content of single value cgroup stat file
|
||||
func getStatFileContentUint64(filePath string) uint64 {
|
||||
contents, err := ioutil.ReadFile(filePath)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
return 0
|
||||
}
|
||||
trimmed := strings.TrimSpace(string(contents))
|
||||
if trimmed == "max" {
|
||||
return math.MaxUint64
|
||||
}
|
||||
|
||||
res, err := parseUint(trimmed, 10, 64)
|
||||
if err != nil {
|
||||
logrus.Errorf("unable to parse %q as a uint from Cgroup file %q", string(contents), filePath)
|
||||
return res
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
func rdmaStats(filepath string) []*stats.RdmaEntry {
|
||||
currentData, err := ioutil.ReadFile(filepath)
|
||||
if err != nil {
|
||||
return []*stats.RdmaEntry{}
|
||||
}
|
||||
return toRdmaEntry(strings.Split(string(currentData), "\n"))
|
||||
}
|
||||
|
||||
func parseRdmaKV(raw string, entry *stats.RdmaEntry) {
|
||||
var value uint64
|
||||
var err error
|
||||
|
||||
parts := strings.Split(raw, "=")
|
||||
switch len(parts) {
|
||||
case 2:
|
||||
if parts[1] == "max" {
|
||||
value = math.MaxUint32
|
||||
} else {
|
||||
value, err = parseUint(parts[1], 10, 32)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if parts[0] == "hca_handle" {
|
||||
entry.HcaHandles = uint32(value)
|
||||
} else if parts[0] == "hca_object" {
|
||||
entry.HcaObjects = uint32(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func toRdmaEntry(strEntries []string) []*stats.RdmaEntry {
|
||||
var rdmaEntries []*stats.RdmaEntry
|
||||
for i := range strEntries {
|
||||
parts := strings.Fields(strEntries[i])
|
||||
switch len(parts) {
|
||||
case 3:
|
||||
entry := new(stats.RdmaEntry)
|
||||
entry.Device = parts[0]
|
||||
parseRdmaKV(parts[1], entry)
|
||||
parseRdmaKV(parts[2], entry)
|
||||
|
||||
rdmaEntries = append(rdmaEntries, entry)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
return rdmaEntries
|
||||
}
|
||||
8
vendor/github.com/containerd/containerd/client.go
generated
vendored
8
vendor/github.com/containerd/containerd/client.go
generated
vendored
@@ -54,6 +54,7 @@ import (
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/containerd/containerd/remotes"
|
||||
"github.com/containerd/containerd/remotes/docker"
|
||||
"github.com/containerd/containerd/services/introspection"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
snproxy "github.com/containerd/containerd/snapshots/proxy"
|
||||
"github.com/containerd/typeurl"
|
||||
@@ -621,10 +622,13 @@ func (c *Client) DiffService() DiffService {
|
||||
}
|
||||
|
||||
// IntrospectionService returns the underlying Introspection Client
|
||||
func (c *Client) IntrospectionService() introspectionapi.IntrospectionClient {
|
||||
func (c *Client) IntrospectionService() introspection.Service {
|
||||
if c.introspectionService != nil {
|
||||
return c.introspectionService
|
||||
}
|
||||
c.connMu.Lock()
|
||||
defer c.connMu.Unlock()
|
||||
return introspectionapi.NewIntrospectionClient(c.conn)
|
||||
return introspection.NewIntrospectionServiceFromClient(introspectionapi.NewIntrospectionClient(c.conn))
|
||||
}
|
||||
|
||||
// LeasesService returns the underlying Leases Client
|
||||
|
||||
6
vendor/github.com/containerd/containerd/image.go
generated
vendored
6
vendor/github.com/containerd/containerd/image.go
generated
vendored
@@ -58,6 +58,8 @@ type Image interface {
|
||||
IsUnpacked(context.Context, string) (bool, error)
|
||||
// ContentStore provides a content store which contains image blob data
|
||||
ContentStore() content.Store
|
||||
// Metadata returns the underlying image metadata
|
||||
Metadata() images.Image
|
||||
}
|
||||
|
||||
type usageOptions struct {
|
||||
@@ -130,6 +132,10 @@ type image struct {
|
||||
platform platforms.MatchComparer
|
||||
}
|
||||
|
||||
func (i *image) Metadata() images.Image {
|
||||
return i.i
|
||||
}
|
||||
|
||||
func (i *image) Name() string {
|
||||
return i.i.Name
|
||||
}
|
||||
|
||||
2
vendor/github.com/containerd/containerd/images/archive/importer.go
generated
vendored
2
vendor/github.com/containerd/containerd/images/archive/importer.go
generated
vendored
@@ -181,7 +181,7 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader, opt
|
||||
Layers: layers,
|
||||
}
|
||||
|
||||
desc, err := writeManifest(ctx, store, manifest, ocispec.MediaTypeImageManifest)
|
||||
desc, err := writeManifest(ctx, store, manifest, manifest.MediaType)
|
||||
if err != nil {
|
||||
return ocispec.Descriptor{}, errors.Wrap(err, "write docker manifest")
|
||||
}
|
||||
|
||||
8
vendor/github.com/containerd/containerd/install.go
generated
vendored
8
vendor/github.com/containerd/containerd/install.go
generated
vendored
@@ -24,7 +24,6 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
introspectionapi "github.com/containerd/containerd/api/services/introspection/v1"
|
||||
"github.com/containerd/containerd/archive"
|
||||
"github.com/containerd/containerd/archive/compression"
|
||||
"github.com/containerd/containerd/content"
|
||||
@@ -99,11 +98,8 @@ func (c *Client) getInstallPath(ctx context.Context, config InstallConfig) (stri
|
||||
if config.Path != "" {
|
||||
return config.Path, nil
|
||||
}
|
||||
resp, err := c.IntrospectionService().Plugins(ctx, &introspectionapi.PluginsRequest{
|
||||
Filters: []string{
|
||||
"id==opt",
|
||||
},
|
||||
})
|
||||
filters := []string{"id==opt"}
|
||||
resp, err := c.IntrospectionService().Plugins(ctx, filters)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
4
vendor/github.com/containerd/containerd/metadata/adaptors.go
generated
vendored
4
vendor/github.com/containerd/containerd/metadata/adaptors.go
generated
vendored
@@ -159,9 +159,7 @@ func adaptSnapshot(info snapshots.Info) filters.Adaptor {
|
||||
case "name":
|
||||
return info.Name, true
|
||||
case "parent":
|
||||
if info.Parent != "" {
|
||||
return info.Parent, true
|
||||
}
|
||||
return info.Parent, true
|
||||
case "labels":
|
||||
return checkMap(fieldpath[1:], info.Labels)
|
||||
}
|
||||
|
||||
260
vendor/github.com/containerd/containerd/metadata/snapshot.go
generated
vendored
260
vendor/github.com/containerd/containerd/metadata/snapshot.go
generated
vendored
@@ -38,6 +38,7 @@ import (
|
||||
|
||||
const (
|
||||
inheritedLabelsPrefix = "containerd.io/snapshot/"
|
||||
labelSnapshotRef = "containerd.io/snapshot.ref"
|
||||
)
|
||||
|
||||
type snapshotter struct {
|
||||
@@ -159,6 +160,7 @@ func (s *snapshotter) Update(ctx context.Context, info snapshots.Info, fieldpath
|
||||
local = snapshots.Info{
|
||||
Name: info.Name,
|
||||
}
|
||||
updated bool
|
||||
)
|
||||
if err := update(ctx, s.db, func(tx *bolt.Tx) error {
|
||||
bkt := getSnapshotterBucket(tx, ns, s.name)
|
||||
@@ -217,20 +219,22 @@ func (s *snapshotter) Update(ctx context.Context, info snapshots.Info, fieldpath
|
||||
|
||||
inner := snapshots.Info{
|
||||
Name: bkey,
|
||||
Labels: filterInheritedLabels(local.Labels),
|
||||
Labels: snapshots.FilterInheritedLabels(local.Labels),
|
||||
}
|
||||
|
||||
if _, err := s.Snapshotter.Update(ctx, inner, fieldpaths...); err != nil {
|
||||
// NOTE: Perform this inside the transaction to reduce the
|
||||
// chances of out of sync data. The backend snapshotters
|
||||
// should perform the Update as fast as possible.
|
||||
if info, err = s.Snapshotter.Update(ctx, inner, fieldpaths...); err != nil {
|
||||
return err
|
||||
}
|
||||
updated = true
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return snapshots.Info{}, err
|
||||
}
|
||||
|
||||
info, err = s.Snapshotter.Stat(ctx, bkey)
|
||||
if err != nil {
|
||||
if updated {
|
||||
log.G(ctx).WithField("snapshotter", s.name).WithField("key", local.Name).WithError(err).Error("transaction failed after updating snapshot backend")
|
||||
}
|
||||
return snapshots.Info{}, err
|
||||
}
|
||||
|
||||
@@ -297,31 +301,158 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m []mount.Mount
|
||||
var (
|
||||
target = base.Labels[labelSnapshotRef]
|
||||
bparent string
|
||||
bkey string
|
||||
bopts = []snapshots.Opt{
|
||||
snapshots.WithLabels(snapshots.FilterInheritedLabels(base.Labels)),
|
||||
}
|
||||
)
|
||||
|
||||
if err := update(ctx, s.db, func(tx *bolt.Tx) error {
|
||||
bkt, err := createSnapshotterBucket(tx, ns, s.name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bbkt, err := bkt.CreateBucket([]byte(key))
|
||||
if err != nil {
|
||||
if err == bolt.ErrBucketExists {
|
||||
err = errors.Wrapf(errdefs.ErrAlreadyExists, "snapshot %q", key)
|
||||
// Check if target exists, if so, return already exists
|
||||
if target != "" {
|
||||
if tbkt := bkt.Bucket([]byte(target)); tbkt != nil {
|
||||
return errors.Wrapf(errdefs.ErrAlreadyExists, "target snapshot %q", target)
|
||||
}
|
||||
return err
|
||||
}
|
||||
if err := addSnapshotLease(ctx, tx, s.name, key); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var bparent string
|
||||
if bbkt := bkt.Bucket([]byte(key)); bbkt != nil {
|
||||
return errors.Wrapf(errdefs.ErrAlreadyExists, "snapshot %q", key)
|
||||
}
|
||||
|
||||
if parent != "" {
|
||||
pbkt := bkt.Bucket([]byte(parent))
|
||||
if pbkt == nil {
|
||||
return errors.Wrapf(errdefs.ErrNotFound, "parent snapshot %v does not exist", parent)
|
||||
}
|
||||
bparent = string(pbkt.Get(bucketKeyName))
|
||||
}
|
||||
|
||||
sid, err := bkt.NextSequence()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bkey = createKey(sid, ns, key)
|
||||
|
||||
return err
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
m []mount.Mount
|
||||
created string
|
||||
rerr error
|
||||
)
|
||||
if readonly {
|
||||
m, err = s.Snapshotter.View(ctx, bkey, bparent, bopts...)
|
||||
} else {
|
||||
m, err = s.Snapshotter.Prepare(ctx, bkey, bparent, bopts...)
|
||||
}
|
||||
|
||||
// An already exists error should indicate the backend found a snapshot
|
||||
// matching a provided target reference.
|
||||
if errdefs.IsAlreadyExists(err) {
|
||||
if target != "" {
|
||||
var tinfo *snapshots.Info
|
||||
filter := fmt.Sprintf(`labels."containerd.io/snapshot.ref"==%s,parent==%q`, target, bparent)
|
||||
if err := s.Snapshotter.Walk(ctx, func(ctx context.Context, i snapshots.Info) error {
|
||||
if tinfo == nil && i.Kind == snapshots.KindCommitted {
|
||||
if i.Labels["containerd.io/snapshot.ref"] != target {
|
||||
// Walk did not respect filter
|
||||
return nil
|
||||
}
|
||||
if i.Parent != bparent {
|
||||
// Walk did not respect filter
|
||||
return nil
|
||||
}
|
||||
tinfo = &i
|
||||
}
|
||||
return nil
|
||||
|
||||
}, filter); err != nil {
|
||||
return nil, errors.Wrap(err, "failed walking backend snapshots")
|
||||
}
|
||||
|
||||
if tinfo == nil {
|
||||
return nil, errors.Wrapf(errdefs.ErrNotFound, "target snapshot %q in backend", target)
|
||||
}
|
||||
|
||||
key = target
|
||||
bkey = tinfo.Name
|
||||
bparent = tinfo.Parent
|
||||
base.Created = tinfo.Created
|
||||
base.Updated = tinfo.Updated
|
||||
if base.Labels == nil {
|
||||
base.Labels = tinfo.Labels
|
||||
} else {
|
||||
for k, v := range tinfo.Labels {
|
||||
if _, ok := base.Labels[k]; !ok {
|
||||
base.Labels[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate this error after the final update
|
||||
rerr = errors.Wrapf(errdefs.ErrAlreadyExists, "target snapshot %q from snapshotter", target)
|
||||
} else {
|
||||
// This condition is unexpected as the key provided is expected
|
||||
// to be new and unique, return as unknown response from backend
|
||||
// to avoid confusing callers handling already exists.
|
||||
return nil, errors.Wrapf(errdefs.ErrUnknown, "unexpected error from snapshotter: %v", err)
|
||||
}
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
ts := time.Now().UTC()
|
||||
base.Created = ts
|
||||
base.Updated = ts
|
||||
created = bkey
|
||||
}
|
||||
|
||||
if txerr := update(ctx, s.db, func(tx *bolt.Tx) error {
|
||||
bkt := getSnapshotterBucket(tx, ns, s.name)
|
||||
if bkt == nil {
|
||||
return errors.Wrapf(errdefs.ErrNotFound, "can not find snapshotter %q", s.name)
|
||||
}
|
||||
|
||||
if err := addSnapshotLease(ctx, tx, s.name, key); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bbkt, err := bkt.CreateBucket([]byte(key))
|
||||
if err != nil {
|
||||
if err != bolt.ErrBucketExists {
|
||||
return err
|
||||
}
|
||||
if rerr == nil {
|
||||
rerr = errors.Wrapf(errdefs.ErrAlreadyExists, "snapshot %q", key)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if parent != "" {
|
||||
pbkt := bkt.Bucket([]byte(parent))
|
||||
if pbkt == nil {
|
||||
return errors.Wrapf(errdefs.ErrNotFound, "parent snapshot %v does not exist", parent)
|
||||
}
|
||||
|
||||
// Ensure the backend's parent matches the metadata store's parent
|
||||
// If it is mismatched, then a target was provided for a snapshotter
|
||||
// which has a different parent then requested.
|
||||
// NOTE: The backend snapshotter is responsible for enforcing the
|
||||
// uniqueness of the reference relationships, the metadata store
|
||||
// can only error out to prevent inconsistent data.
|
||||
if bparent != string(pbkt.Get(bucketKeyName)) {
|
||||
return errors.Wrapf(errdefs.ErrInvalidArgument, "mismatched parent %s from target %s", parent, target)
|
||||
}
|
||||
|
||||
cbkt, err := pbkt.CreateBucketIfNotExists(bucketKeyChildren)
|
||||
if err != nil {
|
||||
@@ -336,36 +467,28 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re
|
||||
}
|
||||
}
|
||||
|
||||
sid, err := bkt.NextSequence()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bkey := createKey(sid, ns, key)
|
||||
if err := bbkt.Put(bucketKeyName, []byte(bkey)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ts := time.Now().UTC()
|
||||
if err := boltutil.WriteTimestamps(bbkt, ts, ts); err != nil {
|
||||
if err := boltutil.WriteTimestamps(bbkt, base.Created, base.Updated); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := boltutil.WriteLabels(bbkt, base.Labels); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
inheritedOpt := snapshots.WithLabels(filterInheritedLabels(base.Labels))
|
||||
|
||||
// TODO: Consider doing this outside of transaction to lessen
|
||||
// metadata lock time
|
||||
if readonly {
|
||||
m, err = s.Snapshotter.View(ctx, bkey, bparent, inheritedOpt)
|
||||
} else {
|
||||
m, err = s.Snapshotter.Prepare(ctx, bkey, bparent, inheritedOpt)
|
||||
}
|
||||
return err
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
return bbkt.Put(bucketKeyName, []byte(bkey))
|
||||
}); txerr != nil {
|
||||
rerr = txerr
|
||||
}
|
||||
|
||||
if rerr != nil {
|
||||
// If the created reference is not stored, attempt clean up
|
||||
if created != "" {
|
||||
if err := s.Snapshotter.Remove(ctx, created); err != nil {
|
||||
log.G(ctx).WithField("snapshotter", s.name).WithField("key", created).WithError(err).Error("failed to cleanup unreferenced snapshot")
|
||||
}
|
||||
}
|
||||
return nil, rerr
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
@@ -389,7 +512,8 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap
|
||||
return err
|
||||
}
|
||||
|
||||
return update(ctx, s.db, func(tx *bolt.Tx) error {
|
||||
var bname string
|
||||
if err := update(ctx, s.db, func(tx *bolt.Tx) error {
|
||||
bkt := getSnapshotterBucket(tx, ns, s.name)
|
||||
if bkt == nil {
|
||||
return errors.Wrapf(errdefs.ErrNotFound,
|
||||
@@ -462,12 +586,40 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap
|
||||
return err
|
||||
}
|
||||
|
||||
inheritedOpt := snapshots.WithLabels(filterInheritedLabels(base.Labels))
|
||||
inheritedOpt := snapshots.WithLabels(snapshots.FilterInheritedLabels(base.Labels))
|
||||
|
||||
// TODO: Consider doing this outside of transaction to lessen
|
||||
// metadata lock time
|
||||
return s.Snapshotter.Commit(ctx, nameKey, bkey, inheritedOpt)
|
||||
})
|
||||
// NOTE: Backend snapshotters should commit fast and reliably to
|
||||
// prevent metadata store locking and minimizing rollbacks.
|
||||
// This operation should be done in the transaction to minimize the
|
||||
// risk of the committed keys becoming out of sync. If this operation
|
||||
// succeed and the overall transaction fails then the risk of out of
|
||||
// sync data is higher and may require manual cleanup.
|
||||
if err := s.Snapshotter.Commit(ctx, nameKey, bkey, inheritedOpt); err != nil {
|
||||
if errdefs.IsNotFound(err) {
|
||||
log.G(ctx).WithField("snapshotter", s.name).WithField("key", key).WithError(err).Error("uncommittable snapshot: missing in backend, snapshot should be removed")
|
||||
}
|
||||
// NOTE: Consider handling already exists here from the backend. Currently
|
||||
// already exists from the backend may be confusing to the client since it
|
||||
// may require the client to re-attempt from prepare. However, if handling
|
||||
// here it is not clear what happened with the existing backend key and
|
||||
// whether the already prepared snapshot would still be used or must be
|
||||
// discarded. It is best that all implementations of the snapshotter
|
||||
// interface behave the same, in which case the backend should handle the
|
||||
// mapping of duplicates and not error.
|
||||
return err
|
||||
}
|
||||
bname = nameKey
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
if bname != "" {
|
||||
log.G(ctx).WithField("snapshotter", s.name).WithField("key", key).WithField("bname", bname).WithError(err).Error("uncommittable snapshot: transaction failed after commit, snapshot should be removed")
|
||||
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
@@ -787,19 +939,3 @@ func (s *snapshotter) pruneBranch(ctx context.Context, node *treeNode) error {
|
||||
func (s *snapshotter) Close() error {
|
||||
return s.Snapshotter.Close()
|
||||
}
|
||||
|
||||
// filterInheritedLabels filters the provided labels by removing any key which doesn't have
|
||||
// a prefix of "containerd.io/snapshot/".
|
||||
func filterInheritedLabels(labels map[string]string) map[string]string {
|
||||
if labels == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
filtered := make(map[string]string)
|
||||
for k, v := range labels {
|
||||
if strings.HasPrefix(k, inheritedLabelsPrefix) {
|
||||
filtered[k] = v
|
||||
}
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
73
vendor/github.com/containerd/containerd/metrics/cgroups/cgroups.go
generated
vendored
73
vendor/github.com/containerd/containerd/metrics/cgroups/cgroups.go
generated
vendored
@@ -19,20 +19,13 @@
|
||||
package cgroups
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
eventstypes "github.com/containerd/containerd/api/events"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/events"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
v1 "github.com/containerd/containerd/metrics/cgroups/v1"
|
||||
v2 "github.com/containerd/containerd/metrics/cgroups/v2"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/containerd/containerd/runtime"
|
||||
"github.com/containerd/containerd/runtime/v1/linux"
|
||||
metrics "github.com/docker/go-metrics"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Config for the cgroups monitor
|
||||
@@ -56,8 +49,15 @@ func New(ic *plugin.InitContext) (interface{}, error) {
|
||||
if !config.NoPrometheus {
|
||||
ns = metrics.NewNamespace("container", "", nil)
|
||||
}
|
||||
collector := newCollector(ns)
|
||||
oom, err := newOOMCollector(ns)
|
||||
var (
|
||||
tm runtime.TaskMonitor
|
||||
err error
|
||||
)
|
||||
if cgroups.Mode() == cgroups.Unified {
|
||||
tm, err = v2.NewTaskMonitor(ic.Context, ic.Events, ns)
|
||||
} else {
|
||||
tm, err = v1.NewTaskMonitor(ic.Context, ic.Events, ns)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -65,54 +65,5 @@ func New(ic *plugin.InitContext) (interface{}, error) {
|
||||
metrics.Register(ns)
|
||||
}
|
||||
ic.Meta.Platforms = append(ic.Meta.Platforms, platforms.DefaultSpec())
|
||||
return &cgroupsMonitor{
|
||||
collector: collector,
|
||||
oom: oom,
|
||||
context: ic.Context,
|
||||
publisher: ic.Events,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type cgroupsMonitor struct {
|
||||
collector *collector
|
||||
oom *oomCollector
|
||||
context context.Context
|
||||
publisher events.Publisher
|
||||
}
|
||||
|
||||
func (m *cgroupsMonitor) Monitor(c runtime.Task) error {
|
||||
if err := m.collector.Add(c); err != nil {
|
||||
return err
|
||||
}
|
||||
t, ok := c.(*linux.Task)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
cg, err := t.Cgroup()
|
||||
if err != nil {
|
||||
if errdefs.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
err = m.oom.Add(c.ID(), c.Namespace(), cg, m.trigger)
|
||||
if err == cgroups.ErrMemoryNotSupported {
|
||||
logrus.WithError(err).Warn("OOM monitoring failed")
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *cgroupsMonitor) Stop(c runtime.Task) error {
|
||||
m.collector.Remove(c)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *cgroupsMonitor) trigger(id, namespace string, cg cgroups.Cgroup) {
|
||||
ctx := namespaces.WithNamespace(m.context, namespace)
|
||||
if err := m.publisher.Publish(ctx, runtime.TaskOOMEventTopic, &eventstypes.TaskOOM{
|
||||
ContainerID: id,
|
||||
}); err != nil {
|
||||
log.G(m.context).WithError(err).Error("post OOM event")
|
||||
}
|
||||
return tm, nil
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package v1
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
93
vendor/github.com/containerd/containerd/metrics/cgroups/v1/cgroups.go
generated
vendored
Normal file
93
vendor/github.com/containerd/containerd/metrics/cgroups/v1/cgroups.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
// +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 (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
eventstypes "github.com/containerd/containerd/api/events"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/events"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/runtime"
|
||||
"github.com/containerd/containerd/runtime/v1/linux"
|
||||
metrics "github.com/docker/go-metrics"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// NewTaskMonitor returns a new cgroups monitor
|
||||
func NewTaskMonitor(ctx context.Context, publisher events.Publisher, ns *metrics.Namespace) (runtime.TaskMonitor, error) {
|
||||
collector := newCollector(ns)
|
||||
oom, err := newOOMCollector(ns)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cgroupsMonitor{
|
||||
collector: collector,
|
||||
oom: oom,
|
||||
context: ctx,
|
||||
publisher: publisher,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type cgroupsMonitor struct {
|
||||
collector *collector
|
||||
oom *oomCollector
|
||||
context context.Context
|
||||
publisher events.Publisher
|
||||
}
|
||||
|
||||
func (m *cgroupsMonitor) Monitor(c runtime.Task) error {
|
||||
if err := m.collector.Add(c); err != nil {
|
||||
return err
|
||||
}
|
||||
t, ok := c.(*linux.Task)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
cg, err := t.Cgroup()
|
||||
if err != nil {
|
||||
if errdefs.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
err = m.oom.Add(c.ID(), c.Namespace(), cg, m.trigger)
|
||||
if err == cgroups.ErrMemoryNotSupported {
|
||||
logrus.WithError(err).Warn("OOM monitoring failed")
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *cgroupsMonitor) Stop(c runtime.Task) error {
|
||||
m.collector.Remove(c)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *cgroupsMonitor) trigger(id, namespace string, cg cgroups.Cgroup) {
|
||||
ctx := namespaces.WithNamespace(m.context, namespace)
|
||||
if err := m.publisher.Publish(ctx, runtime.TaskOOMEventTopic, &eventstypes.TaskOOM{
|
||||
ContainerID: id,
|
||||
}); err != nil {
|
||||
log.G(m.context).WithError(err).Error("post OOM event")
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package v1
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
@@ -16,7 +16,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "github.com/containerd/containerd/metrics/types/v1"
|
||||
@@ -16,7 +16,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "github.com/containerd/containerd/metrics/types/v1"
|
||||
@@ -16,7 +16,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "github.com/containerd/containerd/metrics/types/v1"
|
||||
@@ -16,7 +16,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -16,7 +16,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package v1
|
||||
|
||||
import (
|
||||
"sync"
|
||||
@@ -16,7 +16,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "github.com/containerd/containerd/metrics/types/v1"
|
||||
70
vendor/github.com/containerd/containerd/metrics/cgroups/v2/cgroups.go
generated
vendored
Normal file
70
vendor/github.com/containerd/containerd/metrics/cgroups/v2/cgroups.go
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
// +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 v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/events"
|
||||
"github.com/containerd/containerd/runtime"
|
||||
"github.com/containerd/containerd/runtime/v1/linux"
|
||||
metrics "github.com/docker/go-metrics"
|
||||
)
|
||||
|
||||
// NewTaskMonitor returns a new cgroups monitor
|
||||
func NewTaskMonitor(ctx context.Context, publisher events.Publisher, ns *metrics.Namespace) (runtime.TaskMonitor, error) {
|
||||
collector := newCollector(ns)
|
||||
return &cgroupsMonitor{
|
||||
collector: collector,
|
||||
context: ctx,
|
||||
publisher: publisher,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type cgroupsMonitor struct {
|
||||
collector *collector
|
||||
context context.Context
|
||||
publisher events.Publisher
|
||||
}
|
||||
|
||||
func (m *cgroupsMonitor) Monitor(c runtime.Task) error {
|
||||
if err := m.collector.Add(c); err != nil {
|
||||
return err
|
||||
}
|
||||
t, ok := c.(*linux.Task)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
cg, err := t.Cgroup()
|
||||
if err != nil {
|
||||
if errdefs.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
// OOM handler is not implemented yet
|
||||
_ = cg
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *cgroupsMonitor) Stop(c runtime.Task) error {
|
||||
m.collector.Remove(c)
|
||||
return nil
|
||||
}
|
||||
124
vendor/github.com/containerd/containerd/metrics/cgroups/v2/cpu.go
generated
vendored
Normal file
124
vendor/github.com/containerd/containerd/metrics/cgroups/v2/cpu.go
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
// +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 v2
|
||||
|
||||
import (
|
||||
v2 "github.com/containerd/containerd/metrics/types/v2"
|
||||
metrics "github.com/docker/go-metrics"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
var cpuMetrics = []*metric{
|
||||
{
|
||||
name: "cpu_usage_usec",
|
||||
help: "Total cpu usage (cgroup v2)",
|
||||
unit: metrics.Unit("microseconds"),
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.CPU == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.CPU.UsageUsec),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cpu_user_usec",
|
||||
help: "Current cpu usage in user space (cgroup v2)",
|
||||
unit: metrics.Unit("microseconds"),
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.CPU == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.CPU.UserUsec),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cpu_system_usec",
|
||||
help: "Current cpu usage in kernel space (cgroup v2)",
|
||||
unit: metrics.Unit("microseconds"),
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.CPU == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.CPU.SystemUsec),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cpu_nr_periods",
|
||||
help: "Current cpu number of periods (only if controller is enabled)",
|
||||
unit: metrics.Total,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.CPU == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.CPU.NrPeriods),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cpu_nr_throttled",
|
||||
help: "Total number of times tasks have been throttled (only if controller is enabled)",
|
||||
unit: metrics.Total,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.CPU == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.CPU.NrThrottled),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cpu_throttled_usec",
|
||||
help: "Total time duration for which tasks have been throttled. (only if controller is enabled)",
|
||||
unit: metrics.Unit("microseconds"),
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.CPU == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.CPU.ThrottledUsec),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
589
vendor/github.com/containerd/containerd/metrics/cgroups/v2/memory.go
generated
vendored
Normal file
589
vendor/github.com/containerd/containerd/metrics/cgroups/v2/memory.go
generated
vendored
Normal file
@@ -0,0 +1,589 @@
|
||||
// +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 v2
|
||||
|
||||
import (
|
||||
v2 "github.com/containerd/containerd/metrics/types/v2"
|
||||
metrics "github.com/docker/go-metrics"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
var memoryMetrics = []*metric{
|
||||
{
|
||||
name: "memory_usage",
|
||||
help: "Current memory usage (cgroup v2)",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Usage),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_usage_limit",
|
||||
help: "Current memory usage limit (cgroup v2)",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.UsageLimit),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_swap_usage",
|
||||
help: "Current swap usage (cgroup v2)",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.SwapUsage),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_swap_limit",
|
||||
help: "Current swap usage limit (cgroup v2)",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.SwapLimit),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "memory_file_mapped",
|
||||
help: "The file_mapped amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.FileMapped),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_file_dirty",
|
||||
help: "The file_dirty amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.FileDirty),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_file_writeback",
|
||||
help: "The file_writeback amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.FileWriteback),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_pgactivate",
|
||||
help: "The pgactivate amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Pgactivate),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_pgdeactivate",
|
||||
help: "The pgdeactivate amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Pgdeactivate),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_pgfault",
|
||||
help: "The pgfault amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Pgfault),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_pgmajfault",
|
||||
help: "The pgmajfault amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Pgmajfault),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_pglazyfree",
|
||||
help: "The pglazyfree amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Pglazyfree),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_pgrefill",
|
||||
help: "The pgrefill amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Pgrefill),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_pglazyfreed",
|
||||
help: "The pglazyfreed amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Pglazyfreed),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_pgscan",
|
||||
help: "The pgscan amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Pgscan),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_pgsteal",
|
||||
help: "The pgsteal amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Pgsteal),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_inactive_anon",
|
||||
help: "The inactive_anon amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.InactiveAnon),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_active_anon",
|
||||
help: "The active_anon amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.ActiveAnon),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_inactive_file",
|
||||
help: "The inactive_file amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.InactiveFile),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_active_file",
|
||||
help: "The active_file amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.ActiveFile),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_unevictable",
|
||||
help: "The unevictable amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Unevictable),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_anon",
|
||||
help: "The anon amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Anon),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_file",
|
||||
help: "The file amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.File),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_kernel_stack",
|
||||
help: "The kernel_stack amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.KernelStack),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_slab",
|
||||
help: "The slab amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Slab),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_sock",
|
||||
help: "The sock amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Sock),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_shmem",
|
||||
help: "The shmem amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Shmem),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_anon_thp",
|
||||
help: "The anon_thp amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.AnonThp),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_slab_reclaimable",
|
||||
help: "The slab_reclaimable amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.SlabReclaimable),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_slab_unreclaimable",
|
||||
help: "The slab_unreclaimable amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.SlabUnreclaimable),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_workingset_refault",
|
||||
help: "The workingset_refault amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.WorkingsetRefault),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_workingset_activate",
|
||||
help: "The workingset_activate amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.WorkingsetActivate),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_workingset_nodereclaim",
|
||||
help: "The workingset_nodereclaim amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.WorkingsetNodereclaim),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_thp_fault_alloc",
|
||||
help: "The thp_fault_alloc amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.ThpFaultAlloc),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "memory_thp_collapse_alloc",
|
||||
help: "The thp_collapse_alloc amount",
|
||||
unit: metrics.Bytes,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Memory == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.ThpCollapseAlloc),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
61
vendor/github.com/containerd/containerd/metrics/cgroups/v2/metric.go
generated
vendored
Normal file
61
vendor/github.com/containerd/containerd/metrics/cgroups/v2/metric.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
// +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 v2
|
||||
|
||||
import (
|
||||
v2 "github.com/containerd/containerd/metrics/types/v2"
|
||||
metrics "github.com/docker/go-metrics"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type value struct {
|
||||
v float64
|
||||
l []string
|
||||
}
|
||||
|
||||
type metric struct {
|
||||
name string
|
||||
help string
|
||||
unit metrics.Unit
|
||||
vt prometheus.ValueType
|
||||
labels []string
|
||||
// getValues returns the value and labels for the data
|
||||
getValues func(stats *v2.Metrics) []value
|
||||
}
|
||||
|
||||
func (m *metric) desc(ns *metrics.Namespace) *prometheus.Desc {
|
||||
// the namespace label is for containerd namespaces
|
||||
return ns.NewDesc(m.name, m.help, m.unit, append([]string{"container_id", "namespace"}, m.labels...)...)
|
||||
}
|
||||
|
||||
func (m *metric) collect(id, namespace string, stats *v2.Metrics, ns *metrics.Namespace, ch chan<- prometheus.Metric, block bool) {
|
||||
values := m.getValues(stats)
|
||||
for _, v := range values {
|
||||
// block signals to block on the sending the metrics so none are missed
|
||||
if block {
|
||||
ch <- prometheus.MustNewConstMetric(m.desc(ns), m.vt, v.v, append([]string{id, namespace}, v.l...)...)
|
||||
continue
|
||||
}
|
||||
// non-blocking metrics can be dropped if the chan is full
|
||||
select {
|
||||
case ch <- prometheus.MustNewConstMetric(m.desc(ns), m.vt, v.v, append([]string{id, namespace}, v.l...)...):
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
143
vendor/github.com/containerd/containerd/metrics/cgroups/v2/metrics.go
generated
vendored
Normal file
143
vendor/github.com/containerd/containerd/metrics/cgroups/v2/metrics.go
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
// +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 v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/containerd/log"
|
||||
v2 "github.com/containerd/containerd/metrics/types/v2"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/runtime"
|
||||
"github.com/containerd/typeurl"
|
||||
metrics "github.com/docker/go-metrics"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// newCollector registers the collector with the provided namespace and returns it so
|
||||
// that cgroups can be added for collection
|
||||
func newCollector(ns *metrics.Namespace) *collector {
|
||||
if ns == nil {
|
||||
return &collector{}
|
||||
}
|
||||
c := &collector{
|
||||
ns: ns,
|
||||
tasks: make(map[string]runtime.Task),
|
||||
}
|
||||
c.metrics = append(c.metrics, pidMetrics...)
|
||||
c.metrics = append(c.metrics, cpuMetrics...)
|
||||
c.metrics = append(c.metrics, memoryMetrics...)
|
||||
c.storedMetrics = make(chan prometheus.Metric, 100*len(c.metrics))
|
||||
ns.Add(c)
|
||||
return c
|
||||
}
|
||||
|
||||
func taskID(id, namespace string) string {
|
||||
return fmt.Sprintf("%s-%s", id, namespace)
|
||||
}
|
||||
|
||||
// collector provides the ability to collect container stats and export
|
||||
// them in the prometheus format
|
||||
type collector struct {
|
||||
mu sync.RWMutex
|
||||
|
||||
tasks map[string]runtime.Task
|
||||
ns *metrics.Namespace
|
||||
metrics []*metric
|
||||
storedMetrics chan prometheus.Metric
|
||||
}
|
||||
|
||||
func (c *collector) Describe(ch chan<- *prometheus.Desc) {
|
||||
for _, m := range c.metrics {
|
||||
ch <- m.desc(c.ns)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *collector) Collect(ch chan<- prometheus.Metric) {
|
||||
c.mu.RLock()
|
||||
wg := &sync.WaitGroup{}
|
||||
for _, t := range c.tasks {
|
||||
wg.Add(1)
|
||||
go c.collect(t, ch, true, wg)
|
||||
}
|
||||
storedLoop:
|
||||
for {
|
||||
// read stored metrics until the channel is flushed
|
||||
select {
|
||||
case m := <-c.storedMetrics:
|
||||
ch <- m
|
||||
default:
|
||||
break storedLoop
|
||||
}
|
||||
}
|
||||
c.mu.RUnlock()
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func (c *collector) collect(t runtime.Task, ch chan<- prometheus.Metric, block bool, wg *sync.WaitGroup) {
|
||||
if wg != nil {
|
||||
defer wg.Done()
|
||||
}
|
||||
ctx := namespaces.WithNamespace(context.Background(), t.Namespace())
|
||||
stats, err := t.Stats(ctx)
|
||||
if err != nil {
|
||||
log.L.WithError(err).Errorf("stat task %s", t.ID())
|
||||
return
|
||||
}
|
||||
data, err := typeurl.UnmarshalAny(stats)
|
||||
if err != nil {
|
||||
log.L.WithError(err).Errorf("unmarshal stats for %s", t.ID())
|
||||
return
|
||||
}
|
||||
s, ok := data.(*v2.Metrics)
|
||||
if !ok {
|
||||
log.L.WithError(err).Errorf("invalid metric type for %s", t.ID())
|
||||
return
|
||||
}
|
||||
for _, m := range c.metrics {
|
||||
m.collect(t.ID(), t.Namespace(), s, c.ns, ch, block)
|
||||
}
|
||||
}
|
||||
|
||||
// Add adds the provided cgroup and id so that metrics are collected and exported
|
||||
func (c *collector) Add(t runtime.Task) error {
|
||||
if c.ns == nil {
|
||||
return nil
|
||||
}
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
id := taskID(t.ID(), t.Namespace())
|
||||
if _, ok := c.tasks[id]; ok {
|
||||
return nil // requests to collect metrics should be idempotent
|
||||
}
|
||||
c.tasks[id] = t
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove removes the provided cgroup by id from the collector
|
||||
func (c *collector) Remove(t runtime.Task) {
|
||||
if c.ns == nil {
|
||||
return
|
||||
}
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
delete(c.tasks, taskID(t.ID(), t.Namespace()))
|
||||
}
|
||||
60
vendor/github.com/containerd/containerd/metrics/cgroups/v2/pids.go
generated
vendored
Normal file
60
vendor/github.com/containerd/containerd/metrics/cgroups/v2/pids.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// +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 v2
|
||||
|
||||
import (
|
||||
v2 "github.com/containerd/containerd/metrics/types/v2"
|
||||
metrics "github.com/docker/go-metrics"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
var pidMetrics = []*metric{
|
||||
{
|
||||
name: "pids",
|
||||
help: "The limit to the number of pids allowed (cgroup v2)",
|
||||
unit: metrics.Unit("limit"),
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Pids == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Pids.Limit),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "pids",
|
||||
help: "The current number of pids (cgroup v2)",
|
||||
unit: metrics.Unit("current"),
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *v2.Metrics) []value {
|
||||
if stats.Pids == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Pids.Current),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
34
vendor/github.com/containerd/containerd/metrics/types/v2/types.go
generated
vendored
Normal file
34
vendor/github.com/containerd/containerd/metrics/types/v2/types.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
// +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 v2
|
||||
|
||||
import (
|
||||
v2 "github.com/containerd/cgroups/v2/stats"
|
||||
)
|
||||
|
||||
type (
|
||||
// Metrics alias
|
||||
Metrics = v2.Metrics
|
||||
// MemoryStat alias
|
||||
MemoryStat = v2.MemoryStat
|
||||
// CPUStat alias
|
||||
CPUStat = v2.CPUStat
|
||||
// PidsStat alias
|
||||
PidsStat = v2.PidsStat
|
||||
)
|
||||
11
vendor/github.com/containerd/containerd/oci/spec_opts.go
generated
vendored
11
vendor/github.com/containerd/containerd/oci/spec_opts.go
generated
vendored
@@ -439,7 +439,7 @@ func WithHostLocaltime(_ context.Context, _ Client, _ *containers.Container, s *
|
||||
|
||||
// WithUserNamespace sets the uid and gid mappings for the task
|
||||
// this can be called multiple times to add more mappings to the generated spec
|
||||
func WithUserNamespace(container, host, size uint32) SpecOpts {
|
||||
func WithUserNamespace(uidMap, gidMap []specs.LinuxIDMapping) SpecOpts {
|
||||
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
var hasUserns bool
|
||||
setLinux(s)
|
||||
@@ -454,13 +454,8 @@ func WithUserNamespace(container, host, size uint32) SpecOpts {
|
||||
Type: specs.UserNamespace,
|
||||
})
|
||||
}
|
||||
mapping := specs.LinuxIDMapping{
|
||||
ContainerID: container,
|
||||
HostID: host,
|
||||
Size: size,
|
||||
}
|
||||
s.Linux.UIDMappings = append(s.Linux.UIDMappings, mapping)
|
||||
s.Linux.GIDMappings = append(s.Linux.GIDMappings, mapping)
|
||||
s.Linux.UIDMappings = append(s.Linux.UIDMappings, uidMap...)
|
||||
s.Linux.GIDMappings = append(s.Linux.GIDMappings, gidMap...)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
3
vendor/github.com/containerd/containerd/pkg/process/exec.go
generated
vendored
3
vendor/github.com/containerd/containerd/pkg/process/exec.go
generated
vendored
@@ -96,7 +96,6 @@ func (e *execProcess) setExited(status int) {
|
||||
e.status = status
|
||||
e.exited = time.Now()
|
||||
e.parent.Platform.ShutdownConsole(context.Background(), e.console)
|
||||
e.pid.set(StoppedPID)
|
||||
close(e.waitBlock)
|
||||
}
|
||||
|
||||
@@ -147,7 +146,7 @@ func (e *execProcess) kill(ctx context.Context, sig uint32, _ bool) error {
|
||||
switch {
|
||||
case pid == 0:
|
||||
return errors.Wrap(errdefs.ErrFailedPrecondition, "process not created")
|
||||
case pid < 0:
|
||||
case !e.exited.IsZero():
|
||||
return errors.Wrapf(errdefs.ErrNotFound, "process already finished")
|
||||
default:
|
||||
if err := unix.Kill(pid, syscall.Signal(sig)); err != nil {
|
||||
|
||||
9
vendor/github.com/containerd/containerd/pkg/process/init.go
generated
vendored
9
vendor/github.com/containerd/containerd/pkg/process/init.go
generated
vendored
@@ -66,7 +66,7 @@ type Init struct {
|
||||
pausing *atomicBool
|
||||
status int
|
||||
exited time.Time
|
||||
pid safePid
|
||||
pid int
|
||||
closers []io.Closer
|
||||
stdin io.Closer
|
||||
stdio stdio.Stdio
|
||||
@@ -116,8 +116,6 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
|
||||
pio *processIO
|
||||
pidFile = newPidFile(p.Bundle)
|
||||
)
|
||||
p.pid.Lock()
|
||||
defer p.pid.Unlock()
|
||||
|
||||
if r.Terminal {
|
||||
if socket, err = runc.NewTempConsoleSocket(); err != nil {
|
||||
@@ -173,7 +171,7 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to retrieve OCI runtime container pid")
|
||||
}
|
||||
p.pid.pid = pid
|
||||
p.pid = pid
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -219,7 +217,7 @@ func (p *Init) ID() string {
|
||||
|
||||
// Pid of the process
|
||||
func (p *Init) Pid() int {
|
||||
return p.pid.get()
|
||||
return p.pid
|
||||
}
|
||||
|
||||
// ExitStatus of the process
|
||||
@@ -275,7 +273,6 @@ func (p *Init) setExited(status int) {
|
||||
p.exited = time.Now()
|
||||
p.status = status
|
||||
p.Platform.ShutdownConsole(context.Background(), p.console)
|
||||
p.pid.set(StoppedPID)
|
||||
close(p.waitBlock)
|
||||
}
|
||||
|
||||
|
||||
5
vendor/github.com/containerd/containerd/pkg/process/init_state.go
generated
vendored
5
vendor/github.com/containerd/containerd/pkg/process/init_state.go
generated
vendored
@@ -147,9 +147,6 @@ func (s *createdCheckpointState) Start(ctx context.Context) error {
|
||||
p := s.p
|
||||
sio := p.stdio
|
||||
|
||||
p.pid.Lock()
|
||||
defer p.pid.Unlock()
|
||||
|
||||
var (
|
||||
err error
|
||||
socket *runc.Socket
|
||||
@@ -189,7 +186,7 @@ func (s *createdCheckpointState) Start(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to retrieve OCI runtime container pid")
|
||||
}
|
||||
p.pid.pid = pid
|
||||
p.pid = pid
|
||||
return s.transition("running")
|
||||
}
|
||||
|
||||
|
||||
8
vendor/github.com/containerd/containerd/pkg/process/utils.go
generated
vendored
8
vendor/github.com/containerd/containerd/pkg/process/utils.go
generated
vendored
@@ -39,8 +39,6 @@ import (
|
||||
const (
|
||||
// RuncRoot is the path to the root runc state directory
|
||||
RuncRoot = "/run/containerd/runc"
|
||||
// StoppedPID is the pid assigned after a container has run and stopped
|
||||
StoppedPID = -1
|
||||
// InitPidFile name of the file that contains the init pid
|
||||
InitPidFile = "init.pid"
|
||||
)
|
||||
@@ -57,12 +55,6 @@ func (s *safePid) get() int {
|
||||
return s.pid
|
||||
}
|
||||
|
||||
func (s *safePid) set(pid int) {
|
||||
s.Lock()
|
||||
s.pid = pid
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
type atomicBool int32
|
||||
|
||||
func (ab *atomicBool) set(b bool) {
|
||||
|
||||
12
vendor/github.com/containerd/containerd/platforms/cpuinfo.go
generated
vendored
12
vendor/github.com/containerd/containerd/platforms/cpuinfo.go
generated
vendored
@@ -96,16 +96,16 @@ func getCPUVariant() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
switch variant {
|
||||
case "8", "AArch64":
|
||||
switch strings.ToLower(variant) {
|
||||
case "8", "aarch64":
|
||||
variant = "v8"
|
||||
case "7", "7M", "?(12)", "?(13)", "?(14)", "?(15)", "?(16)", "?(17)":
|
||||
case "7", "7m", "?(12)", "?(13)", "?(14)", "?(15)", "?(16)", "?(17)":
|
||||
variant = "v7"
|
||||
case "6", "6TEJ":
|
||||
case "6", "6tej":
|
||||
variant = "v6"
|
||||
case "5", "5T", "5TE", "5TEJ":
|
||||
case "5", "5t", "5te", "5tej":
|
||||
variant = "v5"
|
||||
case "4", "4T":
|
||||
case "4", "4t":
|
||||
variant = "v4"
|
||||
case "3":
|
||||
variant = "v3"
|
||||
|
||||
7
vendor/github.com/containerd/containerd/pull.go
generated
vendored
7
vendor/github.com/containerd/containerd/pull.go
generated
vendored
@@ -70,11 +70,6 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima
|
||||
}
|
||||
unpackWrapper, eg := u.handlerWrapper(ctx, &unpacks)
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
// Forcibly stop the unpacker if there is
|
||||
// an error.
|
||||
eg.Cancel()
|
||||
}
|
||||
if err := eg.Wait(); err != nil {
|
||||
if retErr == nil {
|
||||
retErr = errors.Wrap(err, "unpack")
|
||||
@@ -86,7 +81,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima
|
||||
if wrapper == nil {
|
||||
return unpackWrapper(h)
|
||||
}
|
||||
return wrapper(unpackWrapper(h))
|
||||
return unpackWrapper(wrapper(h))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
14
vendor/github.com/containerd/containerd/remotes/docker/authorizer.go
generated
vendored
14
vendor/github.com/containerd/containerd/remotes/docker/authorizer.go
generated
vendored
@@ -196,10 +196,11 @@ func (a *dockerAuthorizer) generateTokenOptions(ctx context.Context, host string
|
||||
}
|
||||
|
||||
scope, ok := c.parameters["scope"]
|
||||
if !ok {
|
||||
return tokenOptions{}, errors.Errorf("no scope specified for token auth challenge")
|
||||
if ok {
|
||||
to.scopes = append(to.scopes, scope)
|
||||
} else {
|
||||
log.G(ctx).WithField("host", host).Debug("no scope specified for token auth challenge")
|
||||
}
|
||||
to.scopes = append(to.scopes, scope)
|
||||
|
||||
if a.credentials != nil {
|
||||
to.username, to.secret, err = a.credentials(host)
|
||||
@@ -273,9 +274,6 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (string, error) {
|
||||
to := ah.common
|
||||
|
||||
to.scopes = getTokenScopes(ctx, to.scopes)
|
||||
if len(to.scopes) == 0 {
|
||||
return "", errors.Errorf("no scope specified for token auth challenge")
|
||||
}
|
||||
|
||||
// Docs: https://docs.docker.com/registry/spec/auth/scope
|
||||
scoped := strings.Join(to.scopes, " ")
|
||||
@@ -332,7 +330,9 @@ type postTokenResponse struct {
|
||||
|
||||
func (ah *authHandler) fetchTokenWithOAuth(ctx context.Context, to tokenOptions) (string, error) {
|
||||
form := url.Values{}
|
||||
form.Set("scope", strings.Join(to.scopes, " "))
|
||||
if len(to.scopes) > 0 {
|
||||
form.Set("scope", strings.Join(to.scopes, " "))
|
||||
}
|
||||
form.Set("service", to.service)
|
||||
// TODO: Allow setting client_id
|
||||
form.Set("client_id", "containerd-client")
|
||||
|
||||
30
vendor/github.com/containerd/containerd/remotes/docker/fetcher.go
generated
vendored
30
vendor/github.com/containerd/containerd/remotes/docker/fetcher.go
generated
vendored
@@ -95,41 +95,49 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R
|
||||
images.MediaTypeDockerSchema1Manifest,
|
||||
ocispec.MediaTypeImageManifest, ocispec.MediaTypeImageIndex:
|
||||
|
||||
var firstErr error
|
||||
for _, host := range r.hosts {
|
||||
req := r.request(host, http.MethodGet, "manifests", desc.Digest.String())
|
||||
|
||||
rc, err := r.open(ctx, req, desc.MediaType, offset)
|
||||
if err != nil {
|
||||
if errdefs.IsNotFound(err) {
|
||||
continue // try another host
|
||||
// Store the error for referencing later
|
||||
if firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
|
||||
return nil, err
|
||||
continue // try another host
|
||||
}
|
||||
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
return nil, firstErr
|
||||
}
|
||||
|
||||
// Finally use blobs endpoints
|
||||
var firstErr error
|
||||
for _, host := range r.hosts {
|
||||
req := r.request(host, http.MethodGet, "blobs", desc.Digest.String())
|
||||
|
||||
rc, err := r.open(ctx, req, desc.MediaType, offset)
|
||||
if err != nil {
|
||||
if errdefs.IsNotFound(err) {
|
||||
continue // try another host
|
||||
// Store the error for referencing later
|
||||
if firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
|
||||
return nil, err
|
||||
continue // try another host
|
||||
}
|
||||
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
return nil, errors.Wrapf(errdefs.ErrNotFound,
|
||||
"could not fetch content descriptor %v (%v) from remote",
|
||||
desc.Digest, desc.MediaType)
|
||||
if errdefs.IsNotFound(firstErr) {
|
||||
firstErr = errors.Wrapf(errdefs.ErrNotFound,
|
||||
"could not fetch content descriptor %v (%v) from remote",
|
||||
desc.Digest, desc.MediaType)
|
||||
}
|
||||
|
||||
return nil, firstErr
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
6
vendor/github.com/containerd/containerd/remotes/docker/resolver.go
generated
vendored
6
vendor/github.com/containerd/containerd/remotes/docker/resolver.go
generated
vendored
@@ -286,7 +286,11 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
|
||||
if errors.Cause(err) == ErrInvalidAuthorization {
|
||||
err = errors.Wrapf(err, "pull access denied, repository does not exist or may require authorization")
|
||||
}
|
||||
return "", ocispec.Descriptor{}, err
|
||||
// Store the error for referencing later
|
||||
if lastErr == nil {
|
||||
lastErr = err
|
||||
}
|
||||
continue // try another host
|
||||
}
|
||||
resp.Body.Close() // don't care about body contents.
|
||||
|
||||
|
||||
2
vendor/github.com/containerd/containerd/runtime/v2/binary.go
generated
vendored
2
vendor/github.com/containerd/containerd/runtime/v2/binary.go
generated
vendored
@@ -74,7 +74,7 @@ func (b *binary) Start(ctx context.Context, opts *types.Any, onClose func()) (_
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f, err := openShimLog(ctx, b.bundle, client.AnonDialer)
|
||||
f, err := openShimLog(context.Background(), b.bundle, client.AnonDialer)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "open shim log pipe")
|
||||
}
|
||||
|
||||
10
vendor/github.com/containerd/containerd/runtime/v2/manager.go
generated
vendored
10
vendor/github.com/containerd/containerd/runtime/v2/manager.go
generated
vendored
@@ -29,6 +29,7 @@ import (
|
||||
"github.com/containerd/containerd/metadata"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/pkg/timeout"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/containerd/containerd/runtime"
|
||||
@@ -154,8 +155,13 @@ func (m *TaskManager) Create(ctx context.Context, id string, opts runtime.Create
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
shim.Shutdown(ctx)
|
||||
shim.Close()
|
||||
dctx, cancel := timeout.WithContext(context.Background(), cleanupTimeout)
|
||||
defer cancel()
|
||||
_, errShim := shim.Delete(dctx)
|
||||
if errShim != nil {
|
||||
shim.Shutdown(ctx)
|
||||
shim.Close()
|
||||
}
|
||||
}
|
||||
}()
|
||||
t, err := shim.Create(ctx, opts)
|
||||
|
||||
4
vendor/github.com/containerd/containerd/runtime/v2/shim.go
generated
vendored
4
vendor/github.com/containerd/containerd/runtime/v2/shim.go
generated
vendored
@@ -235,11 +235,11 @@ func (s *shim) Delete(ctx context.Context) (*runtime.Exit, error) {
|
||||
// this seems dirty but it cleans up the API across runtimes, tasks, and the service
|
||||
s.rtTasks.Delete(ctx, s.ID())
|
||||
if err := s.waitShutdown(ctx); err != nil {
|
||||
log.G(ctx).WithError(err).Error("failed to shutdown shim")
|
||||
log.G(ctx).WithField("id", s.ID()).WithError(err).Error("failed to shutdown shim")
|
||||
}
|
||||
s.Close()
|
||||
if err := s.bundle.Delete(); err != nil {
|
||||
log.G(ctx).WithError(err).Error("failed to delete bundle")
|
||||
log.G(ctx).WithField("id", s.ID()).WithError(err).Error("failed to delete bundle")
|
||||
}
|
||||
if shimErr != nil {
|
||||
return nil, shimErr
|
||||
|
||||
28
vendor/github.com/containerd/containerd/services.go
generated
vendored
28
vendor/github.com/containerd/containerd/services.go
generated
vendored
@@ -20,6 +20,7 @@ import (
|
||||
containersapi "github.com/containerd/containerd/api/services/containers/v1"
|
||||
"github.com/containerd/containerd/api/services/diff/v1"
|
||||
imagesapi "github.com/containerd/containerd/api/services/images/v1"
|
||||
introspectionapi "github.com/containerd/containerd/api/services/introspection/v1"
|
||||
namespacesapi "github.com/containerd/containerd/api/services/namespaces/v1"
|
||||
"github.com/containerd/containerd/api/services/tasks/v1"
|
||||
"github.com/containerd/containerd/containers"
|
||||
@@ -27,19 +28,21 @@ import (
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/leases"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/services/introspection"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
)
|
||||
|
||||
type services struct {
|
||||
contentStore content.Store
|
||||
imageStore images.Store
|
||||
containerStore containers.Store
|
||||
namespaceStore namespaces.Store
|
||||
snapshotters map[string]snapshots.Snapshotter
|
||||
taskService tasks.TasksClient
|
||||
diffService DiffService
|
||||
eventService EventService
|
||||
leasesService leases.Manager
|
||||
contentStore content.Store
|
||||
imageStore images.Store
|
||||
containerStore containers.Store
|
||||
namespaceStore namespaces.Store
|
||||
snapshotters map[string]snapshots.Snapshotter
|
||||
taskService tasks.TasksClient
|
||||
diffService DiffService
|
||||
eventService EventService
|
||||
leasesService leases.Manager
|
||||
introspectionService introspection.Service
|
||||
}
|
||||
|
||||
// ServicesOpt allows callers to set options on the services
|
||||
@@ -110,3 +113,10 @@ func WithLeasesService(leasesService leases.Manager) ServicesOpt {
|
||||
s.leasesService = leasesService
|
||||
}
|
||||
}
|
||||
|
||||
// WithIntrospectionService sets the introspection service.
|
||||
func WithIntrospectionService(in introspectionapi.IntrospectionClient) ServicesOpt {
|
||||
return func(s *services) {
|
||||
s.introspectionService = introspection.NewIntrospectionServiceFromClient(in)
|
||||
}
|
||||
}
|
||||
|
||||
62
vendor/github.com/containerd/containerd/services/introspection/introspection.go
generated
vendored
Normal file
62
vendor/github.com/containerd/containerd/services/introspection/introspection.go
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
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 introspection
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
api "github.com/containerd/containerd/api/services/introspection/v1"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
ptypes "github.com/gogo/protobuf/types"
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
Plugins(context.Context, []string) (*api.PluginsResponse, error)
|
||||
Server(context.Context, *ptypes.Empty) (*api.ServerResponse, error)
|
||||
}
|
||||
|
||||
type introspectionRemote struct {
|
||||
client api.IntrospectionClient
|
||||
}
|
||||
|
||||
var _ = (Service)(&introspectionRemote{})
|
||||
|
||||
func NewIntrospectionServiceFromClient(c api.IntrospectionClient) Service {
|
||||
return &introspectionRemote{client: c}
|
||||
}
|
||||
|
||||
func (i *introspectionRemote) Plugins(ctx context.Context, filters []string) (*api.PluginsResponse, error) {
|
||||
resp, err := i.client.Plugins(ctx, &api.PluginsRequest{
|
||||
Filters: filters,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, errdefs.FromGRPC(err)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (i *introspectionRemote) Server(ctx context.Context, in *ptypes.Empty) (*api.ServerResponse, error) {
|
||||
resp, err := i.client.Server(ctx, in)
|
||||
|
||||
if err != nil {
|
||||
return nil, errdefs.FromGRPC(err)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
227
vendor/github.com/containerd/containerd/services/introspection/local.go
generated
vendored
Normal file
227
vendor/github.com/containerd/containerd/services/introspection/local.go
generated
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
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 introspection
|
||||
|
||||
import (
|
||||
context "context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
api "github.com/containerd/containerd/api/services/introspection/v1"
|
||||
"github.com/containerd/containerd/api/types"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/filters"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/containerd/containerd/services"
|
||||
"github.com/gogo/googleapis/google/rpc"
|
||||
ptypes "github.com/gogo/protobuf/types"
|
||||
"github.com/google/uuid"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func init() {
|
||||
plugin.Register(&plugin.Registration{
|
||||
Type: plugin.ServicePlugin,
|
||||
ID: services.IntrospectionService,
|
||||
Requires: []plugin.Type{},
|
||||
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
|
||||
// this service works by using the plugin context up till the point
|
||||
// this service is initialized. Since we require this service last,
|
||||
// it should provide the full set of plugins.
|
||||
pluginsPB := pluginsToPB(ic.GetAll())
|
||||
return &Local{
|
||||
plugins: pluginsPB,
|
||||
root: ic.Root,
|
||||
}, nil
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
type Local struct {
|
||||
mu sync.Mutex
|
||||
plugins []api.Plugin
|
||||
root string
|
||||
}
|
||||
|
||||
var _ = (api.IntrospectionClient)(&Local{})
|
||||
|
||||
func (l *Local) UpdateLocal(root string, plugins []api.Plugin) {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
l.root = root
|
||||
l.plugins = plugins
|
||||
}
|
||||
|
||||
func (l *Local) Plugins(ctx context.Context, req *api.PluginsRequest, _ ...grpc.CallOption) (*api.PluginsResponse, error) {
|
||||
filter, err := filters.ParseAll(req.Filters...)
|
||||
if err != nil {
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
var plugins []api.Plugin
|
||||
allPlugins := l.getPlugins()
|
||||
for _, p := range allPlugins {
|
||||
if !filter.Match(adaptPlugin(p)) {
|
||||
continue
|
||||
}
|
||||
|
||||
plugins = append(plugins, p)
|
||||
}
|
||||
|
||||
return &api.PluginsResponse{
|
||||
Plugins: plugins,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (l *Local) getPlugins() []api.Plugin {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
return l.plugins
|
||||
}
|
||||
|
||||
func (l *Local) Server(ctx context.Context, _ *ptypes.Empty, _ ...grpc.CallOption) (*api.ServerResponse, error) {
|
||||
u, err := l.getUUID()
|
||||
if err != nil {
|
||||
return nil, errdefs.ToGRPC(err)
|
||||
}
|
||||
return &api.ServerResponse{
|
||||
UUID: u,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (l *Local) getUUID() (string, error) {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
|
||||
data, err := ioutil.ReadFile(l.uuidPath())
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return l.generateUUID()
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
u := string(data)
|
||||
if _, err := uuid.Parse(u); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (l *Local) generateUUID() (string, error) {
|
||||
u, err := uuid.NewRandom()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
path := l.uuidPath()
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
|
||||
return "", err
|
||||
}
|
||||
uu := u.String()
|
||||
if err := ioutil.WriteFile(path, []byte(uu), 0666); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return uu, nil
|
||||
}
|
||||
|
||||
func (l *Local) uuidPath() string {
|
||||
return filepath.Join(l.root, "uuid")
|
||||
}
|
||||
|
||||
func adaptPlugin(o interface{}) filters.Adaptor {
|
||||
obj := o.(api.Plugin)
|
||||
return filters.AdapterFunc(func(fieldpath []string) (string, bool) {
|
||||
if len(fieldpath) == 0 {
|
||||
return "", false
|
||||
}
|
||||
|
||||
switch fieldpath[0] {
|
||||
case "type":
|
||||
return obj.Type, len(obj.Type) > 0
|
||||
case "id":
|
||||
return obj.ID, len(obj.ID) > 0
|
||||
case "platforms":
|
||||
// TODO(stevvooe): Another case here where have multiple values.
|
||||
// May need to refactor the filter system to allow filtering by
|
||||
// platform, if this is required.
|
||||
case "capabilities":
|
||||
// TODO(stevvooe): Need a better way to match against
|
||||
// collections. We can only return "the value" but really it
|
||||
// would be best if we could return a set of values for the
|
||||
// path, any of which could match.
|
||||
}
|
||||
|
||||
return "", false
|
||||
})
|
||||
}
|
||||
|
||||
func pluginsToPB(plugins []*plugin.Plugin) []api.Plugin {
|
||||
var pluginsPB []api.Plugin
|
||||
for _, p := range plugins {
|
||||
var platforms []types.Platform
|
||||
for _, p := range p.Meta.Platforms {
|
||||
platforms = append(platforms, types.Platform{
|
||||
OS: p.OS,
|
||||
Architecture: p.Architecture,
|
||||
Variant: p.Variant,
|
||||
})
|
||||
}
|
||||
|
||||
var requires []string
|
||||
for _, r := range p.Registration.Requires {
|
||||
requires = append(requires, r.String())
|
||||
}
|
||||
|
||||
var initErr *rpc.Status
|
||||
if err := p.Err(); err != nil {
|
||||
st, ok := status.FromError(errdefs.ToGRPC(err))
|
||||
if ok {
|
||||
var details []*ptypes.Any
|
||||
for _, d := range st.Proto().Details {
|
||||
details = append(details, &ptypes.Any{
|
||||
TypeUrl: d.TypeUrl,
|
||||
Value: d.Value,
|
||||
})
|
||||
}
|
||||
initErr = &rpc.Status{
|
||||
Code: int32(st.Code()),
|
||||
Message: st.Message(),
|
||||
Details: details,
|
||||
}
|
||||
} else {
|
||||
initErr = &rpc.Status{
|
||||
Code: int32(rpc.UNKNOWN),
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pluginsPB = append(pluginsPB, api.Plugin{
|
||||
Type: p.Registration.Type.String(),
|
||||
ID: p.Registration.ID,
|
||||
Requires: requires,
|
||||
Platforms: platforms,
|
||||
Capabilities: p.Meta.Capabilities,
|
||||
Exports: p.Meta.Exports,
|
||||
InitErr: initErr,
|
||||
})
|
||||
}
|
||||
|
||||
return pluginsPB
|
||||
}
|
||||
205
vendor/github.com/containerd/containerd/services/introspection/service.go
generated
vendored
205
vendor/github.com/containerd/containerd/services/introspection/service.go
generated
vendored
@@ -18,21 +18,13 @@ package introspection
|
||||
|
||||
import (
|
||||
context "context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
api "github.com/containerd/containerd/api/services/introspection/v1"
|
||||
"github.com/containerd/containerd/api/types"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/filters"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/gogo/googleapis/google/rpc"
|
||||
"github.com/containerd/containerd/services"
|
||||
ptypes "github.com/gogo/protobuf/types"
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -44,177 +36,50 @@ func init() {
|
||||
// this service works by using the plugin context up till the point
|
||||
// this service is initialized. Since we require this service last,
|
||||
// it should provide the full set of plugins.
|
||||
pluginsPB := pluginsToPB(ic.GetAll())
|
||||
return NewService(pluginsPB, ic.Root), nil
|
||||
plugins, err := ic.GetByType(plugin.ServicePlugin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p, ok := plugins[services.IntrospectionService]
|
||||
if !ok {
|
||||
return nil, errors.New("introspection service not found")
|
||||
}
|
||||
|
||||
i, err := p.Instance()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
allPluginsPB := pluginsToPB(ic.GetAll())
|
||||
|
||||
localClient, ok := i.(*Local)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("Could not create a local client for introspection service")
|
||||
}
|
||||
localClient.UpdateLocal(ic.Root, allPluginsPB)
|
||||
|
||||
return &server{
|
||||
local: localClient,
|
||||
}, nil
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
type service struct {
|
||||
mu sync.Mutex
|
||||
plugins []api.Plugin
|
||||
root string
|
||||
type server struct {
|
||||
local api.IntrospectionClient
|
||||
}
|
||||
|
||||
// NewService returns the GRPC introspection server
|
||||
func NewService(plugins []api.Plugin, root string) api.IntrospectionServer {
|
||||
return &service{
|
||||
plugins: plugins,
|
||||
root: root,
|
||||
}
|
||||
}
|
||||
var _ = (api.IntrospectionServer)(&server{})
|
||||
|
||||
func (s *service) Register(server *grpc.Server) error {
|
||||
func (s *server) Register(server *grpc.Server) error {
|
||||
api.RegisterIntrospectionServer(server, s)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *service) Plugins(ctx context.Context, req *api.PluginsRequest) (*api.PluginsResponse, error) {
|
||||
filter, err := filters.ParseAll(req.Filters...)
|
||||
if err != nil {
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
var plugins []api.Plugin
|
||||
for _, p := range s.plugins {
|
||||
if !filter.Match(adaptPlugin(p)) {
|
||||
continue
|
||||
}
|
||||
|
||||
plugins = append(plugins, p)
|
||||
}
|
||||
|
||||
return &api.PluginsResponse{
|
||||
Plugins: plugins,
|
||||
}, nil
|
||||
func (s *server) Plugins(ctx context.Context, req *api.PluginsRequest) (*api.PluginsResponse, error) {
|
||||
return s.local.Plugins(ctx, req)
|
||||
}
|
||||
|
||||
func (s *service) Server(ctx context.Context, _ *ptypes.Empty) (*api.ServerResponse, error) {
|
||||
u, err := s.getUUID()
|
||||
if err != nil {
|
||||
return nil, errdefs.ToGRPC(err)
|
||||
}
|
||||
return &api.ServerResponse{
|
||||
UUID: u,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *service) getUUID() (string, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
data, err := ioutil.ReadFile(s.uuidPath())
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return s.generateUUID()
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
u := string(data)
|
||||
if _, err := uuid.Parse(u); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (s *service) generateUUID() (string, error) {
|
||||
u, err := uuid.NewRandom()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
path := s.uuidPath()
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
|
||||
return "", err
|
||||
}
|
||||
uu := u.String()
|
||||
if err := ioutil.WriteFile(path, []byte(uu), 0666); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return uu, nil
|
||||
}
|
||||
|
||||
func (s *service) uuidPath() string {
|
||||
return filepath.Join(s.root, "uuid")
|
||||
}
|
||||
|
||||
func adaptPlugin(o interface{}) filters.Adaptor {
|
||||
obj := o.(api.Plugin)
|
||||
return filters.AdapterFunc(func(fieldpath []string) (string, bool) {
|
||||
if len(fieldpath) == 0 {
|
||||
return "", false
|
||||
}
|
||||
|
||||
switch fieldpath[0] {
|
||||
case "type":
|
||||
return obj.Type, len(obj.Type) > 0
|
||||
case "id":
|
||||
return obj.ID, len(obj.ID) > 0
|
||||
case "platforms":
|
||||
// TODO(stevvooe): Another case here where have multiple values.
|
||||
// May need to refactor the filter system to allow filtering by
|
||||
// platform, if this is required.
|
||||
case "capabilities":
|
||||
// TODO(stevvooe): Need a better way to match against
|
||||
// collections. We can only return "the value" but really it
|
||||
// would be best if we could return a set of values for the
|
||||
// path, any of which could match.
|
||||
}
|
||||
|
||||
return "", false
|
||||
})
|
||||
}
|
||||
|
||||
func pluginsToPB(plugins []*plugin.Plugin) []api.Plugin {
|
||||
var pluginsPB []api.Plugin
|
||||
for _, p := range plugins {
|
||||
var platforms []types.Platform
|
||||
for _, p := range p.Meta.Platforms {
|
||||
platforms = append(platforms, types.Platform{
|
||||
OS: p.OS,
|
||||
Architecture: p.Architecture,
|
||||
Variant: p.Variant,
|
||||
})
|
||||
}
|
||||
|
||||
var requires []string
|
||||
for _, r := range p.Registration.Requires {
|
||||
requires = append(requires, r.String())
|
||||
}
|
||||
|
||||
var initErr *rpc.Status
|
||||
if err := p.Err(); err != nil {
|
||||
st, ok := status.FromError(errdefs.ToGRPC(err))
|
||||
if ok {
|
||||
var details []*ptypes.Any
|
||||
for _, d := range st.Proto().Details {
|
||||
details = append(details, &ptypes.Any{
|
||||
TypeUrl: d.TypeUrl,
|
||||
Value: d.Value,
|
||||
})
|
||||
}
|
||||
initErr = &rpc.Status{
|
||||
Code: int32(st.Code()),
|
||||
Message: st.Message(),
|
||||
Details: details,
|
||||
}
|
||||
} else {
|
||||
initErr = &rpc.Status{
|
||||
Code: int32(rpc.UNKNOWN),
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pluginsPB = append(pluginsPB, api.Plugin{
|
||||
Type: p.Registration.Type.String(),
|
||||
ID: p.Registration.ID,
|
||||
Requires: requires,
|
||||
Platforms: platforms,
|
||||
Capabilities: p.Meta.Capabilities,
|
||||
Exports: p.Meta.Exports,
|
||||
InitErr: initErr,
|
||||
})
|
||||
}
|
||||
|
||||
return pluginsPB
|
||||
func (s *server) Server(ctx context.Context, empty *ptypes.Empty) (*api.ServerResponse, error) {
|
||||
return s.local.Server(ctx, empty)
|
||||
}
|
||||
|
||||
34
vendor/github.com/containerd/containerd/services/server/server_linux.go
generated
vendored
34
vendor/github.com/containerd/containerd/services/server/server_linux.go
generated
vendored
@@ -21,6 +21,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v2"
|
||||
"github.com/containerd/containerd/log"
|
||||
srvconfig "github.com/containerd/containerd/services/server/config"
|
||||
"github.com/containerd/containerd/sys"
|
||||
@@ -37,20 +38,35 @@ func apply(ctx context.Context, config *srvconfig.Config) error {
|
||||
}
|
||||
}
|
||||
if config.Cgroup.Path != "" {
|
||||
cg, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(config.Cgroup.Path))
|
||||
if err != nil {
|
||||
if err != cgroups.ErrCgroupDeleted {
|
||||
if cgroups.Mode() == cgroups.Unified {
|
||||
cg, err := cgroupsv2.LoadManager("/sys/fs/cgroup", config.Cgroup.Path)
|
||||
if err != nil {
|
||||
if err != cgroupsv2.ErrCgroupDeleted {
|
||||
return err
|
||||
}
|
||||
if cg, err = cgroupsv2.NewManager("/sys/fs/cgroup", config.Cgroup.Path, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := cg.AddProc(uint64(os.Getpid())); err != nil {
|
||||
return err
|
||||
}
|
||||
if cg, err = cgroups.New(cgroups.V1, cgroups.StaticPath(config.Cgroup.Path), &specs.LinuxResources{}); err != nil {
|
||||
} else {
|
||||
cg, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(config.Cgroup.Path))
|
||||
if err != nil {
|
||||
if err != cgroups.ErrCgroupDeleted {
|
||||
return err
|
||||
}
|
||||
if cg, err = cgroups.New(cgroups.V1, cgroups.StaticPath(config.Cgroup.Path), &specs.LinuxResources{}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := cg.Add(cgroups.Process{
|
||||
Pid: os.Getpid(),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := cg.Add(cgroups.Process{
|
||||
Pid: os.Getpid(),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/containerd/containerd/services/services.go
generated
vendored
2
vendor/github.com/containerd/containerd/services/services.go
generated
vendored
@@ -33,4 +33,6 @@ const (
|
||||
LeasesService = "leases-service"
|
||||
// DiffService is id of diff service.
|
||||
DiffService = "diff-service"
|
||||
// IntrospectionService is the id of introspection service
|
||||
IntrospectionService = "introspection-service"
|
||||
)
|
||||
|
||||
22
vendor/github.com/containerd/containerd/snapshots/snapshotter.go
generated
vendored
22
vendor/github.com/containerd/containerd/snapshots/snapshotter.go
generated
vendored
@@ -25,6 +25,11 @@ import (
|
||||
"github.com/containerd/containerd/mount"
|
||||
)
|
||||
|
||||
const (
|
||||
inheritedLabelsPrefix = "containerd.io/snapshot/"
|
||||
labelSnapshotRef = "containerd.io/snapshot.ref"
|
||||
)
|
||||
|
||||
// Kind identifies the kind of snapshot.
|
||||
type Kind uint8
|
||||
|
||||
@@ -346,3 +351,20 @@ func WithLabels(labels map[string]string) Opt {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// FilterInheritedLabels filters the provided labels by removing any key which
|
||||
// isn't a snapshot label. Snapshot labels have a prefix of "containerd.io/snapshot/"
|
||||
// or are the "containerd.io/snapshot.ref" label.
|
||||
func FilterInheritedLabels(labels map[string]string) map[string]string {
|
||||
if labels == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
filtered := make(map[string]string)
|
||||
for k, v := range labels {
|
||||
if k == labelSnapshotRef || strings.HasPrefix(k, inheritedLabelsPrefix) {
|
||||
filtered[k] = v
|
||||
}
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
4
vendor/github.com/containerd/containerd/snapshots/storage/bolt.go
generated
vendored
4
vendor/github.com/containerd/containerd/snapshots/storage/bolt.go
generated
vendored
@@ -633,9 +633,7 @@ func adaptSnapshot(info snapshots.Info) filters.Adaptor {
|
||||
case "name":
|
||||
return info.Name, true
|
||||
case "parent":
|
||||
if info.Parent != "" {
|
||||
return info.Parent, true
|
||||
}
|
||||
return info.Parent, true
|
||||
case "labels":
|
||||
if len(info.Labels) == 0 {
|
||||
return "", false
|
||||
|
||||
4
vendor/github.com/containerd/containerd/sys/socket_unix.go
generated
vendored
4
vendor/github.com/containerd/containerd/sys/socket_unix.go
generated
vendored
@@ -68,11 +68,11 @@ func GetLocalListener(path string, uid, gid int) (net.Listener, error) {
|
||||
}
|
||||
|
||||
func mkdirAs(path string, uid, gid int) error {
|
||||
if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) {
|
||||
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.Mkdir(path, 0770); err != nil {
|
||||
if err := os.MkdirAll(path, 0770); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/containerd/containerd/task.go
generated
vendored
2
vendor/github.com/containerd/containerd/task.go
generated
vendored
@@ -159,7 +159,7 @@ type Task interface {
|
||||
// Pids returns a list of system specific process ids inside the task
|
||||
Pids(context.Context) ([]ProcessInfo, error)
|
||||
// Checkpoint serializes the runtime and memory information of a task into an
|
||||
// OCI Index that can be push and pulled from a remote resource.
|
||||
// OCI Index that can be pushed and pulled from a remote resource.
|
||||
//
|
||||
// Additional software like CRIU maybe required to checkpoint and restore tasks
|
||||
// NOTE: Checkpoint supports to dump task information to a directory, in this way,
|
||||
|
||||
52
vendor/github.com/containerd/containerd/task_opts_unix.go
generated
vendored
52
vendor/github.com/containerd/containerd/task_opts_unix.go
generated
vendored
@@ -103,3 +103,55 @@ func WithShimCgroup(path string) NewTaskOpts {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithUIDOwner allows console I/O to work with the remapped UID in user namespace
|
||||
func WithUIDOwner(uid uint32) NewTaskOpts {
|
||||
return func(ctx context.Context, c *Client, ti *TaskInfo) error {
|
||||
if CheckRuntime(ti.Runtime(), "io.containerd.runc") {
|
||||
if ti.Options == nil {
|
||||
ti.Options = &options.Options{}
|
||||
}
|
||||
opts, ok := ti.Options.(*options.Options)
|
||||
if !ok {
|
||||
return errors.New("invalid v2 shim create options format")
|
||||
}
|
||||
opts.IoUid = uid
|
||||
} else {
|
||||
if ti.Options == nil {
|
||||
ti.Options = &runctypes.CreateOptions{}
|
||||
}
|
||||
opts, ok := ti.Options.(*runctypes.CreateOptions)
|
||||
if !ok {
|
||||
return errors.New("could not cast TaskInfo Options to CreateOptions")
|
||||
}
|
||||
opts.IoUid = uid
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithGIDOwner allows console I/O to work with the remapped GID in user namespace
|
||||
func WithGIDOwner(gid uint32) NewTaskOpts {
|
||||
return func(ctx context.Context, c *Client, ti *TaskInfo) error {
|
||||
if CheckRuntime(ti.Runtime(), "io.containerd.runc") {
|
||||
if ti.Options == nil {
|
||||
ti.Options = &options.Options{}
|
||||
}
|
||||
opts, ok := ti.Options.(*options.Options)
|
||||
if !ok {
|
||||
return errors.New("invalid v2 shim create options format")
|
||||
}
|
||||
opts.IoGid = gid
|
||||
} else {
|
||||
if ti.Options == nil {
|
||||
ti.Options = &runctypes.CreateOptions{}
|
||||
}
|
||||
opts, ok := ti.Options.(*runctypes.CreateOptions)
|
||||
if !ok {
|
||||
return errors.New("could not cast TaskInfo Options to CreateOptions")
|
||||
}
|
||||
opts.IoGid = gid
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
318
vendor/github.com/containerd/containerd/unpacker.go
generated
vendored
318
vendor/github.com/containerd/containerd/unpacker.go
generated
vendored
@@ -18,34 +18,39 @@ package containerd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/rootfs"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/image-spec/identity"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"golang.org/x/sync/semaphore"
|
||||
)
|
||||
|
||||
type layerState struct {
|
||||
layer rootfs.Layer
|
||||
downloaded bool
|
||||
unpacked bool
|
||||
}
|
||||
const (
|
||||
labelSnapshotRef = "containerd.io/snapshot.ref"
|
||||
)
|
||||
|
||||
type unpacker struct {
|
||||
updateCh chan ocispec.Descriptor
|
||||
snapshotter string
|
||||
config UnpackConfig
|
||||
c *Client
|
||||
limiter *semaphore.Weighted
|
||||
}
|
||||
|
||||
func (c *Client) newUnpacker(ctx context.Context, rCtx *RemoteContext) (*unpacker, error) {
|
||||
@@ -67,7 +72,7 @@ func (c *Client) newUnpacker(ctx context.Context, rCtx *RemoteContext) (*unpacke
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (u *unpacker) unpack(ctx context.Context, config ocispec.Descriptor, layers []ocispec.Descriptor) error {
|
||||
func (u *unpacker) unpack(ctx context.Context, h images.Handler, config ocispec.Descriptor, layers []ocispec.Descriptor) error {
|
||||
p, err := content.ReadBlob(ctx, u.c.ContentStore(), config)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -87,85 +92,135 @@ func (u *unpacker) unpack(ctx context.Context, config ocispec.Descriptor, layers
|
||||
a = u.c.DiffService()
|
||||
cs = u.c.ContentStore()
|
||||
|
||||
states []layerState
|
||||
chain []digest.Digest
|
||||
chain []digest.Digest
|
||||
|
||||
fetchOffset int
|
||||
fetchC []chan struct{}
|
||||
fetchErr chan error
|
||||
)
|
||||
|
||||
// If there is an early return, ensure any ongoing
|
||||
// fetches get their context cancelled
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
EachLayer:
|
||||
for i, desc := range layers {
|
||||
states = append(states, layerState{
|
||||
layer: rootfs.Layer{
|
||||
Blob: desc,
|
||||
Diff: ocispec.Descriptor{
|
||||
MediaType: ocispec.MediaTypeImageLayer,
|
||||
Digest: diffIDs[i],
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
for {
|
||||
var layer ocispec.Descriptor
|
||||
select {
|
||||
case layer = <-u.updateCh:
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
parent := identity.ChainID(chain)
|
||||
chain = append(chain, diffIDs[i])
|
||||
|
||||
chainID := identity.ChainID(chain).String()
|
||||
if _, err := sn.Stat(ctx, chainID); err == nil {
|
||||
// no need to handle
|
||||
continue
|
||||
} else if !errdefs.IsNotFound(err) {
|
||||
return errors.Wrapf(err, "failed to stat snapshot %s", chainID)
|
||||
}
|
||||
log.G(ctx).WithField("desc", layer).Debug("layer downloaded")
|
||||
for i := range states {
|
||||
if states[i].layer.Blob.Digest != layer.Digest {
|
||||
continue
|
||||
}
|
||||
// Different layers may have the same digest. When that
|
||||
// happens, we should continue marking the next layer
|
||||
// as downloaded.
|
||||
if states[i].downloaded {
|
||||
continue
|
||||
}
|
||||
states[i].downloaded = true
|
||||
break
|
||||
|
||||
// inherits annotations which are provided as snapshot labels.
|
||||
labels := snapshots.FilterInheritedLabels(desc.Annotations)
|
||||
if labels == nil {
|
||||
labels = make(map[string]string)
|
||||
}
|
||||
for i := range states {
|
||||
if !states[i].downloaded {
|
||||
labels[labelSnapshotRef] = chainID
|
||||
labelOpt := snapshots.WithLabels(labels)
|
||||
|
||||
var (
|
||||
key string
|
||||
mounts []mount.Mount
|
||||
)
|
||||
|
||||
for try := 1; try <= 3; try++ {
|
||||
// Prepare snapshot with from parent, label as root
|
||||
key = fmt.Sprintf("extract-%s %s", uniquePart(), chainID)
|
||||
mounts, err = sn.Prepare(ctx, key, parent.String(), labelOpt)
|
||||
if err != nil {
|
||||
if errdefs.IsAlreadyExists(err) {
|
||||
if _, err := sn.Stat(ctx, chainID); err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return errors.Wrapf(err, "failed to stat snapshot %s", chainID)
|
||||
}
|
||||
// Try again, this should be rare, log it
|
||||
log.G(ctx).WithField("key", key).WithField("chainid", chainID).Debug("extraction snapshot already exists, chain id not found")
|
||||
} else {
|
||||
// no need to handle, snapshot now found with chain id
|
||||
continue EachLayer
|
||||
}
|
||||
} else {
|
||||
return errors.Wrapf(err, "failed to prepare extraction snapshot %q", key)
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
if states[i].unpacked {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to prepare extraction snapshot")
|
||||
}
|
||||
|
||||
// Abort the snapshot if commit does not happen
|
||||
abort := func() {
|
||||
if err := sn.Remove(ctx, key); err != nil {
|
||||
log.G(ctx).WithError(err).Errorf("failed to cleanup %q", key)
|
||||
}
|
||||
}
|
||||
|
||||
if fetchErr == nil {
|
||||
fetchErr = make(chan error, 1)
|
||||
fetchOffset = i
|
||||
fetchC = make([]chan struct{}, len(layers)-fetchOffset)
|
||||
for i := range fetchC {
|
||||
fetchC[i] = make(chan struct{})
|
||||
}
|
||||
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
"desc": states[i].layer.Blob,
|
||||
"diff": states[i].layer.Diff,
|
||||
}).Debug("unpack layer")
|
||||
go func() {
|
||||
err := u.fetch(ctx, h, layers[i:], fetchC)
|
||||
if err != nil {
|
||||
fetchErr <- err
|
||||
}
|
||||
close(fetchErr)
|
||||
}()
|
||||
}
|
||||
|
||||
unpacked, err := rootfs.ApplyLayerWithOpts(ctx, states[i].layer, chain, sn, a,
|
||||
u.config.SnapshotOpts, u.config.ApplyOpts)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case err := <-fetchErr:
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case <-fetchC[i-fetchOffset]:
|
||||
}
|
||||
|
||||
if unpacked {
|
||||
// Set the uncompressed label after the uncompressed
|
||||
// digest has been verified through apply.
|
||||
cinfo := content.Info{
|
||||
Digest: states[i].layer.Blob.Digest,
|
||||
Labels: map[string]string{
|
||||
"containerd.io/uncompressed": states[i].layer.Diff.Digest.String(),
|
||||
},
|
||||
}
|
||||
if _, err := cs.Update(ctx, cinfo, "labels.containerd.io/uncompressed"); err != nil {
|
||||
return err
|
||||
}
|
||||
diff, err := a.Apply(ctx, desc, mounts)
|
||||
if err != nil {
|
||||
abort()
|
||||
return errors.Wrapf(err, "failed to extract layer %s", diffIDs[i])
|
||||
}
|
||||
if diff.Digest != diffIDs[i] {
|
||||
abort()
|
||||
return errors.Errorf("wrong diff id calculated on extraction %q", diffIDs[i])
|
||||
}
|
||||
|
||||
if err = sn.Commit(ctx, chainID, key, labelOpt); err != nil {
|
||||
abort()
|
||||
if errdefs.IsAlreadyExists(err) {
|
||||
continue
|
||||
}
|
||||
return errors.Wrapf(err, "failed to commit snapshot %s", key)
|
||||
}
|
||||
|
||||
chain = append(chain, states[i].layer.Diff.Digest)
|
||||
states[i].unpacked = true
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
"desc": states[i].layer.Blob,
|
||||
"diff": states[i].layer.Diff,
|
||||
}).Debug("layer unpacked")
|
||||
// Set the uncompressed label after the uncompressed
|
||||
// digest has been verified through apply.
|
||||
cinfo := content.Info{
|
||||
Digest: desc.Digest,
|
||||
Labels: map[string]string{
|
||||
"containerd.io/uncompressed": diff.Digest.String(),
|
||||
},
|
||||
}
|
||||
// Check whether all layers are unpacked.
|
||||
if states[len(states)-1].unpacked {
|
||||
break
|
||||
if _, err := cs.Update(ctx, cinfo, "labels.containerd.io/uncompressed"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
chainID := identity.ChainID(chain).String()
|
||||
@@ -183,40 +238,45 @@ func (u *unpacker) unpack(ctx context.Context, config ocispec.Descriptor, layers
|
||||
"config": config.Digest,
|
||||
"chainID": chainID,
|
||||
}).Debug("image unpacked")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type errGroup struct {
|
||||
*errgroup.Group
|
||||
cancel context.CancelFunc
|
||||
func (u *unpacker) fetch(ctx context.Context, h images.Handler, layers []ocispec.Descriptor, done []chan struct{}) error {
|
||||
eg, ctx2 := errgroup.WithContext(ctx)
|
||||
for i, desc := range layers {
|
||||
desc := desc
|
||||
i := i
|
||||
|
||||
if u.limiter != nil {
|
||||
if err := u.limiter.Acquire(ctx, 1); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
eg.Go(func() error {
|
||||
_, err := h.Handle(ctx2, desc)
|
||||
if u.limiter != nil {
|
||||
u.limiter.Release(1)
|
||||
}
|
||||
if err != nil && errors.Cause(err) != images.ErrSkipDesc {
|
||||
return err
|
||||
}
|
||||
close(done[i])
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
return eg.Wait()
|
||||
}
|
||||
|
||||
func newErrGroup(ctx context.Context) (*errGroup, context.Context) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
return &errGroup{
|
||||
Group: eg,
|
||||
cancel: cancel,
|
||||
}, ctx
|
||||
}
|
||||
|
||||
func (e *errGroup) Cancel() {
|
||||
e.cancel()
|
||||
}
|
||||
|
||||
func (e *errGroup) Wait() error {
|
||||
err := e.Group.Wait()
|
||||
e.cancel()
|
||||
return err
|
||||
}
|
||||
|
||||
func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(images.Handler) images.Handler, *errGroup) {
|
||||
eg, uctx := newErrGroup(uctx)
|
||||
func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(images.Handler) images.Handler, *errgroup.Group) {
|
||||
eg, uctx := errgroup.WithContext(uctx)
|
||||
return func(f images.Handler) images.Handler {
|
||||
var (
|
||||
lock sync.Mutex
|
||||
layers []ocispec.Descriptor
|
||||
schema1 bool
|
||||
lock sync.Mutex
|
||||
layers = map[digest.Digest][]ocispec.Descriptor{}
|
||||
)
|
||||
return images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
||||
children, err := f.Handle(ctx, desc)
|
||||
@@ -224,56 +284,48 @@ func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(im
|
||||
return children, err
|
||||
}
|
||||
|
||||
// `Pull` only supports one platform, so there is only
|
||||
// one manifest to handle, and manifest list can be
|
||||
// safely skipped.
|
||||
// TODO: support multi-platform unpack.
|
||||
switch mt := desc.MediaType; {
|
||||
case mt == images.MediaTypeDockerSchema1Manifest:
|
||||
lock.Lock()
|
||||
schema1 = true
|
||||
lock.Unlock()
|
||||
case mt == images.MediaTypeDockerSchema2Manifest || mt == ocispec.MediaTypeImageManifest:
|
||||
lock.Lock()
|
||||
switch desc.MediaType {
|
||||
case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
|
||||
var nonLayers []ocispec.Descriptor
|
||||
var manifestLayers []ocispec.Descriptor
|
||||
|
||||
// Split layers from non-layers, layers will be handled after
|
||||
// the config
|
||||
for _, child := range children {
|
||||
if child.MediaType == images.MediaTypeDockerSchema2Config ||
|
||||
child.MediaType == ocispec.MediaTypeImageConfig {
|
||||
continue
|
||||
if images.IsLayerType(child.MediaType) {
|
||||
manifestLayers = append(manifestLayers, child)
|
||||
} else {
|
||||
nonLayers = append(nonLayers, child)
|
||||
}
|
||||
layers = append(layers, child)
|
||||
}
|
||||
|
||||
lock.Lock()
|
||||
for _, nl := range nonLayers {
|
||||
layers[nl.Digest] = manifestLayers
|
||||
}
|
||||
lock.Unlock()
|
||||
case mt == images.MediaTypeDockerSchema2Config || mt == ocispec.MediaTypeImageConfig:
|
||||
|
||||
children = nonLayers
|
||||
case images.MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig:
|
||||
lock.Lock()
|
||||
l := append([]ocispec.Descriptor{}, layers...)
|
||||
l := layers[desc.Digest]
|
||||
lock.Unlock()
|
||||
if len(l) > 0 {
|
||||
atomic.AddInt32(unpacks, 1)
|
||||
eg.Go(func() error {
|
||||
return u.unpack(uctx, desc, l)
|
||||
return u.unpack(uctx, f, desc, l)
|
||||
})
|
||||
}
|
||||
case images.IsLayerType(mt):
|
||||
lock.Lock()
|
||||
update := !schema1
|
||||
lock.Unlock()
|
||||
if update {
|
||||
select {
|
||||
case <-uctx.Done():
|
||||
// Do not send update if unpacker is not running.
|
||||
default:
|
||||
select {
|
||||
case u.updateCh <- desc:
|
||||
case <-uctx.Done():
|
||||
// Do not send update if unpacker is not running.
|
||||
}
|
||||
}
|
||||
// Checking ctx.Done() prevents the case that unpacker
|
||||
// exits unexpectedly, but update continues to be generated,
|
||||
// and eventually fills up updateCh and blocks forever.
|
||||
}
|
||||
}
|
||||
return children, nil
|
||||
})
|
||||
}, eg
|
||||
}
|
||||
|
||||
func uniquePart() string {
|
||||
t := time.Now()
|
||||
var b [3]byte
|
||||
// Ignore read failures, just decreases uniqueness
|
||||
rand.Read(b[:])
|
||||
return fmt.Sprintf("%d-%s", t.Nanosecond(), base64.URLEncoding.EncodeToString(b[:]))
|
||||
}
|
||||
|
||||
173
vendor/github.com/containerd/containerd/vendor.conf
generated
vendored
173
vendor/github.com/containerd/containerd/vendor.conf
generated
vendored
@@ -1,91 +1,94 @@
|
||||
github.com/containerd/go-runc e029b79d8cda8374981c64eba71f28ec38e5526f
|
||||
github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
|
||||
github.com/containerd/cgroups abd0b19954a6b05e0963f48427062d1481b7faad
|
||||
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
|
||||
github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
|
||||
github.com/containerd/btrfs af5082808c833de0e79c1e72eea9fea239364877
|
||||
github.com/containerd/continuity f2a389ac0a02ce21c09edd7344677a601970f41c
|
||||
github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
|
||||
github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
|
||||
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
||||
github.com/docker/go-units v0.4.0
|
||||
github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f
|
||||
github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823
|
||||
github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c
|
||||
github.com/prometheus/common 89604d197083d4781071d3c65855d24ecfb0a563
|
||||
github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd
|
||||
github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1
|
||||
github.com/gogo/protobuf v1.2.1
|
||||
github.com/gogo/googleapis v1.2.0
|
||||
github.com/golang/protobuf v1.2.0
|
||||
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
|
||||
github.com/opencontainers/runc d736ef14f0288d6993a1845745d6756cfc9ddd5a # v1.0.0-rc9
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1
|
||||
github.com/sirupsen/logrus v1.4.1
|
||||
github.com/urfave/cli v1.22.0
|
||||
golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3
|
||||
google.golang.org/grpc 39e8a7b072a67ca2a75f57fa2e0d50995f5b22f6 # v1.23.1
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
|
||||
golang.org/x/sys c990c680b611ac1aeb7d8f2af94a825f98d69720 https://github.com/golang/sys
|
||||
github.com/opencontainers/image-spec v1.0.1
|
||||
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
|
||||
github.com/Microsoft/go-winio v0.4.14
|
||||
github.com/Microsoft/hcsshim d2849cbdb9dfe5f513292a9610ca2eb734cdd1e7
|
||||
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
||||
github.com/containerd/ttrpc 92c8520ef9f86600c650dd540266a007bf03670f
|
||||
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
|
||||
gotest.tools v2.3.0
|
||||
github.com/google/go-cmp v0.2.0
|
||||
go.etcd.io/bbolt v1.3.3
|
||||
github.com/hashicorp/errwrap v1.0.0
|
||||
github.com/hashicorp/go-multierror v1.0.0
|
||||
github.com/hashicorp/golang-lru v0.5.3
|
||||
go.opencensus.io v0.22.0
|
||||
github.com/imdario/mergo v0.3.7
|
||||
github.com/cpuguy83/go-md2man v1.0.10
|
||||
github.com/russross/blackfriday v1.5.2
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
|
||||
github.com/BurntSushi/toml 3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005 # v0.3.1
|
||||
github.com/containerd/btrfs af5082808c833de0e79c1e72eea9fea239364877
|
||||
github.com/containerd/cgroups fada802a7909d430bd17126fd6e4bbf5716f2bcd
|
||||
github.com/containerd/console 8375c3424e4d7b114e8a90a4a40c8e1b40d1d4e6
|
||||
github.com/containerd/continuity f2a389ac0a02ce21c09edd7344677a601970f41c
|
||||
github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
|
||||
github.com/containerd/go-runc a5c2862aed5e6358b305b0e16bfce58e0549b1cd
|
||||
github.com/containerd/ttrpc 92c8520ef9f86600c650dd540266a007bf03670f
|
||||
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
|
||||
github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
|
||||
github.com/cpuguy83/go-md2man 7762f7e404f8416dfa1d9bb6a8c192aa9acb4d19 # v1.0.10
|
||||
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
||||
github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
|
||||
github.com/docker/go-units 519db1ee28dcc9fd2474ae59fca29a810482bfb1 # v0.4.0
|
||||
github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f
|
||||
github.com/gogo/googleapis d31c731455cb061f42baff3bda55bad0118b126b # v1.2.0
|
||||
github.com/gogo/protobuf ba06b47c162d49f2af050fb4c75bcbc86a159d5c # v1.2.1
|
||||
github.com/golang/protobuf aa810b61a9c79d51363740d207bb46cf8e620ed5 # v1.2.0
|
||||
github.com/google/go-cmp 3af367b6b30c263d47e8895973edcca9a49cf029 # v0.2.0
|
||||
github.com/google/uuid 0cd6bf5da1e1c83f8b45653022c74f71af0538a4 # v1.1.1
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
|
||||
github.com/hashicorp/errwrap 8a6fb523712970c966eefc6b39ed2c5e74880354 # v1.0.0
|
||||
github.com/hashicorp/go-multierror 886a7fbe3eb1c874d46f623bfa70af45f425b3d1 # v1.0.0
|
||||
github.com/hashicorp/golang-lru 7f827b33c0f158ec5dfbba01bb0b14a4541fd81d # v0.5.3
|
||||
github.com/imdario/mergo 7c29201646fa3de8506f701213473dd407f19646 # v0.3.7
|
||||
github.com/konsorten/go-windows-terminal-sequences 5c8c8bd35d3832f5d134ae1e1e375b69a4d25242 # v1.0.1
|
||||
github.com/matttproud/golang_protobuf_extensions c12348ce28de40eed0136aa2b644d0ee0650e56c # v1.0.1
|
||||
github.com/Microsoft/go-winio 6c72808b55902eae4c5943626030429ff20f3b63 # v0.4.14
|
||||
github.com/Microsoft/hcsshim d2849cbdb9dfe5f513292a9610ca2eb734cdd1e7
|
||||
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
|
||||
github.com/opencontainers/image-spec d60099175f88c47cd379c4738d158884749ed235 # v1.0.1
|
||||
github.com/opencontainers/runc d736ef14f0288d6993a1845745d6756cfc9ddd5a # v1.0.0-rc9
|
||||
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
|
||||
github.com/pkg/errors ba968bfe8b2f7e042a574c888954fccecfa385b4 # v0.8.1
|
||||
github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823
|
||||
github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c
|
||||
github.com/prometheus/common 89604d197083d4781071d3c65855d24ecfb0a563
|
||||
github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd
|
||||
github.com/russross/blackfriday 05f3235734ad95d0016f6a23902f06461fcf567a # v1.5.2
|
||||
github.com/sirupsen/logrus 8bdbc7bcc01dcbb8ec23dc8a28e332258d25251f # v1.4.1
|
||||
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
|
||||
github.com/urfave/cli bfe2e925cfb6d44b40ad3a779165ea7e8aff9212 # v1.22.0
|
||||
go.etcd.io/bbolt a0458a2b35708eef59eb5f620ceb3cd1c01a824d # v1.3.3
|
||||
go.opencensus.io 9c377598961b706d1542bd2d84d538b5094d596e # v0.22.0
|
||||
golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3
|
||||
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
|
||||
golang.org/x/sys c990c680b611ac1aeb7d8f2af94a825f98d69720 https://github.com/golang/sys
|
||||
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
||||
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||
google.golang.org/grpc 39e8a7b072a67ca2a75f57fa2e0d50995f5b22f6 # v1.23.1
|
||||
gotest.tools 1083505acf35a0bd8a696b26837e1fb3187a7a83 # v2.3.0
|
||||
|
||||
# cri dependencies
|
||||
github.com/containerd/cri 8ce2ad6b7c9a83f830684d1025034fb3ad2ec375 # master
|
||||
github.com/containerd/go-cni 0d360c50b10b350b6bb23863fd4dfb1c232b01c9
|
||||
github.com/containernetworking/cni v0.7.1
|
||||
github.com/containernetworking/plugins v0.7.6
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
|
||||
github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00
|
||||
github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528
|
||||
github.com/emicklei/go-restful v2.9.5
|
||||
github.com/google/gofuzz v1.0.0
|
||||
github.com/json-iterator/go v1.1.7
|
||||
github.com/modern-go/reflect2 1.0.1
|
||||
github.com/modern-go/concurrent 1.0.3
|
||||
github.com/opencontainers/selinux v1.2.2
|
||||
github.com/seccomp/libseccomp-golang v0.9.1
|
||||
github.com/tchap/go-patricia v2.2.6
|
||||
golang.org/x/crypto 5c40567a22f818bd14a1ea7245dad9f8ef0691aa
|
||||
golang.org/x/oauth2 0f29369cfe4552d0e4bcddc57cc75f4d7e672a33
|
||||
golang.org/x/time 85acf8d2951cb2a3bde7632f9ff273ef0379bcbd
|
||||
gopkg.in/inf.v0 v0.9.0
|
||||
gopkg.in/yaml.v2 v2.2.2
|
||||
k8s.io/api kubernetes-1.16.0-rc.2
|
||||
k8s.io/apimachinery kubernetes-1.16.0-rc.2
|
||||
k8s.io/apiserver kubernetes-1.16.0-rc.2
|
||||
k8s.io/cri-api kubernetes-1.16.0-rc.2
|
||||
k8s.io/client-go kubernetes-1.16.0-rc.2
|
||||
k8s.io/klog v0.4.0
|
||||
k8s.io/kubernetes v1.16.0-rc.2
|
||||
k8s.io/utils c2654d5206da6b7b6ace12841e8f359bb89b443c
|
||||
sigs.k8s.io/yaml v1.1.0
|
||||
github.com/containerd/cri c9d45e65263e26f7e7f0ac8fdca0d510622f12cb # master
|
||||
github.com/containerd/go-cni 0d360c50b10b350b6bb23863fd4dfb1c232b01c9
|
||||
github.com/containernetworking/cni 4cfb7b568922a3c79a23e438dc52fe537fc9687e # v0.7.1
|
||||
github.com/containernetworking/plugins 9f96827c7cabb03f21d86326000c00f61e181f6a # v0.7.6
|
||||
github.com/davecgh/go-spew 8991bc29aa16c548c550c7ff78260e27b9ab7c73 # v1.1.1
|
||||
github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
|
||||
github.com/docker/docker d1d5f6476656c6aad457e2a91d3436e66b6f2251
|
||||
github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528
|
||||
github.com/emicklei/go-restful b993709ae1a4f6dd19cfa475232614441b11c9d5 # v2.9.5
|
||||
github.com/google/gofuzz f140a6486e521aad38f5917de355cbf147cc0496 # v1.0.0
|
||||
github.com/json-iterator/go 27518f6661eba504be5a7a9a9f6d9460d892ade3 # v1.1.7
|
||||
github.com/modern-go/concurrent bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94 # 1.0.3
|
||||
github.com/modern-go/reflect2 4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd # 1.0.1
|
||||
github.com/opencontainers/selinux 3a1f366feb7aecbf7a0e71ac4cea88b31597de9e # v1.2.2
|
||||
github.com/seccomp/libseccomp-golang 689e3c1541a84461afc49c1c87352a6cedf72e9c # v0.9.1
|
||||
github.com/tchap/go-patricia 666120de432aea38ab06bd5c818f04f4129882c9 # v2.2.6
|
||||
golang.org/x/crypto 5c40567a22f818bd14a1ea7245dad9f8ef0691aa
|
||||
golang.org/x/oauth2 0f29369cfe4552d0e4bcddc57cc75f4d7e672a33
|
||||
golang.org/x/time 85acf8d2951cb2a3bde7632f9ff273ef0379bcbd
|
||||
gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 # v0.9.0
|
||||
gopkg.in/yaml.v2 51d6538a90f86fe93ac480b35f37b2be17fef232 # v2.2.2
|
||||
k8s.io/api d2ab659560cb09bd6c9a3011b6468f0025c65e63 # kubernetes-1.16.0-rc.2
|
||||
k8s.io/apimachinery 27d36303b6556f377b4f34e64705fa9024a12b0c # kubernetes-1.16.0-rc.2
|
||||
k8s.io/apiserver 5669a5603d961de1ecb7a73b85199e4799081334 # kubernetes-1.16.0-rc.2
|
||||
k8s.io/client-go 5ff489491ea74e098486c3530bbfa0171dc7bf95 # kubernetes-1.16.0-rc.2
|
||||
k8s.io/cri-api 608eb1dad4ac015f9d4f36a3fc70ad3e579af892 # kubernetes-1.16.0-rc.2
|
||||
k8s.io/klog 3ca30a56d8a775276f9cdae009ba326fdc05af7f # v0.4.0
|
||||
k8s.io/kubernetes 4cb51f0d2d8392ea12aeae13182b41008b3a268e # v1.16.0-rc.2
|
||||
k8s.io/utils c2654d5206da6b7b6ace12841e8f359bb89b443c
|
||||
sigs.k8s.io/yaml fd68e9863619f6ec2fdd8625fe1f02e7c877e480 # v1.1.0
|
||||
|
||||
# zfs dependencies
|
||||
github.com/containerd/zfs 9abf673ca6ff9ab8d9bd776a4ceff8f6dc699c3d
|
||||
github.com/mistifyio/go-zfs f784269be439d704d3dfa1906f45dd848fed2beb
|
||||
github.com/containerd/zfs 9abf673ca6ff9ab8d9bd776a4ceff8f6dc699c3d
|
||||
github.com/mistifyio/go-zfs f784269be439d704d3dfa1906f45dd848fed2beb
|
||||
|
||||
# aufs dependencies
|
||||
github.com/containerd/aufs 371312c1e31c210a21e49bf3dfd3f31729ed9f2f
|
||||
github.com/containerd/aufs 371312c1e31c210a21e49bf3dfd3f31729ed9f2f
|
||||
|
||||
# cgroups dependencies
|
||||
github.com/cilium/ebpf 60c3aa43f488292fe2ee50fb8b833b383ca8ebbb
|
||||
|
||||
Reference in New Issue
Block a user