mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
Fix upgrading compute for provider (#39156)
* Fix upgrading compute for provider * Add flag for disk management section in database settings --------- Co-authored-by: Alaister Young <a@alaisteryoung.com>
This commit is contained in:
1 parent
8e3419834a
commit
8cc39ebfbc
5 files changed
+74
-35
No files matched your search
@@ -1,3 +1,4 @@
|
||||
import { CloudProvider } from 'shared-data'
|
||||
import { z } from 'zod'
|
||||
import { ComputeInstanceAddonVariantId } from './DiskManagement.types'
|
||||
import {
|
||||
@@ -9,7 +10,6 @@ import {
|
||||
formatNumber,
|
||||
} from './DiskManagement.utils'
|
||||
import { DISK_LIMITS, DiskType } from './ui/DiskManagement.constants'
|
||||
import { CloudProvider } from 'shared-data'
|
||||
|
||||
const baseSchema = z.object({
|
||||
storageType: z.enum(['io2', 'gp3']).describe('Type of storage: io2 or gp3'),
|
||||
@@ -41,13 +41,22 @@ const baseSchema = z.object({
|
||||
.nullable(),
|
||||
})
|
||||
|
||||
export const CreateDiskStorageSchema = (defaultTotalSize: number, cloudProvider: CloudProvider) => {
|
||||
export const CreateDiskStorageSchema = ({
|
||||
defaultTotalSize,
|
||||
cloudProvider,
|
||||
}: {
|
||||
defaultTotalSize: number
|
||||
cloudProvider: CloudProvider
|
||||
}) => {
|
||||
const isFlyProject = cloudProvider === 'FLY'
|
||||
const isAwsNimbusProject = cloudProvider === 'AWS_NIMBUS'
|
||||
|
||||
const validateDiskConfiguration = !isFlyProject && !isAwsNimbusProject
|
||||
|
||||
const schema = baseSchema.superRefine((data, ctx) => {
|
||||
const { storageType, totalSize, provisionedIOPS, throughput, maxSizeGb } = data
|
||||
|
||||
if (!isFlyProject && totalSize < 8) {
|
||||
if (validateDiskConfiguration && totalSize < 8) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: 'Allocated disk size must be at least 8 GB.',
|
||||
@@ -55,7 +64,7 @@ export const CreateDiskStorageSchema = (defaultTotalSize: number, cloudProvider:
|
||||
})
|
||||
}
|
||||
|
||||
if (!isFlyProject && totalSize < defaultTotalSize) {
|
||||
if (validateDiskConfiguration && totalSize < defaultTotalSize) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Disk size cannot be reduced in size. Reduce your database size and then head to the Infrastructure settings and go through a Postgres version upgrade to right-size your disk.`,
|
||||
@@ -64,7 +73,7 @@ export const CreateDiskStorageSchema = (defaultTotalSize: number, cloudProvider:
|
||||
}
|
||||
|
||||
// Validate maxSizeGb cannot be lower than totalSize
|
||||
if (!isFlyProject && !!maxSizeGb && maxSizeGb < totalSize) {
|
||||
if (validateDiskConfiguration && !!maxSizeGb && maxSizeGb < totalSize) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Max disk size cannot be lower than the current disk size. Must be at least ${formatNumber(totalSize)} GB.`,
|
||||
@@ -72,7 +81,7 @@ export const CreateDiskStorageSchema = (defaultTotalSize: number, cloudProvider:
|
||||
})
|
||||
}
|
||||
|
||||
if (!isFlyProject && storageType === 'io2') {
|
||||
if (validateDiskConfiguration && storageType === 'io2') {
|
||||
// Validation rules for io2
|
||||
|
||||
if (provisionedIOPS > DISK_LIMITS[DiskType.IO2].maxIops) {
|
||||
@@ -129,7 +138,7 @@ export const CreateDiskStorageSchema = (defaultTotalSize: number, cloudProvider:
|
||||
}
|
||||
}
|
||||
|
||||
if (!isFlyProject && storageType === 'gp3') {
|
||||
if (validateDiskConfiguration && storageType === 'gp3') {
|
||||
const maxIopsAllowedForDiskSizeWithGp3 = calculateMaxIopsAllowedForDiskSizeWithGp3(totalSize)
|
||||
|
||||
if (provisionedIOPS > DISK_LIMITS[DiskType.GP3].maxIops) {
|
||||
|
||||
@@ -30,6 +30,7 @@ import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization
|
||||
import {
|
||||
useIsAwsCloudProvider,
|
||||
useIsAwsK8sCloudProvider,
|
||||
useIsAwsNimbusCloudProvider,
|
||||
useSelectedProjectQuery,
|
||||
} from 'hooks/misc/useSelectedProject'
|
||||
import { DOCS_URL, GB, PROJECT_STATUS } from 'lib/constants'
|
||||
@@ -78,6 +79,7 @@ export function DiskManagementForm() {
|
||||
const isReadOnlyMode = projectResourceWarnings?.is_readonly_mode_enabled
|
||||
const isAws = useIsAwsCloudProvider()
|
||||
const isAwsK8s = useIsAwsK8sCloudProvider()
|
||||
const isAwsNimbus = useIsAwsNimbusCloudProvider()
|
||||
|
||||
const { can: canUpdateDiskConfiguration, isSuccess: isPermissionsLoaded } =
|
||||
useAsyncCheckPermissions(PermissionAction.UPDATE, 'projects', {
|
||||
@@ -156,7 +158,10 @@ export function DiskManagementForm() {
|
||||
|
||||
const form = useForm<DiskStorageSchemaType>({
|
||||
resolver: zodResolver(
|
||||
CreateDiskStorageSchema(defaultValues.totalSize, project?.cloud_provider as CloudProvider)
|
||||
CreateDiskStorageSchema({
|
||||
defaultTotalSize: defaultValues.totalSize,
|
||||
cloudProvider: project?.cloud_provider as CloudProvider,
|
||||
})
|
||||
),
|
||||
defaultValues,
|
||||
mode: 'onBlur',
|
||||
@@ -241,12 +246,14 @@ export function DiskManagementForm() {
|
||||
let willUpdateDiskConfiguration = false
|
||||
setMessageState(null)
|
||||
|
||||
// [Joshen] Skip disk configuration related stuff for AWS Nimbus
|
||||
try {
|
||||
if (
|
||||
payload.storageType !== form.formState.defaultValues?.storageType ||
|
||||
payload.provisionedIOPS !== form.formState.defaultValues?.provisionedIOPS ||
|
||||
payload.throughput !== form.formState.defaultValues?.throughput ||
|
||||
payload.totalSize !== form.formState.defaultValues?.totalSize
|
||||
!isAwsNimbus &&
|
||||
(payload.storageType !== form.formState.defaultValues?.storageType ||
|
||||
payload.provisionedIOPS !== form.formState.defaultValues?.provisionedIOPS ||
|
||||
payload.throughput !== form.formState.defaultValues?.throughput ||
|
||||
payload.totalSize !== form.formState.defaultValues?.totalSize)
|
||||
) {
|
||||
willUpdateDiskConfiguration = true
|
||||
|
||||
@@ -260,9 +267,10 @@ export function DiskManagementForm() {
|
||||
}
|
||||
|
||||
if (
|
||||
payload.growthPercent !== form.formState.defaultValues?.growthPercent ||
|
||||
payload.minIncrementGb !== form.formState.defaultValues?.minIncrementGb ||
|
||||
payload.maxSizeGb !== form.formState.defaultValues?.maxSizeGb
|
||||
!isAwsNimbus &&
|
||||
(payload.growthPercent !== form.formState.defaultValues?.growthPercent ||
|
||||
payload.minIncrementGb !== form.formState.defaultValues?.minIncrementGb ||
|
||||
payload.maxSizeGb !== form.formState.defaultValues?.maxSizeGb)
|
||||
) {
|
||||
await updateDiskAutoscaleConfig({
|
||||
projectRef,
|
||||
@@ -344,12 +352,16 @@ export function DiskManagementForm() {
|
||||
</div>
|
||||
) : null}
|
||||
<Separator />
|
||||
|
||||
<ComputeSizeField form={form} disabled={disableComputeInputs} />
|
||||
<Separator />
|
||||
|
||||
{!(isAws || isAwsNimbus) && <Separator />}
|
||||
|
||||
<SpendCapDisabledSection />
|
||||
|
||||
<NoticeBar
|
||||
type="default"
|
||||
visible={!isAws}
|
||||
visible={!(isAws || isAwsNimbus)}
|
||||
title="Disk configuration is only available for projects in the AWS cloud provider"
|
||||
description={
|
||||
isAwsK8s
|
||||
|
||||
+10
-6
@@ -7,7 +7,7 @@ import { ButtonTooltip } from 'components/ui/ButtonTooltip'
|
||||
import { useProjectAddonsQuery } from 'data/subscriptions/project-addons-query'
|
||||
import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization'
|
||||
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
|
||||
import { useIsAwsNimbusCloudProvider, useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
|
||||
import { formatCurrency } from 'lib/helpers'
|
||||
import {
|
||||
Alert_Shadcn_,
|
||||
@@ -150,6 +150,7 @@ export const DiskManagementReviewAndSubmitDialog = ({
|
||||
}: DiskSizeMeterProps) => {
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const { data: org } = useSelectedOrganizationQuery()
|
||||
const isAwsNimbus = useIsAwsNimbusCloudProvider()
|
||||
|
||||
const { formState, getValues } = form
|
||||
|
||||
@@ -213,19 +214,22 @@ export const DiskManagementReviewAndSubmitDialog = ({
|
||||
const hasComputeChanges =
|
||||
form.formState.defaultValues?.computeSize !== form.getValues('computeSize')
|
||||
const hasTotalSizeChanges =
|
||||
form.formState.defaultValues?.totalSize !== form.getValues('totalSize')
|
||||
!isAwsNimbus && form.formState.defaultValues?.totalSize !== form.getValues('totalSize')
|
||||
const hasStorageTypeChanges =
|
||||
form.formState.defaultValues?.storageType !== form.getValues('storageType')
|
||||
!isAwsNimbus && form.formState.defaultValues?.storageType !== form.getValues('storageType')
|
||||
const hasThroughputChanges =
|
||||
form.formState.defaultValues?.throughput !== form.getValues('throughput')
|
||||
!isAwsNimbus && form.formState.defaultValues?.throughput !== form.getValues('throughput')
|
||||
const hasIOPSChanges =
|
||||
!isAwsNimbus &&
|
||||
form.formState.defaultValues?.provisionedIOPS !== form.getValues('provisionedIOPS')
|
||||
|
||||
const hasGrowthPercentChanges =
|
||||
form.formState.defaultValues?.growthPercent !== form.getValues('growthPercent')
|
||||
!isAwsNimbus && form.formState.defaultValues?.growthPercent !== form.getValues('growthPercent')
|
||||
const hasMinIncrementChanges =
|
||||
!isAwsNimbus &&
|
||||
form.formState.defaultValues?.minIncrementGb !== form.getValues('minIncrementGb')
|
||||
const hasMaxSizeChanges = form.formState.defaultValues?.maxSizeGb !== form.getValues('maxSizeGb')
|
||||
const hasMaxSizeChanges =
|
||||
!isAwsNimbus && form.formState.defaultValues?.maxSizeGb !== form.getValues('maxSizeGb')
|
||||
|
||||
const hasDiskConfigChanges =
|
||||
hasIOPSChanges ||
|
||||
|
||||
@@ -13,8 +13,9 @@ import Panel from 'components/ui/Panel'
|
||||
import { useProjectDiskResizeMutation } from 'data/config/project-disk-resize-mutation'
|
||||
import { useDatabaseSizeQuery } from 'data/database/database-size-query'
|
||||
import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
|
||||
import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization'
|
||||
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
|
||||
import { useIsAwsNimbusCloudProvider, useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
|
||||
import { useUrlState } from 'hooks/ui/useUrlState'
|
||||
import { DOCS_URL } from 'lib/constants'
|
||||
import { formatBytes } from 'lib/helpers'
|
||||
@@ -29,6 +30,9 @@ const DiskSizeConfiguration = ({ disabled = false }: DiskSizeConfigurationProps)
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const { data: organization } = useSelectedOrganizationQuery()
|
||||
|
||||
const isAwsNimbus = useIsAwsNimbusCloudProvider()
|
||||
const { reportsAll } = useIsFeatureEnabled(['reports:all'])
|
||||
|
||||
const [{ show_increase_disk_size_modal }, setUrlParams] = useUrlState()
|
||||
const showIncreaseDiskSizeModal = show_increase_disk_size_modal === 'true'
|
||||
const setShowIncreaseDiskSizeModal = (value: SetStateAction<boolean>) => {
|
||||
@@ -80,9 +84,10 @@ const DiskSizeConfiguration = ({ disabled = false }: DiskSizeConfigurationProps)
|
||||
Supabase employs auto-scaling storage and allows for manual disk size
|
||||
adjustments when necessary
|
||||
</p>
|
||||
<div className="flex items-end justify-end">
|
||||
{!isAwsNimbus && (
|
||||
<ButtonTooltip
|
||||
type="default"
|
||||
className="w-min ml-auto"
|
||||
disabled={!canUpdateDiskSizeConfig || disabled}
|
||||
onClick={() => setShowIncreaseDiskSizeModal(true)}
|
||||
tooltip={{
|
||||
@@ -96,7 +101,7 @@ const DiskSizeConfiguration = ({ disabled = false }: DiskSizeConfigurationProps)
|
||||
>
|
||||
Increase disk size
|
||||
</ButtonTooltip>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-12 gap-2 mt-12 items-start">
|
||||
@@ -112,15 +117,17 @@ const DiskSizeConfiguration = ({ disabled = false }: DiskSizeConfigurationProps)
|
||||
<span className="text-lg">{currentDiskSize} GB</span>
|
||||
</div>
|
||||
|
||||
<div className="col-span-2 mt-4">
|
||||
<Button asChild type="default" iconRight={<ExternalLink size={14} />}>
|
||||
<Link
|
||||
href={`/project/${projectRef}/reports/database#database-size-report`}
|
||||
>
|
||||
View detailed summary
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
{reportsAll && (
|
||||
<div className="col-span-2 mt-4">
|
||||
<Button asChild type="default" iconRight={<ExternalLink size={14} />}>
|
||||
<Link
|
||||
href={`/project/${projectRef}/reports/database#database-size-report`}
|
||||
>
|
||||
View detailed summary
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="col-span-8">
|
||||
|
||||
@@ -53,6 +53,13 @@ export const useIsAwsK8sCloudProvider = () => {
|
||||
return isAwsK8s
|
||||
}
|
||||
|
||||
export const useIsAwsNimbusCloudProvider = () => {
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const isAwsNimbus = project?.cloud_provider === PROVIDERS.AWS_NIMBUS.id
|
||||
|
||||
return isAwsNimbus
|
||||
}
|
||||
|
||||
export const useIsOrioleDb = () => {
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const isOrioleDb = project?.dbVersion?.endsWith('orioledb')
|
||||
|
||||
Reference in new issue
Block a user