- автозапуск - некоторые виртуалки нужно запускать одновременно с host сервером
- корректное завершение работы, т.е. автоматическое и корректное выключение виртуалок вместе с host сервером
а) родными средствами VirtualBox-а эти задачи не решаются
б) есть некоторое кол-во самописных скриптов, но...
в) все они некорректно работают с VB v4.x.
Пришлось брать, и "допиливать"...
За основу взял скрипты некого Jochem Kossen-а. Как оказалось, "несовместимостей всего 2:
- Изменился формат вывода списка виртуалок (результаты VBoxManage list runningvms)
- Немного изменился формат запуска
- Скачать и распаковать архив (например в /opt/vboxcontrol)
- Поколдовать над содержимым /opt/vboxcontrol/vboxcontrol
- Еще раз внимательно прочитать README и создать файлы /etc/virtualbox/config и /etc/virtualbox/machines_enabled
- Сделать ссылку в /etc/init.d/ и обновить init rc скрипты. Например:
sudo ln -s /opt/vboxcontrol/vboxcontrol /etc/init.d/vboxcontrol
sudo update-rc.d vboxcontrol defaults 99 10
sudo service vboxcontrol start|stop|status|savestate|poweroff
А также
sudo service vboxcontrol vm-start|vm-stop|vm-poweroff|vm-savestate|vm-reset VM_NAME
Также, надо не забыть установить пакет acpid на гостевые системы.
Модифицированный скрипт:
#! /bin/sh ### BEGIN INIT INFO # Provides: virtualbox_vms # Required-Start: $local_fs $syslog $remote_fs # Required-Stop: $local_fs $syslog $remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Control VirtualBox Virtual Machine instances ### END INIT INFO # # Version 2008051100 by Jochem Kossen# http://farfewertoes.com # # Released in the public domain # # This file came with a README file containing the instructions on how # to use this script. # . /lib/lsb/init-functions # Are we running from init? run_by_init() { ([ "$previous" ] && [ "$runlevel" ]) || [ "$runlevel" = S ] } ################################################################################ # INITIAL CONFIGURATION VBOXDIR="/etc/virtualbox" VM_USER="root" USE_NAT="yes" export PATH="${PATH:+$PATH:}/bin:/usr/bin:/usr/sbin:/sbin" if [ -f $VBOXDIR/config ]; then . $VBOXDIR/config else echo "ERROR: $VBOXDIR/config does not exist. Exiting." exit 1 fi SU="su $VM_USER -c" VBOXMANAGE="VBoxManage -nologo" ################################################################################ # FUNCTIONS # Determine if USE_NAT is set to "yes" use_nat() { if [ "$USE_NAT" = "yes" ]; then return `true` else return `false` fi } # Bring up the bridge interface enable_bridge() { # If NAT is enabled, don't do anything use_nat && return # Load the tun module if [ ! -e /dev/net/tun ]; then modprobe tun fi brctl addbr br0 || /bin/true # Disable $HOST_IF; host will use br0 instead ifdown $HOST_IF ifconfig $HOST_IF 0.0.0.0 promisc brctl addif br0 $HOST_IF # Bring up br0 ifup br0 # Answer ARP requests for $HOST_IP (which now come on br0) with the MAC # address of $HOST_IF arp -Ds $HOST_IP $HOST_IF pub } # Bring down the bridge interface disable_bridge() { # If NAT is enabled, don't do anything use_nat && return ifdown br0 brctl delbr br0 ifup $HOST_IF } # Activate tap interfaces enable_taps() { # If NAT is enabled, don't do anything use_nat && return for TAP in $TAPS; do # Check if $TAP is configured already ifconfig $TAP > /dev/null 2>&1 if [ $? != 0 ]; then tunctl -t $TAP -u $VM_USER brctl addif br0 $TAP # Disable tap interfaces for host; guest will activate them for themselves ifconfig $TAP 0.0.0.0 promisc # Enable proxy_arp so that ARP requests can be answered correctly # by the host echo 1 > /proc/sys/net/ipv4/conf/$TAP/proxy_arp # Add a route for the tap device route add -host $HOST_IP dev $TAP else log_failure_msg "Interface $TAP already configured" fi done } # Disable/deconfigure tap interfaces disable_taps() { # If NAT is enabled, don't do anything use_nat && return for TAP in $TAPS; do route del -host $HOST_IP dev $TAP brctl delif br0 $TAP tunctl -d $TAP done } # Check for running machines every few seconds; return when all machines are # down wait_for_closing_machines() { RUNNING_MACHINES=`$SU "$VBOXMANAGE list runningvms" | wc -l` if [ $RUNNING_MACHINES != 0 ]; then sleep 5 wait_for_closing_machines fi } ################################################################################ # RUN case "$1" in start) if [ -f /etc/virtualbox/machines_enabled ]; then if [ ! `use_nat` ]; then enable_bridge enable_taps chown root.vboxusers /dev/net/tun chmod 0660 /dev/net/tun fi cat /etc/virtualbox/machines_enabled | while read VM; do log_action_msg "Starting VM: $VM ..." $SU "$VBOXMANAGE startvm \"$VM\" --type headless" done fi ;; stop) # NOTE: this stops all running VM's. Not just the ones listed in the # config $SU "$VBOXMANAGE list runningvms |sed -e 's/ {.*}//'" | while read VM; do log_action_msg "Shutting down VM: $VM ..." $SU "$VBOXMANAGE controlvm \"$VM\" acpipowerbutton" done wait_for_closing_machines if [ ! `use_nat` ]; then disable_taps disable_bridge fi ;; savestate) # NOTE: this suspends all running VM's. Not just the ones listed in the # config $SU "$VBOXMANAGE list runningvms |sed -e 's/ {.*}//'" | while read VM; do log_action_msg "Suspending VM: $VM ..." $SU "$VBOXMANAGE controlvm \"$VM\" savestate" done wait_for_closing_machines if [ ! `use_nat` ]; then disable_taps disable_bridge fi ;; poweroff) # NOTE: this stop all running VM's. Not just the ones listed in the # config $SU "$VBOXMANAGE list runningvms |sed -e 's/ {.*}//'" | while read VM; do log_action_msg "Shutting down VM: $VM ..." $SU "$VBOXMANAGE controlvm \"$VM\" savestate" done wait_for_closing_machines if [ ! `use_nat` ]; then disable_taps disable_bridge fi ;; bridge-up) enable_bridge ;; bridge-down) disable_bridge ;; taps-up) enable_taps ;; taps-down) disable_taps ;; vm-start) log_action_msg "Starting VM: $2 ..." $SU "$VBOXMANAGE startvm \"$2\" --type headless" ;; vm-stop) log_action_msg "Stopping VM: $2 ..." $SU "$VBOXMANAGE controlvm \"$2\" acpipowerbutton" ;; vm-poweroff) log_action_msg "Powering off VM: $2 ..." $SU "$VBOXMANAGE controlvm \"$2\" poweroff" ;; vm-savestate) log_action_msg "Savestate VM: $2 ..." $SU "$VBOXMANAGE controlvm \"$2\" savestate" ;; vm-reset) log_action_msg "Reset VM: $2 ..." $SU "$VBOXMANAGE controlvm \"$2\" reset" ;; status) log_action_msg "The following virtual machines are currently running:" $SU "$VBOXMANAGE list runningvms |sed -e 's/ {.*}//'" | while read VM; do echo -n "$VM " echo done ;; *) log_failure_msg "Usage: $0 {start|stop|status|savestate|poweroff|vm-start |vm-stop |vm-poweroff |vm-savestate |vm-reset |bridge-up|bridge-down|taps-up|taps-down}" exit 3 esac exit 0
Update (2012-07-25)
>> ссылки не работают, Таки да, автор удалил статью на своем сайте. Возможные причины:
a) этот скрипт перепостили такое количество раз, что автор больше не видит смысла держать его на своих ресурсах :)
б) Отпала надобность в этом скрипте - за последние 4-5 релизов ораклисты серьезно причесали свой продукт, так что весьма вероятно, что теперь автостарт и т.д. можно достичь стандартными средствами. Я не изучал этот вопрос, потому как вышеописанный скрипт уже пару лет успешно служит на серверах. А, как известно, не надо трогать то, что работает :)
>> инструкцию по установке и настройке выложите пожалуйста.
В исходном архиве лежат 4 файла:
- 'vboxcontrol' - приведенный выше скрипт.
- 'README' - см. ниже
- 'LICENSE' - см. ниже
- 'ChangeLog' - см. ниже
This script was developed for use on an Ubuntu host machine. These instructions are for such a system as well. INSTALLATION * Make sure you have sudo, bridge-utils, uml-utilities and obviously VirtualBox installed * Put the vboxcontrol script in the /etc/init.d/ directory * Make the script executable: chmod 0755 /etc/init.d/vboxcontrol * If you use 'Host interface' networking, put a br0 entry in /etc/network/interfaces: iface br0 inet dhcp * Create a new directory called /etc/virtualbox * Create a file called /etc/virtualbox/config with the following lines: HOST_IF="eth0" HOST_IP="192.168.1.5" VM_USER="jochem" USE_NAT="no" TAPS="tap0 tap1" Change all values appropriately for your system: HOST_IF is the interface which VirtualBox uses to bridge. HOST_IP is the standard ip address of the host. VM_USER is the system user under which all virtual machines will run. USE_NAT specifies if you want to use NAT networking (set it to "yes") or Host interface networking (set it to "no") TAPS are the tap interfaces you want to set up. Use one for each VM, seperate them by a space. Only applicable if USE_NAT is set to "no". * Create a file called /etc/virtualbox/machines_enabled with a virtual machine name on each line. Example: Debian Webserver OpenBSD Fileserver * Set up VirtualBox to use the specified tap interfaces for your machines (in the Network settings screen for your VM, set 'Attached To' to 'Host Interface', and 'Interface Name' to 'tap0' for the first VM, 'tap1' for the second VM, etc. * Let the script start up at boot: # update-rc.d vboxcontrol defaults 99 10 This command starts the machine at the latest possible time, when everything else has already booted, and at reboot/shutdown it's executed in the beginning of the shutdown procedure) USAGE Start all specified virtual machines: # /etc/init.d/vboxcontrol start Stop all virtual machines: # /etc/init.d/vboxcontrol stop View status of all running virtual machines: # /etc/init.d/vboxcontrol status Start a specific vm calledСодержимое 'LICENSE': # /etc/init.d/vboxcontrol start-vm Stop a specific vm called (this sends an acpi power down event): # /etc/init.d/vboxcontrol stop-vm Turn off a specific vm called (this sends an immediate power down event): # /etc/init.d/vboxcontrol poweroff-vm Bring the configured bridge up: # /etc/init.d/vboxcontrol bridge-up Bring the configured bridge down: # /etc/init.d/vboxcontrol bridge-down Bring up the configured tap devices: # /etc/init.d/vboxcontrol taps-up Bring down the configured tap devices: # /etc/init.d/vboxcontrol taps-down ISSUES - The 'stop' command stops all virtual machines, not just the ones configured in /etc/virtualbox/machines_enabled - Perhaps the main functionality should not be in an init.d script; this would make portability easier CONTACT The original author is Jochem Kossen. You can reach him at jochem.kossen@gmail.com
This contents of this package is released under the public domain. This means you can do with it whatever you like, but it comes without any warranty or whatsoever. For more information about this, see http://en.wikipedia.org/wiki/Wikipedia:Copyright_FAQ#Public_domain Regards, Jochem Kossen jochem.kossen@gmail.comСодержимое 'ChangeLog' (актуально для оригинальной версии)
20080511: - add USE_NAT config variable to make the script work with non-tap based networking - add stop-vm method which sends an ACPI powerbutton event - add poweroff-vm method which powers off the VM instantly - more documentation - add ChangeLog and README files - minor cleanups - rename VirtualBoxMachines to vboxcontrol - put in Git for revision controll 20080331: - cleanups - add bridge-up/bridge-down, taps-up/taps-down methods - rename setup_* to enable_* for consistency - show VM names in 'status' output - check if tap interfaces are configured already before bringing them up 20080309: - initial version
Отличный скрипт! Использую уже на втором сервере. Спасибо за адаптацию для Убунуту.
ОтветитьУдалитьНа здоровье :)
ОтветитьУдалитьссылки не работают, инструкцию по установке и настройке выложите пожалуйста.
ОтветитьУдалитьПрисоединяюсь - работает отлично. И я тоже не трогаю, работает и работает.
ОтветитьУдалить