Как проверить с помощью командной строки, если виртуальная машина VirtualBox не работает в Windows - PullRequest
0 голосов
/ 04 июня 2018

Я работаю над проектом Jenkins для удаленного запуска и выключения определенной виртуальной машины с предоставленными пользователем параметрами.

Мне удалось найти способ определить, что указанная виртуальная машина запущена, работает и готовадля дальнейших инструкций, но мне еще предстоит найти способ определить, что указанная виртуальная машина отключена.

Текущий код, используемый на этапе сборки, выглядит следующим образом:

@ECHO OFF
SETLOCAL EnableDelayedExpansion

ECHO Shutting down VM %VM% on Host %computername%...
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" controlvm %VM% acpipowerbutton
ECHO %ERRORLEVEL%
IF ERRORLEVEL 1 EXIT /B 1

:LOOP
WAITFOR /T 10 VMtoShutDown 2>NUL
FOR /f %%a IN ('VBoxManage list runningvms ^| FINDSTR %VM%') DO SET VM_State=%%a
IF [!VM_State!] EQU [] (
ECHO %VM% is not running.
EXIT /b 0
)
GOTO LOOP

Логикаэто:

  1. Отправить controlvm команду для завершения ACPI целевой виртуальной машины.
  2. Используйте FOR для просмотра списка работающих виртуальных машин, чтобы увидеть, работает ли целевая виртуальная машина.
  3. Если целевая виртуальная машина все еще работает, ничего не делать и вернуться к началу: LOOP и перепроверить, пока не изменится результат.
  4. Если целевая виртуальная машина больше не работаетв списке запущенных виртуальных машин этот этап сборки считается успешным.

Основная проблема - оператор FOR в предложении :LOOP.На этапе запуска этапа сборки я могу использовать VboxManage list runningvms, чтобы определить, указана ли указанная виртуальная машина, и таким образом обработать ее как таковую и указать, что сборка Jenkins для запуска указанной виртуальной машины прошла успешно.

Однако я заметил, что как только целевая виртуальная машина исключается из списка работающих виртуальных машин с помощью более ранней команды controlvm, вся часть DO оператора FOR просто ничего не делает.Он не устанавливает VM_State=%%a, например, и не делает ничего другого, что я бросил в оператор FOR.Это приводит к тому, что :LOOP продолжает бесконечное зацикливание, поскольку единственная проверка состояния не срабатывает.

Вопрос: Есть ли способ определить, выключена ли виртуальная машина с определенным именем?

Примечания:

  • Плагин VirtualBox для Jenkins несовместим с текущей версией VirtualBox (5.1.30).
  • Версия Jenkins - 2.122.
  • Приведенный выше код проверен на то же самое при работе в качестве автономного файла .bat на целевой машине и на моей собственной машине.
  • Все задействованные системы находятся в Windows 10 v1803.

1 Ответ

0 голосов
/ 17 декабря 2018

Это работает для меня в Windows 10, надеюсь, это поможет!

@ECHO OFF
SETLOCAL EnableDelayedExpansion

ECHO Shutting down VM %VM% on Host %computername%...
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" controlvm %VM% acpipowerbutton
ECHO VirtualBox command return code: %ERRORLEVEL%
IF ERRORLEVEL 1 EXIT /B 1

:LOOP
REM Sleep for 1 second by using a ping hack :)
ping -n 2 127.0.0.1 > nul
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" showvminfo %VM% | findstr /c:"powered off" >NUL
IF %ERRORLEVEL% EQU 0 GOTO END
echo VM %VM% not powered off yet...
GOTO LOOP

:END
echo VM %VM% powered off.
...