utils.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package execdriver
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/docker/docker/pkg/stringutils"
  6. "github.com/syndtr/gocapability/capability"
  7. )
  8. var capabilityList Capabilities
  9. func init() {
  10. last := capability.CAP_LAST_CAP
  11. // hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap
  12. if last == capability.Cap(63) {
  13. last = capability.CAP_BLOCK_SUSPEND
  14. }
  15. for _, cap := range capability.List() {
  16. if cap > last {
  17. continue
  18. }
  19. capabilityList = append(capabilityList,
  20. &CapabilityMapping{
  21. Key: strings.ToUpper(cap.String()),
  22. Value: cap,
  23. },
  24. )
  25. }
  26. }
  27. type (
  28. CapabilityMapping struct {
  29. Key string `json:"key,omitempty"`
  30. Value capability.Cap `json:"value,omitempty"`
  31. }
  32. Capabilities []*CapabilityMapping
  33. )
  34. func (c *CapabilityMapping) String() string {
  35. return c.Key
  36. }
  37. func GetCapability(key string) *CapabilityMapping {
  38. for _, capp := range capabilityList {
  39. if capp.Key == key {
  40. cpy := *capp
  41. return &cpy
  42. }
  43. }
  44. return nil
  45. }
  46. func GetAllCapabilities() []string {
  47. output := make([]string, len(capabilityList))
  48. for i, capability := range capabilityList {
  49. output[i] = capability.String()
  50. }
  51. return output
  52. }
  53. func TweakCapabilities(basics, adds, drops []string) ([]string, error) {
  54. var (
  55. newCaps []string
  56. allCaps = GetAllCapabilities()
  57. )
  58. // look for invalid cap in the drop list
  59. for _, cap := range drops {
  60. if strings.ToLower(cap) == "all" {
  61. continue
  62. }
  63. if !stringutils.InSlice(allCaps, cap) {
  64. return nil, fmt.Errorf("Unknown capability drop: %q", cap)
  65. }
  66. }
  67. // handle --cap-add=all
  68. if stringutils.InSlice(adds, "all") {
  69. basics = allCaps
  70. }
  71. if !stringutils.InSlice(drops, "all") {
  72. for _, cap := range basics {
  73. // skip `all` aready handled above
  74. if strings.ToLower(cap) == "all" {
  75. continue
  76. }
  77. // if we don't drop `all`, add back all the non-dropped caps
  78. if !stringutils.InSlice(drops, cap) {
  79. newCaps = append(newCaps, strings.ToUpper(cap))
  80. }
  81. }
  82. }
  83. for _, cap := range adds {
  84. // skip `all` aready handled above
  85. if strings.ToLower(cap) == "all" {
  86. continue
  87. }
  88. if !stringutils.InSlice(allCaps, cap) {
  89. return nil, fmt.Errorf("Unknown capability to add: %q", cap)
  90. }
  91. // add cap if not already in the list
  92. if !stringutils.InSlice(newCaps, cap) {
  93. newCaps = append(newCaps, strings.ToUpper(cap))
  94. }
  95. }
  96. return newCaps, nil
  97. }