Запуск виртуальной машины Buildbot
Один из типов сборки, выполняемых в BuildBot, — это сборка и тестирование бинарных пакетов MariaDB для платформ, на которых мы производим выпуск. Мы собираем и тестируем пакеты для Debian (4 и 5), Ubuntu (8.04–10.04), Centos 5 и общего Linux; архитектуры amd64 и i386. Это тестирование выполняется с помощью виртуальных машин, запущенных в KVM.
Для лучшего управления запуском и завершением работы виртуальных машин мы используем небольшой оболочный скрипт вокруг KVM, разработанный нами и названный runvm. Цель этой утилиты — упростить запуск виртуальной машины, выполнение некоторых команд сборки внутри неё и чистое завершение работы.
Этот оболочный скрипт инкапсулирует шаги, необходимые для запуска виртуальной машины, выполнения ряда команд внутри неё и последующего корректного завершения. В скрипте уделено особое внимание тому, чтобы виртуальная машина всегда завершалась после использования (корректно, если это возможно), даже в случае различных сбоев или потери родительского процесса или контролирующего терминала. Кроме того, если какая-то конфликтная виртуальная машина каким-то образом избежит завершения, runvm автоматически пытается её завершить перед запуском новой. Эта дополнительная надёжность важна для полностью автоматизированного тестирования, как в нашей установке Buildbot, чтобы обеспечить возможность бесприсутственного выполнения системы в течение более длительных периодов времени.
По существу, вместо обычной сессии Buildbot, которая делала бы что-то вроде этого на сервере:
./configure && make
Вместо этого мы используем runvm для выполнения того же самого внутри виртуальной машины, работающей как гость KVM с сервером сборки в качестве хоста:
runvm image.qcow2 "./configure" "make"
См. разделы runvm Примеры использования или runvm --help ниже для более подробных примеров, но это основная идея.
Примеры использования runvm
Пример использования один
Вот пример команды, которую можно использовать для запуска сборки внутри виртуальной машины с помощью runvm:
runvm --port=2222 ubuntu-hardy-i386.qcow2 \ "= scp -P 2222 mariadb-5.1.41-rc.tar.gz localhost:" \ "tar zxf mariadb-5.1.41-rc.tar.gz" \ "cd mariadb-5.1.41-rc && ./configure" \ "cd mariadb-5.1.41-rc && make"
В этом примере ubuntu-hardy-amd64.qcow2 — это образ KVM, уже установленный с компиляторами и настроенный для беспарольного доступа SSH (с использованием аутентификации с открытым ключом). Порт 2222 на стороне хоста перенаправляется на службу SSH (порт 22) на стороне гостя (поэтому, указав разные --port опции, легко запустить несколько runvm вызовов параллельно; в нашей установке Buildbot мы запускаем 3 сборки параллельно таким образом).
Обратите внимание на использование команды scp, предваряемой знаком равенства "=". Команды, предваряемые таким образом, выполняются на стороне хоста, а не гостя; это удобный способ копировать данные в или результаты из виртуальной машины во время работы сессии runvm.
Используя runvm таким образом, мы можем легко и гибко управлять большим количеством виртуальных машин для автоматизированных сборок с очень небольшими накладными расходами и сложностью. На самом деле у нас около 70 отдельных виртуальных машин! Единственный ресурс, который они потребляют, — это немного места на диске (около 37 ГБ). Кроме того, образы виртуальных машин также просты в настройке, требуя только минимальной установки; нет необходимости настраивать сетевые мосты или IP-адреса или устанавливать клиента Buildbot. Вся сложная логика работает на системе хоста, которая должна быть установлена только один раз.
Благодаря простоте виртуальных образов, сборки и тесты выполняются в минимальной среде, что полезно для выявления отсутствующих зависимостей или других проблем, которые не проявляются на обычных машинах разработчиков с полной установкой рабочего стола (мы даже выполняем тесты установки на отдельной виртуальной машине, отличной от той, которая используется для сборки, с компиляторами и т. д., не установленные на машине, используемой для тестирования).
Пример использования два
Дальнейшим усовершенствованием примера один (выше) является создание нового временного образа виртуальной машины перед каждым шагом как копии эталонного образа, выполнение сборки и удаление временного образа после сборки. Это исключает любую возможность влияния предыдущей сборки на последующую сборку (и, следовательно, также упрощает настройку сборки, поскольку мы можем свободно устанавливать вещи без необходимости очистки). Это также позволяет избежать необходимости исправления повреждённого образа, например, при необходимости выполнить fsck вручную после сбоя или аналогичной проблемы. Мы используем этот метод для большинства сборок бинарных пакетов в Buildbot.
Для использования этой техники копирования и удаления с runvm полезна опция --base-image:
runvm --port=2222 --base-image=ubuntu-hardy-i386.qcow2 tmp.qcow2 \ "= scp -P 2222 mariadb-5.1.41-rc.tar.gz localhost:" \ "tar zxf mariadb-5.1.41-rc.tar.gz" \ "cd mariadb-5.1.41-rc && ./configure" \ "cd mariadb-5.1.41-rc && make"
Это запустит сборку в временной копии tmp.qcow2 эталонного образа ubuntu-hardy-i386.qcow2, не изменяя эталонный образ каким-либо образом. Это использует функцию копирования по требованию формата изображения qcow2 (см. qemu-img(1)), поэтому это занимает всего очень мало времени (доли секунды) и минимальное место (записываются только изменённые блоки в новый образ).
Дополнительные примеры использования
Вышеприведённые два примера в основном демонстрируют, как выполняется тестирование пакетов в нашей установке Buildbot. Конечно, есть и некоторые дополнительные детали, такие как больше опций для команд сборки и дополнительные меры для получения файлов журнала для отладки проблем; полные сведения доступны в нашем файле конфигурации Buildbot. Но основной принцип заключается в наборе runvm команд, аналогичных приведённым примерам.
Получение runvm
Утилита runvm доступна по лицензии GPL на Lauchpad в проекте Инструменты для MariaDB. В репозитории bzr она находится в виде buildbot/runvm. Если кто-то сочтёт её полезной или имеет предложения по улучшениям, пожалуйста, напишите нам на список рассылки maria-developers.
runvm --help
Поскольку это может быть полезно, вот вывод из runvm --help (проверьте последнюю версию утилиты для актуального вывода):
Usage: ./runvm <options> image.qcow2 [command ...]
Boot the given KVM virtual machine image and wait for it to come up.
Run the list of commands one at a time, aborting on receiving an error.
When all commands are run (or one of them failed), shutdown the virtual
machine and exit.
Commands are by default run inside the virtual machine using ssh(1). By
prefixing a command with an equals sign '=', it will instead be run on the
host system (for example to copy files into or out of the virtual machine
using scp(1)).
Some care is taken to ensure that the virtual machine is shutdown
gracefully and not left running even in case the controlling tty is
closed or the parent process killed. If a previous virtual machine is
already running on a conflicting port, an attempt is made to shut it
down first. For this purpose, a PID file is created in $HOME/.runvm/
Available options:
-p, --port=N Forward this port on the host side to the ssh port (port
22) on the guest side. Must be different for each runvm
instance running in parallel to avoid conflicts. The
default is 2222.
To copy files in/out of the guest use a command prefixed
with '=' calling scp(1) with the -P option using the port
specified here, like this:
runvm img.qcow2 "=scp -P 2222 file.txt localhost:"
-u, --user=USER Name of the account to ssh into in the guest. Defaults to
the name of the user invoking runvm on the host.
-m, --memory=N Amount of memory (in megabytes) to allocate to the guest.
Defaults to 2047.
--smp=N Number of CPU cores to allocate to the guest.
Defaults to 2.
-c, --cpu=NAME Type of CPU to emulate for KVM, see qemu(1) for details.
For example:
--cpu=qemu64 For 64-bit amd64 emulation
--cpu=qemu32 For 32-bit x86 emulation
--cpu=qemu32,-nx 32-bit and disable "no-execute"
The default is qemu32,-nx
--netdev=NAME Network device to emulate. The 'virtio' device has good
performance but may not have driver support in all
operating systems, if so another can be specified.
The default is virtio.
--kvm=OPT Pass additional option OPT to kvm. Specify multiple times
to pass more than one option. For example
runvm --kvm=-cdrom --kvm=mycd.iso img.qcow2 ...
--initial-sleep=SECS
Wait this many seconds before starting to poll the guest
ssh port for it to be up. Default 15.
--startup-timeout=SECS
Wait at most this many seconds for the guest OS to respond
to ssh. If this time is exceeded assume it has failed to
boot correctly. Default 300.
--shutdown-timeout=SECS
Wait at most this many seconds for the guest OS to
shutdown gracefully after sending a shutdown command. If
this time is exceeded, assume the guest has failed to
shutdown gracefully and kill it forcibly. Default 120.
--kvm-retries=N If the guest fails to come up, retry the boot this many
times before giving up. This helps if the virtual machine
sometimes crashes during boot. Default 3.
-l, --logfile=FILE File to redirect the output from kvm into. This includes
any (error) messages from kvm, and also includes anything
the guest writes to the kvm emulated serial port (it can
be useful to set the guest to send boot loader and kernel
messages to the serial console and log them with this
option). Default is to not log this output anywhere.
-b, --base-image=IMG
Instead of booting an existing image, create a new
copy-on-write image based on IMG. This uses the -b option
of qemu-img(1). IMG is not modified in any way. This way,
the booted image can be discarded after use, so that each
use of IMG is using the same reference image with no risk
of "polution" between different invocations.
Note that this DELETES any existing image of the same
name as the one specified on the command line to boot! It
will be replaced with the image created as a copy of IMG,
with any modifications done during the runvm session.
Эта страница основана на записи в блоге Кристиана Нильсена, основного разработчика runvm.
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/runvm/