Desligando todas as VMs do VirtualBox (vagrant) em um comando bash fácil de usar (que pode ser colocado em um arquivo bash)

63

Eu uso vagrant para desenvolvimento. Eu esqueço de desligar algumas das VMs. Quando vou fazer logoff da minha máquina host, o processo de desligamento do Ubuntu parece travar.

Poderia haver uma maneira de roteirizar um close de todas as caixas vagabundas com um pouco de linha de comando? Algo como o seguinte, mas algo que, bem, funciona.

for f in $HOME/vagrant;
do;
  cd $f
  vagrant halt
done;
    
por Richard 29.04.2014 / 00:59

8 respostas

82

Para um controle com script de máquinas Virtual Box, podemos fazer uso do VBoxManage comandos:

  • Listar máquinas em execução (retorna o nome e o UUID):

    VBoxManage list runningvms
    
  • Pare de executar as VMs "hibernando" as mesmas (recomendadas para evitar a perda de dados)

    VBoxManage controlvm <name|uuid> savestate
    
  • Poweroff executando VMs (não recomendado porque podemos perder dados no convidado)

    VBoxManage controlvm <name|uuid> poweroff
    
  • Use ACPI em um sistema operacional convidado compatível com ACPI (preferível a poweroff para um desligamento normal dos convidados)

    VBoxManage controlvm <name|uuid> acpipowerbutton
    

Veja também: Como encerrar com segurança Convidado OS no VirtualBox usando a linha de comando

Atualização do OP

Com base nesta resposta correta selecionada abaixo, adicionei este script " $HOME/bin/stop-vagrant.sh ". Então agora eu tenho algo que pode seguramente iniciar uma parada de todas as VMs vagabundas que eu poderia ter ligado ainda em uma sessão.

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

Comando explicado:

vboxmanage list runningvms | - obtém uma lista de todos os vms em execução no VirtualBox

sed -r 's/.*\{(.*)\}//' | - retira a string para o número de identificação

xargs -L1 -I {} VBoxManage controlvm {} savestate - executa o comando salvar estado em cada caixa aberta.

Em xargs

  • -L1 - pegue uma linha de cada vez
  • -I {} - usa {} como espaço reservado para o próximo comando
por Takkat 29.04.2014 / 11:31
21

A outra resposta é ótima para lidar com o Virtualbox, mas o Vagrant possui seus próprios mecanismos para manipular máquinas virtuais, e como mencionado em um dos comentários, ele suporta mais do que apenas o VirtualBox, apenas VMWare no momento, mas quem sabe mais tarde !

Isso parece funcionar para mim:

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

Nota:

Isso funciona com versões do Vagrant após o 1.6, para versões mais antigas, você provavelmente deve atualizar, mas se você não conseguir, uma das outras opções que se concentram no Virtualbox pode ser melhor.

    
por ThomasRedstone 23.12.2014 / 15:35
9

Meu mecanismo para isso:

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

  • status global lista todas as caixas
  • filtra que para linhas contendo virtualbox (Filtra o texto de ajuda, será quebrado se você estiver usando outro provedor)
  • Filtre para exibir apenas os 9 primeiros caracteres (o ID exclusivo global)
  • Embora ainda possamos ler uma linha dessa entrada, leia-a como a variável $ line:
    • Imprima essa linha $
    • execute vagrant halt $line parando o vagrant para esse ID exclusivo global

Isso é melhor do que o método Virtualbox acima, porque ele também executará qualquer mecanismo de desligamento configurado pelo vagrant.

    
por Aquarion 03.05.2015 / 09:21
5

Caso outras pessoas cheguem a esta pergunta: Para quem usa o VirtualBox, ele já pode cuidar disso, só envolve editar um arquivo:

# 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

A vantagem é que não é necessário editar / criar qualquer logout ou init.d stript para executar os comandos postados nas outras respostas. A desvantagem é que esta solução é específica para o VirtualBox.

Testado no Ubuntu 14.10 com o VirtualBox 4.3.18.

Todo o crédito vai para este post .

    
por Armando Pérez Marqués 11.04.2015 / 19:54
3

Combinando algumas das outras respostas, isso fechará todas as caixas do vagabundo virtualbox:

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

Eu só uso vagrant halt . Se você executá-lo sem mais argumentos, ele parará todas as máquinas definidas no Vagrantfile .

    
por nomen 15.03.2016 / 04:42
1

Se você estiver escrevendo scripts para analisar os comandos do Vagrant, é aconselhável analisar a saída compatível com a máquina ( --machine-readable ), que é mais consistente.

O formato é:

timestamp,target,type,data...

para que você possa importá-lo como arquivo CSV, já que ele é separado por vírgula.

Com o shell, provavelmente é mais difícil analisá-lo, por exemplo:

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

Veja: Vagrant - Saída legível por máquina

No entanto, acho mais fácil analisar a saída padrão, por exemplo

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

Entre. Teoricamente, o comando vagrant deve aceitar uma expressão regular para a lista de VMs a serem suspensas de acordo com esta postagem , por exemplo:

vagrant suspend '*'

mas isso não funciona e há um bug # 7221 que está pendente para corrigi-lo .

Bilhetes relacionados ao GitHub:

por kenorb 08.04.2016 / 22:14
0

Isso pode ou não funcionar para você ;-) Funciona para mim

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
    
por brad parks 11.04.2018 / 20:23