@@ -20,9 +20,11 @@ import (
20
20
"io/ioutil"
21
21
"os"
22
22
"path/filepath"
23
+ "strings"
23
24
24
25
"github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3"
25
26
"github.com/operator-framework/operator-registry/pkg/lib/bundle"
27
+ corev1 "k8s.io/api/core/v1"
26
28
"sigs.k8s.io/yaml"
27
29
28
30
metricsannotations "github.com/operator-framework/operator-sdk/internal/annotations/metrics"
@@ -188,6 +190,11 @@ func (c bundleCmd) runManifests() (err error) {
188
190
c .println ("Building a ClusterServiceVersion without an existing base" )
189
191
}
190
192
193
+ relatedImages , err := c .findRelatedImages (col )
194
+ if err != nil {
195
+ return err
196
+ }
197
+
191
198
var opts []gencsv.Option
192
199
stdout := genutil .NewMultiManifestWriter (os .Stdout )
193
200
if c .stdout {
@@ -202,6 +209,7 @@ func (c bundleCmd) runManifests() (err error) {
202
209
Collector : col ,
203
210
Annotations : metricsannotations .MakeBundleObjectAnnotations (c .layout ),
204
211
ExtraServiceAccounts : c .extraServiceAccounts ,
212
+ RelatedImages : relatedImages ,
205
213
}
206
214
if err := csvGen .Generate (opts ... ); err != nil {
207
215
return fmt .Errorf ("error generating ClusterServiceVersion: %v" , err )
@@ -287,3 +295,51 @@ func (c bundleCmd) runMetadata() error {
287
295
288
296
return bundleMetadata .GenerateMetadata ()
289
297
}
298
+
299
+ // findRelatedImages looks in the controller manager's environment for images used by the operator.
300
+ func (c bundleCmd ) findRelatedImages (col * collector.Manifests ) (map [string ]string , error ) {
301
+ const relatedImagePrefix = "RELATED_IMAGE_"
302
+ env , err := c .findManagerEnvironment (col )
303
+ if err != nil {
304
+ return nil , err
305
+ }
306
+ imageNames := make (map [string ]string , len (env ))
307
+ for _ , envVar := range env {
308
+ if strings .HasPrefix (envVar .Name , relatedImagePrefix ) {
309
+ if envVar .ValueFrom != nil {
310
+ return nil , fmt .Errorf ("related images with valueFrom field unsupported, found in %s`" , envVar .Name )
311
+ }
312
+
313
+ // transforms RELATED_IMAGE_This_IS_a_cool_image to this-is-a-cool-image
314
+ name := strings .ToLower (strings .Replace (strings .TrimPrefix (envVar .Name , relatedImagePrefix ), "_" , "-" , - 1 ))
315
+ imageNames [name ] = envVar .Value
316
+ }
317
+ }
318
+
319
+ return imageNames , nil
320
+ }
321
+
322
+ // findManagerEnvironment returns the environment passed to the controller manager container.
323
+ func (c bundleCmd ) findManagerEnvironment (col * collector.Manifests ) ([]corev1.EnvVar , error ) {
324
+ const (
325
+ managerLabel = "control-plane"
326
+ managerLabelValue = "controller-manager"
327
+ managerContainerName = "manager"
328
+ )
329
+
330
+ for _ , deployment := range col .Deployments {
331
+ if val , ok := deployment .GetLabels ()[managerLabel ]; ok && val == managerLabelValue {
332
+ for _ , container := range deployment .Spec .Template .Spec .Containers {
333
+ if container .Name == managerContainerName {
334
+ return container .Env , nil
335
+ }
336
+ }
337
+
338
+ return nil , fmt .Errorf ("manager deployment does not have container named %q" , managerContainerName )
339
+ }
340
+ }
341
+
342
+ return nil , fmt .Errorf (
343
+ "could not find manager deployment, should have label %s=%s" , managerLabel , managerLabelValue ,
344
+ )
345
+ }
0 commit comments