0

I have two servers: Linux shell (192.168.1.11) and ESXI host ash shell (192.168.1.12).

Desired outcome:

  • Local testsuspend.sh scp uploads suspendvm.sh to remote ESXI server and executes on ESXI. When finished testsuspend.sh continues and exits.
  • Script testsuspend.sh on .11 uploads an ash script (suspendvm.sh) to ESXi host .12, should execute it and wait until it's finished,then finish testsuspend.sh.

On Linux I want to remote execute a script suspendvm.sh from another script testsuspend.sh to suspend all VMs and put ESXI host in maintenance mode.

When I execute the testsuspend.sh on Linux it stops on executing suspendvm.sh via SSH. If I execute the suspend script sustendvm.sh on the ESXI host directly it works.

File after copy on ESXI:

-rwxr-xr-x    1 root     root          1260 Apr 16 07:06 suspendvm.sh

Would you have an idea on what I need to do here to get the ssh remote script to execute properly on the ESXi host and the local script to wait until remote is finished?

... So I found that if I run this in the testsuspend.sh it works:

cat suspendVM.sh | ssh -T $user@$host

Why does this work but not the copy and execute?

Local script 192.168.1.11, testsuspend.sh should execute suspenvm.sh remotely:

#!/bin/sh
user="root"
host="192.168.1.120"

scp suspendvm.sh $user@$host:/tmp
echo "copy suspend script"
ssh $user@$host 'sh -s /tmp/suspendvm.sh' &
exit

Remote script 192.168.1.12, suspendvm.sh works when I execute on ESXI host .12):

#!/bin/sh
RUNNING=0
VMS=`vim-cmd vmsvc/getallvms | grep -v Vmid | awk '{print $1}'`
for VM in $VMS ; do
     # echo "Probing VM with id: $VM."
     PWR=`vim-cmd vmsvc/power.getstate $VM | grep -v "Retrieved runtime info"`
     name=`vim-cmd vmsvc/get.config $VM | grep -i "name =" | awk '{print $3}' | head -1 | awk -F'"' '{print $2}'
     echo "VM with id $VM has power state $PWR (name = $name)."
     if [ "$PWR" == "Powered on" ] ; then
          RUNNING=1
          echo "Powered on VM with id $VM and name: $name"
          echo "Suspending VM with id $VM and name: $name"
          vim-cmd vmsvc/power.suspend $VM > /dev/null &
     fi
done

while true ; do
     if [ $RUNNING -eq 0 ] ; then
          echo "Gone..."
          break
     echo "Powered on VM with id $VM and name: $name"
          echo "Suspending VM with id $VM and name: $name"
          vim-cmd vmsvc/power.suspend $VM > /dev/null &
     fi
done

while true ; do
     if [ $RUNNING -eq 0 ] ; then
          echo "Gone..."
          break
     fi
     RUNNING=0
     for VM in $VMS ; do
          PWR=`vim-cmd vmsvc/power.getstate $VM | grep -v "Retrieved runtime info"`
          if [ "$PWR" == "Powered on" ] ; then
               name=`vim-cmd vmsvc/get.config $VM | grep -i "name =" | awk '{print $3}' | head -1 | awk -F'"' '{$
               echo "Waiting for id $VM and name: $name..."
               RUNNING=1
          fi
     done
     sleep 1
esxcli system maintenanceMode set --enable true
done

Remote script #2 that should do the same via esxicli, it also works when I execute it on .12 but not via ssh from .11:

#! /bin/ash
#test2
rm -f listid
touch listid

######## Listing the running vms################

esxcli vm process list |grep -v "^\s.*"| grep -v "^$" > list

######## If you want to reuse list for later use #######
####### put the file in a datastore, else it ##########
#######gonna be erease on next reboot ##########
####### Command look like this: ###############

## esxcli vm process list |grep -v "^\s.*"| grep -v "^$" > /vmfs/volumes/tmp/list

########## cleaning the id.s file by keeping only the id
for name in `cat list`;do
########## Dont forget to change the path if #######
########## you choose to put it in a datastore #####
####### put the file in a datastore, else it ##########
#######gonna be erease on next reboot ##########
####### Command look like this: ###############

## esxcli vm process list |grep -v "^\s.*"| grep -v "^$" > /vmfs/volumes/tmp/list

########## cleaning the id.s file by keeping only the id
for name in `cat list`;do
########## Dont forget to change the path if #######
########## you choose to put it in a datastore #####

## Example: for name in `cat /vmfs/volumes/yourDatastore/list`;do

        vim-cmd vmsvc/getallvms | grep $name | grep vmx | grep -v "^$" | awk '{print $1}'>> listid
done

for id in `cat listid`;do
        ###### suspending vms##########
        echo "Suspending the running machines"
        vim-cmd vmsvc/power.suspend $id

## Example: for name in `cat /vmfs/volumes/yourDatastore/list`;do

        vim-cmd vmsvc/getallvms | grep $name | grep vmx | grep -v "^$" | awk '{print $1}'>> listid
done

for id in `cat listid`;do
        ###### suspending vms##########
        echo "Suspending the running machines"
        vim-cmd vmsvc/power.suspend $id

done

echo "done."
echo "shutting down the host now.."
#/bin/poweroff
vim-cmd hostsvc/maintenance_mode_enter
#excli system maintenanceMode set --enable true
#done
Bubba
  • 1
  • 2
  • Whenever a shell is terminated, under default settings, all it's spawned processes will be killed. It might take some time, but this is the expected behavior. You need to change the parent process if you need to keep the process running even after closing the shell. Refer to this answer: https://unix.stackexchange.com/a/488/126691 – Anubis Apr 16 '19 at 08:25
  • Remove the `&` from ssh line. The ` &` makes a command run in background. – KamilCuk Apr 16 '19 at 08:41
  • As an aside, you cant to avoid [useless use of `cat`](/questions/11710552/useless-use-of-cat) and https://mywiki.wooledge.org/DontReadLinesWithFor and generally test your script at http://shellcheck.net/ before asking for human assistance. – tripleee Apr 16 '19 at 15:30
  • There's an odd typo with a lone dollar sign at the end of the line with the `name=` assignment, is that in your real script? It's probably pretty harmless but it wrecks the code colorization on Stack Overflow. – tripleee Apr 16 '19 at 15:32

0 Answers0