QEMU/KVM :Как добавлять видеоустройства во время выполнения

Следующие сценарии sed основаны на идее, что строка, содержащая ноль -или -дополнительных пробелов и строка «задача Listen», определяет начало блока текста, который вы хотите отредактировать, и что блок продолжается до следующей «задачи» или до конца файла (, в зависимости от того, что наступит раньше ).

Это работает в тех случаях, когда строка 'edit TRIES 2' может не следовать сразу за строкой task Listen, а может быть в любом месте в блоке task Listen.

Он также справится с вариациями количества пробелов в строке edit TRIES 2.

sed -E -e '/^ *task Listen/,/^ *task/ {s/edit +TRIES +2 *$/edit TRIES 3/}'

Расширенные регулярные выражения включены (с -E), поэтому мы можем использовать+(1 -или -больше )без необходимости использовать обратную косую черту. Также используется для чередования (task|xyz)без искажения обратной косой черты во втором примере.

*$в конце регулярного выражения поиска гарантирует, что оно будет соответствовать только 2, а не какому-либо другому числу, начинающемуся с 2.

Например, если ввести это:

$ cat input.txt 
  task something
    edit TRIES 2
  task Listen
    foo
    bar
    edit TRIES 25
    edit TRIES 2
  task somethingelse
    edit TRIES 2

Будет получен следующий результат:

$ sed -E -e '/^ *task Listen/,/^ *task/ {s/edit +TRIES +2 *$/edit TRIES 3/1}' input.txt 
  task something
    edit TRIES 2
  task Listen
    foo
    bar
    edit TRIES 25
    edit TRIES 3
  task somethingelse
    edit TRIES 2

Обратите внимание, что a )не изменил ПОПЫТКИ 2 на ПОПЫТКИ 3 ни в предыдущем, ни в последующем блоке задач, а b )изменил ПОПЫТКИ 2 везде, где он появлялся в «задаче». Блок «Слушай». ПРИМЕЧАНИЕ. :, если в этом блоке более одного раза встречается «edit TRIES 2», все вхождения будут изменены.

Если блок «Прослушивание задачи» завершается или может заканчиваться чем-либо, кроме строки, начинающейся с нуля -или -дополнительных пробелов и слова «задача», вы можете изменить второй адрес в соответствии с. например. если блок может заканчиваться либо новым блоком задачи, либо блоком "xyz":

sed -E -e '/^ *task Listen/,/^ *(task|xyz)/ {s/edit +TRIES +2 *$/edit TRIES 3/1}'

Чтобы заставить любую из приведенных выше команд sed фактически изменить входной файл, а не только выходной поток,используйте опцию sed -i.

Наконец, если вводимый текст может содержать пробелы и/или символы табуляции вместо просто пробелов, вы можете использовать класс символов [[:blank:]]для их сопоставления. например.

 sed -E -e '/^[[:blank:]]*task Listen/,/^[[:blank:]]*task/ {
   s/edit[[:blank:]]+TRIES[[:blank:]]+2[[:blank:]]*$/edit TRIES 3/}'

или, если ваша версия sed поддерживает perl -совместимые регулярные выражения (, например. GNU-сед):

sed -E -e '/^\s*task Listen/,/^\s*task/ {s/edit\s+TRIES\s+2\s*$/edit TRIES 3/}'
0
03.10.2021, 00:23
1 ответ

Таким образом, из моего исследования темы, о которой я мало что знаю :, невозможно напрямую редактировать файл конфигурации, используя только virsh.

После быстрого погружения в Python я смог собрать этот скрипт, который выполняет свою работу

#!/usr/bin/python3

import xml.etree.ElementTree as ET
import libvirt
import sys
import os

desired_number_of_monitors = 3
domain_name = 'win10'
remote_viewer_config_path = os.path.join( os.path.dirname(os.path.realpath(__file__)), 'remote-viewer-win10-connection.ini')

if not os.path.exists(remote_viewer_config_path):
    print(f'could not find {remote_viewer_config_path}: try again')
    sys.exit(1)

if len(sys.argv) >= 2:
    desired_number_of_monitors = int(sys.argv[1])

try:
    libvert_con = libvirt.open(None)
except libvirt.libvirt.libvirtError:
    print('Failed to open connection to the hypervisor')
    sys.exit(1)

try:
    win10_domain = libvert_con.lookupByName(domain_name)    
except libvirt.libvirtError:
    print(f'Failed to find domain {domain_name}')
    sys.exit(1)

try:
    raw_xml = win10_domain.XMLDesc(0)  
except libvirt.libvirtError:
    print(f'Failed to get xml from domain {domain_name}')
    sys.exit(1)

try:
    tree = ET.ElementTree(ET.fromstring(raw_xml))
    devices = tree.find('.//devices')

    #remove all video nodes
    for v in devices.findall('video'):
        devices.remove(v)
        
    #add the desired number of video nodes
    while desired_number_of_monitors  > len(devices.findall('video')):
        video = ET.Element('video')
        video.append(ET.fromstring("<model type='qxl'></model>"))
        video.append(ET.fromstring("<address type='pci'></address>"))
        devices.append(video)

    #the updated xml configuration
    output_xml = ET.tostring(tree.getroot(),encoding='unicode')
except Exception as e:
    print(f'failed to edit the xml for {domain_name} : {e}')

try:
    win10_domain = libvert_con.defineXML(output_xml)
    #if the domain is running stop exit
    if win10_domain.isActive():
        print(f'{win10_domain.name()} is running: try again')
        sys.exit(1)
    else:
        #start the vm? am I actually re-creating the vm or just starting it and does it matter
        if win10_domain.create() < 0:
            print(f'Failed to start the {win10_domain.name()} domain')
        else:
            print(f'{win10_domain.name()} vm started')
            os.system(f'remote-viewer -f {remote_viewer_config_path}')
except Exception as e2:
    print(f'failed to start update or start {domain_name} : {e2}')
0
03.10.2021, 23:19

Теги

Похожие вопросы