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 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("--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,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_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=969-1000") # Bogus cpuset
c.add_invalid("--vcpus 32 --cpuset=autofoo") # 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("--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("--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 c.add_invalid("--clock foo_tickpolicy=merge") # Unknown timer
@ -951,7 +951,7 @@ _cmdlist += vconv.cmds
for _cmd in _cmdlist: for _cmd in _cmdlist:
newidx += 1 newidx += 1
setattr(CLITests, "testCLI%s%d" % (_cmd.app.replace("-", ""), newidx), setattr(CLITests, "testCLI%s%.4d" % (_cmd.app.replace("-", ""), newidx),
maketest(_cmd)) maketest(_cmd))
atexit.register(cleanup) 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 # We skip validation here, since we may have converted
# --file-size to --disk size=8 which doesn't validate on # --file-size to --disk size=8 which doesn't validate on
# its own. # 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 path = dev.path
sparse = dev.get_sparse() 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): class Clock(XMLBuilder):
_XML_ROOT_NAME = "clock" _XML_ROOT_NAME = "clock"
TIMER_NAMES = ["platform", "pit", "rtc", "hpet", "tsc", "kvmclock"]
offset = XMLProperty("./@offset") offset = XMLProperty("./@offset")
timers = XMLChildProperty(_ClockTimer) timers = XMLChildProperty(_ClockTimer)

View File

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

View File

@ -149,6 +149,24 @@ class _VirtualCharDevice(VirtualDevice):
return self.type in users[propname] return self.type in users[propname]
return hasattr(self, 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", _XML_PROP_ORDER = ["type", "_has_mode_bind", "_has_mode_connect",
"bind_host", "bind_port", "bind_host", "bind_port",

View File

@ -33,7 +33,7 @@ class OSXML(XMLBuilder):
BOOT_DEVICE_CDROM = "cdrom" BOOT_DEVICE_CDROM = "cdrom"
BOOT_DEVICE_FLOPPY = "fd" BOOT_DEVICE_FLOPPY = "fd"
BOOT_DEVICE_NETWORK = "network" 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] BOOT_DEVICE_FLOPPY, BOOT_DEVICE_NETWORK]
def is_hvm(self): def is_hvm(self):