mlrun 1.6.4rc7__py3-none-any.whl → 1.7.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 +11 -1
- mlrun/__main__.py +40 -122
- mlrun/alerts/__init__.py +15 -0
- mlrun/alerts/alert.py +248 -0
- mlrun/api/schemas/__init__.py +5 -4
- mlrun/artifacts/__init__.py +8 -3
- mlrun/artifacts/base.py +47 -257
- mlrun/artifacts/dataset.py +11 -192
- mlrun/artifacts/manager.py +79 -47
- mlrun/artifacts/model.py +31 -159
- mlrun/artifacts/plots.py +23 -380
- mlrun/common/constants.py +74 -1
- mlrun/common/db/sql_session.py +5 -5
- mlrun/common/formatters/__init__.py +21 -0
- mlrun/common/formatters/artifact.py +45 -0
- mlrun/common/formatters/base.py +113 -0
- mlrun/common/formatters/feature_set.py +33 -0
- mlrun/common/formatters/function.py +46 -0
- mlrun/common/formatters/pipeline.py +53 -0
- mlrun/common/formatters/project.py +51 -0
- mlrun/common/formatters/run.py +29 -0
- mlrun/common/helpers.py +12 -3
- mlrun/common/model_monitoring/helpers.py +9 -5
- mlrun/{runtimes → common/runtimes}/constants.py +37 -9
- mlrun/common/schemas/__init__.py +31 -5
- mlrun/common/schemas/alert.py +202 -0
- mlrun/common/schemas/api_gateway.py +196 -0
- mlrun/common/schemas/artifact.py +25 -4
- mlrun/common/schemas/auth.py +16 -5
- mlrun/common/schemas/background_task.py +1 -1
- mlrun/common/schemas/client_spec.py +4 -2
- mlrun/common/schemas/common.py +7 -4
- mlrun/common/schemas/constants.py +3 -0
- mlrun/common/schemas/feature_store.py +74 -44
- mlrun/common/schemas/frontend_spec.py +15 -7
- mlrun/common/schemas/function.py +12 -1
- mlrun/common/schemas/hub.py +11 -18
- mlrun/common/schemas/memory_reports.py +2 -2
- mlrun/common/schemas/model_monitoring/__init__.py +20 -4
- mlrun/common/schemas/model_monitoring/constants.py +123 -42
- mlrun/common/schemas/model_monitoring/grafana.py +13 -9
- mlrun/common/schemas/model_monitoring/model_endpoints.py +101 -54
- mlrun/common/schemas/notification.py +71 -14
- mlrun/common/schemas/object.py +2 -2
- mlrun/{model_monitoring/controller_handler.py → common/schemas/pagination.py} +9 -12
- mlrun/common/schemas/pipeline.py +8 -1
- mlrun/common/schemas/project.py +69 -18
- mlrun/common/schemas/runs.py +7 -1
- mlrun/common/schemas/runtime_resource.py +8 -12
- mlrun/common/schemas/schedule.py +4 -4
- mlrun/common/schemas/tag.py +1 -2
- mlrun/common/schemas/workflow.py +12 -4
- mlrun/common/types.py +14 -1
- mlrun/config.py +154 -69
- mlrun/data_types/data_types.py +6 -1
- mlrun/data_types/spark.py +2 -2
- mlrun/data_types/to_pandas.py +67 -37
- mlrun/datastore/__init__.py +6 -8
- mlrun/datastore/alibaba_oss.py +131 -0
- mlrun/datastore/azure_blob.py +143 -42
- mlrun/datastore/base.py +102 -58
- mlrun/datastore/datastore.py +34 -13
- mlrun/datastore/datastore_profile.py +146 -20
- mlrun/datastore/dbfs_store.py +3 -7
- mlrun/datastore/filestore.py +1 -4
- mlrun/datastore/google_cloud_storage.py +97 -33
- mlrun/datastore/hdfs.py +56 -0
- mlrun/datastore/inmem.py +6 -3
- mlrun/datastore/redis.py +7 -2
- mlrun/datastore/s3.py +34 -12
- mlrun/datastore/snowflake_utils.py +45 -0
- mlrun/datastore/sources.py +303 -111
- mlrun/datastore/spark_utils.py +31 -2
- mlrun/datastore/store_resources.py +9 -7
- mlrun/datastore/storeytargets.py +151 -0
- mlrun/datastore/targets.py +453 -176
- mlrun/datastore/utils.py +72 -58
- mlrun/datastore/v3io.py +6 -1
- mlrun/db/base.py +274 -41
- mlrun/db/factory.py +1 -1
- mlrun/db/httpdb.py +893 -225
- mlrun/db/nopdb.py +291 -33
- mlrun/errors.py +36 -6
- mlrun/execution.py +115 -42
- mlrun/feature_store/__init__.py +0 -2
- mlrun/feature_store/api.py +65 -73
- mlrun/feature_store/common.py +7 -12
- mlrun/feature_store/feature_set.py +76 -55
- mlrun/feature_store/feature_vector.py +39 -31
- mlrun/feature_store/ingestion.py +7 -6
- mlrun/feature_store/retrieval/base.py +16 -11
- mlrun/feature_store/retrieval/dask_merger.py +2 -0
- mlrun/feature_store/retrieval/job.py +13 -4
- mlrun/feature_store/retrieval/local_merger.py +2 -0
- mlrun/feature_store/retrieval/spark_merger.py +24 -32
- mlrun/feature_store/steps.py +45 -34
- mlrun/features.py +11 -21
- mlrun/frameworks/_common/artifacts_library.py +9 -9
- mlrun/frameworks/_common/mlrun_interface.py +5 -5
- mlrun/frameworks/_common/model_handler.py +48 -48
- mlrun/frameworks/_common/plan.py +5 -6
- mlrun/frameworks/_common/producer.py +3 -4
- mlrun/frameworks/_common/utils.py +5 -5
- mlrun/frameworks/_dl_common/loggers/logger.py +6 -7
- mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +9 -9
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +23 -47
- mlrun/frameworks/_ml_common/artifacts_library.py +1 -2
- mlrun/frameworks/_ml_common/loggers/logger.py +3 -4
- mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +4 -5
- mlrun/frameworks/_ml_common/model_handler.py +24 -24
- mlrun/frameworks/_ml_common/pkl_model_server.py +2 -2
- mlrun/frameworks/_ml_common/plan.py +2 -2
- mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +2 -3
- mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +2 -3
- mlrun/frameworks/_ml_common/plans/dataset_plan.py +3 -3
- mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +3 -3
- mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +4 -4
- mlrun/frameworks/_ml_common/utils.py +4 -4
- mlrun/frameworks/auto_mlrun/auto_mlrun.py +9 -9
- mlrun/frameworks/huggingface/model_server.py +4 -4
- mlrun/frameworks/lgbm/__init__.py +33 -33
- mlrun/frameworks/lgbm/callbacks/callback.py +2 -4
- mlrun/frameworks/lgbm/callbacks/logging_callback.py +4 -5
- mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +4 -5
- mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -3
- mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +6 -6
- mlrun/frameworks/lgbm/model_handler.py +10 -10
- mlrun/frameworks/lgbm/model_server.py +6 -6
- mlrun/frameworks/lgbm/utils.py +5 -5
- mlrun/frameworks/onnx/dataset.py +8 -8
- mlrun/frameworks/onnx/mlrun_interface.py +3 -3
- mlrun/frameworks/onnx/model_handler.py +6 -6
- mlrun/frameworks/onnx/model_server.py +7 -7
- mlrun/frameworks/parallel_coordinates.py +6 -6
- mlrun/frameworks/pytorch/__init__.py +18 -18
- mlrun/frameworks/pytorch/callbacks/callback.py +4 -5
- mlrun/frameworks/pytorch/callbacks/logging_callback.py +17 -17
- mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +11 -11
- mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +23 -29
- mlrun/frameworks/pytorch/callbacks_handler.py +38 -38
- mlrun/frameworks/pytorch/mlrun_interface.py +20 -20
- mlrun/frameworks/pytorch/model_handler.py +17 -17
- mlrun/frameworks/pytorch/model_server.py +7 -7
- mlrun/frameworks/sklearn/__init__.py +13 -13
- mlrun/frameworks/sklearn/estimator.py +4 -4
- mlrun/frameworks/sklearn/metrics_library.py +14 -14
- mlrun/frameworks/sklearn/mlrun_interface.py +16 -9
- mlrun/frameworks/sklearn/model_handler.py +2 -2
- mlrun/frameworks/tf_keras/__init__.py +10 -7
- mlrun/frameworks/tf_keras/callbacks/logging_callback.py +15 -15
- mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +11 -11
- mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +19 -23
- mlrun/frameworks/tf_keras/mlrun_interface.py +9 -11
- mlrun/frameworks/tf_keras/model_handler.py +14 -14
- mlrun/frameworks/tf_keras/model_server.py +6 -6
- mlrun/frameworks/xgboost/__init__.py +13 -13
- mlrun/frameworks/xgboost/model_handler.py +6 -6
- mlrun/k8s_utils.py +61 -17
- mlrun/launcher/__init__.py +1 -1
- mlrun/launcher/base.py +16 -15
- mlrun/launcher/client.py +13 -11
- mlrun/launcher/factory.py +1 -1
- mlrun/launcher/local.py +23 -13
- mlrun/launcher/remote.py +17 -10
- mlrun/lists.py +7 -6
- mlrun/model.py +478 -103
- mlrun/model_monitoring/__init__.py +1 -1
- mlrun/model_monitoring/api.py +163 -371
- mlrun/{runtimes/mpijob/v1alpha1.py → model_monitoring/applications/__init__.py} +9 -15
- mlrun/model_monitoring/applications/_application_steps.py +188 -0
- mlrun/model_monitoring/applications/base.py +108 -0
- mlrun/model_monitoring/applications/context.py +341 -0
- mlrun/model_monitoring/{evidently_application.py → applications/evidently_base.py} +27 -22
- mlrun/model_monitoring/applications/histogram_data_drift.py +354 -0
- mlrun/model_monitoring/applications/results.py +99 -0
- mlrun/model_monitoring/controller.py +131 -278
- mlrun/model_monitoring/db/__init__.py +18 -0
- mlrun/model_monitoring/db/stores/__init__.py +136 -0
- mlrun/model_monitoring/db/stores/base/__init__.py +15 -0
- mlrun/model_monitoring/db/stores/base/store.py +213 -0
- mlrun/model_monitoring/db/stores/sqldb/__init__.py +13 -0
- mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +71 -0
- mlrun/model_monitoring/db/stores/sqldb/models/base.py +190 -0
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +103 -0
- mlrun/model_monitoring/{stores/models/mysql.py → db/stores/sqldb/models/sqlite.py} +19 -13
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +659 -0
- mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +13 -0
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +726 -0
- mlrun/model_monitoring/db/tsdb/__init__.py +105 -0
- mlrun/model_monitoring/db/tsdb/base.py +448 -0
- mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
- mlrun/model_monitoring/db/tsdb/tdengine/__init__.py +15 -0
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +279 -0
- mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +42 -0
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +507 -0
- mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
- mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +158 -0
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +849 -0
- mlrun/model_monitoring/features_drift_table.py +134 -106
- mlrun/model_monitoring/helpers.py +199 -55
- mlrun/model_monitoring/metrics/__init__.py +13 -0
- mlrun/model_monitoring/metrics/histogram_distance.py +127 -0
- mlrun/model_monitoring/model_endpoint.py +3 -2
- mlrun/model_monitoring/stream_processing.py +131 -398
- mlrun/model_monitoring/tracking_policy.py +9 -2
- mlrun/model_monitoring/writer.py +161 -125
- mlrun/package/__init__.py +6 -6
- mlrun/package/context_handler.py +5 -5
- mlrun/package/packager.py +7 -7
- mlrun/package/packagers/default_packager.py +8 -8
- mlrun/package/packagers/numpy_packagers.py +15 -15
- mlrun/package/packagers/pandas_packagers.py +5 -5
- mlrun/package/packagers/python_standard_library_packagers.py +10 -10
- mlrun/package/packagers_manager.py +19 -23
- mlrun/package/utils/_formatter.py +6 -6
- mlrun/package/utils/_pickler.py +2 -2
- mlrun/package/utils/_supported_format.py +4 -4
- mlrun/package/utils/log_hint_utils.py +2 -2
- mlrun/package/utils/type_hint_utils.py +4 -9
- mlrun/platforms/__init__.py +11 -10
- mlrun/platforms/iguazio.py +24 -203
- mlrun/projects/operations.py +52 -25
- mlrun/projects/pipelines.py +191 -197
- mlrun/projects/project.py +1227 -400
- mlrun/render.py +16 -19
- mlrun/run.py +209 -184
- mlrun/runtimes/__init__.py +83 -15
- mlrun/runtimes/base.py +51 -35
- mlrun/runtimes/daskjob.py +17 -10
- mlrun/runtimes/databricks_job/databricks_cancel_task.py +1 -1
- mlrun/runtimes/databricks_job/databricks_runtime.py +8 -7
- mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
- mlrun/runtimes/funcdoc.py +1 -29
- mlrun/runtimes/function_reference.py +1 -1
- mlrun/runtimes/kubejob.py +34 -128
- mlrun/runtimes/local.py +40 -11
- mlrun/runtimes/mpijob/__init__.py +0 -20
- mlrun/runtimes/mpijob/abstract.py +9 -10
- mlrun/runtimes/mpijob/v1.py +1 -1
- mlrun/{model_monitoring/stores/models/sqlite.py → runtimes/nuclio/__init__.py} +7 -9
- mlrun/runtimes/nuclio/api_gateway.py +769 -0
- mlrun/runtimes/nuclio/application/__init__.py +15 -0
- mlrun/runtimes/nuclio/application/application.py +758 -0
- mlrun/runtimes/nuclio/application/reverse_proxy.go +95 -0
- mlrun/runtimes/{function.py → nuclio/function.py} +200 -83
- mlrun/runtimes/{nuclio.py → nuclio/nuclio.py} +6 -6
- mlrun/runtimes/{serving.py → nuclio/serving.py} +65 -68
- mlrun/runtimes/pod.py +281 -101
- mlrun/runtimes/remotesparkjob.py +12 -9
- mlrun/runtimes/sparkjob/spark3job.py +67 -51
- mlrun/runtimes/utils.py +41 -75
- mlrun/secrets.py +9 -5
- mlrun/serving/__init__.py +8 -1
- mlrun/serving/remote.py +2 -7
- mlrun/serving/routers.py +85 -69
- mlrun/serving/server.py +69 -44
- mlrun/serving/states.py +209 -36
- mlrun/serving/utils.py +22 -14
- mlrun/serving/v1_serving.py +6 -7
- mlrun/serving/v2_serving.py +129 -54
- mlrun/track/tracker.py +2 -1
- mlrun/track/tracker_manager.py +3 -3
- mlrun/track/trackers/mlflow_tracker.py +6 -2
- mlrun/utils/async_http.py +6 -8
- mlrun/utils/azure_vault.py +1 -1
- mlrun/utils/clones.py +1 -2
- mlrun/utils/condition_evaluator.py +3 -3
- mlrun/utils/db.py +21 -3
- mlrun/utils/helpers.py +405 -225
- mlrun/utils/http.py +3 -6
- mlrun/utils/logger.py +112 -16
- mlrun/utils/notifications/notification/__init__.py +17 -13
- mlrun/utils/notifications/notification/base.py +50 -2
- mlrun/utils/notifications/notification/console.py +2 -0
- mlrun/utils/notifications/notification/git.py +24 -1
- mlrun/utils/notifications/notification/ipython.py +3 -1
- mlrun/utils/notifications/notification/slack.py +96 -21
- mlrun/utils/notifications/notification/webhook.py +59 -2
- mlrun/utils/notifications/notification_pusher.py +149 -30
- mlrun/utils/regex.py +9 -0
- mlrun/utils/retryer.py +208 -0
- mlrun/utils/singleton.py +1 -1
- mlrun/utils/v3io_clients.py +4 -6
- mlrun/utils/version/version.json +2 -2
- mlrun/utils/version/version.py +2 -6
- mlrun-1.7.0.dist-info/METADATA +378 -0
- mlrun-1.7.0.dist-info/RECORD +351 -0
- {mlrun-1.6.4rc7.dist-info → mlrun-1.7.0.dist-info}/WHEEL +1 -1
- mlrun/feature_store/retrieval/conversion.py +0 -273
- mlrun/kfpops.py +0 -868
- mlrun/model_monitoring/application.py +0 -310
- mlrun/model_monitoring/batch.py +0 -1095
- mlrun/model_monitoring/prometheus.py +0 -219
- mlrun/model_monitoring/stores/__init__.py +0 -111
- mlrun/model_monitoring/stores/kv_model_endpoint_store.py +0 -576
- mlrun/model_monitoring/stores/model_endpoint_store.py +0 -147
- mlrun/model_monitoring/stores/models/__init__.py +0 -27
- mlrun/model_monitoring/stores/models/base.py +0 -84
- mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -384
- mlrun/platforms/other.py +0 -306
- mlrun-1.6.4rc7.dist-info/METADATA +0 -272
- mlrun-1.6.4rc7.dist-info/RECORD +0 -314
- {mlrun-1.6.4rc7.dist-info → mlrun-1.7.0.dist-info}/LICENSE +0 -0
- {mlrun-1.6.4rc7.dist-info → mlrun-1.7.0.dist-info}/entry_points.txt +0 -0
- {mlrun-1.6.4rc7.dist-info → mlrun-1.7.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// Copyright 2024 Iguazio
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
package main
|
|
15
|
+
|
|
16
|
+
import (
|
|
17
|
+
"bytes"
|
|
18
|
+
"fmt"
|
|
19
|
+
"net/http"
|
|
20
|
+
"net/http/httptest"
|
|
21
|
+
"net/http/httputil"
|
|
22
|
+
"net/url"
|
|
23
|
+
"os"
|
|
24
|
+
"strings"
|
|
25
|
+
|
|
26
|
+
nuclio "github.com/nuclio/nuclio-sdk-go"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
func Handler(context *nuclio.Context, event nuclio.Event) (interface{}, error) {
|
|
30
|
+
reverseProxy := context.UserData.(map[string]interface{})["reverseProxy"].(*httputil.ReverseProxy)
|
|
31
|
+
sidecarUrl := context.UserData.(map[string]interface{})["server"].(string)
|
|
32
|
+
|
|
33
|
+
// populate reverse proxy http request
|
|
34
|
+
httpRequest, err := http.NewRequest(event.GetMethod(), event.GetPath(), bytes.NewReader(event.GetBody()))
|
|
35
|
+
if err != nil {
|
|
36
|
+
context.Logger.ErrorWith("Failed to create a reverse proxy request")
|
|
37
|
+
return nil, err
|
|
38
|
+
}
|
|
39
|
+
for k, v := range event.GetHeaders() {
|
|
40
|
+
httpRequest.Header[k] = []string{v.(string)}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// populate query params
|
|
44
|
+
query := httpRequest.URL.Query()
|
|
45
|
+
for k, v := range event.GetFields() {
|
|
46
|
+
query.Set(k, v.(string))
|
|
47
|
+
}
|
|
48
|
+
httpRequest.URL.RawQuery = query.Encode()
|
|
49
|
+
|
|
50
|
+
recorder := httptest.NewRecorder()
|
|
51
|
+
reverseProxy.ServeHTTP(recorder, httpRequest)
|
|
52
|
+
|
|
53
|
+
// send request to sidecar
|
|
54
|
+
context.Logger.DebugWith("Forwarding request to sidecar", "sidecarUrl", sidecarUrl, "query", httpRequest.URL.Query())
|
|
55
|
+
response := recorder.Result()
|
|
56
|
+
|
|
57
|
+
headers := make(map[string]interface{})
|
|
58
|
+
for key, value := range response.Header {
|
|
59
|
+
headers[key] = value[0]
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// let the processor calculate the content length
|
|
63
|
+
delete(headers, "Content-Length")
|
|
64
|
+
return nuclio.Response{
|
|
65
|
+
StatusCode: response.StatusCode,
|
|
66
|
+
Body: recorder.Body.Bytes(),
|
|
67
|
+
ContentType: response.Header.Get("Content-Type"),
|
|
68
|
+
Headers: headers,
|
|
69
|
+
}, nil
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
func InitContext(context *nuclio.Context) error {
|
|
73
|
+
sidecarHost := os.Getenv("SIDECAR_HOST")
|
|
74
|
+
sidecarPort := os.Getenv("SIDECAR_PORT")
|
|
75
|
+
if sidecarHost == "" {
|
|
76
|
+
sidecarHost = "http://localhost"
|
|
77
|
+
} else if !strings.Contains(sidecarHost, "://") {
|
|
78
|
+
sidecarHost = fmt.Sprintf("http://%s", sidecarHost)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// url for request forwarding
|
|
82
|
+
sidecarUrl := fmt.Sprintf("%s:%s", sidecarHost, sidecarPort)
|
|
83
|
+
parsedURL, err := url.Parse(sidecarUrl)
|
|
84
|
+
if err != nil {
|
|
85
|
+
context.Logger.ErrorWith("Failed to parse sidecar url", "sidecarUrl", sidecarUrl)
|
|
86
|
+
return err
|
|
87
|
+
}
|
|
88
|
+
reverseProxy := httputil.NewSingleHostReverseProxy(parsedURL)
|
|
89
|
+
|
|
90
|
+
context.UserData = map[string]interface{}{
|
|
91
|
+
"server": sidecarUrl,
|
|
92
|
+
"reverseProxy": reverseProxy,
|
|
93
|
+
}
|
|
94
|
+
return nil
|
|
95
|
+
}
|
|
@@ -19,12 +19,16 @@ import warnings
|
|
|
19
19
|
from datetime import datetime
|
|
20
20
|
from time import sleep
|
|
21
21
|
|
|
22
|
+
import inflection
|
|
22
23
|
import nuclio
|
|
23
24
|
import nuclio.utils
|
|
24
25
|
import requests
|
|
25
26
|
import semver
|
|
26
27
|
from aiohttp.client import ClientSession
|
|
27
28
|
from kubernetes import client
|
|
29
|
+
from mlrun_pipelines.common.mounts import VolumeMount
|
|
30
|
+
from mlrun_pipelines.common.ops import deploy_op
|
|
31
|
+
from mlrun_pipelines.mounts import mount_v3io, v3io_cred
|
|
28
32
|
from nuclio.deploy import find_dashboard_url, get_deploy_status
|
|
29
33
|
from nuclio.triggers import V3IOStreamTrigger
|
|
30
34
|
|
|
@@ -34,56 +38,27 @@ import mlrun.k8s_utils
|
|
|
34
38
|
import mlrun.utils
|
|
35
39
|
import mlrun.utils.helpers
|
|
36
40
|
from mlrun.common.schemas import AuthInfo
|
|
37
|
-
|
|
38
|
-
from
|
|
39
|
-
from
|
|
40
|
-
from
|
|
41
|
-
from
|
|
42
|
-
from ..model import RunObject
|
|
43
|
-
from ..platforms.iguazio import (
|
|
44
|
-
VolumeMount,
|
|
45
|
-
mount_v3io,
|
|
41
|
+
from mlrun.config import config as mlconf
|
|
42
|
+
from mlrun.errors import err_to_str
|
|
43
|
+
from mlrun.lists import RunList
|
|
44
|
+
from mlrun.model import RunObject
|
|
45
|
+
from mlrun.platforms.iguazio import (
|
|
46
46
|
parse_path,
|
|
47
47
|
split_path,
|
|
48
|
-
v3io_cred,
|
|
49
48
|
)
|
|
50
|
-
from
|
|
51
|
-
from .
|
|
52
|
-
from .
|
|
53
|
-
from .utils import
|
|
49
|
+
from mlrun.runtimes.base import FunctionStatus, RunError
|
|
50
|
+
from mlrun.runtimes.pod import KubeResource, KubeResourceSpec
|
|
51
|
+
from mlrun.runtimes.utils import get_item_name, log_std
|
|
52
|
+
from mlrun.utils import get_in, logger, update_in
|
|
54
53
|
|
|
55
54
|
|
|
56
55
|
def validate_nuclio_version_compatibility(*min_versions):
|
|
57
56
|
"""
|
|
58
57
|
:param min_versions: Valid minimum version(s) required, assuming no 2 versions has equal major and minor.
|
|
59
58
|
"""
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
try:
|
|
64
|
-
parsed_current_version = semver.VersionInfo.parse(mlconf.nuclio_version)
|
|
65
|
-
except ValueError:
|
|
66
|
-
# only log when version is set but invalid
|
|
67
|
-
if mlconf.nuclio_version:
|
|
68
|
-
logger.warning(
|
|
69
|
-
"Unable to parse nuclio version, assuming compatibility",
|
|
70
|
-
nuclio_version=mlconf.nuclio_version,
|
|
71
|
-
min_versions=min_versions,
|
|
72
|
-
)
|
|
73
|
-
return True
|
|
74
|
-
|
|
75
|
-
parsed_min_versions.sort(reverse=True)
|
|
76
|
-
for parsed_min_version in parsed_min_versions:
|
|
77
|
-
if (
|
|
78
|
-
parsed_current_version.major == parsed_min_version.major
|
|
79
|
-
and parsed_current_version.minor == parsed_min_version.minor
|
|
80
|
-
and parsed_current_version.patch < parsed_min_version.patch
|
|
81
|
-
):
|
|
82
|
-
return False
|
|
83
|
-
|
|
84
|
-
if parsed_current_version >= parsed_min_version:
|
|
85
|
-
return True
|
|
86
|
-
return False
|
|
59
|
+
return mlrun.utils.helpers.validate_component_version_compatibility(
|
|
60
|
+
"nuclio", *min_versions
|
|
61
|
+
)
|
|
87
62
|
|
|
88
63
|
|
|
89
64
|
def min_nuclio_versions(*versions):
|
|
@@ -92,9 +67,13 @@ def min_nuclio_versions(*versions):
|
|
|
92
67
|
if validate_nuclio_version_compatibility(*versions):
|
|
93
68
|
return function(*args, **kwargs)
|
|
94
69
|
|
|
70
|
+
if function.__name__ == "__init__":
|
|
71
|
+
name = inflection.titleize(function.__qualname__.split(".")[0])
|
|
72
|
+
else:
|
|
73
|
+
name = function.__qualname__
|
|
74
|
+
|
|
95
75
|
message = (
|
|
96
|
-
f"{
|
|
97
|
-
f"nuclio {mlconf.nuclio_version}, please upgrade."
|
|
76
|
+
f"'{name}' function requires Nuclio v{' or v'.join(versions)} or higher"
|
|
98
77
|
)
|
|
99
78
|
raise mlrun.errors.MLRunIncompatibleVersionError(message)
|
|
100
79
|
|
|
@@ -292,6 +271,10 @@ class RemoteRuntime(KubeResource):
|
|
|
292
271
|
def status(self, status):
|
|
293
272
|
self._status = self._verify_dict(status, "status", NuclioStatus)
|
|
294
273
|
|
|
274
|
+
def pre_deploy_validation(self):
|
|
275
|
+
if self.metadata.tag:
|
|
276
|
+
mlrun.utils.validate_tag_name(self.metadata.tag, "function.metadata.tag")
|
|
277
|
+
|
|
295
278
|
def set_config(self, key, value):
|
|
296
279
|
self.spec.config[key] = value
|
|
297
280
|
return self
|
|
@@ -314,10 +297,37 @@ class RemoteRuntime(KubeResource):
|
|
|
314
297
|
"""
|
|
315
298
|
if hasattr(spec, "to_dict"):
|
|
316
299
|
spec = spec.to_dict()
|
|
300
|
+
|
|
301
|
+
self._validate_triggers(spec)
|
|
302
|
+
|
|
317
303
|
spec["name"] = name
|
|
318
304
|
self.spec.config[f"spec.triggers.{name}"] = spec
|
|
319
305
|
return self
|
|
320
306
|
|
|
307
|
+
def _validate_triggers(self, spec):
|
|
308
|
+
# ML-7763 / NUC-233
|
|
309
|
+
min_nuclio_version = "1.13.12"
|
|
310
|
+
if mlconf.nuclio_version and semver.VersionInfo.parse(
|
|
311
|
+
mlconf.nuclio_version
|
|
312
|
+
) < semver.VersionInfo.parse(min_nuclio_version):
|
|
313
|
+
explicit_ack_enabled = False
|
|
314
|
+
num_triggers = 0
|
|
315
|
+
trigger_name = spec.get("name", "UNKNOWN")
|
|
316
|
+
for key, config in [(f"spec.triggers.{trigger_name}", spec)] + list(
|
|
317
|
+
self.spec.config.items()
|
|
318
|
+
):
|
|
319
|
+
if key.startswith("spec.triggers."):
|
|
320
|
+
num_triggers += 1
|
|
321
|
+
explicit_ack_enabled = (
|
|
322
|
+
config.get("explicitAckMode", "disable") != "disable"
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
if num_triggers > 1 and explicit_ack_enabled:
|
|
326
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
327
|
+
"Multiple triggers cannot be used in conjunction with explicit ack. "
|
|
328
|
+
f"Please upgrade to nuclio {min_nuclio_version} or newer."
|
|
329
|
+
)
|
|
330
|
+
|
|
321
331
|
def with_source_archive(
|
|
322
332
|
self,
|
|
323
333
|
source,
|
|
@@ -343,17 +353,21 @@ class RemoteRuntime(KubeResource):
|
|
|
343
353
|
|
|
344
354
|
git::
|
|
345
355
|
|
|
346
|
-
fn.with_source_archive(
|
|
347
|
-
|
|
348
|
-
|
|
356
|
+
fn.with_source_archive(
|
|
357
|
+
"git://github.com/org/repo#my-branch",
|
|
358
|
+
handler="main:handler",
|
|
359
|
+
workdir="path/inside/repo",
|
|
360
|
+
)
|
|
349
361
|
|
|
350
362
|
s3::
|
|
351
363
|
|
|
352
364
|
fn.spec.nuclio_runtime = "golang"
|
|
353
|
-
fn.with_source_archive(
|
|
365
|
+
fn.with_source_archive(
|
|
366
|
+
"s3://my-bucket/path/in/bucket/my-functions-archive",
|
|
354
367
|
handler="my_func:Handler",
|
|
355
368
|
workdir="path/inside/functions/archive",
|
|
356
|
-
runtime="golang"
|
|
369
|
+
runtime="golang",
|
|
370
|
+
)
|
|
357
371
|
"""
|
|
358
372
|
self.spec.build.source = source
|
|
359
373
|
# update handler in function_handler
|
|
@@ -386,7 +400,7 @@ class RemoteRuntime(KubeResource):
|
|
|
386
400
|
workers: typing.Optional[int] = 8,
|
|
387
401
|
port: typing.Optional[int] = None,
|
|
388
402
|
host: typing.Optional[str] = None,
|
|
389
|
-
paths: typing.Optional[
|
|
403
|
+
paths: typing.Optional[list[str]] = None,
|
|
390
404
|
canary: typing.Optional[float] = None,
|
|
391
405
|
secret: typing.Optional[str] = None,
|
|
392
406
|
worker_timeout: typing.Optional[int] = None,
|
|
@@ -432,14 +446,8 @@ class RemoteRuntime(KubeResource):
|
|
|
432
446
|
raise ValueError(
|
|
433
447
|
"gateway timeout must be greater than the worker timeout"
|
|
434
448
|
)
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
)
|
|
438
|
-
annotations["nginx.ingress.kubernetes.io/proxy-read-timeout"] = (
|
|
439
|
-
f"{gateway_timeout}"
|
|
440
|
-
)
|
|
441
|
-
annotations["nginx.ingress.kubernetes.io/proxy-send-timeout"] = (
|
|
442
|
-
f"{gateway_timeout}"
|
|
449
|
+
mlrun.runtimes.utils.enrich_gateway_timeout_annotations(
|
|
450
|
+
annotations, gateway_timeout
|
|
443
451
|
)
|
|
444
452
|
|
|
445
453
|
trigger = nuclio.HttpTrigger(
|
|
@@ -460,6 +468,11 @@ class RemoteRuntime(KubeResource):
|
|
|
460
468
|
return self
|
|
461
469
|
|
|
462
470
|
def from_image(self, image):
|
|
471
|
+
"""
|
|
472
|
+
Deploy the function with an existing nuclio processor image.
|
|
473
|
+
|
|
474
|
+
:param image: image name
|
|
475
|
+
"""
|
|
463
476
|
config = nuclio.config.new_config()
|
|
464
477
|
update_in(
|
|
465
478
|
config,
|
|
@@ -510,6 +523,11 @@ class RemoteRuntime(KubeResource):
|
|
|
510
523
|
extra_attributes = extra_attributes or {}
|
|
511
524
|
if ack_window_size:
|
|
512
525
|
extra_attributes["ackWindowSize"] = ack_window_size
|
|
526
|
+
|
|
527
|
+
access_key = kwargs.pop("access_key", None)
|
|
528
|
+
if not access_key:
|
|
529
|
+
access_key = self._resolve_v3io_access_key()
|
|
530
|
+
|
|
513
531
|
self.add_trigger(
|
|
514
532
|
name,
|
|
515
533
|
V3IOStreamTrigger(
|
|
@@ -521,11 +539,14 @@ class RemoteRuntime(KubeResource):
|
|
|
521
539
|
webapi=endpoint or "http://v3io-webapi:8081",
|
|
522
540
|
extra_attributes=extra_attributes,
|
|
523
541
|
read_batch_size=256,
|
|
542
|
+
access_key=access_key,
|
|
524
543
|
**kwargs,
|
|
525
544
|
),
|
|
526
545
|
)
|
|
527
|
-
self.spec.min_replicas
|
|
528
|
-
|
|
546
|
+
if self.spec.min_replicas != shards or self.spec.max_replicas != shards:
|
|
547
|
+
logger.warning(f"Setting function replicas to {shards}")
|
|
548
|
+
self.spec.min_replicas = shards
|
|
549
|
+
self.spec.max_replicas = shards
|
|
529
550
|
|
|
530
551
|
def deploy(
|
|
531
552
|
self,
|
|
@@ -541,11 +562,16 @@ class RemoteRuntime(KubeResource):
|
|
|
541
562
|
:param project: project name
|
|
542
563
|
:param tag: function tag
|
|
543
564
|
:param verbose: set True for verbose logging
|
|
544
|
-
:param auth_info: service AuthInfo
|
|
565
|
+
:param auth_info: service AuthInfo (deprecated and ignored)
|
|
545
566
|
:param builder_env: env vars dict for source archive config/credentials e.g. builder_env={"GIT_TOKEN": token}
|
|
546
567
|
:param force_build: set True for force building the image
|
|
547
568
|
"""
|
|
548
|
-
|
|
569
|
+
if auth_info:
|
|
570
|
+
# TODO: remove in 1.9.0
|
|
571
|
+
warnings.warn(
|
|
572
|
+
"'auth_info' is deprecated for nuclio runtimes in 1.7.0 and will be removed in 1.9.0",
|
|
573
|
+
FutureWarning,
|
|
574
|
+
)
|
|
549
575
|
|
|
550
576
|
old_http_session = getattr(self, "_http_session", None)
|
|
551
577
|
if old_http_session:
|
|
@@ -562,15 +588,12 @@ class RemoteRuntime(KubeResource):
|
|
|
562
588
|
if tag:
|
|
563
589
|
self.metadata.tag = tag
|
|
564
590
|
|
|
565
|
-
save_record = False
|
|
566
591
|
# Attempt auto-mounting, before sending to remote build
|
|
567
592
|
self.try_auto_mount_based_on_config()
|
|
568
593
|
self._fill_credentials()
|
|
569
594
|
db = self._get_db()
|
|
570
595
|
logger.info("Starting remote function deploy")
|
|
571
|
-
data = db.
|
|
572
|
-
self, False, builder_env=builder_env, force_build=force_build
|
|
573
|
-
)
|
|
596
|
+
data = db.deploy_nuclio_function(func=self, builder_env=builder_env)
|
|
574
597
|
self.status = data["data"].get("status")
|
|
575
598
|
self._update_credentials_from_remote_build(data["data"])
|
|
576
599
|
|
|
@@ -578,19 +601,25 @@ class RemoteRuntime(KubeResource):
|
|
|
578
601
|
# this also means that the function object will be updated with the function status
|
|
579
602
|
self._wait_for_function_deployment(db, verbose=verbose)
|
|
580
603
|
|
|
604
|
+
return self._enrich_command_from_status()
|
|
605
|
+
|
|
606
|
+
def _enrich_command_from_status(self):
|
|
581
607
|
# NOTE: on older mlrun versions & nuclio versions, function are exposed via NodePort
|
|
582
608
|
# now, functions can be not exposed (using service type ClusterIP) and hence
|
|
583
609
|
# for BC we first try to populate the external invocation url, and then
|
|
584
610
|
# if not exists, take the internal invocation url
|
|
585
|
-
if
|
|
611
|
+
if (
|
|
612
|
+
self.status.external_invocation_urls
|
|
613
|
+
and self.status.external_invocation_urls[0] != ""
|
|
614
|
+
):
|
|
586
615
|
self.spec.command = f"http://{self.status.external_invocation_urls[0]}"
|
|
587
|
-
|
|
588
|
-
|
|
616
|
+
elif (
|
|
617
|
+
self.status.internal_invocation_urls
|
|
618
|
+
and self.status.internal_invocation_urls[0] != ""
|
|
619
|
+
):
|
|
589
620
|
self.spec.command = f"http://{self.status.internal_invocation_urls[0]}"
|
|
590
|
-
|
|
591
|
-
elif self.status.address:
|
|
621
|
+
elif self.status.address and self.status.address != "":
|
|
592
622
|
self.spec.command = f"http://{self.status.address}"
|
|
593
|
-
save_record = True
|
|
594
623
|
|
|
595
624
|
logger.info(
|
|
596
625
|
"Successfully deployed function",
|
|
@@ -598,13 +627,11 @@ class RemoteRuntime(KubeResource):
|
|
|
598
627
|
external_invocation_urls=self.status.external_invocation_urls,
|
|
599
628
|
)
|
|
600
629
|
|
|
601
|
-
|
|
602
|
-
self.save(versioned=False)
|
|
630
|
+
self.save(versioned=False)
|
|
603
631
|
|
|
604
632
|
return self.spec.command
|
|
605
633
|
|
|
606
634
|
def _wait_for_function_deployment(self, db, verbose=False):
|
|
607
|
-
text = ""
|
|
608
635
|
state = ""
|
|
609
636
|
last_log_timestamp = 1
|
|
610
637
|
while state not in ["ready", "error", "unhealthy"]:
|
|
@@ -612,7 +639,7 @@ class RemoteRuntime(KubeResource):
|
|
|
612
639
|
int(mlrun.mlconf.httpdb.logs.nuclio.pull_deploy_status_default_interval)
|
|
613
640
|
)
|
|
614
641
|
try:
|
|
615
|
-
text, last_log_timestamp = db.
|
|
642
|
+
text, last_log_timestamp = db.get_nuclio_deploy_status(
|
|
616
643
|
self, last_log_timestamp=last_log_timestamp, verbose=verbose
|
|
617
644
|
)
|
|
618
645
|
except mlrun.db.RunDBError:
|
|
@@ -629,9 +656,9 @@ class RemoteRuntime(KubeResource):
|
|
|
629
656
|
def with_node_selection(
|
|
630
657
|
self,
|
|
631
658
|
node_name: typing.Optional[str] = None,
|
|
632
|
-
node_selector: typing.Optional[
|
|
659
|
+
node_selector: typing.Optional[dict[str, str]] = None,
|
|
633
660
|
affinity: typing.Optional[client.V1Affinity] = None,
|
|
634
|
-
tolerations: typing.Optional[
|
|
661
|
+
tolerations: typing.Optional[list[client.V1Toleration]] = None,
|
|
635
662
|
):
|
|
636
663
|
"""k8s node selection attributes"""
|
|
637
664
|
if tolerations and not validate_nuclio_version_compatibility("1.7.5"):
|
|
@@ -683,14 +710,14 @@ class RemoteRuntime(KubeResource):
|
|
|
683
710
|
|
|
684
711
|
def set_state_thresholds(
|
|
685
712
|
self,
|
|
686
|
-
state_thresholds:
|
|
713
|
+
state_thresholds: dict[str, int],
|
|
687
714
|
patch: bool = True,
|
|
688
715
|
):
|
|
689
716
|
raise NotImplementedError(
|
|
690
717
|
"State thresholds do not apply for nuclio as it has its own function pods healthiness monitoring"
|
|
691
718
|
)
|
|
692
719
|
|
|
693
|
-
@min_nuclio_versions("1.
|
|
720
|
+
@min_nuclio_versions("1.13.1")
|
|
694
721
|
def disable_default_http_trigger(
|
|
695
722
|
self,
|
|
696
723
|
):
|
|
@@ -699,7 +726,7 @@ class RemoteRuntime(KubeResource):
|
|
|
699
726
|
"""
|
|
700
727
|
self.spec.disable_default_http_trigger = True
|
|
701
728
|
|
|
702
|
-
@min_nuclio_versions("1.
|
|
729
|
+
@min_nuclio_versions("1.13.1")
|
|
703
730
|
def enable_default_http_trigger(
|
|
704
731
|
self,
|
|
705
732
|
):
|
|
@@ -708,6 +735,10 @@ class RemoteRuntime(KubeResource):
|
|
|
708
735
|
"""
|
|
709
736
|
self.spec.disable_default_http_trigger = False
|
|
710
737
|
|
|
738
|
+
def skip_image_enrichment(self):
|
|
739
|
+
# make sure the API does not enrich the base image if the function is not a python function
|
|
740
|
+
return self.spec.nuclio_runtime and "python" not in self.spec.nuclio_runtime
|
|
741
|
+
|
|
711
742
|
def _get_state(
|
|
712
743
|
self,
|
|
713
744
|
dashboard="",
|
|
@@ -716,7 +747,7 @@ class RemoteRuntime(KubeResource):
|
|
|
716
747
|
raise_on_exception=True,
|
|
717
748
|
resolve_address=True,
|
|
718
749
|
auth_info: AuthInfo = None,
|
|
719
|
-
) ->
|
|
750
|
+
) -> tuple[str, str, typing.Optional[float]]:
|
|
720
751
|
if dashboard:
|
|
721
752
|
(
|
|
722
753
|
state,
|
|
@@ -750,7 +781,7 @@ class RemoteRuntime(KubeResource):
|
|
|
750
781
|
return state, text, last_log_timestamp
|
|
751
782
|
|
|
752
783
|
try:
|
|
753
|
-
text, last_log_timestamp = self._get_db().
|
|
784
|
+
text, last_log_timestamp = self._get_db().get_nuclio_deploy_status(
|
|
754
785
|
self, last_log_timestamp=last_log_timestamp, verbose=verbose
|
|
755
786
|
)
|
|
756
787
|
except mlrun.db.RunDBError:
|
|
@@ -770,10 +801,13 @@ class RemoteRuntime(KubeResource):
|
|
|
770
801
|
runtime_env["MLRUN_NAMESPACE"] = mlconf.namespace
|
|
771
802
|
if self.metadata.credentials.access_key:
|
|
772
803
|
runtime_env[
|
|
773
|
-
mlrun.runtimes.constants.FunctionEnvironmentVariables.auth_session
|
|
804
|
+
mlrun.common.runtimes.constants.FunctionEnvironmentVariables.auth_session
|
|
774
805
|
] = self.metadata.credentials.access_key
|
|
775
806
|
return runtime_env
|
|
776
807
|
|
|
808
|
+
def _get_serving_spec(self):
|
|
809
|
+
return None
|
|
810
|
+
|
|
777
811
|
def _get_nuclio_config_spec_env(self):
|
|
778
812
|
env_dict = {}
|
|
779
813
|
external_source_env_dict = {}
|
|
@@ -959,6 +993,62 @@ class RemoteRuntime(KubeResource):
|
|
|
959
993
|
data = json.loads(data)
|
|
960
994
|
return data
|
|
961
995
|
|
|
996
|
+
def with_sidecar(
|
|
997
|
+
self,
|
|
998
|
+
name: str = None,
|
|
999
|
+
image: str = None,
|
|
1000
|
+
ports: typing.Optional[typing.Union[int, list[int]]] = None,
|
|
1001
|
+
command: typing.Optional[str] = None,
|
|
1002
|
+
args: typing.Optional[list[str]] = None,
|
|
1003
|
+
):
|
|
1004
|
+
"""
|
|
1005
|
+
Add a sidecar container to the function pod
|
|
1006
|
+
:param name: Sidecar container name.
|
|
1007
|
+
:param image: Sidecar container image.
|
|
1008
|
+
:param ports: Sidecar container ports to expose. Can be a single port or a list of ports.
|
|
1009
|
+
:param command: Sidecar container command instead of the image entrypoint.
|
|
1010
|
+
:param args: Sidecar container command args (requires command to be set).
|
|
1011
|
+
"""
|
|
1012
|
+
name = name or f"{self.metadata.name}-sidecar"
|
|
1013
|
+
sidecar = self._set_sidecar(name)
|
|
1014
|
+
if image:
|
|
1015
|
+
sidecar["image"] = image
|
|
1016
|
+
|
|
1017
|
+
ports = mlrun.utils.helpers.as_list(ports)
|
|
1018
|
+
# according to RFC-6335, port name should be less than 15 characters,
|
|
1019
|
+
# so we truncate it if needed and leave room for the index
|
|
1020
|
+
port_name = name[:13].rstrip("-_") if len(name) > 13 else name
|
|
1021
|
+
sidecar["ports"] = [
|
|
1022
|
+
{
|
|
1023
|
+
"name": f"{port_name}-{i}",
|
|
1024
|
+
"containerPort": port,
|
|
1025
|
+
"protocol": "TCP",
|
|
1026
|
+
}
|
|
1027
|
+
for i, port in enumerate(ports)
|
|
1028
|
+
]
|
|
1029
|
+
|
|
1030
|
+
# if it is a redeploy, 'command' might be set with the previous invocation url.
|
|
1031
|
+
# in this case, we don't want to use it as the sidecar command
|
|
1032
|
+
if command and not command.startswith("http"):
|
|
1033
|
+
sidecar["command"] = mlrun.utils.helpers.as_list(command)
|
|
1034
|
+
|
|
1035
|
+
if args and sidecar.get("command"):
|
|
1036
|
+
sidecar["args"] = mlrun.utils.helpers.as_list(args)
|
|
1037
|
+
|
|
1038
|
+
# populate the sidecar resources from the function spec
|
|
1039
|
+
if self.spec.resources:
|
|
1040
|
+
sidecar["resources"] = self.spec.resources
|
|
1041
|
+
|
|
1042
|
+
def _set_sidecar(self, name: str) -> dict:
|
|
1043
|
+
self.spec.config.setdefault("spec.sidecars", [])
|
|
1044
|
+
sidecars = self.spec.config["spec.sidecars"]
|
|
1045
|
+
for sidecar in sidecars:
|
|
1046
|
+
if sidecar["name"] == name:
|
|
1047
|
+
return sidecar
|
|
1048
|
+
|
|
1049
|
+
sidecars.append({"name": name})
|
|
1050
|
+
return sidecars[-1]
|
|
1051
|
+
|
|
962
1052
|
def _trigger_of_kind_exists(self, kind: str) -> bool:
|
|
963
1053
|
if not self.spec.config:
|
|
964
1054
|
return False
|
|
@@ -1185,6 +1275,13 @@ class RemoteRuntime(KubeResource):
|
|
|
1185
1275
|
|
|
1186
1276
|
return self._resolve_invocation_url("", force_external_address)
|
|
1187
1277
|
|
|
1278
|
+
@staticmethod
|
|
1279
|
+
def _resolve_v3io_access_key():
|
|
1280
|
+
# Nuclio supports generating access key for v3io stream trigger only from version 1.13.11
|
|
1281
|
+
if validate_nuclio_version_compatibility("1.13.11"):
|
|
1282
|
+
return mlrun.model.Credentials.generate_access_key
|
|
1283
|
+
return None
|
|
1284
|
+
|
|
1188
1285
|
|
|
1189
1286
|
def parse_logs(logs):
|
|
1190
1287
|
logs = json.loads(logs)
|
|
@@ -1279,3 +1376,23 @@ def get_nuclio_deploy_status(
|
|
|
1279
1376
|
else:
|
|
1280
1377
|
text = "\n".join(outputs) if outputs else ""
|
|
1281
1378
|
return state, address, name, last_log_timestamp, text, function_status
|
|
1379
|
+
|
|
1380
|
+
|
|
1381
|
+
def enrich_nuclio_function_from_headers(
|
|
1382
|
+
func: RemoteRuntime,
|
|
1383
|
+
headers: dict,
|
|
1384
|
+
):
|
|
1385
|
+
func.status.state = headers.get("x-mlrun-function-status", "")
|
|
1386
|
+
func.status.address = headers.get("x-mlrun-address", "")
|
|
1387
|
+
func.status.nuclio_name = headers.get("x-mlrun-name", "")
|
|
1388
|
+
func.status.internal_invocation_urls = (
|
|
1389
|
+
headers.get("x-mlrun-internal-invocation-urls", "").split(",")
|
|
1390
|
+
if headers.get("x-mlrun-internal-invocation-urls")
|
|
1391
|
+
else []
|
|
1392
|
+
)
|
|
1393
|
+
func.status.external_invocation_urls = (
|
|
1394
|
+
headers.get("x-mlrun-external-invocation-urls", "").split(",")
|
|
1395
|
+
if headers.get("x-mlrun-external-invocation-urls")
|
|
1396
|
+
else []
|
|
1397
|
+
)
|
|
1398
|
+
func.status.container_image = headers.get("x-mlrun-container-image", "")
|
|
@@ -17,13 +17,13 @@ import os
|
|
|
17
17
|
import socket
|
|
18
18
|
|
|
19
19
|
import mlrun.db
|
|
20
|
+
from mlrun.errors import err_to_str
|
|
21
|
+
from mlrun.execution import MLClientCtx
|
|
22
|
+
from mlrun.model import RunTemplate
|
|
23
|
+
from mlrun.runtimes.local import get_func_arg
|
|
24
|
+
from mlrun.serving.server import v2_serving_init
|
|
25
|
+
from mlrun.serving.v1_serving import nuclio_serving_init
|
|
20
26
|
|
|
21
|
-
from ..errors import err_to_str
|
|
22
|
-
from ..execution import MLClientCtx
|
|
23
|
-
from ..model import RunTemplate
|
|
24
|
-
from ..serving.server import v2_serving_init
|
|
25
|
-
from ..serving.v1_serving import nuclio_serving_init
|
|
26
|
-
from .local import get_func_arg
|
|
27
27
|
from .serving import serving_subkind
|
|
28
28
|
|
|
29
29
|
|