Skip to content

[EN-1038] feat(db): add template disk entitlement schema#3286

Open
gm-e2b wants to merge 1 commit into
mainfrom
db-migration-disk-size
Open

[EN-1038] feat(db): add template disk entitlement schema#3286
gm-e2b wants to merge 1 commit into
mainfrom
db-migration-disk-size

Conversation

@gm-e2b

@gm-e2b gm-e2b commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Separate the default template free-space target from the maximum total root filesystem size that a team may build.

Add nullable default_free_disk_size_mb and max_disk_size_mb columns to tiers, plus extra_max_disk_size_mb to add-ons. Keep extra_disk_mb as the add-on contribution to default free space and add constraints preventing invalid negative or inverted tier values.

Keep the existing team_limits view unchanged for current consumers and introduce team_limits_v2 with the new effective default and maximum fields. Preserve compatibility with legacy add-on writers by treating a null extra maximum as equal to extra_disk_mb.

Leave data population and runtime adoption to later rollout steps so this commit remains an expand-only schema change.

Regenerate the database models and add focused migration coverage for the new columns, the unchanged V1 view, the V2 contract, security invoker behavior, and effective tier-plus-add-on calculations.

Part of: EN-1038

@linear-code

linear-code Bot commented Jul 14, 2026

Copy link
Copy Markdown

EN-1038

@cla-bot cla-bot Bot added the cla-signed label Jul 14, 2026
@codecov

codecov Bot commented Jul 14, 2026

Copy link
Copy Markdown

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
3329 2 3327 9
View the top 2 failed test(s) by shortest run time
github.com/e2b-dev/infra/tests/integration/internal/tests/api/templates::TestDeleteTemplateFromAnotherTeamAPIKey
Stack Traces | 154s run time
=== RUN   TestDeleteTemplateFromAnotherTeamAPIKey
=== PAUSE TestDeleteTemplateFromAnotherTeamAPIKey
=== CONT  TestDeleteTemplateFromAnotherTeamAPIKey
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] Building template 7luoj9ahjkzxp8fu0qf7/f5e485a4-c5c8-47c1-a63f-1ae3f2b277b1
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] [base] FROM ubuntu:22.04 [f9f564014e009a9561a82bf8c84f9314242971e833fb019936654ecba452f184]
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] Base Docker image size: 30 MB
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] Creating file system and pulling Docker image
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] Uncompressing layer sha256:d6834b4a794c03efa2c998853e64969fa8851b11b2ade63292268872a37759d0 30 MB
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] Uncompressing layer sha256:34c5246d3923ede5f06708d0e499beffe6a06044f1f67ce730c76f32b2bcf004 13 MB
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] Uncompressing layer sha256:8c4b1b28875140ed3abacaf16ad0d696f6bef912f52d2148f261a23e3349465b 168 B
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] Layers extracted
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] Root filesystem structure: bin, boot, dev, etc, home, lib, lib32, lib64, libx32, media, mnt, opt, proc, root, run, sbin, srv, sys, tmp, usr, var
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] Provisioning sandbox template
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] Provisioning was successful, cleaning up
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] Sandbox template provisioned
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] [base] DEFAULT USER user [49e586c2171254c6bc4a09e84eedac32dbcf113a158c24248129af2f49cbed74]
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] [builder 1/1] RUN echo 'Hello, World!' [c72b4f813c2a16b0fc1a1c5da7b1365a304cbac516b22dc304a71f70aae48ac0]
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] [builder 1/1] [stdout]: Hello, World!
    build_template_test.go:133: test-to-delete-another-team-api-key: [info] [finalize] Finalizing template build [92c524e30533398ebb41ce04c2596130f0cdecc9aa328e28fdb16a1b11f61d62]
    build_template_test.go:133: test-to-delete-another-team-api-key: [error] Build failed: An internal error occurred. Please try again or contact support with the build ID.
    delete_template_test.go:51: Build failed: {<nil> An internal error occurred. Please try again or contact support with the build ID. <nil>}
--- FAIL: TestDeleteTemplateFromAnotherTeamAPIKey (153.74s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/templates::TestTemplateBuildFromTemplateStartCommand
Stack Traces | 170s run time
=== RUN   TestTemplateBuildFromTemplateStartCommand
=== PAUSE TestTemplateBuildFromTemplateStartCommand
=== CONT  TestTemplateBuildFromTemplateStartCommand
    build_template_test.go:133: test-ubuntu-start-base: [info] Building template hiufpf40okrako5pxz7k/8485d523-08a5-4d99-b6ac-df292ed7e647
    build_template_test.go:133: test-ubuntu-start-base: [info] [base] FROM ubuntu:22.04 [f9f564014e009a9561a82bf8c84f9314242971e833fb019936654ecba452f184]
    build_template_test.go:133: test-ubuntu-start-base: [info] Base Docker image size: 30 MB
    build_template_test.go:133: test-ubuntu-start-base: [info] Creating file system and pulling Docker image
    build_template_test.go:133: test-ubuntu-start-base: [info] Uncompressing layer sha256:d6834b4a794c03efa2c998853e64969fa8851b11b2ade63292268872a37759d0 30 MB
    build_template_test.go:133: test-ubuntu-start-base: [info] Uncompressing layer sha256:34c5246d3923ede5f06708d0e499beffe6a06044f1f67ce730c76f32b2bcf004 13 MB
    build_template_test.go:133: test-ubuntu-start-base: [info] Uncompressing layer sha256:8c4b1b28875140ed3abacaf16ad0d696f6bef912f52d2148f261a23e3349465b 168 B
    build_template_test.go:133: test-ubuntu-start-base: [info] Layers extracted
    build_template_test.go:133: test-ubuntu-start-base: [info] Root filesystem structure: bin, boot, dev, etc, home, lib, lib32, lib64, libx32, media, mnt, opt, proc, root, run, sbin, srv, sys, tmp, usr, var
    build_template_test.go:133: test-ubuntu-start-base: [info] Provisioning sandbox template
    build_template_test.go:133: test-ubuntu-start-base: [info] Provisioning was successful, cleaning up
    build_template_test.go:133: test-ubuntu-start-base: [info] Sandbox template provisioned
    build_template_test.go:133: test-ubuntu-start-base: [info] [base] DEFAULT USER user [49e586c2171254c6bc4a09e84eedac32dbcf113a158c24248129af2f49cbed74]
    build_template_test.go:133: test-ubuntu-start-base: [info] [builder 1/2] ENV START_ENV start_value [22ecb2c2ce1b1d262e37d2cd71b90e6d33fdf99ecfca361e1a2c284afb7fc08a]
    build_template_test.go:133: test-ubuntu-start-base: [info] [builder 2/2] WORKDIR /start/workdir [f841574929b92d8b6e15a8fc6477f0f1e568eac3d30ae7110a831bbcea62e921]
    build_template_test.go:133: test-ubuntu-start-base: [info] [finalize] Finalizing template build [a509f6bf83c53e4844e4d62e9e93f7dae0d5706e070f3f756fe6d227a04976e4]
    build_template_test.go:133: test-ubuntu-start-base: [error] Build failed: An internal error occurred. Please try again or contact support with the build ID.
    build_template_test.go:700: Build failed: {<nil> An internal error occurred. Please try again or contact support with the build ID. <nil>}
--- FAIL: TestTemplateBuildFromTemplateStartCommand (170.15s)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces database migrations to add disk entitlement columns to the tiers and addons tables, creates a new team_limits_v2 view, and adds corresponding Go models and tests. The review feedback identifies a critical issue where explicit ::bigint casts in the view definition cause sqlc to generate non-nullable int64 fields in Go, which will lead to runtime scan crashes when database values are NULL. To resolve this, the reviewer recommends removing the redundant casts so sqlc can correctly infer nullability, and updating the migration tests to scan into nullable pointer types.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/db/migrations/20260714091415_extend_team_limits.sql
Comment thread packages/db/pkg/tests/disk_entitlements_migration_test.go Outdated

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — straightforward, well-tested expand-only schema migration.

What was reviewed:

  • Migration adds nullable disk-entitlement columns to tiers/addons with CHECK constraints (NULL-safe, no backfill needed).
  • New team_limits_v2 view combines tier + addon values, preserves security_invoker=on and legacy extra_max_disk_size_mb→extra_disk_mb fallback for old add-on writers.
  • Verified the effective default/max math in the migration test matches expectations, and that the existing team_limits (v1) view is left untouched.
  • Checked the generated TeamLimitsV2 Go struct typing NULL-derived columns as int64 instead of pgtype.Int8 — inert since no query in the codebase currently selects from team_limits_v2, so it has no runtime effect and will be corrected on the next real sqlc generation.
Extended reasoning...

Overview

This PR adds two nullable bigint columns (default_free_disk_size_mb, max_disk_size_mb) to tiers, one nullable column (extra_max_disk_size_mb) to addons, and CHECK constraints preventing negative or inverted tier values. It then introduces a new team_limits_v2 view that surfaces the effective (tier + active add-ons) default and maximum disk sizes, while leaving the existing team_limits view untouched for current consumers. Test coverage exercises column nullability, view column sets for v1 vs v2, security_invoker behavior, and the arithmetic for effective values including legacy add-on fallback.

Security risks

None identified. The new view preserves security_invoker=on, matching the existing team_limits v1 view's RLS-respecting behavior, and this is explicitly covered by a test. No auth, crypto, or permission logic is touched.

Level of scrutiny

This is a pure, additive (expand-only) database schema change with no runtime/application code wired up yet — the PR description explicitly defers data population and adoption to later steps. Given the low blast radius (no existing code paths depend on the new columns/view yet) and strong test coverage of the new schema behavior, a lighter level of scrutiny is appropriate compared to changes touching live request paths.

Other factors

The bug-hunting system found no issues. I independently checked the flagged-and-ruled-out concern about the generated TeamLimitsV2 struct mistyping nullable view columns as non-nullable int64, and confirmed it has no functional impact since nothing in the codebase queries team_limits_v2 yet — it's inert generated code that will be corrected whenever sqlc is actually re-run against a query using it. The migration's up/down scripts are symmetric and CHECK constraints are correctly NULL-safe for the expand-only rollout.

@gm-e2b gm-e2b force-pushed the db-migration-disk-size branch 3 times, most recently from 67bcfe1 to 4621212 Compare July 14, 2026 15:46

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add if not exists to the statements🙏🏻

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added for new columns. Adding constraint checks does not support IF NOT EXISTS.

Comment thread packages/db/migrations/20260714091415_create_team_limits_v2.sql Outdated
Add nullable tier entitlements for the default template free-space target
and maximum logical rootfs size, plus an add-on contribution to the maximum.
Validate non-negative defaults and add-on increments, positive maxima, and
that each default does not exceed its maximum.

Backfill existing add-ons so their maximum contribution initially matches
extra_disk_mb. Keep the new field nullable and fall back to extra_disk_mb
for writes from legacy services during rollout. Leave tier population to
the audited follow-up data migration.

Extend team_limits in place, preserving its existing columns and appending
the effective default_free_disk_size_mb and max_disk_size_mb values computed
from active add-ons.

Regenerate sqlc queries and models with nullable int64 entitlement fields,
and cover the schema shape, security-invoker setting, column compatibility,
and tier-plus-add-on calculations in the migration test.

Part of: EN-1038
@gm-e2b gm-e2b force-pushed the db-migration-disk-size branch from 4621212 to 6f513fb Compare July 15, 2026 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants