Skip to content

[ENH]: Rust sysdb schema migration service#6069

Merged
tanujnay112 merged 1 commit intomainfrom
spanner-changes
Dec 21, 2025
Merged

[ENH]: Rust sysdb schema migration service#6069
tanujnay112 merged 1 commit intomainfrom
spanner-changes

Conversation

@tanujnay112
Copy link
Copy Markdown
Contributor

@tanujnay112 tanujnay112 commented Dec 19, 2025

Description of changes

Summarize the changes made by this PR.

  • Improvements & Bug fixes
    • Create a rust-sysdb-migration service that bootstraps the Spanner emulator and runs a stub migration service binary.
    • Moved spanner emulator configuration to a common crate.
  • New functionality
    • ...

Test plan

How are these changes tested?

  • Tests pass locally with pytest for python, yarn test for js, cargo test for rust

Migration plan

Are there any migrations, or any forwards/backwards compatibility changes needed in order to make sure this change deploys reliably?

Observability plan

What is the plan to instrument and monitor this change?

Documentation Changes

Are all docstrings for user-facing APIs updated if required? Do we need to make documentation changes in the _docs section?_

Copy link
Copy Markdown
Contributor Author

tanujnay112 commented Dec 19, 2025

@github-actions
Copy link
Copy Markdown

Reviewer Checklist

Please leverage this checklist to ensure your code review is thorough before approving

Testing, Bugs, Errors, Logs, Documentation

  • Can you think of any use case in which the code does not behave as intended? Have they been tested?
  • Can you think of any inputs or external events that could break the code? Is user input validated and safe? Have they been tested?
  • If appropriate, are there adequate property based tests?
  • If appropriate, are there adequate unit tests?
  • Should any logging, debugging, tracing information be added or removed?
  • Are error messages user-friendly?
  • Have all documentation changes needed been made?
  • Have all non-obvious changes been commented?

System Compatibility

  • Are there any potential impacts on other parts of the system or backward compatibility?
  • Does this change intersect with any items on our roadmap, and if so, is there a plan for fitting them together?

Quality

  • Is this code of a unexpectedly high quality (Readability, Modularity, Intuitiveness)

@github-actions
Copy link
Copy Markdown

⚠️ The Helm chart was updated without a version bump. Your changes will only be published if the version field in k8s/distributed-chroma/Chart.yaml is updated.

@tanujnay112 tanujnay112 force-pushed the spanner-changes branch 4 times, most recently from 8a541ce to 8acc93a Compare December 19, 2025 08:04
@tanujnay112 tanujnay112 changed the title [ENH]: Spanner schema migration [ENH]: Rust sysdb schema migration service Dec 19, 2025
@tanujnay112 tanujnay112 marked this pull request as ready for review December 19, 2025 22:10
@propel-code-bot
Copy link
Copy Markdown
Contributor

propel-code-bot Bot commented Dec 19, 2025

Add rust-based Spanner migration service and centralize emulator config

Introduces a Rust spanner-migrations binary and Kubernetes job that bootstraps the Spanner emulator before schema migrations, while refactoring emulator configuration into the shared chroma-config crate. Updates the Rust workspace, Docker build, and Tilt/Helm assets so the new migration job is built, published, and supplied with configuration separate from the runtime sysdb service.
This release also removes inline emulator bootstrap logic from rust-sysdb, aligns both services on the shared config structures, and promotes the Rust toolchain to 1.88 for the unified builder image.

Key Changes

• Added rust/rust-sysdb/spanner-migrations crate with bootstrap_emulator gRPC admin flow and configuration loader for the migration job
• Moved SpannerConfig and SpannerEmulatorConfig into rust/config/src/spanner.rs and re-exported them from rust-sysdb/src/config.rs
• Updated rust/rust-sysdb/src/spanner.rs to rely on pre-created emulator resources and removed REST bootstrap logic
• Extended rust/Dockerfile (Rust 1.88) to build and package the spanner_migration binary and added a new runtime stage
• Provisioned Helm/Tilt plumbing (k8s/distributed-chroma/templates/rust-sysdb-migration.yaml, Tiltfile, .github/actions/tilt-setup-prebuild/docker-bake.hcl, k8s/distributed-chroma/values.yaml) to deploy the migration job with optional ConfigMap-based configuration

Affected Areas

• rust/rust-sysdb/spanner-migrations/src
• rust/config/src/spanner.rs
• rust/rust-sysdb/src/config.rs
• rust/rust-sysdb/src/spanner.rs
• rust/Dockerfile
• Tiltfile
• k8s/distributed-chroma/templates/rust-sysdb-migration.yaml
• k8s/distributed-chroma/values.yaml
• Cargo workspace metadata

This summary was automatically generated by @propel-code-bot

Comment thread Tiltfile Outdated
Comment thread go/Dockerfile.rust-migration Outdated
Comment thread rust/rust-sysdb/spanner-config/src/lib.rs Outdated
@tanujnay112 tanujnay112 force-pushed the spanner-changes branch 2 times, most recently from 5316f50 to 335646c Compare December 20, 2025 02:02
Comment thread .github/actions/tilt-setup-prebuild/docker-bake.hcl Outdated
Comment thread k8s/distributed-chroma/templates/rust-sysdb-migration.yaml Outdated
Comment thread .github/actions/tilt-setup-prebuild/docker-bake.hcl
metadata:
name: rust-sysdb-migration-{{ .Values.rustSysdbMigration.image.tag }}
namespace: {{ .Values.namespace }}
annotations:
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.

do you need annotations?

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.

keeping it because sysdb-migration service has it

Copy link
Copy Markdown
Contributor

@sanketkedia sanketkedia Dec 21, 2025

Choose a reason for hiding this comment

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

right, but why does it need it was my question

- name: config
configMap:
name: rust-sysdb-migration-config
{{if .Values.rustSysdbMigration.tolerations}}
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.

does it need tolerations and node selector?

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.

keeping since sysdb-migration has

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.

reading the description, it doesn't seem like it's applicable here. would prefer to clean this up in a future change along with sysdb-migration service.

@@ -0,0 +1,149 @@
//! Shared Spanner configuration types.
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.

thoughts on moving this to the chroma-config crate instead of creating one here? In general, I was thinking of moving all the mcmr common config (like topology, regions, etc) into this crate and reuse it across services.

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.

Even the bootstrap function?

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.

why does the bootstrap function need to be shared? shouldn't only the rust-sysdb-migration perform the bootstrap? and rust-sysdb assume that all the entities exist in the db?

Comment thread rust/rust-sysdb/spanner-config/src/lib.rs Outdated
Comment thread k8s/distributed-chroma/values.yaml Outdated
image:
repository: 'rust-sysdb-migration'
tag: 'latest'
project: chroma-dev
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.

why not use the rust/worker/chroma_config.yaml directly. We inject config using that and not helm values. It'd be hard to maintain this with that

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.

create a rust_sysdb_migration section and put it under there. Next week, I'll centralize all of this under mcmr_config section

@@ -0,0 +1,10 @@
[package]
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.

see above. would prefer it to be a part of chroma-config crate

@tanujnay112 tanujnay112 force-pushed the spanner-changes branch 2 times, most recently from ac91667 to 2bac7cf Compare December 20, 2025 22:09
Comment thread rust/rust-sysdb/spanner-migrations/src/config.rs Outdated
Comment thread rust/rust-sysdb/spanner-config/src/lib.rs Outdated
Comment thread rust/rust-sysdb/spanner-migrations/src/config.rs Outdated
Comment thread rust/rust-sysdb/spanner-migrations/src/main.rs Outdated
Comment thread rust/rust-sysdb/spanner-migrations/src/main.rs
Comment on lines +1 to +50
{{- if .Values.rustSysdbMigration.configuration }}
apiVersion: v1
kind: ConfigMap
metadata:
name: rust-sysdb-migration-config
namespace: {{ .Values.namespace }}
data:
config.yaml: |
{{ .Values.rustSysdbMigration.configuration | indent 4 }}
---
{{- end }}
apiVersion: batch/v1
kind: Job
metadata:
name: rust-sysdb-migration-{{ .Values.rustSysdbMigration.image.tag }}
namespace: {{ .Values.namespace }}
spec:
template:
metadata:
labels:
app: rust-sysdb-migration
spec:
restartPolicy: OnFailure
containers:
- name: rust-sysdb-migration
image: "{{ .Values.rustSysdbMigration.image.repository }}:{{ .Values.rustSysdbMigration.image.tag }}"
imagePullPolicy: IfNotPresent
env:
- name: CONFIG_PATH
value: "/config/config.yaml"
volumeMounts:
{{- if .Values.rustSysdbMigration.configuration }}
- name: config
mountPath: /config/
{{- end }}
{{- if .Values.rustSysdbMigration.configuration }}
volumes:
- name: config
configMap:
name: rust-sysdb-migration-config
{{- end }}
{{- if .Values.rustSysdbMigration.tolerations }}
tolerations:
{{- toYaml .Values.rustSysdbMigration.tolerations | nindent 8 }}
{{- end }}
{{- if .Values.rustSysdbMigration.nodeSelector }}
nodeSelector:
{{- toYaml .Values.rustSysdbMigration.nodeSelector | nindent 8 }}
{{- end }}
---
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.

Important

[Logic] The current Helm template creates the Job resource unconditionally, while the ConfigMap it depends on is only created if .Values.rustSysdbMigration.configuration is provided. This will cause the job to fail at runtime if no configuration is supplied, as the path specified in CONFIG_PATH will not exist.

To prevent deploying a non-functional job, it's better to make the creation of all related resources conditional on the presence of the configuration. Wrapping the entire template in a conditional block ensures that both the ConfigMap and the Job are only created when the necessary configuration is available. This also allows for the removal of redundant inner conditional checks for volumes and volume mounts.

Context for Agents
The current Helm template creates the `Job` resource unconditionally, while the `ConfigMap` it depends on is only created if `.Values.rustSysdbMigration.configuration` is provided. This will cause the job to fail at runtime if no configuration is supplied, as the path specified in `CONFIG_PATH` will not exist.

To prevent deploying a non-functional job, it's better to make the creation of all related resources conditional on the presence of the configuration. Wrapping the entire template in a conditional block ensures that both the `ConfigMap` and the `Job` are only created when the necessary configuration is available. This also allows for the removal of redundant inner conditional checks for volumes and volume mounts.

File: k8s/distributed-chroma/templates/rust-sysdb-migration.yaml
Line: 50

@tanujnay112 tanujnay112 force-pushed the spanner-changes branch 4 times, most recently from 0a8304b to 76fe609 Compare December 21, 2025 06:16
Comment thread k8s/distributed-chroma/templates/rust-sysdb-migration.yaml
Comment thread rust/worker/chroma_config.yaml Outdated
instance: "test-instance"
database: "local-database" No newline at end of file
database: "local-database"
rust-sysdb-migration:
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.

this is not needed right? Since the schema service is only in chroma2 namespace

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.

Not needed yes, removing.

Comment thread Tiltfile Outdated
k8s_yaml(
local(
'helm template --set-file rustFrontendService.configuration=' + rfe_config_file + ',rustLogService.configuration=rust/worker/chroma_config.yaml,heapTenderService.configuration=rust/worker/chroma_config.yaml,compactionService.configuration=rust/worker/chroma_config.yaml,queryService.configuration=rust/worker/chroma_config.yaml,garbageCollector.configuration=rust/worker/chroma_config.yaml,rustSysdbService.configuration=rust/worker/chroma_config.yaml --values ' + distributed_chroma_values + ' k8s/distributed-chroma'
'helm template --set-file rustFrontendService.configuration=' + rfe_config_file + ',rustLogService.configuration=rust/worker/chroma_config.yaml,heapTenderService.configuration=rust/worker/chroma_config.yaml,compactionService.configuration=rust/worker/chroma_config.yaml,queryService.configuration=rust/worker/chroma_config.yaml,garbageCollector.configuration=rust/worker/chroma_config.yaml,rustSysdbService.configuration=rust/worker/chroma_config.yaml,rustSysdbMigration.configuration=rust/worker/chroma_config.yaml --values ' + distributed_chroma_values + ' k8s/distributed-chroma'
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.

this is not needed?

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.

it populates

.Values.rustSysdbMigration.configuration 

in rust-sysdb-migration.yaml

use std::env;

const CONFIG_PATH_ENV_VAR: &str = "CONFIG_PATH";
const DEFAULT_CONFIG_PATH: &str = "./chroma_config.yaml";
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.

If this is in chroma2 namespace then should this be chroma_config2.yaml?

);

// Set environment variable for clients
std::env::set_var("SPANNER_EMULATOR_HOST", emulator.grpc_endpoint());
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.

Is this needed? since you set the config in AdminClientConfig below, I am guessing this is not needed

Comment thread Tiltfile
k8s_yaml(
local(
'helm template --set-file rustFrontendService.configuration=' + rfe_config_file + ',rustLogService.configuration=rust/worker/chroma_config.yaml,heapTenderService.configuration=rust/worker/chroma_config.yaml,compactionService.configuration=rust/worker/chroma_config.yaml,queryService.configuration=rust/worker/chroma_config.yaml,garbageCollector.configuration=rust/worker/chroma_config.yaml,rustSysdbService.configuration=rust/worker/chroma_config.yaml --values ' + distributed_chroma_values + ' k8s/distributed-chroma'
'helm template --set-file rustFrontendService.configuration=' + rfe_config_file + ',rustLogService.configuration=rust/worker/chroma_config.yaml,heapTenderService.configuration=rust/worker/chroma_config.yaml,compactionService.configuration=rust/worker/chroma_config.yaml,queryService.configuration=rust/worker/chroma_config.yaml,garbageCollector.configuration=rust/worker/chroma_config.yaml,rustSysdbService.configuration=rust/worker/chroma_config.yaml,rustSysdbMigration.configuration=rust/worker/chroma_config2.yaml --values ' + distributed_chroma_values + ' k8s/distributed-chroma'
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.

nit: I think this change is not needed

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.

it populates

.Values.rustSysdbMigration.configuration 

in rust-sysdb-migration.yaml

the service panics without this change as it can't find the configuration path

@@ -0,0 +1,50 @@
{{- if .Values.rustSysdbMigration.configuration }}
Copy link
Copy Markdown
Contributor

@sanketkedia sanketkedia Dec 21, 2025

Choose a reason for hiding this comment

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

ok to do in another PR but would encourage you to think about how to feature flag bringing up the migration service in staging/prod since it would fail currently due to no real spanner present. One idea that I've done for the rust sysdb service is disable this entire manifest conditioned on a value that you set to true in values.dev.yaml and false in values.yaml. i.e. at the top of this file add:

{{- if .Values.rustSysdbMigration.enabled }}

and at the end of this file add:

{{-end }}

And then in values.dev.yaml set
rust-sysdb-migration:
enabled: true

In values.yaml set:
rust-sysdb-migration:
enabled: false

@tanujnay112 tanujnay112 merged commit 3e2be15 into main Dec 21, 2025
64 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants