mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-01-11 05:17:59 +03:00
cli: Centralize most option handling dispatch
Rather than require tools to do multiple parse_* calls. This infrastructure will help with virt-xml as well.
This commit is contained in:
parent
269339f29f
commit
54b73f4502
17
virt-image
17
virt-image
@ -75,6 +75,7 @@ def main(conn=None):
|
||||
|
||||
options.quiet = options.xmlonly or options.quiet
|
||||
cli.setupLogging("virt-image", options.debug, options.quiet)
|
||||
cli.set_prompt(False)
|
||||
|
||||
if conn is None:
|
||||
conn = cli.getConnection(options.connect)
|
||||
@ -100,21 +101,23 @@ def main(conn=None):
|
||||
cli.convert_old_graphics(guest, options,
|
||||
default_override=bool(image.domain.graphics))
|
||||
cli.convert_old_features(options)
|
||||
if not options.vcpus:
|
||||
options.vcpus = image.domain.vcpu or ""
|
||||
|
||||
guest.replace = options.replace
|
||||
|
||||
cli.get_name(guest, options.name or image.name)
|
||||
cli.get_memory(guest, options.memory or (image.domain.memory and
|
||||
int(image.domain.memory)))
|
||||
|
||||
if options.uuid:
|
||||
guest.uuid = options.uuid
|
||||
cli.parse_vcpus(guest, options.vcpus or image.domain.vcpu or "")
|
||||
cli.get_cpuset(guest, options.cpuset)
|
||||
cli.parse_cpu(guest, options.cpu)
|
||||
cli.parse_network(guest, options.network)
|
||||
cli.parse_graphics(guest, options.graphics)
|
||||
cli.set_os_variant(guest, options.distro_type, options.distro_variant)
|
||||
cli.parse_features(guest, getattr(options, "features", None))
|
||||
|
||||
parsermap = cli.build_parser_map(options,
|
||||
only=["vcpus", "cpu", "network", "graphics", "features"])
|
||||
cli.parse_option_strings(parsermap, options, guest, None)
|
||||
|
||||
cli.get_cpuset(guest, options.cpuset)
|
||||
|
||||
if not guest.get_devices("input"):
|
||||
guest.add_default_input_device()
|
||||
|
29
virt-install
29
virt-install
@ -506,35 +506,10 @@ def build_guest_instance(conn, options):
|
||||
guest.os.init = options.init
|
||||
if options.uuid:
|
||||
guest.uuid = options.uuid
|
||||
cli.parse_vcpus(guest, options.vcpus)
|
||||
cli.parse_numatune(guest, options.numatune)
|
||||
cli.parse_cpu(guest, options.cpu)
|
||||
cli.parse_security(guest, options.security)
|
||||
cli.parse_boot(guest, options.boot)
|
||||
cli.parse_features(guest, options.features)
|
||||
cli.parse_clock(guest, options.clock)
|
||||
|
||||
guest.description = options.description
|
||||
|
||||
# Non-default devices
|
||||
cli.parse_controller(guest, options.controller)
|
||||
cli.parse_redirdev(guest, options.redirdev)
|
||||
cli.parse_memballoon(guest, options.memballoon)
|
||||
cli.parse_network(guest, options.network)
|
||||
cli.parse_graphics(guest, options.graphics)
|
||||
cli.parse_video(guest, options.video)
|
||||
cli.parse_watchdog(guest, options.watchdog)
|
||||
cli.parse_filesystem(guest, options.filesystem)
|
||||
cli.parse_sound(guest, options.soundhw)
|
||||
cli.parse_serial(guest, options.serial)
|
||||
cli.parse_parallel(guest, options.parallel)
|
||||
cli.parse_channel(guest, options.channel)
|
||||
cli.parse_console(guest, options.console)
|
||||
cli.parse_hostdev(guest, options.host_device)
|
||||
cli.parse_smartcard(guest, options.smartcard)
|
||||
cli.parse_tpm(guest, options.tpm)
|
||||
cli.parse_rng(guest, options.rng)
|
||||
cli.parse_panic(guest, options.panic)
|
||||
parsermap = cli.build_parser_map(options, skip=["disk"])
|
||||
cli.parse_option_strings(parsermap, options, guest, None)
|
||||
|
||||
guest.add_default_input_device()
|
||||
guest.add_default_console_device()
|
||||
|
144
virtinst/cli.py
144
virtinst/cli.py
@ -1096,10 +1096,12 @@ class VirtCLIParser(object):
|
||||
"""
|
||||
devclass = None
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, cli_arg_name):
|
||||
"""
|
||||
These values should be set by subclasses in _init_params
|
||||
|
||||
@cli_arg_name: The command line argument this maps to, so
|
||||
"host-device" for --host-device
|
||||
@guest: Will be set parse(), the toplevel virtinst.Guest object
|
||||
@remove_first: Passed to VirtOptionString
|
||||
@check_none: If the parsed option string is just 'none', return None
|
||||
@ -1107,6 +1109,11 @@ class VirtCLIParser(object):
|
||||
Called before the virtinst object is altered. Take arguments
|
||||
(inst, attrname, cliname)
|
||||
"""
|
||||
self.cli_arg_name = cli_arg_name
|
||||
# This is the name of the variable that argparse will set in
|
||||
# the result of parse_args()
|
||||
self.option_variable_name = cli_arg_name.replace("-", "_")
|
||||
|
||||
self.guest = None
|
||||
self.remove_first = None
|
||||
self.check_none = False
|
||||
@ -1125,13 +1132,12 @@ class VirtCLIParser(object):
|
||||
self._params.append(_VirtCLIArgument(*args, **kwargs))
|
||||
|
||||
def parse(self, guest, optlist, inst=None, validate=True):
|
||||
# XXX: review
|
||||
optlist = util.listify(optlist)
|
||||
editting = bool(inst)
|
||||
|
||||
if editting and optlist:
|
||||
# If an object is passed in, we are updating it in place, and
|
||||
# only use the last command line occurence
|
||||
# only use the last command line occurence, eg. from virt-xml
|
||||
optlist = [optlist[-1]]
|
||||
|
||||
ret = []
|
||||
@ -1156,8 +1162,9 @@ class VirtCLIParser(object):
|
||||
except Exception, e:
|
||||
logging.debug("Exception parsing inst=%s optstr=%s",
|
||||
inst, optstr, exc_info=True)
|
||||
fail(_("Error in %(options)s: %(err)s") %
|
||||
{"options": optstr, "err": str(e)})
|
||||
fail(_("Error: --%(cli_arg_name)s %(options)s: %(err)s") %
|
||||
{"cli_arg_name": self.cli_arg_name,
|
||||
"options": optstr, "err": str(e)})
|
||||
|
||||
if not ret:
|
||||
return None
|
||||
@ -1207,8 +1214,6 @@ class ParserNumatune(VirtCLIParser):
|
||||
self.set_param("numatune.memory_nodeset", "nodeset", can_comma=True)
|
||||
self.set_param("numatune.memory_mode", "mode")
|
||||
|
||||
parse_numatune = ParserNumatune().parse
|
||||
|
||||
|
||||
##################
|
||||
# --vcpu parsing #
|
||||
@ -1241,8 +1246,6 @@ class ParserVCPU(VirtCLIParser):
|
||||
inst.vcpus = inst.cpu.vcpus_from_topology()
|
||||
return ret
|
||||
|
||||
parse_vcpus = ParserVCPU().parse
|
||||
|
||||
|
||||
#################
|
||||
# --cpu parsing #
|
||||
@ -1299,9 +1302,6 @@ class ParserCPU(VirtCLIParser):
|
||||
return VirtCLIParser._parse(self, optsobj, inst)
|
||||
|
||||
|
||||
parse_cpu = ParserCPU().parse
|
||||
|
||||
|
||||
##################
|
||||
# --boot parsing #
|
||||
##################
|
||||
@ -1339,8 +1339,6 @@ class ParserBoot(VirtCLIParser):
|
||||
|
||||
VirtCLIParser._parse(self, opts, inst)
|
||||
|
||||
parse_boot = ParserBoot().parse
|
||||
|
||||
|
||||
######################
|
||||
# --security parsing #
|
||||
@ -1354,9 +1352,6 @@ class ParserSecurity(VirtCLIParser):
|
||||
is_onoff=True)
|
||||
|
||||
|
||||
parse_security = ParserSecurity().parse
|
||||
|
||||
|
||||
######################
|
||||
# --features parsing #
|
||||
######################
|
||||
@ -1383,8 +1378,6 @@ class ParserFeatures(VirtCLIParser):
|
||||
self.set_param("features.hyperv_spinlocks_retries",
|
||||
"hyperv_spinlocks_retries")
|
||||
|
||||
parse_features = ParserFeatures().parse
|
||||
|
||||
|
||||
###################
|
||||
# --clock parsing #
|
||||
@ -1417,9 +1410,6 @@ class ParserClock(VirtCLIParser):
|
||||
self.set_param(None, tname + "_tickpolicy", setter_cb=set_timer)
|
||||
|
||||
|
||||
parse_clock = ParserClock().parse
|
||||
|
||||
|
||||
##########################
|
||||
# Guest <device> parsing #
|
||||
##########################
|
||||
@ -1561,7 +1551,7 @@ class ParserDisk(VirtCLIParser):
|
||||
return inst
|
||||
|
||||
|
||||
parse_disk = ParserDisk().parse
|
||||
parse_disk = ParserDisk("disk").parse
|
||||
|
||||
|
||||
#####################
|
||||
@ -1602,9 +1592,6 @@ class ParserNetwork(VirtCLIParser):
|
||||
return VirtCLIParser._parse(self, optsobj, inst)
|
||||
|
||||
|
||||
parse_network = ParserNetwork().parse
|
||||
|
||||
|
||||
######################
|
||||
# --graphics parsing #
|
||||
######################
|
||||
@ -1649,9 +1636,6 @@ class ParserGraphics(VirtCLIParser):
|
||||
self.set_param("passwdValidTo", "passwordvalidto")
|
||||
|
||||
|
||||
parse_graphics = ParserGraphics().parse
|
||||
|
||||
|
||||
########################
|
||||
# --controller parsing #
|
||||
########################
|
||||
@ -1678,9 +1662,6 @@ class ParserController(VirtCLIParser):
|
||||
return VirtCLIParser._parse(self, opts, inst)
|
||||
|
||||
|
||||
parse_controller = ParserController().parse
|
||||
|
||||
|
||||
#######################
|
||||
# --smartcard parsing #
|
||||
#######################
|
||||
@ -1695,9 +1676,6 @@ class ParserSmartcard(VirtCLIParser):
|
||||
self.set_param("type", "type")
|
||||
|
||||
|
||||
parse_smartcard = ParserSmartcard().parse
|
||||
|
||||
|
||||
######################
|
||||
# --redirdev parsing #
|
||||
######################
|
||||
@ -1712,8 +1690,6 @@ class ParserRedir(VirtCLIParser):
|
||||
self.set_param("type", "type")
|
||||
self.set_param("parse_friendly_server", "server")
|
||||
|
||||
parse_redirdev = ParserRedir().parse
|
||||
|
||||
|
||||
#################
|
||||
# --tpm parsing #
|
||||
@ -1735,9 +1711,6 @@ class ParserTPM(VirtCLIParser):
|
||||
return VirtCLIParser._parse(self, opts, inst)
|
||||
|
||||
|
||||
parse_tpm = ParserTPM().parse
|
||||
|
||||
|
||||
#################
|
||||
# --rng parsing #
|
||||
#################
|
||||
@ -1807,9 +1780,6 @@ class ParserRNG(VirtCLIParser):
|
||||
return VirtCLIParser._parse(self, optsobj, inst)
|
||||
|
||||
|
||||
parse_rng = ParserRNG().parse
|
||||
|
||||
|
||||
######################
|
||||
# --watchdog parsing #
|
||||
######################
|
||||
@ -1823,9 +1793,6 @@ class ParserWatchdog(VirtCLIParser):
|
||||
self.set_param("action", "action")
|
||||
|
||||
|
||||
parse_watchdog = ParserWatchdog().parse
|
||||
|
||||
|
||||
########################
|
||||
# --memballoon parsing #
|
||||
########################
|
||||
@ -1838,9 +1805,6 @@ class ParserMemballoon(VirtCLIParser):
|
||||
self.set_param("model", "model")
|
||||
|
||||
|
||||
parse_memballoon = ParserMemballoon().parse
|
||||
|
||||
|
||||
###################
|
||||
# --panic parsing #
|
||||
###################
|
||||
@ -1859,9 +1823,6 @@ class ParserPanic(VirtCLIParser):
|
||||
self.set_param(None, "iobase", setter_cb=set_iobase_cb)
|
||||
|
||||
|
||||
parse_panic = ParserPanic().parse
|
||||
|
||||
|
||||
######################################################
|
||||
# --serial, --parallel, --channel, --console parsing #
|
||||
######################################################
|
||||
@ -1904,22 +1865,18 @@ class _ParserChar(VirtCLIParser):
|
||||
|
||||
class ParserSerial(_ParserChar):
|
||||
devclass = virtinst.VirtualSerialDevice
|
||||
parse_serial = ParserSerial().parse
|
||||
|
||||
|
||||
class ParserParallel(_ParserChar):
|
||||
devclass = virtinst.VirtualParallelDevice
|
||||
parse_parallel = ParserParallel().parse
|
||||
|
||||
|
||||
class ParserChannel(_ParserChar):
|
||||
devclass = virtinst.VirtualChannelDevice
|
||||
parse_channel = ParserChannel().parse
|
||||
|
||||
|
||||
class ParserConsole(_ParserChar):
|
||||
devclass = virtinst.VirtualConsoleDevice
|
||||
parse_console = ParserConsole().parse
|
||||
|
||||
|
||||
########################
|
||||
@ -1937,9 +1894,6 @@ class ParserFilesystem(VirtCLIParser):
|
||||
self.set_param("target", "target")
|
||||
|
||||
|
||||
parse_filesystem = ParserFilesystem().parse
|
||||
|
||||
|
||||
###################
|
||||
# --video parsing #
|
||||
###################
|
||||
@ -1952,9 +1906,6 @@ class ParserVideo(VirtCLIParser):
|
||||
self.set_param("model", "model", ignore_default=True)
|
||||
|
||||
|
||||
parse_video = ParserVideo().parse
|
||||
|
||||
|
||||
#####################
|
||||
# --soundhw parsing #
|
||||
#####################
|
||||
@ -1967,9 +1918,6 @@ class ParserSound(VirtCLIParser):
|
||||
self.set_param("model", "model", ignore_default=True)
|
||||
|
||||
|
||||
parse_sound = ParserSound().parse
|
||||
|
||||
|
||||
#####################
|
||||
# --hostdev parsing #
|
||||
#####################
|
||||
@ -1989,4 +1937,68 @@ class ParserHostdev(VirtCLIParser):
|
||||
self.set_param("driver_name", "driver_name")
|
||||
|
||||
|
||||
parse_hostdev = ParserHostdev().parse
|
||||
###########################
|
||||
# Register parser classes #
|
||||
###########################
|
||||
|
||||
def build_parser_map(options, skip=None, only=None):
|
||||
"""
|
||||
Build a dictionary with mapping of cli-name->parserinstance, so
|
||||
--vcpus -> ParserVCPU object.
|
||||
"""
|
||||
parsermap = {}
|
||||
def register_parser(cli_arg_name, parserclass):
|
||||
if cli_arg_name in util.listify(skip):
|
||||
return
|
||||
if only and cli_arg_name not in util.listify(only):
|
||||
return
|
||||
|
||||
parserobj = parserclass(cli_arg_name)
|
||||
if not hasattr(options, parserobj.option_variable_name):
|
||||
raise RuntimeError("programming error: unknown option=%s "
|
||||
"cliname=%s class=%s" %
|
||||
(parserobj.option_variable_name,
|
||||
parserobj.cli_arg_name, parserclass))
|
||||
parsermap[parserobj.option_variable_name] = parserobj
|
||||
|
||||
register_parser("vcpus", ParserVCPU)
|
||||
register_parser("cpu", ParserCPU)
|
||||
register_parser("numatune", ParserNumatune)
|
||||
register_parser("boot", ParserBoot)
|
||||
register_parser("security", ParserSecurity)
|
||||
register_parser("features", ParserFeatures)
|
||||
register_parser("clock", ParserClock)
|
||||
register_parser("disk", ParserDisk)
|
||||
register_parser("network", ParserNetwork)
|
||||
register_parser("graphics", ParserGraphics)
|
||||
register_parser("controller", ParserController)
|
||||
register_parser("smartcard", ParserSmartcard)
|
||||
register_parser("redirdev", ParserRedir)
|
||||
register_parser("tpm", ParserTPM)
|
||||
register_parser("rng", ParserRNG)
|
||||
register_parser("watchdog", ParserWatchdog)
|
||||
register_parser("memballoon", ParserMemballoon)
|
||||
register_parser("serial", ParserSerial)
|
||||
register_parser("parallel", ParserParallel)
|
||||
register_parser("channel", ParserChannel)
|
||||
register_parser("console", ParserConsole)
|
||||
register_parser("filesystem", ParserFilesystem)
|
||||
register_parser("video", ParserVideo)
|
||||
register_parser("soundhw", ParserSound)
|
||||
register_parser("host-device", ParserHostdev)
|
||||
register_parser("panic", ParserPanic)
|
||||
|
||||
return parsermap
|
||||
|
||||
|
||||
def parse_option_strings(parsermap, options, guest, inst):
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user