import { Formik } from 'formik'; import { useMutation } from 'react-query'; import { useCurrentStateAndParams } from '@uirouter/react'; import { notifySuccess } from '@/portainer/services/notifications'; import { mutationOptions, withError } from '@/react-tools/react-query'; import { useSystemLimits } from '@/react/docker/proxy/queries/useInfo'; import { useEnvironmentId } from '@/react/hooks/useEnvironmentId'; import { EnvironmentId } from '@/react/portainer/environments/types'; import { LoadingButton } from '@@/buttons'; import { TextTip } from '@@/Tip/TextTip'; import { updateContainer } from '../../queries/useUpdateContainer'; import { ResourceFieldset, resourcesValidation, Values, } from './ResourcesFieldset'; import { toConfigCpu, toConfigMemory } from './memory-utils'; export function EditResourcesForm({ redeploy, initialValues, isImageInvalid, }: { initialValues: Values; redeploy: (values: Values) => Promise; isImageInvalid: boolean; }) { const { params: { from: containerId }, } = useCurrentStateAndParams(); if (!containerId || typeof containerId !== 'string') { throw new Error('missing parameter "from"'); } const updateMutation = useMutation( updateLimitsOrCreate, mutationOptions(withError('Failed to update limits')) ); const environmentId = useEnvironmentId(); const systemLimits = useSystemLimits(environmentId); return ( resourcesValidation(systemLimits)} > {({ values, errors, setValues, dirty, submitForm }) => (
Update Limits {settingUnlimitedResources(values) && ( Updating any resource value to 'unlimited' will redeploy this container. )}
)}
); function handleSubmit(values: Values) { updateMutation.mutate(values, { onSuccess: () => { notifySuccess('Success', 'Limits updated'); }, }); } function settingUnlimitedResources(values: Values) { return ( (initialValues.limit > 0 && values.limit === 0) || (initialValues.reservation > 0 && values.reservation === 0) || (initialValues.cpu > 0 && values.cpu === 0) ); } async function updateLimitsOrCreate(values: Values) { if (settingUnlimitedResources(values)) { return redeploy(values); } return updateLimits(environmentId, containerId, values); } } async function updateLimits( environmentId: EnvironmentId, containerId: string, values: Values ) { return updateContainer(environmentId, containerId, { // MemorySwap: must be set // -1: non limits, 0: treated as unset(cause update error). MemorySwap: -1, MemoryReservation: toConfigMemory(values.reservation), Memory: toConfigMemory(values.limit), NanoCpus: toConfigCpu(values.cpu), }); }