Ver Fonte

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>
Tibor Vass há 8 anos atrás
pai
commit
9f239281b1
3 ficheiros alterados com 59 adições e 17 exclusões
  1. 14 5
      api/swagger.yaml
  2. 17 4
      api/types/plugin.go
  3. 28 8
      plugin/v2/plugin.go

+ 14 - 5
api/swagger.yaml

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

+ 17 - 4
api/types/plugin.go

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

+ 28 - 8
plugin/v2/plugin.go

@@ -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{
 		privileges = append(privileges, types.PluginPrivilege{
 			Name:        "capabilities",
 			Name:        "capabilities",
 			Description: "",
 			Description: "",
-			Value:       m.Capabilities,
+			Value:       m.Linux.Capabilities,
 		})
 		})
 	}
 	}
 	return privileges
 	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?
 		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{
 	mounts := append(p.PluginObj.Settings.Mounts, types.PluginMount{
 		Source:      &p.RuntimeSourcePath,
 		Source:      &p.RuntimeSourcePath,
 		Destination: defaultPluginRuntimeDestination,
 		Destination: defaultPluginRuntimeDestination,
@@ -322,6 +334,12 @@ func (p *Plugin) InitSpec(s specs.Spec, libRoot string) (*specs.Spec, error) {
 		s.Mounts = append(s.Mounts, m)
 		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 := make([]string, 1, len(p.PluginObj.Settings.Env)+1)
 	envs[0] = "PATH=" + system.DefaultPathEnv
 	envs[0] = "PATH=" + system.DefaultPathEnv
 	envs = append(envs, p.PluginObj.Settings.Env...)
 	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 {
 	if len(cwd) == 0 {
 		cwd = "/"
 		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
 	return &s, nil
 }
 }