Signed-off-by: Stefan J. Wernli <swernli@microsoft.com>
| ... | ... |
@@ -405,6 +405,10 @@ func Tar(path string, compression Compression) (io.ReadCloser, error) {
|
| 405 | 405 |
// paths are included in `options.IncludeFiles` (if non-nil) or not in `options.ExcludePatterns`. |
| 406 | 406 |
func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) {
|
| 407 | 407 |
|
| 408 |
+ // Fix the source path to work with long path names. This is a no-op |
|
| 409 |
+ // on platforms other than Windows. |
|
| 410 |
+ srcPath = fixVolumePathPrefix(srcPath) |
|
| 411 |
+ |
|
| 408 | 412 |
patterns, patDirs, exceptions, err := fileutils.CleanPatterns(options.ExcludePatterns) |
| 409 | 413 |
|
| 410 | 414 |
if err != nil {
|
| ... | ... |
@@ -474,9 +478,7 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) |
| 474 | 474 |
for _, include := range options.IncludeFiles {
|
| 475 | 475 |
rebaseName := options.RebaseNames[include] |
| 476 | 476 |
|
| 477 |
- // We can't use filepath.Join(srcPath, include) because this will |
|
| 478 |
- // clean away a trailing "." or "/" which may be important. |
|
| 479 |
- walkRoot := strings.Join([]string{srcPath, include}, string(filepath.Separator))
|
|
| 477 |
+ walkRoot := getWalkRoot(srcPath, include) |
|
| 480 | 478 |
filepath.Walk(walkRoot, func(filePath string, f os.FileInfo, err error) error {
|
| 481 | 479 |
if err != nil {
|
| 482 | 480 |
logrus.Debugf("Tar: Can't stat file %s to tar: %s", srcPath, err)
|
| ... | ... |
@@ -6,11 +6,26 @@ import ( |
| 6 | 6 |
"archive/tar" |
| 7 | 7 |
"errors" |
| 8 | 8 |
"os" |
| 9 |
+ "path/filepath" |
|
| 9 | 10 |
"syscall" |
| 10 | 11 |
|
| 11 | 12 |
"github.com/docker/docker/pkg/system" |
| 12 | 13 |
) |
| 13 | 14 |
|
| 15 |
+// fixVolumePathPrefix does platform specific processing to ensure that if |
|
| 16 |
+// the path being passed in is not in a volume path format, convert it to one. |
|
| 17 |
+func fixVolumePathPrefix(srcPath string) string {
|
|
| 18 |
+ return srcPath |
|
| 19 |
+} |
|
| 20 |
+ |
|
| 21 |
+// getWalkRoot calculates the root path when performing a TarWithOptions. |
|
| 22 |
+// We use a seperate function as this is platform specific. On Linux, we |
|
| 23 |
+// can't use filepath.Join(srcPath,include) because this will clean away |
|
| 24 |
+// a trailing "." or "/" which may be important. |
|
| 25 |
+func getWalkRoot(srcPath string, include string) string {
|
|
| 26 |
+ return srcPath + string(filepath.Separator) + include |
|
| 27 |
+} |
|
| 28 |
+ |
|
| 14 | 29 |
// CanonicalTarNameForPath returns platform-specific filepath |
| 15 | 30 |
// to canonical posix-style path for tar archival. p is relative |
| 16 | 31 |
// path. |
| ... | ... |
@@ -6,9 +6,25 @@ import ( |
| 6 | 6 |
"archive/tar" |
| 7 | 7 |
"fmt" |
| 8 | 8 |
"os" |
| 9 |
+ "path/filepath" |
|
| 9 | 10 |
"strings" |
| 10 | 11 |
) |
| 11 | 12 |
|
| 13 |
+// fixVolumePathPrefix does platform specific processing to ensure that if |
|
| 14 |
+// the path being passed in is not in a volume path format, convert it to one. |
|
| 15 |
+func fixVolumePathPrefix(srcPath string) string {
|
|
| 16 |
+ if !strings.HasPrefix(srcPath, `\\?\`) {
|
|
| 17 |
+ srcPath = `\\?\` + srcPath |
|
| 18 |
+ } |
|
| 19 |
+ return srcPath |
|
| 20 |
+} |
|
| 21 |
+ |
|
| 22 |
+// getWalkRoot calculates the root path when performing a TarWithOptions. |
|
| 23 |
+// We use a seperate function as this is platform specific. |
|
| 24 |
+func getWalkRoot(srcPath string, include string) string {
|
|
| 25 |
+ return filepath.Join(srcPath, include) |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 12 | 28 |
// canonicalTarNameForPath returns platform-specific filepath |
| 13 | 29 |
// to canonical posix-style path for tar archival. p is relative |
| 14 | 30 |
// path. |
| ... | ... |
@@ -5,6 +5,7 @@ import ( |
| 5 | 5 |
"io/ioutil" |
| 6 | 6 |
"os" |
| 7 | 7 |
"path/filepath" |
| 8 |
+ "strings" |
|
| 8 | 9 |
|
| 9 | 10 |
"github.com/docker/docker/pkg/archive" |
| 10 | 11 |
) |
| ... | ... |
@@ -14,6 +15,12 @@ import ( |
| 14 | 14 |
// contents of the layer. |
| 15 | 15 |
func applyLayerHandler(dest string, layer archive.Reader, decompress bool) (size int64, err error) {
|
| 16 | 16 |
dest = filepath.Clean(dest) |
| 17 |
+ |
|
| 18 |
+ // Ensure it is a Windows-style volume path |
|
| 19 |
+ if !strings.HasPrefix(dest, `\\?\`) {
|
|
| 20 |
+ dest = `\\?\` + dest |
|
| 21 |
+ } |
|
| 22 |
+ |
|
| 17 | 23 |
if decompress {
|
| 18 | 24 |
decompressed, err := archive.DecompressStream(layer) |
| 19 | 25 |
if err != nil {
|