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:
Joshen LimandAlaister Young authored and GitHub committed 2025-10-01 19:19:09 +00:00
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
@@ -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')