Browse code

Support a new image stream tag reference policy

Will allow deployment configs and builds to leverage pull through by
default.

Clayton Coleman authored on 2016/12/11 06:59:21
Showing 5 changed files
... ...
@@ -235,6 +235,8 @@ type TagReference struct {
235 235
 	Generation *int64
236 236
 	// ImportPolicy is information that controls how images may be imported by the server.
237 237
 	ImportPolicy TagImportPolicy
238
+	// ReferencePolicy defines how other components should consume the image
239
+	ReferencePolicy TagReferencePolicy
238 240
 }
239 241
 
240 242
 type TagImportPolicy struct {
... ...
@@ -244,6 +246,35 @@ type TagImportPolicy struct {
244 244
 	Scheduled bool
245 245
 }
246 246
 
247
+// TagReferencePolicyType describes how pull-specs for images in an image stream tag are generated when
248
+// image change triggers are fired.
249
+type TagReferencePolicyType string
250
+
251
+const (
252
+	// SourceTagReferencePolicy indicates the image's original location should be used when the image stream tag
253
+	// is resolved into other resources (builds and deployment configurations).
254
+	SourceTagReferencePolicy TagReferencePolicyType = "Source"
255
+	// LocalTagReferencePolicy indicates the image should prefer to pull via the local integrated registry,
256
+	// falling back to the remote location if the integrated registry has not been configured. The reference will
257
+	// use the internal DNS name or registry service IP.
258
+	LocalTagReferencePolicy TagReferencePolicyType = "Local"
259
+)
260
+
261
+// TagReferencePolicy describes how pull-specs for images in this image stream tag are generated when
262
+// image change triggers in deployment configs or builds are resolved. This allows the image stream
263
+// author to control how images are accessed.
264
+type TagReferencePolicy struct {
265
+	// Type determines how the image pull spec should be transformed when the image stream tag is used in
266
+	// deployment config triggers or new builds. The default value is `Source`, indicating the original
267
+	// location of the image should be used (if imported). The user may also specify `Local`, indicating
268
+	// that the pull spec should point to the integrated Docker registry and leverage the registry's
269
+	// ability to proxy the pull to an upstream registry. `Local` allows the credentials used to pull this
270
+	// image to be managed from the image stream's namespace, so others on the platform can access a remote
271
+	// image but have no access to the remote secret. It also allows the image layers to be mirrored into
272
+	// the local registry which the images can still be pulled even if the upstream registry is unavailable.
273
+	Type TagReferencePolicyType
274
+}
275
+
247 276
 // ImageStreamStatus contains information about the state of this image stream.
248 277
 type ImageStreamStatus struct {
249 278
 	// DockerImageRepository represents the effective location this stream may be accessed at. May be empty until the server
... ...
@@ -16,8 +16,15 @@ func SetDefaults_ImageImportSpec(obj *ImageImportSpec) {
16 16
 	}
17 17
 }
18 18
 
19
+func SetDefaults_TagReferencePolicy(obj *TagReferencePolicy) {
20
+	if len(obj.Type) == 0 {
21
+		obj.Type = SourceTagReferencePolicy
22
+	}
23
+}
24
+
19 25
 func addDefaultingFuncs(scheme *runtime.Scheme) error {
20 26
 	return scheme.AddDefaultingFuncs(
21 27
 		SetDefaults_ImageImportSpec,
28
+		SetDefaults_TagReferencePolicy,
22 29
 	)
23 30
 }
... ...
@@ -178,9 +178,11 @@ type TagReference struct {
178 178
 	Generation *int64 `json:"generation" protobuf:"varint,5,opt,name=generation"`
179 179
 	// Import is information that controls how images may be imported by the server.
180 180
 	ImportPolicy TagImportPolicy `json:"importPolicy,omitempty" protobuf:"bytes,6,opt,name=importPolicy"`
181
+	// ReferencePolicy defines how other components should consume the image
182
+	ReferencePolicy TagReferencePolicy `json:"referencePolicy,omitempty" protobuf:"bytes,7,opt,name=referencePolicy"`
181 183
 }
182 184
 
183
-// TagImportPolicy describes the tag import policy
185
+// TagImportPolicy controls how images related to this tag will be imported.
184 186
 type TagImportPolicy struct {
185 187
 	// Insecure is true if the server may bypass certificate verification or connect directly over HTTP during image import.
186 188
 	Insecure bool `json:"insecure,omitempty" protobuf:"varint,1,opt,name=insecure"`
... ...
@@ -188,6 +190,35 @@ type TagImportPolicy struct {
188 188
 	Scheduled bool `json:"scheduled,omitempty" protobuf:"varint,2,opt,name=scheduled"`
189 189
 }
190 190
 
191
+// TagReferencePolicyType describes how pull-specs for images in an image stream tag are generated when
192
+// image change triggers are fired.
193
+type TagReferencePolicyType string
194
+
195
+const (
196
+	// SourceTagReferencePolicy indicates the image's original location should be used when the image stream tag
197
+	// is resolved into other resources (builds and deployment configurations).
198
+	SourceTagReferencePolicy TagReferencePolicyType = "Source"
199
+	// LocalTagReferencePolicy indicates the image should prefer to pull via the local integrated registry,
200
+	// falling back to the remote location if the integrated registry has not been configured. The reference will
201
+	// use the internal DNS name or registry service IP.
202
+	LocalTagReferencePolicy TagReferencePolicyType = "Local"
203
+)
204
+
205
+// TagReferencePolicy describes how pull-specs for images in this image stream tag are generated when
206
+// image change triggers in deployment configs or builds are resolved. This allows the image stream
207
+// author to control how images are accessed.
208
+type TagReferencePolicy struct {
209
+	// Type determines how the image pull spec should be transformed when the image stream tag is used in
210
+	// deployment config triggers or new builds. The default value is `Source`, indicating the original
211
+	// location of the image should be used (if imported). The user may also specify `Local`, indicating
212
+	// that the pull spec should point to the integrated Docker registry and leverage the registry's
213
+	// ability to proxy the pull to an upstream registry. `Local` allows the credentials used to pull this
214
+	// image to be managed from the image stream's namespace, so others on the platform can access a remote
215
+	// image but have no access to the remote secret. It also allows the image layers to be mirrored into
216
+	// the local registry which the images can still be pulled even if the upstream registry is unavailable.
217
+	Type TagReferencePolicyType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=TagReferencePolicyType"`
218
+}
219
+
191 220
 // ImageStreamStatus contains information about the state of this image stream.
192 221
 type ImageStreamStatus struct {
193 222
 	// DockerImageRepository represents the effective location this stream may be accessed at.
... ...
@@ -208,6 +208,11 @@ func ValidateImageStreamTagReference(tagRef api.TagReference, fldPath *field.Pat
208 208
 			errs = append(errs, field.Required(fldPath.Child("from", "kind"), "valid values are 'DockerImage', 'ImageStreamImage', 'ImageStreamTag'"))
209 209
 		}
210 210
 	}
211
+	switch tagRef.ReferencePolicy.Type {
212
+	case api.SourceTagReferencePolicy, api.LocalTagReferencePolicy:
213
+	default:
214
+		errs = append(errs, field.Invalid(fldPath.Child("referencePolicy", "type"), tagRef.ReferencePolicy.Type, fmt.Sprintf("valid values are %q, %q", api.SourceTagReferencePolicy, api.LocalTagReferencePolicy)))
215
+	}
211 216
 	return errs
212 217
 }
213 218
 
... ...
@@ -452,6 +452,22 @@ func TestValidateImageStream(t *testing.T) {
452 452
 				field.Required(field.NewPath("status", "tags").Key("tag").Child("items").Index(2).Child("dockerImageReference"), ""),
453 453
 			},
454 454
 		},
455
+		"referencePolicy.type must be valid": {
456
+			namespace: "namespace",
457
+			name:      "foo",
458
+			specTags: map[string]api.TagReference{
459
+				"tag": {
460
+					From: &kapi.ObjectReference{
461
+						Kind: "DockerImage",
462
+						Name: "abc",
463
+					},
464
+					ReferencePolicy: api.TagReferencePolicy{Type: api.TagReferencePolicyType("Other")},
465
+				},
466
+			},
467
+			expected: field.ErrorList{
468
+				field.Invalid(field.NewPath("spec", "tags").Key("tag").Child("referencePolicy", "type"), api.TagReferencePolicyType("Other"), "valid values are \"Source\", \"Local\""),
469
+			},
470
+		},
455 471
 		"ImageStreamTags can't be scheduled": {
456 472
 			namespace: "namespace",
457 473
 			name:      "foo",
... ...
@@ -461,14 +477,16 @@ func TestValidateImageStream(t *testing.T) {
461 461
 						Kind: "DockerImage",
462 462
 						Name: "abc",
463 463
 					},
464
-					ImportPolicy: api.TagImportPolicy{Scheduled: true},
464
+					ImportPolicy:    api.TagImportPolicy{Scheduled: true},
465
+					ReferencePolicy: api.TagReferencePolicy{Type: api.SourceTagReferencePolicy},
465 466
 				},
466 467
 				"other": {
467 468
 					From: &kapi.ObjectReference{
468 469
 						Kind: "ImageStreamTag",
469 470
 						Name: "other:latest",
470 471
 					},
471
-					ImportPolicy: api.TagImportPolicy{Scheduled: true},
472
+					ImportPolicy:    api.TagImportPolicy{Scheduled: true},
473
+					ReferencePolicy: api.TagReferencePolicy{Type: api.SourceTagReferencePolicy},
472 474
 				},
473 475
 			},
474 476
 			expected: field.ErrorList{
... ...
@@ -484,7 +502,8 @@ func TestValidateImageStream(t *testing.T) {
484 484
 						Kind: "DockerImage",
485 485
 						Name: "abc@badid",
486 486
 					},
487
-					ImportPolicy: api.TagImportPolicy{Scheduled: true},
487
+					ImportPolicy:    api.TagImportPolicy{Scheduled: true},
488
+					ReferencePolicy: api.TagReferencePolicy{Type: api.SourceTagReferencePolicy},
488 489
 				},
489 490
 			},
490 491
 			expected: field.ErrorList{
... ...
@@ -500,7 +519,8 @@ func TestValidateImageStream(t *testing.T) {
500 500
 						Kind: "ImageStreamImage",
501 501
 						Name: "other@latest",
502 502
 					},
503
-					ImportPolicy: api.TagImportPolicy{Scheduled: true},
503
+					ImportPolicy:    api.TagImportPolicy{Scheduled: true},
504
+					ReferencePolicy: api.TagReferencePolicy{Type: api.SourceTagReferencePolicy},
504 505
 				},
505 506
 			},
506 507
 			expected: field.ErrorList{
... ...
@@ -516,12 +536,14 @@ func TestValidateImageStream(t *testing.T) {
516 516
 						Kind: "DockerImage",
517 517
 						Name: "abc",
518 518
 					},
519
+					ReferencePolicy: api.TagReferencePolicy{Type: api.SourceTagReferencePolicy},
519 520
 				},
520 521
 				"other": {
521 522
 					From: &kapi.ObjectReference{
522 523
 						Kind: "ImageStreamTag",
523 524
 						Name: "other:latest",
524 525
 					},
526
+					ReferencePolicy: api.TagReferencePolicy{Type: api.SourceTagReferencePolicy},
525 527
 				},
526 528
 			},
527 529
 			statusTags: map[string]api.TagEventList{
... ...
@@ -574,7 +596,7 @@ func TestValidateImageStream(t *testing.T) {
574 574
 
575 575
 		errs := ValidateImageStream(&stream)
576 576
 		if e, a := test.expected, errs; !reflect.DeepEqual(e, a) {
577
-			t.Errorf("%s: unexpected errors: %s", name, diff.ObjectDiff(e, a))
577
+			t.Errorf("%s: unexpected errors: %s", name, diff.ObjectReflectDiff(e, a))
578 578
 		}
579 579
 	}
580 580
 }
... ...
@@ -613,8 +635,9 @@ func TestValidateISTUpdate(t *testing.T) {
613 613
 			A: api.ImageStreamTag{
614 614
 				ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "foo:bar", ResourceVersion: "1", Annotations: map[string]string{"one": "two"}},
615 615
 				Tag: &api.TagReference{
616
-					From:        &kapi.ObjectReference{Kind: "DockerImage", Name: "some/other:system"},
617
-					Annotations: map[string]string{"one": "three"},
616
+					From:            &kapi.ObjectReference{Kind: "DockerImage", Name: "some/other:system"},
617
+					Annotations:     map[string]string{"one": "three"},
618
+					ReferencePolicy: api.TagReferencePolicy{Type: api.SourceTagReferencePolicy},
618 619
 				},
619 620
 			},
620 621
 			T: field.ErrorTypeInvalid,
... ...
@@ -624,7 +647,8 @@ func TestValidateISTUpdate(t *testing.T) {
624 624
 			A: api.ImageStreamTag{
625 625
 				ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "foo:bar", ResourceVersion: "1", Annotations: map[string]string{"one": "two"}},
626 626
 				Tag: &api.TagReference{
627
-					From: &kapi.ObjectReference{Kind: "DockerImage", Name: ""},
627
+					From:            &kapi.ObjectReference{Kind: "DockerImage", Name: ""},
628
+					ReferencePolicy: api.TagReferencePolicy{Type: api.SourceTagReferencePolicy},
628 629
 				},
629 630
 			},
630 631
 			T: field.ErrorTypeRequired,
... ...
@@ -634,7 +658,8 @@ func TestValidateISTUpdate(t *testing.T) {
634 634
 			A: api.ImageStreamTag{
635 635
 				ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "foo:bar", ResourceVersion: "1", Annotations: map[string]string{"one": "two"}},
636 636
 				Tag: &api.TagReference{
637
-					From: &kapi.ObjectReference{Kind: "", Name: "foo/bar:biz"},
637
+					From:            &kapi.ObjectReference{Kind: "", Name: "foo/bar:biz"},
638
+					ReferencePolicy: api.TagReferencePolicy{Type: api.SourceTagReferencePolicy},
638 639
 				},
639 640
 			},
640 641
 			T: field.ErrorTypeRequired,