plugins: linux capabilities and device creation

In the plugin manifest, Capabilities has been moved to
Linux.Capabilities to avoid confusion with Interface.Types[i].Capability

A DeviceCreation boolean has also been added to the manifest. This could
be changed in the future to be specific to a major number.

Signed-off-by: Tibor Vass <tibor@docker.com>
This commit is contained in:
Tibor Vass 2016-09-09 09:27:53 -07:00
parent eac91a19d6
commit 9f239281b1
3 changed files with 59 additions and 17 deletions

View file

@ -1311,9 +1311,10 @@ definitions:
- Entrypoint
- Workdir
- Network
- Capabilities
- Linux
- Mounts
- Devices
- DeviceCreation
- Env
- Args
properties:
@ -1361,10 +1362,15 @@ definitions:
Type:
x-nullable: false
type: "string"
Capabilities:
type: "array"
items:
type: "string"
Linux:
type: "object"
x-nullable: false
required: [Capabilities]
properties:
Capabilities:
type: "array"
items:
type: "string"
Mounts:
type: "array"
items:
@ -1373,6 +1379,9 @@ definitions:
type: "array"
items:
$ref: "#/definitions/PluginDevice"
DeviceCreation:
type: "boolean"
x-nullable: false
Env:
type: "array"
items:

View file

@ -39,14 +39,14 @@ type PluginConfig struct {
// Required: true
Args PluginConfigArgs `json:"Args"`
// capabilities
// Required: true
Capabilities []string `json:"Capabilities"`
// description
// Required: true
Description string `json:"Description"`
// device creation
// Required: true
DeviceCreation bool `json:"DeviceCreation"`
// devices
// Required: true
Devices []PluginDevice `json:"Devices"`
@ -67,6 +67,10 @@ type PluginConfig struct {
// Required: true
Interface PluginConfigInterface `json:"Interface"`
// linux
// Required: true
Linux PluginConfigLinux `json:"Linux"`
// mounts
// Required: true
Mounts []PluginMount `json:"Mounts"`
@ -117,6 +121,15 @@ type PluginConfigInterface struct {
Types []PluginInterfaceType `json:"Types"`
}
// PluginConfigLinux plugin config linux
// swagger:model PluginConfigLinux
type PluginConfigLinux struct {
// capabilities
// Required: true
Capabilities []string `json:"Capabilities"`
}
// PluginConfigNetwork plugin config network
// swagger:model PluginConfigNetwork
type PluginConfigNetwork struct {

View file

@ -242,11 +242,18 @@ func (p *Plugin) ComputePrivileges() types.PluginPrivileges {
})
}
}
if len(m.Capabilities) > 0 {
if m.DeviceCreation {
privileges = append(privileges, types.PluginPrivilege{
Name: "device-creation",
Description: "",
Value: []string{"true"},
})
}
if len(m.Linux.Capabilities) > 0 {
privileges = append(privileges, types.PluginPrivilege{
Name: "capabilities",
Description: "",
Value: m.Capabilities,
Value: m.Linux.Capabilities,
})
}
return privileges
@ -292,6 +299,11 @@ func (p *Plugin) InitSpec(s specs.Spec, libRoot string) (*specs.Spec, error) {
Readonly: false, // TODO: all plugins should be readonly? settable in config?
}
if p.PluginObj.Config.DeviceCreation {
rwm := "rwm"
s.Linux.Resources.Devices = []specs.DeviceCgroup{{Allow: true, Access: &rwm}}
}
mounts := append(p.PluginObj.Settings.Mounts, types.PluginMount{
Source: &p.RuntimeSourcePath,
Destination: defaultPluginRuntimeDestination,
@ -322,6 +334,12 @@ func (p *Plugin) InitSpec(s specs.Spec, libRoot string) (*specs.Spec, error) {
s.Mounts = append(s.Mounts, m)
}
for i, m := range s.Mounts {
if strings.HasPrefix(m.Destination, "/dev/") && true { // TODO: && user specified /dev
s.Mounts = append(s.Mounts[:i], s.Mounts[i+1:]...)
}
}
envs := make([]string, 1, len(p.PluginObj.Settings.Env)+1)
envs[0] = "PATH=" + system.DefaultPathEnv
envs = append(envs, p.PluginObj.Settings.Env...)
@ -331,12 +349,14 @@ func (p *Plugin) InitSpec(s specs.Spec, libRoot string) (*specs.Spec, error) {
if len(cwd) == 0 {
cwd = "/"
}
s.Process = specs.Process{
Terminal: false,
Args: args,
Cwd: cwd,
Env: envs,
}
s.Process.Terminal = false
s.Process.Args = args
s.Process.Cwd = cwd
s.Process.Env = envs
// TODO: what about duplicates?
// TODO: Should not need CAP_ prefix in manifest?
s.Process.Capabilities = append(s.Process.Capabilities, p.PluginObj.Config.Linux.Capabilities...)
return &s, nil
}