Is there a right way to update NR from a flow?

Is there a right way to update NR from a flow? Calling the official Pi script as a use case? From an exec node?

Stop and restart of NR would be required of course. Expect the exec node to queue the task... so the actual Pi script runs as a separate process, which ensures the live NR instance can be shut down gracefully... systemctl stop nodred for example?.

Working on a prototype experiment...

  1. Flow invokes bash script (1) via by exec node, sleeps, or watches pid of NR?
  2. Flow executes NR stop... yes this kills NR gracefully, so orphans an current active (ui) dashboard session
  3. Script (1) spawns Script (2) after sleep, or when pid NR disappears(?)
  4. Script (2) runs official Pi script
  5. Script (2) starts NR
  6. Orphaned (ui) dashboard will try to reconnect? Right? Lost connection logic is to try to reconnect as I recall

Ideas, have script (1) archive .node-red directory or key files?

Assumptions, NR install is already in place, so settings.js and flows.json exist, and others of course.

#!/bin/sh
#
# Script1.sh
#

set -e

sleep 60 && ./Script2.sh &
systemctl stop nodered

exit 0

#!/bin/sh
#
# Script2.sh
#

set -e

echo "Execute Pi NR Script Here"
systemctl start nodred

exit 0

Have you tried
systemctl restart nodered
from an exec node? I am not sure what that will do when it is invoked from within the process being restarted. I will see what I can find out.

look a this :

I see that does (on a linux system) does a systemctl restart. I wonder if that is actually safe though, it depends on how it works whether killing the process that is running systemctl can cause problems.

That is why I abstract the restart via a separate script, the first script spawns from exec node, but is not a child process, just invoked by said active process, and shuts down NR. Then calls the install script. Then a spawned second script starts NR post install.

By doing this, I am isolating each phase as a different process tree, no child PIDs. This can be done various ways, via cron, sooner, etc. You just have to make sure they are completely separate processes, for the stop and start tasking, and from the original NR instance.

The only question I see, is how to watch the sequence appropriately, and once everything is done how to report it back to NR, when NR is alive ago. I may even finalize this via python, so I can hold results and send same to NR via say MQTT as the final status report type of thing.

@SuperNinja
Yes, I have my own variant of a 'watch' for new version flow as well. But my variant does not as yet, try to update NR. Will be interesting to see how the update sequence is done. I believe process isolation is the safe way to do any NR initialed NR updating.

If systemctl restart initiates a separate process to do the work, or just sends a message to a long running process then that is simpler and guaranteed to work.

You could use a separate node.js or python script that you run as a systemd service and that communicates with nodered over mqtt. This little service could than do the work of stopping/updating/starting and include error handling or even notify you if something goes wrong.

I have managed to glean some useful information on systemctl. This is from Colin Watson:

"systemctl restart" is implemented as sending a single D-Bus method call
(RestartUnit) to pid 1, so I believe this will indeed currently work
since it's pid 1 that's doing the actual restart work and all that the
systemctl process is doing after sending the request is waiting for it
to respond. I don't think this implementation detail is officially
documented or guaranteed, though, so it might change in future.

So it seems it is safe to use systemctll restart to kill oneself at the moment, but might change at some point in the future. I suspect that it is highly unlikely to change within what one might call the foreseeable future.

Yeah, given systemctl has to be all powerful (compared to the services, most anyway) it controls, that model makes sense. There are other ways to control processes up and down the 'ring' scopes... if you know OS design, my reference to rings should be familiar. Recall on DG systems, there was a way to access ring 0, to do an emergency stop, basically a controlled crash of the OS, but as I recall this was somewhat unique to DG OS design at the time... long time ago. :slight_smile: Definitely a 'Don't ever push the red button' type of thing.

I think my pid isolation logic is the way to go for now for me... Only because I am curious about how it will work as I create it. That is NOT ignoring the systemctl restart methodology that seems ok to do. Knowing systemctl restart is an option, I would say most should use that method for now if they are considering doing an automated NR update flow (initiator).

@JGKK, doing it as a service in the final design definitely is a good idea. Once I get my idea working, will move in that direction. An open question is how I want to 'watch' the progress if at all... for now, NR watching NR does not seem important. Checking for processes that need restart logic I have, Checking for pending reboot logic I have as well, not needed here, but it is part of my current update OS flow. I could just hook NR update into my OS update flow as well, but think I will keep them separate. I don't like cascading changes, makes issue resolution difficult.

Oh, the method of using npm to update NR, is another question do be considered... I explicitly want to use the official script to do the NR update. This is not because npm method can't be used, only that I want to update NR via the same methodology that I use to install NR. This makes for a bit more complex initiator as I noted above than just 'npm' it and 'systemctl' restart it. :slight_smile: