Я пытаюсь, чтобы несколько изображений VirtualBox запускались автоматически при загрузке и корректно завершались при отключении хоста перед отключением питания. У меня есть сценарий bash, /usr/local/bin/vmctl.sh, который обрабатывает запуск и остановку гостевых изображений с помощью вызовов VBoxManage. Стартовый вызов очень прост - он просто просматривает список изображений, а вызовы VBoxManage startvm --type headless "<imgname>" затем выходят из 0. Стоп-звонок циклически перебирается по списку и вызывает VBoxManage controlvm "<imgname>" acpipowerbutton, затем цикл до тех пор, пока VBoxManage list runningvms не вернет пустой список ИЛИ пройдет 60 секунд прежде чем он выйдет 0. Запуск сценария из командной строки работает отлично.
Я установил единичный файл в /lib/systemd/system/vmctl.service:
[Unit]
Description=VirtualBox Control
After=virtualbox.service
[Service]
ExecStart=/usr/local/bin/vmctl.sh start
ExecStop=/usr/local/bin/vmctl.sh stop
[Install]
WantedBy=multi-user.target
Когда я запускаю systemctl start vmctl.service , он вызывает и стартовую, и стоп-линию. Когда я вызываю systemctl stop vmctl.service, в syslog есть запись, в которой указано Stopped VirtualBox Control, но она ничего не делает.
Я полный неофит для systemd. Недавно я обновил этот Ubuntu до 16.04.
Спасибо!
Обновление, основанное на предположении Марка:
! d6]
Я подтвердил синтаксис с помощью systemd-analyze verify /etc/systemd/system/vmctl.service (после перемещения файла там - спасибо за подсказку). Затем я изменил ExecStart и ExecStop, как вы предположили, выполнил systemctl daemon-reload и все еще видит то же поведение. Журнал показывает оба исполнения при вызове systemctl start vmctl, но ни при запуске systemctl stop vmctl:
# journalctl -u vmctl | tail
.
.
.
Apr 06 19:28:18 macmi10-builder systemd[1]: Started VirtualBox Control.
Apr 06 19:28:18 macmi10-builder echo[13901]: I started
Apr 06 19:28:18 macmi10-builder echo[13904]: I stopped
Apr 06 19:28:33 macmi10-builder systemd[1]: Stopped VirtualBox Control.
Параметр Тип по умолчанию для Единицы обслуживания - Type = simple, который используется, когда процесс, сконфигурированный с помощью ExecStart =, является основным процессом службы. Такой блок будет ожидать, пока процесс, указанный ExecStart, не будет возвращен, затем деактивируйте, запустив процесс, указанный ExecStop.
Тип = simple используется, когда ожидается, что процесс, указанный ExecStart, ожидается, будет выполняться, как только будут запущены виртуальные машины (не то, что вы хотите). для выхода после завершения запуска, а его дочерние процессы (ы) продолжаются (ы) для запуска в фоновом режиме. Это поведение традиционных демонов UNIX и рекомендуемый выбор в вашем случае. Процесс, указанный ExecStop, будет выполняться в случае сбоя службы или команды «systemctl stop vmctl».
Таким образом, ваш файл устройства должен быть:
[Unit]
Description=VirtualBox Control
After=virtualbox.service
[Service]
Type=forking
ExecStart=/usr/local/bin/vmctl.sh start
ExecStop=/usr/local/bin/vmctl.sh stop
[Install]
WantedBy=multi-user.target
Как уже упоминалось, проблема в том, что vmctl.sh сразу же выходит. В отличие от ответа Кристофа, разветвление не будет работать, скорее всего, поскольку vmctl.sh, вероятно, не развивает. Вам нужна услуга oneshot, с RemainAfterExit=true. Если вы просто измените его на oneshot, вы получите то же самое поведение. Часть RemainAfterExit сообщает, что даже после выхода ExecStart сервис все равно следует считать запущенным, поэтому он не должен запускать ExecStop (s).
Ваш синтаксис systemd верен. Ваша проблема в другом месте.
Сначала вы можете подтвердить, что сам синтаксис правильный:
systemd-analyze verify /path/to/your/vmctl.service
Во-вторых, попробуйте подставить эти строки:
ExecStart=/bin/echo "I started"
ExecStop=/bin/echo "I stopped"
После запуска systemctl start vmctl или systemctl stop vmctl используйте journalctl -u vmctl для проверки журналов. Я ожидаю, что вы подтвердите systemd выполнили правильные команды.
Также /lib/systemd/system предназначен для места для пакетов для управления файлами systemd. Файлы, которые изменяются и управляются человеком, предназначены для входа в /etc/systemd/system
Параметр Тип по умолчанию для Единицы обслуживания - Type = simple, который используется, когда процесс, сконфигурированный с помощью ExecStart =, является основным процессом службы. Такой блок будет ожидать, пока процесс, указанный ExecStart, не будет возвращен, затем деактивируйте, запустив процесс, указанный ExecStop.
Тип = simple используется, когда ожидается, что процесс, указанный ExecStart, ожидается, будет выполняться, как только будут запущены виртуальные машины (не то, что вы хотите). для выхода после завершения запуска, а его дочерние процессы (ы) продолжаются (ы) для запуска в фоновом режиме. Это поведение традиционных демонов UNIX и рекомендуемый выбор в вашем случае. Процесс, указанный ExecStop, будет выполняться в случае сбоя службы или команды «systemctl stop vmctl».
Таким образом, ваш файл устройства должен быть:
[Unit]
Description=VirtualBox Control
After=virtualbox.service
[Service]
Type=forking
ExecStart=/usr/local/bin/vmctl.sh start
ExecStop=/usr/local/bin/vmctl.sh stop
[Install]
WantedBy=multi-user.target
Как уже упоминалось, проблема в том, что vmctl.sh сразу же выходит. В отличие от ответа Кристофа, разветвление не будет работать, скорее всего, поскольку vmctl.sh, вероятно, не развивает. Вам нужна услуга oneshot, с RemainAfterExit=true. Если вы просто измените его на oneshot, вы получите то же самое поведение. Часть RemainAfterExit сообщает, что даже после выхода ExecStart сервис все равно следует считать запущенным, поэтому он не должен запускать ExecStop (s).
Ваш синтаксис systemd верен. Ваша проблема в другом месте.
Сначала вы можете подтвердить, что сам синтаксис правильный:
systemd-analyze verify /path/to/your/vmctl.service
Во-вторых, попробуйте подставить эти строки:
ExecStart=/bin/echo "I started"
ExecStop=/bin/echo "I stopped"
После запуска systemctl start vmctl или systemctl stop vmctl используйте journalctl -u vmctl для проверки журналов. Я ожидаю, что вы подтвердите systemd выполнили правильные команды.
Также /lib/systemd/system предназначен для места для пакетов для управления файлами systemd. Файлы, которые изменяются и управляются человеком, предназначены для входа в /etc/systemd/system
Параметр Тип по умолчанию для Единицы обслуживания - Type = simple, который используется, когда процесс, сконфигурированный с помощью ExecStart =, является основным процессом службы. Такой блок будет ожидать, пока процесс, указанный ExecStart, не будет возвращен, затем деактивируйте, запустив процесс, указанный ExecStop.
Тип = simple используется, когда ожидается, что процесс, указанный ExecStart, ожидается, будет выполняться, как только будут запущены виртуальные машины (не то, что вы хотите). для выхода после завершения запуска, а его дочерние процессы (ы) продолжаются (ы) для запуска в фоновом режиме. Это поведение традиционных демонов UNIX и рекомендуемый выбор в вашем случае. Процесс, указанный ExecStop, будет выполняться в случае сбоя службы или команды «systemctl stop vmctl».
Таким образом, ваш файл устройства должен быть:
[Unit]
Description=VirtualBox Control
After=virtualbox.service
[Service]
Type=forking
ExecStart=/usr/local/bin/vmctl.sh start
ExecStop=/usr/local/bin/vmctl.sh stop
[Install]
WantedBy=multi-user.target
Как уже упоминалось, проблема в том, что vmctl.sh сразу же выходит. В отличие от ответа Кристофа, разветвление не будет работать, скорее всего, поскольку vmctl.sh, вероятно, не развивает. Вам нужна услуга oneshot, с RemainAfterExit=true. Если вы просто измените его на oneshot, вы получите то же самое поведение. Часть RemainAfterExit сообщает, что даже после выхода ExecStart сервис все равно следует считать запущенным, поэтому он не должен запускать ExecStop (s).
Ваш синтаксис systemd верен. Ваша проблема в другом месте.
Сначала вы можете подтвердить, что сам синтаксис правильный:
systemd-analyze verify /path/to/your/vmctl.service
Во-вторых, попробуйте подставить эти строки:
ExecStart=/bin/echo "I started"
ExecStop=/bin/echo "I stopped"
После запуска systemctl start vmctl или systemctl stop vmctl используйте journalctl -u vmctl для проверки журналов. Я ожидаю, что вы подтвердите systemd выполнили правильные команды.
Также /lib/systemd/system предназначен для места для пакетов для управления файлами systemd. Файлы, которые изменяются и управляются человеком, предназначены для входа в /etc/systemd/system