Arrestare tutte le VM VirtualBox (vagrant) in un unico comando bash di facile utilizzo (che può essere inserito in un file bash)


70

Uso il vagabondo per lo sviluppo. Ho dimenticato di spegnere alcune VM. Quando esco per disconnettermi dalla mia macchina host, il processo di spegnimento di Ubuntu sembra bloccarsi.

Potrebbe esserci un modo per scrivere una chiusura di tutte le scatole vagabonde con un po 'di commandline-fu? Qualcosa come il seguente, ma qualcosa che, beh, funziona.

for f in $HOME/vagrant;
do;
  cd $f
  vagrant halt
done;

Non conosco il vagabondo ma sembra essere collegato a VMWare, non a VirtualBox. Stai effettivamente usando VirtualBox?
terdon

@terdon: Vagrant inizialmente supportava solo Vbox. Penso che ora supportino altri tipi di formati VM (capire VMWare)
Sylvain Pineau,

@SylvainPineau ah, OK. Ho appena dato un'occhiata alla loro pagina web e ho visto un link "Integrazione VMWare" e ho ipotizzato. Grazie per il chiarimento.
terdon

1
Darei un'occhiata a questo script . Il post completo del blog è qui . Non testato
Sylvain Pineau,

Richard, per favore, non modificare la risposta alla tua domanda. Sei libero di rispondere alla tua domanda in una risposta separata. Ti ho dato un voto per una buona domanda.
don.joey,

Risposte:


91

Per un controllo tramite script delle macchine Virtual Box possiamo utilizzare i comandi VBoxManage :

  • Elenco macchine in esecuzione (restituisce nome e UUID):

    VBoxManage list runningvms
    
  • Interrompere l'esecuzione di macchine virtuali "ibernandole" (consigliato per evitare la perdita di dati)

    VBoxManage controlvm <name|uuid> savestate
    
  • Spegnimento con VM in esecuzione (sconsigliato perché potremmo perdere i dati nel guest)

    VBoxManage controlvm <name|uuid> poweroff
    
  • Utilizzare ACPI in un sistema operativo guest compatibile con ACPI (preferibile poweroffper l'arresto regolare degli ospiti)

    VBoxManage controlvm <name|uuid> acpipowerbutton
    

Vedi anche: Come arrestare in modo sicuro il SO guest in VirtualBox usando la riga di comando

Aggiornamento dall'OP

Sulla base di questa risposta corretta selezionata di seguito, ho aggiunto questo script bash " $HOME/bin/stop-vagrant.sh". Quindi ora ho qualcosa che può tranquillamente iniziare una fermata di tutte le macchine virtuali vaghe che avrei potuto accendere ma che avevo dimenticato in una sessione.

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

Spiegazione del comando:

vboxmanage list runningvms | - ottiene un elenco di tutti i vms in esecuzione in VirtualBox

sed -r 's/.*\{(.*)\}/\1/' | - riduce la stringa al numero ID

xargs -L1 -I {} VBoxManage controlvm {} savestate - esegue il comando save state su ogni casella aperta.

Sopra xargs

  • -L1 - prendi una riga alla volta
  • -I {} - usa {} come segnaposto per il comando successivo

Whoo Hoo! Dato il consiglio di cui sopra, questa riga di comando funziona in modo magico: elenco vboxmanage runningvms | sed -r 's /.* \ {(. *) \} / \ 1 /' | xargs -L1 -I {} VBoxManage controlvm {} savestate
Rick

1
Nota, l' -ropzione è unica per GNU Sed.
George V. Reilly,

Il miglior one-liner magico che abbia mai visto! Buon lavoro! : D
tftd,

1
Su OSX / macOS, dovrai usare -Einvece di -r. È la bandiera per l'utilizzo di espressioni regolari estese.
JayD3e

22

L'altra risposta è ottima per la gestione di Virtualbox, ma Vagrant presenta i propri meccanismi per la gestione di macchine virtuali e, come è stato menzionato in uno dei commenti, supporta più di VirtualBox, solo VMWare al momento, ma chi lo sa dopo!

Questo sembra funzionare per me:

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

Nota:

Funziona con le versioni di Vagrant successive alla 1.6, per le versioni precedenti, probabilmente dovresti aggiornare, ma se non puoi, una delle altre opzioni che si concentra su Virtualbox potrebbe essere migliore.


4
questa è ovviamente una risposta molto corretta (tm). @Richard dovrebbe prendere in considerazione l'
idea di

Il global-statuscomando è stato introdotto in Vagrant 1.6 . Gli utenti delle versioni precedenti di Vagrant, in particolare quelli che lo hanno installato tramite apt-gete potrebbero essere ancora su 1.4.3, dovranno aggiornare la loro installazione di Vagrant prima di poter utilizzare questo comando.
Curtis Gibby,

1
BSD xargsnon supporta -r, quindi è possibile installare gxargstramite brewe utilizzarlo invece.
Kenorb,

11

Il mio meccanismo per questo:

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

  • stato globale elenca tutte le caselle
  • filtralo per le righe contenenti virtualbox( filtra il testo di aiuto, si interromperà se stai usando un altro provider)
  • Filtra questo per visualizzare solo i primi 9 caratteri (l'ID univoco globale)
  • Mentre possiamo ancora leggere una riga da quell'input, leggila come variabile $ line quindi:
    • Stampa quella linea $
    • corri vagrant halt $linefermando il vagabondo per quell'ID univoco globale

Questo è meglio del metodo Virtualbox sopra, perché eseguirà anche qualsiasi meccanismo di spegnimento configurato da Vagrant.


3
Questo comando funziona anche per host OS X. Altri falliscono a causa delle differenze nella gestione degli argomenti della riga di comando tra le versioni OSX e Linux di sede awk. Grazie!
Andrew Андрей Листочкин,

@ AndrewАндрейЛисточкин Conferma: funziona bene su OS X 10. Non testato su altri sistemi operativi, sebbene.
setevoy

2
Il comando precedente tenta di arrestare tutte le caselle, indipendentemente dal fatto che siano in esecuzione o meno, impiegando così molto tempo per l'esecuzione. Per quanto mi riguarda, poiché utilizzo solo virtualbox, ho modificato il grep "virtualbox" in "running", per ottenere solo quelli in esecuzione.
Alex2php,

Questa è una buona risposta, ma ti potrebbe piacere usare vagrant suspendinvece di vagrant haltsalvare lo stato e sospenderlo per un più veloce su e giù.
David Thomas,

Vero, e se funziona per te è fantastico. Ho avuto enormi problemi di cronometraggio con VM sospese in Virtualbox, quindi non lo consiglierei.
Aquarion,

5

Nel caso in cui altre persone arrivino a questa domanda: per coloro che usano VirtualBox, può già occuparsene, comporta solo la modifica di un file:

# 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

Il lato positivo è che non è necessario modificare / creare alcun logout o init.dstript per eseguire i comandi pubblicati nelle altre risposte. L'aspetto negativo è che questa soluzione è specifica per VirtualBox.

Testato su Ubuntu 14.10 con VirtualBox 4.3.18.

Tutto il merito va a questo post .


5

Combinando alcune delle altre risposte, questo chiuderà tutte le caselle vagabonde di virtualbox in esecuzione:

vagrant global-status | awk '/virtualbox running/{ print $1 }' | xargs vagrant halt

Questo ha funzionato per me!
Dayron Gallardo,

3

Io uso solo vagrant halt. Se lo esegui senza un ulteriore argomento, arresta tutte le macchine definite in Vagrantfile.


1

Se stai scrivendo script per analizzare i comandi di Vagrant, è consigliabile analizzare l'output ( --machine-readable) più intuitivo.

Il formato è:

timestamp,target,type,data...

quindi puoi importarlo come file CSV, poiché è separato da virgola.

Con shell, è probabilmente più difficile analizzare, ad esempio:

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

Vedi: Vagrant - Output leggibile dalla macchina


Tuttavia, trovo più facile analizzare l'output standard, ad es

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

Btw. Teoricamente il vagrantcomando dovrebbe accettare un'espressione regolare per l'elenco delle macchine virtuali da sospendere secondo questo post GH , ad esempio:

vagrant suspend '*'

ma non funziona e c'è un bug # 7221 che è in sospeso per risolverlo.


Biglietti GitHub correlati:


0

Questo può o meno funzionare per te ;-) Funziona per me

vagrant_halt_all.sh

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

for i in $(vagrant global-status | grep running | awk '{print $1}'); do 
  DIR=$(vagrant global-status | grep running | awk '{print $5}')
  cd "$DIR";
  OUT=$(vagrant halt);
  echo "attempted to halt $i: $OUT"
done
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.