From 4d1edcb2cce34bd86d2602923872f8b5c80560c8 Mon Sep 17 00:00:00 2001
From: Anusha Ragunathan <anusha.ragunathan@docker.com>
Date: Fri, 10 Mar 2017 14:17:24 -0800
Subject: [PATCH] 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 <anusha.ragunathan@docker.com>
---
 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"))