mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	add pkg/chrootarchive and use it on the daemon
Docker-DCO-1.1-Signed-off-by: Cristian Staretu <cristian.staretu@gmail.com> (github: unclejack) Conflicts: builder/internals.go daemon/graphdriver/aufs/aufs.go daemon/volumes.go fixed conflicts in imports
This commit is contained in:
		
							parent
							
								
									fa1484d12c
								
							
						
					
					
						commit
						1cb17f03d0
					
				
					 11 changed files with 176 additions and 13 deletions
				
			
		| 
						 | 
				
			
			@ -24,6 +24,7 @@ import (
 | 
			
		|||
	"github.com/docker/docker/daemon"
 | 
			
		||||
	imagepkg "github.com/docker/docker/image"
 | 
			
		||||
	"github.com/docker/docker/pkg/archive"
 | 
			
		||||
	"github.com/docker/docker/pkg/chrootarchive"
 | 
			
		||||
	"github.com/docker/docker/pkg/parsers"
 | 
			
		||||
	"github.com/docker/docker/pkg/symlink"
 | 
			
		||||
	"github.com/docker/docker/pkg/system"
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +47,9 @@ func (b *Builder) readContext(context io.Reader) error {
 | 
			
		|||
	if b.context, err = tarsum.NewTarSum(decompressedStream, true, tarsum.Version0); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if err := archive.Untar(b.context, tmpdirPath, nil); err != nil {
 | 
			
		||||
 | 
			
		||||
	os.MkdirAll(tmpdirPath, 0700)
 | 
			
		||||
	if err := chrootarchive.Untar(b.context, tmpdirPath, nil); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -627,7 +630,7 @@ func (b *Builder) addContext(container *daemon.Container, orig, dest string, dec
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		// try to successfully untar the orig
 | 
			
		||||
		if err := archive.UntarPath(origPath, tarDest); err == nil {
 | 
			
		||||
		if err := chrootarchive.UntarPath(origPath, tarDest); err == nil {
 | 
			
		||||
			return nil
 | 
			
		||||
		} else if err != io.EOF {
 | 
			
		||||
			log.Debugf("Couldn't untar %s to %s: %s", origPath, tarDest, err)
 | 
			
		||||
| 
						 | 
				
			
			@ -637,7 +640,7 @@ func (b *Builder) addContext(container *daemon.Container, orig, dest string, dec
 | 
			
		|||
	if err := os.MkdirAll(path.Dir(destPath), 0755); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if err := archive.CopyWithTar(origPath, destPath); err != nil {
 | 
			
		||||
	if err := chrootarchive.CopyWithTar(origPath, destPath); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -650,7 +653,7 @@ func (b *Builder) addContext(container *daemon.Container, orig, dest string, dec
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func copyAsDirectory(source, destination string, destinationExists bool) error {
 | 
			
		||||
	if err := archive.CopyWithTar(source, destination); err != nil {
 | 
			
		||||
	if err := chrootarchive.CopyWithTar(source, destination); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,7 @@ import (
 | 
			
		|||
	log "github.com/Sirupsen/logrus"
 | 
			
		||||
	"github.com/docker/docker/daemon/graphdriver"
 | 
			
		||||
	"github.com/docker/docker/pkg/archive"
 | 
			
		||||
	"github.com/docker/docker/pkg/chrootarchive"
 | 
			
		||||
	mountpk "github.com/docker/docker/pkg/mount"
 | 
			
		||||
	"github.com/docker/docker/utils"
 | 
			
		||||
	"github.com/docker/libcontainer/label"
 | 
			
		||||
| 
						 | 
				
			
			@ -305,7 +306,7 @@ func (a *Driver) Diff(id, parent string) (archive.Archive, error) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (a *Driver) applyDiff(id string, diff archive.ArchiveReader) error {
 | 
			
		||||
	return archive.Untar(diff, path.Join(a.rootPath(), "diff", id), nil)
 | 
			
		||||
	return chrootarchive.Untar(diff, path.Join(a.rootPath(), "diff", id), nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DiffSize calculates the changes between the specified id
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ import (
 | 
			
		|||
 | 
			
		||||
	log "github.com/Sirupsen/logrus"
 | 
			
		||||
	"github.com/docker/docker/pkg/archive"
 | 
			
		||||
	"github.com/docker/docker/pkg/chrootarchive"
 | 
			
		||||
	"github.com/docker/docker/pkg/ioutils"
 | 
			
		||||
	"github.com/docker/docker/utils"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -122,7 +123,7 @@ func (gdw *naiveDiffDriver) ApplyDiff(id, parent string, diff archive.ArchiveRea
 | 
			
		|||
 | 
			
		||||
	start := time.Now().UTC()
 | 
			
		||||
	log.Debugf("Start untar layer")
 | 
			
		||||
	if err = archive.ApplyLayer(layerFs, diff); err != nil {
 | 
			
		||||
	if err = chrootarchive.ApplyLayer(layerFs, diff); err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	log.Debugf("Untar time: %vs", time.Now().UTC().Sub(start).Seconds())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ import (
 | 
			
		|||
	"path"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/daemon/graphdriver"
 | 
			
		||||
	"github.com/docker/docker/pkg/archive"
 | 
			
		||||
	"github.com/docker/docker/pkg/chrootarchive"
 | 
			
		||||
	"github.com/docker/libcontainer/label"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +66,7 @@ func (d *Driver) Create(id, parent string) error {
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("%s: %s", parent, err)
 | 
			
		||||
	}
 | 
			
		||||
	if err := archive.CopyWithTar(parentDir, dir); err != nil {
 | 
			
		||||
	if err := chrootarchive.CopyWithTar(parentDir, dir); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,7 @@ import (
 | 
			
		|||
 | 
			
		||||
	log "github.com/Sirupsen/logrus"
 | 
			
		||||
	"github.com/docker/docker/daemon/execdriver"
 | 
			
		||||
	"github.com/docker/docker/pkg/archive"
 | 
			
		||||
	"github.com/docker/docker/pkg/chrootarchive"
 | 
			
		||||
	"github.com/docker/docker/pkg/symlink"
 | 
			
		||||
	"github.com/docker/docker/volumes"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -320,7 +320,7 @@ func copyExistingContents(source, destination string) error {
 | 
			
		|||
 | 
			
		||||
		if len(srcList) == 0 {
 | 
			
		||||
			// If the source volume is empty copy files from the root into the volume
 | 
			
		||||
			if err := archive.CopyWithTar(source, destination); err != nil {
 | 
			
		||||
			if err := chrootarchive.CopyWithTar(source, destination); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										76
									
								
								pkg/chrootarchive/archive.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								pkg/chrootarchive/archive.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,76 @@
 | 
			
		|||
package chrootarchive
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"flag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"syscall"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/pkg/archive"
 | 
			
		||||
	"github.com/docker/docker/pkg/reexec"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func untar() {
 | 
			
		||||
	runtime.LockOSThread()
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
 | 
			
		||||
	if err := syscall.Chroot(flag.Arg(0)); err != nil {
 | 
			
		||||
		fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	if err := syscall.Chdir("/"); err != nil {
 | 
			
		||||
		fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	if err := archive.Untar(os.Stdin, "/", nil); err != nil {
 | 
			
		||||
		fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	os.Exit(0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	chrootArchiver = &archive.Archiver{Untar}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Untar(archive io.Reader, dest string, options *archive.TarOptions) error {
 | 
			
		||||
	if _, err := os.Stat(dest); os.IsNotExist(err) {
 | 
			
		||||
		if err := os.MkdirAll(dest, 0777); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	cmd := reexec.Command("docker-untar", dest)
 | 
			
		||||
	cmd.Stdin = archive
 | 
			
		||||
	out, err := cmd.CombinedOutput()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("Untar %s %s", err, out)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TarUntar(src, dst string) error {
 | 
			
		||||
	return chrootArchiver.TarUntar(src, dst)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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 {
 | 
			
		||||
	return chrootArchiver.CopyWithTar(src, dst)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CopyFileWithTar emulates the behavior of the 'cp' command-line
 | 
			
		||||
// for a single file. It copies a regular file from path `src` to
 | 
			
		||||
// path `dst`, and preserves all its metadata.
 | 
			
		||||
//
 | 
			
		||||
// If `dst` ends with a trailing slash '/', the final destination path
 | 
			
		||||
// will be `dst/base(src)`.
 | 
			
		||||
func CopyFileWithTar(src, dst string) (err error) {
 | 
			
		||||
	return chrootArchiver.CopyFileWithTar(src, dst)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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 {
 | 
			
		||||
	return chrootArchiver.UntarPath(src, dst)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								pkg/chrootarchive/diff.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								pkg/chrootarchive/diff.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
package chrootarchive
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"flag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"syscall"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/pkg/archive"
 | 
			
		||||
	"github.com/docker/docker/pkg/reexec"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func applyLayer() {
 | 
			
		||||
	runtime.LockOSThread()
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
 | 
			
		||||
	if err := syscall.Chroot(flag.Arg(0)); err != nil {
 | 
			
		||||
		fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	if err := syscall.Chdir("/"); err != nil {
 | 
			
		||||
		fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	if err := archive.ApplyLayer("/", os.Stdin); err != nil {
 | 
			
		||||
		fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	os.Exit(0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ApplyLayer(dest string, layer archive.ArchiveReader) error {
 | 
			
		||||
	cmd := reexec.Command("docker-applyLayer", dest)
 | 
			
		||||
	cmd.Stdin = layer
 | 
			
		||||
	out, err := cmd.CombinedOutput()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("ApplyLayer %s %s", err, out)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								pkg/chrootarchive/init.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								pkg/chrootarchive/init.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
package chrootarchive
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/pkg/reexec"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	reexec.Register("docker-untar", untar)
 | 
			
		||||
	reexec.Register("docker-applyLayer", applyLayer)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func fatal(err error) {
 | 
			
		||||
	fmt.Fprint(os.Stderr, err)
 | 
			
		||||
	os.Exit(1)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								pkg/reexec/command_linux.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								pkg/reexec/command_linux.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
// +build linux
 | 
			
		||||
 | 
			
		||||
package reexec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"syscall"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Command(args ...string) *exec.Cmd {
 | 
			
		||||
	return &exec.Cmd{
 | 
			
		||||
		Path: Self(),
 | 
			
		||||
		Args: args,
 | 
			
		||||
		SysProcAttr: &syscall.SysProcAttr{
 | 
			
		||||
			Pdeathsig: syscall.SIGTERM,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								pkg/reexec/command_unsupported.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								pkg/reexec/command_unsupported.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
// +build !linux
 | 
			
		||||
 | 
			
		||||
package reexec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"os/exec"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Command(args ...string) *exec.Cmd {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -27,19 +27,16 @@ func Init() bool {
 | 
			
		|||
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Self returns the path to the current processes binary
 | 
			
		||||
func Self() string {
 | 
			
		||||
	name := os.Args[0]
 | 
			
		||||
 | 
			
		||||
	if filepath.Base(name) == name {
 | 
			
		||||
		if lp, err := exec.LookPath(name); err == nil {
 | 
			
		||||
			name = lp
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return name
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue