virt-xml: Make --domain positional, allow stdin XML

This commit is contained in:
Cole Robinson 2014-01-25 18:16:16 -05:00
parent 6fa2876486
commit ecfc1a527d
4 changed files with 97 additions and 30 deletions

View File

@ -0,0 +1,20 @@
<domain type="test" id="1">
<name>test</name>
<uuid>6695eb01-f6a4-8304-79aa-97f2502e193f</uuid>
<memory unit="KiB">8388608</memory>
<currentMemory unit="KiB">2097152</currentMemory>
<vcpu placement="static">2</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>
<cpu mode="custom" match="exact">
<model>host-passthrough</model>
</cpu>
</domain>

View File

@ -0,0 +1,18 @@
<domain type='test' id='1'>
<name>test</name>
<uuid>6695eb01-f6a4-8304-79aa-97f2502e193f</uuid>
<memory unit='KiB'>8388608</memory>
<currentMemory unit='KiB'>2097152</currentMemory>
<vcpu placement='static'>2</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>

View File

@ -146,6 +146,7 @@ class Command(object):
self.check_success = True
self.compare_file = None
self.support_check = None
self.input_file = None
app, opts = self.cmdstr.split(" ", 1)
self.app = app
@ -172,12 +173,15 @@ class Command(object):
oldstdout = sys.stdout
oldstderr = sys.stderr
oldstdin = sys.stdin
oldargv = sys.argv
try:
out = StringIO.StringIO()
sys.stdout = out
sys.stderr = out
sys.argv = self.argv
if self.input_file:
sys.stdin = file(self.input_file)
try:
if app.count("virt-install"):
@ -202,6 +206,7 @@ class Command(object):
finally:
sys.stdout = oldstdout
sys.stderr = oldstderr
sys.stdin = oldstdin
sys.argv = oldargv
@ -402,7 +407,8 @@ class App(object):
self.categories[catname] = default_args
return _CategoryProxy(self, catname)
def _add(self, catname, testargs, valid, compfile, support_check=None):
def _add(self, catname, testargs, valid, compfile, support_check=None,
input_file=None):
args = self.categories[catname] + " " + testargs
args = self._default_args(args, bool(compfile)) + " " + args
cmdstr = "./%s %s" % (self.appname, args)
@ -412,6 +418,7 @@ class App(object):
if compfile:
cmd.compare_file = "%s/%s.xml" % (compare_xmldir, compfile)
cmd.support_check = support_check
cmd.input_file = input_file
self.cmds.append(cmd)
def add_valid(self, cat, args, **kwargs):
@ -751,14 +758,16 @@ 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.add_invalid("test --edit --hostdev driver_name=vfio") # Guest has no hostdev to edit
c.add_invalid("test --edit --cpu host-passthrough --boot hd,network") # Specified more than 1 option
c.add_invalid("test --edit") # specified no edit option
c.add_invalid("test --edit 2 --cpu host-passthrough") # specifing --edit number where it doesn't make sense
c.add_invalid("test-many-devices --edit 5 --tpm /dev/tpm") # device edit out of range
c.add_compare("test --print-xml --edit --vcpus 7", "virtxml-print-xml") # test --print-xml
c.add_compare("--edit --cpu host-passthrough", "virtxml-stdin-edit", input_file=(xmldir + "/virtxml-stdin-edit.xml")) # stdin test
c = vixml.add_category("simple edit diff", "--domain test-many-devices --edit --print-diff --define")
c = vixml.add_category("simple edit diff", "test-many-devices --edit --print-diff --define")
c.add_compare("""--metadata name=foo-my-new-name,uuid=12345678-12F4-1234-1234-123456789AFA,description="hey this is my
new
very,very=new desc\\\'",title="This is my,funky=new title" """, "virtxml-edit-simple-metadata")
@ -789,7 +798,7 @@ 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 = vixml.add_category("edit selection", "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")
@ -799,13 +808,13 @@ c.add_compare("--edit target=hda --disk /dev/null", "virtxml-edit-select-disk-ta
c.add_compare("--edit /tmp/foobar2 --disk shareable=off,readonly=on", "virtxml-edit-select-disk-path")
c.add_compare("--edit mac=00:11:7f:33:44:55 --network target=nic55", "virtxml-edit-select-network-mac")
c = vixml.add_category("edit clear", "--domain test-many-devices --print-diff --define")
c = vixml.add_category("edit clear", "test-many-devices --print-diff --define")
c.add_invalid("--edit --memory 200,clearxml") # clear isn't wired up for memory
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 = vixml.add_category("add/rm devices", "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")
@ -979,7 +988,7 @@ 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 "
p8 = PromptTest("virt-xml --connect %(TESTURI)s --confirm test "
"--edit --cpu host-passthrough")
p8.add("Define 'test' with the changed XML", "yes", num_lines=12)
promptlist.append(p8)

View File

@ -65,10 +65,14 @@ def get_diff(origxml, newxml):
return ret
def get_domain_and_guest(conn, domstr):
if not domstr:
fail("--domain must be specified")
def _make_guest(conn, xml):
# We do this to minimize the diff, sanitizing XML quotes to what libxml
# generates
return virtinst.Guest(conn,
parsexml=virtinst.Guest(conn, parsexml=xml).get_xml_config())
def get_domain_and_guest(conn, domstr):
try:
int(domstr)
isint = True
@ -91,17 +95,12 @@ def get_domain_and_guest(conn, domstr):
except libvirt.libvirtError, e:
fail(_("Could not find domain '%s': %s") % (domstr, e))
def _make_guest(xml):
# We do this to minimize the diff, removing things like ' -> "
return virtinst.Guest(conn,
parsexml=virtinst.Guest(conn, parsexml=xml).get_xml_config())
state = domain.info()[0]
active_xmlobj = None
inactive_xmlobj = _make_guest(domain.XMLDesc(0))
inactive_xmlobj = _make_guest(conn, domain.XMLDesc(0))
if state != libvirt.VIR_DOMAIN_SHUTOFF:
active_xmlobj = inactive_xmlobj
inactive_xmlobj = _make_guest(
inactive_xmlobj = _make_guest(conn,
domain.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE))
return (domain, inactive_xmlobj, active_xmlobj)
@ -228,7 +227,8 @@ def parse_args():
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("domain", nargs='?',
help=_("Domain name, id, or uuid"))
actg.add_argument("--edit", nargs='?', default=-1,
help=_("Edit VM XML. Examples:\n"
"--edit --disk ... (edit first disk device)\n"
@ -281,22 +281,42 @@ def main(conn=None):
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
options.stdinxml = None
if (not options.domain and
not sys.stdin.closed and
not sys.stdin.isatty()):
if options.confirm:
fail(_("Can't use --confirm is stdin is closed."))
options.stdinxml = sys.stdin.read()
elif not options.domain:
fail("domain must be specified")
if not options.print_xml and not options.print_diff:
if options.stdinxml:
if not options.define:
options.print_xml = True
else:
options.define = True
if options.confirm and not options.print_xml:
options.print_diff = True
if conn is None:
conn = cli.getConnection(options.connect)
domain, inactive_xmlobj, active_xmlobj = get_domain_and_guest(
conn, options.domain)
if options.domain:
domain, inactive_xmlobj, active_xmlobj = get_domain_and_guest(
conn, options.domain)
else:
domain = None
active_xmlobj = None
inactive_xmlobj = _make_guest(conn, options.stdinxml)
guest = inactive_xmlobj
origxml = guest.get_xml_config()
# XXX: do we ever need the domain?