feat(cluster): add default container registry field to advanced config
Surface the top-level system_default_container_registry as a dedicated input (both Docker and K8s), coerce blank to null, and drop its redundant worker_config YAML hint.
This commit is contained in:
@@ -162,6 +162,9 @@ export default {
|
||||
'clusters.volume.configMap.name': 'ConfigMap Name',
|
||||
'clusters.volume.configMap.optional': 'Optional',
|
||||
'clusters.volume.add': 'Add Volume Mount',
|
||||
'clusters.systemDefaultContainerRegistry.title': 'Default Container Registry',
|
||||
'clusters.systemDefaultContainerRegistry.tip':
|
||||
'Default registry used to resolve GPUStack images for this cluster. Falls back to the server default when unset.',
|
||||
'clusters.k8sOptions.title': 'K8s Deployment Options',
|
||||
'clusters.imageCredentials.title': 'Image Credentials',
|
||||
'clusters.imageCredentials.add': 'Add Credential',
|
||||
|
||||
@@ -162,6 +162,9 @@ export default {
|
||||
'clusters.volume.configMap.name': 'ConfigMap Name',
|
||||
'clusters.volume.configMap.optional': 'Optional',
|
||||
'clusters.volume.add': 'Add Volume Mount',
|
||||
'clusters.systemDefaultContainerRegistry.title': 'Default Container Registry',
|
||||
'clusters.systemDefaultContainerRegistry.tip':
|
||||
'Default registry used to resolve GPUStack images for this cluster. Falls back to the server default when unset.',
|
||||
'clusters.k8sOptions.title': 'K8s Deployment Options',
|
||||
'clusters.imageCredentials.title': 'Image Credentials',
|
||||
'clusters.imageCredentials.add': 'Add Credential',
|
||||
|
||||
@@ -163,6 +163,9 @@ export default {
|
||||
'clusters.volume.configMap.name': 'ConfigMap Name',
|
||||
'clusters.volume.configMap.optional': 'Optional',
|
||||
'clusters.volume.add': 'Add Volume Mount',
|
||||
'clusters.systemDefaultContainerRegistry.title': 'Default Container Registry',
|
||||
'clusters.systemDefaultContainerRegistry.tip':
|
||||
'Default registry used to resolve GPUStack images for this cluster. Falls back to the server default when unset.',
|
||||
'clusters.k8sOptions.title': 'K8s Deployment Options',
|
||||
'clusters.imageCredentials.title': 'Image Credentials',
|
||||
'clusters.imageCredentials.add': 'Add Credential',
|
||||
|
||||
@@ -163,6 +163,9 @@ export default {
|
||||
'clusters.volume.configMap.name': 'ConfigMap Name',
|
||||
'clusters.volume.configMap.optional': 'Optional',
|
||||
'clusters.volume.add': 'Add Volume Mount',
|
||||
'clusters.systemDefaultContainerRegistry.title': 'Default Container Registry',
|
||||
'clusters.systemDefaultContainerRegistry.tip':
|
||||
'Default registry used to resolve GPUStack images for this cluster. Falls back to the server default when unset.',
|
||||
'clusters.k8sOptions.title': 'K8s Deployment Options',
|
||||
'clusters.imageCredentials.title': 'Image Credentials',
|
||||
'clusters.imageCredentials.add': 'Add Credential',
|
||||
|
||||
@@ -155,6 +155,9 @@ export default {
|
||||
'clusters.volume.configMap.name': '配置名称',
|
||||
'clusters.volume.configMap.optional': '可选',
|
||||
'clusters.volume.add': '添加卷挂载',
|
||||
'clusters.systemDefaultContainerRegistry.title': '默认容器镜像仓库',
|
||||
'clusters.systemDefaultContainerRegistry.tip':
|
||||
'用于解析该集群 GPUStack 镜像的默认镜像仓库。未设置时回退到服务端默认值。',
|
||||
'clusters.k8sOptions.title': 'K8s 部署选项',
|
||||
'clusters.imageCredentials.title': '镜像仓库凭证',
|
||||
'clusters.imageCredentials.add': '添加凭证',
|
||||
|
||||
@@ -64,8 +64,18 @@ const ClusterForm: React.FC<AddModalProps> = forwardRef(
|
||||
// "no auth". Coerce empty form values to null before sending so a blank
|
||||
// input is unambiguous rather than an empty string that defeats fallbacks.
|
||||
const normalizeOutgoing = (values: any): any => {
|
||||
const opts = values?.k8s_options;
|
||||
if (!opts) return values;
|
||||
const base: any = { ...values };
|
||||
// Top-level cluster field shared by Docker and K8s. Trim then coerce a
|
||||
// blank input to null so clearing it on edit (or a whitespace-only
|
||||
// value) falls back to the server default rather than persisting an
|
||||
// empty string.
|
||||
if (base.system_default_container_registry !== undefined) {
|
||||
base.system_default_container_registry =
|
||||
base.system_default_container_registry?.trim() || null;
|
||||
}
|
||||
|
||||
const opts = base.k8s_options;
|
||||
if (!opts) return base;
|
||||
|
||||
const next: any = { ...opts };
|
||||
|
||||
@@ -90,7 +100,7 @@ const ClusterForm: React.FC<AddModalProps> = forwardRef(
|
||||
};
|
||||
}
|
||||
|
||||
return { ...values, k8s_options: next };
|
||||
return { ...base, k8s_options: next };
|
||||
};
|
||||
|
||||
const handleOnFinish = (_values: FormData) => {
|
||||
|
||||
@@ -9,7 +9,6 @@ export const dockerConfig = `# This is a template for worker_config.
|
||||
|
||||
# ========= container & image ===========
|
||||
|
||||
# system_default_container_registry: "docker.io"
|
||||
# image_name_override: "gpustack/gpustack:dev"
|
||||
# image_repo: "gpustack/gpustack"
|
||||
|
||||
@@ -53,7 +52,6 @@ export const kubernetesConfig = `# This is a template for worker_config.
|
||||
|
||||
# ========= container & image ===========
|
||||
|
||||
# system_default_container_registry: "docker.io"
|
||||
# image_name_override: "gpustack/gpustack:dev"
|
||||
# image_repo: "gpustack/gpustack"
|
||||
|
||||
|
||||
@@ -88,6 +88,24 @@ const ClusterAdvanceConfig: React.FC<{
|
||||
>
|
||||
<CInput.TextArea required={false} trim={false}></CInput.TextArea>
|
||||
</Form.Item>
|
||||
{/* Default container registry used to resolve images for this cluster.
|
||||
A top-level cluster field shared by both Docker and Kubernetes
|
||||
providers (the backend hoists any legacy worker_config value onto
|
||||
this column). */}
|
||||
<Form.Item<FormData>
|
||||
name="system_default_container_registry"
|
||||
style={{ marginBottom: 16 }}
|
||||
>
|
||||
<CInput.Input
|
||||
label={intl.formatMessage({
|
||||
id: 'clusters.systemDefaultContainerRegistry.title'
|
||||
})}
|
||||
description={intl.formatMessage({
|
||||
id: 'clusters.systemDefaultContainerRegistry.tip'
|
||||
})}
|
||||
placeholder="docker.io"
|
||||
></CInput.Input>
|
||||
</Form.Item>
|
||||
<Title>
|
||||
{intl.formatMessage({ id: 'clusters.create.workerConfig' })}
|
||||
</Title>
|
||||
|
||||
Reference in New Issue
Block a user