| package graphdriver // import "github.com/docker/docker/daemon/graphdriver" | |
| import ( | |
| "errors" | |
| "fmt" | |
| "io" | |
| "github.com/docker/docker/pkg/archive" | |
| "github.com/docker/docker/pkg/idtools" | |
| "github.com/docker/docker/pkg/plugingetter" | |
| "github.com/docker/docker/pkg/plugins" | |
| ) | |
| type graphDriverProxy struct { | |
| name string | |
| p plugingetter.CompatPlugin | |
| caps Capabilities | |
| client *plugins.Client | |
| } | |
| type graphDriverRequest struct { | |
| ID string `json:",omitempty"` | |
| Parent string `json:",omitempty"` | |
| MountLabel string `json:",omitempty"` | |
| StorageOpt map[string]string `json:",omitempty"` | |
| } | |
| type graphDriverResponse struct { | |
| Err string `json:",omitempty"` | |
| Dir string `json:",omitempty"` | |
| Exists bool `json:",omitempty"` | |
| Status [][2]string `json:",omitempty"` | |
| Changes []archive.Change `json:",omitempty"` | |
| Size int64 `json:",omitempty"` | |
| Metadata map[string]string `json:",omitempty"` | |
| Capabilities Capabilities `json:",omitempty"` | |
| } | |
| type graphDriverInitRequest struct { | |
| Home string | |
| Opts []string `json:"Opts"` | |
| idtools.IdentityMapping | |
| } | |
| func (d *graphDriverProxy) Init(home string, opts []string, idMap idtools.IdentityMapping) error { | |
| if !d.p.IsV1() { | |
| if cp, ok := d.p.(plugingetter.CountedPlugin); ok { | |
| // always acquire here, it will be cleaned up on daemon shutdown | |
| cp.Acquire() | |
| } | |
| } | |
| args := &graphDriverInitRequest{ | |
| Home: home, | |
| Opts: opts, | |
| IdentityMapping: idMap, | |
| } | |
| var ret graphDriverResponse | |
| if err := d.client.Call("GraphDriver.Init", args, &ret); err != nil { | |
| return err | |
| } | |
| if ret.Err != "" { | |
| return errors.New(ret.Err) | |
| } | |
| caps, err := d.fetchCaps() | |
| if err != nil { | |
| return err | |
| } | |
| d.caps = caps | |
| return nil | |
| } | |
| func (d *graphDriverProxy) fetchCaps() (Capabilities, error) { | |
| args := &graphDriverRequest{} | |
| var ret graphDriverResponse | |
| if err := d.client.Call("GraphDriver.Capabilities", args, &ret); err != nil { | |
| if !plugins.IsNotFound(err) { | |
| return Capabilities{}, err | |
| } | |
| } | |
| return ret.Capabilities, nil | |
| } | |
| func (d *graphDriverProxy) String() string { | |
| return d.name | |
| } | |
| func (d *graphDriverProxy) Capabilities() Capabilities { | |
| return d.caps | |
| } | |
| func (d *graphDriverProxy) CreateReadWrite(id, parent string, opts *CreateOpts) error { | |
| return d.create("GraphDriver.CreateReadWrite", id, parent, opts) | |
| } | |
| func (d *graphDriverProxy) Create(id, parent string, opts *CreateOpts) error { | |
| return d.create("GraphDriver.Create", id, parent, opts) | |
| } | |
| func (d *graphDriverProxy) create(method, id, parent string, opts *CreateOpts) error { | |
| args := &graphDriverRequest{ | |
| ID: id, | |
| Parent: parent, | |
| } | |
| if opts != nil { | |
| args.MountLabel = opts.MountLabel | |
| args.StorageOpt = opts.StorageOpt | |
| } | |
| var ret graphDriverResponse | |
| if err := d.client.Call(method, args, &ret); err != nil { | |
| return err | |
| } | |
| if ret.Err != "" { | |
| return errors.New(ret.Err) | |
| } | |
| return nil | |
| } | |
| func (d *graphDriverProxy) Remove(id string) error { | |
| args := &graphDriverRequest{ID: id} | |
| var ret graphDriverResponse | |
| if err := d.client.Call("GraphDriver.Remove", args, &ret); err != nil { | |
| return err | |
| } | |
| if ret.Err != "" { | |
| return errors.New(ret.Err) | |
| } | |
| return nil | |
| } | |
| func (d *graphDriverProxy) Get(id, mountLabel string) (string, error) { | |
| args := &graphDriverRequest{ | |
| ID: id, | |
| MountLabel: mountLabel, | |
| } | |
| var ret graphDriverResponse | |
| if err := d.client.Call("GraphDriver.Get", args, &ret); err != nil { | |
| return "", err | |
| } | |
| var err error | |
| if ret.Err != "" { | |
| err = errors.New(ret.Err) | |
| } | |
| return d.p.ScopedPath(ret.Dir), err | |
| } | |
| func (d *graphDriverProxy) Put(id string) error { | |
| args := &graphDriverRequest{ID: id} | |
| var ret graphDriverResponse | |
| if err := d.client.Call("GraphDriver.Put", args, &ret); err != nil { | |
| return err | |
| } | |
| if ret.Err != "" { | |
| return errors.New(ret.Err) | |
| } | |
| return nil | |
| } | |
| func (d *graphDriverProxy) Exists(id string) bool { | |
| args := &graphDriverRequest{ID: id} | |
| var ret graphDriverResponse | |
| if err := d.client.Call("GraphDriver.Exists", args, &ret); err != nil { | |
| return false | |
| } | |
| return ret.Exists | |
| } | |
| func (d *graphDriverProxy) Status() [][2]string { | |
| args := &graphDriverRequest{} | |
| var ret graphDriverResponse | |
| if err := d.client.Call("GraphDriver.Status", args, &ret); err != nil { | |
| return nil | |
| } | |
| return ret.Status | |
| } | |
| func (d *graphDriverProxy) GetMetadata(id string) (map[string]string, error) { | |
| args := &graphDriverRequest{ | |
| ID: id, | |
| } | |
| var ret graphDriverResponse | |
| if err := d.client.Call("GraphDriver.GetMetadata", args, &ret); err != nil { | |
| return nil, err | |
| } | |
| if ret.Err != "" { | |
| return nil, errors.New(ret.Err) | |
| } | |
| return ret.Metadata, nil | |
| } | |
| func (d *graphDriverProxy) Cleanup() error { | |
| if !d.p.IsV1() { | |
| if cp, ok := d.p.(plugingetter.CountedPlugin); ok { | |
| // always release | |
| defer cp.Release() | |
| } | |
| } | |
| args := &graphDriverRequest{} | |
| var ret graphDriverResponse | |
| if err := d.client.Call("GraphDriver.Cleanup", args, &ret); err != nil { | |
| return nil | |
| } | |
| if ret.Err != "" { | |
| return errors.New(ret.Err) | |
| } | |
| return nil | |
| } | |
| func (d *graphDriverProxy) Diff(id, parent string) (io.ReadCloser, error) { | |
| args := &graphDriverRequest{ | |
| ID: id, | |
| Parent: parent, | |
| } | |
| body, err := d.client.Stream("GraphDriver.Diff", args) | |
| if err != nil { | |
| return nil, err | |
| } | |
| return body, nil | |
| } | |
| func (d *graphDriverProxy) Changes(id, parent string) ([]archive.Change, error) { | |
| args := &graphDriverRequest{ | |
| ID: id, | |
| Parent: parent, | |
| } | |
| var ret graphDriverResponse | |
| if err := d.client.Call("GraphDriver.Changes", args, &ret); err != nil { | |
| return nil, err | |
| } | |
| if ret.Err != "" { | |
| return nil, errors.New(ret.Err) | |
| } | |
| return ret.Changes, nil | |
| } | |
| func (d *graphDriverProxy) ApplyDiff(id, parent string, diff io.Reader) (int64, error) { | |
| var ret graphDriverResponse | |
| if err := d.client.SendFile(fmt.Sprintf("GraphDriver.ApplyDiff?id=%s&parent=%s", id, parent), diff, &ret); err != nil { | |
| return -1, err | |
| } | |
| if ret.Err != "" { | |
| return -1, errors.New(ret.Err) | |
| } | |
| return ret.Size, nil | |
| } | |
| func (d *graphDriverProxy) DiffSize(id, parent string) (int64, error) { | |
| args := &graphDriverRequest{ | |
| ID: id, | |
| Parent: parent, | |
| } | |
| var ret graphDriverResponse | |
| if err := d.client.Call("GraphDriver.DiffSize", args, &ret); err != nil { | |
| return -1, err | |
| } | |
| if ret.Err != "" { | |
| return -1, errors.New(ret.Err) | |
| } | |
| return ret.Size, nil | |
| } |