graphical progress bar hooks for pv guests

This commit is contained in:
Hugh O. Brock 2007-01-10 16:11:57 -05:00
parent 483f3436aa
commit c6e5a99343
3 changed files with 75 additions and 39 deletions

View File

@ -4275,31 +4275,6 @@ For all domains</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="window-text">
<property name="visible">True</property>
<property name="label" translatable="yes">Please wait...</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">13</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkProgressBar" id="pbar">
<property name="visible">True</property>
@ -4310,7 +4285,7 @@ For all domains</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="padding">8</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>

View File

@ -35,19 +35,20 @@ class vmmAsyncJob(gobject.GObject):
def run(self):
threading.Thread.run(self)
def __init__(self, config, callback, args=None, title="Progress", text="Please wait..."):
def __init__(self, config, callback, args=None, title="Progress"):
self.__gobject_init__()
self.config = config
self.pbar_glade = gtk.glade.XML(self.config.get_glade_file(), "vmm-progress", domain="virt-manager")
self.pbar_win = self.pbar_glade.get_widget("vmm-progress")
self.pbar = self.pbar_glade.get_widget("pbar")
self.pbar_win.set_title(title)
self.pbar_glade.get_widget("window-text").set_label(text)
self.pbar_win.hide()
args.insert(0, self)
self.bg_thread = vmmAsyncJob.asyncJobWorker(callback, args)
self.is_pulsing = False
def run(self):
self.timer = gobject.timeout_add (100, self.pulse_pbar)
self.timer = gobject.timeout_add (100, self.exit_if_necessary)
self.pbar_win.present()
self.pbar_win.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
self.bg_thread.start()
@ -56,10 +57,28 @@ class vmmAsyncJob(gobject.GObject):
self.timer = 0
self.pbar_win.destroy()
def pulse_pbar(self):
def pulse_pbar(self, text=_("Working...")):
self.is_pulsing = True
self.pbar.set_text(text)
def set_pbar_fraction(self, frac, text):
# callback for progress meter when file size is known
self.is_pulsing=False
self.pbar.set_text(text)
self.pbar.set_fraction(frac)
def set_pbar_done(self, text):
#callback for progress meter when progress is done
self.is_pulsing=False
self.pbar.set_text(text)
self.pbar.set_fraction(1)
def exit_if_necessary(self):
if(self.bg_thread.isAlive()):
self.pbar.pulse()
if(self.is_pulsing):
self.pbar.pulse()
return True
else:
gtk.main_quit()
return False

View File

@ -27,7 +27,7 @@ import virtinst
import os, sys
import re
import subprocess
import urlgrabber.grabber as grabber
import urlgrabber.progress as progress
import tempfile
import logging
import dbus
@ -45,6 +45,48 @@ VM_STORAGE_FILE = 2
DEFAULT_STORAGE_FILE_SIZE = 500
class vmmCreateMeter(progress.BaseMeter):
def __init__(self, asyncjob):
# progress meter has to run asynchronously, so pass in the
# async job to call back to with progress info
progress.BaseMeter.__init__(self)
self.asyncjob = asyncjob
def _do_start(self, now):
if self.text is not None:
text = self.text
else:
text = self.basename
if self.size is None:
self.asyncjob.pulse_pbar(text)
else:
self.asyncjob.set_pbar_fraction(0, text)
def _do_update(self, amount_read, now=None):
fread = progress.format_number(amount_read)
#self.size = None
if self.text is not None:
text = self.text
else:
text = self.basename
if self.size is None:
out = '\r%-60.60s %5sB' % \
(text, fread)
self.asyncjob.pulse_pbar(out)
else:
frac = self.re.fraction_read()
out = '\r%-25.25s %3i%% %5sB' % \
(text, frac*100, fread)
self.asyncjob.set_pbar_fraction(frac, out)
def _do_end(self, amount_read, now=None):
if self.text is not None:
text = self.text
else:
text = self.basename
out = '\r%-25.25s 100%%' % text
self.asyncjob.set_pbar_done(out)
class vmmCreate(gobject.GObject):
__gsignals__ = {
"action-show-console": (gobject.SIGNAL_RUN_FIRST,
@ -59,7 +101,6 @@ class vmmCreate(gobject.GObject):
self.window = gtk.glade.XML(config.get_glade_file(), "vmm-create", domain="virt-manager")
self.topwin = self.window.get_widget("vmm-create")
self.topwin.hide()
self.window.signal_autoconnect({
"on_create_pages_switch_page" : self.page_changed,
"on_create_cancel_clicked" : self.close,
@ -411,15 +452,14 @@ class vmmCreate(gobject.GObject):
self.topwin.set_sensitive(False)
self.topwin.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
if not self.non_sparse:
text=_("Please wait...")
logging.debug("Sparse file or partition selected")
else:
text=_("Creating the storage file for your guest can take 30 seconds or more per GB, please be patient.")
logging.debug("Non-sparse file selected")
progWin = vmmAsyncJob(self.config, self.do_install, [guest],
title=_("Creating Virtual Machine"),
text=text)
title=_("Creating Virtual Machine"))
progWin.run()
if self.install_error != None:
logging.error("Async job failed to create VM " + str(self.install_error))
self._validation_error_box(_("Guest Install Error"), self.install_error)
@ -445,10 +485,11 @@ class vmmCreate(gobject.GObject):
self.emit("action-show-terminal", self.connection.get_uri(), guest.uuid)
self.close()
def do_install(self, guest):
def do_install(self, asyncjob, guest):
meter = vmmCreateMeter(asyncjob)
try:
logging.debug("Starting background install process")
dom = guest.start_install(False)
dom = guest.start_install(False, meter = meter)
if dom == None:
self.install_error = "Guest installation failed to complete"
logging.error("Guest install did not return a domain")
@ -721,3 +762,4 @@ class vmmCreate(gobject.GObject):
else:
return True