2021-09-13 05:15:45 +01:00
import { Server } from '@/api/admin/servers/getServers' ;
import ServerDeleteButton from '@/components/admin/servers/ServerDeleteButton' ;
2021-10-09 20:02:32 +01:00
import { faBalanceScale } from '@fortawesome/free-solid-svg-icons' ;
2021-05-20 23:00:46 +01:00
import React from 'react' ;
import AdminBox from '@/components/admin/AdminBox' ;
2021-09-13 05:15:45 +01:00
import { useHistory } from 'react-router-dom' ;
2021-05-20 23:00:46 +01:00
import tw from 'twin.macro' ;
import { object } from 'yup' ;
2021-09-13 05:15:45 +01:00
import updateServer , { Values } from '@/api/admin/servers/updateServer' ;
2021-05-20 23:00:46 +01:00
import Field from '@/components/elements/Field' ;
import SpinnerOverlay from '@/components/elements/SpinnerOverlay' ;
import { Form , Formik , FormikHelpers , useFormikContext } from 'formik' ;
2021-09-16 21:59:22 +01:00
import { Context , ServerIncludes } from '@/components/admin/servers/ServerRouter' ;
2021-05-20 23:00:46 +01:00
import { ApplicationStore } from '@/state' ;
import { Actions , useStoreActions } from 'easy-peasy' ;
import Button from '@/components/elements/Button' ;
import FormikSwitch from '@/components/elements/FormikSwitch' ;
2021-10-04 00:10:06 +01:00
import BaseSettingsBox from '@/components/admin/servers/settings/BaseSettingsBox' ;
2021-10-04 02:38:45 +01:00
import FeatureLimitsBox from '@/components/admin/servers/settings/FeatureLimitsBox' ;
2021-10-09 20:02:32 +01:00
import NetworkingBox from '@/components/admin/servers/settings/NetworkingBox' ;
2021-09-16 21:59:22 +01:00
2021-09-13 05:15:45 +01:00
export function ServerResourceContainer ( ) {
2021-05-20 23:00:46 +01:00
const { isSubmitting } = useFormikContext ( ) ;
return (
2021-09-15 22:37:17 +01:00
< AdminBox icon = { faBalanceScale } title = { 'Resources' } css = { tw ` relative w-full ` } >
2021-05-20 23:00:46 +01:00
< SpinnerOverlay visible = { isSubmitting } / >
2021-08-05 05:16:52 +01:00
< div css = { tw ` mb-6 md:w-full md:flex md:flex-row ` } >
< div css = { tw ` mb-6 md:w-full md:flex md:flex-col md:mr-4 md:mb-0 ` } >
< Field
2021-09-16 21:59:22 +01:00
id = { 'limits.cpu' }
name = { 'limits.cpu' }
2021-08-05 05:16:52 +01:00
label = { 'CPU Limit' }
2021-09-15 22:37:17 +01:00
type = { 'text' }
description = { 'Each thread on the system is considered to be 100%. Setting this value to 0 will allow the server to use CPU time without restriction.' }
2021-08-05 05:16:52 +01:00
/ >
2021-05-20 23:00:46 +01:00
< / div >
2021-08-05 05:16:52 +01:00
< div css = { tw ` mb-6 md:w-full md:flex md:flex-col md:ml-4 md:mb-0 ` } >
< Field
2021-09-16 21:59:22 +01:00
id = { 'limits.threads' }
name = { 'limits.threads' }
2021-08-05 05:16:52 +01:00
label = { 'CPU Pinning' }
2021-09-15 22:37:17 +01:00
type = { 'text' }
description = { 'Advanced: Enter the specific CPU cores that this server can run on, or leave blank to allow all cores. This can be a single number, and or a comma seperated list, and or a dashed range. Example: 0, 0-1,3, or 0,1,3,4. It is recommended to leave this value blank and let the CPU handle balancing the load.' }
2021-08-05 05:16:52 +01:00
/ >
2021-05-20 23:00:46 +01:00
< / div >
2021-08-05 05:16:52 +01:00
< / div >
< div css = { tw ` mb-6 md:w-full md:flex md:flex-row ` } >
< div css = { tw ` mb-6 md:w-full md:flex md:flex-col md:mr-4 md:mb-0 ` } >
< Field
2021-09-16 21:59:22 +01:00
id = { 'limits.memory' }
name = { 'limits.memory' }
2021-08-05 05:16:52 +01:00
label = { 'Memory Limit' }
type = { 'number' }
description = { 'The maximum amount of memory allowed for this container. Setting this to 0 will allow unlimited memory in a container.' }
/ >
2021-05-20 23:00:46 +01:00
< / div >
2021-08-05 05:16:52 +01:00
< div css = { tw ` mb-6 md:w-full md:flex md:flex-col md:ml-4 md:mb-0 ` } >
< Field
2021-09-16 21:59:22 +01:00
id = { 'limits.swap' }
name = { 'limits.swap' }
2021-08-05 05:16:52 +01:00
label = { 'Swap Limit' }
type = { 'number' }
/ >
< / div >
< / div >
< div css = { tw ` mb-6 md:w-full md:flex md:flex-row ` } >
< div css = { tw ` mb-6 md:w-full md:flex md:flex-col md:mr-4 md:mb-0 ` } >
< Field
2021-09-16 21:59:22 +01:00
id = { 'limits.disk' }
name = { 'limits.disk' }
2021-08-05 05:16:52 +01:00
label = { 'Disk Limit' }
type = { 'number' }
description = { 'This server will not be allowed to boot if it is using more than this amount of space. If a server goes over this limit while running it will be safely stopped and locked until enough space is available. Set to 0 to allow unlimited disk usage.' }
/ >
2021-05-20 23:00:46 +01:00
< / div >
2021-08-05 05:16:52 +01:00
< div css = { tw ` mb-6 md:w-full md:flex md:flex-col md:ml-4 md:mb-0 ` } >
< Field
2021-09-16 21:59:22 +01:00
id = { 'limits.io' }
name = { 'limits.io' }
2021-08-05 05:16:52 +01:00
label = { 'Block IO Proportion' }
type = { 'number' }
description = { 'Advanced: The IO performance of this server relative to other running containers on the system. Value should be between 10 and 1000.' }
/ >
< / div >
< / div >
2021-09-18 19:26:36 +01:00
< div css = { tw ` mb-2 md:w-full md:flex md:flex-row ` } >
2021-09-15 22:37:17 +01:00
< div css = { tw ` bg-neutral-800 border border-neutral-900 shadow-inner p-4 rounded ` } >
2021-08-05 05:16:52 +01:00
< FormikSwitch
2021-09-16 21:59:22 +01:00
name = { 'limits.oomDisabled' }
2021-08-05 05:16:52 +01:00
label = { 'Out of Memory Killer' }
2021-09-15 22:37:17 +01:00
description = { 'Enabling the Out of Memory Killer may cause server processes to exit unexpectedly.' }
2021-08-05 05:16:52 +01:00
/ >
< / div >
< / div >
2021-05-20 23:00:46 +01:00
< / AdminBox >
) ;
2021-09-13 05:15:45 +01:00
}
2021-05-20 23:00:46 +01:00
2021-09-16 04:19:39 +01:00
export default function ServerSettingsContainer2 ( { server } : { server : Server } ) {
2021-09-13 05:15:45 +01:00
const history = useHistory ( ) ;
2021-05-20 23:00:46 +01:00
2021-10-09 20:02:32 +01:00
const {
clearFlashes ,
clearAndAddHttpError ,
} = useStoreActions ( ( actions : Actions < ApplicationStore > ) = > actions . flashes ) ;
2021-05-20 23:00:46 +01:00
const setServer = Context . useStoreActions ( actions = > actions . setServer ) ;
2021-09-16 21:59:22 +01:00
const submit = ( values : Values , { setSubmitting , setFieldValue } : FormikHelpers < Values > ) = > {
2021-05-20 23:00:46 +01:00
clearFlashes ( 'server' ) ;
2021-09-16 21:59:22 +01:00
// This value is inverted to have the switch be on when the
// OOM Killer is enabled, rather than when disabled.
values . limits . oomDisabled = ! values . limits . oomDisabled ;
updateServer ( server . id , values , ServerIncludes )
2021-09-15 22:37:17 +01:00
. then ( s = > {
setServer ( { . . . server , . . . s } ) ;
// TODO: Figure out how to properly clear react-selects for allocations.
setFieldValue ( 'addAllocations' , [ ] ) ;
setFieldValue ( 'removeAllocations' , [ ] ) ;
} )
2021-05-20 23:00:46 +01:00
. catch ( error = > {
console . error ( error ) ;
clearAndAddHttpError ( { key : 'server' , error } ) ;
} )
. then ( ( ) = > setSubmitting ( false ) ) ;
} ;
return (
< Formik
onSubmit = { submit }
initialValues = { {
externalId : server.externalId || '' ,
name : server.name ,
2021-09-13 05:15:45 +01:00
ownerId : server.ownerId ,
2021-05-20 23:00:46 +01:00
2021-09-16 21:59:22 +01:00
limits : {
memory : server.limits.memory ,
swap : server.limits.swap ,
disk : server.limits.disk ,
io : server.limits.io ,
cpu : server.limits.cpu ,
threads : server.limits.threads || '' ,
// This value is inverted to have the switch be on when the
// OOM Killer is enabled, rather than when disabled.
oomDisabled : ! server . limits . oomDisabled ,
} ,
featureLimits : {
allocations : server.featureLimits.allocations ,
backups : server.featureLimits.backups ,
databases : server.featureLimits.databases ,
} ,
2021-09-15 22:37:17 +01:00
allocationId : server.allocationId ,
addAllocations : [ ] as number [ ] ,
removeAllocations : [ ] as number [ ] ,
2021-05-20 23:00:46 +01:00
} }
2021-10-09 20:02:32 +01:00
validationSchema = { object ( ) . shape ( { } ) }
2021-05-20 23:00:46 +01:00
>
2021-09-15 18:09:54 +01:00
{ ( { isSubmitting , isValid } ) = > (
< Form >
2021-09-18 19:26:36 +01:00
< div css = { tw ` grid grid-cols-1 md:grid-cols-2 gap-y-6 gap-x-8 mb-16 ` } >
2021-10-04 01:26:44 +01:00
< div css = { tw ` grid grid-cols-1 gap-y-6 ` } >
< BaseSettingsBox / >
2021-10-04 02:38:45 +01:00
< FeatureLimitsBox / >
2021-10-09 20:02:32 +01:00
< NetworkingBox / >
2021-09-16 04:19:39 +01:00
< / div >
< div css = { tw ` flex flex-col ` } >
2021-10-04 01:26:44 +01:00
< ServerResourceContainer / >
< div css = { tw ` bg-neutral-700 rounded shadow-md py-2 px-6 mt-6 ` } >
2021-09-15 18:09:54 +01:00
< div css = { tw ` flex flex-row ` } >
< ServerDeleteButton
serverId = { server ? . id }
onDeleted = { ( ) = > history . push ( '/admin/servers' ) }
/ >
2021-10-09 20:02:32 +01:00
< Button
type = "submit"
size = "small"
css = { tw ` ml-auto ` }
disabled = { isSubmitting || ! isValid }
>
2021-09-15 18:09:54 +01:00
Save Changes
< / Button >
2021-05-20 23:00:46 +01:00
< / div >
< / div >
< / div >
2021-09-15 18:09:54 +01:00
< / div >
< / Form >
) }
2021-05-20 23:00:46 +01:00
< / Formik >
) ;
2021-09-13 05:15:45 +01:00
}