When importing tag and image metadata from an external Docker image
repository, don't import a tag if it has an entry in spec.tags with a
dockerImageReference or from set.
... | ... |
@@ -14,56 +14,44 @@ import ( |
14 | 14 |
) |
15 | 15 |
|
16 | 16 |
type ImportController struct { |
17 |
- repositories client.ImageStreamsNamespacer |
|
18 |
- mappings client.ImageStreamMappingsNamespacer |
|
19 |
- client dockerregistry.Client |
|
17 |
+ streams client.ImageStreamsNamespacer |
|
18 |
+ mappings client.ImageStreamMappingsNamespacer |
|
19 |
+ client dockerregistry.Client |
|
20 | 20 |
} |
21 | 21 |
|
22 |
-// needsImport returns true if the provided repository should have its tags imported. |
|
23 |
-func needsImport(repo *api.ImageStream) bool { |
|
24 |
- if len(repo.Spec.DockerImageRepository) == 0 { |
|
22 |
+// needsImport returns true if the provided image stream should have its tags imported. |
|
23 |
+func needsImport(stream *api.ImageStream) bool { |
|
24 |
+ if len(stream.Spec.DockerImageRepository) == 0 { |
|
25 | 25 |
return false |
26 | 26 |
} |
27 |
- if repo.Annotations != nil && len(repo.Annotations[api.DockerImageRepositoryCheckAnnotation]) != 0 { |
|
27 |
+ if stream.Annotations != nil && len(stream.Annotations[api.DockerImageRepositoryCheckAnnotation]) != 0 { |
|
28 | 28 |
return false |
29 | 29 |
} |
30 | 30 |
return true |
31 |
- /* |
|
32 |
- if len(repo.Spec.Tags) == 0 { |
|
33 |
- return true |
|
34 |
- } |
|
35 |
- emptyTags := 0 |
|
36 |
- for _, v := range repo.Spec.Tags { |
|
37 |
- if len(v.DockerImageReference) == 0 { |
|
38 |
- emptyTags++ |
|
39 |
- } |
|
40 |
- } |
|
41 |
- return emptyTags > 0 |
|
42 |
- */ |
|
43 | 31 |
} |
44 | 32 |
|
45 | 33 |
// retryCount is the number of times to retry on a conflict when updating an image stream |
46 | 34 |
const retryCount = 2 |
47 | 35 |
|
48 |
-// Next processes the given image repository, looking for repos that have DockerImageRepository |
|
36 |
+// Next processes the given image stream, looking for streams that have DockerImageRepository |
|
49 | 37 |
// set but have not yet been marked as "ready". If transient errors occur, err is returned but |
50 |
-// the image repository is not modified (so it will be tried again later). If a permanent |
|
38 |
+// the image stream is not modified (so it will be tried again later). If a permanent |
|
51 | 39 |
// failure occurs the image is marked with an annotation. The tags of the original spec image |
52 | 40 |
// are left as is (those are updated through status). |
53 |
-func (c *ImportController) Next(repo *api.ImageStream) error { |
|
54 |
- if !needsImport(repo) { |
|
41 |
+func (c *ImportController) Next(stream *api.ImageStream) error { |
|
42 |
+ if !needsImport(stream) { |
|
55 | 43 |
return nil |
56 | 44 |
} |
57 |
- name := repo.Spec.DockerImageRepository |
|
45 |
+ name := stream.Spec.DockerImageRepository |
|
58 | 46 |
|
59 | 47 |
ref, err := api.ParseDockerImageReference(name) |
60 | 48 |
if err != nil { |
61 | 49 |
err = fmt.Errorf("invalid docker image repository, cannot import data: %v", err) |
62 | 50 |
util.HandleError(err) |
63 |
- return c.done(repo, err.Error(), retryCount) |
|
51 |
+ return c.done(stream, err.Error(), retryCount) |
|
64 | 52 |
} |
65 | 53 |
|
66 |
- insecure := repo.Annotations != nil && repo.Annotations[api.InsecureRepositoryAnnotation] == "true" |
|
54 |
+ insecure := stream.Annotations != nil && stream.Annotations[api.InsecureRepositoryAnnotation] == "true" |
|
67 | 55 |
|
68 | 56 |
conn, err := c.client.Connect(ref.Registry, insecure) |
69 | 57 |
if err != nil { |
... | ... |
@@ -72,56 +60,32 @@ func (c *ImportController) Next(repo *api.ImageStream) error { |
72 | 72 |
tags, err := conn.ImageTags(ref.Namespace, ref.Name) |
73 | 73 |
switch { |
74 | 74 |
case dockerregistry.IsRepositoryNotFound(err), dockerregistry.IsRegistryNotFound(err): |
75 |
- return c.done(repo, err.Error(), retryCount) |
|
75 |
+ return c.done(stream, err.Error(), retryCount) |
|
76 | 76 |
case err != nil: |
77 | 77 |
return err |
78 | 78 |
} |
79 | 79 |
|
80 |
- newTags := make(map[string]string) //, len(repo.Spec.Tags)) |
|
81 | 80 |
imageToTag := make(map[string][]string) |
82 |
- //switch { |
|
83 |
- //case len(repo.Tags) == 0: |
|
84 |
- // copy all tags |
|
85 |
- for tag := range tags { |
|
86 |
- // TODO: switch to image when pull by ID is automatic |
|
87 |
- newTags[tag] = tag |
|
88 |
- } |
|
89 | 81 |
for tag, image := range tags { |
82 |
+ if specTag, ok := stream.Spec.Tags[tag]; ok && (len(specTag.DockerImageReference) != 0 || specTag.From != nil) { |
|
83 |
+ // spec tag is set to track another tag - do not import |
|
84 |
+ continue |
|
85 |
+ } |
|
86 |
+ |
|
90 | 87 |
imageToTag[image] = append(imageToTag[image], tag) |
91 | 88 |
} |
92 |
- /* |
|
93 |
- default: |
|
94 |
- for tag, v := range repo.Tags { |
|
95 |
- if len(v) != 0 { |
|
96 |
- newTags[tag] = v |
|
97 |
- continue |
|
98 |
- } |
|
99 |
- image, ok := tags[tag] |
|
100 |
- if !ok { |
|
101 |
- // tag not found, set empty |
|
102 |
- continue |
|
103 |
- } |
|
104 |
- imageToTag[image] = append(imageToTag[image], tag) |
|
105 |
- // TODO: switch to image when pull by ID is automatic |
|
106 |
- newTags[tag] = tag |
|
107 |
- } |
|
108 |
- } |
|
109 |
- */ |
|
110 | 89 |
|
111 |
- // nothing to tag - no images in the upstream repo, or we're in sync |
|
90 |
+ // no tags to import |
|
112 | 91 |
if len(imageToTag) == 0 { |
113 |
- return c.done(repo, "", retryCount) |
|
92 |
+ return c.done(stream, "", retryCount) |
|
114 | 93 |
} |
115 | 94 |
|
116 | 95 |
for id, tags := range imageToTag { |
117 | 96 |
dockerImage, err := conn.ImageByID(ref.Namespace, ref.Name, id) |
118 | 97 |
switch { |
119 | 98 |
case dockerregistry.IsRepositoryNotFound(err), dockerregistry.IsRegistryNotFound(err): |
120 |
- return c.done(repo, err.Error(), retryCount) |
|
99 |
+ return c.done(stream, err.Error(), retryCount) |
|
121 | 100 |
case dockerregistry.IsImageNotFound(err): |
122 |
- for _, tag := range tags { |
|
123 |
- delete(newTags, tag) |
|
124 |
- } |
|
125 | 101 |
continue |
126 | 102 |
case err != nil: |
127 | 103 |
return err |
... | ... |
@@ -130,7 +94,7 @@ func (c *ImportController) Next(repo *api.ImageStream) error { |
130 | 130 |
if err := kapi.Scheme.Convert(dockerImage, &image); err != nil { |
131 | 131 |
err = fmt.Errorf("could not convert image: %#v", err) |
132 | 132 |
util.HandleError(err) |
133 |
- return c.done(repo, err.Error(), retryCount) |
|
133 |
+ return c.done(stream, err.Error(), retryCount) |
|
134 | 134 |
} |
135 | 135 |
|
136 | 136 |
idTagPresent := false |
... | ... |
@@ -156,8 +120,8 @@ func (c *ImportController) Next(repo *api.ImageStream) error { |
156 | 156 |
|
157 | 157 |
mapping := &api.ImageStreamMapping{ |
158 | 158 |
ObjectMeta: kapi.ObjectMeta{ |
159 |
- Name: repo.Name, |
|
160 |
- Namespace: repo.Namespace, |
|
159 |
+ Name: stream.Name, |
|
160 |
+ Namespace: stream.Namespace, |
|
161 | 161 |
}, |
162 | 162 |
Tag: tag, |
163 | 163 |
Image: api.Image{ |
... | ... |
@@ -168,9 +132,9 @@ func (c *ImportController) Next(repo *api.ImageStream) error { |
168 | 168 |
DockerImageMetadata: image, |
169 | 169 |
}, |
170 | 170 |
} |
171 |
- if err := c.mappings.ImageStreamMappings(repo.Namespace).Create(mapping); err != nil { |
|
171 |
+ if err := c.mappings.ImageStreamMappings(stream.Namespace).Create(mapping); err != nil { |
|
172 | 172 |
if errors.IsNotFound(err) { |
173 |
- return c.done(repo, err.Error(), retryCount) |
|
173 |
+ return c.done(stream, err.Error(), retryCount) |
|
174 | 174 |
} |
175 | 175 |
return err |
176 | 176 |
} |
... | ... |
@@ -178,22 +142,22 @@ func (c *ImportController) Next(repo *api.ImageStream) error { |
178 | 178 |
} |
179 | 179 |
|
180 | 180 |
// we've completed our updates |
181 |
- return c.done(repo, "", retryCount) |
|
181 |
+ return c.done(stream, "", retryCount) |
|
182 | 182 |
} |
183 | 183 |
|
184 |
-// done marks the repository as being processed due to an error or failure condition |
|
185 |
-func (c *ImportController) done(repo *api.ImageStream, reason string, retry int) error { |
|
184 |
+// done marks the stream as being processed due to an error or failure condition |
|
185 |
+func (c *ImportController) done(stream *api.ImageStream, reason string, retry int) error { |
|
186 | 186 |
if len(reason) == 0 { |
187 | 187 |
reason = util.Now().UTC().Format(time.RFC3339) |
188 | 188 |
} |
189 |
- if repo.Annotations == nil { |
|
190 |
- repo.Annotations = make(map[string]string) |
|
189 |
+ if stream.Annotations == nil { |
|
190 |
+ stream.Annotations = make(map[string]string) |
|
191 | 191 |
} |
192 |
- repo.Annotations[api.DockerImageRepositoryCheckAnnotation] = reason |
|
193 |
- if _, err := c.repositories.ImageStreams(repo.Namespace).Update(repo); err != nil && !errors.IsNotFound(err) { |
|
192 |
+ stream.Annotations[api.DockerImageRepositoryCheckAnnotation] = reason |
|
193 |
+ if _, err := c.streams.ImageStreams(stream.Namespace).Update(stream); err != nil && !errors.IsNotFound(err) { |
|
194 | 194 |
if errors.IsConflict(err) && retry > 0 { |
195 |
- if repo, err := c.repositories.ImageStreams(repo.Namespace).Get(repo.Name); err == nil { |
|
196 |
- return c.done(repo, reason, retry-1) |
|
195 |
+ if stream, err := c.streams.ImageStreams(stream.Namespace).Get(stream.Name); err == nil { |
|
196 |
+ return c.done(stream, reason, retry-1) |
|
197 | 197 |
} |
198 | 198 |
} |
199 | 199 |
return err |
... | ... |
@@ -68,28 +68,28 @@ func (f *fakeDockerRegistryClient) ImageByID(namespace, name, id string) (*docke |
68 | 68 |
|
69 | 69 |
func TestControllerNoDockerRepo(t *testing.T) { |
70 | 70 |
cli, fake := &fakeDockerRegistryClient{}, &client.Fake{} |
71 |
- c := ImportController{client: cli, repositories: fake, mappings: fake} |
|
71 |
+ c := ImportController{client: cli, streams: fake, mappings: fake} |
|
72 | 72 |
|
73 |
- repo := api.ImageStream{ |
|
73 |
+ stream := api.ImageStream{ |
|
74 | 74 |
ObjectMeta: kapi.ObjectMeta{ |
75 | 75 |
Name: "test", |
76 | 76 |
Namespace: "other", |
77 | 77 |
}, |
78 | 78 |
} |
79 |
- other := repo |
|
80 |
- if err := c.Next(&repo); err != nil { |
|
79 |
+ other := stream |
|
80 |
+ if err := c.Next(&stream); err != nil { |
|
81 | 81 |
t.Errorf("unexpected error: %v", err) |
82 | 82 |
} |
83 |
- if !kapi.Semantic.DeepEqual(repo, other) { |
|
84 |
- t.Errorf("did not expect change to repo") |
|
83 |
+ if !kapi.Semantic.DeepEqual(stream, other) { |
|
84 |
+ t.Errorf("did not expect change to stream") |
|
85 | 85 |
} |
86 | 86 |
} |
87 | 87 |
|
88 | 88 |
func TestControllerRepoHandled(t *testing.T) { |
89 | 89 |
cli, fake := &fakeDockerRegistryClient{}, &client.Fake{} |
90 |
- c := ImportController{client: cli, repositories: fake, mappings: fake} |
|
90 |
+ c := ImportController{client: cli, streams: fake, mappings: fake} |
|
91 | 91 |
|
92 |
- repo := api.ImageStream{ |
|
92 |
+ stream := api.ImageStream{ |
|
93 | 93 |
ObjectMeta: kapi.ObjectMeta{ |
94 | 94 |
Name: "test", |
95 | 95 |
Namespace: "other", |
... | ... |
@@ -98,11 +98,11 @@ func TestControllerRepoHandled(t *testing.T) { |
98 | 98 |
DockerImageRepository: "foo/bar", |
99 | 99 |
}, |
100 | 100 |
} |
101 |
- if err := c.Next(&repo); err != nil { |
|
101 |
+ if err := c.Next(&stream); err != nil { |
|
102 | 102 |
t.Errorf("unexpected error: %v", err) |
103 | 103 |
} |
104 |
- if len(repo.Annotations["openshift.io/image.dockerRepositoryCheck"]) == 0 { |
|
105 |
- t.Errorf("did not set annotation: %#v", repo) |
|
104 |
+ if len(stream.Annotations["openshift.io/image.dockerRepositoryCheck"]) == 0 { |
|
105 |
+ t.Errorf("did not set annotation: %#v", stream) |
|
106 | 106 |
} |
107 | 107 |
if len(fake.Actions) != 1 { |
108 | 108 |
t.Errorf("expected an update action: %#v", fake.Actions) |
... | ... |
@@ -111,19 +111,19 @@ func TestControllerRepoHandled(t *testing.T) { |
111 | 111 |
|
112 | 112 |
func TestControllerTagRetrievalFails(t *testing.T) { |
113 | 113 |
cli, fake := &fakeDockerRegistryClient{Err: fmt.Errorf("test error")}, &client.Fake{} |
114 |
- c := ImportController{client: cli, repositories: fake, mappings: fake} |
|
114 |
+ c := ImportController{client: cli, streams: fake, mappings: fake} |
|
115 | 115 |
|
116 |
- repo := api.ImageStream{ |
|
116 |
+ stream := api.ImageStream{ |
|
117 | 117 |
ObjectMeta: kapi.ObjectMeta{Name: "test", Namespace: "other"}, |
118 | 118 |
Spec: api.ImageStreamSpec{ |
119 | 119 |
DockerImageRepository: "foo/bar", |
120 | 120 |
}, |
121 | 121 |
} |
122 |
- if err := c.Next(&repo); err != cli.Err { |
|
122 |
+ if err := c.Next(&stream); err != cli.Err { |
|
123 | 123 |
t.Errorf("unexpected error: %v", err) |
124 | 124 |
} |
125 |
- if len(repo.Annotations["openshift.io/image.dockerRepositoryCheck"]) != 0 { |
|
126 |
- t.Errorf("should not set annotation: %#v", repo) |
|
125 |
+ if len(stream.Annotations["openshift.io/image.dockerRepositoryCheck"]) != 0 { |
|
126 |
+ t.Errorf("should not set annotation: %#v", stream) |
|
127 | 127 |
} |
128 | 128 |
if len(fake.Actions) != 0 { |
129 | 129 |
t.Error("expected no actions on fake client") |
... | ... |
@@ -132,9 +132,9 @@ func TestControllerTagRetrievalFails(t *testing.T) { |
132 | 132 |
|
133 | 133 |
func TestControllerRetrievesInsecure(t *testing.T) { |
134 | 134 |
cli, fake := &fakeDockerRegistryClient{Err: fmt.Errorf("test error")}, &client.Fake{} |
135 |
- c := ImportController{client: cli, repositories: fake, mappings: fake} |
|
135 |
+ c := ImportController{client: cli, streams: fake, mappings: fake} |
|
136 | 136 |
|
137 |
- repo := api.ImageStream{ |
|
137 |
+ stream := api.ImageStream{ |
|
138 | 138 |
ObjectMeta: kapi.ObjectMeta{ |
139 | 139 |
Name: "test", |
140 | 140 |
Namespace: "other", |
... | ... |
@@ -146,58 +146,34 @@ func TestControllerRetrievesInsecure(t *testing.T) { |
146 | 146 |
DockerImageRepository: "foo/bar", |
147 | 147 |
}, |
148 | 148 |
} |
149 |
- if err := c.Next(&repo); err != cli.Err { |
|
149 |
+ if err := c.Next(&stream); err != cli.Err { |
|
150 | 150 |
t.Errorf("unexpected error: %v", err) |
151 | 151 |
} |
152 | 152 |
if !cli.Insecure { |
153 | 153 |
t.Errorf("expected insecure call: %#v", cli) |
154 | 154 |
} |
155 |
- if len(repo.Annotations["openshift.io/image.dockerRepositoryCheck"]) != 0 { |
|
156 |
- t.Errorf("should not set annotation: %#v", repo) |
|
155 |
+ if len(stream.Annotations["openshift.io/image.dockerRepositoryCheck"]) != 0 { |
|
156 |
+ t.Errorf("should not set annotation: %#v", stream) |
|
157 | 157 |
} |
158 | 158 |
if len(fake.Actions) != 0 { |
159 | 159 |
t.Error("expected no actions on fake client") |
160 | 160 |
} |
161 | 161 |
} |
162 | 162 |
|
163 |
-/* |
|
164 |
-func TestControllerRepoTagsAlreadySet(t *testing.T) { |
|
165 |
- cli, fake := &fakeDockerRegistryClient{}, &client.Fake{} |
|
166 |
- c := ImportController{client: cli, repositories: fake, mappings: fake} |
|
167 |
- |
|
168 |
- repo := api.ImageStream{ |
|
169 |
- ObjectMeta: kapi.ObjectMeta{Name: "test", Namespace: "other"}, |
|
170 |
- //DockerImageRepository: "foo/bar", |
|
171 |
- Tags: map[string]string{ |
|
172 |
- "test": "", |
|
173 |
- }, |
|
174 |
- } |
|
175 |
- if err := c.Next(&repo); err != nil { |
|
176 |
- t.Fatalf("unexpected error: %v", err) |
|
177 |
- } |
|
178 |
- if len(repo.Annotations["openshift.io/image.dockerRepositoryCheck"]) == 0 { |
|
179 |
- t.Errorf("did not set annotation: %#v", repo) |
|
180 |
- } |
|
181 |
- if len(fake.Actions) != 1 { |
|
182 |
- t.Errorf("expected an update action: %#v", fake.Actions) |
|
183 |
- } |
|
184 |
-} |
|
185 |
-*/ |
|
186 |
- |
|
187 | 163 |
func TestControllerImageNotFoundError(t *testing.T) { |
188 | 164 |
cli, fake := &fakeDockerRegistryClient{Tags: map[string]string{api.DefaultImageTag: "not_found"}}, &client.Fake{} |
189 |
- c := ImportController{client: cli, repositories: fake, mappings: fake} |
|
190 |
- repo := api.ImageStream{ |
|
165 |
+ c := ImportController{client: cli, streams: fake, mappings: fake} |
|
166 |
+ stream := api.ImageStream{ |
|
191 | 167 |
ObjectMeta: kapi.ObjectMeta{Name: "test", Namespace: "other"}, |
192 | 168 |
Spec: api.ImageStreamSpec{ |
193 | 169 |
DockerImageRepository: "foo/bar", |
194 | 170 |
}, |
195 | 171 |
} |
196 |
- if err := c.Next(&repo); err != nil { |
|
172 |
+ if err := c.Next(&stream); err != nil { |
|
197 | 173 |
t.Errorf("unexpected error: %v", err) |
198 | 174 |
} |
199 |
- if len(repo.Annotations["openshift.io/image.dockerRepositoryCheck"]) == 0 { |
|
200 |
- t.Errorf("did not set annotation: %#v", repo) |
|
175 |
+ if len(stream.Annotations["openshift.io/image.dockerRepositoryCheck"]) == 0 { |
|
176 |
+ t.Errorf("did not set annotation: %#v", stream) |
|
201 | 177 |
} |
202 | 178 |
if len(fake.Actions) != 1 { |
203 | 179 |
t.Errorf("expected an update action: %#v", fake.Actions) |
... | ... |
@@ -214,18 +190,18 @@ func TestControllerImageWithGenericError(t *testing.T) { |
214 | 214 |
}, |
215 | 215 |
}, |
216 | 216 |
}, &client.Fake{} |
217 |
- c := ImportController{client: cli, repositories: fake, mappings: fake} |
|
218 |
- repo := api.ImageStream{ |
|
217 |
+ c := ImportController{client: cli, streams: fake, mappings: fake} |
|
218 |
+ stream := api.ImageStream{ |
|
219 | 219 |
ObjectMeta: kapi.ObjectMeta{Name: "test", Namespace: "other"}, |
220 | 220 |
Spec: api.ImageStreamSpec{ |
221 | 221 |
DockerImageRepository: "foo/bar", |
222 | 222 |
}, |
223 | 223 |
} |
224 |
- if err := c.Next(&repo); err != cli.Images[0].Err { |
|
224 |
+ if err := c.Next(&stream); err != cli.Images[0].Err { |
|
225 | 225 |
t.Fatalf("unexpected error: %v", err) |
226 | 226 |
} |
227 |
- if len(repo.Annotations["openshift.io/image.dockerRepositoryCheck"]) != 0 { |
|
228 |
- t.Errorf("did not expect annotation: %#v", repo) |
|
227 |
+ if len(stream.Annotations["openshift.io/image.dockerRepositoryCheck"]) != 0 { |
|
228 |
+ t.Errorf("did not expect annotation: %#v", stream) |
|
229 | 229 |
} |
230 | 230 |
if len(fake.Actions) != 0 { |
231 | 231 |
t.Errorf("expected no update action: %#v", fake.Actions) |
... | ... |
@@ -245,57 +221,98 @@ func TestControllerWithImage(t *testing.T) { |
245 | 245 |
}, |
246 | 246 |
}, |
247 | 247 |
}, &client.Fake{} |
248 |
- c := ImportController{client: cli, repositories: fake, mappings: fake} |
|
249 |
- repo := api.ImageStream{ |
|
248 |
+ c := ImportController{client: cli, streams: fake, mappings: fake} |
|
249 |
+ stream := api.ImageStream{ |
|
250 | 250 |
ObjectMeta: kapi.ObjectMeta{Name: "test", Namespace: "other"}, |
251 | 251 |
Spec: api.ImageStreamSpec{ |
252 | 252 |
DockerImageRepository: "foo/bar", |
253 | 253 |
}, |
254 | 254 |
} |
255 |
- if err := c.Next(&repo); err != nil { |
|
255 |
+ if err := c.Next(&stream); err != nil { |
|
256 | 256 |
t.Errorf("unexpected error: %v", err) |
257 | 257 |
} |
258 |
- if !isRFC3339(repo.Annotations["openshift.io/image.dockerRepositoryCheck"]) { |
|
259 |
- t.Fatalf("did not set annotation: %#v", repo) |
|
258 |
+ if !isRFC3339(stream.Annotations["openshift.io/image.dockerRepositoryCheck"]) { |
|
259 |
+ t.Fatalf("did not set annotation: %#v", stream) |
|
260 | 260 |
} |
261 | 261 |
if len(fake.Actions) != 2 { |
262 | 262 |
t.Errorf("expected an update action: %#v", fake.Actions) |
263 | 263 |
} |
264 | 264 |
} |
265 | 265 |
|
266 |
-/* |
|
267 |
-func TestControllerWithEmptyTag(t *testing.T) { |
|
268 |
- cli, fake := &fakeDockerRegistryClient{ |
|
269 |
- Tags: map[string]string{api.DefaultImageTag: "found"}, |
|
270 |
- Images: []expectedImage{ |
|
271 |
- { |
|
272 |
- ID: "found", |
|
273 |
- Image: &docker.Image{ |
|
274 |
- Comment: "foo", |
|
275 |
- Config: &docker.Config{}, |
|
276 |
- }, |
|
277 |
- }, |
|
266 |
+func TestControllerWithSpecTags(t *testing.T) { |
|
267 |
+ tests := map[string]struct { |
|
268 |
+ dockerImageReference string |
|
269 |
+ from *kapi.ObjectReference |
|
270 |
+ expectUpdate bool |
|
271 |
+ }{ |
|
272 |
+ "no tracking": { |
|
273 |
+ expectUpdate: true, |
|
278 | 274 |
}, |
279 |
- }, &client.Fake{} |
|
280 |
- c := ImportController{client: cli, repositories: fake, mappings: fake} |
|
281 |
- repo := api.ImageStream{ |
|
282 |
- ObjectMeta: kapi.ObjectMeta{Name: "test", Namespace: "other"}, |
|
283 |
- //DockerImageRepository: "foo/bar", |
|
284 |
- Tags: map[string]string{ |
|
285 |
- api.DefaultImageTag: "", |
|
275 |
+ "dockerImageReference": { |
|
276 |
+ dockerImageReference: "some/repo", |
|
277 |
+ expectUpdate: false, |
|
278 |
+ }, |
|
279 |
+ "from tracking": { |
|
280 |
+ from: &kapi.ObjectReference{ |
|
281 |
+ Kind: "ImageStreamTag", |
|
282 |
+ Name: "2.0", |
|
283 |
+ }, |
|
284 |
+ expectUpdate: false, |
|
286 | 285 |
}, |
287 | 286 |
} |
288 |
- if err := c.Next(&repo); err != nil { |
|
289 |
- t.Errorf("unexpected error: %v", err) |
|
290 |
- } |
|
291 |
- if !isRFC3339(repo.Annotations["openshift.io/image.dockerRepositoryCheck"]) { |
|
292 |
- t.Fatalf("did not set annotation: %#v", repo) |
|
293 |
- } |
|
294 |
- if len(fake.Actions) != 2 { |
|
295 |
- t.Errorf("expected an update action: %#v", fake.Actions) |
|
287 |
+ |
|
288 |
+ for name, test := range tests { |
|
289 |
+ cli, fake := &fakeDockerRegistryClient{ |
|
290 |
+ Tags: map[string]string{api.DefaultImageTag: "found"}, |
|
291 |
+ Images: []expectedImage{ |
|
292 |
+ { |
|
293 |
+ ID: "found", |
|
294 |
+ Image: &docker.Image{ |
|
295 |
+ Comment: "foo", |
|
296 |
+ Config: &docker.Config{}, |
|
297 |
+ }, |
|
298 |
+ }, |
|
299 |
+ }, |
|
300 |
+ }, &client.Fake{} |
|
301 |
+ c := ImportController{client: cli, streams: fake, mappings: fake} |
|
302 |
+ stream := api.ImageStream{ |
|
303 |
+ ObjectMeta: kapi.ObjectMeta{Name: "test", Namespace: "other"}, |
|
304 |
+ Spec: api.ImageStreamSpec{ |
|
305 |
+ DockerImageRepository: "foo/bar", |
|
306 |
+ Tags: map[string]api.TagReference{ |
|
307 |
+ api.DefaultImageTag: { |
|
308 |
+ DockerImageReference: test.dockerImageReference, |
|
309 |
+ From: test.from, |
|
310 |
+ }, |
|
311 |
+ }, |
|
312 |
+ }, |
|
313 |
+ } |
|
314 |
+ if err := c.Next(&stream); err != nil { |
|
315 |
+ t.Errorf("%s: unexpected error: %v", name, err) |
|
316 |
+ } |
|
317 |
+ if !isRFC3339(stream.Annotations["openshift.io/image.dockerRepositoryCheck"]) { |
|
318 |
+ t.Fatalf("%s: did not set annotation: %#v", name, stream) |
|
319 |
+ } |
|
320 |
+ if test.expectUpdate { |
|
321 |
+ if len(fake.Actions) != 2 { |
|
322 |
+ t.Errorf("%s: expected an update action: %#v", name, fake.Actions) |
|
323 |
+ } |
|
324 |
+ if e, a := "create-imagestream-mapping", fake.Actions[0].Action; e != a { |
|
325 |
+ t.Errorf("%s: expected %s, got %s", name, e, a) |
|
326 |
+ } |
|
327 |
+ if e, a := "update-imagestream", fake.Actions[1].Action; e != a { |
|
328 |
+ t.Errorf("%s: expected %s, got %s", name, e, a) |
|
329 |
+ } |
|
330 |
+ } else { |
|
331 |
+ if len(fake.Actions) != 1 { |
|
332 |
+ t.Errorf("%s: expected no update action: %#v", name, fake.Actions) |
|
333 |
+ } |
|
334 |
+ if e, a := "update-imagestream", fake.Actions[0].Action; e != a { |
|
335 |
+ t.Errorf("%s: expected %s, got %s", name, e, a) |
|
336 |
+ } |
|
337 |
+ } |
|
296 | 338 |
} |
297 | 339 |
} |
298 |
-*/ |
|
299 | 340 |
|
300 | 341 |
func isRFC3339(s string) bool { |
301 | 342 |
_, err := time.Parse(time.RFC3339, s) |
... | ... |
@@ -37,9 +37,9 @@ func (f *ImportControllerFactory) Create() controller.RunnableController { |
37 | 37 |
cache.NewReflector(lw, &api.ImageStream{}, q, 2*time.Minute).Run() |
38 | 38 |
|
39 | 39 |
c := &ImportController{ |
40 |
- client: dockerregistry.NewClient(), |
|
41 |
- repositories: f.Client, |
|
42 |
- mappings: f.Client, |
|
40 |
+ client: dockerregistry.NewClient(), |
|
41 |
+ streams: f.Client, |
|
42 |
+ mappings: f.Client, |
|
43 | 43 |
} |
44 | 44 |
|
45 | 45 |
return &controller.RetryController{ |