@@ -51,8 +51,9 @@ type AlternativeImage struct {
5151
5252type Container struct {
5353 * corev1.Container
54- IsInit bool
55- Images []AlternativeImage
54+ IsInit bool
55+ Images []AlternativeImage
56+ Alternatives map [string ]struct {}
5657}
5758
5859var _ webhook.CustomDefaulter = & PodCustomDefaulter {}
@@ -70,6 +71,29 @@ func (d *PodCustomDefaulter) Default(ctx context.Context, obj runtime.Object) er
7071
7172 log .Info ("defaulting for Pod" )
7273
74+ containers := make ([]Container , 0 , len (pod .Spec .Containers )+ len (pod .Spec .InitContainers ))
75+ for i := range pod .Spec .Containers {
76+ containers = append (containers , Container {
77+ Container : & pod .Spec .Containers [i ],
78+ Alternatives : map [string ]struct {}{},
79+ })
80+ }
81+ for i := range pod .Spec .InitContainers {
82+ containers = append (containers , Container {
83+ Container : & pod .Spec .InitContainers [i ],
84+ IsInit : true ,
85+ Alternatives : map [string ]struct {}{},
86+ })
87+ }
88+
89+ var cismList kuikv1alpha1.ClusterImageSetMirrorList
90+ if err := d .List (ctx , & cismList ); err != nil {
91+ return err
92+ }
93+ var ismList kuikv1alpha1.ImageSetMirrorList
94+ if err := d .List (ctx , & ismList ); err != nil {
95+ return err
96+ }
7397 var crisList kuikv1alpha1.ClusterReplicatedImageSetList
7498 if err := d .List (ctx , & crisList ); err != nil {
7599 return err
@@ -79,6 +103,20 @@ func (d *PodCustomDefaulter) Default(ctx context.Context, obj runtime.Object) er
79103 return err
80104 }
81105
106+ imageSetMirrors := make ([]kuikv1alpha1.ImageSetMirror , 0 , len (cismList .Items ))
107+ for _ , cism := range cismList .Items {
108+ imageSetMirrors = append (imageSetMirrors , kuikv1alpha1.ImageSetMirror {
109+ ObjectMeta : cism .ObjectMeta ,
110+ Spec : kuikv1alpha1 .ImageSetMirrorSpec (cism .Spec ),
111+ })
112+ }
113+ for _ , ism := range ismList .Items {
114+ if ism .Namespace != pod .Namespace {
115+ continue
116+ }
117+ imageSetMirrors = append (imageSetMirrors , ism )
118+ }
119+
82120 replicatedImageSets := make ([]kuikv1alpha1.ReplicatedImageSet , 0 , len (crisList .Items ))
83121 for _ , cris := range crisList .Items {
84122 replicatedImageSets = append (replicatedImageSets , kuikv1alpha1.ReplicatedImageSet {
@@ -93,19 +131,6 @@ func (d *PodCustomDefaulter) Default(ctx context.Context, obj runtime.Object) er
93131 replicatedImageSets = append (replicatedImageSets , ris )
94132 }
95133
96- containers := make ([]Container , 0 , len (pod .Spec .Containers )+ len (pod .Spec .InitContainers ))
97- for i := range pod .Spec .Containers {
98- containers = append (containers , Container {
99- Container : & pod .Spec .Containers [i ],
100- })
101- }
102- for i := range pod .Spec .InitContainers {
103- containers = append (containers , Container {
104- Container : & pod .Spec .InitContainers [i ],
105- IsInit : true ,
106- })
107- }
108-
109134 podCredentialSecrets := make ([]* kuikv1alpha1.CredentialSecret , 0 , len (pod .Spec .ImagePullSecrets ))
110135 for _ , imagePullSecret := range pod .Spec .ImagePullSecrets {
111136 podCredentialSecrets = append (podCredentialSecrets , & kuikv1alpha1.CredentialSecret {
@@ -115,7 +140,6 @@ func (d *PodCustomDefaulter) Default(ctx context.Context, obj runtime.Object) er
115140 }
116141
117142 podImagePullSecrets := make ([]corev1.Secret , len (podCredentialSecrets ))
118-
119143 for i , podCredentialSecret := range podCredentialSecrets {
120144 objectKey := client.ObjectKey {Namespace : podCredentialSecret .Namespace , Name : podCredentialSecret .Name }
121145 if err := d .Get (ctx , objectKey , & podImagePullSecrets [i ]); err != nil {
@@ -127,9 +151,30 @@ func (d *PodCustomDefaulter) Default(ctx context.Context, obj runtime.Object) er
127151 }
128152 }
129153
154+ for _ , ism := range imageSetMirrors {
155+ matcher := regexp .MustCompile (ism .Spec .ImageMatcher )
156+
157+ for i := range containers {
158+ container := & containers [i ]
159+ if ! matcher .MatchString (container .Image ) {
160+ continue
161+ }
162+
163+ container .Images = make ([]AlternativeImage , 0 , 1 + len (ism .Spec .Mirrors ))
164+ container .addAlternative (container .Image )
165+
166+ _ , imgPath , err := internal .RegistryAndPathFromReference (container .Image )
167+ if err != nil {
168+ return err
169+ }
170+
171+ for _ , mirror := range ism .Spec .Mirrors {
172+ container .addAlternative (path .Join (mirror .Registry , mirror .Path , imgPath ))
173+ }
174+ }
175+ }
176+
130177 for _ , container := range containers {
131- container .Images = []AlternativeImage {}
132- imagesIndex := map [string ]int {}
133178 for _ , ris := range replicatedImageSets {
134179 index := slices .IndexFunc (ris .Spec .Upstreams , func (upstream kuikv1alpha1.ReplicatedUpstream ) bool {
135180 // TODO: use a validating admission policy to ensure the regexp is valid
@@ -146,14 +191,8 @@ func (d *PodCustomDefaulter) Default(ctx context.Context, obj runtime.Object) er
146191
147192 for _ , upstream := range ris .Spec .Upstreams {
148193 reference := path .Join (upstream .Registry , upstream .Path , suffix )
149- if _ , ok := imagesIndex [reference ]; ok {
150- continue // don't add the same image twice
151- }
152- imagesIndex [reference ] = len (container .Images )
153- container .Images = append (container .Images , AlternativeImage {
154- Reference : reference ,
155- // TODO: handle using CredentialSecret from upstream configuration
156- })
194+ // TODO: handle using CredentialSecret from upstream configuration
195+ container .addAlternative (reference )
157196 }
158197 }
159198
@@ -203,3 +242,12 @@ func (d *PodCustomDefaulter) checkImageAvailability(ctx context.Context, referen
203242
204243 return err == nil , nil
205244}
245+
246+ func (c * Container ) addAlternative (reference string ) {
247+ if _ , ok := c .Alternatives [reference ]; ok {
248+ return
249+ }
250+
251+ c .Alternatives [reference ] = struct {}{}
252+ c .Images = append (c .Images , AlternativeImage {Reference : reference })
253+ }
0 commit comments