Skip to content

Commit 3392cb8

Browse files
Merge pull request #2867 from lucferbux/rhoaieng-5414-fix
Fix issue that fetch the wrong Notebook Image if two Imagestream Version shared the same sha
2 parents 4aa0a8c + 7ffb101 commit 3392cb8

File tree

4 files changed

+98
-11
lines changed

4 files changed

+98
-11
lines changed

frontend/src/__mocks__/mockImageStreamK8sResource.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ type MockResourceConfigType = {
77
namespace?: string;
88
displayName?: string;
99
imageTag?: string;
10+
tagName?: string;
1011
opts?: RecursivePartial<ImageStreamKind>;
1112
};
1213

@@ -15,6 +16,7 @@ export const mockImageStreamK8sResource = ({
1516
namespace = 'test-project',
1617
displayName = 'Test Image',
1718
imageTag = 'quay.io/opendatahub/notebooks@sha256:a138838e1c9acd7708462e420bf939e03296b97e9cf6c0aa0fd9a5d20361ab75',
19+
tagName = '1.2',
1820
opts = {},
1921
}: MockResourceConfigType): ImageStreamKind =>
2022
_.mergeWith(
@@ -50,7 +52,7 @@ export const mockImageStreamK8sResource = ({
5052
},
5153
tags: [
5254
{
53-
name: '1.2',
55+
name: tagName,
5456
annotations: {
5557
'opendatahub.io/notebook-python-dependencies':
5658
'[{"name":"JupyterLab","version": "3.2"}, {"name": "Notebook","version": "6.4"}]',

frontend/src/__mocks__/mockNotebookK8sResource.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type MockResourceConfigType = {
1414
envFromName?: string;
1515
resources?: ContainerResources;
1616
image?: string;
17+
lastImageSelection?: string;
1718
opts?: RecursivePartial<NotebookKind>;
1819
uid?: string;
1920
};
@@ -27,6 +28,7 @@ export const mockNotebookK8sResource = ({
2728
description = '',
2829
resources = DEFAULT_NOTEBOOK_SIZES[0].resources,
2930
image = 'test-imagestream:1.2',
31+
lastImageSelection = 's2i-minimal-notebook:py3.8-v1',
3032
opts = {},
3133
uid = genUID('notebook'),
3234
}: MockResourceConfigType): NotebookKind =>
@@ -38,7 +40,7 @@ export const mockNotebookK8sResource = ({
3840
annotations: {
3941
'notebooks.kubeflow.org/last-activity': '2023-02-14T21:45:14Z',
4042
'notebooks.opendatahub.io/inject-oauth': 'true',
41-
'notebooks.opendatahub.io/last-image-selection': 's2i-minimal-notebook:py3.8-v1',
43+
'notebooks.opendatahub.io/last-image-selection': lastImageSelection,
4244
'notebooks.opendatahub.io/last-size-selection': 'Small',
4345
'notebooks.opendatahub.io/oauth-logout-url':
4446
'http://localhost:4010/projects/project?notebookLogout=workbench',

frontend/src/pages/projects/screens/detail/notebooks/__tests__/useNotebookImageData.spec.ts

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,95 @@ import { getNotebookImageData } from '~/pages/projects/screens/detail/notebooks/
44
import { NotebookImageAvailability } from '~/pages/projects/screens/detail/notebooks/const';
55

66
describe('getNotebookImageData', () => {
7-
it('should return image data when image stream exists and image version exists', () => {
7+
it('should return image data when image stream exists and image version exists with internal registry', () => {
88
const notebook = mockNotebookK8sResource({
99
image:
1010
'quay.io/opendatahub/notebooks@sha256:a138838e1c9acd7708462e420bf939e03296b97e9cf6c0aa0fd9a5d20361ab75',
11+
lastImageSelection: 'jupyter-datascience-notebook',
1112
});
1213
const images = [
1314
mockImageStreamK8sResource({
1415
imageTag:
1516
'quay.io/opendatahub/notebooks@sha256:a138838e1c9acd7708462e420bf939e03296b97e9cf6c0aa0fd9a5d20361ab75',
17+
name: 'jupyter-datascience-notebook',
1618
}),
1719
];
1820
const result = getNotebookImageData(notebook, images);
1921
expect(result?.imageAvailability).toBe(NotebookImageAvailability.ENABLED);
2022
});
2123

24+
it('should return image data when image stream exists and image version exists without internal registry', () => {
25+
const imageName = 'jupyter-datascience-notebook';
26+
const tagName = '2024.1';
27+
const notebook = mockNotebookK8sResource({
28+
image: `image-registry.openshift-image-registry.svc:5000/opendatahub/${imageName}:${tagName}`,
29+
lastImageSelection: 'jupyter-datascience-notebook',
30+
});
31+
const images = [
32+
mockImageStreamK8sResource({
33+
imageTag:
34+
'quay.io/opendatahub/notebooks@sha256:a138838e1c9acd7708462e420bf939e03296b97e9cf6c0aa0fd9a5d20361ab75',
35+
tagName,
36+
name: imageName,
37+
}),
38+
];
39+
const result = getNotebookImageData(notebook, images);
40+
expect(result?.imageAvailability).toBe(NotebookImageAvailability.ENABLED);
41+
});
42+
43+
it('should return the right image if multiple ImageStreams have the same image with internal registry', () => {
44+
const displayName = 'Jupyter Data Science Notebook';
45+
const notebook = mockNotebookK8sResource({
46+
image:
47+
'quay.io/opendatahub/notebooks@sha256:a138838e1c9acd7708462e420bf939e03296b97e9cf6c0aa0fd9a5d20361ab75',
48+
lastImageSelection: 'jupyter-datascience-notebook',
49+
});
50+
const images = [
51+
mockImageStreamK8sResource({
52+
imageTag:
53+
'quay.io/opendatahub/notebooks@sha256:a138838e1c9acd7708462e420bf939e03296b97e9cf6c0aa0fd9a5d20361ab75',
54+
name: 'jupyter-datascience-notebook',
55+
displayName,
56+
}),
57+
mockImageStreamK8sResource({
58+
imageTag:
59+
'quay.io/opendatahub/notebooks@sha256:a138838e1c9acd7708462e420bf939e03296b97e9cf6c0aa0fd9a5d20361ab75',
60+
name: 'custom-notebook',
61+
displayName: 'Custom Notebook',
62+
}),
63+
];
64+
const result = getNotebookImageData(notebook, images);
65+
expect(result?.imageDisplayName).toBe(displayName);
66+
});
67+
68+
it('should return the right image if multiple ImageStreams have the same tag without internal registry', () => {
69+
const imageName = 'jupyter-datascience-notebook';
70+
const tagName = '2024.1';
71+
const displayName = 'Jupyter Data Science Notebook';
72+
const notebook = mockNotebookK8sResource({
73+
image: `image-registry.openshift-image-registry.svc:5000/opendatahub/${imageName}:${tagName}`,
74+
lastImageSelection: 'jupyter-datascience-notebook',
75+
});
76+
const images = [
77+
mockImageStreamK8sResource({
78+
imageTag:
79+
'quay.io/opendatahub/notebooks@sha256:a138838e1c9acd7708462e420bf939e03296b97e9cf6c0aa0fd9a5d20361ab75',
80+
tagName,
81+
name: 'code-server',
82+
displayName: 'Code Server',
83+
}),
84+
mockImageStreamK8sResource({
85+
imageTag:
86+
'quay.io/opendatahub/notebooks@sha256:a138838e1c9acd7708462e420bf939e03296b97e9cf6c0aa0fd9a5d20361ab75',
87+
tagName,
88+
name: imageName,
89+
displayName,
90+
}),
91+
];
92+
const result = getNotebookImageData(notebook, images);
93+
expect(result?.imageDisplayName).toBe(displayName);
94+
});
95+
2296
it('should return image data when image stream exists and image version does not exist', () => {
2397
const notebook = mockNotebookK8sResource({
2498
image:

frontend/src/pages/projects/screens/detail/notebooks/useNotebookImageData.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,23 @@ export const getNotebookImageData = (
2323
};
2424
}
2525

26-
const [, versionName] = imageTag;
27-
const imageStream = images.find((image) =>
28-
image.spec.tags
29-
? image.spec.tags.find(
30-
(version) => version.name === versionName || version.from?.name === container.image,
31-
)
32-
: false,
33-
);
26+
const [imageName, versionName] = imageTag;
27+
const [lastImageSelectionName] =
28+
notebook.metadata.annotations?.['notebooks.opendatahub.io/last-image-selection']?.split(':') ??
29+
[];
30+
31+
// Fallback for non internal registry clusters
32+
const imageStream =
33+
images.find((image) => image.metadata.name === imageName) ||
34+
images.find((image) =>
35+
image.spec.tags
36+
? image.spec.tags.find(
37+
(version) =>
38+
version.from?.name === container.image &&
39+
image.metadata.name === lastImageSelectionName,
40+
)
41+
: false,
42+
);
3443

3544
// if the image stream is not found, consider it deleted
3645
if (!imageStream) {

0 commit comments

Comments
 (0)