Add the parent directory to changes set if new files are generated
The "TestChangesWithChanges" case randomlly fails on my development VM with the following errors: ``` --- FAIL: TestChangesWithChanges (0.00s) changes_test.go:201: no change for expected change C /dir1/subfolder != A /dir1/subfolder/newFile ``` If I apply the following patch to changes_test.go, the test passes. ```diff diff --git a/pkg/archive/changes_test.go b/pkg/archive/changes_test.go index 290b2dd..ba1aca0 100644 --- a/pkg/archive/changes_test.go +++ b/pkg/archive/changes_test.go @@ -156,6 +156,7 @@ func TestChangesWithChanges(t *testing.T) { } defer os.RemoveAll(layer) createSampleDir(t, layer) + time.Sleep(5 * time.Millisecond) os.MkdirAll(path.Join(layer, "dir1/subfolder"), 0740) // Let's modify modtime for dir1 to be sure it's the same for the two layer (to not having false positive) ``` It seems that if a file is created immediately after the directory is created, the `archive.Changes` function could't recognize that the parent directory of the new file is modified. Perhaps the problem may reproduce on machines with low time precision? I had successfully reproduced the failure on my development VM as well as a VM on DigitalOcean. Signed-off-by: Shijiang Wei <mountkin@gmail.com>
This commit is contained in:
parent
6c2626b90e
commit
e10c7b3f07
2 changed files with 110 additions and 41 deletions
|
@ -68,7 +68,11 @@ func sameFsTimeSpec(a, b syscall.Timespec) bool {
|
|||
// Changes walks the path rw and determines changes for the files in the path,
|
||||
// with respect to the parent layers
|
||||
func Changes(layers []string, rw string) ([]Change, error) {
|
||||
var changes []Change
|
||||
var (
|
||||
changes []Change
|
||||
changedDirs = make(map[string]struct{})
|
||||
)
|
||||
|
||||
err := filepath.Walk(rw, func(path string, f os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -129,6 +133,21 @@ func Changes(layers []string, rw string) ([]Change, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// If /foo/bar/file.txt is modified, then /foo/bar must be part of the changed files.
|
||||
// This block is here to ensure the change is recorded even if the
|
||||
// modify time, mode and size of the parent directoriy in the rw and ro layers are all equal.
|
||||
// Check https://github.com/docker/docker/pull/13590 for details.
|
||||
if f.IsDir() {
|
||||
changedDirs[path] = struct{}{}
|
||||
}
|
||||
if change.Kind == ChangeAdd || change.Kind == ChangeDelete {
|
||||
parent := filepath.Dir(path)
|
||||
if _, ok := changedDirs[parent]; !ok && parent != "/" {
|
||||
changes = append(changes, Change{Path: parent, Kind: ChangeModify})
|
||||
changedDirs[parent] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// Record change
|
||||
changes = append(changes, change)
|
||||
return nil
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue