cli: Rework adhoc CLI parsing into a class structure

This adds:

VirtCLIArgument: a single foo=bar mapping
VirtOptionString: A collection of VirtCLIArguments, that parses the whole thing
VirtCLIParser: Represents a single cli option like --disk, --network, etc.

Centralizing this infrastructure opens up a lot of doors for future
improvements, like cli option introspection.
This commit is contained in:
Cole Robinson 2014-01-19 13:56:06 -05:00
parent a98515a4da
commit 41a84bae9f
7 changed files with 754 additions and 635 deletions

View File

@ -425,12 +425,12 @@ c.add_valid("--vcpus sockets=2,threads=2") # Topology only
c.add_valid("--cpu somemodel") # Simple --cpu
c.add_valid("--cpu foobar,+x2apic,+x2apicagain,-distest,forbid=foo,forbid=bar,disable=distest2,optional=opttest,require=reqtest,match=strict,vendor=meee") # Crazy --cpu
c.add_valid("--numatune 1,2,3,5-7,^6") # Simple --numatune
c.add_valid("--numatune 1-3,4,mode=strict") # More complex, parser should do the right thing here
c.add_compare("--connect %(DEFAULTURI)s --cpuset auto --vcpus 2", "cpuset-auto") # --cpuset=auto actually works
c.add_invalid("--vcpus 32 --cpuset=969-1000") # Bogus cpuset
c.add_invalid("--vcpus 32 --cpuset=autofoo") # Bogus cpuset
c.add_invalid("--vcpus 20 --check-cpu") # Over host vcpus w/ --check-cpu
c.add_invalid("--cpu host") # --cpu host, but no host CPU in caps
c.add_invalid("--numatune 1-3,4,mode=strict") # Non-escaped numatune
c.add_invalid("--clock foo_tickpolicy=merge") # Unknown timer
@ -951,7 +951,7 @@ _cmdlist += vconv.cmds
for _cmd in _cmdlist:
newidx += 1
setattr(CLITests, "testCLI%s%d" % (_cmd.app.replace("-", ""), newidx),
setattr(CLITests, "testCLI%s%.4d" % (_cmd.app.replace("-", ""), newidx),
maketest(_cmd))
atexit.register(cleanup)

View File

@ -139,7 +139,9 @@ def get_disks(guest, disks, nodisks, need_storage):
# We skip validation here, since we may have converted
# --file-size to --disk size=8 which doesn't validate on
# its own.
dev, size = cli.parse_disk(guest, diskopts, validate=False)
dev = cli.parse_disk(guest, diskopts,
virtinst.VirtualDisk(guest.conn))
size = dev.cli_size
path = dev.path
sparse = dev.get_sparse()

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,8 @@ class _ClockTimer(XMLBuilder):
class Clock(XMLBuilder):
_XML_ROOT_NAME = "clock"
TIMER_NAMES = ["platform", "pit", "rtc", "hpet", "tsc", "kvmclock"]
offset = XMLProperty("./@offset")
timers = XMLChildProperty(_ClockTimer)

View File

@ -30,7 +30,7 @@ from virtinst import StorageVolume
from virtinst import pollhelpers
from virtinst import support
from virtinst import util
from virtinst.cli import parse_optstr
from virtinst.cli import VirtOptionString
_virtinst_uri_magic = "__virtinst_test__"
@ -79,7 +79,8 @@ class VirtualConnection(object):
uri = _initial_uri.replace(_virtinst_uri_magic, "")
ret = uri.split(",", 1)
self._open_uri = ret[0]
self._test_opts = parse_optstr(len(ret) > 1 and ret[1] or "")
self._test_opts = VirtOptionString(
len(ret) > 1 and ret[1] or "", []).opts
self._early_virtinst_test_uri()
self._uri = self._virtinst_uri_make_fake()
else:

View File

@ -149,6 +149,24 @@ class _VirtualCharDevice(VirtualDevice):
return self.type in users[propname]
return hasattr(self, propname)
def _set_host_helper(self, hostparam, portparam, val):
def parse_host(val):
host, ignore, port = (val or "").partition(":")
return host or None, port or None
host, port = parse_host(val)
if host:
setattr(self, hostparam, host)
if port:
setattr(self, portparam, port)
def set_friendly_source(self, val):
self._set_host_helper("source_host", "source_port", val)
def set_friendly_bind(self, val):
self._set_host_helper("bind_host", "bind_port", val)
def set_friendly_target(self, val):
self._set_host_helper("target_address", "target_port", val)
_XML_PROP_ORDER = ["type", "_has_mode_bind", "_has_mode_connect",
"bind_host", "bind_port",

View File

@ -33,7 +33,7 @@ class OSXML(XMLBuilder):
BOOT_DEVICE_CDROM = "cdrom"
BOOT_DEVICE_FLOPPY = "fd"
BOOT_DEVICE_NETWORK = "network"
boot_devices = [BOOT_DEVICE_HARDDISK, BOOT_DEVICE_CDROM,
BOOT_DEVICES = [BOOT_DEVICE_HARDDISK, BOOT_DEVICE_CDROM,
BOOT_DEVICE_FLOPPY, BOOT_DEVICE_NETWORK]
def is_hvm(self):