Allow adding rules to cgroup devices.allow on container create/run

This introduce a new `--device-cgroup-rule` flag that allow a user to
add one or more entry to the container cgroup device `devices.allow`

Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
This commit is contained in:
Kenfe-Mickael Laventure 2016-05-06 15:09:46 -07:00
parent 96c7794e95
commit f33bf818a2
1 changed files with 20 additions and 0 deletions

View File

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"path" "path"
"regexp"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -21,6 +22,10 @@ import (
"github.com/spf13/pflag" "github.com/spf13/pflag"
) )
var (
deviceCgroupRuleRegexp = regexp.MustCompile("^[acb] ([0-9]+|\\*):([0-9]+|\\*) [rwm]{1,3}$")
)
// containerOptions is a data object with all the options for creating a container // containerOptions is a data object with all the options for creating a container
type containerOptions struct { type containerOptions struct {
attach opts.ListOpts attach opts.ListOpts
@ -36,6 +41,7 @@ type containerOptions struct {
deviceWriteIOps opts.ThrottledeviceOpt deviceWriteIOps opts.ThrottledeviceOpt
env opts.ListOpts env opts.ListOpts
labels opts.ListOpts labels opts.ListOpts
deviceCgroupRules opts.ListOpts
devices opts.ListOpts devices opts.ListOpts
ulimits *opts.UlimitOpt ulimits *opts.UlimitOpt
sysctls *opts.MapOpts sysctls *opts.MapOpts
@ -127,6 +133,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions {
dns: opts.NewListOpts(opts.ValidateIPAddress), dns: opts.NewListOpts(opts.ValidateIPAddress),
dnsOptions: opts.NewListOpts(nil), dnsOptions: opts.NewListOpts(nil),
dnsSearch: opts.NewListOpts(opts.ValidateDNSSearch), dnsSearch: opts.NewListOpts(opts.ValidateDNSSearch),
deviceCgroupRules: opts.NewListOpts(validateDeviceCgroupRule),
deviceReadBps: opts.NewThrottledeviceOpt(opts.ValidateThrottleBpsDevice), deviceReadBps: opts.NewThrottledeviceOpt(opts.ValidateThrottleBpsDevice),
deviceReadIOps: opts.NewThrottledeviceOpt(opts.ValidateThrottleIOpsDevice), deviceReadIOps: opts.NewThrottledeviceOpt(opts.ValidateThrottleIOpsDevice),
deviceWriteBps: opts.NewThrottledeviceOpt(opts.ValidateThrottleBpsDevice), deviceWriteBps: opts.NewThrottledeviceOpt(opts.ValidateThrottleBpsDevice),
@ -154,6 +161,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions {
// General purpose flags // General purpose flags
flags.VarP(&copts.attach, "attach", "a", "Attach to STDIN, STDOUT or STDERR") flags.VarP(&copts.attach, "attach", "a", "Attach to STDIN, STDOUT or STDERR")
flags.Var(&copts.deviceCgroupRules, "device-cgroup-rule", "Add a rule to the cgroup allowed devices list")
flags.Var(&copts.devices, "device", "Add a host device to the container") flags.Var(&copts.devices, "device", "Add a host device to the container")
flags.VarP(&copts.env, "env", "e", "Set environment variables") flags.VarP(&copts.env, "env", "e", "Set environment variables")
flags.Var(&copts.envFile, "env-file", "Read in a file of environment variables") flags.Var(&copts.envFile, "env-file", "Read in a file of environment variables")
@ -548,6 +556,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*container.Config, *c
IOMaximumIOps: copts.ioMaxIOps, IOMaximumIOps: copts.ioMaxIOps,
IOMaximumBandwidth: uint64(maxIOBandwidth), IOMaximumBandwidth: uint64(maxIOBandwidth),
Ulimits: copts.ulimits.GetList(), Ulimits: copts.ulimits.GetList(),
DeviceCgroupRules: copts.deviceCgroupRules.GetAll(),
Devices: deviceMappings, Devices: deviceMappings,
} }
@ -762,6 +771,17 @@ func parseDevice(device string) (container.DeviceMapping, error) {
return deviceMapping, nil return deviceMapping, nil
} }
// validateDeviceCgroupRule validates a device cgroup rule string format
// It will make sure 'val' is in the form:
// 'type major:minor mode'
func validateDeviceCgroupRule(val string) (string, error) {
if deviceCgroupRuleRegexp.MatchString(val) {
return val, nil
}
return val, fmt.Errorf("invalid device cgroup format '%s'", val)
}
// validDeviceMode checks if the mode for device is valid or not. // validDeviceMode checks if the mode for device is valid or not.
// Valid mode is a composition of r (read), w (write), and m (mknod). // Valid mode is a composition of r (read), w (write), and m (mknod).
func validDeviceMode(mode string) bool { func validDeviceMode(mode string) bool {