diff --git a/layer/layer.go b/layer/layer.go index d0c7fa8608..53923ad42a 100644 --- a/layer/layer.go +++ b/layer/layer.go @@ -145,6 +145,9 @@ type RWLayer interface { // Metadata returns the low level metadata for the mutable layer Metadata() (map[string]string, error) + + // ApplyDiff applies the diff to the RW layer + ApplyDiff(diff io.Reader) (int64, error) } // Metadata holds information about a diff --git a/layer/mount_test.go b/layer/mount_test.go index 1cfc370eed..3c868b2b20 100644 --- a/layer/mount_test.go +++ b/layer/mount_test.go @@ -206,6 +206,64 @@ func TestMountChanges(t *testing.T) { }) } +func TestMountApply(t *testing.T) { + // TODO Windows: Figure out why this is failing + if runtime.GOOS == "windows" { + t.Skip("Failing on Windows") + } + ls, _, cleanup := newTestStore(t) + defer cleanup() + + basefile := newTestFile("testfile.txt", []byte("base data!"), 0644) + newfile := newTestFile("newfile.txt", []byte("new data!"), 0755) + + li := initWithFiles(basefile) + layer, err := createLayer(ls, "", li) + if err != nil { + t.Fatal(err) + } + + di := initWithFiles(newfile) + diffLayer, err := createLayer(ls, "", di) + if err != nil { + t.Fatal(err) + } + + m, err := ls.CreateRWLayer("fun-mount", layer.ChainID(), nil) + if err != nil { + t.Fatal(err) + } + + r, err := diffLayer.TarStream() + if err != nil { + t.Fatal(err) + } + + if _, err := m.ApplyDiff(r); err != nil { + t.Fatal(err) + } + + pathFS, err := m.Mount("") + if err != nil { + t.Fatal(err) + } + + f, err := pathFS.Open(pathFS.Join(pathFS.Path(), "newfile.txt")) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + b, err := ioutil.ReadAll(f) + if err != nil { + t.Fatal(err) + } + + if expected := "new data!"; string(b) != expected { + t.Fatalf("Unexpected test file contents %q, expected %q", string(b), expected) + } +} + func assertChange(t *testing.T, actual, expected archive.Change) { if actual.Path != expected.Path { t.Fatalf("Unexpected change path %s, expected %s", actual.Path, expected.Path) diff --git a/layer/mounted_layer.go b/layer/mounted_layer.go index d6858c662c..4dba000b50 100644 --- a/layer/mounted_layer.go +++ b/layer/mounted_layer.go @@ -98,3 +98,8 @@ func (rl *referencedRWLayer) Mount(mountLabel string) (containerfs.ContainerFS, func (rl *referencedRWLayer) Unmount() error { return rl.layerStore.driver.Put(rl.mountedLayer.mountID) } + +// ApplyDiff applies specified diff to the layer +func (rl *referencedRWLayer) ApplyDiff(diff io.Reader) (int64, error) { + return rl.layerStore.driver.ApplyDiff(rl.mountID, rl.cacheParent(), diff) +}