github.com/ld86/docker@v1.7.1-rc3/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 struct {
    34  		Key   string         `json:"key,omitempty"`
    35  		Value capability.Cap `json:"value,omitempty"`
    36  	}
    37  	Capabilities []*CapabilityMapping
    38  )
    39  
    40  func (c *CapabilityMapping) String() string {
    41  	return c.Key
    42  }
    43  
    44  func GetCapability(key string) *CapabilityMapping {
    45  	for _, capp := range capabilityList {
    46  		if capp.Key == key {
    47  			cpy := *capp
    48  			return &cpy
    49  		}
    50  	}
    51  	return nil
    52  }
    53  
    54  func GetAllCapabilities() []string {
    55  	output := make([]string, len(capabilityList))
    56  	for i, capability := range capabilityList {
    57  		output[i] = capability.String()
    58  	}
    59  	return output
    60  }
    61  
    62  func TweakCapabilities(basics, adds, drops []string) ([]string, error) {
    63  	var (
    64  		newCaps []string
    65  		allCaps = GetAllCapabilities()
    66  	)
    67  
    68  	// look for invalid cap in the drop list
    69  	for _, cap := range drops {
    70  		if strings.ToLower(cap) == "all" {
    71  			continue
    72  		}
    73  		if !stringutils.InSlice(allCaps, cap) {
    74  			return nil, fmt.Errorf("Unknown capability drop: %q", cap)
    75  		}
    76  	}
    77  
    78  	// handle --cap-add=all
    79  	if stringutils.InSlice(adds, "all") {
    80  		basics = allCaps
    81  	}
    82  
    83  	if !stringutils.InSlice(drops, "all") {
    84  		for _, cap := range basics {
    85  			// skip `all` aready handled above
    86  			if strings.ToLower(cap) == "all" {
    87  				continue
    88  			}
    89  
    90  			// if we don't drop `all`, add back all the non-dropped caps
    91  			if !stringutils.InSlice(drops, cap) {
    92  				newCaps = append(newCaps, strings.ToUpper(cap))
    93  			}
    94  		}
    95  	}
    96  
    97  	for _, cap := range adds {
    98  		// skip `all` aready handled above
    99  		if strings.ToLower(cap) == "all" {
   100  			continue
   101  		}
   102  
   103  		if !stringutils.InSlice(allCaps, cap) {
   104  			return nil, fmt.Errorf("Unknown capability to add: %q", cap)
   105  		}
   106  
   107  		// add cap if not already in the list
   108  		if !stringutils.InSlice(newCaps, cap) {
   109  			newCaps = append(newCaps, strings.ToUpper(cap))
   110  		}
   111  	}
   112  
   113  	return newCaps, nil
   114  }