From 6d6185c2577c473fa9046d73a850c09a254e9a81 Mon Sep 17 00:00:00 2001 From: Anusha Ragunathan Date: Tue, 7 Mar 2017 18:26:09 -0800 Subject: [PATCH 1/3] Add support in plugin config for accessing host ipc namespace. Plugins might need access to host ipc namespace. A good usecase is a volume plugin running iscsi multipath commands that need access to host kernel locks. Tested with a custom plugin (aragunathan/global-net-plugin-full) that's built with `"ipchost" : true` in config.json. Observed using `readlink /proc/self/ns/ipc` that plugin and host have the same ns. Signed-off-by: Anusha Ragunathan --- api/swagger.yaml | 4 ++++ api/types/plugin.go | 4 ++++ docs/extend/config.md | 3 +++ plugin/backend_linux.go | 7 +++++++ plugin/v2/plugin_linux.go | 4 ++++ 5 files changed, 22 insertions(+) diff --git a/api/swagger.yaml b/api/swagger.yaml index be71e0ffa3..254042115a 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -1446,6 +1446,7 @@ definitions: - Network - Linux - PropagatedMount + - IpcHost - Mounts - Env - Args @@ -1513,6 +1514,9 @@ definitions: PropagatedMount: type: "string" x-nullable: false + IpcHost: + type: "boolean" + x-nullable: false Mounts: type: "array" items: diff --git a/api/types/plugin.go b/api/types/plugin.go index 6cc7a23b02..ecd45b4a0a 100644 --- a/api/types/plugin.go +++ b/api/types/plugin.go @@ -58,6 +58,10 @@ type PluginConfig struct { // Required: true Interface PluginConfigInterface `json:"Interface"` + // ipc host + // Required: true + IpcHost bool `json:"IpcHost"` + // linux // Required: true Linux PluginConfigLinux `json:"Linux"` diff --git a/docs/extend/config.md b/docs/extend/config.md index dab755d97b..3fc377f76c 100644 --- a/docs/extend/config.md +++ b/docs/extend/config.md @@ -115,6 +115,9 @@ Config provides the base accessible fields for working with V0 plugin format options of the mount. +- **`ipchost`** *boolean* + Access to host ipc namespace. + - **`propagatedMount`** *string* path to be mounted as rshared, so that mounts under that path are visible to docker. This is useful for volume plugins. diff --git a/plugin/backend_linux.go b/plugin/backend_linux.go index 380d0ddaff..586ff73dd2 100644 --- a/plugin/backend_linux.go +++ b/plugin/backend_linux.go @@ -150,6 +150,13 @@ func computePrivileges(c types.PluginConfig) (types.PluginPrivileges, error) { Value: []string{c.Network.Type}, }) } + if c.IpcHost { + privileges = append(privileges, types.PluginPrivilege{ + Name: "host ipc namespace", + Description: "allow access to host ipc namespace", + Value: []string{"true"}, + }) + } for _, mount := range c.Mounts { if mount.Source != nil { privileges = append(privileges, types.PluginPrivilege{ diff --git a/plugin/v2/plugin_linux.go b/plugin/v2/plugin_linux.go index e980e7f29a..d02716d63b 100644 --- a/plugin/v2/plugin_linux.go +++ b/plugin/v2/plugin_linux.go @@ -61,6 +61,10 @@ func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) { }) } + if p.PluginObj.Config.IpcHost { + oci.RemoveNamespace(&s, specs.NamespaceType("ipc")) + } + for _, mnt := range mounts { m := specs.Mount{ Destination: mnt.Destination, From 4d1edcb2cce34bd86d2602923872f8b5c80560c8 Mon Sep 17 00:00:00 2001 From: Anusha Ragunathan Date: Fri, 10 Mar 2017 14:17:24 -0800 Subject: [PATCH 2/3] Add pid host support Tested using global-net-plugin-ipc which sets PidHost in config.json. Plugins might need access to host pid namespace. Add support for that. Tested using aragunathan/global-net-plugin-ipc which sets "pidhost" in config.json. Observed using `readlink /proc/self/ns/pid` that plugin and host have the same ns. Signed-off-by: Anusha Ragunathan --- api/swagger.yaml | 4 ++++ api/types/plugin.go | 4 ++++ docs/extend/config.md | 2 ++ plugin/backend_linux.go | 7 +++++++ plugin/v2/plugin_linux.go | 3 +++ 5 files changed, 20 insertions(+) diff --git a/api/swagger.yaml b/api/swagger.yaml index 254042115a..3991437e67 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -1445,6 +1445,7 @@ definitions: - WorkDir - Network - Linux + - PidHost - PropagatedMount - IpcHost - Mounts @@ -1517,6 +1518,9 @@ definitions: IpcHost: type: "boolean" x-nullable: false + PidHost: + type: "boolean" + x-nullable: false Mounts: type: "array" items: diff --git a/api/types/plugin.go b/api/types/plugin.go index ecd45b4a0a..14f0f956be 100644 --- a/api/types/plugin.go +++ b/api/types/plugin.go @@ -74,6 +74,10 @@ type PluginConfig struct { // Required: true Network PluginConfigNetwork `json:"Network"` + // pid host + // Required: true + PidHost bool `json:"PidHost"` + // propagated mount // Required: true PropagatedMount string `json:"PropagatedMount"` diff --git a/docs/extend/config.md b/docs/extend/config.md index 3fc377f76c..ad43e898c7 100644 --- a/docs/extend/config.md +++ b/docs/extend/config.md @@ -117,6 +117,8 @@ Config provides the base accessible fields for working with V0 plugin format - **`ipchost`** *boolean* Access to host ipc namespace. +- **`pidhost`** *boolean* + Access to host pid namespace. - **`propagatedMount`** *string* diff --git a/plugin/backend_linux.go b/plugin/backend_linux.go index 586ff73dd2..31587efbe6 100644 --- a/plugin/backend_linux.go +++ b/plugin/backend_linux.go @@ -157,6 +157,13 @@ func computePrivileges(c types.PluginConfig) (types.PluginPrivileges, error) { Value: []string{"true"}, }) } + if c.PidHost { + privileges = append(privileges, types.PluginPrivilege{ + Name: "host pid namespace", + Description: "allow access to host pid namespace", + Value: []string{"true"}, + }) + } for _, mount := range c.Mounts { if mount.Source != nil { privileges = append(privileges, types.PluginPrivilege{ diff --git a/plugin/v2/plugin_linux.go b/plugin/v2/plugin_linux.go index d02716d63b..6da63b3b6f 100644 --- a/plugin/v2/plugin_linux.go +++ b/plugin/v2/plugin_linux.go @@ -60,6 +60,9 @@ func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) { Options: []string{"rbind", "ro"}, }) } + if p.PluginObj.Config.PidHost { + oci.RemoveNamespace(&s, specs.NamespaceType("pid")) + } if p.PluginObj.Config.IpcHost { oci.RemoveNamespace(&s, specs.NamespaceType("ipc")) From 342ed107bc6283cfc9b3301142e71f20aae0aaca Mon Sep 17 00:00:00 2001 From: Anusha Ragunathan Date: Tue, 21 Mar 2017 14:07:41 -0700 Subject: [PATCH 3/3] Embed DockerVersion in plugin config. Embedding DockerVersion in plugin config when the plugin is created, enables users to do a docker plugin inspect and know which version the plugin was built on. This is helpful in cases where users are running a new plugin on older docker releases and confused at unexpected behavior. By embedding DockerVersion in the config, we claim that there's no guarantee that if the plugin config's DockerVersion is greater that the version of the docker engine the plugin is executed against, the plugin will work as expected. For example, lets say: - in 17.03, a plugin was released as johndoe/foo:v1 - in 17.05, the plugin uses the new ipchost config setting and author publishes johndoe/foo:v2 In this case, johndoe/foo:v2 was built on 17.05 using ipchost, but is running on docker-engine version 17.03. Since 17.05 > 17.03, there's no guarantee that the plugin will work as expected. Ofcourse, if the plugin did not use newly added config settings (ipchost in this case) in 17.05, it would work fine in 17.03. Signed-off-by: Anusha Ragunathan --- api/swagger.yaml | 4 ++++ api/types/plugin.go | 3 +++ plugin/backend_linux.go | 3 +++ 3 files changed, 10 insertions(+) diff --git a/api/swagger.yaml b/api/swagger.yaml index 3991437e67..a8b4b553c0 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -1452,6 +1452,10 @@ definitions: - Env - Args properties: + DockerVersion: + description: "Docker Version used to create the plugin" + type: "string" + x-nullable: false Description: type: "string" x-nullable: false diff --git a/api/types/plugin.go b/api/types/plugin.go index 14f0f956be..ed3c2c26e4 100644 --- a/api/types/plugin.go +++ b/api/types/plugin.go @@ -42,6 +42,9 @@ type PluginConfig struct { // Required: true Description string `json:"Description"` + // Docker Version used to create the plugin + DockerVersion string `json:"DockerVersion,omitempty"` + // documentation // Required: true Documentation string `json:"Documentation"` diff --git a/plugin/backend_linux.go b/plugin/backend_linux.go index 31587efbe6..8924daa996 100644 --- a/plugin/backend_linux.go +++ b/plugin/backend_linux.go @@ -24,6 +24,7 @@ import ( "github.com/docker/docker/distribution" progressutils "github.com/docker/docker/distribution/utils" "github.com/docker/docker/distribution/xfer" + "github.com/docker/docker/dockerversion" "github.com/docker/docker/image" "github.com/docker/docker/layer" "github.com/docker/docker/pkg/chrootarchive" @@ -758,6 +759,8 @@ func (pm *Manager) CreateFromContext(ctx context.Context, tarCtx io.ReadCloser, DiffIds: []string{layerDigester.Digest().String()}, } + config.DockerVersion = dockerversion.Version + configBlob, err := pm.blobStore.New() if err != nil { return err