Skip to content

Commit

Permalink
Merge pull request #2123 from opendatahub-io/f/model-serving
Browse files Browse the repository at this point in the history
Merge `f/model-serving` to `main`
  • Loading branch information
openshift-merge-bot[bot] authored Nov 13, 2023
2 parents b13896b + 051fe59 commit 34c5a09
Show file tree
Hide file tree
Showing 135 changed files with 4,836 additions and 1,329 deletions.
35 changes: 31 additions & 4 deletions backend/src/routes/api/cluster-settings/clusterSettingsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ const DEFAULT_CLUSTER_SETTINGS: ClusterSettings = {
cullerTimeout: DEFAULT_CULLER_TIMEOUT,
userTrackingEnabled: false,
notebookTolerationSettings: { enabled: false, key: 'NotebooksOnly' },
modelServingPlatformEnabled: {
kServe: true,
modelMesh: false,
},
};

export const updateClusterSettings = async (
Expand All @@ -28,10 +32,30 @@ export const updateClusterSettings = async (
): Promise<{ success: boolean; error: string }> => {
const coreV1Api = fastify.kube.coreV1Api;
const namespace = fastify.kube.namespace;
const { pvcSize, cullerTimeout, userTrackingEnabled, notebookTolerationSettings } = request.body;
const {
pvcSize,
cullerTimeout,
userTrackingEnabled,
notebookTolerationSettings,
modelServingPlatformEnabled,
} = request.body;
const dashConfig = getDashboardConfig();
const isJupyterEnabled = checkJupyterEnabled();
try {
if (
modelServingPlatformEnabled.kServe !== !dashConfig.spec.dashboardConfig.disableKServe ||
modelServingPlatformEnabled.modelMesh !== !dashConfig.spec.dashboardConfig.disableModelMesh
) {
await setDashboardConfig(fastify, {
spec: {
dashboardConfig: {
disableKServe: !modelServingPlatformEnabled.kServe,
disableModelMesh: !modelServingPlatformEnabled.modelMesh,
},
},
});
}

await patchCM(fastify, segmentKeyCfg, {
data: { segmentKeyEnabled: String(userTrackingEnabled) },
}).catch((e) => {
Expand All @@ -41,7 +65,6 @@ export const updateClusterSettings = async (
if (isJupyterEnabled) {
await setDashboardConfig(fastify, {
spec: {
dashboardConfig: dashConfig.spec.dashboardConfig,
notebookController: {
enabled: isJupyterEnabled,
pvcSize: `${pvcSize}Gi`,
Expand Down Expand Up @@ -124,10 +147,14 @@ export const getClusterSettings = async (
): Promise<ClusterSettings | string> => {
const coreV1Api = fastify.kube.coreV1Api;
const namespace = fastify.kube.namespace;
const clusterSettings = {
const dashConfig = getDashboardConfig();
const clusterSettings: ClusterSettings = {
...DEFAULT_CLUSTER_SETTINGS,
modelServingPlatformEnabled: {
kServe: !dashConfig.spec.dashboardConfig.disableKServe,
modelMesh: !dashConfig.spec.dashboardConfig.disableModelMesh,
},
};
const dashConfig = getDashboardConfig();
const isJupyterEnabled = checkJupyterEnabled();
if (!dashConfig.spec.dashboardConfig.disableTracking) {
try {
Expand Down
8 changes: 6 additions & 2 deletions backend/src/routes/api/namespaces/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ export enum NamespaceApplicationCase {
*/
DSG_CREATION,
/**
* Upgrade an existing DSG project to work with model serving.
* Upgrade an existing DSG project to work with model mesh.
*/
MODEL_SERVING_PROMOTION,
MODEL_MESH_PROMOTION,
/**
* Upgrade an existing DSG project to work with model kserve.
*/
KSERVE_PROMOTION,
}
7 changes: 6 additions & 1 deletion backend/src/routes/api/namespaces/namespaceUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,16 @@ export const applyNamespaceChange = async (
'opendatahub.io/dashboard': 'true',
};
break;
case NamespaceApplicationCase.MODEL_SERVING_PROMOTION:
case NamespaceApplicationCase.MODEL_MESH_PROMOTION:
labels = {
'modelmesh-enabled': 'true',
};
break;
case NamespaceApplicationCase.KSERVE_PROMOTION:
labels = {
'modelmesh-enabled': 'false',
};
break;
default:
throw createCustomError('Unknown configuration', 'Cannot apply namespace change', 400);
}
Expand Down
8 changes: 7 additions & 1 deletion backend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export type DashboardConfig = K8sResourceCommon & {
disableCustomServingRuntimes: boolean;
modelMetricsNamespace: string;
disablePipelines: boolean;
disableKServe: boolean;
disableModelMesh: boolean;
};
groupsConfig?: {
adminGroups: string;
Expand Down Expand Up @@ -100,6 +102,10 @@ export type ClusterSettings = {
cullerTimeout: number;
userTrackingEnabled: boolean;
notebookTolerationSettings: NotebookTolerationSettings | null;
modelServingPlatformEnabled: {
kServe: boolean;
modelMesh: boolean;
};
};

// Add a minimal QuickStart type here as there is no way to get types without pulling in frontend (React) modules
Expand Down Expand Up @@ -947,7 +953,7 @@ type ComponentNames =

export type DataScienceClusterKindStatus = {
conditions: [];
installedComponents: { [key in ComponentNames]: boolean };
installedComponents: { [key in ComponentNames]?: boolean };
phase?: string;
};

Expand Down
2 changes: 2 additions & 0 deletions backend/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ export const blankDashboardCR: DashboardConfig = {
disableCustomServingRuntimes: false,
modelMetricsNamespace: '',
disablePipelines: false,
disableKServe: false,
disableModelMesh: true,
},
notebookController: {
enabled: true,
Expand Down
15 changes: 15 additions & 0 deletions backend/src/utils/resourceUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ const fetchOrCreateDashboardCR = async (
)
.then((res) => {
const dashboardCR = res?.body as DashboardConfig;
if (
dashboardCR &&
dashboardCR.spec.dashboardConfig.disableKServe === undefined &&
dashboardCR.spec.dashboardConfig.disableModelMesh === undefined
) {
// return a merge between dashboardCR and blankDashboardCR but changing spec.disableKServe to true and spec.disableModelMesh to false
return _.merge({}, blankDashboardCR, dashboardCR, {
spec: {
dashboardConfig: {
disableKServe: true,
disableModelMesh: false,
},
},
});
}
return _.merge({}, blankDashboardCR, dashboardCR); // merge with blank CR to prevent any missing values
})
.catch((e) => {
Expand Down
2 changes: 2 additions & 0 deletions docs/dashboard-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ The following are a list of features that are supported, along with there defaul
| disableModelServing | false | Disables Model Serving from the dashboard and from Data Science Projects. |
| disableProjectSharing | false | Disables Project Sharing from Data Science Projects. |
| disableCustomServingRuntimes | false | Disables Custom Serving Runtimes from the Admin Panel. |
| disableKServe | false | Disables the ability to select KServe as a Serving Platform. |
| disableModelMesh | true | Disables the ability to select ModelMesh as a Serving Platform. |
| modelMetricsNamespace | false | Enables the namespace in which the Model Serving Metrics' Prometheus Operator is installed. |

## Defaults
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/__mocks__/mockClusterSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@ export const mockClusterSettings = ({
key: 'NotebooksOnlyChange',
enabled: true,
},
modelServingPlatformEnabled = {
kServe: true,
modelMesh: true,
},
}: Partial<ClusterSettingsType>): ClusterSettingsType => ({
userTrackingEnabled,
cullerTimeout,
pvcSize,
notebookTolerationSettings,
modelServingPlatformEnabled,
});
6 changes: 6 additions & 0 deletions frontend/src/__mocks__/mockDashboardConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ type MockDashboardConfigType = {
disablePipelines?: boolean;
disableModelServing?: boolean;
disableCustomServingRuntimes?: boolean;
disableKServe?: boolean;
disableModelMesh?: boolean;
};

export const mockDashboardConfig = ({
Expand All @@ -28,6 +30,8 @@ export const mockDashboardConfig = ({
disableModelServing = false,
disableCustomServingRuntimes = false,
disablePipelines = false,
disableKServe = false,
disableModelMesh = true,
}: MockDashboardConfigType): DashboardConfigKind => ({
apiVersion: 'opendatahub.io/v1alpha',
kind: 'OdhDashboardConfig',
Expand Down Expand Up @@ -55,6 +59,8 @@ export const mockDashboardConfig = ({
disablePipelines,
modelMetricsNamespace: 'test-project',
disableProjectSharing: false,
disableKServe,
disableModelMesh,
},
notebookController: {
enabled: true,
Expand Down
104 changes: 100 additions & 4 deletions frontend/src/__mocks__/mockDscStatus.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,116 @@
import { DataScienceClusterKindStatus } from '~/k8sTypes';
import { DataScienceClusterKindStatus, K8sCondition } from '~/k8sTypes';
import { StackComponent } from '~/concepts/areas/types';

type MockDscStatus = {
export type MockDscStatus = {
conditions?: K8sCondition[];
phase?: string;
installedComponents?: DataScienceClusterKindStatus['installedComponents'];
};

export const mockDscStatus = ({
installedComponents,
conditions = [],
phase = 'Ready',
}: MockDscStatus): DataScienceClusterKindStatus => ({
conditions: [],
conditions: [
...[
{
lastHeartbeatTime: '2023-10-20T11:44:48Z',
lastTransitionTime: '2023-10-15T19:04:21Z',
message: 'DataScienceCluster resource reconciled successfully',
reason: 'ReconcileCompleted',
status: 'True',
type: 'ReconcileComplete',
},
{
lastHeartbeatTime: '2023-10-20T11:44:48Z',
lastTransitionTime: '2023-10-15T19:04:21Z',
message: 'DataScienceCluster resource reconciled successfully',
reason: 'ReconcileCompleted',
status: 'True',
type: 'Available',
},
{
lastHeartbeatTime: '2023-10-20T11:44:48Z',
lastTransitionTime: '2023-10-15T19:04:21Z',
message: 'DataScienceCluster resource reconciled successfully',
reason: 'ReconcileCompleted',
status: 'False',
type: 'Progressing',
},
{
lastHeartbeatTime: '2023-10-20T11:44:48Z',
lastTransitionTime: '2023-10-15T19:04:10Z',
message: 'DataScienceCluster resource reconciled successfully',
reason: 'ReconcileCompleted',
status: 'False',
type: 'Degraded',
},
{
lastHeartbeatTime: '2023-10-20T11:44:48Z',
lastTransitionTime: '2023-10-15T19:04:21Z',
message: 'DataScienceCluster resource reconciled successfully',
reason: 'ReconcileCompleted',
status: 'True',
type: 'Upgradeable',
},
{
lastHeartbeatTime: '2023-10-20T11:44:59Z',
lastTransitionTime: '2023-10-20T11:44:59Z',
message: 'Component reconciled successfully',
reason: 'ReconcileCompleted',
status: 'True',
type: 'odh-dashboardReady',
},
{
lastHeartbeatTime: '2023-10-20T11:44:59Z',
lastTransitionTime: '2023-10-20T11:44:59Z',
message: 'Component reconciled successfully',
reason: 'ReconcileCompleted',
status: 'True',
type: 'data-science-pipelines-operatorReady',
},
{
lastHeartbeatTime: '2023-10-20T11:45:01Z',
lastTransitionTime: '2023-10-20T11:45:01Z',
message: 'Component reconciled successfully',
reason: 'ReconcileCompleted',
status: 'True',
type: 'workbenchesReady',
},
{
lastHeartbeatTime: '2023-10-20T11:45:04Z',
lastTransitionTime: '2023-10-20T11:45:04Z',
message: 'Component reconciled successfully',
reason: 'ReconcileCompleted',
status: 'True',
type: 'kserveReady',
},
{
lastHeartbeatTime: '2023-10-20T11:45:04Z',
lastTransitionTime: '2023-10-20T11:45:04Z',
message: 'Component reconciled successfully',
reason: 'ReconcileCompleted',
status: 'True',
type: 'model-meshReady',
},
{
lastHeartbeatTime: '2023-10-20T11:45:06Z',
lastTransitionTime: '2023-10-20T11:45:06Z',
message: 'Component is disabled',
reason: 'ReconcileInit',
status: 'Unknown',
type: 'rayReady',
},
],
...conditions,
],
installedComponents: Object.values(StackComponent).reduce(
(acc, component) => ({
...acc,
[component]: installedComponents?.[component] ?? false,
}),
{},
),
phase: 'Ready',
phase,
});
21 changes: 18 additions & 3 deletions frontend/src/__mocks__/mockInferenceServiceK8sResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ type MockResourceConfigType = {
displayName?: string;
modelName?: string;
secretName?: string;
deleted?: boolean;
isModelMesh?: boolean;
activeModelState?: string;
url?: string;
};

export const mockInferenceServicek8sError = () => ({
Expand Down Expand Up @@ -37,15 +41,26 @@ export const mockInferenceServiceK8sResource = ({
displayName = 'Test Inference Service',
modelName = 'test-model',
secretName = 'test-secret',
deleted = false,
isModelMesh = false,
activeModelState = 'Pending',
url = '',
}: MockResourceConfigType): InferenceServiceKind => ({
apiVersion: 'serving.kserve.io/v1beta1',
kind: 'InferenceService',
metadata: {
annotations: {
'openshift.io/display-name': displayName,
'serving.kserve.io/deploymentMode': 'ModelMesh',
...(isModelMesh
? { 'serving.kserve.io/deploymentMode': 'ModelMesh' }
: {
'serving.knative.openshift.io/enablePassthrough': 'true',
'sidecar.istio.io/inject': 'true',
'sidecar.istio.io/rewriteAppHTTPProbers': 'true',
}),
},
creationTimestamp: '2023-03-17T16:12:41Z',
...(deleted ? { deletionTimestamp: new Date().toUTCString() } : {}),
generation: 1,
labels: {
name: name,
Expand Down Expand Up @@ -73,7 +88,7 @@ export const mockInferenceServiceK8sResource = ({
},
status: {
components: {},
url: '',
url,
conditions: [
{
lastTransitionTime: '2023-03-17T16:12:41Z',
Expand All @@ -99,7 +114,7 @@ export const mockInferenceServiceK8sResource = ({
time: '',
},
states: {
activeModelState: 'Pending',
activeModelState,
targetModelState: '',
},
transitionStatus: '',
Expand Down
Loading

0 comments on commit 34c5a09

Please sign in to comment.