github.com/adityamillind98/moby@v23.0.0-rc.4+incompatible/daemon/export.go (about) 1 package daemon // import "github.com/docker/docker/daemon" 2 3 import ( 4 "fmt" 5 "io" 6 7 "github.com/docker/docker/container" 8 "github.com/docker/docker/errdefs" 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 ctr, err := daemon.GetContainer(name) 17 if err != nil { 18 return err 19 } 20 21 if isWindows && ctr.OS == "windows" { 22 return fmt.Errorf("the daemon on this operating system does not support exporting Windows containers") 23 } 24 25 if ctr.IsDead() { 26 err := fmt.Errorf("You cannot export container %s which is Dead", ctr.ID) 27 return errdefs.Conflict(err) 28 } 29 30 if ctr.IsRemovalInProgress() { 31 err := fmt.Errorf("You cannot export container %s which is being removed", ctr.ID) 32 return errdefs.Conflict(err) 33 } 34 35 data, err := daemon.containerExport(ctr) 36 if err != nil { 37 return fmt.Errorf("Error exporting container %s: %v", name, err) 38 } 39 defer data.Close() 40 41 // Stream the entire contents of the container (basically a volatile snapshot) 42 if _, err := io.Copy(out, data); err != nil { 43 return fmt.Errorf("Error exporting container %s: %v", name, err) 44 } 45 return nil 46 } 47 48 func (daemon *Daemon) containerExport(container *container.Container) (arch io.ReadCloser, err error) { 49 rwlayer, err := daemon.imageService.GetLayerByID(container.ID) 50 if err != nil { 51 return nil, err 52 } 53 defer func() { 54 if err != nil { 55 daemon.imageService.ReleaseLayer(rwlayer) 56 } 57 }() 58 59 basefs, err := rwlayer.Mount(container.GetMountLabel()) 60 if err != nil { 61 return nil, err 62 } 63 64 archv, err := archivePath(basefs, basefs.Path(), &archive.TarOptions{ 65 Compression: archive.Uncompressed, 66 IDMap: daemon.idMapping, 67 }, basefs.Path()) 68 if err != nil { 69 rwlayer.Unmount() 70 return nil, err 71 } 72 arch = ioutils.NewReadCloserWrapper(archv, func() error { 73 err := archv.Close() 74 rwlayer.Unmount() 75 daemon.imageService.ReleaseLayer(rwlayer) 76 return err 77 }) 78 daemon.LogContainerEvent(container, "export") 79 return arch, err 80 }