如何自动启动和关闭VirtualBox计算机?


52

我需要运行旨在作为设备安装在专用计算机上的软件系统。为了节省能源,我计划在VirtualBox VM上运行系统。

主机是带有SysV-Init系统的标准Linux盒,来宾是经过大量修改的Linux,我希望不必再对其进行更改。在OSE版本中使用VirtualBox。

我已经弄清楚了主机启动时如何启动VM(编辑:这已经完成,如下文Nikhil所述,通过命令VBoxManager startvm),但是如何优雅地关闭VM?在主机上运行的任何脚本都需要等待,直到客户机完全关闭。

谁能提出建议,例如,执行此操作的服务文件将如何显示?


您能否提供启动脚本以在启动时启动虚拟机
初学者

Answers:


34

您是否尝试过acpipowerbutton此命令集?

VBoxManage controlvm        <uuid>|<name>
                            pause|resume|reset|poweroff|savestate|
                            acpipowerbutton|acpisleepbutton|

阅读评论后进行编辑:

您可以使用acpid或其他acpi实用程序来使其优雅。另外,您能否提供有关当前如何关闭计算机的更多信息?

平原shutdown不会等待未完成的工作,时间延迟可能太长。

我认为您没有使用窗口管理器,因此请尝试使用工具。

刚看过这个守护进程。您可能会发现它很有用。


感谢您的回复,欢迎访问unix.stackexchange.com!但是,恐怕您的回答也无法解决我的问题:acpipowerbutton模拟在真实计算机上按下电源按钮,但是在主机上发出此命令后,VM将再次需要一些时间来关闭。
jstarek 2012年

4
当然。因此,您必须编写一个循环来检查VM是否仍在运行。为此,ACPI与我在脚本中使用的方法完全相同。vboxmanage list runningvms直到您的虚拟机消失。
尼尔斯2012年

好的,虽然我认为我会在实践中满足于管理包装的要求,但是+50给您指出了初始化脚本!
jstarek 2012年

16

与其亲自编写代码,不如考虑使用Vagrant,该实例旨在实例化和控制virtualbox实例。该文档非常出色,建议您将其检出,而不要尝试自己动手制作。

它的长短在于创建一个简单的控制文件,然后运行vagrant up以启动所需的任意数量的VirtualBox实例。您可以vagrant ssh用来登录主机和vagrant halt关闭主机(不终止)。 vagrant destroy将摆脱实例。

它支持使用puppet,Ansible或Chef进行配置,并允许您控制大多数公开的VBox配置设置。


2
我是一个无所事事的粉丝,但是在这种情况下,您到底想要什么?OP正在运行设备,而不是在构建自己的系统,因此,配置完全失去了重点。当您基本上要通过使用virtualbox建立系统的过程来进行操作时,为什么要在设备外制作一个自定义的“盒子”以使用流浪汉呢?
mc0e

10

我有与您类似的应用程序,但有一个区别:我需要重新启动系统并从快照中恢复。

您感兴趣的是无头模式

我有一些这样的服务,所以我使用以下脚本:

VBox_StopRestoreStart.sh

#!/bin/bash
if [ -z "$1" ]; then
        echo "Usage: $0 VMNAME_or_UUID"
        exit 1
fi
set -x
VBoxManage controlvm  "$1" poweroff  #enforce turnoff
VBoxManage snapshot   "$1" restorecurrent   #retore state
VBoxManage showvminfo "$1" | grep State   #display state to ensure
VBoxHeadless -s       "$1"  #run in headless mode in background

如何正常关闭虚拟机?

如果要正常关闭VM,则有两种选择,具体取决于您的应用程序:

  • 模拟“关闭按钮”或“睡眠按钮”,并准备VM对其做出反应(正常关闭)
    • VBoxManage controlvm <uuid>|<VMname> acpipowerbutton
    • VBoxManage controlvm <uuid>|<VMname> acpisleepbutton
  • 保存虚拟机状态以便以后还原
    • VBoxManage controlvm <uuid>|<VMname> savestate

提示:您可能会发现有用的:

  • VBoxManage list vms -可用虚拟机列表
  • rdesktop IP-ADDR:3389rdesktop-vrdp IP-ADDR:3389-当您以无头模式运行时想要GUI(甚至是远程)时:VBoxHeadless -s <uuid>|<VMname>
  • VBoxManage startvm -从GUI开始进行本地调试

相关VirtualBox手册的章节:第7章。远程虚拟机-逐步说明:在无头服务器上创建虚拟机

PS:如果您对已经实施的功能齐全的解决方案感兴趣,那么OpenStack似乎是一个有趣的选择。


10

http://www.virtualbox.org/manual/ch08.html上查看VirtualBox VM管理文档

要列出虚拟机,请使用以下命令 VBoxManage list vms

要启动VM,请使用以下命令 VBoxManage startvm

http://www.virtualbox.org/manual/ch08.html#vboxmanage-controlvm

要控制VM,请使用 VBoxManage controlvm

controlvm命令允许你改变当前正在运行的虚拟机的状态。可以指定以下内容:

VBoxManage controlvm <vm> pause暂时搁置虚拟机,而不会永久更改其状态。VM窗口将涂成灰色,以指示VM当前已暂停。(这等效于在GUI的“机器”菜单中选择“暂停”项。)

使用VBoxManage controlvm <vm> resume到撤销之前的暂停指令。(这等效于在GUI的“机器”菜单中选择“恢复”项目。)

VBoxManage controlvm <vm> reset在虚拟机上的效果与在真实计算机上按下“重置”按钮的效果相同:虚拟机的冷重启,它将重新启动并立即重新启动来宾操作系统。VM的状态不会预先保存,并且可能会丢失数据。(这等效于在GUI的“机器”菜单中选择“重置”项。)

VBoxManage controlvm <vm> poweroff对虚拟机的影响与拉动真实计算机上的电源线相同。同样,VM的状态不会预先保存,并且数据可能会丢失。(这等效于在GUI的“机器”菜单中选择“关闭”项,或按窗口的关闭按钮,然后在对话框中选择“关闭机器电源”。)

此后,VM的状态将为“关闭电源”。


请注意,在某些系统上,它是vboxmanage(全部小写)。
Arcege 2012年

2
感谢您的答复,但不幸的是,这不能解决我的问题:我需要正常关闭访客,即在访客内部发出“ shutdown -h now”,并使主机等待直到访客完全关闭。没有VBoxManage controlvm任何子命令可以执行此操作。
jstarek 2012年

您可以通过在主机关闭之前重新检查主机中的所有VM来确保它。如果您需要从来宾内部控制主机,则可以使用virtualbox.org/manual/ch08.html#vboxmanage-guestcontrol,但这可能无法满足您的需求。您应该/etc/init.d/vboxvms-service在主机系统上编写一个启动脚本(如脚本),启动后将使所有vms停止,停止时将使所有vms崩溃。
Nikhil Mulley 2012年

VBoxManage controlvm savestate是另一种可能性(至少Google告诉我),它可以保存计算机状态并干净地将其关闭,但仍然无法强制主机等待。
巴恩2012年

5

对于基于systemd的系统,您可以尝试此操作。

步骤#1:创建服务文件

[Unit]
Description=VBox Virtual Machine %i Service
Requires=systemd-modules-load.service
After=systemd-modules-load.service

[Service]
User=user
Group=vboxusers
ExecStart=/usr/bin/VBoxHeadless -s %i
ExecStop=/usr/bin/VBoxManage controlvm %i savestate

[Install]
WantedBy=multi-user.target

步骤2:启用服务文件

$ sudo systemctl enable vboxvmservice@vm_name.service

参考文献


1
最好在此处包括答案,并可以选择提供指向更详细信息的链接。链接目标会在不通知的情况下消失,使您的答案毫无价值。
Anthon 2013年

好吧,问题是我不能真正在此处复制链接1中的整个systemd文件,还是应该这样做?
JanRüegg2013年

好吧,不幸的是,在这些情况下,“链接腐烂”是一个巨大的问题……我想,为方便起见,以下两行内容抓住了Link背后的基本思想:它正在创建VBoxHeadless -s %i用于启动和VBoxManage controlvm %i savestate停止VM的服务。
jstarek 2013年

在Debian Jessie中进行了尝试,但是没有用。创建用户和组,设置所有文件的所有权(包括/ dev / vbox *)。但是,当服务启动时,即使名称正确,也无法找到VM。毕竟将使用普通的init脚本。
mivk 2015年

3

如何通过ssh从主机向来宾发送命令?

我不确定它是否可以工作,是否可以稍后检查机器状态或获得类似退出状态的信息,但是它至少应该干净。


很好的想法,但这将保证来宾VM至少可以通过ssh端口(22)通过主机从网络访问。
Nikhil Mulley 2012年

基本上,这将起作用,可以通过其DNS条目在整个LAN中访问该设备。但是,假设我编写了一个脚本,每当主机关闭时,该脚本便被推送到设备中-它仍然必须阻塞(暂停),直到访客完全关闭为止。这正是我的问题的重点:脚本如何知道来宾何时关闭,以便可以将控制流返回给SysV-Init,并且主机可以继续关闭?
jstarek 2012年

1
您的评论假定一切都将在主机系统而不是来宾系统上顺利运行。如果将电源线插入主机系统怎么办?它是一个不同的讨论。只要服务脚本了解以正确方式关闭来宾VM的逻辑(在远程主机上执行exec关机或仅通过vbox界面关闭电源),您的主机系统上的SysV-init就会等待服务脚本停止VM。然后yield将成功或失败状态返回到控制台或init。
Nikhil Mulley 2012年

1
关于:脚本如何知道guest虚拟机何时关闭,请尝试简单检查vm是否从VboxManager界面打开或关闭,以及guest虚拟机是否可打开。另外,在主机系统上进行一些监视,该监视将执行是否可从Vboxmanager以及是否可以及时从其打开虚拟机。
Nikhil Mulley 2012年

1

我的解决方案:在此shellscript中,“ root”是调用者,“ theuser”是“ thevm”的所有者

我知道当命令的输出VBoxManage list runningvms返回空字符串时,vms已经结束。

...
start(){
    su -c "VBoxHeadless --startvm thevm" -s /bin/bash theuser &
    # maybe another vbox command
}

stop(){
    su -c "VBoxManage controlvm thevm acpipowerbutton" -s /bin/bash theuser
    # maybe another vbox command
    while [ "`su -c 'VBoxManage list runningvms' -s /bin/bash theuser`" != "" ]
    do
        echo waiting for VMs to shutdown
        sleep 3
    done
}
...

1

要启动虚拟机:

VBoxManage startvm VMNAME --type headless

停止虚拟机:

VBoxManage controlvm VMNAME savestate

列出所有正在运行的虚拟机:

VBoxManage list runningvms

0

也许这将有助于解决方案。

VBoxManage list runningvms | tr -s '\" {' '%{' | cut -d '%' -f3  | while read uuid; do
   VBoxManage controlvm $uuid savestate; 
done

0

您为什么不登录访客并从那里关机?

除非您有充分的理由不安装sshd并通过VBox真正访问VM,否则我会选择只发出的脚本ssh shutdown -h now。老实说,我会为每台机器创建一个脚本,以将其正确关闭并在运行时进行一些检查。

只需打包一个/etc/init.d/shutdown_vm脚本,该脚本从主机调用另一个脚本,该调用将阻塞直到准备就绪。此过程(如上所述)在来宾系统上添加了linux依赖项,但在主机处删除了VBox依赖项。

顺其自然:您无需访问VBox即可关闭计算机,如果您有某种访问它的方法(例如ssh),则操作系统将始终具有某些方法(将其打开,当然是不同的)


原因有两个:首先,如原始问题所述,如果确实没有必要,我不想更改经过大量修改的来宾OS。其次,更重要的是,这旨在提供一种干净的方法,以在主机关闭时自动关闭所有正在运行的VM。
jstarek 2014年

@jstarek但是,如果您不想进行修改,则不必修改来宾操作系统(99.99%的时间,您可以通过某种方式登录,或者这是一个例外)。正是这个主意,如果主机关闭,则在更改运行时时将调用适当的脚本,并且该脚本将记录到来宾并从“内部”关闭,这是流浪者无论如何所做的……在“强行执行”之前力”即是
estani 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.