Bug 1792411 - Using virt-install with --print-xml will print the definition TWO times if a cdrom is defined
Summary: Using virt-install with --print-xml will print the definition TWO times if a ...
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: virt-manager
Version: 31
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Cole Robinson
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2020-01-17 15:55 UTC by Oliver
Modified: 2020-01-27 08:49 UTC (History)
13 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2020-01-17 16:18:11 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Oliver 2020-01-17 15:55:06 UTC
Hi, 

using --cdrom with virt-install and --print-xml will print out _two_ times the definition.

I am using:

# virsh -V
Virsh command line tool of libvirt 5.10.0

# virt-install --version
2.2.1



This command:

#virt-install -n kvm17826 --ram=8000 --vcpus 4,maxvcpus=32 --disk /dev/kvm-storage/465-1b3f4da7-f195-48c6-b659-45258309d112,bus=sata,cache=none --cdrom /opt/iso/SW_DVD9_Win_Server_STD_CORE_2019_1809.1_64Bit_English_DC_STD_MLF_X22-02970.ISO --boot cdrom --os-type=winxp  --os-variant=win2k19 --network network="Public Network",model=e1000,target=k1786-MJceW --graphics vnc,listen=0.0.0.0,keymap=en-us,password=kgqOTcmG4 --cpu host --noautoconsole --print-xml 

will print:

<domain type="kvm">
  <name>kvm17826</name>
  <uuid>58dde898-7348-4a63-8eeb-ba62bf17d4a1</uuid>
  <metadata>
    <libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
      <libosinfo:os id="http://microsoft.com/win/2k19"/>
    </libosinfo:libosinfo>
  </metadata>
  <memory>8192000</memory>
  <currentMemory>8192000</currentMemory>
  <vcpu current="4">32</vcpu>
  <os>
    <type arch="x86_64" machine="q35">hvm</type>
    <boot dev="cdrom"/>
    <boot dev="hd"/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <hyperv>
      <relaxed state="on"/>
      <vapic state="on"/>
      <spinlocks state="on" retries="8191"/>
    </hyperv>
  </features>
  <cpu mode="host-model"/>
  <clock offset="localtime">
    <timer name="rtc" tickpolicy="catchup"/>
    <timer name="pit" tickpolicy="delay"/>
    <timer name="hpet" present="no"/>
    <timer name="hypervclock" present="yes"/>
  </clock>
  <on_reboot>destroy</on_reboot>
  <pm>
    <suspend-to-mem enabled="no"/>
    <suspend-to-disk enabled="no"/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type="block" device="disk">
      <driver name="qemu" type="raw" cache="none" io="native"/>
      <source dev="/dev/kvm-storage/465-1b3f4da7-f195-48c6-b659-45258309d112"/>
      <target dev="sda" bus="sata"/>
    </disk>
    <disk type="file" device="cdrom">
      <driver name="qemu" type="raw"/>
      <source file="/opt/iso/SW_DVD9_Win_Server_STD_CORE_2019_1809.1_64Bit_English_DC_STD_MLF_X22-02970.ISO"/>
      <target dev="sdb" bus="sata"/>
      <readonly/>
    </disk>
    <controller type="usb" index="0" model="qemu-xhci" ports="15"/>
    <interface type="network">
      <source network="Public Network"/>
      <mac address="52:54:00:87:c8:3c"/>
      <target dev="k1786-MJceW"/>
      <model type="e1000"/>
    </interface>
    <console type="pty"/>
    <input type="tablet" bus="usb"/>
    <graphics type="vnc" port="-1" keymap="en-us" listen="0.0.0.0" passwd="kgqOTcmG4"/>
    <video>
      <model type="qxl"/>
    </video>
  </devices>
</domain>
<domain type="kvm">
  <name>kvm17826</name>
  <uuid>58dde898-7348-4a63-8eeb-ba62bf17d4a1</uuid>
  <metadata>
    <libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
      <libosinfo:os id="http://microsoft.com/win/2k19"/>
    </libosinfo:libosinfo>
  </metadata>
  <memory>8192000</memory>
  <currentMemory>8192000</currentMemory>
  <vcpu current="4">32</vcpu>
  <os>
    <type arch="x86_64" machine="q35">hvm</type>
    <boot dev="cdrom"/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <hyperv>
      <relaxed state="on"/>
      <vapic state="on"/>
      <spinlocks state="on" retries="8191"/>
    </hyperv>
  </features>
  <cpu mode="host-model"/>
  <clock offset="localtime">
    <timer name="rtc" tickpolicy="catchup"/>
    <timer name="pit" tickpolicy="delay"/>
    <timer name="hpet" present="no"/>
    <timer name="hypervclock" present="yes"/>
  </clock>
  <pm>
    <suspend-to-mem enabled="no"/>
    <suspend-to-disk enabled="no"/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type="block" device="disk">
      <driver name="qemu" type="raw" cache="none" io="native"/>
      <source dev="/dev/kvm-storage/465-1b3f4da7-f195-48c6-b659-45258309d112"/>
      <target dev="sda" bus="sata"/>
    </disk>
    <disk type="file" device="cdrom">
      <driver name="qemu" type="raw"/>
      <source file="/opt/iso/SW_DVD9_Win_Server_STD_CORE_2019_1809.1_64Bit_English_DC_STD_MLF_X22-02970.ISO"/>
      <target dev="sdb" bus="sata"/>
      <readonly/>
    </disk>
    <controller type="usb" index="0" model="qemu-xhci" ports="15"/>
    <interface type="network">
      <source network="Public Network"/>
      <mac address="52:54:00:87:c8:3c"/>
      <target dev="k1786-MJceW"/>
      <model type="e1000"/>
    </interface>
    <console type="pty"/>
    <input type="tablet" bus="usb"/>
    <graphics type="vnc" port="-1" keymap="en-us" listen="0.0.0.0" passwd="kgqOTcmG4"/>
    <video>
      <model type="qxl"/>
    </video>
  </devices>
</domain>


-- Its no error, that you see the definition two times, thats actually the output --

Now we have the same command, without the cdrom:

# virt-install -n kvm17826 --ram=8000 --vcpus 4,maxvcpus=32 --disk /dev/kvm-storage/465-1b3f4da7-f195-48c6-b659-45258309d112,bus=sata,cache=none --boot cdrom --os-type=winxp  --os-variant=win2k19 --network network="Public Network",model=e1000,target=k1786-MJceW --graphics vnc,listen=0.0.0.0,keymap=en-us,password=kgqOTcmG4 --cpu host --noautoconsole --print-xml


Producing:

<domain type="kvm">
  <name>kvm17826</name>
  <uuid>57050760-8a15-429a-935e-d8c4cfe82e28</uuid>
  <metadata>
    <libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
      <libosinfo:os id="http://microsoft.com/win/2k19"/>
    </libosinfo:libosinfo>
  </metadata>
  <memory>8192000</memory>
  <currentMemory>8192000</currentMemory>
  <vcpu current="4">32</vcpu>
  <os>
    <type arch="x86_64" machine="q35">hvm</type>
    <boot dev="cdrom"/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <hyperv>
      <relaxed state="on"/>
      <vapic state="on"/>
      <spinlocks state="on" retries="8191"/>
    </hyperv>
  </features>
  <cpu mode="host-model"/>
  <clock offset="localtime">
    <timer name="rtc" tickpolicy="catchup"/>
    <timer name="pit" tickpolicy="delay"/>
    <timer name="hpet" present="no"/>
    <timer name="hypervclock" present="yes"/>
  </clock>
  <pm>
    <suspend-to-mem enabled="no"/>
    <suspend-to-disk enabled="no"/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type="block" device="disk">
      <driver name="qemu" type="raw" cache="none" io="native"/>
      <source dev="/dev/kvm-storage/465-1b3f4da7-f195-48c6-b659-45258309d112"/>
      <target dev="sda" bus="sata"/>
    </disk>
    <controller type="usb" index="0" model="qemu-xhci" ports="15"/>
    <interface type="network">
      <source network="Public Network"/>
      <mac address="52:54:00:c4:44:d8"/>
      <target dev="k1786-MJceW"/>
      <model type="e1000"/>
    </interface>
    <console type="pty"/>
    <input type="tablet" bus="usb"/>
    <graphics type="vnc" port="-1" keymap="en-us" listen="0.0.0.0" passwd="kgqOTcmG4"/>
    <video>
      <model type="qxl"/>
    </video>
  </devices>
</domain>

---- Here things work correct. The definition was printed out one time.


When i dont use the print-xml option, the VM will be created correctly and started.

Comment 1 Pavel Hrdina 2020-01-17 16:18:11 UTC
This is not a bug but a feature.  When creating ans installing new VM virt-install can have multiple phases of the installation which means it will print multiple XML definitions.

In this case you used an installation option --cdrom which tells virt-install that you want to install a VM from that specific ISO image.

It's also in the man page of virt-install command if you look for --print-xml option.

Comment 2 Oliver 2020-01-17 17:09:00 UTC
Hi, 

please forgive me, but maybe i was not clear enough.

I am fully aware of what --print-xml does and it worked always quiet fine up until this version.

According to the manpage:

[...]print the generated XML instead of defining the guest.[...]

.. print the guest.

Not print 2x the guest.

I am sorry, but how can it not be a bug, if --print-xml will print out TWO times in a row the guest definition IF a ISO cdrom is defined.

While it will rpint out only ONE time the guest definition ( like its described in the manpage ) if this ISO is not defined.

This behaviour looks strange in my humble opinion. Whats the good point if a software generates an identical xml definition twice ?

If i let this definition pipe into a file, i can not let virsh define the guest from it because it will throw the error:

error: Failed to define domain from kvm1786-VM-definition
error: (domain_definition):73: Extra content at the end of the document
<domain type="kvm">
^

Comment 3 Pavel Hrdina 2020-01-17 17:36:46 UTC
From man virt-install on Fedora 31:

       --print-xml [STEP]
           Print the generated XML of the guest, instead of defining it. By default this WILL do storage creation (can be disabled with --dry-run). This option implies
           --quiet.

           If the VM install has multiple phases, by default this will print all generated XML. If you want to print a particular step, use --print-xml 2 (for the
           second phase XML).

Here you can see how it works and how you can get only a single XML for the specific phase.

Additional note, why are you passing the XML from virt-install to virsh if you can let virt-install do the job for you?

So here is the explanation how it works, if you run virt-install with any of these options: --cdrom, --location, --pxe or --install without no_install=yes the installation process have two phases.  First phase is used to install a VM and the second phase is used to define the VM and then use the second definition as the final one once installation is completed.

There are some difference in the XMLs, the main one is that the install XML has the installation data, such as cdrom, or kernel image path and it also has <on_reboot>destroy</on_reboot> in the XML definition to make sure that once the installation process is done and the VM is rebooted it is actually destroyed and started again using the second XML. The runtime XML definition is lacking the installation data and also the <on_reboot> element.

In case of windows the process is a bit more complicated because the reboot happens in the middle of the installation process and usually the installation media is required after the reboot as well so it remains in the second XML as well.

Now some notes on the command line that you are using:


--boot cdrom

No need to use this option if you use --cdrom /path/to/iso, virt-install sets cdrom as the first boot option automatically in the first XML because it know that the installation will be from CDROM
in the second XML the default boot will be from disk, because that's what usually users need.  My guess here is that you use this option because you are running the installation manually using virsh.

--os-type=winxp

No need to use this option, it is now ignored, the usage of --os-variant is sufficient.

Comment 4 Dariusz Wojewódzki 2020-01-25 19:56:04 UTC
> Additional note, why are you passing the XML from virt-install to virsh if you can let virt-install do the job for you?

On a clean hypervisor You may want to initially prepare set of vms. I do not mean real vm installation but rather just a domain registration for future use.




> If the VM install has multiple phases, by default this will print all generated XML. If you want to print a particular step, use --print-xml 2 (for the second phase XML).

This is true, however output redirection may cause some complications.
Let me add here some additional observations:



ex.

The following cmd will produce full XML (with two parts)

[root@dwlab ~]# virt-install  --name rhel8 --memory 2048 --vcpus 2 --disk size=8 --location /var/lib/libvirt/images/rhel-8.1-x86_64-dvd.iso --os-variant rhel8.1 --dry-run --print-xml |egrep -e "domain type|iso"
<domain type="kvm">
      <source file="/var/lib/libvirt/images/rhel-8.1-x86_64-dvd.iso"/>
<domain type="kvm">




If You want 1st part only use --print-xml 1

[root@dwlab ~]# virt-install  --name rhel8 --memory 2048 --vcpus 2 --disk size=8 --location /var/lib/libvirt/images/rhel-8.1-x86_64-dvd.iso --os-variant rhel8.1 --dry-run --print-xml 1|egrep -e "domain type|iso"
<domain type="kvm">
      <source file="/var/lib/libvirt/images/rhel-8.1-x86_64-dvd.iso"/>




--print-xml 1 with stdout redirection to file will give You two xml parts again !

[root@dwlab ~]# virt-install  --name rhel8 --memory 2048 --vcpus 2 --disk size=8 --location /var/lib/libvirt/images/rhel-8.1-x86_64-dvd.iso --os-variant rhel8.1 --dry-run --print-xml 1>/tmp/rhel8.xml


The XML file will contain two parts despite the fact of using `--print-xml 1` 

[root@dwlab ~]# egrep -e "domain type|iso" /tmp/rhel8.xml
<domain type="kvm">
      <source file="/var/lib/libvirt/images/rhel-8.1-x86_64-dvd.iso"/>
<domain type="kvm">



In case You need output redirection to file,  there is another helpful option: --print-step:

ex with --print-step 1  --print-xml > /tmp/rhel8.xml You will get just the first part in xml file.


hth

Comment 5 Pavel Hrdina 2020-01-27 08:49:30 UTC
(In reply to Dariusz Wojewódzki from comment #4)
> > Additional note, why are you passing the XML from virt-install to virsh if you can let virt-install do the job for you?
> 
> On a clean hypervisor You may want to initially prepare set of vms. I do not
> mean real vm installation but rather just a domain registration for future
> use.

For that case you should use --import as an installation method.  The install step usually contains some additional data that may not work without virt-install being involved.

For example in case of --location virt-install fetches initrd and vmlinuz to temporary directory and configure these as the boot method for step 1 (the installation step) which results to have this part in the XML:

  <os>
    <kernel>/var/lib/libvirt/boot/virtinst-9a_kumj4-vmlinuz</kernel>
    <initrd>/var/lib/libvirt/boot/virtinst-ufh3fvg8-initrd.img</initrd>
  </os>

Obviously that cannot be used later since the files will not exist anymore.  In addition every installation method that has multiple steps puts this into XML:

  <on_reboot>destroy</on_reboot>

Which forces the VM to be destroyed on reboot to make sure that the following boot of the VM will lack the installation data that are in the step 1 XML.

If I remember correctly the only installation method that has only single step is --import and that one is the ideal option to prepare VMs that can be installed/used later.

In your case you can use this to precreate VMs for later use:

virt-install --name kvm17826 --memory 8000 --vcpus 4,maxvcpus=32 --import --disk /dev/kvm-storage/465-1b3f4da7-f195-48c6-b659-45258309d112,bus=sata,cache=none --disk /opt/iso/SW_DVD9_Win_Server_STD_CORE_2019_1809.1_64Bit_English_DC_STD_MLF_X22-02970.ISO,device=cdrom --boot cdrom --os-variant=win2k19 --network network="Public Network",model=e1000,target=k1786-MJceW --graphics vnc,listen=0.0.0.0,keymap=en-us,password=kgqOTcmG4 --cpu host --noautoconsole

There difference here is that --import is used and instead of --cdrom the ISO image is defined using --disk with device=cdrom.

This will produce only single XML without any installation data included in the XML.

> > If the VM install has multiple phases, by default this will print all generated XML. If you want to print a particular step, use --print-xml 2 (for the second phase XML).
> 
> This is true, however output redirection may cause some complications.
> Let me add here some additional observations:
> 
> 
> 
> ex.
> 
> The following cmd will produce full XML (with two parts)
> 
> [root@dwlab ~]# virt-install  --name rhel8 --memory 2048 --vcpus 2 --disk
> size=8 --location /var/lib/libvirt/images/rhel-8.1-x86_64-dvd.iso
> --os-variant rhel8.1 --dry-run --print-xml |egrep -e "domain type|iso"
> <domain type="kvm">
>       <source file="/var/lib/libvirt/images/rhel-8.1-x86_64-dvd.iso"/>
> <domain type="kvm">
> 
> 
> 
> 
> If You want 1st part only use --print-xml 1
> 
> [root@dwlab ~]# virt-install  --name rhel8 --memory 2048 --vcpus 2 --disk
> size=8 --location /var/lib/libvirt/images/rhel-8.1-x86_64-dvd.iso
> --os-variant rhel8.1 --dry-run --print-xml 1|egrep -e "domain type|iso"
> <domain type="kvm">
>       <source file="/var/lib/libvirt/images/rhel-8.1-x86_64-dvd.iso"/>
> 
> 
> 
> 
> --print-xml 1 with stdout redirection to file will give You two xml parts
> again !
> 
> [root@dwlab ~]# virt-install  --name rhel8 --memory 2048 --vcpus 2 --disk
> size=8 --location /var/lib/libvirt/images/rhel-8.1-x86_64-dvd.iso
> --os-variant rhel8.1 --dry-run --print-xml 1>/tmp/rhel8.xml

The complication here is that you are using bash incorrectly.  Spaces are important and has certain meaning.  In this case the '1' is not consumed by --print-xml option but it's part of the redirection.  1> means redirect only stdout, 2> means redirect only stderr and so on, you can see the description here [1].

> The XML file will contain two parts despite the fact of using `--print-xml
> 1` 
> 
> [root@dwlab ~]# egrep -e "domain type|iso" /tmp/rhel8.xml
> <domain type="kvm">
>       <source file="/var/lib/libvirt/images/rhel-8.1-x86_64-dvd.iso"/>
> <domain type="kvm">
> 
> 
> 
> In case You need output redirection to file,  there is another helpful
> option: --print-step:
> 
> ex with --print-step 1  --print-xml > /tmp/rhel8.xml You will get just the
> first part in xml file.

Option --print-step is deprecated and --print-xml replaces that one completely.  The only reason why --print-step works for you is because of the space mistake described above.

[1] <https://www.tldp.org/LDP/abs/html/io-redirection.html>


Note You need to log in before you can comment on or make changes to this bug.