diff -r e148147cdbd2 man/en/virt-install.pod --- a/man/en/virt-install.pod Tue Jul 22 12:38:25 2008 -0400 +++ b/man/en/virt-install.pod Wed Jul 23 11:06:13 2008 -0400 @@ -1,4 +1,4 @@ -=pod +=od =head1 NAME @@ -490,6 +490,16 @@ Prevent interactive prompts. If the intended prompt was a yes/no prompt, always say yes. For any other prompts, the application will exit. +=item --wait=WAIT + +Amount of time to wait (in minutes) for a VM to complete its install. +Without this option, virt-install will wait for the console to close (not +neccessarily indicating the guest has shutdown), or in the case of +--noautoconsole, simply kick off the install and exit. Any negative +value will make virt-install wait indefinitely, a value of 0 is the same as +not specifying --wait. If the time limit is succeeded, virt-install simply +exits, leaving the virtual machine in its current state. + =back =head1 EXAMPLES diff -r e148147cdbd2 virt-install --- a/virt-install Tue Jul 22 12:38:25 2008 -0400 +++ b/virt-install Wed Jul 23 11:06:13 2008 -0400 @@ -22,6 +22,7 @@ # MA 02110-1301 USA. import os, sys, string +import time import errno from optparse import OptionParser, OptionValueError import subprocess @@ -286,6 +287,10 @@ parser.add_option("", "--force", action="store_true", dest="force", help=_("Do not prompt for input. Answers yes where applicable, terminates for all other prompts"), default=False) + parser.add_option("", "--wait", type="int", dest="wait", + help=_("Total time to wait for VM to complete install " + "(shutdown). Time less than 0 waits " + "indefinitely.")) (options,args) = parser.parse_args() @@ -454,18 +459,25 @@ else: conscb = show_console + if options.wait: + wait = True + wait_time = options.wait * 60 + progresscb = progress.TextMeter() # we've got everything -- try to start the install try: print _("\n\nStarting install...") + start_time = time.time() + started = False while True: if not started: - dom = guest.start_install(conscb,progresscb) + dom = guest.start_install(conscb, progresscb, wait=(not wait)) elif continue_inst: - dom = guest.continue_install(conscb,progresscb) + dom = guest.continue_install(conscb, progresscb, + wait=(not wait)) continue_inst = False else: break @@ -475,8 +487,25 @@ sys.exit(0) elif dom.info()[0] != libvirt.VIR_DOMAIN_SHUTOFF: # domain seems to be running - print _("Domain installation still in progress. You can reconnect to \nthe console to complete the installation process.") - sys.exit(0) + if wait: + print _("Domain installation still in progress. " + "Waiting for domain to shutdown.") + while True: + if dom.info()[0] == libvirt.VIR_DOMAIN_SHUTOFF: + print _("Domain has shutdown. Continuing.") + break + if wait_time < 0 or \ + ((time.time() - start_time) < wait_time): + time.sleep(2) + else: + print _("Installation has exceeded specified time" + "limit. Aborting.") + sys.exit(1) + else: + print _("Domain installation still in progress. " + "You can reconnect to \nthe console to complete " + "the installation process.") + sys.exit(0) if not started: started = True diff -r e148147cdbd2 virtinst/FullVirtGuest.py --- a/virtinst/FullVirtGuest.py Tue Jul 22 12:38:25 2008 -0400 +++ b/virtinst/FullVirtGuest.py Wed Jul 23 11:06:13 2008 -0400 @@ -254,7 +254,7 @@ return FullVirtGuest.OS_TYPES[self.os_type]["continue"] return False - def continue_install(self, consolecb, meter): + def continue_install(self, consolecb, meter, wait=True): install_xml = self.get_config_xml(disk_boot = True) logging.debug("Starting guest from '%s'" % ( install_xml )) meter.start(size=None, text="Starting domain...") @@ -263,7 +263,7 @@ raise RuntimeError, _("Unable to start domain for guest, aborting installation!") meter.end(0) - self.connect_console(consolecb) + self.connect_console(consolecb, wait) # ensure there's time for the domain to finish destroying if the # install has finished or the guest crashed diff -r e148147cdbd2 virtinst/Guest.py --- a/virtinst/Guest.py Tue Jul 22 12:38:25 2008 -0400 +++ b/virtinst/Guest.py Wed Jul 23 11:06:13 2008 -0400 @@ -954,7 +954,8 @@ "action": action } - def start_install(self, consolecb = None, meter = None, removeOld = False): + def start_install(self, consolecb=None, meter=None, removeOld=False, + wait=None): """Do the startup of the guest installation.""" self.validate_parms() @@ -964,7 +965,7 @@ self._prepare_install(meter) try: - return self._do_install(consolecb, meter, removeOld) + return self._do_install(consolecb, meter, removeOld, wait) finally: self._installer.cleanup() @@ -972,7 +973,7 @@ self._install_disks = self.disks[:] self._install_nics = self.nics[:] - def _do_install(self, consolecb, meter, removeOld=False): + def _do_install(self, consolecb, meter, removeOld=False, wait=True): vm = None try: vm = self.conn.lookupByName(self.name) @@ -1030,7 +1031,7 @@ logging.debug("Saving XML boot config '%s'" % ( boot_xml )) self.conn.defineXML(boot_xml) - if child: # if we connected the console, wait for it to finish + if child and wait: # if we connected the console, wait for it to finish try: (pid, status) = os.waitpid(child, 0) except OSError, (errno, msg): @@ -1047,7 +1048,7 @@ def post_install_check(self): return self.installer.post_install_check(self) - def connect_console(self, consolecb): + def connect_console(self, consolecb, wait=True): logging.debug("Restarted guest, looking to see if it is running") # sleep in .25 second increments until either a) we get running # domain ID or b) it's been 5 seconds. this is so that @@ -1075,7 +1076,7 @@ logging.debug("Launching console callback") child = consolecb(self.domain) - if child: # if we connected the console, wait for it to finish + if child and wait: # if we connected the console, wait for it to finish try: (pid, status) = os.waitpid(child, 0) except OSError, (errno, msg):