Run task before NR startup and when you click on the deploy button

Hello, Do you think it is possible to:

  1. Run a private task before the nodered service is started ?
  2. Launch a script when using the Deploy button ?

For the 1st case, we can obviously create a script that does the private task and then launches node-red-start. But maybe there is already something integrated in NR ?

For the 2nd case, I don't see how to do it, any ideas?

Is that a long running service that you want to start before the node-red service starts? If so then you can build that requirement into the systemd startup script (assuming this is on a system that uses systemd, such as Raspbian or Ubuntu). Make a systemd script to start the service and then require that in the node red systemd script.

Another possibility is to use an exec node to run the script and trigger that from an Inject node set to fire on startup, but that may be too late for your requirement.

Thank you Colin for your thoughts.
The idea behind this is the following.
I want to "somewhat" protect my flows from being stolen.

I imagine encrypting my flows with OpenSSL into a script and decrypting them before NR reads them, once NR starts, launch an exec node that re-encrypts those same flows.
Also for the Deploy, I would like to have an automatic encryption once the flows are written and saved in the .json. This point is the least important.

The mechanics are not yet finalized, but it's the idea that if the map is stolen, it's not so easy to read the json file with a simple editor.
You will also have to find the decryption key. Not everything is accessible at once.

Couldn't someone who has access to the editor just export the entire flow?

hello @zenofmud
The editor is password protected. It's should be enough. The people just use de /ui

I seem to remember reading that the filing system in node-red is pluggable, so one could replace that with your encrypt/decrypt code, but perhaps my memory is just of an intention to make it pluggable. Someone more knowledgeable would have to comment on that.

Yes, absolutely. Colin has given one suggestion but another would be to put the task into Node-RED's settings.js file above the exports line. I do this regularly to capture some information that I want to be able to use later. That information can be fed into Node-RED flows via the globals property in the settings.

Yes, this is possible too. But in this case, you need a custom node.

I don't know that the pluggable flows are ready yet? The events are in place though.

Storage API : Node-RED (nodered.org)

Very interesting to be able to link everything from NR and not outside.
When you say above the part *module.exports = * is it the place where for example I can define a variable? process.env.test = "blabla";
What would be the format to launch a shell named for example decrypt.sh?
On the command line it is: sh decrypt.sh
Will NR launch the script synchronously to make sure that it can read the json files

The plugable storage linked to by @TotallyInformation must surely be the way to go. Then you can encrypt it there and don't need to worry about anything else.

1 Like

Here I must say that I did not understand, it is completely beyond my knowledge.
Are they talking about storage :thinking:
it must have another meaning in English.

You may need to read up a little on node.js apps and how they work. The settings.js file is actually a node.js module that is loaded by Node-RED as it starts up.

Anything above (technically anything outside) the extports object is run before the export and any stored values will not be available to Node-RED unless you shove them into the exports section. That's what the globals property is there for, it exposes whatever you put in it as a global variable in Node-RED.

In your case, you might be able to decrypt the file there but you would have to try it as I don't know exactly where Node-RED reads the json file.

As Colin says, you will almost certainly be better off working with the Custom Storage Module approach.

1 Like

Yes, disc (or whatever) storage for flows etc. It is possible to replace the code that node-red uses to write to disc storage, with your own code. If you do that then you can decrypt the flow file before passing it to node-red and you can encrypt when node-red gives it to you to save.

there it is clearer. I'm going to dig in this direction

I understand the idea of putting code there, I've read a lot of articles but for me it's like looking for something I don't know in the fog. Not easy :thinking:
I didn't know Node.js before I discovered NR.
What I'm thinking of doing is just a script at startup that decrypts the files and then runs NR.
Thanks for the advice though.

Would it be possible to show me one or two examples of actions taken before the launch of NR.
And the associated code used in the settings.js file.
This will help me to get on the right track.
Thanks for your help
/JL

Here is the start of the settings.js for my dev instance:

const path = require('path')   // Node core library. path library for cross-platform file system specs
const fs   = require('fs')     // The `https` setting requires the `fs` module.
//const _    = require('lodash'); // lodash (improved underscore) for JS utility fns

/** Save a PID file so that Node-RED can be easily restarted even when run manually */
const pid = process.pid
console.info('PID: ', pid)
process.env.node_red_pid = pid+''
fs.readdir('.', (err, files)=>{
    if (err) throw err

    for (var i = 0, len = files.length; i < len; i++) {
        var match = files[i].match(/.*\.pid/)
        if(match !== null) fs.unlink(match[0], (err) => {
            if (err) throw err
        })
    }

    fs.writeFile(`${pid}.pid`, `${pid}`, (err) => {
        if (err) throw err
    })
})

// const Gun = require('gun')
// const thoughts = Gun().get('thoughts')
// thoughts.map().on(function(thought, id){
//     console.log('A THOUGHT OCCURED: ', thought)
// })

/** Optionally display the Node.js/v8 engine heap size on startup */
const v8 = require('v8')
console.info(`V8 Total Heap Size: ${(v8.getHeapStatistics().total_available_size / 1024 / 1024).toFixed(2)} MB`)
let mem = process.memoryUsage()
const formatMem = (m) => ( m/1048576 ).toFixed(2)
console.info(`Initial Memory Use (MB): RSS=${formatMem(mem.rss)}. Heap: Used=${formatMem(mem.heapUsed)}, Tot=${formatMem(mem.heapTotal)}. Ext C++=${formatMem(mem.external)}`)
 
const nrsettings = {
    // ,,, the settings ...
} // ---- End of exports ---- //

module.exports = nrsettings
1 Like

With an example, it becomes clearer. I appreciate your help.
I will see how to launch a shell script from javascript commands.

image

1 Like

Certainly worth getting to know JavaScript and Node.js a bit more.

The structure of modules and how they work is especially useful to understand.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.