diff --git a/archive.go b/archive.go index 06466627a1..44fdd56be3 100644 --- a/archive.go +++ b/archive.go @@ -51,6 +51,7 @@ func Tar(path string, compression Compression) (io.Reader, error) { return CmdStream(cmd) } +// FIXME: specify behavior when target path exists vs. doesn't exist. func Untar(archive io.Reader, path string) error { cmd := exec.Command("bsdtar", "-f", "-", "-C", path, "-x") cmd.Stdin = archive @@ -64,6 +65,30 @@ func Untar(archive io.Reader, path string) error { return nil } +// UntarPath is a convenience function which looks for an archive +// at filesystem path `src`, and unpacks it at `dst`. +func UntarPath(src, dst string) error { + if archive, err := os.Open(src); err != nil { + return err + } else if err := Untar(archive, dst); err != nil { + return err + } + return nil +} + +// CopyWithTar creates a tar archive of filesystem path `src`, and +// unpacks it at filesystem path `dst`. +// The archive is streamed directly with fixed buffering and no +// intermediary disk IO. +// +func CopyWithTar(src, dst string) error { + archive, err := Tar(src, Uncompressed) + if err != nil { + return err + } + return Untar(archive, dst) +} + // CmdStream executes a command, and returns its stdout as a stream. // If the command fails to run or doesn't complete successfully, an error // will be returned, including anything written on stderr. diff --git a/buildfile.go b/buildfile.go index 2b29a46b1f..f0a3d5b4f4 100644 --- a/buildfile.go +++ b/buildfile.go @@ -186,21 +186,17 @@ func (b *buildFile) addContext(container *Container, orig, dest string) error { if err := os.MkdirAll(destPath, 0700); err != nil { return err } - - files, err := ioutil.ReadDir(path.Join(b.context, orig)) - if err != nil { + if err := CopyWithTar(origPath, destPath); err != nil { return err } - for _, fi := range files { - if err := utils.CopyDirectory(path.Join(origPath, fi.Name()), path.Join(destPath, fi.Name())); err != nil { - return err - } - } - } else { + // First try to unpack the source as an archive + } else if err := UntarPath(origPath, destPath); err != nil { + utils.Debugf("Couldn't untar %s to %s: %s", origPath, destPath, err) + // If that fails, just copy it as a regular file if err := os.MkdirAll(path.Dir(destPath), 0700); err != nil { return err } - if err := utils.CopyDirectory(origPath, destPath); err != nil { + if err := CopyWithTar(origPath, destPath); err != nil { return err } } diff --git a/buildfile_test.go b/buildfile_test.go index ef5663c0be..908cf06a5b 100644 --- a/buildfile_test.go +++ b/buildfile_test.go @@ -33,6 +33,12 @@ run sh -c 'echo root:testpass > /tmp/passwd' run mkdir -p /var/run/sshd add . /src` +// FIXME: test building with a context + +// FIXME: test building with a local ADD as first command + +// FIXME: test building with 2 successive overlapping ADD commands + func TestBuildFile(t *testing.T) { dockerfiles := []string{Dockerfile, DockerfileNoNewLine} for _, Dockerfile := range dockerfiles { diff --git a/docs/sources/use/index.rst b/docs/sources/use/index.rst index a1086c1fd2..2f74f60718 100644 --- a/docs/sources/use/index.rst +++ b/docs/sources/use/index.rst @@ -14,6 +14,7 @@ Contents: basics workingwithrepository + port_redirection builder puppet diff --git a/docs/sources/use/port_redirection.rst b/docs/sources/use/port_redirection.rst new file mode 100644 index 0000000000..5cf848f9ea --- /dev/null +++ b/docs/sources/use/port_redirection.rst @@ -0,0 +1,25 @@ +:title: Port redirection +:description: usage about port redirection +:keywords: Usage, basic port, docker, documentation, examples + + +Port redirection +================ + +Docker can redirect public tcp ports to your container, so it can be reached over the network. +Port redirection is done on ``docker run`` using the -p flag. + +A port redirect is specified as PUBLIC:PRIVATE, where tcp port PUBLIC will be redirected to +tcp port PRIVATE. As a special case, the public port can be omitted, in which case a random +public port will be allocated. + +.. code-block:: bash + + # A random PUBLIC port is redirected to PRIVATE port 80 on the container + docker run -p 80 + + # PUBLIC port 80 is redirected to PRIVATE port 80 + docker run -p 80:80 + + +Default port redirects can be built into a container with the EXPOSE build command. diff --git a/utils/utils.go b/utils/utils.go index 83a7f322b4..cc8a3c798a 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -548,6 +548,7 @@ func GetKernelVersion() (*KernelVersionInfo, error) { }, nil } +// FIXME: this is deprecated by CopyWithTar in archive.go func CopyDirectory(source, dest string) error { if output, err := exec.Command("cp", "-ra", source, dest).CombinedOutput(); err != nil { return fmt.Errorf("Error copy: %s (%s)", err, output)