Skip to content

Commit 0661976

Browse files
ndeloofvvoland
authored andcommitted
remove GetLayerByID from ImageService interface
Co-authored-by: Nicolas De Loof <[email protected]> Co-authored-by: Paweł Gronowski <[email protected]> Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent a1f6a70 commit 0661976

9 files changed

Lines changed: 68 additions & 50 deletions

File tree

api/server/router/container/backend.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type execBackend interface {
2525
type copyBackend interface {
2626
ContainerArchivePath(name string, path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error)
2727
ContainerCopy(name string, res string) (io.ReadCloser, error)
28-
ContainerExport(name string, out io.Writer) error
28+
ContainerExport(ctx context.Context, name string, out io.Writer) error
2929
ContainerExtractToDir(name, path string, copyUIDGID, noOverwriteDirNonDir bool, content io.Reader) error
3030
ContainerStatPath(name string, path string) (stat *types.ContainerPathStat, err error)
3131
}

api/server/router/container/container_routes.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ func (s *containerRouter) getContainersLogs(ctx context.Context, w http.Response
174174
}
175175

176176
func (s *containerRouter) getContainersExport(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
177-
return s.backend.ContainerExport(vars["name"], w)
177+
return s.backend.ContainerExport(ctx, vars["name"], w)
178178
}
179179

180180
type bodyOnStartError struct{}

daemon/containerd/image_exporter.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import (
99
cerrdefs "github.com/containerd/containerd/errdefs"
1010
containerdimages "github.com/containerd/containerd/images"
1111
"github.com/containerd/containerd/images/archive"
12+
"github.com/containerd/containerd/mount"
1213
cplatforms "github.com/containerd/containerd/platforms"
1314
"github.com/docker/distribution/reference"
15+
"github.com/docker/docker/container"
1416
"github.com/docker/docker/errdefs"
1517
"github.com/docker/docker/pkg/platforms"
1618
"github.com/docker/docker/pkg/streamformatter"
@@ -19,6 +21,15 @@ import (
1921
"github.com/sirupsen/logrus"
2022
)
2123

24+
func (i *ImageService) PerformWithBaseFS(ctx context.Context, c *container.Container, fn func(root string) error) error {
25+
snapshotter := i.client.SnapshotService(i.snapshotter)
26+
mounts, err := snapshotter.Mounts(ctx, c.ID)
27+
if err != nil {
28+
return err
29+
}
30+
return mount.WithTempMount(ctx, mounts, fn)
31+
}
32+
2233
// ExportImage exports a list of images to the given output stream. The
2334
// exported images are archived into a tar when written to the output
2435
// stream. All images with the given tag and all versions containing

daemon/containerd/service.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,6 @@ func (i *ImageService) CreateLayer(container *container.Container, initFunc laye
7575
return nil, errdefs.NotImplemented(errdefs.NotImplemented(errors.New("not implemented")))
7676
}
7777

78-
// GetLayerByID returns a layer by ID
79-
// called from daemon.go Daemon.restore(), and Daemon.containerExport().
80-
func (i *ImageService) GetLayerByID(cid string) (layer.RWLayer, error) {
81-
return nil, errdefs.NotImplemented(errors.New("not implemented"))
82-
}
83-
8478
// LayerStoreStatus returns the status for each layer store
8579
// called from info.go
8680
func (i *ImageService) LayerStoreStatus() [][2]string {

daemon/daemon.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,11 @@ func (daemon *Daemon) RegistryHosts() docker.RegistryHosts {
218218
return resolver.NewRegistryConfig(m)
219219
}
220220

221+
// layerAccessor may be implemented by ImageService
222+
type layerAccessor interface {
223+
GetLayerByID(cid string) (layer.RWLayer, error)
224+
}
225+
221226
func (daemon *Daemon) restore() error {
222227
var mapLock sync.Mutex
223228
containers := make(map[string]*container.Container)
@@ -259,12 +264,14 @@ func (daemon *Daemon) restore() error {
259264
log.Debugf("not restoring container because it was created with another storage driver (%s)", c.Driver)
260265
return
261266
}
262-
rwlayer, err := daemon.imageService.GetLayerByID(c.ID)
263-
if err != nil {
264-
log.WithError(err).Error("failed to load container mount")
265-
return
267+
if accessor, ok := daemon.imageService.(layerAccessor); ok {
268+
rwlayer, err := accessor.GetLayerByID(c.ID)
269+
if err != nil {
270+
log.WithError(err).Error("failed to load container mount")
271+
return
272+
}
273+
c.RWLayer = rwlayer
266274
}
267-
c.RWLayer = rwlayer
268275
log.WithFields(logrus.Fields{
269276
"running": c.IsRunning(),
270277
"paused": c.IsPaused(),

daemon/export.go

Lines changed: 16 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
package daemon // import "github.com/docker/docker/daemon"
22

33
import (
4+
"context"
45
"fmt"
56
"io"
67

78
"github.com/docker/docker/container"
89
"github.com/docker/docker/errdefs"
910
"github.com/docker/docker/pkg/archive"
1011
"github.com/docker/docker/pkg/chrootarchive"
11-
"github.com/docker/docker/pkg/ioutils"
1212
)
1313

1414
// ContainerExport writes the contents of the container to the given
1515
// writer. An error is returned if the container cannot be found.
16-
func (daemon *Daemon) ContainerExport(name string, out io.Writer) error {
16+
func (daemon *Daemon) ContainerExport(ctx context.Context, name string, out io.Writer) error {
1717
ctr, err := daemon.GetContainer(name)
1818
if err != nil {
1919
return err
@@ -33,49 +33,31 @@ func (daemon *Daemon) ContainerExport(name string, out io.Writer) error {
3333
return errdefs.Conflict(err)
3434
}
3535

36-
data, err := daemon.containerExport(ctr)
36+
err = daemon.containerExport(ctx, ctr, out)
3737
if err != nil {
3838
return fmt.Errorf("Error exporting container %s: %v", name, err)
3939
}
40-
defer data.Close()
4140

42-
// Stream the entire contents of the container (basically a volatile snapshot)
43-
if _, err := io.Copy(out, data); err != nil {
44-
return fmt.Errorf("Error exporting container %s: %v", name, err)
45-
}
4641
return nil
4742
}
4843

49-
func (daemon *Daemon) containerExport(container *container.Container) (arch io.ReadCloser, err error) {
50-
rwlayer, err := daemon.imageService.GetLayerByID(container.ID)
51-
if err != nil {
52-
return nil, err
53-
}
54-
defer func() {
44+
func (daemon *Daemon) containerExport(ctx context.Context, container *container.Container, out io.Writer) error {
45+
err := daemon.imageService.PerformWithBaseFS(ctx, container, func(basefs string) error {
46+
archv, err := chrootarchive.Tar(basefs, &archive.TarOptions{
47+
Compression: archive.Uncompressed,
48+
IDMap: daemon.idMapping,
49+
}, basefs)
5550
if err != nil {
56-
daemon.imageService.ReleaseLayer(rwlayer)
51+
return err
5752
}
58-
}()
59-
60-
basefs, err := rwlayer.Mount(container.GetMountLabel())
61-
if err != nil {
62-
return nil, err
63-
}
6453

65-
archv, err := chrootarchive.Tar(basefs, &archive.TarOptions{
66-
Compression: archive.Uncompressed,
67-
IDMap: daemon.idMapping,
68-
}, basefs)
69-
if err != nil {
70-
rwlayer.Unmount()
71-
return nil, err
72-
}
73-
arch = ioutils.NewReadCloserWrapper(archv, func() error {
74-
err := archv.Close()
75-
rwlayer.Unmount()
76-
daemon.imageService.ReleaseLayer(rwlayer)
54+
// Stream the entire contents of the container (basically a volatile snapshot)
55+
_, err = io.Copy(out, archv)
7756
return err
7857
})
58+
if err != nil {
59+
return err
60+
}
7961
daemon.LogContainerEvent(container, "export")
80-
return arch, err
62+
return nil
8163
}

daemon/image_service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type ImageService interface {
3030
CreateImage(config []byte, parent string) (builder.Image, error)
3131
ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error)
3232
ExportImage(ctx context.Context, names []string, outStream io.Writer) error
33+
PerformWithBaseFS(ctx context.Context, c *container.Container, fn func(string) error) error
3334
LoadImage(ctx context.Context, inTar io.ReadCloser, outStream io.Writer, quiet bool) error
3435
Images(ctx context.Context, opts types.ImageListOptions) ([]*types.ImageSummary, error)
3536
LogImageEvent(imageID, refName, action string)
@@ -52,7 +53,6 @@ type ImageService interface {
5253

5354
GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts backend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error)
5455
CreateLayer(container *container.Container, initFunc layer.MountInit) (layer.RWLayer, error)
55-
GetLayerByID(cid string) (layer.RWLayer, error)
5656
LayerStoreStatus() [][2]string
5757
GetLayerMountID(cid string) (string, error)
5858
ReleaseLayer(rwlayer layer.RWLayer) error

daemon/images/image_exporter.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import (
44
"context"
55
"io"
66

7+
"github.com/docker/docker/container"
78
"github.com/docker/docker/image/tarexport"
9+
"github.com/sirupsen/logrus"
810
)
911

1012
// ExportImage exports a list of images to the given output stream. The
@@ -17,6 +19,28 @@ func (i *ImageService) ExportImage(ctx context.Context, names []string, outStrea
1719
return imageExporter.Save(names, outStream)
1820
}
1921

22+
func (i *ImageService) PerformWithBaseFS(ctx context.Context, c *container.Container, fn func(root string) error) error {
23+
rwlayer, err := i.layerStore.GetRWLayer(c.ID)
24+
if err != nil {
25+
return err
26+
}
27+
defer func() {
28+
if err != nil {
29+
err2 := i.ReleaseLayer(rwlayer)
30+
if err2 != nil {
31+
logrus.WithError(err2).WithField("container", c.ID).Warn("Failed to release layer")
32+
}
33+
}
34+
}()
35+
36+
basefs, err := rwlayer.Mount(c.GetMountLabel())
37+
if err != nil {
38+
return err
39+
}
40+
41+
return fn(basefs)
42+
}
43+
2044
// LoadImage uploads a set of images into the repository. This is the
2145
// complement of ExportImage. The input stream is an uncompressed tar
2246
// ball containing images and metadata.

daemon/images/service.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func (i *ImageService) CreateLayer(container *container.Container, initFunc laye
136136
}
137137

138138
// GetLayerByID returns a layer by ID
139-
// called from daemon.go Daemon.restore(), and Daemon.containerExport().
139+
// called from daemon.go Daemon.restore().
140140
func (i *ImageService) GetLayerByID(cid string) (layer.RWLayer, error) {
141141
return i.layerStore.GetRWLayer(cid)
142142
}
@@ -169,7 +169,7 @@ func (i *ImageService) StorageDriver() string {
169169
}
170170

171171
// ReleaseLayer releases a layer allowing it to be removed
172-
// called from delete.go Daemon.cleanupContainer(), and Daemon.containerExport()
172+
// called from delete.go Daemon.cleanupContainer().
173173
func (i *ImageService) ReleaseLayer(rwlayer layer.RWLayer) error {
174174
metaData, err := i.layerStore.ReleaseRWLayer(rwlayer)
175175
layer.LogReleaseMetadata(metaData)

0 commit comments

Comments
 (0)