Skip to content

ref: move the rest of NOSTORE options to django settings#117136

Merged
joshuarli merged 9 commits into
masterfrom
ref-options-ds-all-nostore
Jun 15, 2026
Merged

ref: move the rest of NOSTORE options to django settings#117136
joshuarli merged 9 commits into
masterfrom
ref-options-ds-all-nostore

Conversation

@joshuarli

@joshuarli joshuarli commented Jun 8, 2026

Copy link
Copy Markdown
Member

followup to #117102 which has been proven. again, this will go through the same 3-stage rollout:

smoke test that this is still compatible (thanks to options_mapper) with getsentry master:

import os, warnings

os.environ.setdefault("SENTRY_CONF", "getsentry/settings.py")

from sentry.runner import configure
configure()

from django.conf import settings
from sentry.conf.server import DEAD
from sentry.runner.initializer import bootstrap_options, validate_options

# system.base-hostname: a key this branch moved into options_mapper.
# getsentry master still sets it via the OPTION form; verify it bridges into the setting.
KEY, SETTING = "system.base-hostname", "SENTRY_BASE_HOSTNAME"

# boot: getsentry's SENTRY_OPTIONS[KEY] is promoted into settings.SENTRY_BASE_HOSTNAME
assert getattr(settings, SETTING) is not DEAD, "setting never promoted from option"
assert getattr(settings, SETTING) == settings.SENTRY_OPTIONS[KEY], (
    getattr(settings, SETTING),
    settings.SENTRY_OPTIONS[KEY],
)

# deploy re-bootstrap: setting starts DEAD, option is written, bridge promotes it back
setattr(settings, SETTING, DEAD)
settings.SENTRY_OPTIONS[KEY] = "example.test"
bootstrap_options(settings)
assert getattr(settings, SETTING) == "example.test", getattr(settings, SETTING)

# still registered -> no unknown-option warning / crash
with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter("always")
    validate_options(settings)
assert not [m for m in (str(x.message) for x in w) if KEY in m]

print(f"OK: {KEY} option-form config bridges into settings.{SETTING}")

@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Jun 8, 2026
@joshuarli joshuarli force-pushed the ref-options-ds-all-nostore branch from a8f5cd5 to 1306a21 Compare June 8, 2026 22:03
joshuarli and others added 6 commits June 11, 2026 13:04
Promote system.logging-format into the SENTRY_LOGGING_FORMAT Django setting
through options_mapper: declare the setting as DEAD in server.py so bootstrap
doesn't clobber the option, keep the registered default, and keep SENTRY_LOG_FORMAT
as an env override. SENTRY_OPTIONS["system.logging-format"] keeps working.

Co-Authored-By: Claude <noreply@anthropic.com>
Move system.base-hostname, system.organization-base-hostname,
system.organization-url-template, and system.region-api-url-template to
SENTRY_* Django settings via options_mapper (settings declared DEAD, options
kept registered). Consumers read settings; SENTRY_OPTIONS config still works.

Co-Authored-By: Claude <noreply@anthropic.com>
…tings

Move intercom.sentry-api-secret, relay.static_auth, objectstore.config, and
viewer-context.enabled to SENTRY_* Django settings via options_mapper (settings
declared DEAD, options kept registered). Consumers read settings; tests use
override_settings. SENTRY_OPTIONS config still works.

Co-Authored-By: Claude <noreply@anthropic.com>
Move analytics.backend, analytics.options, and mail.list-namespace to SENTRY_*
Django settings via options_mapper. These are read at module import; verified
the values are promoted before the modules load (analytics backend resolves to
'noop', not the DEAD sentinel). SENTRY_OPTIONS config still works.

Co-Authored-By: Claude <noreply@anthropic.com>
Move the 8 filestore.* options (region/relocation/profiles/control backend +
options) to SENTRY_*_FILE_STORAGE_BACKEND / *_CONFIG settings via options_mapper.
The SENTRY_*_FILE_STORAGE_* namespace avoids colliding with the SENTRY_FILESTORE*
env vars ops uses as inputs (and with the legacy SENTRY_FILESTORE settings, whose
apply_legacy_settings bridge still feeds the option, which promotes to the new
setting).

Also annotate the DEAD bootstrap sentinel as 'DEAD: Any' so settings-backed
options type as Any (matching options.get) instead of object, fixing mypy errors
across the migrated consumers.

Co-Authored-By: Claude <noreply@anthropic.com>
@joshuarli joshuarli force-pushed the ref-options-ds-all-nostore branch from 1306a21 to a1daa87 Compare June 11, 2026 20:04
@joshuarli joshuarli marked this pull request as ready for review June 11, 2026 22:51
@joshuarli joshuarli requested review from a team as code owners June 11, 2026 22:51

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5342e5e. Configure here.

Comment thread src/sentry/models/files/utils.py
Comment thread src/sentry/api/authentication.py
Comment thread src/sentry/utils/email/message_builder.py
apply_legacy_settings runs after bootstrap_options, so writing the legacy
value into SENTRY_OPTIONS[key] was too late for keys whose consumers now read
the Django setting (e.g. SENTRY_FILESTORE -> filestore.backend ->
SENTRY_FILE_STORAGE_BACKEND, which get_storage() reads). The override landed in
SENTRY_OPTIONS but never reached the setting, so the boot default silently won.

Re-promote the value via options_mapper after writing the option. Also pre-arms
the SENTRY_ADMIN_EMAIL and GOOGLE_CLIENT_ID/SECRET legacy aliases for when those
options migrate.

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread src/sentry/organizations/absolute_url.py

@markstory markstory left a comment

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.

Looks good to me. The extra layer of settings shims is 😵.

@joshuarli joshuarli merged commit f66885a into master Jun 15, 2026
85 checks passed
@joshuarli joshuarli deleted the ref-options-ds-all-nostore branch June 15, 2026 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants