diff --git a/README.md b/README.md
index ccd8931f7a..14cab83cf8 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,7 @@ This repository periodically synchronizes all official Kubeflow components from
| KServe | applications/kserve/kserve | [v0.15.0](https://github.com/kserve/kserve/releases/tag/v0.15.0/install/v0.15.0) | 600m | 1200Mi | 0GB |
| KServe Models Web Application | applications/kserve/models-web-app | [v0.15.0](https://github.com/kserve/models-web-app/tree/v0.15.0/config) | 6m | 259Mi | 0GB |
| Kubeflow Pipelines | applications/pipeline/upstream | [2.14.3](https://github.com/kubeflow/pipelines/tree/2.14.3/manifests/kustomize) | 970m | 3552Mi | 35GB |
-| Kubeflow Model Registry | applications/model-registry/upstream | [v0.3.0](https://github.com/kubeflow/model-registry/tree/v0.3.0/manifests/kustomize) | 510m | 2112Mi | 20GB |
+| Kubeflow Model Registry | applications/model-registry/upstream | [v0.3.2](https://github.com/kubeflow/model-registry/tree/v0.3.2/manifests/kustomize) | 510m | 2112Mi | 20GB |
| Spark Operator | applications/spark/spark-operator | [2.3.0](https://github.com/kubeflow/spark-operator/tree/v2.3.0) | 9m | 41Mi | 0GB |
| Istio | common/istio | [1.27.0](https://github.com/istio/istio/releases/tag/1.27.0) | 750m | 2364Mi | 0GB |
| Knative | common/knative/knative-serving
common/knative/knative-eventing | [v1.16.2](https://github.com/knative/serving/releases/tag/knative-v1.16.2)
[v1.16.4](https://github.com/knative/eventing/releases/tag/knative-v1.16.4) | 1450m | 1038Mi | 0GB |
diff --git a/applications/model-registry/upstream/base/kustomization.yaml b/applications/model-registry/upstream/base/kustomization.yaml
index bf931e9aee..64bf9030f0 100644
--- a/applications/model-registry/upstream/base/kustomization.yaml
+++ b/applications/model-registry/upstream/base/kustomization.yaml
@@ -8,4 +8,4 @@ resources:
images:
- name: ghcr.io/kubeflow/model-registry/server
newName: ghcr.io/kubeflow/model-registry/server
- newTag: v0.3.0
+ newTag: v0.3.2
diff --git a/applications/model-registry/upstream/options/catalog/README.md b/applications/model-registry/upstream/options/catalog/README.md
index a3bdeef033..40c6a8a5a6 100644
--- a/applications/model-registry/upstream/options/catalog/README.md
+++ b/applications/model-registry/upstream/options/catalog/README.md
@@ -1,40 +1,115 @@
# Model Catalog Manifests
-To deploy the model catalog:
+This directory contains manifests for deploying the Model Catalog using Kustomize.
+
+## Deployment
+
+The model catalog manifests deploy a PostgreSQL database, set `POSTGRES_PASSWORD` in `postgres.env` before deploying the manifests. On Linux, you can generate a random password with:
```sh
-kubectl apply -k . -n NAMESPACE
+(echo POSTGRES_USER=postgres ; echo -n POSTGRES_PASSWORD=; dd if=/dev/random of=/dev/stdout bs=15 count=1 status=none | base64) >base/postgres.env
```
-Replace `NAMESPACE` with your desired Kubernetes namespace.
+To deploy the Model Catalog to your Kubernetes cluster (without Kubeflow--see below for Istio support), run the following command from this directory:
-## sources.yaml Configuration
+```sh
+kubectl apply -k base -n
+```
-The `sources.yaml` file configures the model catalog sources. It contains a top-level `catalogs` list, where each entry defines a single catalog source.
+Replace `` with the Kubernetes namespace where you want to deploy the catalog.
-### Common Properties
+This command will create:
+* A `Deployment` to run the Model Catalog server.
+* A `Service` to expose the Model Catalog server.
+* A `ConfigMap` named `model-catalog-sources` containing the configuration for the catalog sources.
+* A `StatefulSet` with a PostgreSQL database
+* A `PersistentVolumeClaim` for PostgreSQL
-Each catalog source entry supports the following common properties:
+For deployment in a Kubeflow environment with Istio support, use the `overlay` directory instead:
-- **`name`** (*string*, required): A user-friendly name for the catalog source.
-- **`id`** (*string*, required): A unique identifier for the catalog source.
-- **`type`** (*string*, required): The type of catalog source. Supported values are `yaml` and `rhec`.
-- **`enabled`** (*boolean*, optional): Whether the catalog source is enabled. Defaults to `true` if not specified.
+```sh
+kubectl apply -k overlay -n
+```
-### Catalog Source Types
+## Configuring Catalog Sources
-Below are the supported catalog source types and their specific `properties`.
+The Model Catalog is configured via the `sources.yaml` file. This file is **not** a Kubernetes manifest itself, but rather a configuration file for the application.
-#### `yaml`
+When you run `kubectl apply -k .`, Kustomize generates a `ConfigMap` that includes `sources.yaml` and any referenced local YAML catalog files. This `ConfigMap` is then mounted into the Model Catalog pod, making the files available to the application.
-The `yaml` type sources model metadata from a local YAML file.
+### Adding your own YAML-based catalog
+
+You can define your own model catalog by providing a YAML file with model definitions. Here's how to add your own catalog source:
+
+1. **Create your catalog definition file.** Create a new YAML file with your model definitions. You can use `sample-catalog.yaml` as a reference for the format. Let's say you name it `my-catalog.yaml` and place it in this directory.
+
+2. **Add your file to the ConfigMap.** Edit `kustomization.yaml` to include your new file in the `configMapGenerator`:
+
+ ```yaml
+ # kustomization.yaml
+ ...
+ configMapGenerator:
+ - behavior: create
+ files:
+ - sources.yaml=sources.yaml
+ - sample-catalog.yaml=sample-catalog.yaml
+ - my-catalog.yaml=my-catalog.yaml # <-- Add your file here
+ name: sources
+ options:
+ disableNameSuffixHash: true
+ ```
+
+3. **Add a new source entry.** Edit `sources.yaml` to add a new entry for your catalog under the `catalogs` list.
+
+ ```yaml
+ # sources.yaml
+ catalogs:
+ - name: Sample Catalog
+ id: sample_custom_catalog
+ type: yaml
+ enabled: true
+ properties:
+ yamlCatalogPath: sample-catalog.yaml
+ - name: My Custom Catalog
+ id: my_custom_catalog
+ type: yaml
+ enabled: true
+ properties:
+ yamlCatalogPath: my-catalog.yaml # <-- Path to your file
+ ```
+ The `yamlCatalogPath` must be the filename of your catalog definition, as it will be mounted into the same directory as `sources.yaml` inside the pod.
+
+4. **Apply the changes.**
+
+ ```sh
+ kubectl apply -k . -n
+ ```
+
+### Multiple Catalog Sources
+
+The Model Catalog can be configured with multiple sources. You can add multiple entries to the `catalogs` list in `sources.yaml`. The catalog application only loads the single `sources.yaml` file specified at startup, so all sources must be defined within that file.
-##### Properties
-- **`yamlCatalogPath`** (*string*, required): The path to the YAML file containing the model definitions. This path is relative to the directory where the `sources.yaml` file is located.
-- **`excludedModels`** (*string list*, optional): A list of models to exclude from the catalog. These can be an exact name with a tag (e.g., `model-a:1.0`) or a pattern ending with `*` to exclude all tags for a repository (e.g., `model-b:*`).
-##### Example
+### Catalog Source Configuration Details
+
+Each entry in the `catalogs` list configures a single catalog source.
+
+#### Common Properties
+
+- **`name`** (*string*, required): A user-friendly name for the catalog source.
+- **`id`** (*string*, required): A unique identifier for the catalog source.
+- **`type`** (*string*, required): The type of catalog source. Currently supported types are: `yaml`.
+- **`enabled`** (*boolean*, optional): Whether the catalog source is enabled. Defaults to `true`.
+
+#### `yaml` source type properties
+
+The `yaml` type sources model metadata from a local YAML file.
+
+- **`yamlCatalogPath`** (*string*, required): The path to the YAML file containing the model definitions. This file must be available in the `ConfigMap` alongside `sources.yaml`.
+- **`excludedModels`** (*string list*, optional): A list of models to exclude from the catalog. These can be an exact name with a tag (e.g., `model-a:1.0`) or a pattern ending with `*` to exclude all tags for a model (e.g., `model-b:*`).
+
+##### Example `sources.yaml` entry
```yaml
catalogs:
@@ -49,27 +124,6 @@ catalogs:
- model-b:*
```
-#### `rhec`
-
-The `rhec` type sources model metadata from the Red Hat Ecosystem Catalog.
+### Sample Catalog File
-##### Properties
-
-- **`models`** (*string list*, required): A list of models to include from the Red Hat Ecosystem Catalog. Each entry contains the full name of the model repository in the Red Hat Ecosystem Catalog (e.g., `rhelai1/modelcar-granite-7b-starter`).
-- **`excludedModels`** (*string list*, optional): A list of models to exclude from the catalog. These can be an exact name with a tag (e.g., `rhelai1/modelcar-granite-7b-starter:b9514c3`) or a pattern ending with `*` to exclude all tags for a repository (e.g., `rhelai1/modelcar-granite-7b-starter:*`).
-
-##### Example
-
-```yaml
-catalogs:
- - name: Red Hat Ecosystem Catalog
- id: sample_rhec_catalog
- type: rhec
- enabled: true
- properties:
- models:
- - rhelai1/modelcar-granite-7b-starter
- excludedModels:
- - rhelai1/modelcar-granite-7b-starter:v0
- - rhelai1/modelcar-granite-*
-```
\ No newline at end of file
+You can refer to `sample-catalog.yaml` in this directory for an example of how to structure your model definitions file.
diff --git a/applications/model-registry/upstream/options/catalog/deployment.yaml b/applications/model-registry/upstream/options/catalog/base/deployment.yaml
similarity index 60%
rename from applications/model-registry/upstream/options/catalog/deployment.yaml
rename to applications/model-registry/upstream/options/catalog/base/deployment.yaml
index 2e953a776e..3051f24fe9 100644
--- a/applications/model-registry/upstream/options/catalog/deployment.yaml
+++ b/applications/model-registry/upstream/options/catalog/base/deployment.yaml
@@ -1,19 +1,25 @@
apiVersion: apps/v1
kind: Deployment
metadata:
- name: server
+ name: model-catalog-server
labels:
- component: model-catalog-server
+ app.kubernetes.io/name: model-catalog
+ app.kubernetes.io/part-of: model-catalog
+ app.kubernetes.io/component: server
spec:
replicas: 1
selector:
matchLabels:
- component: model-catalog-server
+ app.kubernetes.io/name: model-catalog
+ app.kubernetes.io/part-of: model-catalog
+ app.kubernetes.io/component: server
template:
metadata:
labels:
sidecar.istio.io/inject: "true"
- component: model-catalog-server
+ app.kubernetes.io/name: model-catalog
+ app.kubernetes.io/part-of: model-catalog
+ app.kubernetes.io/component: server
spec:
securityContext:
seccompProfile:
@@ -25,6 +31,19 @@ spec:
name: model-catalog-sources
containers:
- name: catalog
+ env:
+ - name: PGHOST
+ value: model-catalog-postgres
+ - name: PGUSER
+ valueFrom:
+ secretKeyRef:
+ name: model-catalog-postgres
+ key: POSTGRES_USER
+ - name: PGPASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: model-catalog-postgres
+ key: POSTGRES_PASSWORD
command:
- /model-registry
- catalog
diff --git a/applications/model-registry/upstream/options/catalog/hf-sources-example.yaml b/applications/model-registry/upstream/options/catalog/base/hf-sources-example.yaml
similarity index 100%
rename from applications/model-registry/upstream/options/catalog/hf-sources-example.yaml
rename to applications/model-registry/upstream/options/catalog/base/hf-sources-example.yaml
diff --git a/applications/model-registry/upstream/options/catalog/kustomization.yaml b/applications/model-registry/upstream/options/catalog/base/kustomization.yaml
similarity index 61%
rename from applications/model-registry/upstream/options/catalog/kustomization.yaml
rename to applications/model-registry/upstream/options/catalog/base/kustomization.yaml
index 56d3ba34d2..cd7cb4ecff 100644
--- a/applications/model-registry/upstream/options/catalog/kustomization.yaml
+++ b/applications/model-registry/upstream/options/catalog/base/kustomization.yaml
@@ -1,21 +1,29 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
-namePrefix: model-catalog-
-
resources:
- deployment.yaml
- service.yaml
+- postgres-statefulset.yaml
+- postgres-pvc.yaml
+- postgres-service.yaml
configMapGenerator:
- behavior: create
files:
- sources.yaml=sources.yaml
- sample-catalog.yaml=sample-catalog.yaml
- name: sources
+ name: model-catalog-sources
+ options:
+ disableNameSuffixHash: true
+
+secretGenerator:
+- envs:
+ - postgres.env
+ name: model-catalog-postgres
options:
disableNameSuffixHash: true
images:
- name: ghcr.io/kubeflow/model-registry/server
newName: ghcr.io/kubeflow/model-registry/server
- newTag: v0.3.0
+ newTag: v0.3.2
diff --git a/applications/model-registry/upstream/options/catalog/base/postgres-pvc.yaml b/applications/model-registry/upstream/options/catalog/base/postgres-pvc.yaml
new file mode 100644
index 0000000000..140cf476cc
--- /dev/null
+++ b/applications/model-registry/upstream/options/catalog/base/postgres-pvc.yaml
@@ -0,0 +1,10 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: model-catalog-postgres
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 5Gi
diff --git a/applications/model-registry/upstream/options/catalog/base/postgres-service.yaml b/applications/model-registry/upstream/options/catalog/base/postgres-service.yaml
new file mode 100644
index 0000000000..e06377dbba
--- /dev/null
+++ b/applications/model-registry/upstream/options/catalog/base/postgres-service.yaml
@@ -0,0 +1,18 @@
+kind: Service
+apiVersion: v1
+metadata:
+ labels:
+ app.kubernetes.io/name: model-catalog
+ app.kubernetes.io/part-of: model-catalog
+ app.kubernetes.io/component: database
+ name: model-catalog-postgres
+spec:
+ selector:
+ app.kubernetes.io/part-of: model-catalog
+ app.kubernetes.io/name: postgres
+ app.kubernetes.io/component: database
+ type: ClusterIP
+ ports:
+ - port: 5432
+ protocol: TCP
+ name: postgres
diff --git a/applications/model-registry/upstream/options/catalog/base/postgres-statefulset.yaml b/applications/model-registry/upstream/options/catalog/base/postgres-statefulset.yaml
new file mode 100644
index 0000000000..4ea85ae6e2
--- /dev/null
+++ b/applications/model-registry/upstream/options/catalog/base/postgres-statefulset.yaml
@@ -0,0 +1,52 @@
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: model-catalog-postgres
+ labels:
+ component: model-catalog-server
+spec:
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: postgres
+ app.kubernetes.io/part-of: model-catalog
+ replicas: 1
+ template:
+ metadata:
+ name: postgres
+ labels:
+ app.kubernetes.io/name: postgres
+ app.kubernetes.io/part-of: model-catalog
+ app.kubernetes.io/component: database
+ sidecar.istio.io/inject: "false"
+ spec:
+ securityContext:
+ seccompProfile:
+ type: RuntimeDefault
+ runAsNonRoot: true
+ fsGroup: 70
+ containers:
+ - name: postgres
+ image: postgres:17.6
+ env:
+ - name: PGDATA
+ value: /var/lib/postgresql/data/pgdata
+ envFrom:
+ - secretRef:
+ name: model-catalog-postgres
+ ports:
+ - name: postgres
+ containerPort: 5432
+ volumeMounts:
+ - name: model-catalog-postgres
+ mountPath: /var/lib/postgresql/data
+ securityContext:
+ runAsUser: 70
+ runAsGroup: 70
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ volumes:
+ - name: model-catalog-postgres
+ persistentVolumeClaim:
+ claimName: model-catalog-postgres
diff --git a/applications/model-registry/upstream/options/catalog/base/postgres.env b/applications/model-registry/upstream/options/catalog/base/postgres.env
new file mode 100644
index 0000000000..07cfbd56eb
--- /dev/null
+++ b/applications/model-registry/upstream/options/catalog/base/postgres.env
@@ -0,0 +1,2 @@
+POSTGRES_USER=postgres
+POSTGRES_PASSWORD=postgres
diff --git a/applications/model-registry/upstream/options/catalog/sample-catalog.yaml b/applications/model-registry/upstream/options/catalog/base/sample-catalog.yaml
similarity index 100%
rename from applications/model-registry/upstream/options/catalog/sample-catalog.yaml
rename to applications/model-registry/upstream/options/catalog/base/sample-catalog.yaml
diff --git a/applications/model-registry/upstream/options/catalog/base/service.yaml b/applications/model-registry/upstream/options/catalog/base/service.yaml
new file mode 100644
index 0000000000..2fde7d007e
--- /dev/null
+++ b/applications/model-registry/upstream/options/catalog/base/service.yaml
@@ -0,0 +1,18 @@
+kind: Service
+apiVersion: v1
+metadata:
+ labels:
+ app.kubernetes.io/name: model-catalog
+ app.kubernetes.io/component: server
+ app.kubernetes.io/part-of: model-catalog
+ name: model-catalog
+spec:
+ selector:
+ app.kubernetes.io/part-of: model-catalog
+ app.kubernetes.io/component: server
+ type: ClusterIP
+ ports:
+ - port: 8080
+ protocol: TCP
+ appProtocol: http
+ name: http-api
diff --git a/applications/model-registry/upstream/options/catalog/sources.yaml b/applications/model-registry/upstream/options/catalog/base/sources.yaml
similarity index 100%
rename from applications/model-registry/upstream/options/catalog/sources.yaml
rename to applications/model-registry/upstream/options/catalog/base/sources.yaml
diff --git a/applications/model-registry/upstream/options/catalog/overlay/destination-rule.yaml b/applications/model-registry/upstream/options/catalog/overlay/destination-rule.yaml
new file mode 100644
index 0000000000..b358adf1c8
--- /dev/null
+++ b/applications/model-registry/upstream/options/catalog/overlay/destination-rule.yaml
@@ -0,0 +1,9 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+ name: model-catalog-service
+spec:
+ host: model-catalog.kubeflow.svc.cluster.local
+ trafficPolicy:
+ tls:
+ mode: ISTIO_MUTUAL
diff --git a/applications/model-registry/upstream/options/catalog/overlay/kustomization.yaml b/applications/model-registry/upstream/options/catalog/overlay/kustomization.yaml
new file mode 100644
index 0000000000..029a6937ca
--- /dev/null
+++ b/applications/model-registry/upstream/options/catalog/overlay/kustomization.yaml
@@ -0,0 +1,7 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+- istio-authorization-policy.yaml
+- destination-rule.yaml
+- virtual-service.yaml
diff --git a/applications/model-registry/upstream/options/catalog/overlay/virtual-service.yaml b/applications/model-registry/upstream/options/catalog/overlay/virtual-service.yaml
new file mode 100644
index 0000000000..cedc235c78
--- /dev/null
+++ b/applications/model-registry/upstream/options/catalog/overlay/virtual-service.yaml
@@ -0,0 +1,18 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+ name: model-catalog
+spec:
+ gateways:
+ - kubeflow-gateway
+ hosts:
+ - "*"
+ http:
+ - match:
+ - uri:
+ prefix: /api/model_catalog/
+ route:
+ - destination:
+ host: model-catalog.kubeflow.svc.cluster.local
+ port:
+ number: 8080
diff --git a/applications/model-registry/upstream/options/catalog/service.yaml b/applications/model-registry/upstream/options/catalog/service.yaml
deleted file mode 100644
index 6e87175dbe..0000000000
--- a/applications/model-registry/upstream/options/catalog/service.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-kind: Service
-apiVersion: v1
-metadata:
- labels:
- app: model-catalog-service
- app.kubernetes.io/component: model-catalog
- app.kubernetes.io/instance: model-catalog-service
- app.kubernetes.io/name: model-catalog-service
- app.kubernetes.io/part-of: model-catalog
- component: model-catalog
- name: model-catalog-service
-spec:
- selector:
- component: model-catalog-server
- type: ClusterIP
- ports:
- - port: 8080
- protocol: TCP
- appProtocol: http
- name: http-api
diff --git a/applications/model-registry/upstream/options/csi/kustomization.yaml b/applications/model-registry/upstream/options/csi/kustomization.yaml
index c6e7c5b8af..c285d94c65 100644
--- a/applications/model-registry/upstream/options/csi/kustomization.yaml
+++ b/applications/model-registry/upstream/options/csi/kustomization.yaml
@@ -7,4 +7,4 @@ resources:
images:
- name: ghcr.io/kubeflow/model-registry/storage-initializer
newName: ghcr.io/kubeflow/model-registry/storage-initializer
- newTag: v0.3.0
+ newTag: v0.3.2
diff --git a/applications/model-registry/upstream/options/ui/base/kustomization.yaml b/applications/model-registry/upstream/options/ui/base/kustomization.yaml
index 6ee72f56bc..3e9a4516bb 100644
--- a/applications/model-registry/upstream/options/ui/base/kustomization.yaml
+++ b/applications/model-registry/upstream/options/ui/base/kustomization.yaml
@@ -10,4 +10,4 @@ resources:
images:
- name: model-registry-ui
newName: ghcr.io/kubeflow/model-registry/ui
- newTag: v0.3.0
+ newTag: v0.3.2
diff --git a/tests/model_catalog_install.sh b/tests/model_catalog_install.sh
index f1541224ec..56f2ca57de 100755
--- a/tests/model_catalog_install.sh
+++ b/tests/model_catalog_install.sh
@@ -2,7 +2,7 @@
set -euxo pipefail
(
- cd applications/model-registry/upstream/options/catalog
+ cd applications/model-registry/upstream/options/catalog/base
kustomize build . | kubectl apply -n kubeflow -f -
)
diff --git a/tests/model_catalog_test.sh b/tests/model_catalog_test.sh
index 7684d7646c..06669405b6 100755
--- a/tests/model_catalog_test.sh
+++ b/tests/model_catalog_test.sh
@@ -7,14 +7,14 @@ if ! kubectl get deployment/model-catalog-server -n kubeflow; then
exit 1
fi
-if ! kubectl get svc/model-catalog-model-catalog-service -n kubeflow; then
+if ! kubectl get svc/model-catalog -n kubeflow; then
echo "ERROR: Model Catalog service not found"
exit 1
fi
-kubectl get pods -n kubeflow -l component=model-catalog-server
+kubectl get pods -n kubeflow -l app.kubernetes.io/name=model-catalog,app.kubernetes.io/component=server
-nohup kubectl port-forward svc/model-catalog-model-catalog-service -n kubeflow 8082:8080 &
+nohup kubectl port-forward svc/model-catalog -n kubeflow 8082:8080 &
PORT_FORWARD_PID=$!
MAX_RETRIES=30