如何在启动时启动VM,并在VM停止时关闭?

长话短说…

我不得不在这家公司的PC上安装一个运行在VM中的小型服务器应用程序。 两台计算机都运行Windows XP(使用传统软件,因此无法升级),而购买额外的PC目前也是有限的。 因此,我将其中一个主机的Windows转换为VM,并安装了Lubuntu。 然后导入服务器应用程序,一切正常; 除了启动和击落过程外,一切对用户几乎都是透明的。

问题

我想知道如何在主机启动时启动两个虚拟机,然后在Windows XP的VM击落时关闭PC? 现在,工作人员正在手动执行此操作,但我希望自动执行此过程。

要求

  1. Lubuntu应该有一个用户配置登录启动 – > 完成!
  2. 服务器应用程序VM应该从登录开始 – > 不确定
  3. Windows XP VM应该从登录 – > 不确定开始
  4. 服务器应用程序VM应该保存状态并在Windows XP计算机终止时自动关闭 – > 不知道
  5. 当所有VM暂停/关闭时,Lubuntu应该关闭。 – > 不知道

该系统使用VirtualBox 4.3.x在Lubuntu 14.04上运行。

你可以像这样设置一个Init.d / Systemd脚本:

#! /bin/sh # /etc/init.d/vbox #Edit these variables! VMUSER=VMAdmin VMNAME="cdb62186-7c30-4c25-a0b0-e4a32cfb0504" BASEFOLDER=/home/VMAdmin/path/to/backups/ case "$1" in start) echo "Starting VirtualBox VM..." sudo -H -u $VMUSER VBoxManage startvm "$VMNAME" --type headless ;; reset) echo "Resetting VirtualBox VM..." sudo -H -u $VMUSER VBoxManage controlvm "$VMNAME" reset ;; stop) echo "Saving state of Virtualbox VM..." sudo -H -u $VMUSER VBoxManage controlvm "$VMNAME" savestate ;; shutdown) echo "Shutting down Virtualbox VM..." sudo -H -u $VMUSER VBoxManage controlvm "$VMNAME" acpipowerbutton ;; status) sudo -H -u $VMUSER VBoxManage list vms -l | grep -e ^"$VMNAME": -e ^State | sed s/\ \ //g | cut -d: -f2- ;; backup) echo "" sudo -H -u $VMUSER VBoxManage controlvm "$VMNAME" acpipowerbutton echo "Waiting for VM "$VMNAME" to poweroff..." until $(sudo -H -u $VMUSER VBoxManage showvminfo --machinereadable "$VMNAME" | grep -q ^VMState=.poweroff.) do sleep 1 done FILENAME=$(date +"%Y_%m_%d-%T") echo "Backing up Virtualbox VM to '$BASEFOLDER$FILENAME'..." sudo -H -u $VMUSER VBoxManage clonevm "$VMNAME" --options keepallmacs --name $FILENAME --basefolder $BASEFOLDER echo "Restarting VirtualBox VM..." sudo -H -u $VMUSER VBoxManage startvm "$VMNAME" --type headless echo "" ;; *) echo "Usage: sudo service vbox {start|stop|status|shutdown|reset|backup}" exit 1 ;; esac exit 0 

请注意,我从这里获得了该脚本: https : //superuser.com/questions/789653/init-d-control-script-for-virtualbox-vm

请在安装脚本之前validation命令,然后测试每个function。 您需要将它放在/etc/init.d目录中,并在其上运行chmod +x以使其运行。 然后浏览并测试它的function。 一旦满意,运行:

sudo update-rc.d vbox defaults 99 01

这将把它设置为从系统开始。 作为一个FYI,原始post有一些cron作业的步骤。 如果有人知道更新的方法,请随时编辑这篇文章,或发布另一个答案。

我会通过bash脚本结合使用cron作业和使用vboxmanage。

我有一个bash脚本可以启动虚拟机并启动一个cron作业来检查机器的状态。

脚本应该类似于:

 #!/bin/bash vboxmanage startvm "Server App VM name" vboxmanage startvm "Windows XP VM name" crontab ~/check_vms_and_shutdown_job.txt 

假设我们将其保存为start_vms_and_cronjob.sh 。 记得chmod +x它,所以它可以实际执行。

您可能想知道check_vms_and_shutdown_job.txt文件。 它是一个文本文件,包含有关应以特定间隔运行的作业的信息。 在这个例子中,我们将它放在用户的主文件夹中,它应该是:

 */5 * * * * ~/check_vms_and_shutdown.sh 

该文件的行末尾应该有一个新行(保存前按Enter键;))这个文件的作用是描述一个每5分钟运行一次的cron作业并执行一个bash脚本。

现在你可能会问这个check_vms_and_shutdown.sh脚本是什么? 嗯,这是重点。 它应该说:

 #!/bin/bash if vboxmanage list runningvms | grep "Windows XP VM name" then echo "Windows XP still running." else echo "Windows XP shut down. Shutting down the rest." vboxmanage controlvm "Server App VM name" savestate crontab -r shutdown -h now fi 

现在它做了什么,它将检查是否有XP虚拟机在运行。 如果不是,它将订购服务器应用程序虚拟机以保存其状态。 之后,将删除cronjob并关闭系统。 记得chmod +x ,在这里我们也将文件放在用户的主文件夹中。

为了方便和更好地使用,您可能还希望无头运行虚拟机,并通过远程显示来完成它们的使用。

现在将start_vms_and_cronjob.sh添加到启动应用程序中,您应该进行设置。

所以我们在这里有:

  • 系统启动时,虚拟机由shell脚本启动,并从cron作业规则txt文件创建新的cron作业(运行shell脚本)。
  • 在每5分钟,cron作业运行脚本,该脚本检查XP虚拟机是否仍在运行,如果不是,它将保存其他虚拟机,删除cron作业并关闭系统。

希望这可以帮助您配置您需要的东西。

这些是实现所概述任务的步骤。 具有服务器应用程序的VM guest虚拟机将被称为“ServerApp”,即下面的Windows机器“WindowsXP”。 用他们的真名取代这些。

以下方法涉及在主机上创建自定义Xsession 。 这样做的好处是我们可能会删除此会话以仅加载运行虚拟机所需的应用程序(我们可能不需要完整的桌面)。 此外,使用内置于VirtualBox等待方法不需要调用任何其他循环来监视VM状态。

  1. 创建用于运行虚拟机的用户。
  2. 将guest虚拟机添加内容安装到guest虚拟机
  3. 运行VM时,使用Host + F切换到全屏。
  4. 在主机上定义自定义Lubuntu会话:

    • /usr/share/xsessions创建一个文件,并将其命名为WindowsVM.desktop其中包含以下内容:

       [Desktop Entry] Name=WindowsXP # or any other sensible name Comment=Custom Xsession running a VM Exec=/etc/X11/Xsession 
    • 使此文件可执行。 此会话将在登录时调用~/.xsession

  5. 在上面用户的HOME中创建名为~/.xsession的可执行会话启动脚本:

     #! /bin/bash /usr/bin/lxsession -s Lubuntu LXDE & VBoxManage startvm "ServerApp" --type headless VBoxManage startvm "WindowsXP" VBoxManage guestproperty set RUNNING 1 --flags TRANSIENT VBoxManage guestproperty wait "WindowsXP" RUNNING VBoxManage controlvm "SeverApp" savestate dbus-send --system --print-reply --dest="org.freedesktop.ConsoleKit" /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Stop 
  6. 登录时选择4.中的自定义会话。

棘手的一点是从虚拟机中删除guest虚拟机属性RUNNING(或我们选择的任何其他名称),因为它不像规范所暗示的那么短暂。 不幸的是,它将在虚拟机的关闭/断电后继续存在。

因此,我们必须在其关闭例程结束时(或从我们放在那里的关闭脚本)中使用VBoxcontrol.exe(随访客添加件一起安装)添加以下命令:

 VBoxControl.exe guestproperty set RUNNING 

然后,这将终止wait状态以继续保存“ServerAPP”,然后关闭主机电源。

另一种方法是在guest虚拟机上启动Windows应用程序 ,等待此应用程序终止,然后再关闭计算机并关闭主机电源。 然后我们将脚本中的两个set guestproperty命令替换为类似于以下的行:

 VBoxManage --nologo guestcontrol "WindowsXP" execute --image "C:\\full\\path\\to\\program.exe" --username  --password  --wait-exit --wait-stdout 

有关限制,请参阅VirtualBox手册 ,有关如何在Windows中为无密码帐户设置此限制的详细信息。


步骤5中的脚本命令解释:

  • /usr/bin/lxsession -s Lubuntu LXDE
    开始Lubuntu会议(如果适用,替换为任何其他定制的Xsession)

  • VBoxManage startvm "ServerApp --type headless"
    以无头模式启动运行服务器App的虚拟机(即无显示)

  • VBoxManage startvm "WindowsXP"
    启动运行Windows的虚拟机(全屏或上次运行时定义的任何其他分辨率)

  • VBoxManage guestproperty set "WindowsXP" RUNNING 1 --flags TRANSIENT
    为可以从客户操作系统控制的Windows机器设置属性RUNNING

  • VBoxManage guestproperty wait "WindowsXP" RUNNING
    等待从客户端Windows中删除属性RUNNING

  • VBoxManage controlvm "SeverApp" savestate
    在savestate中终止服务器App VM

  • dbus-send --system --print-reply --dest="org.freedesktop.ConsoleKit" \
    /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Stop
    在没有用户交互的情况下终止Lubuntu主机(断电状态)。