From 384777882a4f01b41a3a3dbdaa8d53ac222ade33 Mon Sep 17 00:00:00 2001 From: Pat O'Connor Date: Mon, 1 Sep 2025 12:29:03 +0100 Subject: [PATCH] task(RHOAIENG-33045): Update Runtime image SHAs for PY312 Signed-off-by: Pat O'Connor --- .github/workflows/e2e_tests.yaml | 2 +- .../additional-demos/hf_interactive.ipynb | 3 +- .../additional-demos/local_interactive.ipynb | 1 + .../additional-demos/ray_job_client.ipynb | 1 + demo-notebooks/guided-demos/0_basic_ray.ipynb | 1 + .../guided-demos/1_cluster_job_client.ipynb | 1 + .../guided-demos/2_basic_interactive.ipynb | 1 + .../guided-demos/3_widget_example.ipynb | 1 + .../notebook-ex-outputs/0_basic_ray.ipynb | 1 + .../1_cluster_job_client.ipynb | 1 + .../2_basic_interactive.ipynb | 1 + .../preview_nbs/0_basic_ray.ipynb | 1 + .../preview_nbs/1_cluster_job_client.ipynb | 1 + .../preview_nbs/2_basic_interactive.ipynb | 1 + src/codeflare_sdk/common/utils/constants.py | 15 +++++- .../common/utils/unit_test_support.py | 7 +-- src/codeflare_sdk/common/utils/utils.py | 46 +++++++++++++++++++ .../ray/cluster/build_ray_cluster.py | 17 +++---- .../ray/cluster/test_build_ray_cluster.py | 3 +- tests/e2e/local_interactive_sdk_kind_test.py | 4 +- tests/e2e/support.py | 6 ++- 21 files changed, 94 insertions(+), 21 deletions(-) create mode 100644 src/codeflare_sdk/common/utils/utils.py diff --git a/.github/workflows/e2e_tests.yaml b/.github/workflows/e2e_tests.yaml index d66e4b34..ba59a9e1 100644 --- a/.github/workflows/e2e_tests.yaml +++ b/.github/workflows/e2e_tests.yaml @@ -57,7 +57,7 @@ jobs: - name: Set up specific Python version uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.12' cache: 'pip' # caching pip dependencies - name: Setup NVidia GPU environment for KinD diff --git a/demo-notebooks/additional-demos/hf_interactive.ipynb b/demo-notebooks/additional-demos/hf_interactive.ipynb index 2e8e36fb..2f0334dc 100644 --- a/demo-notebooks/additional-demos/hf_interactive.ipynb +++ b/demo-notebooks/additional-demos/hf_interactive.ipynb @@ -70,7 +70,8 @@ "\n", "NOTE: The default images used by the CodeFlare SDK for creating a RayCluster resource depend on the installed Python version:\n", "\n", - "- For Python 3.11: 'quay.io/modh/ray:2.35.0-py311-cu121'\n", + "- For Python 3.11: 'quay.io/modh/ray:2.47.1-py311-cu121'\n", + "- For Python 3.12: 'quay.io/modh/ray:2.47.1-py312-cu121'\n", "\n", "If you prefer to use a custom Ray image that better suits your needs, you can specify it in the image field to override the default." ] diff --git a/demo-notebooks/additional-demos/local_interactive.ipynb b/demo-notebooks/additional-demos/local_interactive.ipynb index fb1cb3ea..d1318103 100644 --- a/demo-notebooks/additional-demos/local_interactive.ipynb +++ b/demo-notebooks/additional-demos/local_interactive.ipynb @@ -38,6 +38,7 @@ "NOTE: The default images used by the CodeFlare SDK for creating a RayCluster resource depend on the installed Python version:\n", "\n", "- For Python 3.11: 'quay.io/modh/ray:2.47.1-py311-cu121'\n", + "- For Python 3.12: 'quay.io/modh/ray:2.47.1-py312-cu121'\n", "\n", "If you prefer to use a custom Ray image that better suits your needs, you can specify it in the image field to override the default." ] diff --git a/demo-notebooks/additional-demos/ray_job_client.ipynb b/demo-notebooks/additional-demos/ray_job_client.ipynb index 39cf2a16..11689a1b 100644 --- a/demo-notebooks/additional-demos/ray_job_client.ipynb +++ b/demo-notebooks/additional-demos/ray_job_client.ipynb @@ -44,6 +44,7 @@ "NOTE: The default images used by the CodeFlare SDK for creating a RayCluster resource depend on the installed Python version:\n", "\n", "- For Python 3.11: 'quay.io/modh/ray:2.47.1-py311-cu121'\n", + "- For Python 3.12: 'quay.io/modh/ray:2.47.1-py312-cu121'\n", "\n", "If you prefer to use a custom Ray image that better suits your needs, you can specify it in the image field to override the default." ] diff --git a/demo-notebooks/guided-demos/0_basic_ray.ipynb b/demo-notebooks/guided-demos/0_basic_ray.ipynb index 413d31b4..7d35107d 100644 --- a/demo-notebooks/guided-demos/0_basic_ray.ipynb +++ b/demo-notebooks/guided-demos/0_basic_ray.ipynb @@ -50,6 +50,7 @@ "NOTE: The default images used by the CodeFlare SDK for creating a RayCluster resource depend on the installed Python version:\n", "\n", "- For Python 3.11: 'quay.io/modh/ray:2.47.1-py311-cu121'\n", + "- For Python 3.12: 'quay.io/modh/ray:2.47.1-py312-cu121'\n", "\n", "If you prefer to use a custom Ray image that better suits your needs, you can specify it in the image field to override the default." ] diff --git a/demo-notebooks/guided-demos/1_cluster_job_client.ipynb b/demo-notebooks/guided-demos/1_cluster_job_client.ipynb index 5a825b55..0c0b3488 100644 --- a/demo-notebooks/guided-demos/1_cluster_job_client.ipynb +++ b/demo-notebooks/guided-demos/1_cluster_job_client.ipynb @@ -44,6 +44,7 @@ "NOTE: The default images used by the CodeFlare SDK for creating a RayCluster resource depend on the installed Python version:\n", "\n", "- For Python 3.11: 'quay.io/modh/ray:2.47.1-py311-cu121'\n", + "- For Python 3.12: 'quay.io/modh/ray:2.47.1-py312-cu121'\n", "\n", "If you prefer to use a custom Ray image that better suits your needs, you can specify it in the image field to override the default." ] diff --git a/demo-notebooks/guided-demos/2_basic_interactive.ipynb b/demo-notebooks/guided-demos/2_basic_interactive.ipynb index 80f45f13..71d6b78e 100644 --- a/demo-notebooks/guided-demos/2_basic_interactive.ipynb +++ b/demo-notebooks/guided-demos/2_basic_interactive.ipynb @@ -47,6 +47,7 @@ "NOTE: The default images used by the CodeFlare SDK for creating a RayCluster resource depend on the installed Python version:\n", "\n", "- For Python 3.11: 'quay.io/modh/ray:2.47.1-py311-cu121'\n", + "- For Python 3.12: 'quay.io/modh/ray:2.47.1-py312-cu121'\n", "\n", "If you prefer to use a custom Ray image that better suits your needs, you can specify it in the image field to override the default." ] diff --git a/demo-notebooks/guided-demos/3_widget_example.ipynb b/demo-notebooks/guided-demos/3_widget_example.ipynb index d09271c9..28ad43f6 100644 --- a/demo-notebooks/guided-demos/3_widget_example.ipynb +++ b/demo-notebooks/guided-demos/3_widget_example.ipynb @@ -50,6 +50,7 @@ "NOTE: The default images used by the CodeFlare SDK for creating a RayCluster resource depend on the installed Python version:\n", "\n", "- For Python 3.11: 'quay.io/modh/ray:2.47.1-py311-cu121'\n", + "- For Python 3.12: 'quay.io/modh/ray:2.47.1-py312-cu121'\n", "\n", "If you prefer to use a custom Ray image that better suits your needs, you can specify it in the image field to override the default." ] diff --git a/demo-notebooks/guided-demos/notebook-ex-outputs/0_basic_ray.ipynb b/demo-notebooks/guided-demos/notebook-ex-outputs/0_basic_ray.ipynb index e5972711..21631288 100644 --- a/demo-notebooks/guided-demos/notebook-ex-outputs/0_basic_ray.ipynb +++ b/demo-notebooks/guided-demos/notebook-ex-outputs/0_basic_ray.ipynb @@ -50,6 +50,7 @@ "NOTE: The default images used by the CodeFlare SDK for creating a RayCluster resource depend on the installed Python version:\n", "\n", "- For Python 3.11: 'quay.io/modh/ray:2.47.1-py311-cu121'\n", + "- For Python 3.12: 'quay.io/modh/ray:2.47.1-py312-cu121'\n", "\n", "If you prefer to use a custom Ray image that better suits your needs, you can specify it in the image field to override the default." ] diff --git a/demo-notebooks/guided-demos/notebook-ex-outputs/1_cluster_job_client.ipynb b/demo-notebooks/guided-demos/notebook-ex-outputs/1_cluster_job_client.ipynb index 9b34da9b..44546a94 100644 --- a/demo-notebooks/guided-demos/notebook-ex-outputs/1_cluster_job_client.ipynb +++ b/demo-notebooks/guided-demos/notebook-ex-outputs/1_cluster_job_client.ipynb @@ -44,6 +44,7 @@ "NOTE: The default images used by the CodeFlare SDK for creating a RayCluster resource depend on the installed Python version:\n", "\n", "- For Python 3.11: 'quay.io/modh/ray:2.47.1-py311-cu121'\n", + "- For Python 3.12: 'quay.io/modh/ray:2.47.1-py312-cu121'\n", "\n", "If you prefer to use a custom Ray image that better suits your needs, you can specify it in the image field to override the default." ] diff --git a/demo-notebooks/guided-demos/notebook-ex-outputs/2_basic_interactive.ipynb b/demo-notebooks/guided-demos/notebook-ex-outputs/2_basic_interactive.ipynb index db1560ff..35daa0ff 100644 --- a/demo-notebooks/guided-demos/notebook-ex-outputs/2_basic_interactive.ipynb +++ b/demo-notebooks/guided-demos/notebook-ex-outputs/2_basic_interactive.ipynb @@ -47,6 +47,7 @@ "NOTE: The default images used by the CodeFlare SDK for creating a RayCluster resource depend on the installed Python version:\n", "\n", "- For Python 3.11: 'quay.io/modh/ray:2.47.1-py311-cu121'\n", + "- For Python 3.12: 'quay.io/modh/ray:2.47.1-py312-cu121'\n", "\n", "If you prefer to use a custom Ray image that better suits your needs, you can specify it in the image field to override the default." ] diff --git a/demo-notebooks/guided-demos/preview_nbs/0_basic_ray.ipynb b/demo-notebooks/guided-demos/preview_nbs/0_basic_ray.ipynb index e5972711..21631288 100644 --- a/demo-notebooks/guided-demos/preview_nbs/0_basic_ray.ipynb +++ b/demo-notebooks/guided-demos/preview_nbs/0_basic_ray.ipynb @@ -50,6 +50,7 @@ "NOTE: The default images used by the CodeFlare SDK for creating a RayCluster resource depend on the installed Python version:\n", "\n", "- For Python 3.11: 'quay.io/modh/ray:2.47.1-py311-cu121'\n", + "- For Python 3.12: 'quay.io/modh/ray:2.47.1-py312-cu121'\n", "\n", "If you prefer to use a custom Ray image that better suits your needs, you can specify it in the image field to override the default." ] diff --git a/demo-notebooks/guided-demos/preview_nbs/1_cluster_job_client.ipynb b/demo-notebooks/guided-demos/preview_nbs/1_cluster_job_client.ipynb index 6b913142..1d752f6a 100644 --- a/demo-notebooks/guided-demos/preview_nbs/1_cluster_job_client.ipynb +++ b/demo-notebooks/guided-demos/preview_nbs/1_cluster_job_client.ipynb @@ -44,6 +44,7 @@ "NOTE: The default images used by the CodeFlare SDK for creating a RayCluster resource depend on the installed Python version:\n", "\n", "- For Python 3.11: 'quay.io/modh/ray:2.47.1-py311-cu121'\n", + "- For Python 3.12: 'quay.io/modh/ray:2.47.1-py312-cu121'\n", "\n", "If you prefer to use a custom Ray image that better suits your needs, you can specify it in the image field to override the default." ] diff --git a/demo-notebooks/guided-demos/preview_nbs/2_basic_interactive.ipynb b/demo-notebooks/guided-demos/preview_nbs/2_basic_interactive.ipynb index a7ebae08..1c099cfd 100644 --- a/demo-notebooks/guided-demos/preview_nbs/2_basic_interactive.ipynb +++ b/demo-notebooks/guided-demos/preview_nbs/2_basic_interactive.ipynb @@ -47,6 +47,7 @@ "NOTE: The default images used by the CodeFlare SDK for creating a RayCluster resource depend on the installed Python version:\n", "\n", "- For Python 3.11: 'quay.io/modh/ray:2.47.1-py311-cu121'\n", + "- For Python 3.12: 'quay.io/modh/ray:2.47.1-py312-cu121'\n", "\n", "If you prefer to use a custom Ray image that better suits your needs, you can specify it in the image field to override the default." ] diff --git a/src/codeflare_sdk/common/utils/constants.py b/src/codeflare_sdk/common/utils/constants.py index 9721ac85..d380dcc0 100644 --- a/src/codeflare_sdk/common/utils/constants.py +++ b/src/codeflare_sdk/common/utils/constants.py @@ -1,3 +1,14 @@ RAY_VERSION = "2.47.1" -# Below references ray:2.47.1-py311-cu121 -CUDA_RUNTIME_IMAGE = "quay.io/modh/ray@sha256:6d076aeb38ab3c34a6a2ef0f58dc667089aa15826fa08a73273c629333e12f1e" +""" +The below are used to define the default runtime image for the Ray Cluster. +* For python 3.11:ray:2.47.1-py311-cu121 +* For python 3.12:ray:2.47.1-py312-cu121 +""" +CUDA_PY311_RUNTIME_IMAGE = "quay.io/modh/ray@sha256:6d076aeb38ab3c34a6a2ef0f58dc667089aa15826fa08a73273c629333e12f1e" +CUDA_PY312_RUNTIME_IMAGE = "quay.io/modh/ray@sha256:23860dfe2e47bb69709b3883b08fd1a4d836ce02eaf8d0afeeafe6986d0fc8fb" + +# Centralized image selection +SUPPORTED_PYTHON_VERSIONS = { + "3.11": CUDA_PY311_RUNTIME_IMAGE, + "3.12": CUDA_PY312_RUNTIME_IMAGE, +} diff --git a/src/codeflare_sdk/common/utils/unit_test_support.py b/src/codeflare_sdk/common/utils/unit_test_support.py index b382ec01..653e818c 100644 --- a/src/codeflare_sdk/common/utils/unit_test_support.py +++ b/src/codeflare_sdk/common/utils/unit_test_support.py @@ -15,6 +15,7 @@ import string import sys from codeflare_sdk.common.utils import constants +from codeflare_sdk.common.utils.utils import get_ray_image_for_python_version from codeflare_sdk.ray.cluster.cluster import ( Cluster, ClusterConfiguration, @@ -69,7 +70,7 @@ def create_cluster_wrong_type(): worker_extended_resource_requests={"nvidia.com/gpu": 7}, appwrapper=True, image_pull_secrets=["unit-test-pull-secret"], - image=constants.CUDA_RUNTIME_IMAGE, + image=constants.CUDA_PY312_RUNTIME_IMAGE, write_to_file=True, labels={1: 1}, ) @@ -294,8 +295,8 @@ def apply_template(yaml_file_path, variables): def get_expected_image(): - # TODO: Select image based on Python version - return constants.CUDA_RUNTIME_IMAGE + # Use centralized image selection logic (fallback to 3.12 for test consistency) + return get_ray_image_for_python_version(warn_on_unsupported=True) def get_template_variables(): diff --git a/src/codeflare_sdk/common/utils/utils.py b/src/codeflare_sdk/common/utils/utils.py new file mode 100644 index 00000000..f876e924 --- /dev/null +++ b/src/codeflare_sdk/common/utils/utils.py @@ -0,0 +1,46 @@ +# Copyright 2025 IBM, Red Hat +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import sys + +from codeflare_sdk.common.utils.constants import ( + SUPPORTED_PYTHON_VERSIONS, + CUDA_PY312_RUNTIME_IMAGE, +) + + +def get_ray_image_for_python_version(python_version=None, warn_on_unsupported=True): + """ + Get the appropriate Ray image for a given Python version. + If no version is provided, uses the current runtime Python version. + This prevents us needing to hard code image versions for tests. + + Args: + python_version: Python version string (e.g. "3.11"). If None, detects current version. + warn_on_unsupported: If True, warns and returns None for unsupported versions. + If False, silently falls back to Python 3.12 image. + """ + if python_version is None: + python_version = f"{sys.version_info.major}.{sys.version_info.minor}" + + if python_version in SUPPORTED_PYTHON_VERSIONS: + return SUPPORTED_PYTHON_VERSIONS[python_version] + elif warn_on_unsupported: + import warnings + + warnings.warn( + f"No default Ray image defined for {python_version}. Please provide your own image or use one of the following python versions: {', '.join(SUPPORTED_PYTHON_VERSIONS.keys())}." + ) + return None + else: + return CUDA_PY312_RUNTIME_IMAGE diff --git a/src/codeflare_sdk/ray/cluster/build_ray_cluster.py b/src/codeflare_sdk/ray/cluster/build_ray_cluster.py index 92cefef4..e8b68919 100644 --- a/src/codeflare_sdk/ray/cluster/build_ray_cluster.py +++ b/src/codeflare_sdk/ray/cluster/build_ray_cluster.py @@ -21,6 +21,7 @@ from ...common.kubernetes_cluster import get_api_client, config_check from kubernetes.client.exceptions import ApiException from ...common.utils.constants import RAY_VERSION +from ...common.utils.utils import get_ray_image_for_python_version import codeflare_sdk import os @@ -95,9 +96,8 @@ ), ] -SUPPORTED_PYTHON_VERSIONS = { - "3.11": constants.CUDA_RUNTIME_IMAGE, -} +# Use centralized mapping from constants (so that we only have to update constants.py) +SUPPORTED_PYTHON_VERSIONS = constants.SUPPORTED_PYTHON_VERSIONS # RayCluster/AppWrapper builder function @@ -272,16 +272,11 @@ def with_nb_annotations(annotations: dict): def update_image(image) -> str: """ The update_image() function automatically sets the image config parameter to a preset image based on Python version if not specified. - If no Ray image exists for the given Python version a warning is produced. + This now points to the centralized function in utils.py. """ if not image: - python_version = f"{sys.version_info.major}.{sys.version_info.minor}" - if python_version in SUPPORTED_PYTHON_VERSIONS: - image = SUPPORTED_PYTHON_VERSIONS[python_version] - else: - warnings.warn( - f"No default Ray image defined for {python_version}. Please provide your own image or use one of the following python versions: {', '.join(SUPPORTED_PYTHON_VERSIONS.keys())}." - ) + # Pull the image based on the matching Python version (or output a warning if not supported) + image = get_ray_image_for_python_version(warn_on_unsupported=True) return image diff --git a/src/codeflare_sdk/ray/cluster/test_build_ray_cluster.py b/src/codeflare_sdk/ray/cluster/test_build_ray_cluster.py index 6d322b5f..f970d945 100644 --- a/src/codeflare_sdk/ray/cluster/test_build_ray_cluster.py +++ b/src/codeflare_sdk/ray/cluster/test_build_ray_cluster.py @@ -43,6 +43,7 @@ def test_update_image_without_supported_python_version(mocker): "codeflare_sdk.ray.cluster.build_ray_cluster.SUPPORTED_PYTHON_VERSIONS", { "3.11": "ray-py3.11", + "3.12": "ray-py3.12", }, ) @@ -60,7 +61,7 @@ def test_update_image_without_supported_python_version(mocker): # Assert that the warning was called with the expected message warn_mock.assert_called_once_with( - "No default Ray image defined for 3.8. Please provide your own image or use one of the following python versions: 3.11." + "No default Ray image defined for 3.8. Please provide your own image or use one of the following python versions: 3.11, 3.12." ) # Assert that no image was set since the Python version is not supported diff --git a/tests/e2e/local_interactive_sdk_kind_test.py b/tests/e2e/local_interactive_sdk_kind_test.py index 0f5fd93f..1dd8a2e0 100644 --- a/tests/e2e/local_interactive_sdk_kind_test.py +++ b/tests/e2e/local_interactive_sdk_kind_test.py @@ -115,7 +115,9 @@ def heavy_calculation(num_iterations): ref = heavy_calculation.remote(3000) result = ray.get(ref) - assert result == 1789.4644387076714 + assert ( + result == 1789.4644387076728 + ) # Updated result after moving to Python 3.12 (0.0000000000008% difference to old assertion) ray.cancel(ref) ray.shutdown() diff --git a/tests/e2e/support.py b/tests/e2e/support.py index 165a680b..fe9261a2 100644 --- a/tests/e2e/support.py +++ b/tests/e2e/support.py @@ -8,6 +8,7 @@ _kube_api_error_handling, ) from codeflare_sdk.common.utils import constants +from codeflare_sdk.common.utils.utils import get_ray_image_for_python_version def get_ray_cluster(cluster_name, namespace): @@ -27,7 +28,10 @@ def get_ray_cluster(cluster_name, namespace): def get_ray_image(): - return os.getenv("RAY_IMAGE", constants.CUDA_RUNTIME_IMAGE) + return os.getenv( + "RAY_IMAGE", + get_ray_image_for_python_version(warn_on_unsupported=False), + ) def get_setup_env_variables(**kwargs):