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:
parent
f2d2630f45
commit
246e3c9c59
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
23
virt-install
23
virt-install
|
@ -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,13 +719,14 @@ 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():
|
||||
try:
|
||||
dominfo = guest.domain.info()
|
||||
state = dominfo[0]
|
||||
logging.debug("Domain state after install: %s", state)
|
||||
|
@ -730,6 +735,11 @@ def check_domain(guest, conscb, wait_for_install, wait_time, start_time):
|
|||
fail(_("Domain has crashed."))
|
||||
|
||||
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."))
|
||||
|
||||
|
|
|
@ -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,9 +392,10 @@ 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)
|
||||
|
||||
if not transient:
|
||||
self.domain = self.conn.defineXML(final_xml)
|
||||
meter.end(0)
|
||||
|
||||
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue