github.com/gravitational/moby@v1.13.1/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 uidMaps, gidMaps := daemon.GetUIDGIDMaps() 44 archive, err := archive.TarWithOptions(container.BaseFS, &archive.TarOptions{ 45 Compression: archive.Uncompressed, 46 UIDMaps: uidMaps, 47 GIDMaps: gidMaps, 48 }) 49 if err != nil { 50 daemon.Unmount(container) 51 return nil, err 52 } 53 arch := ioutils.NewReadCloserWrapper(archive, func() error { 54 err := archive.Close() 55 daemon.Unmount(container) 56 return err 57 }) 58 daemon.LogContainerEvent(container, "export") 59 return arch, err 60 }