home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / usbcreator / backend.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  20.0 KB  |  668 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import os
  5. import subprocess
  6. import sys
  7. import stat
  8. import shutil
  9. import gobject
  10. import dbus
  11. from dbus.mainloop.glib import DBusGMainLoop
  12. import time
  13. import tempfile
  14.  
  15. class Logger:
  16.     
  17.     def __init__(self):
  18.         if 'SUDO_USER' in os.environ:
  19.             log_file = '%s/.usb-creator.log' % os.path.expanduser('~' + os.environ['SUDO_USER'])
  20.         else:
  21.             log_file = '%s/.usb-creator.log' % os.path.expanduser('~')
  22.         self.fp = open(log_file, 'a')
  23.         self.save = sys.stderr
  24.         sys.stderr = self
  25.         self.new_line = 1
  26.         l = '\n-- Starting up at %s --\n' % time.strftime('%H:%M:%S')
  27.         self.fp.write(l)
  28.         self.fp.flush()
  29.         sys.stdout.write(l)
  30.         sys.stdout.flush()
  31.  
  32.     
  33.     def __del__(self):
  34.         self.fp.close()
  35.         self.stderr = self.save
  36.  
  37.     
  38.     def fileno(self):
  39.         return self.fp.fileno()
  40.  
  41.     
  42.     def write(self, line):
  43.         if self.new_line:
  44.             l = '[%s] ' % time.strftime('%H:%M:%S')
  45.             self.new_line = 0
  46.             l = l + line
  47.         else:
  48.             l = line
  49.         self.fp.write(l)
  50.         self.fp.flush()
  51.         sys.stdout.write(l)
  52.         sys.stdout.flush()
  53.         if line[-1] == '\n':
  54.             self.new_line = 1
  55.         
  56.  
  57.  
  58.  
  59. def popen(cmd):
  60.     print >>sys.stderr, str(cmd)
  61.     process = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = sys.stderr, stdin = subprocess.PIPE)
  62.     res = process.communicate()
  63.     return (process, res)
  64.  
  65.  
  66. def free_space(dev):
  67.     
  68.     try:
  69.         stat = os.statvfs(dev)
  70.     except:
  71.         return 0
  72.  
  73.     return stat.f_bsize * stat.f_bavail
  74.  
  75.  
  76. class Backend:
  77.     
  78.     def __init__(self, frontend):
  79.         self.devices = { }
  80.         self.cds = { }
  81.         self.timeouts = { }
  82.         self.copy_timeout = 0
  83.         self.original_size = 0
  84.         self.progress_description = ''
  85.         self.frontend = frontend
  86.         self.logger = Logger()
  87.         DBusGMainLoop(set_as_default = True)
  88.         self.bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
  89.         hal_obj = self.bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
  90.         self.hal = dbus.Interface(hal_obj, 'org.freedesktop.Hal.Manager')
  91.         self.pipe = None
  92.  
  93.     
  94.     def log(self, line):
  95.         line = str(line) + '\n'
  96.         self.logger.write(line)
  97.  
  98.     
  99.     def set_install_source(self, source):
  100.         self.install_source = source
  101.  
  102.     
  103.     def set_install_target(self, target):
  104.         self.install_target = self.devices[target]
  105.  
  106.     
  107.     def set_persistence_size(self, persist):
  108.         self.persistence_size = persist
  109.  
  110.     
  111.     def format_device(self, device):
  112.         udi = self.hal.FindDeviceStringMatch('block.device', device)
  113.         udi = udi[0]
  114.         children = self.hal.FindDeviceStringMatch('info.parent', udi)
  115.         for child in children:
  116.             dev_obj = self.bus.get_object('org.freedesktop.Hal', child)
  117.             child = dbus.Interface(dev_obj, 'org.freedesktop.Hal.Device')
  118.             dev = str(child.GetProperty('block.device'))
  119.             popen([
  120.                 'umount',
  121.                 dev])
  122.         
  123.         popen([
  124.             'umount',
  125.             device])
  126.         res = popen([
  127.             'parted',
  128.             '-s',
  129.             device,
  130.             'mklabel',
  131.             'msdos'])
  132.         if res[0].returncode:
  133.             message = _('Unable to create a partition table:') + '\n' + str(res[1][0])
  134.             self.log(message)
  135.             self.frontend.notify(message)
  136.             return None
  137.         res = popen([
  138.             'parted',
  139.             '-s',
  140.             device,
  141.             'mkpartfs',
  142.             'primary',
  143.             'fat32',
  144.             '0',
  145.             '--',
  146.             '-0'])
  147.         if res[0].returncode:
  148.             message = _('Unable to format device:') + '\n' + str(res[1][0])
  149.             self.log(message)
  150.             self.frontend.notify(message)
  151.         else:
  152.             self.devices.pop(device)
  153.             self.frontend.device_removed(device, source = False)
  154.  
  155.     
  156.     def device_added(self, udi):
  157.         self.log('possibly adding: ' + str(udi))
  158.         dev_obj = self.bus.get_object('org.freedesktop.Hal', udi)
  159.         dev = dbus.Interface(dev_obj, 'org.freedesktop.Hal.Device')
  160.         if dev.PropertyExists('volume.is_disc') and dev.GetProperty('volume.is_disc'):
  161.             if not dev.GetProperty('volume.disc.is_blank'):
  162.                 self.log('got a disc: %s' % dev.GetProperty('volume.label'))
  163.                 self.bus.add_signal_receiver(self.property_modified, 'PropertyModified', 'org.freedesktop.Hal.Device', 'org.freedesktop.Hal', udi, path_keyword = 'udi')
  164.             
  165.         
  166.         success = False
  167.         if dev.PropertyExists('block.is_volume') and dev.GetProperty('block.is_volume'):
  168.             if (dev.PropertyExists('storage.bus') or dev.GetProperty('storage.bus') == 'usb') and dev.GetProperty('storage.removable'):
  169.                 if dev.GetProperty('volume.fstype') == 'vfat':
  170.                     success = True
  171.                 else:
  172.                     self.log('didnt add because not vfat')
  173.             else:
  174.                 p = dev.GetProperty('info.parent')
  175.                 dev_obj = self.bus.get_object('org.freedesktop.Hal', p)
  176.                 d = dbus.Interface(dev_obj, 'org.freedesktop.Hal.Device')
  177.                 if (d.PropertyExists('storage.bus') or d.GetProperty('storage.bus') == 'usb') and d.GetProperty('storage.removable'):
  178.                     if dev.GetProperty('volume.fstype') == 'vfat':
  179.                         success = True
  180.                     
  181.                 
  182.             if success:
  183.                 self.add_device(dev)
  184.                 return None
  185.         
  186.         if self.IsStorageDevice(dev):
  187.             children = self.hal.FindDeviceStringMatch('info.parent', udi)
  188.             c = False
  189.             for child in children:
  190.                 dev_obj = self.bus.get_object('org.freedesktop.Hal', child)
  191.                 child = dbus.Interface(dev_obj, 'org.freedesktop.Hal.Device')
  192.                 if child.GetProperty('block.is_volume') and child.GetProperty('volume.fstype') == 'vfat':
  193.                     c = True
  194.                 
  195.                 self.log('children: ' + str(children))
  196.             
  197.             if not c and dev.PropertyExists('storage.removable.media_size'):
  198.                 self.log('no children or children not vfat')
  199.                 device = str(dev.GetProperty('block.device'))
  200.                 self.devices[device] = {
  201.                     'label': '',
  202.                     'fstype': '',
  203.                     'uuid': '',
  204.                     'mountpoint': '',
  205.                     'udi': udi,
  206.                     'free': dev.GetProperty('storage.removable.media_size'),
  207.                     'capacity': dev.GetProperty('storage.removable.media_size'),
  208.                     'device': device }
  209.                 self.frontend.add_dest(device)
  210.             
  211.         
  212.  
  213.     
  214.     def property_modified(self, num_changes, change_list, udi):
  215.         dev_obj = self.bus.get_object('org.freedesktop.Hal', udi)
  216.         dev = dbus.Interface(dev_obj, 'org.freedesktop.Hal.Device')
  217.         if dev.PropertyExists('volume.is_disc') and dev.GetProperty('volume.is_disc'):
  218.             if not dev.GetProperty('volume.is_mounted'):
  219.                 return None
  220.             mountpoint = dev.GetProperty('volume.mount_point')
  221.             if mountpoint and os.path.exists('%s/.disk/info' % mountpoint):
  222.                 add = False
  223.                 if not self.cds.has_key(udi):
  224.                     add = True
  225.                 
  226.                 self.cds[udi] = {
  227.                     'label': str(dev.GetProperty('volume.label')),
  228.                     'uuid': str(dev.GetProperty('volume.uuid')),
  229.                     'mountpoint': mountpoint,
  230.                     'udi': udi,
  231.                     'size': dev.GetProperty('volume.size'),
  232.                     'filename': '' }
  233.                 if add:
  234.                     self.frontend.add_source(udi)
  235.                 
  236.                 self.frontend.update_all_rows(None)
  237.             
  238.         else:
  239.             mountpoint = str(dev.GetProperty('volume.mount_point'))
  240.             device = str(dev.GetProperty('block.device'))
  241.             if not mountpoint or free_space(mountpoint):
  242.                 pass
  243.             self.devices[device] = {
  244.                 'label': str(dev.GetProperty('volume.label')).replace(' ', '_'),
  245.                 'fstype': str(dev.GetProperty('volume.fstype')),
  246.                 'uuid': str(dev.GetProperty('volume.uuid')),
  247.                 'mountpoint': mountpoint,
  248.                 'udi': str(dev.GetProperty('info.udi')),
  249.                 'free': 0,
  250.                 'capacity': dev.GetProperty('volume.size'),
  251.                 'device': device }
  252.             self.frontend.update_dest_row(device)
  253.         self.log('prop modified')
  254.         self.log('device_udi: %s' % udi)
  255.         self.log('num_changes: %d' % num_changes)
  256.         for c in change_list:
  257.             self.log('change: %s' % str(c[0]))
  258.         
  259.  
  260.     
  261.     def device_removed(self, udi):
  262.         d = None
  263.         for device in self.devices.itervalues():
  264.             if device['udi'] == udi:
  265.                 self.log('removing %s' % udi)
  266.                 d = device['device']
  267.                 break
  268.                 continue
  269.         
  270.         if d:
  271.             self.devices.pop(d)
  272.             self.frontend.device_removed(d, source = False)
  273.             gobject.source_remove(self.timeouts[d])
  274.             self.timeouts.pop(d)
  275.         else:
  276.             d = None
  277.             for device in self.cds.itervalues():
  278.                 if device['udi'] == udi:
  279.                     self.log('removing %s' % udi)
  280.                     d = udi
  281.                     break
  282.                     continue
  283.             
  284.             if d:
  285.                 self.cds.pop(d)
  286.                 self.frontend.device_removed(d, source = True)
  287.             
  288.  
  289.     
  290.     def add_device(self, dev):
  291.         dev_obj = self.bus.get_object('org.freedesktop.Hal', dev.GetProperty('info.parent'))
  292.         device = dbus.Interface(dev_obj, 'org.freedesktop.Hal.Device')
  293.         d = device.GetProperty('block.device')
  294.         if self.devices.has_key(d):
  295.             self.devices.pop(d)
  296.             self.frontend.device_removed(d, source = False)
  297.         
  298.         udi = dev.GetProperty('info.udi')
  299.         mountpoint = str(dev.GetProperty('volume.mount_point'))
  300.         device = str(dev.GetProperty('block.device'))
  301.         if not mountpoint or free_space(mountpoint):
  302.             pass
  303.         self.devices[device] = {
  304.             'label': str(dev.GetProperty('volume.label')).replace(' ', '_'),
  305.             'fstype': str(dev.GetProperty('volume.fstype')),
  306.             'uuid': str(dev.GetProperty('volume.uuid')),
  307.             'mountpoint': mountpoint,
  308.             'udi': str(dev.GetProperty('info.udi')),
  309.             'free': 0,
  310.             'capacity': dev.GetProperty('volume.size'),
  311.             'device': device }
  312.         self.bus.add_signal_receiver(self.property_modified, 'PropertyModified', 'org.freedesktop.Hal.Device', 'org.freedesktop.Hal', udi, path_keyword = 'udi')
  313.         self.log('new device:\n%s' % self.devices[device])
  314.         self.frontend.add_dest(device)
  315.         
  316.         def update_free(device):
  317.             dev = self.devices[device]
  318.             mp = dev['mountpoint']
  319.             free = dev['free']
  320.             return True
  321.  
  322.         self.timeouts[device] = gobject.timeout_add(2000, update_free, device)
  323.  
  324.     
  325.     def detect_devices(self):
  326.         devices = self.hal.FindDeviceByCapability('volume')
  327.         for device in devices:
  328.             dev_obj = self.bus.get_object('org.freedesktop.Hal', device)
  329.             dev = dbus.Interface(dev_obj, 'org.freedesktop.Hal.Device')
  330.             if dev.PropertyExists('volume.is_disc') and dev.GetProperty('volume.is_disc'):
  331.                 if not dev.GetProperty('volume.disc.is_blank'):
  332.                     self.log('got a disc: %s' % dev.GetProperty('volume.label'))
  333.                     udi = dev.GetProperty('info.udi')
  334.                     if not dev.GetProperty('volume.is_mounted'):
  335.                         self.bus.add_signal_receiver(self.property_modified, 'PropertyModified', 'org.freedesktop.Hal.Device', 'org.freedesktop.Hal', udi, path_keyword = 'udi')
  336.                     else:
  337.                         mountpoint = dev.GetProperty('volume.mount_point')
  338.                         if mountpoint and os.path.exists('%s/.disk/info' % mountpoint):
  339.                             self.cds[udi] = {
  340.                                 'label': str(dev.GetProperty('volume.label')),
  341.                                 'uuid': str(dev.GetProperty('volume.uuid')),
  342.                                 'mountpoint': mountpoint,
  343.                                 'udi': udi,
  344.                                 'size': dev.GetProperty('volume.size'),
  345.                                 'filename': '' }
  346.                             self.frontend.add_source(udi)
  347.                         
  348.                 
  349.             dev.GetProperty('volume.disc.is_blank')
  350.         
  351.         devices = self.hal.FindDeviceByCapability('storage')
  352.         for device in devices:
  353.             dev_obj = self.bus.get_object('org.freedesktop.Hal', device)
  354.             d = dbus.Interface(dev_obj, 'org.freedesktop.Hal.Device')
  355.             if not self.IsStorageDevice(d):
  356.                 continue
  357.             
  358.             if d.GetProperty('block.is_volume'):
  359.                 if d.GetProperty('volume.fstype') == 'vfat':
  360.                     self.add_device(d)
  361.                 
  362.             d.GetProperty('volume.fstype') == 'vfat'
  363.             children = self.hal.FindDeviceStringMatch('info.parent', device)
  364.             c = False
  365.             for child in children:
  366.                 dev_obj = self.bus.get_object('org.freedesktop.Hal', child)
  367.                 child = dbus.Interface(dev_obj, 'org.freedesktop.Hal.Device')
  368.                 if child.GetProperty('block.is_volume'):
  369.                     if child.GetProperty('volume.fstype') == 'vfat':
  370.                         c = True
  371.                         self.add_device(child)
  372.                     
  373.                 child.GetProperty('volume.fstype') == 'vfat'
  374.             
  375.             if not c and d.PropertyExists('storage.removable.media_size'):
  376.                 udi = d.GetProperty('info.udi')
  377.                 device = str(d.GetProperty('block.device'))
  378.                 self.devices[device] = {
  379.                     'label': '',
  380.                     'fstype': '',
  381.                     'uuid': '',
  382.                     'mountpoint': '',
  383.                     'udi': udi,
  384.                     'free': d.GetProperty('storage.removable.media_size'),
  385.                     'capacity': d.GetProperty('storage.removable.media_size'),
  386.                     'device': device }
  387.                 self.frontend.add_dest(device)
  388.                 continue
  389.         
  390.         self.bus.add_signal_receiver(self.device_added, 'DeviceAdded', 'org.freedesktop.Hal.Manager', 'org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
  391.         self.bus.add_signal_receiver(self.device_removed, 'DeviceRemoved', 'org.freedesktop.Hal.Manager', 'org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
  392.  
  393.     
  394.     def mount_iso(self, filename):
  395.         self.log('mounting %s' % filename)
  396.         tmpdir = tempfile.mkdtemp()
  397.         res = popen([
  398.             'mount',
  399.             '-t',
  400.             'iso9660',
  401.             '-o',
  402.             'loop,ro',
  403.             filename,
  404.             tmpdir])
  405.         if res[0].returncode:
  406.             self.log('unable to mount %s to %s' % (filename, tmpdir))
  407.             self.log(res[1])
  408.             self.frontend.notify(_('Unable to mount the image %s.\n\nPlease see ~/.usb-creator.log for more details') % filename)
  409.             return None
  410.         fp = None
  411.         
  412.         try:
  413.             fp = open('%s/.disk/info' % tmpdir)
  414.             line = fp.readline().strip('\x00')
  415.             line = ' '.join(line.split(' ')[:2])
  416.             size = os.stat(filename).st_size
  417.             self.cds[filename] = {
  418.                 'label': line,
  419.                 'uuid': '',
  420.                 'udi': '',
  421.                 'mountpoint': '',
  422.                 'filename': filename,
  423.                 'size': size }
  424.             self.frontend.add_source(filename)
  425.         except Exception:
  426.             res[0].returncode
  427.             e = res[0].returncode
  428.             self.log('Unable to find %s/.disk/info, not using %s' % (tmpdir, filename))
  429.             self.log(str(e))
  430.             self.frontend.notify(_('This is not a desktop install CD and thus cannot be used by this application.'))
  431.             return None
  432.         finally:
  433.             popen([
  434.                 'umount',
  435.                 tmpdir])
  436.             popen([
  437.                 'rmdir',
  438.                 tmpdir])
  439.  
  440.  
  441.     
  442.     def install_bootloader(self):
  443.         self.frontend.progress(0, _('Installing the bootloader'))
  444.         import re
  445.         device = self.install_target['device']
  446.         udi = self.install_target['udi']
  447.         dev_obj = self.bus.get_object('org.freedesktop.Hal', udi)
  448.         dev = dbus.Interface(dev_obj, 'org.freedesktop.Hal.Device')
  449.         dev_obj = self.bus.get_object('org.freedesktop.Hal', dev.GetProperty('info.parent'))
  450.         dev = dbus.Interface(dev_obj, 'org.freedesktop.Hal.Device')
  451.         rootdev = dev.GetProperty('block.device')
  452.         tmp = device.lstrip(rootdev)
  453.         match = re.match('.*([0-9]+)$', tmp)
  454.         num = None
  455.         if match:
  456.             num = match.groups()[0]
  457.         
  458.         self.log('Marking partition %s as active.' % num)
  459.         if not num:
  460.             self.frontend.failed(_('Unable to determine the partition number.'))
  461.         
  462.         self.log('installing the bootloader to %s.' % rootdev)
  463.         process = popen([
  464.             'dd',
  465.             'if=/usr/lib/syslinux/mbr.bin',
  466.             'of=%s' % rootdev,
  467.             'bs=446',
  468.             'count=1',
  469.             'conv=sync'])
  470.         bootloader_failed = _('Error installing the bootloader.')
  471.         if process[0].returncode:
  472.             self.frontend.failed(bootloader_failed)
  473.         
  474.         self.log('installing the bootloader to %s.' % device)
  475.         args = [
  476.             'syslinux']
  477.         if 'USBCREATOR_SAFE' in os.environ:
  478.             args.append('-s')
  479.         
  480.         args.append(device)
  481.         process = popen(args)[0]
  482.         if process.returncode:
  483.             self.frontend.failed(bootloader_failed)
  484.         
  485.         popen([
  486.             'parted',
  487.             '-s',
  488.             rootdev,
  489.             'set',
  490.             num,
  491.             'boot',
  492.             'on'])
  493.  
  494.     
  495.     def copy_files(self):
  496.         tmpdir = ''
  497.         
  498.         def _copy_files(source, target, persist):
  499.             cmd = [
  500.                 '/usr/share/usb-creator/install.py',
  501.                 '-s',
  502.                 '%s/.' % source,
  503.                 '-t',
  504.                 '%s' % target,
  505.                 '-p',
  506.                 '%d' % persist]
  507.             self.log(cmd)
  508.             self.pipe = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = sys.stderr, universal_newlines = True)
  509.             self.watch = gobject.io_add_watch(self.pipe.stdout, gobject.IO_IN | gobject.IO_HUP, self.data_available)
  510.             gobject.child_watch_add(self.pipe.pid, self.on_end)
  511.  
  512.         source = self.cds[self.install_source]
  513.         if not source['udi']:
  514.             tmpdir = tempfile.mkdtemp()
  515.             popen([
  516.                 'mount',
  517.                 '-o',
  518.                 'loop,ro',
  519.                 self.install_source,
  520.                 tmpdir])
  521.             source['mountpoint'] = tmpdir
  522.         elif not source['mountpoint']:
  523.             tmpdir = tempfile.mkdtemp()
  524.             popen([
  525.                 'mount',
  526.                 '-o',
  527.                 'ro',
  528.                 self.install_source,
  529.                 tmpdir])
  530.             source['mountpoint'] = tmpdir
  531.         
  532.         if not self.install_target['mountpoint']:
  533.             tmpdir = tempfile.mkdtemp()
  534.             popen([
  535.                 'mount',
  536.                 self.install_target['device'],
  537.                 tmpdir])
  538.             self.install_target['mountpoint'] = tmpdir
  539.         
  540.         for timeout in self.timeouts.itervalues():
  541.             gobject.source_remove(timeout)
  542.         
  543.         self.timeouts = { }
  544.         self.bus.remove_signal_receiver(self.property_modified)
  545.         t = self.install_target['mountpoint']
  546.         for obj in os.listdir(self.cds[self.install_source]['mountpoint']):
  547.             obj = os.path.join(t, obj)
  548.             popen([
  549.                 'rm',
  550.                 '-rf',
  551.                 obj])
  552.         
  553.         popen([
  554.             'rm',
  555.             os.path.join(t, 'casper-rw')])
  556.         self.original_size = free_space(self.install_target['mountpoint'])
  557.         _copy_files(source['mountpoint'], self.install_target['mountpoint'], self.persistence_size)
  558.  
  559.     
  560.     def shutdown(self):
  561.         self.log('Forcing shutdown of the install process.')
  562.         import signal
  563.         
  564.         try:
  565.             if self.pipe:
  566.                 os.kill(self.pipe.pid, signal.SIGTERM)
  567.         except OSError:
  568.             pass
  569.  
  570.         source = self.cds[self.install_source]
  571.         if source['mountpoint'].startswith('/tmp'):
  572.             self.log('Unmounting source volume.')
  573.             popen([
  574.                 'umount',
  575.                 source['mountpoint']])
  576.             popen([
  577.                 'rmdir',
  578.                 source['mountpoint']])
  579.         
  580.         if self.install_target['mountpoint'].startswith('/tmp'):
  581.             self.log('Unmounting target volume.')
  582.             popen([
  583.                 'umount',
  584.                 self.install_target['mountpoint']])
  585.             popen([
  586.                 'rmdir',
  587.                 self.install_target['mountpoint']])
  588.         
  589.  
  590.     
  591.     def quit(self):
  592.         for dev in self.devices:
  593.             mp = self.devices[dev]['mountpoint']
  594.             if mp and mp.startswith('/tmp'):
  595.                 popen([
  596.                     'umount',
  597.                     mp])
  598.                 popen([
  599.                     'rmdir',
  600.                     mp])
  601.                 continue
  602.         
  603.  
  604.     
  605.     def on_end(self, pid, error_code):
  606.         source = self.cds[self.install_source]
  607.         if source['mountpoint'].startswith('/tmp'):
  608.             self.log('Unmounting source volume.')
  609.             popen([
  610.                 'umount',
  611.                 source['mountpoint']])
  612.             popen([
  613.                 'rmdir',
  614.                 source['mountpoint']])
  615.         
  616.         if self.install_target['mountpoint'].startswith('/tmp'):
  617.             self.log('Unmounting target volume.')
  618.             popen([
  619.                 'umount',
  620.                 self.install_target['mountpoint']])
  621.             popen([
  622.                 'rmdir',
  623.                 self.install_target['mountpoint']])
  624.         
  625.         self.log('Install command exited with code: %d' % error_code)
  626.         if error_code != 0:
  627.             self.frontend.failed()
  628.         
  629.         self.frontend.finished()
  630.  
  631.     
  632.     def copy_progress(self):
  633.         now = free_space(self.install_target['mountpoint'])
  634.         source = float(self.cds[self.install_source]['size'])
  635.         source = source + self.persistence_size
  636.         per = ((self.original_size - now) / source) * 100
  637.         self.frontend.progress(per, self.progress_description)
  638.         return True
  639.  
  640.     
  641.     def data_available(self, source, condition):
  642.         text = source.readline()
  643.         if len(text) > 0:
  644.             self.progress_description = text.strip('\n')
  645.             if not self.copy_timeout:
  646.                 self.copy_timeout = gobject.timeout_add(2000, self.copy_progress)
  647.             
  648.             return True
  649.         if self.copy_timeout:
  650.             gobject.source_remove(self.copy_timeout)
  651.         
  652.         return False
  653.  
  654.     
  655.     def IsStorageDevice(self, d):
  656.         if d.GetProperty('storage.bus') not in ('usb', 'mmc'):
  657.             return False
  658.         drive_types = [
  659.             'disk',
  660.             'sd_mmc',
  661.             'smart_media',
  662.             'memory_stick',
  663.             'compact_flash']
  664.         if d.GetProperty('storage.drive_type') in drive_types:
  665.             return True
  666.  
  667.  
  668.