mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
Merge pull request #3358 from dweomer/fix/3296/caps
containerd: v1.4.4-k3s2
This commit is contained in:
commit
c2e561f25e
4
go.mod
4
go.mod
@ -8,9 +8,9 @@ replace (
|
||||
github.com/containerd/btrfs => github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e
|
||||
github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340
|
||||
github.com/containerd/console => github.com/containerd/console v1.0.0
|
||||
github.com/containerd/containerd => github.com/k3s-io/containerd v1.4.4-k3s1
|
||||
github.com/containerd/containerd => github.com/k3s-io/containerd v1.4.4-k3s2 // k3s-release/1.4
|
||||
github.com/containerd/continuity => github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1
|
||||
github.com/containerd/cri => github.com/k3s-io/cri v1.4.0-k3s.5 // k3s-release/1.4
|
||||
github.com/containerd/cri => github.com/k3s-io/cri v1.4.0-k3s.6 // k3s-release/1.4
|
||||
github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b
|
||||
github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328
|
||||
github.com/containerd/ttrpc => github.com/containerd/ttrpc v1.0.1
|
||||
|
8
go.sum
8
go.sum
@ -530,12 +530,12 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||
github.com/k3s-io/containerd v1.4.4-k3s1 h1:9D9ynaNMW0vT/Kycr7qLstBGby6T84iJpbKFXKGhAPk=
|
||||
github.com/k3s-io/containerd v1.4.4-k3s1/go.mod h1:M0uyTU3ZQ0WEBn5YcYPDs/7LpW/0mqjt5im7Wn2z1kc=
|
||||
github.com/k3s-io/containerd v1.4.4-k3s2 h1:Jgpa+oLISVQuib3YEM9lNCG/rmJwhVW95PNVuxsUZdM=
|
||||
github.com/k3s-io/containerd v1.4.4-k3s2/go.mod h1:0fNz8l5ogmvtVmaK9rW4mUxz6doAlDqFv/CrxGUSiyo=
|
||||
github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1 h1:KEz2rd9IDbrQT8w6RibEYlwfTXiu0P6hQDE+6O4IJdI=
|
||||
github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
|
||||
github.com/k3s-io/cri v1.4.0-k3s.5 h1:Uh7QkRKibPJqSBbtCtgpjYsdNVcx3Tx+7HHlhxKBtu8=
|
||||
github.com/k3s-io/cri v1.4.0-k3s.5/go.mod h1:fGPUUHMKQik/vIegSe05DtX/m4miovdtvVLqRUFAkK0=
|
||||
github.com/k3s-io/cri v1.4.0-k3s.6 h1:Hn/0KRtv62B/KNT8oULl1hWnViyuJ+RB0x9y9zZsmCw=
|
||||
github.com/k3s-io/cri v1.4.0-k3s.6/go.mod h1:fGPUUHMKQik/vIegSe05DtX/m4miovdtvVLqRUFAkK0=
|
||||
github.com/k3s-io/cri-tools v1.21.0-k3s1 h1:MWQtAsx4HCNXenqU/B4V9eU6HMyafkd1PnW6d4HCfos=
|
||||
github.com/k3s-io/cri-tools v1.21.0-k3s1/go.mod h1:Qsz54zxINPR+WVWX9Kc3CTmuDFB1dNLCNV8jE8lUbtU=
|
||||
github.com/k3s-io/etcd v0.5.0-alpha.5.0.20201208200253-50621aee4aea h1:7cwby0GoNAi8IsVrT0q+JfQpB6V76ZaEGhj6qts/mvU=
|
||||
|
4
vendor/github.com/containerd/containerd/go.mod
generated
vendored
4
vendor/github.com/containerd/containerd/go.mod
generated
vendored
@ -4,7 +4,7 @@ go 1.14
|
||||
|
||||
replace (
|
||||
github.com/containerd/continuity => github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1
|
||||
github.com/containerd/cri => github.com/k3s-io/cri v1.4.0-k3s.5 // k3s-release/1.4
|
||||
github.com/containerd/cri => github.com/k3s-io/cri v1.4.0-k3s.6 // k3s-release/1.4
|
||||
github.com/golang/protobuf => github.com/golang/protobuf v1.3.5
|
||||
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63
|
||||
k8s.io/api => k8s.io/api v0.19.5
|
||||
@ -73,7 +73,7 @@ require (
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.7.1
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/tchap/go-patricia v2.2.6+incompatible // indirect
|
||||
github.com/urfave/cli v1.22.2
|
||||
go.etcd.io/bbolt v1.3.5
|
||||
|
4
vendor/github.com/containerd/containerd/go.sum
generated
vendored
4
vendor/github.com/containerd/containerd/go.sum
generated
vendored
@ -402,8 +402,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
|
||||
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||
github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1 h1:KEz2rd9IDbrQT8w6RibEYlwfTXiu0P6hQDE+6O4IJdI=
|
||||
github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
|
||||
github.com/k3s-io/cri v1.4.0-k3s.5 h1:Uh7QkRKibPJqSBbtCtgpjYsdNVcx3Tx+7HHlhxKBtu8=
|
||||
github.com/k3s-io/cri v1.4.0-k3s.5/go.mod h1:fGPUUHMKQik/vIegSe05DtX/m4miovdtvVLqRUFAkK0=
|
||||
github.com/k3s-io/cri v1.4.0-k3s.6 h1:Hn/0KRtv62B/KNT8oULl1hWnViyuJ+RB0x9y9zZsmCw=
|
||||
github.com/k3s-io/cri v1.4.0-k3s.6/go.mod h1:fGPUUHMKQik/vIegSe05DtX/m4miovdtvVLqRUFAkK0=
|
||||
github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
|
113
vendor/github.com/containerd/containerd/oci/spec_opts.go
generated
vendored
113
vendor/github.com/containerd/containerd/oci/spec_opts.go
generated
vendored
@ -38,7 +38,6 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/user"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/syndtr/gocapability/capability"
|
||||
)
|
||||
|
||||
// SpecOpts sets spec specific information to a newly generated OCI spec
|
||||
@ -274,6 +273,28 @@ func WithMounts(mounts []specs.Mount) SpecOpts {
|
||||
}
|
||||
}
|
||||
|
||||
// WithoutMounts removes mounts
|
||||
func WithoutMounts(dests ...string) SpecOpts {
|
||||
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
var (
|
||||
mounts []specs.Mount
|
||||
current = s.Mounts
|
||||
)
|
||||
mLoop:
|
||||
for _, m := range current {
|
||||
mDestination := filepath.Clean(m.Destination)
|
||||
for _, dest := range dests {
|
||||
if mDestination == dest {
|
||||
continue mLoop
|
||||
}
|
||||
}
|
||||
mounts = append(mounts, m)
|
||||
}
|
||||
s.Mounts = mounts
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithHostNamespace allows a task to run inside the host's linux namespace
|
||||
func WithHostNamespace(ns specs.LinuxNamespaceType) SpecOpts {
|
||||
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
@ -295,10 +316,7 @@ func WithLinuxNamespace(ns specs.LinuxNamespace) SpecOpts {
|
||||
setLinux(s)
|
||||
for i, n := range s.Linux.Namespaces {
|
||||
if n.Type == ns.Type {
|
||||
before := s.Linux.Namespaces[:i]
|
||||
after := s.Linux.Namespaces[i+1:]
|
||||
s.Linux.Namespaces = append(before, ns)
|
||||
s.Linux.Namespaces = append(s.Linux.Namespaces, after...)
|
||||
s.Linux.Namespaces[i] = ns
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -536,7 +554,7 @@ func WithUser(userstr string) SpecOpts {
|
||||
}
|
||||
f := func(root string) error {
|
||||
if username != "" {
|
||||
user, err := getUserFromPath(root, func(u user.User) bool {
|
||||
user, err := UserFromPath(root, func(u user.User) bool {
|
||||
return u.Name == username
|
||||
})
|
||||
if err != nil {
|
||||
@ -545,7 +563,7 @@ func WithUser(userstr string) SpecOpts {
|
||||
uid = uint32(user.Uid)
|
||||
}
|
||||
if groupname != "" {
|
||||
gid, err = getGIDFromPath(root, func(g user.Group) bool {
|
||||
gid, err = GIDFromPath(root, func(g user.Group) bool {
|
||||
return g.Name == groupname
|
||||
})
|
||||
if err != nil {
|
||||
@ -600,11 +618,11 @@ func WithUserID(uid uint32) SpecOpts {
|
||||
if !isRootfsAbs(s.Root.Path) {
|
||||
return errors.Errorf("rootfs absolute path is required")
|
||||
}
|
||||
user, err := getUserFromPath(s.Root.Path, func(u user.User) bool {
|
||||
user, err := UserFromPath(s.Root.Path, func(u user.User) bool {
|
||||
return u.Uid == int(uid)
|
||||
})
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) || err == errNoUsersFound {
|
||||
if os.IsNotExist(err) || err == ErrNoUsersFound {
|
||||
s.Process.User.UID, s.Process.User.GID = uid, 0
|
||||
return nil
|
||||
}
|
||||
@ -626,11 +644,11 @@ func WithUserID(uid uint32) SpecOpts {
|
||||
return err
|
||||
}
|
||||
return mount.WithTempMount(ctx, mounts, func(root string) error {
|
||||
user, err := getUserFromPath(root, func(u user.User) bool {
|
||||
user, err := UserFromPath(root, func(u user.User) bool {
|
||||
return u.Uid == int(uid)
|
||||
})
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) || err == errNoUsersFound {
|
||||
if os.IsNotExist(err) || err == ErrNoUsersFound {
|
||||
s.Process.User.UID, s.Process.User.GID = uid, 0
|
||||
return nil
|
||||
}
|
||||
@ -654,7 +672,7 @@ func WithUsername(username string) SpecOpts {
|
||||
if !isRootfsAbs(s.Root.Path) {
|
||||
return errors.Errorf("rootfs absolute path is required")
|
||||
}
|
||||
user, err := getUserFromPath(s.Root.Path, func(u user.User) bool {
|
||||
user, err := UserFromPath(s.Root.Path, func(u user.User) bool {
|
||||
return u.Name == username
|
||||
})
|
||||
if err != nil {
|
||||
@ -675,7 +693,7 @@ func WithUsername(username string) SpecOpts {
|
||||
return err
|
||||
}
|
||||
return mount.WithTempMount(ctx, mounts, func(root string) error {
|
||||
user, err := getUserFromPath(root, func(u user.User) bool {
|
||||
user, err := UserFromPath(root, func(u user.User) bool {
|
||||
return u.Name == username
|
||||
})
|
||||
if err != nil {
|
||||
@ -707,11 +725,11 @@ func WithAdditionalGIDs(userstr string) SpecOpts {
|
||||
var username string
|
||||
uid, err := strconv.Atoi(userstr)
|
||||
if err == nil {
|
||||
user, err := getUserFromPath(root, func(u user.User) bool {
|
||||
user, err := UserFromPath(root, func(u user.User) bool {
|
||||
return u.Uid == uid
|
||||
})
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) || err == errNoUsersFound {
|
||||
if os.IsNotExist(err) || err == ErrNoUsersFound {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
@ -776,29 +794,6 @@ func WithCapabilities(caps []string) SpecOpts {
|
||||
}
|
||||
}
|
||||
|
||||
// WithAllCapabilities sets all linux capabilities for the process
|
||||
var WithAllCapabilities = func(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
|
||||
return WithCapabilities(GetAllCapabilities())(ctx, client, c, s)
|
||||
}
|
||||
|
||||
// GetAllCapabilities returns all caps up to CAP_LAST_CAP
|
||||
// or CAP_BLOCK_SUSPEND on RHEL6
|
||||
func GetAllCapabilities() []string {
|
||||
last := capability.CAP_LAST_CAP
|
||||
// hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap
|
||||
if last == capability.Cap(63) {
|
||||
last = capability.CAP_BLOCK_SUSPEND
|
||||
}
|
||||
var caps []string
|
||||
for _, cap := range capability.List() {
|
||||
if cap > last {
|
||||
continue
|
||||
}
|
||||
caps = append(caps, "CAP_"+strings.ToUpper(cap.String()))
|
||||
}
|
||||
return caps
|
||||
}
|
||||
|
||||
func capsContain(caps []string, s string) bool {
|
||||
for _, c := range caps {
|
||||
if c == s {
|
||||
@ -869,9 +864,12 @@ func WithAmbientCapabilities(caps []string) SpecOpts {
|
||||
}
|
||||
}
|
||||
|
||||
var errNoUsersFound = errors.New("no users found")
|
||||
// ErrNoUsersFound can be returned from UserFromPath
|
||||
var ErrNoUsersFound = errors.New("no users found")
|
||||
|
||||
func getUserFromPath(root string, filter func(user.User) bool) (user.User, error) {
|
||||
// UserFromPath inspects the user object using /etc/passwd in the specified rootfs.
|
||||
// filter can be nil.
|
||||
func UserFromPath(root string, filter func(user.User) bool) (user.User, error) {
|
||||
ppath, err := fs.RootPath(root, "/etc/passwd")
|
||||
if err != nil {
|
||||
return user.User{}, err
|
||||
@ -881,14 +879,17 @@ func getUserFromPath(root string, filter func(user.User) bool) (user.User, error
|
||||
return user.User{}, err
|
||||
}
|
||||
if len(users) == 0 {
|
||||
return user.User{}, errNoUsersFound
|
||||
return user.User{}, ErrNoUsersFound
|
||||
}
|
||||
return users[0], nil
|
||||
}
|
||||
|
||||
var errNoGroupsFound = errors.New("no groups found")
|
||||
// ErrNoGroupsFound can be returned from GIDFromPath
|
||||
var ErrNoGroupsFound = errors.New("no groups found")
|
||||
|
||||
func getGIDFromPath(root string, filter func(user.Group) bool) (gid uint32, err error) {
|
||||
// GIDFromPath inspects the GID using /etc/passwd in the specified rootfs.
|
||||
// filter can be nil.
|
||||
func GIDFromPath(root string, filter func(user.Group) bool) (gid uint32, err error) {
|
||||
gpath, err := fs.RootPath(root, "/etc/group")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@ -898,7 +899,7 @@ func getGIDFromPath(root string, filter func(user.Group) bool) (gid uint32, err
|
||||
return 0, err
|
||||
}
|
||||
if len(groups) == 0 {
|
||||
return 0, errNoGroupsFound
|
||||
return 0, ErrNoGroupsFound
|
||||
}
|
||||
g := groups[0]
|
||||
return uint32(g.Gid), nil
|
||||
@ -948,16 +949,13 @@ func WithReadonlyPaths(paths []string) SpecOpts {
|
||||
|
||||
// WithWriteableSysfs makes any sysfs mounts writeable
|
||||
func WithWriteableSysfs(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
for i, m := range s.Mounts {
|
||||
for _, m := range s.Mounts {
|
||||
if m.Type == "sysfs" {
|
||||
var options []string
|
||||
for _, o := range m.Options {
|
||||
for i, o := range m.Options {
|
||||
if o == "ro" {
|
||||
o = "rw"
|
||||
m.Options[i] = "rw"
|
||||
}
|
||||
options = append(options, o)
|
||||
}
|
||||
s.Mounts[i].Options = options
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -965,16 +963,13 @@ func WithWriteableSysfs(_ context.Context, _ Client, _ *containers.Container, s
|
||||
|
||||
// WithWriteableCgroupfs makes any cgroup mounts writeable
|
||||
func WithWriteableCgroupfs(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
for i, m := range s.Mounts {
|
||||
for _, m := range s.Mounts {
|
||||
if m.Type == "cgroup" {
|
||||
var options []string
|
||||
for _, o := range m.Options {
|
||||
for i, o := range m.Options {
|
||||
if o == "ro" {
|
||||
o = "rw"
|
||||
m.Options[i] = "rw"
|
||||
}
|
||||
options = append(options, o)
|
||||
}
|
||||
s.Mounts[i].Options = options
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -1126,7 +1121,7 @@ func WithDefaultUnixDevices(_ context.Context, _ Client, _ *containers.Container
|
||||
|
||||
// WithPrivileged sets up options for a privileged container
|
||||
var WithPrivileged = Compose(
|
||||
WithAllCapabilities,
|
||||
WithAllCurrentCapabilities,
|
||||
WithMaskedPaths(nil),
|
||||
WithReadonlyPaths(nil),
|
||||
WithWriteableSysfs,
|
||||
@ -1199,15 +1194,13 @@ func WithLinuxDevices(devices []specs.LinuxDevice) SpecOpts {
|
||||
}
|
||||
}
|
||||
|
||||
var ErrNotADevice = errors.New("not a device node")
|
||||
|
||||
// WithLinuxDevice adds the device specified by path to the spec
|
||||
func WithLinuxDevice(path, permissions string) SpecOpts {
|
||||
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
setLinux(s)
|
||||
setResources(s)
|
||||
|
||||
dev, err := deviceFromPath(path, permissions)
|
||||
dev, err := deviceFromPath(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
121
vendor/github.com/containerd/containerd/oci/spec_opts_linux.go
generated
vendored
121
vendor/github.com/containerd/containerd/oci/spec_opts_linux.go
generated
vendored
@ -20,20 +20,17 @@ package oci
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/pkg/cap"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// WithHostDevices adds all the hosts device nodes to the container's spec
|
||||
func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
setLinux(s)
|
||||
|
||||
devs, err := getDevices("/dev")
|
||||
devs, err := HostDevices()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -41,83 +38,28 @@ func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Sp
|
||||
return nil
|
||||
}
|
||||
|
||||
func getDevices(path string) ([]specs.LinuxDevice, error) {
|
||||
files, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var out []specs.LinuxDevice
|
||||
for _, f := range files {
|
||||
switch {
|
||||
case f.IsDir():
|
||||
switch f.Name() {
|
||||
// ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825
|
||||
// ".udev" added to address https://github.com/opencontainers/runc/issues/2093
|
||||
case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts", ".udev":
|
||||
continue
|
||||
default:
|
||||
sub, err := getDevices(filepath.Join(path, f.Name()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out = append(out, sub...)
|
||||
continue
|
||||
}
|
||||
case f.Name() == "console":
|
||||
continue
|
||||
}
|
||||
device, err := deviceFromPath(filepath.Join(path, f.Name()), "rwm")
|
||||
// WithDevices recursively adds devices from the passed in path and associated cgroup rules for that device.
|
||||
// If devicePath is a dir it traverses the dir to add all devices in that dir.
|
||||
// If devicePath is not a dir, it attempts to add the single device.
|
||||
// If containerPath is not set then the device path is used for the container path.
|
||||
func WithDevices(devicePath, containerPath, permissions string) SpecOpts {
|
||||
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
devs, err := getDevices(devicePath, containerPath)
|
||||
if err != nil {
|
||||
if err == ErrNotADevice {
|
||||
continue
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
out = append(out, *device)
|
||||
for _, dev := range devs {
|
||||
s.Linux.Devices = append(s.Linux.Devices, dev)
|
||||
s.Linux.Resources.Devices = append(s.Linux.Resources.Devices, specs.LinuxDeviceCgroup{
|
||||
Allow: true,
|
||||
Type: dev.Type,
|
||||
Major: &dev.Major,
|
||||
Minor: &dev.Minor,
|
||||
Access: permissions,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func deviceFromPath(path, permissions string) (*specs.LinuxDevice, error) {
|
||||
var stat unix.Stat_t
|
||||
if err := unix.Lstat(path, &stat); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
// The type is 32bit on mips.
|
||||
devNumber = uint64(stat.Rdev) // nolint: unconvert
|
||||
major = unix.Major(devNumber)
|
||||
minor = unix.Minor(devNumber)
|
||||
)
|
||||
if major == 0 {
|
||||
return nil, ErrNotADevice
|
||||
}
|
||||
|
||||
var (
|
||||
devType string
|
||||
mode = stat.Mode
|
||||
)
|
||||
switch {
|
||||
case mode&unix.S_IFBLK == unix.S_IFBLK:
|
||||
devType = "b"
|
||||
case mode&unix.S_IFCHR == unix.S_IFCHR:
|
||||
devType = "c"
|
||||
}
|
||||
fm := os.FileMode(mode)
|
||||
return &specs.LinuxDevice{
|
||||
Type: devType,
|
||||
Path: path,
|
||||
Major: int64(major),
|
||||
Minor: int64(minor),
|
||||
FileMode: &fm,
|
||||
UID: &stat.Uid,
|
||||
GID: &stat.Gid,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// WithMemorySwap sets the container's swap in bytes
|
||||
@ -180,3 +122,24 @@ func WithCPUCFS(quota int64, period uint64) SpecOpts {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithAllCurrentCapabilities propagates the effective capabilities of the caller process to the container process.
|
||||
// The capability set may differ from WithAllKnownCapabilities when running in a container.
|
||||
var WithAllCurrentCapabilities = func(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
|
||||
caps, err := cap.Current()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return WithCapabilities(caps)(ctx, client, c, s)
|
||||
}
|
||||
|
||||
// WithAllKnownCapabilities sets all the the known linux capabilities for the container process
|
||||
var WithAllKnownCapabilities = func(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
|
||||
caps := cap.Known()
|
||||
return WithCapabilities(caps)(ctx, client, c, s)
|
||||
}
|
||||
|
||||
// WithoutRunMount removes the `/run` inside the spec
|
||||
func WithoutRunMount(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
|
||||
return WithoutMounts("/run")(ctx, client, c, s)
|
||||
}
|
||||
|
38
vendor/github.com/containerd/containerd/oci/spec_opts_nonlinux.go
generated
vendored
Normal file
38
vendor/github.com/containerd/containerd/oci/spec_opts_nonlinux.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
// +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 oci
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/containerd/containers"
|
||||
)
|
||||
|
||||
// WithAllCurrentCapabilities propagates the effective capabilities of the caller process to the container process.
|
||||
// The capability set may differ from WithAllKnownCapabilities when running in a container.
|
||||
//nolint: deadcode, unused
|
||||
var WithAllCurrentCapabilities = func(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
|
||||
return WithCapabilities(nil)(ctx, client, c, s)
|
||||
}
|
||||
|
||||
// WithAllKnownCapabilities sets all the the known linux capabilities for the container process
|
||||
//nolint: deadcode, unused
|
||||
var WithAllKnownCapabilities = func(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
|
||||
return WithCapabilities(nil)(ctx, client, c, s)
|
||||
}
|
89
vendor/github.com/containerd/containerd/oci/spec_opts_unix.go
generated
vendored
89
vendor/github.com/containerd/containerd/oci/spec_opts_unix.go
generated
vendored
@ -20,20 +20,15 @@ package oci
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containerd/containerd/containers"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// WithHostDevices adds all the hosts device nodes to the container's spec
|
||||
func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
setLinux(s)
|
||||
|
||||
devs, err := getDevices("/dev")
|
||||
devs, err := HostDevices()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -41,82 +36,18 @@ func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Sp
|
||||
return nil
|
||||
}
|
||||
|
||||
func getDevices(path string) ([]specs.LinuxDevice, error) {
|
||||
files, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var out []specs.LinuxDevice
|
||||
for _, f := range files {
|
||||
switch {
|
||||
case f.IsDir():
|
||||
switch f.Name() {
|
||||
// ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825
|
||||
// ".udev" added to address https://github.com/opencontainers/runc/issues/2093
|
||||
case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts", ".udev":
|
||||
continue
|
||||
default:
|
||||
sub, err := getDevices(filepath.Join(path, f.Name()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out = append(out, sub...)
|
||||
continue
|
||||
}
|
||||
case f.Name() == "console":
|
||||
continue
|
||||
}
|
||||
device, err := deviceFromPath(filepath.Join(path, f.Name()), "rwm")
|
||||
// WithDevices recursively adds devices from the passed in path and associated cgroup rules for that device.
|
||||
// If devicePath is a dir it traverses the dir to add all devices in that dir.
|
||||
// If devicePath is not a dir, it attempts to add the single device.
|
||||
func WithDevices(devicePath, containerPath, permissions string) SpecOpts {
|
||||
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
devs, err := getDevices(devicePath, containerPath)
|
||||
if err != nil {
|
||||
if err == ErrNotADevice {
|
||||
continue
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
out = append(out, *device)
|
||||
s.Linux.Devices = append(s.Linux.Devices, devs...)
|
||||
return nil
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func deviceFromPath(path, permissions string) (*specs.LinuxDevice, error) {
|
||||
var stat unix.Stat_t
|
||||
if err := unix.Lstat(path, &stat); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
devNumber = uint64(stat.Rdev)
|
||||
major = unix.Major(devNumber)
|
||||
minor = unix.Minor(devNumber)
|
||||
)
|
||||
if major == 0 {
|
||||
return nil, ErrNotADevice
|
||||
}
|
||||
|
||||
var (
|
||||
devType string
|
||||
mode = stat.Mode
|
||||
)
|
||||
switch {
|
||||
case mode&unix.S_IFBLK == unix.S_IFBLK:
|
||||
devType = "b"
|
||||
case mode&unix.S_IFCHR == unix.S_IFCHR:
|
||||
devType = "c"
|
||||
}
|
||||
fm := os.FileMode(mode)
|
||||
return &specs.LinuxDevice{
|
||||
Type: devType,
|
||||
Path: path,
|
||||
Major: int64(major),
|
||||
Minor: int64(minor),
|
||||
FileMode: &fm,
|
||||
UID: &stat.Uid,
|
||||
GID: &stat.Gid,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// WithCPUCFS sets the container's Completely fair scheduling (CFS) quota and period
|
||||
|
2
vendor/github.com/containerd/containerd/oci/spec_opts_windows.go
generated
vendored
2
vendor/github.com/containerd/containerd/oci/spec_opts_windows.go
generated
vendored
@ -74,6 +74,6 @@ func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Sp
|
||||
return nil
|
||||
}
|
||||
|
||||
func deviceFromPath(path, permissions string) (*specs.LinuxDevice, error) {
|
||||
func deviceFromPath(path string) (*specs.LinuxDevice, error) {
|
||||
return nil, errors.New("device from path not supported on Windows")
|
||||
}
|
||||
|
137
vendor/github.com/containerd/containerd/oci/utils_unix.go
generated
vendored
Normal file
137
vendor/github.com/containerd/containerd/oci/utils_unix.go
generated
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
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 oci
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var errNotADevice = errors.New("not a device node")
|
||||
|
||||
// HostDevices returns all devices that can be found under /dev directory.
|
||||
func HostDevices() ([]specs.LinuxDevice, error) {
|
||||
return getDevices("/dev", "")
|
||||
}
|
||||
|
||||
func getDevices(path, containerPath string) ([]specs.LinuxDevice, error) {
|
||||
stat, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error stating device path")
|
||||
}
|
||||
|
||||
if !stat.IsDir() {
|
||||
dev, err := deviceFromPath(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if containerPath != "" {
|
||||
dev.Path = containerPath
|
||||
}
|
||||
return []specs.LinuxDevice{*dev}, nil
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var out []specs.LinuxDevice
|
||||
for _, f := range files {
|
||||
switch {
|
||||
case f.IsDir():
|
||||
switch f.Name() {
|
||||
// ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825
|
||||
// ".udev" added to address https://github.com/opencontainers/runc/issues/2093
|
||||
case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts", ".udev":
|
||||
continue
|
||||
default:
|
||||
var cp string
|
||||
if containerPath != "" {
|
||||
cp = filepath.Join(containerPath, filepath.Base(f.Name()))
|
||||
}
|
||||
sub, err := getDevices(filepath.Join(path, f.Name()), cp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out = append(out, sub...)
|
||||
continue
|
||||
}
|
||||
case f.Name() == "console":
|
||||
continue
|
||||
}
|
||||
device, err := deviceFromPath(filepath.Join(path, f.Name()))
|
||||
if err != nil {
|
||||
if err == errNotADevice {
|
||||
continue
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if containerPath != "" {
|
||||
device.Path = filepath.Join(containerPath, filepath.Base(f.Name()))
|
||||
}
|
||||
out = append(out, *device)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func deviceFromPath(path string) (*specs.LinuxDevice, error) {
|
||||
var stat unix.Stat_t
|
||||
if err := unix.Lstat(path, &stat); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
devNumber = uint64(stat.Rdev) //nolint: unconvert // the type is 32bit on mips.
|
||||
major = unix.Major(devNumber)
|
||||
minor = unix.Minor(devNumber)
|
||||
)
|
||||
if major == 0 {
|
||||
return nil, errNotADevice
|
||||
}
|
||||
|
||||
var (
|
||||
devType string
|
||||
mode = stat.Mode
|
||||
)
|
||||
switch {
|
||||
case mode&unix.S_IFBLK == unix.S_IFBLK:
|
||||
devType = "b"
|
||||
case mode&unix.S_IFCHR == unix.S_IFCHR:
|
||||
devType = "c"
|
||||
}
|
||||
fm := os.FileMode(mode &^ unix.S_IFMT)
|
||||
return &specs.LinuxDevice{
|
||||
Type: devType,
|
||||
Path: path,
|
||||
Major: int64(major),
|
||||
Minor: int64(minor),
|
||||
FileMode: &fm,
|
||||
UID: &stat.Uid,
|
||||
GID: &stat.Gid,
|
||||
}, nil
|
||||
}
|
192
vendor/github.com/containerd/containerd/pkg/cap/cap_linux.go
generated
vendored
Normal file
192
vendor/github.com/containerd/containerd/pkg/cap/cap_linux.go
generated
vendored
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
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 cap provides Linux capability utility
|
||||
package cap
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// FromNumber returns a cap string like "CAP_SYS_ADMIN"
|
||||
// that corresponds to the given number like 21.
|
||||
//
|
||||
// FromNumber returns an empty string for unknown cap number.
|
||||
func FromNumber(num int) string {
|
||||
if num < 0 || num > len(capsLatest)-1 {
|
||||
return ""
|
||||
}
|
||||
return capsLatest[num]
|
||||
}
|
||||
|
||||
// FromBitmap parses an uint64 bitmap into string slice like
|
||||
// []{"CAP_SYS_ADMIN", ...}.
|
||||
//
|
||||
// Unknown cap numbers are returned as []int.
|
||||
func FromBitmap(v uint64) ([]string, []int) {
|
||||
var (
|
||||
res []string
|
||||
unknown []int
|
||||
)
|
||||
for i := 0; i <= 63; i++ {
|
||||
if b := (v >> i) & 0x1; b == 0x1 {
|
||||
if s := FromNumber(i); s != "" {
|
||||
res = append(res, s)
|
||||
} else {
|
||||
unknown = append(unknown, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
return res, unknown
|
||||
}
|
||||
|
||||
// Type is the type of capability
|
||||
type Type int
|
||||
|
||||
const (
|
||||
// Effective is CapEff
|
||||
Effective Type = 1 << iota
|
||||
// Permitted is CapPrm
|
||||
Permitted
|
||||
// Inheritable is CapInh
|
||||
Inheritable
|
||||
// Bounding is CapBnd
|
||||
Bounding
|
||||
// Ambient is CapAmb
|
||||
Ambient
|
||||
)
|
||||
|
||||
// ParseProcPIDStatus returns uint64 bitmap value from /proc/<PID>/status file
|
||||
func ParseProcPIDStatus(r io.Reader) (map[Type]uint64, error) {
|
||||
res := make(map[Type]uint64)
|
||||
scanner := bufio.NewScanner(r)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
pair := strings.SplitN(line, ":", 2)
|
||||
if len(pair) != 2 {
|
||||
continue
|
||||
}
|
||||
k := strings.TrimSpace(pair[0])
|
||||
v := strings.TrimSpace(pair[1])
|
||||
switch k {
|
||||
case "CapInh", "CapPrm", "CapEff", "CapBnd", "CapAmb":
|
||||
ui64, err := strconv.ParseUint(v, 16, 64)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to parse line %q", line)
|
||||
}
|
||||
switch k {
|
||||
case "CapInh":
|
||||
res[Inheritable] = ui64
|
||||
case "CapPrm":
|
||||
res[Permitted] = ui64
|
||||
case "CapEff":
|
||||
res[Effective] = ui64
|
||||
case "CapBnd":
|
||||
res[Bounding] = ui64
|
||||
case "CapAmb":
|
||||
res[Ambient] = ui64
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Current returns the list of the effective and the known caps of
|
||||
// the current process.
|
||||
//
|
||||
// The result is like []string{"CAP_SYS_ADMIN", ...}.
|
||||
//
|
||||
// The result does not contain caps that are not recognized by
|
||||
// the "github.com/syndtr/gocapability" library.
|
||||
func Current() ([]string, error) {
|
||||
f, err := os.Open("/proc/self/status")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
caps, err := ParseProcPIDStatus(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
capEff := caps[Effective]
|
||||
names, _ := FromBitmap(capEff)
|
||||
return names, nil
|
||||
}
|
||||
|
||||
var (
|
||||
// caps35 is the caps of kernel 3.5 (37 entries)
|
||||
caps35 = []string{
|
||||
"CAP_CHOWN", // 2.2
|
||||
"CAP_DAC_OVERRIDE", // 2.2
|
||||
"CAP_DAC_READ_SEARCH", // 2.2
|
||||
"CAP_FOWNER", // 2.2
|
||||
"CAP_FSETID", // 2.2
|
||||
"CAP_KILL", // 2.2
|
||||
"CAP_SETGID", // 2.2
|
||||
"CAP_SETUID", // 2.2
|
||||
"CAP_SETPCAP", // 2.2
|
||||
"CAP_LINUX_IMMUTABLE", // 2.2
|
||||
"CAP_NET_BIND_SERVICE", // 2.2
|
||||
"CAP_NET_BROADCAST", // 2.2
|
||||
"CAP_NET_ADMIN", // 2.2
|
||||
"CAP_NET_RAW", // 2.2
|
||||
"CAP_IPC_LOCK", // 2.2
|
||||
"CAP_IPC_OWNER", // 2.2
|
||||
"CAP_SYS_MODULE", // 2.2
|
||||
"CAP_SYS_RAWIO", // 2.2
|
||||
"CAP_SYS_CHROOT", // 2.2
|
||||
"CAP_SYS_PTRACE", // 2.2
|
||||
"CAP_SYS_PACCT", // 2.2
|
||||
"CAP_SYS_ADMIN", // 2.2
|
||||
"CAP_SYS_BOOT", // 2.2
|
||||
"CAP_SYS_NICE", // 2.2
|
||||
"CAP_SYS_RESOURCE", // 2.2
|
||||
"CAP_SYS_TIME", // 2.2
|
||||
"CAP_SYS_TTY_CONFIG", // 2.2
|
||||
"CAP_MKNOD", // 2.4
|
||||
"CAP_LEASE", // 2.4
|
||||
"CAP_AUDIT_WRITE", // 2.6.11
|
||||
"CAP_AUDIT_CONTROL", // 2.6.11
|
||||
"CAP_SETFCAP", // 2.6.24
|
||||
"CAP_MAC_OVERRIDE", // 2.6.25
|
||||
"CAP_MAC_ADMIN", // 2.6.25
|
||||
"CAP_SYSLOG", // 2.6.37
|
||||
"CAP_WAKE_ALARM", // 3.0
|
||||
"CAP_BLOCK_SUSPEND", // 3.5
|
||||
}
|
||||
// caps316 is the caps of kernel 3.16 (38 entries)
|
||||
caps316 = append(caps35, "CAP_AUDIT_READ")
|
||||
// caps58 is the caps of kernel 5.8 (40 entries)
|
||||
caps58 = append(caps316, []string{"CAP_PERFMON", "CAP_BPF"}...)
|
||||
// caps59 is the caps of kernel 5.9 (41 entries)
|
||||
caps59 = append(caps58, "CAP_CHECKPOINT_RESTORE")
|
||||
capsLatest = caps59
|
||||
)
|
||||
|
||||
// Known returns the known cap strings of the latest kernel.
|
||||
// The current latest kernel is 5.9.
|
||||
func Known() []string {
|
||||
return capsLatest
|
||||
}
|
192
vendor/github.com/containerd/cri/pkg/cap/cap_linux.go
generated
vendored
Normal file
192
vendor/github.com/containerd/cri/pkg/cap/cap_linux.go
generated
vendored
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
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 cap provides Linux capability utility
|
||||
package cap
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// FromNumber returns a cap string like "CAP_SYS_ADMIN"
|
||||
// that corresponds to the given number like 21.
|
||||
//
|
||||
// FromNumber returns an empty string for unknown cap number.
|
||||
func FromNumber(num int) string {
|
||||
if num < 0 || num > len(capsLatest)-1 {
|
||||
return ""
|
||||
}
|
||||
return capsLatest[num]
|
||||
}
|
||||
|
||||
// FromBitmap parses an uint64 bitmap into string slice like
|
||||
// []{"CAP_SYS_ADMIN", ...}.
|
||||
//
|
||||
// Unknown cap numbers are returned as []int.
|
||||
func FromBitmap(v uint64) ([]string, []int) {
|
||||
var (
|
||||
res []string
|
||||
unknown []int
|
||||
)
|
||||
for i := 0; i <= 63; i++ {
|
||||
if b := (v >> i) & 0x1; b == 0x1 {
|
||||
if s := FromNumber(i); s != "" {
|
||||
res = append(res, s)
|
||||
} else {
|
||||
unknown = append(unknown, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
return res, unknown
|
||||
}
|
||||
|
||||
// Type is the type of capability
|
||||
type Type int
|
||||
|
||||
const (
|
||||
// Effective is CapEff
|
||||
Effective Type = 1 << iota
|
||||
// Permitted is CapPrm
|
||||
Permitted
|
||||
// Inheritable is CapInh
|
||||
Inheritable
|
||||
// Bounding is CapBnd
|
||||
Bounding
|
||||
// Ambient is CapAmb
|
||||
Ambient
|
||||
)
|
||||
|
||||
// ParseProcPIDStatus returns uint64 bitmap value from /proc/<PID>/status file
|
||||
func ParseProcPIDStatus(r io.Reader) (map[Type]uint64, error) {
|
||||
res := make(map[Type]uint64)
|
||||
scanner := bufio.NewScanner(r)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
pair := strings.SplitN(line, ":", 2)
|
||||
if len(pair) != 2 {
|
||||
continue
|
||||
}
|
||||
k := strings.TrimSpace(pair[0])
|
||||
v := strings.TrimSpace(pair[1])
|
||||
switch k {
|
||||
case "CapInh", "CapPrm", "CapEff", "CapBnd", "CapAmb":
|
||||
ui64, err := strconv.ParseUint(v, 16, 64)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to parse line %q", line)
|
||||
}
|
||||
switch k {
|
||||
case "CapInh":
|
||||
res[Inheritable] = ui64
|
||||
case "CapPrm":
|
||||
res[Permitted] = ui64
|
||||
case "CapEff":
|
||||
res[Effective] = ui64
|
||||
case "CapBnd":
|
||||
res[Bounding] = ui64
|
||||
case "CapAmb":
|
||||
res[Ambient] = ui64
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Current returns the list of the effective and the known caps of
|
||||
// the current process.
|
||||
//
|
||||
// The result is like []string{"CAP_SYS_ADMIN", ...}.
|
||||
//
|
||||
// The result does not contain caps that are not recognized by
|
||||
// the "github.com/syndtr/gocapability" library.
|
||||
func Current() ([]string, error) {
|
||||
f, err := os.Open("/proc/self/status")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
caps, err := ParseProcPIDStatus(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
capEff := caps[Effective]
|
||||
names, _ := FromBitmap(capEff)
|
||||
return names, nil
|
||||
}
|
||||
|
||||
var (
|
||||
// caps35 is the caps of kernel 3.5 (37 entries)
|
||||
caps35 = []string{
|
||||
"CAP_CHOWN", // 2.2
|
||||
"CAP_DAC_OVERRIDE", // 2.2
|
||||
"CAP_DAC_READ_SEARCH", // 2.2
|
||||
"CAP_FOWNER", // 2.2
|
||||
"CAP_FSETID", // 2.2
|
||||
"CAP_KILL", // 2.2
|
||||
"CAP_SETGID", // 2.2
|
||||
"CAP_SETUID", // 2.2
|
||||
"CAP_SETPCAP", // 2.2
|
||||
"CAP_LINUX_IMMUTABLE", // 2.2
|
||||
"CAP_NET_BIND_SERVICE", // 2.2
|
||||
"CAP_NET_BROADCAST", // 2.2
|
||||
"CAP_NET_ADMIN", // 2.2
|
||||
"CAP_NET_RAW", // 2.2
|
||||
"CAP_IPC_LOCK", // 2.2
|
||||
"CAP_IPC_OWNER", // 2.2
|
||||
"CAP_SYS_MODULE", // 2.2
|
||||
"CAP_SYS_RAWIO", // 2.2
|
||||
"CAP_SYS_CHROOT", // 2.2
|
||||
"CAP_SYS_PTRACE", // 2.2
|
||||
"CAP_SYS_PACCT", // 2.2
|
||||
"CAP_SYS_ADMIN", // 2.2
|
||||
"CAP_SYS_BOOT", // 2.2
|
||||
"CAP_SYS_NICE", // 2.2
|
||||
"CAP_SYS_RESOURCE", // 2.2
|
||||
"CAP_SYS_TIME", // 2.2
|
||||
"CAP_SYS_TTY_CONFIG", // 2.2
|
||||
"CAP_MKNOD", // 2.4
|
||||
"CAP_LEASE", // 2.4
|
||||
"CAP_AUDIT_WRITE", // 2.6.11
|
||||
"CAP_AUDIT_CONTROL", // 2.6.11
|
||||
"CAP_SETFCAP", // 2.6.24
|
||||
"CAP_MAC_OVERRIDE", // 2.6.25
|
||||
"CAP_MAC_ADMIN", // 2.6.25
|
||||
"CAP_SYSLOG", // 2.6.37
|
||||
"CAP_WAKE_ALARM", // 3.0
|
||||
"CAP_BLOCK_SUSPEND", // 3.5
|
||||
}
|
||||
// caps316 is the caps of kernel 3.16 (38 entries)
|
||||
caps316 = append(caps35, "CAP_AUDIT_READ")
|
||||
// caps58 is the caps of kernel 5.8 (40 entries)
|
||||
caps58 = append(caps316, []string{"CAP_PERFMON", "CAP_BPF"}...)
|
||||
// caps59 is the caps of kernel 5.9 (41 entries)
|
||||
caps59 = append(caps58, "CAP_CHECKPOINT_RESTORE")
|
||||
capsLatest = caps59
|
||||
)
|
||||
|
||||
// Known returns the known cap strings of the latest kernel.
|
||||
// The current latest kernel is 5.9.
|
||||
func Known() []string {
|
||||
return capsLatest
|
||||
}
|
4
vendor/github.com/containerd/cri/pkg/containerd/opts/spec_unix.go
generated
vendored
4
vendor/github.com/containerd/cri/pkg/containerd/opts/spec_unix.go
generated
vendored
@ -332,7 +332,7 @@ func WithDevices(osi osinterface.OS, config *runtime.ContainerConfig) oci.SpecOp
|
||||
}
|
||||
|
||||
// WithCapabilities sets the provided capabilties from the security context
|
||||
func WithCapabilities(sc *runtime.LinuxContainerSecurityContext) oci.SpecOpts {
|
||||
func WithCapabilities(sc *runtime.LinuxContainerSecurityContext, allCaps []string) oci.SpecOpts {
|
||||
capabilities := sc.GetCapabilities()
|
||||
if capabilities == nil {
|
||||
return nullOpt
|
||||
@ -344,7 +344,7 @@ func WithCapabilities(sc *runtime.LinuxContainerSecurityContext) oci.SpecOpts {
|
||||
// AddCapabilities: []string{"ALL"}, DropCapabilities: []string{"CHOWN"}
|
||||
// will be all capabilities without `CAP_CHOWN`.
|
||||
if util.InStringSlice(capabilities.GetAddCapabilities(), "ALL") {
|
||||
opts = append(opts, oci.WithAllCapabilities)
|
||||
opts = append(opts, oci.WithCapabilities(allCaps))
|
||||
}
|
||||
if util.InStringSlice(capabilities.GetDropCapabilities(), "ALL") {
|
||||
opts = append(opts, oci.WithCapabilities(nil))
|
||||
|
4
vendor/github.com/containerd/cri/pkg/server/container_create_unix.go
generated
vendored
4
vendor/github.com/containerd/cri/pkg/server/container_create_unix.go
generated
vendored
@ -203,10 +203,10 @@ func (c *criService) containerSpec(id string, sandboxID string, sandboxPid uint3
|
||||
specOpts = append(specOpts, oci.WithHostDevices, oci.WithAllDevicesAllowed)
|
||||
} else {
|
||||
// add requested devices by the config as host devices are not automatically added
|
||||
specOpts = append(specOpts, customopts.WithDevices(c.os, config), customopts.WithCapabilities(securityContext))
|
||||
specOpts = append(specOpts, customopts.WithDevices(c.os, config), customopts.WithCapabilities(securityContext, c.allCaps))
|
||||
}
|
||||
} else { // not privileged
|
||||
specOpts = append(specOpts, customopts.WithDevices(c.os, config), customopts.WithCapabilities(securityContext))
|
||||
specOpts = append(specOpts, customopts.WithDevices(c.os, config), customopts.WithCapabilities(securityContext, c.allCaps))
|
||||
}
|
||||
|
||||
// Clear all ambient capabilities. The implication of non-root + caps
|
||||
|
3
vendor/github.com/containerd/cri/pkg/server/service.go
generated
vendored
3
vendor/github.com/containerd/cri/pkg/server/service.go
generated
vendored
@ -101,6 +101,9 @@ type criService struct {
|
||||
cniNetConfMonitor *cniNetConfSyncer
|
||||
// baseOCISpecs contains cached OCI specs loaded via `Runtime.BaseRuntimeSpec`
|
||||
baseOCISpecs map[string]*oci.Spec
|
||||
// allCaps is the list of the capabilities.
|
||||
// When nil, parsed from CapEff of /proc/self/status.
|
||||
allCaps []string // nolint
|
||||
}
|
||||
|
||||
// NewCRIService returns a new instance of CRIService
|
||||
|
8
vendor/github.com/containerd/cri/pkg/server/service_unix.go
generated
vendored
8
vendor/github.com/containerd/cri/pkg/server/service_unix.go
generated
vendored
@ -20,6 +20,7 @@ package server
|
||||
|
||||
import (
|
||||
"github.com/containerd/containerd/sys"
|
||||
"github.com/containerd/cri/pkg/cap"
|
||||
cni "github.com/containerd/go-cni"
|
||||
"github.com/opencontainers/selinux/go-selinux"
|
||||
"github.com/pkg/errors"
|
||||
@ -63,6 +64,13 @@ func (c *criService) initPlatform() error {
|
||||
return errors.Wrap(err, "failed to initialize cni")
|
||||
}
|
||||
|
||||
if c.allCaps == nil {
|
||||
c.allCaps, err = cap.Current()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get caps")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
10
vendor/modules.txt
vendored
10
vendor/modules.txt
vendored
@ -173,7 +173,7 @@ github.com/containerd/cgroups/v2
|
||||
github.com/containerd/cgroups/v2/stats
|
||||
# github.com/containerd/console v1.0.2 => github.com/containerd/console v1.0.0
|
||||
github.com/containerd/console
|
||||
# github.com/containerd/containerd v1.5.0-beta.4 => github.com/k3s-io/containerd v1.4.4-k3s1
|
||||
# github.com/containerd/containerd v1.5.0-beta.4 => github.com/k3s-io/containerd v1.4.4-k3s2
|
||||
## explicit
|
||||
github.com/containerd/containerd
|
||||
github.com/containerd/containerd/api/events
|
||||
@ -249,6 +249,7 @@ github.com/containerd/containerd/metrics/types/v2
|
||||
github.com/containerd/containerd/mount
|
||||
github.com/containerd/containerd/namespaces
|
||||
github.com/containerd/containerd/oci
|
||||
github.com/containerd/containerd/pkg/cap
|
||||
github.com/containerd/containerd/pkg/dialer
|
||||
github.com/containerd/containerd/pkg/oom
|
||||
github.com/containerd/containerd/pkg/oom/v1
|
||||
@ -317,12 +318,13 @@ github.com/containerd/continuity/fs
|
||||
github.com/containerd/continuity/pathdriver
|
||||
github.com/containerd/continuity/proto
|
||||
github.com/containerd/continuity/sysx
|
||||
# github.com/containerd/cri v1.11.1-0.20200820101445-b0cc07999aa5 => github.com/k3s-io/cri v1.4.0-k3s.5
|
||||
# github.com/containerd/cri v1.11.1-0.20200820101445-b0cc07999aa5 => github.com/k3s-io/cri v1.4.0-k3s.6
|
||||
## explicit
|
||||
github.com/containerd/cri
|
||||
github.com/containerd/cri/pkg/annotations
|
||||
github.com/containerd/cri/pkg/api/runtimeoptions/v1
|
||||
github.com/containerd/cri/pkg/atomic
|
||||
github.com/containerd/cri/pkg/cap
|
||||
github.com/containerd/cri/pkg/config
|
||||
github.com/containerd/cri/pkg/constants
|
||||
github.com/containerd/cri/pkg/containerd/opts
|
||||
@ -3179,9 +3181,9 @@ sigs.k8s.io/yaml
|
||||
# github.com/containerd/btrfs => github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e
|
||||
# github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340
|
||||
# github.com/containerd/console => github.com/containerd/console v1.0.0
|
||||
# github.com/containerd/containerd => github.com/k3s-io/containerd v1.4.4-k3s1
|
||||
# github.com/containerd/containerd => github.com/k3s-io/containerd v1.4.4-k3s2
|
||||
# github.com/containerd/continuity => github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1
|
||||
# github.com/containerd/cri => github.com/k3s-io/cri v1.4.0-k3s.5
|
||||
# github.com/containerd/cri => github.com/k3s-io/cri v1.4.0-k3s.6
|
||||
# github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b
|
||||
# github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328
|
||||
# github.com/containerd/ttrpc => github.com/containerd/ttrpc v1.0.1
|
||||
|
Loading…
Reference in New Issue
Block a user