Skip to content

Commit 97bd623

Browse files
[CLOUDP-352109] Run MCK E2E tests against OCI published helm chart (#509)
# Summary As part of our work to move towards OCI compatible container registries for our helm chart, we are also planning to run our E2E tests against the helm chart that we publish to OCI. This will make sure that we are testing in our E2E what we are providing to our customers. As part of this effort we have already [raised a PR](#507) that starts publishing our helm chart to the OCI container registry during dev/staging workflows. This PR goes and changes our E2E tests to start consuming the helm chart from OCI registry instead of the local helm chart repo. Additional unrelated change is to fix `kubectl-mongodb` location that is used for gke code snippets. The fix is to add missing `workdir` path suffix. ## Proof of Work Successful CI on this PR. I also ran the test `e2e_replica_set_migration` locally and it was successful. The logs are [here](https://gist.github.com/viveksinghggits/1b6403ffd43d53759a1714aa9cf04f30). `publish_helm_chart` example output: ``` [2025/11/05 22:11:19.857] Running command 'subprocess.exec' in function 'publish_helm_chart' (step 7 of 7). [2025/11/05 22:11:19.919] INFO 2025-11-05 21:11:19,919 [publish_helm_chart] Packaging chart: mongodb-kubernetes with Version: 0.0.0+690bbc0f836fbf0007154375 [2025/11/05 22:11:19.959] INFO 2025-11-05 21:11:19,959 [publish_helm_chart] Successfully executed: helm package --version 0.0.0+690bbc0f836fbf0007154375 helm_chart [2025/11/05 22:11:19.959] INFO 2025-11-05 21:11:19,959 [publish_helm_chart] Successfully packaged chart and saved it to: /data/mci/55da5d1be5488b41a9ec4e7d02041a86/src/github.com/mongodb/mongodb-kubernetes/mongodb-kubernetes-0.0.0+690bbc0f836fbf0007154375.tgz [2025/11/05 22:11:19.959] INFO 2025-11-05 21:11:19,959 [publish_helm_chart] Determined OCI Registry: oci://268558157000.dkr.ecr.us-east-1.amazonaws.com/dev/mongodb/helm-charts [2025/11/05 22:11:19.959] INFO 2025-11-05 21:11:19,959 [publish_helm_chart] Pushing chart to registry: oci://268558157000.dkr.ecr.us-east-1.amazonaws.com/dev/mongodb/helm-charts [2025/11/05 22:11:20.848] INFO 2025-11-05 21:11:20,848 [publish_helm_chart] Successfully executed: helm push mongodb-kubernetes-0.0.0+690bbc0f836fbf0007154375.tgz oci://268558157000.dkr.ecr.us-east-1.amazonaws.com/dev/mongodb/helm-charts [2025/11/05 22:11:20.848] INFO 2025-11-05 21:11:20,848 [publish_helm_chart] Helm Chart mongodb-kubernetes:0.0.0+690bbc0f836fbf0007154375 was published successfully! [2025/11/05 22:11:20.858] Finished command 'subprocess.exec' in function 'publish_helm_chart' (step 7 of 7) in 1.001053371s. ``` Downloading the chart with `helm pull oci://268558157000.dkr.ecr.us-east-1.amazonaws.com/dev/mongodb/helm-charts/mongodb-kubernetes --untar --version 0.0.0+690bbc0f836fbf0007154375` you can see that the `Chart.yaml` version was properly updated: ```yaml apiVersion: v2 description: 'MongoDB Controllers for Kubernetes translate the human knowledge of creating a MongoDB instance into a scalable, repeatable, and standardized method. ' home: https://github.com/mongodb/mongodb-kubernetes icon: https://mongodb-images-new.s3.eu-west-1.amazonaws.com/leaf-green-dark.png keywords: - mongodb - database - nosql kubeVersion: '>=1.16-0' maintainers: - email: [email protected] name: MongoDB name: mongodb-kubernetes type: application version: 0.0.0+690bbc0f836fbf0007154375 ``` Also [run release](https://evergreen.mongodb.com/version/690cf486c59aec0007dd2ba4?redirect_spruce_users=true) test and e2e smoke tests are also passing (ignore `ibm_power`, they are fixed in #573) ## Checklist - [x] Have you linked a jira ticket and/or is the ticket in the title? - [x] Have you checked whether your jira ticket required DOCSP changes? - [x] Have you added changelog file? - use `skip-changelog` label if not needed - refer to [Changelog files and Release Notes](https://github.com/mongodb/mongodb-kubernetes/blob/master/CONTRIBUTING.md#changelog-files-and-release-notes) section in CONTRIBUTING.md for more details --------- Co-authored-by: Maciej Karaś <[email protected]>
1 parent 102501c commit 97bd623

File tree

19 files changed

+291
-81
lines changed

19 files changed

+291
-81
lines changed

.evergreen-release.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ buildvariants:
214214
depends_on:
215215
- name: release_kubectl_mongodb_plugin
216216
variant: release_kubectl_mongodb_plugin
217+
- name: release_chart_to_oci_registry
218+
variant: release_chart_to_oci_registry
217219
tasks:
218220
- name: build_test_image
219221

@@ -228,6 +230,8 @@ buildvariants:
228230
depends_on:
229231
- name: release_kubectl_mongodb_plugin
230232
variant: release_kubectl_mongodb_plugin
233+
- name: release_chart_to_oci_registry
234+
variant: release_chart_to_oci_registry
231235
tasks:
232236
- name: build_test_image_ibm_power
233237

@@ -245,6 +249,8 @@ buildvariants:
245249
depends_on:
246250
- name: release_kubectl_mongodb_plugin
247251
variant: release_kubectl_mongodb_plugin
252+
- name: release_chart_to_oci_registry
253+
variant: release_chart_to_oci_registry
248254
tasks:
249255
- name: build_test_image_ibm_z
250256

@@ -258,6 +264,8 @@ buildvariants:
258264
depends_on:
259265
- name: release_kubectl_mongodb_plugin
260266
variant: release_kubectl_mongodb_plugin
267+
- name: release_chart_to_oci_registry
268+
variant: release_chart_to_oci_registry
261269
tasks:
262270
- name: build_test_image_arm
263271

.evergreen.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ variables:
3737
variant: init_test_run
3838
- name: build_init_om_images_ubi
3939
variant: init_test_run
40+
- name: publish_helm_chart
41+
variant: init_test_run
4042

4143
- &base_no_om_image_dependency
4244
depends_on:
@@ -54,6 +56,8 @@ variables:
5456
variant: init_test_run
5557
- name: build_init_appdb_images_ubi
5658
variant: init_test_run
59+
- name: publish_helm_chart
60+
variant: init_test_run
5761

5862
- &community_dependency
5963
depends_on:
@@ -67,6 +71,8 @@ variables:
6771
variant: init_test_run
6872
- name: build_mco_test_image
6973
variant: init_test_run
74+
- name: publish_helm_chart
75+
variant: init_test_run
7076

7177
- &setup_group
7278
setup_group_can_fail_task: true
@@ -138,6 +144,8 @@ variables:
138144
variant: init_test_run
139145
- name: build_init_om_images_ubi
140146
variant: init_test_run
147+
- name: publish_helm_chart
148+
variant: init_test_run
141149

142150
- &base_om7_dependency_with_race
143151
depends_on:
@@ -155,6 +163,8 @@ variables:
155163
variant: init_test_run
156164
- name: build_init_om_images_ubi
157165
variant: init_test_run
166+
- name: publish_helm_chart
167+
variant: init_test_run
158168

159169
# Any change to base_om8_dependency should be reflected to its copy in .evergreen-snippets.yml
160170
- &base_om8_dependency
@@ -173,6 +183,8 @@ variables:
173183
variant: init_test_run
174184
- name: build_init_om_images_ubi
175185
variant: init_test_run
186+
- name: publish_helm_chart
187+
variant: init_test_run
176188

177189
parameters:
178190
- key: evergreen_retry
@@ -1305,6 +1317,8 @@ buildvariants:
13051317
variant: init_test_run
13061318
- name: build_init_database_image_ubi
13071319
variant: init_test_run
1320+
- name: publish_helm_chart
1321+
variant: init_test_run
13081322

13091323
tasks:
13101324
- name: e2e_custom_domain_task_group
@@ -1442,6 +1456,8 @@ buildvariants:
14421456
variant: init_test_run
14431457
- name: build_test_image_ibm_power
14441458
variant: init_test_run_ibm_power
1459+
- name: publish_helm_chart
1460+
variant: init_test_run
14451461
tasks:
14461462
- name: e2e_smoke_ibm_task_group
14471463

@@ -1461,6 +1477,8 @@ buildvariants:
14611477
variant: init_test_run
14621478
- name: build_test_image_ibm_power
14631479
variant: init_test_run_ibm_power
1480+
- name: publish_helm_chart
1481+
variant: init_test_run
14641482
tasks:
14651483
- name: e2e_smoke_ibm_task_group
14661484

@@ -1483,6 +1501,8 @@ buildvariants:
14831501
variant: init_test_run
14841502
- name: build_test_image_ibm_z
14851503
variant: init_test_run_ibm_z
1504+
- name: publish_helm_chart
1505+
variant: init_test_run
14861506
tasks:
14871507
- name: e2e_smoke_ibm_task_group
14881508

@@ -1503,6 +1523,8 @@ buildvariants:
15031523
variant: init_test_run
15041524
- name: build_test_image_ibm_z
15051525
variant: init_test_run_ibm_z
1526+
- name: publish_helm_chart
1527+
variant: init_test_run
15061528
tasks:
15071529
- name: e2e_smoke_ibm_task_group
15081530

@@ -1521,6 +1543,8 @@ buildvariants:
15211543
variant: init_test_run
15221544
- name: build_test_image_arm
15231545
variant: init_test_run_arm
1546+
- name: publish_helm_chart
1547+
variant: init_test_run
15241548
tasks:
15251549
- name: e2e_smoke_arm_task_group
15261550

@@ -1537,6 +1561,8 @@ buildvariants:
15371561
variant: init_test_run
15381562
- name: build_test_image_arm
15391563
variant: init_test_run_arm
1564+
- name: publish_helm_chart
1565+
variant: init_test_run
15401566
tasks:
15411567
- name: e2e_smoke_arm_task_group
15421568

build_info.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,12 +453,14 @@
453453
"helm-charts": {
454454
"mongodb-kubernetes": {
455455
"patch": {
456+
"version-prefix": "0.0.0+",
456457
"registry": "268558157000.dkr.ecr.us-east-1.amazonaws.com",
457458
"region": "us-east-1",
458459
"repository": "dev/mongodb/helm-charts"
459460
},
460461
"staging": {
461462
"sign": true,
463+
"version-prefix": "0.0.0+",
462464
"registry": "268558157000.dkr.ecr.us-east-1.amazonaws.com",
463465
"region": "us-east-1",
464466
"repository": "staging/mongodb/helm-charts"

docker/mongodb-kubernetes-tests/Dockerfile

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ RUN apt-get -qq update \
1616

1717
COPY requirements.txt requirements.txt
1818

19-
RUN python3 -m venv /venv && . /venv/bin/activate && pip install --upgrade pip && GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1 pip install -r requirements.txt
19+
# install aws, required to run helm registry login while running the tests
20+
RUN python3 -m venv /venv \
21+
&& . /venv/bin/activate \
22+
&& pip install --upgrade pip \
23+
&& GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1 pip install -r requirements.txt \
24+
&& pip install awscli
2025

2126
FROM scratch AS tools_downloader
2227

@@ -75,8 +80,9 @@ WORKDIR /tests
7580

7681
# copying the test files after python build, otherwise pip install will be called each time the tests change
7782
COPY . /tests
78-
# copying the helm_chart directory as well to support installation of the Operator from the test application
79-
COPY helm_chart /helm_chart
83+
# copying the helm_chart/crds directory so that we can install CRDs before installing the operator helm chart to run a test.
84+
# operator is installed via published OCI helm repo and not the local helm repo.
85+
COPY helm_chart/crds /helm_chart/crds
8086
COPY release.json /release.json
8187
# we use the public directory to automatically test resources samples
8288
COPY public /mongodb-kubernetes/public

docker/mongodb-kubernetes-tests/kubetester/helm.py

Lines changed: 90 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
11
import glob
2-
import logging
32
import os
43
import re
54
import subprocess
65
import uuid
76
from typing import Dict, List, Optional, Tuple
87

98
from tests import test_logger
9+
from tests.constants import (
10+
DEFAULT_HELM_CHART_PATH_ENV_VAR_NAME,
11+
OCI_HELM_REGION_ENV_VAR_NAME,
12+
OCI_HELM_REGISTRY_ENV_VAR_NAME,
13+
OCI_HELM_VERSION_ENV_VAR_NAME,
14+
)
1015

1116
logger = test_logger.get_test_logger(__name__)
1217

18+
# LOCAL_CRDS_DIR is the dir where local helm chart's CRDs are copied in tests image
19+
LOCAL_CRDS_DIR = "helm_chart/crds"
20+
OCI_HELM_REGISTRY_ECR = "268558157000.dkr.ecr.us-east-1.amazonaws.com"
21+
1322

1423
def helm_template(
1524
helm_args: Dict,
@@ -25,7 +34,7 @@ def helm_template(
2534
command_args.append("--show-only")
2635
command_args.append(templates)
2736

28-
args = ("helm", "template", *(command_args), helm_chart_path)
37+
args = ("helm", "template", *command_args, helm_chart_path)
2938
logger.info(" ".join(args))
3039

3140
yaml_file_name = "{}.yaml".format(str(uuid.uuid4()))
@@ -145,6 +154,55 @@ def process_run_and_check(args, **kwargs):
145154
raise
146155

147156

157+
def helm_registry_login_to_ecr(helm_registry: str, region: str):
158+
logger.info(f"Attempting to log into ECR registry: {helm_registry}, using helm registry login.")
159+
160+
aws_command = ["aws", "ecr", "get-login-password", "--region", region]
161+
162+
# as we can see the password is being provided by stdin, that would mean we will have to
163+
# pipe the aws_command (it figures out the password) into helm_command.
164+
helm_command = ["helm", "registry", "login", "--username", "AWS", "--password-stdin", helm_registry]
165+
166+
try:
167+
logger.info("Starting AWS ECR credential retrieval.")
168+
aws_proc = subprocess.Popen(
169+
aws_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True # Treat input/output as text strings
170+
)
171+
172+
logger.info("Starting Helm registry login.")
173+
helm_proc = subprocess.Popen(
174+
helm_command, stdin=aws_proc.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
175+
)
176+
177+
# Close the stdout stream of aws_proc in the parent process
178+
# to prevent resource leakage (only needed if you plan to do more processing)
179+
aws_proc.stdout.close()
180+
181+
# Wait for the Helm command (helm_proc) to finish and capture its output
182+
helm_stdout, helm_stderr = helm_proc.communicate()
183+
184+
# Wait for the AWS process to finish as well
185+
aws_proc.wait()
186+
187+
if aws_proc.returncode != 0:
188+
_, aws_stderr = aws_proc.communicate()
189+
raise Exception(f"aws command to get password failed. Error: {aws_stderr}")
190+
191+
if helm_proc.returncode == 0:
192+
logger.info("Login to helm registry was successful.")
193+
logger.info(helm_stdout.strip())
194+
else:
195+
raise Exception(
196+
f"Login to helm registry failed, Exit code: {helm_proc.returncode}, Error: {helm_stderr.strip()}"
197+
)
198+
199+
except FileNotFoundError as e:
200+
# This catches errors if 'aws' or 'helm' are not in the PATH
201+
raise Exception(f"Command not found. Please ensure '{e.filename}' is installed and in your system's PATH.")
202+
except Exception as e:
203+
raise Exception(f"An unexpected error occurred: {e}.")
204+
205+
148206
def helm_upgrade(
149207
name: str,
150208
namespace: str,
@@ -162,7 +220,7 @@ def helm_upgrade(
162220
chart_dir = helm_chart_path
163221

164222
if apply_crds_first:
165-
apply_crds_from_chart(chart_dir)
223+
apply_crds_from_chart(LOCAL_CRDS_DIR)
166224

167225
command_args = _create_helm_args(helm_args, helm_options)
168226
args = [
@@ -183,11 +241,11 @@ def helm_upgrade(
183241
process_run_and_check(command, check=True, capture_output=True, shell=True)
184242

185243

186-
def apply_crds_from_chart(chart_dir: str):
187-
crd_files = glob.glob(os.path.join(chart_dir, "crds", "*.yaml"))
244+
def apply_crds_from_chart(crds_dir: str):
245+
crd_files = glob.glob(os.path.join(crds_dir, "*.yaml"))
188246

189247
if not crd_files:
190-
raise Exception(f"No CRD files found in chart directory: {chart_dir}")
248+
raise Exception(f"No CRD files found in chart directory: {crds_dir}")
191249

192250
logger.info(f"Found {len(crd_files)} CRD files to apply:")
193251

@@ -230,3 +288,29 @@ def _create_helm_args(helm_args: Dict[str, str], helm_options: Optional[List[str
230288
command_args.extend(helm_options)
231289

232290
return command_args
291+
292+
293+
# helm_chart_path_and_version returns the chart path and version that we would like to install to run the E2E tests.
294+
# for local tests it returns early with local helm chart dir and for other scenarios it figures out the chart and version
295+
# based on the caller. In most of the cases we will install chart from OCI registry but for the tests where we would like
296+
# to install MEKO's specific version or MCK's specific version, we would expect `helm_chart_path` to set already.
297+
def helm_chart_path_and_version(helm_chart_path: str, operator_version: str) -> tuple[str, str]:
298+
# if helm_chart_path is not passed, use the default value from DEFAULT_HELM_CHART_PATH
299+
if not helm_chart_path:
300+
helm_chart_path = os.getenv(DEFAULT_HELM_CHART_PATH_ENV_VAR_NAME)
301+
302+
if helm_chart_path.startswith("oci://"):
303+
# If operator_version is not passed, we want to install the current version.
304+
if not operator_version:
305+
operator_version = os.environ.get(OCI_HELM_VERSION_ENV_VAR_NAME)
306+
307+
registry = os.environ.get(OCI_HELM_REGISTRY_ENV_VAR_NAME)
308+
# If ECR we need to login first to the OCI container registry
309+
if registry == OCI_HELM_REGISTRY_ECR:
310+
region = os.environ.get(OCI_HELM_REGION_ENV_VAR_NAME)
311+
try:
312+
helm_registry_login_to_ecr(registry, region)
313+
except Exception as e:
314+
raise Exception(f"Failed to login to ECR helm registry {registry}. Error: {e}")
315+
316+
return helm_chart_path, operator_version

0 commit comments

Comments
 (0)