Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update jupyter & ds projects to hide outdated images #2158

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions backend/src/routes/api/images/imageUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ const getTagInfo = (imageStream: ImageStream): ImageTagInfo[] => {
if (!checkTagExistence(tag, imageStream)) {
return; //Skip tag
}
if (tagAnnotations[IMAGE_ANNOTATIONS.OUTDATED]) {
return; // tag is outdated - we want to keep it around for existing notebooks, not for new ones
}

//TODO: add build status
const tagInfo: ImageTagInfo = {
Expand Down
1 change: 1 addition & 0 deletions backend/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const IMAGE_ANNOTATIONS = {
DEPENDENCIES: 'opendatahub.io/notebook-python-dependencies',
IMAGE_ORDER: 'opendatahub.io/notebook-image-order',
RECOMMENDED: 'opendatahub.io/workbench-image-recommended',
OUTDATED: 'opendatahub.io/image-tag-outdated',
};
export const blankDashboardCR: DashboardConfig = {
apiVersion: 'opendatahub.io/v1alpha',
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/__mocks__/mockImageStreamK8sResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const mockImageStreamK8sResource = ({
displayName = 'Test Image',
opts = {},
}: MockResourceConfigType): ImageStreamKind =>
_.merge(
_.mergeWith(
{
apiVersion: 'image.openshift.io/v1',
kind: 'ImageStream',
Expand Down Expand Up @@ -81,4 +81,8 @@ export const mockImageStreamK8sResource = ({
},
} as ImageStreamKind,
opts,
// Make sure tags can be overridden
(defaultValue, optsValue) =>
// Allow for emptying the array
Array.isArray(optsValue) && optsValue.length === 0 ? [] : undefined,
);
1 change: 1 addition & 0 deletions frontend/src/k8sTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ type ImageStreamSpecTagAnnotations = Partial<{
'opendatahub.io/notebook-software': string;
'opendatahub.io/workbench-image-recommended': string;
'opendatahub.io/default-image': string;
'opendatahub.io/image-tag-outdated': string;
}>;

export type NotebookAnnotations = Partial<{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { AWS_KEYS } from '~/pages/projects/dataConnections/const';
import { isAWSValid } from '~/pages/projects/screens/spawner/spawnerUtils';
import {
getExistingVersionsForImageStream,
isAWSValid,
} from '~/pages/projects/screens/spawner/spawnerUtils';
import { EnvVariableDataEntry } from '~/pages/projects/types';
import { mockImageStreamK8sResource } from '~/__mocks__/mockImageStreamK8sResource';
import { IMAGE_ANNOTATIONS } from '~/pages/projects/screens/spawner/const';

describe('isAWSValid', () => {
const getMockAWSData = ({
Expand Down Expand Up @@ -67,3 +72,66 @@ describe('isAWSValid', () => {
);
});
});

describe('getExistingVersionsForImageStream', () => {
it('should handle no image tags', () => {
const imageStream = mockImageStreamK8sResource({
opts: { spec: { tags: [] }, status: { tags: [] } },
});
expect(getExistingVersionsForImageStream(imageStream)).toHaveLength(0);
});

it('should return the only default value', () => {
expect(getExistingVersionsForImageStream(mockImageStreamK8sResource({}))).toHaveLength(1);
});

it('should exclude the outdated items', () => {
// Override the first value
const imageStream = mockImageStreamK8sResource({
opts: { spec: { tags: [{ annotations: { [IMAGE_ANNOTATIONS.OUTDATED]: 'true' } }] } },
});
expect(getExistingVersionsForImageStream(imageStream)).toHaveLength(0);

// Add an outdated 2nd value
const imageStream2 = mockImageStreamK8sResource({
opts: {
spec: {
tags: [{}, { name: 'test', annotations: { [IMAGE_ANNOTATIONS.OUTDATED]: 'true' } }],
},
},
});
expect(getExistingVersionsForImageStream(imageStream2)).toHaveLength(1);
});

it('should exclude removed tags', () => {
const imageStream = mockImageStreamK8sResource({
opts: {
spec: {
tags: [{ name: 'not-the-available-tag' }],
},
},
});
expect(getExistingVersionsForImageStream(imageStream)).toHaveLength(0);
});

it('should exclude removed tags & outdated ones', () => {
const imageStream = mockImageStreamK8sResource({
opts: {
spec: {
tags: [
{},
{ name: 'not-the-available-tag' },
{ name: 'should-be-included' },
{ name: 'outdated', annotations: { [IMAGE_ANNOTATIONS.OUTDATED]: 'true' } },
],
},
status: {
tags: [{ tag: 'should-be-included' }, { tag: 'outdated' }],
},
},
});
const result = getExistingVersionsForImageStream(imageStream);
expect(result).toHaveLength(1);
expect(result[0]).toEqual({ name: 'should-be-included' });
});
});
2 changes: 2 additions & 0 deletions frontend/src/pages/projects/screens/spawner/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const ScrollableSelectorID = 'workbench-spawner-page';
export const FAILED_PHASES = [BUILD_PHASE.ERROR, BUILD_PHASE.FAILED];
export const PENDING_PHASES = [BUILD_PHASE.NEW, BUILD_PHASE.PENDING, BUILD_PHASE.CANCELLED];

// TODO: Convert to enum
export const IMAGE_ANNOTATIONS = {
DESC: 'opendatahub.io/notebook-image-desc' as const,
DISP_NAME: 'opendatahub.io/notebook-image-name' as const,
Expand All @@ -24,6 +25,7 @@ export const IMAGE_ANNOTATIONS = {
DEPENDENCIES: 'opendatahub.io/notebook-python-dependencies' as const,
IMAGE_ORDER: 'opendatahub.io/notebook-image-order' as const,
RECOMMENDED: 'opendatahub.io/workbench-image-recommended' as const,
OUTDATED: 'opendatahub.io/image-tag-outdated' as const,
};

export const DEFAULT_NOTEBOOK_SIZES = [
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/pages/projects/screens/spawner/spawnerUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,14 +199,19 @@ export const getImageVersionSoftwareString = (imageVersion: ImageStreamSpecTagTy
return softwareString.join(', ');
};

const isOutdated = (version: ImageStreamSpecTagType): boolean =>
!!version.annotations?.[IMAGE_ANNOTATIONS.OUTDATED];

/**
* Get all the `imageStream.spec.tags` and filter the ones exists in `imageStream.status.tags`
*/
export const getExistingVersionsForImageStream = (
imageStream: ImageStreamKind,
): ImageStreamSpecTagType[] => {
const allVersions = imageStream.spec.tags || [];
return allVersions.filter((version) => checkVersionExistence(imageStream, version));
return allVersions
.filter((version) => !isOutdated(version))
.filter((version) => checkVersionExistence(imageStream, version));
};

/**
Expand Down
Loading