Apagar todas las máquinas virtuales de VirtualBox (vagabundo) en un comando bash fácil de usar (que se puede poner en un archivo bash)

65

Utilizo vagabundo para el desarrollo. Olvidé cerrar algunas de las máquinas virtuales. Cuando salgo de la máquina host, el proceso de apagado de Ubuntu parece bloquearse.

¿Podría haber una manera de guiar el cierre de todas las cajas vagabundas con un poco de commandline-fu? Algo como lo siguiente, pero algo que, bueno, funciona.

for f in $HOME/vagrant;
do;
  cd $f
  vagrant halt
done;
    
pregunta Rick 29.04.2014 - 00:59

8 respuestas

82

Para un control de secuencias de comandos de máquinas de Virtual Box, podemos hacer uso del VBoxManage comandos:

  • Listar máquinas en ejecución (nombre de devoluciones y UUID):

    VBoxManage list runningvms
    
  • Deje de ejecutar máquinas virtuales "hibernando" (se recomienda para evitar la pérdida de datos)

    VBoxManage controlvm <name|uuid> savestate
    
  • Poweroff ejecuta VM (no se recomienda porque podemos perder datos en el invitado)

    VBoxManage controlvm <name|uuid> poweroff
    
  • Utilice ACPI en un sistema operativo invitado compatible con ACPI (preferiblemente en poweroff para el cierre ordenado de los invitados)

    VBoxManage controlvm <name|uuid> acpipowerbutton
    

Ver también: Cómo cerrar de manera segura SO invitado en VirtualBox usando la línea de comando

Actualización desde OP

Basándome en la respuesta correcta seleccionada a continuación, agregué este script bash " $HOME/bin/stop-vagrant.sh ". Así que ahora tengo algo que puede iniciar de forma segura una parada de todas las VM vagabundas que podría haber encendido y olvidado en una sesión.

vboxmanage list runningvms | sed -r 's/.*\{(.*)\}//' | xargs -L1 -I {} VBoxManage controlvm {} savestate

Explicación del comando:

vboxmanage list runningvms | - obtiene una lista de todos los vms en ejecución en VirtualBox

sed -r 's/.*\{(.*)\}//' | - quita la cadena al número de identificación

xargs -L1 -I {} VBoxManage controlvm {} savestate - ejecuta el comando guardar estado en cada cuadro que está abierto.

En xargs

  • -L1 - toma una línea a la vez
  • -I {} - usa {} como marcador de posición para el próximo comando
respondido por el Takkat 29.04.2014 - 11:31
21

La otra respuesta es excelente para manejar Virtualbox, pero Vagrant presenta sus propios mecanismos para manejar Máquinas Virtuales, y como se mencionó en uno de los comentarios, es compatible con algo más que VirtualBox, solo VMWare en este momento, pero quién sabe más tarde !

Esto parece funcionar para mí:

vagrant global-status | awk '/running/{print }' | xargs -r -d '\n' -n 1 -- vagrant suspend

Nota:

Esto funciona con versiones de Vagrant posteriores a la 1.6, para versiones anteriores, probablemente debería actualizar, pero si no puede, una de las otras opciones que se enfoca en Virtualbox puede ser mejor.

    
respondido por el ThomasRedstone 23.12.2014 - 15:35
9

Mi mecanismo para esto:

vagrant global-status | grep virtualbox | cut -c 1-9 | while read line; do echo $line; vagrant halt $line; done;

  • estado global enumera todos los cuadros
  • filtra eso para las líneas que contienen virtualbox (elimina el texto de la ayuda, se romperá si estás usando otro proveedor)
  • Filtra eso para que se muestren solo los primeros 9 caracteres (la ID única global)
  • Si bien aún podemos leer una línea de esa entrada, léala como la variable $ line y luego:
    • Imprime esa línea $
    • ejecuta vagrant halt $line deteniendo el vagabundo para esa ID única global

Esto es mejor que el método de Virtualbox anterior, porque también ejecutará cualquier mecanismo de apagado configurado por vagabundo.

    
respondido por el Aquarion 03.05.2015 - 09:21
5

En caso de que otras personas lleguen a esta pregunta: Para aquellos que usan VirtualBox, ya pueden encargarse de esto, solo implica editar un archivo:

# Contents of /etc/default/virtualbox
# ...
# ...
# SHUTDOWN_USERS="foo bar"  
#   check for running VMs of user 'foo' and user 'bar'
#   'all' checks for all active users
# SHUTDOWN=poweroff
# SHUTDOWN=acpibutton
# SHUTDOWN=savestate
#   select one of these shutdown methods for running VMs
#   acpibutton and savestate causes the init script to wait
#   30 seconds for the VMs to shutdown

## My original values
# SHUTDOWN_USERS=""
# SHUTDOWN=poweroff

## My current values
SHUTDOWN_USERS="all"
SHUTDOWN=savestate

Lo bueno es que no es necesario editar / crear ningún cierre de sesión o init.d stript para ejecutar los comandos publicados en las otras respuestas. El inconveniente es que esta solución es específica de VirtualBox.

Probado en Ubuntu 14.10 con VirtualBox 4.3.18.

Todo el crédito va a esta publicación .

    
respondido por el Armando Pérez Marqués 11.04.2015 - 19:54
3

Combinando algunas de las otras respuestas, esto cerrará todos los cuadros vagabundos virtuales en ejecución:

vagrant global-status | awk '/virtualbox running/{ print  }' | xargs vagrant halt
    
respondido por el Ryan 15.03.2016 - 15:51
2

Solo uso vagrant halt . Si lo ejecuta sin otro argumento, detiene todas las máquinas definidas en Vagrantfile .

    
respondido por el nomen 15.03.2016 - 04:42
1

Si está escribiendo scripts para analizar comandos Vagrant, se recomienda analizar la salida compatible con la máquina ( --machine-readable ), que es más consistente.

El formato es:

timestamp,target,type,data...

para que pueda importarlo como archivo CSV, ya que está separado por comas.

Con shell, probablemente sea más difícil de analizar, por ejemplo:

for id in $(vagrant global-status --machine-readable | cut -d, -f5 | grep -B3 running | egrep -o "[0-9a-f]{7}"); do
    vagrant suspend $id;
done

Ver: Vagrant: salida legible por máquina

Sin embargo, me resulta más fácil analizar el resultado estándar, por ejemplo,

while read id name provider state path; do
  [ "$state" = "running" ] && vagrant suspend $id;
done < <(vagrant global-status)

Por cierto. Teóricamente, el comando vagrant debería aceptar una expresión regular para que la lista de máquinas virtuales se suspenda según esta GH publicación , por ejemplo:

vagrant suspend '*'

pero no funciona y hay un error # 7221 que está pendiente para solucionarlo .

Boletos relacionados de GitHub:

respondido por el kenorb 08.04.2016 - 22:14
0

Esto puede funcionar o no para usted ;-) Funciona para mí

vagrant_halt_all.sh

#!/usr/bin/env bash
if [ -z "" ]
then
  OPTS=""
else
  # force close if any arg passed
  OPTS="-f"
fi

for i in $(vagrant global-status | grep running | awk '{print }'); do 
  DIR=$(vagrant global-status | grep running | awk '{print }')
  cd "$DIR";
  OUT=$(vagrant halt);
  echo "attempted to halt $i: $OUT"
done
    
respondido por el brad parks 11.04.2018 - 20:23

Lea otras preguntas en las etiquetas