github.com/mforkel/docker-ce-i386@v17.12.1-ce-rc2+incompatible/components/engine/daemon/graphdriver/proxy.go (about)

     1  package graphdriver
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"path/filepath"
     8  
     9  	"github.com/docker/docker/pkg/archive"
    10  	"github.com/docker/docker/pkg/containerfs"
    11  	"github.com/docker/docker/pkg/idtools"
    12  	"github.com/docker/docker/pkg/plugingetter"
    13  	"github.com/docker/docker/pkg/plugins"
    14  )
    15  
    16  type graphDriverProxy struct {
    17  	name string
    18  	p    plugingetter.CompatPlugin
    19  	caps Capabilities
    20  }
    21  
    22  type graphDriverRequest struct {
    23  	ID         string            `json:",omitempty"`
    24  	Parent     string            `json:",omitempty"`
    25  	MountLabel string            `json:",omitempty"`
    26  	StorageOpt map[string]string `json:",omitempty"`
    27  }
    28  
    29  type graphDriverResponse struct {
    30  	Err          string            `json:",omitempty"`
    31  	Dir          string            `json:",omitempty"`
    32  	Exists       bool              `json:",omitempty"`
    33  	Status       [][2]string       `json:",omitempty"`
    34  	Changes      []archive.Change  `json:",omitempty"`
    35  	Size         int64             `json:",omitempty"`
    36  	Metadata     map[string]string `json:",omitempty"`
    37  	Capabilities Capabilities      `json:",omitempty"`
    38  }
    39  
    40  type graphDriverInitRequest struct {
    41  	Home    string
    42  	Opts    []string        `json:"Opts"`
    43  	UIDMaps []idtools.IDMap `json:"UIDMaps"`
    44  	GIDMaps []idtools.IDMap `json:"GIDMaps"`
    45  }
    46  
    47  func (d *graphDriverProxy) Init(home string, opts []string, uidMaps, gidMaps []idtools.IDMap) error {
    48  	if !d.p.IsV1() {
    49  		if cp, ok := d.p.(plugingetter.CountedPlugin); ok {
    50  			// always acquire here, it will be cleaned up on daemon shutdown
    51  			cp.Acquire()
    52  		}
    53  	}
    54  	args := &graphDriverInitRequest{
    55  		Home:    home,
    56  		Opts:    opts,
    57  		UIDMaps: uidMaps,
    58  		GIDMaps: gidMaps,
    59  	}
    60  	var ret graphDriverResponse
    61  	if err := d.p.Client().Call("GraphDriver.Init", args, &ret); err != nil {
    62  		return err
    63  	}
    64  	if ret.Err != "" {
    65  		return errors.New(ret.Err)
    66  	}
    67  	caps, err := d.fetchCaps()
    68  	if err != nil {
    69  		return err
    70  	}
    71  	d.caps = caps
    72  	return nil
    73  }
    74  
    75  func (d *graphDriverProxy) fetchCaps() (Capabilities, error) {
    76  	args := &graphDriverRequest{}
    77  	var ret graphDriverResponse
    78  	if err := d.p.Client().Call("GraphDriver.Capabilities", args, &ret); err != nil {
    79  		if !plugins.IsNotFound(err) {
    80  			return Capabilities{}, err
    81  		}
    82  	}
    83  	return ret.Capabilities, nil
    84  }
    85  
    86  func (d *graphDriverProxy) String() string {
    87  	return d.name
    88  }
    89  
    90  func (d *graphDriverProxy) Capabilities() Capabilities {
    91  	return d.caps
    92  }
    93  
    94  func (d *graphDriverProxy) CreateReadWrite(id, parent string, opts *CreateOpts) error {
    95  	return d.create("GraphDriver.CreateReadWrite", id, parent, opts)
    96  }
    97  
    98  func (d *graphDriverProxy) Create(id, parent string, opts *CreateOpts) error {
    99  	return d.create("GraphDriver.Create", id, parent, opts)
   100  }
   101  
   102  func (d *graphDriverProxy) create(method, id, parent string, opts *CreateOpts) error {
   103  	args := &graphDriverRequest{
   104  		ID:     id,
   105  		Parent: parent,
   106  	}
   107  	if opts != nil {
   108  		args.MountLabel = opts.MountLabel
   109  		args.StorageOpt = opts.StorageOpt
   110  	}
   111  	var ret graphDriverResponse
   112  	if err := d.p.Client().Call(method, args, &ret); err != nil {
   113  		return err
   114  	}
   115  	if ret.Err != "" {
   116  		return errors.New(ret.Err)
   117  	}
   118  	return nil
   119  }
   120  
   121  func (d *graphDriverProxy) Remove(id string) error {
   122  	args := &graphDriverRequest{ID: id}
   123  	var ret graphDriverResponse
   124  	if err := d.p.Client().Call("GraphDriver.Remove", args, &ret); err != nil {
   125  		return err
   126  	}
   127  	if ret.Err != "" {
   128  		return errors.New(ret.Err)
   129  	}
   130  	return nil
   131  }
   132  
   133  func (d *graphDriverProxy) Get(id, mountLabel string) (containerfs.ContainerFS, error) {
   134  	args := &graphDriverRequest{
   135  		ID:         id,
   136  		MountLabel: mountLabel,
   137  	}
   138  	var ret graphDriverResponse
   139  	if err := d.p.Client().Call("GraphDriver.Get", args, &ret); err != nil {
   140  		return nil, err
   141  	}
   142  	var err error
   143  	if ret.Err != "" {
   144  		err = errors.New(ret.Err)
   145  	}
   146  	return containerfs.NewLocalContainerFS(filepath.Join(d.p.BasePath(), ret.Dir)), err
   147  }
   148  
   149  func (d *graphDriverProxy) Put(id string) error {
   150  	args := &graphDriverRequest{ID: id}
   151  	var ret graphDriverResponse
   152  	if err := d.p.Client().Call("GraphDriver.Put", args, &ret); err != nil {
   153  		return err
   154  	}
   155  	if ret.Err != "" {
   156  		return errors.New(ret.Err)
   157  	}
   158  	return nil
   159  }
   160  
   161  func (d *graphDriverProxy) Exists(id string) bool {
   162  	args := &graphDriverRequest{ID: id}
   163  	var ret graphDriverResponse
   164  	if err := d.p.Client().Call("GraphDriver.Exists", args, &ret); err != nil {
   165  		return false
   166  	}
   167  	return ret.Exists
   168  }
   169  
   170  func (d *graphDriverProxy) Status() [][2]string {
   171  	args := &graphDriverRequest{}
   172  	var ret graphDriverResponse
   173  	if err := d.p.Client().Call("GraphDriver.Status", args, &ret); err != nil {
   174  		return nil
   175  	}
   176  	return ret.Status
   177  }
   178  
   179  func (d *graphDriverProxy) GetMetadata(id string) (map[string]string, error) {
   180  	args := &graphDriverRequest{
   181  		ID: id,
   182  	}
   183  	var ret graphDriverResponse
   184  	if err := d.p.Client().Call("GraphDriver.GetMetadata", args, &ret); err != nil {
   185  		return nil, err
   186  	}
   187  	if ret.Err != "" {
   188  		return nil, errors.New(ret.Err)
   189  	}
   190  	return ret.Metadata, nil
   191  }
   192  
   193  func (d *graphDriverProxy) Cleanup() error {
   194  	if !d.p.IsV1() {
   195  		if cp, ok := d.p.(plugingetter.CountedPlugin); ok {
   196  			// always release
   197  			defer cp.Release()
   198  		}
   199  	}
   200  
   201  	args := &graphDriverRequest{}
   202  	var ret graphDriverResponse
   203  	if err := d.p.Client().Call("GraphDriver.Cleanup", args, &ret); err != nil {
   204  		return nil
   205  	}
   206  	if ret.Err != "" {
   207  		return errors.New(ret.Err)
   208  	}
   209  	return nil
   210  }
   211  
   212  func (d *graphDriverProxy) Diff(id, parent string) (io.ReadCloser, error) {
   213  	args := &graphDriverRequest{
   214  		ID:     id,
   215  		Parent: parent,
   216  	}
   217  	body, err := d.p.Client().Stream("GraphDriver.Diff", args)
   218  	if err != nil {
   219  		return nil, err
   220  	}
   221  	return body, nil
   222  }
   223  
   224  func (d *graphDriverProxy) Changes(id, parent string) ([]archive.Change, error) {
   225  	args := &graphDriverRequest{
   226  		ID:     id,
   227  		Parent: parent,
   228  	}
   229  	var ret graphDriverResponse
   230  	if err := d.p.Client().Call("GraphDriver.Changes", args, &ret); err != nil {
   231  		return nil, err
   232  	}
   233  	if ret.Err != "" {
   234  		return nil, errors.New(ret.Err)
   235  	}
   236  
   237  	return ret.Changes, nil
   238  }
   239  
   240  func (d *graphDriverProxy) ApplyDiff(id, parent string, diff io.Reader) (int64, error) {
   241  	var ret graphDriverResponse
   242  	if err := d.p.Client().SendFile(fmt.Sprintf("GraphDriver.ApplyDiff?id=%s&parent=%s", id, parent), diff, &ret); err != nil {
   243  		return -1, err
   244  	}
   245  	if ret.Err != "" {
   246  		return -1, errors.New(ret.Err)
   247  	}
   248  	return ret.Size, nil
   249  }
   250  
   251  func (d *graphDriverProxy) DiffSize(id, parent string) (int64, error) {
   252  	args := &graphDriverRequest{
   253  		ID:     id,
   254  		Parent: parent,
   255  	}
   256  	var ret graphDriverResponse
   257  	if err := d.p.Client().Call("GraphDriver.DiffSize", args, &ret); err != nil {
   258  		return -1, err
   259  	}
   260  	if ret.Err != "" {
   261  		return -1, errors.New(ret.Err)
   262  	}
   263  	return ret.Size, nil
   264  }