Manage Fork-and-Exec Plugins by Monitoring them by PID
This change implements what I've been calling the "ShellService" which is a class that acts like a fake client application, in order to wrap and manage a external application which has been executed and forked, what we use "ShellCommand" for now. What it does, instead of launching an external application directly, is generates a shell script which runs the command in the background and immediately outputs the PID. The ShellService captures this output and writes it down in a place which corresponds to the plugin name. Once that is done, an entirely new ShellService can be instantiated with the same plugin name can look up the PID and check if it is running.
The use case is for "Native/Freestanding/Fork-and-Exec/Fork-and-Forget" plugins. This makes it so that the router can put them into the background then keep track of if they're running or not. These plugins can now effectively tie their startup, shutdown and lifetime to the lifetime of the I2P application. Importantly, a ShellService will report if it is running correctly on the /configplugins menu. We will not "lose track" of a running plugin and allow the user to start it more than once using the "start" button on /configplugins. If such a plugin needs to be stopped so that it can be updated, a ShellService can accomplish that from the /configplugins menu. Right now I've been testing this with brb
railroad
and a version of Tor's Snowflake
proxy/pluggable transport.
It does expect the freestanding application to handle it's own logging. Such applications should log what is necessary to a file somewhere in it's own plugin directory rather than appearing in the router logs, or provide their own UI for managing logs. If that is desirable, it possible to change the ShellService so that it also handles redirection of the stdout
and stderr
on it's own and also looks up those outputs by plugin name, in order to provide that back to the console, but I have not implemented this capability yet because for now everything that might use it does it's own logging already.