Rajendra Maharjan
Rajendra Maharjan

Reputation: 235

How can i check specific server running or not (using virsh commands), before I start | restart it?

I'm trying to restart, start, shutdown a specific virtual machine. Here, at first I want to check if the virtual machine is already in required state or not before I run the script.

These are the list of VMs.

[root@demohost05 ~]# virsh list --all
Id    Name                           State
----------------------------------------------------
5     OwnCloud01                     running
6     OwnCloud02                     running
7     SiteMon                        running
-     vmtest                         shut off

I want to check if vmtest is runnnig or not before I implement

virsh start vmtest

How can check the status using if condition in shell script ?

How can I avoid to enter password when I've to use sudo command.

sudo virsh start vmtest

I also tried to give root permission using

sudo -i
virsh start vmtest

But script ends without implementing 2nd line. How can I use both commands in same script file?

if [conditions]
then
{

}
fi

I couldnt figure out how to check conditions for such scripts.

Thank you.

Upvotes: 3

Views: 17218

Answers (7)

Gary
Gary

Reputation: 31

I like Sharad's answer but I reversed it into a busy loop while waiting for a VM to shutdown

virsh shutdown $VM
state=$(virsh list --all | grep " $VM " | awk '{ print $3}')
while ([ "$state" != "" ] && [ "$state" == "running" ]); do
  sleep 10
  state=$(virsh list --all | grep " $VM " | awk '{ print $3}')
done;
# now do something else to the shutdown VM and finally restart it
virsh start $VM

In my case I create a snapshot when the VM is shut down, then I restart it. I hard-coded a 10 second sleep into the loop because it seems like a reasonable retry period, given that a Windows VM could take a long time if it is installing updates - could be several minutes or even longer.

Upvotes: 3

user2328273
user2328273

Reputation: 978

I was just looking at this. Instead of piping to grep and awk, there is a built in command. I don't know if that was the case when this question was first asked but for anyone else that may come across this:

virsh domstate <vm name>

Make sure to use quotes of the name has a space in it. Also, the accepted answer only works if the name does not have a space in it. If it does have a space, you need to adjust the awk command.

Upvotes: 3

Nick G
Nick G

Reputation: 78

How can I avoid to enter password when I've to use sudo command.

Ensure your user is a member of the 'libvirt' group.

sudo usermod -G libvirt <username>

You will need to log out and in again for this to take effect.

Note that on RHEL based systems, you might also need to ensure you have the following environment variable set:

LIBVIRT_DEFAULT_URI=qemu:///system

Then try:

$ virsh domstate vmtest
running

Unfortunately, the above doesn't give you a nice easy exit code to test in your bash, so you can try the following (output shown for a machine that isn't running):

$ virsh domstate vmtest | grep running
$ echo $? 
1

Bash script would look like:

#!/bin/bash
virsh domstate vmtest | grep running
if [ $? -ne 0 ] ; then
  echo Starting VM vmtest
  virsh start vmtest
fi

Upvotes: 0

user208145
user208145

Reputation: 379

If you don't need to use virsh commands, on Ubuntu, a running domain name has a PID file and running XML config file at "/var/run/libvirt/qemu/${DomainName}.{pid,xml}".

I wrote a script to start domains on the condition a file exists. This way I don't have to toggle domain autostart options.

================================================================================
2022/01/15 16:18:42:    Okay to start.
2022/01/15 16:18:42:    'ParrotKde' appears to be running already. PID = 24470.
2022/01/15 16:18:45:    'UbuntuServer20' has been started. PID = 25209.

================================================================================
2022/01/15 16:20:45:    '/scripts/startvms' doesn't exist. Aborting.

Upvotes: 0

Benjamin Baez
Benjamin Baez

Reputation: 21

Building on Sharad's and Gary's answers, but only querying the status of VM in question.

virsh shutdown $VM
state=$(virsh dominfo $VM | grep -w "State:" | awk '{ print $2}')
while ([ "$state" != "" ] && [ "$state" == "running" ]); do
  sleep 10
  state=$(virsh dominfo $VM | grep -w "State:" | awk '{ print $2}')
done;
# now do something else to the shutdown VM and finally restart it
virsh start $VM

Upvotes: 2

Gerd
Gerd

Reputation: 464

My scenario is a bit different, so I got a slightly different solution.

I want to start a VM (Windows) and connect to it via xfreerdp all in one script. For this to work port 3389 has to be open inside the VM, which is not the case directly after starting the VM, although virsh list --all returns "running". So here is my little script using nc (aka netcat) to check the port:

# "windows_vm" is the VM-name, while "windows_guest" is the VM's hostname
virsh dominfo windows_vm | grep 'State: *shut off'
if [ $? -eq 0 ]; then
  echo "Start windows_vm..."
  virsh start windows_vm
  while true; do
    echo "Waiting for start..."
    # nc-parameters:
    #   -w1: wait 1s
    #   -z: ony scan the port without sending data
    nc -w1 -z windows_guest 3389 
    if [ $? -eq 0 ]; then
      break
    fi
    sleep 1
  done
fi

xfreerdp /v:windows_guest ...some-more-parameters...

If Remote Desktop capability is not enabled in Windows, there's maybe some other port you can check.

If the guest is a Linux-VM port 22 is always worth a try.

Upvotes: 2

Sharad
Sharad

Reputation: 10622

Try this:


tmp=$(virsh list --all | grep " vmtest " | awk '{ print $3}')
if ([ "x$tmp" == "x" ] || [ "x$tmp" != "xrunning" ])
then
    echo "VM does not exist or is shut down!"
    # Try additional commands here...
else
    echo "VM is running!"
fi

# For passwordless sudo:
sudo cat /etc/sudoers

# You'll see this:

# User privilege specification
root    ALL=(ALL:ALL) ALL

# To add user sharad as a sudo user:

# User privilege specification
root    ALL=(ALL:ALL) ALL
sharad  ALL=(ALL:ALL) ALL

# To add user sharad as a sudo user such that it doesn't ask for password (note the NOPASSWD):

# User privilege specification
root    ALL=(ALL:ALL) ALL
sharad  ALL=(ALL:ALL) NOPASSWD: ALL

# Read this for reference: http://www.ducea.com/2006/06/18/linux-tips-password-usage-in-sudo-passwd-nopasswd/

Upvotes: 7

Related Questions