Skip to content

Commit d05bc85

Browse files
authored
Merge pull request #1267 from fuweid/refactor_image_mgr
refactor: image manager
2 parents ebec621 + dd10b3d commit d05bc85

22 files changed

+1412
-945
lines changed

apis/server/image_bridge.go

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,13 @@ func (s *Server) pullImage(ctx context.Context, rw http.ResponseWriter, req *htt
2828
return httputils.NewHTTPError(err, http.StatusBadRequest)
2929
}
3030

31-
if tag == "" {
32-
tag = "latest"
33-
if index := strings.LastIndex(image, ":"); index > 0 {
34-
tag = image[index+1:]
35-
image = image[:index]
36-
}
31+
if tag != "" {
32+
image = image + ":" + tag
3733
}
34+
3835
// record the time spent during image pull procedure.
3936
defer func(start time.Time) {
40-
metrics.ImagePullSummary.WithLabelValues(image + ":" + tag).Observe(metrics.SinceInMicroseconds(start))
37+
metrics.ImagePullSummary.WithLabelValues(image).Observe(metrics.SinceInMicroseconds(start))
4138
}(time.Now())
4239

4340
// get registry auth from Request header
@@ -50,11 +47,10 @@ func (s *Server) pullImage(ctx context.Context, rw http.ResponseWriter, req *htt
5047
}
5148
}
5249
// Error information has be sent to client, so no need call resp.Write
53-
if err := s.ImageMgr.PullImage(ctx, image+":"+tag, &authConfig, rw); err != nil {
50+
if err := s.ImageMgr.PullImage(ctx, image, &authConfig, rw); err != nil {
5451
logrus.Errorf("failed to pull image %s:%s: %v", image, tag, err)
5552
return nil
5653
}
57-
5854
return nil
5955
}
6056

@@ -114,11 +110,7 @@ func (s *Server) removeImage(ctx context.Context, rw http.ResponseWriter, req *h
114110
return fmt.Errorf("Unable to remove the image %q (must force) - container %s is using this image", image.ID, containers[0].ID)
115111
}
116112

117-
option := &mgr.ImageRemoveOption{
118-
Force: isForce,
119-
}
120-
121-
if err := s.ImageMgr.RemoveImage(ctx, image, name, option); err != nil {
113+
if err := s.ImageMgr.RemoveImage(ctx, name, isForce); err != nil {
122114
return err
123115
}
124116

cli/image_list.go

Lines changed: 88 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import (
44
"context"
55
"fmt"
66

7+
"github.com/alibaba/pouch/apis/types"
78
"github.com/alibaba/pouch/pkg/reference"
89
"github.com/alibaba/pouch/pkg/utils"
910

11+
digest "github.com/opencontainers/go-digest"
1012
"github.com/spf13/cobra"
1113
)
1214

@@ -21,6 +23,13 @@ func (i imageSize) String() string {
2123
return utils.FormatSize(int64(i))
2224
}
2325

26+
type displayImage struct {
27+
id string
28+
name string
29+
size imageSize
30+
digest string
31+
}
32+
2433
// ImagesCommand use to implement 'images' command.
2534
type ImagesCommand struct {
2635
baseCommand
@@ -73,56 +82,100 @@ func (i *ImagesCommand) runImages(args []string) error {
7382
}
7483

7584
display := i.cli.NewTableDisplay()
76-
7785
if i.flagDigest {
7886
display.AddRow([]string{"IMAGE ID", "IMAGE NAME", "DIGEST", "SIZE"})
7987
} else {
8088
display.AddRow([]string{"IMAGE ID", "IMAGE NAME", "SIZE"})
8189
}
8290

83-
for _, image := range imageList {
84-
var name reference.Named
85-
var digest string
86-
if len(image.RepoTags) > 0 {
87-
name, err = reference.ParseNamedReference(image.RepoTags[0])
88-
if err != nil {
89-
return err
90-
}
91-
digestName, err := reference.ParseNamedReference(image.RepoDigests[0])
92-
if err != nil {
93-
return err
94-
}
95-
if digestd, ok := digestName.(reference.Digested); ok {
96-
digest = digestd.Digest()
97-
}
91+
dimgs := make([]displayImage, 0, len(imageList))
92+
for _, img := range imageList {
93+
dimgs = append(dimgs, imageInfoToDisplayImages(img)...)
94+
}
95+
96+
for _, dimg := range dimgs {
97+
if i.flagDigest {
98+
display.AddRow([]string{dimg.id, dimg.name, dimg.digest, fmt.Sprintf("%s", dimg.size)})
9899
} else {
99-
name, err = reference.ParseNamedReference(image.RepoDigests[0])
100-
if err != nil {
101-
return err
100+
display.AddRow([]string{dimg.id, dimg.name, fmt.Sprintf("%s", dimg.size)})
101+
}
102+
}
103+
104+
display.Flush()
105+
return nil
106+
}
107+
108+
func imageInfoToDisplayImages(img types.ImageInfo) []displayImage {
109+
dimgs := make([]displayImage, 0)
110+
111+
nameTags := make(map[string][]string)
112+
digestIndexByName := make(map[string]digest.Digest)
113+
114+
for _, repoTag := range img.RepoTags {
115+
namedRef, err := reference.Parse(repoTag)
116+
// ideally, it should be nil
117+
if err != nil {
118+
continue
119+
}
120+
121+
if reference.IsNameTagged(namedRef) {
122+
taggedRef := namedRef.(reference.Tagged)
123+
nameTags[taggedRef.Name()] = append(nameTags[taggedRef.Name()], taggedRef.Tag())
124+
}
125+
}
126+
127+
for _, repoDigest := range img.RepoDigests {
128+
namedRef, err := reference.Parse(repoDigest)
129+
// ideally, it should be nil
130+
if err != nil {
131+
continue
132+
}
133+
134+
namedRef = reference.TrimTagForDigest(namedRef)
135+
if cdRef, ok := namedRef.(reference.CanonicalDigested); ok {
136+
digestIndexByName[cdRef.Name()] = cdRef.Digest()
137+
}
138+
}
139+
140+
for name, tags := range nameTags {
141+
for _, tag := range tags {
142+
dimg := displayImage{
143+
id: utils.TruncateID(img.ID),
144+
name: name + ":" + tag,
145+
size: imageSize(img.Size),
102146
}
103-
if digestd, ok := name.(reference.Digested); ok {
104-
digest = digestd.Digest()
147+
148+
if dig, ok := digestIndexByName[name]; ok {
149+
dimg.digest = dig.String()
150+
} else {
151+
dimg.digest = "<none>"
105152
}
153+
dimgs = append(dimgs, dimg)
106154
}
155+
}
107156

108-
if i.flagDigest {
109-
display.AddRow([]string{
110-
utils.TruncateID(image.ID),
111-
name.String(),
112-
digest,
113-
fmt.Sprintf("%s", imageSize(image.Size)),
157+
// if there is no repo tags
158+
if len(dimgs) == 0 {
159+
for name, dig := range digestIndexByName {
160+
dimgs = append(dimgs, displayImage{
161+
id: utils.TruncateID(img.ID),
162+
name: name + "@" + dig.String(),
163+
digest: dig.String(),
164+
size: imageSize(img.Size),
114165
})
115-
} else {
116-
display.AddRow([]string{
117-
utils.TruncateID(image.ID),
118-
name.String(),
119-
fmt.Sprintf("%s", imageSize(image.Size)),
166+
}
167+
168+
// if there is no repo digests
169+
if len(dimgs) == 0 {
170+
dimgs = append(dimgs, displayImage{
171+
id: utils.TruncateID(img.ID),
172+
name: "<none>",
173+
digest: "<none>",
174+
size: imageSize(img.Size),
120175
})
121176
}
122177
}
123-
124-
display.Flush()
125-
return nil
178+
return dimgs
126179
}
127180

128181
// imagesExample shows examples in images command, and is used in auto-generated cli docs.

cli/pull.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,22 @@ func (p *PullCommand) addFlags() {
5555

5656
// runPull is the entry of pull command.
5757
func (p *PullCommand) runPull(args []string) error {
58-
namedRef, err := reference.ParseNamedReference(args[0])
58+
namedRef, err := reference.Parse(args[0])
5959
if err != nil {
6060
return fmt.Errorf("failed to pull image: %v", err)
6161
}
62-
taggedRef := reference.WithDefaultTagIfMissing(namedRef).(reference.Tagged)
62+
namedRef = reference.TrimTagForDigest(reference.WithDefaultTagIfMissing(namedRef))
63+
64+
var name, tag string
65+
if reference.IsNameTagged(namedRef) {
66+
name, tag = namedRef.Name(), namedRef.(reference.Tagged).Tag()
67+
} else {
68+
name = namedRef.String()
69+
}
6370

6471
ctx := context.Background()
6572
apiClient := p.cli.Client()
66-
responseBody, err := apiClient.ImagePull(ctx, taggedRef.Name(), taggedRef.Tag(), fetchRegistryAuth(taggedRef.Name()))
73+
responseBody, err := apiClient.ImagePull(ctx, name, tag, fetchRegistryAuth(namedRef.Name()))
6774
if err != nil {
6875
return fmt.Errorf("failed to pull image: %v", err)
6976
}

cli/upgrade.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package main
33
import (
44
"context"
55
"fmt"
6-
"strings"
76

7+
"github.com/alibaba/pouch/pkg/errtypes"
88
"github.com/alibaba/pouch/pkg/reference"
99

1010
"github.com/spf13/cobra"
@@ -61,16 +61,23 @@ func (ug *UpgradeCommand) runUpgrade(args []string) error {
6161

6262
// Check whether the image has been pulled
6363
_, err = apiClient.ImageInspect(ctx, config.Image)
64-
if err != nil && strings.Contains(err.Error(), "not found") {
64+
if err != nil && errtypes.IsNotfound(err) {
6565
fmt.Printf("Image %s not found, try to pull it...\n", config.Image)
6666

67-
namedRef, err := reference.ParseNamedReference(args[0])
67+
namedRef, err := reference.Parse(config.Image)
6868
if err != nil {
6969
return fmt.Errorf("failed to pull image: %v", err)
7070
}
71-
taggedRef := reference.WithDefaultTagIfMissing(namedRef).(reference.Tagged)
71+
namedRef = reference.TrimTagForDigest(reference.WithDefaultTagIfMissing(namedRef))
7272

73-
responseBody, err := apiClient.ImagePull(ctx, taggedRef.Name(), taggedRef.Tag(), fetchRegistryAuth(taggedRef.Name()))
73+
var name, tag string
74+
if reference.IsNameTagged(namedRef) {
75+
name, tag = namedRef.Name(), namedRef.(reference.Tagged).Tag()
76+
} else {
77+
name = namedRef.String()
78+
}
79+
80+
responseBody, err := apiClient.ImagePull(ctx, name, tag, fetchRegistryAuth(namedRef.Name()))
7481
if err != nil {
7582
return fmt.Errorf("failed to pull image: %v", err)
7683
}

0 commit comments

Comments
 (0)