fix: container name in add worker

This commit is contained in:
jialin
2025-12-17 14:59:07 +08:00
parent 6968f9fa6b
commit bd46fcdc75
22 changed files with 332 additions and 207 deletions
@@ -7,6 +7,8 @@ type ViewModalProps = {
workerIP?: string;
modelDir?: string;
cacheDir?: string;
containerName?: string;
gpustackDataVolume?: string;
registrationInfo: {
token: string;
image: string;
@@ -19,7 +21,9 @@ const AddWorkerCommand: React.FC<ViewModalProps> = ({
workerIP,
modelDir,
cacheDir,
currentGPU
currentGPU,
containerName,
gpustackDataVolume
}) => {
const code = React.useMemo(() => {
const commandCode = addWorkerGuide['all'];
@@ -31,13 +35,23 @@ const AddWorkerCommand: React.FC<ViewModalProps> = ({
workerIP: workerIP,
modelDir: modelDir,
cacheDir: cacheDir,
containerName: containerName,
gpustackDataVolume: gpustackDataVolume,
image: registrationInfo.image,
token: registrationInfo.token || '${token}'
})
?.trim()
.replace(/\s+$/gm, '')
.replace(/\\+$/, '');
}, [registrationInfo, currentGPU, workerIP, modelDir, cacheDir]);
}, [
registrationInfo,
currentGPU,
workerIP,
modelDir,
cacheDir,
containerName,
gpustackDataVolume
]);
return (
<HighlightCode
@@ -51,6 +51,14 @@ export interface SummaryDataKeys {
ip: string;
required: boolean;
};
containerNameConfig: {
enabled: boolean;
name: string;
};
gpustackDataVolumeConfig: {
enabled: boolean;
path: string;
};
}
export type SummaryDataMap = {
@@ -25,6 +25,15 @@ const DockerRunCommand = () => {
enable: false,
path: ''
};
const containerNameConfig = summary.get('containerNameConfig') || {
enable: false,
name: ''
};
const gpustackDataVolumeConfig = summary.get('gpustackDataVolumeConfig') || {
enable: false,
path: ''
};
const currentGPU = summary.get('currentGPU') || '';
const stepIndex = stepList.indexOf(StepNamesMap.RunCommand) + 1;
@@ -56,6 +65,12 @@ const DockerRunCommand = () => {
workerIP={workerIPConfig.enable ? workerIPConfig.ip : ''}
modelDir={modelDirConfig.enable ? modelDirConfig.path : ''}
cacheDir={cacheDirConfig.enable ? cacheDirConfig.path : ''}
containerName={
containerNameConfig.enable ? containerNameConfig.name : ''
}
gpustackDataVolume={
gpustackDataVolumeConfig.enable ? gpustackDataVolumeConfig.path : ''
}
currentGPU={currentGPU}
/>
</StepCollapse>
@@ -96,6 +96,16 @@ const SpecifyArguments = () => {
path: ''
};
const containerNameConfig = summary.get('containerNameConfig') || {
enable: false,
name: ''
};
const gpustackDataVolumeConfig = summary.get('gpustackDataVolumeConfig') || {
enable: false,
path: ''
};
const setWorkerIPConfig = (config: {
enable: boolean;
ip?: string;
@@ -138,10 +148,16 @@ const SpecifyArguments = () => {
const unregisterWorkerIP = registerField('workerIPConfig');
const unregisterModelDir = registerField('modelDirConfig');
const unregisterCacheDir = registerField('cacheDirConfig');
const unregisterContainerName = registerField('containerNameConfig');
const unregisterGpustackDataVolume = registerField(
'gpustackDataVolumeConfig'
);
return () => {
unregisterWorkerIP();
unregisterModelDir();
unregisterCacheDir();
unregisterContainerName();
unregisterGpustackDataVolume();
};
}, []);
@@ -161,6 +177,16 @@ const SpecifyArguments = () => {
enable: false,
path: ''
});
updateField('containerNameConfig', {
enable: false,
name: ''
});
updateField('gpustackDataVolumeConfig', {
enable: false,
path: ''
});
}, []);
return (
@@ -246,6 +272,60 @@ const SpecifyArguments = () => {
)
}
></SwitchSetting>
{/* container name config */}
<SwitchSetting
label={intl.formatMessage({ id: 'clusters.addworker.containerName' })}
tips={intl.formatMessage({
id: 'clusters.addworker.containerName.tips'
})}
placeholder={intl.formatMessage(
{
id: 'common.help.default'
},
{ content: 'gpustack-worker' }
)}
checked={containerNameConfig.enable}
value={containerNameConfig.name}
onChange={(checked) =>
updateField('containerNameConfig', {
...containerNameConfig,
enable: checked
})
}
onInputChange={(value) =>
updateField('containerNameConfig', {
...containerNameConfig,
name: value
})
}
></SwitchSetting>
{/* gpustack data volume config */}
<SwitchSetting
label={intl.formatMessage({ id: 'clusters.addworker.dataVolume' })}
tips={intl.formatMessage({
id: 'clusters.addworker.dataVolume.tips'
})}
placeholder={intl.formatMessage(
{
id: 'common.help.default'
},
{ content: 'gpustack-data' }
)}
checked={gpustackDataVolumeConfig.enable}
value={gpustackDataVolumeConfig.path}
onChange={(checked) =>
updateField('gpustackDataVolumeConfig', {
...gpustackDataVolumeConfig,
enable: checked
})
}
onInputChange={(value) =>
updateField('gpustackDataVolumeConfig', {
...gpustackDataVolumeConfig,
path: value
})
}
></SwitchSetting>
{/* model directory config */}
<SwitchSetting
label={intl.formatMessage({ id: 'clusters.addworker.extraVolume' })}
@@ -5,10 +5,77 @@ import {
} from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import React from 'react';
import styled from 'styled-components';
import { useAddWorkerContext } from './add-worker-context';
import { StepNamesMap } from './config';
import { ConfigWrapper, Title } from './constainers';
interface DataItemProps {
enable: boolean;
value: string;
required?: boolean;
label: string;
tips?: string;
}
const DataItemWrapper = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
.label {
color: var(--ant-color-text);
}
.value {
display: flex;
align-items: center;
}
`;
const DataItem: React.FC<DataItemProps> = ({
enable,
value,
required,
label,
tips
}) => {
return (
<DataItemWrapper>
<span className="label">{label}:</span>
<span className="value">
<span>{enable && value ? value : ''}</span>
{tips}
{(!value || !enable) && !required && (
<StopOutlined
style={{
color: 'var(--ant-color-text-tertiary)'
}}
/>
)}
{((enable && value) || (required && !enable)) && (
<CheckCircleOutlined
style={{
color: 'var(--ant-color-success)',
marginLeft: 4
}}
/>
)}
{enable && !value && required && (
<>
<WarningOutlined
style={{
color: 'var(--ant-color-warning)',
marginLeft: 4
}}
/>
</>
)}
</span>
</DataItemWrapper>
);
};
const SummaryData: React.FC = () => {
const intl = useIntl();
const { summary, stepList } = useAddWorkerContext();
@@ -32,6 +99,16 @@ const SummaryData: React.FC = () => {
path: ''
};
const containerNameConfig = summary.get('containerNameConfig') || {
enable: false,
name: ''
};
const gpustackDataVolumeConfig = summary.get('gpustackDataVolumeConfig') || {
enable: false,
path: ''
};
return (
<ConfigWrapper>
<Title>
@@ -39,127 +116,56 @@ const SummaryData: React.FC = () => {
</Title>
<div className="config-content">
{stepList.includes(StepNamesMap.SelectCluster) && (
<div className="item">
<span className="label">
{intl.formatMessage({ id: 'clusters.title' })}:
</span>
<span className="value">
{clusterName}
{clusterName ? (
<CheckCircleOutlined
style={{
color: 'var(--ant-color-success)',
marginLeft: 4
}}
/>
) : (
<WarningOutlined
style={{
color: 'var(--ant-color-warning)',
marginLeft: 4
}}
/>
)}
</span>
</div>
<DataItem
value={clusterName}
enable={true}
label={intl.formatMessage({ id: 'clusters.title' })}
></DataItem>
)}
<div className="item">
<span className="label">
{intl.formatMessage({ id: 'clusters.addworker.gpuVendor' })}:
</span>
<span className="value">
{/* for checked style */}
{workerCommand.label}
<CheckCircleOutlined
style={{
color: 'var(--ant-color-success)',
marginLeft: 4
}}
/>
</span>
</div>
<div className="item">
<span className="label">
{intl.formatMessage({ id: 'clusters.addworker.workerIP' })}:
</span>
<span className="value">
{/* for invalidate style */}
{workerIPConfig.enable
<DataItem
label={intl.formatMessage({ id: 'clusters.addworker.gpuVendor' })}
enable={true}
value={workerCommand.label}
></DataItem>
<DataItem
label={intl.formatMessage({ id: 'clusters.addworker.workerIP' })}
tips={
workerIPConfig.enable
? workerIPConfig.ip
? workerIPConfig.ip
: intl.formatMessage({ id: 'clusters.addworker.notSpecified' })
: intl.formatMessage({ id: 'clusters.addworker.autoDetect' })}
: intl.formatMessage({ id: 'clusters.addworker.autoDetect' })
}
enable={workerIPConfig.enable}
value={workerIPConfig.ip}
required={true}
></DataItem>
{workerIPConfig.enable && !workerIPConfig.ip && (
<WarningOutlined
style={{
color: 'var(--ant-color-warning)',
marginLeft: 4
}}
/>
)}
{(!workerIPConfig.enable || workerIPConfig.ip) && (
<CheckCircleOutlined
style={{
color: 'var(--ant-color-success)',
marginLeft: 4
}}
/>
)}
</span>
</div>
<div className="item">
<span className="label">
{intl.formatMessage({ id: 'clusters.addworker.extraVolume' })}:
</span>
<span className="value">
{modelDirConfig.enable && modelDirConfig.path
? modelDirConfig.path
: ''}
{(!modelDirConfig.path || !modelDirConfig.enable) && (
<StopOutlined
style={{
color: 'var(--ant-color-text-tertiary)'
}}
/>
)}
<DataItem
label={intl.formatMessage({ id: 'clusters.addworker.containerName' })}
enable={containerNameConfig.enable}
value={containerNameConfig.name}
></DataItem>
{modelDirConfig.enable && modelDirConfig.path && (
<CheckCircleOutlined
style={{
color: 'var(--ant-color-success)',
marginLeft: 4
}}
/>
)}
</span>
</div>
<div className="item">
<span className="label">
{intl.formatMessage({ id: 'clusters.addworker.cacheVolume' })}:
</span>
<span className="value">
{cacheDirConfig.enable && cacheDirConfig.path
? cacheDirConfig.path
: ''}
{(!cacheDirConfig.path || !cacheDirConfig.enable) && (
<StopOutlined
style={{
color: 'var(--ant-color-text-tertiary)'
}}
/>
)}
<DataItem
label={intl.formatMessage({ id: 'clusters.addworker.dataVolume' })}
enable={gpustackDataVolumeConfig.enable}
value={gpustackDataVolumeConfig.path}
></DataItem>
{cacheDirConfig.enable && cacheDirConfig.path && (
<CheckCircleOutlined
style={{
color: 'var(--ant-color-success)',
marginLeft: 4
}}
/>
)}
</span>
</div>
<DataItem
label={intl.formatMessage({ id: 'clusters.addworker.extraVolume' })}
enable={modelDirConfig.enable}
value={modelDirConfig.path}
></DataItem>
<DataItem
label={intl.formatMessage({ id: 'clusters.addworker.cacheVolume' })}
enable={cacheDirConfig.enable}
value={cacheDirConfig.path}
></DataItem>
</div>
</ConfigWrapper>
);