Migrate automatically on service start (#7103)

Conrad Irwin created

This avoids a forgettable manual step in deploying collab

Release Notes:

- N/A

Change summary

crates/collab/src/main.rs | 63 +++++++++++++++-------------------------
script/deploy-migration   | 26 ----------------
2 files changed, 24 insertions(+), 65 deletions(-)

Detailed changes

crates/collab/src/main.rs 🔗

@@ -28,49 +28,11 @@ async fn main() -> Result<()> {
         Some("version") => {
             println!("collab v{VERSION}");
         }
-        Some("migrate") => {
-            let config = envy::from_env::<MigrateConfig>().expect("error loading config");
-            let mut db_options = db::ConnectOptions::new(config.database_url.clone());
-            db_options.max_connections(5);
-            let db = Database::new(db_options, Executor::Production).await?;
-
-            let migrations_path = config
-                .migrations_path
-                .as_deref()
-                .unwrap_or_else(|| Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/migrations")));
-
-            let migrations = db.migrate(&migrations_path, false).await?;
-            for (migration, duration) in migrations {
-                println!(
-                    "Ran {} {} {:?}",
-                    migration.version, migration.description, duration
-                );
-            }
-
-            return Ok(());
-        }
         Some("serve") => {
             let config = envy::from_env::<Config>().expect("error loading config");
             init_tracing(&config);
 
-            if config.is_development() {
-                // sanity check database url so even if we deploy a busted ZED_ENVIRONMENT to production
-                // we do not run
-                if config.database_url != "postgres://postgres@localhost/zed" {
-                    panic!("about to run development migrations on a non-development database?")
-                }
-                let migrations_path = Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/migrations"));
-                let db_options = db::ConnectOptions::new(config.database_url.clone());
-                let db = Database::new(db_options, Executor::Production).await?;
-
-                let migrations = db.migrate(&migrations_path, false).await?;
-                for (migration, duration) in migrations {
-                    println!(
-                        "Ran {} {} {:?}",
-                        migration.version, migration.description, duration
-                    );
-                }
-            }
+            run_migrations().await?;
 
             let state = AppState::new(config).await?;
 
@@ -116,6 +78,29 @@ async fn main() -> Result<()> {
     Ok(())
 }
 
+async fn run_migrations() -> Result<()> {
+    let config = envy::from_env::<MigrateConfig>().expect("error loading config");
+    let db_options = db::ConnectOptions::new(config.database_url.clone());
+    let db = Database::new(db_options, Executor::Production).await?;
+
+    let migrations_path = config
+        .migrations_path
+        .as_deref()
+        .unwrap_or_else(|| Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/migrations")));
+
+    let migrations = db.migrate(&migrations_path, false).await?;
+    for (migration, duration) in migrations {
+        log::info!(
+            "Migrated {} {} {:?}",
+            migration.version,
+            migration.description,
+            duration
+        );
+    }
+
+    return Ok(());
+}
+
 async fn handle_root() -> String {
     format!("collab v{VERSION}")
 }

script/deploy-migration 🔗

@@ -1,26 +0,0 @@
-#!/bin/bash
-
-set -eu
-source script/lib/deploy-helpers.sh
-
-if [[ $# < 2 ]]; then
-  echo "Usage: $0 <production|staging|preview|nightly> <tag-name>"
-  exit 1
-fi
-environment=$1
-version=$2
-
-export_vars_for_environment ${environment}
-image_id=$(image_id_for_version ${version})
-
-export ZED_KUBE_NAMESPACE=${environment}
-export ZED_IMAGE_ID=${image_id}
-export ZED_MIGRATE_JOB_NAME=zed-migrate-${version}
-
-target_zed_kube_cluster
-envsubst < crates/collab/k8s/migrate.template.yml | kubectl apply -f -
-
-pod=$(kubectl --namespace=${environment} get pods --selector=job-name=${ZED_MIGRATE_JOB_NAME} --output=jsonpath='{.items[0].metadata.name}')
-
-echo "Job pod:" $pod
-kubectl --namespace=${environment} logs -f ${pod}