Virtualbox Windows arrêt progressif des invités lors de l'arrêt de l'hôte

19

J'essaie de trouver une solution pour arrêter gracieusement toutes les machines virtuelles invitées fonctionnant sous VirtualBox Windows lorsque l'ordinateur hôte est arrêté ou redémarré.

Il semble que l'option la plus sûre serait de déclencher la commande "save state" lorsque l'hôte commence à s'arrêter, mais il n'est pas clair si l'hôte attendra assez longtemps pour que les VM finissent d'enregistrer l'état et s'éteignent.

Quelqu'un at-il une solution robuste pour ce problème (apparemment basique)?

Matt Jenkins
la source
Installer les ajouts d'invités? Cela ne fournit-il pas les fonctionnalités requises?
Canadian Luke REINSTATE MONICA
@CanadianLuke Ce n'est pas le cas. :)
Matt Jenkins

Réponses:

6

J'ai eu un problème similaire et je l'ai résolu en exécutant VirtualBox en tant que service:

http://vboxvmservice.sourceforge.net/

Avec VBoxVMService, vous pouvez choisir la façon dont vous souhaitez que la machine s'arrête (enregistrement de l'état, mise hors tension) et démarre. Puisqu'il fonctionne en tant que service, Windows attendra automatiquement son arrêt, pendant le processus d'arrêt du système.

Bill Westrup
la source
Le processus de configuration n'est pas si automatique sous Windows 10. Je dois me référer au dépannage pour voir ce qui ne va pas. Cependant, après une configuration correcte, ce logiciel fait exactement ce dont j'ai besoin. Merci pour votre excellent travail.
iuradz
3

Malheureusement, cela ne semble pas possible pour les machines virtuelles démarrées via l'interface graphique de VirtualBox. Même si l'interface graphique peut intercepter l'événement d'arrêt de l'hôte et réagir, le service VirtualBox est arrêté: https://forums.virtualbox.org/viewtopic.php?p=278668#p278668

Si vous n'avez pas besoin d'une console graphique, VBoxHeadlessTray ou VBoxVMService pourrait être le chemin à parcourir. Les deux prennent en charge l'enregistrement et la reprise automatiques lors de l'arrêt et du redémarrage de l'hôte Windows.

VirtualBox 5.0 introduit un mode de démarrage "UI détachable" . Ce mode démarre une machine virtuelle sans tête avec un processus d'interface utilisateur distinct. Les performances graphiques en souffrent cependant et l'accélération 3D n'est pas encore prise en charge. Mais peut - être cela peut être combiné avec VBoxHeadlessTray à l'avenir (VBoxHeadlessTray ne supporte pas encore 5.0.) Liens vers dépôt VBoxHeadlessTray GitHub et à la correspondante demande de tirage GitHub pour ajouter le support VirtualBox 5 .

Edit: VBoxVmService ne prend pas non plus en charge le nouveau mode détachable à partir de la version 5.0. Seulement sans tête jusqu'à présent. J'ai ajouté une demande de fonctionnalité pour cela.

Leo B
la source
Comme je ne suis pas autorisé à porter plus de deux liens par publication, voici les liens vers VBoxHeadlessTray et vers la requête pull GitHub correspondante pour ajouter le support de VirtualBox 5.
Leo B
Je ne rencontre pas les problèmes décrits dans le fil. Voir ma réponse sur ce sujet. Je peux exécuter l'arrêt de l'hôte Windows et m'en aller. L'arrêt se bloque jusqu'à ce que toutes mes machines virtuelles soient fermées, et j'ai modifié l'action par défaut pour effectuer un arrêt propre ou un état de sauvegarde.
Kris Bahnsen
2

J'ai 3 scripts batch que j'utilise à la place des boutons d'alimentation du menu Démarrer.

do_shutdown.bat (arrêt du PC avec une période d'attente de 10 secondes, non pas pour donner 10 secondes au VM pour enregistrer l'état, mais pour me permettre d'annuler l'arrêt dans les 10 secondes. Le compte à rebours commence après l'arrêt des VM)

"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Server" savestate
"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Minimal" savestate
shutdown /s /t 10

do_reboot.bat (redémarre immédiatement après l'arrêt du VM)

"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Server" savestate
"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Minimal" savestate
shutdown /r /t 0

do_cancel.bat (me permet d'annuler l'arrêt du PC dans la période d'attente de 10 secondes. Il redémarre ensuite les vm, car ils ont été arrêtés avec le do_shutdown.bat)

shutdown /a
C:\VirtualBox\VBoxManage.exe startvm "Ubuntu Minimal" --type headless
C:\VirtualBox\VBoxManage.exe startvm "Ubuntu Server" --type headless

Au lieu de savestatevous, vous pouvez également utiliser l'un des éléments suivants

poweroff        - pulls the plug
                  (probably not a good idea...)

acpipowerbutton - presses the power off button for a clean shutdown
                  ("The system is going down for power off NOW!" to all consoles)

acpisleepbutton - tells the os to go to sleep
                  (probably just as bad as poweroff)
Daniel F
la source
1
Merci, c'est intéressant. Malheureusement, il existe d'autres scénarios d'arrêt / redémarrage non manuels que je dois également gérer. Par exemple, les redémarrages planifiés par Windows Update ou les événements de mise hors / hors tension de la batterie faible.
Matt Jenkins
1
Ah d'accord. Il y a aussi l' éditeur de stratégie de groupe avec les « Scripts (démarrage / arrêt) » section lifehacker.com/... J'utilise celui - là pour une commande très courte à l' arrêt (un appel boucle), donc je ne sais pas comment il se comporte sur des scripts qui prennent un certain temps à terminer.
Daniel F
2

Désolé, je suis en retard à la fête. Il y a une réponse exacte à cela, bien qu'elle nécessite une commande-foo. Voir cet article de discussion pour plus d'informations: https://forums.virtualbox.org/viewtopic.php?f=6&t=53684#p285540

La commande que vous recherchez est:

"C: \ Program Files \ Oracle \ VirtualBox \ VBoxManage.exe" setextradata GUI "VM NAME" / DefaultCloseAction Shutdown

C'est ce que j'utilise sur plusieurs machines virtuelles, fermez la fenêtre et il démarre automatiquement un arrêt sûr. Arrêtez Windows et dans sa tentative de tout fermer, il attendra la fin de ces processus.

Kris Bahnsen
la source
1

J'avais une question similaire et j'ai trouvé cette page. Je ne veux pas exécuter VirtualBox en tant que service, car j'ai beaucoup de machines virtuelles à tester, et j'en choisis généralement différentes à exécuter dans l'interface utilisateur de VirtualBox. Lorsque j'arrête mon ordinateur, il est ennuyeux de sauvegarder manuellement l'état de chaque machine virtuelle. L'utilisation de scripts pour enregistrer toutes les machines virtuelles en cours d'exécution semble être une solution pratique dans ce cas. Pour rendre la réponse de Daniel F plus générale, j'ai écrit ces scripts qui enregistrent automatiquement l'état de toutes les machines virtuelles en cours d'exécution sans les nommer explicitement.

saveRunningVMs.bat pour Windows:

set VBoxManageEXE="%ProgramFiles%\Oracle\VirtualBox\VBoxManage.exe"
set ListRunningVMS=%VboxManageEXE% list runningvms
for /f tokens^=2^,4^ delims^=^" %%p in ('%ListRunningVMS%') do %VBoxManageEXE% controlvm %%p savestate

echo all vms saved, you can shutdown now.

rem shutdown /s /t 10

saveRunningVMs.sh pour Linux:

#!/bin/bash
vboxmanage list runningvms | while read line; do
  #echo "VBoxManage controlvm $uuid savestate;"
  echo $line
  if [[ $line =~ \{(.*)\} ]]
  then
    vboxmanage controlvm ${BASH_REMATCH[1]} savestate
  fi
done
Karl Wolfram
la source
0

J'ai créé un script python qui suspendrait toutes les machines virtuelles VirtualBox en cours d'exécution, puis j'ai configuré le système pour exécuter le script à la déconnexion en tant que tâche planifiée.

Je ne sais pas à quel point cette méthode est fiable. Comme d'autres l'ont fait remarquer il y a des limites à la durée pendant laquelle le système attendra qu'une tâche Winlogon 7002 se termine. Mais personnellement, je n'ai eu aucun problème à ce qu'il donne des états de sauvegarde utilisables même avec plusieurs machines virtuelles en cours d'exécution sur 4+ Go de RAM de machine virtuelle globale.

Voici les étapes pour le configurer:

  1. Téléchargez et installez Python 2.7.x à partir de python.org
  2. Créez le fichier de script python quelque part sur votre système à l'aide du Bloc-notes ou de tout autre éditeur de texte brut (voir ci-dessous)
  3. Ouvrir le planificateur de tâches
  4. Choisissez Action -> Créer une tâche de base ... et utilisez l'assistant pour créer une tâche avec les paramètres suivants
    • Un nom de votre choix
    • Lancer la tâche lorsqu'un événement spécifique est enregistré
    • Journal: système
    • Source: Winlogon
    • ID d'événement: 7002
    • Démarrer un programme
    • À côté de Program / Script , entrez le chemin d'accès complet à votre python.exe, par exemplec:\Python27\python.exe
    • À côté de Ajouter des arguments , entrez le chemin complet où vous placez le fichier de script python, par exemple, je mets le mien dans un sous-dossier de mon dossier de documents, c'est doncC:\Users\rakslice\Documents\vboxsuspend\vboxsuspend.py
    • Choisissez Terminer.

Désormais, les machines virtuelles VirtualBox doivent être suspendues lors de la déconnexion / redémarrage / arrêt.

Le script python pour effectuer l'arrêt est ci-dessous:

# A script to suspend all running VirtualBox VMs

import os

import subprocess

import sys


class VM(object):
    def __init__(self, name, uuid):
        self.name = name
        self.uuid = uuid

    def __repr__(self):
        return "VM(%r,%r)" % (self.name, self.uuid)


class VBoxRunner(object):
    def __init__(self):
        program_files = os.environ["ProgramW6432"]
        vbox_dir = os.path.join(program_files, "Oracle", "VirtualBox")
        self.vboxmanage_filename = os.path.join(vbox_dir, "VBoxManage.exe")

    def vbox_run(self, *args):
        subprocess.check_call([self.vboxmanage_filename] + list(args))

    def vbox_run_output(self, *args):
        return subprocess.check_output([self.vboxmanage_filename] + list(args))

    def list(self, running=True):
        if running:
            list_cmd = "runningvms"
        else:
            list_cmd = "vms"

        return [self.parse_vm_list_entry(x) for x in self.vbox_run_output("list", list_cmd).strip().split("\n")]

    def suspend_all(self):
        success = True
        stopped_some_vms = False
        vms = self.list(running=True)
        for vm in vms:
            if vm is None:
                continue
            # noinspection PyBroadException
            try:
                self.suspend_vm(vm)
            except:
                success = False
            else:
                stopped_some_vms = True
        if not stopped_some_vms:
            self.message("No running vms")
        return success

    @staticmethod
    def parse_vm_list_entry(x):
        """:type x: str"""
        if not x.startswith('"'):
            return None
        end_pos = x.find('"', 1)
        if end_pos == -1:
            return None
        name = x[1:end_pos]
        assert x[end_pos + 1: end_pos + 3] == " {"
        assert x.endswith("}")
        uuid = x[end_pos + 2:]

        return VM(name, uuid)

    @staticmethod
    def message(msg):
        print >>sys.stderr, msg

    def suspend_vm(self, vm):
        assert isinstance(vm, VM)
        self.vbox_run("controlvm", vm.uuid, "savestate")


def main():
    vr = VBoxRunner()
    success = vr.suspend_all()
    if not success:
        sys.exit(1)


if __name__ == "__main__":
    main()
rakslice
la source
1
La suggestion des autres d'utiliser un script batch que vous pouvez exécuter manuellement qui effectue les sauvegardes puis l'arrêt est excellente si cela correspond à votre cas d'utilisation. Mais ce que je veux vraiment, c'est des redémarrages automatiques de Windows Update, après qu'une machine virtuelle avec laquelle j'ai travaillé a été mise hors tension pendant la nuit par le redémarrage de Windows Update au cours des deux derniers jours d'affilée ...
rakslice