-
Notifications
You must be signed in to change notification settings - Fork 369
Allow configuring disk sizes per template en 1038 v2 #3288
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| -- +goose Up | ||
| -- +goose StatementBegin | ||
|
|
||
| ALTER TABLE "public"."tiers" | ||
| -- Free-rootfs target in the existing MiB convention. | ||
| ADD COLUMN "default_free_disk_size_mb" bigint, | ||
| -- Total logical-rootfs ceiling before active add-ons. | ||
| ADD COLUMN "max_disk_size_mb" bigint; | ||
|
|
||
| ALTER TABLE "public"."addons" | ||
| -- Total-ceiling increment in the existing MiB convention. | ||
| ADD COLUMN "extra_max_disk_size_mb" bigint; | ||
|
|
||
| ALTER TABLE "public"."tiers" | ||
| ADD CONSTRAINT "tiers_default_free_disk_size_mb_check" | ||
| CHECK (default_free_disk_size_mb >= 0), | ||
| ADD CONSTRAINT "tiers_max_disk_size_mb_check" | ||
| CHECK (max_disk_size_mb > 0), | ||
| ADD CONSTRAINT "tiers_default_free_disk_size_lte_max_check" | ||
| CHECK (default_free_disk_size_mb <= max_disk_size_mb); | ||
|
|
||
| ALTER TABLE "public"."addons" | ||
| ADD CONSTRAINT "addons_extra_max_disk_size_mb_check" | ||
| CHECK (extra_max_disk_size_mb >= 0); | ||
|
|
||
| -- +goose StatementEnd | ||
|
|
||
| -- +goose Down | ||
| -- +goose StatementBegin | ||
|
|
||
| ALTER TABLE "public"."tiers" | ||
| DROP CONSTRAINT IF EXISTS "tiers_default_free_disk_size_lte_max_check", | ||
| DROP CONSTRAINT IF EXISTS "tiers_max_disk_size_mb_check", | ||
| DROP CONSTRAINT IF EXISTS "tiers_default_free_disk_size_mb_check", | ||
| DROP COLUMN IF EXISTS "max_disk_size_mb", | ||
| DROP COLUMN IF EXISTS "default_free_disk_size_mb"; | ||
|
|
||
| ALTER TABLE "public"."addons" | ||
| DROP CONSTRAINT IF EXISTS "addons_extra_max_disk_size_mb_check", | ||
| DROP COLUMN IF EXISTS "extra_max_disk_size_mb"; | ||
|
|
||
| -- +goose StatementEnd |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| -- +goose Up | ||
| -- +goose StatementBegin | ||
|
|
||
| CREATE VIEW "public"."team_limits_v2" | ||
| WITH (security_invoker=on) AS | ||
| SELECT | ||
| t.id, | ||
| tier.max_length_hours, | ||
| (tier.concurrent_instances + a.extra_concurrent_sandboxes) AS concurrent_sandboxes, | ||
| (tier.concurrent_template_builds + a.extra_concurrent_template_builds) AS concurrent_template_builds, | ||
| (tier.max_vcpu + a.extra_max_vcpu) AS max_vcpu, | ||
| (tier.max_ram_mb + a.extra_max_ram_mb) AS max_ram_mb, | ||
| (tier.disk_mb + a.extra_disk_mb) AS disk_mb, | ||
| (tier.events_ttl_days + a.extra_events_ttl_days) AS events_ttl_days, | ||
| (tier.default_free_disk_size_mb + a.extra_disk_mb)::bigint AS default_free_disk_size_mb, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Agentic Security Review
Impact: authenticated traffic for affected teams can fail in auth/team-loading paths (availability/DoS) until data is backfilled or the view expression is made NULL-safe. Reviewed by Cursor Security Reviewer for commit c1406f8. Configure here. |
||
| (tier.max_disk_size_mb + a.extra_max_disk_size_mb)::bigint AS max_disk_size_mb | ||
|
Comment on lines
+6
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Migration 20260714091414 adds tiers.default_free_disk_size_mb and tiers.max_disk_size_mb as nullable bigint columns with no DEFAULT and no backfill for existing rows. Because the team_limits_v2 view (20260714091415) does not COALESCE the tier-side value before adding the addon delta, every pre-existing tier yields NULL for these two columns, and since the auth-path generated model (packages/db/pkg/auth/queries/models.go) types them as non-pointer int64 while get_team.sql.go scans directly into that field, pgx will error scanning NULL into it. This breaks GetTeamWithTierByAPIKey/ByTeamID/ByTeamAndUser/GetTeamsWithUsersTeamsWithTier for every existing team as soon as this migration deploys, taking down API-key auth and team lookups system-wide until every tier row is manually backfilled. Extended reasoning...The bug: Migration Where it manifests: The very next migration, (tier.default_free_disk_size_mb + a.extra_disk_mb)::bigint AS default_free_disk_size_mb,
(tier.max_disk_size_mb + a.extra_max_disk_size_mb)::bigint AS max_disk_size_mbThe addon-side operand ( Why the generated code can't absorb a NULL: The
And This non-pointer typing isn't just a stale codegen artifact that a re-run would silently fix either: Step-by-step proof:
Why this isn't caught by the PR's own test: Fix: Either (a) add |
||
| FROM "public"."teams" t | ||
| JOIN "public"."tiers" tier ON t.tier = tier.id | ||
| LEFT JOIN LATERAL ( | ||
| SELECT COALESCE(SUM(extra_concurrent_sandboxes), 0)::bigint AS extra_concurrent_sandboxes, | ||
| COALESCE(SUM(extra_concurrent_template_builds), 0)::bigint AS extra_concurrent_template_builds, | ||
| COALESCE(SUM(extra_max_vcpu), 0)::bigint AS extra_max_vcpu, | ||
| COALESCE(SUM(extra_max_ram_mb), 0)::bigint AS extra_max_ram_mb, | ||
| COALESCE(SUM(extra_disk_mb), 0)::bigint AS extra_disk_mb, | ||
| COALESCE(SUM(extra_events_ttl_days), 0)::bigint AS extra_events_ttl_days, | ||
| COALESCE(SUM(COALESCE(extra_max_disk_size_mb, extra_disk_mb)), 0)::bigint AS extra_max_disk_size_mb | ||
| FROM "public"."addons" addon | ||
| WHERE addon.team_id = t.id | ||
| AND addon.valid_from <= now() | ||
| AND (addon.valid_to IS NULL OR addon.valid_to > now()) | ||
| ) a ON true; | ||
|
|
||
| -- +goose StatementEnd | ||
|
|
||
| -- +goose Down | ||
| -- +goose StatementBegin | ||
|
|
||
| DROP VIEW IF EXISTS "public"."team_limits_v2"; | ||
|
|
||
| -- +goose StatementEnd | ||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To support the nullable
DefaultFreeDiskSizeMbandMaxDiskSizeMbfields (which should be pointers*int64inauthqueries.TeamLimitsV2), updatenewTeamLimitsto safely dereference them and default to0if they arenil. This prevents potential nil-pointer dereference panics and ensures backward compatibility for existing tiers.