diff --git a/braintrust/README.md b/braintrust/README.md index 0b32372..9406aea 100644 --- a/braintrust/README.md +++ b/braintrust/README.md @@ -179,6 +179,14 @@ You may have to adjust your helm values.yaml overrides if you have adjusted any Also if you have custom readiness checks, please unset these customizations and use our new default readiness checks. There is a bug in the dataplane where the endpoint we were using for readiness checks, would never recover if it failed. +### Version 6 + +This version introduces opt-in no-PG mode, allowing Brainstore to store objects directly without PostgreSQL. The new `skipPgForBrainstoreObjects` value defaults to `""` (disabled), so upgrading to v6 makes no behavioral change unless you explicitly set it. This solves a longstanding bottleneck — the rate and volume of data ingestion is no longer limited by Postgres, and this means faster, more reliable data ingestion at higher scale. This is required to be enabled before upgrading to Dataplane 2.x.x. + +> **⚠️ WARNING: This is a one-way operation.** Once an object type has been migrated off PostgreSQL, it cannot be un-migrated without downtime. + +See [UPGRADE.md](UPGRADE.md#v600---no-pg-brainstore-objects) for prerequisites and full migration instructions. + ## Example Values Files Example values files for different cloud providers and configurations are located in the `examples/` folder. diff --git a/braintrust/UPGRADE.md b/braintrust/UPGRADE.md index 35877ac..adee003 100644 --- a/braintrust/UPGRADE.md +++ b/braintrust/UPGRADE.md @@ -2,6 +2,59 @@ This document outlines breaking changes and required configuration updates for major releases. +## v6.0.0 - No-PG Brainstore Objects + +This release introduces the ability to store Brainstore objects (such as project logs) directly in Brainstore, bypassing PostgreSQL entirely. This is an **opt-in** feature — upgrading to v6 makes no behavioral change unless you explicitly set `skipPgForBrainstoreObjects`. This solves a longstanding bottleneck — the rate and volume of data ingestion is no longer limited by Postgres, and this means faster, more reliable data ingestion at higher scale. This is required to be enabled before upgrading to Dataplane 2.x.x. + +> **⚠️ WARNING: This is a one-way operation.** Once an object type has been migrated off PostgreSQL, it cannot be un-migrated without downtime. Do not enable this unless you are ready to commit. + +### Requirements to migrate + +Before enabling no-pg mode, you must: + +1. **Upgrade your data plane to version 1.1.32 or higher.** + +2. **Verify all Brainstore configuration checks pass** on your organization's Data Plane settings page: + + ![Brainstore prerequisites](images/no-pg-prereqs.png) + + The following checks are expected to be incomplete at this stage and can be ignored: + - `Efficient WAL Format` - this will be be configured once the migration below is complete + - `Brainstore direct writes` — this will pass once the migration below is complete + - `Response cache URI` and `Code Bundle URI` — these are part of a separate Topics configuration + +### Enabling no-pg mode + +Set the `skipPgForBrainstoreObjects` value in your `values.yaml`: + +```yaml +# Skip PostgreSQL for all object types +skipPgForBrainstoreObjects: "all" + +# OR: skip for specific objects only +skipPgForBrainstoreObjects: "include:project_logs:5ad850f0-3a1a-4980-b889-d21d4116b5d7,project_logs:45b3aed2-3dde-4f0d-a22c-9af69ee8508e" + +# OR: skip for all objects except specific ones +skipPgForBrainstoreObjects: "exclude:project_logs:5ad850f0-3a1a-4980-b889-d21d4116b5d7" +``` + +Using a limited filter can be done for testing, however this must be configured to `all` before further upgrades can be done. + +When set, the following environment variables are automatically configured: + +- **API**: `BRAINSTORE_WAL_USE_EFFICIENT_FORMAT=true`, `SKIP_PG_FOR_BRAINSTORE_OBJECTS=` +- **Brainstore** (reader, writer, fastreader): `BRAINSTORE_ASYNC_SCORING_OBJECTS=`, `BRAINSTORE_LOG_AUTOMATIONS_OBJECTS=` + + ![Brainstore post upgrade](images/no-pg-post-upgrade.png) + + The `BRAINSTORE_WAL_USE_EFFICIENT_FORMAT` will be configured, however in 1.1.32 it's status can't be fully checked. + +### No rollback + +Unlike previous major version upgrades, there is **no rollback path** for this change. Once objects are migrated off PostgreSQL, reverting requires downtime and manual intervention. Reach out to the Braintrust team on Slack before enabling this if you have concerns. + +--- + ## v2.0.0 - Brainstore Reader/Writer Split This release introduces a significant architectural change that splits the Brainstore service into separate reader and writer services for improved scalability and performance. diff --git a/braintrust/images/no-pg-post-upgrade.png b/braintrust/images/no-pg-post-upgrade.png new file mode 100644 index 0000000..5231ee9 Binary files /dev/null and b/braintrust/images/no-pg-post-upgrade.png differ diff --git a/braintrust/images/no-pg-prereqs.png b/braintrust/images/no-pg-prereqs.png new file mode 100644 index 0000000..4ddfa3e Binary files /dev/null and b/braintrust/images/no-pg-prereqs.png differ diff --git a/braintrust/templates/api-configmap.yaml b/braintrust/templates/api-configmap.yaml index f6414a8..86ddff0 100644 --- a/braintrust/templates/api-configmap.yaml +++ b/braintrust/templates/api-configmap.yaml @@ -51,5 +51,14 @@ data: BRAINSTORE_INSERT_ROW_REFS: "true" # Logs v2 table. Requires pg_partman extension (default enabled in our TF modules) INSERT_LOGS2: "true" - ALLOW_INVALID_BASE64: {{ .Values.api.allowInvalidBase64 | default "false" | quote }} + ALLOW_INVALID_BASE64: {{ .Values.api.allowInvalidBase64 | default "false" | quote }} NODE_MEMORY_PERCENT: {{ .Values.api.nodeMemoryPercent | default "80" | quote }} + {{- if .Values.brainstoreWalFooterVersion }} + BRAINSTORE_WAL_FOOTER_VERSION: {{ .Values.brainstoreWalFooterVersion | quote }} + {{- end }} + {{- if .Values.skipPgForBrainstoreObjects }} + SKIP_PG_FOR_BRAINSTORE_OBJECTS: {{ .Values.skipPgForBrainstoreObjects | quote }} + {{- end }} + {{- if or .Values.brainstoreWalFooterVersion .Values.skipPgForBrainstoreObjects }} + BRAINSTORE_WAL_USE_EFFICIENT_FORMAT: "true" + {{- end }} diff --git a/braintrust/templates/brainstore-fastreader-configmap.yaml b/braintrust/templates/brainstore-fastreader-configmap.yaml index 0faec08..8e07c1b 100644 --- a/braintrust/templates/brainstore-fastreader-configmap.yaml +++ b/braintrust/templates/brainstore-fastreader-configmap.yaml @@ -30,18 +30,38 @@ data: {{- if eq .Values.brainstore.locksBackend "objectStorage" }} BRAINSTORE_LOCKS_URI: "az://{{ .Values.objectStorage.azure.brainstoreContainer }}/brainstore/locks" {{- end }} + {{- if .Values.objectStorage.azure.responseContainer }} + BRAINSTORE_RESPONSE_CACHE_URI: "az://{{ .Values.objectStorage.azure.responseContainer }}" + {{- end }} + {{- if .Values.objectStorage.azure.codeBundleContainer }} + BRAINSTORE_CODE_BUNDLE_URI: "az://{{ .Values.objectStorage.azure.codeBundleContainer }}" + {{- end }} {{- else if eq .Values.cloud "aws" }} BRAINSTORE_INDEX_URI: "s3://{{ .Values.objectStorage.aws.brainstoreBucket }}/brainstore/index" BRAINSTORE_REALTIME_WAL_URI: "s3://{{ .Values.objectStorage.aws.brainstoreBucket }}/brainstore/wal" {{- if eq .Values.brainstore.locksBackend "objectStorage" }} BRAINSTORE_LOCKS_URI: "s3://{{ .Values.objectStorage.aws.brainstoreBucket }}/brainstore/locks" {{- end }} + {{- if .Values.objectStorage.aws.responseBucket }} + BRAINSTORE_RESPONSE_CACHE_URI: "s3://{{ .Values.objectStorage.aws.responseBucket }}" + {{- end }} + {{- if .Values.objectStorage.aws.codeBundleBucket }} + BRAINSTORE_CODE_BUNDLE_URI: "s3://{{ .Values.objectStorage.aws.codeBundleBucket }}" + {{- end }} {{- else if eq .Values.cloud "google" }} BRAINSTORE_INDEX_URI: "gs://{{ .Values.objectStorage.google.brainstoreBucket }}/brainstore/index" BRAINSTORE_REALTIME_WAL_URI: "gs://{{ .Values.objectStorage.google.brainstoreBucket }}/brainstore/wal" {{- if eq .Values.brainstore.locksBackend "objectStorage" }} BRAINSTORE_LOCKS_URI: "gs://{{ .Values.objectStorage.google.brainstoreBucket }}/brainstore/locks" {{- end }} + {{- if .Values.objectStorage.google.apiBucket }} + BRAINSTORE_RESPONSE_CACHE_URI: "gs://{{ .Values.objectStorage.google.apiBucket }}/response" + BRAINSTORE_CODE_BUNDLE_URI: "gs://{{ .Values.objectStorage.google.apiBucket }}/code-bundle" + {{- end }} {{- end }} BRAINSTORE_CONTROL_PLANE_TELEMETRY: {{ .Values.global.controlPlaneTelemetry | quote }} NO_COLOR: "1" + {{- if .Values.skipPgForBrainstoreObjects }} + BRAINSTORE_ASYNC_SCORING_OBJECTS: {{ .Values.skipPgForBrainstoreObjects | quote }} + BRAINSTORE_LOG_AUTOMATIONS_OBJECTS: {{ .Values.skipPgForBrainstoreObjects | quote }} + {{- end }} diff --git a/braintrust/templates/brainstore-reader-configmap.yaml b/braintrust/templates/brainstore-reader-configmap.yaml index 049cc36..8b7757b 100644 --- a/braintrust/templates/brainstore-reader-configmap.yaml +++ b/braintrust/templates/brainstore-reader-configmap.yaml @@ -30,18 +30,38 @@ data: {{- if eq .Values.brainstore.locksBackend "objectStorage" }} BRAINSTORE_LOCKS_URI: "az://{{ .Values.objectStorage.azure.brainstoreContainer }}/brainstore/locks" {{- end }} + {{- if .Values.objectStorage.azure.responseContainer }} + BRAINSTORE_RESPONSE_CACHE_URI: "az://{{ .Values.objectStorage.azure.responseContainer }}" + {{- end }} + {{- if .Values.objectStorage.azure.codeBundleContainer }} + BRAINSTORE_CODE_BUNDLE_URI: "az://{{ .Values.objectStorage.azure.codeBundleContainer }}" + {{- end }} {{- else if eq .Values.cloud "aws" }} BRAINSTORE_INDEX_URI: "s3://{{ .Values.objectStorage.aws.brainstoreBucket }}/brainstore/index" BRAINSTORE_REALTIME_WAL_URI: "s3://{{ .Values.objectStorage.aws.brainstoreBucket }}/brainstore/wal" {{- if eq .Values.brainstore.locksBackend "objectStorage" }} BRAINSTORE_LOCKS_URI: "s3://{{ .Values.objectStorage.aws.brainstoreBucket }}/brainstore/locks" {{- end }} + {{- if .Values.objectStorage.aws.responseBucket }} + BRAINSTORE_RESPONSE_CACHE_URI: "s3://{{ .Values.objectStorage.aws.responseBucket }}" + {{- end }} + {{- if .Values.objectStorage.aws.codeBundleBucket }} + BRAINSTORE_CODE_BUNDLE_URI: "s3://{{ .Values.objectStorage.aws.codeBundleBucket }}" + {{- end }} {{- else if eq .Values.cloud "google" }} BRAINSTORE_INDEX_URI: "gs://{{ .Values.objectStorage.google.brainstoreBucket }}/brainstore/index" BRAINSTORE_REALTIME_WAL_URI: "gs://{{ .Values.objectStorage.google.brainstoreBucket }}/brainstore/wal" {{- if eq .Values.brainstore.locksBackend "objectStorage" }} BRAINSTORE_LOCKS_URI: "gs://{{ .Values.objectStorage.google.brainstoreBucket }}/brainstore/locks" {{- end }} + {{- if .Values.objectStorage.google.apiBucket }} + BRAINSTORE_RESPONSE_CACHE_URI: "gs://{{ .Values.objectStorage.google.apiBucket }}/response" + BRAINSTORE_CODE_BUNDLE_URI: "gs://{{ .Values.objectStorage.google.apiBucket }}/code-bundle" + {{- end }} {{- end }} BRAINSTORE_CONTROL_PLANE_TELEMETRY: {{ .Values.global.controlPlaneTelemetry | quote }} - NO_COLOR: "1" \ No newline at end of file + NO_COLOR: "1" + {{- if .Values.skipPgForBrainstoreObjects }} + BRAINSTORE_ASYNC_SCORING_OBJECTS: {{ .Values.skipPgForBrainstoreObjects | quote }} + BRAINSTORE_LOG_AUTOMATIONS_OBJECTS: {{ .Values.skipPgForBrainstoreObjects | quote }} + {{- end }} \ No newline at end of file diff --git a/braintrust/templates/brainstore-writer-configmap.yaml b/braintrust/templates/brainstore-writer-configmap.yaml index 890d95c..0e31a56 100644 --- a/braintrust/templates/brainstore-writer-configmap.yaml +++ b/braintrust/templates/brainstore-writer-configmap.yaml @@ -30,18 +30,38 @@ data: {{- if eq .Values.brainstore.locksBackend "objectStorage" }} BRAINSTORE_LOCKS_URI: "az://{{ .Values.objectStorage.azure.brainstoreContainer }}/brainstore/locks" {{- end }} + {{- if .Values.objectStorage.azure.responseContainer }} + BRAINSTORE_RESPONSE_CACHE_URI: "az://{{ .Values.objectStorage.azure.responseContainer }}" + {{- end }} + {{- if .Values.objectStorage.azure.codeBundleContainer }} + BRAINSTORE_CODE_BUNDLE_URI: "az://{{ .Values.objectStorage.azure.codeBundleContainer }}" + {{- end }} {{- else if eq .Values.cloud "aws" }} BRAINSTORE_INDEX_URI: "s3://{{ .Values.objectStorage.aws.brainstoreBucket }}/brainstore/index" BRAINSTORE_REALTIME_WAL_URI: "s3://{{ .Values.objectStorage.aws.brainstoreBucket }}/brainstore/wal" {{- if eq .Values.brainstore.locksBackend "objectStorage" }} BRAINSTORE_LOCKS_URI: "s3://{{ .Values.objectStorage.aws.brainstoreBucket }}/brainstore/locks" {{- end }} + {{- if .Values.objectStorage.aws.responseBucket }} + BRAINSTORE_RESPONSE_CACHE_URI: "s3://{{ .Values.objectStorage.aws.responseBucket }}" + {{- end }} + {{- if .Values.objectStorage.aws.codeBundleBucket }} + BRAINSTORE_CODE_BUNDLE_URI: "s3://{{ .Values.objectStorage.aws.codeBundleBucket }}" + {{- end }} {{- else if eq .Values.cloud "google" }} BRAINSTORE_INDEX_URI: "gs://{{ .Values.objectStorage.google.brainstoreBucket }}/brainstore/index" BRAINSTORE_REALTIME_WAL_URI: "gs://{{ .Values.objectStorage.google.brainstoreBucket }}/brainstore/wal" {{- if eq .Values.brainstore.locksBackend "objectStorage" }} BRAINSTORE_LOCKS_URI: "gs://{{ .Values.objectStorage.google.brainstoreBucket }}/brainstore/locks" {{- end }} + {{- if .Values.objectStorage.google.apiBucket }} + BRAINSTORE_RESPONSE_CACHE_URI: "gs://{{ .Values.objectStorage.google.apiBucket }}/response" + BRAINSTORE_CODE_BUNDLE_URI: "gs://{{ .Values.objectStorage.google.apiBucket }}/code-bundle" + {{- end }} {{- end }} BRAINSTORE_CONTROL_PLANE_TELEMETRY: {{ .Values.global.controlPlaneTelemetry | quote }} - NO_COLOR: "1" \ No newline at end of file + NO_COLOR: "1" + {{- if .Values.skipPgForBrainstoreObjects }} + BRAINSTORE_ASYNC_SCORING_OBJECTS: {{ .Values.skipPgForBrainstoreObjects | quote }} + BRAINSTORE_LOG_AUTOMATIONS_OBJECTS: {{ .Values.skipPgForBrainstoreObjects | quote }} + {{- end }} \ No newline at end of file diff --git a/braintrust/tests/api-configmap_test.yaml b/braintrust/tests/api-configmap_test.yaml index e546c32..9e5d22d 100644 --- a/braintrust/tests/api-configmap_test.yaml +++ b/braintrust/tests/api-configmap_test.yaml @@ -188,3 +188,99 @@ tests: - equal: path: data.BRAINSTORE_BACKFILL_DISABLE_NONHISTORICAL value: "true" + + - it: should not include WAL or no-pg vars when neither is set + values: + - __fixtures__/base-values.yaml + release: + namespace: "braintrust" + asserts: + - isNull: + path: data.BRAINSTORE_WAL_FOOTER_VERSION + - isNull: + path: data.BRAINSTORE_WAL_USE_EFFICIENT_FORMAT + - isNull: + path: data.SKIP_PG_FOR_BRAINSTORE_OBJECTS + + - it: should set WAL_FOOTER_VERSION and WAL_USE_EFFICIENT_FORMAT when only brainstoreWalFooterVersion is set + values: + - __fixtures__/base-values.yaml + set: + brainstoreWalFooterVersion: "v1" + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_WAL_FOOTER_VERSION + value: "v1" + - equal: + path: data.BRAINSTORE_WAL_USE_EFFICIENT_FORMAT + value: "true" + - isNull: + path: data.SKIP_PG_FOR_BRAINSTORE_OBJECTS + + - it: should set SKIP_PG and WAL_USE_EFFICIENT_FORMAT when only skipPgForBrainstoreObjects is set + values: + - __fixtures__/base-values.yaml + set: + skipPgForBrainstoreObjects: "all" + release: + namespace: "braintrust" + asserts: + - equal: + path: data.SKIP_PG_FOR_BRAINSTORE_OBJECTS + value: "all" + - equal: + path: data.BRAINSTORE_WAL_USE_EFFICIENT_FORMAT + value: "true" + - isNull: + path: data.BRAINSTORE_WAL_FOOTER_VERSION + + - it: should set all three vars when both brainstoreWalFooterVersion and skipPgForBrainstoreObjects are set + values: + - __fixtures__/base-values.yaml + set: + brainstoreWalFooterVersion: "v3" + skipPgForBrainstoreObjects: "all" + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_WAL_FOOTER_VERSION + value: "v3" + - equal: + path: data.SKIP_PG_FOR_BRAINSTORE_OBJECTS + value: "all" + - equal: + path: data.BRAINSTORE_WAL_USE_EFFICIENT_FORMAT + value: "true" + + - it: should pass through include-style skipPgForBrainstoreObjects value + values: + - __fixtures__/base-values.yaml + set: + skipPgForBrainstoreObjects: "include:project_logs:abc123" + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_WAL_USE_EFFICIENT_FORMAT + value: "true" + - equal: + path: data.SKIP_PG_FOR_BRAINSTORE_OBJECTS + value: "include:project_logs:abc123" + + - it: should pass through exclude-style skipPgForBrainstoreObjects value + values: + - __fixtures__/base-values.yaml + set: + skipPgForBrainstoreObjects: "exclude:project_logs:abc123" + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_WAL_USE_EFFICIENT_FORMAT + value: "true" + - equal: + path: data.SKIP_PG_FOR_BRAINSTORE_OBJECTS + value: "exclude:project_logs:abc123" diff --git a/braintrust/tests/brainstore-fastreader-configmap_test.yaml b/braintrust/tests/brainstore-fastreader-configmap_test.yaml index 3bc9e11..422db84 100644 --- a/braintrust/tests/brainstore-fastreader-configmap_test.yaml +++ b/braintrust/tests/brainstore-fastreader-configmap_test.yaml @@ -32,3 +32,101 @@ tests: - equal: path: metadata.annotations["custom-annotation"] value: value + + - it: should configure AWS URIs including response cache and code bundle + values: + - __fixtures__/base-values.yaml + - __fixtures__/aws-values.yaml + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_RESPONSE_CACHE_URI + value: "s3://test-response-bucket" + - equal: + path: data.BRAINSTORE_CODE_BUNDLE_URI + value: "s3://test-code-bundle-bucket" + + - it: should configure Azure URIs including response cache and code bundle + values: + - __fixtures__/base-values.yaml + - __fixtures__/azure-values.yaml + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_RESPONSE_CACHE_URI + value: "az://responses" + - equal: + path: data.BRAINSTORE_CODE_BUNDLE_URI + value: "az://code-bundles" + + - it: should configure Google Cloud URIs including response cache and code bundle + values: + - __fixtures__/base-values.yaml + - __fixtures__/google-values.yaml + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_RESPONSE_CACHE_URI + value: "gs://test-api-bucket/response" + - equal: + path: data.BRAINSTORE_CODE_BUNDLE_URI + value: "gs://test-api-bucket/code-bundle" + + - it: should not include no-pg vars when skipPgForBrainstoreObjects is not set + values: + - __fixtures__/base-values.yaml + release: + namespace: "braintrust" + asserts: + - isNull: + path: data.BRAINSTORE_ASYNC_SCORING_OBJECTS + - isNull: + path: data.BRAINSTORE_LOG_AUTOMATIONS_OBJECTS + + - it: should include no-pg vars when skipPgForBrainstoreObjects is "all" + values: + - __fixtures__/base-values.yaml + set: + skipPgForBrainstoreObjects: "all" + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_ASYNC_SCORING_OBJECTS + value: "all" + - equal: + path: data.BRAINSTORE_LOG_AUTOMATIONS_OBJECTS + value: "all" + + - it: should pass through include-style skipPgForBrainstoreObjects value + values: + - __fixtures__/base-values.yaml + set: + skipPgForBrainstoreObjects: "include:project_logs:abc123" + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_ASYNC_SCORING_OBJECTS + value: "include:project_logs:abc123" + - equal: + path: data.BRAINSTORE_LOG_AUTOMATIONS_OBJECTS + value: "include:project_logs:abc123" + + - it: should pass through exclude-style skipPgForBrainstoreObjects value + values: + - __fixtures__/base-values.yaml + set: + skipPgForBrainstoreObjects: "exclude:project_logs:abc123" + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_ASYNC_SCORING_OBJECTS + value: "exclude:project_logs:abc123" + - equal: + path: data.BRAINSTORE_LOG_AUTOMATIONS_OBJECTS + value: "exclude:project_logs:abc123" diff --git a/braintrust/tests/brainstore-reader-configmap_test.yaml b/braintrust/tests/brainstore-reader-configmap_test.yaml index 7626c76..30d875d 100644 --- a/braintrust/tests/brainstore-reader-configmap_test.yaml +++ b/braintrust/tests/brainstore-reader-configmap_test.yaml @@ -61,6 +61,12 @@ tests: - equal: path: data.BRAINSTORE_REALTIME_WAL_URI value: "s3://test-brainstore-bucket/brainstore/wal" + - equal: + path: data.BRAINSTORE_RESPONSE_CACHE_URI + value: "s3://test-response-bucket" + - equal: + path: data.BRAINSTORE_CODE_BUNDLE_URI + value: "s3://test-code-bundle-bucket" - it: should configure Azure URIs when cloud is azure values: @@ -78,6 +84,12 @@ tests: - equal: path: data.BRAINSTORE_REALTIME_WAL_URI value: "az://brainstore/brainstore/wal" + - equal: + path: data.BRAINSTORE_RESPONSE_CACHE_URI + value: "az://responses" + - equal: + path: data.BRAINSTORE_CODE_BUNDLE_URI + value: "az://code-bundles" - it: should configure Google Cloud URIs when cloud is google values: @@ -92,6 +104,12 @@ tests: - equal: path: data.BRAINSTORE_REALTIME_WAL_URI value: "gs://test-brainstore-bucket/brainstore/wal" + - equal: + path: data.BRAINSTORE_RESPONSE_CACHE_URI + value: "gs://test-api-bucket/response" + - equal: + path: data.BRAINSTORE_CODE_BUNDLE_URI + value: "gs://test-api-bucket/code-bundle" - it: should include locks URI when locksBackend is objectStorage for AWS values: @@ -182,3 +200,59 @@ tests: - equal: path: metadata.annotations["custom-annotation"] value: value + + - it: should not include no-pg vars when skipPgForBrainstoreObjects is not set + values: + - __fixtures__/base-values.yaml + release: + namespace: "braintrust" + asserts: + - isNull: + path: data.BRAINSTORE_ASYNC_SCORING_OBJECTS + - isNull: + path: data.BRAINSTORE_LOG_AUTOMATIONS_OBJECTS + + - it: should include no-pg vars when skipPgForBrainstoreObjects is "all" + values: + - __fixtures__/base-values.yaml + set: + skipPgForBrainstoreObjects: "all" + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_ASYNC_SCORING_OBJECTS + value: "all" + - equal: + path: data.BRAINSTORE_LOG_AUTOMATIONS_OBJECTS + value: "all" + + - it: should pass through include-style skipPgForBrainstoreObjects value + values: + - __fixtures__/base-values.yaml + set: + skipPgForBrainstoreObjects: "include:project_logs:abc123" + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_ASYNC_SCORING_OBJECTS + value: "include:project_logs:abc123" + - equal: + path: data.BRAINSTORE_LOG_AUTOMATIONS_OBJECTS + value: "include:project_logs:abc123" + + - it: should pass through exclude-style skipPgForBrainstoreObjects value + values: + - __fixtures__/base-values.yaml + set: + skipPgForBrainstoreObjects: "exclude:project_logs:abc123" + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_ASYNC_SCORING_OBJECTS + value: "exclude:project_logs:abc123" + - equal: + path: data.BRAINSTORE_LOG_AUTOMATIONS_OBJECTS + value: "exclude:project_logs:abc123" diff --git a/braintrust/tests/brainstore-writer-configmap_test.yaml b/braintrust/tests/brainstore-writer-configmap_test.yaml index 0de94d4..000755e 100644 --- a/braintrust/tests/brainstore-writer-configmap_test.yaml +++ b/braintrust/tests/brainstore-writer-configmap_test.yaml @@ -61,6 +61,12 @@ tests: - equal: path: data.BRAINSTORE_REALTIME_WAL_URI value: "s3://test-brainstore-bucket/brainstore/wal" + - equal: + path: data.BRAINSTORE_RESPONSE_CACHE_URI + value: "s3://test-response-bucket" + - equal: + path: data.BRAINSTORE_CODE_BUNDLE_URI + value: "s3://test-code-bundle-bucket" - it: should configure Azure URIs when cloud is azure values: @@ -78,6 +84,12 @@ tests: - equal: path: data.BRAINSTORE_REALTIME_WAL_URI value: "az://brainstore/brainstore/wal" + - equal: + path: data.BRAINSTORE_RESPONSE_CACHE_URI + value: "az://responses" + - equal: + path: data.BRAINSTORE_CODE_BUNDLE_URI + value: "az://code-bundles" - it: should configure Google Cloud URIs when cloud is google values: @@ -92,6 +104,12 @@ tests: - equal: path: data.BRAINSTORE_REALTIME_WAL_URI value: "gs://test-brainstore-bucket/brainstore/wal" + - equal: + path: data.BRAINSTORE_RESPONSE_CACHE_URI + value: "gs://test-api-bucket/response" + - equal: + path: data.BRAINSTORE_CODE_BUNDLE_URI + value: "gs://test-api-bucket/code-bundle" - it: should include locks URI when locksBackend is objectStorage for AWS values: @@ -182,3 +200,59 @@ tests: - equal: path: metadata.annotations["custom-annotation"] value: value + + - it: should not include no-pg vars when skipPgForBrainstoreObjects is not set + values: + - __fixtures__/base-values.yaml + release: + namespace: "braintrust" + asserts: + - isNull: + path: data.BRAINSTORE_ASYNC_SCORING_OBJECTS + - isNull: + path: data.BRAINSTORE_LOG_AUTOMATIONS_OBJECTS + + - it: should include no-pg vars when skipPgForBrainstoreObjects is "all" + values: + - __fixtures__/base-values.yaml + set: + skipPgForBrainstoreObjects: "all" + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_ASYNC_SCORING_OBJECTS + value: "all" + - equal: + path: data.BRAINSTORE_LOG_AUTOMATIONS_OBJECTS + value: "all" + + - it: should pass through include-style skipPgForBrainstoreObjects value + values: + - __fixtures__/base-values.yaml + set: + skipPgForBrainstoreObjects: "include:project_logs:abc123" + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_ASYNC_SCORING_OBJECTS + value: "include:project_logs:abc123" + - equal: + path: data.BRAINSTORE_LOG_AUTOMATIONS_OBJECTS + value: "include:project_logs:abc123" + + - it: should pass through exclude-style skipPgForBrainstoreObjects value + values: + - __fixtures__/base-values.yaml + set: + skipPgForBrainstoreObjects: "exclude:project_logs:abc123" + release: + namespace: "braintrust" + asserts: + - equal: + path: data.BRAINSTORE_ASYNC_SCORING_OBJECTS + value: "exclude:project_logs:abc123" + - equal: + path: data.BRAINSTORE_LOG_AUTOMATIONS_OBJECTS + value: "exclude:project_logs:abc123" diff --git a/braintrust/values.yaml b/braintrust/values.yaml index 544b4aa..c8e5e01 100644 --- a/braintrust/values.yaml +++ b/braintrust/values.yaml @@ -68,6 +68,24 @@ objectStorage: # Single API bucket with paths for responses and code bundles apiBucket: "" +# No-PG mode: controls which object types bypass PostgreSQL and use Brainstore directly. +# WARNING: This is a one-way operation. Once migrated off Postgres, objects cannot be +# un-migrated without downtime. +# Options: +# - "" (default): disabled, PostgreSQL used as normal +# - "all": skip PostgreSQL for all object types +# - "include::,...": skip for specific objects only +# e.g. "include:project_logs:5ad850f0-...,project_logs:45b3aed2-..." +# - "exclude::,...": skip for all objects except specific ones +# e.g. "exclude:project_logs:5ad850f0-..." +skipPgForBrainstoreObjects: "" + +# WAL footer version controls the format of WAL entries written by Brainstore. +# This must be enabled in a SEPARATE deploy after all nodes are running the target version. +# Progression: "" (default) -> "v1" (on 1.1.32) -> "v3" (on 2.0, same deploy as image bump) +# WARNING: Do not set "v3" until all nodes are running Data Plane 2.0 images. +brainstoreWalFooterVersion: "" + api: name: "braintrust-api" labels: {}