J'ai besoin d'exécuter un système logiciel destiné à être installé en tant qu'appliance sur une machine dédiée. Afin d'économiser de l'énergie, je prévois d'exécuter le système sur une VirtualBox VM à la place.
L'hôte est une boîte Linux standard avec un système SysV-Init, l'invité est un Linux fortement modifié et je préférerais ne pas avoir à le modifier davantage. VirtualBox est utilisé dans la version OSE.
J'ai déjà compris comment démarrer le VM lorsque l'hôte démarre (Edit: cela se fait, comme Nikhil l'a mentionné ci-dessous, via la commande VBoxManager startvm
), mais comment puis-je éteindre gracieusement la machine virtuelle? Tout script exécuté sur l'hôte devra attendre jusqu'à ce que l'invité se soit complètement arrêté.
Quelqu'un peut-il suggérer, par exemple, à quoi devrait ressembler un fichier de service faisant cela?
Avez-vous essayé acpipowerbutton
à partir de cet ensemble de commandes?
VBoxManage controlvm <uuid>|<name>
pause|resume|reset|poweroff|savestate|
acpipowerbutton|acpisleepbutton|
Modifier après avoir lu les commentaires:
Vous pouvez utiliser acpid
ou d'autres utilitaires acpi pour le rendre gracieux. Pouvez-vous également fournir plus d'informations sur la façon dont vous arrêtez la machine en ce moment?
Plain shutdown
n'attendrait pas les travaux inachevés, un délai peut être trop long.
Je suppose que vous n'utilisez pas de gestionnaire de fenêtres, essayez donc l'outil this .
Vient de voir ce démon . Vous pourriez trouver cela utile.
Plutôt que de coder cela vous-même, pensez à utiliser Vagrant , qui est conçu pour instancier et contrôler les instances de virtualbox. La documentation est excellente et je vous suggère de la consulter plutôt que d'essayer de lancer la vôtre.
Le long et le court de celui-ci est que vous créez un fichier de contrôle simple, puis exécutez vagrant up
pour démarrer autant d'instances VirtualBox que vous le souhaitez. Vous pouvez utiliser vagrant ssh
pour vous connecter aux hôtes et vagrant halt
pour arrêter l'hôte (sans terminer). vagrant destroy
supprimera les instances.
Il prend en charge l'approvisionnement avec marionnette, Ansible ou Chef et vous permet de contrôler la plupart des paramètres de configuration VBox exposés.
J'ai une application similaire à vous, à une différence près: je dois redémarrer le système et récupérer à partir d'un instantané.
Ce qui vous intéresse, c'est le mode sans tête .
J'ai quelques-uns de ces services, j'utilise donc le script suivant:
VBox_StopRestoreStart.sh
#!/bin/bash
if [ -z "$1" ]; then
echo "Usage: $0 VMNAME_or_UUID"
exit 1
fi
set -x
VBoxManage controlvm "$1" poweroff #enforce turnoff
VBoxManage snapshot "$1" restorecurrent #retore state
VBoxManage showvminfo "$1" | grep State #display state to ensure
VBoxHeadless -s "$1" #run in headless mode in background
comment puis-je éteindre gracieusement la machine virtuelle?
SI vous souhaitez désactiver VM gracieusement, vous avez deux options, selon votre application:
VBoxManage controlvm <uuid>|<VMname> acpipowerbutton
VBoxManage controlvm <uuid>|<VMname> acpisleepbutton
VBoxManage controlvm <uuid>|<VMname> savestate
CONSEILS: Vous pourriez trouver utile:
VBoxManage list vms
- liste des vms disponiblesrdesktop IP-ADDR:3389
ou rdesktop-vrdp IP-ADDR:3389
- lorsque vous souhaitez une interface graphique (même à distance ) lorsque vous exécutez en mode sans tête: VBoxHeadless -s <uuid>|<VMname>
VBoxManage startvm
- commencez par l'interface graphique pour le débogage localChapitre du manuel VirtualBox associé: Chapitre 7. Machines virtuelles distantes - Étape par étape: création d'une machine virtuelle sur un serveur sans tête
P.S. Si vous êtes intéressé par des solutions complètes déjà mises en œuvre, OpenStack semble un choix intéressant.
En regardant VirtualBox VM sur http://www.virtualbox.org/manual/ch08.html
Pour répertorier les machines virtuelles, utilisez la commande VBoxManage list vms
Pour démarrer la VM, utilisez la commande VBoxManage startvm
http://www.virtualbox.org/manual/ch08.html#vboxmanage-controlvm
Pour contrôler VM, utilisez VBoxManage controlvm
La sous-commande controlvm
vous permet de modifier l'état d'une machine virtuelle en cours d'exécution. Les éléments suivants peuvent être spécifiés:
VBoxManage controlvm <vm> pause
met temporairement une machine virtuelle en attente, sans changer définitivement son état. La fenêtre VM sera peinte en gris pour indiquer que le VM est actuellement en pause. (Cela équivaut à sélectionner l'élément "Pause" dans la "Machine"). "menu de l'interface graphique.)
Utilisation VBoxManage controlvm <vm> resume
pour annuler une commande de pause précédente. (Cela revient à sélectionner l'élément "Reprendre" dans le menu "Machine" de l'interface graphique.)
VBoxManage controlvm <vm> reset
a le même effet sur une machine virtuelle que d'appuyer sur le bouton "Réinitialiser" sur un ordinateur réel: un redémarrage à froid de la machine virtuelle, qui redémarrera et redémarrera immédiatement le système d'exploitation invité. L'état du VM n'est pas enregistré au préalable et des données peuvent être perdues. (Cela revient à sélectionner l'élément "Réinitialiser" dans le menu "Machine" de l'interface graphique).)
VBoxManage controlvm <vm> poweroff
a le même effet sur une machine virtuelle que de tirer le câble d'alimentation sur un ordinateur réel. Encore une fois, l'état du VM n'est pas enregistré au préalable et des données peuvent être perdues. (Cela revient à sélectionner l'élément "Fermer" dans le menu "Machine" de l'interface graphique ou à appuyer sur la le bouton de fermeture de la fenêtre, puis en sélectionnant "Éteindre la machine" dans la boîte de dialogue.)
Après cela, l'état de la machine virtuelle sera "Éteint".
Pour un système basé sur systemd, vous pouvez essayer ceci.
[Unit]
Description=VBox Virtual Machine %i Service
Requires=systemd-modules-load.service
After=systemd-modules-load.service
[Service]
User=user
Group=vboxusers
ExecStart=/usr/bin/VBoxHeadless -s %i
ExecStop=/usr/bin/VBoxManage controlvm %i savestate
[Install]
WantedBy=multi-user.target
$ Sudo systemctl enable vboxvmservice@vm_name.service
Que diriez-vous d'envoyer la commande via ssh de l'hôte à l'invité?
Je ne sais pas si cela fonctionne et si vous pouvez vérifier l'état de la machine par la suite ou obtenir quelque chose comme un état de sortie, mais cela devrait au moins être net.
Pour démarrer vm:
VBoxManage startvm VMNAME --type headless
Pour arrêter vm:
VBoxManage controlvm VMNAME savestate
Liste de tous les VM en cours d'exécution:
VBoxManage list runningvms
Ma solution: dans ce shellscript, "root" est l'invocateur et "theuser" est le propriétaire de "thevm"
Je sais que les vms sont terminées lorsque la sortie de la commande VBoxManage list runningvms
renvoie une chaîne vide.
...
start(){
su -c "VBoxHeadless --startvm thevm" -s /bin/bash theuser &
# maybe another vbox command
}
stop(){
su -c "VBoxManage controlvm thevm acpipowerbutton" -s /bin/bash theuser
# maybe another vbox command
while [ "`su -c 'VBoxManage list runningvms' -s /bin/bash theuser`" != "" ]
do
echo waiting for VMs to shutdown
sleep 3
done
}
...
Pourquoi ne vous connectez-vous pas à votre invité et arrêtez-vous à partir de là?
À moins que vous n'ayez une bonne raison de ne pas installer sshd et d'accéder à VM vraiment via VBox, je choisirais un script qui émet simplement un ssh shutdown -h now
. Pour être honnête, je créerais un script pour chaque machine qui l'arrêterait correctement et effectuerais des vérifications sur place.
Emballez simplement un script /etc/init.d/shutdown_vm qui appelle l'autre depuis l'hôte, l'appel se bloquera jusqu'à ce qu'il soit prêt. Ce processus (comme décrit) ajoute une dépendance Linux sur l'invité mais supprime la dépendance VBox sur l'hôte.
Pour aller plus loin: vous n'avez pas besoin d'accéder à VBox pour arrêter une machine, si vous avez un moyen d'y accéder (c'est-à-dire ssh), le système d'exploitation aura toujours un moyen pour cela (l'activer, c'est différent bien sûr)
Peut-être que cela aidera dans le cadre de la solution.
VBoxManage list runningvms | tr -s '\" {' '%{' | cut -d '%' -f3 | while read uuid; do
VBoxManage controlvm $uuid savestate;
done