mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-01-11 05:17:59 +03:00
Guest: Convert to new style XML prop, drop a bunch of XML infrastructure
Now every XML property is new style, without explicit local get/set handlers. Drop a bunch of XML infrastructure that was helping with the transition.
This commit is contained in:
parent
4e4ce6d395
commit
2ba3ec2684
@ -20,9 +20,9 @@
|
||||
<devices>
|
||||
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||
<disk type="block" device="floppy">
|
||||
<driver type="vmdk"/>
|
||||
<target dev="fda" bus="fdc"/>
|
||||
<address type="drive" controller="0" bus="0" target="0" unit="0"/>
|
||||
<driver type="vmdk"/>
|
||||
<source dev="/disk-pool/diskvol1-clone"/>
|
||||
</disk>
|
||||
<disk type="block" device="disk">
|
||||
|
@ -9,7 +9,9 @@
|
||||
<boot dev="network"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
@ -35,7 +37,9 @@
|
||||
<boot dev="network"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -9,7 +9,9 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -11,7 +11,9 @@
|
||||
<cmdline>method=tests/cli-test-xml/faketree console=ttyS0</cmdline>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<cpu mode="custom" match="exact">
|
||||
<model>core2duo</model>
|
||||
@ -65,7 +67,9 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<cpu mode="custom" match="exact">
|
||||
<model>core2duo</model>
|
||||
|
@ -9,7 +9,9 @@
|
||||
<boot dev="fd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,9 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="localtime"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
@ -53,7 +55,9 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="localtime"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
@ -96,7 +100,9 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="localtime"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -6,7 +6,8 @@
|
||||
<vcpu>1</vcpu>
|
||||
<bootloader>/usr/bin/pygrub</bootloader>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
|
@ -14,7 +14,9 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
@ -100,7 +102,9 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -9,7 +9,9 @@
|
||||
<boot dev="network"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -9,7 +9,9 @@
|
||||
<boot dev="cdrom"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<cpu mode="custom" match="exact">
|
||||
<model>Penryn</model>
|
||||
|
@ -9,7 +9,9 @@
|
||||
<boot dev="fd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -9,7 +9,9 @@
|
||||
<boot dev="network"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
@ -35,7 +37,9 @@
|
||||
<boot dev="network"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,9 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<cpu>
|
||||
<topology sockets="1" cores="4" threads="1"/>
|
||||
@ -48,7 +50,9 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<cpu>
|
||||
<topology sockets="1" cores="4" threads="1"/>
|
||||
@ -86,7 +90,9 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<cpu>
|
||||
<topology sockets="1" cores="4" threads="1"/>
|
||||
|
@ -6,7 +6,8 @@
|
||||
<vcpu>1</vcpu>
|
||||
<bootloader>/usr/bin/pygrub</bootloader>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
|
@ -11,7 +11,9 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -6,7 +6,8 @@
|
||||
<vcpu>1</vcpu>
|
||||
<bootloader>/usr/bin/pygrub</bootloader>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
|
@ -12,7 +12,8 @@
|
||||
<cmdline>method=tests/cli-test-xml/faketree</cmdline>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
@ -48,7 +49,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -11,7 +11,8 @@
|
||||
<cmdline>method=tests/cli-test-xml/faketree</cmdline>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>destroy</on_reboot>
|
||||
@ -40,7 +41,8 @@
|
||||
<vcpu>1</vcpu>
|
||||
<bootloader>/usr/bin/pygrub</bootloader>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
|
@ -11,7 +11,8 @@
|
||||
<cmdline>method=tests/cli-test-xml/faketree</cmdline>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>destroy</on_reboot>
|
||||
@ -40,7 +41,8 @@
|
||||
<vcpu>1</vcpu>
|
||||
<bootloader>/usr/bin/pygrub</bootloader>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
|
@ -9,7 +9,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -9,7 +9,9 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/><pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -3,14 +3,15 @@
|
||||
<uuid>12345678-1234-1234-1234-123456789012</uuid>
|
||||
<memory>409600</memory>
|
||||
<currentMemory>204800</currentMemory>
|
||||
<vcpu cpuset="0,1,2,3,4,5,6,7" current="5">7</vcpu>
|
||||
<vcpu cpuset="0,1,2,3,4,5,6,7">7</vcpu>
|
||||
<os>
|
||||
<type arch="i686">hvm</type>
|
||||
<loader>/usr/lib/xen/boot/hvmloader</loader>
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<cpu match="minimum" mode="custom">
|
||||
<model>footest</model>
|
||||
|
@ -1,38 +0,0 @@
|
||||
<domain type="xen">
|
||||
<name>TestGuest</name>
|
||||
<uuid>12345678-1234-1234-1234-123456789012</uuid>
|
||||
<memory>409600</memory>
|
||||
<currentMemory>204800</currentMemory>
|
||||
<vcpu>5</vcpu>
|
||||
<os>
|
||||
<type arch="i686">hvm</type>
|
||||
<loader>/usr/lib/xen/boot/hvmloader</loader>
|
||||
<boot dev="network"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||
<interface type="bridge">
|
||||
<source bridge="br0"/>
|
||||
<mac address="22:22:33:44:55:66"/>
|
||||
</interface>
|
||||
<interface type="bridge">
|
||||
<mac address="22:22:33:44:55:67"/>
|
||||
<source bridge="foobr0"/>
|
||||
</interface>
|
||||
|
||||
<interface type="bridge">
|
||||
<mac address="22:22:33:44:55:68"/>
|
||||
</interface>
|
||||
|
||||
<input type="mouse" bus="ps2"/>
|
||||
<graphics type="sdl" display=":3.4" xauth="/tmp/.Xauthority"/>
|
||||
<console type="pty"/>
|
||||
</devices>
|
||||
</domain>
|
@ -10,7 +10,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -11,7 +11,8 @@
|
||||
<bootmenu enable="yes"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="network"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="network"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -14,7 +14,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="localtime"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
@ -40,11 +41,11 @@
|
||||
<target dev="sdb" bus="scsi"/>
|
||||
<address type="spapr-vio"/>
|
||||
</disk>
|
||||
<controller type="ide" index="3"/>
|
||||
<controller type="virtio-serial" index="0" ports="32" vectors="17"/>
|
||||
<controller type="scsi" index="0">
|
||||
<address type="spapr-vio"/>
|
||||
</controller>
|
||||
<controller type="ide" index="3"/>
|
||||
<controller type="virtio-serial" index="0" ports="32" vectors="17"/>
|
||||
<interface type="network">
|
||||
<source network="default"/>
|
||||
<mac address="22:22:33:44:55:66"/>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="network"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="network"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="network"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="network"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -9,7 +9,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -9,7 +9,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -9,7 +9,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -9,7 +9,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -9,7 +9,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -11,7 +11,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -11,7 +11,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -12,7 +12,8 @@
|
||||
<cmdline>my kernel args</cmdline>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -14,7 +14,8 @@
|
||||
<bootmenu enable="no"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="cdrom"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="network"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -11,7 +11,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -11,7 +11,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="localtime"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -11,7 +11,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -11,7 +11,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -11,7 +11,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -11,7 +11,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -14,7 +14,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -11,7 +11,8 @@
|
||||
<cmdline>method=tests/cli-test-xml/fakerhel6tree</cmdline>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -9,7 +9,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -10,7 +10,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="localtime"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -9,7 +9,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="localtime"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -9,7 +9,8 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<clock offset="localtime"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
|
@ -877,7 +877,7 @@ class TestXMLConfig(unittest.TestCase):
|
||||
# Cpuset
|
||||
cpustr = g.generate_cpuset(g.conn, g.memory)
|
||||
g.cpuset = cpustr
|
||||
g.maxvcpus = 7
|
||||
g.vcpus = 7
|
||||
|
||||
g.cpu.model = "footest"
|
||||
g.cpu.vendor = "Intel"
|
||||
@ -920,7 +920,8 @@ class TestXMLConfig(unittest.TestCase):
|
||||
i = utils.make_pxe_installer()
|
||||
g = utils.get_basic_fullyvirt_guest(installer=i)
|
||||
|
||||
g.add_usb_ich9_controllers()
|
||||
for dev in virtinst.VirtualController.get_usb2_controllers(g.conn):
|
||||
g.add_device(dev)
|
||||
|
||||
self._compare(g, "boot-usb2", False)
|
||||
|
||||
@ -969,35 +970,41 @@ class TestXMLConfig(unittest.TestCase):
|
||||
origfunc = None
|
||||
util = None
|
||||
try:
|
||||
i = utils.make_pxe_installer()
|
||||
g = utils.get_basic_fullyvirt_guest(installer=i)
|
||||
util = getattr(virtinst, "util")
|
||||
origfunc = util.default_bridge
|
||||
|
||||
def newbridge(ignore_conn):
|
||||
return ["bridge", "br0"]
|
||||
return ["bridge", "bzz0"]
|
||||
util.default_bridge = newbridge
|
||||
|
||||
dev1 = virtinst.VirtualNetworkInterface(g.conn)
|
||||
dev1 = virtinst.VirtualNetworkInterface(utils.get_conn())
|
||||
dev1.macaddr = "22:22:33:44:55:66"
|
||||
g.add_device(dev1)
|
||||
|
||||
dev2 = virtinst.VirtualNetworkInterface(g.conn,
|
||||
parsexml=dev1.get_xml_config().strip("\n"))
|
||||
dev2 = virtinst.VirtualNetworkInterface(utils.get_conn(),
|
||||
parsexml=dev1.get_xml_config())
|
||||
dev2.source = None
|
||||
dev2.source = "foobr0"
|
||||
dev2.macaddr = "22:22:33:44:55:67"
|
||||
g.add_device(dev2)
|
||||
|
||||
dev3 = virtinst.VirtualNetworkInterface(g.conn,
|
||||
parsexml=dev1.get_xml_config().strip("\n"))
|
||||
dev3 = virtinst.VirtualNetworkInterface(utils.get_conn(),
|
||||
parsexml=dev1.get_xml_config())
|
||||
dev3.source = None
|
||||
dev3.macaddr = "22:22:33:44:55:68"
|
||||
g.add_device(dev3)
|
||||
|
||||
self._compare(g, "boot-default-bridge", False, do_create=False)
|
||||
dev3.type = dev3.TYPE_USER
|
||||
self._compare(g, None, False)
|
||||
utils.diff_compare(dev1.get_xml_config(), None,
|
||||
" <interface type=\"bridge\">\n"
|
||||
" <source bridge=\"bzz0\"/>\n"
|
||||
" <mac address=\"22:22:33:44:55:66\"/>\n"
|
||||
" </interface>")
|
||||
utils.diff_compare(dev2.get_xml_config(), None,
|
||||
"<interface type=\"bridge\">\n"
|
||||
" <mac address=\"22:22:33:44:55:67\"/>\n"
|
||||
" <source bridge=\"foobr0\"/>\n"
|
||||
" </interface>\n")
|
||||
utils.diff_compare(dev3.get_xml_config(), None,
|
||||
"<interface type=\"bridge\">\n"
|
||||
" <mac address=\"22:22:33:44:55:68\"/>\n"
|
||||
" </interface>\n")
|
||||
finally:
|
||||
if util and origfunc:
|
||||
util.default_bridge = origfunc
|
||||
|
@ -24,9 +24,9 @@
|
||||
<feature name="addfeature" policy="require"/>
|
||||
</cpu>
|
||||
<clock offset="localtime"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<on_poweroff>restart</on_poweroff>
|
||||
<on_reboot>destroy</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<vcpu cpuset="1-5,15" current="10">12</vcpu>
|
||||
<devices>
|
||||
<emulator>/usr/binnnn/fooemu</emulator>
|
||||
|
@ -103,8 +103,8 @@ class XMLParseTest(unittest.TestCase):
|
||||
check = self._make_checker(guest)
|
||||
check("name", "TestGuest", "change_name")
|
||||
check("description", None, "Hey desc changed&")
|
||||
check("maxvcpus", 5, 12)
|
||||
check("vcpus", 12, 10)
|
||||
check("vcpus", 5, 12)
|
||||
check("curvcpus", None, 10)
|
||||
check("cpuset", "1-3", "1-8,^6", "1-5,15")
|
||||
check("maxmemory", 409600, 512000)
|
||||
check("memory", 204800, 1024000)
|
||||
@ -115,6 +115,9 @@ class XMLParseTest(unittest.TestCase):
|
||||
check("hugepage", False, True)
|
||||
check("type", "kvm", "test")
|
||||
check("bootloader", None, "pygrub")
|
||||
check("on_poweroff", "destroy", "restart")
|
||||
check("on_reboot", "restart", "destroy")
|
||||
check("on_crash", "restart", "destroy")
|
||||
|
||||
check = self._make_checker(guest.clock)
|
||||
check("offset", "utc", "localtime")
|
||||
|
@ -480,8 +480,8 @@ class vmmDomain(vmmLibvirtObject):
|
||||
# CPU define methods
|
||||
def define_vcpus(self, vcpus, maxvcpus):
|
||||
def change(guest):
|
||||
guest.vcpus = int(vcpus)
|
||||
guest.maxvcpus = int(maxvcpus)
|
||||
guest.curvcpus = int(vcpus)
|
||||
guest.vcpus = int(maxvcpus)
|
||||
return self._redefine_guest(change)
|
||||
def define_cpuset(self, cpuset):
|
||||
def change(guest):
|
||||
@ -813,7 +813,9 @@ class vmmDomain(vmmLibvirtObject):
|
||||
guest.remove_device(dev)
|
||||
|
||||
if newmodel == "ich9-ehci1":
|
||||
guest.add_usb_ich9_controllers()
|
||||
for dev in virtinst.VirtualController.get_usb2_controllers(
|
||||
guest.conn):
|
||||
guest.add_device(dev)
|
||||
|
||||
return self._redefine_device(change, devobj)
|
||||
|
||||
@ -986,9 +988,9 @@ class vmmDomain(vmmLibvirtObject):
|
||||
return int(self._get_guest().vcpus)
|
||||
def vcpu_max_count(self):
|
||||
guest = self._get_guest()
|
||||
has_xml_max = (guest.vcpus != guest.maxvcpus)
|
||||
has_xml_max = (guest.curvcpus != guest.vcpus)
|
||||
if has_xml_max or not self.is_active():
|
||||
return guest.maxvcpus
|
||||
return guest.vcpus
|
||||
|
||||
if self._startup_vcpus is None:
|
||||
self._startup_vcpus = int(self.vcpu_count())
|
||||
|
@ -19,8 +19,6 @@
|
||||
|
||||
from virtinst.xmlbuilder import XMLBuilder, XMLProperty
|
||||
|
||||
import libxml2
|
||||
|
||||
|
||||
class CPUFeature(XMLBuilder):
|
||||
"""
|
||||
@ -31,7 +29,6 @@ class CPUFeature(XMLBuilder):
|
||||
|
||||
_XML_PROP_ORDER = ["_xmlname", "policy"]
|
||||
_XML_ROOT_NAME = "cpu"
|
||||
_XML_XPATH_RELATIVE = True
|
||||
_XML_INDENT = 4
|
||||
|
||||
def __init__(self, conn, name, parsexml=None, parsexmlnode=None):
|
||||
@ -47,13 +44,13 @@ class CPUFeature(XMLBuilder):
|
||||
def _name_xpath(self):
|
||||
return "./cpu/feature[@name='%s']/@name" % self._name
|
||||
_xmlname = XMLProperty(name="feature name",
|
||||
xml_get_xpath=_name_xpath,
|
||||
xml_set_xpath=_name_xpath)
|
||||
make_getter_xpath_cb=_name_xpath,
|
||||
make_setter_xpath_cb=_name_xpath)
|
||||
def _policy_xpath(self):
|
||||
return "./cpu/feature[@name='%s']/@policy" % self._name
|
||||
policy = XMLProperty(name="feature policy",
|
||||
xml_get_xpath=_policy_xpath,
|
||||
xml_set_xpath=_policy_xpath)
|
||||
make_getter_xpath_cb=_policy_xpath,
|
||||
make_setter_xpath_cb=_policy_xpath)
|
||||
|
||||
def clear(self):
|
||||
self.policy = None
|
||||
@ -70,13 +67,11 @@ class CPU(XMLBuilder):
|
||||
_dumpxml_xpath = "/domain/cpu"
|
||||
_XML_ROOT_NAME = "cpu"
|
||||
_XML_INDENT = 2
|
||||
_XML_XPATH_RELATIVE = True
|
||||
_XML_PROP_ORDER = ["mode", "match", "model", "vendor",
|
||||
"sockets", "cores", "threads"]
|
||||
"sockets", "cores", "threads", "_features"]
|
||||
|
||||
def __init__(self, conn, parsexml=None, parsexmlnode=None):
|
||||
self._features = []
|
||||
self._XML_SUB_ELEMENTS = self._XML_SUB_ELEMENTS + ["_features"]
|
||||
XMLBuilder.__init__(self, conn, parsexml, parsexmlnode)
|
||||
|
||||
def _parsexml(self, xml, node):
|
||||
|
@ -24,6 +24,5 @@ class Clock(XMLBuilder):
|
||||
_dumpxml_xpath = "/domain/clock"
|
||||
_XML_INDENT = 2
|
||||
_XML_ROOT_NAME = "clock"
|
||||
_XML_XPATH_RELATIVE = True
|
||||
|
||||
offset = XMLProperty(xpath="./clock/@offset")
|
||||
|
@ -101,7 +101,7 @@ class Cloner(object):
|
||||
return self._clone_name
|
||||
def set_clone_name(self, name):
|
||||
try:
|
||||
self._valid_guest.set_name(name)
|
||||
self._valid_guest.name = name
|
||||
except ValueError, e:
|
||||
raise ValueError(_("Invalid name for new guest: %s") % e)
|
||||
|
||||
@ -111,7 +111,7 @@ class Cloner(object):
|
||||
|
||||
def set_clone_uuid(self, uuid):
|
||||
try:
|
||||
self._valid_guest.set_uuid(uuid)
|
||||
self._valid_guest.uuid = uuid
|
||||
except ValueError, e:
|
||||
raise ValueError(_("Invalid uuid for new guest: %s") % e)
|
||||
|
||||
|
@ -286,7 +286,7 @@ class DistroInstaller(Installer.Installer):
|
||||
guest.os.os_type)
|
||||
(kernelfn, initrdfn, args) = media
|
||||
|
||||
if guest.get_os_autodetect():
|
||||
if guest.os_autodetect:
|
||||
if os_type:
|
||||
logging.debug("Auto detected OS type as: %s", os_type)
|
||||
guest.os_type = os_type
|
||||
|
@ -27,7 +27,6 @@ class DomainFeatures(XMLBuilder):
|
||||
_dumpxml_xpath = "/domain/features"
|
||||
_XML_ROOT_NAME = "features"
|
||||
_XML_INDENT = 2
|
||||
_XML_XPATH_RELATIVE = True
|
||||
_XML_PROP_ORDER = ["acpi", "apic", "pae"]
|
||||
|
||||
acpi = XMLProperty(xpath="./features/acpi", is_tri=True)
|
||||
@ -40,9 +39,3 @@ class DomainFeatures(XMLBuilder):
|
||||
return getattr(self, attr)
|
||||
def __delitem__(self, attr):
|
||||
return setattr(self, attr, None)
|
||||
|
||||
def _cleanup_xml(self, xml):
|
||||
# Format it in the old style
|
||||
xml = xml.replace("\n ", "")
|
||||
xml = xml.replace("<features>", "<features>\n ")
|
||||
return xml
|
||||
|
@ -98,7 +98,6 @@ class DomainNumatune(XMLBuilder):
|
||||
_dumpxml_xpath = "/domain/numatune"
|
||||
_XML_ROOT_NAME = "numatune"
|
||||
_XML_INDENT = 2
|
||||
_XML_XPATH_RELATIVE = True
|
||||
_XML_PROP_ORDER = ["memory_mode", "memory_nodeset"]
|
||||
|
||||
memory_nodeset = XMLProperty(xpath="./numatune/memory/@nodeset")
|
||||
|
@ -35,8 +35,6 @@ from virtinst.osxml import OSXML
|
||||
from virtinst.xmlbuilder import XMLBuilder, XMLProperty
|
||||
from virtinst.VirtualDevice import VirtualDevice
|
||||
from virtinst.VirtualDisk import VirtualDisk
|
||||
from virtinst.VirtualInputDevice import VirtualInputDevice
|
||||
from virtinst.VirtualController import VirtualController
|
||||
from virtinst.Clock import Clock
|
||||
from virtinst.Seclabel import Seclabel
|
||||
from virtinst.CPU import CPU
|
||||
@ -163,27 +161,22 @@ class Guest(XMLBuilder):
|
||||
|
||||
return cpustr
|
||||
|
||||
|
||||
_XML_ROOT_NAME = "domain"
|
||||
_XML_INDENT = 0
|
||||
_XML_PROP_ORDER = ["type", "name", "uuid", "description",
|
||||
"maxmemory", "memory", "hugepage", "vcpus", "curvcpus",
|
||||
"numatune", "bootloader", "os", "features", "cpu", "clock",
|
||||
"on_poweroff", "on_reboot", "on_crash", "emulator", "all_devices",
|
||||
"seclabel"]
|
||||
|
||||
def __init__(self, conn, parsexml=None, parsexmlnode=None):
|
||||
self._name = None
|
||||
self._uuid = None
|
||||
self._memory = None
|
||||
self._maxmemory = None
|
||||
self._hugepage = None
|
||||
self._vcpus = 1
|
||||
self._maxvcpus = 1
|
||||
self._cpuset = None
|
||||
self._autostart = False
|
||||
self._clock = None
|
||||
self._seclabel = None
|
||||
self._description = None
|
||||
self._features = None
|
||||
self._replace = None
|
||||
self._emulator = None
|
||||
self._type = None
|
||||
self.autostart = False
|
||||
self.replace = False
|
||||
self.os_autodetect = False
|
||||
|
||||
self._os_type = None
|
||||
self._os_variant = None
|
||||
self._os_autodetect = False
|
||||
|
||||
self.installer = None
|
||||
|
||||
@ -204,8 +197,6 @@ class Guest(XMLBuilder):
|
||||
|
||||
self.installer = virtinst.DistroInstaller(conn)
|
||||
|
||||
self._type = "xen"
|
||||
|
||||
# Need to do this after all parameter init
|
||||
self.os = OSXML(self.conn, parsexml, parsexmlnode)
|
||||
self.features = DomainFeatures(self.conn)
|
||||
@ -219,123 +210,73 @@ class Guest(XMLBuilder):
|
||||
# Property accessors #
|
||||
######################
|
||||
|
||||
# Domain name of the guest
|
||||
def get_name(self):
|
||||
return self._name
|
||||
def set_name(self, val):
|
||||
def _validate_name(self, val):
|
||||
if val == self.name:
|
||||
return
|
||||
|
||||
util.validate_name(_("Guest"), val, lencheck=True)
|
||||
if self.replace:
|
||||
return
|
||||
|
||||
do_fail = False
|
||||
if self.replace is not True:
|
||||
try:
|
||||
self.conn.lookupByName(val)
|
||||
do_fail = True
|
||||
except:
|
||||
# Name not found
|
||||
pass
|
||||
try:
|
||||
self.conn.lookupByName(val)
|
||||
except:
|
||||
return
|
||||
raise ValueError(_("Guest name '%s' is already in use.") % val)
|
||||
name = XMLProperty(xpath="./name", validate_cb=_validate_name)
|
||||
|
||||
if do_fail:
|
||||
raise ValueError(_("Guest name '%s' is already in use.") % val)
|
||||
|
||||
self._name = val
|
||||
name = XMLProperty(get_name, set_name,
|
||||
xpath="./name")
|
||||
|
||||
# Memory allocated to the guest. Should be given in MB
|
||||
def get_memory(self):
|
||||
return self._memory
|
||||
def set_memory(self, val):
|
||||
self._memory = val
|
||||
def _set_memory(self, val):
|
||||
if val is None:
|
||||
return None
|
||||
|
||||
if self.maxmemory is None or self.maxmemory < val:
|
||||
self.maxmemory = val
|
||||
memory = XMLProperty(get_memory, set_memory, is_int=True,
|
||||
xpath="./currentMemory")
|
||||
|
||||
# Memory allocated to the guest. Should be given in MB
|
||||
def get_maxmemory(self):
|
||||
return self._maxmemory
|
||||
def set_maxmemory(self, val):
|
||||
self._maxmemory = val
|
||||
maxmemory = XMLProperty(get_maxmemory, set_maxmemory, is_int=True,
|
||||
xpath="./memory")
|
||||
|
||||
def get_hugepage(self):
|
||||
return self._hugepage
|
||||
def set_hugepage(self, val):
|
||||
if val is None:
|
||||
return val
|
||||
self._hugepage = bool(val)
|
||||
hugepage = XMLProperty(get_hugepage, set_hugepage,
|
||||
xpath="./memoryBacking/hugepages", is_bool=True)
|
||||
|
||||
# UUID for the guest
|
||||
def get_uuid(self):
|
||||
return self._uuid
|
||||
def set_uuid(self, val):
|
||||
val = util.validate_uuid(val)
|
||||
self._uuid = val
|
||||
uuid = XMLProperty(get_uuid, set_uuid,
|
||||
xpath="./uuid")
|
||||
|
||||
def __validate_cpus(self, val):
|
||||
val = int(val)
|
||||
if val < 1:
|
||||
raise ValueError(_("Number of vcpus must be a positive integer."))
|
||||
return val
|
||||
memory = XMLProperty(xpath="./currentMemory", is_int=True,
|
||||
default_cb=lambda s: 1,
|
||||
set_converter=_set_memory)
|
||||
maxmemory = XMLProperty(xpath="./memory", is_int=True)
|
||||
|
||||
# number of vcpus for the guest
|
||||
def get_vcpus(self):
|
||||
return self._vcpus
|
||||
def set_vcpus(self, val):
|
||||
val = self.__validate_cpus(val)
|
||||
self._vcpus = val
|
||||
def _set_vcpus(self, val):
|
||||
if val is None:
|
||||
return None
|
||||
|
||||
# Don't force set maxvcpus unless already specified
|
||||
if self.maxvcpus is not None and self.maxvcpus < val:
|
||||
self.maxvcpus = val
|
||||
def _vcpus_get_converter(self, val):
|
||||
# If no current VCPUs, return maxvcpus
|
||||
if not val:
|
||||
val = self.maxvcpus
|
||||
return int(val)
|
||||
vcpus = XMLProperty(get_vcpus, set_vcpus,
|
||||
xpath="./vcpu/@current",
|
||||
get_converter=_vcpus_get_converter)
|
||||
|
||||
def _get_maxvcpus(self):
|
||||
return self._maxvcpus
|
||||
def _set_maxvcpus(self, val):
|
||||
val = self.__validate_cpus(val)
|
||||
self._maxvcpus = val
|
||||
maxvcpus = XMLProperty(_get_maxvcpus, _set_maxvcpus,
|
||||
xpath="./vcpu", is_int=True)
|
||||
|
||||
# set phy-cpus for the guest
|
||||
def get_cpuset(self):
|
||||
return self._cpuset
|
||||
def set_cpuset(self, val):
|
||||
if val is None or val == "":
|
||||
self._cpuset = None
|
||||
return
|
||||
# Don't force set curvcpus unless already specified
|
||||
if self.curvcpus is not None and self.curvcpus > val:
|
||||
self.curvcpus = val
|
||||
return val
|
||||
vcpus = XMLProperty(xpath="./vcpu", is_int=True,
|
||||
set_converter=_set_vcpus,
|
||||
default_cb=lambda s: 1)
|
||||
curvcpus = XMLProperty(xpath="./vcpu/@current", is_int=True)
|
||||
|
||||
def _validate_cpuset(self, val):
|
||||
DomainNumatune.validate_cpuset(self.conn, val)
|
||||
self._cpuset = val
|
||||
cpuset = XMLProperty(get_cpuset, set_cpuset,
|
||||
xpath="./vcpu/@cpuset")
|
||||
cpuset = XMLProperty(xpath="./vcpu/@cpuset",
|
||||
validate_cb=_validate_cpuset)
|
||||
|
||||
type = XMLProperty(xpath="./@type", default_cb=lambda s: "xen")
|
||||
hugepage = XMLProperty(xpath="./memoryBacking/hugepages", is_bool=True)
|
||||
uuid = XMLProperty(xpath="./uuid",
|
||||
validate_cb=lambda s, v: util.validate_uuid(v))
|
||||
bootloader = XMLProperty(xpath="./bootloader")
|
||||
description = XMLProperty(xpath="./description")
|
||||
emulator = XMLProperty(xpath="./devices/emulator")
|
||||
|
||||
on_poweroff = XMLProperty(xpath="./on_poweroff",
|
||||
default_cb=lambda s: "destroy")
|
||||
on_reboot = XMLProperty(xpath="./on_reboot")
|
||||
on_crash = XMLProperty(xpath="./on_crash")
|
||||
|
||||
|
||||
###############################
|
||||
# Distro detection properties #
|
||||
###############################
|
||||
|
||||
# GAH! - installer.os_type = "hvm" or "xen" (aka xen paravirt)
|
||||
# guest.os_type = "Solaris", "Windows", "Linux"
|
||||
# FIXME: We should really rename this property to something else,
|
||||
# change it throughout the codebase for readability sake, but
|
||||
# maintain back compat.
|
||||
def get_os_type(self):
|
||||
return self._os_type
|
||||
def set_os_type(self, val):
|
||||
if type(val) is not str:
|
||||
raise ValueError(_("OS type must be a string."))
|
||||
val = val.lower()
|
||||
|
||||
if val in self._OS_TYPES:
|
||||
if self._os_type != val:
|
||||
# Invalidate variant, since it may not apply to the new os type
|
||||
@ -344,14 +285,11 @@ class Guest(XMLBuilder):
|
||||
else:
|
||||
raise ValueError(_("OS type '%s' does not exist in our "
|
||||
"dictionary") % val)
|
||||
|
||||
os_type = property(get_os_type, set_os_type)
|
||||
|
||||
def get_os_variant(self):
|
||||
return self._os_variant
|
||||
def set_os_variant(self, val):
|
||||
if type(val) is not str:
|
||||
raise ValueError(_("OS variant must be a string."))
|
||||
val = val.lower()
|
||||
|
||||
if self.os_type:
|
||||
@ -374,49 +312,12 @@ class Guest(XMLBuilder):
|
||||
|
||||
if not found:
|
||||
raise ValueError(_("Unknown OS variant '%s'" % val))
|
||||
|
||||
os_variant = property(get_os_variant, set_os_variant)
|
||||
|
||||
def set_os_autodetect(self, val):
|
||||
self._os_autodetect = bool(val)
|
||||
def get_os_autodetect(self):
|
||||
return self._os_autodetect
|
||||
os_autodetect = property(get_os_autodetect, set_os_autodetect)
|
||||
|
||||
# Get the current variants 'distro' tag: 'rhel', 'fedora', etc.
|
||||
def get_os_distro(self):
|
||||
return self._lookup_osdict_key("distro")
|
||||
os_distro = property(get_os_distro)
|
||||
|
||||
def get_autostart(self):
|
||||
return self._autostart
|
||||
def set_autostart(self, val):
|
||||
self._autostart = bool(val)
|
||||
autostart = property(get_autostart, set_autostart,
|
||||
doc="Have domain autostart when the host boots.")
|
||||
|
||||
def _get_description(self):
|
||||
return self._description
|
||||
def _set_description(self, val):
|
||||
self._description = val
|
||||
description = XMLProperty(_get_description, _set_description,
|
||||
xpath="./description")
|
||||
|
||||
def _get_emulator(self):
|
||||
return self._emulator
|
||||
def _set_emulator(self, val):
|
||||
self._emulator = val
|
||||
emulator = XMLProperty(_get_emulator, _set_emulator,
|
||||
xpath="./devices/emulator")
|
||||
|
||||
def _get_replace(self):
|
||||
return self._replace
|
||||
def _set_replace(self, val):
|
||||
self._replace = bool(val)
|
||||
replace = property(_get_replace, _set_replace,
|
||||
doc=_("Whether we should overwrite an existing guest "
|
||||
"with the same name."))
|
||||
|
||||
|
||||
########################################
|
||||
# Device Add/Remove Public API methods #
|
||||
@ -450,15 +351,10 @@ class Guest(XMLBuilder):
|
||||
|
||||
self._track_device(dev)
|
||||
if set_defaults:
|
||||
def list_one_dev(devtype):
|
||||
if dev.virtual_device_type == devtype:
|
||||
return [dev][:]
|
||||
else:
|
||||
return []
|
||||
origdev = self._devices
|
||||
try:
|
||||
self._devices = [dev]
|
||||
self._set_defaults(self.features)
|
||||
self._set_device_defaults()
|
||||
except:
|
||||
self._devices = origdev
|
||||
|
||||
@ -511,13 +407,6 @@ class Guest(XMLBuilder):
|
||||
if xpath:
|
||||
self._remove_child_xpath(xpath)
|
||||
|
||||
bootloader = XMLProperty(xpath="./bootloader")
|
||||
type = XMLProperty(xpath="./@type", default_cb=lambda s: "xen")
|
||||
|
||||
def _cleanup_xml(self, xml):
|
||||
if not xml.endswith("\n"):
|
||||
xml += "\n"
|
||||
return xml
|
||||
|
||||
################################
|
||||
# Private xml building methods #
|
||||
@ -575,7 +464,7 @@ class Guest(XMLBuilder):
|
||||
def add_default_input_device(self):
|
||||
if self.os.is_container():
|
||||
return
|
||||
self.add_device(VirtualInputDevice(self.conn))
|
||||
self.add_device(virtinst.VirtualInputDevice(self.conn))
|
||||
|
||||
def add_default_console_device(self):
|
||||
if self.os.is_xenpv():
|
||||
@ -584,151 +473,6 @@ class Guest(XMLBuilder):
|
||||
dev.type = dev.TYPE_PTY
|
||||
self.add_device(dev)
|
||||
|
||||
def _get_device_xml(self, devs, install=True):
|
||||
def do_remove_media(d):
|
||||
# Keep cdrom around, but with no media attached,
|
||||
# But only if we are a distro that doesn't have a multi
|
||||
# stage install (aka not Windows)
|
||||
return (d.virtual_device_type == VirtualDevice.VIRTUAL_DEV_DISK and
|
||||
d.device == VirtualDisk.DEVICE_CDROM
|
||||
and d.transient
|
||||
and not install and
|
||||
not self.get_continue_inst())
|
||||
|
||||
def do_skip_disk(d):
|
||||
# Skip transient labeled non-media disks
|
||||
return (d.virtual_device_type == VirtualDevice.VIRTUAL_DEV_DISK and
|
||||
d.device == VirtualDisk.DEVICE_DISK
|
||||
and d.transient
|
||||
and not install)
|
||||
|
||||
# Wrapper for building disk XML, handling transient CDROMs
|
||||
def get_dev_xml(dev):
|
||||
origpath = None
|
||||
try:
|
||||
if do_skip_disk(dev):
|
||||
return ""
|
||||
|
||||
if do_remove_media(dev):
|
||||
origpath = dev.path
|
||||
dev.path = None
|
||||
|
||||
return dev.get_xml_config()
|
||||
finally:
|
||||
if origpath:
|
||||
dev.path = origpath
|
||||
def get_vscsi_ctrl_xml():
|
||||
ctrl = virtinst.VirtualController(self.conn)
|
||||
ctrl.type = "scsi"
|
||||
ctrl.address.set_addrstr("spapr-vio")
|
||||
return ctrl.get_xml_config()
|
||||
|
||||
xml = self._get_emulator_xml()
|
||||
# Build XML
|
||||
for dev in devs:
|
||||
xml = util.xml_append(xml, get_dev_xml(dev))
|
||||
if (dev.address.type == "spapr-vio" and
|
||||
dev.virtual_device_type == VirtualDevice.VIRTUAL_DEV_DISK):
|
||||
xml = util.xml_append(xml, get_vscsi_ctrl_xml())
|
||||
|
||||
return xml
|
||||
|
||||
def _get_emulator_xml(self):
|
||||
emulator = self.emulator
|
||||
if self.os.is_xenpv():
|
||||
return ""
|
||||
|
||||
if (not self.emulator and
|
||||
self.os.is_hvm() and
|
||||
self.type == "xen"):
|
||||
if self.conn.caps.host.arch in ("x86_64"):
|
||||
emulator = "/usr/lib64/xen/bin/qemu-dm"
|
||||
else:
|
||||
emulator = "/usr/lib/xen/bin/qemu-dm"
|
||||
|
||||
emu_xml = ""
|
||||
if emulator is not None:
|
||||
emu_xml = " <emulator>%s</emulator>" % emulator
|
||||
|
||||
return emu_xml
|
||||
|
||||
def _get_features_xml(self, features):
|
||||
"""
|
||||
Return features (pae, acpi, apic) xml
|
||||
"""
|
||||
if self.os.is_container():
|
||||
return ""
|
||||
return features.get_xml_config()
|
||||
|
||||
def _get_cpu_xml(self):
|
||||
"""
|
||||
Return <cpu> XML
|
||||
"""
|
||||
self.cpu.set_topology_defaults(self.vcpus)
|
||||
return self.cpu.get_xml_config()
|
||||
|
||||
def _get_clock_xml(self):
|
||||
"""
|
||||
Return <clock/> xml
|
||||
"""
|
||||
return self.clock.get_xml_config()
|
||||
|
||||
def _get_seclabel_xml(self):
|
||||
"""
|
||||
Return <seclabel> XML
|
||||
"""
|
||||
xml = ""
|
||||
if self.seclabel:
|
||||
xml = self.seclabel.get_xml_config()
|
||||
|
||||
return xml
|
||||
|
||||
def _get_default_init(self):
|
||||
for fs in self.get_devices("filesystem"):
|
||||
if fs.target == "/":
|
||||
return "/sbin/init"
|
||||
return "/bin/sh"
|
||||
|
||||
def _get_osblob(self, install):
|
||||
"""
|
||||
Return os, features, and clock xml (Implemented in subclass)
|
||||
"""
|
||||
oscopy = self.os.copy()
|
||||
self.installer.alter_bootconfig(self, install, oscopy)
|
||||
|
||||
if oscopy.is_container() and not oscopy.init:
|
||||
oscopy.init = self._get_default_init()
|
||||
if not oscopy.loader and oscopy.is_hvm() and self.type == "xen":
|
||||
oscopy.loader = "/usr/lib/xen/boot/hvmloader"
|
||||
if oscopy.os_type == "xen" and self.type == "xen":
|
||||
# Use older libvirt 'linux' value for back compat
|
||||
oscopy.os_type = "linux"
|
||||
if oscopy.kernel or oscopy.init:
|
||||
oscopy.bootorder = []
|
||||
|
||||
return oscopy.get_xml_config() or None
|
||||
|
||||
def _get_osblob_helper(self, guest, isinstall,
|
||||
bootconfig, endbootconfig):
|
||||
return self.get_xml_config()
|
||||
|
||||
def _get_vcpu_xml(self):
|
||||
curvcpus_supported = self.conn.check_conn_support(
|
||||
self.conn.SUPPORT_CONN_MAXVCPUS_XML)
|
||||
cpuset = ""
|
||||
if self.cpuset is not None:
|
||||
cpuset = " cpuset='%s'" % self.cpuset
|
||||
|
||||
maxv = self.maxvcpus
|
||||
curv = self.vcpus
|
||||
|
||||
curxml = ""
|
||||
if maxv != curv and curvcpus_supported:
|
||||
curxml = " current='%s'" % curv
|
||||
else:
|
||||
maxv = curv
|
||||
|
||||
return " <vcpu%s%s>%s</vcpu>" % (cpuset, curxml, maxv)
|
||||
|
||||
############################
|
||||
# Install Helper functions #
|
||||
@ -756,23 +500,42 @@ class Guest(XMLBuilder):
|
||||
for dev in self.get_all_devices():
|
||||
dev.setup(progresscb)
|
||||
|
||||
all_devices = property(lambda s: s.get_all_devices())
|
||||
|
||||
|
||||
##############
|
||||
# Public API #
|
||||
##############
|
||||
|
||||
def _get_xml_config(self, *args, **kwargs):
|
||||
def _prepare_get_xml(self):
|
||||
# We do a shallow copy of the device list here, and set the defaults.
|
||||
# This way, default changes aren't persistent, and we don't need
|
||||
# to worry about when to call set_defaults
|
||||
origdevs = self._devices
|
||||
data = (self._devices, self.features, self.os)
|
||||
try:
|
||||
self._devices = [dev.copy() for dev in self._devices]
|
||||
return self._do_get_xml_config(*args, **kwargs)
|
||||
finally:
|
||||
self._devices = origdevs
|
||||
self.features = self.features.copy()
|
||||
self.os = self.os.copy()
|
||||
except:
|
||||
self._finish_get_xml(data)
|
||||
raise
|
||||
return data
|
||||
|
||||
def _finish_get_xml(self, data):
|
||||
self._devices, self.features, self.os = data
|
||||
|
||||
def _do_get_xml_config(self, install=True, disk_boot=False):
|
||||
def _cleanup_xml(self, xml):
|
||||
lines = xml.splitlines()
|
||||
newlines = []
|
||||
for line in lines:
|
||||
newlines.append(line)
|
||||
|
||||
xml = "\n".join(newlines)
|
||||
if not xml.endswith("\n"):
|
||||
xml += "\n"
|
||||
return xml
|
||||
|
||||
def _get_xml_config(self, install=True, disk_boot=False):
|
||||
"""
|
||||
Return the full Guest xml configuration.
|
||||
|
||||
@ -790,67 +553,36 @@ class Guest(XMLBuilder):
|
||||
"""
|
||||
# pylint: disable=W0221
|
||||
# Argument number differs from overridden method
|
||||
tmpfeat = self.features.copy()
|
||||
self._set_defaults(tmpfeat)
|
||||
|
||||
action = install and "destroy" or "restart"
|
||||
osblob_install = install and not disk_boot
|
||||
|
||||
if osblob_install and not self.installer.has_install_phase():
|
||||
return None
|
||||
|
||||
self.installer.alter_bootconfig(self, osblob_install, self.os)
|
||||
self.set_defaults()
|
||||
self._set_transient_device_defaults(install)
|
||||
|
||||
action = install and "destroy" or "restart"
|
||||
self.on_reboot = action
|
||||
self.on_crash = action
|
||||
|
||||
self.bootloader = None
|
||||
if (not install and
|
||||
self.os.is_xenpv() and
|
||||
not self.os.kernel):
|
||||
osblob = " <bootloader>/usr/bin/pygrub</bootloader>"
|
||||
else:
|
||||
osblob = self._get_osblob(osblob_install)
|
||||
self.bootloader = "/usr/bin/pygrub"
|
||||
self.os.clear()
|
||||
|
||||
desc_xml = ""
|
||||
if self.description is not None:
|
||||
desc = str(self.description)
|
||||
desc_xml = (" <description>%s</description>" %
|
||||
util.xml_escape(desc))
|
||||
count = {}
|
||||
for dev in self.get_all_devices():
|
||||
devtype = dev.virtual_device_type
|
||||
if devtype not in count:
|
||||
count[devtype] = 1
|
||||
newpath = "./devices/%s[%d]" % (devtype, count[devtype])
|
||||
setattr(dev, "_XML_NEW_ROOT_PATH", newpath)
|
||||
count[devtype] += 1
|
||||
|
||||
xml = ""
|
||||
add = lambda x: util.xml_append(xml, x)
|
||||
|
||||
xml = add("<domain type='%s'>" % self.type)
|
||||
xml = add(" <name>%s</name>" % self.name)
|
||||
xml = add(" <uuid>%s</uuid>" % self.uuid)
|
||||
xml = add(desc_xml)
|
||||
xml = add(" <memory>%s</memory>" % self.maxmemory)
|
||||
xml = add(" <currentMemory>%s</currentMemory>" % self.memory)
|
||||
|
||||
# <blkiotune>
|
||||
# <memtune>
|
||||
if self.hugepage is True:
|
||||
xml = add(" <memoryBacking>")
|
||||
xml = add(" <hugepages/>")
|
||||
xml = add(" </memoryBacking>")
|
||||
|
||||
xml = add(self._get_vcpu_xml())
|
||||
# <cputune>
|
||||
xml = add(self.numatune.get_xml_config())
|
||||
# <sysinfo>
|
||||
xml = add(osblob)
|
||||
xml = add(self._get_features_xml(tmpfeat))
|
||||
xml = add(self._get_cpu_xml())
|
||||
xml = add(self._get_clock_xml())
|
||||
xml = add(" <on_poweroff>destroy</on_poweroff>")
|
||||
xml = add(" <on_reboot>%s</on_reboot>" % action)
|
||||
xml = add(" <on_crash>%s</on_crash>" % action)
|
||||
xml = add(" <devices>")
|
||||
xml = add(self._get_device_xml(self.get_all_devices(), install))
|
||||
xml = add(" </devices>")
|
||||
xml = add(self._get_seclabel_xml())
|
||||
xml = add("</domain>\n")
|
||||
|
||||
def cb(doc, ctx):
|
||||
ignore = ctx
|
||||
return doc.serialize()
|
||||
xml = util.xml_parse_wrapper(xml, cb)
|
||||
return "\n".join(xml.splitlines()[1:]) + "\n"
|
||||
return self._make_xml_stub()
|
||||
|
||||
def get_continue_inst(self):
|
||||
"""
|
||||
@ -987,7 +719,6 @@ class Guest(XMLBuilder):
|
||||
self.domain = self._create_guest(consolecb, meter, wait,
|
||||
start_xml, final_xml, is_initial,
|
||||
noboot)
|
||||
|
||||
# Set domain autostart flag if requested
|
||||
self._flag_autostart()
|
||||
|
||||
@ -1139,6 +870,31 @@ class Guest(XMLBuilder):
|
||||
# Device defaults #
|
||||
###################
|
||||
|
||||
def _set_transient_device_defaults(self, install):
|
||||
def do_remove_media(d):
|
||||
# Keep cdrom around, but with no media attached,
|
||||
# But only if we are a distro that doesn't have a multi
|
||||
# stage install (aka not Windows)
|
||||
return (d.virtual_device_type == VirtualDevice.VIRTUAL_DEV_DISK and
|
||||
d.device == VirtualDisk.DEVICE_CDROM
|
||||
and d.transient
|
||||
and not install and
|
||||
not self.get_continue_inst())
|
||||
|
||||
def do_skip_disk(d):
|
||||
# Skip transient labeled non-media disks
|
||||
return (d.virtual_device_type == VirtualDevice.VIRTUAL_DEV_DISK and
|
||||
d.device == VirtualDisk.DEVICE_DISK
|
||||
and d.transient
|
||||
and not install)
|
||||
|
||||
for dev in self.get_all_devices():
|
||||
if do_skip_disk(dev):
|
||||
self.remove_device(dev)
|
||||
continue
|
||||
if do_remove_media(dev):
|
||||
dev.path = None
|
||||
|
||||
def set_defaults(self):
|
||||
"""
|
||||
Public function to set guest defaults. Things like preferred
|
||||
@ -1146,9 +902,46 @@ class Guest(XMLBuilder):
|
||||
The install process will call a non-persistent version, so calling
|
||||
this manually isn't required.
|
||||
"""
|
||||
self._set_defaults(self.features)
|
||||
self._set_osxml_defaults()
|
||||
self._set_feature_defaults()
|
||||
self._set_device_defaults()
|
||||
self._set_emulator_defaults()
|
||||
self._set_cpu_defaults()
|
||||
|
||||
def _set_hvm_defaults(self, features):
|
||||
def _set_cpu_defaults(self):
|
||||
self.cpu.set_topology_defaults(self.vcpus)
|
||||
|
||||
def _set_emulator_defaults(self):
|
||||
if self.os.is_xenpv():
|
||||
self.emulator = None
|
||||
return
|
||||
|
||||
if self.emulator:
|
||||
return
|
||||
|
||||
if self.os.is_hvm() and self.type == "xen":
|
||||
if self.conn.caps.host.arch == "x86_64":
|
||||
self.emulator = "/usr/lib64/xen/bin/qemu-dm"
|
||||
else:
|
||||
self.emulator = "/usr/lib/xen/bin/qemu-dm"
|
||||
|
||||
def _set_osxml_defaults(self):
|
||||
if self.os.is_container() and not self.os.init:
|
||||
for fs in self.get_devices("filesystem"):
|
||||
if fs.target == "/":
|
||||
self.os.init = "/sbin/init"
|
||||
break
|
||||
self.os.init = self.os.init or "/bin/sh"
|
||||
|
||||
if not self.os.loader and self.os.is_hvm() and self.type == "xen":
|
||||
self.os.loader = "/usr/lib/xen/boot/hvmloader"
|
||||
if self.os.os_type == "xen" and self.type == "xen":
|
||||
# Use older libvirt 'linux' value for back compat
|
||||
self.os.os_type = "linux"
|
||||
if self.os.kernel or self.os.init:
|
||||
self.os.bootorder = []
|
||||
|
||||
def _set_hvm_defaults(self):
|
||||
disktype = VirtualDevice.VIRTUAL_DEV_DISK
|
||||
nettype = VirtualDevice.VIRTUAL_DEV_NET
|
||||
disk_bus = self._lookup_device_param(disktype, "bus")
|
||||
@ -1167,13 +960,6 @@ class Guest(XMLBuilder):
|
||||
if self.clock.offset is None:
|
||||
self.clock.offset = self._lookup_osdict_key("clock")
|
||||
|
||||
if features["acpi"] is None:
|
||||
features["acpi"] = self._lookup_osdict_key("acpi")
|
||||
if features["apic"] is None:
|
||||
features["apic"] = self._lookup_osdict_key("apic")
|
||||
if features["pae"] is None:
|
||||
features["pae"] = self.conn.caps.support_pae()
|
||||
|
||||
if (self.os.machine is None and
|
||||
self.conn.caps.host.arch == "ppc64"):
|
||||
self.os.machine = "pseries"
|
||||
@ -1192,36 +978,40 @@ class Guest(XMLBuilder):
|
||||
if d.bus == d.BUS_DEFAULT:
|
||||
d.bus = d.BUS_XEN
|
||||
|
||||
def add_usb_ich9_controllers(self):
|
||||
ctrl = VirtualController(self.conn)
|
||||
ctrl.type = "usb"
|
||||
ctrl.model = "ich9-ehci1"
|
||||
self.add_device(ctrl)
|
||||
def _set_feature_defaults(self):
|
||||
if self.os.is_container():
|
||||
self.features.acpi = None
|
||||
self.features.apic = None
|
||||
self.features.pae = None
|
||||
return
|
||||
|
||||
ctrl = VirtualController(self.conn)
|
||||
ctrl.type = "usb"
|
||||
ctrl.model = "ich9-uhci1"
|
||||
ctrl.master_startport = 0
|
||||
self.add_device(ctrl)
|
||||
if not self.os.is_hvm():
|
||||
return
|
||||
|
||||
ctrl = VirtualController(self.conn)
|
||||
ctrl.type = "usb"
|
||||
ctrl.model = "ich9-uhci2"
|
||||
ctrl.master_startport = 2
|
||||
self.add_device(ctrl)
|
||||
if self.features["acpi"] is None:
|
||||
self.features["acpi"] = self._lookup_osdict_key("acpi")
|
||||
if self.features["apic"] is None:
|
||||
self.features["apic"] = self._lookup_osdict_key("apic")
|
||||
if self.features["pae"] is None:
|
||||
self.features["pae"] = self.conn.caps.support_pae()
|
||||
|
||||
ctrl = VirtualController(self.conn)
|
||||
ctrl.type = "usb"
|
||||
ctrl.model = "ich9-uhci3"
|
||||
ctrl.master_startport = 4
|
||||
self.add_device(ctrl)
|
||||
|
||||
def _set_defaults(self, features):
|
||||
def _set_device_defaults(self):
|
||||
for dev in self.get_devices("all"):
|
||||
dev.set_defaults()
|
||||
|
||||
# Add spapr-vio controller if needed
|
||||
if (dev.address.type == "spapr-vio" and
|
||||
dev.virtual_device_type == VirtualDevice.VIRTUAL_DEV_DISK and
|
||||
not any([cont.address.type == "spapr-vio" for cont in
|
||||
self.get_devices("controller")])):
|
||||
ctrl = virtinst.VirtualController(self.conn)
|
||||
ctrl.type = "scsi"
|
||||
ctrl.address.set_addrstr("spapr-vio")
|
||||
self.add_device(ctrl)
|
||||
|
||||
|
||||
if self.os.is_hvm():
|
||||
self._set_hvm_defaults(features)
|
||||
self._set_hvm_defaults()
|
||||
if self.os.is_xenpv():
|
||||
self._set_pv_defaults()
|
||||
|
||||
|
@ -41,7 +41,6 @@ class Seclabel(XMLBuilder):
|
||||
_dumpxml_xpath = "/domain/seclabel"
|
||||
_XML_ROOT_NAME = "seclabel"
|
||||
_XML_INDENT = 2
|
||||
_XML_XPATH_RELATIVE = True
|
||||
_XML_PROP_ORDER = ["type", "model", "relabel", "label", "imagelabel"]
|
||||
|
||||
def _guess_secmodel(self):
|
||||
|
@ -151,7 +151,7 @@ class _VirtualCharDevice(VirtualDevice):
|
||||
|
||||
def _sourcepath_get_xpath(self):
|
||||
return "./source/@path | ./@tty"
|
||||
source_path = XMLProperty(xml_get_xpath=_sourcepath_get_xpath,
|
||||
source_path = XMLProperty(make_getter_xpath_cb=_sourcepath_get_xpath,
|
||||
doc=_("Host input path to attach to the guest."),
|
||||
xpath="./source/@path")
|
||||
|
||||
@ -167,8 +167,8 @@ class _VirtualCharDevice(VirtualDevice):
|
||||
return "./source/@mode"
|
||||
source_mode = XMLProperty(name="char sourcemode",
|
||||
doc=_("Target connect/listen mode."),
|
||||
xml_get_xpath=_sourcemode_xpath,
|
||||
xml_set_xpath=_sourcemode_xpath,
|
||||
make_getter_xpath_cb=_sourcemode_xpath,
|
||||
make_setter_xpath_cb=_sourcemode_xpath,
|
||||
default_cb=_get_default_source_mode)
|
||||
|
||||
def _get_default_sourcehost(self):
|
||||
@ -188,8 +188,8 @@ class _VirtualCharDevice(VirtualDevice):
|
||||
return "./source[@mode='%s']/@host" % mode
|
||||
source_host = XMLProperty(name="char sourcehost",
|
||||
doc=_("Address to connect/listen to."),
|
||||
xml_get_xpath=_sourcehost_xpath,
|
||||
xml_set_xpath=_sourcehost_xpath,
|
||||
make_getter_xpath_cb=_sourcehost_xpath,
|
||||
make_setter_xpath_cb=_sourcehost_xpath,
|
||||
default_cb=_get_default_sourcehost,
|
||||
set_converter=_set_source_validate)
|
||||
|
||||
@ -197,8 +197,8 @@ class _VirtualCharDevice(VirtualDevice):
|
||||
return "./source[@mode='%s']/@service" % self.source_mode
|
||||
source_port = XMLProperty(name="char sourceport",
|
||||
doc=_("Port on target host to connect/listen to."),
|
||||
xml_get_xpath=_sourceport_xpath,
|
||||
xml_set_xpath=_sourceport_xpath,
|
||||
make_getter_xpath_cb=_sourceport_xpath,
|
||||
make_setter_xpath_cb=_sourceport_xpath,
|
||||
set_converter=_set_source_validate, is_int=True)
|
||||
|
||||
_has_mode_connect = XMLProperty(xpath="./source[@mode='connect']/@mode")
|
||||
|
@ -54,7 +54,35 @@ class VirtualController(VirtualDevice):
|
||||
return ctype
|
||||
return pretty_mappings[ctype]
|
||||
|
||||
_XML_PROP_ORDER = ["type", "index", "model"]
|
||||
@staticmethod
|
||||
def get_usb2_controllers(conn):
|
||||
ret = []
|
||||
ctrl = VirtualController(conn)
|
||||
ctrl.type = "usb"
|
||||
ctrl.model = "ich9-ehci1"
|
||||
ret.append(ctrl)
|
||||
|
||||
ctrl = VirtualController(conn)
|
||||
ctrl.type = "usb"
|
||||
ctrl.model = "ich9-uhci1"
|
||||
ctrl.master_startport = 0
|
||||
ret.append(ctrl)
|
||||
|
||||
ctrl = VirtualController(conn)
|
||||
ctrl.type = "usb"
|
||||
ctrl.model = "ich9-uhci2"
|
||||
ctrl.master_startport = 2
|
||||
ret.append(ctrl)
|
||||
|
||||
ctrl = VirtualController(conn)
|
||||
ctrl.type = "usb"
|
||||
ctrl.model = "ich9-uhci3"
|
||||
ctrl.master_startport = 4
|
||||
ret.append(ctrl)
|
||||
return ret
|
||||
|
||||
|
||||
_XML_PROP_ORDER = ["type", "index", "model", "master_startport"]
|
||||
|
||||
type = XMLProperty(xpath="./@type")
|
||||
model = XMLProperty(xpath="./@model")
|
||||
|
@ -82,7 +82,7 @@ class VirtualDevice(XMLBuilder):
|
||||
|
||||
self.alias = VirtualDeviceAlias(conn, parsexmlnode=parsexmlnode)
|
||||
self.address = VirtualDeviceAddress(conn, parsexmlnode=parsexmlnode)
|
||||
self._XML_SUB_ELEMENTS = ["alias", "address"]
|
||||
self._XML_PROP_ORDER = self._XML_PROP_ORDER + ["alias", "address"]
|
||||
|
||||
if not self.virtual_device_type:
|
||||
raise ValueError(_("Virtual device type must be set in subclass."))
|
||||
@ -132,7 +132,6 @@ class VirtualDeviceAddress(XMLBuilder):
|
||||
|
||||
_XML_ROOT_NAME = "address"
|
||||
_XML_INDENT = 0
|
||||
#_XML_XPATH_RELATIVE = True
|
||||
_XML_PROP_ORDER = ["type", "domain", "bus", "slot", "function"]
|
||||
|
||||
def set_addrstr(self, addrstr):
|
||||
|
@ -452,6 +452,8 @@ class VirtualDisk(VirtualDevice):
|
||||
return self._storage_backend.get_dev_type()
|
||||
|
||||
def _get_default_driver_name(self):
|
||||
if not self.path:
|
||||
return None
|
||||
if self.conn.is_qemu():
|
||||
return self.DRIVER_QEMU
|
||||
return None
|
||||
@ -480,7 +482,7 @@ class VirtualDisk(VirtualDevice):
|
||||
# XML properties #
|
||||
##################
|
||||
|
||||
def _xml_get_xpath(self):
|
||||
def _make_getter_xpath_cb(self):
|
||||
xpath = None
|
||||
ret = "./source/@file"
|
||||
for prop in _TARGET_PROPS:
|
||||
@ -489,11 +491,11 @@ class VirtualDisk(VirtualDevice):
|
||||
ret = xpath
|
||||
break
|
||||
return ret
|
||||
def _xml_set_xpath(self):
|
||||
def _make_setter_xpath_cb(self):
|
||||
return "./source/@" + self.disk_type_to_target_prop(self.type)
|
||||
_xmlpath = XMLProperty(name="disk path",
|
||||
xml_get_xpath=_xml_get_xpath,
|
||||
xml_set_xpath=_xml_set_xpath,
|
||||
make_getter_xpath_cb=_make_getter_xpath_cb,
|
||||
make_setter_xpath_cb=_make_setter_xpath_cb,
|
||||
clear_first=["./source/@" + target for target in
|
||||
_TARGET_PROPS])
|
||||
|
||||
@ -591,9 +593,21 @@ class VirtualDisk(VirtualDevice):
|
||||
self._storage_backend = backend
|
||||
|
||||
def _refresh_backend_settings(self):
|
||||
self._refresh_xml_prop("type")
|
||||
self._refresh_xml_prop("driver_name")
|
||||
self._refresh_xml_prop("driver_type")
|
||||
def refresh_prop_xml(propname):
|
||||
# When parsing, we can pull info from _propstore or the
|
||||
# backing XML. The problem is that disk XML has several
|
||||
# interdependent properties that we need to update if
|
||||
# one or the other changes.
|
||||
#
|
||||
# This will update the XML value with the newly determined
|
||||
# default value, but it won't edit propstore. This means
|
||||
prop = self.all_xml_props()[propname]
|
||||
val = getattr(prop, "_default_cb")(self)
|
||||
prop.setter(self, val, call_fset=False)
|
||||
|
||||
refresh_prop_xml("type")
|
||||
refresh_prop_xml("driver_name")
|
||||
refresh_prop_xml("driver_type")
|
||||
self._xmlpath = self.path
|
||||
|
||||
def __managed_storage(self):
|
||||
@ -709,14 +723,6 @@ class VirtualDisk(VirtualDevice):
|
||||
self.type == self.TYPE_BLOCK):
|
||||
self.driver_io = self.IO_MODE_NATIVE
|
||||
|
||||
def _cleanup_xml(self, xml):
|
||||
# Remove <driver> block if path is None. Might not be strictly
|
||||
# requires but it's what we've always done
|
||||
if not self.path and "<driver" in xml:
|
||||
xml = "\n".join([l for l in xml.splitlines()
|
||||
if "<driver" not in l])
|
||||
return xml
|
||||
|
||||
def is_size_conflict(self):
|
||||
"""
|
||||
reports if disk size conflicts with available space
|
||||
|
@ -99,8 +99,8 @@ class VirtualFilesystem(VirtualDevice):
|
||||
ret = "./source/@" + self.type_to_source_prop(self.type)
|
||||
return ret
|
||||
source = XMLProperty(name="filesystem source",
|
||||
xml_get_xpath=_xml_get_source_xpath,
|
||||
xml_set_xpath=_xml_set_source_xpath)
|
||||
make_getter_xpath_cb=_xml_get_source_xpath,
|
||||
make_setter_xpath_cb=_xml_set_source_xpath)
|
||||
|
||||
def _validate_set_target(self, val):
|
||||
# In case of qemu for default fs type (mount) target is not
|
||||
|
@ -54,10 +54,8 @@ def _random_mac(conn):
|
||||
|
||||
class VirtualPort(XMLBuilder):
|
||||
type = XMLProperty(xpath="./virtualport/@type")
|
||||
|
||||
managerid = XMLProperty(xpath="./virtualport/parameters/@managerid",
|
||||
is_int=True)
|
||||
|
||||
typeid = XMLProperty(xpath="./virtualport/parameters/@typeid", is_int=True)
|
||||
typeidversion = XMLProperty(
|
||||
xpath="./virtualport/parameters/@typeidversion", is_int=True)
|
||||
@ -65,7 +63,6 @@ class VirtualPort(XMLBuilder):
|
||||
|
||||
|
||||
class VirtualNetworkInterface(VirtualDevice):
|
||||
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_NET
|
||||
|
||||
TYPE_BRIDGE = "bridge"
|
||||
@ -138,7 +135,6 @@ class VirtualNetworkInterface(VirtualDevice):
|
||||
VirtualDevice.__init__(self, conn, parsexml, parsexmlnode)
|
||||
|
||||
self.virtualport = VirtualPort(conn, parsexml, parsexmlnode)
|
||||
self._XML_SUB_ELEMENTS.append("virtualport")
|
||||
|
||||
self._random_mac = None
|
||||
self._default_bridge = None
|
||||
@ -200,7 +196,7 @@ class VirtualNetworkInterface(VirtualDevice):
|
||||
|
||||
_XML_PROP_ORDER = [
|
||||
"bridge", "network", "source_dev", "source_mode",
|
||||
"macaddr", "target_dev", "model"]
|
||||
"macaddr", "target_dev", "model", "virtualport"]
|
||||
|
||||
type = XMLProperty(xpath="./@type",
|
||||
default_cb=lambda s: s.TYPE_BRIDGE)
|
||||
|
@ -754,7 +754,7 @@ def get_networks(guest, networks, macs):
|
||||
def set_os_variant(guest, distro_type, distro_variant):
|
||||
if not distro_type and not distro_variant:
|
||||
# Default to distro autodetection
|
||||
guest.set_os_autodetect(True)
|
||||
guest.os_autodetect = True
|
||||
return
|
||||
|
||||
if (distro_type and str(distro_type).lower() != "none"):
|
||||
@ -798,7 +798,7 @@ def digest_graphics(guest, options, default_override=None):
|
||||
elif "DISPLAY" in os.environ.keys():
|
||||
logging.debug("DISPLAY is set: looking for pre-configured graphics")
|
||||
if cliconfig.default_graphics in ["spice", "vnc", "sdl"]:
|
||||
logging.debug("Defaulting graphics to pre-configured %s" %
|
||||
logging.debug("Defaulting graphics to pre-configured %s",
|
||||
cliconfig.default_graphics.upper())
|
||||
return [cliconfig.default_graphics]
|
||||
logging.debug("No valid pre-configured graphics "
|
||||
@ -1189,10 +1189,11 @@ def parse_vcpu(guest, optstring, default_vcpus=None):
|
||||
|
||||
set_param = _build_set_param(guest, opts)
|
||||
set_cpu_param = _build_set_param(guest.cpu, opts)
|
||||
has_vcpus = ("vcpus" in opts or (vcpus is not None))
|
||||
has_max = ("maxvcpus" in opts)
|
||||
has_vcpus = ("vcpus" in opts) or has_max
|
||||
|
||||
set_param("vcpus", "vcpus")
|
||||
set_param("maxvcpus", "maxvcpus")
|
||||
set_param(has_max and "curvcpus" or "vcpus", "vcpus")
|
||||
set_param("vcpus", "maxvcpus")
|
||||
|
||||
set_cpu_param("sockets", "sockets")
|
||||
set_cpu_param("cores", "cores")
|
||||
@ -1637,7 +1638,8 @@ def parse_controller(guest, optstring, dev=None):
|
||||
return None
|
||||
|
||||
if optstring == "usb2":
|
||||
guest.add_usb_ich9_controllers()
|
||||
for dev in virtinst.VirtualController.get_usb2_controllers(guest.conn):
|
||||
guest.add_device(dev)
|
||||
return None
|
||||
|
||||
# Peel the mode off the front
|
||||
|
@ -42,7 +42,6 @@ class OSXML(XMLBuilder):
|
||||
_dumpxml_xpath = "/domain/os"
|
||||
_XML_ROOT_NAME = "os"
|
||||
_XML_INDENT = 2
|
||||
_XML_XPATH_RELATIVE = True
|
||||
_XML_PROP_ORDER = ["arch", "os_type", "loader",
|
||||
"kernel", "initrd", "kernel_args",
|
||||
"bootorder"]
|
||||
|
@ -52,6 +52,15 @@ class _CtxCleanupWrapper(object):
|
||||
return getattr(self._ctx, attrname)
|
||||
|
||||
|
||||
def _indent(xmlstr, level):
|
||||
xml = ""
|
||||
if not xmlstr:
|
||||
return xml
|
||||
if not level:
|
||||
return xmlstr
|
||||
return "\n".join((" " * level + l) for l in xmlstr.splitlines())
|
||||
|
||||
|
||||
def _tuplify_lists(*args):
|
||||
"""
|
||||
Similar to zip(), but use None if lists aren't long enough, and
|
||||
@ -232,9 +241,9 @@ def _remove_xpath_node(ctx, xpath, dofree=True, root_name=None):
|
||||
|
||||
|
||||
class XMLProperty(property):
|
||||
def __init__(self, fget=None, fset=None, doc=None, xpath=None, name=None,
|
||||
get_converter=None, set_converter=None,
|
||||
xml_get_xpath=None, xml_set_xpath=None,
|
||||
def __init__(self, doc=None, xpath=None, name=None,
|
||||
set_converter=None, validate_cb=None,
|
||||
make_getter_xpath_cb=None, make_setter_xpath_cb=None,
|
||||
is_bool=False, is_tri=False, is_int=False,
|
||||
is_multi=False, is_yesno=False,
|
||||
clear_first=None, default_cb=None, default_name=None):
|
||||
@ -249,23 +258,22 @@ class XMLProperty(property):
|
||||
use the xpath value to map the name property to the underlying XML
|
||||
definition.
|
||||
|
||||
@param fget: typical getter function for the property
|
||||
@param fset: typical setter function for the property
|
||||
@param doc: option doc string for the property
|
||||
@param xpath: xpath string which maps to the associated property
|
||||
in a typical XML document
|
||||
@param name: Just a string to print for debugging, only needed
|
||||
if xpath isn't specified.
|
||||
@param get_converter:
|
||||
@param set_converter: optional function for converting the property
|
||||
value from the virtinst API to the guest XML. For example,
|
||||
the Guest.memory API was once in MB, but the libvirt domain
|
||||
memory API is in KB. So, if xpath is specified, on a 'get'
|
||||
operation we convert the XML value with int(val) / 1024.
|
||||
@param xml_get_xpath:
|
||||
@param xml_set_xpath: Not all props map cleanly to a static xpath.
|
||||
This allows passing functions which generate an xpath for getting
|
||||
or setting.
|
||||
@param validate_cb: Called once when value is set, should
|
||||
raise a RuntimeError if the value is not proper.
|
||||
@param make_getter_xpath_cb:
|
||||
@param make_setter_xpath_cb: Not all props map cleanly to a
|
||||
static xpath. This allows passing functions which generate
|
||||
an xpath for getting or setting.
|
||||
@param is_bool: Whether this is a boolean property in the XML
|
||||
@param is_tri: Boolean XML property, but return None if there's
|
||||
no value set.
|
||||
@ -294,10 +302,10 @@ class XMLProperty(property):
|
||||
self._is_multi = is_multi
|
||||
self._is_yesno = is_yesno
|
||||
|
||||
self._xpath_for_getter_cb = xml_get_xpath
|
||||
self._xpath_for_setter_cb = xml_set_xpath
|
||||
self._xpath_for_getter_cb = make_getter_xpath_cb
|
||||
self._xpath_for_setter_cb = make_setter_xpath_cb
|
||||
|
||||
self._convert_value_for_getter_cb = get_converter
|
||||
self._validate_cb = validate_cb
|
||||
self._convert_value_for_setter_cb = set_converter
|
||||
self._setter_clear_these_first = clear_first or []
|
||||
self._default_cb = default_cb
|
||||
@ -310,43 +318,21 @@ class XMLProperty(property):
|
||||
if self._default_name and not self._default_cb:
|
||||
raise RuntimeError("default_name requires default_cb.")
|
||||
|
||||
self._fget = fget
|
||||
self._fset = fset
|
||||
if _trackprops:
|
||||
_allprops.append(self)
|
||||
|
||||
if self._is_new_style_prop():
|
||||
if _trackprops:
|
||||
_allprops.append(self)
|
||||
else:
|
||||
if self._default_cb:
|
||||
raise RuntimeError("Can't set default_cb for old style XML "
|
||||
"prop.")
|
||||
|
||||
property.__init__(self, fget=self.new_getter, fset=self.new_setter)
|
||||
property.__init__(self, fget=self.getter, fset=self.setter)
|
||||
self.__doc__ = doc
|
||||
|
||||
|
||||
##################
|
||||
# Public-ish API #
|
||||
##################
|
||||
|
||||
def __repr__(self):
|
||||
return "<XMLProperty %s %s>" % (str(self._name), id(self))
|
||||
|
||||
def has_default_value(self):
|
||||
return bool(self._default_cb)
|
||||
|
||||
|
||||
####################
|
||||
# Internal helpers #
|
||||
####################
|
||||
|
||||
def _is_new_style_prop(self):
|
||||
"""
|
||||
True if this is a prop without an explicitly passed in fget/fset
|
||||
pair.
|
||||
"""
|
||||
return not bool(self._fget)
|
||||
|
||||
def _findpropname(self, xmlbuilder):
|
||||
"""
|
||||
Map the raw property() instance to the param name it's exposed
|
||||
@ -372,14 +358,9 @@ class XMLProperty(property):
|
||||
raise RuntimeError("%s: didn't generate any setter xpath." % self)
|
||||
return self._xpath_fix_relative(xmlbuilder, ret)
|
||||
def _xpath_fix_relative(self, xmlbuilder, xpath):
|
||||
if not getattr(xmlbuilder, "_xml_fixup_relative_xpath"):
|
||||
if not xmlbuilder._XML_NEW_ROOT_PATH:
|
||||
return xpath
|
||||
root = "./%s" % getattr(xmlbuilder, "_XML_ROOT_NAME")
|
||||
if not xpath.startswith(root):
|
||||
raise RuntimeError("%s: xpath did not start with root=%s" %
|
||||
(str(self), root))
|
||||
ret = "." + xpath[len(root):]
|
||||
return ret
|
||||
return "./%s%s" % (xmlbuilder._XML_NEW_ROOT_PATH, xpath.strip("."))
|
||||
|
||||
|
||||
def _xpath_list_for_setter(self, xpath, setval, nodelist):
|
||||
@ -401,7 +382,7 @@ class XMLProperty(property):
|
||||
|
||||
def _convert_value_for_setter(self, xmlbuilder):
|
||||
# Convert from API value to XML value
|
||||
val = self._orig_fget(xmlbuilder)
|
||||
val = self._nonxml_fget(xmlbuilder)
|
||||
if self._default_name and val == self._default_name:
|
||||
val = self._default_cb(xmlbuilder)
|
||||
elif self._is_yesno:
|
||||
@ -440,12 +421,7 @@ class XMLProperty(property):
|
||||
return clear_nodes
|
||||
|
||||
|
||||
def _convert_get_value(self, xmlbuilder, val, initial=False):
|
||||
if self._fget and initial:
|
||||
# If user passed in an fget impl, we expect them to put things
|
||||
# in the form they want.
|
||||
return val
|
||||
|
||||
def _convert_get_value(self, val, initial=False):
|
||||
if self._is_bool:
|
||||
if initial and self._is_tri and val is None:
|
||||
ret = None
|
||||
@ -462,38 +438,36 @@ class XMLProperty(property):
|
||||
ret = []
|
||||
else:
|
||||
ret = val
|
||||
|
||||
if self._convert_value_for_getter_cb:
|
||||
ret = self._convert_value_for_getter_cb(xmlbuilder, ret)
|
||||
return ret
|
||||
|
||||
def _orig_fget(self, xmlbuilder):
|
||||
# Returns (is unset, fget value)
|
||||
if self._fget:
|
||||
# For the passed in fget callback, we have any way to
|
||||
# tell if the value is unset or not.
|
||||
return self._fget(xmlbuilder)
|
||||
|
||||
# The flip side to default_orig_fset, fetch the value from
|
||||
# XMLBuilder._propstore
|
||||
def _prop_is_unset(self, xmlbuilder):
|
||||
propstore = getattr(xmlbuilder, "_propstore")
|
||||
propname = self._findpropname(xmlbuilder)
|
||||
unset = (propname not in propstore)
|
||||
if unset and self._default_cb:
|
||||
if self._default_name:
|
||||
return self._default_name
|
||||
return self._default_cb(xmlbuilder)
|
||||
return propstore.get(propname, None)
|
||||
return (propname not in propstore)
|
||||
|
||||
def _orig_fset(self, xmlbuilder, val):
|
||||
def _set_default(self, xmlbuilder):
|
||||
"""
|
||||
If no fset specified, this stores the value in XMLBuilder._propstore
|
||||
Encode the property default into the XML and propstore, but
|
||||
only if a default is registered, and only if the property was
|
||||
not already explicitly set by the API user.
|
||||
|
||||
This is called during the get_xml_config process and shouldn't
|
||||
be called from outside this file.
|
||||
"""
|
||||
if not self._prop_is_unset(xmlbuilder):
|
||||
return
|
||||
if not self._default_cb:
|
||||
return
|
||||
if self._default_cb(xmlbuilder) is None:
|
||||
return
|
||||
self.setter(xmlbuilder, self.getter(xmlbuilder), validate=False)
|
||||
|
||||
def _nonxml_fset(self, xmlbuilder, val):
|
||||
"""
|
||||
This stores the value in XMLBuilder._propstore
|
||||
dict as propname->value. This saves us from having to explicitly
|
||||
track every variable.
|
||||
"""
|
||||
if self._fset:
|
||||
return self._fset(xmlbuilder, val)
|
||||
|
||||
propstore = getattr(xmlbuilder, "_propstore")
|
||||
proporder = getattr(xmlbuilder, "_proporder")
|
||||
|
||||
@ -506,31 +480,50 @@ class XMLProperty(property):
|
||||
proporder.remove(propname)
|
||||
proporder.append(propname)
|
||||
|
||||
def _nonxml_fget(self, xmlbuilder):
|
||||
"""
|
||||
The flip side to nonxml_fset, fetch the value from
|
||||
XMLBuilder._propstore
|
||||
"""
|
||||
propstore = getattr(xmlbuilder, "_propstore")
|
||||
propname = self._findpropname(xmlbuilder)
|
||||
unset = (propname not in propstore)
|
||||
if unset and self._default_cb:
|
||||
if self._default_name:
|
||||
return self._default_name
|
||||
return self._default_cb(xmlbuilder)
|
||||
return propstore.get(propname, None)
|
||||
|
||||
def _clear(self, xmlbuilder):
|
||||
val = None
|
||||
if self._is_multi:
|
||||
val = []
|
||||
self.setter(xmlbuilder, val)
|
||||
|
||||
|
||||
##################################
|
||||
# The actual getter/setter impls #
|
||||
##################################
|
||||
|
||||
def new_getter(self, xmlbuilder):
|
||||
fgetval = self._orig_fget(xmlbuilder)
|
||||
def getter(self, xmlbuilder):
|
||||
fgetval = self._nonxml_fget(xmlbuilder)
|
||||
|
||||
root_node = getattr(xmlbuilder, "_xml_node")
|
||||
if root_node is None:
|
||||
return self._convert_get_value(xmlbuilder, fgetval, initial=True)
|
||||
return self._convert_get_value(fgetval, initial=True)
|
||||
|
||||
xpath = self._xpath_for_getter(xmlbuilder)
|
||||
nodelist = self._build_node_list(xmlbuilder, xpath)
|
||||
|
||||
if not nodelist:
|
||||
return self._convert_get_value(xmlbuilder, None)
|
||||
return self._convert_get_value(None)
|
||||
|
||||
ret = []
|
||||
for node in nodelist:
|
||||
content = node.content
|
||||
if self._is_bool:
|
||||
content = True
|
||||
val = self._convert_get_value(xmlbuilder, content)
|
||||
val = self._convert_get_value(content)
|
||||
if not self._is_multi:
|
||||
return val
|
||||
# If user is querying multiple nodes, return a list of results
|
||||
@ -538,9 +531,11 @@ class XMLProperty(property):
|
||||
return ret
|
||||
|
||||
|
||||
def new_setter(self, xmlbuilder, val, call_fset=True):
|
||||
def setter(self, xmlbuilder, val, call_fset=True, validate=True):
|
||||
if call_fset:
|
||||
self._orig_fset(xmlbuilder, val)
|
||||
if validate and self._validate_cb:
|
||||
self._validate_cb(xmlbuilder, val)
|
||||
self._nonxml_fset(xmlbuilder, val)
|
||||
|
||||
root_node = getattr(xmlbuilder, "_xml_node")
|
||||
if root_node is None:
|
||||
@ -574,45 +569,11 @@ class XMLProperty(property):
|
||||
continue
|
||||
node.setContent(util.xml_escape(str(val)))
|
||||
|
||||
def _prop_is_unset(self, xmlbuilder):
|
||||
propstore = getattr(xmlbuilder, "_propstore")
|
||||
propname = self._findpropname(xmlbuilder)
|
||||
return (propname not in propstore)
|
||||
|
||||
def refresh_xml(self, xmlbuilder, force_call_fset=False):
|
||||
call_fset = True
|
||||
if not self._is_new_style_prop():
|
||||
call_fset = False
|
||||
elif getattr(xmlbuilder, "_is_parse")():
|
||||
call_fset = False
|
||||
elif self._prop_is_unset(xmlbuilder) and self._default_cb:
|
||||
call_fset = False
|
||||
|
||||
if force_call_fset:
|
||||
call_fset = True
|
||||
self.fset(xmlbuilder, self.fget(xmlbuilder), call_fset=call_fset)
|
||||
|
||||
def set_default(self, xmlbuilder):
|
||||
if not self._prop_is_unset(xmlbuilder) or not self._default_cb:
|
||||
return
|
||||
if self._default_cb(xmlbuilder) is None:
|
||||
return
|
||||
self.refresh_xml(xmlbuilder, force_call_fset=True)
|
||||
|
||||
|
||||
class XMLBuilder(object):
|
||||
"""
|
||||
Base for all classes which build or parse domain XML
|
||||
"""
|
||||
@staticmethod
|
||||
def indent(xmlstr, level):
|
||||
xml = ""
|
||||
if not xmlstr:
|
||||
return xml
|
||||
if not level:
|
||||
return xmlstr
|
||||
return "\n".join((" " * level + l) for l in xmlstr.splitlines())
|
||||
|
||||
# Order that we should apply values to the XML. Keeps XML generation
|
||||
# consistent with what the test suite expects.
|
||||
_XML_PROP_ORDER = []
|
||||
@ -624,16 +585,11 @@ class XMLBuilder(object):
|
||||
# Integer indentation level for generated XML.
|
||||
_XML_INDENT = None
|
||||
|
||||
# If XML xpaths are relative to a different element, like
|
||||
# device addresses.
|
||||
_XML_XPATH_RELATIVE = False
|
||||
|
||||
# List of property names that point to a manually tracked
|
||||
# XMLBuilder that alters our device xml, like self.address for
|
||||
# VirtualDevice
|
||||
_XML_SUB_ELEMENTS = []
|
||||
# This is only used to make device XML work for guest XML generating
|
||||
_XML_NEW_ROOT_PATH = ""
|
||||
|
||||
_dumpxml_xpath = "."
|
||||
|
||||
def __init__(self, conn, parsexml=None, parsexmlnode=None):
|
||||
"""
|
||||
Initialize state
|
||||
@ -649,7 +605,6 @@ class XMLBuilder(object):
|
||||
self._xml_node = None
|
||||
self._xml_ctx = None
|
||||
self._xml_root_doc = None
|
||||
self._xml_fixup_relative_xpath = False
|
||||
self._propstore = {}
|
||||
self._proporder = []
|
||||
|
||||
@ -679,7 +634,7 @@ class XMLBuilder(object):
|
||||
return self._xml_node.nodePath()
|
||||
return None
|
||||
|
||||
def get_xml_config(self, *args, **kwargs):
|
||||
def _do_get_xml_config(self, dumpxml_xpath, clean, *args, **kwargs):
|
||||
"""
|
||||
Construct and return object xml
|
||||
|
||||
@ -687,11 +642,7 @@ class XMLBuilder(object):
|
||||
@rtype: str
|
||||
"""
|
||||
if self._xml_ctx:
|
||||
dumpxml_path = self._dumpxml_xpath
|
||||
if self._xml_fixup_relative_xpath:
|
||||
dumpxml_path = "."
|
||||
|
||||
node = _get_xpath_node(self._xml_ctx, dumpxml_path)
|
||||
node = _get_xpath_node(self._xml_ctx, dumpxml_xpath)
|
||||
if not node:
|
||||
ret = ""
|
||||
else:
|
||||
@ -701,16 +652,26 @@ class XMLBuilder(object):
|
||||
ret = self._get_xml_config(*args, **kwargs)
|
||||
if ret is None:
|
||||
return None
|
||||
ret = self._add_parse_bits(ret)
|
||||
|
||||
for propname in self._XML_SUB_ELEMENTS:
|
||||
for prop in util.listify(getattr(self, propname)):
|
||||
ret = prop._add_parse_bits(ret)
|
||||
|
||||
ret = self._add_parse_bits(ret, clean=False)
|
||||
if ret == xmlstub:
|
||||
ret = ""
|
||||
|
||||
return self._cleanup_xml(ret)
|
||||
if clean:
|
||||
ret = self._cleanup_xml(ret)
|
||||
return ret
|
||||
|
||||
def get_xml_config(self, *args, **kwargs):
|
||||
data = self._prepare_get_xml()
|
||||
try:
|
||||
return self._do_get_xml_config(self._dumpxml_xpath, True,
|
||||
*args, **kwargs)
|
||||
finally:
|
||||
self._finish_get_xml(data)
|
||||
|
||||
def clear(self):
|
||||
for prop in self.all_xml_props().values():
|
||||
prop._clear(self)
|
||||
|
||||
|
||||
#######################
|
||||
@ -720,13 +681,6 @@ class XMLBuilder(object):
|
||||
def _is_parse(self):
|
||||
return bool(self._xml_node or self._xml_ctx)
|
||||
|
||||
def _refresh_xml_prop(self, propname):
|
||||
"""
|
||||
Refresh the XML for the passed class propname. Used to adjust
|
||||
the XML when an interdependent property changes.
|
||||
"""
|
||||
self.all_xml_props()[propname].refresh_xml(self)
|
||||
|
||||
|
||||
###################
|
||||
# Child overrides #
|
||||
@ -738,6 +692,11 @@ class XMLBuilder(object):
|
||||
def validate(self):
|
||||
pass
|
||||
|
||||
def _prepare_get_xml(self):
|
||||
return None
|
||||
def _finish_get_xml(self, data):
|
||||
ignore = data
|
||||
|
||||
def _get_xml_config(self):
|
||||
"""
|
||||
Internal XML building function. Must be overwritten by subclass
|
||||
@ -766,8 +725,7 @@ class XMLBuilder(object):
|
||||
raise RuntimeError("Must specify _XML_INDENT.")
|
||||
if self._XML_ROOT_NAME == "":
|
||||
return ""
|
||||
|
||||
return self.indent("<%s/>" % (self._XML_ROOT_NAME), self._XML_INDENT)
|
||||
return _indent("<%s/>" % (self._XML_ROOT_NAME), self._XML_INDENT)
|
||||
|
||||
def _add_child_node(self, parent_xpath, newnode):
|
||||
ret = _build_xpath_node(self._xml_ctx, parent_xpath, newnode)
|
||||
@ -802,12 +760,11 @@ class XMLBuilder(object):
|
||||
ret[key] = val
|
||||
return ret
|
||||
|
||||
def _do_add_parse_bits(self, xml):
|
||||
# Find all properties that have default callbacks
|
||||
def _do_add_parse_bits(self, xml, node, clean):
|
||||
# Set all defaults if the properties have one registered
|
||||
xmlprops = self.all_xml_props()
|
||||
defaultprops = [v for v in xmlprops.values() if v.has_default_value()]
|
||||
for prop in defaultprops:
|
||||
prop.set_default(self)
|
||||
for prop in xmlprops.values():
|
||||
prop._set_default(self)
|
||||
|
||||
# Default props alter our _propstore. But at this point _propstore
|
||||
# is empty, there's nothing for us to do, so exit early
|
||||
@ -816,15 +773,16 @@ class XMLBuilder(object):
|
||||
|
||||
# Unindent XML
|
||||
indent = 0
|
||||
for c in xml:
|
||||
if c != " ":
|
||||
break
|
||||
indent += 1
|
||||
xml = "\n".join([l[indent:] for l in xml.splitlines()])
|
||||
if xml:
|
||||
for c in xml:
|
||||
if c != " ":
|
||||
break
|
||||
indent += 1
|
||||
xml = "\n".join([l[indent:] for l in xml.splitlines()])
|
||||
|
||||
# Parse the XML into our internal state. Use the raw
|
||||
# _parsexml so we don't hit Guest parsing into its internal state
|
||||
XMLBuilder._parsexml(self, xml, None)
|
||||
XMLBuilder._parsexml(self, xml, node)
|
||||
|
||||
# Set up preferred XML ordering
|
||||
do_order = self._proporder[:]
|
||||
@ -832,13 +790,24 @@ class XMLBuilder(object):
|
||||
if key in do_order:
|
||||
do_order.remove(key)
|
||||
do_order.insert(0, key)
|
||||
elif key not in xmlprops:
|
||||
do_order.insert(0, key)
|
||||
|
||||
# Alter the XML
|
||||
for key in do_order:
|
||||
setattr(self, key, self._propstore[key])
|
||||
return self.indent(self.get_xml_config().strip("\n"), indent)
|
||||
if key in xmlprops:
|
||||
xmlprops[key].setter(self, self._propstore[key],
|
||||
validate=False)
|
||||
else:
|
||||
for obj in util.listify(getattr(self, key)):
|
||||
if self._XML_NEW_ROOT_PATH and not obj._XML_NEW_ROOT_PATH:
|
||||
obj._XML_NEW_ROOT_PATH = self._XML_NEW_ROOT_PATH
|
||||
obj._add_parse_bits(xml=None, node=self._xml_node)
|
||||
|
||||
def _add_parse_bits(self, xml):
|
||||
xml = self._do_get_xml_config(".", clean).strip("\n")
|
||||
return _indent(xml, indent)
|
||||
|
||||
def _add_parse_bits(self, xml, node=None, clean=True):
|
||||
"""
|
||||
Callback that adds the implicitly tracked XML properties to
|
||||
the manually generated xml. This should only exist until all
|
||||
@ -850,12 +819,10 @@ class XMLBuilder(object):
|
||||
origproporder = self._proporder[:]
|
||||
origpropstore = self._propstore.copy()
|
||||
try:
|
||||
self._xml_fixup_relative_xpath = self._XML_XPATH_RELATIVE
|
||||
return self._do_add_parse_bits(xml)
|
||||
return self._do_add_parse_bits(xml, node, clean)
|
||||
finally:
|
||||
self._xml_root_doc = None
|
||||
self._xml_node = None
|
||||
self._xml_ctx = None
|
||||
self._proporder = origproporder
|
||||
self._propstore = origpropstore
|
||||
self._xml_fixup_relative_xpath = False
|
||||
|
Loading…
Reference in New Issue
Block a user