|
@@ -34,6 +34,8 @@ type layerStore struct {
|
|
|
|
|
|
mounts map[string]*mountedLayer
|
|
|
mountL sync.Mutex
|
|
|
+
|
|
|
+ useTarSplit bool
|
|
|
}
|
|
|
|
|
|
// StoreOptions are the options used to create a new Store instance
|
|
@@ -74,11 +76,17 @@ func NewStoreFromOptions(options StoreOptions) (Store, error) {
|
|
|
// metadata store and graph driver. The metadata store will be used to restore
|
|
|
// the Store.
|
|
|
func NewStoreFromGraphDriver(store MetadataStore, driver graphdriver.Driver) (Store, error) {
|
|
|
+ caps := graphdriver.Capabilities{}
|
|
|
+ if capDriver, ok := driver.(graphdriver.CapabilityDriver); ok {
|
|
|
+ caps = capDriver.Capabilities()
|
|
|
+ }
|
|
|
+
|
|
|
ls := &layerStore{
|
|
|
- store: store,
|
|
|
- driver: driver,
|
|
|
- layerMap: map[ChainID]*roLayer{},
|
|
|
- mounts: map[string]*mountedLayer{},
|
|
|
+ store: store,
|
|
|
+ driver: driver,
|
|
|
+ layerMap: map[ChainID]*roLayer{},
|
|
|
+ mounts: map[string]*mountedLayer{},
|
|
|
+ useTarSplit: !caps.ReproducesExactDiffs,
|
|
|
}
|
|
|
|
|
|
ids, mounts, err := store.List()
|
|
@@ -207,18 +215,21 @@ func (ls *layerStore) applyTar(tx MetadataTransaction, ts io.Reader, parent stri
|
|
|
digester := digest.Canonical.Digester()
|
|
|
tr := io.TeeReader(ts, digester.Hash())
|
|
|
|
|
|
- tsw, err := tx.TarSplitWriter(true)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- metaPacker := storage.NewJSONPacker(tsw)
|
|
|
- defer tsw.Close()
|
|
|
+ rdr := tr
|
|
|
+ if ls.useTarSplit {
|
|
|
+ tsw, err := tx.TarSplitWriter(true)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ metaPacker := storage.NewJSONPacker(tsw)
|
|
|
+ defer tsw.Close()
|
|
|
|
|
|
- // we're passing nil here for the file putter, because the ApplyDiff will
|
|
|
- // handle the extraction of the archive
|
|
|
- rdr, err := asm.NewInputTarStream(tr, metaPacker, nil)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
+ // we're passing nil here for the file putter, because the ApplyDiff will
|
|
|
+ // handle the extraction of the archive
|
|
|
+ rdr, err = asm.NewInputTarStream(tr, metaPacker, nil)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
applySize, err := ls.driver.ApplyDiff(layer.cacheID, parent, rdr)
|
|
@@ -640,6 +651,34 @@ func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc Mou
|
|
|
return initID, nil
|
|
|
}
|
|
|
|
|
|
+func (ls *layerStore) getTarStream(rl *roLayer) (io.ReadCloser, error) {
|
|
|
+ if !ls.useTarSplit {
|
|
|
+ var parentCacheID string
|
|
|
+ if rl.parent != nil {
|
|
|
+ parentCacheID = rl.parent.cacheID
|
|
|
+ }
|
|
|
+
|
|
|
+ return ls.driver.Diff(rl.cacheID, parentCacheID)
|
|
|
+ }
|
|
|
+
|
|
|
+ r, err := ls.store.TarSplitReader(rl.chainID)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ pr, pw := io.Pipe()
|
|
|
+ go func() {
|
|
|
+ err := ls.assembleTarTo(rl.cacheID, r, nil, pw)
|
|
|
+ if err != nil {
|
|
|
+ pw.CloseWithError(err)
|
|
|
+ } else {
|
|
|
+ pw.Close()
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ return pr, nil
|
|
|
+}
|
|
|
+
|
|
|
func (ls *layerStore) assembleTarTo(graphID string, metadata io.ReadCloser, size *int64, w io.Writer) error {
|
|
|
diffDriver, ok := ls.driver.(graphdriver.DiffGetterDriver)
|
|
|
if !ok {
|