contenthash: fix recursive directory deletes

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
docker-18.09
Tonis Tiigi 2017-11-16 13:30:19 -08:00
parent 353d23a6ba
commit aaca443ebf
2 changed files with 52 additions and 2 deletions

View File

@ -386,7 +386,9 @@ func (cc *cacheContext) commitActiveTransaction() {
addParentToMap(d, cc.dirtyMap)
}
for d := range cc.dirtyMap {
cc.txn.Insert([]byte(d), &CacheRecord{Type: CacheRecordTypeDir})
if _, ok := cc.txn.Get([]byte(d)); ok {
cc.txn.Insert([]byte(d), &CacheRecord{Type: CacheRecordTypeDir})
}
}
cc.tree = cc.txn.Commit()
cc.node = nil
@ -402,8 +404,8 @@ func (cc *cacheContext) lazyChecksum(ctx context.Context, m *mount, p string) (*
}
}
k := []byte(p)
root = cc.tree.Root()
txn := cc.tree.Txn()
root = txn.Root()
cr, updated, err := cc.checksum(ctx, root, txn, m, k)
if err != nil {
return nil, err

View File

@ -254,6 +254,54 @@ func TestHandleChange(t *testing.T) {
require.NoError(t, err)
}
func TestHandleRecursiveDir(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "buildkit-state")
require.NoError(t, err)
defer os.RemoveAll(tmpdir)
snapshotter, err := naive.NewSnapshotter(filepath.Join(tmpdir, "snapshots"))
require.NoError(t, err)
cm := setupCacheManager(t, tmpdir, snapshotter)
defer cm.Close()
ch := []string{
"ADD d0 dir",
"ADD d0/foo dir",
"ADD d0/foo/bar dir",
"ADD d0/foo/bar/foo file data0",
"ADD d0/foo/bar/bar file data1",
"ADD d1 dir",
"ADD d1/foo file data0",
}
ref := createRef(t, cm, nil)
cc, err := newCacheContext(ref.Metadata())
assert.NoError(t, err)
err = emit(cc.HandleChange, changeStream(ch))
assert.NoError(t, err)
dgst, err := cc.Checksum(context.TODO(), ref, "d0/foo/bar")
assert.NoError(t, err)
ch = []string{
"DEL d0 dir",
"DEL d0/foo dir", // the differ can produce a record for subdir as well
"ADD d1/bar file data1",
}
err = emit(cc.HandleChange, changeStream(ch))
assert.NoError(t, err)
dgst2, err := cc.Checksum(context.TODO(), ref, "d1")
assert.NoError(t, err)
assert.Equal(t, dgst2, dgst)
_, err = cc.Checksum(context.TODO(), ref, "")
assert.NoError(t, err)
}
func TestPersistence(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "buildkit-state")
require.NoError(t, err)