feat: k8s volume mounts
This commit is contained in:
@@ -134,5 +134,29 @@ export default {
|
|||||||
'clusters.addworker.theadNotes-02':
|
'clusters.addworker.theadNotes-02':
|
||||||
'T-Head PPU uses the Container Device Interface (CDI) for device injection and requires the <span class="bold-text">/var/run/cdi</span> directory to be available for CDI generation.',
|
'T-Head PPU uses the Container Device Interface (CDI) for device injection and requires the <span class="bold-text">/var/run/cdi</span> directory to be available for CDI generation.',
|
||||||
'clusters.addworker.nvidiaNotes':
|
'clusters.addworker.nvidiaNotes':
|
||||||
'The built-in inference backends in GPUStack v2.1 require <span class="bold-text">CUDA 12.6+</span>. Please ensure your NVIDIA driver version is <span class="bold-text">560</span> or newer.'
|
'The built-in inference backends in GPUStack v2.1 require <span class="bold-text">CUDA 12.6+</span>. Please ensure your NVIDIA driver version is <span class="bold-text">560</span> or newer.',
|
||||||
|
'clusters.volume.title': 'Volume Mounts',
|
||||||
|
'clusters.volume.name': 'Volume Name',
|
||||||
|
'clusters.volume.mountPath': 'Container Path',
|
||||||
|
'clusters.volume.mountPath.format': 'Path must start with /',
|
||||||
|
'clusters.volume.readOnly': 'Read Only',
|
||||||
|
'clusters.volume.sourceType': 'Source Type',
|
||||||
|
'clusters.volume.sourceType.hostPath': 'Host Path',
|
||||||
|
'clusters.volume.sourceType.pvc': 'Persistent Volume Claim (PVC)',
|
||||||
|
'clusters.volume.sourceType.configMap': 'ConfigMap',
|
||||||
|
'clusters.volume.hostPath.path': 'Host Path',
|
||||||
|
'clusters.volume.hostPath.type': 'Path Type',
|
||||||
|
'clusters.volume.hostPath.type.directory': 'Directory',
|
||||||
|
'clusters.volume.hostPath.type.directoryOrCreate':
|
||||||
|
'Directory (create if not exists)',
|
||||||
|
'clusters.volume.hostPath.type.file': 'File',
|
||||||
|
'clusters.volume.hostPath.type.fileOrCreate': 'File (create if not exists)',
|
||||||
|
'clusters.volume.hostPath.type.socket': 'Socket',
|
||||||
|
'clusters.volume.hostPath.type.charDevice': 'Character Device',
|
||||||
|
'clusters.volume.hostPath.type.blockDevice': 'Block Device',
|
||||||
|
'clusters.volume.pvc.claimName': 'PVC Name',
|
||||||
|
'clusters.volume.pvc.readOnly': 'Read Only',
|
||||||
|
'clusters.volume.configMap.name': 'ConfigMap Name',
|
||||||
|
'clusters.volume.configMap.optional': 'Optional',
|
||||||
|
'clusters.volume.add': 'Add Volume Mount'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -134,7 +134,31 @@ export default {
|
|||||||
'clusters.addworker.theadNotes-02':
|
'clusters.addworker.theadNotes-02':
|
||||||
'T-Head PPU uses the Container Device Interface (CDI) for device injection and requires the <span class="bold-text">/var/run/cdi</span> directory to be available for CDI generation.',
|
'T-Head PPU uses the Container Device Interface (CDI) for device injection and requires the <span class="bold-text">/var/run/cdi</span> directory to be available for CDI generation.',
|
||||||
'clusters.addworker.nvidiaNotes':
|
'clusters.addworker.nvidiaNotes':
|
||||||
'The built-in inference backends in GPUStack v2.1 require <span class="bold-text">CUDA 12.6+</span>. Please ensure your NVIDIA driver version is <span class="bold-text">560</span> or newer.'
|
'The built-in inference backends in GPUStack v2.1 require <span class="bold-text">CUDA 12.6+</span>. Please ensure your NVIDIA driver version is <span class="bold-text">560</span> or newer.',
|
||||||
|
'clusters.volume.title': 'Volume Mounts',
|
||||||
|
'clusters.volume.name': 'Volume Name',
|
||||||
|
'clusters.volume.mountPath': 'Container Path',
|
||||||
|
'clusters.volume.mountPath.format': 'Path must start with /',
|
||||||
|
'clusters.volume.readOnly': 'Read Only',
|
||||||
|
'clusters.volume.sourceType': 'Source Type',
|
||||||
|
'clusters.volume.sourceType.hostPath': 'Host Path',
|
||||||
|
'clusters.volume.sourceType.pvc': 'Persistent Volume Claim (PVC)',
|
||||||
|
'clusters.volume.sourceType.configMap': 'ConfigMap',
|
||||||
|
'clusters.volume.hostPath.path': 'Host Path',
|
||||||
|
'clusters.volume.hostPath.type': 'Path Type',
|
||||||
|
'clusters.volume.hostPath.type.directory': 'Directory',
|
||||||
|
'clusters.volume.hostPath.type.directoryOrCreate':
|
||||||
|
'Directory (create if not exists)',
|
||||||
|
'clusters.volume.hostPath.type.file': 'File',
|
||||||
|
'clusters.volume.hostPath.type.fileOrCreate': 'File (create if not exists)',
|
||||||
|
'clusters.volume.hostPath.type.socket': 'Socket',
|
||||||
|
'clusters.volume.hostPath.type.charDevice': 'Character Device',
|
||||||
|
'clusters.volume.hostPath.type.blockDevice': 'Block Device',
|
||||||
|
'clusters.volume.pvc.claimName': 'PVC Name',
|
||||||
|
'clusters.volume.pvc.readOnly': 'Read Only',
|
||||||
|
'clusters.volume.configMap.name': 'ConfigMap Name',
|
||||||
|
'clusters.volume.configMap.optional': 'Optional',
|
||||||
|
'clusters.volume.add': 'Add Volume Mount'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
|
|||||||
@@ -135,7 +135,31 @@ export default {
|
|||||||
'clusters.addworker.theadNotes-02':
|
'clusters.addworker.theadNotes-02':
|
||||||
'T-Head PPU uses the Container Device Interface (CDI) for device injection and requires the <span class="bold-text">/var/run/cdi</span> directory to be available for CDI generation.',
|
'T-Head PPU uses the Container Device Interface (CDI) for device injection and requires the <span class="bold-text">/var/run/cdi</span> directory to be available for CDI generation.',
|
||||||
'clusters.addworker.nvidiaNotes':
|
'clusters.addworker.nvidiaNotes':
|
||||||
'The built-in inference backends in GPUStack v2.1 require <span class="bold-text">CUDA 12.6+</span>. Please ensure your NVIDIA driver version is <span class="bold-text">560</span> or newer.'
|
'The built-in inference backends in GPUStack v2.1 require <span class="bold-text">CUDA 12.6+</span>. Please ensure your NVIDIA driver version is <span class="bold-text">560</span> or newer.',
|
||||||
|
'clusters.volume.title': 'Volume Mounts',
|
||||||
|
'clusters.volume.name': 'Volume Name',
|
||||||
|
'clusters.volume.mountPath': 'Container Path',
|
||||||
|
'clusters.volume.mountPath.format': 'Path must start with /',
|
||||||
|
'clusters.volume.readOnly': 'Read Only',
|
||||||
|
'clusters.volume.sourceType': 'Source Type',
|
||||||
|
'clusters.volume.sourceType.hostPath': 'Host Path',
|
||||||
|
'clusters.volume.sourceType.pvc': 'Persistent Volume Claim (PVC)',
|
||||||
|
'clusters.volume.sourceType.configMap': 'ConfigMap',
|
||||||
|
'clusters.volume.hostPath.path': 'Host Path',
|
||||||
|
'clusters.volume.hostPath.type': 'Path Type',
|
||||||
|
'clusters.volume.hostPath.type.directory': 'Directory',
|
||||||
|
'clusters.volume.hostPath.type.directoryOrCreate':
|
||||||
|
'Directory (create if not exists)',
|
||||||
|
'clusters.volume.hostPath.type.file': 'File',
|
||||||
|
'clusters.volume.hostPath.type.fileOrCreate': 'File (create if not exists)',
|
||||||
|
'clusters.volume.hostPath.type.socket': 'Socket',
|
||||||
|
'clusters.volume.hostPath.type.charDevice': 'Character Device',
|
||||||
|
'clusters.volume.hostPath.type.blockDevice': 'Block Device',
|
||||||
|
'clusters.volume.pvc.claimName': 'PVC Name',
|
||||||
|
'clusters.volume.pvc.readOnly': 'Read Only',
|
||||||
|
'clusters.volume.configMap.name': 'ConfigMap Name',
|
||||||
|
'clusters.volume.configMap.optional': 'Optional',
|
||||||
|
'clusters.volume.add': 'Add Volume Mount'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export default {
|
|||||||
'clusters.create.steps.selectProvider': 'Sağlayıcı Seç',
|
'clusters.create.steps.selectProvider': 'Sağlayıcı Seç',
|
||||||
'clusters.create.configBasic': 'Temel Yapılandırma',
|
'clusters.create.configBasic': 'Temel Yapılandırma',
|
||||||
'clusters.create.execCommand': 'Komutu Çalıştır',
|
'clusters.create.execCommand': 'Komutu Çalıştır',
|
||||||
'clusters.create.supportedGpu': 'Desteklenen GPU\'lar',
|
'clusters.create.supportedGpu': "Desteklenen GPU'lar",
|
||||||
'clusters.create.skipfornow': 'Şimdilik Atla',
|
'clusters.create.skipfornow': 'Şimdilik Atla',
|
||||||
'clusters.create.noImages': 'Kullanılabilir imaj yok',
|
'clusters.create.noImages': 'Kullanılabilir imaj yok',
|
||||||
'clusters.create.noInstanceTypes': 'Kullanılabilir örnek türü yok',
|
'clusters.create.noInstanceTypes': 'Kullanılabilir örnek türü yok',
|
||||||
@@ -70,16 +70,16 @@ export default {
|
|||||||
'clusters.addworker.checkEnv': 'Ortamı Kontrol Et',
|
'clusters.addworker.checkEnv': 'Ortamı Kontrol Et',
|
||||||
'clusters.addworker.specifyArgs': 'Argümanları Belirle',
|
'clusters.addworker.specifyArgs': 'Argümanları Belirle',
|
||||||
'clusters.addworker.runCommand': 'Komutu Çalıştır',
|
'clusters.addworker.runCommand': 'Komutu Çalıştır',
|
||||||
'clusters.addworker.specifyWorkerIP': 'İşçi Düğüm IP\'si',
|
'clusters.addworker.specifyWorkerIP': "İşçi Düğüm IP'si",
|
||||||
'clusters.addworker.detectWorkerIP': 'İşçi Düğüm IP\'sini Otomatik Algıla',
|
'clusters.addworker.detectWorkerIP': "İşçi Düğüm IP'sini Otomatik Algıla",
|
||||||
'clusters.addworker.specifyWorkerAddress': 'İşçi Düğüm Harici Adresi',
|
'clusters.addworker.specifyWorkerAddress': 'İşçi Düğüm Harici Adresi',
|
||||||
'clusters.addworker.detectWorkerAddress': 'İşçi Düğüm Harici Adresi',
|
'clusters.addworker.detectWorkerAddress': 'İşçi Düğüm Harici Adresi',
|
||||||
'clusters.addworker.detectWorkerAddress.tips':
|
'clusters.addworker.detectWorkerAddress.tips':
|
||||||
'Belirtilmezse İşçi Düğüm IP\'si varsayılır.',
|
"Belirtilmezse İşçi Düğüm IP'si varsayılır.",
|
||||||
'clusters.addworker.externalIP.tips':
|
'clusters.addworker.externalIP.tips':
|
||||||
'VPC veya özel ağda çalıştırılıyorsa, lütfen GPUStack Sunucusuna erişilebilir İşçi Düğüm harici adresini belirtin.',
|
'VPC veya özel ağda çalıştırılıyorsa, lütfen GPUStack Sunucusuna erişilebilir İşçi Düğüm harici adresini belirtin.',
|
||||||
'clusters.addworker.enterWorkerIP': 'İşçi düğüm IP\'sini girin',
|
'clusters.addworker.enterWorkerIP': "İşçi düğüm IP'sini girin",
|
||||||
'clusters.addworker.enterWorkerIP.error': 'Lütfen işçi düğüm IP\'sini girin.',
|
'clusters.addworker.enterWorkerIP.error': "Lütfen işçi düğüm IP'sini girin.",
|
||||||
'clusters.addworker.enterWorkerAddress': 'İşçi düğüm harici adresini girin',
|
'clusters.addworker.enterWorkerAddress': 'İşçi düğüm harici adresini girin',
|
||||||
'clusters.addworker.enterWorkerAddress.error':
|
'clusters.addworker.enterWorkerAddress.error':
|
||||||
'Lütfen işçi düğüm harici adresini girin.',
|
'Lütfen işçi düğüm harici adresini girin.',
|
||||||
@@ -89,7 +89,7 @@ export default {
|
|||||||
'Model önbellek dizinini özelleştirmek istiryorsanız, bağlamak için yolu belirtebilirsiniz.',
|
'Model önbellek dizinini özelleştirmek istiryorsanız, bağlamak için yolu belirtebilirsiniz.',
|
||||||
'clusters.addworker.configSummary': 'Yapılandırma Özeti',
|
'clusters.addworker.configSummary': 'Yapılandırma Özeti',
|
||||||
'clusters.addworker.gpuVendor': 'GPU Üreticisi',
|
'clusters.addworker.gpuVendor': 'GPU Üreticisi',
|
||||||
'clusters.addworker.workerIP': 'İşçi Düğüm IP\'si',
|
'clusters.addworker.workerIP': "İşçi Düğüm IP'si",
|
||||||
'clusters.addworker.workerExternalIP': 'İşçi Düğüm Harici Adresi',
|
'clusters.addworker.workerExternalIP': 'İşçi Düğüm Harici Adresi',
|
||||||
'clusters.addworker.notSpecified': 'Belirtilmedi',
|
'clusters.addworker.notSpecified': 'Belirtilmedi',
|
||||||
'clusters.addworker.autoDetect': 'Otomatik',
|
'clusters.addworker.autoDetect': 'Otomatik',
|
||||||
@@ -105,7 +105,7 @@ export default {
|
|||||||
'{count} yeni işçi düğüm kümeye eklendi.',
|
'{count} yeni işçi düğüm kümeye eklendi.',
|
||||||
'clusters.addworker.message.success_multiple':
|
'clusters.addworker.message.success_multiple':
|
||||||
'{count} yeni işçi düğüm kümeye eklendi.',
|
'{count} yeni işçi düğüm kümeye eklendi.',
|
||||||
'clusters.create.serverUrl': 'GPUStack Sunucu URL\'si',
|
'clusters.create.serverUrl': "GPUStack Sunucu URL'si",
|
||||||
'clusters.create.workerConfig': 'İşçi Düğüm Yapılandırması',
|
'clusters.create.workerConfig': 'İşçi Düğüm Yapılandırması',
|
||||||
'clusters.addworker.containerName': 'İşçi Düğüm Konteyner Adı',
|
'clusters.addworker.containerName': 'İşçi Düğüm Konteyner Adı',
|
||||||
'clusters.addworker.containerName.tips':
|
'clusters.addworker.containerName.tips':
|
||||||
@@ -116,7 +116,7 @@ export default {
|
|||||||
'clusters.table.ip.internal': 'Dahili',
|
'clusters.table.ip.internal': 'Dahili',
|
||||||
'clusters.table.ip.external': 'Harici',
|
'clusters.table.ip.external': 'Harici',
|
||||||
'clusters.form.serverUrl.tips':
|
'clusters.form.serverUrl.tips':
|
||||||
'İşçi düğüm GPUStack Sunucusuna doğrudan erişemiyorsa, harici olarak erişilebilir bir GPUStack hizmet URL\'si belirtin.',
|
"İşçi düğüm GPUStack Sunucusuna doğrudan erişemiyorsa, harici olarak erişilebilir bir GPUStack hizmet URL'si belirtin.",
|
||||||
'clusters.form.setDefault': 'Varsayılan Olarak Ayarla',
|
'clusters.form.setDefault': 'Varsayılan Olarak Ayarla',
|
||||||
'clusters.form.setDefault.tips': 'Dağıtım için varsayılan.',
|
'clusters.form.setDefault.tips': 'Dağıtım için varsayılan.',
|
||||||
'clusters.addworker.noClusters': 'Kullanılabilir Docker kümesi bulunamadı',
|
'clusters.addworker.noClusters': 'Kullanılabilir Docker kümesi bulunamadı',
|
||||||
@@ -126,7 +126,8 @@ export default {
|
|||||||
'clusters.create.dockerTips1': 'Sonraki adım, bu kümeye işçi düğüm ekleyin.',
|
'clusters.create.dockerTips1': 'Sonraki adım, bu kümeye işçi düğüm ekleyin.',
|
||||||
'clusters.create.dockerTips2':
|
'clusters.create.dockerTips2':
|
||||||
'Bu adımı atlayabilir ve daha sonra küme listesinden ekleyebilirsiniz.',
|
'Bu adımı atlayabilir ve daha sonra küme listesinden ekleyebilirsiniz.',
|
||||||
'clusters.create.k8sTips1': 'Sonraki adım, mevcut Kubernetes kümesini kaydedin.',
|
'clusters.create.k8sTips1':
|
||||||
|
'Sonraki adım, mevcut Kubernetes kümesini kaydedin.',
|
||||||
'clusters.create.k8sTips2':
|
'clusters.create.k8sTips2':
|
||||||
'Bu adımı atlayabilir ve daha sonra küme listesinden kaydedebilirsiniz.',
|
'Bu adımı atlayabilir ve daha sonra küme listesinden kaydedebilirsiniz.',
|
||||||
'clusters.addworker.theadNotes':
|
'clusters.addworker.theadNotes':
|
||||||
@@ -134,5 +135,29 @@ export default {
|
|||||||
'clusters.addworker.theadNotes-02':
|
'clusters.addworker.theadNotes-02':
|
||||||
'T-Head PPU, cihaz enjeksiyonu için Container Device Interface (CDI) kullanır ve CDI oluşturma için <span class="bold-text">/var/run/cdi</span> dizininin kullanılabilir olmasını gerektirir.',
|
'T-Head PPU, cihaz enjeksiyonu için Container Device Interface (CDI) kullanır ve CDI oluşturma için <span class="bold-text">/var/run/cdi</span> dizininin kullanılabilir olmasını gerektirir.',
|
||||||
'clusters.addworker.nvidiaNotes':
|
'clusters.addworker.nvidiaNotes':
|
||||||
'GPUStack v2.1\'deki yerleşik çıkarım altyapıları <span class="bold-text">CUDA 12.6+</span> gerektirir. Lütfen NVIDIA sürücü sürümünüzün <span class="bold-text">560</span> veya daha yeni olduğundan emin olun.'
|
'GPUStack v2.1\'deki yerleşik çıkarım altyapıları <span class="bold-text">CUDA 12.6+</span> gerektirir. Lütfen NVIDIA sürücü sürümünüzün <span class="bold-text">560</span> veya daha yeni olduğundan emin olun.',
|
||||||
|
'clusters.volume.title': 'Volume Mounts',
|
||||||
|
'clusters.volume.name': 'Volume Name',
|
||||||
|
'clusters.volume.mountPath': 'Container Path',
|
||||||
|
'clusters.volume.mountPath.format': 'Path must start with /',
|
||||||
|
'clusters.volume.readOnly': 'Read Only',
|
||||||
|
'clusters.volume.sourceType': 'Source Type',
|
||||||
|
'clusters.volume.sourceType.hostPath': 'Host Path',
|
||||||
|
'clusters.volume.sourceType.pvc': 'Persistent Volume Claim (PVC)',
|
||||||
|
'clusters.volume.sourceType.configMap': 'ConfigMap',
|
||||||
|
'clusters.volume.hostPath.path': 'Host Path',
|
||||||
|
'clusters.volume.hostPath.type': 'Path Type',
|
||||||
|
'clusters.volume.hostPath.type.directory': 'Directory',
|
||||||
|
'clusters.volume.hostPath.type.directoryOrCreate':
|
||||||
|
'Directory (create if not exists)',
|
||||||
|
'clusters.volume.hostPath.type.file': 'File',
|
||||||
|
'clusters.volume.hostPath.type.fileOrCreate': 'File (create if not exists)',
|
||||||
|
'clusters.volume.hostPath.type.socket': 'Socket',
|
||||||
|
'clusters.volume.hostPath.type.charDevice': 'Character Device',
|
||||||
|
'clusters.volume.hostPath.type.blockDevice': 'Block Device',
|
||||||
|
'clusters.volume.pvc.claimName': 'PVC Name',
|
||||||
|
'clusters.volume.pvc.readOnly': 'Read Only',
|
||||||
|
'clusters.volume.configMap.name': 'ConfigMap Name',
|
||||||
|
'clusters.volume.configMap.optional': 'Optional',
|
||||||
|
'clusters.volume.add': 'Add Volume Mount'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -128,5 +128,28 @@ export default {
|
|||||||
'clusters.addworker.theadNotes-02':
|
'clusters.addworker.theadNotes-02':
|
||||||
'平头哥(T-Head)PPU 使用容器设备接口(CDI)进行设备注入,因此需要确保 <span class="bold-text">/var/run/cdi</span> 目录可用以生成 CDI。',
|
'平头哥(T-Head)PPU 使用容器设备接口(CDI)进行设备注入,因此需要确保 <span class="bold-text">/var/run/cdi</span> 目录可用以生成 CDI。',
|
||||||
'clusters.addworker.nvidiaNotes':
|
'clusters.addworker.nvidiaNotes':
|
||||||
'GPUStack v2.1 内置推理后端依赖 <span class="bold-text">CUDA 12.6</span> 及以上版本,请确保 NVIDIA 驱动版本为 <span class="bold-text">560</span> 或以上。'
|
'GPUStack v2.1 内置推理后端依赖 <span class="bold-text">CUDA 12.6</span> 及以上版本,请确保 NVIDIA 驱动版本为 <span class="bold-text">560</span> 或以上。',
|
||||||
|
'clusters.volume.title': '卷挂载',
|
||||||
|
'clusters.volume.name': '卷名称',
|
||||||
|
'clusters.volume.mountPath': '容器内路径',
|
||||||
|
'clusters.volume.mountPath.format': '路径必须以 / 开头',
|
||||||
|
'clusters.volume.readOnly': '只读',
|
||||||
|
'clusters.volume.sourceType': '存储来源',
|
||||||
|
'clusters.volume.sourceType.hostPath': '主机路径',
|
||||||
|
'clusters.volume.sourceType.pvc': '存储卷声明(PVC)',
|
||||||
|
'clusters.volume.sourceType.configMap': '配置映射(ConfigMap)',
|
||||||
|
'clusters.volume.hostPath.path': '宿主机路径',
|
||||||
|
'clusters.volume.hostPath.type': '路径类型',
|
||||||
|
'clusters.volume.hostPath.type.directory': '目录',
|
||||||
|
'clusters.volume.hostPath.type.directoryOrCreate': '目录(不存在则创建)',
|
||||||
|
'clusters.volume.hostPath.type.file': '文件',
|
||||||
|
'clusters.volume.hostPath.type.fileOrCreate': '文件(不存在则创建)',
|
||||||
|
'clusters.volume.hostPath.type.socket': '套接字',
|
||||||
|
'clusters.volume.hostPath.type.charDevice': '字符设备',
|
||||||
|
'clusters.volume.hostPath.type.blockDevice': '块设备',
|
||||||
|
'clusters.volume.pvc.claimName': 'PVC 名称',
|
||||||
|
'clusters.volume.pvc.readOnly': '只读',
|
||||||
|
'clusters.volume.configMap.name': '配置名称',
|
||||||
|
'clusters.volume.configMap.optional': '可选',
|
||||||
|
'clusters.volume.add': '添加卷挂载'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ const VersionsForm: React.FC<AddModalProps> = ({
|
|||||||
<div
|
<div
|
||||||
key={name}
|
key={name}
|
||||||
style={{
|
style={{
|
||||||
borderRadius: 'var(--ant-border-radius)',
|
borderRadius: 'var(--ant-border-radius-lg)',
|
||||||
border: '1px solid var(--ant-color-split)'
|
border: '1px solid var(--ant-color-split)'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
} from '../config/types';
|
} from '../config/types';
|
||||||
import AdvanceConfig from '../step-forms/advance-config';
|
import AdvanceConfig from '../step-forms/advance-config';
|
||||||
import CloudProvider from './cloud-provider-form';
|
import CloudProvider from './cloud-provider-form';
|
||||||
|
import K8SVolumeMount from './k8s-volume-mount';
|
||||||
|
|
||||||
type AddModalProps = {
|
type AddModalProps = {
|
||||||
action: PageActionType;
|
action: PageActionType;
|
||||||
@@ -60,7 +61,17 @@ const ClusterForm: React.FC<AddModalProps> = forwardRef(
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (currentData) {
|
if (currentData) {
|
||||||
form.setFieldsValue(currentData);
|
const volumeMounts = currentData?.k8s_volume_mounts || [];
|
||||||
|
const realVolumeList = (volumeMounts || []).map(
|
||||||
|
(item: any, index: number) => ({
|
||||||
|
...item,
|
||||||
|
sourceType: Object.keys(item.volumeSource || {})[0] || 'hostPath'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
form.setFieldsValue({
|
||||||
|
...currentData,
|
||||||
|
k8s_volume_mounts: realVolumeList
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, [currentData]);
|
}, [currentData]);
|
||||||
|
|
||||||
@@ -151,6 +162,7 @@ const ClusterForm: React.FC<AddModalProps> = forwardRef(
|
|||||||
credentialList={credentialList}
|
credentialList={credentialList}
|
||||||
></CloudProvider>
|
></CloudProvider>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Form.Item<FormData>
|
<Form.Item<FormData>
|
||||||
name="description"
|
name="description"
|
||||||
rules={[{ required: false }]}
|
rules={[{ required: false }]}
|
||||||
@@ -161,6 +173,12 @@ const ClusterForm: React.FC<AddModalProps> = forwardRef(
|
|||||||
label={intl.formatMessage({ id: 'common.table.description' })}
|
label={intl.formatMessage({ id: 'common.table.description' })}
|
||||||
></SealTextArea>
|
></SealTextArea>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
{provider === ProviderValueMap.Kubernetes && (
|
||||||
|
<K8SVolumeMount
|
||||||
|
action={action}
|
||||||
|
currentData={currentData}
|
||||||
|
></K8SVolumeMount>
|
||||||
|
)}
|
||||||
<CollapsePanel
|
<CollapsePanel
|
||||||
accordion={false}
|
accordion={false}
|
||||||
activeKey={activeKey}
|
activeKey={activeKey}
|
||||||
|
|||||||
@@ -0,0 +1,432 @@
|
|||||||
|
import CollapsibleContainer from '@/components/collapse-container';
|
||||||
|
import SealCheckbox from '@/components/seal-form/seal-checkbox';
|
||||||
|
import SealInput from '@/components/seal-form/seal-input';
|
||||||
|
import SealSelect from '@/components/seal-form/seal-select';
|
||||||
|
import SealSwitch from '@/components/seal-form/seal-switch';
|
||||||
|
import { PageAction } from '@/config';
|
||||||
|
import { PageActionType } from '@/config/types';
|
||||||
|
import useAppUtils from '@/hooks/use-app-utils';
|
||||||
|
import { MinusOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
|
import { useIntl } from '@umijs/max';
|
||||||
|
import { Button, Flex, Form } from 'antd';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { hostTypeOptions, sourceTypeOptions } from '../config';
|
||||||
|
|
||||||
|
const Label = styled.span`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
color: var(--ant-color-text-secondary);
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Title = styled.div`
|
||||||
|
position: sticky;
|
||||||
|
top: -16px;
|
||||||
|
z-index: 100;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: var(--ant-color-bg-container);
|
||||||
|
font-weight: 600;
|
||||||
|
padding-top: 8px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const VolumeMountsForm: React.FC<{ action: PageActionType }> = ({ action }) => {
|
||||||
|
const form = Form.useFormInstance();
|
||||||
|
const intl = useIntl();
|
||||||
|
const { getRuleMessage } = useAppUtils();
|
||||||
|
|
||||||
|
const [collapseKey, setCollapseKey] = useState<Set<number | string>>(
|
||||||
|
new Set([0])
|
||||||
|
);
|
||||||
|
|
||||||
|
const volumeList = [
|
||||||
|
{
|
||||||
|
name: 'volume-1',
|
||||||
|
mountPath: '',
|
||||||
|
readOnly: false,
|
||||||
|
sourceType: 'hostPath',
|
||||||
|
volumeSource: {
|
||||||
|
hostPath: {
|
||||||
|
path: '',
|
||||||
|
type: 'DirectoryOrCreate'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (action === PageAction.CREATE) {
|
||||||
|
form.setFieldValue('k8s_volume_mounts', volumeList);
|
||||||
|
}
|
||||||
|
}, [action]);
|
||||||
|
|
||||||
|
const onToggle = (open: boolean, key: number) => {
|
||||||
|
setCollapseKey(open ? new Set([key]) : new Set());
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAdd = async () => {
|
||||||
|
try {
|
||||||
|
await form.validateFields(['k8s_volume_mounts'], {
|
||||||
|
recursive: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const list = form.getFieldValue('k8s_volume_mounts') || [];
|
||||||
|
|
||||||
|
form.setFieldValue('k8s_volume_mounts', [
|
||||||
|
...list,
|
||||||
|
{
|
||||||
|
name: `volume-${list.length + 1}`,
|
||||||
|
mountPath: '',
|
||||||
|
readOnly: false,
|
||||||
|
sourceType: 'hostPath',
|
||||||
|
volumeSource: {
|
||||||
|
hostPath: {
|
||||||
|
path: '',
|
||||||
|
type: 'DirectoryOrCreate'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setCollapseKey(new Set([list.length]));
|
||||||
|
}, 100);
|
||||||
|
} catch (e: any) {
|
||||||
|
const errorIndex = e?.errorFields?.[0]?.name?.[1];
|
||||||
|
if (typeof errorIndex === 'number') {
|
||||||
|
setCollapseKey(new Set([errorIndex]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSourceChange = (value: string, index: number) => {
|
||||||
|
const list = form.getFieldValue('k8s_volume_mounts') || [];
|
||||||
|
|
||||||
|
const updated = list.map((item: any, i: number) => {
|
||||||
|
if (i !== index) return item;
|
||||||
|
|
||||||
|
let volumeSource: any = {};
|
||||||
|
|
||||||
|
if (value === 'hostPath') {
|
||||||
|
volumeSource = {
|
||||||
|
hostPath: { path: '', type: 'DirectoryOrCreate' }
|
||||||
|
};
|
||||||
|
} else if (value === 'pvc') {
|
||||||
|
volumeSource = {
|
||||||
|
persistentVolumeClaim: { claimName: '', readOnly: false }
|
||||||
|
};
|
||||||
|
} else if (value === 'configMap') {
|
||||||
|
volumeSource = {
|
||||||
|
configMap: { name: '', optional: false }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
sourceType: value,
|
||||||
|
volumeSource
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
form.setFieldValue('k8s_volume_mounts', updated);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Title>
|
||||||
|
<div className="flex-center gap-8">
|
||||||
|
<span>{intl.formatMessage({ id: 'clusters.volume.title' })}</span>
|
||||||
|
<Button type="link" onClick={handleAdd}>
|
||||||
|
<PlusOutlined /> {intl.formatMessage({ id: 'clusters.volume.add' })}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Title>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: '16px',
|
||||||
|
marginBottom: '24px'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Form.List name="k8s_volume_mounts">
|
||||||
|
{(fields, { remove }) => {
|
||||||
|
const list = form.getFieldValue('k8s_volume_mounts') || [];
|
||||||
|
|
||||||
|
return fields.map(({ name }) => {
|
||||||
|
const item = list[name] || {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={name}
|
||||||
|
style={{
|
||||||
|
border: '1px solid var(--ant-color-split)',
|
||||||
|
borderRadius: 'var(--ant-border-radius-lg)'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CollapsibleContainer
|
||||||
|
collapsible={true}
|
||||||
|
showExpandIcon={true}
|
||||||
|
open={collapseKey.has(name)}
|
||||||
|
onToggle={(open) => onToggle(open, name)}
|
||||||
|
styles={{
|
||||||
|
body: collapseKey.has(name) ? { padding: 16 } : {},
|
||||||
|
content: { paddingTop: 0 },
|
||||||
|
header: {
|
||||||
|
backgroundColor: 'unset'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
title={
|
||||||
|
<Label>
|
||||||
|
<span>
|
||||||
|
{intl.formatMessage({ id: 'clusters.volume.name' })}:
|
||||||
|
</span>
|
||||||
|
<span>{list[name]?.name}</span>
|
||||||
|
</Label>
|
||||||
|
}
|
||||||
|
right={
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
shape="circle"
|
||||||
|
onClick={() => remove(name)}
|
||||||
|
>
|
||||||
|
<MinusOutlined />
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
name={[name, 'name']}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: getRuleMessage(
|
||||||
|
'input',
|
||||||
|
'clusters.volume.name'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealInput.Input
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id: 'clusters.volume.name'
|
||||||
|
})}
|
||||||
|
required
|
||||||
|
></SealInput.Input>
|
||||||
|
</Form.Item>
|
||||||
|
<Flex style={{ gap: 16, width: '100%' }}>
|
||||||
|
{/* Mount Path */}
|
||||||
|
<div style={{ flex: 1 }}>
|
||||||
|
<Form.Item
|
||||||
|
name={[name, 'mountPath']}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: getRuleMessage(
|
||||||
|
'input',
|
||||||
|
'clusters.volume.mountPath'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealInput.Input
|
||||||
|
required
|
||||||
|
placeholder={intl.formatMessage({
|
||||||
|
id: 'clusters.volume.mountPath.format'
|
||||||
|
})}
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id: 'clusters.volume.mountPath'
|
||||||
|
})}
|
||||||
|
></SealInput.Input>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ReadOnly */}
|
||||||
|
<Form.Item
|
||||||
|
style={{ width: 240 }}
|
||||||
|
name={[name, 'readOnly']}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<SealSwitch
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id: 'clusters.volume.readOnly'
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
{/* Source Type */}
|
||||||
|
<Form.Item
|
||||||
|
name={[name, 'sourceType']}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: getRuleMessage(
|
||||||
|
'select',
|
||||||
|
'clusters.volume.sourceType'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealSelect
|
||||||
|
required
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id: 'clusters.volume.sourceType'
|
||||||
|
})}
|
||||||
|
onChange={(value) => handleSourceChange(value, name)}
|
||||||
|
options={sourceTypeOptions}
|
||||||
|
value={item.sourceType}
|
||||||
|
></SealSelect>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
{/* Dynamic Source Form */}
|
||||||
|
{item.sourceType === 'hostPath' && (
|
||||||
|
<Flex style={{ gap: 16 }}>
|
||||||
|
<div style={{ flex: 1 }}>
|
||||||
|
<Form.Item
|
||||||
|
name={[name, 'volumeSource', 'hostPath', 'path']}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: getRuleMessage(
|
||||||
|
'input',
|
||||||
|
'clusters.volume.hostPath.path'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealInput.Input
|
||||||
|
required
|
||||||
|
placeholder={intl.formatMessage({
|
||||||
|
id: 'clusters.volume.mountPath.format'
|
||||||
|
})}
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id: 'clusters.volume.sourceType.hostPath'
|
||||||
|
})}
|
||||||
|
></SealInput.Input>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
style={{ width: 240 }}
|
||||||
|
name={[name, 'volumeSource', 'hostPath', 'type']}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: getRuleMessage(
|
||||||
|
'select',
|
||||||
|
'clusters.volume.hostPath.type'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealSelect
|
||||||
|
required
|
||||||
|
options={hostTypeOptions}
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id: 'clusters.volume.hostPath.type'
|
||||||
|
})}
|
||||||
|
></SealSelect>
|
||||||
|
</Form.Item>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{item.sourceType === 'pvc' && (
|
||||||
|
<Flex style={{ gap: 16 }}>
|
||||||
|
<div style={{ flex: 1 }}>
|
||||||
|
<Form.Item
|
||||||
|
name={[
|
||||||
|
name,
|
||||||
|
'volumeSource',
|
||||||
|
'persistentVolumeClaim',
|
||||||
|
'claimName'
|
||||||
|
]}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: getRuleMessage(
|
||||||
|
'input',
|
||||||
|
'clusters.volume.pvc.claimName'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealInput.Input
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id: 'clusters.volume.pvc.claimName'
|
||||||
|
})}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
style={{ width: 240 }}
|
||||||
|
name={[
|
||||||
|
name,
|
||||||
|
'volumeSource',
|
||||||
|
'persistentVolumeClaim',
|
||||||
|
'readOnly'
|
||||||
|
]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<SealSwitch
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id: 'clusters.volume.pvc.readOnly'
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{item.sourceType === 'configMap' && (
|
||||||
|
<Flex style={{ gap: 16 }}>
|
||||||
|
<div style={{ flex: 1 }}>
|
||||||
|
<Form.Item
|
||||||
|
name={[name, 'volumeSource', 'configMap', 'name']}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: getRuleMessage(
|
||||||
|
'input',
|
||||||
|
'clusters.volume.configMap.name'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealInput.Input
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id: 'clusters.volume.configMap.name'
|
||||||
|
})}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
style={{ width: 240 }}
|
||||||
|
name={[name, 'volumeSource', 'configMap', 'optional']}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<SealCheckbox
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id: 'clusters.volume.configMap.optional'
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</CollapsibleContainer>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
</Form.List>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default VolumeMountsForm;
|
||||||
@@ -97,3 +97,55 @@ export const CloudOptionItems = [
|
|||||||
key: 'volumes'
|
key: 'volumes'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const hostTypeOptions = [
|
||||||
|
{
|
||||||
|
label: 'clusters.volume.hostPath.type.directory',
|
||||||
|
locale: true,
|
||||||
|
value: 'Directory'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'clusters.volume.hostPath.type.directoryOrCreate',
|
||||||
|
locale: true,
|
||||||
|
value: 'DirectoryOrCreate'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'clusters.volume.hostPath.type.file',
|
||||||
|
locale: true,
|
||||||
|
value: 'File'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'clusters.volume.hostPath.type.fileOrCreate',
|
||||||
|
locale: true,
|
||||||
|
value: 'FileOrCreate'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'clusters.volume.hostPath.type.socket',
|
||||||
|
locale: true,
|
||||||
|
value: 'Socket'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'clusters.volume.hostPath.type.charDevice',
|
||||||
|
locale: true,
|
||||||
|
value: 'CharDevice'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'clusters.volume.hostPath.type.blockDevice',
|
||||||
|
locale: true,
|
||||||
|
value: 'BlockDevice'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export const sourceTypeOptions = [
|
||||||
|
{
|
||||||
|
label: 'clusters.volume.sourceType.hostPath',
|
||||||
|
locale: true,
|
||||||
|
value: 'hostPath'
|
||||||
|
},
|
||||||
|
{ label: 'clusters.volume.sourceType.pvc', locale: true, value: 'pvc' },
|
||||||
|
{
|
||||||
|
label: 'clusters.volume.sourceType.configMap',
|
||||||
|
locale: true,
|
||||||
|
value: 'configMap'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|||||||
@@ -48,6 +48,25 @@ export interface NodePoolListItem extends NodePoolFormData {
|
|||||||
updated_at: string;
|
updated_at: string;
|
||||||
cluster_id: number;
|
cluster_id: number;
|
||||||
}
|
}
|
||||||
|
export interface VolumeMount {
|
||||||
|
name: string;
|
||||||
|
mountPath: string;
|
||||||
|
readOnly: boolean;
|
||||||
|
volumeSource: {
|
||||||
|
hostPath: {
|
||||||
|
path: string;
|
||||||
|
type: string;
|
||||||
|
};
|
||||||
|
persistentVolumeClaim: {
|
||||||
|
claimName: string;
|
||||||
|
readOnly: boolean;
|
||||||
|
};
|
||||||
|
configMap: {
|
||||||
|
name: string;
|
||||||
|
optional: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export interface ClusterListItem {
|
export interface ClusterListItem {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -68,6 +87,7 @@ export interface ClusterListItem {
|
|||||||
state: ClusterStatusType;
|
state: ClusterStatusType;
|
||||||
state_message: string;
|
state_message: string;
|
||||||
worker_pools: NodePoolListItem[];
|
worker_pools: NodePoolListItem[];
|
||||||
|
k8s_volume_mounts?: VolumeMount[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ClusterFormData {
|
export interface ClusterFormData {
|
||||||
@@ -81,6 +101,7 @@ export interface ClusterFormData {
|
|||||||
server_url?: string;
|
server_url?: string;
|
||||||
worker_config?: Record<string, any>;
|
worker_config?: Record<string, any>;
|
||||||
worker_pools?: NodePoolFormData[];
|
worker_pools?: NodePoolFormData[];
|
||||||
|
k8s_volume_mounts?: VolumeMount[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SystemConfig {
|
export interface SystemConfig {
|
||||||
|
|||||||
@@ -1,20 +1,8 @@
|
|||||||
import { PageActionType } from '@/config/types';
|
import { PageActionType } from '@/config/types';
|
||||||
import { useIntl } from '@umijs/max';
|
|
||||||
import { forwardRef, useImperativeHandle, useRef } from 'react';
|
import { forwardRef, useImperativeHandle, useRef } from 'react';
|
||||||
import styled from 'styled-components';
|
|
||||||
import ClusterForm from '../components/cluster-form';
|
import ClusterForm from '../components/cluster-form';
|
||||||
import { ProviderType } from '../config';
|
import { ProviderType } from '../config';
|
||||||
|
|
||||||
const Title = styled.span`
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 14px;
|
|
||||||
.text {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
interface BasicFormProps {
|
interface BasicFormProps {
|
||||||
provider: ProviderType;
|
provider: ProviderType;
|
||||||
action: PageActionType;
|
action: PageActionType;
|
||||||
@@ -23,7 +11,6 @@ interface BasicFormProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const BasicForm = forwardRef((props: BasicFormProps, ref) => {
|
const BasicForm = forwardRef((props: BasicFormProps, ref) => {
|
||||||
const intl = useIntl();
|
|
||||||
const { provider, credentialList, action, currentData } = props;
|
const { provider, credentialList, action, currentData } = props;
|
||||||
const formRef = useRef<any>(null);
|
const formRef = useRef<any>(null);
|
||||||
|
|
||||||
@@ -38,25 +25,14 @@ const BasicForm = forwardRef((props: BasicFormProps, ref) => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<ClusterForm
|
||||||
{/* <PageTools
|
provider={provider}
|
||||||
marginBottom={16}
|
action={action}
|
||||||
left={
|
ref={formRef}
|
||||||
<Title>
|
credentialList={credentialList}
|
||||||
{intl.formatMessage({ id: 'clusters.create.configBasic' })}
|
onFinish={handleOnFinish}
|
||||||
</Title>
|
currentData={currentData}
|
||||||
}
|
></ClusterForm>
|
||||||
marginTop={0}
|
|
||||||
></PageTools> */}
|
|
||||||
<ClusterForm
|
|
||||||
provider={provider}
|
|
||||||
action={action}
|
|
||||||
ref={formRef}
|
|
||||||
credentialList={credentialList}
|
|
||||||
onFinish={handleOnFinish}
|
|
||||||
currentData={currentData}
|
|
||||||
></ClusterForm>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user