admin migrate-database

This commit is contained in:
2025-11-11 15:54:57 +01:00
parent 6f34a0a4fa
commit 31db4ede38
6 changed files with 60 additions and 5 deletions
+36 -2
View File
@@ -3,18 +3,21 @@ use std::sync::Arc;
use anyhow::{anyhow, bail, Context, Result};
use chrono::{Duration as ChronoDuration, Utc};
use clap::{Parser, Subcommand, ValueEnum};
use diesel::{dsl::exists, prelude::*, select};
use diesel::{dsl::exists, pg::PgConnection, prelude::*, select};
use diesel_migrations::MigrationHarness;
use rand::{rngs::OsRng, TryRngCore};
use reqwest::{Client, Method, StatusCode};
use sha2::{Digest, Sha256};
use tokio::task;
use uuid::Uuid;
use papercrate::{
auth::capability_sets::{ensure_capability_set, owner_capabilities},
config::AppConfig,
config::{redact_database_url, AppConfig},
db::{self, PgPool},
documents::search::ensure_quickwit_index,
jobs::{enqueue_job, JOB_ANALYZE_DOCUMENT, JOB_DELETE_TENANT},
migrations::MIGRATIONS,
models::{
DocumentAsset, DocumentAssetObject, MagicToken, MagicTokenKind, NewUser, NewUserMembership,
Tenant, TenantStatus, User,
@@ -112,6 +115,14 @@ enum Command {
#[arg(long = "kind", value_enum, default_value_t = MagicTokenKindArg::EmailLogin)]
kind: MagicTokenKindArg,
},
MigrateDatabase {
#[arg(
long = "database-url",
value_name = "URL",
help = "Override the migrations database URL (defaults to MIGRATIONS_DATABASE_URL or DATABASE_URL)"
)]
database_url: Option<String>,
},
}
#[derive(Copy, Clone, Debug, ValueEnum)]
@@ -211,11 +222,34 @@ async fn main() -> Result<()> {
} => {
create_magic_token(&pool, &username, ttl_minutes, max_uses, kind.into())?;
}
Command::MigrateDatabase { database_url } => {
let url = database_url.unwrap_or_else(|| config.migrations_database_url().to_string());
migrate_database(url).await?;
}
}
Ok(())
}
async fn migrate_database(database_url: String) -> Result<()> {
let redacted = redact_database_url(&database_url);
tracing::info!(database_url = %redacted, "running pending migrations");
let result = task::spawn_blocking(move || -> Result<()> {
let mut conn =
PgConnection::establish(&database_url).context("failed to connect to database")?;
conn.run_pending_migrations(MIGRATIONS)
.map_err(|err| anyhow!("failed to run migrations: {err}"))?;
Ok(())
})
.await
.context("migration task panicked")?;
result?;
tracing::info!(database_url = %redacted, "migrations completed");
Ok(())
}
fn create_user(pool: &PgPool, username: &str) -> Result<()> {
let username = normalize_identifier(
username,