mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 07:49:41 +02:00
fix(app): improve resource quota error handling [EE-5933] (#10951)
This commit is contained in:
parent
488fcc7cc5
commit
6d71a28584
9 changed files with 122 additions and 50 deletions
|
@ -0,0 +1,41 @@
|
|||
import { FormikErrors } from 'formik';
|
||||
|
||||
import { BoxSelector } from '@@/BoxSelector';
|
||||
import { FormSection } from '@@/form-components/FormSection';
|
||||
import { TextTip } from '@@/Tip/TextTip';
|
||||
import { FormError } from '@@/form-components/FormError';
|
||||
|
||||
import { DeploymentType } from '../../types';
|
||||
import { getDeploymentOptions } from '../../CreateView/deploymentOptions';
|
||||
|
||||
interface Props {
|
||||
values: DeploymentType;
|
||||
onChange(values: DeploymentType): void;
|
||||
errors: FormikErrors<DeploymentType>;
|
||||
supportGlobalDeployment: boolean;
|
||||
}
|
||||
|
||||
export function AppDeploymentTypeFormSection({
|
||||
values,
|
||||
onChange,
|
||||
errors,
|
||||
supportGlobalDeployment,
|
||||
}: Props) {
|
||||
const options = getDeploymentOptions(supportGlobalDeployment);
|
||||
|
||||
return (
|
||||
<FormSection title="Deployment">
|
||||
<TextTip color="blue">
|
||||
Select how you want to deploy your application inside the cluster.
|
||||
</TextTip>
|
||||
<BoxSelector
|
||||
slim
|
||||
options={options}
|
||||
value={values}
|
||||
onChange={onChange}
|
||||
radioName="deploymentType"
|
||||
/>
|
||||
{!!errors && <FormError>{errors}</FormError>}
|
||||
</FormSection>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import { SchemaOf, mixed } from 'yup';
|
||||
|
||||
import { DeploymentType } from '../../types';
|
||||
|
||||
type ValidationData = {
|
||||
isQuotaExceeded: boolean;
|
||||
};
|
||||
|
||||
export function deploymentTypeValidation(
|
||||
validationData?: ValidationData
|
||||
): SchemaOf<DeploymentType> {
|
||||
return mixed()
|
||||
.oneOf(['Replicated', 'Global'])
|
||||
.test(
|
||||
'exhaused',
|
||||
`This application would exceed available resources. Please review resource reservations or the instance count.`,
|
||||
() => !validationData?.isQuotaExceeded
|
||||
);
|
||||
}
|
|
@ -55,14 +55,16 @@ export function ResourceReservationFormSection({
|
|||
tooltip="An instance of this application will reserve this amount of memory. If the instance memory usage exceeds the reservation, it might be subject to OOM."
|
||||
>
|
||||
<div className="col-xs-10">
|
||||
<SliderWithInput
|
||||
value={Number(values.memoryLimit) ?? 0}
|
||||
onChange={(value) => onChange({ ...values, memoryLimit: value })}
|
||||
max={maxMemoryLimit}
|
||||
step={128}
|
||||
dataCy="k8sAppCreate-memoryLimit"
|
||||
visibleTooltip
|
||||
/>
|
||||
{maxMemoryLimit > 0 && (
|
||||
<SliderWithInput
|
||||
value={Number(values.memoryLimit) ?? 0}
|
||||
onChange={(value) => onChange({ ...values, memoryLimit: value })}
|
||||
max={maxMemoryLimit}
|
||||
step={128}
|
||||
dataCy="k8sAppCreate-memoryLimit"
|
||||
visibleTooltip
|
||||
/>
|
||||
)}
|
||||
{errors?.memoryLimit && (
|
||||
<FormError className="pt-1">{errors.memoryLimit}</FormError>
|
||||
)}
|
||||
|
@ -74,21 +76,23 @@ export function ResourceReservationFormSection({
|
|||
tooltip="An instance of this application will reserve this amount of CPU. If the instance CPU usage exceeds the reservation, it might be subject to CPU throttling."
|
||||
>
|
||||
<div className="col-xs-10">
|
||||
<Slider
|
||||
onChange={(value) =>
|
||||
onChange(
|
||||
typeof value === 'number'
|
||||
? { ...values, cpuLimit: value }
|
||||
: { ...values, cpuLimit: value[0] ?? 0 }
|
||||
)
|
||||
}
|
||||
value={values.cpuLimit}
|
||||
min={0}
|
||||
max={maxCpuLimit}
|
||||
step={0.01}
|
||||
dataCy="k8sAppCreate-cpuLimitSlider"
|
||||
visibleTooltip
|
||||
/>
|
||||
{maxCpuLimit > 0 && (
|
||||
<Slider
|
||||
onChange={(value) =>
|
||||
onChange(
|
||||
typeof value === 'number'
|
||||
? { ...values, cpuLimit: value }
|
||||
: { ...values, cpuLimit: value[0] ?? 0 }
|
||||
)
|
||||
}
|
||||
value={values.cpuLimit}
|
||||
min={0}
|
||||
max={maxCpuLimit}
|
||||
step={0.1}
|
||||
dataCy="k8sAppCreate-cpuLimitSlider"
|
||||
visibleTooltip
|
||||
/>
|
||||
)}
|
||||
{errors?.cpuLimit && (
|
||||
<FormError className="pt-1">{errors.cpuLimit}</FormError>
|
||||
)}
|
||||
|
|
|
@ -5,6 +5,7 @@ import { ResourceQuotaFormValues } from './types';
|
|||
type ValidationData = {
|
||||
maxMemoryLimit: number;
|
||||
maxCpuLimit: number;
|
||||
isEnvironmentAdmin: boolean;
|
||||
};
|
||||
|
||||
export function resourceReservationValidation(
|
||||
|
@ -13,16 +14,36 @@ export function resourceReservationValidation(
|
|||
return object().shape({
|
||||
memoryLimit: number()
|
||||
.min(0)
|
||||
.test(
|
||||
'exhaused',
|
||||
`The memory capacity for this namespace has been exhausted, so you cannot deploy the application.${
|
||||
validationData?.isEnvironmentAdmin
|
||||
? ''
|
||||
: ' Contact your administrator to expand the memory capacity of the namespace.'
|
||||
}`,
|
||||
() => !!validationData && validationData.maxMemoryLimit > 0
|
||||
)
|
||||
.max(
|
||||
validationData?.maxMemoryLimit || 0,
|
||||
`Value must be between 0 and ${validationData?.maxMemoryLimit}`
|
||||
({ value }) =>
|
||||
`Value must be between 0 and ${validationData?.maxMemoryLimit}MB now - the previous value of ${value} exceeds this`
|
||||
)
|
||||
.required(),
|
||||
cpuLimit: number()
|
||||
.min(0)
|
||||
.test(
|
||||
'exhaused',
|
||||
`The CPU capacity for this namespace has been exhausted, so you cannot deploy the application.${
|
||||
validationData?.isEnvironmentAdmin
|
||||
? ''
|
||||
: ' Contact your administrator to expand the CPU capacity of the namespace.'
|
||||
}`,
|
||||
() => !!validationData && validationData.maxCpuLimit > 0
|
||||
)
|
||||
.max(
|
||||
validationData?.maxCpuLimit || 0,
|
||||
`Value must be between 0 and ${validationData?.maxCpuLimit}`
|
||||
({ value }) =>
|
||||
`Value must be between 0 and ${validationData?.maxCpuLimit} now - the previous value of ${value} exceeds this`
|
||||
)
|
||||
.required(),
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue