mlrun 1.3.3__py3-none-any.whl → 1.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mlrun might be problematic. Click here for more details.
- mlrun/__init__.py +3 -3
- mlrun/__main__.py +79 -37
- mlrun/api/__init__.py +1 -1
- mlrun/api/api/__init__.py +1 -1
- mlrun/api/api/api.py +4 -4
- mlrun/api/api/deps.py +10 -21
- mlrun/api/api/endpoints/__init__.py +1 -1
- mlrun/api/api/endpoints/artifacts.py +64 -36
- mlrun/api/api/endpoints/auth.py +4 -4
- mlrun/api/api/endpoints/background_tasks.py +11 -11
- mlrun/api/api/endpoints/client_spec.py +5 -5
- mlrun/api/api/endpoints/clusterization_spec.py +6 -4
- mlrun/api/api/endpoints/feature_store.py +124 -115
- mlrun/api/api/endpoints/files.py +22 -14
- mlrun/api/api/endpoints/frontend_spec.py +28 -21
- mlrun/api/api/endpoints/functions.py +142 -87
- mlrun/api/api/endpoints/grafana_proxy.py +89 -442
- mlrun/api/api/endpoints/healthz.py +20 -7
- mlrun/api/api/endpoints/hub.py +320 -0
- mlrun/api/api/endpoints/internal/__init__.py +1 -1
- mlrun/api/api/endpoints/internal/config.py +1 -1
- mlrun/api/api/endpoints/internal/memory_reports.py +9 -9
- mlrun/api/api/endpoints/logs.py +11 -11
- mlrun/api/api/endpoints/model_endpoints.py +74 -70
- mlrun/api/api/endpoints/operations.py +13 -9
- mlrun/api/api/endpoints/pipelines.py +93 -88
- mlrun/api/api/endpoints/projects.py +35 -35
- mlrun/api/api/endpoints/runs.py +69 -27
- mlrun/api/api/endpoints/runtime_resources.py +28 -28
- mlrun/api/api/endpoints/schedules.py +98 -41
- mlrun/api/api/endpoints/secrets.py +37 -32
- mlrun/api/api/endpoints/submit.py +12 -12
- mlrun/api/api/endpoints/tags.py +20 -22
- mlrun/api/api/utils.py +251 -42
- mlrun/api/constants.py +1 -1
- mlrun/api/crud/__init__.py +18 -15
- mlrun/api/crud/artifacts.py +10 -10
- mlrun/api/crud/client_spec.py +4 -4
- mlrun/api/crud/clusterization_spec.py +3 -3
- mlrun/api/crud/feature_store.py +54 -46
- mlrun/api/crud/functions.py +3 -3
- mlrun/api/crud/hub.py +312 -0
- mlrun/api/crud/logs.py +11 -9
- mlrun/api/crud/model_monitoring/__init__.py +3 -3
- mlrun/api/crud/model_monitoring/grafana.py +435 -0
- mlrun/api/crud/model_monitoring/model_endpoints.py +352 -129
- mlrun/api/crud/notifications.py +149 -0
- mlrun/api/crud/pipelines.py +67 -52
- mlrun/api/crud/projects.py +51 -23
- mlrun/api/crud/runs.py +7 -5
- mlrun/api/crud/runtime_resources.py +13 -13
- mlrun/api/{db/filedb → crud/runtimes}/__init__.py +1 -1
- mlrun/api/crud/runtimes/nuclio/__init__.py +14 -0
- mlrun/api/crud/runtimes/nuclio/function.py +505 -0
- mlrun/api/crud/runtimes/nuclio/helpers.py +310 -0
- mlrun/api/crud/secrets.py +88 -46
- mlrun/api/crud/tags.py +5 -5
- mlrun/api/db/__init__.py +1 -1
- mlrun/api/db/base.py +102 -54
- mlrun/api/db/init_db.py +2 -3
- mlrun/api/db/session.py +4 -12
- mlrun/api/db/sqldb/__init__.py +1 -1
- mlrun/api/db/sqldb/db.py +439 -196
- mlrun/api/db/sqldb/helpers.py +1 -1
- mlrun/api/db/sqldb/models/__init__.py +3 -3
- mlrun/api/db/sqldb/models/models_mysql.py +82 -64
- mlrun/api/db/sqldb/models/models_sqlite.py +76 -64
- mlrun/api/db/sqldb/session.py +27 -20
- mlrun/api/initial_data.py +82 -24
- mlrun/api/launcher.py +196 -0
- mlrun/api/main.py +91 -22
- mlrun/api/middlewares.py +6 -5
- mlrun/api/migrations_mysql/env.py +1 -1
- mlrun/api/migrations_mysql/versions/28383af526f3_market_place_to_hub.py +40 -0
- mlrun/api/migrations_mysql/versions/32bae1b0e29c_increase_timestamp_fields_precision.py +1 -1
- mlrun/api/migrations_mysql/versions/4903aef6a91d_tag_foreign_key_and_cascades.py +1 -1
- mlrun/api/migrations_mysql/versions/5f1351c88a19_adding_background_tasks_table.py +1 -1
- mlrun/api/migrations_mysql/versions/88e656800d6a_add_requested_logs_column_and_index_to_.py +1 -1
- mlrun/api/migrations_mysql/versions/9d16de5f03a7_adding_data_versions_table.py +1 -1
- mlrun/api/migrations_mysql/versions/b86f5b53f3d7_adding_name_and_updated_to_runs_table.py +1 -1
- mlrun/api/migrations_mysql/versions/c4af40b0bf61_init.py +1 -1
- mlrun/api/migrations_mysql/versions/c905d15bd91d_notifications.py +72 -0
- mlrun/api/migrations_mysql/versions/ee041e8fdaa0_adding_next_run_time_column_to_schedule_.py +1 -1
- mlrun/api/migrations_sqlite/env.py +1 -1
- mlrun/api/migrations_sqlite/versions/11f8dd2dc9fe_init.py +1 -1
- mlrun/api/migrations_sqlite/versions/1c954f8cb32d_schedule_last_run_uri.py +1 -1
- mlrun/api/migrations_sqlite/versions/2b6d23c715aa_adding_feature_sets.py +1 -1
- mlrun/api/migrations_sqlite/versions/4acd9430b093_market_place_to_hub.py +77 -0
- mlrun/api/migrations_sqlite/versions/6401142f2d7c_adding_next_run_time_column_to_schedule_.py +1 -1
- mlrun/api/migrations_sqlite/versions/64d90a1a69bc_adding_background_tasks_table.py +1 -1
- mlrun/api/migrations_sqlite/versions/803438ecd005_add_requested_logs_column_to_runs.py +1 -1
- mlrun/api/migrations_sqlite/versions/863114f0c659_refactoring_feature_set.py +1 -1
- mlrun/api/migrations_sqlite/versions/959ae00528ad_notifications.py +63 -0
- mlrun/api/migrations_sqlite/versions/accf9fc83d38_adding_data_versions_table.py +1 -1
- mlrun/api/migrations_sqlite/versions/b68e8e897a28_schedule_labels.py +1 -1
- mlrun/api/migrations_sqlite/versions/bcd0c1f9720c_adding_project_labels.py +1 -1
- mlrun/api/migrations_sqlite/versions/cf21882f938e_schedule_id.py +1 -1
- mlrun/api/migrations_sqlite/versions/d781f58f607f_tag_object_name_string.py +1 -1
- mlrun/api/migrations_sqlite/versions/deac06871ace_adding_marketplace_sources_table.py +1 -1
- mlrun/api/migrations_sqlite/versions/e1dd5983c06b_schedule_concurrency_limit.py +1 -1
- mlrun/api/migrations_sqlite/versions/e5594ed3ab53_adding_name_and_updated_to_runs_table.py +1 -1
- mlrun/api/migrations_sqlite/versions/f4249b4ba6fa_adding_feature_vectors.py +1 -1
- mlrun/api/migrations_sqlite/versions/f7b5a1a03629_adding_feature_labels.py +1 -1
- mlrun/api/schemas/__init__.py +216 -138
- mlrun/api/utils/__init__.py +1 -1
- mlrun/api/utils/asyncio.py +1 -1
- mlrun/api/utils/auth/__init__.py +1 -1
- mlrun/api/utils/auth/providers/__init__.py +1 -1
- mlrun/api/utils/auth/providers/base.py +7 -7
- mlrun/api/utils/auth/providers/nop.py +6 -7
- mlrun/api/utils/auth/providers/opa.py +17 -17
- mlrun/api/utils/auth/verifier.py +36 -34
- mlrun/api/utils/background_tasks.py +24 -24
- mlrun/{builder.py → api/utils/builder.py} +216 -123
- mlrun/api/utils/clients/__init__.py +1 -1
- mlrun/api/utils/clients/chief.py +19 -4
- mlrun/api/utils/clients/iguazio.py +106 -60
- mlrun/api/utils/clients/log_collector.py +1 -1
- mlrun/api/utils/clients/nuclio.py +23 -23
- mlrun/api/utils/clients/protocols/grpc.py +2 -2
- mlrun/api/utils/db/__init__.py +1 -1
- mlrun/api/utils/db/alembic.py +1 -1
- mlrun/api/utils/db/backup.py +1 -1
- mlrun/api/utils/db/mysql.py +24 -25
- mlrun/api/utils/db/sql_collation.py +1 -1
- mlrun/api/utils/db/sqlite_migration.py +2 -2
- mlrun/api/utils/events/__init__.py +14 -0
- mlrun/api/utils/events/base.py +57 -0
- mlrun/api/utils/events/events_factory.py +41 -0
- mlrun/api/utils/events/iguazio.py +217 -0
- mlrun/api/utils/events/nop.py +55 -0
- mlrun/api/utils/helpers.py +16 -13
- mlrun/api/utils/memory_reports.py +1 -1
- mlrun/api/utils/periodic.py +6 -3
- mlrun/api/utils/projects/__init__.py +1 -1
- mlrun/api/utils/projects/follower.py +33 -33
- mlrun/api/utils/projects/leader.py +36 -34
- mlrun/api/utils/projects/member.py +27 -27
- mlrun/api/utils/projects/remotes/__init__.py +1 -1
- mlrun/api/utils/projects/remotes/follower.py +13 -13
- mlrun/api/utils/projects/remotes/leader.py +10 -10
- mlrun/api/utils/projects/remotes/nop_follower.py +27 -21
- mlrun/api/utils/projects/remotes/nop_leader.py +17 -16
- mlrun/api/utils/scheduler.py +140 -51
- mlrun/api/utils/singletons/__init__.py +1 -1
- mlrun/api/utils/singletons/db.py +9 -15
- mlrun/api/utils/singletons/k8s.py +677 -5
- mlrun/api/utils/singletons/logs_dir.py +1 -1
- mlrun/api/utils/singletons/project_member.py +1 -1
- mlrun/api/utils/singletons/scheduler.py +1 -1
- mlrun/artifacts/__init__.py +2 -2
- mlrun/artifacts/base.py +8 -2
- mlrun/artifacts/dataset.py +5 -3
- mlrun/artifacts/manager.py +7 -1
- mlrun/artifacts/model.py +15 -4
- mlrun/artifacts/plots.py +1 -1
- mlrun/common/__init__.py +1 -1
- mlrun/common/constants.py +15 -0
- mlrun/common/model_monitoring.py +209 -0
- mlrun/common/schemas/__init__.py +167 -0
- mlrun/{api → common}/schemas/artifact.py +13 -14
- mlrun/{api → common}/schemas/auth.py +10 -8
- mlrun/{api → common}/schemas/background_task.py +3 -3
- mlrun/{api → common}/schemas/client_spec.py +1 -1
- mlrun/{api → common}/schemas/clusterization_spec.py +3 -3
- mlrun/{api → common}/schemas/constants.py +21 -8
- mlrun/common/schemas/events.py +36 -0
- mlrun/{api → common}/schemas/feature_store.py +2 -1
- mlrun/{api → common}/schemas/frontend_spec.py +7 -6
- mlrun/{api → common}/schemas/function.py +5 -5
- mlrun/{api → common}/schemas/http.py +3 -3
- mlrun/common/schemas/hub.py +134 -0
- mlrun/{api → common}/schemas/k8s.py +3 -3
- mlrun/{api → common}/schemas/memory_reports.py +1 -1
- mlrun/common/schemas/model_endpoints.py +342 -0
- mlrun/common/schemas/notification.py +57 -0
- mlrun/{api → common}/schemas/object.py +6 -6
- mlrun/{api → common}/schemas/pipeline.py +3 -3
- mlrun/{api → common}/schemas/project.py +6 -5
- mlrun/common/schemas/regex.py +24 -0
- mlrun/common/schemas/runs.py +30 -0
- mlrun/{api → common}/schemas/runtime_resource.py +3 -3
- mlrun/{api → common}/schemas/schedule.py +19 -7
- mlrun/{api → common}/schemas/secret.py +3 -3
- mlrun/{api → common}/schemas/tag.py +2 -2
- mlrun/common/types.py +25 -0
- mlrun/config.py +152 -20
- mlrun/data_types/__init__.py +7 -2
- mlrun/data_types/data_types.py +4 -2
- mlrun/data_types/infer.py +1 -1
- mlrun/data_types/spark.py +10 -3
- mlrun/datastore/__init__.py +10 -3
- mlrun/datastore/azure_blob.py +1 -1
- mlrun/datastore/base.py +185 -53
- mlrun/datastore/datastore.py +1 -1
- mlrun/datastore/filestore.py +1 -1
- mlrun/datastore/google_cloud_storage.py +1 -1
- mlrun/datastore/inmem.py +4 -1
- mlrun/datastore/redis.py +1 -1
- mlrun/datastore/s3.py +1 -1
- mlrun/datastore/sources.py +192 -70
- mlrun/datastore/spark_udf.py +44 -0
- mlrun/datastore/store_resources.py +4 -4
- mlrun/datastore/targets.py +115 -45
- mlrun/datastore/utils.py +127 -5
- mlrun/datastore/v3io.py +1 -1
- mlrun/datastore/wasbfs/__init__.py +1 -1
- mlrun/datastore/wasbfs/fs.py +1 -1
- mlrun/db/__init__.py +7 -5
- mlrun/db/base.py +112 -68
- mlrun/db/httpdb.py +445 -277
- mlrun/db/nopdb.py +491 -0
- mlrun/db/sqldb.py +112 -65
- mlrun/errors.py +6 -1
- mlrun/execution.py +44 -22
- mlrun/feature_store/__init__.py +1 -1
- mlrun/feature_store/api.py +143 -95
- mlrun/feature_store/common.py +16 -20
- mlrun/feature_store/feature_set.py +42 -12
- mlrun/feature_store/feature_vector.py +32 -21
- mlrun/feature_store/ingestion.py +9 -12
- mlrun/feature_store/retrieval/__init__.py +3 -2
- mlrun/feature_store/retrieval/base.py +388 -66
- mlrun/feature_store/retrieval/dask_merger.py +63 -151
- mlrun/feature_store/retrieval/job.py +30 -12
- mlrun/feature_store/retrieval/local_merger.py +40 -133
- mlrun/feature_store/retrieval/spark_merger.py +129 -127
- mlrun/feature_store/retrieval/storey_merger.py +173 -0
- mlrun/feature_store/steps.py +132 -15
- mlrun/features.py +8 -3
- mlrun/frameworks/__init__.py +1 -1
- mlrun/frameworks/_common/__init__.py +1 -1
- mlrun/frameworks/_common/artifacts_library.py +1 -1
- mlrun/frameworks/_common/mlrun_interface.py +1 -1
- mlrun/frameworks/_common/model_handler.py +1 -1
- mlrun/frameworks/_common/plan.py +1 -1
- mlrun/frameworks/_common/producer.py +1 -1
- mlrun/frameworks/_common/utils.py +1 -1
- mlrun/frameworks/_dl_common/__init__.py +1 -1
- mlrun/frameworks/_dl_common/loggers/__init__.py +1 -1
- mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
- mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +1 -1
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +1 -1
- mlrun/frameworks/_dl_common/model_handler.py +1 -1
- mlrun/frameworks/_dl_common/utils.py +1 -1
- mlrun/frameworks/_ml_common/__init__.py +1 -1
- mlrun/frameworks/_ml_common/artifacts_library.py +1 -1
- mlrun/frameworks/_ml_common/loggers/__init__.py +1 -1
- mlrun/frameworks/_ml_common/loggers/logger.py +1 -1
- mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
- mlrun/frameworks/_ml_common/model_handler.py +1 -1
- mlrun/frameworks/_ml_common/pkl_model_server.py +13 -1
- mlrun/frameworks/_ml_common/plan.py +1 -1
- mlrun/frameworks/_ml_common/plans/__init__.py +1 -1
- mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +1 -6
- mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +1 -1
- mlrun/frameworks/_ml_common/plans/dataset_plan.py +1 -1
- mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +1 -1
- mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +1 -1
- mlrun/frameworks/_ml_common/producer.py +1 -1
- mlrun/frameworks/_ml_common/utils.py +1 -1
- mlrun/frameworks/auto_mlrun/__init__.py +1 -1
- mlrun/frameworks/auto_mlrun/auto_mlrun.py +1 -1
- mlrun/frameworks/huggingface/__init__.py +1 -1
- mlrun/frameworks/huggingface/model_server.py +1 -1
- mlrun/frameworks/lgbm/__init__.py +1 -1
- mlrun/frameworks/lgbm/callbacks/__init__.py +1 -1
- mlrun/frameworks/lgbm/callbacks/callback.py +1 -1
- mlrun/frameworks/lgbm/callbacks/logging_callback.py +1 -1
- mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +1 -1
- mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -1
- mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -1
- mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +1 -1
- mlrun/frameworks/lgbm/mlrun_interfaces/model_mlrun_interface.py +1 -1
- mlrun/frameworks/lgbm/model_handler.py +1 -1
- mlrun/frameworks/lgbm/model_server.py +1 -1
- mlrun/frameworks/lgbm/utils.py +1 -1
- mlrun/frameworks/onnx/__init__.py +1 -1
- mlrun/frameworks/onnx/dataset.py +1 -1
- mlrun/frameworks/onnx/mlrun_interface.py +1 -1
- mlrun/frameworks/onnx/model_handler.py +1 -1
- mlrun/frameworks/onnx/model_server.py +1 -1
- mlrun/frameworks/parallel_coordinates.py +1 -1
- mlrun/frameworks/pytorch/__init__.py +1 -1
- mlrun/frameworks/pytorch/callbacks/__init__.py +1 -1
- mlrun/frameworks/pytorch/callbacks/callback.py +1 -1
- mlrun/frameworks/pytorch/callbacks/logging_callback.py +1 -1
- mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +1 -1
- mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +1 -1
- mlrun/frameworks/pytorch/callbacks_handler.py +1 -1
- mlrun/frameworks/pytorch/mlrun_interface.py +1 -1
- mlrun/frameworks/pytorch/model_handler.py +1 -1
- mlrun/frameworks/pytorch/model_server.py +1 -1
- mlrun/frameworks/pytorch/utils.py +1 -1
- mlrun/frameworks/sklearn/__init__.py +1 -1
- mlrun/frameworks/sklearn/estimator.py +1 -1
- mlrun/frameworks/sklearn/metric.py +1 -1
- mlrun/frameworks/sklearn/metrics_library.py +1 -1
- mlrun/frameworks/sklearn/mlrun_interface.py +1 -1
- mlrun/frameworks/sklearn/model_handler.py +1 -1
- mlrun/frameworks/sklearn/utils.py +1 -1
- mlrun/frameworks/tf_keras/__init__.py +1 -1
- mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -1
- mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
- mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +1 -1
- mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +1 -1
- mlrun/frameworks/tf_keras/mlrun_interface.py +1 -1
- mlrun/frameworks/tf_keras/model_handler.py +1 -1
- mlrun/frameworks/tf_keras/model_server.py +1 -1
- mlrun/frameworks/tf_keras/utils.py +1 -1
- mlrun/frameworks/xgboost/__init__.py +1 -1
- mlrun/frameworks/xgboost/mlrun_interface.py +1 -1
- mlrun/frameworks/xgboost/model_handler.py +1 -1
- mlrun/frameworks/xgboost/utils.py +1 -1
- mlrun/k8s_utils.py +14 -765
- mlrun/kfpops.py +14 -17
- mlrun/launcher/__init__.py +13 -0
- mlrun/launcher/base.py +406 -0
- mlrun/launcher/client.py +159 -0
- mlrun/launcher/factory.py +50 -0
- mlrun/launcher/local.py +276 -0
- mlrun/launcher/remote.py +178 -0
- mlrun/lists.py +10 -2
- mlrun/mlutils/__init__.py +1 -1
- mlrun/mlutils/data.py +1 -1
- mlrun/mlutils/models.py +1 -1
- mlrun/mlutils/plots.py +1 -1
- mlrun/model.py +252 -14
- mlrun/model_monitoring/__init__.py +41 -0
- mlrun/model_monitoring/features_drift_table.py +1 -1
- mlrun/model_monitoring/helpers.py +123 -38
- mlrun/model_monitoring/model_endpoint.py +144 -0
- mlrun/model_monitoring/model_monitoring_batch.py +310 -259
- mlrun/model_monitoring/stores/__init__.py +106 -0
- mlrun/model_monitoring/stores/kv_model_endpoint_store.py +448 -0
- mlrun/model_monitoring/stores/model_endpoint_store.py +147 -0
- mlrun/model_monitoring/stores/models/__init__.py +23 -0
- mlrun/model_monitoring/stores/models/base.py +18 -0
- mlrun/model_monitoring/stores/models/mysql.py +100 -0
- mlrun/model_monitoring/stores/models/sqlite.py +98 -0
- mlrun/model_monitoring/stores/sql_model_endpoint_store.py +370 -0
- mlrun/model_monitoring/stream_processing_fs.py +239 -271
- mlrun/package/__init__.py +163 -0
- mlrun/package/context_handler.py +325 -0
- mlrun/package/errors.py +47 -0
- mlrun/package/packager.py +298 -0
- mlrun/{runtimes/package → package/packagers}/__init__.py +3 -1
- mlrun/package/packagers/default_packager.py +422 -0
- mlrun/package/packagers/numpy_packagers.py +612 -0
- mlrun/package/packagers/pandas_packagers.py +968 -0
- mlrun/package/packagers/python_standard_library_packagers.py +616 -0
- mlrun/package/packagers_manager.py +786 -0
- mlrun/package/utils/__init__.py +53 -0
- mlrun/package/utils/_archiver.py +226 -0
- mlrun/package/utils/_formatter.py +211 -0
- mlrun/package/utils/_pickler.py +234 -0
- mlrun/package/utils/_supported_format.py +71 -0
- mlrun/package/utils/log_hint_utils.py +93 -0
- mlrun/package/utils/type_hint_utils.py +298 -0
- mlrun/platforms/__init__.py +1 -1
- mlrun/platforms/iguazio.py +34 -2
- mlrun/platforms/other.py +1 -1
- mlrun/projects/__init__.py +1 -1
- mlrun/projects/operations.py +14 -9
- mlrun/projects/pipelines.py +31 -13
- mlrun/projects/project.py +762 -238
- mlrun/render.py +49 -19
- mlrun/run.py +57 -326
- mlrun/runtimes/__init__.py +3 -9
- mlrun/runtimes/base.py +247 -784
- mlrun/runtimes/constants.py +1 -1
- mlrun/runtimes/daskjob.py +45 -41
- mlrun/runtimes/funcdoc.py +43 -7
- mlrun/runtimes/function.py +66 -656
- mlrun/runtimes/function_reference.py +1 -1
- mlrun/runtimes/generators.py +1 -1
- mlrun/runtimes/kubejob.py +99 -116
- mlrun/runtimes/local.py +59 -66
- mlrun/runtimes/mpijob/__init__.py +1 -1
- mlrun/runtimes/mpijob/abstract.py +13 -15
- mlrun/runtimes/mpijob/v1.py +3 -1
- mlrun/runtimes/mpijob/v1alpha1.py +1 -1
- mlrun/runtimes/nuclio.py +1 -1
- mlrun/runtimes/pod.py +51 -26
- mlrun/runtimes/remotesparkjob.py +3 -1
- mlrun/runtimes/serving.py +12 -4
- mlrun/runtimes/sparkjob/__init__.py +1 -2
- mlrun/runtimes/sparkjob/abstract.py +44 -31
- mlrun/runtimes/sparkjob/spark3job.py +11 -9
- mlrun/runtimes/utils.py +61 -42
- mlrun/secrets.py +16 -18
- mlrun/serving/__init__.py +3 -2
- mlrun/serving/merger.py +1 -1
- mlrun/serving/remote.py +1 -1
- mlrun/serving/routers.py +39 -42
- mlrun/serving/server.py +23 -13
- mlrun/serving/serving_wrapper.py +1 -1
- mlrun/serving/states.py +172 -39
- mlrun/serving/utils.py +1 -1
- mlrun/serving/v1_serving.py +1 -1
- mlrun/serving/v2_serving.py +29 -21
- mlrun/utils/__init__.py +1 -2
- mlrun/utils/async_http.py +8 -1
- mlrun/utils/azure_vault.py +1 -1
- mlrun/utils/clones.py +2 -2
- mlrun/utils/condition_evaluator.py +65 -0
- mlrun/utils/db.py +52 -0
- mlrun/utils/helpers.py +188 -13
- mlrun/utils/http.py +89 -54
- mlrun/utils/logger.py +48 -8
- mlrun/utils/model_monitoring.py +132 -100
- mlrun/utils/notifications/__init__.py +1 -1
- mlrun/utils/notifications/notification/__init__.py +8 -6
- mlrun/utils/notifications/notification/base.py +20 -14
- mlrun/utils/notifications/notification/console.py +7 -4
- mlrun/utils/notifications/notification/git.py +36 -19
- mlrun/utils/notifications/notification/ipython.py +10 -8
- mlrun/utils/notifications/notification/slack.py +18 -13
- mlrun/utils/notifications/notification_pusher.py +377 -56
- mlrun/utils/regex.py +6 -1
- mlrun/utils/singleton.py +1 -1
- mlrun/utils/v3io_clients.py +1 -1
- mlrun/utils/vault.py +270 -269
- mlrun/utils/version/__init__.py +1 -1
- mlrun/utils/version/version.json +2 -2
- mlrun/utils/version/version.py +1 -1
- {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/METADATA +16 -10
- mlrun-1.4.0.dist-info/RECORD +434 -0
- mlrun/api/api/endpoints/marketplace.py +0 -257
- mlrun/api/crud/marketplace.py +0 -221
- mlrun/api/crud/model_monitoring/model_endpoint_store.py +0 -847
- mlrun/api/db/filedb/db.py +0 -518
- mlrun/api/schemas/marketplace.py +0 -128
- mlrun/api/schemas/model_endpoints.py +0 -185
- mlrun/db/filedb.py +0 -891
- mlrun/feature_store/retrieval/online.py +0 -92
- mlrun/model_monitoring/constants.py +0 -67
- mlrun/runtimes/package/context_handler.py +0 -711
- mlrun/runtimes/sparkjob/spark2job.py +0 -59
- mlrun-1.3.3.dist-info/RECORD +0 -381
- {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/LICENSE +0 -0
- {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/WHEEL +0 -0
- {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/entry_points.txt +0 -0
- {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2023 Iguazio
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -11,38 +11,36 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
|
|
14
|
+
import os.path
|
|
15
15
|
import pathlib
|
|
16
16
|
import re
|
|
17
|
-
import tarfile
|
|
18
17
|
import tempfile
|
|
18
|
+
import typing
|
|
19
19
|
from base64 import b64decode, b64encode
|
|
20
20
|
from os import path
|
|
21
21
|
from urllib.parse import urlparse
|
|
22
22
|
|
|
23
23
|
from kubernetes import client
|
|
24
24
|
|
|
25
|
-
import mlrun.api.
|
|
25
|
+
import mlrun.api.utils.singletons.k8s
|
|
26
|
+
import mlrun.common.constants
|
|
27
|
+
import mlrun.common.schemas
|
|
26
28
|
import mlrun.errors
|
|
27
29
|
import mlrun.runtimes.utils
|
|
28
|
-
|
|
29
|
-
from .config import config
|
|
30
|
-
from .
|
|
31
|
-
from .k8s_utils import BasePod, get_k8s_helper
|
|
32
|
-
from .utils import enrich_image_url, get_parsed_docker_registry, logger, normalize_name
|
|
33
|
-
|
|
34
|
-
IMAGE_NAME_ENRICH_REGISTRY_PREFIX = "."
|
|
30
|
+
import mlrun.utils
|
|
31
|
+
from mlrun.config import config
|
|
32
|
+
from mlrun.utils.helpers import remove_image_protocol_prefix
|
|
35
33
|
|
|
36
34
|
|
|
37
35
|
def make_dockerfile(
|
|
38
|
-
base_image,
|
|
39
|
-
commands=None,
|
|
40
|
-
source=None,
|
|
41
|
-
|
|
42
|
-
workdir="/mlrun",
|
|
43
|
-
extra="",
|
|
44
|
-
user_unix_id=None,
|
|
45
|
-
enriched_group_id=None,
|
|
36
|
+
base_image: str,
|
|
37
|
+
commands: list = None,
|
|
38
|
+
source: str = None,
|
|
39
|
+
requirements_path: str = None,
|
|
40
|
+
workdir: str = "/mlrun",
|
|
41
|
+
extra: str = "",
|
|
42
|
+
user_unix_id: int = None,
|
|
43
|
+
enriched_group_id: int = None,
|
|
46
44
|
):
|
|
47
45
|
dock = f"FROM {base_image}\n"
|
|
48
46
|
|
|
@@ -55,20 +53,20 @@ def make_dockerfile(
|
|
|
55
53
|
dock += f"ARG {build_arg_key}={build_arg_value}\n"
|
|
56
54
|
|
|
57
55
|
if source:
|
|
58
|
-
dock += f"RUN mkdir -p {workdir}\n"
|
|
59
56
|
dock += f"WORKDIR {workdir}\n"
|
|
60
57
|
# 'ADD' command does not extract zip files - add extraction stage to the dockerfile
|
|
61
58
|
if source.endswith(".zip"):
|
|
59
|
+
source_dir = os.path.join(workdir, "source")
|
|
62
60
|
stage1 = f"""
|
|
63
61
|
FROM {base_image} AS extractor
|
|
64
62
|
RUN apt-get update -qqy && apt install --assume-yes unzip
|
|
65
|
-
RUN mkdir -p
|
|
66
|
-
COPY {source}
|
|
67
|
-
RUN cd
|
|
63
|
+
RUN mkdir -p {source_dir}
|
|
64
|
+
COPY {source} {source_dir}
|
|
65
|
+
RUN cd {source_dir} && unzip {source} && rm {source}
|
|
68
66
|
"""
|
|
69
67
|
dock = stage1 + "\n" + dock
|
|
70
68
|
|
|
71
|
-
dock += f"COPY --from=extractor /
|
|
69
|
+
dock += f"COPY --from=extractor {source_dir}/ {workdir}\n"
|
|
72
70
|
else:
|
|
73
71
|
dock += f"ADD {source} {workdir}\n"
|
|
74
72
|
|
|
@@ -76,13 +74,16 @@ def make_dockerfile(
|
|
|
76
74
|
dock += f"RUN chown -R {user_unix_id}:{enriched_group_id} {workdir}\n"
|
|
77
75
|
|
|
78
76
|
dock += f"ENV PYTHONPATH {workdir}\n"
|
|
79
|
-
if requirements:
|
|
80
|
-
dock += f"RUN python -m pip install -r {requirements}\n"
|
|
81
77
|
if commands:
|
|
82
78
|
dock += "".join([f"RUN {command}\n" for command in commands])
|
|
79
|
+
if requirements_path:
|
|
80
|
+
dock += (
|
|
81
|
+
f"RUN echo 'Installing {requirements_path}...'; cat {requirements_path}\n"
|
|
82
|
+
)
|
|
83
|
+
dock += f"RUN python -m pip install -r {requirements_path}\n"
|
|
83
84
|
if extra:
|
|
84
85
|
dock += extra
|
|
85
|
-
logger.debug("Resolved dockerfile", dockfile_contents=dock)
|
|
86
|
+
mlrun.utils.logger.debug("Resolved dockerfile", dockfile_contents=dock)
|
|
86
87
|
return dock
|
|
87
88
|
|
|
88
89
|
|
|
@@ -95,6 +96,7 @@ def make_kaniko_pod(
|
|
|
95
96
|
inline_code=None,
|
|
96
97
|
inline_path=None,
|
|
97
98
|
requirements=None,
|
|
99
|
+
requirements_path=None,
|
|
98
100
|
secret_name=None,
|
|
99
101
|
name="",
|
|
100
102
|
verbose=False,
|
|
@@ -134,7 +136,16 @@ def make_kaniko_pod(
|
|
|
134
136
|
if dockertext:
|
|
135
137
|
dockerfile = "/empty/Dockerfile"
|
|
136
138
|
|
|
137
|
-
args = [
|
|
139
|
+
args = [
|
|
140
|
+
"--dockerfile",
|
|
141
|
+
dockerfile,
|
|
142
|
+
"--context",
|
|
143
|
+
context,
|
|
144
|
+
"--destination",
|
|
145
|
+
dest,
|
|
146
|
+
"--image-fs-extract-retry",
|
|
147
|
+
config.httpdb.builder.kaniko_image_fs_extraction_retries,
|
|
148
|
+
]
|
|
138
149
|
for value, flag in [
|
|
139
150
|
(config.httpdb.builder.insecure_pull_registry_mode, "--insecure-pull"),
|
|
140
151
|
(config.httpdb.builder.insecure_push_registry_mode, "--insecure"),
|
|
@@ -158,7 +169,7 @@ def make_kaniko_pod(
|
|
|
158
169
|
mem=default_requests.get("memory"), cpu=default_requests.get("cpu")
|
|
159
170
|
)
|
|
160
171
|
}
|
|
161
|
-
kpod = BasePod(
|
|
172
|
+
kpod = mlrun.api.utils.singletons.k8s.BasePod(
|
|
162
173
|
name or "mlrun-build",
|
|
163
174
|
config.httpdb.builder.kaniko_image,
|
|
164
175
|
args=args,
|
|
@@ -193,19 +204,23 @@ def make_kaniko_pod(
|
|
|
193
204
|
commands = []
|
|
194
205
|
env = {}
|
|
195
206
|
if dockertext:
|
|
196
|
-
|
|
207
|
+
# set and encode docker content to the DOCKERFILE environment variable in the kaniko pod
|
|
197
208
|
env["DOCKERFILE"] = b64encode(dockertext.encode("utf-8")).decode("utf-8")
|
|
209
|
+
# dump dockerfile content and decode to Dockerfile destination
|
|
210
|
+
commands.append("echo ${DOCKERFILE} | base64 -d > /empty/Dockerfile")
|
|
198
211
|
if inline_code:
|
|
199
212
|
name = inline_path or "main.py"
|
|
200
|
-
commands.append("echo ${CODE} | base64 -d > /empty/" + name)
|
|
201
213
|
env["CODE"] = b64encode(inline_code.encode("utf-8")).decode("utf-8")
|
|
214
|
+
commands.append("echo ${CODE} | base64 -d > /empty/" + name)
|
|
202
215
|
if requirements:
|
|
203
|
-
|
|
204
|
-
"echo ${REQUIREMENTS} | base64 -d > /empty/requirements.txt"
|
|
205
|
-
)
|
|
216
|
+
# set and encode requirements to the REQUIREMENTS environment variable in the kaniko pod
|
|
206
217
|
env["REQUIREMENTS"] = b64encode(
|
|
207
218
|
"\n".join(requirements).encode("utf-8")
|
|
208
219
|
).decode("utf-8")
|
|
220
|
+
# dump requirement content and decode to the requirement.txt destination
|
|
221
|
+
commands.append(
|
|
222
|
+
"echo ${REQUIREMENTS}" + " | " + f"base64 -d > {requirements_path}"
|
|
223
|
+
)
|
|
209
224
|
|
|
210
225
|
kpod.append_init_container(
|
|
211
226
|
config.httpdb.builder.kaniko_init_container_image,
|
|
@@ -221,7 +236,21 @@ def make_kaniko_pod(
|
|
|
221
236
|
if end == -1:
|
|
222
237
|
end = len(dest)
|
|
223
238
|
repo = dest[dest.find("/") + 1 : end]
|
|
224
|
-
|
|
239
|
+
|
|
240
|
+
# if no secret is given, assume ec2 instance has attached role which provides read/write access to ECR
|
|
241
|
+
assume_instance_role = not config.httpdb.builder.docker_registry_secret
|
|
242
|
+
configure_kaniko_ecr_init_container(kpod, registry, repo, assume_instance_role)
|
|
243
|
+
|
|
244
|
+
# project secret might conflict with the attached instance role
|
|
245
|
+
# ensure "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY" have no values or else kaniko will fail
|
|
246
|
+
# due to credentials conflict / lack of permission on given credentials
|
|
247
|
+
if assume_instance_role:
|
|
248
|
+
kpod.pod.spec.containers[0].env.extend(
|
|
249
|
+
[
|
|
250
|
+
client.V1EnvVar(name="AWS_ACCESS_KEY_ID", value=""),
|
|
251
|
+
client.V1EnvVar(name="AWS_SECRET_ACCESS_KEY", value=""),
|
|
252
|
+
]
|
|
253
|
+
)
|
|
225
254
|
|
|
226
255
|
# mount regular docker config secret
|
|
227
256
|
elif secret_name:
|
|
@@ -231,7 +260,9 @@ def make_kaniko_pod(
|
|
|
231
260
|
return kpod
|
|
232
261
|
|
|
233
262
|
|
|
234
|
-
def configure_kaniko_ecr_init_container(
|
|
263
|
+
def configure_kaniko_ecr_init_container(
|
|
264
|
+
kpod, registry, repo, assume_instance_role=True
|
|
265
|
+
):
|
|
235
266
|
region = registry.split(".")[3]
|
|
236
267
|
|
|
237
268
|
# fail silently in order to ignore "repository already exists" errors
|
|
@@ -242,12 +273,13 @@ def configure_kaniko_ecr_init_container(kpod, registry, repo):
|
|
|
242
273
|
)
|
|
243
274
|
init_container_env = {}
|
|
244
275
|
|
|
245
|
-
if
|
|
276
|
+
if assume_instance_role:
|
|
246
277
|
|
|
247
278
|
# assume instance role has permissions to register and store a container image
|
|
248
279
|
# https://github.com/GoogleContainerTools/kaniko#pushing-to-amazon-ecr
|
|
249
280
|
# we only need this in the kaniko container
|
|
250
281
|
kpod.env.append(client.V1EnvVar(name="AWS_SDK_LOAD_CONFIG", value="true"))
|
|
282
|
+
|
|
251
283
|
else:
|
|
252
284
|
aws_credentials_file_env_key = "AWS_SHARED_CREDENTIALS_FILE"
|
|
253
285
|
aws_credentials_file_env_value = "/tmp/credentials"
|
|
@@ -278,24 +310,12 @@ def configure_kaniko_ecr_init_container(kpod, registry, repo):
|
|
|
278
310
|
)
|
|
279
311
|
|
|
280
312
|
|
|
281
|
-
def upload_tarball(source_dir, target, secrets=None):
|
|
282
|
-
|
|
283
|
-
# will delete the temp file
|
|
284
|
-
with tempfile.NamedTemporaryFile(suffix=".tar.gz") as temp_fh:
|
|
285
|
-
with tarfile.open(mode="w:gz", fileobj=temp_fh) as tar:
|
|
286
|
-
tar.add(source_dir, arcname="")
|
|
287
|
-
stores = store_manager.set(secrets)
|
|
288
|
-
datastore, subpath = stores.get_or_create_store(target)
|
|
289
|
-
datastore.upload(subpath, temp_fh.name)
|
|
290
|
-
|
|
291
|
-
|
|
292
313
|
def build_image(
|
|
293
|
-
auth_info: mlrun.
|
|
314
|
+
auth_info: mlrun.common.schemas.AuthInfo,
|
|
294
315
|
project: str,
|
|
295
316
|
image_target,
|
|
296
317
|
commands=None,
|
|
297
318
|
source="",
|
|
298
|
-
mounter="v3io",
|
|
299
319
|
base_image=None,
|
|
300
320
|
requirements=None,
|
|
301
321
|
inline_code=None,
|
|
@@ -315,43 +335,24 @@ def build_image(
|
|
|
315
335
|
):
|
|
316
336
|
runtime_spec = runtime.spec if runtime else None
|
|
317
337
|
builder_env = builder_env or {}
|
|
318
|
-
image_target, secret_name =
|
|
338
|
+
image_target, secret_name = resolve_image_target_and_registry_secret(
|
|
319
339
|
image_target, registry, secret_name
|
|
320
340
|
)
|
|
321
341
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
if source:
|
|
326
|
-
raise ValueError("requirements list only works with inline code")
|
|
327
|
-
else:
|
|
328
|
-
requirements_list = None
|
|
329
|
-
requirements_path = requirements
|
|
330
|
-
|
|
331
|
-
commands = commands or []
|
|
332
|
-
if with_mlrun:
|
|
333
|
-
# mlrun prerequisite - upgrade pip
|
|
334
|
-
upgrade_pip_command = resolve_upgrade_pip_command(commands)
|
|
335
|
-
if upgrade_pip_command:
|
|
336
|
-
commands.append(upgrade_pip_command)
|
|
337
|
-
|
|
338
|
-
mlrun_command = resolve_mlrun_install_command(
|
|
339
|
-
mlrun_version_specifier, client_version, commands
|
|
340
|
-
)
|
|
341
|
-
if mlrun_command:
|
|
342
|
-
commands.append(mlrun_command)
|
|
342
|
+
commands, requirements_list, requirements_path = _resolve_build_requirements(
|
|
343
|
+
requirements, commands, with_mlrun, mlrun_version_specifier, client_version
|
|
344
|
+
)
|
|
343
345
|
|
|
344
|
-
if not inline_code and not source and not commands:
|
|
345
|
-
logger.info("skipping build, nothing to add")
|
|
346
|
+
if not inline_code and not source and not commands and not requirements:
|
|
347
|
+
mlrun.utils.logger.info("skipping build, nothing to add")
|
|
346
348
|
return "skipped"
|
|
347
349
|
|
|
348
350
|
context = "/context"
|
|
349
351
|
to_mount = False
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
)
|
|
352
|
+
is_v3io_source = False
|
|
353
|
+
if source:
|
|
354
|
+
is_v3io_source = source.startswith("v3io://") or source.startswith("v3ios://")
|
|
355
|
+
|
|
355
356
|
access_key = builder_env.get(
|
|
356
357
|
"V3IO_ACCESS_KEY", auth_info.data_session or auth_info.access_key
|
|
357
358
|
)
|
|
@@ -365,7 +366,8 @@ def build_image(
|
|
|
365
366
|
if inline_code or runtime_spec.build.load_source_on_run or not source:
|
|
366
367
|
context = "/empty"
|
|
367
368
|
|
|
368
|
-
|
|
369
|
+
# source is remote
|
|
370
|
+
elif source and "://" in source and not is_v3io_source:
|
|
369
371
|
if source.startswith("git://"):
|
|
370
372
|
# if the user provided branch (w/o refs/..) we add the "refs/.."
|
|
371
373
|
fragment = parsed_url.fragment or ""
|
|
@@ -376,19 +378,34 @@ def build_image(
|
|
|
376
378
|
context = source
|
|
377
379
|
source_to_copy = "."
|
|
378
380
|
|
|
381
|
+
# source is local / v3io
|
|
379
382
|
else:
|
|
380
|
-
if
|
|
383
|
+
if is_v3io_source:
|
|
381
384
|
source = parsed_url.path
|
|
382
385
|
to_mount = True
|
|
383
386
|
source_dir_to_mount, source_to_copy = path.split(source)
|
|
384
|
-
|
|
387
|
+
|
|
388
|
+
# source is a path without a scheme, we allow to copy absolute paths assuming they are valid paths
|
|
389
|
+
# in the image, however, it is recommended to use `workdir` instead in such cases
|
|
390
|
+
# which is set during runtime (mlrun.runtimes.local.LocalRuntime._pre_run).
|
|
391
|
+
# relative paths are not supported at build time
|
|
392
|
+
# "." and "./" are considered as 'project context'
|
|
393
|
+
# TODO: enrich with project context if pulling on build time
|
|
394
|
+
elif path.isabs(source):
|
|
385
395
|
source_to_copy = source
|
|
386
396
|
|
|
397
|
+
else:
|
|
398
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
399
|
+
f"Load of relative source ({source}) is not supported at build time "
|
|
400
|
+
"see 'mlrun.runtimes.kubejob.KubejobRuntime.with_source_archive' or "
|
|
401
|
+
"'mlrun.projects.project.MlrunProject.set_source' for more details"
|
|
402
|
+
)
|
|
403
|
+
|
|
387
404
|
user_unix_id = None
|
|
388
405
|
enriched_group_id = None
|
|
389
406
|
if (
|
|
390
407
|
mlrun.mlconf.function.spec.security_context.enrichment_mode
|
|
391
|
-
!= mlrun.
|
|
408
|
+
!= mlrun.common.schemas.SecurityContextEnrichmentModes.disabled.value
|
|
392
409
|
):
|
|
393
410
|
from mlrun.api.api.utils import ensure_function_security_context
|
|
394
411
|
|
|
@@ -396,14 +413,29 @@ def build_image(
|
|
|
396
413
|
user_unix_id = runtime.spec.security_context.run_as_user
|
|
397
414
|
enriched_group_id = runtime.spec.security_context.run_as_group
|
|
398
415
|
|
|
416
|
+
if source_to_copy and (
|
|
417
|
+
not runtime.spec.clone_target_dir
|
|
418
|
+
or not os.path.isabs(runtime.spec.clone_target_dir)
|
|
419
|
+
):
|
|
420
|
+
# use a temp dir for permissions and set it as the workdir
|
|
421
|
+
tmpdir = tempfile.mkdtemp()
|
|
422
|
+
relative_workdir = runtime.spec.clone_target_dir or ""
|
|
423
|
+
if relative_workdir.startswith("./"):
|
|
424
|
+
# TODO: use 'removeprefix' when we drop python 3.7 support
|
|
425
|
+
# relative_workdir.removeprefix("./")
|
|
426
|
+
relative_workdir = relative_workdir[2:]
|
|
427
|
+
|
|
428
|
+
runtime.spec.clone_target_dir = path.join(tmpdir, "mlrun", relative_workdir)
|
|
429
|
+
|
|
399
430
|
dock = make_dockerfile(
|
|
400
431
|
base_image,
|
|
401
432
|
commands,
|
|
402
433
|
source=source_to_copy,
|
|
403
|
-
|
|
434
|
+
requirements_path=requirements_path,
|
|
404
435
|
extra=extra,
|
|
405
436
|
user_unix_id=user_unix_id,
|
|
406
437
|
enriched_group_id=enriched_group_id,
|
|
438
|
+
workdir=runtime.spec.clone_target_dir,
|
|
407
439
|
)
|
|
408
440
|
|
|
409
441
|
kpod = make_kaniko_pod(
|
|
@@ -414,6 +446,7 @@ def build_image(
|
|
|
414
446
|
inline_code=inline_code,
|
|
415
447
|
inline_path=inline_path,
|
|
416
448
|
requirements=requirements_list,
|
|
449
|
+
requirements_path=requirements_path,
|
|
417
450
|
secret_name=secret_name,
|
|
418
451
|
name=name,
|
|
419
452
|
verbose=verbose,
|
|
@@ -430,14 +463,16 @@ def build_image(
|
|
|
430
463
|
user=username,
|
|
431
464
|
)
|
|
432
465
|
|
|
433
|
-
k8s = get_k8s_helper()
|
|
466
|
+
k8s = mlrun.api.utils.singletons.k8s.get_k8s_helper(silent=False)
|
|
434
467
|
kpod.namespace = k8s.resolve_namespace(namespace)
|
|
435
468
|
|
|
436
469
|
if interactive:
|
|
437
470
|
return k8s.run_job(kpod)
|
|
438
471
|
else:
|
|
439
472
|
pod, ns = k8s.create_pod(kpod)
|
|
440
|
-
logger.info(
|
|
473
|
+
mlrun.utils.logger.info(
|
|
474
|
+
"Build started", pod=pod, namespace=ns, project=project, image=image_target
|
|
475
|
+
)
|
|
441
476
|
return f"build:{pod}"
|
|
442
477
|
|
|
443
478
|
|
|
@@ -453,7 +488,7 @@ def get_kaniko_spec_attributes_from_runtime():
|
|
|
453
488
|
]
|
|
454
489
|
|
|
455
490
|
|
|
456
|
-
def
|
|
491
|
+
def resolve_mlrun_install_command_version(
|
|
457
492
|
mlrun_version_specifier=None, client_version=None, commands=None
|
|
458
493
|
):
|
|
459
494
|
commands = commands or []
|
|
@@ -483,7 +518,7 @@ def resolve_mlrun_install_command(
|
|
|
483
518
|
mlrun_version_specifier = (
|
|
484
519
|
f"{config.package_path}[complete]=={config.version}"
|
|
485
520
|
)
|
|
486
|
-
return
|
|
521
|
+
return mlrun_version_specifier
|
|
487
522
|
|
|
488
523
|
|
|
489
524
|
def resolve_upgrade_pip_command(commands=None):
|
|
@@ -497,7 +532,7 @@ def resolve_upgrade_pip_command(commands=None):
|
|
|
497
532
|
|
|
498
533
|
|
|
499
534
|
def build_runtime(
|
|
500
|
-
auth_info: mlrun.
|
|
535
|
+
auth_info: mlrun.common.schemas.AuthInfo,
|
|
501
536
|
runtime,
|
|
502
537
|
with_mlrun=True,
|
|
503
538
|
mlrun_version_specifier=None,
|
|
@@ -511,7 +546,7 @@ def build_runtime(
|
|
|
511
546
|
namespace = runtime.metadata.namespace
|
|
512
547
|
project = runtime.metadata.project
|
|
513
548
|
if skip_deployed and runtime.is_deployed():
|
|
514
|
-
runtime.status.state = mlrun.
|
|
549
|
+
runtime.status.state = mlrun.common.schemas.FunctionState.ready
|
|
515
550
|
return True
|
|
516
551
|
if build.base_image:
|
|
517
552
|
mlrun_images = [
|
|
@@ -523,7 +558,13 @@ def build_runtime(
|
|
|
523
558
|
# if the base is one of mlrun images - no need to install mlrun
|
|
524
559
|
if any([image in build.base_image for image in mlrun_images]):
|
|
525
560
|
with_mlrun = False
|
|
526
|
-
if
|
|
561
|
+
if (
|
|
562
|
+
not build.source
|
|
563
|
+
and not build.commands
|
|
564
|
+
and not build.requirements
|
|
565
|
+
and not build.extra
|
|
566
|
+
and not with_mlrun
|
|
567
|
+
):
|
|
527
568
|
if not runtime.spec.image:
|
|
528
569
|
if build.base_image:
|
|
529
570
|
runtime.spec.image = build.base_image
|
|
@@ -536,7 +577,7 @@ def build_runtime(
|
|
|
536
577
|
"The deployment was not successful because no image was specified or there are missing build parameters"
|
|
537
578
|
" (commands/source)"
|
|
538
579
|
)
|
|
539
|
-
runtime.status.state = mlrun.
|
|
580
|
+
runtime.status.state = mlrun.common.schemas.FunctionState.ready
|
|
540
581
|
return True
|
|
541
582
|
|
|
542
583
|
build.image = mlrun.runtimes.utils.resolve_function_image_name(runtime, build.image)
|
|
@@ -549,17 +590,23 @@ def build_runtime(
|
|
|
549
590
|
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
550
591
|
"build spec must have a target image, set build.image = <target image>"
|
|
551
592
|
)
|
|
552
|
-
|
|
593
|
+
name = mlrun.utils.normalize_name(f"mlrun-build-{runtime.metadata.name}")
|
|
553
594
|
|
|
554
|
-
name = normalize_name(f"mlrun-build-{runtime.metadata.name}")
|
|
555
595
|
base_image: str = (
|
|
556
596
|
build.base_image or runtime.spec.image or config.default_base_image
|
|
557
597
|
)
|
|
558
|
-
enriched_base_image = enrich_image_url(
|
|
598
|
+
enriched_base_image = mlrun.utils.enrich_image_url(
|
|
559
599
|
base_image,
|
|
560
600
|
client_version,
|
|
561
601
|
client_python_version,
|
|
562
602
|
)
|
|
603
|
+
mlrun.utils.logger.info(
|
|
604
|
+
"Building runtime image",
|
|
605
|
+
base_image=enriched_base_image,
|
|
606
|
+
image=build.image,
|
|
607
|
+
project=project,
|
|
608
|
+
name=name,
|
|
609
|
+
)
|
|
563
610
|
|
|
564
611
|
status = build_image(
|
|
565
612
|
auth_info,
|
|
@@ -567,8 +614,8 @@ def build_runtime(
|
|
|
567
614
|
image_target=build.image,
|
|
568
615
|
base_image=enriched_base_image,
|
|
569
616
|
commands=build.commands,
|
|
617
|
+
requirements=build.requirements,
|
|
570
618
|
namespace=namespace,
|
|
571
|
-
# inline_code=inline,
|
|
572
619
|
source=build.source,
|
|
573
620
|
secret_name=build.secret,
|
|
574
621
|
interactive=interactive,
|
|
@@ -586,11 +633,11 @@ def build_runtime(
|
|
|
586
633
|
# using enriched base image for the runtime spec image, because this will be the image that the function will
|
|
587
634
|
# run with
|
|
588
635
|
runtime.spec.image = enriched_base_image
|
|
589
|
-
runtime.status.state = mlrun.
|
|
636
|
+
runtime.status.state = mlrun.common.schemas.FunctionState.ready
|
|
590
637
|
return True
|
|
591
638
|
|
|
592
639
|
if status.startswith("build:"):
|
|
593
|
-
runtime.status.state = mlrun.
|
|
640
|
+
runtime.status.state = mlrun.common.schemas.FunctionState.deploying
|
|
594
641
|
runtime.status.build_pod = status[6:]
|
|
595
642
|
# using the base_image, and not the enriched one so we won't have the client version in the image, useful for
|
|
596
643
|
# exports and other cases where we don't want to have the client version in the image, but rather enriched on
|
|
@@ -598,48 +645,34 @@ def build_runtime(
|
|
|
598
645
|
runtime.spec.build.base_image = base_image
|
|
599
646
|
return False
|
|
600
647
|
|
|
601
|
-
logger.info(f"build completed with {status}")
|
|
648
|
+
mlrun.utils.logger.info(f"build completed with {status}")
|
|
602
649
|
if status in ["failed", "error"]:
|
|
603
|
-
runtime.status.state = mlrun.
|
|
650
|
+
runtime.status.state = mlrun.common.schemas.FunctionState.error
|
|
604
651
|
return False
|
|
605
652
|
|
|
606
653
|
local = "" if build.secret or build.image.startswith(".") else "."
|
|
607
654
|
runtime.spec.image = local + build.image
|
|
608
|
-
runtime.status.state = mlrun.
|
|
655
|
+
runtime.status.state = mlrun.common.schemas.FunctionState.ready
|
|
609
656
|
return True
|
|
610
657
|
|
|
611
658
|
|
|
612
|
-
def
|
|
613
|
-
k8s = get_k8s_helper()
|
|
614
|
-
secret_name = k8s.get_project_secret_name(project)
|
|
615
|
-
existing_secret_keys = k8s.get_project_secret_keys(project, filter_internal=True)
|
|
616
|
-
|
|
617
|
-
# generate env list from builder env and project secrets
|
|
618
|
-
env = []
|
|
619
|
-
for key in existing_secret_keys:
|
|
620
|
-
if key not in builder_env:
|
|
621
|
-
value_from = client.V1EnvVarSource(
|
|
622
|
-
secret_key_ref=client.V1SecretKeySelector(name=secret_name, key=key)
|
|
623
|
-
)
|
|
624
|
-
env.append(client.V1EnvVar(name=key, value_from=value_from))
|
|
625
|
-
for key, value in builder_env.items():
|
|
626
|
-
env.append(client.V1EnvVar(name=key, value=value))
|
|
627
|
-
return env
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
def _resolve_image_target_and_registry_secret(
|
|
659
|
+
def resolve_image_target_and_registry_secret(
|
|
631
660
|
image_target: str, registry: str = None, secret_name: str = None
|
|
632
661
|
) -> (str, str):
|
|
633
662
|
if registry:
|
|
634
663
|
return "/".join([registry, image_target]), secret_name
|
|
635
664
|
|
|
636
665
|
# if dest starts with a dot, we add the configured registry to the start of the dest
|
|
637
|
-
if image_target.startswith(
|
|
666
|
+
if image_target.startswith(
|
|
667
|
+
mlrun.common.constants.IMAGE_NAME_ENRICH_REGISTRY_PREFIX
|
|
668
|
+
):
|
|
638
669
|
|
|
639
670
|
# remove prefix from image name
|
|
640
|
-
image_target = image_target[
|
|
671
|
+
image_target = image_target[
|
|
672
|
+
len(mlrun.common.constants.IMAGE_NAME_ENRICH_REGISTRY_PREFIX) :
|
|
673
|
+
]
|
|
641
674
|
|
|
642
|
-
registry, repository = get_parsed_docker_registry()
|
|
675
|
+
registry, repository = mlrun.utils.get_parsed_docker_registry()
|
|
643
676
|
secret_name = secret_name or config.httpdb.builder.docker_registry_secret
|
|
644
677
|
if not registry:
|
|
645
678
|
raise ValueError(
|
|
@@ -652,4 +685,64 @@ def _resolve_image_target_and_registry_secret(
|
|
|
652
685
|
|
|
653
686
|
return "/".join(image_target_components), secret_name
|
|
654
687
|
|
|
688
|
+
image_target = remove_image_protocol_prefix(image_target)
|
|
689
|
+
|
|
655
690
|
return image_target, secret_name
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
def _generate_builder_env(project, builder_env):
|
|
694
|
+
k8s = mlrun.api.utils.singletons.k8s.get_k8s_helper(silent=False)
|
|
695
|
+
secret_name = k8s.get_project_secret_name(project)
|
|
696
|
+
existing_secret_keys = k8s.get_project_secret_keys(project, filter_internal=True)
|
|
697
|
+
|
|
698
|
+
# generate env list from builder env and project secrets
|
|
699
|
+
env = []
|
|
700
|
+
for key in existing_secret_keys:
|
|
701
|
+
if key not in builder_env:
|
|
702
|
+
value_from = client.V1EnvVarSource(
|
|
703
|
+
secret_key_ref=client.V1SecretKeySelector(name=secret_name, key=key)
|
|
704
|
+
)
|
|
705
|
+
env.append(client.V1EnvVar(name=key, value_from=value_from))
|
|
706
|
+
for key, value in builder_env.items():
|
|
707
|
+
env.append(client.V1EnvVar(name=key, value=value))
|
|
708
|
+
return env
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
def _resolve_build_requirements(
|
|
712
|
+
requirements: typing.Union[typing.List, str],
|
|
713
|
+
commands: typing.List,
|
|
714
|
+
with_mlrun: bool,
|
|
715
|
+
mlrun_version_specifier: typing.Optional[str],
|
|
716
|
+
client_version: typing.Optional[str],
|
|
717
|
+
):
|
|
718
|
+
"""
|
|
719
|
+
Resolve build requirements list, requirements path and commands.
|
|
720
|
+
If mlrun requirement is needed, we add a pip upgrade command to the commands list (prerequisite).
|
|
721
|
+
"""
|
|
722
|
+
requirements_path = "/empty/requirements.txt"
|
|
723
|
+
if requirements and isinstance(requirements, list):
|
|
724
|
+
requirements_list = requirements
|
|
725
|
+
else:
|
|
726
|
+
requirements_list = []
|
|
727
|
+
requirements_path = requirements or requirements_path
|
|
728
|
+
commands = commands or []
|
|
729
|
+
|
|
730
|
+
if with_mlrun:
|
|
731
|
+
# mlrun prerequisite - upgrade pip
|
|
732
|
+
upgrade_pip_command = resolve_upgrade_pip_command(commands)
|
|
733
|
+
if upgrade_pip_command:
|
|
734
|
+
commands.append(upgrade_pip_command)
|
|
735
|
+
|
|
736
|
+
mlrun_version = resolve_mlrun_install_command_version(
|
|
737
|
+
mlrun_version_specifier, client_version, commands
|
|
738
|
+
)
|
|
739
|
+
|
|
740
|
+
# mlrun must be installed with other python requirements in the same pip command to avoid version conflicts
|
|
741
|
+
if mlrun_version:
|
|
742
|
+
requirements_list.insert(0, mlrun_version)
|
|
743
|
+
|
|
744
|
+
if not requirements_list:
|
|
745
|
+
# no requirements, we don't need a requirements file
|
|
746
|
+
requirements_path = ""
|
|
747
|
+
|
|
748
|
+
return commands, requirements_list, requirements_path
|
mlrun/api/utils/clients/chief.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2023 Iguazio
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -21,8 +21,8 @@ import urllib.parse
|
|
|
21
21
|
import aiohttp
|
|
22
22
|
import fastapi
|
|
23
23
|
|
|
24
|
-
import mlrun.api.schemas
|
|
25
24
|
import mlrun.api.utils.projects.remotes.follower
|
|
25
|
+
import mlrun.common.schemas
|
|
26
26
|
import mlrun.errors
|
|
27
27
|
import mlrun.utils.singleton
|
|
28
28
|
from mlrun.utils import logger
|
|
@@ -157,7 +157,7 @@ class Client(
|
|
|
157
157
|
|
|
158
158
|
async def get_clusterization_spec(
|
|
159
159
|
self, return_fastapi_response: bool = True, raise_on_failure: bool = False
|
|
160
|
-
) -> typing.Union[fastapi.Response, mlrun.
|
|
160
|
+
) -> typing.Union[fastapi.Response, mlrun.common.schemas.ClusterizationSpec]:
|
|
161
161
|
"""
|
|
162
162
|
This method is used both for proxying requests from worker to chief and for aligning the worker state
|
|
163
163
|
with the clusterization spec brought from the chief
|
|
@@ -172,7 +172,22 @@ class Client(
|
|
|
172
172
|
chief_response
|
|
173
173
|
)
|
|
174
174
|
|
|
175
|
-
return mlrun.
|
|
175
|
+
return mlrun.common.schemas.ClusterizationSpec(
|
|
176
|
+
**(await chief_response.json())
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
async def set_schedule_notifications(
|
|
180
|
+
self, project: str, schedule_name: str, request: fastapi.Request, json: dict
|
|
181
|
+
) -> fastapi.Response:
|
|
182
|
+
"""
|
|
183
|
+
Schedules are running only on chief
|
|
184
|
+
"""
|
|
185
|
+
return await self._proxy_request_to_chief(
|
|
186
|
+
"PUT",
|
|
187
|
+
f"projects/{project}/schedules/{schedule_name}/notifications",
|
|
188
|
+
request,
|
|
189
|
+
json,
|
|
190
|
+
)
|
|
176
191
|
|
|
177
192
|
async def _proxy_request_to_chief(
|
|
178
193
|
self,
|