fix: container name in add worker
This commit is contained in:
@@ -164,4 +164,4 @@ const AlertInfo: React.FC<AlertInfoProps> = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(AlertInfo);
|
||||
export default AlertInfo;
|
||||
|
||||
@@ -92,5 +92,11 @@ Same applies to the <span class="bold-text">/opt/dtk</span> directory.`,
|
||||
'clusters.addworker.message.success':
|
||||
'{count} workers have been added to the cluster.',
|
||||
'clusters.create.serverUrl': 'Server URL',
|
||||
'clusters.create.workerConfig': 'Worker Configuration'
|
||||
'clusters.create.workerConfig': 'Worker Configuration',
|
||||
'clusters.addworker.containerName': 'Worker Container Name',
|
||||
'clusters.addworker.containerName.tips':
|
||||
'Specify a name for the worker container.',
|
||||
'clusters.addworker.dataVolume': 'GPUStack Data Volume',
|
||||
'clusters.addworker.dataVolume.tips':
|
||||
'Specify a data storage path for GPUStack.'
|
||||
};
|
||||
|
||||
@@ -270,5 +270,6 @@ export default {
|
||||
'Only designated users can access the model.',
|
||||
'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.`,
|
||||
'models.catalog.nogpus.tips':
|
||||
'No compatible GPUs are available in the selected cluster for this model.'
|
||||
'No compatible GPUs are available in the selected cluster for this model.',
|
||||
'models.form.modelfile.notfound': `The model file path you specified does not exist on the GPUStack server. It's recommended to place the model file at the same path on both the GPUStack server and GPUStack workers. This helps GPUStack make better decisions.`
|
||||
};
|
||||
|
||||
@@ -19,12 +19,12 @@ export default {
|
||||
'users.form.currentpassword': 'Current Password',
|
||||
'users.form.updatepassword': 'Modify Password',
|
||||
'users.form.rule.password':
|
||||
'Contains uppercase and lowercase letters, numbers, and special characters(!@#$%^&*_+), 6 to 12 characters in length, no spaces allowed.',
|
||||
'Contains uppercase and lowercase letters, numbers, and special characters(!@#$%^&*_+), 6 to 32 characters in length, no spaces allowed.',
|
||||
'users.password.uppcase': 'At least one uppercase letter',
|
||||
'users.password.lowercase': 'At least one lowercase letter',
|
||||
'users.password.number': 'At least one number',
|
||||
'users.password.special': 'At least one special character',
|
||||
'users.password.length': 'Length between 6 and 12 characters',
|
||||
'users.password.length': 'Length between 6 and 32 characters',
|
||||
'users.password.modify.title': 'Modify Password',
|
||||
'users.password.modify.description':
|
||||
"For your account's security, please change your initial password.",
|
||||
|
||||
@@ -92,7 +92,13 @@ Same applies to the <span class="bold-text">/opt/dtk</span> directory.`,
|
||||
'clusters.addworker.message.success':
|
||||
'{count} workers have been added to the cluster.',
|
||||
'clusters.create.serverUrl': 'Server URL',
|
||||
'clusters.create.workerConfig': 'Worker Configuration'
|
||||
'clusters.create.workerConfig': 'Worker Configuration',
|
||||
'clusters.addworker.containerName': 'Worker Container Name',
|
||||
'clusters.addworker.containerName.tips':
|
||||
'Specify a name for the worker container.',
|
||||
'clusters.addworker.dataVolume': 'GPUStack Data Volume',
|
||||
'clusters.addworker.dataVolume.tips':
|
||||
'Specify a data storage path for GPUStack.'
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
@@ -172,4 +178,8 @@ Same applies to the <span class="bold-text">/opt/dtk</span> directory.`,
|
||||
// 74. 'clusters.addworker.message.success': '{count} workers have been added to the cluster.',
|
||||
// 75. 'clusters.create.serverUrl': 'Server URL',
|
||||
// 76. 'clusters.create.workerConfig': 'Worker Configuration'
|
||||
// 75. 'clusters.addworker.containerName': 'Worker Container Name',
|
||||
// 76. 'clusters.addworker.containerName.tips':'Specify a name for the worker container.',
|
||||
// 77. 'clusters.addworker.dataVolume': 'GPUStack Data Volume',
|
||||
// 78. 'clusters.addworker.dataVolume.tips': 'Specify a data storage path for GPUStack.'
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -270,7 +270,8 @@ export default {
|
||||
'Only designated users can access the model.',
|
||||
'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.`,
|
||||
'models.catalog.nogpus.tips':
|
||||
'No compatible GPUs are available in the selected cluster for this model.'
|
||||
'No compatible GPUs are available in the selected cluster for this model.',
|
||||
'models.form.modelfile.notfound': `The model file path you specified does not exist on the GPUStack server. It's recommended to place the model file at the same path on both the GPUStack server and GPUStack workers. This helps GPUStack make better decisions.`
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
@@ -363,5 +364,6 @@ export default {
|
||||
// 70. 'models.accessSettings.authed.tips': 'Accessible to all authenticated platform users.',
|
||||
// 71.'models.accessSettings.allowedUsers.tips': 'Only designated users can access the model.',
|
||||
// 72. 'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.`,
|
||||
// 73. 'models.catalog.nogpus.tips': 'No compatible GPUs are available in the selected cluster for this model.'
|
||||
// 73. 'models.catalog.nogpus.tips': 'No compatible GPUs are available in the selected cluster for this model.',
|
||||
// 74. 'models.form.modelfile.notfound': `The model file path you specified does not exist on the GPUStack server. It's recommended to place the model file at the same path on both the GPUStack server and GPUStack workers. This helps GPUStack make better decisions.`
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -20,12 +20,12 @@ export default {
|
||||
'users.form.currentpassword': '現在のパスワード',
|
||||
'users.form.updatepassword': 'パスワードを変更',
|
||||
'users.form.rule.password':
|
||||
'大文字と小文字、数字、特殊文字(!@#$%^&*_+)を含む6〜12文字で、スペースは使用できません。',
|
||||
'大文字と小文字、数字、特殊文字(!@#$%^&*_+)を含む6〜32文字で、スペースは使用できません。',
|
||||
'users.password.uppcase': '少なくとも1つの大文字を含む',
|
||||
'users.password.lowercase': '少なくとも1つの小文字を含む',
|
||||
'users.password.number': '少なくとも1つの数字を含む',
|
||||
'users.password.special': '少なくとも1つの特殊文字を含む',
|
||||
'users.password.length': '6〜12文字の長さ',
|
||||
'users.password.length': '6〜32文字の長さ',
|
||||
'users.password.modify.title': 'パスワードを変更',
|
||||
'users.password.modify.description':
|
||||
'アカウントのセキュリティのため、初期パスワードを変更してください。',
|
||||
|
||||
@@ -92,7 +92,13 @@ export default {
|
||||
'clusters.addworker.message.success':
|
||||
'{count} workers have been added to the cluster.',
|
||||
'clusters.create.serverUrl': 'Server URL',
|
||||
'clusters.create.workerConfig': 'Worker Configuration'
|
||||
'clusters.create.workerConfig': 'Worker Configuration',
|
||||
'clusters.addworker.containerName': 'Worker Container Name',
|
||||
'clusters.addworker.containerName.tips':
|
||||
'Specify a name for the worker container.',
|
||||
'clusters.addworker.dataVolume': 'GPUStack Data Volume',
|
||||
'clusters.addworker.dataVolume.tips':
|
||||
'Specify a data storage path for GPUStack.'
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
@@ -103,4 +109,8 @@ export default {
|
||||
// 5. 'clusters.addworker.message.success': '{count} workers have been added to the cluster.',
|
||||
// 6. 'clusters.create.serverUrl': 'Server URL',
|
||||
// 7. 'clusters.create.workerConfig': 'Worker Configuration'
|
||||
// 6. 'clusters.addworker.containerName': 'Worker Container Name',
|
||||
// 7. 'clusters.addworker.containerName.tips':'Specify a name for the worker container.',
|
||||
// 8. 'clusters.addworker.dataVolume': 'GPUStack Data Volume',
|
||||
// 9. 'clusters.addworker.dataVolume.tips': 'Specify a data storage path for GPUStack.'
|
||||
// ================================================================
|
||||
|
||||
@@ -275,7 +275,8 @@ export default {
|
||||
'Only designated users can access the model.',
|
||||
'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.`,
|
||||
'models.catalog.nogpus.tips':
|
||||
'No compatible GPUs are available in the selected cluster for this model.'
|
||||
'No compatible GPUs are available in the selected cluster for this model.',
|
||||
'models.form.modelfile.notfound': `The model file path you specified does not exist on the GPUStack server. It's recommended to place the model file at the same path on both the GPUStack server and GPUStack workers. This helps GPUStack make better decisions.`
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
@@ -283,5 +284,6 @@ export default {
|
||||
// 2. 'models.accessSettings.authed.tips': 'Accessible to all authenticated platform users.',
|
||||
// 3. 'models.accessSettings.allowedUsers.tips': 'Only designated users can access the model.',
|
||||
// 4. 'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.`,
|
||||
// 5. 'models.catalog.nogpus.tips': 'No compatible GPUs are available in the selected cluster for this model.'
|
||||
// 5. 'models.catalog.nogpus.tips': 'No compatible GPUs are available in the selected cluster for this model.',
|
||||
// 6. 'models.form.modelfile.notfound': `The model file path you specified does not exist on the GPUStack server. It's recommended to place the model file at the same path on both the GPUStack server and GPUStack workers. This helps GPUStack make better decisions.`
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -20,12 +20,12 @@ export default {
|
||||
'users.form.currentpassword': 'Текущий пароль',
|
||||
'users.form.updatepassword': 'Изменить пароль',
|
||||
'users.form.rule.password':
|
||||
'Должен содержать заглавные и строчные буквы, цифры и спецсимволы (!@#$%^&*_+), длина 6-12 символов, без пробелов.',
|
||||
'Должен содержать заглавные и строчные буквы, цифры и спецсимволы (!@#$%^&*_+), длина 6-32 символов, без пробелов.',
|
||||
'users.password.uppcase': 'Минимум одна заглавная буква',
|
||||
'users.password.lowercase': 'Минимум одна строчная буква',
|
||||
'users.password.number': 'Минимум одна цифра',
|
||||
'users.password.special': 'Минимум один спецсимвол',
|
||||
'users.password.length': 'Длина от 6 до 12 символов',
|
||||
'users.password.length': 'Длина от 6 до 32 символов',
|
||||
'users.password.modify.title': 'Смена пароля',
|
||||
'users.password.modify.description':
|
||||
'В целях безопасности измените первоначальный пароль.',
|
||||
|
||||
@@ -90,5 +90,9 @@ export default {
|
||||
'如果 <span class="bold-text">/opt/rocm</span> 目录不存在,请创建一个指向已安装 ROCm 路径的符号链接:<span class="bold-text">ln -s /path/to/rocm /opt/rocm</span>。',
|
||||
'clusters.addworker.message.success': '已将 {count} 个工作节点添加到集群中。',
|
||||
'clusters.create.serverUrl': '服务器地址',
|
||||
'clusters.create.workerConfig': '节点配置'
|
||||
'clusters.create.workerConfig': '节点配置',
|
||||
'clusters.addworker.containerName': '节点容器名称',
|
||||
'clusters.addworker.containerName.tips': '为节点容器指定一个名称。',
|
||||
'clusters.addworker.dataVolume': 'GPUStack 数据卷',
|
||||
'clusters.addworker.dataVolume.tips': '为 GPUStack 指定数据存储路径。'
|
||||
};
|
||||
|
||||
@@ -253,5 +253,7 @@ export default {
|
||||
'models.accessSettings.authed.tips': '平台内所有已认证用户可访问。',
|
||||
'models.accessSettings.allowedUsers.tips': '仅允许选定的特定用户访问。',
|
||||
'models.form.backendVersions.tips': `如需使用更多版本,请前往{link}页面并编辑对应的后端以添加版本。`,
|
||||
'models.catalog.nogpus.tips': '所选集群中没有兼容该模型的 GPU。'
|
||||
'models.catalog.nogpus.tips': '所选集群中没有兼容该模型的 GPU。',
|
||||
'models.form.modelfile.notfound':
|
||||
'你指定的模型文件路径在 GPUStack 服务器上不存在。建议在 GPUStack 服务器和 GPUStack 节点上使用相同的模型文件路径,这有助于 GPUStack 做出更优的调度与决策。'
|
||||
};
|
||||
|
||||
@@ -19,12 +19,12 @@ export default {
|
||||
'users.form.currentpassword': '当前密码',
|
||||
'users.form.updatepassword': '修改密码',
|
||||
'users.form.rule.password':
|
||||
'包含大小写字母、数字和特殊字符(!@#$%^&*_+),6至12个字符,不允许有空格',
|
||||
'包含大小写字母、数字和特殊字符(!@#$%^&*_+),6至32个字符,不允许有空格',
|
||||
'users.password.uppcase': '至少包含一个大写字母',
|
||||
'users.password.lowercase': '至少包含一个小写字母',
|
||||
'users.password.number': '至少包含一个数字',
|
||||
'users.password.special': '至少包含一个特殊字符',
|
||||
'users.password.length': '长度在6至12个字符之间',
|
||||
'users.password.length': '长度在6至32个字符之间',
|
||||
'users.password.modify.title': '修改密码',
|
||||
'users.password.modify.description': '为了确保您的账户安全,请修改初始密码',
|
||||
'users.password.confirm': '确认新密码',
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -184,6 +184,7 @@ export interface CatalogItem {
|
||||
name: string;
|
||||
id: number;
|
||||
description: string;
|
||||
deployment_notes?: string;
|
||||
home: string;
|
||||
icon: string;
|
||||
categories: string[];
|
||||
|
||||
@@ -271,15 +271,20 @@ export const useCheckCompatibility = () => {
|
||||
// current cluster is not available, but other clusters are available
|
||||
const othersAvailable = !hasClaim && resourceClaimMap.size > 0;
|
||||
|
||||
let compatibilityMessage = compatibility_messages.join(' ');
|
||||
|
||||
compatibilityMessage = compatibilityMessage.startsWith(
|
||||
'The model file path you specified does not exist on the GPUStack server'
|
||||
)
|
||||
? intl.formatMessage({ id: 'models.form.modelfile.notfound' })
|
||||
: compatibilityMessage;
|
||||
|
||||
let msgData = {
|
||||
title:
|
||||
scheduling_messages?.length > 0
|
||||
? compatibility_messages?.join(' ')
|
||||
: '',
|
||||
title: scheduling_messages?.length > 0 ? compatibilityMessage : '',
|
||||
message:
|
||||
scheduling_messages?.length > 0
|
||||
? scheduling_messages
|
||||
: compatibility_messages?.join(' ')
|
||||
: compatibilityMessage
|
||||
};
|
||||
|
||||
if (hasClaim) {
|
||||
|
||||
@@ -29,6 +29,7 @@ export const logout = async (userInfo?: any) => {
|
||||
});
|
||||
clearStorageUserSettings();
|
||||
clearAtomStorage(userAtom);
|
||||
|
||||
if (res?.logout_url) {
|
||||
window.location.href = res.logout_url;
|
||||
}
|
||||
|
||||
@@ -129,15 +129,28 @@ export const dockerEnvCommandMap = {
|
||||
GPUsConfigs[GPUDriverMap.METAX]
|
||||
)
|
||||
};
|
||||
|
||||
interface AddWorkerCommandParams {
|
||||
server: string;
|
||||
tag: string;
|
||||
token: string;
|
||||
image: string;
|
||||
gpu: string;
|
||||
workerIP?: string;
|
||||
modelDir?: string;
|
||||
containerName?: string;
|
||||
gpustackDataVolume?: string;
|
||||
cacheDir?: string;
|
||||
}
|
||||
|
||||
const setNormalArgs = (params: any) => {
|
||||
return `CONTAINER_NAME="gpustack-worker"
|
||||
sudo docker run -d --name "\${CONTAINER_NAME}" \\
|
||||
-e "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${CONTAINER_NAME}" \\
|
||||
return `sudo docker run -d --name ${params.containerName || 'gpustack-worker'} \\
|
||||
-e "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=${params.containerName || 'gpustack-worker'}" \\
|
||||
--restart=unless-stopped \\
|
||||
--privileged \\
|
||||
--network=host \\
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \\
|
||||
--volume gpustack-data:/var/lib/gpustack \\
|
||||
--volume ${params.gpustackDataVolume || 'gpustack-data'}:/var/lib/gpustack \\
|
||||
${params.modelDir ? `--volume ${params.modelDir}:${params.modelDir} \\` : ''}
|
||||
${params.cacheDir ? `--volume ${params.cacheDir}:/var/lib/gpustack/cache \\` : ''}`;
|
||||
};
|
||||
@@ -149,18 +162,11 @@ const setImageArgs = (params: any) => {
|
||||
};
|
||||
|
||||
// avaliable for NVIDIA、MThreads
|
||||
const registerWorker = (params: {
|
||||
server: string;
|
||||
tag: string;
|
||||
token: string;
|
||||
image: string;
|
||||
gpu: string;
|
||||
workerIP?: string;
|
||||
modelDir?: string;
|
||||
}) => {
|
||||
const registerWorker = (params: AddWorkerCommandParams) => {
|
||||
const config = GPUsConfigs[params.gpu];
|
||||
const commonArgs = setNormalArgs(params);
|
||||
const imageArgs = setImageArgs(params);
|
||||
|
||||
// remove empty enter lines and trailing backslash
|
||||
return `${commonArgs}
|
||||
--runtime ${config.runtime} \\
|
||||
@@ -169,15 +175,7 @@ const registerWorker = (params: {
|
||||
};
|
||||
|
||||
// avaliable for AMD
|
||||
const registerAMDWorker = (params: {
|
||||
server: string;
|
||||
tag: string;
|
||||
token: string;
|
||||
image: string;
|
||||
gpu: string;
|
||||
workerIP?: string;
|
||||
modelDir?: string;
|
||||
}) => {
|
||||
const registerAMDWorker = (params: AddWorkerCommandParams) => {
|
||||
const config = GPUsConfigs[params.gpu];
|
||||
const commonArgs = setNormalArgs(params);
|
||||
const imageArgs = setImageArgs(params);
|
||||
@@ -190,15 +188,7 @@ const registerAMDWorker = (params: {
|
||||
};
|
||||
|
||||
// avaliable for Ascend
|
||||
const registerAscendWorker = (params: {
|
||||
server: string;
|
||||
tag: string;
|
||||
token: string;
|
||||
image: string;
|
||||
gpu: string;
|
||||
workerIP?: string;
|
||||
modelDir?: string;
|
||||
}) => {
|
||||
const registerAscendWorker = (params: AddWorkerCommandParams) => {
|
||||
const config = GPUsConfigs[params.gpu];
|
||||
const commonArgs = setNormalArgs(params);
|
||||
const imageArgs = setImageArgs(params);
|
||||
@@ -209,15 +199,7 @@ const registerAscendWorker = (params: {
|
||||
${params.workerIP ? `--advertise-address ${params.workerIP} \\` : ''}`;
|
||||
};
|
||||
|
||||
const registerHygonWorker = (params: {
|
||||
server: string;
|
||||
tag: string;
|
||||
token: string;
|
||||
image: string;
|
||||
gpu: string;
|
||||
workerIP?: string;
|
||||
modelDir?: string;
|
||||
}) => {
|
||||
const registerHygonWorker = (params: AddWorkerCommandParams) => {
|
||||
const config = GPUsConfigs[params.gpu];
|
||||
const commonArgs = setNormalArgs(params);
|
||||
const imageArgs = setImageArgs(params);
|
||||
@@ -230,15 +212,7 @@ const registerHygonWorker = (params: {
|
||||
${params.workerIP ? `--advertise-address ${params.workerIP} \\` : ''}`;
|
||||
};
|
||||
|
||||
const registerIluvatarWorker = (params: {
|
||||
server: string;
|
||||
tag: string;
|
||||
token: string;
|
||||
image: string;
|
||||
gpu: string;
|
||||
workerIP?: string;
|
||||
modelDir?: string;
|
||||
}) => {
|
||||
const registerIluvatarWorker = (params: AddWorkerCommandParams) => {
|
||||
const config = GPUsConfigs[params.gpu];
|
||||
const commonArgs = setNormalArgs(params);
|
||||
const imageArgs = setImageArgs(params);
|
||||
@@ -251,15 +225,7 @@ const registerIluvatarWorker = (params: {
|
||||
${params.workerIP ? `--advertise-address ${params.workerIP} \\` : ''}`;
|
||||
};
|
||||
|
||||
const registerMetaXWorker = (params: {
|
||||
server: string;
|
||||
tag: string;
|
||||
token: string;
|
||||
image: string;
|
||||
gpu: string;
|
||||
workerIP?: string;
|
||||
modelDir?: string;
|
||||
}) => {
|
||||
const registerMetaXWorker = (params: AddWorkerCommandParams) => {
|
||||
const config = GPUsConfigs[params.gpu];
|
||||
const commonArgs = setNormalArgs(params);
|
||||
const imageArgs = setImageArgs(params);
|
||||
@@ -270,15 +236,7 @@ const registerMetaXWorker = (params: {
|
||||
${params.workerIP ? `--advertise-address ${params.workerIP} \\` : ''}`;
|
||||
};
|
||||
|
||||
const registerCambriconWorker = (params: {
|
||||
server: string;
|
||||
tag: string;
|
||||
token: string;
|
||||
image: string;
|
||||
gpu: string;
|
||||
workerIP?: string;
|
||||
modelDir?: string;
|
||||
}) => {
|
||||
const registerCambriconWorker = (params: AddWorkerCommandParams) => {
|
||||
const config = GPUsConfigs[params.gpu];
|
||||
const commonArgs = setNormalArgs(params);
|
||||
const imageArgs = setImageArgs(params);
|
||||
|
||||
Reference in New Issue
Block a user