diff --git a/packages/auth/src/db/Replication.js b/packages/auth/src/db/Replication.js index 931bc3d496..7af3c2eb9d 100644 --- a/packages/auth/src/db/Replication.js +++ b/packages/auth/src/db/Replication.js @@ -45,22 +45,6 @@ class Replication { return this.replication } - /** - * Set up an ongoing live sync between 2 CouchDB databases. - * @param {Object} opts - PouchDB replication options - */ - subscribe(opts = {}) { - this.replication = this.source.replicate - .to(this.target, { - live: true, - retry: true, - ...opts, - }) - .on("error", function (err) { - throw new Error(`Replication Error: ${err}`) - }) - } - /** * Rollback the target DB back to the state of the source DB */ diff --git a/packages/builder/src/pages/builder/app/[application]/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/_layout.svelte index 603fb62d99..da4317c8b7 100644 --- a/packages/builder/src/pages/builder/app/[application]/_layout.svelte +++ b/packages/builder/src/pages/builder/app/[application]/_layout.svelte @@ -1,21 +1,24 @@ {#await promise} diff --git a/packages/server/src/api/controllers/application.js b/packages/server/src/api/controllers/application.js index e3aac8bd63..e2e42c20f9 100644 --- a/packages/server/src/api/controllers/application.js +++ b/packages/server/src/api/controllers/application.js @@ -25,7 +25,12 @@ const { BASE_LAYOUTS } = require("../../constants/layouts") const { createHomeScreen } = require("../../constants/screens") const { cloneDeep } = require("lodash/fp") const { processObject } = require("@budibase/string-templates") -const { getAllApps } = require("@budibase/auth/db") +const { + getAllApps, + isDevAppID, + getDeployedAppID, + Replication, +} = require("@budibase/auth/db") const { USERS_TABLE_SCHEMA } = require("../../constants") const { getDeployedApps, @@ -134,7 +139,7 @@ async function createInstance(template) { return { _id: appId } } -exports.fetch = async function (ctx) { +exports.fetch = async ctx => { const dev = ctx.query && ctx.query.status === AppStatus.DEV const all = ctx.query && ctx.query.status === AppStatus.ALL const apps = await getAllApps(CouchDB, { dev, all }) @@ -159,7 +164,7 @@ exports.fetch = async function (ctx) { ctx.body = apps } -exports.fetchAppDefinition = async function (ctx) { +exports.fetchAppDefinition = async ctx => { const db = new CouchDB(ctx.params.appId) const layouts = await getLayouts(db) const userRoleId = getUserRoleId(ctx) @@ -175,7 +180,7 @@ exports.fetchAppDefinition = async function (ctx) { } } -exports.fetchAppPackage = async function (ctx) { +exports.fetchAppPackage = async ctx => { const db = new CouchDB(ctx.params.appId) const application = await db.get(DocumentTypes.APP_METADATA) const layouts = await getLayouts(db) @@ -196,7 +201,7 @@ exports.fetchAppPackage = async function (ctx) { } } -exports.create = async function (ctx) { +exports.create = async ctx => { const { useTemplate, templateKey, templateString } = ctx.request.body const instanceConfig = { useTemplate, @@ -252,13 +257,13 @@ exports.create = async function (ctx) { ctx.body = newApplication } -exports.update = async function (ctx) { +exports.update = async ctx => { const data = await updateAppPackage(ctx, ctx.request.body, ctx.params.appId) ctx.status = 200 ctx.body = data } -exports.updateClient = async function (ctx) { +exports.updateClient = async ctx => { // Get current app version const db = new CouchDB(ctx.params.appId) const application = await db.get(DocumentTypes.APP_METADATA) @@ -280,7 +285,7 @@ exports.updateClient = async function (ctx) { ctx.body = data } -exports.revertClient = async function (ctx) { +exports.revertClient = async ctx => { // Check app can be reverted const db = new CouchDB(ctx.params.appId) const application = await db.get(DocumentTypes.APP_METADATA) @@ -303,7 +308,7 @@ exports.revertClient = async function (ctx) { ctx.body = data } -exports.delete = async function (ctx) { +exports.delete = async ctx => { const db = new CouchDB(ctx.params.appId) const result = await db.destroy() @@ -318,6 +323,35 @@ exports.delete = async function (ctx) { ctx.body = result } +exports.sync = async ctx => { + const appId = ctx.params.appId + if (!isDevAppID(appId)) { + ctx.throw(400, "This action cannot be performed for production apps") + } + const prodAppId = getDeployedAppID(appId) + const replication = new Replication({ + source: prodAppId, + target: appId, + }) + let error + try { + await replication.replicate({ + filter: function (doc) { + return doc._id !== DocumentTypes.APP_METADATA + }, + }) + } catch (err) { + error = err + } + if (error) { + ctx.throw(400, error) + } else { + ctx.body = { + message: "App sync completed successfully.", + } + } +} + const updateAppPackage = async (ctx, appPackage, appId) => { const url = await getAppUrlIfNotInUse(ctx) const db = new CouchDB(appId) diff --git a/packages/server/src/api/controllers/deploy/index.js b/packages/server/src/api/controllers/deploy/index.js index d68b2064d7..13002476fc 100644 --- a/packages/server/src/api/controllers/deploy/index.js +++ b/packages/server/src/api/controllers/deploy/index.js @@ -1,6 +1,6 @@ const CouchDB = require("../../../db") const Deployment = require("./Deployment") -const { Replication } = require("@budibase/auth/db") +const { Replication, getDeployedAppID } = require("@budibase/auth/db") const { DocumentTypes, getAutomationParams } = require("../../../db/utils") const { disableAllCrons, @@ -87,7 +87,7 @@ async function initDeployedApp(prodAppId) { async function deployApp(deployment) { try { - const productionAppId = deployment.appId.replace("_dev", "") + const productionAppId = getDeployedAppID(deployment.appId) const replication = new Replication({ source: deployment.appId, @@ -104,23 +104,8 @@ async function deployApp(deployment) { appDoc.instance._id = productionAppId await db.put(appDoc) console.log("New app doc written successfully.") - - console.log("Setting up live repl between dev and prod") - // Set up live sync between the live and dev instances - const liveReplication = new Replication({ - source: productionAppId, - target: deployment.appId, - }) - liveReplication.subscribe({ - filter: function (doc) { - return doc._id !== DocumentTypes.APP_METADATA - }, - }) - console.log("Set up live repl between dev and prod") - - console.log("Initialising deployed app") await initDeployedApp(productionAppId) - console.log("Init complete, setting deployment to successful") + console.log("Deployed app initialised, setting deployment to successful") deployment.setStatus(DeploymentStatus.SUCCESS) await storeDeploymentHistory(deployment) } catch (err) { diff --git a/packages/server/src/api/routes/application.js b/packages/server/src/api/routes/application.js index 4d67a0f4f4..1a21cc8216 100644 --- a/packages/server/src/api/routes/application.js +++ b/packages/server/src/api/routes/application.js @@ -7,6 +7,7 @@ const usage = require("../../middleware/usageQuota") const router = Router() router + .post("/api/applications/:appId/sync", authorized(BUILDER), controller.sync) .post("/api/applications", authorized(BUILDER), usage, controller.create) .get("/api/applications/:appId/definition", controller.fetchAppDefinition) .get("/api/applications", controller.fetch)