github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/daemon/graphdriver/proxy.go (about)

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