diff --git a/backend/migrations/20251006143821_ducklake_instance_settings_safety_migration.down.sql b/backend/migrations/20251006143821_ducklake_instance_settings_safety_migration.down.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/backend/migrations/20251006143821_ducklake_instance_settings_safety_migration.up.sql b/backend/migrations/20251006143821_ducklake_instance_settings_safety_migration.up.sql new file mode 100644 index 0000000000..05a111edfd --- /dev/null +++ b/backend/migrations/20251006143821_ducklake_instance_settings_safety_migration.up.sql @@ -0,0 +1,27 @@ +-- Copy of 20250731132157_ducklake_instance_settings.up.sql +-- Pushing a instance_settings.yaml without ducklake_user_pg_pwd will remove it from the global settings +-- And the next migration will fail because it will try to insert a NULL value + +INSERT INTO global_settings (name, value) +VALUES ('ducklake_user_pg_pwd', ('"' || gen_random_uuid()::text || '"')::jsonb) +ON CONFLICT DO NOTHING; + +-- Cannot simply create the user because Postgres expect a static string for the password +-- Also we cannot drop the user easily in the down migration because databases will depend on it +-- And we cannot drop databases in transactions (migrations) + +DO $$ +DECLARE + pwd text; +BEGIN + SELECT trim(both '"' from value::text) INTO pwd FROM global_settings WHERE name = 'ducklake_user_pg_pwd'; + IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'ducklake_user') THEN + EXECUTE format('CREATE USER ducklake_user WITH PASSWORD %L', pwd); + ELSE + EXECUTE format('ALTER USER ducklake_user WITH PASSWORD %L', pwd); + END IF; +EXCEPTION + WHEN others THEN + RAISE NOTICE 'ducklake_user migration error, skipping.'; +END +$$; \ No newline at end of file diff --git a/backend/windmill-api/src/settings.rs b/backend/windmill-api/src/settings.rs index b1c9df8536..4851130286 100644 --- a/backend/windmill-api/src/settings.rs +++ b/backend/windmill-api/src/settings.rs @@ -218,6 +218,10 @@ pub struct Value { } pub async fn delete_global_setting(db: &DB, key: &str) -> error::Result<()> { + if key == "ducklake_user_pg_pwd" || key == "ducklake_settings" { + tracing::error!("Tried to unset global setting {}, ignored", key); + return Ok(()); + } sqlx::query!("DELETE FROM global_settings WHERE name = $1", key,) .execute(db) .await?;