Skip to content

Commit

Permalink
refactor: session launcher image parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
agatha197 authored and yomybaby committed Nov 1, 2024
1 parent 3982bf8 commit d2b153b
Show file tree
Hide file tree
Showing 28 changed files with 345 additions and 111 deletions.
2 changes: 1 addition & 1 deletion react/src/components/CustomizedImageList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
SettingOutlined,
} from '@ant-design/icons';
import { useLocalStorageState } from 'ahooks';
import { App, Button, Popconfirm, Table, theme, Typography } from 'antd';
import { App, Button, Input, Popconfirm, Table, theme, Typography } from 'antd';
import { AnyObject } from 'antd/es/_util/type';
import { ColumnsType, ColumnType } from 'antd/es/table';
import graphql from 'babel-plugin-relay/macro';
Expand Down
2 changes: 1 addition & 1 deletion react/src/components/EnvVarFormList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export function isSensitiveEnv(key: string) {
}

export function sanitizeSensitiveEnv(envs: EnvVarFormListValue[]) {
return envs.map((env) => {
return _.map(envs, (env) => {
if (env && isSensitiveEnv(env.variable)) {
return { ...env, value: '' };
}
Expand Down
150 changes: 115 additions & 35 deletions react/src/components/ImageEnvironmentSelectFormItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ const ImageEnvironmentSelectFormItems: React.FC<
const [environmentSearch, setEnvironmentSearch] = useState('');
const [versionSearch, setVersionSearch] = useState('');
const { t } = useTranslation();
const [metadata, { getImageMeta }] = useBackendAIImageMetaData();
const [metadata, { getImageMeta, tagAlias }] = useBackendAIImageMetaData();
const { token } = theme.useToken();
const { isDarkMode } = useThemeMode();

Expand Down Expand Up @@ -128,7 +128,13 @@ const ImageEnvironmentSelectFormItems: React.FC<
key
value
}
namespace @since(version: "24.09.1.")
namespace @since(version: "24.09.1")
base_image_name @since(version: "24.09.1")
tags @since(version: "24.09.1") {
key
value
}
version @since(version: "24.09.1")
}
}
`,
Expand Down Expand Up @@ -498,7 +504,7 @@ const ImageEnvironmentSelectFormItems: React.FC<
}}
/>
<TextHighlighter keyword={environmentSearch}>
{environmentGroup.displayName}
{tagAlias(environmentGroup.displayName)}
</TextHighlighter>
</Flex>
<Flex
Expand Down Expand Up @@ -577,13 +583,25 @@ const ImageEnvironmentSelectFormItems: React.FC<
paddingLeft: token.paddingSM,
}}
>
{t('session.launcher.Version')}
<Divider type="vertical" />
{t('session.launcher.Base')}
<Divider type="vertical" />
{t('session.launcher.Architecture')}
<Divider type="vertical" />
{t('session.launcher.Requirements')}
{supportExtendedImageInfo ? (
<>
{t('session.launcher.Version')}
<Divider type="vertical" />
{t('session.launcher.Architecture')}
<Divider type="vertical" />
{t('session.launcher.Tags')}
</>
) : (
<>
{t('session.launcher.Version')}
<Divider type="vertical" />
{t('session.launcher.Base')}
<Divider type="vertical" />
{t('session.launcher.Architecture')}
<Divider type="vertical" />
{t('session.launcher.Requirements')}
</>
)}
</Flex>
<Divider style={{ margin: '8px 0' }} />
{menu}
Expand All @@ -602,18 +620,21 @@ const ImageEnvironmentSelectFormItems: React.FC<
'-',
) || ['', '', ''];

let tagAlias = metadata?.tagAlias[tag];
if (!tagAlias) {
let metadataTagAlias = metadata?.tagAlias[tag];
if (!metadataTagAlias) {
for (const [key, replaceString] of Object.entries(
metadata?.tagReplace || {},
)) {
const pattern = new RegExp(key);
if (pattern.test(tag)) {
tagAlias = tag?.replace(pattern, replaceString);
metadataTagAlias = tag?.replace(
pattern,
replaceString,
);
}
}
if (!tagAlias) {
tagAlias = tag;
if (!metadataTagAlias) {
metadataTagAlias = tag;
}
}

Expand Down Expand Up @@ -695,39 +716,98 @@ const ImageEnvironmentSelectFormItems: React.FC<
value={getImageFullName(image)}
filterValue={[
version,
tagAlias,
metadataTagAlias,
image?.architecture,
...extraFilterValues,
].join('\t')}
>
<Flex direction="row" justify="between">
{supportExtendedImageInfo ? (
<Flex direction="row">
<TextHighlighter keyword={versionSearch}>
{version}
</TextHighlighter>
<Divider type="vertical" />
<TextHighlighter keyword={versionSearch}>
{tagAlias}
{image?.version}
</TextHighlighter>
<Divider type="vertical" />
<TextHighlighter keyword={versionSearch}>
{image?.architecture}
</TextHighlighter>
<Divider type="vertical" />
<Flex direction="row" align="start">
{/* TODO: replace this with AliasedImageDoubleTags after image list query with ImageNode is implemented. */}
{_.map(
image?.tags,
(tag: { key: string; value: string }) => {
const isCustomized = _.includes(
tag.key,
'customized_',
);
const tagValue = isCustomized
? _.find(image?.labels, {
key: 'ai.backend.customized-image.name',
})?.value
: tag.value;
return (
<DoubleTag
key={tag.key}
values={[
{
label: (
<TextHighlighter
keyword={versionSearch}
key={tag.key}
>
{tagAlias(tag.key)}
</TextHighlighter>
),
color: isCustomized ? 'cyan' : 'blue',
},
{
label: (
<TextHighlighter
keyword={versionSearch}
key={tagValue}
>
{tagValue}
</TextHighlighter>
),
color: isCustomized ? 'cyan' : 'blue',
},
]}
/>
);
},
)}
</Flex>
</Flex>
<Flex
direction="row"
// set specific class name to handle flex wrap using css
className={
isDarkMode ? 'tag-wrap-dark' : 'tag-wrap-light'
}
style={{
marginLeft: token.marginXS,
flexShrink: 1,
}}
>
{requirementTags || '-'}
) : (
<Flex direction="row" justify="between">
<Flex direction="row">
<TextHighlighter keyword={versionSearch}>
{version}
</TextHighlighter>
<Divider type="vertical" />
<TextHighlighter keyword={versionSearch}>
{metadataTagAlias}
</TextHighlighter>
<Divider type="vertical" />
<TextHighlighter keyword={versionSearch}>
{image?.architecture}
</TextHighlighter>
</Flex>
<Flex
direction="row"
// set specific class name to handle flex wrap using css
className={
isDarkMode ? 'tag-wrap-dark' : 'tag-wrap-light'
}
style={{
marginLeft: token.marginXS,
flexShrink: 1,
}}
>
{requirementTags || '-'}
</Flex>
</Flex>
</Flex>
)}
</Select.Option>
);
},
Expand Down
1 change: 1 addition & 0 deletions react/src/components/ImageList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ const ImageList: React.FC<{ style?: React.CSSProperties }> = ({ style }) => {
// highlightKeyword={imageSearch}
// />
<Flex direction="row" align="start">
{/* TODO: replace this with AliasedImageDoubleTags after image list query with ImageNode is implemented. */}
{_.map(text, (tag: { key: string; value: string }) => {
const isCustomized = _.includes(tag.key, 'customized_');
const tagValue = isCustomized
Expand Down
3 changes: 3 additions & 0 deletions react/src/components/ResourceAllocationFormItems.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ describe('getAllocatablePresetNames', () => {
registry: 'registry1',
tag: 'tag1',
resource_limits: [{ key: 'cuda.shares', min: '1', max: '1' }],
base_image_name: undefined,
tags: undefined,
version: undefined,
};

it('should return presets when currentImage has accelerator limits', () => {
Expand Down
3 changes: 3 additions & 0 deletions react/src/hooks/useBackendAIImageMetaData.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ describe('useBackendAIImageMetaData', () => {
value: 'NVIDIA CORPORATION <[email protected]>',
},
],
base_image_name: undefined,
tags: undefined,
version: undefined,
}) || '',
);
expect(key).toBe('training');
Expand Down
Loading

0 comments on commit d2b153b

Please sign in to comment.