virtinst: Add --transient flag.

If this flag is specified, --import|--boot will create a transient
libvirt domain, ie. one which goes away when the guest shuts down or
the host is rebooted.

(crobinso: some tweaks and tests)
This commit is contained in:
Richard W.M. Jones 2016-06-01 14:32:56 +01:00 committed by Cole Robinson
parent f2d2630f45
commit 246e3c9c59
4 changed files with 43 additions and 16 deletions

View File

@ -1576,6 +1576,15 @@ Show program's version number and exit
Set the autostart flag for a domain. This causes the domain to be started
on host boot up.
=item B<--transient>
Use --import or --boot and --transient if you want a transient libvirt
VM. These VMs exist only until the domain is shut down or the host
server is restarted. Libvirt forgets the XML configuration of the VM
after either of these events. Note that the VM's disks will not be
deleted. See:
L<http://wiki.libvirt.org/page/VM_lifecycle#Transient_guest_domains_vs_Persistent_guest_domains>
=item B<--print-xml> [STEP]
Print the generated XML of the guest, instead of defining it. By default this WILL do storage creation (can be disabled with --dry-run). This option implies --quiet.

View File

@ -797,6 +797,7 @@ c = vinst.add_category("console-tests", "--pxe --nodisks")
c.add_valid("--nographics") # mock virsh console waiting
c.add_valid("--graphics vnc --noreboot") # mock virt-viewer waiting, with noreboot magic
c.add_invalid("--noautoconsole --wait 1") # --wait 1 is converted to 1 second if we are in the test suite, so this should actually touch the wait machinery. however in this case it exits with failure
c.add_valid("--nographics --transient") # --transient handling

View File

@ -449,6 +449,9 @@ _cdrom_location_man_page = _("See the man page for examples of "
def check_option_collisions(options, guest):
if options.noreboot and options.transient:
fail(_("--noreboot and --transient can not be specified together"))
# Install collisions
if sum([bool(l) for l in [options.pxe, options.location,
options.cdrom, options.import_install]]) > 1:
@ -688,13 +691,14 @@ def start_install(guest, options):
start_time = time.time()
# Do first install phase
guest.start_install(meter=meter, doboot=not options.noreboot)
guest.start_install(meter=meter, doboot=not options.noreboot,
transient=options.transient)
cli.connect_console(guest, conscb, wait_on_console)
check_domain(guest, conscb,
check_domain(guest, conscb, options.transient,
wait_on_install, wait_time, start_time)
print_stdout(_("Domain creation completed."))
if not guest.domain.isActive():
if not options.transient and not guest.domain.isActive():
if options.noreboot or not guest.installer.has_install_phase():
print_stdout(
_("You can restart your domain by running:\n %s") %
@ -715,21 +719,27 @@ def start_install(guest, options):
cli.install_fail(guest)
def check_domain(guest, conscb, wait_for_install, wait_time, start_time):
def check_domain(guest, conscb, transient,
wait_for_install, wait_time, start_time):
"""
Make sure domain ends up in expected state, and wait if for install
to complete if requested
"""
# Wait a bit so info is accurate
def check_domain_inactive():
dominfo = guest.domain.info()
state = dominfo[0]
logging.debug("Domain state after install: %s", state)
try:
dominfo = guest.domain.info()
state = dominfo[0]
logging.debug("Domain state after install: %s", state)
if state == libvirt.VIR_DOMAIN_CRASHED:
fail(_("Domain has crashed."))
if state == libvirt.VIR_DOMAIN_CRASHED:
fail(_("Domain has crashed."))
return not guest.domain.isActive()
return not guest.domain.isActive()
except libvirt.libvirtError, e:
if transient and e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
logging.debug("transient VM shutdown and disappeared.")
return True
raise
if check_domain_inactive():
return
@ -927,6 +937,9 @@ def parse_args():
misc.add_argument("--autostart", action="store_true", dest="autostart",
default=False,
help=_("Have domain autostart on host boot up."))
misc.add_argument("--transient", action="store_true", dest="transient",
default=False,
help=_("Create a transient domain."))
misc.add_argument("--wait", type=int, dest="wait",
help=_("Minutes to wait for install to complete."))

View File

@ -382,7 +382,7 @@ class Guest(XMLBuilder):
return install_xml, final_xml
def _create_guest(self, meter, install_xml, final_xml, doboot):
def _create_guest(self, meter, install_xml, final_xml, doboot, transient):
"""
Actually do the XML logging, guest defining/creating
@ -392,10 +392,11 @@ class Guest(XMLBuilder):
meter = util.ensure_meter(meter)
meter.start(size=None, text=meter_label)
if doboot or self.installer.has_install_phase():
if doboot or transient or self.installer.has_install_phase():
self.domain = self.conn.createXML(install_xml or final_xml, 0)
self.domain = self.conn.defineXML(final_xml)
if not transient:
self.domain = self.conn.defineXML(final_xml)
meter.end(0)
try:
@ -428,7 +429,8 @@ class Guest(XMLBuilder):
##############
def start_install(self, meter=None,
dry=False, return_xml=False, doboot=True):
dry=False, return_xml=False,
doboot=True, transient=False):
"""
Begin the guest install (stage1).
@param return_xml: Don't create the guest, just return generated XML
@ -455,7 +457,9 @@ class Guest(XMLBuilder):
self.check_vm_collision(self.conn, self.name,
do_remove=self.replace)
self._create_guest(meter, install_xml, final_xml, doboot)
self._create_guest(meter, install_xml, final_xml,
doboot, transient)
# Set domain autostart flag if requested
self._flag_autostart()
finally: