Browse code

Move some image related methods & struct to smaller files

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2016/05/22 05:36:11
Showing 5 changed files
... ...
@@ -24,7 +24,6 @@ import (
24 24
 	"github.com/Sirupsen/logrus"
25 25
 	containerd "github.com/docker/containerd/api/grpc/types"
26 26
 	"github.com/docker/docker/api"
27
-	"github.com/docker/docker/builder"
28 27
 	"github.com/docker/docker/container"
29 28
 	"github.com/docker/docker/daemon/events"
30 29
 	"github.com/docker/docker/daemon/exec"
... ...
@@ -41,7 +40,6 @@ import (
41 41
 	"github.com/docker/docker/distribution/xfer"
42 42
 	"github.com/docker/docker/dockerversion"
43 43
 	"github.com/docker/docker/image"
44
-	"github.com/docker/docker/image/tarexport"
45 44
 	"github.com/docker/docker/layer"
46 45
 	"github.com/docker/docker/libcontainerd"
47 46
 	"github.com/docker/docker/migrate/v1"
... ...
@@ -80,15 +78,6 @@ var (
80 80
 	errSystemNotSupported = fmt.Errorf("The Docker daemon is not supported on this platform.")
81 81
 )
82 82
 
83
-// ErrImageDoesNotExist is error returned when no image can be found for a reference.
84
-type ErrImageDoesNotExist struct {
85
-	RefOrID string
86
-}
87
-
88
-func (e ErrImageDoesNotExist) Error() string {
89
-	return fmt.Sprintf("no such id: %s", e.RefOrID)
90
-}
91
-
92 83
 // Daemon holds information about the Docker daemon.
93 84
 type Daemon struct {
94 85
 	ID                        string
... ...
@@ -1008,221 +997,6 @@ func isBrokenPipe(e error) bool {
1008 1008
 	return e == syscall.EPIPE
1009 1009
 }
1010 1010
 
1011
-// ExportImage exports a list of images to the given output stream. The
1012
-// exported images are archived into a tar when written to the output
1013
-// stream. All images with the given tag and all versions containing
1014
-// the same tag are exported. names is the set of tags to export, and
1015
-// outStream is the writer which the images are written to.
1016
-func (daemon *Daemon) ExportImage(names []string, outStream io.Writer) error {
1017
-	imageExporter := tarexport.NewTarExporter(daemon.imageStore, daemon.layerStore, daemon.referenceStore, daemon)
1018
-	return imageExporter.Save(names, outStream)
1019
-}
1020
-
1021
-// LookupImage looks up an image by name and returns it as an ImageInspect
1022
-// structure.
1023
-func (daemon *Daemon) LookupImage(name string) (*types.ImageInspect, error) {
1024
-	img, err := daemon.GetImage(name)
1025
-	if err != nil {
1026
-		return nil, fmt.Errorf("No such image: %s", name)
1027
-	}
1028
-
1029
-	refs := daemon.referenceStore.References(img.ID())
1030
-	repoTags := []string{}
1031
-	repoDigests := []string{}
1032
-	for _, ref := range refs {
1033
-		switch ref.(type) {
1034
-		case reference.NamedTagged:
1035
-			repoTags = append(repoTags, ref.String())
1036
-		case reference.Canonical:
1037
-			repoDigests = append(repoDigests, ref.String())
1038
-		}
1039
-	}
1040
-
1041
-	var size int64
1042
-	var layerMetadata map[string]string
1043
-	layerID := img.RootFS.ChainID()
1044
-	if layerID != "" {
1045
-		l, err := daemon.layerStore.Get(layerID)
1046
-		if err != nil {
1047
-			return nil, err
1048
-		}
1049
-		defer layer.ReleaseAndLog(daemon.layerStore, l)
1050
-		size, err = l.Size()
1051
-		if err != nil {
1052
-			return nil, err
1053
-		}
1054
-
1055
-		layerMetadata, err = l.Metadata()
1056
-		if err != nil {
1057
-			return nil, err
1058
-		}
1059
-	}
1060
-
1061
-	comment := img.Comment
1062
-	if len(comment) == 0 && len(img.History) > 0 {
1063
-		comment = img.History[len(img.History)-1].Comment
1064
-	}
1065
-
1066
-	imageInspect := &types.ImageInspect{
1067
-		ID:              img.ID().String(),
1068
-		RepoTags:        repoTags,
1069
-		RepoDigests:     repoDigests,
1070
-		Parent:          img.Parent.String(),
1071
-		Comment:         comment,
1072
-		Created:         img.Created.Format(time.RFC3339Nano),
1073
-		Container:       img.Container,
1074
-		ContainerConfig: &img.ContainerConfig,
1075
-		DockerVersion:   img.DockerVersion,
1076
-		Author:          img.Author,
1077
-		Config:          img.Config,
1078
-		Architecture:    img.Architecture,
1079
-		Os:              img.OS,
1080
-		Size:            size,
1081
-		VirtualSize:     size, // TODO: field unused, deprecate
1082
-		RootFS:          rootFSToAPIType(img.RootFS),
1083
-	}
1084
-
1085
-	imageInspect.GraphDriver.Name = daemon.GraphDriverName()
1086
-
1087
-	imageInspect.GraphDriver.Data = layerMetadata
1088
-
1089
-	return imageInspect, nil
1090
-}
1091
-
1092
-// LoadImage uploads a set of images into the repository. This is the
1093
-// complement of ImageExport.  The input stream is an uncompressed tar
1094
-// ball containing images and metadata.
1095
-func (daemon *Daemon) LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
1096
-	imageExporter := tarexport.NewTarExporter(daemon.imageStore, daemon.layerStore, daemon.referenceStore, daemon)
1097
-	return imageExporter.Load(inTar, outStream, quiet)
1098
-}
1099
-
1100
-// ImageHistory returns a slice of ImageHistory structures for the specified image
1101
-// name by walking the image lineage.
1102
-func (daemon *Daemon) ImageHistory(name string) ([]*types.ImageHistory, error) {
1103
-	img, err := daemon.GetImage(name)
1104
-	if err != nil {
1105
-		return nil, err
1106
-	}
1107
-
1108
-	history := []*types.ImageHistory{}
1109
-
1110
-	layerCounter := 0
1111
-	rootFS := *img.RootFS
1112
-	rootFS.DiffIDs = nil
1113
-
1114
-	for _, h := range img.History {
1115
-		var layerSize int64
1116
-
1117
-		if !h.EmptyLayer {
1118
-			if len(img.RootFS.DiffIDs) <= layerCounter {
1119
-				return nil, fmt.Errorf("too many non-empty layers in History section")
1120
-			}
1121
-
1122
-			rootFS.Append(img.RootFS.DiffIDs[layerCounter])
1123
-			l, err := daemon.layerStore.Get(rootFS.ChainID())
1124
-			if err != nil {
1125
-				return nil, err
1126
-			}
1127
-			layerSize, err = l.DiffSize()
1128
-			layer.ReleaseAndLog(daemon.layerStore, l)
1129
-			if err != nil {
1130
-				return nil, err
1131
-			}
1132
-
1133
-			layerCounter++
1134
-		}
1135
-
1136
-		history = append([]*types.ImageHistory{{
1137
-			ID:        "<missing>",
1138
-			Created:   h.Created.Unix(),
1139
-			CreatedBy: h.CreatedBy,
1140
-			Comment:   h.Comment,
1141
-			Size:      layerSize,
1142
-		}}, history...)
1143
-	}
1144
-
1145
-	// Fill in image IDs and tags
1146
-	histImg := img
1147
-	id := img.ID()
1148
-	for _, h := range history {
1149
-		h.ID = id.String()
1150
-
1151
-		var tags []string
1152
-		for _, r := range daemon.referenceStore.References(id) {
1153
-			if _, ok := r.(reference.NamedTagged); ok {
1154
-				tags = append(tags, r.String())
1155
-			}
1156
-		}
1157
-
1158
-		h.Tags = tags
1159
-
1160
-		id = histImg.Parent
1161
-		if id == "" {
1162
-			break
1163
-		}
1164
-		histImg, err = daemon.GetImage(id.String())
1165
-		if err != nil {
1166
-			break
1167
-		}
1168
-	}
1169
-
1170
-	return history, nil
1171
-}
1172
-
1173
-// GetImageID returns an image ID corresponding to the image referred to by
1174
-// refOrID.
1175
-func (daemon *Daemon) GetImageID(refOrID string) (image.ID, error) {
1176
-	id, ref, err := reference.ParseIDOrReference(refOrID)
1177
-	if err != nil {
1178
-		return "", err
1179
-	}
1180
-	if id != "" {
1181
-		if _, err := daemon.imageStore.Get(image.ID(id)); err != nil {
1182
-			return "", ErrImageDoesNotExist{refOrID}
1183
-		}
1184
-		return image.ID(id), nil
1185
-	}
1186
-
1187
-	if id, err := daemon.referenceStore.Get(ref); err == nil {
1188
-		return id, nil
1189
-	}
1190
-	if tagged, ok := ref.(reference.NamedTagged); ok {
1191
-		if id, err := daemon.imageStore.Search(tagged.Tag()); err == nil {
1192
-			for _, namedRef := range daemon.referenceStore.References(id) {
1193
-				if namedRef.Name() == ref.Name() {
1194
-					return id, nil
1195
-				}
1196
-			}
1197
-		}
1198
-	}
1199
-
1200
-	// Search based on ID
1201
-	if id, err := daemon.imageStore.Search(refOrID); err == nil {
1202
-		return id, nil
1203
-	}
1204
-
1205
-	return "", ErrImageDoesNotExist{refOrID}
1206
-}
1207
-
1208
-// GetImage returns an image corresponding to the image referred to by refOrID.
1209
-func (daemon *Daemon) GetImage(refOrID string) (*image.Image, error) {
1210
-	imgID, err := daemon.GetImageID(refOrID)
1211
-	if err != nil {
1212
-		return nil, err
1213
-	}
1214
-	return daemon.imageStore.Get(imgID)
1215
-}
1216
-
1217
-// GetImageOnBuild looks up a Docker image referenced by `name`.
1218
-func (daemon *Daemon) GetImageOnBuild(name string) (builder.Image, error) {
1219
-	img, err := daemon.GetImage(name)
1220
-	if err != nil {
1221
-		return nil, err
1222
-	}
1223
-	return img, nil
1224
-}
1225
-
1226 1011
 // GraphDriverName returns the name of the graph driver used by the layer.Store
1227 1012
 func (daemon *Daemon) GraphDriverName() string {
1228 1013
 	return daemon.layerStore.DriverName()
... ...
@@ -1243,57 +1017,6 @@ func (daemon *Daemon) GetRemappedUIDGID() (int, int) {
1243 1243
 	return uid, gid
1244 1244
 }
1245 1245
 
1246
-// GetCachedImage returns the most recent created image that is a child
1247
-// of the image with imgID, that had the same config when it was
1248
-// created. nil is returned if a child cannot be found. An error is
1249
-// returned if the parent image cannot be found.
1250
-func (daemon *Daemon) GetCachedImage(imgID image.ID, config *containertypes.Config) (*image.Image, error) {
1251
-	// Loop on the children of the given image and check the config
1252
-	getMatch := func(siblings []image.ID) (*image.Image, error) {
1253
-		var match *image.Image
1254
-		for _, id := range siblings {
1255
-			img, err := daemon.imageStore.Get(id)
1256
-			if err != nil {
1257
-				return nil, fmt.Errorf("unable to find image %q", id)
1258
-			}
1259
-
1260
-			if runconfig.Compare(&img.ContainerConfig, config) {
1261
-				// check for the most up to date match
1262
-				if match == nil || match.Created.Before(img.Created) {
1263
-					match = img
1264
-				}
1265
-			}
1266
-		}
1267
-		return match, nil
1268
-	}
1269
-
1270
-	// In this case, this is `FROM scratch`, which isn't an actual image.
1271
-	if imgID == "" {
1272
-		images := daemon.imageStore.Map()
1273
-		var siblings []image.ID
1274
-		for id, img := range images {
1275
-			if img.Parent == imgID {
1276
-				siblings = append(siblings, id)
1277
-			}
1278
-		}
1279
-		return getMatch(siblings)
1280
-	}
1281
-
1282
-	// find match from child images
1283
-	siblings := daemon.imageStore.Children(imgID)
1284
-	return getMatch(siblings)
1285
-}
1286
-
1287
-// GetCachedImageOnBuild returns a reference to a cached image whose parent equals `parent`
1288
-// and runconfig equals `cfg`. A cache miss is expected to return an empty ID and a nil error.
1289
-func (daemon *Daemon) GetCachedImageOnBuild(imgID string, cfg *containertypes.Config) (string, error) {
1290
-	cache, err := daemon.GetCachedImage(image.ID(imgID), cfg)
1291
-	if cache == nil || err != nil {
1292
-		return "", err
1293
-	}
1294
-	return cache.ID().String(), nil
1295
-}
1296
-
1297 1246
 // tempDir returns the default directory to use for temporary files.
1298 1247
 func tempDir(rootDir string, rootUID, rootGID int) (string, error) {
1299 1248
 	var tmpDir string
1300 1249
new file mode 100644
... ...
@@ -0,0 +1,124 @@
0
+package daemon
1
+
2
+import (
3
+	"fmt"
4
+
5
+	"github.com/docker/docker/builder"
6
+	"github.com/docker/docker/image"
7
+	"github.com/docker/docker/reference"
8
+	"github.com/docker/docker/runconfig"
9
+	containertypes "github.com/docker/engine-api/types/container"
10
+)
11
+
12
+// ErrImageDoesNotExist is error returned when no image can be found for a reference.
13
+type ErrImageDoesNotExist struct {
14
+	RefOrID string
15
+}
16
+
17
+func (e ErrImageDoesNotExist) Error() string {
18
+	return fmt.Sprintf("no such id: %s", e.RefOrID)
19
+}
20
+
21
+// GetImageID returns an image ID corresponding to the image referred to by
22
+// refOrID.
23
+func (daemon *Daemon) GetImageID(refOrID string) (image.ID, error) {
24
+	id, ref, err := reference.ParseIDOrReference(refOrID)
25
+	if err != nil {
26
+		return "", err
27
+	}
28
+	if id != "" {
29
+		if _, err := daemon.imageStore.Get(image.ID(id)); err != nil {
30
+			return "", ErrImageDoesNotExist{refOrID}
31
+		}
32
+		return image.ID(id), nil
33
+	}
34
+
35
+	if id, err := daemon.referenceStore.Get(ref); err == nil {
36
+		return id, nil
37
+	}
38
+	if tagged, ok := ref.(reference.NamedTagged); ok {
39
+		if id, err := daemon.imageStore.Search(tagged.Tag()); err == nil {
40
+			for _, namedRef := range daemon.referenceStore.References(id) {
41
+				if namedRef.Name() == ref.Name() {
42
+					return id, nil
43
+				}
44
+			}
45
+		}
46
+	}
47
+
48
+	// Search based on ID
49
+	if id, err := daemon.imageStore.Search(refOrID); err == nil {
50
+		return id, nil
51
+	}
52
+
53
+	return "", ErrImageDoesNotExist{refOrID}
54
+}
55
+
56
+// GetImage returns an image corresponding to the image referred to by refOrID.
57
+func (daemon *Daemon) GetImage(refOrID string) (*image.Image, error) {
58
+	imgID, err := daemon.GetImageID(refOrID)
59
+	if err != nil {
60
+		return nil, err
61
+	}
62
+	return daemon.imageStore.Get(imgID)
63
+}
64
+
65
+// GetImageOnBuild looks up a Docker image referenced by `name`.
66
+func (daemon *Daemon) GetImageOnBuild(name string) (builder.Image, error) {
67
+	img, err := daemon.GetImage(name)
68
+	if err != nil {
69
+		return nil, err
70
+	}
71
+	return img, nil
72
+}
73
+
74
+// GetCachedImage returns the most recent created image that is a child
75
+// of the image with imgID, that had the same config when it was
76
+// created. nil is returned if a child cannot be found. An error is
77
+// returned if the parent image cannot be found.
78
+func (daemon *Daemon) GetCachedImage(imgID image.ID, config *containertypes.Config) (*image.Image, error) {
79
+	// Loop on the children of the given image and check the config
80
+	getMatch := func(siblings []image.ID) (*image.Image, error) {
81
+		var match *image.Image
82
+		for _, id := range siblings {
83
+			img, err := daemon.imageStore.Get(id)
84
+			if err != nil {
85
+				return nil, fmt.Errorf("unable to find image %q", id)
86
+			}
87
+
88
+			if runconfig.Compare(&img.ContainerConfig, config) {
89
+				// check for the most up to date match
90
+				if match == nil || match.Created.Before(img.Created) {
91
+					match = img
92
+				}
93
+			}
94
+		}
95
+		return match, nil
96
+	}
97
+
98
+	// In this case, this is `FROM scratch`, which isn't an actual image.
99
+	if imgID == "" {
100
+		images := daemon.imageStore.Map()
101
+		var siblings []image.ID
102
+		for id, img := range images {
103
+			if img.Parent == imgID {
104
+				siblings = append(siblings, id)
105
+			}
106
+		}
107
+		return getMatch(siblings)
108
+	}
109
+
110
+	// find match from child images
111
+	siblings := daemon.imageStore.Children(imgID)
112
+	return getMatch(siblings)
113
+}
114
+
115
+// GetCachedImageOnBuild returns a reference to a cached image whose parent equals `parent`
116
+// and runconfig equals `cfg`. A cache miss is expected to return an empty ID and a nil error.
117
+func (daemon *Daemon) GetCachedImageOnBuild(imgID string, cfg *containertypes.Config) (string, error) {
118
+	cache, err := daemon.GetCachedImage(image.ID(imgID), cfg)
119
+	if cache == nil || err != nil {
120
+		return "", err
121
+	}
122
+	return cache.ID().String(), nil
123
+}
0 124
new file mode 100644
... ...
@@ -0,0 +1,25 @@
0
+package daemon
1
+
2
+import (
3
+	"io"
4
+
5
+	"github.com/docker/docker/image/tarexport"
6
+)
7
+
8
+// ExportImage exports a list of images to the given output stream. The
9
+// exported images are archived into a tar when written to the output
10
+// stream. All images with the given tag and all versions containing
11
+// the same tag are exported. names is the set of tags to export, and
12
+// outStream is the writer which the images are written to.
13
+func (daemon *Daemon) ExportImage(names []string, outStream io.Writer) error {
14
+	imageExporter := tarexport.NewTarExporter(daemon.imageStore, daemon.layerStore, daemon.referenceStore, daemon)
15
+	return imageExporter.Save(names, outStream)
16
+}
17
+
18
+// LoadImage uploads a set of images into the repository. This is the
19
+// complement of ImageExport.  The input stream is an uncompressed tar
20
+// ball containing images and metadata.
21
+func (daemon *Daemon) LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
22
+	imageExporter := tarexport.NewTarExporter(daemon.imageStore, daemon.layerStore, daemon.referenceStore, daemon)
23
+	return imageExporter.Load(inTar, outStream, quiet)
24
+}
0 25
new file mode 100644
... ...
@@ -0,0 +1,82 @@
0
+package daemon
1
+
2
+import (
3
+	"fmt"
4
+
5
+	"github.com/docker/docker/layer"
6
+	"github.com/docker/docker/reference"
7
+	"github.com/docker/engine-api/types"
8
+)
9
+
10
+// ImageHistory returns a slice of ImageHistory structures for the specified image
11
+// name by walking the image lineage.
12
+func (daemon *Daemon) ImageHistory(name string) ([]*types.ImageHistory, error) {
13
+	img, err := daemon.GetImage(name)
14
+	if err != nil {
15
+		return nil, err
16
+	}
17
+
18
+	history := []*types.ImageHistory{}
19
+
20
+	layerCounter := 0
21
+	rootFS := *img.RootFS
22
+	rootFS.DiffIDs = nil
23
+
24
+	for _, h := range img.History {
25
+		var layerSize int64
26
+
27
+		if !h.EmptyLayer {
28
+			if len(img.RootFS.DiffIDs) <= layerCounter {
29
+				return nil, fmt.Errorf("too many non-empty layers in History section")
30
+			}
31
+
32
+			rootFS.Append(img.RootFS.DiffIDs[layerCounter])
33
+			l, err := daemon.layerStore.Get(rootFS.ChainID())
34
+			if err != nil {
35
+				return nil, err
36
+			}
37
+			layerSize, err = l.DiffSize()
38
+			layer.ReleaseAndLog(daemon.layerStore, l)
39
+			if err != nil {
40
+				return nil, err
41
+			}
42
+
43
+			layerCounter++
44
+		}
45
+
46
+		history = append([]*types.ImageHistory{{
47
+			ID:        "<missing>",
48
+			Created:   h.Created.Unix(),
49
+			CreatedBy: h.CreatedBy,
50
+			Comment:   h.Comment,
51
+			Size:      layerSize,
52
+		}}, history...)
53
+	}
54
+
55
+	// Fill in image IDs and tags
56
+	histImg := img
57
+	id := img.ID()
58
+	for _, h := range history {
59
+		h.ID = id.String()
60
+
61
+		var tags []string
62
+		for _, r := range daemon.referenceStore.References(id) {
63
+			if _, ok := r.(reference.NamedTagged); ok {
64
+				tags = append(tags, r.String())
65
+			}
66
+		}
67
+
68
+		h.Tags = tags
69
+
70
+		id = histImg.Parent
71
+		if id == "" {
72
+			break
73
+		}
74
+		histImg, err = daemon.GetImage(id.String())
75
+		if err != nil {
76
+			break
77
+		}
78
+	}
79
+
80
+	return history, nil
81
+}
0 82
new file mode 100644
... ...
@@ -0,0 +1,81 @@
0
+package daemon
1
+
2
+import (
3
+	"fmt"
4
+	"time"
5
+
6
+	"github.com/docker/docker/layer"
7
+	"github.com/docker/docker/reference"
8
+	"github.com/docker/engine-api/types"
9
+)
10
+
11
+// LookupImage looks up an image by name and returns it as an ImageInspect
12
+// structure.
13
+func (daemon *Daemon) LookupImage(name string) (*types.ImageInspect, error) {
14
+	img, err := daemon.GetImage(name)
15
+	if err != nil {
16
+		return nil, fmt.Errorf("No such image: %s", name)
17
+	}
18
+
19
+	refs := daemon.referenceStore.References(img.ID())
20
+	repoTags := []string{}
21
+	repoDigests := []string{}
22
+	for _, ref := range refs {
23
+		switch ref.(type) {
24
+		case reference.NamedTagged:
25
+			repoTags = append(repoTags, ref.String())
26
+		case reference.Canonical:
27
+			repoDigests = append(repoDigests, ref.String())
28
+		}
29
+	}
30
+
31
+	var size int64
32
+	var layerMetadata map[string]string
33
+	layerID := img.RootFS.ChainID()
34
+	if layerID != "" {
35
+		l, err := daemon.layerStore.Get(layerID)
36
+		if err != nil {
37
+			return nil, err
38
+		}
39
+		defer layer.ReleaseAndLog(daemon.layerStore, l)
40
+		size, err = l.Size()
41
+		if err != nil {
42
+			return nil, err
43
+		}
44
+
45
+		layerMetadata, err = l.Metadata()
46
+		if err != nil {
47
+			return nil, err
48
+		}
49
+	}
50
+
51
+	comment := img.Comment
52
+	if len(comment) == 0 && len(img.History) > 0 {
53
+		comment = img.History[len(img.History)-1].Comment
54
+	}
55
+
56
+	imageInspect := &types.ImageInspect{
57
+		ID:              img.ID().String(),
58
+		RepoTags:        repoTags,
59
+		RepoDigests:     repoDigests,
60
+		Parent:          img.Parent.String(),
61
+		Comment:         comment,
62
+		Created:         img.Created.Format(time.RFC3339Nano),
63
+		Container:       img.Container,
64
+		ContainerConfig: &img.ContainerConfig,
65
+		DockerVersion:   img.DockerVersion,
66
+		Author:          img.Author,
67
+		Config:          img.Config,
68
+		Architecture:    img.Architecture,
69
+		Os:              img.OS,
70
+		Size:            size,
71
+		VirtualSize:     size, // TODO: field unused, deprecate
72
+		RootFS:          rootFSToAPIType(img.RootFS),
73
+	}
74
+
75
+	imageInspect.GraphDriver.Name = daemon.GraphDriverName()
76
+
77
+	imageInspect.GraphDriver.Data = layerMetadata
78
+
79
+	return imageInspect, nil
80
+}