Encerramento normal dos convidados do Windowsbox no encerramento do host

17

Estou tentando encontrar uma solução para encerrar normalmente qualquer VM guest em execução no VirtualBox Windows quando o computador host for desligado ou reiniciado.

Parece que a opção mais segura seria acionar o comando "save state" quando o host começa a desligar, mas não está claro se o host irá esperar o tempo suficiente para as VMs concluírem o estado de gravação e desligarem.

Alguém tem uma solução robusta para esse problema (aparentemente básico)?

    
por Matt Jenkins 19.08.2015 / 14:24

6 respostas

6

Eu tive um problema semelhante e resolvi isso executando o VirtualBox como um serviço:

link

Com o VBoxVMService, você pode escolher como deseja que a máquina desligue (Salvar estado, desligue) e inicie. Como está sendo executado como um serviço, o Windows espera automaticamente que ele seja desligado durante o processo de desligamento do sistema.

    
por 31.10.2015 / 11:18
3

Infelizmente, isso não parece ser possível para as VMs iniciadas via VirtualBox GUI. Mesmo que a GUI possa capturar o evento de desligamento do host e reagir, o serviço VirtualBox é encerrado: link

Se você não precisa de um console gráfico, VBoxHeadlessTray ou VBoxVMService pode ser o caminho a percorrer. Ambos suportam salvamento e reinício automáticos no desligamento e reinicialização do host do Windows.

O VirtualBox 5.0 introduz um modo de início "UI destacável" . Este modo inicia uma VM sem cabeçalho com um processo de interface do usuário separado. O desempenho gráfico sofre e a aceleração 3D ainda não é suportada. Mas talvez isso possa ser combinado com o VBoxHeadlessTray no futuro (o VBoxHeadlessTray ainda não suporta 5.0). Links para o repositório VBoxHeadlessTray GitHub e para o pedido de pull do GitHub correspondente para adicionar suporte ao VirtualBox 5 .

Editar: VBoxVmService também não suporta novo modo destacável a partir da versão 5.0. Apenas sem cabeça até agora. Eu adicionei uma solicitação de recurso para isso.

    
por 31.10.2015 / 10:48
2

Desculpe, estou atrasado para a festa. Há uma resposta exata para isso, embora exija um pouco de linha de comando. Consulte esta publicação para mais informações: link

O comando que você está procurando é:

"C: \ Arquivos de programas \ Oracle \ VirtualBox \ VBoxManage.exe" setextradata "VM NAME" GUI / DefaultCloseAction Desligamento

Isso é o que eu uso em várias VMs, fecho a janela e inicia um desligamento seguro automaticamente. Desligue o Windows e, em sua tentativa de fechar tudo, ele aguardará a conclusão desses processos.

    
por 04.04.2018 / 18:57
1

Eu tenho 3 scripts em lote que eu uso em vez dos botões power startmenu.

do_shutdown.bat (pc desligado com um período de espera de 10 segundos, para não dar tempo de 10 segundos para o vm salvar, mas para permitir que eu cancele o desligamento em 10 segundos. A contagem regressiva começa depois os vm foram desligados)

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

do_reboot.bat (reinicializa imediatamente após o desligamento da VM)

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

do_cancel.bat (permite cancelar o desligamento do PC dentro do período de espera de 10 segundos. Ele reinicia a VM novamente, pois foi encerrado com o do_shutdown.bat)

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

Em vez de savestate , você também pode usar um dos seguintes

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)
    
por 06.11.2015 / 10:03
1

Eu fiz uma pergunta semelhante e encontrei esta página. Eu não quero executar o VirtualBox como um serviço, porque eu tenho um monte de VMs para testes e, geralmente, escolho diferentes para executar na interface do usuário do VirtualBox. Quando eu desligo meu computador, é irritante salvar manualmente o estado de cada VM. Usar scripts para salvar todas as VMs em execução parece ser uma solução prática nesse caso. Para tornar a resposta de Daniel F mais geral, escrevi esses scripts que salvam automaticamente o estado de todas as VMs em execução sem nomeá-las explicitamente.

saveRunningVMs.bat para 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 para 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
    
por 02.03.2017 / 09:12
0

Eu criei um script python que suspendia todas as VMs do VirtualBox em execução e depois configurava o sistema para executar o script no logout como uma tarefa agendada.

Eu não sei quão confiável este método é exatamente. Como outros já observaram , há limites para quanto tempo o sistema aguardará a conclusão de uma tarefa do Winlogon 7002. Mas, pessoalmente, não tive nenhum problema em fornecer estados de economia utilizáveis, mesmo com várias VMs em execução em mais de 4 GB de RAM geral da VM.

Aqui estão os passos para configurá-lo:

  1. Faça o download e instale o Python 2.7.x em python.org
  2. Crie o arquivo de script python em algum lugar do sistema usando o Bloco de Notas ou qualquer outro editor de texto simples (veja abaixo)
  3. Abra o Agendador de Tarefas
  4. Escolher ação - > Crie uma Tarefa Básica ... e use o assistente para criar uma tarefa com as seguintes configurações
    • Um nome de sua escolha
    • Iniciar a tarefa quando um evento específico é registrado
    • Log: sistema
    • Fonte: Winlogon
    • ID do evento: 7002
    • Iniciar um programa
    • Ao lado de Programa / Script , insira o caminho completo para seu python.exe , por exemplo c:\Python27\python.exe
    • Ao lado de Adicionar argumentos , insira o caminho completo onde você colocou o arquivo de script python, por exemplo, coloquei o meu em uma subpasta da pasta my documents, portanto, isso é C:\Users\rakslice\Documents\vboxsuspend\vboxsuspend.py
    • Escolha Concluir.

Agora as VMs do VirtualBox devem ser suspensas no logout / restart / shutdown.

O script python para fazer o desligamento está abaixo:

# 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()
    
por 04.06.2018 / 05:46