Draft
Conversation
This reverts commit 91956c6.
…#9224) ### 📝 Description This PR introduces support for loading single-file artifacts, forming the first part of the Application Runtime’s single-file support and pull-at-runtime feature. It enables the MLRun CLI to download a single artifact from the artifact store into a specified target directory. This ensures that single-file artifacts are correctly materialized on a shared volume, allowing application runtimes and sidecars to initialize with the required source code. --- ### 🛠️ Changes Made Added `mlrun load-source` CLI command with options for --project, --source-uri, and --target. Example Usage: `mlrun load-source store://artifacts/my-project/handler.py -t /tmp/my_code` Implemented `load_source_code` function to: - Validate the store URI and required parameters. - Download a single-file artifact from the MLRun artifact store. - Ensure the target directory exists. - Return the full path to the downloaded file. --- ### ✅ Checklist - [x] I updated the documentation (if applicable) - [x] I have tested the changes in this PR - [ ] I confirmed whether my changes are covered by system tests - [ ] If yes, I ran all relevant system tests and ensured they passed before submitting this PR - [ ] I updated existing system tests and/or added new ones if needed to cover my changes - [ ] If I introduced a deprecation: - [ ] I followed the [Deprecation Guidelines](./DEPRECATION.md) - [ ] I updated the relevant Jira ticket for documentation --- ### 🧪 Testing Unit tests covering : - Successful loading of artifacts with and without a project. - Validation errors for missing or invalid parameters. - Assertions for correct artifact resolution, directory creation, and file download. Tested on vmdev: 1) After logging an artifact : ``` $ mlrun load-source 'store://artifacts/my-proj/my_artifact#04be5629d-a115-4d78-a6d9-7738ab909ffd^702fe0fa5c0e0e1acff5f839978db6fe1d06d67a' --target /tmp/mlrun_code Successfully loaded source to: /tmp/mlrun_code/my_artifact.txt ``` 2) Invalid artifact store : ``` $ mlrun load-source 'https://example/file.py' --target /tmp/mlrun_code Error loading source: source_uri must be a store artifact URI (store://...), got: https://example/file.py ``` 3) Artifact uri does not exist : ``` $ mlrun load-source 'store://artifacts/my-proj/wrong_uri' --target /tmp/mlrun_code Error loading source: read artifact my-proj/wrong_uri details: MLRunNotFoundError('Artifact my-proj/wrong_uri#0:latest not found'), caused by: 404 Client Error: Not Found for url: http://mlrun-api:8080/api/v2/projects/my-proj/artifacts/wrong_uri?format=full&tag=latest&iter=0 ``` --- ### 🔗 References - Ticket link: https://iguazio.atlassian.net/browse/ML-11952 - Design docs links: - External links: --- ### 🚨 Breaking Changes? - [ ] Yes (explain below) - [x] No <!-- If yes, describe what needs to be changed downstream: --> --- ### 🔍️ Additional Notes <!-- Anything else reviewers should know (follow-up tasks, known issues, affected areas etc.). --> <!-- ### 📸 Screenshots / Logs -->
### 📝 Description Bumping nuclio-jupyter to 0.13.1 as 0.13.0 was released with requirement misconfigurations bringing needless packages (twice). --- ### 🛠️ Changes Made <!-- - Key changes (e.g., added feature X, refactored Y, fixed Z) --> --- ### ✅ Checklist - [ ] I updated the documentation (if applicable) - [ ] I have tested the changes in this PR - [ ] I confirmed whether my changes are covered by system tests - [ ] If yes, I ran all relevant system tests and ensured they passed before submitting this PR - [ ] I updated existing system tests and/or added new ones if needed to cover my changes - [ ] If I introduced a deprecation: - [ ] I followed the [Deprecation Guidelines](./DEPRECATION.md) - [ ] I updated the relevant Jira ticket for documentation --- ### 🧪 Testing <!-- - How it was tested (unit tests, manual, integration) --> <!-- - Any special cases covered. --> --- ### 🔗 References - Ticket link: https://iguazio.atlassian.net/browse/ML-11972 - Design docs links: - External links: --- ### 🚨 Breaking Changes? - [ ] Yes (explain below) - [x] No <!-- If yes, describe what needs to be changed downstream: --> --- ### 🔍️ Additional Notes <!-- Anything else reviewers should know (follow-up tasks, known issues, affected areas etc.). --> <!-- ### 📸 Screenshots / Logs -->
### 📝 Description This PR fixes project state handling after saving a project to the DB by replacing a raw `__dict__` update with a controlled in-place enrichment. The enrichment preserves runtime-only fields (e.g. `spec.context`) while still updating persisted fields returned from the DB. --- ### 🛠️ Changes Made - Replace `self.__dict__.update(project.__dict__)` with `self._enrich(project)` after `save_to_db(...)` - Add unit test for `_enrich` behavior (`tests/projects/test_project.py`) - Minor system test alignment (`tests/system/projects/test_project.py`) --- ### ✅ Checklist - [ ] I updated the documentation (if applicable) - [x] I have tested the changes in this PR - [x] I confirmed whether my changes are covered by system tests - [ ] If yes, I ran all relevant system tests and ensured they passed before submitting this PR - [x] I updated existing system tests and/or added new ones if needed to cover my changes - [ ] If I introduced a deprecation: - [ ] I followed the [Deprecation Guidelines](./DEPRECATION.md) - [ ] I updated the relevant Jira ticket for documentation --- ### 🧪 Testing - UT + failing system tests --- ### 🔗 References - Ticket link: <JIRA-LINK-HERE> - Design docs links: - External links: --- ### 🚨 Breaking Changes? - [ ] Yes (explain below) - [x] No --- ### 🔍️ Additional Notes - `_enrich` is intentionally additive and avoids replacing `spec/metadata/status` objects to prevent losing runtime-only fields.
### 📝 Description <!-- A short summary of what this PR does. --> <!-- Include any relevant context or background information. --> This PR introduces a PR summary for the private release pipeline that allows to easily identify the version and previous_version to use in promotion pipeline, and ( more importantly ) it creates a tag at this stage so that we avoid race conditions ( commits between private release run and promotion run ) that could be misleading eventually. --- ### 🛠️ Changes Made <!-- - Key changes (e.g., added feature X, refactored Y, fixed Z) --> --- ### ✅ Checklist - [ ] I updated the documentation (if applicable) - [ ] I have tested the changes in this PR - [ ] I confirmed whether my changes are covered by system tests - [ ] If yes, I ran all relevant system tests and ensured they passed before submitting this PR - [ ] I updated existing system tests and/or added new ones if needed to cover my changes - [ ] If I introduced a deprecation: - [ ] I followed the [Deprecation Guidelines](./DEPRECATION.md) - [ ] I updated the relevant Jira ticket for documentation --- ### 🧪 Testing <!-- - How it was tested (unit tests, manual, integration) --> <!-- - Any special cases covered. --> --- ### 🔗 References - Ticket link: - Design docs links: - External links: --- ### 🚨 Breaking Changes? - [ ] Yes (explain below) - [ ] No <!-- If yes, describe what needs to be changed downstream: --> --- ### 🔍️ Additional Notes <!-- Anything else reviewers should know (follow-up tasks, known issues, affected areas etc.). --> <!-- ### 📸 Screenshots / Logs -->
…alls (mlrun#9233) ### 📝 Description This PR enables request context propagation across Iguazio's internal service calls by injecting the `x-igz-ctx` header into outgoing requests to Nuclio and Iguazio services. This allows for logging correlation and distributed tracing across the platform's microservices. When an incoming request contains a context ID (via `x-igz-ctx`, `igz-ctx`, or `x-request-id` headers), this context is now propagated to all downstream service calls, enabling end-to-end request tracing. --- ### 🛠️ Changes Made - Added `x-igz-ctx` and `igz-ctx` (legacy) header constants to `HeaderNames` schema - Enhanced `RequestLoggerMiddleware` to resolve context ID from multiple header sources with fallback logic - Added `inject_context_id_header()` helper method for injecting context headers into outgoing requests - Refactored `enrich_headers()` helper to centralize header enrichment (context ID + project role headers) - Updated Nuclio client, async Nuclio client, and Iguazio v3 client to use header enrichment - Fixed Iguazio v4 client to use context manager pattern (`with_headers`) instead of `set_override_auth_headers` - Bumped `iguazio` package version from `0.0.1a22` to `0.0.1a27` - Added comprehensive unit tests for context propagation --- ### ✅ Checklist - [ ] I updated the documentation (if applicable) - [x] I have tested the changes in this PR - [ ] I confirmed whether my changes are covered by system tests - [ ] If yes, I ran all relevant system tests and ensured they passed before submitting this PR - [ ] I updated existing system tests and/or added new ones if needed to cover my changes - [ ] If I introduced a deprecation: - [ ] I followed the [Deprecation Guidelines](./DEPRECATION.md) - [ ] I updated the relevant Jira ticket for documentation --- ### 🧪 Testing - Added unit tests for `inject_context_id_header()` and `enrich_headers()` methods: - Verifies header injection when context is set - Verifies existing headers are not overridden - Verifies no-op when context is not set - Added unit tests for Nuclio client context propagation: - Verifies `x-igz-ctx` header is included in requests - Verifies context propagation on project store operations - Verifies header is not present when context is unset - Added unit tests for async Nuclio client context propagation - Added unit tests for Iguazio v4 client context propagation - *Manual tests:* - Created a project in Iguazio 4 via MLRun and made sure the context is preserved: ``` Project name: 'qwe-2' Context ID: 31f4fbb11e6d6de5e2d36291fffae8eb # MLRun: [iguazio@192.168.227.64-k8s-master-node-1 ~]$ kubectl -n tomer logs deployment/mlrun-api-chief | grep qwe-2 > 2026-01-21 14:05:26,076 [debug] Received request: {"client_address":"10.42.50.35:40082","ctx":"db001ab26b1303a917be95d63ff29e09","headers":{"accept":"*/*","accept-encoding":"gzip, deflate","host":"mlrun-api.tomer.vmdev223ig4.lab.iguazeng.com","user-agent":"python-requests/2.32.5 mlrun/1.11.0-rc17","x-forwarded-for":"192.168.101.17","x-forwarded-host":"mlrun-api.tomer.vmdev223ig4.lab.iguazeng.com","x-forwarded-port":"443","x-forwarded-proto":"https","x-forwarded-scheme":"https","x-mlrun-client-python-version":"3.11.14","x-mlrun-client-version":"1.11.0-rc17","x-real-ip":"192.168.101.17","x-request-id":"db001ab26b1303a917be95d63ff29e09","x-scheme":"https"},"http_version":"1.1","method":"GET","request_id":"db001ab26b1303a917be95d63ff29e09","uri":"/api/v1/projects/qwe-2"} > 2026-01-21 14:05:26,265 [warning] Request handling returned error status: {"ctx":"db001ab26b1303a917be95d63ff29e09","error_message":"MLRunNotFoundError('Project not found: name=qwe-2, project_id=None')","request_id":"db001ab26b1303a917be95d63ff29e09","status_code":404,"traceback":"Traceback (most recent call last):\n File \"/usr/local/lib/python3.11/site-packages/starlette/_exception_handler.py\", line 42, in wrapped_app\n await app(scope, receive, sender)\n File \"/usr/local/lib/python3.11/site-packages/fastapi/routing.py\", line 110, in app\n response = await f(request)\n ^^^^^^^^^^^^^^^^\n File \"/usr/local/lib/python3.11/site-packages/fastapi/routing.py\", line 390, in app\n raw_response = await run_endpoint_function(\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/usr/local/lib/python3.11/site-packages/fastapi/routing.py\", line 289, in run_endpoint_function\n return await dependant.call(**values)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/mlrun/server/py/services/api/api/endpoints/projects.py\", line 175, in get_project\n project = await run_in_threadpool(\n ^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/usr/local/lib/python3.11/site-packages/starlette/concurrency.py\", line 38, in run_in_threadpool\n return await anyio.to_thread.run_sync(func)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/usr/local/lib/python3.11/site-packages/anyio/to_thread.py\", line 63, in run_sync\n return await get_async_backend().run_sync_in_worker_thread(\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py\", line 2502, in run_sync_in_worker_thread\n return await future\n ^^^^^^^^^^^^\n File \"/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py\", line 986, in run\n result = context.run(func, *args)\n ^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/mlrun/server/py/framework/utils/projects/leader.py\", line 138, in get_project\n return self._leader_follower.get_project(db_session, name, auth_info)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/mlrun/server/py/services/api/crud/projects.py\", line 287, in get_project\n return framework.utils.singletons.db.get_db().get_project(session, name)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/mlrun/server/py/framework/db/sqldb/db.py\", line 3469, in get_project\n project_record = self._get_project_record(session, name, project_id)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/mlrun/server/py/framework/db/sqldb/db.py\", line 4176, in _get_project_record\n raise mlrun.errors.MLRunNotFoundError(\nmlrun.errors.MLRunNotFoundError: Project not found: name=qwe-2, project_id=None\n"} > 2026-01-21 14:05:26,266 [debug] Sending response: {"ctx":"db001ab26b1303a917be95d63ff29e09","elapsed_time_in_ms":189.820315,"headers":{"accept":"*/*","accept-encoding":"gzip, deflate","host":"mlrun-api.tomer.vmdev223ig4.lab.iguazeng.com","user-agent":"python-requests/2.32.5 mlrun/1.11.0-rc17","x-forwarded-for":"192.168.101.17","x-forwarded-host":"mlrun-api.tomer.vmdev223ig4.lab.iguazeng.com","x-forwarded-port":"443","x-forwarded-proto":"https","x-forwarded-scheme":"https","x-mlrun-client-python-version":"3.11.14","x-mlrun-client-version":"1.11.0-rc17","x-real-ip":"192.168.101.17","x-request-id":"db001ab26b1303a917be95d63ff29e09","x-scheme":"https"},"method":"GET","request_id":"db001ab26b1303a917be95d63ff29e09","status_code":404,"uri":"/api/v1/projects/qwe-2"} > 2026-01-21 14:05:26,428 [debug] Creating project: {"artifact_amount":0,"created_time":null,"ctx":"31f4fbb11e6d6de5e2d36291fffae8eb","desired_state":"online","function_amount":0,"name":"qwe-2","owner":null,"state":"online","workflows_amount":0} > 2026-01-21 14:05:26,428 [debug] Creating project in DB: {"ctx":"31f4fbb11e6d6de5e2d36291fffae8eb","project_name":"qwe-2"} > 2026-01-21 14:05:26,607 [debug] Creating project in Nuclio: {"ctx":"31f4fbb11e6d6de5e2d36291fffae8eb","project":{"kind":"project","metadata":{"annotations":{},"created":"2026-01-21T14:05:26.428592+00:00","labels":{},"name":"qwe-2"},"spec":{"artifact_path":null,"artifacts":[],"build":null,"conda":"","custom_packagers":null,"default_function_node_selector":{},"default_image":null,"description":null,"desired_state":"online","functions":[],"goals":null,"origin_url":null,"owner":null,"params":{},"source":"","subpath":null,"workflows":[]},"status":{"state":"online"}}} # Nuclio: [iguazio@192.168.227.64-k8s-master-node-1 ~]$ kubectl -n tomer logs deployment/nuclio-dashboard | grep qwe-2 Defaulted container "nuclio-dashboard" out of: nuclio-dashboard, nuclio-opa-server {"level":"debug","time":"2026-01-21T14:05:27.151Z","name":"dashboard.server.api/projects","message":"Creating project","requestID":"31f4fbb11e6d6de5e2d36291fffae8eb","more":{"newProject":{"meta":{"name":"qwe-2","namespace":"tomer"},"spec":{},"status":{}}}} {"level":"debug","time":"2026-01-21T14:05:27.151Z","name":"dashboard.platform","message":"Creating project","requestID":"31f4fbb11e6d6de5e2d36291fffae8eb","more":{"projectName":"qwe-2"}} {"level":"debug","time":"2026-01-21T14:05:28.167Z","name":"dashboard.server.api/projects","message":"Successfully created project","requestID":"31f4fbb11e6d6de5e2d36291fffae8eb","more":{"attributes":{"metadata":{"name":"qwe-2","namespace":"tomer"},"spec":{"owner":"admin"},"status":{}},"id":""}} # Orca: [iguazio@192.168.227.64-k8s-master-node-1 ~]$ kubectl -n tomer logs deployment/igz-identity | grep qwe-2 Defaulted container "igz-identity" out of: igz-identity, opa-server {"level":"info","time":"2026-01-21T14:05:26.454Z","name":"daemon.authorization","message":"Received create default project policies request","ctx":"31f4fbb11e6d6de5e2d36291fffae8eb","more":{"project":"qwe-2"}} {"level":"info","time":"2026-01-21T14:05:26.456Z","name":"daemon.authorization.projectsCrud","message":"Creating project policies and assigning owner","ctx":"31f4fbb11e6d6de5e2d36291fffae8eb","more":{"project":"qwe-2"}} {"level":"debug","time":"2026-01-21T14:05:26.604Z","name":"daemon.authorization.projectsCrud","message":"Successfully created project policies","ctx":"31f4fbb11e6d6de5e2d36291fffae8eb","more":{"project":"qwe-2"}} {"level":"info","time":"2026-01-21T14:05:26.604Z","name":"daemon.authorization","message":"Returning create default project policies response","ctx":"31f4fbb11e6d6de5e2d36291fffae8eb","more":{"project":"qwe-2"}} ``` --- ### 🔗 References - Ticket link: https://iguazio.atlassian.net/browse/IG4-1185 - Reference PRs: - iguazio/orca#473 - iguazio/orca#477 - nuclio/nuclio#3971 --- ### 🚨 Breaking Changes? - [ ] Yes (explain below) - [x] No --- ### 🔍️ Additional Notes - The `iguazio` package version bump to `0.0.1a27` is required for the `with_headers` context manager support in the Iguazio client - The Iguazio v4 client was refactored to use the context manager pattern instead of `set_override_auth_headers` for cleaner and more thread-safe header injection
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
just for finding differences.