XML-описание передаётся libvirt при создании и редактировании виртуальной машины. На последнем этапе перед передачей XML в libvirt выполняется обработчик editxml. Добавив плагин на данный обработчик, можно изменять XML-описание виртуальной машины. В VMmanager внесённые изменения учитываются.

Входные параметры обработчика:

  • vmi — наименование шаблона ОС;
  • hostnode — идентификатор узла кластера, на котором расположена виртуальная машина.

XML для libvirt находится в теге "/doc/outxml". VMmanager также считает XML из тега "/doc/outxml".

Пример обработчика


Задача

Необходимо добавить в XML тэги "pm" (Power Management).

...
<pm>
  <suspend-to-disk enabled='yes'/>
  <suspend-to-mem enabled='yes'/>  
</pm>
...
BASH


Также необходимо для шаблона ОС с именем "SlitazOs" найти все виртуальные диски типа "block" и изменить тип кэширования на "writeback".

Решение

Нужно создать файл описания обработчика и сохранить его в директорию /usr/local/mgr5/etc/xml.

Файл /usr/local/mgr5/etc/xml/vmmgr_mod_pm.xml:

<mgrdata>
  <handler name="editxml_pm.py" type="xml">
  <event name="editxml" after="yes"/>
</handler>
</mgrdata>
BASH

Нужен скрипт editxml_pm.py, который должен находиться в /usr/local/mgr5/addon.

Файл /usr/local/mgr5/addon/editxml_pm.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import xml.etree.ElementTree as ET

# Содержимое сессии VMmanager в виде XML-файла
sesXmlContent = sys.stdin.read()
ses = ET.fromstring(sesXmlContent)
# Получить наименование шаблона ОС
vmi = ses.find("./vmi").text
# Получить ID узла кластера
hostNodeId = ses.find("./hostnode").text
# Оригинальный xml виртуальной машины
domainXmlString = ses.find("./outxml").text
domainXml = ET.fromstring(domainXmlString)
# Получить имя виртуальной машины
domainName = domainXml.find("./name").text
# Исправляем XML только для шаблона SlitazOs
if vmi == "SlitazOs":
    # Добавим тег <pm> (Power Management)
    pm = ET.SubElement(domainXml, "pm")
    suspendToDisk = ET.SubElement(pm, "suspend-to-disk", {"enabled": "yes"})
    suspendToMem = ET.SubElement(pm, "suspend-to-mem", {"enabled": "yes"})
    # Поиск всех подключенных дисков
    disks = domainXml.findall("./devices/disk")
    for diskNode in disks:
        # Получаем тип виртуального диска (file, network, block, volume)
        diskType = diskNode.get("type")
        # Исправляем только для типа "block"
        if diskType == "block":
            # Устанавливаем тип кэша "writeback"
            driver = diskNode.find("driver")
            driver.set("cache", "writeback")

# Формируем XML для вывода
newDomContent = ET.tostring(domainXml, "UTF-8")
ses.find("./outxml").text = newDomContent
# Вывод XML
sys.stdout.write(ET.tostring(ses, "UTF-8"))
BASH


Для файла /usr/local/mgr5/addon/editxml_pm.py установите права на запуск:

chmod +x /usr/local/mgr5/addon/editxml_pm.py
BASH

После этого перезапустите VMmanager:

killall core
BASH

При запуске VMmanager в логе vmmgr.log должна появиться строка:

Dec  9 06:48:45 [15118:1] action EXTINFO Register event 'editxml_pm.py' for action 'editxml'
BASH

Наличие данной строки означает, что плагин готов к обработке. Теперь при любом редактировании виртуальной машины плагин отработает и изменит соответствующим образом XML-описание виртуальной машины.

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

/usr/local/mgr5/sbin/mgrctl -m vmmgr vm.redefine elid=<VM_ID>
BASH