Merge branch 'master' into fix/aws-session-token-s3-ver2
This commit is contained in:
commit
cede6a8a0b
|
@ -1,4 +1,4 @@
|
|||
import queue from "./queue"
|
||||
import { getAppMigrationQueue } from "./queue"
|
||||
import { Next } from "koa"
|
||||
import { getAppMigrationVersion } from "./appMigrationMetadata"
|
||||
import { MIGRATIONS } from "./migrations"
|
||||
|
@ -37,8 +37,10 @@ export async function checkMissingMigrations(
|
|||
) {
|
||||
const currentVersion = await getAppMigrationVersion(appId)
|
||||
const latestMigration = getLatestEnabledMigrationId()
|
||||
const queue = getAppMigrationQueue()
|
||||
|
||||
if (
|
||||
queue &&
|
||||
latestMigration &&
|
||||
getTimestamp(currentVersion) < getTimestamp(latestMigration)
|
||||
) {
|
||||
|
|
|
@ -12,17 +12,19 @@ export async function processMigrations(
|
|||
migrations: AppMigration[]
|
||||
) {
|
||||
console.log(`Processing app migration for "${appId}"`)
|
||||
// have to wrap in context, this gets the tenant from the app ID
|
||||
await context.doInAppContext(appId, async () => {
|
||||
await locks.doWithLock(
|
||||
{
|
||||
name: LockName.APP_MIGRATION,
|
||||
type: LockType.AUTO_EXTEND,
|
||||
resource: appId,
|
||||
},
|
||||
async () => {
|
||||
try {
|
||||
try {
|
||||
// have to wrap in context, this gets the tenant from the app ID
|
||||
await context.doInAppContext(appId, async () => {
|
||||
console.log(`Acquiring app migration lock for "${appId}"`)
|
||||
await locks.doWithLock(
|
||||
{
|
||||
name: LockName.APP_MIGRATION,
|
||||
type: LockType.AUTO_EXTEND,
|
||||
resource: appId,
|
||||
},
|
||||
async () => {
|
||||
await context.doInAppMigrationContext(appId, async () => {
|
||||
console.log(`Lock acquired starting app migration for "${appId}"`)
|
||||
let currentVersion = await getAppMigrationVersion(appId)
|
||||
|
||||
const pendingMigrations = migrations
|
||||
|
@ -30,6 +32,9 @@ export async function processMigrations(
|
|||
.sort((a, b) => a.id.localeCompare(b.id))
|
||||
|
||||
const migrationIds = migrations.map(m => m.id).sort()
|
||||
console.log(
|
||||
`App migrations to run for "${appId}" - ${migrationIds.join(",")}`
|
||||
)
|
||||
|
||||
let index = 0
|
||||
for (const { id, func } of pendingMigrations) {
|
||||
|
@ -55,13 +60,13 @@ export async function processMigrations(
|
|||
currentVersion = id
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
logging.logAlert("Failed to run app migration", err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
console.log(`App migration for "${appId}" processed`)
|
||||
})
|
||||
console.log(`App migration for "${appId}" processed`)
|
||||
})
|
||||
} catch (err) {
|
||||
logging.logAlert("Failed to run app migration", err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,23 +2,40 @@ import { queue, logging } from "@budibase/backend-core"
|
|||
import { Job } from "bull"
|
||||
import { MIGRATIONS } from "./migrations"
|
||||
import { processMigrations } from "./migrationsProcessor"
|
||||
import { apiEnabled } from "../features"
|
||||
|
||||
const MAX_ATTEMPTS = 3
|
||||
const MAX_ATTEMPTS = 1
|
||||
|
||||
const appMigrationQueue = queue.createQueue(queue.JobQueue.APP_MIGRATION, {
|
||||
jobOptions: {
|
||||
attempts: MAX_ATTEMPTS,
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
},
|
||||
maxStalledCount: MAX_ATTEMPTS,
|
||||
removeStalledCb: async (job: Job) => {
|
||||
logging.logAlert(
|
||||
`App migration failed, queue job ID: ${job.id} - reason: ${job.failedReason}`
|
||||
)
|
||||
},
|
||||
})
|
||||
appMigrationQueue.process(processMessage)
|
||||
export type AppMigrationJob = {
|
||||
appId: string
|
||||
}
|
||||
|
||||
let appMigrationQueue: queue.Queue<AppMigrationJob> | undefined
|
||||
|
||||
export function init() {
|
||||
// only run app migrations in main API services
|
||||
if (!apiEnabled()) {
|
||||
return
|
||||
}
|
||||
appMigrationQueue = queue.createQueue<AppMigrationJob>(
|
||||
queue.JobQueue.APP_MIGRATION,
|
||||
{
|
||||
jobOptions: {
|
||||
attempts: MAX_ATTEMPTS,
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
},
|
||||
maxStalledCount: MAX_ATTEMPTS,
|
||||
removeStalledCb: async (job: Job) => {
|
||||
logging.logAlert(
|
||||
`App migration failed, queue job ID: ${job.id} - reason: ${job.failedReason}`
|
||||
)
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
return appMigrationQueue.process(processMessage)
|
||||
}
|
||||
|
||||
async function processMessage(job: Job) {
|
||||
const { appId } = job.data
|
||||
|
@ -26,4 +43,6 @@ async function processMessage(job: Job) {
|
|||
await processMigrations(appId, MIGRATIONS)
|
||||
}
|
||||
|
||||
export default appMigrationQueue
|
||||
export function getAppMigrationQueue() {
|
||||
return appMigrationQueue
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import { KoaAdapter } from "@bull-board/koa"
|
|||
import { queue } from "@budibase/backend-core"
|
||||
import * as automation from "../threads/automation"
|
||||
import { backups } from "@budibase/pro"
|
||||
import { getAppMigrationQueue } from "../appMigrations/queue"
|
||||
import { createBullBoard } from "@bull-board/api"
|
||||
import BullQueue from "bull"
|
||||
|
||||
|
@ -16,10 +17,14 @@ const PATH_PREFIX = "/bulladmin"
|
|||
export async function init() {
|
||||
// Set up queues for bull board admin
|
||||
const backupQueue = backups.getBackupQueue()
|
||||
const appMigrationQueue = getAppMigrationQueue()
|
||||
const queues = [automationQueue]
|
||||
if (backupQueue) {
|
||||
queues.push(backupQueue)
|
||||
}
|
||||
if (appMigrationQueue) {
|
||||
queues.push(appMigrationQueue)
|
||||
}
|
||||
const adapters = []
|
||||
const serverAdapter: any = new KoaAdapter()
|
||||
for (let queue of queues) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import * as fileSystem from "../utilities/fileSystem"
|
|||
import { default as eventEmitter, init as eventInit } from "../events"
|
||||
import * as migrations from "../migrations"
|
||||
import * as bullboard from "../automations/bullboard"
|
||||
import * as appMigrations from "../appMigrations/queue"
|
||||
import * as pro from "@budibase/pro"
|
||||
import * as api from "../api"
|
||||
import sdk from "../sdk"
|
||||
|
@ -114,6 +115,7 @@ export async function startup(
|
|||
// configure events to use the pro audit log write
|
||||
// can't integrate directly into backend-core due to cyclic issues
|
||||
queuePromises.push(events.processors.init(pro.sdk.auditLogs.write))
|
||||
queuePromises.push(appMigrations.init())
|
||||
if (automationsEnabled()) {
|
||||
queuePromises.push(automations.init())
|
||||
}
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
export * from "./environment"
|
||||
export * from "./status"
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
export type SystemStatusResponse = {
|
||||
passing?: boolean
|
||||
checks?: {
|
||||
login: boolean
|
||||
search: boolean
|
||||
}
|
||||
health?: {
|
||||
passing: boolean
|
||||
}
|
||||
version?: string
|
||||
}
|
|
@ -1,16 +1,24 @@
|
|||
import { accounts } from "@budibase/backend-core"
|
||||
import { accounts, env as coreEnv } from "@budibase/backend-core"
|
||||
import { Ctx, SystemStatusResponse } from "@budibase/types"
|
||||
import env from "../../../environment"
|
||||
import { BBContext } from "@budibase/types"
|
||||
|
||||
export const fetch = async (ctx: BBContext) => {
|
||||
export const fetch = async (ctx: Ctx<void, SystemStatusResponse>) => {
|
||||
let status: SystemStatusResponse | undefined
|
||||
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
|
||||
const status = await accounts.getStatus()
|
||||
ctx.body = status
|
||||
} else {
|
||||
ctx.body = {
|
||||
status = await accounts.getStatus()
|
||||
}
|
||||
|
||||
if (!status) {
|
||||
status = {
|
||||
health: {
|
||||
passing: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if (coreEnv.VERSION) {
|
||||
status.version = coreEnv.VERSION
|
||||
}
|
||||
|
||||
ctx.body = status
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ describe("/api/system/status", () => {
|
|||
health: {
|
||||
passing: true,
|
||||
},
|
||||
version: expect.any(String),
|
||||
})
|
||||
expect(accounts.getStatus).toHaveBeenCalledTimes(0)
|
||||
config.cloudHosted()
|
||||
|
|
Loading…
Reference in New Issue