github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/daemon/export.go (about) 1 package daemon 2 3 import ( 4 "fmt" 5 "io" 6 "runtime" 7 8 "github.com/docker/docker/container" 9 "github.com/docker/docker/pkg/archive" 10 "github.com/docker/docker/pkg/ioutils" 11 ) 12 13 // ContainerExport writes the contents of the container to the given 14 // writer. An error is returned if the container cannot be found. 15 func (daemon *Daemon) ContainerExport(name string, out io.Writer) error { 16 if runtime.GOOS == "windows" { 17 return fmt.Errorf("the daemon on this platform does not support export of a container") 18 } 19 20 container, err := daemon.GetContainer(name) 21 if err != nil { 22 return err 23 } 24 25 data, err := daemon.containerExport(container) 26 if err != nil { 27 return fmt.Errorf("Error exporting container %s: %v", name, err) 28 } 29 defer data.Close() 30 31 // Stream the entire contents of the container (basically a volatile snapshot) 32 if _, err := io.Copy(out, data); err != nil { 33 return fmt.Errorf("Error exporting container %s: %v", name, err) 34 } 35 return nil 36 } 37 38 func (daemon *Daemon) containerExport(container *container.Container) (io.ReadCloser, error) { 39 if err := daemon.Mount(container); err != nil { 40 return nil, err 41 } 42 43 archive, err := archive.TarWithOptions(container.BaseFS, &archive.TarOptions{ 44 Compression: archive.Uncompressed, 45 UIDMaps: daemon.idMappings.UIDs(), 46 GIDMaps: daemon.idMappings.GIDs(), 47 }) 48 if err != nil { 49 daemon.Unmount(container) 50 return nil, err 51 } 52 arch := ioutils.NewReadCloserWrapper(archive, func() error { 53 err := archive.Close() 54 daemon.Unmount(container) 55 return err 56 }) 57 daemon.LogContainerEvent(container, "export") 58 return arch, err 59 }