| ... | ... |
@@ -15,7 +15,15 @@ import ( |
| 15 | 15 |
|
| 16 | 16 |
type Archive io.Reader |
| 17 | 17 |
|
| 18 |
-type Compression uint32 |
|
| 18 |
+type Compression int |
|
| 19 |
+ |
|
| 20 |
+type TarOptions struct {
|
|
| 21 |
+ Includes []string |
|
| 22 |
+ Excludes []string |
|
| 23 |
+ Recursive bool |
|
| 24 |
+ Compression Compression |
|
| 25 |
+ CreateFiles []string |
|
| 26 |
+} |
|
| 19 | 27 |
|
| 20 | 28 |
const ( |
| 21 | 29 |
Uncompressed Compression = iota |
| ... | ... |
@@ -80,7 +88,7 @@ func (compression *Compression) Extension() string {
|
| 80 | 80 |
// Tar creates an archive from the directory at `path`, and returns it as a |
| 81 | 81 |
// stream of bytes. |
| 82 | 82 |
func Tar(path string, compression Compression) (io.Reader, error) {
|
| 83 |
- return TarFilter(path, compression, nil, true, nil) |
|
| 83 |
+ return TarFilter(path, &TarOptions{Recursive: true, Compression: compression})
|
|
| 84 | 84 |
} |
| 85 | 85 |
|
| 86 | 86 |
func escapeName(name string) string {
|
| ... | ... |
@@ -101,25 +109,29 @@ func escapeName(name string) string {
|
| 101 | 101 |
|
| 102 | 102 |
// Tar creates an archive from the directory at `path`, only including files whose relative |
| 103 | 103 |
// paths are included in `filter`. If `filter` is nil, then all files are included. |
| 104 |
-func TarFilter(path string, compression Compression, filter []string, recursive bool, createFiles []string) (io.Reader, error) {
|
|
| 104 |
+func TarFilter(path string, options *TarOptions) (io.Reader, error) {
|
|
| 105 | 105 |
args := []string{"tar", "--numeric-owner", "-f", "-", "-C", path, "-T", "-"}
|
| 106 |
- if filter == nil {
|
|
| 107 |
- filter = []string{"."}
|
|
| 106 |
+ if options.Includes == nil {
|
|
| 107 |
+ options.Includes = []string{"."}
|
|
| 108 |
+ } |
|
| 109 |
+ args = append(args, "-c"+options.Compression.Flag()) |
|
| 110 |
+ |
|
| 111 |
+ for _, exclude := range options.Excludes {
|
|
| 112 |
+ args = append(args, fmt.Sprintf("--exclude=%s", exclude))
|
|
| 108 | 113 |
} |
| 109 |
- args = append(args, "-c"+compression.Flag()) |
|
| 110 | 114 |
|
| 111 |
- if !recursive {
|
|
| 115 |
+ if !options.Recursive {
|
|
| 112 | 116 |
args = append(args, "--no-recursion") |
| 113 | 117 |
} |
| 114 | 118 |
|
| 115 | 119 |
files := "" |
| 116 |
- for _, f := range filter {
|
|
| 120 |
+ for _, f := range options.Includes {
|
|
| 117 | 121 |
files = files + escapeName(f) + "\n" |
| 118 | 122 |
} |
| 119 | 123 |
|
| 120 | 124 |
tmpDir := "" |
| 121 | 125 |
|
| 122 |
- if createFiles != nil {
|
|
| 126 |
+ if options.CreateFiles != nil {
|
|
| 123 | 127 |
var err error // Can't use := here or we override the outer tmpDir |
| 124 | 128 |
tmpDir, err = ioutil.TempDir("", "docker-tar")
|
| 125 | 129 |
if err != nil {
|
| ... | ... |
@@ -127,7 +139,7 @@ func TarFilter(path string, compression Compression, filter []string, recursive |
| 127 | 127 |
} |
| 128 | 128 |
|
| 129 | 129 |
files = files + "-C" + tmpDir + "\n" |
| 130 |
- for _, f := range createFiles {
|
|
| 130 |
+ for _, f := range options.CreateFiles {
|
|
| 131 | 131 |
path := filepath.Join(tmpDir, f) |
| 132 | 132 |
err := os.MkdirAll(filepath.Dir(path), 0600) |
| 133 | 133 |
if err != nil {
|
| ... | ... |
@@ -194,7 +206,7 @@ func Untar(archive io.Reader, path string) error {
|
| 194 | 194 |
// TarUntar aborts and returns the error. |
| 195 | 195 |
func TarUntar(src string, filter []string, dst string) error {
|
| 196 | 196 |
utils.Debugf("TarUntar(%s %s %s)", src, filter, dst)
|
| 197 |
- archive, err := TarFilter(src, Uncompressed, filter, true, nil) |
|
| 197 |
+ archive, err := TarFilter(src, &TarOptions{Compression: Uncompressed, Includes: filter, Recursive: true})
|
|
| 198 | 198 |
if err != nil {
|
| 199 | 199 |
return err |
| 200 | 200 |
} |
| ... | ... |
@@ -207,24 +207,22 @@ func ChangesDirs(newDir, oldDir string) ([]Change, error) {
|
| 207 | 207 |
return changes, nil |
| 208 | 208 |
} |
| 209 | 209 |
|
| 210 |
- |
|
| 211 | 210 |
func ExportChanges(root, rw string) (Archive, error) {
|
| 212 |
- changes, err := ChangesDirs(root, rw) |
|
| 213 |
- if err != nil {
|
|
| 214 |
- return nil, err |
|
| 215 |
- } |
|
| 216 |
- files := make([]string, 0) |
|
| 217 |
- deletions := make([]string, 0) |
|
| 218 |
- for _, change := range changes {
|
|
| 219 |
- if change.Kind == ChangeModify || change.Kind == ChangeAdd {
|
|
| 220 |
- files = append(files, change.Path) |
|
| 221 |
- } |
|
| 222 |
- if change.Kind == ChangeDelete {
|
|
| 223 |
- base := filepath.Base(change.Path) |
|
| 224 |
- dir := filepath.Dir(change.Path) |
|
| 225 |
- deletions = append(deletions, filepath.Join(dir, ".wh."+base)) |
|
| 226 |
- } |
|
| 227 |
- } |
|
| 228 |
- return TarFilter(root, Uncompressed, files, false, deletions) |
|
| 211 |
+ changes, err := ChangesDirs(root, rw) |
|
| 212 |
+ if err != nil {
|
|
| 213 |
+ return nil, err |
|
| 214 |
+ } |
|
| 215 |
+ files := make([]string, 0) |
|
| 216 |
+ deletions := make([]string, 0) |
|
| 217 |
+ for _, change := range changes {
|
|
| 218 |
+ if change.Kind == ChangeModify || change.Kind == ChangeAdd {
|
|
| 219 |
+ files = append(files, change.Path) |
|
| 220 |
+ } |
|
| 221 |
+ if change.Kind == ChangeDelete {
|
|
| 222 |
+ base := filepath.Base(change.Path) |
|
| 223 |
+ dir := filepath.Dir(change.Path) |
|
| 224 |
+ deletions = append(deletions, filepath.Join(dir, ".wh."+base)) |
|
| 225 |
+ } |
|
| 226 |
+ } |
|
| 227 |
+ return TarFilter(root, &TarOptions{Compression: Uncompressed, Recursive: false, Includes: files, CreateFiles: deletions})
|
|
| 229 | 228 |
} |
| 230 |
- |
| ... | ... |
@@ -137,8 +137,7 @@ func (a *AufsDriver) createDirsFor(id string) error {
|
| 137 | 137 |
} |
| 138 | 138 |
|
| 139 | 139 |
for _, p := range paths {
|
| 140 |
- dir := path.Join(a.rootPath(), p, id) |
|
| 141 |
- if err := os.MkdirAll(dir, 0755); err != nil {
|
|
| 140 |
+ if err := os.MkdirAll(path.Join(a.rootPath(), p, id), 0755); err != nil {
|
|
| 142 | 141 |
return err |
| 143 | 142 |
} |
| 144 | 143 |
} |
| ... | ... |
@@ -201,11 +200,14 @@ func (a *AufsDriver) Get(id string) (string, error) {
|
| 201 | 201 |
|
| 202 | 202 |
// Returns an archive of the contents for the id |
| 203 | 203 |
func (a *AufsDriver) Diff(id string) (archive.Archive, error) {
|
| 204 |
- p, err := a.Get(id) |
|
| 205 |
- if err != nil {
|
|
| 206 |
- return nil, err |
|
| 207 |
- } |
|
| 208 |
- return archive.Tar(p, archive.Uncompressed) |
|
| 204 |
+ // Exclude top level aufs metadata from the diff |
|
| 205 |
+ return archive.TarFilter( |
|
| 206 |
+ path.Join(a.rootPath(), "diff", id), |
|
| 207 |
+ &archive.TarOptions{
|
|
| 208 |
+ Excludes: []string{".wh*"},
|
|
| 209 |
+ Recursive: true, |
|
| 210 |
+ Compression: archive.Uncompressed, |
|
| 211 |
+ }) |
|
| 209 | 212 |
} |
| 210 | 213 |
|
| 211 | 214 |
// Returns the size of the contents for the id |
| ... | ... |
@@ -1527,7 +1527,11 @@ func (container *Container) Copy(resource string) (archive.Archive, error) {
|
| 1527 | 1527 |
filter = []string{path.Base(basePath)}
|
| 1528 | 1528 |
basePath = path.Dir(basePath) |
| 1529 | 1529 |
} |
| 1530 |
- return archive.TarFilter(basePath, archive.Uncompressed, filter, true, nil) |
|
| 1530 |
+ return archive.TarFilter(basePath, &archive.TarOptions{
|
|
| 1531 |
+ Compression: archive.Uncompressed, |
|
| 1532 |
+ Includes: filter, |
|
| 1533 |
+ Recursive: true, |
|
| 1534 |
+ }) |
|
| 1531 | 1535 |
} |
| 1532 | 1536 |
|
| 1533 | 1537 |
// Returns true if the container exposes a certain port |