viernes, 10 de septiembre de 2010

Onoffvbox, Script para arrancar o parar máquinas virtuales headless en Virtual Box 3.2.8

ACTUALIZACIÓN: 12 Sep 2010: He hecho unos cambios en el script para que haya algunas verificaciones antes de arrancar/parar todas/grupos de máquinas virtuales.

He creado un script bash para el arranque, parada y alguna función más para máquinas virtuales (MV) de Virtual Box 3.2.8.

Podemos arrancar y parar todas, una, o un grupo dado de MVs, lo que nos permite manejar "aceptablemente" una granja de servidores. El script se encuentra documentado en el propio fichero pero tenemos que tener en cuenta una serie de cosas importantes.

  • Las máquinas virtuales no pueden contener espacios en el nombre ya que el espacio es un separador que usan muchos comandos de bash.
  • Las MVs se arrancarán en modo headless, es decir, sin GUI. Podremos acceder a ellas a través de rdp o de ssh. Así no tendremos 200 pantallas molestando, solo usaremos las que necesitemos.
  • Debemos tener instalado en todas las máquinas virtuales GNU\Linux el demonio acpid. En k/ubuntu se instala con sudo apt-get install acpid. Esto es para el correcto apagado de la máquina virtual. No podemos usar poweroff y correr el riesgo de perder datos. He probado con Ms Windows 2008 R2 y el apagado funciona, por tanto, seguramente funcionará en Ms Windows 7. No he probado otros Ms Windows, podéis hacer la prueba y ponerlo en los comentarios.
  • En los desktop GNU\Linux, hay que tener en cuenta que al enviar la señal de apagado acpi, el desktop (Gnome Ubuntu) espera unos 60 sg a apagarse. En las MV sin escritorio es más rápido pero siempre hay que tener en cuenta que hay que esperar un tiempo prudencial a que se apaguen enciendan las MVs, sobretodo si son varias.
  • El script tiene la misma licencia CC que los artículos del blog y que podéis ver en la parte superior derecha del blog.

Para usarlo:

  1. Copiáis el texto del script a un fichero y le dais el nombre onoffvbox.
  2. Configuráis las variables de la parte de configuración con vuestros valores.
  3. Le dais permiso de ejecución.
  4. Podéis copiarlo a un directorio que tengáis en el PATH para poder ejecutarlo desde cualquier lugar.
  5. Y listo pero cuidado con la opción all, no vayáis a parar o a arrancar todas las MVs a no ser que realmente sepáis lo que hacéis y sea necesario. Recordad que no me hago responsable de lo que hagáis en vuestros sistemas.

Un ejemplo de uso

He configurado un grupo dentro del script con 4 MVs ubuntu server para poder arrancar solo esas 4 MVs ya que las uso mucho. Para ello he creado/descomentado la variable MV_GROUP en el lugar correspondiente y le he puesto la lista de MVs así.

MV_GROUP="ubults6400 ubults6401 ubults6402 ubults6403"

Puedo ver si tengo MVs arrancadas

$ onoffvbox mvlist run
Mostrando Máquinas Virtuales arrancadas:

Oracle VM VirtualBox Command Line Management Interface Version 3.2.8
(C) 2005-2010 Oracle Corporation
All rights reserved.

Veo que no. Ahora, para arrancar esas y solo esas MVs solo tengo que ejecutar

$ onoffvbox start mvgroup
El grupo de máquinas virtuales activo es:
-----------------------------------------

ubults6400 ubults6401 ubults6402 ubults6403

¿Está seguro? (y/n):
y

Arrancando Máquina virtual ubults6400
---------------------------------------------

Oracle VM VirtualBox Command Line Management Interface Version 3.2.8
(C) 2005-2010 Oracle Corporation
All rights reserved.

Waiting for the VM to power on...
VM has been successfully started.

Arrancando Máquina virtual ubults6401
---------------------------------------------

Oracle VM VirtualBox Command Line Management Interface Version 3.2.8
(C) 2005-2010 Oracle Corporation
All rights reserved.

Waiting for the VM to power on...
VM has been successfully started.

Arrancando Máquina virtual ubults6402
---------------------------------------------

Oracle VM VirtualBox Command Line Management Interface Version 3.2.8
(C) 2005-2010 Oracle Corporation
All rights reserved.

Waiting for the VM to power on...
VM has been successfully started.

Arrancando Máquina virtual ubults6403
---------------------------------------------

Oracle VM VirtualBox Command Line Management Interface Version 3.2.8
(C) 2005-2010 Oracle Corporation
All rights reserved.

Waiting for the VM to power on...
VM has been successfully started.

Mostrando Máquinas Virtuales arrancadas:

Oracle VM VirtualBox Command Line Management Interface Version 3.2.8
(C) 2005-2010 Oracle Corporation
All rights reserved.

"ubults6400" {978efc44-1d26-4c86-ad88-499b97a7fa27}
"ubults6401" {5f8456d7-7aeb-40c8-9e1f-9e1d457bad93}
"ubults6402" {bc0b7de1-06ad-4331-abfe-be8720322c57}
"ubults6403" {b790c07b-0af3-4086-a9ad-a97e791ad062}

Y listo :-). Tened en cuenta que para apagar las máquinas virtuales headless debéis usar el script onoffvbox o el comando VBoxManage. Espero que opinéis y que digáis si os es útil.

Script onoffvbox

#!/bin/bash
# Añadir/Quitar -x -v a /bin/bash para debug del script
#
# Author: Francisco J. Bejarano 
# Creative Commons License 3.0 Ver en
# http://yoadminisis.blogspot.com
# Puedes usar/modificar el script como quieras respetando la licencia CC
# 
# Versión: 1.5
# Script de arranque/parada de máquinas virtuales con Virtual Box 3.2.8
# Arranca máquinas sin consola gráfica (headless) pero  con la
# posibilidad de arrancar una consola gráfica de forma remota (vrdp)
#
#

## BEGIN CONFIGURATION
#

# Los siguientes datos se deben adecuar a las localizaciones que
# eligió el usuario en en la instalación de su servidor Virtual Box

# Binario de Virtual Box
VBOX_BIN=/usr/bin/VBoxManage

# Directorio de almacenaje de Máquinas Virtuales
MV_DIR=/dir/usuario/Vmachines

# Lista del grupo de máquinas virtuales a arrancar o parar.
# Si tenemos una lista grande de máquinas virtuales podemos
# poner aquí sus nombres y usar mvgroup como segundo argumento para no
# ejecutar el script start o stop muchas veces.
# Podemos tener las máquinas en diferentes grupos y comentar y descomentar 
# unos u otros para usarlos. Cuidado con las mayúsculas y minúsculas.
#MV_GROUP="ubults6400 ubults6401 ubults6402 ubults6403"
#MV_GROUP="ubudesk00 ubudesk01"
#MV_GROUP="swin2k800 miservidorwindows2 miclientewindows1"
#MV_GROUP="miotrosserver1 miotroserver2"

# LIMITACIONES:
# Las Maquinas virtuales no deberían contener espacios en el nombre
# ya que estructuras como select los usan como separador.

#
## END CONFIGURATION

# Función que muestra las máquinas virtuales arrancadas
show_mv_running()
{
  echo "Mostrando Máquinas Virtuales arrancadas:"
  echo ""
  $VBOX_BIN list runningvms
  echo ""
}

# Función que muestra las máquinas virtuales registradas
show_mv_registered()
{
  echo "Mostrando Máquinas Virtuales registradas:"
  echo ""
  $VBOX_BIN list vms
  echo ""
}

# Función de arranque de máquinas virtuales
arranque()
{
  echo "Arrancando Máquina virtual $MV"
  echo "---------------------------------------------"
  echo ""
  # Iniciamos las máquinas virtuales headless con vrdp
  $VBOX_BIN startvm "$MV" --type vrdp
  echo ""
}

# Función de parada de máquinas virtuales
parada()
{
  echo "Parando Máquina virtual $MV"
  echo "---------------------------------------------"
  echo ""
  # Paramos las máquinas virtuales headless
  # Usamos acpipowerbutton para hacer un apagado ordenado de la 
  # máquina virtual (con poweroff apagaríamos a lo bestia ¿perdida de datos?
  # y con savestate haríamos una suspensión no un apagado)
  # IMPORTANTE: Las Maquinas Virtuales GNU\Linux deben tener instalado el demonio acpid
  # $ sudo apt-get install acpid
  $VBOX_BIN controlvm "$MV" acpipowerbutton 
  echo ""
  sleep 10
}

# Función para mostrar el grupo de máquinas virtuales
# actualmente seleccionado.
show_group()
{
  echo "El grupo de máquinas virtuales activo es:"
  echo "-----------------------------------------"
  echo ""
  echo "$MV_GROUP"
  echo ""
}

# Función para verificar una acción
verify_yn()
{
  echo "¿Está seguro? (y/n):"
  read RESPUESTA
  if [ $RESPUESTA = "n" ]
  then
    echo "Saliendo..."
    echo ""
    exit
  fi
  if [ $RESPUESTA != "y" ]
  then
    echo "Por favor, pulse y (yes,si) o n (no)"
    echo ""
    exit
  fi
}

# Función de ayuda del script
help_onoffvbox()
{
  echo "Uso: $0 (start|stop|mvlist|helpme) (all|mvgroup)"
  echo ""
  echo " Nota: Este script es válido para máquinas virtuales de VirtualBox 3.2 arrancadas en "
  echo "       modo Headless sin GUI."
  echo "       Los nombres de las máquinas virtuales no pueden contener espacios."
  echo ""
  echo " ADVERTENCIA: Tenga cuidado al usar la opción all ya que puede dejar sin recursos al "
  echo "              servidor o parar todos los servicios que ofrece con las máquinas virtuales."
  echo ""
  echo " $0 start"
  echo " Inicia una máquina virtual que seleccionemos de la lista de máquinas disponibles mostrada."
  echo ""
  echo " $0 start all"
  echo " Inicia todas las máquinas virtuales registradas"
  echo ""
  echo " $0 start mvgroup"  
  echo " Inicia el grupo de máquinas virtuales contenidas en la variable MV_GROUPS del script $0"
  echo ""
  echo " $0 stop"
  echo " Para una máquina virtual de la lista de máquinas en funcionamiento."
  echo ""
  echo " $0 stop all"
  echo " Para todas las máquinas virtuales de la lista de máquinas en funcionamiento."
  echo ""
  echo " $0 stop mvgroup"
  echo " Para el grupo de máquinas virtuales contenidas en la variable MV_GROUPS del script $0"
  echo ""
  echo " $0 mvlist run"
  echo " Lista las máquinas virtuales actualmente en funcionamiento."
  echo ""
  echo " $0 mvlist reg"
  echo " Lista las máquinas virtuales registradas."
  echo ""
  echo " $0 mvlist group"
  echo " Lista el grupo de máquinas virtuales activo."
  echo ""
}


# Comprobación de binario y directorios
[ -d $MV_DIR ] || echo "No existe el directorio de almacenaje de Máquinas Virtuales"
[ -x $VBOX_BIN ] || echo "No existe el binario VBoxManage o no es ejecutable."


#### PROGRAMA PRINCIPAL
##

# Valores posibles del argumento 1
# start, stop, mvlistr, helpme
case "$1" in
    # Arranque de máquinas virtuales
    start)
    # Valores posibles de start
    # all: Todas las maquinas virtuales registradas
    # mvgroup: lista de máquinas virtuales de MV_GROUP
    # Por defecto usa el nombre de la máquina virtual que le demos
    case "$2" in
      # Arranque de todas las MV
      all)
        verify_yn
        # El comando extrae las máquinas virtuales registradas
        for MV in `$VBOX_BIN list vms | gawk -F \" '{ print $2 }'`
        do
          arranque
        done
        show_mv_running
      ;;
      # Arranque del grupo de máquinas virtuales
      mvgroup)
        show_group
        verify_yn
        for MV in $MV_GROUP 
        do
          arranque
        done
        show_mv_running
      ;;
      # Arranque de una única máquina virtual
      *)
        PS3="Seleccióna una máquina virtual de las disponibles: "
        select MV in `$VBOX_BIN list vms | gawk -F \" '{ print $2 }'`
        do
          arranque
          show_mv_running
          exit
        done
      ;;
    esac
    ;;     

    # Parada de máquinas virtuales
    
    stop)
    # Valores posibles de stop
    # all: Todas las máquinas virtuales en funcionamiento 
    # mvgroup: lista de máquinas virtuales de MV_GROUP
    # Por defecto usa el nombre de la máquina virtual que le demos
    case "$2" in
      # Parada de todas las MV
      all)
        verify_yn
        for MV in `$VBOX_BIN list runningvms | gawk -F \" '{ print $2 }'`
        do
          parada
        done
        # Pausamos X sg para que de tiempo a que paren las máquinas
        # 30 sg por defecto.
        # Es posible que al pasar los 30 sg, todavia se muestren
        # algunas MV como ejecutandose, pero estarán parando.
        sleep 30
        show_mv_running
      ;;
      # Parada del grupo de máquinas virtuales
      mvgroup)
        show_group
        verify_yn
        for MV in $MV_GROUP 
        do
          parada
        done
        sleep 15
        show_mv_running
      ;;
      # Parada de una única máquina virtual
      *)
        PS3="Seleccióna una máquina virtual de las disponibles: "
        select MV in `$VBOX_BIN list runningvms | gawk -F \" '{ print $2 }'`
        do
        parada
        sleep 15
        show_mv_running
        exit
        done
      ;;
    esac
    ;;

    mvlist)
    case "$2" in
      # Muestra maquinas en funcionamiento
      run)
        show_mv_running
      ;;
      reg)
        show_mv_registered
      ;;
      group)
        show_group
      ;;
      *)
        echo "Valores posibles:"
        echo "* run (MV arrancadas)"
        echo "* reg (MV registradas)"
        echo "* group (Grupo de MVs actual)"
        echo ""
      ;;
    esac
    ;;

    helpme)
      help_onoffvbox
    ;;

    *)
      help_onoffvbox
    ;;
esac
Related Posts with Thumbnails