Browse code

pkg/archive: sort files

sort changes found and exported.

Sorting the files before appending them to the tar archive
would mean a dependable ordering for types like hardlinks.

Also, combine sort logic used

Signed-off-by: Vincent Batts <vbatts@redhat.com>

Vincent Batts authored on 2015/02/05 19:48:58
Showing 3 changed files
... ...
@@ -458,7 +458,7 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
458 458
 				}
459 459
 
460 460
 				if err := ta.addTarFile(filePath, relFilePath); err != nil {
461
-					log.Debugf("Can't add file %s to tar: %s", srcPath, err)
461
+					log.Debugf("Can't add file %s to tar: %s", filePath, err)
462 462
 				}
463 463
 				return nil
464 464
 			})
... ...
@@ -6,6 +6,7 @@ import (
6 6
 	"io"
7 7
 	"os"
8 8
 	"path/filepath"
9
+	"sort"
9 10
 	"strings"
10 11
 	"syscall"
11 12
 	"time"
... ...
@@ -43,6 +44,13 @@ func (change *Change) String() string {
43 43
 	return fmt.Sprintf("%s %s", kind, change.Path)
44 44
 }
45 45
 
46
+// for sort.Sort
47
+type changesByPath []Change
48
+
49
+func (c changesByPath) Less(i, j int) bool { return c[i].Path < c[j].Path }
50
+func (c changesByPath) Len() int           { return len(c) }
51
+func (c changesByPath) Swap(i, j int)      { c[j], c[i] = c[i], c[j] }
52
+
46 53
 // Gnu tar and the go tar writer don't have sub-second mtime
47 54
 // precision, which is problematic when we apply changes via tar
48 55
 // files, we handle this by comparing for exact times, *or* same
... ...
@@ -373,6 +381,8 @@ func ExportChanges(dir string, changes []Change) (Archive, error) {
373 373
 		// this buffer is needed for the duration of this piped stream
374 374
 		defer pools.BufioWriter32KPool.Put(ta.Buffer)
375 375
 
376
+		sort.Sort(changesByPath(changes))
377
+
376 378
 		// In general we log errors here but ignore them because
377 379
 		// during e.g. a diff operation the container can continue
378 380
 		// mutating the filesystem and we can see transient errors
... ...
@@ -25,13 +25,6 @@ func copyDir(src, dst string) error {
25 25
 	return nil
26 26
 }
27 27
 
28
-// Helper to sort []Change by path
29
-type byPath struct{ changes []Change }
30
-
31
-func (b byPath) Less(i, j int) bool { return b.changes[i].Path < b.changes[j].Path }
32
-func (b byPath) Len() int           { return len(b.changes) }
33
-func (b byPath) Swap(i, j int)      { b.changes[i], b.changes[j] = b.changes[j], b.changes[i] }
34
-
35 28
 type FileType uint32
36 29
 
37 30
 const (
... ...
@@ -220,7 +213,7 @@ func TestChangesDirsMutated(t *testing.T) {
220 220
 		t.Fatal(err)
221 221
 	}
222 222
 
223
-	sort.Sort(byPath{changes})
223
+	sort.Sort(changesByPath(changes))
224 224
 
225 225
 	expectedChanges := []Change{
226 226
 		{"/dir1", ChangeDelete},