fix: k8s volume config

This commit is contained in:
jialin
2026-04-14 20:42:01 +08:00
committed by jialin
parent 46b9855c87
commit 41c9b86fd9
6 changed files with 66 additions and 41 deletions
+1
View File
@@ -53,6 +53,7 @@ const SealSlider: React.FC<SealSwitchProps> = (props) => {
required={required} required={required}
status={checkStatus || status} status={checkStatus || status}
className="no-focus" className="no-focus"
disabled={props.disabled}
> >
<Inner> <Inner>
<LabelInfo label={label} description={description}></LabelInfo> <LabelInfo label={label} description={description}></LabelInfo>
@@ -83,7 +83,7 @@ const useModelsColumns = ({
key: 'masked_value', key: 'masked_value',
render: (text: string, record: ListItem) => ( render: (text: string, record: ListItem) => (
<AutoTooltip ghost style={{ maxWidth: 400 }}> <AutoTooltip ghost style={{ maxWidth: 400 }}>
{text} {text || '-'}
</AutoTooltip> </AutoTooltip>
) )
}, },
@@ -14,7 +14,6 @@ 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;
@@ -72,6 +71,23 @@ const ClusterForm: React.FC<AddModalProps> = forwardRef(
...currentData, ...currentData,
k8s_volume_mounts: realVolumeList k8s_volume_mounts: realVolumeList
}); });
} else {
form.setFieldsValue({
k8s_volume_mounts: [
{
name: 'gpustack-data-dir',
mountPath: '/var/lib/gpustack',
readOnly: false,
sourceType: 'hostPath',
volumeSource: {
hostPath: {
path: '/var/lib/gpustack',
type: 'DirectoryOrCreate'
}
}
}
]
});
} }
}, [currentData]); }, [currentData]);
@@ -173,9 +189,7 @@ 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}></K8SVolumeMount>
)}
<CollapsePanel <CollapsePanel
accordion={false} accordion={false}
activeKey={activeKey} activeKey={activeKey}
@@ -21,15 +21,13 @@ const Label = styled.span`
`; `;
const Title = styled.div` const Title = styled.div`
position: sticky;
top: -16px;
z-index: 100;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
background-color: var(--ant-color-bg-container); background-color: var(--ant-color-bg-container);
font-weight: 600; font-weight: 500;
padding-top: 8px; font-size: 14px;
padding-top: 0px;
padding-bottom: 8px; padding-bottom: 8px;
`; `;
@@ -141,7 +139,7 @@ const VolumeMountsForm: React.FC<{ action: PageActionType }> = ({ action }) => {
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
gap: '16px', gap: '16px',
marginBottom: '24px' marginBottom: '8px'
}} }}
> >
<Form.List name="k8s_volume_mounts"> <Form.List name="k8s_volume_mounts">
@@ -180,13 +178,17 @@ const VolumeMountsForm: React.FC<{ action: PageActionType }> = ({ action }) => {
</Label> </Label>
} }
right={ right={
<Button <>
size="small" {name > 0 && (
shape="circle" <Button
onClick={() => remove(name)} size="small"
> shape="circle"
<MinusOutlined /> onClick={() => remove(name)}
</Button> >
<MinusOutlined />
</Button>
)}
</>
} }
> >
<Form.Item <Form.Item
@@ -202,6 +204,7 @@ const VolumeMountsForm: React.FC<{ action: PageActionType }> = ({ action }) => {
]} ]}
> >
<SealInput.Input <SealInput.Input
disabled={name === 0}
label={intl.formatMessage({ label={intl.formatMessage({
id: 'clusters.volume.name' id: 'clusters.volume.name'
})} })}
@@ -231,6 +234,7 @@ const VolumeMountsForm: React.FC<{ action: PageActionType }> = ({ action }) => {
> >
<SealInput.Input <SealInput.Input
required required
disabled={name === 0}
placeholder={intl.formatMessage({ placeholder={intl.formatMessage({
id: 'clusters.volume.mountPath.format' id: 'clusters.volume.mountPath.format'
})} })}
@@ -248,6 +252,7 @@ const VolumeMountsForm: React.FC<{ action: PageActionType }> = ({ action }) => {
valuePropName="checked" valuePropName="checked"
> >
<SealSwitch <SealSwitch
disabled={name === 0}
label={intl.formatMessage({ label={intl.formatMessage({
id: 'clusters.volume.readOnly' id: 'clusters.volume.readOnly'
})} })}
@@ -270,6 +275,7 @@ const VolumeMountsForm: React.FC<{ action: PageActionType }> = ({ action }) => {
> >
<SealSelect <SealSelect
required required
disabled={name === 0}
label={intl.formatMessage({ label={intl.formatMessage({
id: 'clusters.volume.sourceType' id: 'clusters.volume.sourceType'
})} })}
@@ -328,6 +334,7 @@ const VolumeMountsForm: React.FC<{ action: PageActionType }> = ({ action }) => {
> >
<SealSelect <SealSelect
required required
disabled={name === 0}
options={hostTypeOptions} options={hostTypeOptions}
label={intl.formatMessage({ label={intl.formatMessage({
id: 'clusters.volume.hostPath.type' id: 'clusters.volume.hostPath.type'
@@ -365,23 +372,6 @@ const VolumeMountsForm: React.FC<{ action: PageActionType }> = ({ action }) => {
/> />
</Form.Item> </Form.Item>
</div> </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> </Flex>
)} )}
+5 -5
View File
@@ -146,10 +146,10 @@ export const sourceTypeOptions = [
label: 'clusters.volume.sourceType.pvc', label: 'clusters.volume.sourceType.pvc',
locale: true, locale: true,
value: 'persistentVolumeClaim' value: 'persistentVolumeClaim'
},
{
label: 'clusters.volume.sourceType.configMap',
locale: true,
value: 'configMap'
} }
// {
// label: 'clusters.volume.sourceType.configMap',
// locale: true,
// value: 'configMap'
// }
]; ];
@@ -6,11 +6,25 @@ import YamlEditor from '@/pages/_components/yaml-editor';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Button, Form } from 'antd'; import { Button, Form } from 'antd';
import React, { forwardRef, useEffect, useImperativeHandle } from 'react'; import React, { forwardRef, useEffect, useImperativeHandle } from 'react';
import styled from 'styled-components';
import K8SVolumeMount from '../components/k8s-volume-mount';
import { ProviderType, ProviderValueMap } from '../config'; import { ProviderType, ProviderValueMap } from '../config';
import { ClusterFormData as FormData } from '../config/types'; import { ClusterFormData as FormData } from '../config/types';
import schema from '../config/worker-config.json'; import schema from '../config/worker-config.json';
import { dockerConfig, kubernetesConfig } from '../config/yaml-template'; import { dockerConfig, kubernetesConfig } from '../config/yaml-template';
const Title = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
background-color: var(--ant-color-bg-container);
font-weight: 500;
font-size: 14px;
padding-top: 0px;
height: 56px;
padding-bottom: 8px;
`;
const ClusterAdvanceConfig: React.FC<{ const ClusterAdvanceConfig: React.FC<{
action: PageActionType; action: PageActionType;
provider: ProviderType; provider: ProviderType;
@@ -59,11 +73,17 @@ const ClusterAdvanceConfig: React.FC<{
> >
<SealInput.TextArea required={false} trim={false}></SealInput.TextArea> <SealInput.TextArea required={false} trim={false}></SealInput.TextArea>
</Form.Item> </Form.Item>
{provider === ProviderValueMap.Kubernetes && (
<K8SVolumeMount action={action}></K8SVolumeMount>
)}
<Title>
{intl.formatMessage({ id: 'clusters.create.workerConfig' })}
</Title>
<YamlEditor <YamlEditor
ref={editorRef} ref={editorRef}
title={ title={
<span className="flex-center"> <span className="flex-center">
<span>{`${intl.formatMessage({ id: 'clusters.create.workerConfig' })} (YAML)`}</span> <span>{`YAML`}</span>
<Button <Button
size="small" size="small"
type="link" type="link"