From 5fe58b63c61a3f03f09a46fdc23a8ecb0d26b70d Mon Sep 17 00:00:00 2001 From: Taneem Ibrahim Date: Mon, 19 Jun 2023 15:17:15 -0500 Subject: [PATCH 01/45] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 9 ++++++--- .github/ISSUE_TEMPLATE/feature_request.md | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index af5aaaa177f..9e096b591fd 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,9 @@ --- name: Bug report about: Tell us about a problem you are experiencing +title: '' +labels: kind/bug +assignees: '' --- @@ -26,7 +29,7 @@ about: Tell us about a problem you are experiencing - Knative Version: - KServe Version: - Kubeflow version: -- Cloud Environment:[k8s_istio/istio_dex/gcp_basic_auth/gcp_iap/aws/aws_cognito/ibm] -- Minikube/Kind version: -- Kubernetes version: (use `kubectl version`): +- Open Data Hub version: +- Deployment Environment:[cloud (aws|gcp|ibm|azure), on prem, edge ] +- OpenShift version: (use `kubectl version`): - OS (e.g. from `/etc/os-release`): diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index ec7c001bdc6..84376883e9c 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,6 +1,9 @@ --- name: Feature enhancement request about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' --- From 4e7f0df84e94366132a71e62c4cc584d4a360b4d Mon Sep 17 00:00:00 2001 From: Reto Lehmann Date: Wed, 12 Jul 2023 21:08:23 +0200 Subject: [PATCH 02/45] add storage-initializer uid handling for OpenShift with istio-cni (#18) **What this does / why we need it**: This PR adds custom code to make KServe run on OpenShift without the need for anyuid SCC. **More context**: OpenShift uses istio-cni which causes an issue with init-containers when calling external services like S3 or similar. Setting the uid for the storage-initializer to the same uid as the uid of the istio-proxy resolves the issue. In OpenShift the istio-proxy always gets assigned the first uid from the namespaces uid range + 1 (The range is defined in an annotation on the namespace). **Release note**: ```release-note The `storage-initializer` container will now run with the same `uid` as the `istio-proxy` which resolves an issue when istio-cni is used. ``` --- Squashed commit titles: * add storage-initializer uid handling for OpenShift with istio-cni * update storage_initializer_injector tests * Also use annotation on pod to override uid --- .../pod/metrics_aggregate_injector.go | 1 + pkg/webhook/admission/pod/mutator.go | 15 +- .../pod/storage_initializer_injector.go | 32 ++- .../pod/storage_initializer_injector_test.go | 195 +++++++++++++++++- 4 files changed, 230 insertions(+), 13 deletions(-) diff --git a/pkg/webhook/admission/pod/metrics_aggregate_injector.go b/pkg/webhook/admission/pod/metrics_aggregate_injector.go index 3a5d6fa3569..223a930f042 100644 --- a/pkg/webhook/admission/pod/metrics_aggregate_injector.go +++ b/pkg/webhook/admission/pod/metrics_aggregate_injector.go @@ -19,6 +19,7 @@ package pod import ( "encoding/json" "fmt" + "github.com/kserve/kserve/pkg/constants" v1 "k8s.io/api/core/v1" ) diff --git a/pkg/webhook/admission/pod/mutator.go b/pkg/webhook/admission/pod/mutator.go index c320967f3c1..f5b2e266bb2 100644 --- a/pkg/webhook/admission/pod/mutator.go +++ b/pkg/webhook/admission/pod/mutator.go @@ -62,7 +62,14 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis // For some reason pod namespace is always empty when coming to pod mutator, need to set from admission request pod.Namespace = req.AdmissionRequest.Namespace - if err := mutator.mutate(pod, configMap); err != nil { + targetNs := &v1.Namespace{} + err = mutator.Client.Get(context.TODO(), k8types.NamespacedName{Name: pod.Namespace, Namespace: pod.Namespace}, targetNs) + if err != nil { + log.Error(err, "Failed to get the target namespace", "name", pod.Namespace) + return admission.Errored(http.StatusInternalServerError, err) + } + + if err := mutator.mutate(pod, configMap, targetNs); err != nil { log.Error(err, "Failed to mutate pod", "name", pod.Labels[constants.InferenceServicePodLabelKey]) return admission.Errored(http.StatusInternalServerError, err) } @@ -76,7 +83,7 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis return admission.PatchResponseFromRaw(req.AdmissionRequest.Object.Raw, patch) } -func (mutator *Mutator) mutate(pod *v1.Pod, configMap *v1.ConfigMap) error { +func (mutator *Mutator) mutate(pod *v1.Pod, configMap *v1.ConfigMap, targetNs *v1.Namespace) error { credentialBuilder := credentials.NewCredentialBulder(mutator.Client, configMap) storageInitializerConfig, err := getStorageInitializerConfigs(configMap) @@ -118,7 +125,9 @@ func (mutator *Mutator) mutate(pod *v1.Pod, configMap *v1.ConfigMap) error { mutators := []func(pod *v1.Pod) error{ InjectGKEAcceleratorSelector, - storageInitializer.InjectStorageInitializer, + func(pod *v1.Pod) error { + return storageInitializer.InjectStorageInitializer(pod, targetNs) + }, agentInjector.InjectAgent, metricsAggregator.InjectMetricsAggregator, } diff --git a/pkg/webhook/admission/pod/storage_initializer_injector.go b/pkg/webhook/admission/pod/storage_initializer_injector.go index fb7aa032ab2..39bb93eb7f1 100644 --- a/pkg/webhook/admission/pod/storage_initializer_injector.go +++ b/pkg/webhook/admission/pod/storage_initializer_injector.go @@ -41,6 +41,7 @@ const ( PvcURIPrefix = "pvc://" PvcSourceMountName = "kserve-pvc-source" PvcSourceMountPath = "/mnt/pvc" + OpenShiftUidRangeAnnotationKey = "openshift.io/sa.scc.uid-range" ) type StorageInitializerConfig struct { @@ -85,7 +86,7 @@ func getStorageInitializerConfigs(configMap *v1.ConfigMap) (*StorageInitializerC // for the serving container in a unified way across storage tech by injecting // a provisioning INIT container. This is a work around because KNative does not // support INIT containers: https://github.com/knative/serving/issues/4307 -func (mi *StorageInitializerInjector) InjectStorageInitializer(pod *v1.Pod) error { +func (mi *StorageInitializerInjector) InjectStorageInitializer(pod *v1.Pod, targetNs *v1.Namespace) error { // Only inject if the required annotations are set srcURI, ok := pod.ObjectMeta.Annotations[constants.StorageInitializerSourceUriInternalAnnotationKey] if !ok { @@ -330,12 +331,37 @@ func (mi *StorageInitializerInjector) InjectStorageInitializer(pod *v1.Pod) erro } } - // Allow to override the uid for the case where ISTIO CNI with DNS proxy is enabled - // See for more: https://istio.io/latest/docs/setup/additional-setup/cni/#compatibility-with-application-init-containers. + /* + OpenShift uses istio-cni which causes an issue with init-containers when calling external services + like S3 or similar. Setting the `uid` for the `storage-initializer` to the same `uid` as the + `uid` of the `istio-proxy` resolves the issue. + + With upstream istio the user has the option to set the uid to 1337 described in https://istio.io/latest/docs/setup/additional-setup/cni/#compatibility-with-application-init-containers + using the annotation IstioSidecarUIDAnnotationKey. + + In OpenShift the `istio-proxy` always gets assigned the first `uid` from the namespaces + `uid` range + 1 (The range is defined in an annotation on the namespace). + */ if value, ok := pod.GetAnnotations()[constants.IstioSidecarUIDAnnotationKey]; ok { if uid, err := strconv.ParseInt(value, 10, 64); err == nil { + if initContainer.SecurityContext == nil { + initContainer.SecurityContext = &v1.SecurityContext{} + } initContainer.SecurityContext.RunAsUser = ptr.Int64(uid) } + } else { + uidStr := targetNs.Annotations[OpenShiftUidRangeAnnotationKey] + if uidStr != "" { + uidStrParts := strings.Split(uidStr, "/") + if uid, err := strconv.ParseInt(uidStrParts[0], 10, 64); err == nil { + // Set the uid to the first uid in the namespaces range + 1 + uid++ + if initContainer.SecurityContext == nil { + initContainer.SecurityContext = &v1.SecurityContext{} + } + initContainer.SecurityContext.RunAsUser = ptr.Int64(uid) + } + } } // Add init container to the spec diff --git a/pkg/webhook/admission/pod/storage_initializer_injector_test.go b/pkg/webhook/admission/pod/storage_initializer_injector_test.go index 80456344032..b4f83f61cb8 100644 --- a/pkg/webhook/admission/pod/storage_initializer_injector_test.go +++ b/pkg/webhook/admission/pod/storage_initializer_injector_test.go @@ -22,6 +22,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" "knative.dev/pkg/kmp" + "knative.dev/pkg/ptr" "github.com/kserve/kserve/pkg/constants" "github.com/kserve/kserve/pkg/credentials" @@ -62,6 +63,17 @@ var ( v1.ResourceMemory: resource.MustParse(StorageInitializerDefaultMemoryRequest), }, } + + targetNS = &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "my-ns", + Annotations: map[string]string{ + OpenShiftUidRangeAnnotationKey: "1000740000/10000", + }, + }, + } + + expectedInitContainerUid = ptr.Int64(1000740001) ) func TestStorageInitializerInjector(t *testing.T) { @@ -182,6 +194,9 @@ func TestStorageInitializerInjector(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, + SecurityContext: &v1.SecurityContext{ + RunAsUser: expectedInitContainerUid, + }, }, }, Volumes: []v1.Volume{ @@ -252,6 +267,9 @@ func TestStorageInitializerInjector(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, + SecurityContext: &v1.SecurityContext{ + RunAsUser: expectedInitContainerUid, + }, }, }, Volumes: []v1.Volume{ @@ -332,6 +350,9 @@ func TestStorageInitializerInjector(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, + SecurityContext: &v1.SecurityContext{ + RunAsUser: expectedInitContainerUid, + }, }, }, Volumes: []v1.Volume{ @@ -354,7 +375,7 @@ func TestStorageInitializerInjector(t *testing.T) { }), config: storageInitializerConfig, } - if err := injector.InjectStorageInitializer(scenario.original); err != nil { + if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { t.Errorf("Test %q unexpected result: %s", name, err) } if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" { @@ -394,7 +415,7 @@ func TestStorageInitializerFailureCases(t *testing.T) { }), config: storageInitializerConfig, } - if err := injector.InjectStorageInitializer(scenario.original); err != nil { + if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { if !strings.HasPrefix(err.Error(), scenario.expectedErrorPrefix) { t.Errorf("Test %q unexpected failure [%s], expected: %s", name, err.Error(), scenario.expectedErrorPrefix) } @@ -404,6 +425,145 @@ func TestStorageInitializerFailureCases(t *testing.T) { } } +func TestStorageInitializerInjectorUIDHandling(t *testing.T) { + scenarios := map[string]struct { + namespace *v1.Namespace + original *v1.Pod + expected *v1.Pod + }{ + "NoAnnotationNoUid": { + namespace: &v1.Namespace{}, + original: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + constants.StorageInitializerSourceUriInternalAnnotationKey: "gs://foo", + }, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: constants.InferenceServiceContainerName, + }, + }, + }, + }, + expected: &v1.Pod{ + Spec: v1.PodSpec{ + InitContainers: []v1.Container{ + { + Name: "storage-initializer", + Image: StorageInitializerContainerImage + ":" + StorageInitializerContainerImageVersion, + Args: []string{"gs://foo", constants.DefaultModelLocalMountPath}, + Resources: resourceRequirement, + TerminationMessagePolicy: "FallbackToLogsOnError", + VolumeMounts: []v1.VolumeMount{ + { + Name: "kserve-provision-location", + MountPath: constants.DefaultModelLocalMountPath, + }, + }, + }, + }, + }, + }, + }, + "UidFromOpenShiftNamespaceAnnotation": { + namespace: targetNS, + original: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + constants.StorageInitializerSourceUriInternalAnnotationKey: "gs://foo", + }, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: constants.InferenceServiceContainerName, + }, + }, + }, + }, + expected: &v1.Pod{ + Spec: v1.PodSpec{ + InitContainers: []v1.Container{ + { + Name: "storage-initializer", + Image: StorageInitializerContainerImage + ":" + StorageInitializerContainerImageVersion, + Args: []string{"gs://foo", constants.DefaultModelLocalMountPath}, + Resources: resourceRequirement, + TerminationMessagePolicy: "FallbackToLogsOnError", + VolumeMounts: []v1.VolumeMount{ + { + Name: "kserve-provision-location", + MountPath: constants.DefaultModelLocalMountPath, + }, + }, + SecurityContext: &v1.SecurityContext{ + RunAsUser: expectedInitContainerUid, + }, + }, + }, + }, + }, + }, + "UidFromPodAnnotation": { + namespace: targetNS, + original: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + constants.StorageInitializerSourceUriInternalAnnotationKey: "gs://foo", + constants.IstioSidecarUIDAnnotationKey: "1337", + }, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: constants.InferenceServiceContainerName, + }, + }, + }, + }, + expected: &v1.Pod{ + Spec: v1.PodSpec{ + InitContainers: []v1.Container{ + { + Name: "storage-initializer", + Image: StorageInitializerContainerImage + ":" + StorageInitializerContainerImageVersion, + Args: []string{"gs://foo", constants.DefaultModelLocalMountPath}, + Resources: resourceRequirement, + TerminationMessagePolicy: "FallbackToLogsOnError", + VolumeMounts: []v1.VolumeMount{ + { + Name: "kserve-provision-location", + MountPath: constants.DefaultModelLocalMountPath, + }, + }, + SecurityContext: &v1.SecurityContext{ + RunAsUser: ptr.Int64(1337), + }, + }, + }, + }, + }, + }, + } + + for name, scenario := range scenarios { + injector := &StorageInitializerInjector{ + credentialBuilder: credentials.NewCredentialBulder(c, &v1.ConfigMap{ + Data: map[string]string{}, + }), + config: storageInitializerConfig, + } + if err := injector.InjectStorageInitializer(scenario.original, scenario.namespace); err != nil { + t.Errorf("Test %q unexpected result: %s", name, err) + } + if diff, _ := kmp.SafeDiff(scenario.expected.Spec.InitContainers, scenario.original.Spec.InitContainers); diff != "" { + t.Errorf("Test %q unexpected result (-want +got): %v", name, diff) + } + } +} + func TestCustomSpecStorageUriInjection(t *testing.T) { scenarios := map[string]struct { original *v1.Pod @@ -493,7 +653,7 @@ func TestCustomSpecStorageUriInjection(t *testing.T) { }), config: storageInitializerConfig, } - if err := injector.InjectStorageInitializer(scenario.original); err != nil { + if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { t.Errorf("Test %q unexpected result: %s", name, err) } @@ -597,6 +757,9 @@ func TestCredentialInjection(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, + SecurityContext: &v1.SecurityContext{ + RunAsUser: expectedInitContainerUid, + }, Env: []v1.EnvVar{ { Name: s3.AWSAccessKeyId, @@ -702,6 +865,9 @@ func TestCredentialInjection(t *testing.T) { MountPath: gcs.GCSCredentialVolumeMountPath, }, }, + SecurityContext: &v1.SecurityContext{ + RunAsUser: expectedInitContainerUid, + }, Env: []v1.EnvVar{ { Name: gcs.GCSCredentialEnvKey, @@ -790,6 +956,9 @@ func TestCredentialInjection(t *testing.T) { Name: "storage-initializer", Image: StorageInitializerContainerImage + ":" + StorageInitializerContainerImageVersion, Args: []string{"s3://my-bucket/foo/bar", constants.DefaultModelLocalMountPath}, + SecurityContext: &v1.SecurityContext{ + RunAsUser: expectedInitContainerUid, + }, Env: []v1.EnvVar{ { Name: credentials.StorageConfigEnvKey, @@ -885,6 +1054,9 @@ func TestCredentialInjection(t *testing.T) { Name: "storage-initializer", Image: StorageInitializerContainerImage + ":" + StorageInitializerContainerImageVersion, Args: []string{"s3://my-bucket/foo/bar", constants.DefaultModelLocalMountPath}, + SecurityContext: &v1.SecurityContext{ + RunAsUser: expectedInitContainerUid, + }, Env: []v1.EnvVar{ { Name: credentials.StorageConfigEnvKey, @@ -944,7 +1116,7 @@ func TestCredentialInjection(t *testing.T) { credentialBuilder: builder, config: storageInitializerConfig, } - if err := injector.InjectStorageInitializer(scenario.original); err != nil { + if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { t.Errorf("Test %q unexpected failure [%s]", name, err.Error()) } if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" { @@ -1008,6 +1180,9 @@ func TestStorageInitializerConfigmap(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, + SecurityContext: &v1.SecurityContext{ + RunAsUser: expectedInitContainerUid, + }, }, }, Volumes: []v1.Volume{ @@ -1037,7 +1212,7 @@ func TestStorageInitializerConfigmap(t *testing.T) { StorageSpecSecretName: StorageInitializerDefaultStorageSpecSecretName, }, } - if err := injector.InjectStorageInitializer(scenario.original); err != nil { + if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { t.Errorf("Test %q unexpected result: %s", name, err) } if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" { @@ -1272,7 +1447,7 @@ func TestDirectVolumeMountForPvc(t *testing.T) { EnableDirectPvcVolumeMount: true, // enable direct volume mount for PVC }, } - if err := injector.InjectStorageInitializer(scenario.original); err != nil { + if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { t.Errorf("Test %q unexpected result: %s", name, err) } if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" { @@ -1385,6 +1560,9 @@ func TestTransformerCollocation(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, + SecurityContext: &v1.SecurityContext{ + RunAsUser: expectedInitContainerUid, + }, }, }, Volumes: []v1.Volume{ @@ -1563,6 +1741,9 @@ func TestTransformerCollocation(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, + SecurityContext: &v1.SecurityContext{ + RunAsUser: expectedInitContainerUid, + }, }, }, Volumes: []v1.Volume{ @@ -1594,7 +1775,7 @@ func TestTransformerCollocation(t *testing.T) { }), config: scenario.storageConfig, } - if err := injector.InjectStorageInitializer(scenario.original); err != nil { + if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { t.Errorf("Test %q unexpected result: %s", name, err) } if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" { From 9d58b322f5d79d9077dc3b54a9d90b9e2192ee33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Wed, 5 Jul 2023 18:39:01 -0600 Subject: [PATCH 03/45] * OpenShift patches to Kustomize manifests * Remove manager's rbac-proxy and add ODH requried network policies * Workaround for Kustomize bug about creationTimestamp See: https://github.com/kubernetes-sigs/kustomize/issues/5031 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this workaround, some Kustomize versions are generating `creationTimestamp: "null"` (null as a string). Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- config/crd/kustomization.yaml | 2 +- .../cainjection_conversion_webhook.yaml | 2 +- .../inferenceservice_conversion_webhook.yaml | 1 + ...svc_mutatingwebhook_cainjection_patch.yaml | 2 +- ...c_validatingwebhook_cainjection_patch.yaml | 2 +- config/default/kustomization.yaml | 33 ++++++++++- config/default/network-policies.yaml | 11 ++++ .../svc_webhook_cainjection_patch.yaml | 7 +++ ...del_mutatingwebhook_cainjection_patch.yaml | 2 +- ...l_validatingwebhook_cainjection_patch.yaml | 2 +- pkg/apis/serving/v1beta1/predictor_model.go | 29 +++++----- .../serving/v1beta1/predictor_model_test.go | 55 ++++++++++--------- .../v1beta1/inferenceservice/utils/utils.go | 18 +++--- .../inferenceservice/utils/utils_test.go | 32 +++++------ 14 files changed, 125 insertions(+), 73 deletions(-) create mode 100644 config/default/network-policies.yaml create mode 100644 config/default/svc_webhook_cainjection_patch.yaml diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index fc0d49588b7..dfe61ba42c6 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -13,7 +13,7 @@ kind: Kustomization resources: - serving.kserve.io_inferenceservices.yaml - serving.kserve.io_trainedmodels.yaml -- serving.kserve.io_clusterservingruntimes.yaml +# - serving.kserve.io_clusterservingruntimes.yaml # Not supported in ODH - serving.kserve.io_servingruntimes.yaml - serving.kserve.io_inferencegraphs.yaml diff --git a/config/default/cainjection_conversion_webhook.yaml b/config/default/cainjection_conversion_webhook.yaml index af5dadeb060..92f5d3114bc 100644 --- a/config/default/cainjection_conversion_webhook.yaml +++ b/config/default/cainjection_conversion_webhook.yaml @@ -4,5 +4,5 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - cert-manager.io/inject-ca-from: $(kserveNamespace)/serving-cert + service.beta.openshift.io/inject-cabundle: "true" name: inferenceservices.serving.kserve.io diff --git a/config/default/inferenceservice_conversion_webhook.yaml b/config/default/inferenceservice_conversion_webhook.yaml index 18be2e28d25..7f6916b8871 100644 --- a/config/default/inferenceservice_conversion_webhook.yaml +++ b/config/default/inferenceservice_conversion_webhook.yaml @@ -4,6 +4,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: inferenceservices.serving.kserve.io + creationTimestamp: null spec: preserveUnknownFields: false conversion: diff --git a/config/default/isvc_mutatingwebhook_cainjection_patch.yaml b/config/default/isvc_mutatingwebhook_cainjection_patch.yaml index cff6c92acdc..e91ee9f50aa 100644 --- a/config/default/isvc_mutatingwebhook_cainjection_patch.yaml +++ b/config/default/isvc_mutatingwebhook_cainjection_patch.yaml @@ -3,6 +3,6 @@ kind: MutatingWebhookConfiguration metadata: name: inferenceservice.serving.kserve.io annotations: - cert-manager.io/inject-ca-from: $(kserveNamespace)/serving-cert + service.beta.openshift.io/inject-cabundle: "true" webhooks: - name: inferenceservice.kserve-webhook-server.defaulter diff --git a/config/default/isvc_validatingwebhook_cainjection_patch.yaml b/config/default/isvc_validatingwebhook_cainjection_patch.yaml index 946b7e5ca54..f0f0d437ab8 100644 --- a/config/default/isvc_validatingwebhook_cainjection_patch.yaml +++ b/config/default/isvc_validatingwebhook_cainjection_patch.yaml @@ -3,6 +3,6 @@ kind: ValidatingWebhookConfiguration metadata: name: inferenceservice.serving.kserve.io annotations: - cert-manager.io/inject-ca-from: $(kserveNamespace)/serving-cert + service.beta.openshift.io/inject-cabundle: "true" webhooks: - name: inferenceservice.kserve-webhook-server.validator diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index d2994225e85..a86faccb55d 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -4,6 +4,10 @@ kind: Kustomization # Adds namespace to all resources. namespace: kserve +# Add recommended Kubernetes labels +commonLabels: + app.kubernetes.io/part-of: kserve + # Labels to add to all resources and selectors. #commonLabels: # app.kubernetes.io/name: kserve @@ -13,7 +17,8 @@ resources: - ../rbac - ../manager - ../webhook -- ../certmanager +# - ../certmanager # not needed, because ODH is using OpenShift's serving certificates for WebHooks +- network-policies.yaml # ODH specific generatorOptions: disableNameSuffixHash: true @@ -156,11 +161,35 @@ replacements: #- manager_prometheus_metrics_patch.yaml patches: - path: manager_image_patch.yaml -- path: manager_auth_proxy_patch.yaml +#- path: manager_auth_proxy_patch.yaml - path: isvc_mutatingwebhook_cainjection_patch.yaml - path: isvc_validatingwebhook_cainjection_patch.yaml - path: trainedmodel_mutatingwebhook_cainjection_patch.yaml - path: trainedmodel_validatingwebhook_cainjection_patch.yaml +- path: svc_webhook_cainjection_patch.yaml - path: manager_resources_patch.yaml - path: inferenceservice_conversion_webhook.yaml - path: cainjection_conversion_webhook.yaml + +patches: + # Since OpenShift serving-certificates are being used, + # remove CA bundle placeholders + - patch: |- + - op: remove + path: "/spec/conversion/webhook/clientConfig/caBundle" + target: + kind: CustomResourceDefinition + name: inferenceservices.serving.kserve.io + - patch: |- + - op: remove + path: "/webhooks/0/clientConfig/caBundle" + - op: remove + path: "/webhooks/1/clientConfig/caBundle" + target: + kind: MutatingWebhookConfiguration + - patch: |- + - op: remove + path: "/webhooks/0/clientConfig/caBundle" + target: + kind: ValidatingWebhookConfiguration + diff --git a/config/default/network-policies.yaml b/config/default/network-policies.yaml new file mode 100644 index 00000000000..cafdb17b52c --- /dev/null +++ b/config/default/network-policies.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: kserve-controller-manager +spec: + podSelector: + matchLabels: + control-plane: kserve-controller-manager + ingress: + - {} diff --git a/config/default/svc_webhook_cainjection_patch.yaml b/config/default/svc_webhook_cainjection_patch.yaml new file mode 100644 index 00000000000..cd76dcf28b3 --- /dev/null +++ b/config/default/svc_webhook_cainjection_patch.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Service +metadata: + name: kserve-webhook-server-service + namespace: kserve + annotations: + service.beta.openshift.io/serving-cert-secret-name: kserve-webhook-server-cert diff --git a/config/default/trainedmodel_mutatingwebhook_cainjection_patch.yaml b/config/default/trainedmodel_mutatingwebhook_cainjection_patch.yaml index 5e94b5d3309..a39d282a96b 100644 --- a/config/default/trainedmodel_mutatingwebhook_cainjection_patch.yaml +++ b/config/default/trainedmodel_mutatingwebhook_cainjection_patch.yaml @@ -3,6 +3,6 @@ kind: ValidatingWebhookConfiguration metadata: name: inferencegraph.serving.kserve.io annotations: - cert-manager.io/inject-ca-from: $(kserveNamespace)/serving-cert + service.beta.openshift.io/inject-cabundle: "true" webhooks: - name: inferencegraph.kserve-webhook-server.validator diff --git a/config/default/trainedmodel_validatingwebhook_cainjection_patch.yaml b/config/default/trainedmodel_validatingwebhook_cainjection_patch.yaml index abad6f07faa..ce021eae541 100644 --- a/config/default/trainedmodel_validatingwebhook_cainjection_patch.yaml +++ b/config/default/trainedmodel_validatingwebhook_cainjection_patch.yaml @@ -3,6 +3,6 @@ kind: ValidatingWebhookConfiguration metadata: name: trainedmodel.serving.kserve.io annotations: - cert-manager.io/inject-ca-from: $(kserveNamespace)/serving-cert + service.beta.openshift.io/inject-cabundle: "true" webhooks: - name: trainedmodel.kserve-webhook-server.validator diff --git a/pkg/apis/serving/v1beta1/predictor_model.go b/pkg/apis/serving/v1beta1/predictor_model.go index dd90ac1df6c..4ebd879a400 100644 --- a/pkg/apis/serving/v1beta1/predictor_model.go +++ b/pkg/apis/serving/v1beta1/predictor_model.go @@ -99,13 +99,14 @@ func (m *ModelSpec) GetSupportingRuntimes(cl client.Client, namespace string, is // Sort namespace-scoped runtimes by created timestamp desc and name asc. sortServingRuntimeList(runtimes) - // List all cluster-scoped runtimes. - clusterRuntimes := &v1alpha1.ClusterServingRuntimeList{} - if err := cl.List(context.TODO(), clusterRuntimes); err != nil { - return nil, err - } - // Sort cluster-scoped runtimes by created timestamp desc and name asc. - sortClusterServingRuntimeList(clusterRuntimes) + // ODH does not support ClusterServingRuntimes + //// List all cluster-scoped runtimes. + //clusterRuntimes := &v1alpha1.ClusterServingRuntimeList{} + //if err := cl.List(context.TODO(), clusterRuntimes); err != nil { + // return nil, err + //} + //// Sort cluster-scoped runtimes by created timestamp desc and name asc. + //sortClusterServingRuntimeList(clusterRuntimes) srSpecs := []v1alpha1.SupportedRuntime{} for i := range runtimes.Items { @@ -116,13 +117,13 @@ func (m *ModelSpec) GetSupportingRuntimes(cl client.Client, namespace string, is } } - for i := range clusterRuntimes.Items { - crt := &clusterRuntimes.Items[i] - if !crt.Spec.IsDisabled() && crt.Spec.IsMultiModelRuntime() == isMMS && - m.RuntimeSupportsModel(&crt.Spec) && crt.Spec.IsProtocolVersionSupported(modelProtcolVersion) { - srSpecs = append(srSpecs, v1alpha1.SupportedRuntime{Name: crt.GetName(), Spec: crt.Spec}) - } - } + //for i := range clusterRuntimes.Items { + // crt := &clusterRuntimes.Items[i] + // if !crt.Spec.IsDisabled() && crt.Spec.IsMultiModelRuntime() == isMMS && + // m.RuntimeSupportsModel(&crt.Spec) && crt.Spec.IsProtocolVersionSupported(modelProtcolVersion) { + // srSpecs = append(srSpecs, v1alpha1.SupportedRuntime{Name: crt.GetName(), Spec: crt.Spec}) + // } + //} return srSpecs, nil } diff --git a/pkg/apis/serving/v1beta1/predictor_model_test.go b/pkg/apis/serving/v1beta1/predictor_model_test.go index b13367a9701..7d757a42083 100644 --- a/pkg/apis/serving/v1beta1/predictor_model_test.go +++ b/pkg/apis/serving/v1beta1/predictor_model_test.go @@ -39,7 +39,7 @@ func TestGetSupportingRuntimes(t *testing.T) { pmmlRuntime := "pmml-runtime" mlserverRuntime := "mlserver-runtime" xgboostRuntime := "xgboost-runtime" - clusterServingRuntimePrefix := "cluster-" + //clusterServingRuntimePrefix := "cluster-" protocolV2 := constants.ProtocolV2 protocolV1 := constants.ProtocolV1 @@ -179,28 +179,29 @@ func TestGetSupportingRuntimes(t *testing.T) { }, } - clusterRuntimes := &v1alpha1.ClusterServingRuntimeList{ - Items: []v1alpha1.ClusterServingRuntime{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: clusterServingRuntimePrefix + mlserverRuntime, - }, - Spec: servingRuntimeSpecs[mlserverRuntime], - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: clusterServingRuntimePrefix + tfRuntime, - }, - Spec: servingRuntimeSpecs[tfRuntime], - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: clusterServingRuntimePrefix + xgboostRuntime, - }, - Spec: servingRuntimeSpecs[xgboostRuntime], - }, - }, - } + // ODH does not support ClusterServingRuntimeList + //clusterRuntimes := &v1alpha1.ClusterServingRuntimeList{ + // Items: []v1alpha1.ClusterServingRuntime{ + // { + // ObjectMeta: metav1.ObjectMeta{ + // Name: clusterServingRuntimePrefix + mlserverRuntime, + // }, + // Spec: servingRuntimeSpecs[mlserverRuntime], + // }, + // { + // ObjectMeta: metav1.ObjectMeta{ + // Name: clusterServingRuntimePrefix + tfRuntime, + // }, + // Spec: servingRuntimeSpecs[tfRuntime], + // }, + // { + // ObjectMeta: metav1.ObjectMeta{ + // Name: clusterServingRuntimePrefix + xgboostRuntime, + // }, + // Spec: servingRuntimeSpecs[xgboostRuntime], + // }, + // }, + //} var storageUri = "s3://test/model" scenarios := map[string]struct { @@ -218,7 +219,7 @@ func TestGetSupportingRuntimes(t *testing.T) { }, }, isMMS: false, - expected: []v1alpha1.SupportedRuntime{{Name: tfRuntime, Spec: servingRuntimeSpecs[tfRuntime]}, {Name: clusterServingRuntimePrefix + tfRuntime, Spec: servingRuntimeSpecs[tfRuntime]}}, + expected: []v1alpha1.SupportedRuntime{{Name: tfRuntime, Spec: servingRuntimeSpecs[tfRuntime]} /*, {Name: clusterServingRuntimePrefix + tfRuntime, Spec: servingRuntimeSpecs[tfRuntime]}*/}, }, "RuntimeNotFound": { spec: &ModelSpec{ @@ -255,7 +256,7 @@ func TestGetSupportingRuntimes(t *testing.T) { }, }, isMMS: true, - expected: []v1alpha1.SupportedRuntime{{Name: clusterServingRuntimePrefix + mlserverRuntime, Spec: servingRuntimeSpecs[mlserverRuntime]}}, + expected: []v1alpha1.SupportedRuntime{ /*{Name: clusterServingRuntimePrefix + mlserverRuntime, Spec: servingRuntimeSpecs[mlserverRuntime]}*/ }, }, "SMSRuntimeModelFormatSpecified": { spec: &ModelSpec{ @@ -280,7 +281,7 @@ func TestGetSupportingRuntimes(t *testing.T) { }, }, isMMS: false, - expected: []v1alpha1.SupportedRuntime{{Name: clusterServingRuntimePrefix + xgboostRuntime, Spec: servingRuntimeSpecs[xgboostRuntime]}}, + expected: []v1alpha1.SupportedRuntime{ /*{Name: clusterServingRuntimePrefix + xgboostRuntime, Spec: servingRuntimeSpecs[xgboostRuntime]}*/ }, }, "RuntimeV1ProtocolNotFound": { spec: &ModelSpec{ @@ -303,7 +304,7 @@ func TestGetSupportingRuntimes(t *testing.T) { t.Errorf("unable to add scheme : %v", err) } - mockClient := fake.NewClientBuilder().WithLists(runtimes, clusterRuntimes).WithScheme(s).Build() + mockClient := fake.NewClientBuilder().WithLists(runtimes /*, clusterRuntimes*/).WithScheme(s).Build() for name, scenario := range scenarios { t.Run(name, func(t *testing.T) { res, _ := scenario.spec.GetSupportingRuntimes(mockClient, namespace, scenario.isMMS) diff --git a/pkg/controller/v1beta1/inferenceservice/utils/utils.go b/pkg/controller/v1beta1/inferenceservice/utils/utils.go index 1de02e1bdde..3c1b928773c 100644 --- a/pkg/controller/v1beta1/inferenceservice/utils/utils.go +++ b/pkg/controller/v1beta1/inferenceservice/utils/utils.go @@ -246,14 +246,16 @@ func GetServingRuntime(cl client.Client, name string, namespace string) (*v1alph return nil, err } - clusterRuntime := &v1alpha1.ClusterServingRuntime{} - err = cl.Get(context.TODO(), client.ObjectKey{Name: name}, clusterRuntime) - if err == nil { - return &clusterRuntime.Spec, nil - } else if !errors.IsNotFound(err) { - return nil, err - } - return nil, goerrors.New("No ServingRuntimes or ClusterServingRuntimes with the name: " + name) + // ODH does not support ClusterServingRuntimes + //clusterRuntime := &v1alpha1.ClusterServingRuntime{} + //err = cl.Get(context.TODO(), client.ObjectKey{Name: name}, clusterRuntime) + //if err == nil { + // return &clusterRuntime.Spec, nil + //} else if !errors.IsNotFound(err) { + // return nil, err + //} + + return nil, goerrors.New("No ServingRuntimes with the name: " + name) } // ReplacePlaceholders Replace placeholders in runtime container by values from inferenceservice metadata diff --git a/pkg/controller/v1beta1/inferenceservice/utils/utils_test.go b/pkg/controller/v1beta1/inferenceservice/utils/utils_test.go index 8ce85d173a4..02bd5c3b034 100644 --- a/pkg/controller/v1beta1/inferenceservice/utils/utils_test.go +++ b/pkg/controller/v1beta1/inferenceservice/utils/utils_test.go @@ -941,16 +941,16 @@ func TestGetServingRuntime(t *testing.T) { }, } - clusterRuntimes := &v1alpha1.ClusterServingRuntimeList{ - Items: []v1alpha1.ClusterServingRuntime{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: sklearnRuntime, - }, - Spec: servingRuntimeSpecs[sklearnRuntime], - }, - }, - } + //clusterRuntimes := &v1alpha1.ClusterServingRuntimeList{ + // Items: []v1alpha1.ClusterServingRuntime{ + // { + // ObjectMeta: metav1.ObjectMeta{ + // Name: sklearnRuntime, + // }, + // Spec: servingRuntimeSpecs[sklearnRuntime], + // }, + // }, + //} scenarios := map[string]struct { runtimeName string @@ -960,16 +960,16 @@ func TestGetServingRuntime(t *testing.T) { runtimeName: tfRuntime, expected: servingRuntimeSpecs[tfRuntime], }, - "ClusterServingRuntime": { - runtimeName: sklearnRuntime, - expected: servingRuntimeSpecs[sklearnRuntime], - }, + //"ClusterServingRuntime": { + // runtimeName: sklearnRuntime, + // expected: servingRuntimeSpecs[sklearnRuntime], + //}, } s := runtime.NewScheme() v1alpha1.AddToScheme(s) - mockClient := fake.NewClientBuilder().WithLists(runtimes, clusterRuntimes).WithScheme(s).Build() + mockClient := fake.NewClientBuilder().WithLists(runtimes /*, clusterRuntimes*/).WithScheme(s).Build() for name, scenario := range scenarios { t.Run(name, func(t *testing.T) { res, _ := GetServingRuntime(mockClient, scenario.runtimeName, namespace) @@ -985,7 +985,7 @@ func TestGetServingRuntime(t *testing.T) { if !g.Expect(res).To(gomega.BeNil()) { t.Errorf("got %v, want %v", res, nil) } - g.Expect(err.Error()).To(gomega.ContainSubstring("No ServingRuntimes or ClusterServingRuntimes with the name")) + g.Expect(err.Error()).To(gomega.ContainSubstring("No ServingRuntimes with the name")) }) } From 6e2f13c13bcf1cba28c3d049a4e058dea5374077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Thu, 13 Jul 2023 14:39:22 -0600 Subject: [PATCH 04/45] Adapt GH-workflows to correctly push to ODH container repositories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Workflows are changed to push to Quay.io. * The go.yml workflow is changed to omit updating the coverage badge (we don't have one, for now). * The README.md file is updated to right ODH urls. Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- .github/workflows/agent-docker-publish.yml | 25 ++++++++++++------- .github/workflows/go.yml | 4 ++- .../kserve-controller-docker-publish.yml | 21 ++++++++++------ .github/workflows/router-docker-publish.yml | 25 ++++++++++++------- .../storage-initializer-docker-publisher.yml | 14 ++++++++--- README.md | 10 +++----- 6 files changed, 63 insertions(+), 36 deletions(-) diff --git a/.github/workflows/agent-docker-publish.yml b/.github/workflows/agent-docker-publish.yml index 5b6b9ec732f..af8b72757db 100644 --- a/.github/workflows/agent-docker-publish.yml +++ b/.github/workflows/agent-docker-publish.yml @@ -5,6 +5,7 @@ on: # Publish `master` as Docker `latest` image. branches: - master + - release-* # Publish `v1.2.3` tags as releases. tags: @@ -14,7 +15,7 @@ on: pull_request: env: - IMAGE_NAME: agent + IMAGE_NAME: kserve-agent jobs: # Run tests. @@ -54,15 +55,16 @@ jobs: - name: Setup Docker Buildx uses: docker/setup-buildx-action@v2 - - name: Login to DockerHub + - name: Login to Quay uses: docker/login-action@v2 with: - username: ${{ secrets.DOCKER_USER }} - password: ${{ secrets.DOCKER_PASSWORD }} + registry: quay.io + username: ${{ secrets.QUAY_USER }} + password: ${{ secrets.QUAY_PASSWORD }} - name: export version variable run: | - IMAGE_ID=kserve/$IMAGE_NAME + IMAGE_ID=quay.io/${{ vars.QUAY_OWNER }}/$IMAGE_NAME # Change all uppercase to lowercase IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') @@ -75,9 +77,14 @@ jobs: # Use Docker `latest` tag convention [ "$VERSION" == "master" ] && VERSION=latest - - echo VERSION=$VERSION >> $GITHUB_ENV - echo IMAGE_ID=$IMAGE_ID >> $GITHUB_ENV + [[ "$VERSION" =~ ^release- ]] && VERSION=$(echo $VERSION | sed 's/^release-//')-latest + + TAGS=$IMAGE_ID:$VERSION + + # If a vX.Y.Z release is being built, also update the vX.Y tag. + [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] && TAGS=$TAGS,$IMAGE_ID:$(echo $VERSION | sed 's/\(.*\)\.[[:digit:]]\+$/\1/') + + echo CONTAINER_TAGS=$TAGS >> $GITHUB_ENV - name: Build and push uses: docker/build-push-action@v3 @@ -86,4 +93,4 @@ jobs: context: . file: agent.Dockerfile push: true - tags: ${{ env.IMAGE_ID }}:${{ env.VERSION }} + tags: ${{ env.CONTAINER_TAGS }} diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 4bfb82594b7..26486a1b098 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -47,7 +47,9 @@ jobs: echo "Coverage output is ${{ steps.test.outputs.coverage }}" - name: Update coverage badge - if: github.ref == 'refs/heads/master' + # Disabling, because this tries to update a Gist owned by KServe. + # More info: https://github.com/opendatahub-io/kserve/issues/29 + if: false # github.ref == 'refs/heads/master' uses: schneegans/dynamic-badges-action@v1.4.0 with: auth: ${{ secrets.GIST_SECRET }} diff --git a/.github/workflows/kserve-controller-docker-publish.yml b/.github/workflows/kserve-controller-docker-publish.yml index 90def6755de..f7c2f2b9c23 100644 --- a/.github/workflows/kserve-controller-docker-publish.yml +++ b/.github/workflows/kserve-controller-docker-publish.yml @@ -5,6 +5,7 @@ on: # Publish `master` as Docker `latest` image. branches: - master + - release-* # Publish `v1.2.3` tags as releases. tags: @@ -52,15 +53,16 @@ jobs: - name: Setup Docker Buildx uses: docker/setup-buildx-action@v2 - - name: Login to DockerHub + - name: Login to Quay uses: docker/login-action@v2 with: - username: ${{ secrets.DOCKER_USER }} - password: ${{ secrets.DOCKER_PASSWORD }} + registry: quay.io + username: ${{ secrets.QUAY_USER }} + password: ${{ secrets.QUAY_PASSWORD }} - name: export version variable run: | - IMAGE_ID=kserve/$IMAGE_NAME + IMAGE_ID=quay.io/${{ vars.QUAY_OWNER }}/$IMAGE_NAME # Change all uppercase to lowercase IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') @@ -73,9 +75,14 @@ jobs: # Use Docker `latest` tag convention [ "$VERSION" == "master" ] && VERSION=latest + [[ "$VERSION" =~ ^release- ]] && VERSION=$(echo $VERSION | sed 's/^release-//')-latest - echo VERSION=$VERSION >> $GITHUB_ENV - echo IMAGE_ID=$IMAGE_ID >> $GITHUB_ENV + TAGS=$IMAGE_ID:$VERSION + + # If a vX.Y.Z release is being built, also update the vX.Y tag. + [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] && TAGS=$TAGS,$IMAGE_ID:$(echo $VERSION | sed 's/\(.*\)\.[[:digit:]]\+$/\1/') + + echo CONTAINER_TAGS=$TAGS >> $GITHUB_ENV - name: Build and push uses: docker/build-push-action@v3 @@ -84,4 +91,4 @@ jobs: context: . file: Dockerfile push: true - tags: ${{ env.IMAGE_ID }}:${{ env.VERSION }} + tags: ${{ env.CONTAINER_TAGS }} diff --git a/.github/workflows/router-docker-publish.yml b/.github/workflows/router-docker-publish.yml index ad701ce4199..e7f8b329fd3 100644 --- a/.github/workflows/router-docker-publish.yml +++ b/.github/workflows/router-docker-publish.yml @@ -5,6 +5,7 @@ on: # Publish `master` as Docker `latest` image. branches: - master + - release-* # Publish `v1.2.3` tags as releases. tags: @@ -14,7 +15,7 @@ on: pull_request: env: - IMAGE_NAME: router + IMAGE_NAME: kserve-router jobs: # Run tests. @@ -52,15 +53,16 @@ jobs: - name: Setup Docker Buildx uses: docker/setup-buildx-action@v2 - - name: Login to DockerHub + - name: Login to Quay uses: docker/login-action@v2 with: - username: ${{ secrets.DOCKER_USER }} - password: ${{ secrets.DOCKER_PASSWORD }} + registry: quay.io + username: ${{ secrets.QUAY_USER }} + password: ${{ secrets.QUAY_PASSWORD }} - name: export version variable run: | - IMAGE_ID=kserve/$IMAGE_NAME + IMAGE_ID=quay.io/${{ vars.QUAY_OWNER }}/$IMAGE_NAME # Change all uppercase to lowercase IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') @@ -73,9 +75,14 @@ jobs: # Use Docker `latest` tag convention [ "$VERSION" == "master" ] && VERSION=latest - - echo VERSION=$VERSION >> $GITHUB_ENV - echo IMAGE_ID=$IMAGE_ID >> $GITHUB_ENV + [[ "$VERSION" =~ ^release- ]] && VERSION=$(echo $VERSION | sed 's/^release-//')-latest + + TAGS=$IMAGE_ID:$VERSION + + # If a vX.Y.Z release is being built, also update the vX.Y tag. + [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] && TAGS=$TAGS,$IMAGE_ID:$(echo $VERSION | sed 's/\(.*\)\.[[:digit:]]\+$/\1/') + + echo CONTAINER_TAGS=$TAGS >> $GITHUB_ENV - name: Build and push uses: docker/build-push-action@v3 @@ -84,4 +91,4 @@ jobs: context: . file: router.Dockerfile push: true - tags: ${{ env.IMAGE_ID }}:${{ env.VERSION }} + tags: ${{ env.CONTAINER_TAGS }} diff --git a/.github/workflows/storage-initializer-docker-publisher.yml b/.github/workflows/storage-initializer-docker-publisher.yml index 6543f4ca8f0..5444d06ec6d 100644 --- a/.github/workflows/storage-initializer-docker-publisher.yml +++ b/.github/workflows/storage-initializer-docker-publisher.yml @@ -5,6 +5,7 @@ on: # Publish `master` as Docker `latest` image. branches: - master + - release-* # Publish `v1.2.3` tags as releases. tags: @@ -14,7 +15,7 @@ on: pull_request: env: - IMAGE_NAME: storage-initializer + IMAGE_NAME: kserve-storage-initializer jobs: # Run tests. @@ -53,11 +54,11 @@ jobs: docker buildx build . --file storage-initializer.Dockerfile --tag $IMAGE_NAME - name: Log into registry - run: docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASSWORD }} + run: docker login -u ${{ secrets.QUAY_USER }} -p ${{ secrets.QUAY_PASSWORD }} quay.io - name: Push image run: | - IMAGE_ID=kserve/$IMAGE_NAME + IMAGE_ID=quay.io/${{ vars.QUAY_OWNER }}/$IMAGE_NAME # Change all uppercase to lowercase IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') @@ -70,10 +71,15 @@ jobs: # Use Docker `latest` tag convention [ "$VERSION" == "master" ] && VERSION=latest + [[ "$VERSION" =~ ^release- ]] && VERSION=$(echo $VERSION | sed 's/^release-//')-latest echo IMAGE_ID=$IMAGE_ID echo VERSION=$VERSION docker tag $IMAGE_NAME $IMAGE_ID:$VERSION docker push $IMAGE_ID:$VERSION - + + # If a vX.Y.Z release is being built, also update the vX.Y tag. + [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] && MINOR_VERSION=$(echo $VERSION | sed 's/\(.*\)\.[[:digit:]]\+$/\1/') + [ ! -z "$MINOR_VERSION" ] && docker tag $IMAGE_NAME $IMAGE_ID:$MINOR_VERSION + [ ! -z "$MINOR_VERSION" ] && docker push $IMAGE_ID:$MINOR_VERSION || true \ No newline at end of file diff --git a/README.md b/README.md index 6a733c363a5..47d735831c3 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ # KServe -[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white)](https://pkg.go.dev/github.com/kserve/kserve) -[![Coverage Status](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/andyi2it/5174bd748ac63a6e4803afea902e9810/raw/coverage.json)](https://github.com/kserve/kserve/actions/workflows/go.yml) -[![Go Report Card](https://goreportcard.com/badge/github.com/kserve/kserve)](https://goreportcard.com/report/github.com/kserve/kserve) -[![OpenSSF Best Practices](https://bestpractices.coreinfrastructure.org/projects/6643/badge)](https://bestpractices.coreinfrastructure.org/projects/6643) -[![Releases](https://img.shields.io/github/release-pre/kserve/kserve.svg?sort=semver)](https://github.com/kserve/kserve/releases) -[![LICENSE](https://img.shields.io/github/license/kserve/kserve.svg)](https://github.com/kserve/kserve/blob/master/LICENSE) +[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white)](https://pkg.go.dev/github.com/opendatahub-io/kserve) +[![Go Report Card](https://goreportcard.com/badge/github.com/opendatahub-io/kserve)](https://goreportcard.com/report/github.com/opendatahub-io/kserve) +[![Releases](https://img.shields.io/github/release-pre/opendatahub-io/kserve.svg?sort=semver)](https://github.com/opendatahub-io/kserve/releases) +[![LICENSE](https://img.shields.io/github/license/opendatahub-io/kserve.svg)](https://github.com/opendatahub-io/kserve/blob/master/LICENSE) [![Slack Status](https://img.shields.io/badge/slack-join_chat-white.svg?logo=slack&style=social)](https://kubeflow.slack.com/archives/CH6E58LNP) KServe provides a Kubernetes [Custom Resource Definition](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) for serving machine learning (ML) models on arbitrary frameworks. It aims to solve production model serving use cases by providing performant, high abstraction interfaces for common ML frameworks like Tensorflow, XGBoost, ScikitLearn, PyTorch, and ONNX. From caea0d64ac39906d58d27b9eb4438d25e8a42f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Mon, 24 Jul 2023 13:38:58 -0600 Subject: [PATCH 05/45] Fix Kustomize manifests for OpenShift MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Kustomize patches for OpenShift were cherry-picked from the release-v0.10 branch. The cherry-pick succeeded, but the resulting manifests were not working, because of the differences. This fixes the manifests and bring them back to a working state. Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- config/default/kustomization.yaml | 148 +++++++++++++++--------------- 1 file changed, 73 insertions(+), 75 deletions(-) diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index a86faccb55d..672d67076f4 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -68,9 +68,9 @@ replacements: index: 0 - source: - group: cert-manager.io - kind: Certificate - name: serving-cert + group: apps + kind: Deployment + name: kserve-controller-manager version: v1 fieldPath: metadata.namespace targets: @@ -99,56 +99,56 @@ replacements: name: inferencegraph.serving.kserve.io fieldPaths: - webhooks.*.clientConfig.service.namespace - - select: - kind: Certificate - name: serving-cert - namespace: kserve - fieldPaths: - - spec.commonName - - spec.dnsNames.0 - options: - delimiter: '.' - index: 1 - - select: - kind: CustomResourceDefinition - name: inferenceservices.serving.kserve.io - fieldPaths: - - metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 0 - - select: - kind: MutatingWebhookConfiguration - name: inferenceservice.serving.kserve.io - fieldPaths: - - metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 0 - - select: - kind: ValidatingWebhookConfiguration - name: inferenceservice.serving.kserve.io - fieldPaths: - - metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 0 - - select: - kind: ValidatingWebhookConfiguration - name: trainedmodel.serving.kserve.io - fieldPaths: - - metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 0 - - select: - kind: ValidatingWebhookConfiguration - name: inferencegraph.serving.kserve.io - fieldPaths: - - metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 0 +# - select: +# kind: Certificate +# name: serving-cert +# namespace: kserve +# fieldPaths: +# - spec.commonName +# - spec.dnsNames.0 +# options: +# delimiter: '.' +# index: 1 +# - select: +# kind: CustomResourceDefinition +# name: inferenceservices.serving.kserve.io +# fieldPaths: +# - metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 +# - select: +# kind: MutatingWebhookConfiguration +# name: inferenceservice.serving.kserve.io +# fieldPaths: +# - metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 +# - select: +# kind: ValidatingWebhookConfiguration +# name: inferenceservice.serving.kserve.io +# fieldPaths: +# - metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 +# - select: +# kind: ValidatingWebhookConfiguration +# name: trainedmodel.serving.kserve.io +# fieldPaths: +# - metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 +# - select: +# kind: ValidatingWebhookConfiguration +# name: inferencegraph.serving.kserve.io +# fieldPaths: +# - metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 # Protect the /metrics endpoint by putting it behind auth. # Only one of manager_auth_proxy_patch.yaml and @@ -170,26 +170,24 @@ patches: - path: manager_resources_patch.yaml - path: inferenceservice_conversion_webhook.yaml - path: cainjection_conversion_webhook.yaml - -patches: - # Since OpenShift serving-certificates are being used, - # remove CA bundle placeholders - - patch: |- - - op: remove - path: "/spec/conversion/webhook/clientConfig/caBundle" - target: - kind: CustomResourceDefinition - name: inferenceservices.serving.kserve.io - - patch: |- - - op: remove - path: "/webhooks/0/clientConfig/caBundle" - - op: remove - path: "/webhooks/1/clientConfig/caBundle" - target: - kind: MutatingWebhookConfiguration - - patch: |- - - op: remove - path: "/webhooks/0/clientConfig/caBundle" - target: - kind: ValidatingWebhookConfiguration +# Since OpenShift serving-certificates are being used, +# remove CA bundle placeholders +- patch: |- + - op: remove + path: "/spec/conversion/webhook/clientConfig/caBundle" + target: + kind: CustomResourceDefinition + name: inferenceservices.serving.kserve.io +- patch: |- + - op: remove + path: "/webhooks/0/clientConfig/caBundle" + - op: remove + path: "/webhooks/1/clientConfig/caBundle" + target: + kind: MutatingWebhookConfiguration +- patch: |- + - op: remove + path: "/webhooks/0/clientConfig/caBundle" + target: + kind: ValidatingWebhookConfiguration From 70117d19af183a7fa76c31381185282ba82b6f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= Date: Tue, 25 Jul 2023 09:11:01 -0600 Subject: [PATCH 06/45] Update OWNERS files --- OWNERS | 27 ++++++++++++++++----------- python/kserve/OWNERS | 3 --- 2 files changed, 16 insertions(+), 14 deletions(-) delete mode 100644 python/kserve/OWNERS diff --git a/OWNERS b/OWNERS index d84c9a5b462..b0f1ad5a5ee 100644 --- a/OWNERS +++ b/OWNERS @@ -1,13 +1,18 @@ approvers: - - njhill - - yuzisun + - anishasthana + - danielezonca + - heyselbi + - israel-hdez + - Jooho + - VedantMahabaleshwarkar + - Xaenalt + - vaibhavjainwiz reviewers: - - adriangonz - - alexagriffith - - ckadner - - iamlovingit - - rachitchauhan43 - - sukumargaonkar - - theofpa - - njhill - - yuzisun + - anishasthana + - danielezonca + - heyselbi + - israel-hdez + - Jooho + - VedantMahabaleshwarkar + - Xaenalt + - vaibhavjainwiz diff --git a/python/kserve/OWNERS b/python/kserve/OWNERS deleted file mode 100644 index 9d5065e4021..00000000000 --- a/python/kserve/OWNERS +++ /dev/null @@ -1,3 +0,0 @@ -approvers: - - jinchihe - - yuzisun From ecff0797f50bb942fa5a86a2387bd7aa7019afd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Tue, 25 Jul 2023 11:51:39 -0600 Subject: [PATCH 07/45] Onboarding on openshift-ci MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are the needed changes to have openshift-ci running the E2E tests successfully. There are several groups of E2E tests that can be deduced from the .github/workflows/e2e-test.yaml file: fast, slow, explainer, transformer-mms, qpext, grpc, helm, raw and kourier. For ODH, the `fast`, `slow` and `grpc` groups are the ones that cover the features that are going to be supported in the initial adoption of ODH. This commit contains the needed adaptations to the E2E tests of the `fast` and `slow` groups to successfully run them in an openshift cluster. It also adds a few scripts on test/scripts/openshift-ci to run these E2Es in the openshift-ci operator. Some of these changes should be seen as provisional and should be rolled back: * test/e2e/common/utils.py: because of the networking/DNS expectations, that are currently not covered in ODH's installation. * test/e2e/predictor/*: * In general all changes under this path should be seen as provisional. However, since ODH won't support all ServingRuntimes, it is possible that some of the tests will stay out. * There are some GRPC-related tests marked as skipped. Since this work is not enabling the `grpc` group, a subsequent commit/PR for enabling GRPC E2Es should remove/revert those skip marks. * Also, there are some tests skipped with the `Not testable in ODH at the moment` reason. The root cause of the failure should be investigated to re-enable these tests. * python/kserve/kserve/models/v1beta1_inference_service.py: This is injecting an annotation that is required given the specifics of OSSM/Maistra and OpenShift-Serverless that are used in ODH. This annotation is, currently, user responsibility and this was the cleanest way to add it in the E2Es. Being platform-specific, it's been discussed that this (and some other) annotation should be injected by some controller to relief the user from this responsibility. If this happens, this change should be reverted. Also, ideally, changes to the following files should be contributed back to upstream. Those changes are not required in upstream and should have no effect, but in openshift-ci become required because a different builder image is being used: * Dockerfile * agent.Dockerfile Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- Dockerfile | 2 +- agent.Dockerfile | 2 +- .../models/v1beta1_inference_service.py | 2 + test/e2e/common/utils.py | 19 +- test/e2e/predictor/test_paddle.py | 1 + test/e2e/predictor/test_sklearn.py | 5 + test/e2e/predictor/test_tensorflow.py | 3 + test/e2e/predictor/test_torchserve.py | 2 + test/e2e/predictor/test_triton.py | 3 + test/scripts/openshift-ci/deploy.ossm.sh | 160 ++++++++++++++++ .../scripts/openshift-ci/deploy.serverless.sh | 174 ++++++++++++++++++ test/scripts/openshift-ci/run-e2e-tests.sh | 111 +++++++++++ 12 files changed, 473 insertions(+), 11 deletions(-) create mode 100755 test/scripts/openshift-ci/deploy.ossm.sh create mode 100755 test/scripts/openshift-ci/deploy.serverless.sh create mode 100755 test/scripts/openshift-ci/run-e2e-tests.sh diff --git a/Dockerfile b/Dockerfile index 5066adcc201..934ea8fc884 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ COPY cmd/ cmd/ COPY pkg/ pkg/ # Build -RUN CGO_ENABLED=0 GOOS=linux go build -a -o manager ./cmd/manager +RUN CGO_ENABLED=0 GOOS=linux GOFLAGS=-mod=mod go build -a -o manager ./cmd/manager # Copy the controller-manager into a thin image FROM gcr.io/distroless/static:nonroot diff --git a/agent.Dockerfile b/agent.Dockerfile index a70ee0fb09e..7b22f4fbdaf 100644 --- a/agent.Dockerfile +++ b/agent.Dockerfile @@ -12,7 +12,7 @@ COPY pkg/ pkg/ COPY cmd/ cmd/ # Build -RUN CGO_ENABLED=0 GOOS=linux go build -a -o agent ./cmd/agent +RUN CGO_ENABLED=0 GOOS=linux GOFLAGS=-mod=mod go build -a -o agent ./cmd/agent # Copy the inference-agent into a thin image FROM gcr.io/distroless/static:nonroot diff --git a/python/kserve/kserve/models/v1beta1_inference_service.py b/python/kserve/kserve/models/v1beta1_inference_service.py index 0f64aabf8b3..d6bd3f89f25 100644 --- a/python/kserve/kserve/models/v1beta1_inference_service.py +++ b/python/kserve/kserve/models/v1beta1_inference_service.py @@ -150,6 +150,8 @@ def metadata(self, metadata): :param metadata: The metadata of this V1beta1InferenceService. # noqa: E501 :type: V1ObjectMeta """ + if metadata is not None: + metadata.annotations = {"serving.knative.openshift.io/enablePassthrough": "true"} self._metadata = metadata diff --git a/test/e2e/common/utils.py b/test/e2e/common/utils.py index 058c4c6c0a7..4a2bbca8a0b 100644 --- a/test/e2e/common/utils.py +++ b/test/e2e/common/utils.py @@ -80,22 +80,23 @@ def predict_str(service_name, input_json, protocol_version="v1", ) # temporary sleep until this is fixed https://github.com/kserve/kserve/issues/604 time.sleep(10) - cluster_ip = get_cluster_ip() - host = urlparse(isvc["status"]["url"]).netloc - path = urlparse(isvc["status"]["url"]).path + # cluster_ip = get_cluster_ip() + host = urlparse(isvc["status"]["components"]["predictor"]["url"]).netloc + path = urlparse(isvc["status"]["components"]["predictor"]["url"]).path + cluster_ip = host headers = {"Host": host, "Content-Type": "application/json"} if model_name is None: model_name = service_name - url = f"http://{cluster_ip}{path}/v1/models/{model_name}:predict" + url = f"https://{cluster_ip}{path}/v1/models/{model_name}:predict" if protocol_version == "v2": - url = f"http://{cluster_ip}{path}/v2/models/{model_name}/infer" + url = f"https://{cluster_ip}{path}/v2/models/{model_name}/infer" logging.info("Sending Header = %s", headers) logging.info("Sending url = %s", url) logging.info("Sending request data: %s", input_json) - response = requests.post(url, input_json, headers=headers) + response = requests.post(url, input_json, headers=headers, verify=False) logging.info("Got response code %s, content %s", response.status_code, response.content) if response.status_code == 200: preds = json.loads(response.content.decode("utf-8")) @@ -118,7 +119,7 @@ def predict_ig(ig_name, input_json, protocol_version="v1", ) cluster_ip = get_cluster_ip() - host = urlparse(ig["status"]["url"]).netloc + host = urlparse(ig["status"]["components"]["predictor"]["url"]).netloc headers = {"Host": host} url = f"http://{cluster_ip}" @@ -154,7 +155,7 @@ def explain_response(service_name, input_json): # temporary sleep until this is fixed https://github.com/kserve/kserve/issues/604 time.sleep(10) cluster_ip = get_cluster_ip() - host = urlparse(isvc["status"]["url"]).netloc + host = urlparse(isvc["status"]["components"]["predictor"]["url"]).netloc url = "http://{}/v1/models/{}:explain".format(cluster_ip, service_name) headers = {"Host": host} with open(input_json) as json_file: @@ -217,7 +218,7 @@ def predict_grpc(service_name, payload, parameters=None, version=constants.KSERV namespace=KSERVE_TEST_NAMESPACE, version=version, ) - host = urlparse(isvc["status"]["url"]).netloc + host = urlparse(isvc["status"]["components"]["predictor"]["url"]).netloc if ":" not in cluster_ip: cluster_ip = cluster_ip + ":80" diff --git a/test/e2e/predictor/test_paddle.py b/test/e2e/predictor/test_paddle.py index 687fec741af..5fb0b8aa922 100644 --- a/test/e2e/predictor/test_paddle.py +++ b/test/e2e/predictor/test_paddle.py @@ -162,6 +162,7 @@ def test_paddle_v2_kserve(): @pytest.mark.slow +@pytest.mark.skip("GRPC tests are failing in ODH at the moment") def test_paddle_v2_grpc(): service_name = "isvc-paddle-v2-grpc" model_name = "paddle" diff --git a/test/e2e/predictor/test_sklearn.py b/test/e2e/predictor/test_sklearn.py index 58546d31af0..cb3f9efa67e 100644 --- a/test/e2e/predictor/test_sklearn.py +++ b/test/e2e/predictor/test_sklearn.py @@ -206,6 +206,7 @@ def test_sklearn_v2(): @pytest.mark.slow +@pytest.mark.skip("GRPC tests are failing in ODH at the moment") def test_sklearn_v2_grpc(): service_name = "isvc-sklearn-v2-grpc" model_name = "sklearn" @@ -254,7 +255,10 @@ def test_sklearn_v2_grpc(): kserve_client.delete(service_name, KSERVE_TEST_NAMESPACE) +# In ODH, this test generates the following response: +# Code 500 - 'ColumnTransformer' object has no attribute '_name_to_fitted_passthrough' @pytest.mark.slow +@pytest.mark.skip("Not testable in ODH at the moment") def test_sklearn_v2_mixed(): service_name = "isvc-sklearn-v2-mixed" predictor = V1beta1PredictorSpec( @@ -291,6 +295,7 @@ def test_sklearn_v2_mixed(): @pytest.mark.slow +@pytest.mark.skip("GRPC tests are failing in ODH at the moment") def test_sklearn_v2_mixed_grpc(): service_name = "isvc-sklearn-v2-mixed-grpc" model_name = "sklearn" diff --git a/test/e2e/predictor/test_tensorflow.py b/test/e2e/predictor/test_tensorflow.py index 457d6fd95d3..e1c060dbdbf 100644 --- a/test/e2e/predictor/test_tensorflow.py +++ b/test/e2e/predictor/test_tensorflow.py @@ -59,7 +59,10 @@ def test_tensorflow_kserve(): kserve_client.delete(service_name, namespace=KSERVE_TEST_NAMESPACE) +# In ODH, this test generates the following response: +# 502 Server Error: Bad Gateway for url @pytest.mark.slow +@pytest.mark.skip("Not testable in ODH at the moment") def test_tensorflow_runtime_kserve(): service_name = 'isvc-tensorflow-runtime' predictor = V1beta1PredictorSpec( diff --git a/test/e2e/predictor/test_torchserve.py b/test/e2e/predictor/test_torchserve.py index 6ca35a5b7a1..5b537a4d7ec 100644 --- a/test/e2e/predictor/test_torchserve.py +++ b/test/e2e/predictor/test_torchserve.py @@ -32,6 +32,8 @@ from ..common.utils import KSERVE_TEST_NAMESPACE from ..common import inference_pb2 +pytest.skip("ODH does not support torchserve at the moment", allow_module_level=True) + @pytest.mark.slow def test_torchserve_kserve(): diff --git a/test/e2e/predictor/test_triton.py b/test/e2e/predictor/test_triton.py index 00293445094..b5f5aab565e 100644 --- a/test/e2e/predictor/test_triton.py +++ b/test/e2e/predictor/test_triton.py @@ -70,7 +70,10 @@ def test_triton(): kserve_client.delete(service_name, KSERVE_TEST_NAMESPACE) +# Not testable in ODH until the following issue is solved: +# https://github.com/opendatahub-io/odh-model-controller/issues/59 @pytest.mark.fast +@pytest.mark.skip(reason="Not testable in ODH at the moment") def test_triton_runtime_with_transformer(): service_name = 'isvc-triton-runtime' predictor = V1beta1PredictorSpec( diff --git a/test/scripts/openshift-ci/deploy.ossm.sh b/test/scripts/openshift-ci/deploy.ossm.sh new file mode 100755 index 00000000000..2e3876a39ca --- /dev/null +++ b/test/scripts/openshift-ci/deploy.ossm.sh @@ -0,0 +1,160 @@ +#!/usr/bin/env bash +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eu + +waitforpodlabeled() { + local ns=${1?namespace is required}; shift + local podlabel=${1?pod label is required}; shift + + echo "Waiting for pod -l $podlabel to be created" + until oc get pod -n "$ns" -l $podlabel -o=jsonpath='{.items[0].metadata.name}' >/dev/null 2>&1; do + sleep 1 + done +} + +waitpodready() { + local ns=${1?namespace is required}; shift + local podlabel=${1?pod label is required}; shift + + waitforpodlabeled "$ns" "$podlabel" + echo "Waiting for pod -l $podlabel to become ready" + oc wait --for=condition=ready --timeout=180s pod -n $ns -l $podlabel +} + + +# Deploy Distributed tracing operator (Jaeger) +cat </dev/null 2>&1; do + sleep 1 + done +} + +waitpodready() { + local ns=${1?namespace is required}; shift + local podlabel=${1?pod label is required}; shift + + waitforpodlabeled "$ns" "$podlabel" + sleep 10 + oc get pod -n $ns -l $podlabel + + echo "Waiting for pod -l $podlabel to become ready" + oc wait --for=condition=ready --timeout=600s pod -n $ns -l $podlabel || (oc get pod -n $ns -l $podlabel && false) +} + +# Deploy Serverless operator +cat < /dev/null; then + echo "Installing Kustomize" + curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash -s -- 5.0.1 $HOME/.local/bin +fi + +# If minio CLI is not installed, install it +if ! command -v mc &> /dev/null; then + echo "Installing Minio CLI" + curl https://dl.min.io/client/mc/release/linux-amd64/mc --create-dirs -o $HOME/.local/bin/mc + chmod +x $HOME/.local/bin/mc +fi + +# +echo "Installing KServe Python SDK ..." +pushd $PROJECT_ROOT >/dev/null + ./test/scripts/gh-actions/setup-poetry.sh + ./test/scripts/gh-actions/check-poetry-lockfile.sh +popd +pushd $PROJECT_ROOT/python/kserve >/dev/null + poetry install --with=test --no-interaction +popd + +# Install KServe stack +echo "Installing OSSM" +$MY_PATH/deploy.ossm.sh +echo "Installing Serverless" +$MY_PATH/deploy.serverless.sh + +echo "Installing KServe with Minio" +kustomize build $PROJECT_ROOT/config/overlays/test | \ + sed "s|kserve/storage-initializer:latest|${STORAGE_INITIALIZER_IMAGE}|" | \ + sed "s|kserve/agent:latest|${KSERVE_AGENT_IMAGE}|" | \ + sed "s|kserve/router:latest|${KSERVE_ROUTER_IMAGE}|" | \ + sed "s|kserve/kserve-controller:latest|${KSERVE_CONTROLLER_IMAGE}|" | \ + oc apply -f - +oc wait --for=condition=ready pod -l control-plane=kserve-controller-manager -n kserve --timeout=300s + +echo "Add testing models to minio storage ..." # Reference: config/overlays/test/minio/minio-init-job.yaml +curl -L https://storage.googleapis.com/kfserving-examples/models/sklearn/1.0/model/model.joblib -o /tmp/sklearn-model.joblib +oc expose service minio-service -n kserve && sleep 5 +MINIO_ROUTE=$(oc get routes -n kserve minio-service -o jsonpath="{.spec.host}") +mc alias set storage http://$MINIO_ROUTE minio minio123 +mc mb storage/example-models +mc cp /tmp/sklearn-model.joblib storage/example-models/sklearn/model.joblib +oc delete route -n kserve minio-service + +# +echo "Prepare CI namespace and install ServingRuntimes" +cat </dev/null + ./test/scripts/gh-actions/run-e2e-tests.sh "$1" +popd From 50d33edee49f1eeb1db4a184e1aefb69cf5ac82a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Fri, 21 Jul 2023 13:01:14 -0600 Subject: [PATCH 08/45] Add ODH overlay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Augments the `default` profile with some changes expected by an ODH installation: * Removes the `Namespace` CR, because the ODH operator does not expect such resource. The Namespace is expected to be created in advance to later create a KfDef on it, where resources are going to be installed. * Adds cluster roles, to extend the cluster's default user-facing roles with KServe privileges. Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- config/overlays/odh/kustomization.yaml | 9 ++++ config/overlays/odh/remove-namespace.yaml | 6 +++ config/overlays/odh/user-cluster-roles.yaml | 57 +++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 config/overlays/odh/kustomization.yaml create mode 100644 config/overlays/odh/remove-namespace.yaml create mode 100644 config/overlays/odh/user-cluster-roles.yaml diff --git a/config/overlays/odh/kustomization.yaml b/config/overlays/odh/kustomization.yaml new file mode 100644 index 00000000000..87ae27f946f --- /dev/null +++ b/config/overlays/odh/kustomization.yaml @@ -0,0 +1,9 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- ../../default +- user-cluster-roles.yaml + +patchesStrategicMerge: +- remove-namespace.yaml diff --git a/config/overlays/odh/remove-namespace.yaml b/config/overlays/odh/remove-namespace.yaml new file mode 100644 index 00000000000..bdca3de1243 --- /dev/null +++ b/config/overlays/odh/remove-namespace.yaml @@ -0,0 +1,6 @@ +# Remove namespace resource as namespace will already exist. +$patch: delete +apiVersion: v1 +kind: Namespace +metadata: + name: kserve diff --git a/config/overlays/odh/user-cluster-roles.yaml b/config/overlays/odh/user-cluster-roles.yaml new file mode 100644 index 00000000000..d248b9996fa --- /dev/null +++ b/config/overlays/odh/user-cluster-roles.yaml @@ -0,0 +1,57 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kserve-admin + labels: + rbac.authorization.k8s.io/aggregate-to-admin: "true" +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.authorization.k8s.io/aggregate-to-kserve-admin: "true" +rules: [] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kserve-edit + labels: + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-kserve-admin: "true" +rules: + - apiGroups: + - serving.kserve.io + resources: + - inferenceservices + - servingruntimes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kserve-view + labels: + rbac.authorization.k8s.io/aggregate-to-view: "true" +rules: + - apiGroups: + - kubeflow.org + resources: + - servingruntimes + - servingruntimes/status + - servingruntimes/finalizers + - inferenceservices + - inferenceservices/status + - inferenceservices/finalizers + verbs: + - get + - list + - watch From ebfe75c86a4220e46b433b4235e49c9bc01d23c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Tue, 12 Sep 2023 11:26:39 -0600 Subject: [PATCH 09/45] Adapt kserve/kserve#3031 for ODH and OpenShift MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- cmd/manager/main.go | 4 +- config/default/kustomization.yaml | 22 +- ...e_validationwebhook_cainjection_patch.yaml | 2 +- config/webhook/manifests.yaml | 54 +- .../servingruntime/servingruntime_webhook.go | 90 +- .../serving.kserve.io_inferenceservices.yaml | 1880 ----------------- 6 files changed, 86 insertions(+), 1966 deletions(-) diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 3e86b0d9706..ab3101a0c05 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -222,8 +222,8 @@ func main() { log.Info("registering webhooks to the webhook server") hookServer.Register("/mutate-pods", &webhook.Admission{Handler: &pod.Mutator{}}) - log.Info("registering cluster serving runtime validator webhook to the webhook server") - hookServer.Register("/validate-serving-kserve-io-v1alpha1-clusterservingruntime", &webhook.Admission{Handler: &servingruntime.ClusterServingRuntimeValidator{}}) + //log.Info("registering cluster serving runtime validator webhook to the webhook server") + //hookServer.Register("/validate-serving-kserve-io-v1alpha1-clusterservingruntime", &webhook.Admission{Handler: &servingruntime.ClusterServingRuntimeValidator{}}) log.Info("registering serving runtime validator webhook to the webhook server") hookServer.Register("/validate-serving-kserve-io-v1alpha1-servingruntime", &webhook.Admission{Handler: &servingruntime.ServingRuntimeValidator{}}) diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index fb09160a801..2a0cb426618 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -56,11 +56,11 @@ replacements: name: inferencegraph.serving.kserve.io fieldPaths: - webhooks.*.clientConfig.service.name - - select: - kind: ValidatingWebhookConfiguration - name: clusterservingruntime.serving.kserve.io - fieldPaths: - - webhooks.*.clientConfig.service.name +# - select: +# kind: ValidatingWebhookConfiguration +# name: clusterservingruntime.serving.kserve.io +# fieldPaths: +# - webhooks.*.clientConfig.service.name - select: kind: ValidatingWebhookConfiguration name: servingruntime.serving.kserve.io @@ -109,11 +109,11 @@ replacements: name: inferencegraph.serving.kserve.io fieldPaths: - webhooks.*.clientConfig.service.namespace - - select: - kind: ValidatingWebhookConfiguration - name: clusterservingruntime.serving.kserve.io - fieldPaths: - - webhooks.*.clientConfig.service.namespace +# - select: +# kind: ValidatingWebhookConfiguration +# name: clusterservingruntime.serving.kserve.io +# fieldPaths: +# - webhooks.*.clientConfig.service.namespace - select: kind: ValidatingWebhookConfiguration name: servingruntime.serving.kserve.io @@ -202,7 +202,7 @@ patches: - path: isvc_validatingwebhook_cainjection_patch.yaml - path: inferencegraph_validatingwebhook_cainjection_patch.yaml - path: trainedmodel_validatingwebhook_cainjection_patch.yaml -- path: clusterservingruntime_validatingwebhook_cainjection_patch.yaml +#- path: clusterservingruntime_validatingwebhook_cainjection_patch.yaml - path: servingruntime_validationwebhook_cainjection_patch.yaml - path: svc_webhook_cainjection_patch.yaml - path: manager_resources_patch.yaml diff --git a/config/default/servingruntime_validationwebhook_cainjection_patch.yaml b/config/default/servingruntime_validationwebhook_cainjection_patch.yaml index ac87c8516b3..c7335123f51 100644 --- a/config/default/servingruntime_validationwebhook_cainjection_patch.yaml +++ b/config/default/servingruntime_validationwebhook_cainjection_patch.yaml @@ -3,6 +3,6 @@ kind: ValidatingWebhookConfiguration metadata: name: servingruntime.serving.kserve.io annotations: - cert-manager.io/inject-ca-from: $(kserveNamespace)/serving-cert + service.beta.openshift.io/inject-cabundle: "true" webhooks: - name: servingruntime.kserve-webhook-server.validator diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 37baf57812a..92c00a79411 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -136,33 +136,33 @@ webhooks: resources: - inferencegraphs --- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - creationTimestamp: null - name: clusterservingruntime.serving.kserve.io -webhooks: - - clientConfig: - caBundle: Cg== - service: - name: $(webhookServiceName) - namespace: $(kserveNamespace) - path: /validate-serving-kserve-io-v1alpha1-clusterservingruntime - failurePolicy: Fail - name: clusterservingruntime.kserve-webhook-server.validator - sideEffects: None - admissionReviewVersions: ["v1beta1"] - rules: - - apiGroups: - - serving.kserve.io - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - resources: - - clusterservingruntimes ---- +#apiVersion: admissionregistration.k8s.io/v1 +#kind: ValidatingWebhookConfiguration +#metadata: +# creationTimestamp: null +# name: clusterservingruntime.serving.kserve.io +#webhooks: +# - clientConfig: +# caBundle: Cg== +# service: +# name: $(webhookServiceName) +# namespace: $(kserveNamespace) +# path: /validate-serving-kserve-io-v1alpha1-clusterservingruntime +# failurePolicy: Fail +# name: clusterservingruntime.kserve-webhook-server.validator +# sideEffects: None +# admissionReviewVersions: ["v1beta1"] +# rules: +# - apiGroups: +# - serving.kserve.io +# apiVersions: +# - v1alpha1 +# operations: +# - CREATE +# - UPDATE +# resources: +# - clusterservingruntimes +#--- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: diff --git a/pkg/webhook/admission/servingruntime/servingruntime_webhook.go b/pkg/webhook/admission/servingruntime/servingruntime_webhook.go index ed6b7056a67..c1165ef95b6 100644 --- a/pkg/webhook/admission/servingruntime/servingruntime_webhook.go +++ b/pkg/webhook/admission/servingruntime/servingruntime_webhook.go @@ -34,17 +34,17 @@ import ( var log = logf.Log.WithName(constants.ServingRuntimeValidatorWebhookName) const ( - InvalidPriorityError = "Same priority assigned for the model format %s" - InvalidPriorityServingRuntimeError = "%s in the servingruntimes %s and %s in namespace %s" - InvalidPriorityClusterServingRuntimeError = "%s in the clusterservingruntimes %s and %s" + InvalidPriorityError = "Same priority assigned for the model format %s" + InvalidPriorityServingRuntimeError = "%s in the servingruntimes %s and %s in namespace %s" + //InvalidPriorityClusterServingRuntimeError = "%s in the clusterservingruntimes %s and %s" ) -// +kubebuilder:webhook:verbs=create;update,path=/validate-serving-kserve-io-v1alpha1-clusterservingruntime,mutating=false,failurePolicy=fail,groups=serving.kserve.io,resources=clusterservingruntimes,versions=v1alpha1,name=clusterservingruntime.kserve-webhook-server.validator - -type ClusterServingRuntimeValidator struct { - Client client.Client - Decoder *admission.Decoder -} +//// kubebuilder:webhook:verbs=create;update,path=/validate-serving-kserve-io-v1alpha1-clusterservingruntime,mutating=false,failurePolicy=fail,groups=serving.kserve.io,resources=clusterservingruntimes,versions=v1alpha1,name=clusterservingruntime.kserve-webhook-server.validator +// +//type ClusterServingRuntimeValidator struct { +// Client client.Client +// Decoder *admission.Decoder +//} // +kubebuilder:webhook:verbs=create;update,path=/validate-serving-kserve-io-v1alpha1-servingruntime,mutating=false,failurePolicy=fail,groups=serving.kserve.io,resources=servingruntimes,versions=v1alpha1,name=servingruntime.kserve-webhook-server.validator @@ -79,32 +79,32 @@ func (sr *ServingRuntimeValidator) Handle(ctx context.Context, req admission.Req return admission.Allowed("") } -// Handle validates the incoming request -func (csr *ClusterServingRuntimeValidator) Handle(ctx context.Context, req admission.Request) admission.Response { - clusterServingRuntime := &v1alpha1.ClusterServingRuntime{} - if err := csr.Decoder.Decode(req, clusterServingRuntime); err != nil { - log.Error(err, "Failed to decode cluster serving runtime", "name", clusterServingRuntime.Name) - return admission.Errored(http.StatusBadRequest, err) - } - - ExistingRuntimes := &v1alpha1.ClusterServingRuntimeList{} - if err := csr.Client.List(context.TODO(), ExistingRuntimes); err != nil { - log.Error(err, "Failed to get cluster serving runtime list") - return admission.Errored(http.StatusInternalServerError, err) - } - - // Only validate for priority if the new cluster serving runtime is not disabled - if clusterServingRuntime.Spec.IsDisabled() { - return admission.Allowed("") - } - - for i := range ExistingRuntimes.Items { - if err := validateServingRuntimePriority(&clusterServingRuntime.Spec, &ExistingRuntimes.Items[i].Spec, clusterServingRuntime.Name, ExistingRuntimes.Items[i].Name); err != nil { - return admission.Denied(fmt.Sprintf(InvalidPriorityClusterServingRuntimeError, err.Error(), ExistingRuntimes.Items[i].Name, clusterServingRuntime.Name)) - } - } - return admission.Allowed("") -} +//// Handle validates the incoming request +//func (csr *ClusterServingRuntimeValidator) Handle(ctx context.Context, req admission.Request) admission.Response { +// clusterServingRuntime := &v1alpha1.ClusterServingRuntime{} +// if err := csr.Decoder.Decode(req, clusterServingRuntime); err != nil { +// log.Error(err, "Failed to decode cluster serving runtime", "name", clusterServingRuntime.Name) +// return admission.Errored(http.StatusBadRequest, err) +// } +// +// ExistingRuntimes := &v1alpha1.ClusterServingRuntimeList{} +// if err := csr.Client.List(context.TODO(), ExistingRuntimes); err != nil { +// log.Error(err, "Failed to get cluster serving runtime list") +// return admission.Errored(http.StatusInternalServerError, err) +// } +// +// // Only validate for priority if the new cluster serving runtime is not disabled +// if clusterServingRuntime.Spec.IsDisabled() { +// return admission.Allowed("") +// } +// +// for i := range ExistingRuntimes.Items { +// if err := validateServingRuntimePriority(&clusterServingRuntime.Spec, &ExistingRuntimes.Items[i].Spec, clusterServingRuntime.Name, ExistingRuntimes.Items[i].Name); err != nil { +// return admission.Denied(fmt.Sprintf(InvalidPriorityClusterServingRuntimeError, err.Error(), ExistingRuntimes.Items[i].Name, clusterServingRuntime.Name)) +// } +// } +// return admission.Allowed("") +//} func areSupportedModelFormatsEqual(m1 v1alpha1.SupportedModelFormat, m2 v1alpha1.SupportedModelFormat) bool { if strings.EqualFold(m1.Name, m2.Name) && ((m1.Version == nil && m2.Version == nil) || @@ -151,20 +151,20 @@ func contains[T comparable](slice []T, element T) bool { return false } -// InjectClient injects the client. -func (csr *ClusterServingRuntimeValidator) InjectClient(c client.Client) error { - csr.Client = c - return nil -} +//// InjectClient injects the client. +//func (csr *ClusterServingRuntimeValidator) InjectClient(c client.Client) error { +// csr.Client = c +// return nil +//} // ClusterServingRuntimeValidator implements admission.DecoderInjector. // A decoder will be automatically injected. -// InjectDecoder injects the decoder. -func (csr *ClusterServingRuntimeValidator) InjectDecoder(d *admission.Decoder) error { - csr.Decoder = d - return nil -} +//// InjectDecoder injects the decoder. +//func (csr *ClusterServingRuntimeValidator) InjectDecoder(d *admission.Decoder) error { +// csr.Decoder = d +// return nil +//} // InjectClient injects the client. func (sr *ServingRuntimeValidator) InjectClient(c client.Client) error { diff --git a/test/crds/serving.kserve.io_inferenceservices.yaml b/test/crds/serving.kserve.io_inferenceservices.yaml index a439cdb7f19..140007c962a 100644 --- a/test/crds/serving.kserve.io_inferenceservices.yaml +++ b/test/crds/serving.kserve.io_inferenceservices.yaml @@ -1,1885 +1,5 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.12.0 - name: clusterservingruntimes.serving.kserve.io -spec: - group: serving.kserve.io - names: - kind: ClusterServingRuntime - listKind: ClusterServingRuntimeList - plural: clusterservingruntimes - singular: clusterservingruntime - scope: Cluster - versions: - - additionalPrinterColumns: - - jsonPath: .spec.disabled - name: Disabled - type: boolean - - jsonPath: .spec.supportedModelFormats[*].name - name: ModelType - type: string - - jsonPath: .spec.containers[*].name - name: Containers - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - properties: - apiVersion: - type: string - kind: - type: string - metadata: - type: object - spec: - properties: - affinity: - properties: - nodeAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - preference: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - weight: - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - properties: - nodeSelectorTerms: - items: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - type: array - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - topologyKey: - type: string - required: - - topologyKey - type: object - weight: - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - topologyKey: - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - topologyKey: - type: string - required: - - topologyKey - type: object - weight: - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - topologyKey: - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - annotations: - additionalProperties: - type: string - type: object - builtInAdapter: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - memBufferBytes: - type: integer - modelLoadingTimeoutMillis: - type: integer - runtimeManagementPort: - type: integer - serverType: - type: string - type: object - containers: - items: - properties: - args: - items: - type: string - type: array - command: - items: - type: string - type: array - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - envFrom: - items: - properties: - configMapRef: - properties: - name: - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - type: string - secretRef: - properties: - name: - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - resources: - properties: - claims: - items: - properties: - name: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - capabilities: - properties: - add: - items: - type: string - type: array - drop: - items: - type: string - type: array - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: - type: string - name: - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - type: string - required: - - name - type: object - type: array - disabled: - type: boolean - grpcDataEndpoint: - type: string - grpcEndpoint: - type: string - httpDataEndpoint: - type: string - imagePullSecrets: - items: - properties: - name: - type: string - type: object - x-kubernetes-map-type: atomic - type: array - labels: - additionalProperties: - type: string - type: object - multiModel: - type: boolean - nodeSelector: - additionalProperties: - type: string - type: object - protocolVersions: - items: - type: string - type: array - replicas: - type: integer - storageHelper: - properties: - disabled: - type: boolean - type: object - supportedModelFormats: - items: - properties: - autoSelect: - type: boolean - name: - type: string - priority: - format: int32 - minimum: 1 - type: integer - version: - type: string - required: - - name - type: object - type: array - tolerations: - items: - properties: - effect: - type: string - key: - type: string - operator: - type: string - tolerationSeconds: - format: int64 - type: integer - value: - type: string - type: object - type: array - volumes: - items: - properties: - awsElasticBlockStore: - properties: - fsType: - type: string - partition: - format: int32 - type: integer - readOnly: - type: boolean - volumeID: - type: string - required: - - volumeID - type: object - azureDisk: - properties: - cachingMode: - type: string - diskName: - type: string - diskURI: - type: string - fsType: - type: string - kind: - type: string - readOnly: - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - properties: - readOnly: - type: boolean - secretName: - type: string - shareName: - type: string - required: - - secretName - - shareName - type: object - cephfs: - properties: - monitors: - items: - type: string - type: array - path: - type: string - readOnly: - type: boolean - secretFile: - type: string - secretRef: - properties: - name: - type: string - type: object - x-kubernetes-map-type: atomic - user: - type: string - required: - - monitors - type: object - cinder: - properties: - fsType: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - type: string - type: object - x-kubernetes-map-type: atomic - volumeID: - type: string - required: - - volumeID - type: object - configMap: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - name: - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - csi: - properties: - driver: - type: string - fsType: - type: string - nodePublishSecretRef: - properties: - name: - type: string - type: object - x-kubernetes-map-type: atomic - readOnly: - type: boolean - volumeAttributes: - additionalProperties: - type: string - type: object - required: - - driver - type: object - downwardAPI: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - format: int32 - type: integer - path: - type: string - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - type: object - emptyDir: - properties: - medium: - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - ephemeral: - properties: - volumeClaimTemplate: - properties: - metadata: - type: object - spec: - properties: - accessModes: - items: - type: string - type: array - dataSource: - properties: - apiGroup: - type: string - kind: - type: string - name: - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - properties: - apiGroup: - type: string - kind: - type: string - name: - type: string - namespace: - type: string - required: - - kind - - name - type: object - resources: - properties: - claims: - items: - properties: - name: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - type: string - volumeMode: - type: string - volumeName: - type: string - type: object - required: - - spec - type: object - type: object - fc: - properties: - fsType: - type: string - lun: - format: int32 - type: integer - readOnly: - type: boolean - targetWWNs: - items: - type: string - type: array - wwids: - items: - type: string - type: array - type: object - flexVolume: - properties: - driver: - type: string - fsType: - type: string - options: - additionalProperties: - type: string - type: object - readOnly: - type: boolean - secretRef: - properties: - name: - type: string - type: object - x-kubernetes-map-type: atomic - required: - - driver - type: object - flocker: - properties: - datasetName: - type: string - datasetUUID: - type: string - type: object - gcePersistentDisk: - properties: - fsType: - type: string - partition: - format: int32 - type: integer - pdName: - type: string - readOnly: - type: boolean - required: - - pdName - type: object - gitRepo: - properties: - directory: - type: string - repository: - type: string - revision: - type: string - required: - - repository - type: object - glusterfs: - properties: - endpoints: - type: string - path: - type: string - readOnly: - type: boolean - required: - - endpoints - - path - type: object - hostPath: - properties: - path: - type: string - type: - type: string - required: - - path - type: object - iscsi: - properties: - chapAuthDiscovery: - type: boolean - chapAuthSession: - type: boolean - fsType: - type: string - initiatorName: - type: string - iqn: - type: string - iscsiInterface: - type: string - lun: - format: int32 - type: integer - portals: - items: - type: string - type: array - readOnly: - type: boolean - secretRef: - properties: - name: - type: string - type: object - x-kubernetes-map-type: atomic - targetPortal: - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - type: string - nfs: - properties: - path: - type: string - readOnly: - type: boolean - server: - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - properties: - claimName: - type: string - readOnly: - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - properties: - fsType: - type: string - pdID: - type: string - required: - - pdID - type: object - portworxVolume: - properties: - fsType: - type: string - readOnly: - type: boolean - volumeID: - type: string - required: - - volumeID - type: object - projected: - properties: - defaultMode: - format: int32 - type: integer - sources: - items: - properties: - configMap: - properties: - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - name: - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - downwardAPI: - properties: - items: - items: - properties: - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - format: int32 - type: integer - path: - type: string - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - type: object - secret: - properties: - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - name: - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - serviceAccountToken: - properties: - audience: - type: string - expirationSeconds: - format: int64 - type: integer - path: - type: string - required: - - path - type: object - type: object - type: array - type: object - quobyte: - properties: - group: - type: string - readOnly: - type: boolean - registry: - type: string - tenant: - type: string - user: - type: string - volume: - type: string - required: - - registry - - volume - type: object - rbd: - properties: - fsType: - type: string - image: - type: string - keyring: - type: string - monitors: - items: - type: string - type: array - pool: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - type: string - type: object - x-kubernetes-map-type: atomic - user: - type: string - required: - - image - - monitors - type: object - scaleIO: - properties: - fsType: - type: string - gateway: - type: string - protectionDomain: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - type: string - type: object - x-kubernetes-map-type: atomic - sslEnabled: - type: boolean - storageMode: - type: string - storagePool: - type: string - system: - type: string - volumeName: - type: string - required: - - gateway - - secretRef - - system - type: object - secret: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - optional: - type: boolean - secretName: - type: string - type: object - storageos: - properties: - fsType: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - type: string - type: object - x-kubernetes-map-type: atomic - volumeName: - type: string - volumeNamespace: - type: string - type: object - vsphereVolume: - properties: - fsType: - type: string - storagePolicyID: - type: string - storagePolicyName: - type: string - volumePath: - type: string - required: - - volumePath - type: object - required: - - name - type: object - type: array - required: - - containers - type: object - status: - type: object - type: object - served: true - storage: true - subresources: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.12.0 From 5e9ee8425fd6440dc8e299a8d72e6d0e2cbb6d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Tue, 19 Sep 2023 13:46:39 -0600 Subject: [PATCH 10/45] Adapt kserve/kserve#3039 for openshift-ci MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- test/scripts/openshift-ci/run-e2e-tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/test/scripts/openshift-ci/run-e2e-tests.sh b/test/scripts/openshift-ci/run-e2e-tests.sh index aca693c1e0f..df4393ef677 100755 --- a/test/scripts/openshift-ci/run-e2e-tests.sh +++ b/test/scripts/openshift-ci/run-e2e-tests.sh @@ -107,5 +107,6 @@ kustomize build $PROJECT_ROOT/config/overlays/test/runtimes | \ # echo "Run E2E tests: $1" pushd $PROJECT_ROOT >/dev/null + export GITHUB_SHA=$(git rev-parse HEAD) ./test/scripts/gh-actions/run-e2e-tests.sh "$1" popd From 17fb6b99d94079d27d9cd9a52ede74627bb24b7d Mon Sep 17 00:00:00 2001 From: heyselbi Date: Wed, 4 Oct 2023 14:18:37 -0400 Subject: [PATCH 11/45] automate addition of new isues into ODH board Signed-off-by: heyselbi --- .../workflows/auto-add-issues-to-project.yaml | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/auto-add-issues-to-project.yaml diff --git a/.github/workflows/auto-add-issues-to-project.yaml b/.github/workflows/auto-add-issues-to-project.yaml new file mode 100644 index 00000000000..e7dd1781f0a --- /dev/null +++ b/.github/workflows/auto-add-issues-to-project.yaml @@ -0,0 +1,28 @@ +name: Auto Add Issues to Tracking boards +on: + issues: + types: + - opened +jobs: + add-to-project: + name: Add issue to projects + runs-on: ubuntu-latest + steps: + - name: Generate github-app token + id: app-token + uses: getsentry/action-github-app-token@v2 + with: + app_id: ${{ secrets.DEVOPS_APP_ID }} + private_key: ${{ secrets.DEVOPS_APP_PRIVATE_KEY }} + - uses: actions/add-to-project@v0.5.0 + with: + project-url: https://github.com/orgs/opendatahub-io/projects/40 + github-token: ${{ steps.app-token.outputs.token }} + - uses: actions/add-to-project@v0.5.0 + with: + project-url: https://github.com/orgs/opendatahub-io/projects/45 + github-token: ${{ steps.app-token.outputs.token }} + - uses: actions/add-to-project@v0.5.0 + with: + project-url: https://github.com/orgs/opendatahub-io/projects/42 + github-token: ${{ steps.app-token.outputs.token }} \ No newline at end of file From 165f73cf7681ca0703684a2d7629eda38058bd2a Mon Sep 17 00:00:00 2001 From: Spolti Date: Thu, 19 Oct 2023 17:05:21 -0300 Subject: [PATCH 12/45] [RHODS-12555] - CVE-2023-44487 Signed-off-by: Spolti --- go.mod | 12 ++++++------ go.sum | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index b02f33c7e13..6911835d255 100644 --- a/go.mod +++ b/go.mod @@ -101,20 +101,20 @@ require ( go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.12.0 // indirect + golang.org/x/crypto v0.14.0 // indirect golang.org/x/mod v0.10.0 // indirect - golang.org/x/net v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/term v0.11.0 // indirect - golang.org/x/text v0.12.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.8.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.55.0 // indirect + google.golang.org/grpc v1.56.3 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index a0cac9ee6bc..c1056bd45c9 100644 --- a/go.sum +++ b/go.sum @@ -534,8 +534,8 @@ golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -616,8 +616,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -694,13 +694,13 @@ golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -712,8 +712,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -861,8 +861,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= From 595cc560ed5fc928ed6b3152085d7c2713b3d7df Mon Sep 17 00:00:00 2001 From: Spolti Date: Fri, 20 Oct 2023 15:27:26 -0300 Subject: [PATCH 13/45] add spoltin in the OWNERS file Signed-off-by: Spolti --- OWNERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OWNERS b/OWNERS index b0f1ad5a5ee..761dc94d8f7 100644 --- a/OWNERS +++ b/OWNERS @@ -4,6 +4,7 @@ approvers: - heyselbi - israel-hdez - Jooho + - spolti - VedantMahabaleshwarkar - Xaenalt - vaibhavjainwiz @@ -13,6 +14,7 @@ reviewers: - heyselbi - israel-hdez - Jooho + - spolti - VedantMahabaleshwarkar - Xaenalt - vaibhavjainwiz From caa980eabf6b1fed1ab4c2c3e952d45bb9fa9a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Fri, 13 Oct 2023 14:31:13 -0600 Subject: [PATCH 14/45] Preparation for odh-opeartor v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Open Data Hub operator v2 is going to be consuming Kustomize manifests from component repos, and `odh-manifests` repo is going to be archived. This is moving/copying artifacts from `odh-manifests` into an already existent odh overlay. With these changes, the overlay can be directly consumed by ODH-operator v2. Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- .../odh/inferenceservice-config-patch.yaml | 70 +++++++++++++++++++ config/overlays/odh/kustomization.yaml | 54 +++++++++++++- config/overlays/odh/params.env | 4 ++ config/overlays/odh/params.yaml | 5 ++ .../scripts/openshift-ci/deploy.serverless.sh | 6 ++ 5 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 config/overlays/odh/inferenceservice-config-patch.yaml create mode 100644 config/overlays/odh/params.env create mode 100644 config/overlays/odh/params.yaml diff --git a/config/overlays/odh/inferenceservice-config-patch.yaml b/config/overlays/odh/inferenceservice-config-patch.yaml new file mode 100644 index 00000000000..e40682fd0cc --- /dev/null +++ b/config/overlays/odh/inferenceservice-config-patch.yaml @@ -0,0 +1,70 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: inferenceservice-config + namespace: kserve +data: + explainers: "{}" + storageInitializer: |- + { + "image" : "$(kserve-storage-initializer)", + "memoryRequest": "100Mi", + "memoryLimit": "1Gi", + "cpuRequest": "100m", + "cpuLimit": "1", + "enableDirectPvcVolumeMount": false + } + ingress: |- + { + "ingressGateway" : "knative-serving/knative-ingress-gateway", + "ingressService" : "istio-ingressgateway.istio-system.svc.cluster.local", + "localGateway" : "knative-serving/knative-local-gateway", + "localGatewayService" : "knative-local-gateway.istio-system.svc.cluster.local", + "ingressDomain" : "example.com", + "ingressClassName" : "istio", + "domainTemplate": "{{ .Name }}-{{ .Namespace }}.{{ .IngressDomain }}", + "urlScheme": "https", + "disableIstioVirtualHost": true + } + logger: |- + { + "image" : "$(kserve-agent)", + "memoryRequest": "100Mi", + "memoryLimit": "1Gi", + "cpuRequest": "100m", + "cpuLimit": "1", + "defaultUrl": "http://default-broker" + } + batcher: |- + { + "image" : "$(kserve-agent)", + "memoryRequest": "1Gi", + "memoryLimit": "1Gi", + "cpuRequest": "1", + "cpuLimit": "1" + } + agent: |- + { + "image" : "$(kserve-agent)", + "memoryRequest": "100Mi", + "memoryLimit": "1Gi", + "cpuRequest": "100m", + "cpuLimit": "1" + } + router: |- + { + "image" : "$(kserve-router)", + "memoryRequest": "100Mi", + "memoryLimit": "1Gi", + "cpuRequest": "100m", + "cpuLimit": "1" + } + deploy: |- + { + "defaultDeploymentMode": "Serverless" + } + metricsAggregator: |- + { + "enableMetricAggregation": "false", + "enablePrometheusScraping" : "false" + } diff --git a/config/overlays/odh/kustomization.yaml b/config/overlays/odh/kustomization.yaml index 87ae27f946f..b6ec0336989 100644 --- a/config/overlays/odh/kustomization.yaml +++ b/config/overlays/odh/kustomization.yaml @@ -5,5 +5,55 @@ resources: - ../../default - user-cluster-roles.yaml -patchesStrategicMerge: -- remove-namespace.yaml +namespace: opendatahub + +patches: +- path: remove-namespace.yaml +- path: inferenceservice-config-patch.yaml + +replacements: +- source: + kind: ConfigMap + name: kserve-parameters + fieldpath: data.kserve-controller + targets: + - select: + kind: Deployment + name: kserve-controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].image + +configMapGenerator: +- envs: + - params.env + name: kserve-parameters + +generatorOptions: + disableNameSuffixHash: true + +vars: +- fieldref: + fieldpath: data.kserve-storage-initializer + name: kserve-storage-initializer + objref: + apiVersion: v1 + kind: ConfigMap + name: kserve-parameters +- fieldref: + fieldpath: data.kserve-agent + name: kserve-agent + objref: + apiVersion: v1 + kind: ConfigMap + name: kserve-parameters +- fieldref: + fieldpath: data.kserve-router + name: kserve-router + objref: + apiVersion: v1 + kind: ConfigMap + name: kserve-parameters + +configurations: + - params.yaml + diff --git a/config/overlays/odh/params.env b/config/overlays/odh/params.env new file mode 100644 index 00000000000..f4233dc6a6e --- /dev/null +++ b/config/overlays/odh/params.env @@ -0,0 +1,4 @@ +kserve-controller=quay.io/opendatahub/kserve-controller:latest +kserve-agent=quay.io/opendatahub/kserve-agent:latest +kserve-router=quay.io/opendatahub/kserve-router:latest +kserve-storage-initializer=quay.io/opendatahub/kserve-storage-initializer:latest diff --git a/config/overlays/odh/params.yaml b/config/overlays/odh/params.yaml new file mode 100644 index 00000000000..dc7f5878ccf --- /dev/null +++ b/config/overlays/odh/params.yaml @@ -0,0 +1,5 @@ +varReference: + - path: spec/template/spec/containers/image + kind: Deployment + - path: data + kind: ConfigMap diff --git a/test/scripts/openshift-ci/deploy.serverless.sh b/test/scripts/openshift-ci/deploy.serverless.sh index 9c66d85eeb6..93e4d1c60a1 100755 --- a/test/scripts/openshift-ci/deploy.serverless.sh +++ b/test/scripts/openshift-ci/deploy.serverless.sh @@ -98,6 +98,12 @@ spec: enabled: true EOF +# Apparently, as part of KNative installation, deployments can be restarted because +# of configuration changes, leading to waitpodready to fail sometimes. +# Let's sleep 2minutes to let the KNative operator to stabilize the installation before +# checking for the readiness of KNative stack. +sleep 120 + waitpodready "knative-serving" "app=controller" waitpodready "knative-serving" "app=net-istio-controller" waitpodready "knative-serving" "app=net-istio-webhook" From ba610a319f36253d5f8a0b9c67c03e0f955afe5c Mon Sep 17 00:00:00 2001 From: Spolti Date: Mon, 23 Oct 2023 14:22:43 -0300 Subject: [PATCH 15/45] [RHODS-12555] - CVE-2023-44487 - qpext Signed-off-by: Spolti --- qpext/go.mod | 10 +++++----- qpext/go.sum | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/qpext/go.mod b/qpext/go.mod index 51101b56445..bf613d856fa 100644 --- a/qpext/go.mod +++ b/qpext/go.mod @@ -50,18 +50,18 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/automaxprocs v1.5.2 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/net v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/term v0.11.0 // indirect - golang.org/x/text v0.12.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/api v0.122.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.55.0 // indirect + google.golang.org/grpc v1.56.3 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/qpext/go.sum b/qpext/go.sum index 129aed29f02..34f71b1e6b9 100644 --- a/qpext/go.sum +++ b/qpext/go.sum @@ -49,6 +49,7 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5 github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -84,6 +85,7 @@ github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -107,6 +109,7 @@ github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -145,6 +148,7 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= @@ -175,9 +179,11 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -185,6 +191,7 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 h1:gDLXvp5S9izjldquuoAhDzccbskOL6tDC5jMSyx3zxE= github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2/go.mod h1:7pdNwVWBBHGiCxa9lAszqCJMbfTISJ7oMftp8+UGV08= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -199,6 +206,9 @@ github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -223,6 +233,7 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -238,8 +249,10 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -290,6 +303,7 @@ github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9 github.com/prometheus/statsd_exporter v0.23.1 h1:TiNAE1XevlZZrpSbmf51l/Ryl2Eek9rYh//KlvcNvKw= github.com/prometheus/statsd_exporter v0.23.1/go.mod h1:FFmnBRWf+HxX+PR+2fnc0ciBIONVAPJ6k4lqIbdqVxo= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -409,6 +423,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -475,10 +491,14 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -488,6 +508,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -618,6 +640,8 @@ google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -639,6 +663,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= From b7eb6d02ae914830413ec5a0a3a823eac4b606f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Mon, 23 Oct 2023 18:49:25 -0600 Subject: [PATCH 16/45] Enable Istio Virtual Host MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Partial revert of https://github.com/opendatahub-io/odh-manifests/pull/916, because https://github.com/opendatahub-io/odh-model-controller/pull/84 has been completed. Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- config/overlays/odh/inferenceservice-config-patch.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/overlays/odh/inferenceservice-config-patch.yaml b/config/overlays/odh/inferenceservice-config-patch.yaml index e40682fd0cc..0f6d4f8a328 100644 --- a/config/overlays/odh/inferenceservice-config-patch.yaml +++ b/config/overlays/odh/inferenceservice-config-patch.yaml @@ -24,7 +24,7 @@ data: "ingressClassName" : "istio", "domainTemplate": "{{ .Name }}-{{ .Namespace }}.{{ .IngressDomain }}", "urlScheme": "https", - "disableIstioVirtualHost": true + "disableIstioVirtualHost": false } logger: |- { From de9117214eedc86811d49e21d9f8726308023566 Mon Sep 17 00:00:00 2001 From: Vedant Mahabaleshwarkar Date: Wed, 8 Nov 2023 13:56:18 -0500 Subject: [PATCH 17/45] remove webhook from inferenceservice crd Signed-off-by: Vedant Mahabaleshwarkar --- config/default/kustomization.yaml | 34 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index 2a0cb426618..9af24326fda 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -31,11 +31,11 @@ replacements: name: kserve-webhook-server-service fieldPath: metadata.name targets: - - select: - kind: CustomResourceDefinition - name: inferenceservices.serving.kserve.io - fieldPaths: - - spec.conversion.webhook.clientConfig.service.name + # - select: + # kind: CustomResourceDefinition + # name: inferenceservices.serving.kserve.io + # fieldPaths: + # - spec.conversion.webhook.clientConfig.service.name - select: kind: MutatingWebhookConfiguration name: inferenceservice.serving.kserve.io @@ -84,11 +84,11 @@ replacements: version: v1 fieldPath: metadata.namespace targets: - - select: - kind: CustomResourceDefinition - name: inferenceservices.serving.kserve.io - fieldPaths: - - spec.conversion.webhook.clientConfig.service.namespace + # - select: + # kind: CustomResourceDefinition + # name: inferenceservices.serving.kserve.io + # fieldPaths: + # - spec.conversion.webhook.clientConfig.service.namespace - select: kind: MutatingWebhookConfiguration name: inferenceservice.serving.kserve.io @@ -206,16 +206,16 @@ patches: - path: servingruntime_validationwebhook_cainjection_patch.yaml - path: svc_webhook_cainjection_patch.yaml - path: manager_resources_patch.yaml -- path: inferenceservice_conversion_webhook.yaml +#- path: inferenceservice_conversion_webhook.yaml - path: cainjection_conversion_webhook.yaml # Since OpenShift serving-certificates are being used, # remove CA bundle placeholders -- patch: |- - - op: remove - path: "/spec/conversion/webhook/clientConfig/caBundle" - target: - kind: CustomResourceDefinition - name: inferenceservices.serving.kserve.io +# - patch: |- +# - op: remove +# path: "/spec/conversion/webhook/clientConfig/caBundle" +# target: +# kind: CustomResourceDefinition +# name: inferenceservices.serving.kserve.io - patch: |- - op: remove path: "/webhooks/0/clientConfig/caBundle" From f6c61075680a7030e768a451d76896f4c5500fa1 Mon Sep 17 00:00:00 2001 From: jooho Date: Wed, 15 Nov 2023 15:28:40 -0500 Subject: [PATCH 18/45] increase kserve controller limit resources(cpu/memory) Signed-off-by: jooho --- config/overlays/odh/kustomization.yaml | 2 +- .../overlays/odh/set-resources-manager-patch.yaml | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 config/overlays/odh/set-resources-manager-patch.yaml diff --git a/config/overlays/odh/kustomization.yaml b/config/overlays/odh/kustomization.yaml index b6ec0336989..863bc66a360 100644 --- a/config/overlays/odh/kustomization.yaml +++ b/config/overlays/odh/kustomization.yaml @@ -10,6 +10,7 @@ namespace: opendatahub patches: - path: remove-namespace.yaml - path: inferenceservice-config-patch.yaml +- path: set-resources-manager-patch.yaml replacements: - source: @@ -56,4 +57,3 @@ vars: configurations: - params.yaml - diff --git a/config/overlays/odh/set-resources-manager-patch.yaml b/config/overlays/odh/set-resources-manager-patch.yaml new file mode 100644 index 00000000000..164e0cb5ad1 --- /dev/null +++ b/config/overlays/odh/set-resources-manager-patch.yaml @@ -0,0 +1,14 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kserve-controller-manager + namespace: kserve +spec: + template: + spec: + containers: + - name: manager + resources: + limits: + cpu: 500m + memory: 500Mi From 694bf54067391b778768ac1be5f06c43b6ad014a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Fri, 24 Nov 2023 11:39:50 -0600 Subject: [PATCH 19/45] Fix OpenShift-CI: renaming of overlays/test/runtimes The config/overlays/test/runtimes is renamed to overlays/test/clusterresources. --- test/scripts/openshift-ci/run-e2e-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/scripts/openshift-ci/run-e2e-tests.sh b/test/scripts/openshift-ci/run-e2e-tests.sh index df4393ef677..12854f030bd 100755 --- a/test/scripts/openshift-ci/run-e2e-tests.sh +++ b/test/scripts/openshift-ci/run-e2e-tests.sh @@ -99,7 +99,7 @@ EOF oc apply -f $PROJECT_ROOT/config/overlays/test/minio/minio-user-secret.yaml -n kserve-ci-e2e-test -kustomize build $PROJECT_ROOT/config/overlays/test/runtimes | \ +kustomize build $PROJECT_ROOT/config/overlays/test/clusterresources | \ sed 's/ClusterServingRuntime/ServingRuntime/' | \ sed "s|kserve/sklearnserver:latest|${SKLEARN_IMAGE}|" | \ oc apply -n kserve-ci-e2e-test -f - From 204e899c25a1e80f82efa318d544acdeb40a6706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Wed, 13 Dec 2023 10:56:51 -0600 Subject: [PATCH 20/45] Use ThirdParty tokens for CI, for compatibility with ROSA-Hosted clusters Also, remove Mesh-related components that are not needed. --- test/scripts/openshift-ci/deploy.ossm.sh | 31 +++++++++---------- .../scripts/openshift-ci/deploy.serverless.sh | 2 +- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/test/scripts/openshift-ci/deploy.ossm.sh b/test/scripts/openshift-ci/deploy.ossm.sh index 2e3876a39ca..c30bd673017 100755 --- a/test/scripts/openshift-ci/deploy.ossm.sh +++ b/test/scripts/openshift-ci/deploy.ossm.sh @@ -111,25 +111,24 @@ metadata: name: basic namespace: istio-system spec: - version: v2.3 - tracing: - type: Jaeger - sampling: 10000 -# Uncomment if on ROSA -# security: -# identity: -# type: ThirdParty addons: - jaeger: - name: jaeger - install: - storage: - type: Memory + grafana: + enabled: false kiali: - enabled: true + enabled: false name: kiali - grafana: - enabled: true + prometheus: + enabled: false + jaeger: + name: jaeger + gateways: + openshiftRoute: + enabled: false + security: + identity: + type: ThirdParty + tracing: + type: None EOF # Waiting for OSSM minimum start diff --git a/test/scripts/openshift-ci/deploy.serverless.sh b/test/scripts/openshift-ci/deploy.serverless.sh index 93e4d1c60a1..a41b51e0b84 100755 --- a/test/scripts/openshift-ci/deploy.serverless.sh +++ b/test/scripts/openshift-ci/deploy.serverless.sh @@ -29,7 +29,7 @@ waitpodready() { local podlabel=${1?pod label is required}; shift waitforpodlabeled "$ns" "$podlabel" - sleep 10 + sleep 2 oc get pod -n $ns -l $podlabel echo "Waiting for pod -l $podlabel to become ready" From b489d2c2428a6da4026e398106b6c6f3836d0dd9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 23:05:45 +0000 Subject: [PATCH 21/45] Bump golang.org/x/crypto in /docs/samples/graph/bgtest/bgtest Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.1.0 to 0.17.0. - [Commits](https://github.com/golang/crypto/compare/v0.1.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/samples/graph/bgtest/bgtest/go.mod | 4 ++-- docs/samples/graph/bgtest/bgtest/go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/samples/graph/bgtest/bgtest/go.mod b/docs/samples/graph/bgtest/bgtest/go.mod index 5af1a021c27..d13f1dcb09a 100644 --- a/docs/samples/graph/bgtest/bgtest/go.mod +++ b/docs/samples/graph/bgtest/bgtest/go.mod @@ -16,7 +16,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect github.com/ugorji/go/codec v1.1.7 // indirect - golang.org/x/crypto v0.1.0 // indirect - golang.org/x/sys v0.1.0 // indirect + golang.org/x/crypto v0.17.0 // indirect + golang.org/x/sys v0.15.0 // indirect gopkg.in/yaml.v2 v2.2.8 // indirect ) diff --git a/docs/samples/graph/bgtest/bgtest/go.sum b/docs/samples/graph/bgtest/bgtest/go.sum index 4e1d169179d..8576541ef59 100644 --- a/docs/samples/graph/bgtest/bgtest/go.sum +++ b/docs/samples/graph/bgtest/bgtest/go.sum @@ -37,14 +37,14 @@ github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From f5fdcf48110c288e89aa94795a6bd7dfe98cd755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Wed, 13 Dec 2023 17:01:28 -0600 Subject: [PATCH 22/45] Revert and re-adapt test/e2e/common/utils.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts changes done in commit ecff079 to test/e2e/common/utils.py. It is possible to revert since opendatahub-io/odh-model-controller#59 is solved. After the revert, another adaptation was needed. CI in upstream assumes that the URL in the InferenceService cannot be resolved, so it uses the IP of the istio-ingressgateway together with the HTTP Host header to workaround this limitation. However, in ODH testing environment the URL of InferenceServices can be resolved. The adaptation adds a flag to use the URL of the isvc, rather than using the IP of the istio-ingressgateway. This adaptation can be contributed to upstream, because the community can benefit from it. The CI setup is updated, so that the revert works correctly: * odh-model-controller is now being installed * TLS is removed from the istio-ingressgateway Additionally, the following other changes were done to the CI setup: * Turn off Mesh-related components that are not needed for CI * Prefer usage of the ServiceMeshMember CRD to enroll namespaces to the Mesh Fixes opendatahub-io/kserve#50 Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- test/e2e/common/utils.py | 30 +++++++++-------- test/e2e/predictor/test_tensorflow.py | 2 +- test/scripts/openshift-ci/deploy.ossm.sh | 22 ------------- .../scripts/openshift-ci/deploy.serverless.sh | 32 +++++++------------ test/scripts/openshift-ci/kustomization.yaml | 7 ++++ test/scripts/openshift-ci/run-e2e-tests.sh | 16 ++++++++-- 6 files changed, 50 insertions(+), 59 deletions(-) create mode 100644 test/scripts/openshift-ci/kustomization.yaml diff --git a/test/e2e/common/utils.py b/test/e2e/common/utils.py index 4a2bbca8a0b..442299f04b0 100644 --- a/test/e2e/common/utils.py +++ b/test/e2e/common/utils.py @@ -80,23 +80,20 @@ def predict_str(service_name, input_json, protocol_version="v1", ) # temporary sleep until this is fixed https://github.com/kserve/kserve/issues/604 time.sleep(10) - # cluster_ip = get_cluster_ip() - host = urlparse(isvc["status"]["components"]["predictor"]["url"]).netloc - path = urlparse(isvc["status"]["components"]["predictor"]["url"]).path - cluster_ip = host + cluster_ip, host, path = get_isvc_endpoint(isvc) headers = {"Host": host, "Content-Type": "application/json"} if model_name is None: model_name = service_name - url = f"https://{cluster_ip}{path}/v1/models/{model_name}:predict" + url = f"http://{cluster_ip}{path}/v1/models/{model_name}:predict" if protocol_version == "v2": - url = f"https://{cluster_ip}{path}/v2/models/{model_name}/infer" + url = f"http://{cluster_ip}{path}/v2/models/{model_name}/infer" logging.info("Sending Header = %s", headers) logging.info("Sending url = %s", url) logging.info("Sending request data: %s", input_json) - response = requests.post(url, input_json, headers=headers, verify=False) + response = requests.post(url, input_json, headers=headers) logging.info("Got response code %s, content %s", response.status_code, response.content) if response.status_code == 200: preds = json.loads(response.content.decode("utf-8")) @@ -118,8 +115,7 @@ def predict_ig(ig_name, input_json, protocol_version="v1", version=version, ) - cluster_ip = get_cluster_ip() - host = urlparse(ig["status"]["components"]["predictor"]["url"]).netloc + cluster_ip, host, _ = get_isvc_endpoint(ig) headers = {"Host": host} url = f"http://{cluster_ip}" @@ -154,8 +150,7 @@ def explain_response(service_name, input_json): ) # temporary sleep until this is fixed https://github.com/kserve/kserve/issues/604 time.sleep(10) - cluster_ip = get_cluster_ip() - host = urlparse(isvc["status"]["components"]["predictor"]["url"]).netloc + cluster_ip, host, _ = get_isvc_endpoint(isvc) url = "http://{}/v1/models/{}:explain".format(cluster_ip, service_name) headers = {"Host": host} with open(input_json) as json_file: @@ -210,7 +205,6 @@ def get_cluster_ip(name="istio-ingressgateway", namespace="istio-system"): def predict_grpc(service_name, payload, parameters=None, version=constants.KSERVE_V1BETA1_VERSION, model_name=None): - cluster_ip = get_cluster_ip() kfs_client = KServeClient( config_file=os.environ.get("KUBECONFIG", "~/.kube/config")) isvc = kfs_client.get( @@ -218,7 +212,7 @@ def predict_grpc(service_name, payload, parameters=None, version=constants.KSERV namespace=KSERVE_TEST_NAMESPACE, version=version, ) - host = urlparse(isvc["status"]["components"]["predictor"]["url"]).netloc + cluster_ip, host, _ = get_isvc_endpoint(isvc) if ":" not in cluster_ip: cluster_ip = cluster_ip + ":80" @@ -244,3 +238,13 @@ def predict_modelmesh(service_name, input_json, pod_name, model_name=None): url = f"http://localhost:8008/v2/models/{model_name}/infer" response = requests.post(url, json.dumps(data)) return json.loads(response.content.decode("utf-8")) + + +def get_isvc_endpoint(isvc): + host = urlparse(isvc["status"]["url"]).netloc + path = urlparse(isvc["status"]["url"]).path + if os.environ.get("CI_USE_ISVC_HOST") == "1": + cluster_ip = host + else: + cluster_ip = get_cluster_ip() + return cluster_ip, host, path diff --git a/test/e2e/predictor/test_tensorflow.py b/test/e2e/predictor/test_tensorflow.py index e1c060dbdbf..6654ef053e4 100644 --- a/test/e2e/predictor/test_tensorflow.py +++ b/test/e2e/predictor/test_tensorflow.py @@ -38,7 +38,7 @@ def test_tensorflow_kserve(): storage_uri='gs://kfserving-examples/models/tensorflow/flowers', resources=V1ResourceRequirements( requests={'cpu': '10m', 'memory': '128Mi'}, - limits={'cpu': '100m', 'memory': '256Mi'} + limits={'cpu': '100m', 'memory': '512Mi'} ) ) ) diff --git a/test/scripts/openshift-ci/deploy.ossm.sh b/test/scripts/openshift-ci/deploy.ossm.sh index c30bd673017..d91c07e9d11 100755 --- a/test/scripts/openshift-ci/deploy.ossm.sh +++ b/test/scripts/openshift-ci/deploy.ossm.sh @@ -134,26 +134,4 @@ EOF # Waiting for OSSM minimum start waitpodready "istio-system" "app=istiod" -# Create SMMR to enroll namespaces via a label. Also, set mTLS policy to strict by default. -cat </dev/null export GITHUB_SHA=$(git rev-parse HEAD) + export CI_USE_ISVC_HOST="1" ./test/scripts/gh-actions/run-e2e-tests.sh "$1" popd From 12efb9196c4b1728e28b7aeafed1ff784f39e14e Mon Sep 17 00:00:00 2001 From: Spolti Date: Thu, 4 Jan 2024 11:39:23 -0300 Subject: [PATCH 23/45] fix securityContext on storage_initializer tests Signed-off-by: Spolti --- .../admission/pod/storage_initializer_injector_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/webhook/admission/pod/storage_initializer_injector_test.go b/pkg/webhook/admission/pod/storage_initializer_injector_test.go index cd7f18e6c20..428426a3578 100644 --- a/pkg/webhook/admission/pod/storage_initializer_injector_test.go +++ b/pkg/webhook/admission/pod/storage_initializer_injector_test.go @@ -1446,6 +1446,7 @@ func TestCaBundleConfigMapVolumeMountInStorageInitializer(t *testing.T) { }, Resources: resourceRequirement, TerminationMessagePolicy: "FallbackToLogsOnError", + SecurityContext: &v1.SecurityContext{RunAsUser: expectedInitContainerUid}, VolumeMounts: []v1.VolumeMount{ { Name: "kserve-provision-location", @@ -1549,6 +1550,7 @@ func TestCaBundleConfigMapVolumeMountInStorageInitializer(t *testing.T) { }, Resources: resourceRequirement, TerminationMessagePolicy: "FallbackToLogsOnError", + SecurityContext: &v1.SecurityContext{RunAsUser: expectedInitContainerUid}, VolumeMounts: []v1.VolumeMount{ { Name: "kserve-provision-location", @@ -1670,6 +1672,7 @@ func TestCaBundleConfigMapVolumeMountInStorageInitializer(t *testing.T) { }, Resources: resourceRequirement, TerminationMessagePolicy: "FallbackToLogsOnError", + SecurityContext: &v1.SecurityContext{RunAsUser: expectedInitContainerUid}, VolumeMounts: []v1.VolumeMount{ { Name: "kserve-provision-location", @@ -1792,6 +1795,7 @@ func TestCaBundleConfigMapVolumeMountInStorageInitializer(t *testing.T) { }, Resources: resourceRequirement, TerminationMessagePolicy: "FallbackToLogsOnError", + SecurityContext: &v1.SecurityContext{RunAsUser: expectedInitContainerUid}, VolumeMounts: []v1.VolumeMount{ { Name: "kserve-provision-location", @@ -1905,6 +1909,7 @@ func TestCaBundleConfigMapVolumeMountInStorageInitializer(t *testing.T) { }, Resources: resourceRequirement, TerminationMessagePolicy: "FallbackToLogsOnError", + SecurityContext: &v1.SecurityContext{RunAsUser: expectedInitContainerUid}, VolumeMounts: []v1.VolumeMount{ { Name: "kserve-provision-location", @@ -2013,6 +2018,7 @@ func TestCaBundleConfigMapVolumeMountInStorageInitializer(t *testing.T) { }, Resources: resourceRequirement, TerminationMessagePolicy: "FallbackToLogsOnError", + SecurityContext: &v1.SecurityContext{RunAsUser: expectedInitContainerUid}, VolumeMounts: []v1.VolumeMount{ { Name: "kserve-provision-location", From bff84d394b0cd117feb6ac507a3edd06f1726c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Fri, 26 Jan 2024 13:50:28 -0600 Subject: [PATCH 24/45] Revert "automate addition of new isues into ODH board" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 17fb6b99d94079d27d9cd9a52ede74627bb24b7d. Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- .../workflows/auto-add-issues-to-project.yaml | 28 ------------------- 1 file changed, 28 deletions(-) delete mode 100644 .github/workflows/auto-add-issues-to-project.yaml diff --git a/.github/workflows/auto-add-issues-to-project.yaml b/.github/workflows/auto-add-issues-to-project.yaml deleted file mode 100644 index e7dd1781f0a..00000000000 --- a/.github/workflows/auto-add-issues-to-project.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: Auto Add Issues to Tracking boards -on: - issues: - types: - - opened -jobs: - add-to-project: - name: Add issue to projects - runs-on: ubuntu-latest - steps: - - name: Generate github-app token - id: app-token - uses: getsentry/action-github-app-token@v2 - with: - app_id: ${{ secrets.DEVOPS_APP_ID }} - private_key: ${{ secrets.DEVOPS_APP_PRIVATE_KEY }} - - uses: actions/add-to-project@v0.5.0 - with: - project-url: https://github.com/orgs/opendatahub-io/projects/40 - github-token: ${{ steps.app-token.outputs.token }} - - uses: actions/add-to-project@v0.5.0 - with: - project-url: https://github.com/orgs/opendatahub-io/projects/45 - github-token: ${{ steps.app-token.outputs.token }} - - uses: actions/add-to-project@v0.5.0 - with: - project-url: https://github.com/orgs/opendatahub-io/projects/42 - github-token: ${{ steps.app-token.outputs.token }} \ No newline at end of file From 51517140cc79cf954734021a981827cdf0e7d819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Fri, 26 Jan 2024 14:44:44 -0600 Subject: [PATCH 25/45] Revert "add storage-initializer uid handling for OpenShift with istio-cni" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 4e7f0df84e94366132a71e62c4cc584d4a360b4d Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- .../pod/metrics_aggregate_injector.go | 1 - pkg/webhook/admission/pod/mutator.go | 15 +- .../pod/storage_initializer_injector.go | 32 +-- .../pod/storage_initializer_injector_test.go | 211 +----------------- 4 files changed, 15 insertions(+), 244 deletions(-) diff --git a/pkg/webhook/admission/pod/metrics_aggregate_injector.go b/pkg/webhook/admission/pod/metrics_aggregate_injector.go index 223a930f042..3a5d6fa3569 100644 --- a/pkg/webhook/admission/pod/metrics_aggregate_injector.go +++ b/pkg/webhook/admission/pod/metrics_aggregate_injector.go @@ -19,7 +19,6 @@ package pod import ( "encoding/json" "fmt" - "github.com/kserve/kserve/pkg/constants" v1 "k8s.io/api/core/v1" ) diff --git a/pkg/webhook/admission/pod/mutator.go b/pkg/webhook/admission/pod/mutator.go index 38cebc86fa1..4d47ca35a98 100644 --- a/pkg/webhook/admission/pod/mutator.go +++ b/pkg/webhook/admission/pod/mutator.go @@ -62,14 +62,7 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis // For some reason pod namespace is always empty when coming to pod mutator, need to set from admission request pod.Namespace = req.AdmissionRequest.Namespace - targetNs := &v1.Namespace{} - err = mutator.Client.Get(context.TODO(), k8types.NamespacedName{Name: pod.Namespace, Namespace: pod.Namespace}, targetNs) - if err != nil { - log.Error(err, "Failed to get the target namespace", "name", pod.Namespace) - return admission.Errored(http.StatusInternalServerError, err) - } - - if err := mutator.mutate(pod, configMap, targetNs); err != nil { + if err := mutator.mutate(pod, configMap); err != nil { log.Error(err, "Failed to mutate pod", "name", pod.Labels[constants.InferenceServicePodLabelKey]) return admission.Errored(http.StatusInternalServerError, err) } @@ -83,7 +76,7 @@ func (mutator *Mutator) Handle(ctx context.Context, req admission.Request) admis return admission.PatchResponseFromRaw(req.AdmissionRequest.Object.Raw, patch) } -func (mutator *Mutator) mutate(pod *v1.Pod, configMap *v1.ConfigMap, targetNs *v1.Namespace) error { +func (mutator *Mutator) mutate(pod *v1.Pod, configMap *v1.ConfigMap) error { credentialBuilder := credentials.NewCredentialBuilder(mutator.Client, configMap) storageInitializerConfig, err := getStorageInitializerConfigs(configMap) @@ -126,9 +119,7 @@ func (mutator *Mutator) mutate(pod *v1.Pod, configMap *v1.ConfigMap, targetNs *v mutators := []func(pod *v1.Pod) error{ InjectGKEAcceleratorSelector, - func(pod *v1.Pod) error { - return storageInitializer.InjectStorageInitializer(pod, targetNs) - }, + storageInitializer.InjectStorageInitializer, agentInjector.InjectAgent, metricsAggregator.InjectMetricsAggregator, } diff --git a/pkg/webhook/admission/pod/storage_initializer_injector.go b/pkg/webhook/admission/pod/storage_initializer_injector.go index 14debe39154..f154b64e3b1 100644 --- a/pkg/webhook/admission/pod/storage_initializer_injector.go +++ b/pkg/webhook/admission/pod/storage_initializer_injector.go @@ -46,7 +46,6 @@ const ( OciURIPrefix = "oci://" PvcSourceMountName = "kserve-pvc-source" PvcSourceMountPath = "/mnt/pvc" - OpenShiftUidRangeAnnotationKey = "openshift.io/sa.scc.uid-range" CaBundleVolumeName = "cabundle-cert" ModelcarContainerName = "modelcar" ModelInitModeEnv = "MODEL_INIT_MODE" @@ -188,7 +187,7 @@ func (mi *StorageInitializerInjector) InjectModelcar(pod *v1.Pod) error { // for the serving container in a unified way across storage tech by injecting // a provisioning INIT container. This is a work around because KNative does not // support INIT containers: https://github.com/knative/serving/issues/4307 -func (mi *StorageInitializerInjector) InjectStorageInitializer(pod *v1.Pod, targetNs *v1.Namespace) error { +func (mi *StorageInitializerInjector) InjectStorageInitializer(pod *v1.Pod) error { // Only inject if the required annotations are set srcURI, ok := pod.ObjectMeta.Annotations[constants.StorageInitializerSourceUriInternalAnnotationKey] if !ok { @@ -482,37 +481,12 @@ func (mi *StorageInitializerInjector) InjectStorageInitializer(pod *v1.Pod, targ } } - /* - OpenShift uses istio-cni which causes an issue with init-containers when calling external services - like S3 or similar. Setting the `uid` for the `storage-initializer` to the same `uid` as the - `uid` of the `istio-proxy` resolves the issue. - - With upstream istio the user has the option to set the uid to 1337 described in https://istio.io/latest/docs/setup/additional-setup/cni/#compatibility-with-application-init-containers - using the annotation IstioSidecarUIDAnnotationKey. - - In OpenShift the `istio-proxy` always gets assigned the first `uid` from the namespaces - `uid` range + 1 (The range is defined in an annotation on the namespace). - */ + // Allow to override the uid for the case where ISTIO CNI with DNS proxy is enabled + // See for more: https://istio.io/latest/docs/setup/additional-setup/cni/#compatibility-with-application-init-containers. if value, ok := pod.GetAnnotations()[constants.IstioSidecarUIDAnnotationKey]; ok { if uid, err := strconv.ParseInt(value, 10, 64); err == nil { - if initContainer.SecurityContext == nil { - initContainer.SecurityContext = &v1.SecurityContext{} - } initContainer.SecurityContext.RunAsUser = ptr.Int64(uid) } - } else { - uidStr := targetNs.Annotations[OpenShiftUidRangeAnnotationKey] - if uidStr != "" { - uidStrParts := strings.Split(uidStr, "/") - if uid, err := strconv.ParseInt(uidStrParts[0], 10, 64); err == nil { - // Set the uid to the first uid in the namespaces range + 1 - uid++ - if initContainer.SecurityContext == nil { - initContainer.SecurityContext = &v1.SecurityContext{} - } - initContainer.SecurityContext.RunAsUser = ptr.Int64(uid) - } - } } // Add init container to the spec diff --git a/pkg/webhook/admission/pod/storage_initializer_injector_test.go b/pkg/webhook/admission/pod/storage_initializer_injector_test.go index 428426a3578..5d031a4647a 100644 --- a/pkg/webhook/admission/pod/storage_initializer_injector_test.go +++ b/pkg/webhook/admission/pod/storage_initializer_injector_test.go @@ -70,17 +70,6 @@ var ( v1.ResourceMemory: resource.MustParse(StorageInitializerDefaultMemoryRequest), }, } - - targetNS = &v1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "my-ns", - Annotations: map[string]string{ - OpenShiftUidRangeAnnotationKey: "1000740000/10000", - }, - }, - } - - expectedInitContainerUid = ptr.Int64(1000740001) ) func TestStorageInitializerInjector(t *testing.T) { @@ -201,9 +190,6 @@ func TestStorageInitializerInjector(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, - SecurityContext: &v1.SecurityContext{ - RunAsUser: expectedInitContainerUid, - }, }, }, Volumes: []v1.Volume{ @@ -274,9 +260,6 @@ func TestStorageInitializerInjector(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, - SecurityContext: &v1.SecurityContext{ - RunAsUser: expectedInitContainerUid, - }, }, }, Volumes: []v1.Volume{ @@ -357,9 +340,6 @@ func TestStorageInitializerInjector(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, - SecurityContext: &v1.SecurityContext{ - RunAsUser: expectedInitContainerUid, - }, }, }, Volumes: []v1.Volume{ @@ -383,7 +363,7 @@ func TestStorageInitializerInjector(t *testing.T) { config: storageInitializerConfig, client: c, } - if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { + if err := injector.InjectStorageInitializer(scenario.original); err != nil { t.Errorf("Test %q unexpected result: %s", name, err) } if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" { @@ -424,7 +404,7 @@ func TestStorageInitializerFailureCases(t *testing.T) { config: storageInitializerConfig, client: c, } - if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { + if err := injector.InjectStorageInitializer(scenario.original); err != nil { if !strings.HasPrefix(err.Error(), scenario.expectedErrorPrefix) { t.Errorf("Test %q unexpected failure [%s], expected: %s", name, err.Error(), scenario.expectedErrorPrefix) } @@ -434,146 +414,6 @@ func TestStorageInitializerFailureCases(t *testing.T) { } } -func TestStorageInitializerInjectorUIDHandling(t *testing.T) { - scenarios := map[string]struct { - namespace *v1.Namespace - original *v1.Pod - expected *v1.Pod - }{ - "NoAnnotationNoUid": { - namespace: &v1.Namespace{}, - original: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: map[string]string{ - constants.StorageInitializerSourceUriInternalAnnotationKey: "gs://foo", - }, - }, - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Name: constants.InferenceServiceContainerName, - }, - }, - }, - }, - expected: &v1.Pod{ - Spec: v1.PodSpec{ - InitContainers: []v1.Container{ - { - Name: "storage-initializer", - Image: StorageInitializerContainerImage + ":" + StorageInitializerContainerImageVersion, - Args: []string{"gs://foo", constants.DefaultModelLocalMountPath}, - Resources: resourceRequirement, - TerminationMessagePolicy: "FallbackToLogsOnError", - VolumeMounts: []v1.VolumeMount{ - { - Name: "kserve-provision-location", - MountPath: constants.DefaultModelLocalMountPath, - }, - }, - }, - }, - }, - }, - }, - "UidFromOpenShiftNamespaceAnnotation": { - namespace: targetNS, - original: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: map[string]string{ - constants.StorageInitializerSourceUriInternalAnnotationKey: "gs://foo", - }, - }, - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Name: constants.InferenceServiceContainerName, - }, - }, - }, - }, - expected: &v1.Pod{ - Spec: v1.PodSpec{ - InitContainers: []v1.Container{ - { - Name: "storage-initializer", - Image: StorageInitializerContainerImage + ":" + StorageInitializerContainerImageVersion, - Args: []string{"gs://foo", constants.DefaultModelLocalMountPath}, - Resources: resourceRequirement, - TerminationMessagePolicy: "FallbackToLogsOnError", - VolumeMounts: []v1.VolumeMount{ - { - Name: "kserve-provision-location", - MountPath: constants.DefaultModelLocalMountPath, - }, - }, - SecurityContext: &v1.SecurityContext{ - RunAsUser: expectedInitContainerUid, - }, - }, - }, - }, - }, - }, - "UidFromPodAnnotation": { - namespace: targetNS, - original: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: map[string]string{ - constants.StorageInitializerSourceUriInternalAnnotationKey: "gs://foo", - constants.IstioSidecarUIDAnnotationKey: "1337", - }, - }, - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Name: constants.InferenceServiceContainerName, - }, - }, - }, - }, - expected: &v1.Pod{ - Spec: v1.PodSpec{ - InitContainers: []v1.Container{ - { - Name: "storage-initializer", - Image: StorageInitializerContainerImage + ":" + StorageInitializerContainerImageVersion, - Args: []string{"gs://foo", constants.DefaultModelLocalMountPath}, - Resources: resourceRequirement, - TerminationMessagePolicy: "FallbackToLogsOnError", - VolumeMounts: []v1.VolumeMount{ - { - Name: "kserve-provision-location", - MountPath: constants.DefaultModelLocalMountPath, - }, - }, - SecurityContext: &v1.SecurityContext{ - RunAsUser: ptr.Int64(1337), - }, - }, - }, - }, - }, - }, - } - - for name, scenario := range scenarios { - injector := &StorageInitializerInjector{ - credentialBuilder: credentials.NewCredentialBuilder(c, &v1.ConfigMap{ - Data: map[string]string{}, - }), - config: storageInitializerConfig, - client: c, - } - if err := injector.InjectStorageInitializer(scenario.original, scenario.namespace); err != nil { - t.Errorf("Test %q unexpected result: %s", name, err) - } - if diff, _ := kmp.SafeDiff(scenario.expected.Spec.InitContainers, scenario.original.Spec.InitContainers); diff != "" { - t.Errorf("Test %q unexpected result (-want +got): %v", name, diff) - } - } -} - func TestCustomSpecStorageUriInjection(t *testing.T) { scenarios := map[string]struct { original *v1.Pod @@ -664,7 +504,7 @@ func TestCustomSpecStorageUriInjection(t *testing.T) { config: storageInitializerConfig, client: c, } - if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { + if err := injector.InjectStorageInitializer(scenario.original); err != nil { t.Errorf("Test %q unexpected result: %s", name, err) } @@ -768,9 +608,6 @@ func TestCredentialInjection(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, - SecurityContext: &v1.SecurityContext{ - RunAsUser: expectedInitContainerUid, - }, Env: []v1.EnvVar{ { Name: s3.AWSAccessKeyId, @@ -876,9 +713,6 @@ func TestCredentialInjection(t *testing.T) { MountPath: gcs.GCSCredentialVolumeMountPath, }, }, - SecurityContext: &v1.SecurityContext{ - RunAsUser: expectedInitContainerUid, - }, Env: []v1.EnvVar{ { Name: gcs.GCSCredentialEnvKey, @@ -967,9 +801,6 @@ func TestCredentialInjection(t *testing.T) { Name: "storage-initializer", Image: StorageInitializerContainerImage + ":" + StorageInitializerContainerImageVersion, Args: []string{"s3://my-bucket/foo/bar", constants.DefaultModelLocalMountPath}, - SecurityContext: &v1.SecurityContext{ - RunAsUser: expectedInitContainerUid, - }, Env: []v1.EnvVar{ { Name: credentials.StorageConfigEnvKey, @@ -1065,9 +896,6 @@ func TestCredentialInjection(t *testing.T) { Name: "storage-initializer", Image: StorageInitializerContainerImage + ":" + StorageInitializerContainerImageVersion, Args: []string{"s3://my-bucket/foo/bar", constants.DefaultModelLocalMountPath}, - SecurityContext: &v1.SecurityContext{ - RunAsUser: expectedInitContainerUid, - }, Env: []v1.EnvVar{ { Name: credentials.StorageConfigEnvKey, @@ -1128,7 +956,7 @@ func TestCredentialInjection(t *testing.T) { config: storageInitializerConfig, client: c, } - if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { + if err := injector.InjectStorageInitializer(scenario.original); err != nil { t.Errorf("Test %q unexpected failure [%s]", name, err.Error()) } if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" { @@ -1192,9 +1020,6 @@ func TestStorageInitializerConfigmap(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, - SecurityContext: &v1.SecurityContext{ - RunAsUser: expectedInitContainerUid, - }, }, }, Volumes: []v1.Volume{ @@ -1226,7 +1051,7 @@ func TestStorageInitializerConfigmap(t *testing.T) { }, client: c, } - if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { + if err := injector.InjectStorageInitializer(scenario.original); err != nil { t.Errorf("Test %q unexpected result: %s", name, err) } if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" { @@ -1446,7 +1271,6 @@ func TestCaBundleConfigMapVolumeMountInStorageInitializer(t *testing.T) { }, Resources: resourceRequirement, TerminationMessagePolicy: "FallbackToLogsOnError", - SecurityContext: &v1.SecurityContext{RunAsUser: expectedInitContainerUid}, VolumeMounts: []v1.VolumeMount{ { Name: "kserve-provision-location", @@ -1550,7 +1374,6 @@ func TestCaBundleConfigMapVolumeMountInStorageInitializer(t *testing.T) { }, Resources: resourceRequirement, TerminationMessagePolicy: "FallbackToLogsOnError", - SecurityContext: &v1.SecurityContext{RunAsUser: expectedInitContainerUid}, VolumeMounts: []v1.VolumeMount{ { Name: "kserve-provision-location", @@ -1672,7 +1495,6 @@ func TestCaBundleConfigMapVolumeMountInStorageInitializer(t *testing.T) { }, Resources: resourceRequirement, TerminationMessagePolicy: "FallbackToLogsOnError", - SecurityContext: &v1.SecurityContext{RunAsUser: expectedInitContainerUid}, VolumeMounts: []v1.VolumeMount{ { Name: "kserve-provision-location", @@ -1795,7 +1617,6 @@ func TestCaBundleConfigMapVolumeMountInStorageInitializer(t *testing.T) { }, Resources: resourceRequirement, TerminationMessagePolicy: "FallbackToLogsOnError", - SecurityContext: &v1.SecurityContext{RunAsUser: expectedInitContainerUid}, VolumeMounts: []v1.VolumeMount{ { Name: "kserve-provision-location", @@ -1909,7 +1730,6 @@ func TestCaBundleConfigMapVolumeMountInStorageInitializer(t *testing.T) { }, Resources: resourceRequirement, TerminationMessagePolicy: "FallbackToLogsOnError", - SecurityContext: &v1.SecurityContext{RunAsUser: expectedInitContainerUid}, VolumeMounts: []v1.VolumeMount{ { Name: "kserve-provision-location", @@ -2018,7 +1838,6 @@ func TestCaBundleConfigMapVolumeMountInStorageInitializer(t *testing.T) { }, Resources: resourceRequirement, TerminationMessagePolicy: "FallbackToLogsOnError", - SecurityContext: &v1.SecurityContext{RunAsUser: expectedInitContainerUid}, VolumeMounts: []v1.VolumeMount{ { Name: "kserve-provision-location", @@ -2065,7 +1884,7 @@ func TestCaBundleConfigMapVolumeMountInStorageInitializer(t *testing.T) { config: scenario.storageConfig, client: c, } - if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { + if err := injector.InjectStorageInitializer(scenario.original); err != nil { t.Errorf("Test %q unexpected failure [%s]", name, err.Error()) } if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" { @@ -2193,7 +2012,7 @@ func TestDirectVolumeMountForPvc(t *testing.T) { }, client: c, } - if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { + if err := injector.InjectStorageInitializer(scenario.original); err != nil { t.Errorf("Test %q unexpected result: %s", name, err) } if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" { @@ -2296,9 +2115,6 @@ func TestTransformerCollocation(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, - SecurityContext: &v1.SecurityContext{ - RunAsUser: expectedInitContainerUid, - }, }, }, Volumes: []v1.Volume{ @@ -2467,9 +2283,6 @@ func TestTransformerCollocation(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, - SecurityContext: &v1.SecurityContext{ - RunAsUser: expectedInitContainerUid, - }, }, }, Volumes: []v1.Volume{ @@ -2502,7 +2315,7 @@ func TestTransformerCollocation(t *testing.T) { config: scenario.storageConfig, client: c, } - if err := injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { + if err := injector.InjectStorageInitializer(scenario.original); err != nil { t.Errorf("Test %q unexpected result: %s", name, err) } if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" { @@ -2691,9 +2504,6 @@ func TestStorageContainerCRDInjection(t *testing.T) { Env: []v1.EnvVar{ {Name: "name", Value: "value"}, }, - SecurityContext: &v1.SecurityContext{ - RunAsUser: expectedInitContainerUid, - }, }, }, Volumes: []v1.Volume{ @@ -2754,9 +2564,6 @@ func TestStorageContainerCRDInjection(t *testing.T) { MountPath: constants.DefaultModelLocalMountPath, }, }, - SecurityContext: &v1.SecurityContext{ - RunAsUser: expectedInitContainerUid, - }, }, }, Volumes: []v1.Volume{ @@ -2780,7 +2587,7 @@ func TestStorageContainerCRDInjection(t *testing.T) { client: mockClient, } - if err = injector.InjectStorageInitializer(scenario.original, targetNS); err != nil { + if err = injector.InjectStorageInitializer(scenario.original); err != nil { t.Errorf("Test %q unexpected result: %s", name, err) } if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" { From 63778d4ff0d0a4471bb37af3ce42a5ec8dbbf0b8 Mon Sep 17 00:00:00 2001 From: heyselbi Date: Wed, 7 Feb 2024 09:53:24 -0500 Subject: [PATCH 26/45] Update OWNERS Signed-off-by: heyselbi --- OWNERS | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/OWNERS b/OWNERS index 761dc94d8f7..da4e0c74550 100644 --- a/OWNERS +++ b/OWNERS @@ -1,20 +1,21 @@ approvers: - - anishasthana - danielezonca + - davidesalerno + - dtrifiro - heyselbi - israel-hdez - Jooho + - rpancham - spolti + - terrytangyuan + - vaibhavjainwiz - VedantMahabaleshwarkar - Xaenalt - - vaibhavjainwiz + - z103cb reviewers: - - anishasthana - - danielezonca - - heyselbi + - davidesalerno - israel-hdez - Jooho - spolti + - terrytangyuan - VedantMahabaleshwarkar - - Xaenalt - - vaibhavjainwiz From fbb6a13f8724502af2a7681c29b6881cd58695d2 Mon Sep 17 00:00:00 2001 From: Vedant Mahabaleshwarkar Date: Tue, 27 Feb 2024 11:51:05 -0500 Subject: [PATCH 27/45] set disableIngressCreation to true in odh overlay Signed-off-by: Vedant Mahabaleshwarkar --- config/overlays/odh/inferenceservice-config-patch.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/overlays/odh/inferenceservice-config-patch.yaml b/config/overlays/odh/inferenceservice-config-patch.yaml index 0f6d4f8a328..b32dde72005 100644 --- a/config/overlays/odh/inferenceservice-config-patch.yaml +++ b/config/overlays/odh/inferenceservice-config-patch.yaml @@ -25,6 +25,7 @@ data: "domainTemplate": "{{ .Name }}-{{ .Namespace }}.{{ .IngressDomain }}", "urlScheme": "https", "disableIstioVirtualHost": false + "disableIngressCreation": true } logger: |- { From 6eebd6e433cb2bff5f450dce8c8fe4cb89164d2e Mon Sep 17 00:00:00 2001 From: jooho Date: Wed, 28 Feb 2024 10:43:59 -0500 Subject: [PATCH 28/45] add .tekton to gitignore to avoid conflict due to Konflux Signed-off-by: jooho --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 00368ddc92b..714bb0e7bbc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Binaries for programs and plugins +.tekton *.exe *.exe~ *.dll From d779e7e065e85d2a00b0328a5e303e9cb9d80595 Mon Sep 17 00:00:00 2001 From: Spolti Date: Thu, 29 Feb 2024 10:00:22 -0300 Subject: [PATCH 29/45] [RHOAIENG-3551] - fastapi - Regular Expression Denial of Service (ReDoS) Fixes CVE-2024-24762 - Regular Expression Denial of Service (ReDoS) Remove the fastapi when this is addressed: https://issues.redhat.com/browse/RHOAIENG-3894 or ray releses a new version that removes the fastapi version pinning and it gets updated on KServe Signed-off-by: Spolti --- python/storage-initializer.Dockerfile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/python/storage-initializer.Dockerfile b/python/storage-initializer.Dockerfile index a84d4de4014..ac58d8f5a6a 100644 --- a/python/storage-initializer.Dockerfile +++ b/python/storage-initializer.Dockerfile @@ -33,7 +33,12 @@ RUN apt-get update && apt-get install -y \ krb5-config \ && rm -rf /var/lib/apt/lists/* -RUN pip install --no-cache-dir krbcontext==0.10 hdfs~=2.6.0 requests-kerberos==0.14.0 +# Fixes CVE-2024-24762 - Regular Expression Denial of Service (ReDoS) +# Remove the fastapi when this is addressed: https://issues.redhat.com/browse/RHOAIENG-3894 +# or ray releses a new version that removes the fastapi version pinning and it gets updated on KServe +RUN pip install --no-cache-dir krbcontext==0.10 hdfs~=2.6.0 requests-kerberos==0.14.0 fastapi==0.109.1 +# Fixes Quay alert GHSA-2jv5-9r88-3w3p https://github.com/Kludex/python-multipart/security/advisories/GHSA-2jv5-9r88-3w3p +RUN pip install --no-cache-dir starlette==0.36.2 FROM ${BASE_IMAGE} as prod From fcc28b19c7c3e8d992e2a0f09bce340281a51c08 Mon Sep 17 00:00:00 2001 From: Vedant Mahabaleshwarkar Date: Thu, 29 Feb 2024 10:21:51 -0500 Subject: [PATCH 30/45] fix syntax error in inferenceservice-config patch Signed-off-by: Vedant Mahabaleshwarkar --- config/overlays/odh/inferenceservice-config-patch.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/overlays/odh/inferenceservice-config-patch.yaml b/config/overlays/odh/inferenceservice-config-patch.yaml index b32dde72005..2a1eac9de58 100644 --- a/config/overlays/odh/inferenceservice-config-patch.yaml +++ b/config/overlays/odh/inferenceservice-config-patch.yaml @@ -24,7 +24,7 @@ data: "ingressClassName" : "istio", "domainTemplate": "{{ .Name }}-{{ .Namespace }}.{{ .IngressDomain }}", "urlScheme": "https", - "disableIstioVirtualHost": false + "disableIstioVirtualHost": false, "disableIngressCreation": true } logger: |- From 3b09426661ebec29aaa18906ebee4f5d25a5923a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Fri, 1 Mar 2024 12:26:04 -0600 Subject: [PATCH 31/45] Increase memory limit of kserve-controller pod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The increased memory limit is for the controller pod to work normally in clusters having 9k+ secrets. Related https://issues.redhat.com/browse/RHOAIENG-3996 Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- config/overlays/odh/set-resources-manager-patch.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/overlays/odh/set-resources-manager-patch.yaml b/config/overlays/odh/set-resources-manager-patch.yaml index 164e0cb5ad1..7e65bb2137c 100644 --- a/config/overlays/odh/set-resources-manager-patch.yaml +++ b/config/overlays/odh/set-resources-manager-patch.yaml @@ -11,4 +11,4 @@ spec: resources: limits: cpu: 500m - memory: 500Mi + memory: 5Gi From f6d0b8d0c5c47b97dff1873c703034b3779913b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Tue, 20 Feb 2024 13:59:05 -0600 Subject: [PATCH 32/45] Add capability to run RawDeployment E2Es in OpenShift-ci MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since ODH would support KServe's RawDeployment mode, this modifies the scripts around OpenShift-ci setup to be possible to run RawDeployment-related E2Es. The run-e2e-tests.sh script is modified to exclude installation of Service Mesh and Serverless, when RawDeployments E2Es are requested to run. A supporting file inferenceservice-openshift-ci-raw.yaml was added to patch KServe's configuration to use RawDeployment mode by default and to use OpenShift Ingress when exposing Inference Services. Since the E2Es use some annotations in the InferenceService, changes done to the v1beta1_inference_service.py file in commit ecff079 were reverted. As an alternative, the `enablePassthrough` annotation was moved to the ServingRuntime resources. This is not only cleaner, but also reduces the diverging code with the upstream repository. Furthermore, this seems to be an auto-generated file that should not be touched. Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- .../inferenceservice-openshift-ci-raw.yaml | 23 +++++++++++ .../models/v1beta1_inference_service.py | 2 - test/e2e/predictor/test_raw_deployment.py | 1 + test/e2e/transformer/test_collocation.py | 1 + test/e2e/transformer/test_raw_transformer.py | 1 + test/scripts/openshift-ci/run-e2e-tests.sh | 41 +++++++++++++++---- 6 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 config/overlays/test/configmap/inferenceservice-openshift-ci-raw.yaml diff --git a/config/overlays/test/configmap/inferenceservice-openshift-ci-raw.yaml b/config/overlays/test/configmap/inferenceservice-openshift-ci-raw.yaml new file mode 100644 index 00000000000..f36e02a5309 --- /dev/null +++ b/config/overlays/test/configmap/inferenceservice-openshift-ci-raw.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: inferenceservice-config + namespace: kserve +data: + deploy: |- + { + "defaultDeploymentMode": "RawDeployment" + } + ingress: |- + { + "ingressGateway" : "knative-serving/knative-ingress-gateway", + "ingressService" : "istio-ingressgateway.istio-system.svc.cluster.local", + "localGateway" : "knative-serving/knative-local-gateway", + "localGatewayService" : "knative-local-gateway.istio-system.svc.cluster.local", + "ingressDomain" : "$OPENSHIFT_INGRESS_DOMAIN", + "ingressClassName" : "openshift-default", + "domainTemplate": "{{ .Name }}-{{ .Namespace }}.{{ .IngressDomain }}", + "urlScheme": "http", + "disableIstioVirtualHost": false, + "disableIngressCreation": false + } diff --git a/python/kserve/kserve/models/v1beta1_inference_service.py b/python/kserve/kserve/models/v1beta1_inference_service.py index d6bd3f89f25..0f64aabf8b3 100644 --- a/python/kserve/kserve/models/v1beta1_inference_service.py +++ b/python/kserve/kserve/models/v1beta1_inference_service.py @@ -150,8 +150,6 @@ def metadata(self, metadata): :param metadata: The metadata of this V1beta1InferenceService. # noqa: E501 :type: V1ObjectMeta """ - if metadata is not None: - metadata.annotations = {"serving.knative.openshift.io/enablePassthrough": "true"} self._metadata = metadata diff --git a/test/e2e/predictor/test_raw_deployment.py b/test/e2e/predictor/test_raw_deployment.py index fe9879b9278..17e7b2c0297 100644 --- a/test/e2e/predictor/test_raw_deployment.py +++ b/test/e2e/predictor/test_raw_deployment.py @@ -113,6 +113,7 @@ def test_raw_deployment_runtime_kserve(): @pytest.mark.grpc @pytest.mark.raw +@pytest.mark.skip("The custom-model-grpc image fails in OpenShift with a permission denied error") def test_raw_isvc_with_multiple_container_port(): service_name = "raw-multiport-custom-model" model_name = "custom-model" diff --git a/test/e2e/transformer/test_collocation.py b/test/e2e/transformer/test_collocation.py index 0b48a3ae8de..bd5389946ec 100644 --- a/test/e2e/transformer/test_collocation.py +++ b/test/e2e/transformer/test_collocation.py @@ -101,6 +101,7 @@ def test_transformer_collocation(): @pytest.mark.raw +@pytest.mark.skip("The torchserve container fails in OpenShift with permission denied errors") def test_raw_transformer_collocation(): service_name = "raw-custom-model-collocation" model_name = "mnist" diff --git a/test/e2e/transformer/test_raw_transformer.py b/test/e2e/transformer/test_raw_transformer.py index cb3a8cc66cc..f0675573313 100644 --- a/test/e2e/transformer/test_raw_transformer.py +++ b/test/e2e/transformer/test_raw_transformer.py @@ -32,6 +32,7 @@ @pytest.mark.raw +@pytest.mark.skip("The torchserve container fails in OpenShift with permission denied errors") def test_transformer(): service_name = 'raw-transformer' predictor = V1beta1PredictorSpec( diff --git a/test/scripts/openshift-ci/run-e2e-tests.sh b/test/scripts/openshift-ci/run-e2e-tests.sh index 7c34df8fb8a..85497b7816b 100755 --- a/test/scripts/openshift-ci/run-e2e-tests.sh +++ b/test/scripts/openshift-ci/run-e2e-tests.sh @@ -63,10 +63,12 @@ pushd $PROJECT_ROOT/python/kserve >/dev/null popd # Install KServe stack -echo "Installing OSSM" -$MY_PATH/deploy.ossm.sh -echo "Installing Serverless" -$MY_PATH/deploy.serverless.sh +if [ "$1" != "raw" ]; then + echo "Installing OSSM" + $MY_PATH/deploy.ossm.sh + echo "Installing Serverless" + $MY_PATH/deploy.serverless.sh +fi echo "Installing KServe with Minio" kustomize build $PROJECT_ROOT/config/overlays/test | \ @@ -75,10 +77,21 @@ kustomize build $PROJECT_ROOT/config/overlays/test | \ sed "s|kserve/router:latest|${KSERVE_ROUTER_IMAGE}|" | \ sed "s|kserve/kserve-controller:latest|${KSERVE_CONTROLLER_IMAGE}|" | \ oc apply -f - + +# Patch the inferenceservice-config ConfigMap, when running RawDeployment tests + if [ "$1" == "raw" ]; then + export OPENSHIFT_INGRESS_DOMAIN=$(oc get ingresses.config cluster -o jsonpath='{.spec.domain}') + oc patch configmap inferenceservice-config -n kserve --patch-file <(cat config/overlays/test/configmap/inferenceservice-openshift-ci-raw.yaml | envsubst) + oc delete pod -n kserve -l control-plane=kserve-controller-manager + fi + +# Wait until KServe starts oc wait --for=condition=ready pod -l control-plane=kserve-controller-manager -n kserve --timeout=300s -echo "Installing odh-model-controller" -oc apply -k $PROJECT_ROOT/test/scripts/openshift-ci +if [ "$1" != "raw" ]; then + echo "Installing odh-model-controller" + oc apply -k $PROJECT_ROOT/test/scripts/openshift-ci +fi echo "Add testing models to minio storage ..." # Reference: config/overlays/test/minio/minio-init-job.yaml curl -L https://storage.googleapis.com/kfserving-examples/models/sklearn/1.0/model/model.joblib -o /tmp/sklearn-model.joblib @@ -96,7 +109,10 @@ apiVersion: v1 kind: Namespace metadata: name: kserve-ci-e2e-test ---- +EOF + +if [ "$1" != "raw" ]; then + cat </dev/null + # Note: The following images are set by openshift-ci. Uncomment if you are running on your own machine. + # export CUSTOM_MODEL_GRPC_IMG_TAG=kserve/custom-model-grpc:latest + # export IMAGE_TRANSFORMER_IMG_TAG=kserve/image-transformer:latest + export GITHUB_SHA=$(git rev-parse HEAD) export CI_USE_ISVC_HOST="1" ./test/scripts/gh-actions/run-e2e-tests.sh "$1" From c8e53e9e9bb0e32b84c4eb566d7a90e3dcb17685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Fri, 22 Mar 2024 10:05:35 -0600 Subject: [PATCH 33/45] Fix CI: Serverless removed domain-mapping deployment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Serverless version 1.32.0, the `domain-mapping` deployment no longer exists. This updates the deploy.serverless.sh script used in openshift-ci to no longer wait for this deployment. Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- test/scripts/openshift-ci/deploy.serverless.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/test/scripts/openshift-ci/deploy.serverless.sh b/test/scripts/openshift-ci/deploy.serverless.sh index 63e1db5a85c..a15880923ed 100755 --- a/test/scripts/openshift-ci/deploy.serverless.sh +++ b/test/scripts/openshift-ci/deploy.serverless.sh @@ -111,7 +111,6 @@ waitpodready "knative-serving" "app=controller" waitpodready "knative-serving" "app=net-istio-controller" waitpodready "knative-serving" "app=net-istio-webhook" waitpodready "knative-serving" "app=autoscaler-hpa" -waitpodready "knative-serving" "app=domain-mapping" waitpodready "knative-serving" "app=webhook" waitpodready "knative-serving" "app=activator" waitpodready "knative-serving" "app=autoscaler" From c9935219ef16326a186d12a05094a86de1928d34 Mon Sep 17 00:00:00 2001 From: Spolti Date: Tue, 2 Apr 2024 13:46:12 -0300 Subject: [PATCH 34/45] [RHOAIENG-5073] - Routing and Headless Service Support in KServe Raw Mode Deployment Signed-off-by: Spolti --- .../reconcilers/service/service_reconciler.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/controller/v1beta1/inferenceservice/reconcilers/service/service_reconciler.go b/pkg/controller/v1beta1/inferenceservice/reconcilers/service/service_reconciler.go index b5dab512808..bea459d559b 100644 --- a/pkg/controller/v1beta1/inferenceservice/reconcilers/service/service_reconciler.go +++ b/pkg/controller/v1beta1/inferenceservice/reconcilers/service/service_reconciler.go @@ -129,6 +129,10 @@ func createService(componentMeta metav1.ObjectMeta, componentExt *v1beta1.Compon "app": constants.GetRawServiceLabel(componentMeta.Name), }, Ports: servicePorts, + // TODO - add a control flag + // Need to add a control flag to properly set it, enable/disable this behavior. + // Follow up issue to align with upstream: https://issues.redhat.com/browse/RHOAIENG-5077 + ClusterIP: corev1.ClusterIPNone, }, } return service From b855d526eebcddba11fd482a4084821e2a6c54b5 Mon Sep 17 00:00:00 2001 From: Spolti Date: Thu, 4 Apr 2024 11:56:18 -0300 Subject: [PATCH 35/45] comment ce logs for headless services Signed-off-by: Spolti --- test/e2e/logger/test_logger.py | 1 + test/e2e/logger/test_raw_logger.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/test/e2e/logger/test_logger.py b/test/e2e/logger/test_logger.py index 9e82de632da..d8698b1d4b6 100644 --- a/test/e2e/logger/test_logger.py +++ b/test/e2e/logger/test_logger.py @@ -96,6 +96,7 @@ def test_kserve_logger(): namespace=pod.metadata.namespace, container="kserve-container") print(log) + assert ("org.kubeflow.serving.inference.request" in log) assert ("org.kubeflow.serving.inference.response" in log) kserve_client.delete(service_name, KSERVE_TEST_NAMESPACE) diff --git a/test/e2e/logger/test_raw_logger.py b/test/e2e/logger/test_raw_logger.py index 4c7961727bc..fcc505a3cc6 100644 --- a/test/e2e/logger/test_raw_logger.py +++ b/test/e2e/logger/test_raw_logger.py @@ -98,7 +98,10 @@ def test_kserve_logger(): namespace=pod.metadata.namespace, container="kserve-container") print(log) - assert ("org.kubeflow.serving.inference.request" in log) - assert ("org.kubeflow.serving.inference.response" in log) + + # TODO, as part of the https://issues.redhat.com/browse/RHOAIENG-5077 + # add the control flag here to check the logs when headless service is disabled + # assert ("org.kubeflow.serving.inference.request" in log) + # assert ("org.kubeflow.serving.inference.response" in log) kserve_client.delete(service_name, KSERVE_TEST_NAMESPACE) kserve_client.delete(msg_dumper, KSERVE_TEST_NAMESPACE) From fc1b99f970c2fe19a51ae75605838468f4119deb Mon Sep 17 00:00:00 2001 From: Spolti Date: Mon, 8 Apr 2024 15:06:08 -0300 Subject: [PATCH 36/45] lint the required test files Signed-off-by: Spolti --- test/e2e/predictor/test_raw_deployment.py | 4 +++- test/e2e/transformer/test_collocation.py | 4 +++- test/e2e/transformer/test_raw_transformer.py | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/test/e2e/predictor/test_raw_deployment.py b/test/e2e/predictor/test_raw_deployment.py index a853a7e5961..bcc2f5fae65 100644 --- a/test/e2e/predictor/test_raw_deployment.py +++ b/test/e2e/predictor/test_raw_deployment.py @@ -119,7 +119,9 @@ def test_raw_deployment_runtime_kserve(): @pytest.mark.grpc @pytest.mark.raw -@pytest.mark.skip("The custom-model-grpc image fails in OpenShift with a permission denied error") +@pytest.mark.skip( + "The custom-model-grpc image fails in OpenShift with a permission denied error" +) def test_raw_isvc_with_multiple_container_port(): service_name = "raw-multiport-custom-model" model_name = "custom-model" diff --git a/test/e2e/transformer/test_collocation.py b/test/e2e/transformer/test_collocation.py index 6ec20219e05..506d4dcf9cd 100644 --- a/test/e2e/transformer/test_collocation.py +++ b/test/e2e/transformer/test_collocation.py @@ -119,7 +119,9 @@ def test_transformer_collocation(): @pytest.mark.raw -@pytest.mark.skip("The torchserve container fails in OpenShift with permission denied errors") +@pytest.mark.skip( + "The torchserve container fails in OpenShift with permission denied errors" +) def test_raw_transformer_collocation(): service_name = "raw-custom-model-collocation" model_name = "mnist" diff --git a/test/e2e/transformer/test_raw_transformer.py b/test/e2e/transformer/test_raw_transformer.py index c9c23e29910..75e9afcb784 100644 --- a/test/e2e/transformer/test_raw_transformer.py +++ b/test/e2e/transformer/test_raw_transformer.py @@ -33,7 +33,9 @@ @pytest.mark.raw -@pytest.mark.skip("The torchserve container fails in OpenShift with permission denied errors") +@pytest.mark.skip( + "The torchserve container fails in OpenShift with permission denied errors" +) def test_transformer(): service_name = "raw-transformer" predictor = V1beta1PredictorSpec( From 3c5d8b499062e132ee5b1fe072fbd78917257afa Mon Sep 17 00:00:00 2001 From: jooho Date: Wed, 17 Apr 2024 12:41:03 -0400 Subject: [PATCH 37/45] remove unnecessary operators Signed-off-by: jooho --- test/scripts/openshift-ci/deploy.ossm.sh | 48 ------------------------ 1 file changed, 48 deletions(-) diff --git a/test/scripts/openshift-ci/deploy.ossm.sh b/test/scripts/openshift-ci/deploy.ossm.sh index d91c07e9d11..5afba75c593 100755 --- a/test/scripts/openshift-ci/deploy.ossm.sh +++ b/test/scripts/openshift-ci/deploy.ossm.sh @@ -33,54 +33,6 @@ waitpodready() { oc wait --for=condition=ready --timeout=180s pod -n $ns -l $podlabel } - -# Deploy Distributed tracing operator (Jaeger) -cat < Date: Fri, 19 Apr 2024 11:41:14 +0530 Subject: [PATCH 38/45] Create Workflow for release and tag with Changelog (#287) --- .github/workflows/create-release-tag.yml | 103 +++++++++++++++++++ .github/workflows/odh-create-release-tag.yml | 103 +++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 .github/workflows/create-release-tag.yml create mode 100644 .github/workflows/odh-create-release-tag.yml diff --git a/.github/workflows/create-release-tag.yml b/.github/workflows/create-release-tag.yml new file mode 100644 index 00000000000..5a9be9586de --- /dev/null +++ b/.github/workflows/create-release-tag.yml @@ -0,0 +1,103 @@ +name: Create Tag and Release with Changelog + +on: + workflow_dispatch: + inputs: + tag_name: + description: 'Tag name for the new release' + required: true + +permissions: + contents: write + packages: write + pull-requests: write + +jobs: + fetch-tag: + runs-on: ubuntu-latest + outputs: + old_tag: ${{ steps.get_tag.outputs.old_tag_name }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.ref }} + fetch-depth: 0 + + - name: Get latest tag + id: get_tag + run: | + echo "old_tag_name=$(git ls-remote --tags origin | awk -F'/' '{print $3}' | grep -v '{}' | sort -V | tail -n1)" >> $GITHUB_OUTPUT + - name: print tag + id: print_tag + run: | + echo "Old Tag=${{ steps.get_tag.outputs.old_tag_name }}" + echo "NEW_TAG=${{ github.event.inputs.tag_name }}" >> $GITHUB_ENV + echo "$(basename ${{ github.ref }})" + + - name: Check if tag exists + id: check_tag + run: | + import sys + import subprocess + tag_name = "${{ github.event.inputs.tag_name }}" + command = ['git', 'tag', '-l', tag_name] + output = subprocess.check_output(command, stderr=subprocess.STDOUT) + if output.decode() != "": + print(f"Error: Tag '{tag_name}' already exists.", file=sys.stderr) + sys.exit(1) + else: + print(f"Tag '{tag_name}' does not exists.") + + shell: python + continue-on-error: false + +#this works only if params.env contains image:tag_version_number + update-params-env: + runs-on: ubuntu-latest + needs: fetch-tag + outputs: + param_env: ${{ steps.read_params_env.outputs.params_env }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.ref }} + + - name: Update params.env with new release version + run: | + sed -i 's|:v[0-9.]*\b|:${{ github.event.inputs.tag_name }}|gm' config/overlays/odh/params.env + - name: Commit changes + run: | + git config --global user.email "github-actions@github.com" + git config --global user.name "GitHub Actions" + git add config/overlays/odh/params.env + git commit -m "Update image refs for odh release." + + - name: Create Tag + id: create_tag + run: | + git tag -a ${{ github.event.inputs.tag_name }} -m "Prepare for ODH release ${{ github.event.inputs.tag_name }}" + git push origin ${{ github.event.inputs.tag_name }} + + changelog: + name: Changelog + needs: [fetch-tag,update-params-env] + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.ref }} + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + token: ${{ github.token }} + tag_name: ${{ github.event.inputs.tag_name }} + prerelease: false + draft: false + #this takes the path of payload to upload as an asset in the changelog + files: bin/* + generate_release_notes: true + name: ${{ github.event.inputs.tag_name }} \ No newline at end of file diff --git a/.github/workflows/odh-create-release-tag.yml b/.github/workflows/odh-create-release-tag.yml new file mode 100644 index 00000000000..5a9be9586de --- /dev/null +++ b/.github/workflows/odh-create-release-tag.yml @@ -0,0 +1,103 @@ +name: Create Tag and Release with Changelog + +on: + workflow_dispatch: + inputs: + tag_name: + description: 'Tag name for the new release' + required: true + +permissions: + contents: write + packages: write + pull-requests: write + +jobs: + fetch-tag: + runs-on: ubuntu-latest + outputs: + old_tag: ${{ steps.get_tag.outputs.old_tag_name }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.ref }} + fetch-depth: 0 + + - name: Get latest tag + id: get_tag + run: | + echo "old_tag_name=$(git ls-remote --tags origin | awk -F'/' '{print $3}' | grep -v '{}' | sort -V | tail -n1)" >> $GITHUB_OUTPUT + - name: print tag + id: print_tag + run: | + echo "Old Tag=${{ steps.get_tag.outputs.old_tag_name }}" + echo "NEW_TAG=${{ github.event.inputs.tag_name }}" >> $GITHUB_ENV + echo "$(basename ${{ github.ref }})" + + - name: Check if tag exists + id: check_tag + run: | + import sys + import subprocess + tag_name = "${{ github.event.inputs.tag_name }}" + command = ['git', 'tag', '-l', tag_name] + output = subprocess.check_output(command, stderr=subprocess.STDOUT) + if output.decode() != "": + print(f"Error: Tag '{tag_name}' already exists.", file=sys.stderr) + sys.exit(1) + else: + print(f"Tag '{tag_name}' does not exists.") + + shell: python + continue-on-error: false + +#this works only if params.env contains image:tag_version_number + update-params-env: + runs-on: ubuntu-latest + needs: fetch-tag + outputs: + param_env: ${{ steps.read_params_env.outputs.params_env }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.ref }} + + - name: Update params.env with new release version + run: | + sed -i 's|:v[0-9.]*\b|:${{ github.event.inputs.tag_name }}|gm' config/overlays/odh/params.env + - name: Commit changes + run: | + git config --global user.email "github-actions@github.com" + git config --global user.name "GitHub Actions" + git add config/overlays/odh/params.env + git commit -m "Update image refs for odh release." + + - name: Create Tag + id: create_tag + run: | + git tag -a ${{ github.event.inputs.tag_name }} -m "Prepare for ODH release ${{ github.event.inputs.tag_name }}" + git push origin ${{ github.event.inputs.tag_name }} + + changelog: + name: Changelog + needs: [fetch-tag,update-params-env] + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.ref }} + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + token: ${{ github.token }} + tag_name: ${{ github.event.inputs.tag_name }} + prerelease: false + draft: false + #this takes the path of payload to upload as an asset in the changelog + files: bin/* + generate_release_notes: true + name: ${{ github.event.inputs.tag_name }} \ No newline at end of file From a3155d8f3f11b582494ac109bb71d1b7c3e472c8 Mon Sep 17 00:00:00 2001 From: Filippe Spolti Date: Mon, 29 Apr 2024 22:14:37 -0300 Subject: [PATCH 39/45] [RHOAIENG-4617] - follow up - remove hardcoded fastapi from Dockerfile (#292) * [RHOAIENG-4617] - follow up - remove hardcoded fastapi from Dockerfile As the Ray Serve latest release removed the hard dependency of old fastapi version we can now remove the workaround from the Storage Initializer Container Image. Signed-off-by: Spolti --- python/storage-initializer.Dockerfile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/python/storage-initializer.Dockerfile b/python/storage-initializer.Dockerfile index ac58d8f5a6a..647bb9b12ab 100644 --- a/python/storage-initializer.Dockerfile +++ b/python/storage-initializer.Dockerfile @@ -33,10 +33,7 @@ RUN apt-get update && apt-get install -y \ krb5-config \ && rm -rf /var/lib/apt/lists/* -# Fixes CVE-2024-24762 - Regular Expression Denial of Service (ReDoS) -# Remove the fastapi when this is addressed: https://issues.redhat.com/browse/RHOAIENG-3894 -# or ray releses a new version that removes the fastapi version pinning and it gets updated on KServe -RUN pip install --no-cache-dir krbcontext==0.10 hdfs~=2.6.0 requests-kerberos==0.14.0 fastapi==0.109.1 +RUN pip install --no-cache-dir krbcontext==0.10 hdfs~=2.6.0 requests-kerberos==0.14.0 # Fixes Quay alert GHSA-2jv5-9r88-3w3p https://github.com/Kludex/python-multipart/security/advisories/GHSA-2jv5-9r88-3w3p RUN pip install --no-cache-dir starlette==0.36.2 From 6d1e00b1918a4b97cad4ad6960783bcde9ae37bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= Date: Fri, 3 May 2024 13:21:08 -0600 Subject: [PATCH 40/45] Fix storage-initializer-docker-publisher workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is an error in the storage-initializer-docker-publisher workflow where a string is being used, but should be a variable. On PR merges, this is causing an error when trying to push the docker image of the storage initializer. This is fixing the issue by properly using the variable. Signed-off-by: Edgar Hernández --- .github/workflows/storage-initializer-docker-publisher.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/storage-initializer-docker-publisher.yml b/.github/workflows/storage-initializer-docker-publisher.yml index 3574531c1c1..c9dd81c0c9b 100644 --- a/.github/workflows/storage-initializer-docker-publisher.yml +++ b/.github/workflows/storage-initializer-docker-publisher.yml @@ -88,7 +88,7 @@ jobs: TAGS=$IMAGE_ID:$VERSION # If a vX.Y.Z release is being built, also update the vX.Y tag. [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] && MINOR_VERSION=$(echo $VERSION | sed 's/\(.*\)\.[[:digit:]]\+$/\1/') - [ ! -z "env.MINOR_VERSION" ] && TAGS=$TAGS,$IMAGE_ID:$MINOR_VERSION + [ ! -z "$MINOR_VERSION" ] && TAGS=$TAGS,$IMAGE_ID:$MINOR_VERSION echo TAGS=$TAGS >> $GITHUB_ENV From c5bebaa3bb699033ab2d7f9e382acee2cdaf24b8 Mon Sep 17 00:00:00 2001 From: Spolti Date: Wed, 15 May 2024 17:09:51 -0300 Subject: [PATCH 41/45] fix lint issues Signed-off-by: Spolti --- cmd/manager/main.go | 8 +-- config/crd/full/kustomization.yaml | 2 +- config/crd/kustomization.yaml | 12 ++-- config/crd/minimal/kustomization.yaml | 2 +- pkg/apis/serving/v1beta1/predictor_model.go | 64 +++++++++---------- .../v1beta1/inferenceservice/utils/utils.go | 14 ++-- .../servingruntime/servingruntime_webhook.go | 22 +++---- 7 files changed, 63 insertions(+), 61 deletions(-) diff --git a/cmd/manager/main.go b/cmd/manager/main.go index fc9a0bfabf2..91cc4eb44e0 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -248,10 +248,10 @@ func main() { Handler: &pod.Mutator{Client: mgr.GetClient(), Clientset: clientSet, Decoder: admission.NewDecoder(mgr.GetScheme())}, }) - //log.Info("registering cluster serving runtime validator webhook to the webhook server") - //hookServer.Register("/validate-serving-kserve-io-v1alpha1-clusterservingruntime", &webhook.Admission{ - // Handler: &servingruntime.ClusterServingRuntimeValidator{Client: mgr.GetClient(), Decoder: admission.NewDecoder(mgr.GetScheme())}, - //}) + // log.Info("registering cluster serving runtime validator webhook to the webhook server") + // hookServer.Register("/validate-serving-kserve-io-v1alpha1-clusterservingruntime", &webhook.Admission{ + // Handler: &servingruntime.ClusterServingRuntimeValidator{Client: mgr.GetClient(), Decoder: admission.NewDecoder(mgr.GetScheme())}, + // }) setupLog.Info("registering serving runtime validator webhook to the webhook server") hookServer.Register("/validate-serving-kserve-io-v1alpha1-servingruntime", &webhook.Admission{ diff --git a/config/crd/full/kustomization.yaml b/config/crd/full/kustomization.yaml index fd581386912..2ed142ca844 100644 --- a/config/crd/full/kustomization.yaml +++ b/config/crd/full/kustomization.yaml @@ -4,7 +4,7 @@ kind: Kustomization resources: - serving.kserve.io_inferenceservices.yaml - serving.kserve.io_trainedmodels.yaml - - serving.kserve.io_clusterservingruntimes.yaml + # - serving.kserve.io_clusterservingruntimes.yaml # Not supported in ODH - serving.kserve.io_servingruntimes.yaml - serving.kserve.io_inferencegraphs.yaml - serving.kserve.io_clusterstoragecontainers.yaml diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index ea388c39506..9d7880d6821 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -11,12 +11,14 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: -- serving.kserve.io_inferenceservices.yaml -- serving.kserve.io_trainedmodels.yaml +- full/serving.kserve.io_inferenceservices.yaml +- full/serving.kserve.io_trainedmodels.yaml # - serving.kserve.io_clusterservingruntimes.yaml # Not supported in ODH -- serving.kserve.io_servingruntimes.yaml -- serving.kserve.io_inferencegraphs.yaml -- serving.kserve.io_clusterstoragecontainers.yaml +# - full/serving.kserve.io_clusterservingruntimes.yaml +- full/serving.kserve.io_servingruntimes.yaml +- full/serving.kserve.io_inferencegraphs.yaml +- full/serving.kserve.io_clusterstoragecontainers.yaml + patches: # Fix for https://github.com/kubernetes/kubernetes/issues/91395 diff --git a/config/crd/minimal/kustomization.yaml b/config/crd/minimal/kustomization.yaml index fd581386912..2ed142ca844 100644 --- a/config/crd/minimal/kustomization.yaml +++ b/config/crd/minimal/kustomization.yaml @@ -4,7 +4,7 @@ kind: Kustomization resources: - serving.kserve.io_inferenceservices.yaml - serving.kserve.io_trainedmodels.yaml - - serving.kserve.io_clusterservingruntimes.yaml + # - serving.kserve.io_clusterservingruntimes.yaml # Not supported in ODH - serving.kserve.io_servingruntimes.yaml - serving.kserve.io_inferencegraphs.yaml - serving.kserve.io_clusterstoragecontainers.yaml diff --git a/pkg/apis/serving/v1beta1/predictor_model.go b/pkg/apis/serving/v1beta1/predictor_model.go index 9b767d1a051..ed6e0b3543d 100644 --- a/pkg/apis/serving/v1beta1/predictor_model.go +++ b/pkg/apis/serving/v1beta1/predictor_model.go @@ -96,16 +96,16 @@ func (m *ModelSpec) GetSupportingRuntimes(cl client.Client, namespace string, is sortServingRuntimeList(runtimes) // ODH does not support ClusterServingRuntimes - //// List all cluster-scoped runtimes. - //clusterRuntimes := &v1alpha1.ClusterServingRuntimeList{} - //if err := cl.List(context.TODO(), clusterRuntimes); err != nil { + // // List all cluster-scoped runtimes. + // clusterRuntimes := &v1alpha1.ClusterServingRuntimeList{} + // if err := cl.List(context.TODO(), clusterRuntimes); err != nil { // return nil, err - //} - //// Sort cluster-scoped runtimes by created timestamp desc and name asc. - //sortClusterServingRuntimeList(clusterRuntimes) + // } + // // Sort cluster-scoped runtimes by created timestamp desc and name asc. + // sortClusterServingRuntimeList(clusterRuntimes) srSpecs := []v1alpha1.SupportedRuntime{} - //var clusterSrSpecs []v1alpha1.SupportedRuntime + // var clusterSrSpecs []v1alpha1.SupportedRuntime for i := range runtimes.Items { rt := &runtimes.Items[i] if !rt.Spec.IsDisabled() && rt.Spec.IsMultiModelRuntime() == isMMS && @@ -114,15 +114,15 @@ func (m *ModelSpec) GetSupportingRuntimes(cl client.Client, namespace string, is } } sortSupportedRuntimeByPriority(srSpecs, m.ModelFormat) - //for i := range clusterRuntimes.Items { + // for i := range clusterRuntimes.Items { // crt := &clusterRuntimes.Items[i] // if !crt.Spec.IsDisabled() && crt.Spec.IsMultiModelRuntime() == isMMS && // m.RuntimeSupportsModel(&crt.Spec) && crt.Spec.IsProtocolVersionSupported(modelProtocolVersion) { - // clusterSrSpecs = append(clusterSrSpecs, v1alpha1.SupportedRuntime{Name: crt.GetName(), Spec: crt.Spec}) - // } - //} - //sortSupportedRuntimeByPriority(clusterSrSpecs, m.ModelFormat) - //srSpecs = append(srSpecs, clusterSrSpecs...) + // clusterSrSpecs = append(clusterSrSpecs, v1alpha1.SupportedRuntime{Name: crt.GetName(), Spec: crt.Spec}) + // } + // } + // sortSupportedRuntimeByPriority(clusterSrSpecs, m.ModelFormat) + // srSpecs = append(srSpecs, clusterSrSpecs...) return srSpecs, nil } @@ -179,25 +179,25 @@ func sortServingRuntimeList(runtimes *v1alpha1.ServingRuntimeList) { }) } -func sortClusterServingRuntimeList(runtimes *v1alpha1.ClusterServingRuntimeList) { - sort.Slice(runtimes.Items, func(i, j int) bool { - if GetProtocolVersionPriority(runtimes.Items[i].Spec.ProtocolVersions) < - GetProtocolVersionPriority(runtimes.Items[j].Spec.ProtocolVersions) { - return true - } - if GetProtocolVersionPriority(runtimes.Items[i].Spec.ProtocolVersions) > - GetProtocolVersionPriority(runtimes.Items[j].Spec.ProtocolVersions) { - return false - } - if runtimes.Items[i].CreationTimestamp.Before(&runtimes.Items[j].CreationTimestamp) { - return false - } - if runtimes.Items[j].CreationTimestamp.Before(&runtimes.Items[i].CreationTimestamp) { - return true - } - return runtimes.Items[i].Name < runtimes.Items[j].Name - }) -} +// func sortClusterServingRuntimeList(runtimes *v1alpha1.ClusterServingRuntimeList) { +// sort.Slice(runtimes.Items, func(i, j int) bool { +// if GetProtocolVersionPriority(runtimes.Items[i].Spec.ProtocolVersions) < +// GetProtocolVersionPriority(runtimes.Items[j].Spec.ProtocolVersions) { +// return true +// } +// if GetProtocolVersionPriority(runtimes.Items[i].Spec.ProtocolVersions) > +// GetProtocolVersionPriority(runtimes.Items[j].Spec.ProtocolVersions) { +// return false +// } +// if runtimes.Items[i].CreationTimestamp.Before(&runtimes.Items[j].CreationTimestamp) { +// return false +// } +// if runtimes.Items[j].CreationTimestamp.Before(&runtimes.Items[i].CreationTimestamp) { +// return true +// } +// return runtimes.Items[i].Name < runtimes.Items[j].Name +// }) +// } func sortSupportedRuntimeByPriority(runtimes []v1alpha1.SupportedRuntime, modelFormat ModelFormat) { sort.Slice(runtimes, func(i, j int) bool { diff --git a/pkg/controller/v1beta1/inferenceservice/utils/utils.go b/pkg/controller/v1beta1/inferenceservice/utils/utils.go index 8c1b50e0571..270dfc024c1 100644 --- a/pkg/controller/v1beta1/inferenceservice/utils/utils.go +++ b/pkg/controller/v1beta1/inferenceservice/utils/utils.go @@ -259,13 +259,13 @@ func GetServingRuntime(cl client.Client, name string, namespace string) (*v1alph } // ODH does not support ClusterServingRuntimes - //clusterRuntime := &v1alpha1.ClusterServingRuntime{} - //err = cl.Get(context.TODO(), client.ObjectKey{Name: name}, clusterRuntime) - //if err == nil { - // return &clusterRuntime.Spec, nil - //} else if !errors.IsNotFound(err) { - // return nil, err - //} + // clusterRuntime := &v1alpha1.ClusterServingRuntime{} + // err = cl.Get(context.TODO(), client.ObjectKey{Name: name}, clusterRuntime) + // if err == nil { + // return &clusterRuntime.Spec, nil + // } else if !errors.IsNotFound(err) { + // return nil, err + // } return nil, goerrors.New("No ServingRuntimes with the name: " + name) } diff --git a/pkg/webhook/admission/servingruntime/servingruntime_webhook.go b/pkg/webhook/admission/servingruntime/servingruntime_webhook.go index 617a469e221..e8f4e0ebb3d 100644 --- a/pkg/webhook/admission/servingruntime/servingruntime_webhook.go +++ b/pkg/webhook/admission/servingruntime/servingruntime_webhook.go @@ -36,18 +36,18 @@ var log = logf.Log.WithName(constants.ServingRuntimeValidatorWebhookName) const ( InvalidPriorityError = "Same priority assigned for the model format %s" InvalidPriorityServingRuntimeError = "%s in the servingruntimes %s and %s in namespace %s" - //InvalidPriorityClusterServingRuntimeError = "%s in the clusterservingruntimes %s and %s" + // InvalidPriorityClusterServingRuntimeError = "%s in the clusterservingruntimes %s and %s" ProrityIsNotSameError = "Different priorities assigned for the model format %s" ProrityIsNotSameServingRuntimeError = "%s under the servingruntime %s" ProrityIsNotSameClusterServingRuntimeError = "%s under the clusterservingruntime %s" ) -//// kubebuilder:webhook:verbs=create;update,path=/validate-serving-kserve-io-v1alpha1-clusterservingruntime,mutating=false,failurePolicy=fail,groups=serving.kserve.io,resources=clusterservingruntimes,versions=v1alpha1,name=clusterservingruntime.kserve-webhook-server.validator +// // kubebuilder:webhook:verbs=create;update,path=/validate-serving-kserve-io-v1alpha1-clusterservingruntime,mutating=false,failurePolicy=fail,groups=serving.kserve.io,resources=clusterservingruntimes,versions=v1alpha1,name=clusterservingruntime.kserve-webhook-server.validator // -//type ClusterServingRuntimeValidator struct { -// Client client.Client -// Decoder *admission.Decoder -//} +// type ClusterServingRuntimeValidator struct { +// Client client.Client +// Decoder *admission.Decoder +// } // +kubebuilder:webhook:verbs=create;update,path=/validate-serving-kserve-io-v1alpha1-servingruntime,mutating=false,failurePolicy=fail,groups=serving.kserve.io,resources=servingruntimes,versions=v1alpha1,name=servingruntime.kserve-webhook-server.validator @@ -86,10 +86,10 @@ func (sr *ServingRuntimeValidator) Handle(ctx context.Context, req admission.Req return admission.Allowed("") } -//// Handle validates the incoming request -//func (csr *ClusterServingRuntimeValidator) Handle(ctx context.Context, req admission.Request) admission.Response { -// clusterServingRuntime := &v1alpha1.ClusterServingRuntime{} -// if err := csr.Decoder.Decode(req, clusterServingRuntime); err != nil { +// // Handle validates the incoming request +// func (csr *ClusterServingRuntimeValidator) Handle(ctx context.Context, req admission.Request) admission.Response { +// clusterServingRuntime := &v1alpha1.ClusterServingRuntime{} +// if err := csr.Decoder.Decode(req, clusterServingRuntime); err != nil { // log.Error(err, "Failed to decode cluster serving runtime", "name", clusterServingRuntime.Name) // return admission.Errored(http.StatusBadRequest, err) // } @@ -114,7 +114,7 @@ func (sr *ServingRuntimeValidator) Handle(ctx context.Context, req admission.Req // } // } // return admission.Allowed("") -//} +// } func areSupportedModelFormatsEqual(m1 v1alpha1.SupportedModelFormat, m2 v1alpha1.SupportedModelFormat) bool { if strings.EqualFold(m1.Name, m2.Name) && ((m1.Version == nil && m2.Version == nil) || From d2c26b721a08040eb3aed5510187b5842fa048d3 Mon Sep 17 00:00:00 2001 From: Vedant Mahabaleshwarkar Date: Tue, 21 May 2024 15:52:06 -0400 Subject: [PATCH 42/45] replace upstream Dockerfiles with ubi dockerfiles. Signed-off-by: Vedant Mahabaleshwarkar --- Dockerfile | 15 +++++++++++---- agent.Dockerfile | 16 ++++++++++++---- python/storage-initializer.Dockerfile | 27 +++++++++------------------ router.Dockerfile | 15 +++++++++++---- 4 files changed, 43 insertions(+), 30 deletions(-) diff --git a/Dockerfile b/Dockerfile index 42c74b5ae66..29cd04475a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build the manager binary -FROM golang:1.21 as builder +FROM registry.access.redhat.com/ubi8/go-toolset:1.21 as builder # Copy in the go src WORKDIR /go/src/github.com/kserve/kserve @@ -12,10 +12,17 @@ COPY cmd/ cmd/ COPY pkg/ pkg/ # Build +USER root RUN CGO_ENABLED=0 GOOS=linux GOFLAGS=-mod=mod go build -a -o manager ./cmd/manager -# Copy the controller-manager into a thin image -FROM gcr.io/distroless/static:nonroot +# Use distroless as minimal base image to package the manager binary +FROM registry.access.redhat.com/ubi8/ubi-minimal:latest +RUN microdnf install -y shadow-utils && \ + microdnf clean all && \ + useradd kserve -m -u 1000 +RUN microdnf remove -y shadow-utils COPY third_party/ /third_party/ COPY --from=builder /go/src/github.com/kserve/kserve/manager / -ENTRYPOINT ["/manager"] +USER 1000:1000 + +ENTRYPOINT ["/manager"] \ No newline at end of file diff --git a/agent.Dockerfile b/agent.Dockerfile index ecb44a688cf..9d3a65ed4b3 100644 --- a/agent.Dockerfile +++ b/agent.Dockerfile @@ -1,5 +1,5 @@ # Build the inference-agent binary -FROM golang:1.21 as builder +FROM registry.access.redhat.com/ubi8/go-toolset:1.21 as builder # Copy in the go src WORKDIR /go/src/github.com/kserve/kserve @@ -8,15 +8,23 @@ COPY go.sum go.sum RUN go mod download -COPY cmd/ cmd/ COPY pkg/ pkg/ +COPY cmd/ cmd/ # Build +USER root RUN CGO_ENABLED=0 GOOS=linux GOFLAGS=-mod=mod go build -a -o agent ./cmd/agent # Copy the inference-agent into a thin image -FROM gcr.io/distroless/static:nonroot +FROM registry.access.redhat.com/ubi8/ubi-minimal:latest + +RUN microdnf install -y shadow-utils && \ + microdnf clean all && \ + useradd kserve -m -u 1000 +RUN microdnf remove -y shadow-utils COPY third_party/ third_party/ WORKDIR /ko-app COPY --from=builder /go/src/github.com/kserve/kserve/agent /ko-app/ -ENTRYPOINT ["/ko-app/agent"] +USER 1000:1000 + +ENTRYPOINT ["/ko-app/agent"] \ No newline at end of file diff --git a/python/storage-initializer.Dockerfile b/python/storage-initializer.Dockerfile index 763213909de..d63cd8f4447 100644 --- a/python/storage-initializer.Dockerfile +++ b/python/storage-initializer.Dockerfile @@ -1,24 +1,22 @@ ARG PYTHON_VERSION=3.9 -ARG BASE_IMAGE=python:${PYTHON_VERSION}-slim-bullseye ARG VENV_PATH=/prod_venv -FROM ${BASE_IMAGE} as builder +FROM registry.access.redhat.com/ubi8/ubi-minimal:latest as builder + +# Install Python and dependencies +RUN microdnf install -y python39 python39-devel gcc libffi-devel openssl-devel krb5-workstation krb5-libs && microdnf clean all # Install Poetry ARG POETRY_HOME=/opt/poetry ARG POETRY_VERSION=1.7.1 -# Required for building packages for arm64 arch -RUN apt-get update && apt-get install -y --no-install-recommends python3-dev build-essential && apt-get clean && \ - rm -rf /var/lib/apt/lists/* - -RUN python3 -m venv ${POETRY_HOME} && ${POETRY_HOME}/bin/pip install poetry==${POETRY_VERSION} +RUN python -m venv ${POETRY_HOME} && ${POETRY_HOME}/bin/pip install poetry==${POETRY_VERSION} ENV PATH="$PATH:${POETRY_HOME}/bin" # Activate virtual env ARG VENV_PATH ENV VIRTUAL_ENV=${VENV_PATH} -RUN python3 -m venv $VIRTUAL_ENV +RUN python -m venv $VIRTUAL_ENV ENV PATH="$VIRTUAL_ENV/bin:$PATH" COPY kserve/pyproject.toml kserve/poetry.lock kserve/ @@ -26,20 +24,11 @@ RUN cd kserve && poetry install --no-root --no-interaction --no-cache --extras " COPY kserve kserve RUN cd kserve && poetry install --no-interaction --no-cache --extras "storage" -ARG DEBIAN_FRONTEND=noninteractive - -RUN apt-get update && apt-get install -y \ - gcc \ - libkrb5-dev \ - krb5-config \ - && rm -rf /var/lib/apt/lists/* - RUN pip install --no-cache-dir krbcontext==0.10 hdfs~=2.6.0 requests-kerberos==0.14.0 # Fixes Quay alert GHSA-2jv5-9r88-3w3p https://github.com/Kludex/python-multipart/security/advisories/GHSA-2jv5-9r88-3w3p RUN pip install --no-cache-dir starlette==0.36.2 - -FROM ${BASE_IMAGE} as prod +FROM registry.access.redhat.com/ubi8/ubi-minimal:latest as prod COPY third_party third_party @@ -48,6 +37,8 @@ ARG VENV_PATH ENV VIRTUAL_ENV=${VENV_PATH} ENV PATH="$VIRTUAL_ENV/bin:$PATH" +RUN microdnf install -y shadow-utils python39 python39-devel && \ + microdnf clean all RUN useradd kserve -m -u 1000 -d /home/kserve COPY --from=builder --chown=kserve:kserve $VIRTUAL_ENV $VIRTUAL_ENV diff --git a/router.Dockerfile b/router.Dockerfile index c9a416d5124..b0dd13813f9 100644 --- a/router.Dockerfile +++ b/router.Dockerfile @@ -1,5 +1,5 @@ # Build the inference-router binary -FROM golang:1.21 as builder +FROM registry.access.redhat.com/ubi8/go-toolset:1.21 as builder # Copy in the go src WORKDIR /go/src/github.com/kserve/kserve @@ -8,15 +8,22 @@ COPY go.sum go.sum RUN go mod download -COPY cmd/ cmd/ COPY pkg/ pkg/ +COPY cmd/ cmd/ # Build +USER root RUN CGO_ENABLED=0 go build -a -o router ./cmd/router # Copy the inference-router into a thin image -FROM gcr.io/distroless/static:nonroot +FROM registry.access.redhat.com/ubi8/ubi-minimal:latest +RUN microdnf install -y shadow-utils && \ + microdnf clean all && \ + useradd kserve -m -u 1000 +RUN microdnf remove -y shadow-utils COPY third_party/ third_party/ WORKDIR /ko-app COPY --from=builder /go/src/github.com/kserve/kserve/router /ko-app/ -ENTRYPOINT ["/ko-app/router"] +USER 1000:1000 + +ENTRYPOINT ["/ko-app/router"] \ No newline at end of file From 4e12777b33278e35ffac87b486c6131dcd037f05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Hern=C3=A1ndez?= <23639005+israel-hdez@users.noreply.github.com> Date: Tue, 27 Feb 2024 19:12:43 -0600 Subject: [PATCH 43/45] Docs for authorization feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Edgar Hernández <23639005+israel-hdez@users.noreply.github.com> --- docs/odh/authorino-setup-manual.md | 155 +++++++++++++++++++++++++++ docs/odh/authorization.md | 163 +++++++++++++++++++++++++++++ 2 files changed, 318 insertions(+) create mode 100644 docs/odh/authorino-setup-manual.md create mode 100644 docs/odh/authorization.md diff --git a/docs/odh/authorino-setup-manual.md b/docs/odh/authorino-setup-manual.md new file mode 100644 index 00000000000..45501d24248 --- /dev/null +++ b/docs/odh/authorino-setup-manual.md @@ -0,0 +1,155 @@ +# Setting up Authorino to work with ODH KServe + +This page guides you through the process of installing Authorino, +changing Service Mesh configuration to be able to use Authorino as an +authorization provider, and shows the needed configurations to let +ODH KServe work correctly. + +## Prerequisites + +* A configured instance of OpenShift Service Mesh is available in the cluster +* The [Authorino Operator](https://operatorhub.io/operator/authorino-operator) is already installed in the cluster +* The Open Data Hub operator is available in the cluster + +## Creating an Authorino instance + +The following steps will create a dedicated Authorino instance for usage in Open Data Hub. +We recommend that you don't share . + +1. Create a namespace to install the Authorino instance: + * `oc new-project opendatahub-auth-provider` +1. Enroll the namespace to the Service Mesh. Assuming your `ServiceMeshControlPlane` resource + is in the `istio-system` namespace and named `data-science-smcp`, you would need to create + the following resource: + ```yaml + apiVersion: maistra.io/v1 + kind: ServiceMeshMember + metadata: + name: default + namespace: opendatahub-auth-provider + spec: + controlPlaneRef: + namespace: istio-system + name: data-science-smcp + ``` +1. Create the following `Authorino` resource: + ```yaml + apiVersion: operator.authorino.kuadrant.io/v1beta1 + kind: Authorino + metadata: + name: authorino + namespace: opendatahub-auth-provider + spec: + authConfigLabelSelectors: security.opendatahub.io/authorization-group=default + clusterWide: true + listener: + tls: + enabled: false + oidcServer: + tls: + enabled: false + ``` +1. Once Authorino is running, patch the Authorino deployment to inject the Istio +sidecar and make it part of the Service Mesh: + * `oc patch deployment authorino -n opendatahub-auth-provider -p '{"spec": {"template":{"metadata":{"labels":{"sidecar.istio.io/inject":"true"}}}} }'` + +## Prepare the Service Mesh to work with Authorino + +Once the Authorino instance is configured, the `ServiceMeshControlPlane` resource +needs to be modified to configure Authorino as an authorization provider of the Mesh. + +Assuming you have your `ServiceMeshControlPlane` resource in the `istio-system` namespace, +you named it `data-science-smcp`, and you followed the previous section without +renaming any resource, the following is a patch that you can apply with +`oc patch smcp --type merge -n istio-system`: + +```yaml +spec: + techPreview: + meshConfig: + extensionProviders: + - name: opendatahub-auth-provider + envoyExtAuthzGrpc: + service: authorino-authorino-authorization.opendatahub-auth-provider.svc.cluster.local + port: 50051 +``` + +> [!IMPORTANT] +> You should apply this patch only if you don't have other extension providers. If you do, +> you should manually edit your `ServiceMeshControlPlane` resource and add the +> needed configuration. + +## Configure KServe authorization + +In ODH KServe, authorization is configured using a global Istio +`AuthorizationPolicy` targeting the predictor pods of InferenceServices. Also, +given the several hops of a request, an `EnvoyFilter` is used to reset the HTTP +_Host_ header to the original one of the inference request. + +The following YAML are the resources that you need to apply to the namespace +where Service Mesh is installed, assuming you have followed the previous +instructions without renaming any resource. If you created your `ServiceMeshControlPlane` +resource in the `istio-system` namespace, you can create the resources using +an `oc apply -n istio-system` command. + +```yaml +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: kserve-predictor +spec: + action: CUSTOM + provider: + name: opendatahub-auth-provider + rules: + - to: + - operation: + notPaths: + - /healthz + - /debug/pprof/ + - /metrics + - /wait-for-drain + selector: + matchLabels: + component: predictor +--- +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: activator-host-header +spec: + priority: 20 + workloadSelector: + labels: + component: predictor + configPatches: + - applyTo: HTTP_FILTER + match: + listener: + filterChain: + filter: + name: envoy.filters.network.http_connection_manager + patch: + operation: INSERT_BEFORE + value: + name: envoy.filters.http.lua + typed_config: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + inlineCode: | + function envoy_on_request(request_handle) + local headers = request_handle:headers() + if not headers then + return + end + + local original_host = headers:get("k-original-host") + if original_host then + + port_seperator = string.find(original_host, ":", 7) + if port_seperator then + original_host = string.sub(original_host, 0, port_seperator-1) + end + headers:replace('host', original_host) + end + end +``` diff --git a/docs/odh/authorization.md b/docs/odh/authorization.md new file mode 100644 index 00000000000..c1fb3881bae --- /dev/null +++ b/docs/odh/authorization.md @@ -0,0 +1,163 @@ +# Protecting Inference Services under authorization + +Starting Open Data Hub version 2.8, KServe is enhanced with request authorization +for `InferenceServices`. The protected services will require clients to provide +valid credentials in the HTTP Authorization request header. The provided credentials +must be valid, and must have enough privileges for the request to be accepted. + +> [!NOTE] +> In ODH v2.8, the feature is broken and is fixed in ODH v2.9. + +## Setup + +Authorization was implemented using [Istio's External Authorization +feature](https://istio.io/latest/docs/tasks/security/authorization/authz-custom/). +The chosen external authorizer is [Kuadrant's Authorino project](https://github.com/Kuadrant/authorino). + +The Open Data Hub operator will deploy and manage an instance of Authorino. For +this, the [Authorino Operator](https://github.com/Kuadrant/authorino-operator) is +required to be installed in the cluster, which is [available in the +OperatorHub](https://operatorhub.io/operator/authorino-operator). + +> [!NOTE] +> If you don't need authorization features, you can skip installing the Authorino +> Operator. The ODH operator will detect such situation and won't try to configure +> authorization capabilities. + +Once you install Open Data Hub, you can use the [`DSCInitialization` sample +available in the opendatahub-operator repository](https://github.com/opendatahub-io/opendatahub-operator/blob/incubation/config/samples/dscinitialization_v1_dscinitialization.yaml): + +```shell +oc apply -f https://github.com/opendatahub-io/opendatahub-operator/blob/incubation/config/samples/dscinitialization_v1_dscinitialization.yaml +``` + +After creating the `DSCInitialization` resource, the Open Data Hub operator should +deploy a Service Mesh instance, and an Authorino instance. Both components will +be configured to work together. + +To deploy KServe, the `DataScienceCluster` resource required is the +following one: + +```yaml +kind: DataScienceCluster +apiVersion: datasciencecluster.opendatahub.io/v1 +metadata: + name: default-dsc +spec: + components: + kserve: + managementState: Managed +``` + +Notice that the provided `DataScienceCluster` only specifies the KServe component. +The fields for other components may get their default values, and you may end-up +with a quite complete ODH setup. If you need only KServe or a smaller set of +ODH components, use the [`DataScienceCluster` resource sample](https://github.com/opendatahub-io/opendatahub-operator/blob/incubation/config/samples/datasciencecluster_v1_datasciencecluster.yaml) and +modify it to fit your needs. + +Once the `DataScienceCluster` resource is created, Knative serving will be installed +and configured to work with the Service Mesh and the Authorino instance that were +deployed via the `DSCInitialization` resource. + +## Deploying a protected InferenceService + +To demonstrate how to protect an `InferenceService`, a sample model generally +available from the upstream community will be used. The sample model is a +Scikit-learn model, and the following `ServingRuntime` needs to be created in +some namespace: + +```yaml +apiVersion: serving.kserve.io/v1alpha1 +kind: ServingRuntime +metadata: + name: kserve-sklearnserver +spec: + annotations: + prometheus.kserve.io/port: '8080' + prometheus.kserve.io/path: "/metrics" + serving.knative.openshift.io/enablePassthrough: "true" + sidecar.istio.io/inject: "true" + sidecar.istio.io/rewriteAppHTTPProbers: "true" + supportedModelFormats: + - name: sklearn + version: "1" + autoSelect: true + priority: 1 + protocolVersions: + - v1 + - v2 + containers: + - name: kserve-container + image: docker.io/kserve/sklearnserver:latest + args: + - --model_name={{.Name}} + - --model_dir=/mnt/models + - --http_port=8080 + resources: + requests: + cpu: "1" + memory: 2Gi + limits: + cpu: "1" + memory: 2Gi +``` + +Then, deploy the sample model by creating the following `InferenceService` resource +in the same namespace as the previous `ServingRuntime`: + +```yaml +apiVersion: "serving.kserve.io/v1beta1" +kind: "InferenceService" +metadata: + name: "sklearn-v2-iris" +spec: + predictor: + model: + modelFormat: + name: sklearn + protocolVersion: v2 + runtime: kserve-sklearnserver + storageUri: "gs://kfserving-examples/models/sklearn/1.0/model" +``` + +The `InferenceService` still does not have authorization enabled. A sanity check +can be done by sending an unauthenticated request to the service, which should +reply as normally: + +```bash +# Get the endpoint of the InferenceService +MODEL_ENDPOINT=$(kubectl get inferenceservice sklearn-v2-iris -o jsonpath='{.status.url}') +# Send an inference request: +curl -v \ + -H "Content-Type: application/json" \ + -d @./iris-input-v2.json \ + ${MODEL_ENDPOINT}/v2/models/sklearn-v2-iris/infer +``` + +You can download the `iris-input-v2.json` file from the following link: +[iris-input.json](https://github.com/opendatahub-io/kserve/blob/c146e06df7ea3907cd3702ed539b1da7885b616c/docs/samples/v1beta1/xgboost/iris-input.json) + +If the sanity check is successful, the `InferenceService` is protected by +adding the `security.opendatahub.io/enable-auth=true` annotation: + +```bash +oc annotate isvc sklearn-v2-iris security.opendatahub.io/enable-auth=true +``` + +The KServe controller will re-deploy the model. Once it is ready, the previous +`curl` request should be rejected because it is missing credentials. The credentials +are provided via the standard HTTP Authorization request header. The updated +`curl` request has the following form: + +```bash +curl -v \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $TOKEN" + -d @./iris-input-v2.json \ + ${MODEL_ENDPOINT}/v2/models/sklearn-v2-iris/infer +``` + +You can provide any `$TOKEN` that is accepted by the OpenShift API server. The +request will only be accepted if the provided token has the `get` privilege over +`v1/Services` resources (core Kubernetes Services) in the namespace where +the `InferenceService` lives. From 5b62ee3e4a33208a61f70f792dfa8828c90014e2 Mon Sep 17 00:00:00 2001 From: Vedant Mahabaleshwarkar Date: Thu, 6 Jun 2024 12:05:15 -0400 Subject: [PATCH 44/45] enable DirectPvcVolumeMount Signed-off-by: Vedant Mahabaleshwarkar --- config/overlays/odh/inferenceservice-config-patch.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/overlays/odh/inferenceservice-config-patch.yaml b/config/overlays/odh/inferenceservice-config-patch.yaml index 2a1eac9de58..088c58efc11 100644 --- a/config/overlays/odh/inferenceservice-config-patch.yaml +++ b/config/overlays/odh/inferenceservice-config-patch.yaml @@ -12,7 +12,7 @@ data: "memoryLimit": "1Gi", "cpuRequest": "100m", "cpuLimit": "1", - "enableDirectPvcVolumeMount": false + "enableDirectPvcVolumeMount": true } ingress: |- { From c287f27afbc2c066660897b764cd3643c29648ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 23:00:50 +0000 Subject: [PATCH 45/45] Bump urllib3 from 2.2.1 to 2.2.2 in /python/artexplainer Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.2.1 to 2.2.2. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.2.1...2.2.2) --- updated-dependencies: - dependency-name: urllib3 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- python/artexplainer/poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/artexplainer/poetry.lock b/python/artexplainer/poetry.lock index b8bef782b3c..c90464ce30b 100644 --- a/python/artexplainer/poetry.lock +++ b/python/artexplainer/poetry.lock @@ -2762,13 +2762,13 @@ files = [ [[package]] name = "urllib3" -version = "2.2.1" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras]