in frontend/src/old-pages/Configure/Storage.tsx [207:514]
export function FsxLustreSettings({index}: any) {
const {t} = useTranslation()
const isLustrePersistent2Active = useFeatureFlag('lustre_persistent2')
const isDeletionPolicyEnabled = useFeatureFlag('lustre_deletion_policy')
const useExisting =
useState(['app', 'wizard', 'storage', 'ui', index, 'useExisting']) || false
const fsxPath = useMemo(
() => [...storagePath, index, 'FsxLustreSettings'],
[index],
)
const storageCapacityPath = [...fsxPath, 'StorageCapacity']
const lustreTypePath = [...fsxPath, 'DeploymentType']
// support FSx Lustre PERSISTENT_2 only in >= 3.2.0
const lustreTypes = [
isLustrePersistent2Active ? 'PERSISTENT_2' : null,
'PERSISTENT_1',
'SCRATCH_1',
'SCRATCH_2',
].filter(Boolean)
const storageThroughputPath = [...fsxPath, 'PerUnitStorageThroughput']
const importPathPath = [...fsxPath, 'ImportPath']
const exportPathPath = [...fsxPath, 'ExportPath']
const compressionPath = [...fsxPath, 'DataCompressionType']
const deletionPolicyPath = [...fsxPath, 'DeletionPolicy']
const storageCapacity = useState(storageCapacityPath)
const lustreType = useState(lustreTypePath)
const storageThroughput = useState(storageThroughputPath)
const importPath = useState(importPathPath) || ''
const exportPath = useState(exportPathPath) || ''
const compression = useState(compressionPath)
const deletionPolicy = useState(deletionPolicyPath)
const supportedDeletionPolicies: FsxLustreDeletionPolicy[] = [
'Delete',
'Retain',
]
React.useEffect(() => {
const fsxPath = [...storagePath, index, 'FsxLustreSettings']
const storageCapacityPath = [...fsxPath, 'StorageCapacity']
const lustreTypePath = [...fsxPath, 'DeploymentType']
const deletionPolicyPath = [...fsxPath, 'DeletionPolicy']
const storageThroughputPath = [...fsxPath, 'PerUnitStorageThroughput']
if (isDeletionPolicyEnabled && deletionPolicy === null)
setState(deletionPolicyPath, DEFAULT_DELETION_POLICY)
if (storageCapacity === null && !useExisting)
setState(storageCapacityPath, 1200)
if (!storageThroughput && !useExisting) {
setDefaultStorageThroughput(lustreType, storageThroughputPath)
}
if (lustreType === null && !useExisting)
setState(
lustreTypePath,
isLustrePersistent2Active ? 'PERSISTENT_2' : 'PERSISTENT_1',
)
}, [
storageCapacity,
lustreType,
storageThroughput,
index,
useExisting,
isLustrePersistent2Active,
deletionPolicy,
isDeletionPolicyEnabled,
])
const toggleCompression = () => {
if (compression) clearState(compressionPath)
else setState(compressionPath, 'LZ4')
}
const setImportPath = (path: any) => {
if (path !== '') setState(importPathPath, path)
else clearState(importPathPath)
}
const setExportPath = (path: any) => {
if (path !== '') setState(exportPathPath, path)
else clearState(exportPathPath)
}
const capacityMin = 1200
const capacityMax = 100800
const capacityStep = 1200
const clampCapacity = (inCapacityStr: string) => {
return clamp(
parseInt(inCapacityStr),
capacityMin,
capacityMax,
capacityStep,
).toString()
}
const onDeletionPolicyChange = useCallback(
(selectedDeletionPolicy: DeletionPolicy) => {
const deletionPolicyPath = [...fsxPath, 'DeletionPolicy']
setState(deletionPolicyPath, selectedDeletionPolicy)
},
[fsxPath],
)
const throughputFooterLinks = useMemo(
() => [
{
title: t('wizard.storage.Fsx.throughput.link.title'),
href: t('wizard.storage.Fsx.throughput.link.href'),
},
],
[t],
)
const lustreTypeFooterLinks = useMemo(
() => [
{
title: t('wizard.storage.Fsx.lustreType.link.title'),
href: t('wizard.storage.Fsx.lustreType.link.href'),
},
],
[t],
)
const lustreCompressionFooterLinks = useMemo(
() => [
{
title: t('wizard.storage.Fsx.compression.link.title'),
href: t('wizard.storage.Fsx.compression.link.href'),
},
],
[t],
)
return (
<SpaceBetween direction="vertical" size="m">
<ColumnLayout columns={2}>
<FormField
label={
<Trans
i18nKey="wizard.storage.Fsx.lustreType.label"
values={{storageCapacity: storageCapacity}}
/>
}
info={
<InfoLink
helpPanel={
<TitleDescriptionHelpPanel
title={t('wizard.storage.Fsx.lustreType.label')}
description={
<Trans i18nKey="wizard.storage.Fsx.lustreType.help" />
}
footerLinks={lustreTypeFooterLinks}
/>
}
/>
}
>
<Select
selectedOption={strToOption(lustreType || 'PERSISTENT_1')}
onChange={({detail}) => {
setState(lustreTypePath, detail.selectedOption.value)
setDefaultStorageThroughput(
detail.selectedOption.value!,
storageThroughputPath,
)
}}
options={lustreTypes.map(strToOption)}
/>
</FormField>
</ColumnLayout>
<ColumnLayout columns={2}>
<FormField label={t('wizard.storage.Fsx.capacity.label')}>
<Input
value={storageCapacity}
placeholder={t('wizard.storage.Fsx.capacity.placeholder')}
step={1200}
onChange={({detail}) => {
setState(storageCapacityPath, detail.value)
}}
onBlur={_e => {
setState(storageCapacityPath, clampCapacity(storageCapacity))
}}
type="number"
/>
</FormField>
</ColumnLayout>
{lustreType === 'PERSISTENT_1' && (
<>
<ColumnLayout columns={2}>
<FormField
label={t('wizard.storage.Fsx.import.label')}
info={
<InfoLink
helpPanel={
<TitleDescriptionHelpPanel
title={t('wizard.storage.Fsx.import.label')}
description={
<Trans i18nKey="wizard.storage.Fsx.import.help">
<a
rel="noreferrer"
target="_blank"
href="https://docs.aws.amazon.com/parallelcluster/latest/ug/SharedStorage-v3.html#yaml-SharedStorage-FsxLustreSettings-ImportPath"
></a>
</Trans>
}
/>
}
/>
}
>
<Input
placeholder={t('wizard.storage.Fsx.import.placeholder')}
value={importPath}
onChange={({detail}) => setImportPath(detail.value)}
/>
</FormField>
</ColumnLayout>
<ColumnLayout columns={2}>
<FormField
label={t('wizard.storage.Fsx.export.label')}
info={
<InfoLink
helpPanel={
<TitleDescriptionHelpPanel
title={t('wizard.storage.Fsx.export.label')}
description={
<Trans i18nKey="wizard.storage.Fsx.export.help">
<a
rel="noreferrer"
target="_blank"
href="https://docs.aws.amazon.com/parallelcluster/latest/ug/SharedStorage-v3.html#yaml-SharedStorage-FsxLustreSettings-ExportPath"
></a>
</Trans>
}
/>
}
/>
}
>
<Input
placeholder={t('wizard.storage.Fsx.export.placeholder')}
value={exportPath}
onChange={({detail}) => {
setExportPath(detail.value)
}}
/>
</FormField>
</ColumnLayout>
</>
)}
{isPersistentFsx(lustreType) && (
<ColumnLayout columns={2}>
<FormField
label={t('wizard.storage.Fsx.throughput.label')}
info={
<InfoLink
helpPanel={
<TitleDescriptionHelpPanel
title={t('wizard.storage.Fsx.throughput.label')}
description={t('wizard.storage.Fsx.throughput.help')}
footerLinks={throughputFooterLinks}
/>
}
/>
}
>
<Select
selectedOption={strToOption(storageThroughput || '')}
onChange={({detail}) => {
setState(storageThroughputPath, detail.selectedOption.value)
}}
options={
lustreType == 'PERSISTENT_1'
? storageThroughputsP1.map(strToOption)
: storageThroughputsP2.map(strToOption)
}
/>
</FormField>
</ColumnLayout>
)}
<SpaceBetween direction="horizontal" size="xs">
<Checkbox checked={compression !== null} onChange={toggleCompression}>
<Trans i18nKey="wizard.storage.Fsx.compression.label" />
</Checkbox>
<InfoLink
helpPanel={
<TitleDescriptionHelpPanel
title={t('wizard.storage.Fsx.compression.label')}
description={t('wizard.storage.Fsx.compression.help')}
footerLinks={lustreCompressionFooterLinks}
/>
}
/>
</SpaceBetween>
{isDeletionPolicyEnabled && (
<ColumnLayout columns={2}>
<DeletionPolicyFormField
options={supportedDeletionPolicies}
value={deletionPolicy}
onDeletionPolicyChange={onDeletionPolicyChange}
/>
</ColumnLayout>
)}
</SpaceBetween>
)
}