Reputation: 235
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
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
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
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
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
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
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
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