Script Bash para aguardar o desligamento da VM do Virtualbox?

Script Bash para aguardar o desligamento da VM do Virtualbox?

O Virtualbox tem a capacidade de emitir um comando para uma VM em execução:

vboxmanage controlvm NameOfRunningVM acpipowerbutton

No entanto, este comando retorna imediatamente, o que resulta em um desligamento não normal para minha situação.

A situação: pretendo usar isso em um script /etc/init.d. Isso permitiria o desligamento normal de todas as VMs em execução. Atualmente, quando emito o vboxmanage controlvm NameOfRunningVM acpipowerbuttoncomando, o desligamento é interrompido porque o comando não espera o desligamento da VM.

Preciso de um script Bash que receba como entrada o nome da máquina Virtualbox e um tempo limite em segundos e aguarde a VM retornar ao estado "desligado" ou o tempo limite ocorre?

Não tenho certeza de qual é a melhor maneira de fazer isso.


Estava pensando em verificar o estado da VM com o seguinte comando:

[user@machine ~]$ vboxmanage list runningvms
"VirtualMachineName" {65c93f1f-4508-4119-b07d-ce9e89b23b8e}

O script bash talvez estivesse pesquisando uma lista de VMs em execução. Assim que o nome da máquina parar de ser listado, a VM será considerada concluída.

Responder1

Usando polling, isso poderia ser feito assim:

#!/bin/bash
MACHINE=$1
echo "Waiting for machine $MACHINE to poweroff..."

until $(VBoxManage showvminfo --machinereadable $MACHINE | grep -q ^VMState=.poweroff.)
do
  sleep 1
done

Responder2

a mesma ideia de @larstobi, mas com menos barulho transferindo o comando poll para watch:

$ vboxmanage list vms
"guest" {fubar-rabuf-bufu}
$ vboxmanage showvminfo guest | grep -i state
State:           running (since 2020-08-05T02:37:13.784000000)
$ printf '( watch -te  -- "! vboxmanage showvminfo guest | grep -i poweroff" >&- & wait )' | time -p bash
Command terminated by signal 2
real 5.05
user 0.00
sys 0.00

O -esinalizador causa saída com resultado diferente de zero do comando, enquanto -tdesativa cabeçalhos irritantes; fechamos o stdout para watch, pois o objetivo é bloquear e rodamos em fork, enquanto tecnicamente o bloqueio waité interrompível.

Estou passando a string de comando para time -p bash, para que possa anexá-la facilmente timepara fins desta demonstração, mas na prática, você poderia simplesmente fazer:

$ ( watch -te  -- "! expression" >&- & wait )

Isenção de responsabilidade: nada disso foi realmente testado

informação relacionada