mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
+ Builder: ADD of a local file will detect tar archives and unpack them
into the container instead of copying them as a regular file. * Builder: ADD uses tar/untar for copies instead of calling 'cp -ar'. This is more consistent, reduces the number of dependencies, and fixe #896.
This commit is contained in:
parent
5799806414
commit
5b8287617d
4 changed files with 38 additions and 10 deletions
25
archive.go
25
archive.go
|
@ -51,6 +51,7 @@ func Tar(path string, compression Compression) (io.Reader, error) {
|
||||||
return CmdStream(cmd)
|
return CmdStream(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: specify behavior when target path exists vs. doesn't exist.
|
||||||
func Untar(archive io.Reader, path string) error {
|
func Untar(archive io.Reader, path string) error {
|
||||||
cmd := exec.Command("bsdtar", "-f", "-", "-C", path, "-x")
|
cmd := exec.Command("bsdtar", "-f", "-", "-C", path, "-x")
|
||||||
cmd.Stdin = archive
|
cmd.Stdin = archive
|
||||||
|
@ -64,6 +65,30 @@ func Untar(archive io.Reader, path string) error {
|
||||||
return nil
|
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.
|
// CmdStream executes a command, and returns its stdout as a stream.
|
||||||
// If the command fails to run or doesn't complete successfully, an error
|
// If the command fails to run or doesn't complete successfully, an error
|
||||||
// will be returned, including anything written on stderr.
|
// will be returned, including anything written on stderr.
|
||||||
|
|
16
buildfile.go
16
buildfile.go
|
@ -200,21 +200,17 @@ func (b *buildFile) CmdAdd(args string) error {
|
||||||
if err := os.MkdirAll(destPath, 0700); err != nil {
|
if err := os.MkdirAll(destPath, 0700); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := CopyWithTar(origPath, destPath); err != nil {
|
||||||
files, err := ioutil.ReadDir(path.Join(b.context, orig))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, fi := range files {
|
// First try to unpack the source as an archive
|
||||||
if err := utils.CopyDirectory(path.Join(origPath, fi.Name()), path.Join(destPath, fi.Name())); err != nil {
|
} else if err := UntarPath(origPath, destPath); err != nil {
|
||||||
return err
|
utils.Debugf("Couldn't untar %s to %s: %s", origPath, destPath, err)
|
||||||
}
|
// If that fails, just copy it as a regular file
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := os.MkdirAll(path.Dir(destPath), 0700); err != nil {
|
if err := os.MkdirAll(path.Dir(destPath), 0700); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := utils.CopyDirectory(origPath, destPath); err != nil {
|
if err := CopyWithTar(origPath, destPath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,12 @@ from ` + unitTestImageName + `
|
||||||
run sh -c 'echo root:testpass > /tmp/passwd'
|
run sh -c 'echo root:testpass > /tmp/passwd'
|
||||||
run mkdir -p /var/run/sshd`
|
run mkdir -p /var/run/sshd`
|
||||||
|
|
||||||
|
// 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 TestBuild(t *testing.T) {
|
func TestBuild(t *testing.T) {
|
||||||
dockerfiles := []string{Dockerfile, DockerfileNoNewLine}
|
dockerfiles := []string{Dockerfile, DockerfileNoNewLine}
|
||||||
for _, Dockerfile := range dockerfiles {
|
for _, Dockerfile := range dockerfiles {
|
||||||
|
|
|
@ -548,6 +548,7 @@ func GetKernelVersion() (*KernelVersionInfo, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: this is deprecated by CopyWithTar in archive.go
|
||||||
func CopyDirectory(source, dest string) error {
|
func CopyDirectory(source, dest string) error {
|
||||||
if output, err := exec.Command("cp", "-ra", source, dest).CombinedOutput(); err != nil {
|
if output, err := exec.Command("cp", "-ra", source, dest).CombinedOutput(); err != nil {
|
||||||
return fmt.Errorf("Error copy: %s (%s)", err, output)
|
return fmt.Errorf("Error copy: %s (%s)", err, output)
|
||||||
|
|
Loading…
Reference in a new issue