在开始之前,如何检查特定服务器是否正在运行(使用 virsh 命令)|重启一下?

问题描述 投票:0回答:7

我正在尝试重新启动、启动、关闭特定虚拟机。 在这里,首先我想在运行脚本之前检查虚拟机是否已处于所需状态。

这些是虚拟机列表。

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

我想在实施之前检查 vmtest 是否正在运行

virsh start vmtest

如何在 shell 脚本中使用 if 条件检查状态?

当我必须使用 sudo 命令时,如何避免输入密码。

sudo virsh start vmtest

我还尝试使用

授予 root 权限
sudo -i
virsh start vmtest

但是脚本结束时没有执行第二行。 如何在同一个脚本文件中使用这两个命令?

if [conditions]
then
{

}
fi

我不知道如何检查此类脚本的条件。

谢谢你。

linux bash shell virtual-machine virsh
7个回答
7
投票

试试这个:


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/

3
投票

我喜欢 Sharad 的回答,但我在等待虚拟机关闭时将其反转为繁忙循环

    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

就我而言,我在虚拟机关闭时创建快照,然后重新启动它。我将 10 秒的睡眠硬编码到循环中,因为这似乎是一个合理的重试周期,因为 Windows 虚拟机在安装更新时可能需要很长时间 - 可能是几分钟甚至更长。


2
投票

基于 Sharad 和 Gary 的答案,但仅查询相关虚拟机的状态。

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

1
投票

我的场景有点不同,所以我得到了稍微不同的解决方案。

我想启动一台虚拟机 (Windows) 并通过

xfreerdp
全部在一个脚本中连接到它。为此,端口 3389 必须在 VM 内打开,启动 VM 后情况并非如此,尽管
virsh list --all
返回“正在运行”。所以这是我的小脚本,使用
nc
(又名
netcat
)来检查端口:

# "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...

如果 Windows 中未启用远程桌面功能,您可能可以检查其他端口。

如果来宾是 Linux-VM,端口 22 总是值得一试。


1
投票

我刚刚在看这个。有一个内置命令,而不是通过管道连接到

grep
awk
。我不知道第一次问这个问题时是否是这种情况,但对于其他可能遇到此问题的人来说:

virsh domstate <vm name>

确保使用的名称引号中包含空格。 此外,仅当名称中不含空格时,接受的答案才有效。如果确实有空格,则需要调整

awk
命令。


0
投票

如果您不需要使用

virsh
命令,在 Ubuntu 上,运行域名有一个 PID 文件和运行 XML 配置文件,位于
"/var/run/libvirt/qemu/${DomainName}.{pid,xml}"

我编写了一个脚本,在文件存在的情况下启动域。这样我就不必切换域自动启动选项。

================================================================================
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.

0
投票

当我必须使用 sudo 命令时,如何避免输入密码。

确保您的用户是“libvirt”组的成员。

sudo usermod -G libvirt <username>

您需要注销并重新登录才能生效。

请注意,在基于 RHEL 的系统上,您可能还需要确保设置了以下环境变量:

LIBVIRT_DEFAULT_URI=qemu:///system

然后尝试:

$ virsh domstate vmtest
running

不幸的是,上面的内容并没有为您提供一个很好的简单退出代码来在 bash 中进行测试,因此您可以尝试以下操作(针对未运行的机器显示的输出):

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

Bash 脚本如下所示:

#!/bin/bash
virsh domstate vmtest | grep running
if [ $? -ne 0 ] ; then
  echo Starting VM vmtest
  virsh start vmtest
fi
© www.soinside.com 2019 - 2024. All rights reserved.