mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-01-08 21:18:04 +03:00
virt-xml: Initial commit, basic set of tests
This commit is contained in:
parent
ffa9bb77b3
commit
748ff1c4cc
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,6 +17,7 @@ po/virt-manager.pot
|
||||
/man/virt-image.1
|
||||
/man/virt-convert.1
|
||||
/man/virt-image.5
|
||||
/man/virt-xml.1
|
||||
|
||||
/virt-manager.spec
|
||||
/virtcli/cli.cfg
|
||||
|
77
man/virt-xml.pod
Normal file
77
man/virt-xml.pod
Normal file
@ -0,0 +1,77 @@
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
virt-xml - XXX
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<virt-xml> XXX
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<virt-xml> XXX
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 4
|
||||
|
||||
=item -h, --help
|
||||
|
||||
Show the help message and exit
|
||||
|
||||
=back
|
||||
|
||||
=head2 BAR SECTION
|
||||
|
||||
=over 2
|
||||
|
||||
=item FOO
|
||||
|
||||
FOO
|
||||
|
||||
=item BAR
|
||||
|
||||
BAR
|
||||
|
||||
=back
|
||||
|
||||
=head2 Miscellaneous Options
|
||||
|
||||
=over 2
|
||||
|
||||
=item -q, --quiet
|
||||
|
||||
Avoid verbose output.
|
||||
|
||||
=item -d, --debug
|
||||
|
||||
Print debugging information
|
||||
|
||||
=item --dry-run
|
||||
|
||||
Proceed through the conversion process, but don't convert disks or actually
|
||||
write any converted files.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
XXX
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Please see http://virt-manager.org/page/BugReporting
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) Red Hat, Inc, and various contributors.
|
||||
This is free software. You may redistribute copies of it under the terms
|
||||
of the GNU General Public License C<http://www.gnu.org/licenses/gpl.html>.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<virt-install(1)>, the project website C<http://virt-manager.org>
|
||||
|
||||
=cut
|
13
setup.py
13
setup.py
@ -32,7 +32,7 @@ def _generate_potfiles_in():
|
||||
return ret
|
||||
|
||||
scripts = ["virt-manager", "virt-install",
|
||||
"virt-clone", "virt-image", "virt-convert"]
|
||||
"virt-clone", "virt-image", "virt-convert", "virt-xml"]
|
||||
|
||||
potfiles = "\n".join(scripts) + "\n\n"
|
||||
potfiles += "\n".join(find("virtManager", "*.py")) + "\n\n"
|
||||
@ -145,7 +145,7 @@ class my_build(build):
|
||||
|
||||
def _make_bin_wrappers(self):
|
||||
cmds = ["virt-manager", "virt-install", "virt-clone",
|
||||
"virt-image", "virt-convert"]
|
||||
"virt-image", "virt-convert", "virt-xml"]
|
||||
|
||||
if not os.path.exists("build"):
|
||||
os.mkdir("build")
|
||||
@ -559,7 +559,7 @@ class CheckPylint(Command):
|
||||
|
||||
def run(self):
|
||||
files = ["setup.py", "virt-install", "virt-clone", "virt-image",
|
||||
"virt-convert", "virt-manager",
|
||||
"virt-convert", "virt-xml", "virt-manager",
|
||||
"virtcli", "virtinst", "virtconv", "virtManager",
|
||||
"tests"]
|
||||
|
||||
@ -590,7 +590,8 @@ setup(
|
||||
"build/virt-clone",
|
||||
"build/virt-install",
|
||||
"build/virt-image",
|
||||
"build/virt-convert"]),
|
||||
"build/virt-convert",
|
||||
"build/virt-xml"]),
|
||||
|
||||
data_files=[
|
||||
("share/virt-manager/", [
|
||||
@ -599,6 +600,7 @@ setup(
|
||||
"virt-clone",
|
||||
"virt-image",
|
||||
"virt-convert",
|
||||
"virt-xml",
|
||||
]),
|
||||
("share/glib-2.0/schemas",
|
||||
["data/org.virt-manager.virt-manager.gschema.xml"]),
|
||||
@ -609,7 +611,8 @@ setup(
|
||||
"man/virt-install.1",
|
||||
"man/virt-clone.1",
|
||||
"man/virt-image.1",
|
||||
"man/virt-convert.1"
|
||||
"man/virt-convert.1",
|
||||
"man/virt-xml.1"
|
||||
]),
|
||||
("share/man/man5", ["man/virt-image.5"]),
|
||||
|
||||
|
@ -70,6 +70,7 @@ virtinstall = _import("virtinstall", "virt-install")
|
||||
virtimage = _import("virtimage", "virt-image")
|
||||
virtclone = _import("virtclone", "virt-clone")
|
||||
virtconvert = _import("virtconvert", "virt-convert")
|
||||
virtxml = _import("virtxml", "virt-xml")
|
||||
|
||||
# Variable used to store a local iso or dir path to check for a distro
|
||||
# Specified via 'python setup.py test_urls --path"
|
||||
|
30
tests/cli-test-xml/compare/virtxml-edit-all.xml
Normal file
30
tests/cli-test-xml/compare/virtxml-edit-all.xml
Normal file
@ -0,0 +1,30 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -265,21 +265,25 @@
|
||||
<vendor id="0x04b3"/>
|
||||
<product id="0x4485"/>
|
||||
</source>
|
||||
+ <driver name="vfio"/>
|
||||
</hostdev>
|
||||
<hostdev mode="subsystem" type="usb" managed="yes">
|
||||
<source>
|
||||
<address bus="3" device="2"/>
|
||||
</source>
|
||||
+ <driver name="vfio"/>
|
||||
</hostdev>
|
||||
<hostdev mode="subsystem" type="pci" managed="yes">
|
||||
<source>
|
||||
<address domain="0x0000" bus="0x00" slot="0x19" function="0x0"/>
|
||||
</source>
|
||||
+ <driver name="vfio"/>
|
||||
</hostdev>
|
||||
<hostdev mode="subsystem" type="pci" managed="yes">
|
||||
<source>
|
||||
<address domain="0x0003" bus="0x00" slot="0x19" function="0x0"/>
|
||||
</source>
|
||||
+ <driver name="vfio"/>
|
||||
</hostdev>
|
||||
<redirdev bus="usb" type="tcp">
|
||||
<source mode="connect" host="localhost" service="4000"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
13
tests/cli-test-xml/compare/virtxml-edit-neg-num.xml
Normal file
13
tests/cli-test-xml/compare/virtxml-edit-neg-num.xml
Normal file
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -258,7 +258,7 @@
|
||||
<model type="vmvga" vram="9216" heads="1"/>
|
||||
</video>
|
||||
<video>
|
||||
- <model type="cirrus" vram="10240" heads="3"/>
|
||||
+ <model type="qxl" vram="10240" heads="3"/>
|
||||
</video>
|
||||
<hostdev mode="subsystem" type="usb" managed="yes">
|
||||
<source>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
13
tests/cli-test-xml/compare/virtxml-edit-pos-num.xml
Normal file
13
tests/cli-test-xml/compare/virtxml-edit-pos-num.xml
Normal file
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -253,7 +253,7 @@
|
||||
</graphics>
|
||||
<sound model="sb16"/>
|
||||
<sound model="es1370"/>
|
||||
- <sound model="ich6"/>
|
||||
+ <sound model="pcspk"/>
|
||||
<video>
|
||||
<model type="vmvga" vram="9216" heads="1"/>
|
||||
</video>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -65,7 +65,7 @@
|
||||
<address type="drive" controller="0" bus="0" target="0" unit="1"/>
|
||||
</disk>
|
||||
<disk type="file" device="disk">
|
||||
- <source file="/tmp/foobar"/>
|
||||
+ <source file="/dev/null"/>
|
||||
<target dev="hda" bus="ide"/>
|
||||
<iotune>
|
||||
<read_bytes_sec>5242880</read_bytes_sec>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -159,7 +159,7 @@
|
||||
<interface type="ethernet">
|
||||
<mac address="00:11:7f:33:44:55"/>
|
||||
<script path="/etc/qemu-ifup"/>
|
||||
- <target dev="nic02"/>
|
||||
+ <target dev="nic55"/>
|
||||
</interface>
|
||||
<interface type="direct">
|
||||
<mac address="f0:11:22:33:44:5f"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -253,7 +253,7 @@
|
||||
</graphics>
|
||||
<sound model="sb16"/>
|
||||
<sound model="es1370"/>
|
||||
- <sound model="ich6"/>
|
||||
+ <sound model="pcspk"/>
|
||||
<video>
|
||||
<model type="vmvga" vram="9216" heads="1"/>
|
||||
</video>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
17
tests/cli-test-xml/compare/virtxml-edit-simple-boot.xml
Normal file
17
tests/cli-test-xml/compare/virtxml-edit-simple-boot.xml
Normal file
@ -0,0 +1,17 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -15,8 +15,10 @@
|
||||
</numatune>
|
||||
<os>
|
||||
<type arch="i686">hvm</type>
|
||||
- <loader>/usr/lib/xen/boot/hvmloader</loader>
|
||||
- <boot dev="hd"/>
|
||||
+ <loader>foo.bar</loader>
|
||||
+ <boot dev="network"/>
|
||||
+ <bios useserial="yes"/>
|
||||
+ <init>/bin/bash</init>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
13
tests/cli-test-xml/compare/virtxml-edit-simple-channel.xml
Normal file
13
tests/cli-test-xml/compare/virtxml-edit-simple-channel.xml
Normal file
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -214,7 +214,7 @@
|
||||
<console type="pty">
|
||||
<target type="uml" port="1"/>
|
||||
</console>
|
||||
- <channel type="pipe">
|
||||
+ <channel type="null">
|
||||
<source path="/tmp/guestfwd"/>
|
||||
<target type="guestfwd" address="10.0.2.1" port="4600"/>
|
||||
</channel>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
19
tests/cli-test-xml/compare/virtxml-edit-simple-clock.xml
Normal file
19
tests/cli-test-xml/compare/virtxml-edit-simple-clock.xml
Normal file
@ -0,0 +1,19 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -44,10 +44,11 @@
|
||||
<feature policy="require" name="xtpr"/>
|
||||
<feature policy="require" name="acpi"/>
|
||||
</cpu>
|
||||
- <clock offset="utc">
|
||||
- <timer name="rtc" tickpolicy="catchup"/>
|
||||
+ <clock offset="localtime">
|
||||
+ <timer name="rtc" tickpolicy="merge"/>
|
||||
<timer name="pit" tickpolicy="delay"/>
|
||||
- <timer name="hpet" present="no"/>
|
||||
+ <timer name="hpet" present="yes"/>
|
||||
+ <timer name="kvmclock" present="no"/>
|
||||
</clock>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
13
tests/cli-test-xml/compare/virtxml-edit-simple-console.xml
Normal file
13
tests/cli-test-xml/compare/virtxml-edit-simple-console.xml
Normal file
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -209,7 +209,7 @@
|
||||
<target port="2"/>
|
||||
</parallel>
|
||||
<console type="pty">
|
||||
- <target type="virtio" port="0"/>
|
||||
+ <target type="serial" port="0"/>
|
||||
</console>
|
||||
<console type="pty">
|
||||
<target type="uml" port="1"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -98,7 +98,7 @@
|
||||
<source file="/tmp/foobar4"/>
|
||||
<target dev="xvdc" bus="xen"/>
|
||||
</disk>
|
||||
- <controller type="scsi" index="0" model="virtio-scsi"/>
|
||||
+ <controller type="scsi" index="2" model="lsilogic"/>
|
||||
<controller type="usb" index="0"/>
|
||||
<controller type="fdc" index="0"/>
|
||||
<controller type="ide" index="0"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
24
tests/cli-test-xml/compare/virtxml-edit-simple-cpu.xml
Normal file
24
tests/cli-test-xml/compare/virtxml-edit-simple-cpu.xml
Normal file
@ -0,0 +1,24 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -28,9 +28,9 @@
|
||||
</hyperv>
|
||||
</features>
|
||||
<cpu mode="custom" match="exact">
|
||||
- <model fallback="allow">core2duo</model>
|
||||
+ <model fallback="allow">pentium2</model>
|
||||
<vendor>Intel</vendor>
|
||||
- <feature policy="require" name="pbe"/>
|
||||
+ <feature policy="forbid" name="pbe"/>
|
||||
<feature policy="require" name="tm2"/>
|
||||
<feature policy="require" name="est"/>
|
||||
<feature policy="require" name="ss"/>
|
||||
@@ -43,6 +43,7 @@
|
||||
<feature policy="require" name="ds_cpl"/>
|
||||
<feature policy="require" name="xtpr"/>
|
||||
<feature policy="require" name="acpi"/>
|
||||
+ <feature name="x2apic" policy="force"/>
|
||||
</cpu>
|
||||
<clock offset="utc">
|
||||
<timer name="rtc" tickpolicy="catchup"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
16
tests/cli-test-xml/compare/virtxml-edit-simple-disk.xml
Normal file
16
tests/cli-test-xml/compare/virtxml-edit-simple-disk.xml
Normal file
@ -0,0 +1,16 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -55,9 +55,10 @@
|
||||
<devices>
|
||||
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||
<disk type="block" device="floppy">
|
||||
- <source dev="/dev/null"/>
|
||||
+ <source dev="/dev/zero" startupPolicy="optional"/>
|
||||
<target dev="fda" bus="fdc"/>
|
||||
<address type="drive" controller="0" bus="0" target="0" unit="0"/>
|
||||
+ <readonly/>
|
||||
</disk>
|
||||
<disk type="dir" device="floppy">
|
||||
<source dir="/tmp"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
17
tests/cli-test-xml/compare/virtxml-edit-simple-features.xml
Normal file
17
tests/cli-test-xml/compare/virtxml-edit-simple-features.xml
Normal file
@ -0,0 +1,17 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -19,10 +19,9 @@
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<features>
|
||||
- <acpi/>
|
||||
- <apic eoi="off"/>
|
||||
+ <apic eoi="on"/>
|
||||
<hyperv>
|
||||
- <relaxed state="on"/>
|
||||
+ <relaxed state="off"/>
|
||||
<vapic state="on"/>
|
||||
<spinlocks state="on" retries="12287"/>
|
||||
</hyperv>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
@ -0,0 +1,18 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -105,10 +105,10 @@
|
||||
<controller type="virtio-serial" index="1"/>
|
||||
<controller type="virtio-serial" index="0"/>
|
||||
<controller type="ccid" index="0"/>
|
||||
- <filesystem type="mount" accessmode="passthrough">
|
||||
+ <filesystem type="mount" accessmode="mapped">
|
||||
<driver type="handle"/>
|
||||
- <source dir="/foo/bar"/>
|
||||
- <target dir="/bar/baz"/>
|
||||
+ <source dir="/1/2/3"/>
|
||||
+ <target dir="/4/5/6"/>
|
||||
</filesystem>
|
||||
<filesystem type="template" accessmode="passthrough">
|
||||
<source name="template_fedora"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
13
tests/cli-test-xml/compare/virtxml-edit-simple-graphics.xml
Normal file
13
tests/cli-test-xml/compare/virtxml-edit-simple-graphics.xml
Normal file
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -238,7 +238,7 @@
|
||||
</backend>
|
||||
</tpm>
|
||||
<input type="mouse" bus="ps2"/>
|
||||
- <graphics type="sdl" display=":3.4" xauth="/testdir/.Xauthority" fullscreen="yes"/>
|
||||
+ <graphics type="sdl" display=":3.4" xauth="/testdir/.Xauthority" fullscreen="yes" tlsPort="5902" keymap="ja"/>
|
||||
<graphics type="vnc" port="-1" autoport="yes"/>
|
||||
<graphics type="vnc" port="-1" autoport="yes" listen="1.2.3.4" keymap="fi">
|
||||
<listen type="address" address="1.2.3.4"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
@ -0,0 +1,17 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -262,9 +262,10 @@
|
||||
</video>
|
||||
<hostdev mode="subsystem" type="usb" managed="yes">
|
||||
<source>
|
||||
- <vendor id="0x04b3"/>
|
||||
- <product id="0x4485"/>
|
||||
+ <vendor id="0x0781"/>
|
||||
+ <product id="0x5151"/>
|
||||
</source>
|
||||
+ <driver name="vfio"/>
|
||||
</hostdev>
|
||||
<hostdev mode="subsystem" type="usb" managed="yes">
|
||||
<source>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -293,7 +293,7 @@
|
||||
<usbdev allow="no"/>
|
||||
</redirfilter>
|
||||
<watchdog model="ib700" action="poweroff"/>
|
||||
- <memballoon model="virtio"/>
|
||||
+ <memballoon model="none"/>
|
||||
<rng model="virtio">
|
||||
<rate bytes="1234" period="2000"/>
|
||||
<backend model="egd" type="tcp">
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
19
tests/cli-test-xml/compare/virtxml-edit-simple-network.xml
Normal file
19
tests/cli-test-xml/compare/virtxml-edit-simple-network.xml
Normal file
@ -0,0 +1,19 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -124,11 +124,10 @@
|
||||
<source dir="/foo/bar"/>
|
||||
<target dir="/bar/baz"/>
|
||||
</filesystem>
|
||||
- <interface type="network">
|
||||
- <mac address="22:22:33:54:32:10"/>
|
||||
- <source network="default"/>
|
||||
+ <interface type="bridge">
|
||||
+ <source bridge="br0"/>
|
||||
<target dev="testnet0"/>
|
||||
- <model type="e1000"/>
|
||||
+ <model type="virtio"/>
|
||||
</interface>
|
||||
<interface type="network">
|
||||
<mac address="22:11:11:11:11:11"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
13
tests/cli-test-xml/compare/virtxml-edit-simple-numatune.xml
Normal file
13
tests/cli-test-xml/compare/virtxml-edit-simple-numatune.xml
Normal file
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -11,7 +11,7 @@
|
||||
</memoryBacking>
|
||||
<vcpu placement="static" cpuset="1-2,5-9,11,13-14">9</vcpu>
|
||||
<numatune>
|
||||
- <memory mode="interleave" placement="auto"/>
|
||||
+ <memory mode="strict" placement="auto" nodeset="1-5,7"/>
|
||||
</numatune>
|
||||
<os>
|
||||
<type arch="i686">hvm</type>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
15
tests/cli-test-xml/compare/virtxml-edit-simple-parallel.xml
Normal file
15
tests/cli-test-xml/compare/virtxml-edit-simple-parallel.xml
Normal file
@ -0,0 +1,15 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -195,8 +195,8 @@
|
||||
<protocol type="telnet"/>
|
||||
<target port="1"/>
|
||||
</serial>
|
||||
- <parallel type="file">
|
||||
- <source path="/tmp/foo.log"/>
|
||||
+ <parallel type="unix">
|
||||
+ <source path="/some/other/log"/>
|
||||
<target port="0"/>
|
||||
</parallel>
|
||||
<parallel type="unix">
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
15
tests/cli-test-xml/compare/virtxml-edit-simple-redirdev.xml
Normal file
15
tests/cli-test-xml/compare/virtxml-edit-simple-redirdev.xml
Normal file
@ -0,0 +1,15 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -281,8 +281,8 @@
|
||||
<address domain="0x0003" bus="0x00" slot="0x19" function="0x0"/>
|
||||
</source>
|
||||
</hostdev>
|
||||
- <redirdev bus="usb" type="tcp">
|
||||
- <source mode="connect" host="localhost" service="4000"/>
|
||||
+ <redirdev bus="usb" type="spicevmc">
|
||||
+ <source mode="connect" host="example.com" service="12345"/>
|
||||
<protocol type="raw"/>
|
||||
</redirdev>
|
||||
<redirdev bus="usb" type="spicevmc">
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
13
tests/cli-test-xml/compare/virtxml-edit-simple-rng.xml
Normal file
13
tests/cli-test-xml/compare/virtxml-edit-simple-rng.xml
Normal file
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -295,7 +295,7 @@
|
||||
<watchdog model="ib700" action="poweroff"/>
|
||||
<memballoon model="virtio"/>
|
||||
<rng model="virtio">
|
||||
- <rate bytes="1234" period="2000"/>
|
||||
+ <rate bytes="3333" period="4444"/>
|
||||
<backend model="egd" type="tcp">
|
||||
<source mode="connect" host="1.2.3.4" service="1234"/>
|
||||
<protocol type="raw"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
12
tests/cli-test-xml/compare/virtxml-edit-simple-security.xml
Normal file
12
tests/cli-test-xml/compare/virtxml-edit-simple-security.xml
Normal file
@ -0,0 +1,12 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -302,4 +302,7 @@
|
||||
</backend>
|
||||
</rng>
|
||||
</devices>
|
||||
+ <seclabel relabel="yes">
|
||||
+ <label>foo,bar,baz</label>
|
||||
+ </seclabel>
|
||||
</domain>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
13
tests/cli-test-xml/compare/virtxml-edit-simple-serial.xml
Normal file
13
tests/cli-test-xml/compare/virtxml-edit-simple-serial.xml
Normal file
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -187,7 +187,7 @@
|
||||
<protocol type="raw"/>
|
||||
<address type="ccid" controller="0" slot="3"/>
|
||||
</smartcard>
|
||||
- <serial type="null">
|
||||
+ <serial type="pty">
|
||||
<target port="0"/>
|
||||
</serial>
|
||||
<serial type="tcp">
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
13
tests/cli-test-xml/compare/virtxml-edit-simple-smartcard.xml
Normal file
13
tests/cli-test-xml/compare/virtxml-edit-simple-smartcard.xml
Normal file
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -170,7 +170,7 @@
|
||||
<target dev="testnet6"/>
|
||||
<address type="pci" domain="0x0000" bus="0x00" slot="0x07" function="0x0"/>
|
||||
</interface>
|
||||
- <smartcard mode="host">
|
||||
+ <smartcard mode="host" type="spicevmc">
|
||||
<address type="ccid" controller="0" slot="0"/>
|
||||
</smartcard>
|
||||
<smartcard mode="host-certificates">
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
13
tests/cli-test-xml/compare/virtxml-edit-simple-soundhw.xml
Normal file
13
tests/cli-test-xml/compare/virtxml-edit-simple-soundhw.xml
Normal file
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -251,7 +251,7 @@
|
||||
<channel name="inputs" mode="secure"/>
|
||||
<channel name="record" mode="insecure"/>
|
||||
</graphics>
|
||||
- <sound model="sb16"/>
|
||||
+ <sound model="pcspk"/>
|
||||
<sound model="es1370"/>
|
||||
<sound model="ich6"/>
|
||||
<video>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
13
tests/cli-test-xml/compare/virtxml-edit-simple-tpm.xml
Normal file
13
tests/cli-test-xml/compare/virtxml-edit-simple-tpm.xml
Normal file
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -234,7 +234,7 @@
|
||||
<input type="tablet" bus="usb"/>
|
||||
<tpm model="tpm-tis">
|
||||
<backend type="passthrough">
|
||||
- <device path="/dev/tzz"/>
|
||||
+ <device path="/dev/tpm"/>
|
||||
</backend>
|
||||
</tpm>
|
||||
<input type="mouse" bus="ps2"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
21
tests/cli-test-xml/compare/virtxml-edit-simple-vcpus.xml
Normal file
21
tests/cli-test-xml/compare/virtxml-edit-simple-vcpus.xml
Normal file
@ -0,0 +1,21 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -9,7 +9,7 @@
|
||||
<memoryBacking>
|
||||
<hugepages/>
|
||||
</memoryBacking>
|
||||
- <vcpu placement="static" cpuset="1-2,5-9,11,13-14">9</vcpu>
|
||||
+ <vcpu placement="static" cpuset="1-2,5-9,11,13-14" current="10">20</vcpu>
|
||||
<numatune>
|
||||
<memory mode="interleave" placement="auto"/>
|
||||
</numatune>
|
||||
@@ -43,6 +43,7 @@
|
||||
<feature policy="require" name="ds_cpl"/>
|
||||
<feature policy="require" name="xtpr"/>
|
||||
<feature policy="require" name="acpi"/>
|
||||
+ <topology sockets="4" cores="5" threads="1"/>
|
||||
</cpu>
|
||||
<clock offset="utc">
|
||||
<timer name="rtc" tickpolicy="catchup"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
13
tests/cli-test-xml/compare/virtxml-edit-simple-video.xml
Normal file
13
tests/cli-test-xml/compare/virtxml-edit-simple-video.xml
Normal file
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -255,7 +255,7 @@
|
||||
<sound model="es1370"/>
|
||||
<sound model="ich6"/>
|
||||
<video>
|
||||
- <model type="vmvga" vram="9216" heads="1"/>
|
||||
+ <model type="cirrus" vram="9216" heads="1"/>
|
||||
</video>
|
||||
<video>
|
||||
<model type="cirrus" vram="10240" heads="3"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
13
tests/cli-test-xml/compare/virtxml-edit-simple-watchdog.xml
Normal file
13
tests/cli-test-xml/compare/virtxml-edit-simple-watchdog.xml
Normal file
@ -0,0 +1,13 @@
|
||||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -292,7 +292,7 @@
|
||||
<usbdev class="0x08" vendor="0x15E1" product="0x2007" version="1.10" allow="yes"/>
|
||||
<usbdev allow="no"/>
|
||||
</redirfilter>
|
||||
- <watchdog model="ib700" action="poweroff"/>
|
||||
+ <watchdog model="ib700" action="reset"/>
|
||||
<memballoon model="virtio"/>
|
||||
<rng model="virtio">
|
||||
<rate bytes="1234" period="2000"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
17
tests/cli-test-xml/compare/virtxml-print-xml.xml
Normal file
17
tests/cli-test-xml/compare/virtxml-print-xml.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<domain type="test" id="1">
|
||||
<name>test</name>
|
||||
<uuid>4a64cc71-19c4-2fd0-2323-3050941ea3c3</uuid>
|
||||
<memory unit="KiB">8388608</memory>
|
||||
<currentMemory unit="KiB">2097152</currentMemory>
|
||||
<vcpu placement="static">7</vcpu>
|
||||
<os>
|
||||
<type arch="i686">hvm</type>
|
||||
<boot dev="hd"/>
|
||||
</os>
|
||||
<clock offset="utc"/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
</devices>
|
||||
</domain>
|
@ -30,9 +30,12 @@ import StringIO
|
||||
import virtinst.cli
|
||||
from virtinst import support
|
||||
|
||||
from tests import virtinstall, virtimage, virtclone, virtconvert
|
||||
from tests import virtinstall, virtimage, virtclone, virtconvert, virtxml
|
||||
from tests import utils
|
||||
|
||||
# Enable this to refresh test output
|
||||
REGENERATE_OUTPUT = False
|
||||
|
||||
os.environ["VIRTCONV_TEST_NO_DISK_CONVERSION"] = "1"
|
||||
os.environ["LANG"] = "en_US.UTF-8"
|
||||
|
||||
@ -185,6 +188,8 @@ class Command(object):
|
||||
ret = virtimage.main(conn=conn)
|
||||
elif app.count("virt-convert"):
|
||||
ret = virtconvert.main()
|
||||
elif app.count("virt-xml"):
|
||||
ret = virtxml.main()
|
||||
except SystemExit, sys_e:
|
||||
ret = sys_e.code
|
||||
|
||||
@ -244,7 +249,7 @@ class Command(object):
|
||||
|
||||
if filename:
|
||||
# Generate test files that don't exist yet
|
||||
if not os.path.exists(filename):
|
||||
if REGENERATE_OUTPUT or not os.path.exists(filename):
|
||||
file(filename, "w").write(output)
|
||||
|
||||
utils.diff_compare(output, filename)
|
||||
@ -260,23 +265,40 @@ class PromptCheck(object):
|
||||
"""
|
||||
Individual question/response pair for automated --prompt tests
|
||||
"""
|
||||
def __init__(self, prompt, response=None):
|
||||
def __init__(self, prompt, response=None, num_lines=1):
|
||||
self.prompt = prompt
|
||||
self.response = response
|
||||
if self.response:
|
||||
self.response = self.response % test_files
|
||||
self.num_lines = num_lines
|
||||
|
||||
self._output = None
|
||||
|
||||
def check(self, proc):
|
||||
out = proc.stdout.readline()
|
||||
timeout = 3
|
||||
def _set_output():
|
||||
self._output = ""
|
||||
for ignore in range(self.num_lines):
|
||||
self._output += proc.stdout.readline()
|
||||
|
||||
if not out.count(self.prompt):
|
||||
out += "\nContent didn't contain prompt '%s'" % (self.prompt)
|
||||
return False, out
|
||||
import threading
|
||||
thread = threading.Thread(target=_set_output)
|
||||
thread.start()
|
||||
thread.join(timeout)
|
||||
|
||||
if thread.isAlive():
|
||||
proc.terminate()
|
||||
return False, self._output + "\nProcess hung on readline()"
|
||||
|
||||
if not self._output.count(self.prompt):
|
||||
self._output += ("\nContent didn't contain prompt '%s'" %
|
||||
(self.prompt))
|
||||
return False, self._output
|
||||
|
||||
if self.response:
|
||||
proc.stdin.write(self.response + "\n")
|
||||
|
||||
return True, out
|
||||
return True, self._output
|
||||
|
||||
|
||||
class PromptTest(Command):
|
||||
@ -725,6 +747,54 @@ c.add_invalid("--hvm --boot kernel=%(TREEDIR)s/pxeboot/vmlinuz,initrd=%(TREEDIR)
|
||||
|
||||
|
||||
|
||||
vixml = App("virt-xml")
|
||||
c = vixml.add_category("misc", "")
|
||||
c.add_valid("--help") # basic --help test
|
||||
c.add_valid("--soundhw=? --tpm=?") # basic introspection test
|
||||
c.add_invalid("--domain test --edit --hostdev driver_name=vfio") # Guest has no hostdev to edit
|
||||
c.add_invalid("--domain test --edit --cpu host-passthrough --boot hd,network") # Specified more than 1 option
|
||||
c.add_invalid("--domain test --edit") # specified no edit option
|
||||
c.add_invalid("--domain test --edit 2 --cpu host-passthrough") # specifing --edit number where it doesn't make sense
|
||||
c.add_invalid("--domain test-many-devices --edit 5 --tpm /dev/tpm") # device edit out of range
|
||||
c.add_compare("--domain test --print-xml --edit --vcpus 7", "virtxml-print-xml") # test --print-xml
|
||||
|
||||
c = vixml.add_category("simple edit diff", "--domain test-many-devices --edit --print-diff --define")
|
||||
c.add_compare("--vcpus 10,maxvcpus=20,cores=5,sockets=4,threads=1", "virtxml-edit-simple-vcpus")
|
||||
c.add_compare("--cpu model=pentium2,+x2apic,forbid=pbe", "virtxml-edit-simple-cpu")
|
||||
c.add_compare("--numatune 1-5,7,mode=strict", "virtxml-edit-simple-numatune")
|
||||
c.add_compare("--boot loader=foo.bar,network,useserial=on,init=/bin/bash", "virtxml-edit-simple-boot")
|
||||
c.add_compare("--security label=foo,bar,baz,relabel=on", "virtxml-edit-simple-security")
|
||||
c.add_compare("--features eoi=on,hyperv_relaxed=off,acpi=", "virtxml-edit-simple-features")
|
||||
c.add_compare("--clock offset=localtime,hpet_present=yes,kvmclock_present=no,rtc_tickpolicy=merge", "virtxml-edit-simple-clock")
|
||||
c.add_compare("--disk /dev/zero,perms=ro,startup_policy=optional", "virtxml-edit-simple-disk")
|
||||
c.add_compare("--network source=br0,type=bridge,model=virtio,mac=", "virtxml-edit-simple-network")
|
||||
c.add_compare("--graphics tlsport=5902,keymap=ja", "virtxml-edit-simple-graphics")
|
||||
c.add_compare("--controller index=2,model=lsilogic", "virtxml-edit-simple-controller")
|
||||
c.add_compare("--smartcard type=spicevmc", "virtxml-edit-simple-smartcard")
|
||||
c.add_compare("--redirdev type=spicevmc,server=example.com:12345", "virtxml-edit-simple-redirdev")
|
||||
c.add_compare("--tpm path=/dev/tpm", "virtxml-edit-simple-tpm")
|
||||
c.add_compare("--rng rate_bytes=3333,rate_period=4444", "virtxml-edit-simple-rng")
|
||||
c.add_compare("--watchdog action=reset", "virtxml-edit-simple-watchdog")
|
||||
c.add_compare("--memballoon model=none", "virtxml-edit-simple-memballoon")
|
||||
c.add_compare("--serial pty", "virtxml-edit-simple-serial")
|
||||
c.add_compare("--parallel unix,path=/some/other/log", "virtxml-edit-simple-parallel")
|
||||
c.add_compare("--channel null", "virtxml-edit-simple-channel")
|
||||
c.add_compare("--console target_type=serial", "virtxml-edit-simple-console")
|
||||
c.add_compare("--filesystem /1/2/3,/4/5/6,mode=mapped", "virtxml-edit-simple-filesystem")
|
||||
c.add_compare("--video cirrus", "virtxml-edit-simple-video")
|
||||
c.add_compare("--soundhw pcspk", "virtxml-edit-simple-soundhw")
|
||||
c.add_compare("--host-device 0x0781:0x5151,driver_name=vfio", "virtxml-edit-simple-host-device")
|
||||
|
||||
c = vixml.add_category("edit selection", "--domain test-many-devices --print-diff --define")
|
||||
c.add_invalid("--edit target=vvv --disk /dev/null") # no match found
|
||||
c.add_compare("--edit 3 --soundhw pcspk", "virtxml-edit-pos-num")
|
||||
c.add_compare("--edit -1 --video qxl", "virtxml-edit-neg-num")
|
||||
c.add_compare("--edit all --host-device driver_name=vfio", "virtxml-edit-all")
|
||||
c.add_compare("--edit ich6 --soundhw pcspk", "virtxml-edit-select-sound-model")
|
||||
c.add_compare("--edit target=hda --disk /dev/null", "virtxml-edit-select-disk-target")
|
||||
c.add_compare("--edit mac=00:11:7f:33:44:55 --network target=nic55", "virtxml-edit-select-network-mac")
|
||||
|
||||
|
||||
vimag = App("virt-image")
|
||||
c = vimag.add_category("graphics", "--name test-image --boot 0 %(IMAGE_XML)s")
|
||||
c.add_valid("--sdl") # SDL
|
||||
@ -887,6 +957,10 @@ p7.add("'/root' must be a file or a device")
|
||||
p7.add("use as the cloned disk", "%(MANAGEDNEW1)s")
|
||||
promptlist.append(p7)
|
||||
|
||||
p8 = PromptTest("virt-xml --connect %(TESTURI)s --confirm --domain test "
|
||||
"--edit --cpu host-passthrough")
|
||||
p8.add("Define 'test' with the changed XML", "yes", num_lines=12)
|
||||
promptlist.append(p8)
|
||||
|
||||
|
||||
#########################
|
||||
@ -949,6 +1023,7 @@ _cmdlist += vinst.cmds
|
||||
_cmdlist += vclon.cmds
|
||||
_cmdlist += vimag.cmds
|
||||
_cmdlist += vconv.cmds
|
||||
_cmdlist += vixml.cmds
|
||||
|
||||
for _cmd in _cmdlist:
|
||||
newidx += 1
|
||||
|
@ -71,13 +71,26 @@
|
||||
yeah boii < > yeahfoo
|
||||
</description>
|
||||
<features>
|
||||
<acpi/><apic/>
|
||||
<acpi/>
|
||||
<apic eoi='off'/>
|
||||
<hyperv>
|
||||
<relaxed state='on'/>
|
||||
<vapic state='on'/>
|
||||
<spinlocks state='on' retries='12287'/>
|
||||
</hyperv>
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<clock offset="utc">
|
||||
<timer name="rtc" tickpolicy="catchup"/>
|
||||
<timer name="pit" tickpolicy="delay"/>
|
||||
<timer name="hpet" present="no"/>
|
||||
</clock>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<vcpu cpuset="1,2,5-9,11,13-14">9</vcpu>
|
||||
<numatune>
|
||||
<memory mode='interleave' placement='auto'/>
|
||||
</numatune>
|
||||
<cpu match="exact">
|
||||
<model>core2duo</model>
|
||||
<vendor>Intel</vendor>
|
||||
@ -148,14 +161,13 @@
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<source network='idontexistfool'/>
|
||||
<mac address='22:11:11:11:11:11'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<source network='dupmac'/>
|
||||
<mac address='22:22:33:54:32:11'/>
|
||||
</interface>
|
||||
<interface type='user'>
|
||||
<mac address='22:11:11:11:11:11'/>
|
||||
</interface>
|
||||
<interface type='user'/>
|
||||
<interface type='bridge'>
|
||||
<source bridge='brempty'/>
|
||||
<mac address='22:22:33:44:AA:BB'/>
|
||||
@ -166,9 +178,8 @@
|
||||
<mac address='22:00:00:44:AA:BF'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<controller type='usb'/>
|
||||
<interface type='ethernet'>
|
||||
<mac address='00:11:7F:33:44:55'/>
|
||||
<mac address='00:11:7f:33:44:55'/>
|
||||
<script path='/etc/qemu-ifup'/>
|
||||
<target dev='nic02'/>
|
||||
</interface>
|
||||
@ -200,6 +211,9 @@
|
||||
<channel name="record" mode="insecure"/>
|
||||
</graphics>
|
||||
|
||||
<!-- controller devices -->
|
||||
<controller type='scsi' model='virtio-scsi'/>
|
||||
<controller type='usb'/>
|
||||
|
||||
<!-- sound devices -->
|
||||
<sound model='sb16'/>
|
||||
@ -363,6 +377,9 @@
|
||||
<panic>
|
||||
<address type='isa' iobase='0x505'/>
|
||||
</panic>
|
||||
|
||||
<!-- memballoon device -->
|
||||
<memballoon model='virtio'/>
|
||||
</devices>
|
||||
</domain>
|
||||
|
||||
|
@ -93,6 +93,7 @@ Provides: virt-install
|
||||
Provides: virt-clone
|
||||
Provides: virt-image
|
||||
Provides: virt-convert
|
||||
Provides: virt-xml
|
||||
Obsoletes: python-virtinst
|
||||
|
||||
%description -n virt-install
|
||||
@ -194,6 +195,7 @@ fi
|
||||
%{_mandir}/man1/virt-install.1*
|
||||
%{_mandir}/man1/virt-clone.1*
|
||||
%{_mandir}/man1/virt-convert.1*
|
||||
%{_mandir}/man1/virt-xml.1*
|
||||
%{_mandir}/man1/virt-image.1*
|
||||
%{_mandir}/man5/virt-image.5*
|
||||
|
||||
@ -201,11 +203,13 @@ fi
|
||||
%{_datadir}/%{name}/virt-clone
|
||||
%{_datadir}/%{name}/virt-image
|
||||
%{_datadir}/%{name}/virt-convert
|
||||
%{_datadir}/%{name}/virt-xml
|
||||
|
||||
%{_bindir}/virt-install
|
||||
%{_bindir}/virt-clone
|
||||
%{_bindir}/virt-image
|
||||
%{_bindir}/virt-convert
|
||||
%{_bindir}/virt-xml
|
||||
|
||||
|
||||
%changelog
|
||||
|
283
virt-xml
Executable file
283
virt-xml
Executable file
@ -0,0 +1,283 @@
|
||||
#!/usr/bin/python -tt
|
||||
#
|
||||
# Copyright 2013 Red Hat, Inc.
|
||||
# Cole Robinson <crobinso@redhat.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301 USA.
|
||||
|
||||
import difflib
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
import libvirt
|
||||
|
||||
import virtinst
|
||||
from virtinst import cli
|
||||
from virtinst.cli import fail, print_stdout, print_stderr
|
||||
|
||||
|
||||
###################
|
||||
# Utility helpers #
|
||||
###################
|
||||
|
||||
def prompt_yes_or_no(msg):
|
||||
while 1:
|
||||
printmsg = msg + " (y/n): "
|
||||
if "VIRTINST_TEST_SUITE" in os.environ:
|
||||
printmsg += "\n"
|
||||
sys.stdout.write(printmsg)
|
||||
sys.stdout.flush()
|
||||
|
||||
inp = sys.stdin.readline().lower().strip()
|
||||
if inp in ["y", "yes"]:
|
||||
return True
|
||||
elif inp in ["n", "no"]:
|
||||
return False
|
||||
else:
|
||||
print_stdout(_("Please enter 'yes' or 'no'."))
|
||||
|
||||
|
||||
def get_diff(origxml, newxml):
|
||||
ret = "".join(difflib.unified_diff(origxml.splitlines(1),
|
||||
newxml.splitlines(1),
|
||||
fromfile="Original XML",
|
||||
tofile="Altered XML"))
|
||||
|
||||
if ret:
|
||||
logging.debug("XML diff:\n%s", ret)
|
||||
else:
|
||||
logging.debug("No XML diff, didn't generate any change.")
|
||||
return ret
|
||||
|
||||
|
||||
def get_domain_and_guest(conn, domstr):
|
||||
if not domstr:
|
||||
fail("--domain must be specified")
|
||||
|
||||
try:
|
||||
int(domstr)
|
||||
isint = True
|
||||
except ValueError:
|
||||
isint = False
|
||||
|
||||
try:
|
||||
virtinst.util.validate_uuid(domstr)
|
||||
isuuid = True
|
||||
except ValueError:
|
||||
isuuid = False
|
||||
|
||||
try:
|
||||
if isint:
|
||||
domain = conn.lookupByID(int(domstr))
|
||||
elif isuuid:
|
||||
domain = conn.lookupByUUIDString(domstr)
|
||||
else:
|
||||
domain = conn.lookupByName(domstr)
|
||||
except libvirt.libvirtError, e:
|
||||
fail(_("Could not find domain '%s': %s") % (domstr, e))
|
||||
|
||||
# XXX: Require this for first pass, but it sucks for testing
|
||||
#if domain.info()[0] != libvirt.VIR_DOMAIN_SHUTOFF:
|
||||
# fail(_("Domain '%s' must be shutoff.") % domain.name())
|
||||
|
||||
# XXX: any flags to use here? INACTIVE prob, though not secure or cpu
|
||||
xml = domain.XMLDesc(0)
|
||||
|
||||
# We do this to minimize the diff, removing things like ' -> "
|
||||
xml = virtinst.Guest(conn, parsexml=xml).get_xml_config()
|
||||
return (domain, xml, virtinst.Guest(conn, parsexml=xml))
|
||||
|
||||
|
||||
################
|
||||
# Change logic #
|
||||
################
|
||||
|
||||
def _find_devices_to_edit(guest, options, parserobj):
|
||||
devlist = guest.get_devices(parserobj.devclass.virtual_device_type)
|
||||
idx = None
|
||||
|
||||
if options.edit is None:
|
||||
idx = 1
|
||||
elif (options.edit.isdigit() or
|
||||
options.edit.startswith("-") and options.edit[1:].isdigit()):
|
||||
idx = int(options.edit)
|
||||
|
||||
if idx is not None:
|
||||
if idx == 0:
|
||||
fail(_("Invalid --edit option '%s'") % options.edit)
|
||||
|
||||
if not devlist:
|
||||
fail(_("No --%s devices found in the XML") %
|
||||
parserobj.cli_arg_name)
|
||||
if len(devlist) < abs(idx):
|
||||
fail(_("--edit %s requested but there's only %s "
|
||||
"--%s devices in the XML") %
|
||||
(idx, len(devlist), parserobj.cli_arg_name))
|
||||
|
||||
if idx > 0:
|
||||
idx -= 1
|
||||
inst = devlist[idx]
|
||||
elif options.edit == "all":
|
||||
inst = devlist[:]
|
||||
else:
|
||||
inst = parserobj.lookup_device_from_option_string(guest, options.edit)
|
||||
if not inst:
|
||||
fail(_("No matching devices found for --edit %s") % options.edit)
|
||||
|
||||
return inst
|
||||
|
||||
|
||||
def change_xml(guest, options, parsermap):
|
||||
# XXX: Make sure actions don't conflict
|
||||
# XXX: Make sure XML options don't conflict
|
||||
# XXX: Find a way to factor out whatever defaults there are
|
||||
if options.edit is -1:
|
||||
fail("--edit must be specified")
|
||||
|
||||
collisions = []
|
||||
for option_variable_name, parserobj in parsermap.items():
|
||||
if getattr(options, option_variable_name):
|
||||
collisions.append(parserobj)
|
||||
|
||||
if len(collisions) == 0:
|
||||
fail(_("No change specified."))
|
||||
if len(collisions) != 1:
|
||||
fail(_("Only one change operation may be specified "
|
||||
"(conflicting options %s)") %
|
||||
["--" + c.cli_arg_name for c in collisions])
|
||||
parserobj = collisions[0]
|
||||
|
||||
if parserobj.devclass:
|
||||
inst = _find_devices_to_edit(guest, options, parserobj)
|
||||
else:
|
||||
inst = guest
|
||||
if options.edit and options.edit != '1' and options.edit != 'all':
|
||||
fail(_("'--edit %s' doesn't make sense with --%s, "
|
||||
"just use empty '--edit'") %
|
||||
(options.edit, parserobj.cli_arg_name))
|
||||
|
||||
cli.parse_option_strings(parsermap, options, guest, inst)
|
||||
|
||||
|
||||
#######################
|
||||
# CLI option handling #
|
||||
#######################
|
||||
|
||||
def parse_args():
|
||||
# XXX: man page: mention introspection if it makes sense
|
||||
# XXX: expand usage
|
||||
# XXX: notes about the default actions, behavior, etc
|
||||
parser = cli.setupParser(
|
||||
"%(prog)s [options]",
|
||||
_("Edit libvirt XML using command line options."),
|
||||
introspection_epilog=True)
|
||||
|
||||
cli.add_connect_option(parser)
|
||||
|
||||
actg = parser.add_argument_group(_("Action Options"))
|
||||
actg.add_argument("--domain", help=_("Domain name, id, or uuid"))
|
||||
actg.add_argument("--edit", nargs='?', default=-1,
|
||||
help=_("Edit VM XML"))
|
||||
|
||||
g = parser.add_argument_group(_("XML options"))
|
||||
cli.add_disk_option(g)
|
||||
cli.add_net_option(g)
|
||||
cli.add_gfx_option(g)
|
||||
cli.vcpu_cli_options(g)
|
||||
cli.add_guest_xml_options(g)
|
||||
cli.add_boot_option(g)
|
||||
cli.add_fs_option(g)
|
||||
cli.add_device_options(g)
|
||||
|
||||
misc = parser.add_argument_group(_("Miscellaneous Options"))
|
||||
cli.add_misc_options(misc, prompt=False, printxml=False, dryrun=False)
|
||||
misc.add_argument("--print-diff", action="store_true",
|
||||
help=_("Only print the requested change, in diff format"))
|
||||
misc.add_argument("--print-xml", action="store_true",
|
||||
help=_("Only print the requested change, in full XML format"))
|
||||
misc.add_argument("--confirm", action="store_true",
|
||||
help=_("Require confirmation before saving any results."))
|
||||
misc.add_argument("--define", action="store_true",
|
||||
help=_("Force defining the domain, only required if a --print "
|
||||
"option was specified."))
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
###################
|
||||
# main() handling #
|
||||
###################
|
||||
|
||||
def main(conn=None):
|
||||
cli.earlyLogging()
|
||||
options = parse_args()
|
||||
|
||||
if options.confirm or options.print_xml or options.print_diff:
|
||||
options.quiet = False
|
||||
if not options.print_xml and not options.print_diff:
|
||||
options.define = True
|
||||
if options.confirm and not options.print_xml:
|
||||
options.print_diff = True
|
||||
|
||||
cli.setupLogging("virt-xml", options.debug, options.quiet)
|
||||
|
||||
parsermap = cli.build_parser_map(options)
|
||||
if cli.check_option_introspection(options, parsermap):
|
||||
return 0
|
||||
|
||||
if conn is None:
|
||||
conn = cli.getConnection(options.connect)
|
||||
|
||||
domain, origxml, guest = get_domain_and_guest(conn, options.domain)
|
||||
# XXX: do we ever need the domain?
|
||||
ignore = domain
|
||||
|
||||
change_xml(guest, options, parsermap)
|
||||
|
||||
newxml = guest.get_xml_config()
|
||||
diff = get_diff(origxml, newxml)
|
||||
|
||||
if options.print_diff:
|
||||
if diff:
|
||||
print_stdout(diff)
|
||||
elif options.print_xml:
|
||||
print_stdout(newxml)
|
||||
|
||||
if not options.define:
|
||||
return 0
|
||||
|
||||
if options.confirm:
|
||||
# XXX: Message needs to depend on what action we will take
|
||||
if not prompt_yes_or_no(
|
||||
_("Define '%s' with the changed XML?" % guest.name)):
|
||||
return 0
|
||||
|
||||
conn.defineXML(guest.get_xml_config())
|
||||
print_stdout(_("Domain '%s' defined successfully." % guest.name))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
sys.exit(main())
|
||||
except SystemExit, sys_e:
|
||||
sys.exit(sys_e.code)
|
||||
except KeyboardInterrupt:
|
||||
logging.debug("", exc_info=True)
|
||||
print_stderr(_("Aborted at user request"))
|
||||
except Exception, main_e:
|
||||
fail(main_e)
|
118
virtinst/cli.py
118
virtinst/cli.py
@ -974,39 +974,39 @@ class _VirtCLIArgument(object):
|
||||
self.ignore_default = ignore_default
|
||||
|
||||
|
||||
def parse(self, opts, inst, support_cb=None):
|
||||
def parse(self, opts, inst, support_cb=None, lookup=False):
|
||||
val = opts.get_opt_param(self.cliname)
|
||||
if val is None:
|
||||
return
|
||||
if val == "":
|
||||
val = None
|
||||
|
||||
if support_cb:
|
||||
support_cb(inst, self.attrname, self.cliname)
|
||||
if self.is_onoff:
|
||||
val = _on_off_convert(self.cliname, val)
|
||||
if val == "default" and self.ignore_default:
|
||||
if val == "default" and self.ignore_default and not lookup:
|
||||
return
|
||||
|
||||
attr = None
|
||||
if lookup and not self.attrname:
|
||||
raise RuntimeError(_("Don't know how to match %s property %s") %
|
||||
(getattr(inst, "virtual_device_type", ""), self.cliname))
|
||||
|
||||
try:
|
||||
if self.setter_cb:
|
||||
attr = None
|
||||
elif callable(self.attrname):
|
||||
attr = self.attrname
|
||||
else:
|
||||
attr = eval("inst." + self.attrname)
|
||||
if self.attrname:
|
||||
eval("inst." + self.attrname)
|
||||
except AttributeError:
|
||||
raise RuntimeError("programming error: obj=%s does not have "
|
||||
"member=%s" % (inst, self.attrname))
|
||||
|
||||
if self.setter_cb:
|
||||
if lookup:
|
||||
return eval("inst." + self.attrname) == val
|
||||
elif self.setter_cb:
|
||||
self.setter_cb(opts, inst, self.cliname, val)
|
||||
elif callable(attr):
|
||||
attr(val)
|
||||
else:
|
||||
exec("inst." + self.attrname + " = val") # pylint: disable=W0122
|
||||
|
||||
|
||||
|
||||
class VirtOptionString(object):
|
||||
def __init__(self, optstr, virtargs, remove_first=None):
|
||||
"""
|
||||
@ -1116,7 +1116,11 @@ class VirtCLIParser(object):
|
||||
A command line argument just extends this interface, implements
|
||||
_init_params, and calls set_param in the order it wants the options
|
||||
parsed on the command line. See existing impls examples of how to
|
||||
do all sorts of crazy stuff
|
||||
do all sorts of crazy stuff.
|
||||
|
||||
set_param must be set unconditionally (ex from _init_params and not
|
||||
from overriding _parse), so that we can show all options when the
|
||||
user requests command line introspection like --disk=?
|
||||
"""
|
||||
devclass = None
|
||||
|
||||
@ -1206,6 +1210,28 @@ class VirtCLIParser(object):
|
||||
return ret[0]
|
||||
return ret
|
||||
|
||||
def lookup_device_from_option_string(self, guest, optstr):
|
||||
"""
|
||||
Given a passed option string, search the guests' device list
|
||||
for all devices which match the passed options.
|
||||
"""
|
||||
devlist = guest.get_devices(self.devclass.virtual_device_type)[:]
|
||||
ret = []
|
||||
|
||||
for inst in devlist:
|
||||
opts = VirtOptionString(optstr, self._params,
|
||||
remove_first=self.remove_first)
|
||||
valid = True
|
||||
for param in self._params:
|
||||
if param.parse(opts, inst,
|
||||
support_cb=None, lookup=True) is False:
|
||||
valid = False
|
||||
break
|
||||
if valid:
|
||||
ret.append(inst)
|
||||
|
||||
return ret
|
||||
|
||||
def _parse_single_optstr(self, guest, optstr, inst):
|
||||
if not optstr:
|
||||
return None
|
||||
@ -1249,9 +1275,9 @@ class ParserNumatune(VirtCLIParser):
|
||||
self.set_param("numatune.memory_mode", "mode")
|
||||
|
||||
|
||||
##################
|
||||
# --vcpu parsing #
|
||||
##################
|
||||
###################
|
||||
# --vcpus parsing #
|
||||
###################
|
||||
|
||||
class ParserVCPU(VirtCLIParser):
|
||||
def _init_params(self):
|
||||
@ -1317,7 +1343,17 @@ class ParserCPU(VirtCLIParser):
|
||||
ignore = opts
|
||||
policy = cliname
|
||||
for feature_name in util.listify(val):
|
||||
inst.cpu.add_feature(feature_name, policy)
|
||||
featureobj = None
|
||||
|
||||
for f in inst.cpu.features:
|
||||
if f.name == feature_name:
|
||||
featureobj = f
|
||||
break
|
||||
|
||||
if featureobj:
|
||||
featureobj.policy = policy
|
||||
else:
|
||||
inst.cpu.add_feature(feature_name, policy)
|
||||
|
||||
self.set_param(None, "model", setter_cb=set_model_cb)
|
||||
self.set_param("cpu.match", "match")
|
||||
@ -1627,7 +1663,7 @@ class ParserNetwork(VirtCLIParser):
|
||||
self.set_param("source_mode", "source_mode")
|
||||
self.set_param("target_dev", "target")
|
||||
self.set_param("model", "model")
|
||||
self.set_param(None, "mac", setter_cb=set_mac_cb)
|
||||
self.set_param("macaddr", "mac", setter_cb=set_mac_cb)
|
||||
self.set_param("filterref", "filterref")
|
||||
|
||||
def _parse(self, optsobj, inst):
|
||||
@ -1701,7 +1737,11 @@ class ParserController(VirtCLIParser):
|
||||
self.set_param("model", "model")
|
||||
self.set_param("index", "index")
|
||||
self.set_param("master_startport", "master")
|
||||
self.set_param("address.set_addrstr", "address")
|
||||
|
||||
def set_server_cb(opts, inst, cliname, val):
|
||||
ignore = opts = cliname
|
||||
inst.address.set_addrstr(val)
|
||||
self.set_param(None, "address", setter_cb=set_server_cb)
|
||||
|
||||
def _parse(self, opts, inst):
|
||||
if opts.fullopts == "usb2":
|
||||
@ -1739,7 +1779,12 @@ class ParserRedir(VirtCLIParser):
|
||||
|
||||
self.set_param("bus", "bus")
|
||||
self.set_param("type", "type")
|
||||
self.set_param("parse_friendly_server", "server")
|
||||
|
||||
def set_server_cb(opts, inst, cliname, val):
|
||||
ignore = opts = cliname
|
||||
inst.parse_friendly_server(val)
|
||||
|
||||
self.set_param(None, "server", setter_cb=set_server_cb)
|
||||
|
||||
|
||||
#################
|
||||
@ -1893,15 +1938,28 @@ class _ParserChar(VirtCLIParser):
|
||||
"optname" : cliname})
|
||||
self.support_cb = support_check
|
||||
|
||||
|
||||
self.set_param("type", "char_type")
|
||||
self.set_param("source_path", "path")
|
||||
self.set_param("source_mode", "mode")
|
||||
self.set_param("protocol", "protocol")
|
||||
self.set_param("target_type", "target_type")
|
||||
self.set_param("target_name", "name")
|
||||
self.set_param("set_friendly_source", "host")
|
||||
self.set_param("set_friendly_bind", "bind_host")
|
||||
self.set_param("set_friendly_target", "target_address")
|
||||
|
||||
def set_host_cb(opts, inst, cliname, val):
|
||||
ignore = opts = cliname
|
||||
inst.set_friendly_source(val)
|
||||
self.set_param(None, "host", setter_cb=set_host_cb)
|
||||
|
||||
def set_bind_cb(opts, inst, cliname, val):
|
||||
ignore = opts = cliname
|
||||
inst.set_friendly_bind(val)
|
||||
self.set_param(None, "bind_host", setter_cb=set_bind_cb)
|
||||
|
||||
def set_target_cb(opts, inst, cliname, val):
|
||||
ignore = opts = cliname
|
||||
inst.set_friendly_target(val)
|
||||
self.set_param(None, "target_address", setter_cb=set_target_cb)
|
||||
|
||||
def _parse(self, opts, inst):
|
||||
if opts.fullopts == "none" and inst.virtual_device_type == "console":
|
||||
@ -2042,17 +2100,23 @@ def build_parser_map(options, skip=None, only=None):
|
||||
return parsermap
|
||||
|
||||
|
||||
def parse_option_strings(parsermap, options, guest, inst):
|
||||
def parse_option_strings(parsermap, options, guest, instlist):
|
||||
"""
|
||||
Iterate over the parsermap, and launch the associated parser
|
||||
function for every value that was filled in on 'options', which
|
||||
came from argparse/the command line.
|
||||
"""
|
||||
instlist = util.listify(instlist)
|
||||
if not instlist:
|
||||
instlist = [None]
|
||||
|
||||
for option_variable_name in dir(options):
|
||||
if option_variable_name not in parsermap:
|
||||
continue
|
||||
parsermap[option_variable_name].parse(
|
||||
guest, getattr(options, option_variable_name), inst)
|
||||
|
||||
for inst in util.listify(instlist):
|
||||
parsermap[option_variable_name].parse(
|
||||
guest, getattr(options, option_variable_name), inst)
|
||||
|
||||
|
||||
def check_option_introspection(options, parsermap):
|
||||
|
Loading…
Reference in New Issue
Block a user