Browse code

Remove use of exec-root in plugins due to socket pathname limits.

Unix sockets are limited to 108 bytes. As a result, we need to be
careful in not using exec-root as the parent directory for pluginID
(which is already 64 bytes), since it can result in socket path names
longer than 108 bytes. Use /tmp instead. Before this change, setting:
- dockerd --exec-root=/go/src/github.com/do passes
- dockerd --exec-root=/go/src/github.com/doc fails
After this change, there's no failure.

Also, write a volume plugins test to verify that the plugins socket
responds.

Signed-off-by: Anusha Ragunathan <anusha@docker.com>
(cherry picked from commit 21ecd5a93db34288c0c579d5738030716d7bef2d)
Signed-off-by: Tibor Vass <tibor@docker.com>

Anusha Ragunathan authored on 2016/07/09 02:37:52
Showing 4 changed files
... ...
@@ -10,5 +10,5 @@ import (
10 10
 )
11 11
 
12 12
 func pluginInit(config *daemon.Config, remote libcontainerd.Remote, rs registry.Service) error {
13
-	return plugin.Init(config.Root, config.ExecRoot, remote, rs, config.LiveRestore)
13
+	return plugin.Init(config.Root, remote, rs, config.LiveRestore)
14 14
 }
... ...
@@ -3,11 +3,14 @@
3 3
 package main
4 4
 
5 5
 import (
6
-	"github.com/docker/docker/pkg/integration/checker"
7
-	"github.com/go-check/check"
8 6
 	"os"
9 7
 	"os/exec"
8
+	"path/filepath"
9
+	"strings"
10 10
 	"time"
11
+
12
+	"github.com/docker/docker/pkg/integration/checker"
13
+	"github.com/go-check/check"
11 14
 )
12 15
 
13 16
 var pluginName = "tiborvass/no-remove"
... ...
@@ -133,3 +136,53 @@ func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *check.C) {
133 133
 		c.Fatalf("Expected exit code '1', got %d err: %v output: %s ", ec, err, out)
134 134
 	}
135 135
 }
136
+
137
+// TestVolumePlugin tests volume creation using a plugin.
138
+func (s *DockerDaemonSuite) TestVolumePlugin(c *check.C) {
139
+	volName := "plugin-volume"
140
+	volRoot := "/data"
141
+	destDir := "/tmp/data/"
142
+	destFile := "foo"
143
+
144
+	if err := s.d.Start(); err != nil {
145
+		c.Fatalf("Could not start daemon: %v", err)
146
+	}
147
+	out, err := s.d.Cmd("plugin", "install", pluginName, "--grant-all-permissions")
148
+	if err != nil {
149
+		c.Fatalf("Could not install plugin: %v %s", err, out)
150
+	}
151
+	defer func() {
152
+		if out, err := s.d.Cmd("plugin", "disable", pluginName); err != nil {
153
+			c.Fatalf("Could not disable plugin: %v %s", err, out)
154
+		}
155
+		if out, err := s.d.Cmd("plugin", "remove", pluginName); err != nil {
156
+			c.Fatalf("Could not remove plugin: %v %s", err, out)
157
+		}
158
+	}()
159
+
160
+	out, err = s.d.Cmd("volume", "create", "-d", pluginName, "--name", volName)
161
+	if err != nil {
162
+		c.Fatalf("Could not create volume: %v %s", err, out)
163
+	}
164
+	defer func() {
165
+		if out, err := s.d.Cmd("volume", "remove", volName); err != nil {
166
+			c.Fatalf("Could not remove volume: %v %s", err, out)
167
+		}
168
+	}()
169
+
170
+	mountPoint, err := s.d.Cmd("volume", "inspect", volName, "--format", "{{.Mountpoint}}")
171
+	if err != nil {
172
+		c.Fatalf("Could not inspect volume: %v %s", err, mountPoint)
173
+	}
174
+	mountPoint = strings.TrimSpace(mountPoint)
175
+
176
+	out, err = s.d.Cmd("run", "--rm", "-v", volName+":"+destDir, "busybox", "touch", destDir+destFile)
177
+	c.Assert(err, checker.IsNil, check.Commentf(out))
178
+	path := filepath.Join(mountPoint, destFile)
179
+	_, err = os.Lstat(path)
180
+	c.Assert(err, checker.IsNil)
181
+
182
+	// tiborvass/no-remove is a volume plugin that persists data on disk at /data,
183
+	// even after the volume is removed. So perform an explicit filesystem cleanup.
184
+	os.RemoveAll(volRoot)
185
+}
... ...
@@ -109,22 +109,15 @@ func GetManager() *Manager {
109 109
 
110 110
 // Init (was NewManager) instantiates the singleton Manager.
111 111
 // TODO: revert this to NewManager once we get rid of all the singletons.
112
-func Init(root, execRoot string, remote libcontainerd.Remote, rs registry.Service, liveRestore bool) (err error) {
112
+func Init(root string, remote libcontainerd.Remote, rs registry.Service, liveRestore bool) (err error) {
113 113
 	if manager != nil {
114 114
 		return nil
115 115
 	}
116 116
 
117 117
 	root = filepath.Join(root, "plugins")
118
-	execRoot = filepath.Join(execRoot, "plugins")
119
-	for _, dir := range []string{root, execRoot} {
120
-		if err := os.MkdirAll(dir, 0700); err != nil {
121
-			return err
122
-		}
123
-	}
124
-
125 118
 	manager = &Manager{
126 119
 		libRoot:         root,
127
-		runRoot:         execRoot,
120
+		runRoot:         "/run/docker",
128 121
 		plugins:         make(map[string]*plugin),
129 122
 		nameToID:        make(map[string]string),
130 123
 		handlers:        make(map[string]func(string, *plugins.Client)),
... ...
@@ -36,8 +36,6 @@ func (pm *Manager) enable(p *plugin) error {
36 36
 		return err
37 37
 	}
38 38
 
39
-	//TODO: check net.Dial
40
-
41 39
 	pm.Lock() // fixme: lock single record
42 40
 	p.P.Active = true
43 41
 	pm.save()