mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #28623 from cpuguy83/update_graphdriver_docs
Ensure graphdriver only loads with experimental flag
This commit is contained in:
commit
d3e3a97cb2
9 changed files with 153 additions and 91 deletions
|
@ -575,6 +575,7 @@ func NewDaemon(config *Config, registryService registry.Service, containerdRemot
|
||||||
UIDMaps: uidMaps,
|
UIDMaps: uidMaps,
|
||||||
GIDMaps: gidMaps,
|
GIDMaps: gidMaps,
|
||||||
PluginGetter: d.PluginStore,
|
PluginGetter: d.PluginStore,
|
||||||
|
ExperimentalEnabled: config.Experimental,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -150,16 +150,16 @@ func Register(name string, initFunc InitFunc) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDriver initializes and returns the registered driver
|
// GetDriver initializes and returns the registered driver
|
||||||
func GetDriver(name, home string, options []string, uidMaps, gidMaps []idtools.IDMap, pg plugingetter.PluginGetter) (Driver, error) {
|
func GetDriver(name string, pg plugingetter.PluginGetter, config Options) (Driver, error) {
|
||||||
if initFunc, exists := drivers[name]; exists {
|
if initFunc, exists := drivers[name]; exists {
|
||||||
return initFunc(filepath.Join(home, name), options, uidMaps, gidMaps)
|
return initFunc(filepath.Join(config.Root, name), config.DriverOptions, config.UIDMaps, config.GIDMaps)
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginDriver, err := lookupPlugin(name, home, options, pg)
|
pluginDriver, err := lookupPlugin(name, pg, config)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return pluginDriver, nil
|
return pluginDriver, nil
|
||||||
}
|
}
|
||||||
logrus.WithError(err).WithField("driver", name).WithField("home-dir", home).Error("Failed to GetDriver graph")
|
logrus.WithError(err).WithField("driver", name).WithField("home-dir", config.Root).Error("Failed to GetDriver graph")
|
||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,15 +172,24 @@ func getBuiltinDriver(name, home string, options []string, uidMaps, gidMaps []id
|
||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Options is used to initialize a graphdriver
|
||||||
|
type Options struct {
|
||||||
|
Root string
|
||||||
|
DriverOptions []string
|
||||||
|
UIDMaps []idtools.IDMap
|
||||||
|
GIDMaps []idtools.IDMap
|
||||||
|
ExperimentalEnabled bool
|
||||||
|
}
|
||||||
|
|
||||||
// New creates the driver and initializes it at the specified root.
|
// New creates the driver and initializes it at the specified root.
|
||||||
func New(root, name string, options []string, uidMaps, gidMaps []idtools.IDMap, pg plugingetter.PluginGetter) (Driver, error) {
|
func New(name string, pg plugingetter.PluginGetter, config Options) (Driver, error) {
|
||||||
if name != "" {
|
if name != "" {
|
||||||
logrus.Debugf("[graphdriver] trying provided driver: %s", name) // so the logs show specified driver
|
logrus.Debugf("[graphdriver] trying provided driver: %s", name) // so the logs show specified driver
|
||||||
return GetDriver(name, root, options, uidMaps, gidMaps, pg)
|
return GetDriver(name, pg, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Guess for prior driver
|
// Guess for prior driver
|
||||||
driversMap := scanPriorDrivers(root)
|
driversMap := scanPriorDrivers(config.Root)
|
||||||
for _, name := range priority {
|
for _, name := range priority {
|
||||||
if name == "vfs" {
|
if name == "vfs" {
|
||||||
// don't use vfs even if there is state present.
|
// 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,
|
||||||
if _, prior := driversMap[name]; prior {
|
if _, prior := driversMap[name]; prior {
|
||||||
// of the state found from prior drivers, check in order of our priority
|
// of the state found from prior drivers, check in order of our priority
|
||||||
// which we would prefer
|
// which we would prefer
|
||||||
driver, err := getBuiltinDriver(name, root, options, uidMaps, gidMaps)
|
driver, err := getBuiltinDriver(name, config.Root, config.DriverOptions, config.UIDMaps, config.GIDMaps)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// unlike below, we will return error here, because there is prior
|
// unlike below, we will return error here, because there is prior
|
||||||
// state, and now it is no longer supported/prereq/compatible, so
|
// 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,
|
||||||
driversSlice = append(driversSlice, name)
|
driversSlice = append(driversSlice, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("%s contains several valid graphdrivers: %s; Please cleanup or explicitly choose storage driver (-s <DRIVER>)", root, strings.Join(driversSlice, ", "))
|
return nil, fmt.Errorf("%s contains several valid graphdrivers: %s; Please cleanup or explicitly choose storage driver (-s <DRIVER>)", config.Root, strings.Join(driversSlice, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Infof("[graphdriver] using prior storage driver: %s", name)
|
logrus.Infof("[graphdriver] using prior storage driver: %s", name)
|
||||||
|
@ -217,7 +226,7 @@ func New(root, name string, options []string, uidMaps, gidMaps []idtools.IDMap,
|
||||||
|
|
||||||
// Check for priority drivers first
|
// Check for priority drivers first
|
||||||
for _, name := range priority {
|
for _, name := range priority {
|
||||||
driver, err := getBuiltinDriver(name, root, options, uidMaps, gidMaps)
|
driver, err := getBuiltinDriver(name, config.Root, config.DriverOptions, config.UIDMaps, config.GIDMaps)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if isDriverNotSupported(err) {
|
if isDriverNotSupported(err) {
|
||||||
continue
|
continue
|
||||||
|
@ -229,7 +238,7 @@ func New(root, name string, options []string, uidMaps, gidMaps []idtools.IDMap,
|
||||||
|
|
||||||
// Check all registered drivers if no priority driver is found
|
// Check all registered drivers if no priority driver is found
|
||||||
for name, initFunc := range drivers {
|
for name, initFunc := range drivers {
|
||||||
driver, err := initFunc(filepath.Join(root, name), options, uidMaps, gidMaps)
|
driver, err := initFunc(filepath.Join(config.Root, name), config.DriverOptions, config.UIDMaps, config.GIDMaps)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if isDriverNotSupported(err) {
|
if isDriverNotSupported(err) {
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -41,7 +41,7 @@ func newDriver(t testing.TB, name string, options []string) *Driver {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d, err := graphdriver.GetDriver(name, root, options, nil, nil, nil)
|
d, err := graphdriver.GetDriver(name, nil, graphdriver.Options{DriverOptions: options, Root: root})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Logf("graphdriver: %v\n", err)
|
t.Logf("graphdriver: %v\n", err)
|
||||||
if err == graphdriver.ErrNotSupported || err == graphdriver.ErrPrerequisites || err == graphdriver.ErrIncompatibleFS {
|
if err == graphdriver.ErrNotSupported || err == graphdriver.ErrPrerequisites || err == graphdriver.ErrIncompatibleFS {
|
||||||
|
|
|
@ -18,15 +18,19 @@ type pluginClient interface {
|
||||||
SendFile(string, io.Reader, interface{}) error
|
SendFile(string, io.Reader, interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupPlugin(name, home string, opts []string, pg plugingetter.PluginGetter) (Driver, error) {
|
func lookupPlugin(name string, pg plugingetter.PluginGetter, config Options) (Driver, error) {
|
||||||
pl, err := pg.Get(name, "GraphDriver", plugingetter.LOOKUP)
|
if !config.ExperimentalEnabled {
|
||||||
|
return nil, fmt.Errorf("graphdriver plugins are only supported with experimental mode")
|
||||||
|
}
|
||||||
|
pl, err := pg.Get(name, "GraphDriver", plugingetter.ACQUIRE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error looking up graphdriver plugin %s: %v", name, err)
|
return nil, fmt.Errorf("Error looking up graphdriver plugin %s: %v", name, err)
|
||||||
}
|
}
|
||||||
return newPluginDriver(name, home, opts, pl)
|
return newPluginDriver(name, pl, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPluginDriver(name, home string, opts []string, pl plugingetter.CompatPlugin) (Driver, error) {
|
func newPluginDriver(name string, pl plugingetter.CompatPlugin, config Options) (Driver, error) {
|
||||||
|
home := config.Root
|
||||||
if !pl.IsV1() {
|
if !pl.IsV1() {
|
||||||
if p, ok := pl.(*v2.Plugin); ok {
|
if p, ok := pl.(*v2.Plugin); ok {
|
||||||
if p.PropagatedMount != "" {
|
if p.PropagatedMount != "" {
|
||||||
|
@ -35,5 +39,5 @@ func newPluginDriver(name, home string, opts []string, pl plugingetter.CompatPlu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
proxy := &graphDriverProxy{name, pl}
|
proxy := &graphDriverProxy{name, pl}
|
||||||
return proxy, proxy.Init(filepath.Join(home, name), opts)
|
return proxy, proxy.Init(filepath.Join(home, name), config.DriverOptions, config.UIDMaps, config.GIDMaps)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/archive"
|
"github.com/docker/docker/pkg/archive"
|
||||||
|
"github.com/docker/docker/pkg/idtools"
|
||||||
"github.com/docker/docker/pkg/plugingetter"
|
"github.com/docker/docker/pkg/plugingetter"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,9 +17,10 @@ type graphDriverProxy struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type graphDriverRequest struct {
|
type graphDriverRequest struct {
|
||||||
ID string `json:",omitempty"`
|
ID string `json:",omitempty"`
|
||||||
Parent string `json:",omitempty"`
|
Parent string `json:",omitempty"`
|
||||||
MountLabel string `json:",omitempty"`
|
MountLabel string `json:",omitempty"`
|
||||||
|
StorageOpt map[string]string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type graphDriverResponse struct {
|
type graphDriverResponse struct {
|
||||||
|
@ -32,11 +34,13 @@ type graphDriverResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type graphDriverInitRequest struct {
|
type graphDriverInitRequest struct {
|
||||||
Home string
|
Home string
|
||||||
Opts []string
|
Opts []string `json:"Opts"`
|
||||||
|
UIDMaps []idtools.IDMap `json:"UIDMaps"`
|
||||||
|
GIDMaps []idtools.IDMap `json:"GIDMaps"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *graphDriverProxy) Init(home string, opts []string) error {
|
func (d *graphDriverProxy) Init(home string, opts []string, uidMaps, gidMaps []idtools.IDMap) error {
|
||||||
if !d.p.IsV1() {
|
if !d.p.IsV1() {
|
||||||
if cp, ok := d.p.(plugingetter.CountedPlugin); ok {
|
if cp, ok := d.p.(plugingetter.CountedPlugin); ok {
|
||||||
// always acquire here, it will be cleaned up on daemon shutdown
|
// always acquire here, it will be cleaned up on daemon shutdown
|
||||||
|
@ -44,8 +48,10 @@ func (d *graphDriverProxy) Init(home string, opts []string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args := &graphDriverInitRequest{
|
args := &graphDriverInitRequest{
|
||||||
Home: home,
|
Home: home,
|
||||||
Opts: opts,
|
Opts: opts,
|
||||||
|
UIDMaps: uidMaps,
|
||||||
|
GIDMaps: gidMaps,
|
||||||
}
|
}
|
||||||
var ret graphDriverResponse
|
var ret graphDriverResponse
|
||||||
if err := d.p.Client().Call("GraphDriver.Init", args, &ret); err != nil {
|
if err := d.p.Client().Call("GraphDriver.Init", args, &ret); err != nil {
|
||||||
|
@ -62,16 +68,15 @@ func (d *graphDriverProxy) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *graphDriverProxy) CreateReadWrite(id, parent string, opts *CreateOpts) error {
|
func (d *graphDriverProxy) CreateReadWrite(id, parent string, opts *CreateOpts) error {
|
||||||
mountLabel := ""
|
args := &graphDriverRequest{
|
||||||
|
ID: id,
|
||||||
|
Parent: parent,
|
||||||
|
}
|
||||||
if opts != nil {
|
if opts != nil {
|
||||||
mountLabel = opts.MountLabel
|
args.MountLabel = opts.MountLabel
|
||||||
|
args.StorageOpt = opts.StorageOpt
|
||||||
}
|
}
|
||||||
|
|
||||||
args := &graphDriverRequest{
|
|
||||||
ID: id,
|
|
||||||
Parent: parent,
|
|
||||||
MountLabel: mountLabel,
|
|
||||||
}
|
|
||||||
var ret graphDriverResponse
|
var ret graphDriverResponse
|
||||||
if err := d.p.Client().Call("GraphDriver.CreateReadWrite", args, &ret); err != nil {
|
if err := d.p.Client().Call("GraphDriver.CreateReadWrite", args, &ret); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -83,14 +88,13 @@ func (d *graphDriverProxy) CreateReadWrite(id, parent string, opts *CreateOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *graphDriverProxy) Create(id, parent string, opts *CreateOpts) error {
|
func (d *graphDriverProxy) Create(id, parent string, opts *CreateOpts) error {
|
||||||
mountLabel := ""
|
|
||||||
if opts != nil {
|
|
||||||
mountLabel = opts.MountLabel
|
|
||||||
}
|
|
||||||
args := &graphDriverRequest{
|
args := &graphDriverRequest{
|
||||||
ID: id,
|
ID: id,
|
||||||
Parent: parent,
|
Parent: parent,
|
||||||
MountLabel: mountLabel,
|
}
|
||||||
|
if opts != nil {
|
||||||
|
args.MountLabel = opts.MountLabel
|
||||||
|
args.StorageOpt = opts.StorageOpt
|
||||||
}
|
}
|
||||||
var ret graphDriverResponse
|
var ret graphDriverResponse
|
||||||
if err := d.p.Client().Call("GraphDriver.Create", args, &ret); err != nil {
|
if err := d.p.Client().Call("GraphDriver.Create", args, &ret); err != nil {
|
||||||
|
|
|
@ -1,12 +1,42 @@
|
||||||
# Experimental: Docker graph driver plugins
|
---
|
||||||
|
title: "Graphdriver plugins"
|
||||||
|
description: "How to manage image and container filesystems with external plugins"
|
||||||
|
keywords: "Examples, Usage, storage, image, docker, data, graph, plugin, api"
|
||||||
|
advisory: experimental
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- This file is maintained within the docker/docker Github
|
||||||
|
repository at https://github.com/docker/docker/. Make all
|
||||||
|
pull requests against that repo. If you see this file in
|
||||||
|
another repository, consider it read-only there, as it will
|
||||||
|
periodically be overwritten by the definitive file. Pull
|
||||||
|
requests which include edits to this file in other repositories
|
||||||
|
will be rejected.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
|
### 1.13.0
|
||||||
|
|
||||||
|
- Support v2 plugins
|
||||||
|
|
||||||
|
# Docker graph driver plugins
|
||||||
|
|
||||||
Docker graph driver plugins enable admins to use an external/out-of-process
|
Docker graph driver plugins enable admins to use an external/out-of-process
|
||||||
graph driver for use with Docker engine. This is an alternative to using the
|
graph driver for use with Docker engine. This is an alternative to using the
|
||||||
built-in storage drivers, such as aufs/overlay/devicemapper/btrfs.
|
built-in storage drivers, such as aufs/overlay/devicemapper/btrfs.
|
||||||
|
|
||||||
A graph driver plugin is used for image and container filesystem storage, as such
|
You need to install and enable the plugin and then restart the Docker daemon
|
||||||
the plugin must be started and available for connections prior to Docker Engine
|
before using the plugin. See the following example for the correct ordering
|
||||||
being started.
|
of steps.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ docker plugin install cpuguy83/docker-overlay2-graphdriver-plugin # this command also enables the driver
|
||||||
|
<output supressed>
|
||||||
|
$ pkill dockerd
|
||||||
|
$ dockerd --experimental -s cpuguy83/docker-overlay2-graphdriver-plugin
|
||||||
|
```
|
||||||
|
|
||||||
# Write a graph driver plugin
|
# Write a graph driver plugin
|
||||||
|
|
||||||
|
@ -22,20 +52,30 @@ expected to provide the rootfs for containers as well as image layer storage.
|
||||||
### /GraphDriver.Init
|
### /GraphDriver.Init
|
||||||
|
|
||||||
**Request**:
|
**Request**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"Home": "/graph/home/path",
|
"Home": "/graph/home/path",
|
||||||
"Opts": []
|
"Opts": [],
|
||||||
|
"UIDMaps": [],
|
||||||
|
"GIDMaps": []
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Initialize the graph driver plugin with a home directory and array of options.
|
Initialize the graph driver plugin with a home directory and array of options.
|
||||||
Plugins are not required to accept these options as the Docker Engine does not
|
These are passed through from the user, but the plugin is not required to parse
|
||||||
require that the plugin use this path or options, they are only being passed
|
or honor them.
|
||||||
through from the user.
|
|
||||||
|
The request also includes a list of UID and GID mappings, structed as follows:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ContainerID": 0,
|
||||||
|
"HostID": 0,
|
||||||
|
"Size": 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**Response**:
|
**Response**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"Err": ""
|
"Err": ""
|
||||||
}
|
}
|
||||||
|
@ -47,20 +87,21 @@ Respond with a non-empty string error if an error occurred.
|
||||||
### /GraphDriver.Create
|
### /GraphDriver.Create
|
||||||
|
|
||||||
**Request**:
|
**Request**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
|
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
|
||||||
"Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
|
"Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142",
|
||||||
"MountLabel": ""
|
"MountLabel": "",
|
||||||
|
"StorageOpt": {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Create a new, empty, read-only filesystem layer with the specified
|
Create a new, empty, read-only filesystem layer with the specified
|
||||||
`ID`, `Parent` and `MountLabel`. `Parent` may be an empty string,
|
`ID`, `Parent` and `MountLabel`. If `Parent` is an empty string, there is no
|
||||||
which would indicate that there is no parent layer.
|
parent layer. `StorageOpt` is map of strings which indicate storage options.
|
||||||
|
|
||||||
**Response**:
|
**Response**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"Err": ""
|
"Err": ""
|
||||||
}
|
}
|
||||||
|
@ -71,11 +112,12 @@ Respond with a non-empty string error if an error occurred.
|
||||||
### /GraphDriver.CreateReadWrite
|
### /GraphDriver.CreateReadWrite
|
||||||
|
|
||||||
**Request**:
|
**Request**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
|
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
|
||||||
"Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
|
"Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142",
|
||||||
"MountLabel": ""
|
"MountLabel": "",
|
||||||
|
"StorageOpt": {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -84,7 +126,7 @@ Similar to `/GraphDriver.Create` but creates a read-write filesystem layer.
|
||||||
### /GraphDriver.Remove
|
### /GraphDriver.Remove
|
||||||
|
|
||||||
**Request**:
|
**Request**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
|
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
|
||||||
}
|
}
|
||||||
|
@ -93,7 +135,7 @@ Similar to `/GraphDriver.Create` but creates a read-write filesystem layer.
|
||||||
Remove the filesystem layer with this given `ID`.
|
Remove the filesystem layer with this given `ID`.
|
||||||
|
|
||||||
**Response**:
|
**Response**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"Err": ""
|
"Err": ""
|
||||||
}
|
}
|
||||||
|
@ -104,9 +146,9 @@ Respond with a non-empty string error if an error occurred.
|
||||||
### /GraphDriver.Get
|
### /GraphDriver.Get
|
||||||
|
|
||||||
**Request**:
|
**Request**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
|
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
|
||||||
"MountLabel": ""
|
"MountLabel": ""
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -114,7 +156,7 @@ Respond with a non-empty string error if an error occurred.
|
||||||
Get the mountpoint for the layered filesystem referred to by the given `ID`.
|
Get the mountpoint for the layered filesystem referred to by the given `ID`.
|
||||||
|
|
||||||
**Response**:
|
**Response**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"Dir": "/var/mygraph/46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
|
"Dir": "/var/mygraph/46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
|
||||||
"Err": ""
|
"Err": ""
|
||||||
|
@ -127,7 +169,7 @@ Respond with a non-empty string error if an error occurred.
|
||||||
### /GraphDriver.Put
|
### /GraphDriver.Put
|
||||||
|
|
||||||
**Request**:
|
**Request**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
|
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
|
||||||
}
|
}
|
||||||
|
@ -137,7 +179,7 @@ Release the system resources for the specified `ID`, such as unmounting the
|
||||||
filesystem layer.
|
filesystem layer.
|
||||||
|
|
||||||
**Response**:
|
**Response**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"Err": ""
|
"Err": ""
|
||||||
}
|
}
|
||||||
|
@ -148,7 +190,7 @@ Respond with a non-empty string error if an error occurred.
|
||||||
### /GraphDriver.Exists
|
### /GraphDriver.Exists
|
||||||
|
|
||||||
**Request**:
|
**Request**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
|
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
|
||||||
}
|
}
|
||||||
|
@ -157,7 +199,7 @@ Respond with a non-empty string error if an error occurred.
|
||||||
Determine if a filesystem layer with the specified `ID` exists.
|
Determine if a filesystem layer with the specified `ID` exists.
|
||||||
|
|
||||||
**Response**:
|
**Response**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"Exists": true
|
"Exists": true
|
||||||
}
|
}
|
||||||
|
@ -169,14 +211,14 @@ Respond with a boolean for whether or not the filesystem layer with the specifie
|
||||||
### /GraphDriver.Status
|
### /GraphDriver.Status
|
||||||
|
|
||||||
**Request**:
|
**Request**:
|
||||||
```
|
```json
|
||||||
{}
|
{}
|
||||||
```
|
```
|
||||||
|
|
||||||
Get low-level diagnostic information about the graph driver.
|
Get low-level diagnostic information about the graph driver.
|
||||||
|
|
||||||
**Response**:
|
**Response**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"Status": [[]]
|
"Status": [[]]
|
||||||
}
|
}
|
||||||
|
@ -189,7 +231,7 @@ information.
|
||||||
### /GraphDriver.GetMetadata
|
### /GraphDriver.GetMetadata
|
||||||
|
|
||||||
**Request**:
|
**Request**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
|
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187"
|
||||||
}
|
}
|
||||||
|
@ -199,7 +241,7 @@ Get low-level diagnostic information about the layered filesystem with the
|
||||||
with the specified `ID`
|
with the specified `ID`
|
||||||
|
|
||||||
**Response**:
|
**Response**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"Metadata": {},
|
"Metadata": {},
|
||||||
"Err": ""
|
"Err": ""
|
||||||
|
@ -213,15 +255,15 @@ Respond with a non-empty string error if an error occurred.
|
||||||
### /GraphDriver.Cleanup
|
### /GraphDriver.Cleanup
|
||||||
|
|
||||||
**Request**:
|
**Request**:
|
||||||
```
|
```json
|
||||||
{}
|
{}
|
||||||
```
|
```
|
||||||
|
|
||||||
Perform necessary tasks to release resources help by the plugin, for example
|
Perform necessary tasks to release resources help by the plugin, such as
|
||||||
unmounting all the layered file systems.
|
unmounting all the layered file systems.
|
||||||
|
|
||||||
**Response**:
|
**Response**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"Err": ""
|
"Err": ""
|
||||||
}
|
}
|
||||||
|
@ -233,7 +275,7 @@ Respond with a non-empty string error if an error occurred.
|
||||||
### /GraphDriver.Diff
|
### /GraphDriver.Diff
|
||||||
|
|
||||||
**Request**:
|
**Request**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
|
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
|
||||||
"Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
|
"Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
|
||||||
|
@ -251,7 +293,7 @@ and `Parent`. `Parent` may be an empty string, in which case there is no parent.
|
||||||
### /GraphDriver.Changes
|
### /GraphDriver.Changes
|
||||||
|
|
||||||
**Request**:
|
**Request**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
|
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
|
||||||
"Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
|
"Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
|
||||||
|
@ -259,10 +301,10 @@ and `Parent`. `Parent` may be an empty string, in which case there is no parent.
|
||||||
```
|
```
|
||||||
|
|
||||||
Get a list of changes between the filesystem layers specified by the `ID` and
|
Get a list of changes between the filesystem layers specified by the `ID` and
|
||||||
`Parent`. `Parent` may be an empty string, in which case there is no parent.
|
`Parent`. If `Parent` is an empty string, there is no parent.
|
||||||
|
|
||||||
**Response**:
|
**Response**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"Changes": [{}],
|
"Changes": [{}],
|
||||||
"Err": ""
|
"Err": ""
|
||||||
|
@ -270,7 +312,7 @@ Get a list of changes between the filesystem layers specified by the `ID` and
|
||||||
```
|
```
|
||||||
|
|
||||||
Respond with a list of changes. The structure of a change is:
|
Respond with a list of changes. The structure of a change is:
|
||||||
```
|
```json
|
||||||
"Path": "/some/path",
|
"Path": "/some/path",
|
||||||
"Kind": 0,
|
"Kind": 0,
|
||||||
```
|
```
|
||||||
|
@ -300,7 +342,7 @@ and `Parent`
|
||||||
- parent (required)- the `Parent` of the given `ID`
|
- parent (required)- the `Parent` of the given `ID`
|
||||||
|
|
||||||
**Response**:
|
**Response**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"Size": 512366,
|
"Size": 512366,
|
||||||
"Err": ""
|
"Err": ""
|
||||||
|
@ -313,7 +355,7 @@ Respond with a non-empty string error if an error occurred.
|
||||||
### /GraphDriver.DiffSize
|
### /GraphDriver.DiffSize
|
||||||
|
|
||||||
**Request**:
|
**Request**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
|
"ID": "46fe8644f2572fd1e505364f7581e0c9dbc7f14640bd1fb6ce97714fb6fc5187",
|
||||||
"Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
|
"Parent": "2cd9c322cb78a55e8212aa3ea8425a4180236d7106938ec921d0935a4b8ca142"
|
||||||
|
@ -323,7 +365,7 @@ Respond with a non-empty string error if an error occurred.
|
||||||
Calculate the changes between the specified `ID`
|
Calculate the changes between the specified `ID`
|
||||||
|
|
||||||
**Response**:
|
**Response**:
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"Size": 512366,
|
"Size": 512366,
|
||||||
"Err": ""
|
"Err": ""
|
|
@ -236,7 +236,7 @@ func (s *DockerDaemonSuite) TestVolumePlugin(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerDaemonSuite) TestGraphdriverPlugin(c *check.C) {
|
func (s *DockerDaemonSuite) TestGraphdriverPlugin(c *check.C) {
|
||||||
testRequires(c, Network, IsAmd64, DaemonIsLinux, overlay2Supported)
|
testRequires(c, Network, IsAmd64, DaemonIsLinux, overlay2Supported, ExperimentalDaemon)
|
||||||
|
|
||||||
s.d.Start(c)
|
s.d.Start(c)
|
||||||
|
|
||||||
|
|
|
@ -45,17 +45,18 @@ type StoreOptions struct {
|
||||||
UIDMaps []idtools.IDMap
|
UIDMaps []idtools.IDMap
|
||||||
GIDMaps []idtools.IDMap
|
GIDMaps []idtools.IDMap
|
||||||
PluginGetter plugingetter.PluginGetter
|
PluginGetter plugingetter.PluginGetter
|
||||||
|
ExperimentalEnabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStoreFromOptions creates a new Store instance
|
// NewStoreFromOptions creates a new Store instance
|
||||||
func NewStoreFromOptions(options StoreOptions) (Store, error) {
|
func NewStoreFromOptions(options StoreOptions) (Store, error) {
|
||||||
driver, err := graphdriver.New(
|
driver, err := graphdriver.New(options.GraphDriver, options.PluginGetter, graphdriver.Options{
|
||||||
options.StorePath,
|
Root: options.StorePath,
|
||||||
options.GraphDriver,
|
DriverOptions: options.GraphDriverOptions,
|
||||||
options.GraphDriverOptions,
|
UIDMaps: options.UIDMaps,
|
||||||
options.UIDMaps,
|
GIDMaps: options.GIDMaps,
|
||||||
options.GIDMaps,
|
ExperimentalEnabled: options.ExperimentalEnabled,
|
||||||
options.PluginGetter)
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error initializing graphdriver: %v", err)
|
return nil, fmt.Errorf("error initializing graphdriver: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ func newVFSGraphDriver(td string) (graphdriver.Driver, error) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return graphdriver.GetDriver("vfs", td, nil, uidMap, gidMap, nil)
|
options := graphdriver.Options{Root: td, UIDMaps: uidMap, GIDMaps: gidMap}
|
||||||
|
return graphdriver.GetDriver("vfs", nil, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestGraphDriver(t *testing.T) (graphdriver.Driver, func()) {
|
func newTestGraphDriver(t *testing.T) (graphdriver.Driver, func()) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue