virt-xml: Add --add-device and --remove-device options
This commit is contained in:
parent
26737eb7d5
commit
e49e61f71e
|
@ -0,0 +1,14 @@
|
|||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -302,5 +302,9 @@
|
||||
<protocol type="raw"/>
|
||||
</backend>
|
||||
</rng>
|
||||
+ <disk type="file" device="disk">
|
||||
+ <source file="/tmp/__virtinst_cli_exist1.img"/>
|
||||
+ <target dev="vdf" bus="virtio"/>
|
||||
+ </disk>
|
||||
</devices>
|
||||
</domain>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
|
@ -0,0 +1,15 @@
|
|||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -302,5 +302,10 @@
|
||||
<protocol type="raw"/>
|
||||
</backend>
|
||||
</rng>
|
||||
+ <hostdev mode="subsystem" type="pci" managed="yes">
|
||||
+ <source>
|
||||
+ <address domain="0" bus="0" slot="25" function="0"/>
|
||||
+ </source>
|
||||
+ </hostdev>
|
||||
</devices>
|
||||
</domain>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
|
@ -0,0 +1,11 @@
|
|||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -302,5 +302,6 @@
|
||||
<protocol type="raw"/>
|
||||
</backend>
|
||||
</rng>
|
||||
+ <sound model="pcspk"/>
|
||||
</devices>
|
||||
</domain>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
|
@ -0,0 +1,17 @@
|
|||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -83,12 +83,6 @@
|
||||
<target dev="sdb" bus="scsi"/>
|
||||
<readonly/>
|
||||
<address type="drive" controller="0" bus="0" target="0" unit="1"/>
|
||||
- </disk>
|
||||
- <disk type="file" device="disk">
|
||||
- <driver name="qemu" type="qcow2" cache="none"/>
|
||||
- <source file="/tmp/foobar2"/>
|
||||
- <target dev="vdc" bus="virtio"/>
|
||||
- <shareable/>
|
||||
</disk>
|
||||
<disk type="block" device="disk">
|
||||
<source dev="/dev/default-pool/overlay.img"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
|
@ -0,0 +1,29 @@
|
|||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -54,11 +54,6 @@
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||
- <disk type="block" device="floppy">
|
||||
- <source dev="/dev/null"/>
|
||||
- <target dev="fda" bus="fdc"/>
|
||||
- <address type="drive" controller="0" bus="0" target="0" unit="0"/>
|
||||
- </disk>
|
||||
<disk type="dir" device="floppy">
|
||||
<source dir="/tmp"/>
|
||||
<target dev="fdb" bus="fdc"/>
|
||||
@@ -72,12 +67,6 @@
|
||||
<total_iops_sec>50</total_iops_sec>
|
||||
</iotune>
|
||||
<address type="drive" controller="0" bus="0" target="0" unit="0"/>
|
||||
- </disk>
|
||||
- <disk type="block" device="disk">
|
||||
- <driver type="raw" cache="none"/>
|
||||
- <source dev="/dev/null"/>
|
||||
- <target dev="hdc" bus="ide"/>
|
||||
- <address type="drive" controller="0" bus="1" target="0" unit="0"/>
|
||||
</disk>
|
||||
<disk type="block" device="cdrom">
|
||||
<target dev="sdb" bus="scsi"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
|
@ -0,0 +1,12 @@
|
|||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -254,7 +254,6 @@
|
||||
</graphics>
|
||||
<sound model="sb16"/>
|
||||
<sound model="es1370"/>
|
||||
- <sound model="ich6"/>
|
||||
<video>
|
||||
<model type="vmvga" vram="9216" heads="1"/>
|
||||
</video>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
|
@ -0,0 +1,17 @@
|
|||
--- Original XML
|
||||
+++ Altered XML
|
||||
@@ -255,12 +255,6 @@
|
||||
<sound model="sb16"/>
|
||||
<sound model="es1370"/>
|
||||
<sound model="ich6"/>
|
||||
- <video>
|
||||
- <model type="vmvga" vram="9216" heads="1"/>
|
||||
- </video>
|
||||
- <video>
|
||||
- <model type="cirrus" vram="10240" heads="3"/>
|
||||
- </video>
|
||||
<hostdev mode="subsystem" type="usb" managed="yes">
|
||||
<source>
|
||||
<vendor id="0x04b3"/>
|
||||
|
||||
Domain 'test-many-devices' defined successfully.
|
|
@ -805,6 +805,16 @@ c.add_compare("--edit --cpu host-passthrough,clearxml", "virtxml-edit-clear-cpu"
|
|||
c.add_compare("--edit --clock offset=utc,clearxml", "virtxml-edit-clear-clock")
|
||||
c.add_compare("--edit --disk /foo/bar,target=fda,bus=fdc,device=floppy,clearxml", "virtxml-edit-clear-disk")
|
||||
|
||||
c = vixml.add_category("add/rm devices", "--domain test-many-devices --print-diff --define")
|
||||
c.add_invalid("--add-device --security foo") # --add-device without a device
|
||||
c.add_invalid("--remove-device --clock utc") # --remove-device without a dev
|
||||
c.add_compare("--add-device --host-device net_00_1c_25_10_b1_e4", "virtxml-add-host-device")
|
||||
c.add_compare("--add-device --soundhw pcspk", "virtxml-add-sound")
|
||||
c.add_compare("--add-device --disk %(EXISTIMG1)s,bus=virtio,target=vdf", "virtxml-add-disk-basic")
|
||||
c.add_compare("--remove-device --soundhw ich6", "virtxml-remove-sound-model")
|
||||
c.add_compare("--remove-device --disk 6", "virtxml-remove-disk-index")
|
||||
c.add_compare("--remove-device --disk /dev/null", "virtxml-remove-disk-path")
|
||||
c.add_compare("--remove-device --video all", "virtxml-remove-video-all")
|
||||
|
||||
|
||||
vimag = App("virt-image")
|
||||
|
|
93
virt-xml
93
virt-xml
|
@ -27,6 +27,7 @@ import libvirt
|
|||
|
||||
import virtinst
|
||||
from virtinst import cli
|
||||
from virtinst import util
|
||||
from virtinst.cli import fail, print_stdout, print_stderr
|
||||
|
||||
|
||||
|
@ -106,19 +107,19 @@ def get_domain_and_guest(conn, domstr):
|
|||
# Change logic #
|
||||
################
|
||||
|
||||
def _find_devices_to_edit(guest, options, parserobj):
|
||||
def _find_devices_to_edit(guest, action_name, editval, parserobj):
|
||||
devlist = guest.get_devices(parserobj.devclass.virtual_device_type)
|
||||
idx = None
|
||||
|
||||
if options.edit is None:
|
||||
if editval is None:
|
||||
idx = 1
|
||||
elif (options.edit.isdigit() or
|
||||
options.edit.startswith("-") and options.edit[1:].isdigit()):
|
||||
idx = int(options.edit)
|
||||
elif (editval.isdigit() or
|
||||
editval.startswith("-") and editval[1:].isdigit()):
|
||||
idx = int(editval)
|
||||
|
||||
if idx is not None:
|
||||
if idx == 0:
|
||||
fail(_("Invalid --edit option '%s'") % options.edit)
|
||||
fail(_("Invalid --edit option '%s'") % editval)
|
||||
|
||||
if not devlist:
|
||||
fail(_("No --%s devices found in the XML") %
|
||||
|
@ -131,23 +132,35 @@ def _find_devices_to_edit(guest, options, parserobj):
|
|||
if idx > 0:
|
||||
idx -= 1
|
||||
inst = devlist[idx]
|
||||
elif options.edit == "all":
|
||||
elif editval == "all":
|
||||
inst = devlist[:]
|
||||
else:
|
||||
inst = parserobj.lookup_device_from_option_string(guest, options.edit)
|
||||
inst = parserobj.lookup_device_from_option_string(guest, editval)
|
||||
if not inst:
|
||||
fail(_("No matching devices found for --edit %s") % options.edit)
|
||||
fail(_("No matching devices found for --%s %s") %
|
||||
(action_name, editval))
|
||||
|
||||
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")
|
||||
def check_action_collision(options):
|
||||
actions = ["edit", "add-device", "remove-device"]
|
||||
|
||||
collisions = []
|
||||
for cliname in actions:
|
||||
optname = cliname.replace("-", "_")
|
||||
if getattr(options, optname) not in [False, -1]:
|
||||
collisions.append(cliname)
|
||||
|
||||
if len(collisions) == 0:
|
||||
fail(_("One of %s must be specified.") %
|
||||
", ".join(["--" + c for c in actions]))
|
||||
if len(collisions) > 1:
|
||||
fail(_("Conflicting options %s") %
|
||||
", ".join(["--" + c for c in collisions]))
|
||||
|
||||
|
||||
def check_xmlopt_collision(options, parsermap):
|
||||
collisions = []
|
||||
for option_variable_name, parserobj in parsermap.items():
|
||||
if getattr(options, option_variable_name):
|
||||
|
@ -159,10 +172,13 @@ def change_xml(guest, options, parsermap):
|
|||
fail(_("Only one change operation may be specified "
|
||||
"(conflicting options %s)") %
|
||||
["--" + c.cli_arg_name for c in collisions])
|
||||
parserobj = collisions[0]
|
||||
|
||||
return collisions[0]
|
||||
|
||||
|
||||
def action_edit(guest, options, parsermap, parserobj):
|
||||
if parserobj.devclass:
|
||||
inst = _find_devices_to_edit(guest, options, parserobj)
|
||||
inst = _find_devices_to_edit(guest, "edit", options.edit, parserobj)
|
||||
else:
|
||||
inst = guest
|
||||
if options.edit and options.edit != '1' and options.edit != 'all':
|
||||
|
@ -173,6 +189,25 @@ def change_xml(guest, options, parsermap):
|
|||
cli.parse_option_strings(parsermap, options, guest, inst, update=True)
|
||||
|
||||
|
||||
def action_add_device(guest, options, parsermap, parserobj):
|
||||
if not parserobj.devclass:
|
||||
fail(_("Cannot use --add-device with --%s") % parserobj.cli_arg_name)
|
||||
cli.parse_option_strings(parsermap, options, guest, None)
|
||||
|
||||
|
||||
def action_remove_device(guest, options, parsermap, parserobj):
|
||||
ignore = parsermap
|
||||
if not parserobj.devclass:
|
||||
fail(_("Cannot use --remove-device with --%s") %
|
||||
parserobj.cli_arg_name)
|
||||
|
||||
devs = _find_devices_to_edit(guest, "remove-device",
|
||||
getattr(options, parserobj.option_variable_name)[-1], parserobj)
|
||||
|
||||
for dev in util.listify(devs):
|
||||
guest.remove_device(dev)
|
||||
|
||||
|
||||
#######################
|
||||
# CLI option handling #
|
||||
#######################
|
||||
|
@ -191,7 +226,19 @@ def parse_args():
|
|||
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"))
|
||||
help=_("Edit VM XML. Examples:\n"
|
||||
"--edit --disk ... (edit first disk device)\n"
|
||||
"--edit 2 --disk ... (edit second disk device)\n"
|
||||
"--edit all --disk ... (edit all disk devices)\n"
|
||||
"--edit target=hda --disk ... (edit disk 'hda')\n"))
|
||||
actg.add_argument("--remove-device", action="store_true",
|
||||
help=_("Remove specified device. Examples:\n"
|
||||
"--remove-device --disk 1 (remove first disk)\n"
|
||||
"--remove-device --disk all (remove all disks)\n"
|
||||
"--remove-device --disk /some/path"))
|
||||
actg.add_argument("--add-device", action="store_true",
|
||||
help=_("Add specified device. Example:\n"
|
||||
"--add-device --disk ..."))
|
||||
|
||||
g = parser.add_argument_group(_("XML options"))
|
||||
cli.add_disk_option(g)
|
||||
|
@ -248,7 +295,15 @@ def main(conn=None):
|
|||
# XXX: do we ever need the domain?
|
||||
ignore = domain
|
||||
|
||||
change_xml(guest, options, parsermap)
|
||||
check_action_collision(options)
|
||||
parserobj = check_xmlopt_collision(options, parsermap)
|
||||
|
||||
if options.edit != -1:
|
||||
action_edit(guest, options, parsermap, parserobj)
|
||||
elif options.add_device:
|
||||
action_add_device(guest, options, parsermap, parserobj)
|
||||
elif options.remove_device:
|
||||
action_remove_device(guest, options, parsermap, parserobj)
|
||||
|
||||
newxml = guest.get_xml_config()
|
||||
diff = get_diff(origxml, newxml)
|
||||
|
|
Loading…
Reference in New Issue