Product SiteDocumentation Site

30.4. Сценарии перехвата (hookscripts)

Сценарии перехвата позволяют выполнить скрипт на узле виртуализации при запуске или остановке ВМ или контейнера. Скрипт может вызываться на разных этапах жизни ВМ: до запуска (pre-start), после запуска (post-start), до остановки (pre-stop), после остановки (post-stop). Сценарии перехвата должны находиться в хранилище, поддерживающем «мини-сценарии» (сниппеты).
Для возможности использовать данную функцию необходимо создать скрипт в каталоге сниппетов (например, для хранилища local по умолчанию это /var/lib/vz/snippets) и добавить его к ВМ или контейнеру.

Примечание

При переносе ВМ на другой узел, следует убедиться, что сценарий перехвата также доступен на целевом узле (хранилище с мини-сценариями, должно быть доступно на всех узлах, на которые будет выполняться миграция).
Добавить сценарий перехвата к ВМ или контейнеру можно с помощью свойства hookscript:
# qm set <vmid> --hookscript <storage>:snippets/<script_file>
# pct set <vmid> --hookscript <storage>:snippets/<script_file>
где <script_file> — исполняемый файл скрипта.
Например:
# qm set 103 --hookscript snippet:snippets/guest-hookscript.pl
update VM 103: -hookscript snippet:snippets/guest-hookscript.pl

Примечание

В настоящее время добавить сценарий перехвата можно только в командной строке. В веб-интерфейсе можно только просмотреть список скриптов в хранилище:
Хранилище snippet на узле pve01
и скрипт, добавленный к ВМ:
Скрипт-ловушка для ВМ 103
Пример сценария перехвата на Perl (файл guest-hookscript.pl):
#!/usr/bin/perl

# Example hookscript for PVE guests

use strict;
use warnings;

print "GUEST HOOK: " . join(' ', @ARGV). "\n";

# First argument is the vmid

my $vmid = shift;

# Second argument is the phase

my $phase = shift;

if ($phase eq 'pre-start') {

    # Первый этап 'pre-start' будет выполнен до запуска ВМ
    # Выход с code != 0 отменит старт ВМ

    print "$vmid is starting, doing preparations.\n";

    # print "preparations failed, aborting."
    # exit(1);

} elsif ($phase eq 'post-start') {

    # Второй этап 'post-start' будет выполнен после успешного
    # запуска ВМ
    system("/root/date.sh $vmid");
    print "$vmid started successfully.\n";

} elsif ($phase eq 'pre-stop') {

    # Третий этап 'pre-stop' будет выполнен до остановки ВМ через API
    # Этап не будет выполнен, если ВМ остановлена изнутри,
    # например, с помощью 'poweroff'

    print "$vmid will be stopped.\n";
} elsif ($phase eq 'post-stop') {

    # Последний этап 'post-stop' будет выполнен после остановки ВМ
    # Этап должен быть выполнен даже в случае сбоя или неожиданной остановки ВМ

    print "$vmid stopped. Doing cleanup.\n";

} else {
    die "got unknown phase '$phase'\n";
}

exit(0);
Функция system() используется для вызова сценария bash которому передается VMID в качестве аргумента. Текст отладки выводится в «консоль»/stdout. Текст будет помещен в журналы задач ВМ и узла PVE. Сообщения pre-start, post-start и pre-stop будут опубликованы в обоих журналах. Сообщения post-stop будут публиковаться только в журналах задач узла PVE (поскольку ВМ уже остановлена).
Выполнение скрипта guest-hookscript.pl при запуске ВМ
Пример сценария перехвата на bash:
#!/bin/bash
if [ $2 == "pre-start" ]
then
echo "Запуск ВМ $1" >> /root/test.txt
date >> /root/test.txt
fi