chore: cluster docker provider

This commit is contained in:
jialin
2025-09-16 11:26:17 +08:00
parent 5e1a26b743
commit 336bafd6ce
21 changed files with 266 additions and 256 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ const LineChart: React.FC<ChartProps> = (props) => {
legendOptions,
gridOptions,
titleOptions,
showArea = 0.25
showArea
} = props;
const {
grid,
+4 -1
View File
@@ -2,6 +2,7 @@ import IconFont from '@/components/icon-font';
import {
ApiOutlined,
DeleteOutlined,
DockerOutlined,
DownloadOutlined,
EditOutlined,
ExperimentOutlined,
@@ -24,6 +25,7 @@ const icons = {
ApiOutlined: React.createElement(ApiOutlined),
KubernetesOutlined: React.createElement(KubernetesOutlined),
ProfileOutlined: React.createElement(ProfileOutlined),
DockerOutlined: React.createElement(DockerOutlined),
Stop: React.createElement(IconFont, { type: 'icon-stop1' }),
Play: React.createElement(IconFont, { type: 'icon-outline-play' }),
Catalog: React.createElement(IconFont, { type: 'icon-catalog' }),
@@ -41,7 +43,8 @@ const icons = {
TencentCloud: React.createElement(IconFont, { type: 'icon-tencentcloud' }),
Nvidia: React.createElement(IconFont, { type: 'icon-nvidia' }),
Ascend: React.createElement(IconFont, { type: 'icon-ascend' }),
AMD: React.createElement(IconFont, { type: 'icon-amd' })
AMD: React.createElement(IconFont, { type: 'icon-amd' }),
KubernetesFilled: React.createElement(IconFont, { type: 'icon-k8s-filled' })
};
export default icons;
+3 -2
View File
@@ -55,7 +55,8 @@ const ScrollerModal = (props: ModalProps & { maxContentHeight?: number }) => {
paddingBottom: '0'
},
body: {
padding: '0'
padding: '0',
paddingBlockEnd: props.footer ? '0' : '24px'
},
footer: props.footer
? {
@@ -71,7 +72,7 @@ const ScrollerModal = (props: ModalProps & { maxContentHeight?: number }) => {
className="overlay-scroller-wrapper"
$maxHeight={props.maxContentHeight || 500}
hidden={false}
style={{ paddingInline: 24, paddingBlockEnd: props.footer ? 0 : 24 }}
style={{ paddingInline: 24, paddingBlockEnd: 0 }}
>
{props.children}
</Wrapper>
+8 -1
View File
@@ -5,11 +5,18 @@ import { Button, Divider, Tooltip } from 'antd';
import classNames from 'classnames';
import React, { useMemo } from 'react';
import 'simplebar-react/dist/simplebar.min.css';
import styled from 'styled-components';
import CopyButton from '../copy-button';
import { TooltipOverlayScroller } from '../overlay-scroller';
import CopyStyle from './copy-btn.less';
import './index.less';
const Text = styled.span`
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
`;
const linkReg = /<a (.*?)>(.*?)<\/a>/g;
export const StatusMaps = {
transitioning: 'blue',
@@ -89,7 +96,7 @@ const StatusTag: React.FC<StatusTagProps> = ({
</>
);
}
return <span>{text}</span>;
return <Text>{text}</Text>;
};
const renderTitle = useMemo(() => {
+9
View File
@@ -0,0 +1,9 @@
export default {
'vendor.nividia': 'NVIDIA',
'vendor.ascend': 'Ascend',
'vendor.hygon': 'Hygon',
'vendor.moorthreads': 'Moore Threads',
'vendor.iluvatar': 'Iluvatar',
'vendor.metax': 'Metax',
'vendor.cambricon': 'Cambricon'
};
+9
View File
@@ -0,0 +1,9 @@
export default {
'vendor.nividia': 'NVIDIA',
'vendor.ascend': 'Ascend',
'vendor.hygon': 'Hygon',
'vendor.moorthreads': 'Moore Threads',
'vendor.iluvatar': 'Iluvatar',
'vendor.metax': 'Metax',
'vendor.cambricon': 'Cambricon'
};
+9
View File
@@ -0,0 +1,9 @@
export default {
'vendor.nividia': 'NVIDIA',
'vendor.ascend': 'Ascend',
'vendor.hygon': 'Hygon',
'vendor.moorthreads': 'Moore Threads',
'vendor.iluvatar': 'Iluvatar',
'vendor.metax': 'Metax',
'vendor.cambricon': 'Cambricon'
};
+9
View File
@@ -0,0 +1,9 @@
export default {
'vendor.nividia': '英伟达',
'vendor.ascend': '昇腾',
'vendor.hygon': '海光',
'vendor.moorthreads': '摩尔线程',
'vendor.iluvatar': '天数智芯',
'vendor.metax': '沐曦',
'vendor.cambricon': '寒武纪'
};
@@ -79,7 +79,7 @@ const ClusterCreate = () => {
cluster_id: 0
});
const [extraData, setExtraData] = useState<ClusterFormData>({
provider: ProviderValueMap.Custom
provider: ProviderValueMap.Docker
} as ClusterFormData);
const [formValues, setFormValues] = useState<Record<string, any>>({});
+19 -4
View File
@@ -8,7 +8,7 @@ import type { PageActionType } from '@/config/types';
import useExpandedRowKeys from '@/hooks/use-expanded-row-keys';
import useTableFetch from '@/hooks/use-table-fetch';
import useWatchList from '@/hooks/use-watch-list';
import AddWorker from '@/pages/resources/components/add-worker';
import AddWorker from '@/pages/cluster-management/components/add-worker';
import { PageContainer } from '@ant-design/pro-components';
import { useIntl, useNavigate, useSearchParams } from '@umijs/max';
import { useMemoizedFn } from 'ahooks';
@@ -90,17 +90,21 @@ const Credentials: React.FC = () => {
const [openAddWorker, setOpenAddWorker] = useState<{
open: boolean;
provider: ProviderType;
registrationInfo: {
token: string;
image: string;
server_url: string;
cluster_id: number;
};
}>({
open: false,
provider: null,
registrationInfo: {
token: '',
image: '',
server_url: ''
server_url: '',
cluster_id: 0
}
});
const [openAddModal, setOpenAddModal] = useState<{
@@ -204,7 +208,11 @@ const Credentials: React.FC = () => {
const data = await queryClusterToken({ id: row.id });
setOpenAddWorker({
open: true,
registrationInfo: data
provider: row.provider as ProviderType,
registrationInfo: {
...data,
cluster_id: row.id
}
});
} catch (error: any) {
message.error(error.message || 'Failed to fetch cluster token');
@@ -384,10 +392,17 @@ const Credentials: React.FC = () => {
></AddCluster>
<AddWorker
open={openAddWorker.open}
provider={openAddWorker.provider}
onCancel={() =>
setOpenAddWorker({
open: false,
registrationInfo: { token: '', image: '', server_url: '' }
provider: null,
registrationInfo: {
token: '',
image: '',
server_url: '',
cluster_id: 0
}
})
}
registrationInfo={openAddWorker.registrationInfo}
@@ -66,7 +66,7 @@ const AddWorkerStep: React.FC<AddModalProps> = ({
const [currentProvider, setCurrentProvider] = React.useState<string>('cuda');
const [workerCommand, setWorkerCommand] = React.useState<Record<string, any>>(
{
label: 'NVIDIA CUDA',
label: 'NVIDIA',
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#nvidia-cuda'
}
);
@@ -85,7 +85,7 @@ const AddWorkerStep: React.FC<AddModalProps> = ({
onSelect={handleSelectProvider}
currentProvider={currentProvider}
/>
{provider === ProviderValueMap.Custom && (
{provider === ProviderValueMap.Docker && (
<Content>
<Line></Line>
<Alert
@@ -1,20 +1,23 @@
import ScrollerModal from '@/components/scroller-modal';
import { useIntl } from '@umijs/max';
import React from 'react';
import ContainerInstall from './container-install';
import { ProviderType } from '../config';
import AddWorkerStep from './add-worker-step';
type ViewModalProps = {
open: boolean;
provider: ProviderType;
registrationInfo: {
token: string;
image: string;
server_url: string;
cluster_id: number;
};
onCancel: () => void;
};
const AddWorker: React.FC<ViewModalProps> = (props) => {
const { open, onCancel, registrationInfo } = props || {};
const { open, onCancel, registrationInfo, provider } = props || {};
const intl = useIntl();
return (
@@ -27,14 +30,14 @@ const AddWorker: React.FC<ViewModalProps> = (props) => {
closeIcon={true}
maskClosable={false}
keyboard={false}
width={700}
width={860}
style={{
top: 100
}}
maxContentHeight={450}
maxContentHeight={600}
footer={null}
>
<ContainerInstall registrationInfo={registrationInfo} />
<AddWorkerStep registrationInfo={registrationInfo} provider={provider} />
</ScrollerModal>
);
};
@@ -5,6 +5,8 @@ import styled from 'styled-components';
const { Step } = Steps;
const Wrapper = styled.div`
width: min(1200px, 100%);
margin: 0 auto;
padding-block: 30px;
background-color: var(--ant-color-bg-container);
.ant-steps-item-description {
@@ -5,7 +5,7 @@ import iluvatarWEBP from '@/assets/logo/Iluvatar.png';
import metaxLogo from '@/assets/logo/metax.png';
import moorePNG from '@/assets/logo/moore _threads.png';
import IconFont from '@/components/icon-font';
import styled from 'styled-components';
import { useIntl } from '@umijs/max';
import ProviderCatalog from './provider-catalog';
const ProviderImage = ({ src, showBg }: { src: string; showBg?: boolean }) => {
@@ -20,110 +20,6 @@ const ProviderImage = ({ src, showBg }: { src: string; showBg?: boolean }) => {
);
};
const supportedHardPlatforms = [
{
label: 'NVIDIA CUDA',
value: 'cuda',
description: '',
key: 'cuda',
locale: false,
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#nvidia-cuda',
icon: <IconFont type="icon-nvidia2" style={{ fontSize: 32 }} />
},
{
label: 'AMD ROCm',
description: '',
value: 'rocm',
key: 'rocm',
locale: false,
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#amd-rocm',
icon: (
<IconFont
type="icon-amd"
style={{ fontSize: 32, color: 'var(--ant-color-text)' }}
/>
)
},
{
label: 'Ascend CANN',
description: '',
value: 'npu',
key: 'npu',
locale: false,
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#ascend-cann',
icon: <ProviderImage src={ascendLogo} showBg />
},
{
label: 'Hygon DTK',
description: '',
value: 'dcu',
key: 'dcu',
locale: false,
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#hygon-dtk',
icon: <ProviderImage src={hyponPNG} />
},
{
label: 'Moore Threads',
description: '',
value: 'musa',
key: 'musa',
locale: false,
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#moore-threads-musa',
icon: <ProviderImage src={moorePNG} />
},
{
label: 'Iluvatar Corex',
description: '',
value: 'corex',
key: 'corex',
locale: false,
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#iluvatar-corex',
icon: <ProviderImage src={iluvatarWEBP} showBg />
},
{
label: 'Cambricon',
value: 'cambricon',
key: 'cambricon',
locale: false,
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#cambricon-mlu',
icon: <ProviderImage src={CambriconPNG} />
},
{
label: 'Metax',
value: 'metax',
key: 'metax',
locale: false,
icon: <ProviderImage src={metaxLogo} showBg />
}
];
const Header = styled.div`
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
justify-content: center;
align-self: center;
`;
const renderHeader = (item: any) => {
return (
<Header>
<span className="icon">{item.icon}</span>
<span className="label">{item.label}</span>
</Header>
);
};
const dataList = supportedHardPlatforms.map((item) => {
return {
label: renderHeader(item),
value: item.value,
key: item.key,
locale: item.locale
};
});
interface SupportedHardwareProps {
onSelect?: (provider: string, item: any) => void;
currentProvider?: string;
@@ -133,6 +29,84 @@ const SupportedHardware: React.FC<SupportedHardwareProps> = ({
onSelect,
currentProvider
}) => {
const intl = useIntl();
const supportedHardPlatforms = [
{
label: intl.formatMessage({ id: 'vendor.nividia' }),
value: 'cuda',
description: '',
key: 'cuda',
locale: false,
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#nvidia-cuda',
icon: <IconFont type="icon-nvidia2" style={{ fontSize: 32 }} />
},
{
label: 'AMD',
description: '',
value: 'rocm',
key: 'rocm',
locale: false,
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#amd-rocm',
icon: (
<IconFont
type="icon-amd"
style={{ fontSize: 32, color: 'var(--ant-color-text)' }}
/>
)
},
{
label: intl.formatMessage({ id: 'vendor.ascend' }),
description: '',
value: 'npu',
key: 'npu',
locale: false,
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#ascend-cann',
icon: <ProviderImage src={ascendLogo} showBg />
},
{
label: intl.formatMessage({ id: 'vendor.hygon' }),
description: '',
value: 'dcu',
key: 'dcu',
locale: false,
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#hygon-dtk',
icon: <ProviderImage src={hyponPNG} />
},
{
label: intl.formatMessage({ id: 'vendor.moorthreads' }),
description: '',
value: 'musa',
key: 'musa',
locale: false,
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#moore-threads-musa',
icon: <ProviderImage src={moorePNG} />
},
{
label: intl.formatMessage({ id: 'vendor.iluvatar' }),
description: '',
value: 'corex',
key: 'corex',
locale: false,
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#iluvatar-corex',
icon: <ProviderImage src={iluvatarWEBP} showBg />
},
{
label: intl.formatMessage({ id: 'vendor.cambricon' }),
value: 'cambricon',
key: 'cambricon',
locale: false,
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#cambricon-mlu',
icon: <ProviderImage src={CambriconPNG} />
},
{
label: intl.formatMessage({ id: 'vendor.metax' }),
value: 'metax',
key: 'metax',
locale: false,
icon: <ProviderImage src={metaxLogo} showBg />
}
];
return (
<ProviderCatalog
onSelect={onSelect}
+5 -5
View File
@@ -24,7 +24,7 @@ export const ClusterStatus: Record<string, StatusType> = {
export const ProviderValueMap = {
Kubernetes: 'Kubernetes',
DigitalOcean: 'DigitalOcean',
Custom: 'Custom',
Docker: 'Docker',
HuaweiCloud: 'HuaweiCloud',
AliCloud: 'AliCloud',
TencentCloud: 'TencentCloud'
@@ -35,7 +35,7 @@ export type ProviderType = keyof typeof ProviderValueMap | null | undefined;
export const ProviderLabelMap = {
[ProviderValueMap.Kubernetes]: 'Kubernetes',
[ProviderValueMap.DigitalOcean]: 'DigitalOcean',
[ProviderValueMap.Custom]: 'Custom'
[ProviderValueMap.Docker]: 'Docker'
};
export const generateRegisterCommand = (params: {
@@ -72,8 +72,8 @@ export const providerList = [
{
label: 'clusters.provider.custom',
locale: true,
value: ProviderValueMap.Custom,
key: ProviderValueMap.Custom,
value: ProviderValueMap.Docker,
key: ProviderValueMap.Docker,
icon: React.cloneElement(icons.Docker, {
style: { color: 'var(--ant-color-primary)' }
}),
@@ -158,7 +158,7 @@ export const clusterActionList = [
{
key: 'add_worker',
label: 'resources.button.create',
provider: ProviderValueMap.Custom,
provider: ProviderValueMap.Docker,
locale: true,
icon: icons.Docker
},
@@ -4,11 +4,11 @@ import { ProviderValueMap } from '.';
export default [
{
label: 'clusters.provider.custom',
locale: true,
value: ProviderValueMap.Custom,
key: ProviderValueMap.Custom,
icon: React.cloneElement(icons.Docker, {
label: 'Docker',
locale: false,
value: ProviderValueMap.Docker,
key: ProviderValueMap.Docker,
icon: React.cloneElement(icons.DockerOutlined, {
style: { color: 'var(--ant-color-primary)' }
}),
group: 'clusters.create.provider.self'
@@ -18,7 +18,7 @@ export default [
locale: false,
value: ProviderValueMap.Kubernetes,
key: ProviderValueMap.Kubernetes,
icon: React.cloneElement(icons.KubernetesOutlined, {
icon: React.cloneElement(icons.KubernetesFilled, {
style: { color: 'var(--ant-color-primary)' }
}),
group: 'clusters.create.provider.self'
@@ -77,7 +77,7 @@ export default function useStepList() {
defaultShow: false,
showForms: [],
showModules: [moduleMap.AddWorkerStep],
providers: [ProviderValueMap.Custom]
providers: [ProviderValueMap.Docker]
},
{
title: intl.formatMessage({ id: 'clusters.button.register' }),
+1 -1
View File
@@ -15,7 +15,7 @@ const renderCardItem = (data: {
const { label, value, bgColor } = data;
return (
<Card
bordered={false}
variant="borderless"
style={{ background: 'var(--color-white-1)' }}
className={styles['card-body']}
>
@@ -173,7 +173,7 @@ export const useGenerateWorkerOptions = () => {
clusterList.map((item) => ({
label: item.name,
value: item.id,
provider: item.provider,
provider: item.provider as string,
state: item.state
}))
);
@@ -202,7 +202,7 @@ export default function useFormInitialValues() {
const list = response.items.map((item) => ({
label: item.name,
value: item.id,
provider: item.provider,
provider: item.provider as string,
state: item.state
}));
setClusterList(list);