Allow for relative paths on ADD/COPY

Moved Tianon's PR from: https://github.com/docker/docker/pull/7870
on top of the latest code

Closes: #3936

Signed-off-by: Andrew Page <admwiggin@gmail.com>
Signed-off-by: Doug Davis <dug@us.ibm.com>
This commit is contained in:
Doug Davis 2014-12-12 10:32:11 -08:00
parent 4988cde7b9
commit f21f9f856e
6 changed files with 85 additions and 20 deletions

View file

@ -172,15 +172,12 @@ func workdir(b *Builder, args []string, attributes map[string]bool, original str
workdir := args[0]
if workdir[0] == '/' {
b.Config.WorkingDir = workdir
} else {
if b.Config.WorkingDir == "" {
b.Config.WorkingDir = "/"
}
b.Config.WorkingDir = filepath.Join(b.Config.WorkingDir, workdir)
if !filepath.IsAbs(workdir) {
workdir = filepath.Join("/", b.Config.WorkingDir, workdir)
}
b.Config.WorkingDir = workdir
return b.commit("", b.Config.Cmd, fmt.Sprintf("WORKDIR %v", workdir))
}

View file

@ -217,6 +217,18 @@ func calcCopyInfo(b *Builder, cmdName string, cInfos *[]*copyInfo, origPath stri
}
origPath = strings.TrimPrefix(origPath, "./")
// Twiddle the destPath when its a relative path - meaning, make it
// relative to the WORKINGDIR
if !filepath.IsAbs(destPath) {
hasSlash := strings.HasSuffix(destPath, "/")
destPath = filepath.Join("/", b.Config.WorkingDir, destPath)
// Make sure we preserve any trailing slash
if hasSlash {
destPath += "/"
}
}
// In the remote/URL case, download it and gen its hashcode
if urlutil.IsURL(origPath) {
if !allowRemote {

View file

@ -132,12 +132,22 @@ or
**ADD**
--**ADD <src>... <dest>** The ADD instruction copies new files, directories
or remote file URLs to the filesystem of the container at path <dest>.
or remote file URLs to the filesystem of the container at path <dest>.
Mutliple <src> resources may be specified but if they are files or directories
then they must be relative to the source directory that is being built
(the context of the build). <dest> is the absolute path to
which the source is copied inside the target container. All new files and
directories are created with mode 0755, with uid and gid 0.
then they must be relative to the source directory that is being built
(the context of the build). The <dest> is the absolute path, or path relative
to `WORKDIR`, into which the source is copied inside the target container.
All new files and directories are created with mode 0755 and with the uid
and gid of 0.
**COPY**
--**COPY <src> <dest>** The COPY instruction copies new files from <src> and
adds them to the filesystem of the container at path <dest>. The <src> must be
the path to a file or directory relative to the source directory that is
being built (the context of the build) or a remote file URL. The `<dest>` is an
absolute path, or a path relative to `WORKDIR`, into which the source will
be copied inside the target container. All new files and directories are
created with mode 0755 and with the uid and gid of 0.
**ENTRYPOINT**
--**ENTRYPOINT** has two forms: ENTRYPOINT ["executable", "param1", "param2"]

View file

@ -65,10 +65,12 @@ directory called httpd may be used to store Dockerfiles for Apache web
server images.
It is also a good practice to add the files required for the image to the
sub-directory. These files will then be specified with the `ADD` instruction
in the Dockerfile. Note: If you include a tar file (a good practice!), then
Docker will automatically extract the contents of the tar file
specified within the `ADD` instruction into the specified target.
sub-directory. These files will then be specified with the `COPY` or `ADD`
instructions in the `Dockerfile`.
Note: If you include a tar file (a good practice), then Docker will
automatically extract the contents of the tar file specified within the `ADD`
instruction into the specified target.
## Building an image and naming that image

View file

@ -397,8 +397,10 @@ For most command line uses this should act as expected, for example:
ADD hom* /mydir/ # adds all files starting with "hom"
ADD hom?.txt /mydir/ # ? is replaced with any single character
The `<dest>` is the absolute path to which the source will be copied inside the
destination container.
The `<dest>` is an absolute path, or a path relative to `WORKDIR`, into which
the source will be copied inside the destination container.
ADD test aDir/ # adds "test" to `WORKDIR`/aDir/
All new files and directories are created with a UID and GID of 0.
@ -494,8 +496,10 @@ For most command line uses this should act as expected, for example:
COPY hom* /mydir/ # adds all files starting with "hom"
COPY hom?.txt /mydir/ # ? is replaced with any single character
The `<dest>` is the absolute path to which the source will be copied inside the
destination container.
The `<dest>` is an absolute path, or a path relative to `WORKDIR`, into which
the source will be copied inside the destination container.
COPY test aDir/ # adds "test" to `WORKDIR`/aDir/
All new files and directories are created with a UID and GID of 0.

View file

@ -1829,6 +1829,46 @@ func TestBuildWorkdirWithEnvVariables(t *testing.T) {
logDone("build - workdir with env variables")
}
func TestBuildRelativeCopy(t *testing.T) {
name := "testbuildrelativecopy"
defer deleteImages(name)
dockerfile := `
FROM busybox
WORKDIR /test1
WORKDIR test2
RUN [ "$PWD" = '/test1/test2' ]
COPY foo ./
RUN [ "$(cat /test1/test2/foo)" = 'hello' ]
ADD foo ./bar/baz
RUN [ "$(cat /test1/test2/bar/baz)" = 'hello' ]
COPY foo ./bar/baz2
RUN [ "$(cat /test1/test2/bar/baz2)" = 'hello' ]
WORKDIR ..
COPY foo ./
RUN [ "$(cat /test1/foo)" = 'hello' ]
COPY foo /test3/
RUN [ "$(cat /test3/foo)" = 'hello' ]
WORKDIR /test4
COPY . .
RUN [ "$(cat /test4/foo)" = 'hello' ]
WORKDIR /test5/test6
COPY foo ../
RUN [ "$(cat /test5/foo)" = 'hello' ]
`
ctx, err := fakeContext(dockerfile, map[string]string{
"foo": "hello",
})
defer ctx.Close()
if err != nil {
t.Fatal(err)
}
_, err = buildImageFromContext(name, ctx, false)
if err != nil {
t.Fatal(err)
}
logDone("build - relative copy/add")
}
func TestBuildEnv(t *testing.T) {
name := "testbuildenv"
expected := "[PATH=/test:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PORT=2375]"