web-dev-qa-db-fra.com

Arrêter toutes les machines virtuelles VirtualBox (vagabond) en une seule commande bash facile à utiliser (pouvant être placée dans un fichier bash)

J'utilise vagrant pour le développement. J'ai oublié de fermer quelques machines virtuelles. Lorsque je vais me déconnecter de mon ordinateur hôte, le processus d'arrêt d'Ubuntu semble se bloquer.

Pourrait-il y avoir un moyen de script une fermeture de toutes les boîtes vagabond avec un peu de commandline-fu? Quelque chose comme ce qui suit, mais quelque chose qui fonctionne bien.

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

Pour un contrôle scriptable des machines Virtual Box, nous pouvons utiliser les commandes VBoxManage:

  • Liste des machines en cours d’exécution (retourne le nom et l’UUID):

    VBoxManage list runningvms
    
  • Arrêtez les machines virtuelles en les "hibernant" (recommandé pour éviter la perte de données)

    VBoxManage controlvm <name|uuid> savestate
    
  • Mise hors tension de machines virtuelles en cours d'exécution (non recommandé car nous risquons de perdre des données dans l'invité)

    VBoxManage controlvm <name|uuid> poweroff
    
  • Utiliser ACPI dans un système d'exploitation invité prenant en compte l'ACPI (préférable à poweroff pour un arrêt en douceur des invités)

    VBoxManage controlvm <name|uuid> acpipowerbutton
    

Voir aussi: Comment arrêter en toute sécurité le système d'exploitation invité dans VirtualBox à l'aide de la ligne de commande

Mise à jour de l'OP

Sur la base de cette réponse correcte sélectionnée ci-dessous, j'ai ajouté ce script bash "$HOME/bin/stop-vagrant.sh". Alors maintenant, j'ai quelque chose qui peut commencer en toute sécurité un arrêt de toutes les machines virtuelles vagabondes que j'ai peut-être allumées mais que j'avais oubliées dans une session.

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

Commande expliquée:

vboxmanage list runningvms | - obtient une liste de tous les vms en cours d'exécution sous VirtualBox

sed -r 's/.*\{(.*)\}/\1/' | - enlève la chaîne au numéro d'identification

xargs -L1 -I {} VBoxManage controlvm {} savestate - exécute la commande save state sur chaque boîte ouverte.

Sur xargs

  • -L1 - prend une ligne à la fois
  • -I {} - utilise {} comme espace réservé pour la commande suivante
87
Takkat

L'autre solution est intéressante pour la gestion de Virtualbox, mais Vagrant dispose de ses propres mécanismes de gestion des machines virtuelles et, comme mentionné dans l'un des commentaires, il prend en charge plus que VirtualBox, juste VMWare pour le moment, mais qui sait plus tard!

Cela semble fonctionner pour moi:

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

Note:

Cela fonctionne avec les versions de Vagrant après la version 1.6; pour les versions plus anciennes, vous devriez probablement mettre à niveau, mais si vous ne pouvez pas, une des autres options qui se concentrent sur Virtualbox peut être meilleure.

21
ThomasRedstone

Mon mécanisme pour cela:

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

  • état global liste toutes les cases
  • filtre cela pour les lignes contenant virtualbox (le texte d'aide est filtré, il sera cassé si vous utilisez un autre fournisseur)
  • Filtrez-le pour n’afficher que les 9 premiers caractères (l’ID unique global)
  • Bien que nous puissions toujours lire une ligne à partir de cette entrée, lisez-la comme la variable $ line puis:
    • Imprimer cette ligne $
    • lancez vagrant halt $line en arrêtant le vagabond pour cet ID unique global

C'est mieux que la méthode Virtualbox ci-dessus, car elle exécutera également tous les mécanismes d'arrêt configurés de manière vagabonde.

10
Aquarion

Au cas où d'autres personnes en arriveraient à cette question: pour ceux qui utilisent VirtualBox, cela peut déjà résoudre le problème, il suffit d'éditer un fichier:

# 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

L'avantage est qu'il n'est pas nécessaire de modifier/créer une déconnexion ou init.d stript pour exécuter les commandes publiées dans les autres réponses. L'inconvénient est que cette solution est spécifique à VirtualBox.

Testé sur Ubuntu 14.10 avec VirtualBox 4.3.18.

Tout le crédit va à ce post .

En combinant certaines des autres réponses, toutes les boîtes virtuelles virtualbox en cours d'exécution seront fermées:

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

Je viens d'utiliser vagrant halt. Si vous l'exécutez sans autre argument, il arrête toutes les machines définies dans Vagrantfilename__.

3
nomen

Si vous écrivez des scripts pour analyser les commandes Vagrant, il est conseillé d’analyser la sortie conviviale pour la machine (--machine-readable), qui est plus cohérente.

Le format est:

timestamp,target,type,data...

vous pouvez donc l'importer en tant que fichier CSV, car il est séparé par des virgules.

Avec Shell, il est probablement plus difficile d'analyser, par exemple:

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

Voir: Vagrant - Sortie lisible par machine


Cependant, je trouve plus facile d'analyser la sortie standard, par exemple.

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

Btw. Théoriquement, la commande vagrantdevrait accepter une expression régulière pour la liste des machines virtuelles à suspendre conformément à ce GH post , par exemple:

vagrant suspend '*'

mais cela ne fonctionne pas et il y a un bug # 7221 qui est en suspens afin de le réparer.


Billets GitHub associés:

1
kenorb

Cela peut ou peut ne pas fonctionner pour vous ;-) Fonctionne pour moi

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
0
brad parks