diff --git a/src/locales/en-US/clusters.ts b/src/locales/en-US/clusters.ts
index 5de8a34c..1cfdf03e 100644
--- a/src/locales/en-US/clusters.ts
+++ b/src/locales/en-US/clusters.ts
@@ -68,8 +68,12 @@ Same applies to the /opt/dtk directory.`,
'clusters.addworker.checkEnv': 'Check Environment',
'clusters.addworker.specifyArgs': 'Specify Arguments',
'clusters.addworker.runCommand': 'Run Command',
- 'clusters.addworker.specifyWorkerIP': 'Specify Worker IP',
- 'clusters.addworker.detectWorkerIP': 'Auto-detect Worker IP',
+ 'clusters.addworker.specifyWorkerIP':
+ 'Specify Worker IP {type}',
+ 'clusters.addworker.detectWorkerIP':
+ 'Auto-detect Worker IP {type}',
+ 'clusters.addworker.externalIP.tips':
+ 'Specify an external IP if the worker is in a VPC or private network.',
'clusters.addworker.enterWorkerIP': 'Enter worker IP',
'clusters.addworker.enterWorkerIP.error': 'Please enter the worker IP.',
'clusters.addworker.extraVolume': 'Additional Volume Mount',
@@ -78,7 +82,8 @@ Same applies to the /opt/dtk directory.`,
'If you want to customize the model cache directory, you can specify the path to mount it.',
'clusters.addworker.configSummary': 'Configuration Summary',
'clusters.addworker.gpuVendor': 'GPU Vendor',
- 'clusters.addworker.workerIP': 'Worker IP',
+ 'clusters.addworker.workerIP':
+ 'Worker IP {type}',
'clusters.addworker.notSpecified': 'Not Specified',
'clusters.addworker.autoDetect': 'Auto-detect',
'clusters.addworker.extraVolume.holder':
diff --git a/src/locales/ja-JP/clusters.ts b/src/locales/ja-JP/clusters.ts
index b9ba21fd..f3e39ca8 100644
--- a/src/locales/ja-JP/clusters.ts
+++ b/src/locales/ja-JP/clusters.ts
@@ -68,8 +68,12 @@ Same applies to the /opt/dtk directory.`,
'clusters.addworker.checkEnv': 'Check Environment',
'clusters.addworker.specifyArgs': 'Specify Arguments',
'clusters.addworker.runCommand': 'Run Command',
- 'clusters.addworker.specifyWorkerIP': 'Specify Worker IP',
- 'clusters.addworker.detectWorkerIP': 'Auto-detect Worker IP',
+ 'clusters.addworker.specifyWorkerIP':
+ 'Specify Worker IP {type}',
+ 'clusters.addworker.externalIP.tips':
+ 'Specify an external IP if the worker is in a VPC or private network.',
+ 'clusters.addworker.detectWorkerIP':
+ 'Auto-detect Worker IP {type}',
'clusters.addworker.enterWorkerIP': 'Enter worker IP',
'clusters.addworker.enterWorkerIP.error': 'Please enter the worker IP.',
'clusters.addworker.extraVolume': 'Additional Volume Mount',
@@ -78,7 +82,8 @@ Same applies to the /opt/dtk directory.`,
'If you want to customize the model cache directory, you can specify the path to mount it.',
'clusters.addworker.configSummary': 'Configuration Summary',
'clusters.addworker.gpuVendor': 'GPU Vendor',
- 'clusters.addworker.workerIP': 'Worker IP',
+ 'clusters.addworker.workerIP':
+ 'Worker IP {type}',
'clusters.addworker.notSpecified': 'Not Specified',
'clusters.addworker.autoDetect': 'Auto-detect',
'clusters.addworker.extraVolume.holder':
@@ -171,7 +176,7 @@ Same applies to the /opt/dtk directory.`,
// 61. 'clusters.addworker.extraVolume': 'Additional Volume Mount',
// 62. 'clusters.addworker.configSummary': 'Configuration Summary',
// 63. 'clusters.addworker.gpuVendor': 'GPU Vendor',
-// 64. 'clusters.addworker.workerIP': 'Worker IP',
+// 64. 'clusters.addworker.workerIP': 'Worker IP {type}',
// 65. 'clusters.addworker.notSpecified': 'Not Specified',
// 66. 'clusters.addworker.autoDetect': 'Auto-detect',
// 67. 'clusters.addworker.extraVolume.holder': 'e.g. /data/models (path must start with /)'
@@ -191,5 +196,6 @@ Same applies to the /opt/dtk directory.`,
// 78. 'clusters.addworker.dataVolume.tips': 'Specify a data storage path for GPUStack.',
// 79. 'clusters.table.ip.internal': 'Internal',
// 80. 'clusters.table.ip.external': 'External',
-// 81. 'clusters.form.serverUrl.tips': 'Specify the server URL accessible from your cloud provider.'
+// 81. 'clusters.form.serverUrl.tips': 'Specify the server URL accessible from your cloud provider.',
+// 82. 'clusters.addworker.externalIP.tips': 'Specify an external IP if the worker is in a VPC or private network.',
// ========== End of To-Do List ==========
diff --git a/src/locales/ru-RU/clusters.ts b/src/locales/ru-RU/clusters.ts
index b66f94a5..bd3f7b9d 100644
--- a/src/locales/ru-RU/clusters.ts
+++ b/src/locales/ru-RU/clusters.ts
@@ -68,8 +68,12 @@ export default {
'clusters.addworker.checkEnv': 'Проверить окружение',
'clusters.addworker.specifyArgs': 'Указать аргументы',
'clusters.addworker.runCommand': 'Выполнить команду',
- 'clusters.addworker.specifyWorkerIP': 'Указать IP воркера',
- 'clusters.addworker.detectWorkerIP': 'Автоопределение IP воркера',
+ 'clusters.addworker.specifyWorkerIP':
+ 'Указать IP воркера {type}',
+ 'clusters.addworker.externalIP.tips':
+ 'Specify an external IP if the worker is in a VPC or private network.',
+ 'clusters.addworker.detectWorkerIP':
+ 'Автоопределение IP воркера {type}',
'clusters.addworker.enterWorkerIP': 'Введите IP воркера',
'clusters.addworker.enterWorkerIP.error': 'Пожалуйста, введите IP воркера.',
'clusters.addworker.extraVolume': 'Дополнительное монтирование тома',
@@ -78,7 +82,8 @@ export default {
'If you want to customize the model cache directory, you can specify the path to mount it.',
'clusters.addworker.configSummary': 'Сводка конфигурации',
'clusters.addworker.gpuVendor': 'Производитель GPU',
- 'clusters.addworker.workerIP': 'IP воркера',
+ 'clusters.addworker.workerIP':
+ 'IP воркера {type}',
'clusters.addworker.notSpecified': 'Не указано',
'clusters.addworker.autoDetect': 'Автоопределение',
'clusters.addworker.extraVolume.holder':
@@ -123,4 +128,5 @@ export default {
// 10. 'clusters.table.ip.internal': 'Internal',
// 11. 'clusters.table.ip.external': 'External',
// 12. 'clusters.form.serverUrl.tips': 'Specify the server URL accessible from your cloud provider.'
+// 13. 'clusters.addworker.specifyWorkerIP': 'Specify Worker IP {type}',
// ================================================================
diff --git a/src/locales/zh-CN/clusters.ts b/src/locales/zh-CN/clusters.ts
index 324f72a9..e56a7891 100644
--- a/src/locales/zh-CN/clusters.ts
+++ b/src/locales/zh-CN/clusters.ts
@@ -66,8 +66,12 @@ export default {
'clusters.addworker.checkEnv': '检查环境',
'clusters.addworker.specifyArgs': '指定参数',
'clusters.addworker.runCommand': '运行指令',
- 'clusters.addworker.specifyWorkerIP': '指定 Worker IP',
- 'clusters.addworker.detectWorkerIP': '自动检测 Worker IP',
+ 'clusters.addworker.specifyWorkerIP':
+ '指定 Worker IP {type}',
+ 'clusters.addworker.detectWorkerIP':
+ '自动检测 Worker IP {type}',
+ 'clusters.addworker.externalIP.tips':
+ '当 worker 位于 VPC 或私有网络时,需要指定外部 IP。',
'clusters.addworker.enterWorkerIP': '输入节点 IP',
'clusters.addworker.enterWorkerIP.error': '请输入节点 IP',
'clusters.addworker.extraVolume': '额外卷挂载',
@@ -76,7 +80,8 @@ export default {
'如果你想自定义模型缓存目录,可以指定路径进行挂载。',
'clusters.addworker.configSummary': '配置摘要',
'clusters.addworker.gpuVendor': 'GPU 厂商',
- 'clusters.addworker.workerIP': '节点 IP',
+ 'clusters.addworker.workerIP':
+ '节点 IP {type}',
'clusters.addworker.notSpecified': '未指定',
'clusters.addworker.autoDetect': '自动检测',
'clusters.addworker.extraVolume.holder':
diff --git a/src/pages/cluster-management/cluster-create.tsx b/src/pages/cluster-management/cluster-create.tsx
index 35bbab31..f80f49e7 100644
--- a/src/pages/cluster-management/cluster-create.tsx
+++ b/src/pages/cluster-management/cluster-create.tsx
@@ -54,6 +54,7 @@ const ClusterCreate = () => {
image: string;
server_url: string;
cluster_id: number;
+ [key: string]: any;
}>({
token: '',
image: '',
diff --git a/src/pages/cluster-management/components/add-worker-command.tsx b/src/pages/cluster-management/components/add-worker-command.tsx
index 96e98400..95a0a17f 100644
--- a/src/pages/cluster-management/components/add-worker-command.tsx
+++ b/src/pages/cluster-management/components/add-worker-command.tsx
@@ -9,15 +9,18 @@ type ViewModalProps = {
cacheDir?: string;
containerName?: string;
gpustackDataVolume?: string;
+ advertisAddress?: string;
registrationInfo: {
token: string;
image: string;
server_url: string;
+ [key: string]: any;
};
};
const AddWorkerCommand: React.FC = ({
registrationInfo,
+ advertisAddress,
workerIP,
modelDir,
cacheDir,
@@ -29,9 +32,11 @@ const AddWorkerCommand: React.FC = ({
const commandCode = addWorkerGuide['all'];
return commandCode
?.registerWorker({
+ registrationInfo,
gpu: currentGPU || '',
server: registrationInfo.server_url || origin,
tag: '',
+ advertisAddress: advertisAddress,
workerIP: workerIP,
modelDir: modelDir,
cacheDir: cacheDir,
@@ -50,7 +55,8 @@ const AddWorkerCommand: React.FC = ({
modelDir,
cacheDir,
containerName,
- gpustackDataVolume
+ gpustackDataVolume,
+ advertisAddress
]);
return (
diff --git a/src/pages/cluster-management/components/add-worker/add-worker-step.tsx b/src/pages/cluster-management/components/add-worker/add-worker-step.tsx
index 3ca44dc7..5a0af073 100644
--- a/src/pages/cluster-management/components/add-worker/add-worker-step.tsx
+++ b/src/pages/cluster-management/components/add-worker/add-worker-step.tsx
@@ -42,6 +42,7 @@ type AddWorkerProps = {
image: string;
server_url: string;
cluster_id: number;
+ [key: string]: any;
};
};
diff --git a/src/pages/cluster-management/components/add-worker/config.ts b/src/pages/cluster-management/components/add-worker/config.ts
index 447d61ec..d2ec6eb5 100644
--- a/src/pages/cluster-management/components/add-worker/config.ts
+++ b/src/pages/cluster-management/components/add-worker/config.ts
@@ -59,6 +59,11 @@ export interface SummaryDataKeys {
enabled: boolean;
path: string;
};
+ externalWorkerIPConfig: {
+ enable: boolean;
+ ip: string;
+ required: boolean;
+ };
}
export type SummaryDataMap = {
diff --git a/src/pages/cluster-management/components/add-worker/docker-run-command.tsx b/src/pages/cluster-management/components/add-worker/docker-run-command.tsx
index b6ffb253..425f494d 100644
--- a/src/pages/cluster-management/components/add-worker/docker-run-command.tsx
+++ b/src/pages/cluster-management/components/add-worker/docker-run-command.tsx
@@ -9,13 +9,17 @@ import VendorNotes from './vendor-notes';
const DockerRunCommand = () => {
const intl = useIntl();
- const { registrationInfo, stepList, summary, clusterList } =
- useAddWorkerContext();
+ const { registrationInfo, stepList, summary } = useAddWorkerContext();
const workerIPConfig = summary.get('workerIPConfig') || {
enable: false,
ip: '',
required: false
};
+ const externalWorkerIPConfig = summary.get('externalWorkerIPConfig') || {
+ enable: false,
+ ip: '',
+ required: false
+ };
const modelDirConfig = summary.get('modelDirConfig') || {
enable: false,
path: '',
@@ -62,6 +66,9 @@ const DockerRunCommand = () => {
{
ip: '',
required: false
};
+
+ const externalWorkerIPConfig = summary.get('externalWorkerIPConfig') || {
+ enable: false,
+ ip: '',
+ required: false
+ };
+
const modelDirConfig = summary.get('modelDirConfig') || {
enable: false,
path: ''
@@ -143,6 +150,15 @@ const SpecifyArguments = () => {
return false;
}
+ if (externalWorkerIPConfig.enable && !externalWorkerIPConfig.ip) {
+ updateField('externalWorkerIPConfig', {
+ ...externalWorkerIPConfig,
+ required: true
+ });
+
+ return false;
+ }
+
return true;
};
@@ -189,6 +205,12 @@ const SpecifyArguments = () => {
enable: true,
path: 'gpustack-data'
});
+
+ updateField('externalWorkerIPConfig', {
+ enable: false,
+ ip: '',
+ required: false
+ });
}, []);
return (
@@ -213,13 +235,27 @@ const SpecifyArguments = () => {
{/* worker IP config */}
}
placeholder={intl.formatMessage({
id: 'clusters.addworker.enterWorkerIP'
@@ -274,6 +310,83 @@ const SpecifyArguments = () => {
)
}
>
+ {/* external worker ip config */}
+
+ }
+ placeholder={intl.formatMessage({
+ id: 'clusters.addworker.enterWorkerIP'
+ })}
+ value={externalWorkerIPConfig.ip}
+ checked={externalWorkerIPConfig.enable}
+ errorMessage={
+ externalWorkerIPConfig.required &&
+ !externalWorkerIPConfig.ip &&
+ intl.formatMessage({
+ id: 'clusters.addworker.enterWorkerIP.error'
+ })
+ }
+ onChange={(checked) =>
+ updateField('externalWorkerIPConfig', {
+ ...externalWorkerIPConfig,
+ enable: checked,
+ required: false
+ })
+ }
+ onInputChange={(value) =>
+ updateField('externalWorkerIPConfig', {
+ ...externalWorkerIPConfig,
+ ip: value
+ })
+ }
+ extra={
+ !externalWorkerIPConfig.enable && (
+ }
+ message={
+
+
+ {intl.formatMessage({
+ id: 'clusters.addworker.externalIP.tips'
+ })}
+
+
+ }
+ >
+ )
+ }
+ >
{/* cache directory config */}
{
path: ''
};
+ const externalWorkerIPConfig = summary.get('externalWorkerIPConfig') || {
+ enable: false,
+ ip: ''
+ };
+
return (
@@ -120,7 +125,18 @@ const SummaryData: React.FC = () => {
>
+ }
tips={
workerIPConfig.enable
? workerIPConfig.ip
@@ -133,6 +149,31 @@ const SummaryData: React.FC = () => {
required={true}
>
+
+ }
+ tips={
+ externalWorkerIPConfig.enable
+ ? externalWorkerIPConfig.ip
+ ? ''
+ : intl.formatMessage({ id: 'clusters.addworker.notSpecified' })
+ : intl.formatMessage({ id: 'clusters.addworker.autoDetect' })
+ }
+ enable={externalWorkerIPConfig.enable}
+ value={externalWorkerIPConfig.ip}
+ required={true}
+ >
+
}
- showTitle
+ SHOWTITLE
ghost
minWidth={20}
>
- {record.instance_spec.description || record.instance_spec.label}
+ {record.instance_spec?.description || record.instance_spec?.label}
)
},
diff --git a/src/pages/resources/config/gpu-driver.ts b/src/pages/resources/config/gpu-driver.ts
index 82c57fc4..f7281038 100644
--- a/src/pages/resources/config/gpu-driver.ts
+++ b/src/pages/resources/config/gpu-driver.ts
@@ -143,9 +143,23 @@ interface AddWorkerCommandParams {
cacheDir?: string;
}
+const generateEnvArgs = (params: any) => {
+ const registrationInfo = params.registrationInfo || {};
+ // generate environment variables args from registrationInfo.env
+ let envArgs = '';
+ if (registrationInfo.env && typeof registrationInfo.env === 'object') {
+ Object.keys(registrationInfo.env).forEach((key) => {
+ const value = registrationInfo.env[key];
+ envArgs += `-e "${key}=${value}" \\\n `;
+ });
+ }
+ return envArgs;
+};
+
const setNormalArgs = (params: any) => {
return `sudo docker run -d --name ${params.containerName || 'gpustack-worker'} \\
-e "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=${params.containerName || 'gpustack-worker'}" \\
+ ${generateEnvArgs(params)}
--restart=unless-stopped \\
--privileged \\
--network=host \\
@@ -155,6 +169,11 @@ const setNormalArgs = (params: any) => {
${params.cacheDir ? `--volume ${params.cacheDir}:/var/lib/gpustack/cache \\` : ''}`;
};
+const setWorkerIPArg = (params: any) => {
+ return `${params.workerIP ? `--worker-ip ${params.workerIP} \\` : ''}
+ ${params.advertisAddress ? `--advertise-address ${params.advertisAddress} \\` : ''}`;
+};
+
const setImageArgs = (params: any) => {
return `${params.image} \\
--server-url ${params.server} \\
@@ -171,7 +190,7 @@ const registerWorker = (params: AddWorkerCommandParams) => {
return `${commonArgs}
--runtime ${config.runtime} \\
${imageArgs}
- ${params.workerIP ? `--advertise-address ${params.workerIP} \\` : ''}`;
+ ${setWorkerIPArg(params)}`;
};
// avaliable for AMD
@@ -184,7 +203,7 @@ const registerAMDWorker = (params: AddWorkerCommandParams) => {
--volume /opt/rocm:/opt/rocm:ro \\
--runtime ${config.runtime} \\
${imageArgs}
- ${params.workerIP ? `--advertise-address ${params.workerIP} \\` : ''}`;
+ ${setWorkerIPArg(params)}`;
};
// avaliable for Ascend
@@ -196,7 +215,7 @@ const registerAscendWorker = (params: AddWorkerCommandParams) => {
--env "ASCEND_VISIBLE_DEVICES=$(sudo ls /dev/davinci* | head -1 | grep -o '[0-9]\\+' || echo "0")" \\
--runtime ${config.runtime} \\
${imageArgs}
- ${params.workerIP ? `--advertise-address ${params.workerIP} \\` : ''}`;
+ ${setWorkerIPArg(params)}`;
};
const registerHygonWorker = (params: AddWorkerCommandParams) => {
@@ -209,7 +228,7 @@ const registerHygonWorker = (params: AddWorkerCommandParams) => {
--env ROCM_PATH=/opt/dtk \\
--env ROCM_SMI_LIB_PATH=/opt/hyhal/lib \\
${imageArgs}
- ${params.workerIP ? `--advertise-address ${params.workerIP} \\` : ''}`;
+ ${setWorkerIPArg(params)}`;
};
const registerIluvatarWorker = (params: AddWorkerCommandParams) => {
@@ -222,7 +241,7 @@ const registerIluvatarWorker = (params: AddWorkerCommandParams) => {
--volume /usr/bin/ixsmi:/usr/bin/ixsmi \\
--runtime ${config.runtime} \\
${imageArgs}
- ${params.workerIP ? `--advertise-address ${params.workerIP} \\` : ''}`;
+ ${setWorkerIPArg(params)}`;
};
const registerMetaXWorker = (params: AddWorkerCommandParams) => {
@@ -233,7 +252,7 @@ const registerMetaXWorker = (params: AddWorkerCommandParams) => {
--volume /opt/mxdriver:/opt/mxdriver:ro \\
--volume /opt/maca:/opt/maca:ro \\
${imageArgs}
- ${params.workerIP ? `--advertise-address ${params.workerIP} \\` : ''}`;
+ ${setWorkerIPArg(params)}`;
};
const registerCambriconWorker = (params: AddWorkerCommandParams) => {
@@ -244,7 +263,7 @@ const registerCambriconWorker = (params: AddWorkerCommandParams) => {
--volume /usr/local/neuware:/usr/local/neuware:ro \\
--volume /usr/bin/cnmon:/usr/bin/cnmon \\
${imageArgs}
- ${params.workerIP ? `--advertise-address ${params.workerIP} \\` : ''}`;
+ ${setWorkerIPArg(params)}`;
};
export const registerAddWokerCommandMap = {
diff --git a/src/pages/resources/config/index.ts b/src/pages/resources/config/index.ts
index 0fce6d88..79abc6a5 100644
--- a/src/pages/resources/config/index.ts
+++ b/src/pages/resources/config/index.ts
@@ -64,6 +64,7 @@ export const addWorkerGuide: Record = {
token: string;
image: string;
gpu: string;
+ [key: string]: any;
}) {
return registerAddWokerCommandMap[params.gpu]?.(params);
},