Изменение xml виртуальной машины

Материал из ISPWiki
Перейти к: навигация, поиск

Иерархия: VMmanager KVM -> Разработчику
VMmanager Cloud -> Разработчику

Иногда возникают потребности переопределить xml документ, который передается libvirt'у при создании и редактировании виртуальной машины. Для этого мы добавили обработчик, который выполняется на последнем этапе перед передачей xml в libvirt. Вы можете добавить плагин на этот обработчик и тем самым изменить как угодно xml описание виртуальной машины.

Имя обработчика - editxml

Входные параметры:

  • vmi - Наименование шаблона ОС (для версии 5.22 и выше)
  • hostnode - ID узла кластера, на котором расположена виртуальная машина

XML для libvirt находится в тэге /doc/outxml

VMmanager так же считает xml из тэга /doc/outxml

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

Необходимо добавить в xml тэги pm (Power management)

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

Кроме этого, для шаблона OS с именем "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>

Кроме этого, нам нужен скрипт 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)
# Получить наименование шаблона OS (только для версии 5.22 и выше)
vmi = ses.find("./vmi").text
# Получить ID узла кластера (только для версии 5.22 и выше)
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"))


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


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


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

killall core

При очередном запуске VMmanager, вы увидите в логе vmmgr.log строку

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

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

Для того, чтобы перегенерировать xml виртуальной машины, не редактируя ее в панели управления, достаточно выполнить запрос:

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