mirror of https://github.com/Budibase/budibase.git
committed by
GitHub
9 changed files with 138 additions and 12 deletions
@ -0,0 +1,13 @@ |
|||
const { migrate, MIGRATIONS } = require("../../../migrations") |
|||
|
|||
export const runMigrations = async (ctx: any) => { |
|||
const options = ctx.request.body |
|||
// don't await as can take a while, just return
|
|||
migrate(options) |
|||
ctx.status = 200 |
|||
} |
|||
|
|||
export const fetchDefinitions = async (ctx: any) => { |
|||
ctx.body = MIGRATIONS |
|||
ctx.status = 200 |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
import Router from "@koa/router" |
|||
import * as migrationsController from "../../controllers/system/migrations" |
|||
import { auth } from "@budibase/backend-core" |
|||
|
|||
const router = new Router() |
|||
|
|||
router |
|||
.post( |
|||
"/api/system/migrations/run", |
|||
auth.internalApi, |
|||
migrationsController.runMigrations |
|||
) |
|||
.get( |
|||
"/api/system/migrations/definitions", |
|||
auth.internalApi, |
|||
migrationsController.fetchDefinitions |
|||
) |
|||
|
|||
export = router |
|||
@ -0,0 +1,20 @@ |
|||
import { User } from "@budibase/types" |
|||
import * as sdk from "../../sdk" |
|||
|
|||
/** |
|||
* Date: |
|||
* Aug 2022 |
|||
* |
|||
* Description: |
|||
* Re-sync the global-db users to the global-info db users |
|||
*/ |
|||
export const run = async (globalDb: any) => { |
|||
const users = (await sdk.users.allUsers()) as User[] |
|||
const promises = [] |
|||
for (let user of users) { |
|||
promises.push( |
|||
sdk.users.addTenant(user.tenantId, user._id as string, user.email) |
|||
) |
|||
} |
|||
await Promise.all(promises) |
|||
} |
|||
@ -0,0 +1,74 @@ |
|||
import { migrations, redis } from "@budibase/backend-core" |
|||
import { Migration, MigrationOptions, MigrationName } from "@budibase/types" |
|||
import env from "../environment" |
|||
|
|||
// migration functions
|
|||
import * as syncUserInfo from "./functions/globalInfoSyncUsers" |
|||
|
|||
/** |
|||
* Populate the migration function and additional configuration from |
|||
* the static migration definitions. |
|||
*/ |
|||
export const buildMigrations = () => { |
|||
const definitions = migrations.DEFINITIONS |
|||
const workerMigrations: Migration[] = [] |
|||
|
|||
for (const definition of definitions) { |
|||
switch (definition.name) { |
|||
case MigrationName.GLOBAL_INFO_SYNC_USERS: { |
|||
// only needed in cloud
|
|||
if (!env.SELF_HOSTED) { |
|||
workerMigrations.push({ |
|||
...definition, |
|||
fn: syncUserInfo.run, |
|||
}) |
|||
} |
|||
break |
|||
} |
|||
} |
|||
} |
|||
|
|||
return workerMigrations |
|||
} |
|||
|
|||
export const MIGRATIONS = buildMigrations() |
|||
|
|||
export const migrate = async (options?: MigrationOptions) => { |
|||
if (env.SELF_HOSTED) { |
|||
await migrateWithLock(options) |
|||
} else { |
|||
await migrations.runMigrations(MIGRATIONS, options) |
|||
} |
|||
} |
|||
|
|||
const migrateWithLock = async (options?: MigrationOptions) => { |
|||
// get a new lock client
|
|||
const redlock = await redis.clients.getMigrationsRedlock() |
|||
// lock for 15 minutes
|
|||
const ttl = 1000 * 60 * 15 |
|||
|
|||
let migrationLock |
|||
|
|||
// acquire lock
|
|||
try { |
|||
migrationLock = await redlock.lock("migrations", ttl) |
|||
} catch (e: any) { |
|||
if (e.name === "LockError") { |
|||
return |
|||
} else { |
|||
throw e |
|||
} |
|||
} |
|||
|
|||
// run migrations
|
|||
try { |
|||
await migrations.runMigrations(MIGRATIONS, options) |
|||
} finally { |
|||
// release lock
|
|||
try { |
|||
await migrationLock.unlock() |
|||
} catch (e) { |
|||
console.error("unable to release migration lock") |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue