diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/locales/en-US/editor.json b/packages/node_modules/@node-red/editor-api/lib/editor/locales/en-US/editor.json index 97295d706..0ffa9de61 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/locales/en-US/editor.json +++ b/packages/node_modules/@node-red/editor-api/lib/editor/locales/en-US/editor.json @@ -97,6 +97,7 @@ "undeployedChanges": "node has undeployed changes", "nodeActionDisabled": "node actions disabled within subflow", "missing-types": "

Flows stopped due to missing node types.

", + "safe-mode":"

Flows stopped in safe mode.

You can modify your flows and deploy the changes to restart.", "restartRequired": "Node-RED must be restarted to enable upgraded modules", "credentials_load_failed": "

Flows stopped as the credentials could not be decrypted.

The flow credential file is encrypted, but the project's encryption key is missing or invalid.

", "credentials_load_failed_reset":"

Credentials could not be decrypted

The flow credential file is encrypted, but the project's encryption key is missing or invalid.

The flow credential file will be reset on the next deployment. Any existing flow credentials will be cleared.

", diff --git a/packages/node_modules/@node-red/editor-client/src/js/red.js b/packages/node_modules/@node-red/editor-client/src/js/red.js index 8acf93d67..d294c8376 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/red.js +++ b/packages/node_modules/@node-red/editor-client/src/js/red.js @@ -201,7 +201,16 @@ var RED = (function() { id: notificationId } if (notificationId === "runtime-state") { - if (msg.error === "missing-types") { + if (msg.error === "safe-mode") { + options.buttons = [ + { + text: RED._("common.label.close"), + click: function() { + persistentNotifications[notificationId].hideNotification(); + } + } + ] + } else if (msg.error === "missing-types") { text+=""; if (!!RED.projects.getActiveProject()) { options.buttons = [ diff --git a/packages/node_modules/@node-red/runtime/lib/api/flows.js b/packages/node_modules/@node-red/runtime/lib/api/flows.js index 7df55ccb0..a96fdd9a3 100644 --- a/packages/node_modules/@node-red/runtime/lib/api/flows.js +++ b/packages/node_modules/@node-red/runtime/lib/api/flows.js @@ -68,7 +68,7 @@ var api = module.exports = { var apiPromise; if (deploymentType === 'reload') { - apiPromise = runtime.nodes.loadFlows(); + apiPromise = runtime.nodes.loadFlows(true); } else { if (flows.hasOwnProperty('rev')) { var currentVersion = runtime.nodes.getFlows().rev; diff --git a/packages/node_modules/@node-red/runtime/lib/nodes/flows/index.js b/packages/node_modules/@node-red/runtime/lib/nodes/flows/index.js index 861d16dd8..a01083759 100644 --- a/packages/node_modules/@node-red/runtime/lib/nodes/flows/index.js +++ b/packages/node_modules/@node-red/runtime/lib/nodes/flows/index.js @@ -102,6 +102,10 @@ function loadFlows() { }); } function load(forceStart) { + if (forceStart && settings.safeMode) { + // This is a force reload from the API - disable safeMode + delete settings.safeMode; + } return setFlows(null,"load",false,forceStart); } @@ -112,6 +116,16 @@ function load(forceStart) { */ function setFlows(_config,type,muteLog,forceStart) { type = type||"full"; + if (settings.safeMode) { + if (type !== "load") { + // If in safeMode, the flows are stopped. We cannot do a modified nodes/flows + // type deploy as nothing is running. Can only do a "load" or "full" deploy. + // The "load" case is already handled in `load()` to distinguish between + // startup-load and api-request-load. + type = "full"; + delete settings.safeMode; + } + } var configSavePromise = null; var config = null; @@ -285,6 +299,13 @@ function start(type,diff,muteLog) { events.emit("runtime-event",{id:"runtime-state",payload:{error:"missing-types", type:"warning",text:"notification.warnings.missing-types",types:activeFlowConfig.missingTypes},retain:true}); return when.resolve(); } + if (settings.safeMode) { + log.info("*****************************************************************") + log.info(log._("nodes.flows.safe-mode")); + log.info("*****************************************************************") + events.emit("runtime-event",{id:"runtime-state",payload:{error:"safe-mode", type:"warning",text:"notification.warnings.safe-mode"},retain:true}); + return Promise.resolve(); + } if (!muteLog) { if (type !== "full") { log.info(log._("nodes.flows.starting-modified-"+type)); diff --git a/packages/node_modules/@node-red/runtime/locales/en-US/runtime.json b/packages/node_modules/@node-red/runtime/locales/en-US/runtime.json index a38f44d08..2a328c0bb 100644 --- a/packages/node_modules/@node-red/runtime/locales/en-US/runtime.json +++ b/packages/node_modules/@node-red/runtime/locales/en-US/runtime.json @@ -88,6 +88,7 @@ "system-key-warning": "\n\n---------------------------------------------------------------------\nYour flow credentials file is encrypted using a system-generated key.\n\nIf the system-generated key is lost for any reason, your credentials\nfile will not be recoverable, you will have to delete it and re-enter\nyour credentials.\n\nYou should set your own key using the 'credentialSecret' option in\nyour settings file. Node-RED will then re-encrypt your credentials\nfile using your chosen key the next time you deploy a change.\n---------------------------------------------------------------------\n" }, "flows": { + "safe-mode": "Flows stopped in safe mode. Deploy to start.", "registered-missing": "Missing type registered: __type__", "error": "Error loading flows: __message__", "starting-modified-nodes": "Starting modified nodes", diff --git a/packages/node_modules/node-red/red.js b/packages/node_modules/node-red/red.js index 19a4284ac..90d1ad3c1 100755 --- a/packages/node_modules/node-red/red.js +++ b/packages/node_modules/node-red/red.js @@ -38,7 +38,8 @@ var knownOpts = { "settings": [path], "title": String, "userDir": [path], - "verbose": Boolean + "verbose": Boolean, + "safe": Boolean }; var shortHands = { "?":["--help"], @@ -59,7 +60,7 @@ var parsedArgs = nopt(knownOpts,shortHands,process.argv,2) if (parsedArgs.help) { console.log("Node-RED v"+RED.version()); console.log("Usage: node-red [-v] [-?] [--settings settings.js] [--userDir DIR]"); - console.log(" [--port PORT] [--title TITLE] [flows.json]"); + console.log(" [--port PORT] [--title TITLE] [--safe] [flows.json]"); console.log(""); console.log("Options:"); console.log(" -p, --port PORT port to listen on"); @@ -67,6 +68,7 @@ if (parsedArgs.help) { console.log(" --title TITLE process window title"); console.log(" -u, --userDir DIR use specified user directory"); console.log(" -v, --verbose enable verbose output"); + console.log(" --safe enable safe mode"); console.log(" -?, --help show this help"); console.log(""); console.log("Documentation can be found at http://nodered.org"); @@ -131,6 +133,9 @@ try { if (parsedArgs.verbose) { settings.verbose = true; } +if (parsedArgs.safe) { + settings.safeMode = true; +} if (settings.https) { server = https.createServer(settings.https,function(req,res) {app(req,res);});