Repository navigation
feat(spark): check control plane version ConfigMap (#221) - #846
Neha-Nimsatkar wants to merge 6 commits into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
/ok-to-test |
RobuRishabh
left a comment
There was a problem hiding this comment.
Hi @Neha-Nimsatkar, Thanks for the contribution. I have left some questions about the ConfigMap deployment and a test-strengthening suggestion. PTAL
| warnings, call_count = _run_verify_backend_with_core_api(core_api) | ||
| combined = "\n".join(warnings) | ||
|
|
||
| assert call_count >= 1 |
There was a problem hiding this comment.
Could this assert the exact API request rather than only checking that some call occurred? The current test would still pass if the implementation used the wrong ConfigMap name, wrong namespace, or performed duplicate reads. Please consider assert_called_once_with(name="kubeflow-spark-public", namespace="kubeflow-system") and add a case covering the KUBEFLOW_SYSTEM_NAMESPACE override.
Hi @RobuRishabh, Thanks for the feedback! I made this PR by following Trainer PR #250 (577cba2). In that PR:
Your suggestions regarding adding a request timeout, testing the exact call arguments, and testing the (KUBEFLOW_SYSTEM_NAMESPACE) override make total sense and strengthen the implementation. I just have two questions:
Would appreciate your thoughts before I push the changes..... |
|
Also, the kubeflow-spark-public ConfigMap and its RBAC permissions are being added upstream in kubeflow/spark-operator#3225 (mirroring how Trainer introduced its producer upstream prior to the SDK check). |
|
From today's community call the decision was to use one namespace env var per component ( Please also raise a PR in http://github.com/kubeflow/pipelines to add a version check in the Let me know if there are any further questions. |
dd3bac1 to
abd9433
Compare
Thanks for the review! I’ve updated the PR with those suggestions:
|
b1cef65 to
abd9433
Compare
| system_namespace = utils.get_component_namespace( | ||
| common_constants.KUBEFLOW_SPARK_NAMESPACE_ENV_VAR, | ||
| default="kubeflow", | ||
| ) |
There was a problem hiding this comment.
In the community call it was decided the env-var naming, but not the default and kubeflow doesn't match either side of the contract:
- The Trainer mirror defaults to
kubeflow-system - The operator chart creates
kubeflow-spark-publicin the release namespace by default, notkubeflow.
So a plain Helm install of the operator with publicConfigMap.create=true puts the ConfigMap in e.g. spark-operator, the SDK looks in kubeflow, and every healthy install logs a spurious warning. That turns the feature into noise out of the box. So now can we align the default with the operator-side contract before this ships?
There was a problem hiding this comment.
I think you can pick kubeflow-system as the canonical default.
- SDK: default="kubeflow-system" to match Trainer.
- Chart: default
publicConfigMap.namespacetokubeflow-systemwhencreate=true, or at minimum document "setKUBEFLOW_SPARK_NAMESPACE=<release-ns>" right next to the publicConfigMap values in the chart README.
But there will be a tradeoff that's standalone operator installs (no Kubeflow platform) must createkubeflow-systemor override both the chart value and the env var. That's the same friction Trainer already accepts.
There was a problem hiding this comment.
Makes sense to me as well. If the default is chosen to be kubeflow-system the expectation on the spark operator opt-in would be to deploy the configmap in the kubeflow-system namespace.
@Neha-Nimsatkar Please update the docs in the repo to reflect this assumption.
| warnings.warn( | ||
| f"{constants.KUBEFLOW_SYSTEM_NAMESPACE_ENV_VAR} is deprecated. " | ||
| f"Please use {component_env_var} instead.", | ||
| DeprecationWarning, | ||
| stacklevel=2, |
There was a problem hiding this comment.
Two small things on the deprecation path:
DeprecationWarningis filtered out by default for library consumers, so most users will never see the migration notice. I'd useUserWarning(orFutureWarning) so the decided nudge actually reaches people.- Transition hazard: A user who follows this warning and switches to
KUBEFLOW_SPARK_NAMESPACEmight breaks their Trainer client. I think we should either sequence Trainer's adoption of this helper in the same release cycle, or soften the message to mention both vars are read during the transition.
and accordingly update the PR description
There was a problem hiding this comment.
I think it makes sense to update the PR to include Trainer support as well. So KUBEFLOW_SYSTEM_NAMESPACE_ENV_VAR can be marked as deprecated for Trainer as well (but still supported for this release cycle) and KUBEFLOW_TRAINER_NAMESPACE_ENV_VAR becomes the supported mechanism for Trainer going forward.
| print("test execution complete") | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( |
There was a problem hiding this comment.
The mocked CoreV1Api returns data for any name/namespace, and we only assert call_count >= 1 so a typo in "kubeflow-spark-public" or a wrong namespace would still pass. Could we assert read_namespaced_config_map.call_args.kwargs for both name and namespace?
Also, the env-var resolution is tested against get_component_namespace directly, but never through verify_backend with ``KUBEFLOW_SPARK_NAMESPACE` set, one backend-level case would prove the wiring.
|
Hi @RobuRishabh, I've addressed the feedback and updated the PR description and pushed the latest changes. All unit tests and pre-commit checks are passing cleanly. PTAL when you get a chance! |
There was a problem hiding this comment.
just quick nit Helper's own default is "kubeflow", but the only production caller passes "kubeflow-system" explicitly. So a caller (Trainer/Pipelines migration) that forgets the default kwarg silently gets kubeflow a footgun the tests won't catch. So maybe make default a required parameter, or align it to kubeflow-system.
Thanks for catching this @RobuRishabh . I have aligned the default parameter in get_component_namespace and its corresponding unit test to "kubeflow-system". |
| # Environment variables for Kubeflow component control plane namespaces. | ||
| KUBEFLOW_SYSTEM_NAMESPACE_ENV_VAR = "KUBEFLOW_SYSTEM_NAMESPACE" | ||
| KUBEFLOW_SPARK_NAMESPACE_ENV_VAR = "KUBEFLOW_SPARK_NAMESPACE" | ||
| KUBEFLOW_TRAINER_NAMESPACE_ENV_VAR = "KUBEFLOW_TRAINER_NAMESPACE" |
There was a problem hiding this comment.
Please also update Trainer to use this constant.
| KUBEFLOW_SYSTEM_NAMESPACE_ENV_VAR = "KUBEFLOW_SYSTEM_NAMESPACE" | ||
| KUBEFLOW_SPARK_NAMESPACE_ENV_VAR = "KUBEFLOW_SPARK_NAMESPACE" | ||
| KUBEFLOW_TRAINER_NAMESPACE_ENV_VAR = "KUBEFLOW_TRAINER_NAMESPACE" | ||
| KUBEFLOW_PIPELINES_NAMESPACE_ENV_VAR = "KUBEFLOW_PIPELINES_NAMESPACE" |
There was a problem hiding this comment.
The Pipelines constant should be removed. It belongs in the KFP repo.
| system_namespace = utils.get_component_namespace( | ||
| common_constants.KUBEFLOW_SPARK_NAMESPACE_ENV_VAR, | ||
| default="kubeflow", | ||
| ) |
There was a problem hiding this comment.
Makes sense to me as well. If the default is chosen to be kubeflow-system the expectation on the spark operator opt-in would be to deploy the configmap in the kubeflow-system namespace.
@Neha-Nimsatkar Please update the docs in the repo to reflect this assumption.
| warnings.warn( | ||
| f"{constants.KUBEFLOW_SYSTEM_NAMESPACE_ENV_VAR} is deprecated. " | ||
| f"Please use {component_env_var} instead.", | ||
| DeprecationWarning, | ||
| stacklevel=2, |
There was a problem hiding this comment.
I think it makes sense to update the PR to include Trainer support as well. So KUBEFLOW_SYSTEM_NAMESPACE_ENV_VAR can be marked as deprecated for Trainer as well (but still supported for this release cycle) and KUBEFLOW_TRAINER_NAMESPACE_ENV_VAR becomes the supported mechanism for Trainer going forward.
fce50aa to
a34b82d
Compare
…zation Signed-off-by: Neha Nimsatkar <1492neha@gmail.com>
…lution in backend tests Signed-off-by: Neha Nimsatkar <1492neha@gmail.com>
Signed-off-by: Neha Nimsatkar <1492neha@gmail.com>
Signed-off-by: Neha Nimsatkar <1492neha@gmail.com>
…EFLOW_SYSTEM_NAMESPACE Signed-off-by: Neha Nimsatkar <1492neha@gmail.com>
a34b82d to
3cd9f8c
Compare
|
Thank you @tariq-hasan , All review feedback has been addressed, and CI is now fully passing. |
tariq-hasan
left a comment
There was a problem hiding this comment.
I have a few minor comments otherwise lgtm from me.
| def test_verify_backend_respects_trainer_namespace_env_var(monkeypatch): | ||
| """Test that verify_backend uses KUBEFLOW_TRAINER_NAMESPACE when set.""" | ||
| monkeypatch.setenv(common_constants.KUBEFLOW_TRAINER_NAMESPACE_ENV_VAR, "custom-trainer-ns") | ||
| core_api = _build_core_api_mock({"kubeflow_trainer_version": "1.0.0"}) | ||
|
|
||
| _, call_count = _run_verify_backend_with_core_api(core_api) | ||
|
|
||
| assert call_count == 1 | ||
| core_api.read_namespaced_config_map.assert_called_with( | ||
| name="kubeflow-trainer-public", | ||
| namespace="custom-trainer-ns", | ||
| ) |
There was a problem hiding this comment.
Please bundle this test as a test case under test_verify_backend.
There was a problem hiding this comment.
Thanks, @tariq-hasan . Bundled this as a parameterized test case under test_verify_backend and verified all tests pass.
|
|
||
| # ------------------------------------------------------------------ | ||
| # Spark Connect sessions | ||
| # ------------------------------------------------------------------ | ||
|
|
There was a problem hiding this comment.
Please move this header below the verify_backend method.
There was a problem hiding this comment.
Moved the section header below verify_backend.
Signed-off-by: Neha Nimsatkar <1492neha@gmail.com>
|
Thanks! Please rebase once #930 merges to pass all the E2E tests. |
|
I think along with rebase we need to pin Spark Operator to the last working commit |
| return os.environ[component_env_var] | ||
|
|
||
| if os.getenv(constants.KUBEFLOW_SYSTEM_NAMESPACE_ENV_VAR): | ||
| warnings.warn( |
There was a problem hiding this comment.
one small nit the deprecation warning can become an exception when warnings are treated as errors. change it to DeprecationWarning so it does not break Spark or Trainer backend initialization.
I've pinned to the latest commit in #930 so a rebase would do now. |
What this PR does / why we need it
Implements control-plane version check during Spark backend/client initialization, validating the
kubeflow-spark-publicConfigMap in the control-plane namespace.To support modular namespace overrides across Kubeflow components, this PR introduces a shared
get_component_namespaceutility inkubeflow/common. The helper resolves namespaces by prioritizing component-specific variables (KUBEFLOW_SPARK_NAMESPACE/KUBEFLOW_TRAINER_NAMESPACE), falling back to the deprecatedKUBEFLOW_SYSTEM_NAMESPACEwith aUserWarning, and defaulting tokubeflow-system. Both Spark and Trainer backends have been aligned to this shared resolution pattern.Fixes #221
Changes
kubeflow/commonget_component_namespace(component_env_var: str, default: str = "kubeflow-system") -> strinkubeflow/common/utils.pywith fallback and deprecation warning handling.kubeflow/common/utils_test.pycovering precedence hierarchy, environment overrides, and warning assertions.kubeflow/sparkverify_backend()toKubernetesBackendinkubeflow/spark/backends/kubernetes/backend.pyand invoked it during backend__init__.kubeflow-spark-publicConfigMap forkubeflow_spark_versionwithout blocking initialization or raising unhandled exceptions on read failure.docs/source/spark/index.rstto documentKUBEFLOW_SPARK_NAMESPACEand fallback order.kubeflow/spark/backends/kubernetes/backend_test.pyenforcing strict mock assertions (assert_called_withfor name and namespace) and verifying env-var wiring.kubeflow/trainerverify_backend()inkubeflow/trainer/backends/kubernetes/backend.pyto usecommon_utils.get_component_namespacewithKUBEFLOW_TRAINER_NAMESPACE_ENV_VAR.test_verify_backend_respects_trainer_namespace_env_varinkubeflow/trainer/backends/kubernetes/backend_test.pyto assert custom trainer namespace resolution and mock arguments.Verification
pre-commit run --all-files).