Shell Script Invoked by Camunda

My requirements has not changed much. The code I have posted is just usage example. In my case I have decided to use Jsch and external task
vimeo video

as it is much more easier to implement.

The Camunda I am using lives in a container on a separate server. In order to run a script the way you have described, I would need to use swarm and docker secrets and many ssh tunnels to get to different servers.

Currently, I am looking how to store secretly passwords in Camunda, and it seems that I will need to use Docker Secretes anyway :smile:

Thank you

:+1:


Note that docker secrets only functions (in its designed secure way) when using Docker Swarm. So keep that in mind. If you are using Kuber, then use kuber secret volumes or one of the other options.

Docker Secrets will work when using Docker-compose (in non-swarm mode) because it was added for testing and development purposes, but the secrets are not actually secured in the way they are described in the docs when you are not using Swarm.

TLDR: If you are not using Docker Swarm, then Docker Secrets are not secure.

Hi Camunders,

Just exploring a new way how to execute a shell script.
I have found that Nashorn should be able to execute shel scripts
the documentation
https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/shell.html#sthref25
I have tried to execute commands locally via Nashorn
e.g.

#!/usr/lib/jvm/java-1.8-openjdk/jre/bin/jjs  -scripting
$EXEC("ls -l")
print($OUT)

which works fine.
But when inserted as a Inline Script (javaScript) into Modeler and executed I get
“…Unable to evaluate script while executing activity…”

Do u have any experience using jjs?
Thx.

M

Nashorn has different modes: the shell scripts are in scripting mode which is not the mode being used by camunda.

Have you tried using the shebang feature?

Hello guys,

had a chance again to work a little bit on this.
So I tried to implement the jsch solution in groovy

so far I came to the following with help of internet :

import com.jcraft.jsch.JSch
import com.jcraft.jsch.Session
import com.jcraft.jsch.UserInfo
import com.jcraft.jsch.Channel
import com.jcraft.jsch.ChannelExec

import java.util.Properties

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;


def sshHost = '1111.12.12.11'
def sshUser = 'vqweq
def sshPass = 'wfdssx'
def sshPort = 22

println "Opening connection to ${sshUser}@${sshHost}:${sshPort}"
Properties config = new Properties()
config.put("StrictHostKeyChecking", "no")
JSch jsch = new JSch()


Session sshSession = jsch.getSession(sshUser, sshHost, sshPort)
sshSession.setPassword(sshPass)
sshSession.setConfig(config)
sshSession.connect()
println "Connected"

// Could use "shell"
Channel channel = sshSession.openChannel("exec")
// Let's just get the hostname
((ChannelExec)channel).setCommand("cd /home/.... && ./CMND_test.sh")
// Spew errors to console
((ChannelExec)channel).setErrStream(System.err)
// We're not sending anything
channel.setInputStream(null)
// Get the input stream
InputStream is = channel.getInputStream()
// Connect
channel.connect()
// This could be written better and groovier...
byte[] tmp = new byte[1024]
// Uh oh. We really need a better way out of the loop...
while (true) { 
  // But it's just an example... :-)
  while (is.available() > 0) {
    int i = is.read(tmp, 0, 1024)
    if (i<0)
      break
    System.out.print(new String(tmp, 0, i))
  }
  if (channel.isClosed()) {
    // All done.
    System.out.println("exit-status: " + channel.getExitStatus())
    def Validity = execution.setVariable('Valid', channel.getExitStatus());
if ( Validity == 1 ) {
 execution.setVariable('Valid', true)
} else if ( Valid != 1) {
   
     execution.createIncident("someType", "someConfiguration", "someMessage");
 // throw new org.camunda.bpm.engine.delegate.BpmnError('Error')
}
    break
  }
  // Ugly: You might want to change this
  try{Thread.sleep(1000);}catch(Exception ee){}
}
// Close channel and session
channel.disconnect()
sshSession.disconnect()

which gives image
which is similar to Error creating incident via javascript - #7 by StephenOTT
which I don’t like as it creates incident and token continues in my process flow
I have tried to use @StephenOTT context but with no luck

If u have an idea how to keep incident “token” on an error task then thank you for advice.

If you want to keep the incident, then use the latest API to throw the incident(execution.createIncident(), or something like that). Or throw just throw a regular error and it will be caught as a incident and stop on the task.