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
... | ... |
@@ -24,6 +24,7 @@ import ( |
24 | 24 |
"github.com/docker/docker/daemon" |
25 | 25 |
imagepkg "github.com/docker/docker/image" |
26 | 26 |
"github.com/docker/docker/pkg/archive" |
27 |
+ "github.com/docker/docker/pkg/chrootarchive" |
|
27 | 28 |
"github.com/docker/docker/pkg/parsers" |
28 | 29 |
"github.com/docker/docker/pkg/symlink" |
29 | 30 |
"github.com/docker/docker/pkg/system" |
... | ... |
@@ -46,7 +47,9 @@ func (b *Builder) readContext(context io.Reader) error { |
46 | 46 |
if b.context, err = tarsum.NewTarSum(decompressedStream, true, tarsum.Version0); err != nil { |
47 | 47 |
return err |
48 | 48 |
} |
49 |
- if err := archive.Untar(b.context, tmpdirPath, nil); err != nil { |
|
49 |
+ |
|
50 |
+ os.MkdirAll(tmpdirPath, 0700) |
|
51 |
+ if err := chrootarchive.Untar(b.context, tmpdirPath, nil); err != nil { |
|
50 | 52 |
return err |
51 | 53 |
} |
52 | 54 |
|
... | ... |
@@ -627,7 +630,7 @@ func (b *Builder) addContext(container *daemon.Container, orig, dest string, dec |
627 | 627 |
} |
628 | 628 |
|
629 | 629 |
// try to successfully untar the orig |
630 |
- if err := archive.UntarPath(origPath, tarDest); err == nil { |
|
630 |
+ if err := chrootarchive.UntarPath(origPath, tarDest); err == nil { |
|
631 | 631 |
return nil |
632 | 632 |
} else if err != io.EOF { |
633 | 633 |
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 |
637 | 637 |
if err := os.MkdirAll(path.Dir(destPath), 0755); err != nil { |
638 | 638 |
return err |
639 | 639 |
} |
640 |
- if err := archive.CopyWithTar(origPath, destPath); err != nil { |
|
640 |
+ if err := chrootarchive.CopyWithTar(origPath, destPath); err != nil { |
|
641 | 641 |
return err |
642 | 642 |
} |
643 | 643 |
|
... | ... |
@@ -650,7 +653,7 @@ func (b *Builder) addContext(container *daemon.Container, orig, dest string, dec |
650 | 650 |
} |
651 | 651 |
|
652 | 652 |
func copyAsDirectory(source, destination string, destinationExists bool) error { |
653 |
- if err := archive.CopyWithTar(source, destination); err != nil { |
|
653 |
+ if err := chrootarchive.CopyWithTar(source, destination); err != nil { |
|
654 | 654 |
return err |
655 | 655 |
} |
656 | 656 |
|
... | ... |
@@ -33,6 +33,7 @@ import ( |
33 | 33 |
log "github.com/Sirupsen/logrus" |
34 | 34 |
"github.com/docker/docker/daemon/graphdriver" |
35 | 35 |
"github.com/docker/docker/pkg/archive" |
36 |
+ "github.com/docker/docker/pkg/chrootarchive" |
|
36 | 37 |
mountpk "github.com/docker/docker/pkg/mount" |
37 | 38 |
"github.com/docker/docker/utils" |
38 | 39 |
"github.com/docker/libcontainer/label" |
... | ... |
@@ -305,7 +306,7 @@ func (a *Driver) Diff(id, parent string) (archive.Archive, error) { |
305 | 305 |
} |
306 | 306 |
|
307 | 307 |
func (a *Driver) applyDiff(id string, diff archive.ArchiveReader) error { |
308 |
- return archive.Untar(diff, path.Join(a.rootPath(), "diff", id), nil) |
|
308 |
+ return chrootarchive.Untar(diff, path.Join(a.rootPath(), "diff", id), nil) |
|
309 | 309 |
} |
310 | 310 |
|
311 | 311 |
// DiffSize calculates the changes between the specified id |
... | ... |
@@ -8,6 +8,7 @@ import ( |
8 | 8 |
|
9 | 9 |
log "github.com/Sirupsen/logrus" |
10 | 10 |
"github.com/docker/docker/pkg/archive" |
11 |
+ "github.com/docker/docker/pkg/chrootarchive" |
|
11 | 12 |
"github.com/docker/docker/pkg/ioutils" |
12 | 13 |
"github.com/docker/docker/utils" |
13 | 14 |
) |
... | ... |
@@ -122,7 +123,7 @@ func (gdw *naiveDiffDriver) ApplyDiff(id, parent string, diff archive.ArchiveRea |
122 | 122 |
|
123 | 123 |
start := time.Now().UTC() |
124 | 124 |
log.Debugf("Start untar layer") |
125 |
- if err = archive.ApplyLayer(layerFs, diff); err != nil { |
|
125 |
+ if err = chrootarchive.ApplyLayer(layerFs, diff); err != nil { |
|
126 | 126 |
return |
127 | 127 |
} |
128 | 128 |
log.Debugf("Untar time: %vs", time.Now().UTC().Sub(start).Seconds()) |
... | ... |
@@ -8,7 +8,7 @@ import ( |
8 | 8 |
"path" |
9 | 9 |
|
10 | 10 |
"github.com/docker/docker/daemon/graphdriver" |
11 |
- "github.com/docker/docker/pkg/archive" |
|
11 |
+ "github.com/docker/docker/pkg/chrootarchive" |
|
12 | 12 |
"github.com/docker/libcontainer/label" |
13 | 13 |
) |
14 | 14 |
|
... | ... |
@@ -66,7 +66,7 @@ func (d *Driver) Create(id, parent string) error { |
66 | 66 |
if err != nil { |
67 | 67 |
return fmt.Errorf("%s: %s", parent, err) |
68 | 68 |
} |
69 |
- if err := archive.CopyWithTar(parentDir, dir); err != nil { |
|
69 |
+ if err := chrootarchive.CopyWithTar(parentDir, dir); err != nil { |
|
70 | 70 |
return err |
71 | 71 |
} |
72 | 72 |
return nil |
... | ... |
@@ -12,7 +12,7 @@ import ( |
12 | 12 |
|
13 | 13 |
log "github.com/Sirupsen/logrus" |
14 | 14 |
"github.com/docker/docker/daemon/execdriver" |
15 |
- "github.com/docker/docker/pkg/archive" |
|
15 |
+ "github.com/docker/docker/pkg/chrootarchive" |
|
16 | 16 |
"github.com/docker/docker/pkg/symlink" |
17 | 17 |
"github.com/docker/docker/volumes" |
18 | 18 |
) |
... | ... |
@@ -320,7 +320,7 @@ func copyExistingContents(source, destination string) error { |
320 | 320 |
|
321 | 321 |
if len(srcList) == 0 { |
322 | 322 |
// If the source volume is empty copy files from the root into the volume |
323 |
- if err := archive.CopyWithTar(source, destination); err != nil { |
|
323 |
+ if err := chrootarchive.CopyWithTar(source, destination); err != nil { |
|
324 | 324 |
return err |
325 | 325 |
} |
326 | 326 |
} |
327 | 327 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,76 @@ |
0 |
+package chrootarchive |
|
1 |
+ |
|
2 |
+import ( |
|
3 |
+ "flag" |
|
4 |
+ "fmt" |
|
5 |
+ "io" |
|
6 |
+ "os" |
|
7 |
+ "runtime" |
|
8 |
+ "syscall" |
|
9 |
+ |
|
10 |
+ "github.com/docker/docker/pkg/archive" |
|
11 |
+ "github.com/docker/docker/pkg/reexec" |
|
12 |
+) |
|
13 |
+ |
|
14 |
+func untar() { |
|
15 |
+ runtime.LockOSThread() |
|
16 |
+ flag.Parse() |
|
17 |
+ |
|
18 |
+ if err := syscall.Chroot(flag.Arg(0)); err != nil { |
|
19 |
+ fatal(err) |
|
20 |
+ } |
|
21 |
+ if err := syscall.Chdir("/"); err != nil { |
|
22 |
+ fatal(err) |
|
23 |
+ } |
|
24 |
+ if err := archive.Untar(os.Stdin, "/", nil); err != nil { |
|
25 |
+ fatal(err) |
|
26 |
+ } |
|
27 |
+ os.Exit(0) |
|
28 |
+} |
|
29 |
+ |
|
30 |
+var ( |
|
31 |
+ chrootArchiver = &archive.Archiver{Untar} |
|
32 |
+) |
|
33 |
+ |
|
34 |
+func Untar(archive io.Reader, dest string, options *archive.TarOptions) error { |
|
35 |
+ if _, err := os.Stat(dest); os.IsNotExist(err) { |
|
36 |
+ if err := os.MkdirAll(dest, 0777); err != nil { |
|
37 |
+ return err |
|
38 |
+ } |
|
39 |
+ } |
|
40 |
+ cmd := reexec.Command("docker-untar", dest) |
|
41 |
+ cmd.Stdin = archive |
|
42 |
+ out, err := cmd.CombinedOutput() |
|
43 |
+ if err != nil { |
|
44 |
+ return fmt.Errorf("Untar %s %s", err, out) |
|
45 |
+ } |
|
46 |
+ return nil |
|
47 |
+} |
|
48 |
+ |
|
49 |
+func TarUntar(src, dst string) error { |
|
50 |
+ return chrootArchiver.TarUntar(src, dst) |
|
51 |
+} |
|
52 |
+ |
|
53 |
+// CopyWithTar creates a tar archive of filesystem path `src`, and |
|
54 |
+// unpacks it at filesystem path `dst`. |
|
55 |
+// The archive is streamed directly with fixed buffering and no |
|
56 |
+// intermediary disk IO. |
|
57 |
+func CopyWithTar(src, dst string) error { |
|
58 |
+ return chrootArchiver.CopyWithTar(src, dst) |
|
59 |
+} |
|
60 |
+ |
|
61 |
+// CopyFileWithTar emulates the behavior of the 'cp' command-line |
|
62 |
+// for a single file. It copies a regular file from path `src` to |
|
63 |
+// path `dst`, and preserves all its metadata. |
|
64 |
+// |
|
65 |
+// If `dst` ends with a trailing slash '/', the final destination path |
|
66 |
+// will be `dst/base(src)`. |
|
67 |
+func CopyFileWithTar(src, dst string) (err error) { |
|
68 |
+ return chrootArchiver.CopyFileWithTar(src, dst) |
|
69 |
+} |
|
70 |
+ |
|
71 |
+// UntarPath is a convenience function which looks for an archive |
|
72 |
+// at filesystem path `src`, and unpacks it at `dst`. |
|
73 |
+func UntarPath(src, dst string) error { |
|
74 |
+ return chrootArchiver.UntarPath(src, dst) |
|
75 |
+} |
0 | 76 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,38 @@ |
0 |
+package chrootarchive |
|
1 |
+ |
|
2 |
+import ( |
|
3 |
+ "flag" |
|
4 |
+ "fmt" |
|
5 |
+ "os" |
|
6 |
+ "runtime" |
|
7 |
+ "syscall" |
|
8 |
+ |
|
9 |
+ "github.com/docker/docker/pkg/archive" |
|
10 |
+ "github.com/docker/docker/pkg/reexec" |
|
11 |
+) |
|
12 |
+ |
|
13 |
+func applyLayer() { |
|
14 |
+ runtime.LockOSThread() |
|
15 |
+ flag.Parse() |
|
16 |
+ |
|
17 |
+ if err := syscall.Chroot(flag.Arg(0)); err != nil { |
|
18 |
+ fatal(err) |
|
19 |
+ } |
|
20 |
+ if err := syscall.Chdir("/"); err != nil { |
|
21 |
+ fatal(err) |
|
22 |
+ } |
|
23 |
+ if err := archive.ApplyLayer("/", os.Stdin); err != nil { |
|
24 |
+ fatal(err) |
|
25 |
+ } |
|
26 |
+ os.Exit(0) |
|
27 |
+} |
|
28 |
+ |
|
29 |
+func ApplyLayer(dest string, layer archive.ArchiveReader) error { |
|
30 |
+ cmd := reexec.Command("docker-applyLayer", dest) |
|
31 |
+ cmd.Stdin = layer |
|
32 |
+ out, err := cmd.CombinedOutput() |
|
33 |
+ if err != nil { |
|
34 |
+ return fmt.Errorf("ApplyLayer %s %s", err, out) |
|
35 |
+ } |
|
36 |
+ return nil |
|
37 |
+} |
0 | 38 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,18 @@ |
0 |
+package chrootarchive |
|
1 |
+ |
|
2 |
+import ( |
|
3 |
+ "fmt" |
|
4 |
+ "os" |
|
5 |
+ |
|
6 |
+ "github.com/docker/docker/pkg/reexec" |
|
7 |
+) |
|
8 |
+ |
|
9 |
+func init() { |
|
10 |
+ reexec.Register("docker-untar", untar) |
|
11 |
+ reexec.Register("docker-applyLayer", applyLayer) |
|
12 |
+} |
|
13 |
+ |
|
14 |
+func fatal(err error) { |
|
15 |
+ fmt.Fprint(os.Stderr, err) |
|
16 |
+ os.Exit(1) |
|
17 |
+} |
0 | 18 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,18 @@ |
0 |
+// +build linux |
|
1 |
+ |
|
2 |
+package reexec |
|
3 |
+ |
|
4 |
+import ( |
|
5 |
+ "os/exec" |
|
6 |
+ "syscall" |
|
7 |
+) |
|
8 |
+ |
|
9 |
+func Command(args ...string) *exec.Cmd { |
|
10 |
+ return &exec.Cmd{ |
|
11 |
+ Path: Self(), |
|
12 |
+ Args: args, |
|
13 |
+ SysProcAttr: &syscall.SysProcAttr{ |
|
14 |
+ Pdeathsig: syscall.SIGTERM, |
|
15 |
+ }, |
|
16 |
+ } |
|
17 |
+} |
... | ... |
@@ -27,19 +27,16 @@ func Init() bool { |
27 | 27 |
|
28 | 28 |
return true |
29 | 29 |
} |
30 |
- |
|
31 | 30 |
return false |
32 | 31 |
} |
33 | 32 |
|
34 | 33 |
// Self returns the path to the current processes binary |
35 | 34 |
func Self() string { |
36 | 35 |
name := os.Args[0] |
37 |
- |
|
38 | 36 |
if filepath.Base(name) == name { |
39 | 37 |
if lp, err := exec.LookPath(name); err == nil { |
40 | 38 |
name = lp |
41 | 39 |
} |
42 | 40 |
} |
43 |
- |
|
44 | 41 |
return name |
45 | 42 |
} |