mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
docker tar: stream the contents of a container as a tar archive
This commit is contained in:
parent
b6fb5bb21b
commit
3703536303
3 changed files with 48 additions and 2 deletions
|
@ -39,6 +39,7 @@ func (srv *Server) Help() string {
|
|||
{"commit", "Save the state of a container"},
|
||||
{"attach", "Attach to the standard inputs and outputs of a running container"},
|
||||
{"info", "Display system-wide information"},
|
||||
{"tar", "Stream the contents of a container as a tar archive"},
|
||||
{"web", "Generate a web UI"},
|
||||
} {
|
||||
help += fmt.Sprintf(" %-10.10s%s\n", cmd...)
|
||||
|
@ -233,9 +234,16 @@ func (srv *Server) CmdTar(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
|||
return nil
|
||||
}
|
||||
name := flags.Arg(0)
|
||||
if _, exists := srv.findContainer(name); exists {
|
||||
if container, exists := srv.findContainer(name); exists {
|
||||
data, err := container.Filesystem.Tar()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Stream the entire contents of the container (basically a volatile snapshot)
|
||||
return fake.WriteFakeTar(stdout)
|
||||
if _, err := io.Copy(stdout, data); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return errors.New("No such container: " + name)
|
||||
}
|
||||
|
|
|
@ -67,6 +67,24 @@ func (fs *Filesystem) IsMounted() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// Tar returns the contents of the filesystem as an uncompressed tar stream
|
||||
func (fs *Filesystem) Tar() (io.Reader, error) {
|
||||
if err := fs.EnsureMounted(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Tar(fs.RootFS)
|
||||
}
|
||||
|
||||
|
||||
func (fs *Filesystem) EnsureMounted() error {
|
||||
if !fs.IsMounted() {
|
||||
if err := fs.Mount(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ChangeType int
|
||||
|
||||
const (
|
||||
|
|
20
utils.go
20
utils.go
|
@ -5,8 +5,28 @@ import (
|
|||
"container/list"
|
||||
"io"
|
||||
"sync"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// Tar generates a tar archive from a filesystem path, and returns it as a stream.
|
||||
// Path must point to a directory.
|
||||
|
||||
func Tar(path string) (io.Reader, error) {
|
||||
cmd := exec.Command("tar", "-C", path, "-c", ".")
|
||||
output, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := cmd.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// FIXME: errors will not be passed because we don't wait for the command.
|
||||
// Instead, consumers will hit EOF right away.
|
||||
// This can be fixed by waiting for the process to exit, or for the first write
|
||||
// on stdout, whichever comes first.
|
||||
return output, nil
|
||||
}
|
||||
|
||||
type nopWriteCloser struct {
|
||||
io.Writer
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue