mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									abdfb21e3a
								
							
						
					
					
						commit
						32d6d49539
					
				
					 3 changed files with 12 additions and 9 deletions
				
			
		| 
						 | 
					@ -458,7 +458,7 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if err := ta.addTarFile(filePath, relFilePath); err != nil {
 | 
									if err := ta.addTarFile(filePath, relFilePath); err != nil {
 | 
				
			||||||
					log.Debugf("Can't add file %s to tar: %s", srcPath, err)
 | 
										log.Debugf("Can't add file %s to tar: %s", filePath, err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return nil
 | 
									return nil
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@ import (
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"sort"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"syscall"
 | 
						"syscall"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
| 
						 | 
					@ -43,6 +44,13 @@ func (change *Change) String() string {
 | 
				
			||||||
	return fmt.Sprintf("%s %s", kind, change.Path)
 | 
						return fmt.Sprintf("%s %s", kind, change.Path)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// for sort.Sort
 | 
				
			||||||
 | 
					type changesByPath []Change
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c changesByPath) Less(i, j int) bool { return c[i].Path < c[j].Path }
 | 
				
			||||||
 | 
					func (c changesByPath) Len() int           { return len(c) }
 | 
				
			||||||
 | 
					func (c changesByPath) Swap(i, j int)      { c[j], c[i] = c[i], c[j] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Gnu tar and the go tar writer don't have sub-second mtime
 | 
					// Gnu tar and the go tar writer don't have sub-second mtime
 | 
				
			||||||
// precision, which is problematic when we apply changes via tar
 | 
					// precision, which is problematic when we apply changes via tar
 | 
				
			||||||
// files, we handle this by comparing for exact times, *or* same
 | 
					// files, we handle this by comparing for exact times, *or* same
 | 
				
			||||||
| 
						 | 
					@ -373,6 +381,8 @@ func ExportChanges(dir string, changes []Change) (Archive, error) {
 | 
				
			||||||
		// this buffer is needed for the duration of this piped stream
 | 
							// this buffer is needed for the duration of this piped stream
 | 
				
			||||||
		defer pools.BufioWriter32KPool.Put(ta.Buffer)
 | 
							defer pools.BufioWriter32KPool.Put(ta.Buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sort.Sort(changesByPath(changes))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// In general we log errors here but ignore them because
 | 
							// In general we log errors here but ignore them because
 | 
				
			||||||
		// during e.g. a diff operation the container can continue
 | 
							// during e.g. a diff operation the container can continue
 | 
				
			||||||
		// mutating the filesystem and we can see transient errors
 | 
							// mutating the filesystem and we can see transient errors
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,13 +25,6 @@ func copyDir(src, dst string) error {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Helper to sort []Change by path
 | 
					 | 
				
			||||||
type byPath struct{ changes []Change }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (b byPath) Less(i, j int) bool { return b.changes[i].Path < b.changes[j].Path }
 | 
					 | 
				
			||||||
func (b byPath) Len() int           { return len(b.changes) }
 | 
					 | 
				
			||||||
func (b byPath) Swap(i, j int)      { b.changes[i], b.changes[j] = b.changes[j], b.changes[i] }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type FileType uint32
 | 
					type FileType uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
| 
						 | 
					@ -220,7 +213,7 @@ func TestChangesDirsMutated(t *testing.T) {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sort.Sort(byPath{changes})
 | 
						sort.Sort(changesByPath(changes))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	expectedChanges := []Change{
 | 
						expectedChanges := []Change{
 | 
				
			||||||
		{"/dir1", ChangeDelete},
 | 
							{"/dir1", ChangeDelete},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue