Skip to content

Commit 82a6c92

Browse files
authored
feat: support configuring multiple catalog index images [RHIDP-12935] (#2717)
* feat: support configuring multiple catalog index images Currently the operator only supports a single catalog index image (CATALOG_INDEX_IMAGE), which limits users who need to load plugin configurations from multiple sources. This adds support for a new EXTRA_CATALOG_INDEX_IMAGES env var on the install-dynamic-plugins init container, accepting a comma-separated list of entries in either name=image_ref or plain image_ref format. For disconnected environments, RELATED_IMAGE_extra_catalog_index_{name} env vars on the controller are collected at reconciliation time and forwarded as EXTRA_CATALOG_INDEX_IMAGES using the name=image_ref format. User-specified extraEnvs or deployment patches take precedence, matching the existing CATALOG_INDEX_IMAGE behavior. Ref: RHIDP-12935 Assisted-by: Claude * Apply suggestions from code review Co-authored-by: Armel Soro <armel@rm3l.org> * fix: preserve env var declaration order in EXTRA_CATALOG_INDEX_IMAGES The install-dynamic-plugins container processes extra catalog index images in order, so sorting them alphabetically could change behavior. Drop the sort and preserve the order in which the RELATED_IMAGE_extra_catalog_index_* env vars are declared. Ref: RHIDP-12935 Assisted-by: Claude * chore: bump catalog index image to 1.10 and add community placeholder Update RELATED_IMAGE_catalog_index to point to the 1.10 tag. Add a commented-out RELATED_IMAGE_extra_catalog_index_community entry for when a community catalog index image becomes available. Ref: RHIDP-12935 Assisted-by: Claude * docs: document RELATED_IMAGE_extra_catalog_index_* and clarify ordering The order of entries in EXTRA_CATALOG_INDEX_IMAGES is determined by the OS and not guaranteed. Update code comments, tests, and docs to reflect this instead of claiming declaration order is preserved. Assisted-by: Claude * Apply suggestions from code review Co-authored-by: Armel Soro <armel@rm3l.org> * Apply suggestion from @rm3l * refactor: remove RELATED_IMAGE_catalog_index and RELATED_IMAGE_extra_catalog_index handling While listing related images in the CSV can serve as a bill of materials of all images the operator needs (consumable by tools like oc-mirror or security scanners), plugin catalog index images are a special case: they are not pulled by the Kubelet but directly by skopeo from inside the install-dynamic-plugins script. This means that in disconnected environments, having them automatically mirrored by oc-mirror would not work out of the box, since ImageContentSourcePolicy, ImageDigestMirrorSet or ImageTagMirrorSet resources have no effect on skopeo pulls. To avoid confusion, we rely on the separate plugin mirroring script and docs for handling plugin and catalog index image mirroring. Assisted-by: Claude * fixup! refactor: remove RELATED_IMAGE_catalog_index and RELATED_IMAGE_extra_catalog_index handling * docs: document catalog index image mirroring in disconnected environments Assisted-by: Claude * Apply suggestion from @rm3l
1 parent 4c2ddbe commit 82a6c92

12 files changed

Lines changed: 45 additions & 122 deletions

File tree

.rhdh/docs/mirror-dynamic-plugins.adoc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,17 @@ After mirroring completes, the script generates a `rhdh-plugin-mirroring-summary
121121

122122
To use the mirrored plugins in RHDH, you need to configure container registry mirroring so that RHDH transparently pulls plugins from your mirror registry instead of the original source registries. This is done by mounting a custom `registries.conf` (and `policy.json` if needed) as extra files into the RHDH init container, as depicted in the sections below. See link:../../examples/plugin-mirroring.yaml[examples/plugin-mirroring.yaml] for a CR example.
123123

124+
[#_catalog_index_image_mirroring]
125+
==== Catalog index image mirroring
126+
127+
When `--plugin-index` is used, the script mirrors the plugin catalog index image itself in addition to the individual plugin artifacts. The mirrored location is included in the generated `rhdh-plugin-mirroring-summary.txt` file.
128+
129+
If you configure transparent registry mirroring via `registries.conf` (as described in <<_creating_registry_mirroring_configmap>>), no additional RHDH configuration is needed -- the catalog index image will be pulled from the mirror automatically.
130+
131+
Alternatively, you can explicitly point RHDH to the mirrored catalog index images by setting `CATALOG_INDEX_IMAGE` and/or `EXTRA_CATALOG_INDEX_IMAGES` environment variables on the `install-dynamic-plugins` init container (see link:../../docs/dynamic-plugins.md#extra-catalog-index-images[Extra catalog index images]). This can be done via `extraEnvs` in the Backstage CR (when using the RHDH Operator) or via `upstream.backstage.initContainers.env` in Helm values (when using the RHDH Helm chart). However, this should not be necessary when `registries.conf` is properly configured for transparent mirroring.
132+
133+
NOTE: Unlike container images pulled by the Kubelet, plugin catalog index images are pulled directly by `skopeo` from inside the `install-dynamic-plugins` init container. This means that cluster-level mirroring resources (`ImageContentSourcePolicy`, `ImageDigestMirrorSet`, `ImageTagMirrorSet`) have no effect. You should use the `registries.conf`-based approach described here.
134+
124135
[#_creating_registry_mirroring_configmap]
125136
==== Creating the registry mirroring ConfigMap
126137

bundle/backstage.io/manifests/backstage-operator.clusterserviceversion.yaml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bundle/rhdh/manifests/backstage-operator.clusterserviceversion.yaml

Lines changed: 1 addition & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bundle/rhdh/manifests/rhdh-default-config_v1_configmap.yaml

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/profile/rhdh/default-config/deployment.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ spec:
6868
value: /opt/app-root/src/.npmrc.dynamic-plugins/.npmrc
6969
- name: MAX_ENTRY_SIZE
7070
value: "30000000"
71-
# CATALOG_INDEX_IMAGE will be replaced by the value of the `RELATED_IMAGE_catalog_index` env var, if set
7271
- name: CATALOG_INDEX_IMAGE
7372
value: "quay.io/rhdh/plugin-catalog-index:1.9"
7473
- name: CATALOG_ENTITIES_EXTRACT_DIR

config/profile/rhdh/patches/deployment-patch.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ spec:
2828
value: quay.io/fedora/postgresql-15:latest
2929
- name: RELATED_IMAGE_backstage
3030
value: quay.io/rhdh-community/rhdh:next
31-
- name: RELATED_IMAGE_catalog_index
32-
value: quay.io/rhdh/plugin-catalog-index:1.9
3331
volumeMounts:
3432
- mountPath: /default-config/flavours/lightspeed
3533
name: flavour-lightspeed-config

dist/rhdh/install.yaml

Lines changed: 0 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/dynamic-plugins.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,31 @@ The operator supports loading default plugin configurations from an OCI containe
5050
By default, the `rhdh` profile of operator [injects](../config/profile/rhdh/patches/deployment-patch.yaml#L31-L32) the `CATALOG_INDEX_IMAGE` environment variable in the RHDH `install-dynamic-plugins` init container.
5151
To use a different catalog index image, such as a newer version or a mirrored image, use the `extraEnvs` field in your Backstage CR. See [examples/catalog-index.yaml](../examples/catalog-index.yaml) for a complete example.
5252

53+
### Extra catalog index images
54+
55+
In addition to the primary catalog index image, you can configure extra catalog index images using the `EXTRA_CATALOG_INDEX_IMAGES` environment variable. This allows loading plugin configurations from multiple catalog index images. See [Using extra catalog index images](https://github.com/redhat-developer/rhdh/blob/main/docs/dynamic-plugins/installing-plugins.md#using-extra-catalog-index-images) for more details on how RHDH handles this environment variables.
56+
57+
The value is a comma-separated list of entries. Each entry supports two forms:
58+
- **`name=image_ref`**: Assigns an explicit name to the catalog index image, which controls the extraction subdirectory under `/extensions/extra/<name>/`.
59+
- **`image_ref`**: A direct image reference without a name; the extraction directory is auto-generated from the image reference.
60+
61+
To configure extra catalog index images, use the `extraEnvs` field in your Backstage CR:
62+
63+
```yaml
64+
apiVersion: rhdh.redhat.com/v1alpha6
65+
kind: Backstage
66+
metadata:
67+
name: my-backstage
68+
spec:
69+
application:
70+
extraEnvs:
71+
envs:
72+
- name: EXTRA_CATALOG_INDEX_IMAGES
73+
value: "rhdh-community=quay.io/rhdh-community/plugin-catalog-index:1.10,registry.example.com/rhdh-catalog:latest"
74+
containers:
75+
- install-dynamic-plugins
76+
```
77+
5378
### Extensions Catalog Entities
5479

5580
Starting from version 1.9, the `rhdh` profile of the operator instructs the RHDH `install-dynamic-plugins` init container to extract catalog entities from the catalog index image to a new `/extensions` volume mount by default.

examples/catalog-index.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,15 @@ spec:
66
application:
77
extraEnvs:
88
envs:
9+
# Override the primary catalog index image
910
- name: CATALOG_INDEX_IMAGE
1011
value: "quay.io/rhdh/plugin-catalog-index:1.9"
1112
containers:
1213
- install-dynamic-plugins
14+
## Optional: add extra catalog index images (comma-separated, supports name=image_ref or image_ref format).
15+
# See https://github.com/redhat-developer/rhdh/blob/main/docs/dynamic-plugins/installing-plugins.md#using-extra-catalog-index-images for more details.
16+
#- name: EXTRA_CATALOG_INDEX_IMAGES
17+
# value: "rhdh-community=quay.io/rhdh-community/plugin-catalog-index:1.10,internal=registry.example.com/rhdh-catalog:latest"
18+
# containers:
19+
# - install-dynamic-plugins
1320

pkg/model/deployment.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ const (
2929
)
3030

3131
const BackstageImageEnvVar = "RELATED_IMAGE_backstage"
32-
const CatalogIndexImageEnvVar = "RELATED_IMAGE_catalog_index"
3332
const DefaultMountDir = "/opt/app-root/src"
3433
const ExtConfigHashAnnotation = "rhdh.redhat.com/ext-config-hash"
3534

@@ -107,13 +106,6 @@ func (b *BackstageDeployment) addToModel(model *BackstageModel, backstage api.Ba
107106
b.setImage(ptr.To(os.Getenv(BackstageImageEnvVar)))
108107
}
109108

110-
// Set CATALOG_INDEX_IMAGE from operator env var BEFORE extraEnvs are applied, so user-specified extraEnvs can still override this value
111-
if catalogIndexImage := os.Getenv(CatalogIndexImageEnvVar); catalogIndexImage != "" {
112-
if i, _ := DynamicPluginsInitContainer(b.podSpec().InitContainers); i >= 0 {
113-
b.setOrAppendEnvVar(&b.podSpec().InitContainers[i], "CATALOG_INDEX_IMAGE", catalogIndexImage)
114-
}
115-
}
116-
117109
if err := b.setDeployment(backstage); err != nil {
118110
return false, err
119111
}

0 commit comments

Comments
 (0)