Fixing Tar functions to support Windows long paths.
Signed-off-by: Stefan J. Wernli <swernli@microsoft.com>
This commit is contained in:
parent
732af35366
commit
1c1d0c5f6f
4 changed files with 43 additions and 3 deletions
|
@ -405,6 +405,10 @@ func Tar(path string, compression Compression) (io.ReadCloser, error) {
|
||||||
// paths are included in `options.IncludeFiles` (if non-nil) or not in `options.ExcludePatterns`.
|
// paths are included in `options.IncludeFiles` (if non-nil) or not in `options.ExcludePatterns`.
|
||||||
func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) {
|
func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) {
|
||||||
|
|
||||||
|
// Fix the source path to work with long path names. This is a no-op
|
||||||
|
// on platforms other than Windows.
|
||||||
|
srcPath = fixVolumePathPrefix(srcPath)
|
||||||
|
|
||||||
patterns, patDirs, exceptions, err := fileutils.CleanPatterns(options.ExcludePatterns)
|
patterns, patDirs, exceptions, err := fileutils.CleanPatterns(options.ExcludePatterns)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -474,9 +478,7 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
|
||||||
for _, include := range options.IncludeFiles {
|
for _, include := range options.IncludeFiles {
|
||||||
rebaseName := options.RebaseNames[include]
|
rebaseName := options.RebaseNames[include]
|
||||||
|
|
||||||
// We can't use filepath.Join(srcPath, include) because this will
|
walkRoot := getWalkRoot(srcPath, include)
|
||||||
// clean away a trailing "." or "/" which may be important.
|
|
||||||
walkRoot := strings.Join([]string{srcPath, include}, string(filepath.Separator))
|
|
||||||
filepath.Walk(walkRoot, func(filePath string, f os.FileInfo, err error) error {
|
filepath.Walk(walkRoot, func(filePath string, f os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Debugf("Tar: Can't stat file %s to tar: %s", srcPath, err)
|
logrus.Debugf("Tar: Can't stat file %s to tar: %s", srcPath, err)
|
||||||
|
|
|
@ -6,11 +6,26 @@ import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/system"
|
"github.com/docker/docker/pkg/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// fixVolumePathPrefix does platform specific processing to ensure that if
|
||||||
|
// the path being passed in is not in a volume path format, convert it to one.
|
||||||
|
func fixVolumePathPrefix(srcPath string) string {
|
||||||
|
return srcPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// getWalkRoot calculates the root path when performing a TarWithOptions.
|
||||||
|
// We use a seperate function as this is platform specific. On Linux, we
|
||||||
|
// can't use filepath.Join(srcPath,include) because this will clean away
|
||||||
|
// a trailing "." or "/" which may be important.
|
||||||
|
func getWalkRoot(srcPath string, include string) string {
|
||||||
|
return srcPath + string(filepath.Separator) + include
|
||||||
|
}
|
||||||
|
|
||||||
// CanonicalTarNameForPath returns platform-specific filepath
|
// CanonicalTarNameForPath returns platform-specific filepath
|
||||||
// to canonical posix-style path for tar archival. p is relative
|
// to canonical posix-style path for tar archival. p is relative
|
||||||
// path.
|
// path.
|
||||||
|
|
|
@ -6,9 +6,25 @@ import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// fixVolumePathPrefix does platform specific processing to ensure that if
|
||||||
|
// the path being passed in is not in a volume path format, convert it to one.
|
||||||
|
func fixVolumePathPrefix(srcPath string) string {
|
||||||
|
if !strings.HasPrefix(srcPath, `\\?\`) {
|
||||||
|
srcPath = `\\?\` + srcPath
|
||||||
|
}
|
||||||
|
return srcPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// getWalkRoot calculates the root path when performing a TarWithOptions.
|
||||||
|
// We use a seperate function as this is platform specific.
|
||||||
|
func getWalkRoot(srcPath string, include string) string {
|
||||||
|
return filepath.Join(srcPath, include)
|
||||||
|
}
|
||||||
|
|
||||||
// canonicalTarNameForPath returns platform-specific filepath
|
// canonicalTarNameForPath returns platform-specific filepath
|
||||||
// to canonical posix-style path for tar archival. p is relative
|
// to canonical posix-style path for tar archival. p is relative
|
||||||
// path.
|
// path.
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/archive"
|
"github.com/docker/docker/pkg/archive"
|
||||||
)
|
)
|
||||||
|
@ -14,6 +15,12 @@ import (
|
||||||
// contents of the layer.
|
// contents of the layer.
|
||||||
func applyLayerHandler(dest string, layer archive.Reader, decompress bool) (size int64, err error) {
|
func applyLayerHandler(dest string, layer archive.Reader, decompress bool) (size int64, err error) {
|
||||||
dest = filepath.Clean(dest)
|
dest = filepath.Clean(dest)
|
||||||
|
|
||||||
|
// Ensure it is a Windows-style volume path
|
||||||
|
if !strings.HasPrefix(dest, `\\?\`) {
|
||||||
|
dest = `\\?\` + dest
|
||||||
|
}
|
||||||
|
|
||||||
if decompress {
|
if decompress {
|
||||||
decompressed, err := archive.DecompressStream(layer)
|
decompressed, err := archive.DecompressStream(layer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue