Browse code

Moves graphdriver plugn docs out of experimental

Also updates some of the structures being sent so plugins are getting
all the new options.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>

Brian Goff authored on 2016/11/20 01:41:07
Showing 10 changed files
... ...
@@ -568,6 +568,7 @@ func NewDaemon(config *Config, registryService registry.Service, containerdRemot
568 568
 		UIDMaps:                   uidMaps,
569 569
 		GIDMaps:                   gidMaps,
570 570
 		PluginGetter:              d.PluginStore,
571
+		ExperimentalEnabled:       config.Experimental,
571 572
 	})
572 573
 	if err != nil {
573 574
 		return nil, err
... ...
@@ -150,16 +150,16 @@ func Register(name string, initFunc InitFunc) error {
150 150
 }
151 151
 
152 152
 // GetDriver initializes and returns the registered driver
153
-func GetDriver(name, home string, options []string, uidMaps, gidMaps []idtools.IDMap, pg plugingetter.PluginGetter) (Driver, error) {
153
+func GetDriver(name string, pg plugingetter.PluginGetter, config Options) (Driver, error) {
154 154
 	if initFunc, exists := drivers[name]; exists {
155
-		return initFunc(filepath.Join(home, name), options, uidMaps, gidMaps)
155
+		return initFunc(filepath.Join(config.Root, name), config.DriverOptions, config.UIDMaps, config.GIDMaps)
156 156
 	}
157 157
 
158
-	pluginDriver, err := lookupPlugin(name, home, options, pg)
158
+	pluginDriver, err := lookupPlugin(name, pg, config)
159 159
 	if err == nil {
160 160
 		return pluginDriver, nil
161 161
 	}
162
-	logrus.WithError(err).WithField("driver", name).WithField("home-dir", home).Error("Failed to GetDriver graph")
162
+	logrus.WithError(err).WithField("driver", name).WithField("home-dir", config.Root).Error("Failed to GetDriver graph")
163 163
 	return nil, ErrNotSupported
164 164
 }
165 165
 
... ...
@@ -172,15 +172,24 @@ func getBuiltinDriver(name, home string, options []string, uidMaps, gidMaps []id
172 172
 	return nil, ErrNotSupported
173 173
 }
174 174
 
175
+// Options is used to initialize a graphdriver
176
+type Options struct {
177
+	Root                string
178
+	DriverOptions       []string
179
+	UIDMaps             []idtools.IDMap
180
+	GIDMaps             []idtools.IDMap
181
+	ExperimentalEnabled bool
182
+}
183
+
175 184
 // New creates the driver and initializes it at the specified root.
176
-func New(root, name string, options []string, uidMaps, gidMaps []idtools.IDMap, pg plugingetter.PluginGetter) (Driver, error) {
185
+func New(name string, pg plugingetter.PluginGetter, config Options) (Driver, error) {
177 186
 	if name != "" {
178 187
 		logrus.Debugf("[graphdriver] trying provided driver: %s", name) // so the logs show specified driver
179
-		return GetDriver(name, root, options, uidMaps, gidMaps, pg)
188
+		return GetDriver(name, pg, config)
180 189
 	}
181 190
 
182 191
 	// Guess for prior driver
183
-	driversMap := scanPriorDrivers(root)
192
+	driversMap := scanPriorDrivers(config.Root)
184 193
 	for _, name := range priority {
185 194
 		if name == "vfs" {
186 195
 			// don't use vfs even if there is state present.
... ...
@@ -189,7 +198,7 @@ func New(root, name string, options []string, uidMaps, gidMaps []idtools.IDMap,
189 189
 		if _, prior := driversMap[name]; prior {
190 190
 			// of the state found from prior drivers, check in order of our priority
191 191
 			// which we would prefer
192
-			driver, err := getBuiltinDriver(name, root, options, uidMaps, gidMaps)
192
+			driver, err := getBuiltinDriver(name, config.Root, config.DriverOptions, config.UIDMaps, config.GIDMaps)
193 193
 			if err != nil {
194 194
 				// unlike below, we will return error here, because there is prior
195 195
 				// state, and now it is no longer supported/prereq/compatible, so
... ...
@@ -207,7 +216,7 @@ func New(root, name string, options []string, uidMaps, gidMaps []idtools.IDMap,
207 207
 					driversSlice = append(driversSlice, name)
208 208
 				}
209 209
 
210
-				return nil, fmt.Errorf("%s contains several valid graphdrivers: %s; Please cleanup or explicitly choose storage driver (-s <DRIVER>)", root, strings.Join(driversSlice, ", "))
210
+				return nil, fmt.Errorf("%s contains several valid graphdrivers: %s; Please cleanup or explicitly choose storage driver (-s <DRIVER>)", config.Root, strings.Join(driversSlice, ", "))
211 211
 			}
212 212
 
213 213
 			logrus.Infof("[graphdriver] using prior storage driver: %s", name)
... ...
@@ -217,7 +226,7 @@ func New(root, name string, options []string, uidMaps, gidMaps []idtools.IDMap,
217 217
 
218 218
 	// Check for priority drivers first
219 219
 	for _, name := range priority {
220
-		driver, err := getBuiltinDriver(name, root, options, uidMaps, gidMaps)
220
+		driver, err := getBuiltinDriver(name, config.Root, config.DriverOptions, config.UIDMaps, config.GIDMaps)
221 221
 		if err != nil {
222 222
 			if isDriverNotSupported(err) {
223 223
 				continue
... ...
@@ -229,7 +238,7 @@ func New(root, name string, options []string, uidMaps, gidMaps []idtools.IDMap,
229 229
 
230 230
 	// Check all registered drivers if no priority driver is found
231 231
 	for name, initFunc := range drivers {
232
-		driver, err := initFunc(filepath.Join(root, name), options, uidMaps, gidMaps)
232
+		driver, err := initFunc(filepath.Join(config.Root, name), config.DriverOptions, config.UIDMaps, config.GIDMaps)
233 233
 		if err != nil {
234 234
 			if isDriverNotSupported(err) {
235 235
 				continue
... ...
@@ -41,7 +41,7 @@ func newDriver(t testing.TB, name string, options []string) *Driver {
41 41
 		t.Fatal(err)
42 42
 	}
43 43
 
44
-	d, err := graphdriver.GetDriver(name, root, options, nil, nil, nil)
44
+	d, err := graphdriver.GetDriver(name, nil, graphdriver.Options{DriverOptions: options, Root: root})
45 45
 	if err != nil {
46 46
 		t.Logf("graphdriver: %v\n", err)
47 47
 		if err == graphdriver.ErrNotSupported || err == graphdriver.ErrPrerequisites || err == graphdriver.ErrIncompatibleFS {
... ...
@@ -18,15 +18,19 @@ type pluginClient interface {
18 18
 	SendFile(string, io.Reader, interface{}) error
19 19
 }
20 20
 
21
-func lookupPlugin(name, home string, opts []string, pg plugingetter.PluginGetter) (Driver, error) {
22
-	pl, err := pg.Get(name, "GraphDriver", plugingetter.LOOKUP)
21
+func lookupPlugin(name string, pg plugingetter.PluginGetter, config Options) (Driver, error) {
22
+	if !config.ExperimentalEnabled {
23
+		return nil, fmt.Errorf("graphdriver plugins are only supported with experimental mode")
24
+	}
25
+	pl, err := pg.Get(name, "GraphDriver", plugingetter.ACQUIRE)
23 26
 	if err != nil {
24 27
 		return nil, fmt.Errorf("Error looking up graphdriver plugin %s: %v", name, err)
25 28
 	}
26
-	return newPluginDriver(name, home, opts, pl)
29
+	return newPluginDriver(name, pl, config)
27 30
 }
28 31
 
29
-func newPluginDriver(name, home string, opts []string, pl plugingetter.CompatPlugin) (Driver, error) {
32
+func newPluginDriver(name string, pl plugingetter.CompatPlugin, config Options) (Driver, error) {
33
+	home := config.Root
30 34
 	if !pl.IsV1() {
31 35
 		if p, ok := pl.(*v2.Plugin); ok {
32 36
 			if p.PropagatedMount != "" {
... ...
@@ -35,5 +39,5 @@ func newPluginDriver(name, home string, opts []string, pl plugingetter.CompatPlu
35 35
 		}
36 36
 	}
37 37
 	proxy := &graphDriverProxy{name, pl}
38
-	return proxy, proxy.Init(filepath.Join(home, name), opts)
38
+	return proxy, proxy.Init(filepath.Join(home, name), config.DriverOptions, config.UIDMaps, config.GIDMaps)
39 39
 }
... ...
@@ -7,6 +7,7 @@ import (
7 7
 	"path/filepath"
8 8
 
9 9
 	"github.com/docker/docker/pkg/archive"
10
+	"github.com/docker/docker/pkg/idtools"
10 11
 	"github.com/docker/docker/pkg/plugingetter"
11 12
 )
12 13
 
... ...
@@ -16,9 +17,10 @@ type graphDriverProxy struct {
16 16
 }
17 17
 
18 18
 type graphDriverRequest struct {
19
-	ID         string `json:",omitempty"`
20
-	Parent     string `json:",omitempty"`
21
-	MountLabel string `json:",omitempty"`
19
+	ID         string            `json:",omitempty"`
20
+	Parent     string            `json:",omitempty"`
21
+	MountLabel string            `json:",omitempty"`
22
+	StorageOpt map[string]string `json:",omitempty"`
22 23
 }
23 24
 
24 25
 type graphDriverResponse struct {
... ...
@@ -32,11 +34,13 @@ type graphDriverResponse struct {
32 32
 }
33 33
 
34 34
 type graphDriverInitRequest struct {
35
-	Home string
36
-	Opts []string
35
+	Home    string
36
+	Opts    []string        `json:"Opts"`
37
+	UIDMaps []idtools.IDMap `json:"UIDMaps"`
38
+	GIDMaps []idtools.IDMap `json:"GIDMaps"`
37 39
 }
38 40
 
39
-func (d *graphDriverProxy) Init(home string, opts []string) error {
41
+func (d *graphDriverProxy) Init(home string, opts []string, uidMaps, gidMaps []idtools.IDMap) error {
40 42
 	if !d.p.IsV1() {
41 43
 		if cp, ok := d.p.(plugingetter.CountedPlugin); ok {
42 44
 			// always acquire here, it will be cleaned up on daemon shutdown
... ...
@@ -44,8 +48,10 @@ func (d *graphDriverProxy) Init(home string, opts []string) error {
44 44
 		}
45 45
 	}
46 46
 	args := &graphDriverInitRequest{
47
-		Home: home,
48
-		Opts: opts,
47
+		Home:    home,
48
+		Opts:    opts,
49
+		UIDMaps: uidMaps,
50
+		GIDMaps: gidMaps,
49 51
 	}
50 52
 	var ret graphDriverResponse
51 53
 	if err := d.p.Client().Call("GraphDriver.Init", args, &ret); err != nil {
... ...
@@ -62,16 +68,15 @@ func (d *graphDriverProxy) String() string {
62 62
 }
63 63
 
64 64
 func (d *graphDriverProxy) CreateReadWrite(id, parent string, opts *CreateOpts) error {
65
-	mountLabel := ""
65
+	args := &graphDriverRequest{
66
+		ID:     id,
67
+		Parent: parent,
68
+	}
66 69
 	if opts != nil {
67
-		mountLabel = opts.MountLabel
70
+		args.MountLabel = opts.MountLabel
71
+		args.StorageOpt = opts.StorageOpt
68 72
 	}
69 73
 
70
-	args := &graphDriverRequest{
71
-		ID:         id,
72
-		Parent:     parent,
73
-		MountLabel: mountLabel,
74
-	}
75 74
 	var ret graphDriverResponse
76 75
 	if err := d.p.Client().Call("GraphDriver.CreateReadWrite", args, &ret); err != nil {
77 76
 		return err
... ...
@@ -83,14 +88,13 @@ func (d *graphDriverProxy) CreateReadWrite(id, parent string, opts *CreateOpts)
83 83
 }
84 84
 
85 85
 func (d *graphDriverProxy) Create(id, parent string, opts *CreateOpts) error {
86
-	mountLabel := ""
87
-	if opts != nil {
88
-		mountLabel = opts.MountLabel
89
-	}
90 86
 	args := &graphDriverRequest{
91
-		ID:         id,
92
-		Parent:     parent,
93
-		MountLabel: mountLabel,
87
+		ID:     id,
88
+		Parent: parent,
89
+	}
90
+	if opts != nil {
91
+		args.MountLabel = opts.MountLabel
92
+		args.StorageOpt = opts.StorageOpt
94 93
 	}
95 94
 	var ret graphDriverResponse
96 95
 	if err := d.p.Client().Call("GraphDriver.Create", args, &ret); err != nil {
97 96
new file mode 100644
... ...
@@ -0,0 +1,376 @@
0
+---
1
+title: "Graphdriver plugins"
2
+description: "How to manage image and container filesystems with external plugins"
3
+keywords: "Examples, Usage, storage, image, docker, data, graph, plugin, api"
4
+advisory: experimental
5
+---
6
+
7
+<!-- This file is maintained within the docker/docker Github
8
+     repository at https://github.com/docker/docker/. Make all
9
+     pull requests against that repo. If you see this file in
10
+     another repository, consider it read-only there, as it will
11
+     periodically be overwritten by the definitive file. Pull
12
+     requests which include edits to this file in other repositories
13
+     will be rejected.
14
+-->
15
+
16
+
17
+## Changelog
18
+
19
+### 1.13.0
20
+
21
+- Support v2 plugins
22
+
23
+# Docker graph driver plugins
24
+
25
+Docker graph driver plugins enable admins to use an external/out-of-process
26
+graph driver for use with Docker engine. This is an alternative to using the
27
+built-in storage drivers, such as aufs/overlay/devicemapper/btrfs.
28
+
29
+You need to install and enable the plugin and then restart the Docker daemon
30
+before using the plugin. See the following example for the correct ordering
31
+of steps.
32
+
33
+```
34
+$ docker plugin install cpuguy83/docker-overlay2-graphdriver-plugin # this command also enables the driver
35
+<output supressed>
36
+$ pkill dockerd
37
+$ dockerd --experimental -s cpuguy83/docker-overlay2-graphdriver-plugin
38
+```
39
+
40
+# Write a graph driver plugin
41
+
42
+See the [plugin documentation](https://docs.docker.com/engine/extend/) for detailed information
43
+on the underlying plugin protocol.
44
+
45
+
46
+## Graph Driver plugin protocol
47
+
48
+If a plugin registers itself as a `GraphDriver` when activated, then it is
49
+expected to provide the rootfs for containers as well as image layer storage.
50
+
51
+### /GraphDriver.Init
52
+
53
+**Request**:
54
+```json
55
+{
56
+  "Home": "/graph/home/path",
57
+  "Opts": [],
58
+  "UIDMaps": [],
59
+  "GIDMaps": []
60
+}
61
+```
62
+
63
+Initialize the graph driver plugin with a home directory and array of options.
64
+These are passed through from the user, but the plugin is not required to parse
65
+or honor them.
66
+
67
+The request also includes a list of UID and GID mappings, structed as follows:
68
+```json
69
+{
70
+  "ContainerID": 0,
71
+  "HostID": 0,
72
+  "Size": 0
73
+}
74
+```
75
+
76
+**Response**:
77
+```json
78
+{
79
+  "Err": ""
80
+}
81
+```
82
+
83
+Respond with a non-empty string error if an error occurred.
84
+
85
+
86
+### /GraphDriver.Create
87
+
88
+**Request**:
89
+```json
90
+{
91
+  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
92
+  "Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142",
93
+  "MountLabel": "",
94
+  "StorageOpt": {}
95
+}
96
+```
97
+
98
+Create a new, empty, read-only filesystem layer with the specified
99
+`ID`, `Parent` and `MountLabel`. If `Parent` is an empty string, there is no
100
+parent layer. `StorageOpt` is map of strings which indicate storage options.
101
+
102
+**Response**:
103
+```json
104
+{
105
+  "Err": ""
106
+}
107
+```
108
+
109
+Respond with a non-empty string error if an error occurred.
110
+
111
+### /GraphDriver.CreateReadWrite
112
+
113
+**Request**:
114
+```json
115
+{
116
+  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
117
+  "Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142",
118
+  "MountLabel": "",
119
+  "StorageOpt": {}
120
+}
121
+```
122
+
123
+Similar to `/GraphDriver.Create` but creates a read-write filesystem layer.
124
+
125
+### /GraphDriver.Remove
126
+
127
+**Request**:
128
+```json
129
+{
130
+  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
131
+}
132
+```
133
+
134
+Remove the filesystem layer with this given `ID`.
135
+
136
+**Response**:
137
+```json
138
+{
139
+  "Err": ""
140
+}
141
+```
142
+
143
+Respond with a non-empty string error if an error occurred.
144
+
145
+### /GraphDriver.Get
146
+
147
+**Request**:
148
+```json
149
+{
150
+  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
151
+  "MountLabel": ""
152
+}
153
+```
154
+
155
+Get the mountpoint for the layered filesystem referred to by the given `ID`.
156
+
157
+**Response**:
158
+```json
159
+{
160
+  "Dir": "/var/mygraph/46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
161
+  "Err": ""
162
+}
163
+```
164
+
165
+Respond with the absolute path to the mounted layered filesystem.
166
+Respond with a non-empty string error if an error occurred.
167
+
168
+### /GraphDriver.Put
169
+
170
+**Request**:
171
+```json
172
+{
173
+  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
174
+}
175
+```
176
+
177
+Release the system resources for the specified `ID`, such as unmounting the
178
+filesystem layer.
179
+
180
+**Response**:
181
+```json
182
+{
183
+  "Err": ""
184
+}
185
+```
186
+
187
+Respond with a non-empty string error if an error occurred.
188
+
189
+### /GraphDriver.Exists
190
+
191
+**Request**:
192
+```json
193
+{
194
+  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
195
+}
196
+```
197
+
198
+Determine if a filesystem layer with the specified `ID` exists.
199
+
200
+**Response**:
201
+```json
202
+{
203
+  "Exists": true
204
+}
205
+```
206
+
207
+Respond with a boolean for whether or not the filesystem layer with the specified
208
+`ID` exists.
209
+
210
+### /GraphDriver.Status
211
+
212
+**Request**:
213
+```json
214
+{}
215
+```
216
+
217
+Get low-level diagnostic information about the graph driver.
218
+
219
+**Response**:
220
+```json
221
+{
222
+  "Status": [[]]
223
+}
224
+```
225
+
226
+Respond with a 2-D array with key/value pairs for the underlying status
227
+information.
228
+
229
+
230
+### /GraphDriver.GetMetadata
231
+
232
+**Request**:
233
+```json
234
+{
235
+  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
236
+}
237
+```
238
+
239
+Get low-level diagnostic information about the layered filesystem with the
240
+with the specified `ID`
241
+
242
+**Response**:
243
+```json
244
+{
245
+  "Metadata": {},
246
+  "Err": ""
247
+}
248
+```
249
+
250
+Respond with a set of key/value pairs containing the low-level diagnostic
251
+information about the layered filesystem.
252
+Respond with a non-empty string error if an error occurred.
253
+
254
+### /GraphDriver.Cleanup
255
+
256
+**Request**:
257
+```json
258
+{}
259
+```
260
+
261
+Perform necessary tasks to release resources help by the plugin, such as
262
+unmounting all the layered file systems.
263
+
264
+**Response**:
265
+```json
266
+{
267
+  "Err": ""
268
+}
269
+```
270
+
271
+Respond with a non-empty string error if an error occurred.
272
+
273
+
274
+### /GraphDriver.Diff
275
+
276
+**Request**:
277
+```json
278
+{
279
+  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
280
+  "Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
281
+}
282
+```
283
+
284
+Get an archive of the changes between the filesystem layers specified by the `ID`
285
+and `Parent`. `Parent` may be an empty string, in which case there is no parent.
286
+
287
+**Response**:
288
+```
289
+{{ TAR STREAM }}
290
+```
291
+
292
+### /GraphDriver.Changes
293
+
294
+**Request**:
295
+```json
296
+{
297
+  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
298
+  "Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
299
+}
300
+```
301
+
302
+Get a list of changes between the filesystem layers specified by the `ID` and
303
+`Parent`. If `Parent` is an empty string, there is no parent.
304
+
305
+**Response**:
306
+```json
307
+{
308
+  "Changes": [{}],
309
+  "Err": ""
310
+}
311
+```
312
+
313
+Respond with a list of changes. The structure of a change is:
314
+```json
315
+  "Path": "/some/path",
316
+  "Kind": 0,
317
+```
318
+
319
+Where the `Path` is the filesystem path within the layered filesystem that is
320
+changed and `Kind` is an integer specifying the type of change that occurred:
321
+
322
+- 0 - Modified
323
+- 1 - Added
324
+- 2 - Deleted
325
+
326
+Respond with a non-empty string error if an error occurred.
327
+
328
+### /GraphDriver.ApplyDiff
329
+
330
+**Request**:
331
+```
332
+{{ TAR STREAM }}
333
+```
334
+
335
+Extract the changeset from the given diff into the layer with the specified `ID`
336
+and `Parent`
337
+
338
+**Query Parameters**:
339
+
340
+- id (required)- the `ID` of the new filesystem layer to extract the diff to
341
+- parent (required)- the `Parent` of the given `ID`
342
+
343
+**Response**:
344
+```json
345
+{
346
+  "Size": 512366,
347
+  "Err": ""
348
+}
349
+```
350
+
351
+Respond with the size of the new layer in bytes.
352
+Respond with a non-empty string error if an error occurred.
353
+
354
+### /GraphDriver.DiffSize
355
+
356
+**Request**:
357
+```json
358
+{
359
+  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
360
+  "Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
361
+}
362
+```
363
+
364
+Calculate the changes between the specified `ID`
365
+
366
+**Response**:
367
+```json
368
+{
369
+  "Size": 512366,
370
+  "Err": ""
371
+}
372
+```
373
+
374
+Respond with the size changes between the specified `ID` and `Parent`
375
+Respond with a non-empty string error if an error occurred.
0 376
deleted file mode 100644
... ...
@@ -1,334 +0,0 @@
1
-# Experimental: Docker graph driver plugins
2
-
3
-Docker graph driver plugins enable admins to use an external/out-of-process
4
-graph driver for use with Docker engine. This is an alternative to using the
5
-built-in storage drivers, such as aufs/overlay/devicemapper/btrfs.
6
-
7
-A graph driver plugin is used for image and container filesystem storage, as such
8
-the plugin must be started and available for connections prior to Docker Engine
9
-being started.
10
-
11
-# Write a graph driver plugin
12
-
13
-See the [plugin documentation](https://docs.docker.com/engine/extend/) for detailed information
14
-on the underlying plugin protocol.
15
-
16
-
17
-## Graph Driver plugin protocol
18
-
19
-If a plugin registers itself as a `GraphDriver` when activated, then it is
20
-expected to provide the rootfs for containers as well as image layer storage.
21
-
22
-### /GraphDriver.Init
23
-
24
-**Request**:
25
-```
26
-{
27
-  "Home": "/graph/home/path",
28
-  "Opts": []
29
-}
30
-```
31
-
32
-Initialize the graph driver plugin with a home directory and array of options.
33
-Plugins are not required to accept these options as the Docker Engine does not
34
-require that the plugin use this path or options, they are only being passed
35
-through from the user.
36
-
37
-**Response**:
38
-```
39
-{
40
-  "Err": ""
41
-}
42
-```
43
-
44
-Respond with a non-empty string error if an error occurred.
45
-
46
-
47
-### /GraphDriver.Create
48
-
49
-**Request**:
50
-```
51
-{
52
-  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
53
-  "Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
54
-  "MountLabel": ""
55
-}
56
-```
57
-
58
-Create a new, empty, read-only filesystem layer with the specified
59
-`ID`, `Parent` and `MountLabel`. `Parent` may be an empty string,
60
-which would indicate that there is no parent layer.
61
-
62
-**Response**:
63
-```
64
-{
65
-  "Err": ""
66
-}
67
-```
68
-
69
-Respond with a non-empty string error if an error occurred.
70
-
71
-### /GraphDriver.CreateReadWrite
72
-
73
-**Request**:
74
-```
75
-{
76
-  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
77
-  "Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
78
-  "MountLabel": ""
79
-}
80
-```
81
-
82
-Similar to `/GraphDriver.Create` but creates a read-write filesystem layer.
83
-
84
-### /GraphDriver.Remove
85
-
86
-**Request**:
87
-```
88
-{
89
-  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
90
-}
91
-```
92
-
93
-Remove the filesystem layer with this given `ID`.
94
-
95
-**Response**:
96
-```
97
-{
98
-  "Err": ""
99
-}
100
-```
101
-
102
-Respond with a non-empty string error if an error occurred.
103
-
104
-### /GraphDriver.Get
105
-
106
-**Request**:
107
-```
108
-{
109
-  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
110
-  "MountLabel": ""
111
-}
112
-```
113
-
114
-Get the mountpoint for the layered filesystem referred to by the given `ID`.
115
-
116
-**Response**:
117
-```
118
-{
119
-  "Dir": "/var/mygraph/46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
120
-  "Err": ""
121
-}
122
-```
123
-
124
-Respond with the absolute path to the mounted layered filesystem.
125
-Respond with a non-empty string error if an error occurred.
126
-
127
-### /GraphDriver.Put
128
-
129
-**Request**:
130
-```
131
-{
132
-  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
133
-}
134
-```
135
-
136
-Release the system resources for the specified `ID`, such as unmounting the
137
-filesystem layer.
138
-
139
-**Response**:
140
-```
141
-{
142
-  "Err": ""
143
-}
144
-```
145
-
146
-Respond with a non-empty string error if an error occurred.
147
-
148
-### /GraphDriver.Exists
149
-
150
-**Request**:
151
-```
152
-{
153
-  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
154
-}
155
-```
156
-
157
-Determine if a filesystem layer with the specified `ID` exists.
158
-
159
-**Response**:
160
-```
161
-{
162
-  "Exists": true
163
-}
164
-```
165
-
166
-Respond with a boolean for whether or not the filesystem layer with the specified
167
-`ID` exists.
168
-
169
-### /GraphDriver.Status
170
-
171
-**Request**:
172
-```
173
-{}
174
-```
175
-
176
-Get low-level diagnostic information about the graph driver.
177
-
178
-**Response**:
179
-```
180
-{
181
-  "Status": [[]]
182
-}
183
-```
184
-
185
-Respond with a 2-D array with key/value pairs for the underlying status
186
-information.
187
-
188
-
189
-### /GraphDriver.GetMetadata
190
-
191
-**Request**:
192
-```
193
-{
194
-  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
195
-}
196
-```
197
-
198
-Get low-level diagnostic information about the layered filesystem with the
199
-with the specified `ID`
200
-
201
-**Response**:
202
-```
203
-{
204
-  "Metadata": {},
205
-  "Err": ""
206
-}
207
-```
208
-
209
-Respond with a set of key/value pairs containing the low-level diagnostic
210
-information about the layered filesystem.
211
-Respond with a non-empty string error if an error occurred.
212
-
213
-### /GraphDriver.Cleanup
214
-
215
-**Request**:
216
-```
217
-{}
218
-```
219
-
220
-Perform necessary tasks to release resources help by the plugin, for example
221
-unmounting all the layered file systems.
222
-
223
-**Response**:
224
-```
225
-{
226
-  "Err": ""
227
-}
228
-```
229
-
230
-Respond with a non-empty string error if an error occurred.
231
-
232
-
233
-### /GraphDriver.Diff
234
-
235
-**Request**:
236
-```
237
-{
238
-  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
239
-  "Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
240
-}
241
-```
242
-
243
-Get an archive of the changes between the filesystem layers specified by the `ID`
244
-and `Parent`. `Parent` may be an empty string, in which case there is no parent.
245
-
246
-**Response**:
247
-```
248
-{{ TAR STREAM }}
249
-```
250
-
251
-### /GraphDriver.Changes
252
-
253
-**Request**:
254
-```
255
-{
256
-  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
257
-  "Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
258
-}
259
-```
260
-
261
-Get a list of changes between the filesystem layers specified by the `ID` and
262
-`Parent`. `Parent` may be an empty string, in which case there is no parent.
263
-
264
-**Response**:
265
-```
266
-{
267
-  "Changes": [{}],
268
-  "Err": ""
269
-}
270
-```
271
-
272
-Respond with a list of changes. The structure of a change is:
273
-```
274
-  "Path": "/some/path",
275
-  "Kind": 0,
276
-```
277
-
278
-Where the `Path` is the filesystem path within the layered filesystem that is
279
-changed and `Kind` is an integer specifying the type of change that occurred:
280
-
281
-- 0 - Modified
282
-- 1 - Added
283
-- 2 - Deleted
284
-
285
-Respond with a non-empty string error if an error occurred.
286
-
287
-### /GraphDriver.ApplyDiff
288
-
289
-**Request**:
290
-```
291
-{{ TAR STREAM }}
292
-```
293
-
294
-Extract the changeset from the given diff into the layer with the specified `ID`
295
-and `Parent`
296
-
297
-**Query Parameters**:
298
-
299
-- id (required)- the `ID` of the new filesystem layer to extract the diff to
300
-- parent (required)- the `Parent` of the given `ID`
301
-
302
-**Response**:
303
-```
304
-{
305
-  "Size": 512366,
306
-  "Err": ""
307
-}
308
-```
309
-
310
-Respond with the size of the new layer in bytes.
311
-Respond with a non-empty string error if an error occurred.
312
-
313
-### /GraphDriver.DiffSize
314
-
315
-**Request**:
316
-```
317
-{
318
-  "ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
319
-  "Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
320
-}
321
-```
322
-
323
-Calculate the changes between the specified `ID`
324
-
325
-**Response**:
326
-```
327
-{
328
-  "Size": 512366,
329
-  "Err": ""
330
-}
331
-```
332
-
333
-Respond with the size changes between the specified `ID` and `Parent`
334
-Respond with a non-empty string error if an error occurred.
... ...
@@ -236,7 +236,7 @@ func (s *DockerDaemonSuite) TestVolumePlugin(c *check.C) {
236 236
 }
237 237
 
238 238
 func (s *DockerDaemonSuite) TestGraphdriverPlugin(c *check.C) {
239
-	testRequires(c, Network, IsAmd64, DaemonIsLinux, overlay2Supported)
239
+	testRequires(c, Network, IsAmd64, DaemonIsLinux, overlay2Supported, ExperimentalDaemon)
240 240
 
241 241
 	s.d.Start(c)
242 242
 
... ...
@@ -45,17 +45,18 @@ type StoreOptions struct {
45 45
 	UIDMaps                   []idtools.IDMap
46 46
 	GIDMaps                   []idtools.IDMap
47 47
 	PluginGetter              plugingetter.PluginGetter
48
+	ExperimentalEnabled       bool
48 49
 }
49 50
 
50 51
 // NewStoreFromOptions creates a new Store instance
51 52
 func NewStoreFromOptions(options StoreOptions) (Store, error) {
52
-	driver, err := graphdriver.New(
53
-		options.StorePath,
54
-		options.GraphDriver,
55
-		options.GraphDriverOptions,
56
-		options.UIDMaps,
57
-		options.GIDMaps,
58
-		options.PluginGetter)
53
+	driver, err := graphdriver.New(options.GraphDriver, options.PluginGetter, graphdriver.Options{
54
+		Root:                options.StorePath,
55
+		DriverOptions:       options.GraphDriverOptions,
56
+		UIDMaps:             options.UIDMaps,
57
+		GIDMaps:             options.GIDMaps,
58
+		ExperimentalEnabled: options.ExperimentalEnabled,
59
+	})
59 60
 	if err != nil {
60 61
 		return nil, fmt.Errorf("error initializing graphdriver: %v", err)
61 62
 	}
... ...
@@ -39,7 +39,8 @@ func newVFSGraphDriver(td string) (graphdriver.Driver, error) {
39 39
 		},
40 40
 	}
41 41
 
42
-	return graphdriver.GetDriver("vfs", td, nil, uidMap, gidMap, nil)
42
+	options := graphdriver.Options{Root: td, UIDMaps: uidMap, GIDMaps: gidMap}
43
+	return graphdriver.GetDriver("vfs", nil, options)
43 44
 }
44 45
 
45 46
 func newTestGraphDriver(t *testing.T) (graphdriver.Driver, func()) {