executing command via ssh library in robotframework - ssh

executing command via ssh library in robotframework
I'm using robotframework to connect to a remote server and start an application there. I use these keywords:
Create SSH Link
Open Connection ${Ip}
Login ${Username} ${Password}
Start Service
${cmd} = "cd " + ${appAddr} + "; ./" + ${appName} + " " + ${appInputArg} + " > /tmp/" + ${appName} "-out.log 2>&1"
log to console Going to run command: ${cmd}
execute command ${cmd}
log to console \nConnected Successfully
Run App
${cmd} = "netstat -putan | grep LISTEN | grep 8898 | awk '{print $7}' | cut -d '/' -f 1"
${stdout} = execute command ${cmd}
Run Keyword If ${stdout} == ${EMPTY} log to console \nCommand ${cmd} retruned Error
Run Keyword Unless ${stdout} == ${EMPTY} Start Service
And this is my test case:
Test Connecting to Remote Server
Create SSH Link
Run App
And Output:
==============================================================================
Scenarios
==============================================================================
Scenarios.Test :: First Test
==============================================================================
Test Connecting to Remote Server
Connected Successfully
| FAIL |
No keyword with name '"netstat -putan | grep LISTEN | grep 8898 | awk '{print $7}' | cut -d '/' -f 1"' found.
------------------------------------------------------------------------------
Scenarios.Test :: First Test | PASS |
0 critical tests, 0 passed, 0 failed
1 test total, 0 passed, 1 failed
==============================================================================
Scenarios | PASS |
0 critical tests, 0 passed, 0 failed
1 test total, 0 passed, 1 failed
==============================================================================
Why it's not going to execute this command on the remote server and searching for a keyword??

The problem lies in this statement:
${cmd} = "netstat -putan | grep LISTEN | grep 8898 | awk '{print $7}' | cut -d '/' -f 1"
This is not a valid Robot Framework Statement. Robot Framework is looking for a keyword and can not find any in this statement.
It should be changed into:
${cmd} = set variable netstat -putan | grep LISTEN | grep 8898 | awk '{print $7}' | cut -d '/' -f 1
Note: no need for double quotes around your string. By default variables are string in Robot.

Related

Checking if a vm status is running using virsh and grep - not working when vm name has a space

Hi I am using this script to check if a vm is running or not before doing an action
#!/bin/bash
vm="PopOS VNC"
vmstate=$(virsh list --all | grep " $vm " | awk '{ print $3}')
if [ "$vmstate" == "x" ] || [ "$vmstate" != "running" ]
then
echo "VM is shut down"
else
echo "VM is running!"
fi
When the vm is running but vm variable has a space the script doesnt work as expected
vm="PopOS VNC"
With the VM running the value of vmstate is "VNC" not "running" as expected
With the vm stopped value is still "VNC"
However it works as expected for a vm name without a space (as below)
vm="CentOS10"
With the VM running the value of vmstate is "running" as expected.
With the VM shutdown the value is "shut" as expected
Please can someone tell me how to get this to work with a vm that has a space in its name.
many thanks :)
edit
output of virsh list --all
Id Name State
--------------------------------------
- Big Sur shut off
- True NAS shut off
- CentOS10 shut off
- Debian-10 shut off
- dos_6.22 shut off
- Windows 95 shut off
- Gparted Live shut off
- Popos AMD gpu shut off
- PopOS VNC shut off
- OpenSUSE shut off
- Windows 98 VNC shut off
- OpenSUSE2 shut off
- pfSense shut off
output of script using set x
+ vm='PopOS VNC'
++ virsh list --all
++ awk '{ print $3}'
++ grep ' PopOS VNC '
+ vmstate=VNC
+ '[' VNC == x ']'
+ '[' VNC '!=' running ']'
+ echo 'VM is shut down'
VM is shut down
+ set +x
I assume there is a problem with quotes " or ' or both.
In order to debug your script and see the actual commands expansion by the shell I use set -x to start commands echo and set +x to stop command echo.
Suggest to run the following script:
#!/bin/bash
set -x
vm="PopOS VNC"
vmstate=$(virsh list --all | grep " $vm " | awk '{ print $3}')
if [ "$vmstate" == "x" ] || [ "$vmstate" != "running" ]
then
echo "VM is shut down"
else
echo "VM is running!"
fi
set +x
I assume there is problem with variable expansion in grep " $vm "
Please post your results in the post.
In addition remember that awk default field separator is . When your $vm is 2 worded the required awk field is shifted right to: awk '{ print $4}', and if the $vm is 3 worded the required awk field is awk '{ print $5}'.
Maybe it is better to take the last word awk '{ print $NF}'
Or to take one word before the last word awk '{ print $(NF - 1)}'

ActiveMQ execution failing on IBM i

Has anyone installed/run ActiveMQ on IBM i and can help me with this?
Either the process does not run or gives ZipException.
I downloaded ActiveMQ 5.16.2 from ActiveMQ 5.16.2 (Apr 28, 2021) - Unix/Linux/Cygwin bundle
for installing on IBMi V7R3 and followed the official steps for installation mentioned on Version 5 Getting Started - 'Installation Procedure for Unix' section.
This is similar to installing on IBMi as mentioned in - Installing activeMQ on IBM i5 V5R4
On running the command ./bin/activemq start, the process starts but ends without actually running ActiveMq.
It shows below error on the console -
./bin/activemq: 001-0019 Error found searching for command whoami. No such path or directory.
Also the command ./bin/activemq status returns ActiveMQ not running .
When running the command ./bin/activemq console, the process starts but gives the same whoami error and ends with ZipException.
On Windows, I have been able to install and run successfully.
Has anyone installed ActiveMQ on IBMi and can help me with this?
You are missing the command
whoami
This is not a shell built-in, so you would need to add that package to your installation.
h/t to #nfgl for the pointer to the IBM OSS rpm repo. If you inspect their src.rpm, you'll see they patch the activemq script. Worth reviewing
SRC RPM calls for this dependency: coreutils-gnu
IBM iSeries Patch of bin/activemq:
$ more activemq-activemq.patch
--- a/bin/activemq 2020-03-30 18:50:50.000000000 +0000
+++ b/bin/activemq 2020-03-30 18:57:03.000000000 +0000
## -336,10 +336,14 ##
-Dactivemq.data=\"${ACTIVEMQ_DATA}\" \
$ACTIVEMQ_CYGWIN \
-jar \"${ACTIVEMQ_HOME}/bin/activemq.jar\" $COMMANDLINE_ARGS >> $ACTIVEMQ_OUT 2>&1 &
- RET=\"\$?\"; APID=\"\$!\";
- echo \$APID > "${PIDFILE}";
- echo \"INFO: pidfile created : '${PIDFILE}' (pid '\$APID')\";exit \$RET" $DOIT_POSTFIX
- RET="$?"
+ exit \"\$?\"" $DOIT_POSTFIX
+ RET="$?"
+ sleep 5
+ OS400_PID=`ps | grep -iE 'java|jFromPASE|jvmStartPase|qp0zspwp' | grep -v '\spgm-' | grep -vE '^\s+1\s' | tail -n 1 | awk '{print $1}'`
+ rm -f $PIDFILE
+ qsh -c "/usr/bin/touch -C 1208 $PIDFILE"
+ echo $OS400_PID > $PIDFILE
+ echo "INFO: pidfile created : '$PIDFILE' (pid '$OS400_PID')"
elif [ -n "$TASK_TODO" ] && [ "$TASK_TODO" = "stop" ];then
SPID="`cat "${PIDFILE}"`"
$EXEC_OPTION $DOIT_PREFIX "\"$JAVACMD\" $ACTIVEMQ_OPTS $ACTIVEMQ_DEBUG_OPTS \
## -384,7 +388,7 ##
return 2
fi
ACTIVEMQ_PID="`cat ${ACTIVEMQ_PIDFILE}`"
- RET="`ps -p "${ACTIVEMQ_PID}"|grep java`"
+ RET=`/QOpenSys/usr/bin/ps -p ${ACTIVEMQ_PID}|grep -iE 'java|jFromPASE|jvmStartPase'`
if [ -n "$RET" ];then
return 0;
else
## -403,7 +407,7 ##
return 2
fi
THEPID=`cat ${PID_STOP}`
- RET=`ps -p $THEPID|grep java`
+ RET=`/QOpenSys/usr/bin/ps -p ${ACTIVEMQ_PID}|grep -iE 'java|jFromPASE|jvmStartPase'`
if [ -n "$RET" ];then
return 0;
else

awk command not working with kubectl exec

From outside container:
$ kubectl exec -it ui-gateway-0 -- bash -c "ps -ef | grep entities_api_svc | head -1"
root 14 9 0 10:34 ? 00:00:02 /svc/bin/entities_api_svc
$ kubectl exec -it ui-gateway-0 -- bash -c "ps -ef | grep entities_api_svc | head -1 | awk '{print $2}'"
root 14 9 0 10:34 ? 00:00:02 /svc/bin/entities_api_svc
From inside container:
[root#ui-gateway-0 /]# ps -ef | grep entities_api_svc | head -1 | awk '{print $2}'
14
I find it easier to use single quotes on the sh/bash command argument so it is closer to what you would type in the shell:
kubectl exec -it ui-gateway-0 -- \
bash -c 'ps -ef | grep entities_api_svc | head -1 | awk "{print \$2}"'
This means the awk uses double quotes, which requires the shell variable marker $ to be escaped.
In the original command, the shell running kubectl was replacing $2 with a zero length string so awk would see only print, which prints the whole line
Multiple levels of nesting
Nested shell escaping gets very obscure very quickly and hard to debug:
$ printf '%q\n' 'echo "single nested $var" | awk "print $2"'
echo\ \"single\ nested\ \$var\"\ \|\ awk\ \"print\ \$2\"
$ printf '%q\n' "$(printf '%q\n' 'echo "double nested $var" | awk "print $2"')"
echo\\\ \\\"double\\\ nested\\\ \\\$var\\\"\\\ \\\|\\\ awk\\\ \\\"print\\\ \\\$2\\\"
If you add a file grep-entities.sh in container
#!/bin/bash
set -uex -o pipefail
ps -ef | grep entities_api_svc | head -1 | awk '{print $2}'
You then don't need to worry about escaping
pid=$(sshpass -p "password" ssh vm#10.10.0.1 kubectl exec ui-gateway-0 -- /grep-entities.sh)
Also pgrep does the scripts job for you
kubectl exec ui-gateway-0 -- pgrep entities_api_svc

Unexpected behaviour from awk in docker-machine

Inspired by this post, I'm attempting to use docker-machine on my Mac to stop a running container. However, awk appears to behave differently in docker-machine ssh than when run directly "in" the container.
When I'm ssh'd to the container directly, everything works as expected:
me#myMac:~$ docker-machine ssh default
docker#default:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
028fd7148881 myrepo/mycontainer "apachectl -DFOREGROU" 14 minutes ago Up 14 minutes 0.0.0.0:80->80/tcp gloomy_mayer
docker#default:~$ docker ps | awk 'NR > 1 {print $1}'
028fd7148881
docker#default:~$ docker ps | awk 'NR > 1 {print $1}' | xargs --no-run-if-empty docker kill
028fd7148881
docker#default:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
But when run remotely, awk behaves differently:
me#myMac:~$ docker-machine ssh default "docker ps"
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7927b10b8a28 myrepo/mycontainer "apachectl -DFOREGROU" 11 seconds ago Up 10 seconds 80/tcp happy_wozniak
me#myMac:~$ docker-machine ssh default "docker ps | awk 'NR > 1 {print $1}'"
7927b10b8a28 myrepo/mycontainer "apachectl -DFOREGROU" About a minute ago Up About a minute 80/tcp happy_wozniak
me#myMac:~$ docker-machine ssh default "docker ps | awk 'NR > 1 {print $1}' | xargs --no-run-if-empty docker kill"
7927b10b8a28
Failed to kill container (myrepo/mycontainer): Error response from daemon: Cannot kill container myrepo/mycontainer: No such container: myRepo/myContainer
Failed to kill container (apachectl -DFOREGROU): Error response from daemon: Cannot kill container apachectl -DFOREGROU: No such container: apachectl -DFOREGROU
Failed to kill container (3): Error response from daemon: Cannot kill container 3: No such container: 3
...
Why does awk behave differently under docker-machine?
"docker ps | awk 'NR > 1 {print \$1}' | xargs --no-run-if-empty docker kill"
$ ==> \$
docker ps -q

Exact string match in multi line string

I have a string as below, I needed to exactly match if string "abc.properties abc Scanner directory: /xyz/xzy/" is present.
I am using the below awk command.
It considers as successful if even a part of string, say, abc.properties is present. But, my criteria is to check for the exact string i.e. "abc.properties abc Scanner directory: /xyz/xzy/".
Can somebody please help?
echo $s | awk 'BEGIN { FS="\n"; RS="";} /abc.properties abc Scanner directory: \/xyz/xzy\// {print $1}'
String is as below:
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no -o ServerAliveInterval=600 -o ServerAliveCountMax=3 -o ConnectTimeout=30 xyz#123.abc.com Password: Creating directory '/home/xyz'. Authorized uses only. All activity may be monitored and reported. Successful login using -u option. If you want to allow X traffic please use -x option. Usage: /111/11/111/111 [policy] -x [target user] su from xyz to abc [abc#xyz ~]$ /111/111/111/111/111/111.sh /111/11/instance/111/111/111/111/ Verifying JVM setting for domain: /111/11/11/11/1111/111/111// abc.properties abc Scanner directory: /xyz/xzy/ [abc#xyz ~]$ exit 0 logout
The output is as below:
$ echo $s | awk 'BEGIN { FS="\n"; RS="";} /abc.properties abc Scanner directory: \/xyz/xzy\// {print $1}'
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no -o ServerAliveInterval=600 -o ServerAliveCountMax=3 -o ConnectTimeout=30 xyz#123.abc.com Password: Creating directory '/home/xyz'. Authorized uses only. All activity may be monitored and reported. Successful login using -u option. If you want to allow X traffic please use -x option. Usage: /111/11/111/111 [policy] -x [target user] su from xyz to abc [abc#xyz ~]$ /111/111/111/111/111/111.sh /111/11/instance/111/111/111/111/ Verifying JVM setting for domain: /111/11/11/11/1111/111/111// abc.properties abc Scanner directory: /xyz/xzy/ [abc#xyz ~]$ exit 0 logout