fix(container): runtime and resources issues EE-6306 (#10611)

pull/10692/head
cmeng 1 year ago committed by GitHub
parent 1bcbfb8213
commit dc574af734
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -138,14 +138,14 @@ function CreateForm() {
});
if (!confirmed) {
return;
return false;
}
}
const registry = getRegistry(values.image, registriesQuery.data || []);
const config = toRequest(values, registry, hideCapabilities);
mutation.mutate(
return mutation.mutate(
{ config, environment, values, registry, oldContainer, extraNetworks },
{
onSuccess() {

@ -186,13 +186,13 @@ export function InnerForm({
? (values) => (
<EditResourcesForm
initialValues={values}
redeploy={(values) => {
onChange={(values) => {
setFieldValue(
'resources.resources',
values
);
return submitForm();
}}
redeploy={submitForm}
isImageInvalid={!!errors?.image}
/>
)

@ -1,7 +1,10 @@
import { Formik } from 'formik';
import { useMutation } from 'react-query';
import { useCurrentStateAndParams } from '@uirouter/react';
import { useState } from 'react';
import { FormikHelpers } from 'formik/dist/types';
import { invalidateContainer } from '@/react/docker/containers/queries/container';
import { notifySuccess } from '@/portainer/services/notifications';
import { mutationOptions, withError } from '@/react-tools/react-query';
import { useSystemLimits } from '@/react/docker/proxy/queries/useInfo';
@ -21,17 +24,22 @@ import {
import { toConfigCpu, toConfigMemory } from './memory-utils';
export function EditResourcesForm({
onChange,
redeploy,
initialValues,
isImageInvalid,
}: {
initialValues: Values;
redeploy: (values: Values) => Promise<void>;
onChange: (values: Values) => void;
redeploy: () => Promise<boolean>;
isImageInvalid: boolean;
}) {
const {
params: { from: containerId },
} = useCurrentStateAndParams();
const [savedInitValues, setSavedInitValues] = useState(initialValues);
if (!containerId || typeof containerId !== 'string') {
throw new Error('missing parameter "from"');
}
@ -54,7 +62,10 @@ export function EditResourcesForm({
<div className="edit-resources p-5">
<ResourceFieldset
values={values}
onChange={setValues}
onChange={(values) => {
onChange(values);
setValues(values);
}}
errors={errors}
/>
@ -82,28 +93,44 @@ export function EditResourcesForm({
</Formik>
);
function handleSubmit(values: Values) {
function handleSubmit(values: Values, helper: FormikHelpers<Values>) {
updateMutation.mutate(values, {
onSuccess: () => {
notifySuccess('Success', 'Limits updated');
onSuccess: (data) => {
if (data) {
notifySuccess('Success', 'Limits updated');
helper.resetForm({ values: initialValues });
invalidateContainer(environmentId, containerId);
}
},
});
}
function settingUnlimitedResources(values: Values) {
return (
(initialValues.limit > 0 && values.limit === 0) ||
(initialValues.reservation > 0 && values.reservation === 0) ||
(initialValues.cpu > 0 && values.cpu === 0)
(savedInitValues.limit > 0 && values.limit === 0) ||
(savedInitValues.reservation > 0 && values.reservation === 0) ||
(savedInitValues.cpu > 0 && values.cpu === 0)
);
}
// return true only if limits are updated
// return false otherwise(container recreated, user canceled container recreation, etc.)
async function updateLimitsOrCreate(values: Values) {
if (settingUnlimitedResources(values)) {
return redeploy(values);
const ret = await redeploy();
if (ret === false) {
return false;
}
setSavedInitValues(values);
return false;
}
return updateLimits(environmentId, containerId, values);
setSavedInitValues(values);
await updateLimits(environmentId, containerId, values);
return true;
}
}

@ -135,7 +135,7 @@ export function GpuFieldset({
checked={values.enabled && !!enableGpuManagement}
onChange={toggleEnableGpu}
className="ml-2"
disabled={enableGpuManagement === false}
disabled={!enableGpuManagement}
/>
</div>
{enableGpuManagement && values.enabled && (

@ -35,6 +35,7 @@ export function ResourceFieldset({
<FormSection title="Resources">
<FormControl label="Memory reservation (MB)" errors={errors?.reservation}>
<SliderWithInput
visibleTooltip
value={values.reservation}
onChange={(value) => onChange({ ...values, reservation: value })}
max={maxMemory}
@ -45,6 +46,7 @@ export function ResourceFieldset({
<FormControl label="Memory limit (MB)" errors={errors?.limit}>
<SliderWithInput
visibleTooltip
value={values.limit}
onChange={(value) => onChange({ ...values, limit: value })}
max={maxMemory}
@ -55,6 +57,7 @@ export function ResourceFieldset({
<FormControl label="Maximum CPU usage" errors={errors?.cpu}>
<Slider
visibleTooltip
value={values.cpu}
onChange={(value) =>
onChange({

@ -12,6 +12,7 @@ import { PortainerResponse } from '@/react/docker/types';
import axios, { parseAxiosError } from '@/portainer/services/axios';
import { ContainerId } from '@/react/docker/containers/types';
import { EnvironmentId } from '@/react/portainer/environments/types';
import { queryClient } from '@/react-tools/react-query';
import { urlBuilder } from '../containers.service';
@ -89,6 +90,15 @@ export function useContainer(
);
}
export function invalidateContainer(
environmentId: EnvironmentId,
containerId?: ContainerId
) {
return queryClient.invalidateQueries(
containerId ? queryKeys.container(environmentId, containerId) : []
);
}
export type ContainerResponse = PortainerResponse<ContainerJSON>;
async function getContainer(

Loading…
Cancel
Save