Elevated permissions and remote command via ssh

Hi all,

I have had this all working previouesly on my RPi but a move to a virtual machine running debian a few weeks back seems to have broken the ability to run remote commands on other devices across ssh.

Ilets take one example. I want to run a script on a remote linus server that updates and upgrades it using its apt package manager.

The rule in openhab is this:

rule "update-venus"
when
Item UpdateVenus received command
then
	var String result = executeCommandLine("sudo -u openhab /usr/bin/ssh idkpmiller@venus 'update_venus'")
	logInfo("update.rules", "Venus OS update requested")
	postUpdate(UpdateVenus,OFF)
	if (result == null) {
		logError("update.rules", "Venus No response from update: " + result)
	} else {
		logInfo("update.rules", "Venus Results: " + result)
	}
end

if I login onto my openhab device and issue the command at the shell as root it works
if I issue the command as openhab or openhabian it works too

to get myself on the shell as the correct user I am login in and issueing sudo su openhab -
or sudo su openhabian -

in both cases the prompt changes to reflect the new user and running the command works just not from the rule.

can someone provide a clue as to what I am doing wrong.

Thanks

Paul

First thing I notice is you do not need to put sudo -u openHAB in the command. That causes the command to be run as the openhab user. The command will already be running as the openhab user so at best it’s redundant, at worse could cause problems.

I suggest you add a timeout to your executeCommandLine and catch and log the results. I bet it will tell you what is wrong. If I had to guess I’d say either the ssh keys were not set it they have the wrong permissions.

var String result = executeCommandLine("sudo -u openhab /usr/bin/ssh idkpmiller@venus 'update_venus'", 30000)
logInfo("test", results)

Thanks Rich,
I can safely say the ssh keys are fully working so thats off the table for the issue.

However, you were certainly correctly to make me simplify and and a timeout to the command.

The outcome of the simplified riles indicates the remote command does get executed just seems not to completion. the reason I had no timeout previously I think was so that it would wait until the command completed before disconnecting, but I could be wrong.

here is the log output.

2018-07-28 13:59:11.070 [ome.event.ItemCommandEvent] - Item 'UpdateVenus' received command ON

2018-07-28 13:59:44.325 [INFO ] [.smarthome.model.script.update.rules] - Ign cdrom://[Debian GNU/Linux 8 _Jessie_ - Official Snapshot amd64 LIVE/INSTALL Binary 20160609-11:54] jessie InRelease

Hit http://ftp.citylink.co.nz jessie-updates InRelease

Hit http://security.debian.org jessie/updates InRelease

Hit http://ftp.citylink.co.nz jessie-updates/main Sources

Get:1 http://ftp.citylink.co.nz jessie-updates/main amd64 Packages/DiffIndex [11.8 kB]

Get:2 http://ftp.citylink.co.nz jessie-updates/main Translation-en/DiffIndex [3,688 B]

Hit http://security.debian.org jessie/updates/main Sources

Hit http://security.debian.org jessie/updates/main amd64 Packages

Hit http://security.debian.org jessie/updates/main Translation-en

2018-07-28 13:59:44.326 [INFO ] [.smarthome.model.script.update.rules] - Venus OS update requested

2018-07-28 13:59:44.330 [vent.ItemStateChangedEvent] - UpdateVenus changed from ON to OFF

I am thinking now you have pointed out to me it is running the command I need to focus my attention on the remote system and start adding logging to the remote script and see what is happening, I suspect that it never completes the full script for some reason.

Thanks

Paul

for anyone reading this in the future it turns out that it was working fine all along and I was making a bad job of checking to see if it was ok or not :frowning:

Sorry Rich, for wasting your time, I will say though your simplification and timeout put me back on the right track and led me to realise it was actually working. So thank you.

Regards

Paul

Unfortunately that is the opposite of how executeCommandLine works. Without the timeout, executeCommandLine returns immediately and you will never get the output of the command. The only way to wait for the command to finish and get what the command output is to set the time out argument.

apt consents can take a long time to run. Make sure you set the time out to be long enough for the apt command to complete. For example, if you pass 30000 to executeCommandLine and it takes longer than 30 seconds to run, the command will be terminated at 30 seconds. I think the default timeout when running executeCommandLine without a timeout is 10 seconds.

And please review (OH 1.x and OH 2.x Rules DSL only] Why have my Rules stopped running? Why Thread::sleep is a bad idea also. This rule is going to take a long time to run which might cause problems in the long run.

Great advice.

In this case the order of events were.

it was working
I thought it was not
to see it it was or not I added the result var and found it was null convincing me it was failing.
in reality the time (10 seconds) was insufficient time for var to gain output. from the remote script
By increasing the timeout to 30 seconds I can do a simple check to see if things are starting to happen and move on if they are or log an error if they are not.
So I think it has improved from the original ‘fire n forget’ that I had earlier, but currently not wanting openhab to wait around for the show to end before my rule carries on.

Thanks

Paul

Well, OH is going to have to wait around somewhere. You can put the call in a Timer and it will at least free up a Rules Thread, but at the end of the day either the command will have to take less than 10 seconds to run or OH will have to tie up a thread waiting for the command to complete.

Personally, I recommend against blind upgrades like this. Sometimes the upgrade requires answering a question (e.g. replace the edited config file with the new version from the package), and sometimes something will go wrong but since you threw away the output from apt you will have no idea what got upgraded and or potential failures.

But if you must, then I would outsource this type of call to something outside of OH. For example GitHub - rkoshak/sensorReporter: A python based service that receives sensor inputs and publishes them in various ways. or GitHub - jpmens/mqtt-launcher: Execute shell commands triggered by published MQTT messages. Then OH just sends an MQTT message and doesn’t have to wait around for the command to complete.