Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pgk/capabilities: modernize, switch to github.com/moby/sys/capability #2167

Merged
merged 5 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ require (
github.com/hashicorp/go-multierror v1.1.1
github.com/jinzhu/copier v0.4.0
github.com/json-iterator/go v1.1.12
github.com/moby/sys/capability v0.3.0
github.com/onsi/ginkgo/v2 v2.20.2
github.com/onsi/gomega v1.34.2
github.com/opencontainers/go-digest v1.0.0
Expand All @@ -41,7 +42,6 @@ require (
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.9.0
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
github.com/vishvananda/netlink v1.3.0
go.etcd.io/bbolt v1.3.11
golang.org/x/crypto v0.27.0
Expand Down Expand Up @@ -124,6 +124,7 @@ require (
github.com/sigstore/sigstore v1.8.4 // indirect
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect
github.com/sylabs/sif/v2 v2.18.0 // indirect
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/sys/capability v0.3.0 h1:kEP+y6te0gEXIaeQhIi0s7vKs/w0RPoH1qPa6jROcVg=
github.com/moby/sys/capability v0.3.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I=
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo=
Expand Down
115 changes: 56 additions & 59 deletions pkg/capabilities/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,13 @@ import (
"errors"
"fmt"
"slices"
"sort"
"strings"
"sync"

"github.com/syndtr/gocapability/capability"
"github.com/moby/sys/capability"
)

var (
// Used internally and populated during init().
capabilityList []string

// Used internally and populated during init().
capsList []capability.Cap

// ErrUnknownCapability is thrown when an unknown capability is processed.
ErrUnknownCapability = errors.New("unknown capability")

Expand All @@ -35,67 +28,67 @@ var (
// Useful on the CLI for `--cap-add=all` etc.
const All = "ALL"

func getCapName(c capability.Cap) string {
func capName(c capability.Cap) string {
return "CAP_" + strings.ToUpper(c.String())
}

func init() {
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
// capStrList returns all capabilities supported by the currently running kernel,
// or an error if the list can not be obtained.
var capStrList = sync.OnceValues(func() ([]string, error) {
list, err := capability.ListSupported()
if err != nil {
return nil, err
}
for _, cap := range capability.List() {
if cap > last {
continue
}
capsList = append(capsList, cap)
capabilityList = append(capabilityList, getCapName(cap))
sort.Strings(capabilityList)
caps := make([]string, len(list))
for i, c := range list {
caps[i] = capName(c)
}
}

var (
boundingSetOnce sync.Once
boundingSetRet []string
boundingSetErr error
)
slices.Sort(caps)
return caps, nil
})

// BoundingSet returns the capabilities in the current bounding set
// BoundingSet returns the capabilities in the current bounding set.
func BoundingSet() ([]string, error) {
boundingSetOnce.Do(func() {
currentCaps, err := capability.NewPid2(0)
if err != nil {
boundingSetErr = err
return
}
err = currentCaps.Load()
if err != nil {
boundingSetErr = err
return
}
var r []string
for _, c := range capsList {
if !currentCaps.Get(capability.BOUNDING, c) {
continue
}
r = append(r, getCapName(c))
}
boundingSetRet = r
sort.Strings(boundingSetRet)
boundingSetErr = err
})
return boundingSetRet, boundingSetErr
return boundingSet()
}

// AllCapabilities returns all known capabilities.
var boundingSet = sync.OnceValues(func() ([]string, error) {
currentCaps, err := capability.NewPid2(0)
if err != nil {
return nil, err
}
err = currentCaps.Load()
if err != nil {
return nil, err
}
list, err := capability.ListSupported()
if err != nil {
return nil, err
}
var r []string
for _, c := range list {
if !currentCaps.Get(capability.BOUNDING, c) {
continue
}
r = append(r, capName(c))
}
slices.Sort(r)
return r, nil
})

// AllCapabilities returns all capabilities supported by the running kernel.
func AllCapabilities() []string {
return capabilityList
list, _ := capStrList()
return list
}

// NormalizeCapabilities normalizes caps by adding a "CAP_" prefix (if not yet
// present).
func NormalizeCapabilities(caps []string) ([]string, error) {
all, err := capStrList()
if err != nil {
return nil, err
}
normalized := make([]string, 0, len(caps))
for _, c := range caps {
c = strings.ToUpper(c)
Expand All @@ -106,19 +99,23 @@ func NormalizeCapabilities(caps []string) ([]string, error) {
if !strings.HasPrefix(c, "CAP_") {
c = "CAP_" + c
}
if !slices.Contains(capabilityList, c) {
if !slices.Contains(all, c) {
return nil, fmt.Errorf("%q: %w", c, ErrUnknownCapability)
}
normalized = append(normalized, c)
}
sort.Strings(normalized)
slices.Sort(normalized)
return normalized, nil
}

// ValidateCapabilities validates if caps only contains valid capabilities.
func ValidateCapabilities(caps []string) error {
all, err := capStrList()
if err != nil {
return err
}
for _, c := range caps {
if !slices.Contains(capabilityList, c) {
if !slices.Contains(all, c) {
return fmt.Errorf("%q: %w", c, ErrUnknownCapability)
}
}
Expand Down Expand Up @@ -155,7 +152,7 @@ func MergeCapabilities(base, adds, drops []string) ([]string, error) {
return nil, errors.New("adding all caps and removing all caps not allowed")
}
// "Drop" all capabilities; return what's in capAdd instead
sort.Strings(capAdd)
slices.Sort(capAdd)
return capAdd, nil
}

Expand Down Expand Up @@ -195,6 +192,6 @@ func MergeCapabilities(base, adds, drops []string) ([]string, error) {
}
caps = append(caps, cap)
}
sort.Strings(caps)
slices.Sort(caps)
return caps, nil
}
3 changes: 3 additions & 0 deletions vendor/github.com/moby/sys/capability/.codespellrc

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions vendor/github.com/moby/sys/capability/.golangci.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

90 changes: 90 additions & 0 deletions vendor/github.com/moby/sys/capability/CHANGELOG.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions vendor/github.com/moby/sys/capability/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions vendor/github.com/moby/sys/capability/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading