Fix docker cp
Behavior With Symlinks
[pkg/archive] Update archive/copy path handling - Remove unused TarOptions.Name field. - Add new TarOptions.RebaseNames field. - Update some of the logic around path dir/base splitting. - Update some of the logic behind archive entry name rebasing. [api/types] Add LinkTarget field to PathStat [daemon] Fix stat, archive, extract of symlinks These operations *should* resolve symlinks that are in the path but if the resource itself is a symlink then it *should not* be resolved. This patch puts this logic into a common function `resolvePath` which resolves symlinks of the path's dir in scope of the container rootfs but does not resolve the final element of the path. Now archive, extract, and stat operations will return symlinks if the path is indeed a symlink. [api/client] Update cp path hanling [docs/reference/api] Update description of stat Add the linkTarget field to the header of the archive endpoint. Remove path field. [integration-cli] Fix/Add cp symlink test cases Copying a symlink should do just that: copy the symlink NOT copy the target of the symlink. Also, the resulting file from the copy should have the name of the symlink NOT the name of the target file. Copying to a symlink should copy to the symlink target and not modify the symlink itself. Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
This commit is contained in:
parent
2b27285a0d
commit
bd8af5b419
4 changed files with 171 additions and 94 deletions
|
@ -37,11 +37,13 @@ type (
|
|||
Compression Compression
|
||||
NoLchown bool
|
||||
ChownOpts *TarChownOptions
|
||||
Name string
|
||||
IncludeSourceDir bool
|
||||
// When unpacking, specifies whether overwriting a directory with a
|
||||
// non-directory is allowed and vice versa.
|
||||
NoOverwriteDirNonDir bool
|
||||
// For each include when creating an archive, the included name will be
|
||||
// replaced with the matching name from this map.
|
||||
RebaseNames map[string]string
|
||||
}
|
||||
|
||||
// Archiver allows the reuse of most utility functions of this package
|
||||
|
@ -454,8 +456,9 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
|
|||
|
||||
seen := make(map[string]bool)
|
||||
|
||||
var renamedRelFilePath string // For when tar.Options.Name is set
|
||||
for _, include := range options.IncludeFiles {
|
||||
rebaseName := options.RebaseNames[include]
|
||||
|
||||
// We can't use filepath.Join(srcPath, include) because this will
|
||||
// clean away a trailing "." or "/" which may be important.
|
||||
walkRoot := strings.Join([]string{srcPath, include}, string(filepath.Separator))
|
||||
|
@ -503,14 +506,17 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
|
|||
}
|
||||
seen[relFilePath] = true
|
||||
|
||||
// TODO Windows: Verify if this needs to be os.Pathseparator
|
||||
// Rename the base resource
|
||||
if options.Name != "" && filePath == srcPath+"/"+filepath.Base(relFilePath) {
|
||||
renamedRelFilePath = relFilePath
|
||||
}
|
||||
// Set this to make sure the items underneath also get renamed
|
||||
if options.Name != "" {
|
||||
relFilePath = strings.Replace(relFilePath, renamedRelFilePath, options.Name, 1)
|
||||
// Rename the base resource.
|
||||
if rebaseName != "" {
|
||||
var replacement string
|
||||
if rebaseName != string(filepath.Separator) {
|
||||
// Special case the root directory to replace with an
|
||||
// empty string instead so that we don't end up with
|
||||
// double slashes in the paths.
|
||||
replacement = rebaseName
|
||||
}
|
||||
|
||||
relFilePath = strings.Replace(relFilePath, include, replacement, 1)
|
||||
}
|
||||
|
||||
if err := ta.addTarFile(filePath, relFilePath); err != nil {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue