github.com/tompao/docker@v1.9.1/daemon/execdriver/utils.go (about) 1 package execdriver 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/docker/docker/pkg/stringutils" 8 "github.com/syndtr/gocapability/capability" 9 ) 10 11 var capabilityList Capabilities 12 13 func init() { 14 last := capability.CAP_LAST_CAP 15 // hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap 16 if last == capability.Cap(63) { 17 last = capability.CAP_BLOCK_SUSPEND 18 } 19 for _, cap := range capability.List() { 20 if cap > last { 21 continue 22 } 23 capabilityList = append(capabilityList, 24 &CapabilityMapping{ 25 Key: strings.ToUpper(cap.String()), 26 Value: cap, 27 }, 28 ) 29 } 30 } 31 32 type ( 33 // CapabilityMapping maps linux capability name to its value of capability.Cap type 34 // Capabilities is one of the security systems in Linux Security Module (LSM) 35 // framework provided by the kernel. 36 // For more details on capabilities, see http://man7.org/linux/man-pages/man7/capabilities.7.html 37 CapabilityMapping struct { 38 Key string `json:"key,omitempty"` 39 Value capability.Cap `json:"value,omitempty"` 40 } 41 // Capabilities contains all CapabilityMapping 42 Capabilities []*CapabilityMapping 43 ) 44 45 // String returns <key> of CapabilityMapping 46 func (c *CapabilityMapping) String() string { 47 return c.Key 48 } 49 50 // GetCapability returns CapabilityMapping which contains specific key 51 func GetCapability(key string) *CapabilityMapping { 52 for _, capp := range capabilityList { 53 if capp.Key == key { 54 cpy := *capp 55 return &cpy 56 } 57 } 58 return nil 59 } 60 61 // GetAllCapabilities returns all of the capabilities 62 func GetAllCapabilities() []string { 63 output := make([]string, len(capabilityList)) 64 for i, capability := range capabilityList { 65 output[i] = capability.String() 66 } 67 return output 68 } 69 70 // TweakCapabilities can tweak capabilities by adding or dropping capabilities 71 // based on the basics capabilities. 72 func TweakCapabilities(basics, adds, drops []string) ([]string, error) { 73 var ( 74 newCaps []string 75 allCaps = GetAllCapabilities() 76 ) 77 78 // look for invalid cap in the drop list 79 for _, cap := range drops { 80 if strings.ToLower(cap) == "all" { 81 continue 82 } 83 if !stringutils.InSlice(allCaps, cap) { 84 return nil, fmt.Errorf("Unknown capability drop: %q", cap) 85 } 86 } 87 88 // handle --cap-add=all 89 if stringutils.InSlice(adds, "all") { 90 basics = allCaps 91 } 92 93 if !stringutils.InSlice(drops, "all") { 94 for _, cap := range basics { 95 // skip `all` already handled above 96 if strings.ToLower(cap) == "all" { 97 continue 98 } 99 100 // if we don't drop `all`, add back all the non-dropped caps 101 if !stringutils.InSlice(drops, cap) { 102 newCaps = append(newCaps, strings.ToUpper(cap)) 103 } 104 } 105 } 106 107 for _, cap := range adds { 108 // skip `all` already handled above 109 if strings.ToLower(cap) == "all" { 110 continue 111 } 112 113 if !stringutils.InSlice(allCaps, cap) { 114 return nil, fmt.Errorf("Unknown capability to add: %q", cap) 115 } 116 117 // add cap if not already in the list 118 if !stringutils.InSlice(newCaps, cap) { 119 newCaps = append(newCaps, strings.ToUpper(cap)) 120 } 121 } 122 return newCaps, nil 123 }