Skip to content

Commit

Permalink
Merge pull request moby#9635 from duglin/Issue3936
Browse files Browse the repository at this point in the history
Allow for relative paths on ADD/COPY
  • Loading branch information
LK4D4 committed Dec 18, 2014
2 parents 21bba5d + f21f9f8 commit 364720b
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 20 deletions.
11 changes: 4 additions & 7 deletions builder/dispatchers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

Expand Down
12 changes: 12 additions & 0 deletions builder/internals.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
20 changes: 15 additions & 5 deletions docs/man/Dockerfile.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
10 changes: 6 additions & 4 deletions docs/man/docker-build.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 8 additions & 4 deletions docs/sources/reference/builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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.

Expand Down
40 changes: 40 additions & 0 deletions integration-cli/docker_cli_build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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]"
Expand Down

0 comments on commit 364720b

Please sign in to comment.