Skip to content

Commit fb1c669

Browse files
committed
Add a way to configure a fallback policy for imageDigestSources
1. Add an install-config option to specify `sourcePolicy` that captures user's intention regarding the fallback policy when there is an error getting images from the mirror 2. Update the ImageDigestcwMirrorSet manifest with this policy. API changes were not required because this value was already present in the API. 3. Update logic to translate from deprecated `imageContentSources` to `imageDigestSources` with the new `sourcePolicy` in place. 4. Updated install-config validation and tests for this new field.
1 parent e064c5f commit fb1c669

File tree

6 files changed

+71
-3
lines changed

6 files changed

+71
-3
lines changed

data/data/install.openshift.io_installconfigs.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4335,6 +4335,14 @@ spec:
43354335
description: Source is the repository that users refer to, e.g.
43364336
in image pull specifications.
43374337
type: string
4338+
sourcePolicy:
4339+
description: |-
4340+
SourcePolicy defines the fallback policy when there is a failure pulling an
4341+
image from the mirrors.
4342+
enum:
4343+
- NeverContactSource
4344+
- AllowContactingSource
4345+
type: string
43384346
required:
43394347
- source
43404348
type: object

pkg/asset/ignition/bootstrap/registries.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func MergedMirrorSets(sources []types.ImageDigestSource) []types.ImageDigestSour
3939
func ContentSourceToDigestMirror(sources []types.ImageContentSource) []types.ImageDigestSource {
4040
digestSources := []types.ImageDigestSource{}
4141
for _, s := range sources {
42-
digestSources = append(digestSources, types.ImageDigestSource(s))
42+
digestSources = append(digestSources, types.ImageDigestSource{Source: s.Source, Mirrors: s.Mirrors})
4343
}
4444
return digestSources
4545
}

pkg/asset/manifests/imagedigestmirrorset.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"path/filepath"
66

77
"github.com/pkg/errors"
8+
"github.com/sirupsen/logrus"
89
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
910
"sigs.k8s.io/yaml"
1011

@@ -90,8 +91,8 @@ func ConvertImageDigestMirrorSet(imageDigestSources []types.ImageDigestSource) *
9091
for mi, mirror := range imageDigestSource.Mirrors {
9192
mirrors[mi] = apicfgv1.ImageMirror(mirror)
9293
}
93-
94-
imageDigestMirrorSet.Spec.ImageDigestMirrors[idsi] = apicfgv1.ImageDigestMirrors{Source: imageDigestSource.Source, Mirrors: mirrors}
94+
logrus.Debugf("SourcePolicy is %q for Source: %s", imageDigestSource.SourcePolicy, imageDigestSource.Source)
95+
imageDigestMirrorSet.Spec.ImageDigestMirrors[idsi] = apicfgv1.ImageDigestMirrors{Source: imageDigestSource.Source, Mirrors: mirrors, MirrorSourcePolicy: imageDigestSource.SourcePolicy}
9596
}
9697

9798
return imageDigestMirrorSet

pkg/types/installconfig.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,11 @@ type ImageDigestSource struct {
517517
// Mirrors is one or more repositories that may also contain the same images.
518518
// +optional
519519
Mirrors []string `json:"mirrors,omitempty"`
520+
521+
// SourcePolicy defines the fallback policy when there is a failure pulling an
522+
// image from the mirrors.
523+
// +optional
524+
SourcePolicy configv1.MirrorSourcePolicy `json:"sourcePolicy"`
520525
}
521526

522527
// CredentialsMode is the mode by which CredentialsRequests will be satisfied.

pkg/types/validation/installconfig.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,10 +1222,27 @@ func validateImageDigestSources(groups []types.ImageDigestSource, fldPath *field
12221222
continue
12231223
}
12241224
}
1225+
if group.SourcePolicy != "" {
1226+
if len(group.Mirrors) == 0 {
1227+
allErrs = append(allErrs, field.Invalid(groupf.Child("sourcePolicy"), group.SourcePolicy, "sourcePolicy cannot be configured without a mirror"))
1228+
}
1229+
if err := validateImageMirrorSourcePolicy(group.SourcePolicy); err != nil {
1230+
allErrs = append(allErrs, field.Invalid(groupf.Child("sourcePolicy"), group.SourcePolicy, err.Error()))
1231+
}
1232+
}
12251233
}
12261234
return allErrs
12271235
}
12281236

1237+
func validateImageMirrorSourcePolicy(sourcePolicy configv1.MirrorSourcePolicy) error {
1238+
switch sourcePolicy {
1239+
case configv1.NeverContactSource, configv1.AllowContactingSource:
1240+
return nil
1241+
default:
1242+
return fmt.Errorf("supported values are %q and %q", configv1.NeverContactSource, configv1.AllowContactingSource)
1243+
}
1244+
}
1245+
12291246
func validateNamedRepository(r string) error {
12301247
ref, err := dockerref.ParseNamed(r)
12311248
if err != nil {

pkg/types/validation/installconfig_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,6 +1487,43 @@ func TestValidateInstallConfig(t *testing.T) {
14871487
return c
14881488
}(),
14891489
},
1490+
{
1491+
name: "valid release image source ImageDigstSource with valid mirror and sourcePolicy",
1492+
installConfig: func() *types.InstallConfig {
1493+
c := validInstallConfig()
1494+
c.ImageDigestSources = []types.ImageDigestSource{{
1495+
Source: "quay.io/ocp/release-x.y",
1496+
Mirrors: []string{"mirror.example.com:5000"},
1497+
SourcePolicy: "NeverContactSource",
1498+
}}
1499+
return c
1500+
}(),
1501+
},
1502+
{
1503+
name: "valid release image source ImageDigstSource with no mirror and valid sourcePolicy",
1504+
installConfig: func() *types.InstallConfig {
1505+
c := validInstallConfig()
1506+
c.ImageDigestSources = []types.ImageDigestSource{{
1507+
Source: "quay.io/ocp/release-x.y",
1508+
SourcePolicy: "NeverContactSource",
1509+
}}
1510+
return c
1511+
}(),
1512+
expectedError: `^imageDigestSources\[0\]\.sourcePolicy: Invalid value: "NeverContactSource": sourcePolicy cannot be configured without a mirror$`,
1513+
},
1514+
{
1515+
name: "valid release image source ImageDigstSource with invalid sourcePolicy",
1516+
installConfig: func() *types.InstallConfig {
1517+
c := validInstallConfig()
1518+
c.ImageDigestSources = []types.ImageDigestSource{{
1519+
Source: "quay.io/ocp/release-x.y",
1520+
Mirrors: []string{"mirror.example.com:5000"},
1521+
SourcePolicy: "InvalidPolicy",
1522+
}}
1523+
return c
1524+
}(),
1525+
expectedError: `^imageDigestSources\[0\]\.sourcePolicy: Invalid value: "InvalidPolicy": supported values are "NeverContactSource" and "AllowContactingSource"$`,
1526+
},
14901527
{
14911528
name: "error out ImageContentSources and ImageDigestSources and are set at the same time",
14921529
installConfig: func() *types.InstallConfig {

0 commit comments

Comments
 (0)