diff --git a/forge/db/models/Project.js b/forge/db/models/Project.js index c972312f41..d9b8b1013a 100644 --- a/forge/db/models/Project.js +++ b/forge/db/models/Project.js @@ -17,7 +17,7 @@ const { col, fn, DataTypes, Op, where } = require('sequelize') const Controllers = require('../controllers') -const { KEY_HOSTNAME, KEY_SETTINGS, KEY_HA, KEY_PROTECTED, KEY_HEALTH_CHECK_INTERVAL, KEY_CUSTOM_HOSTNAME } = require('./ProjectSettings') +const { KEY_HOSTNAME, KEY_SETTINGS, KEY_HA, KEY_PROTECTED, KEY_HEALTH_CHECK_INTERVAL, KEY_CUSTOM_HOSTNAME, KEY_DISABLE_AUTO_SAFE_MODE } = require('./ProjectSettings') const BANNED_NAME_LIST = [ 'app', @@ -408,7 +408,8 @@ module.exports = { { key: KEY_HA }, { key: KEY_PROTECTED }, { key: KEY_CUSTOM_HOSTNAME }, - { key: KEY_HEALTH_CHECK_INTERVAL } + { key: KEY_HEALTH_CHECK_INTERVAL }, + { key: KEY_DISABLE_AUTO_SAFE_MODE } ] }, required: false diff --git a/forge/db/models/ProjectSettings.js b/forge/db/models/ProjectSettings.js index 628574e766..4f6b50e2de 100644 --- a/forge/db/models/ProjectSettings.js +++ b/forge/db/models/ProjectSettings.js @@ -16,6 +16,7 @@ const KEY_PROTECTED = 'protected' const KEY_HEALTH_CHECK_INTERVAL = 'healthCheckInterval' const KEY_CUSTOM_HOSTNAME = 'customHostname' const KEY_SHARED_ASSETS = 'sharedAssets' +const KEY_DISABLE_AUTO_SAFE_MODE = 'disableAutoSafeMode' module.exports = { KEY_SETTINGS, @@ -25,6 +26,7 @@ module.exports = { KEY_HEALTH_CHECK_INTERVAL, KEY_CUSTOM_HOSTNAME, KEY_SHARED_ASSETS, + KEY_DISABLE_AUTO_SAFE_MODE, name: 'ProjectSettings', schema: { ProjectId: { type: DataTypes.UUID, unique: 'pk_settings' }, diff --git a/forge/db/views/Project.js b/forge/db/views/Project.js index 3d9033c4d8..2f4c4d28d1 100644 --- a/forge/db/views/Project.js +++ b/forge/db/views/Project.js @@ -1,4 +1,4 @@ -const { KEY_HOSTNAME, KEY_SETTINGS, KEY_HA, KEY_PROTECTED, KEY_HEALTH_CHECK_INTERVAL, KEY_CUSTOM_HOSTNAME } = require('../models/ProjectSettings') +const { KEY_HOSTNAME, KEY_SETTINGS, KEY_HA, KEY_PROTECTED, KEY_HEALTH_CHECK_INTERVAL, KEY_CUSTOM_HOSTNAME, KEY_DISABLE_AUTO_SAFE_MODE } = require('../models/ProjectSettings') module.exports = function (app) { app.addSchema({ @@ -37,7 +37,8 @@ module.exports = function (app) { launcherSettings: { type: 'object', properties: { - healthCheckInterval: { type: 'number' } + healthCheckInterval: { type: 'number' }, + disableAutoSafeMode: { type: 'boolean' } }, additionalProperties: false } @@ -75,6 +76,11 @@ module.exports = function (app) { result.launcherSettings = {} result.launcherSettings.healthCheckInterval = heathCheckIntervalRow?.value } + const disableAutoSafeMode = proj.ProjectSettings?.find((projectSettingsRow) => projectSettingsRow.key === KEY_DISABLE_AUTO_SAFE_MODE) + if (typeof disableAutoSafeMode?.value === 'boolean') { + result.launcherSettings = result.launcherSettings || {} + result.launcherSettings.disableAutoSafeMode = disableAutoSafeMode.value + } // Environment result.settings.env = app.db.controllers.Project.insertPlatformSpecificEnvVars(proj, result.settings.env) if (!result.settings.palette?.modules) { diff --git a/forge/routes/api/project.js b/forge/routes/api/project.js index 1c635e258c..46bdc75f94 100644 --- a/forge/routes/api/project.js +++ b/forge/routes/api/project.js @@ -1,4 +1,4 @@ -const { KEY_SETTINGS, KEY_HEALTH_CHECK_INTERVAL, KEY_SHARED_ASSETS } = require('../../db/models/ProjectSettings') +const { KEY_SETTINGS, KEY_HEALTH_CHECK_INTERVAL, KEY_DISABLE_AUTO_SAFE_MODE, KEY_SHARED_ASSETS } = require('../../db/models/ProjectSettings') const { Roles } = require('../../lib/roles') const ProjectActions = require('./projectActions') @@ -456,15 +456,24 @@ module.exports = async function (app) { } // Launcher settings - if (request.body?.launcherSettings?.healthCheckInterval) { - const oldInterval = await request.project.getSetting(KEY_HEALTH_CHECK_INTERVAL) - const newInterval = parseInt(request.body.launcherSettings.healthCheckInterval, 10) - if (isNaN(newInterval) || newInterval < 5000) { - reply.code(400).send({ code: 'invalid_heathCheckInterval', error: 'Invalid heath check interval' }) - return + if (request.body?.launcherSettings) { + if (request.body.launcherSettings.healthCheckInterval) { + const oldInterval = await request.project.getSetting(KEY_HEALTH_CHECK_INTERVAL) + const newInterval = parseInt(request.body.launcherSettings.healthCheckInterval, 10) + if (isNaN(newInterval) || newInterval < 5000) { + reply.code(400).send({ code: 'invalid_heathCheckInterval', error: 'Invalid heath check interval' }) + return + } + if (oldInterval !== newInterval) { + changesToPersist.healthCheckInterval = { from: oldInterval, to: newInterval } + } } - if (oldInterval !== newInterval) { - changesToPersist.healthCheckInterval = { from: oldInterval, to: newInterval } + if (typeof request.body.launcherSettings.disableAutoSafeMode === 'boolean') { + const oldInterval = await request.project.getSetting(KEY_DISABLE_AUTO_SAFE_MODE) + const newInterval = request.body.launcherSettings.disableAutoSafeMode + if (oldInterval !== newInterval) { + changesToPersist.disableAutoSafeMode = { from: oldInterval, to: newInterval } + } } } @@ -529,6 +538,10 @@ module.exports = async function (app) { await request.project.updateSetting(KEY_HEALTH_CHECK_INTERVAL, changesToPersist.healthCheckInterval.to, { transaction }) updates.pushDifferences({ healthCheckInterval: changesToPersist.healthCheckInterval.from }, { healthCheckInterval: changesToPersist.healthCheckInterval.to }) } + if (changesToPersist.disableAutoSafeMode) { + await request.project.updateSetting(KEY_DISABLE_AUTO_SAFE_MODE, changesToPersist.disableAutoSafeMode.to, { transaction }) + updates.pushDifferences({ disableAutoSafeMode: changesToPersist.disableAutoSafeMode.from }, { disableAutoSafeMode: changesToPersist.disableAutoSafeMode.to }) + } await transaction.commit() // all good, commit the transaction @@ -802,6 +815,7 @@ module.exports = async function (app) { settings.state = request.project.state settings.stack = request.project.ProjectStack?.properties || {} settings.healthCheckInterval = await request.project.getSetting(KEY_HEALTH_CHECK_INTERVAL) + settings.disableAutoSafeMode = await request.project.getSetting(KEY_DISABLE_AUTO_SAFE_MODE) settings.settings = await app.db.controllers.Project.getRuntimeSettings(request.project) if (settings.settings.env) { settings.env = Object.assign({}, settings.settings.env, settings.env) diff --git a/frontend/src/pages/instance/Settings/LauncherSettings.vue b/frontend/src/pages/instance/Settings/LauncherSettings.vue index ba3de78328..8032c4ac19 100644 --- a/frontend/src/pages/instance/Settings/LauncherSettings.vue +++ b/frontend/src/pages/instance/Settings/LauncherSettings.vue @@ -8,6 +8,18 @@ Flows that perform CPU intensive work may need to increase this from the default of 7500ms. + + Disable Auto Safe Mode + + +
+
+ Some settings are not available until you upgrade your stack. Upgrade +
+
Save settings @@ -17,6 +29,7 @@