liveusb-creator | 5 ++ liveusb/creator.py | 91 +++++++++++++++++++++++++++++++++++--------------- liveusb/gui.py | 37 +++++++++++++++++--- tests/test_creator.py | 4 +- 4 files changed, 103 insertions(+), 34 deletions(-)
New commits: commit 37805207d925c1abaed69dc6e78045f2df36fe75 Author: Luke Macken lmacken@redhat.com Date: Fri Jun 19 02:40:14 2009 -0400
Don't clear the text area when another stick is inserted
diff --git a/liveusb/gui.py b/liveusb/gui.py index 29db568..170733a 100755 --- a/liveusb/gui.py +++ b/liveusb/gui.py @@ -270,7 +270,7 @@ class LiveUSBDialog(QtGui.QDialog, LiveUSBInterface): if self.in_process: return self.driveBox.clear() - self.textEdit.clear() + #self.textEdit.clear() try: self.live.detect_removable_drives() for device, info in self.live.drives.items():
commit d77bb67eceb97f6d85430936ae04df563c929b25 Author: Luke Macken lmacken@redhat.com Date: Fri Jun 19 02:39:53 2009 -0400
Allow people to pass the ISO as a command line argument
diff --git a/liveusb/gui.py b/liveusb/gui.py index 99eb20d..29db568 100755 --- a/liveusb/gui.py +++ b/liveusb/gui.py @@ -51,7 +51,7 @@ class LiveUSBApp(QtGui.QApplication): """ Main application class """ def __init__(self, opts, args): QtGui.QApplication.__init__(self, args) - self.mywindow = LiveUSBDialog(opts) + self.mywindow = LiveUSBDialog(opts, args) self.mywindow.show() try: self.exec_() @@ -234,11 +234,12 @@ class LiveUSBLogHandler(logging.Handler): class LiveUSBDialog(QtGui.QDialog, LiveUSBInterface): """ Our main dialog class """
- def __init__(self, opts): + def __init__(self, opts, args): self.in_process = False QtGui.QDialog.__init__(self) LiveUSBInterface.__init__(self) self.opts = opts + self.args = args self.setupUi(self) self.live = LiveUSBCreator(opts=opts) self.populate_releases() @@ -259,6 +260,12 @@ class LiveUSBDialog(QtGui.QDialog, LiveUSBInterface): if not self.opts.verbose: self.live.log.removeHandler(self.live.handler)
+ # If an ISO was specified on the command line, use it. + if args: + for arg in self.args: + if arg.lower().endswith('.iso') and os.path.exists(arg): + self.selectfile(arg) + def populate_devices(self, *args, **kw): if self.in_process: return @@ -492,9 +499,10 @@ class LiveUSBDialog(QtGui.QDialog, LiveUSBInterface): self.status(_("You can try again to resume your download")) self.enable_widgets(True)
- def selectfile(self): - isofile = QtGui.QFileDialog.getOpenFileName(self, _("Select Live ISO"), - ".", "ISO (*.iso)" ) + def selectfile(self, isofile=None): + if not isofile: + isofile = QtGui.QFileDialog.getOpenFileName(self, + _("Select Live ISO"), ".", "ISO (*.iso)" ) if isofile: try: self.live.set_iso(isofile)
commit 537cff6bf344bad6308e88fd466ace3bf5a5a0be Author: Luke Macken lmacken@redhat.com Date: Fri Jun 19 02:38:54 2009 -0400
Don't try and unmount th device every time the window is closed
diff --git a/liveusb/creator.py b/liveusb/creator.py index 7006af0..476c99e 100755 --- a/liveusb/creator.py +++ b/liveusb/creator.py @@ -632,7 +632,7 @@ class LinuxLiveUSBCreator(LiveUSBCreator): self.log.debug("Killed process %d" % pid) except OSError: pass - self.unmount_device() + #self.unmount_device()
def verify_iso_md5(self): """ Verify the ISO md5sum.
commit cc462b30c4fdde854a6d09984fccc2ccd0377453 Author: Luke Macken lmacken@redhat.com Date: Fri Jun 19 02:38:42 2009 -0400
Some minor command formatting tweaks
diff --git a/liveusb/creator.py b/liveusb/creator.py index d713598..7006af0 100755 --- a/liveusb/creator.py +++ b/liveusb/creator.py @@ -607,8 +607,8 @@ class LinuxLiveUSBCreator(LiveUSBCreator): os.path.join(syslinux_path, "extlinux.conf")) self.popen('extlinux -i %s' % syslinux_path) else: # FAT - self.popen('syslinux%s%s -d %s %s' % (self.opts.force and ' -f' or ' ', - self.opts.safe and ' -s' or ' ', + self.popen('syslinux%s%s -d %s %s' % (self.opts.force and + ' -f' or '', self.opts.safe and ' -s' or '', 'syslinux', self.drive['device']))
def get_free_bytes(self, device=None): @@ -817,12 +817,14 @@ class WindowsLiveUSBCreator(LiveUSBCreator): os.unlink(os.path.join(syslinuxdir, "isolinux.cfg"))
# Don't prompt about overwriting files from mtools (#491234) - for ldlinux in [os.path.join(device + os.path.sep, p) for p in (syslinuxdir, '')]: + for ldlinux in [os.path.join(device + os.path.sep, p, 'ldlinux.sys') + for p in (syslinuxdir, '')]: if os.path.isfile(ldlinux): + self.log.debug(_("Removing") + " %s" % ldlinux) os.unlink(ldlinux)
self.popen('syslinux%s%s -m -a -d %s %s' % (self.opts.force and ' -f' - or ' ', self.opts.safe and ' -s' or ' ', 'syslinux', device)) + or '', self.opts.safe and ' -s' or '', 'syslinux', device))
def _get_device_uuid(self, drive): """ Return the UUID of our selected drive """
commit dcf9a57f7a8a0069d061034a0b9fdcb3d76b3107 Author: Luke Macken lmacken@redhat.com Date: Fri Jun 19 02:38:22 2009 -0400
Fix our ldlinux.sys cleanup code
diff --git a/liveusb/creator.py b/liveusb/creator.py index 8ff9a0b..d713598 100755 --- a/liveusb/creator.py +++ b/liveusb/creator.py @@ -595,7 +595,8 @@ class LinuxLiveUSBCreator(LiveUSBCreator): break
# Don't prompt about overwriting files from mtools (#491234) - for ldlinux in [os.path.join(self.dest, p, 'ldlinux.sys') for p in ('syslinux', '')]: + for ldlinux in [os.path.join(self.dest, p, 'ldlinux.sys') + for p in ('syslinux', '')]: self.log.debug('Looking for %s' % ldlinux) if os.path.isfile(ldlinux): self.log.debug(_("Removing") + " %s" % ldlinux)
commit e6ddd4f673350615a108ecde825789753766e15a Author: Luke Macken lmacken@redhat.com Date: Fri Jun 19 02:37:59 2009 -0400
Make our unmount method a bit more robust.
If HAL fails, call unmount directly...
diff --git a/liveusb/creator.py b/liveusb/creator.py index 21cab48..8ff9a0b 100755 --- a/liveusb/creator.py +++ b/liveusb/creator.py @@ -470,29 +470,38 @@ class LinuxLiveUSBCreator(LiveUSBCreator): else: self.log.debug("Using existing mount: %s" % self.dest)
- def unmount_device(self): + def unmount_device(self, force=False): """ Unmount our device """ import dbus - try: - unmount = self.drive.get('unmount', None) - except KeyError: - return - if self.dest and unmount: + #try: + # unmount = self.drive.get('unmount', None) + #except KeyError, e: + # self.log.exception(e) + # return + if self.dest or force or (self.drive and + self.drive.get('unmount', False)): self.log.debug("Unmounting %s from %s" % (self.drive['device'], self.dest)) try: self.drive['udi'].Unmount([], dbus_interface='org.freedesktop.Hal.Device.Volume') except dbus.exceptions.DBusException, e: - import traceback - self.log.warning("Unable to unmount device: %s" % str(e)) - self.log.debug(traceback.format_exc()) - return + if e.get_dbus_name() == \ + 'org.freedesktop.Hal.Device.Volume.NotMountedByHal': + self.log.debug('Device not mounted by HAL; trying manually') + self.popen('umount %s' % self.drive['device']) + else: + import traceback + self.log.warning("Unable to unmount device: %s" % str(e)) + self.log.debug(traceback.format_exc()) + return self.drive['unmount'] = False self.drive['mount'] = None if os.path.exists(self.dest): self.log.error("Mount %s exists after unmounting" % self.dest) self.dest = None + else: + self.log.warning("self.dest and unmount not set, skipping unmount")
def verify_filesystem(self): self.log.info(_("Verifying filesystem..."))
commit 7c5d3392ae93d7f98702df128ee26cb79edd86b8 Author: Luke Macken lmacken@redhat.com Date: Fri Jun 19 02:37:45 2009 -0400
Bump version for next release
diff --git a/liveusb-creator b/liveusb-creator index 82a6e41..26f021b 100755 --- a/liveusb-creator +++ b/liveusb-creator @@ -18,7 +18,7 @@ # # Author(s): Luke Macken lmacken@redhat.com
-__version__ = '3.6.5' +__version__ = '3.6.6'
def parse_args(): from optparse import OptionParser
commit 5084936157d3f1115f239f06bab32aeaa713aa4c Author: Luke Macken lmacken@redhat.com Date: Fri Jun 19 02:36:03 2009 -0400
Ensure the MBR matches the installed syslinux mbr.bin.
When zeroing out your drive, and then laying down a fresh msdos partition table and FAT32 partition in Gparted, it seems to set an invalid MBR (b8fa). This patch will ensure that your MBR matches the system-wide mbr.bin before continuing. (#506886)
diff --git a/liveusb-creator b/liveusb-creator index d518be2..82a6e41 100755 --- a/liveusb-creator +++ b/liveusb-creator @@ -40,6 +40,9 @@ def parse_args(): ' (eg: -k noswap,selinux=0,elevator=noop)') parser.add_option('-x', '--no-xo', dest='xo', action='store_false', default=True, help='Disable OLPC support') + parser.add_option('-m', '--reset-mbr', dest='reset_mbr', + action='store_true', default=False, + help='Reset the Master Boot Record') #parser.add_option('-z', '--usb-zip', dest='zip', action='store_true', # help='Initialize device with zipdrive-compatible geometry' # ' for booting in USB-ZIP mode with legacy BIOSes. ' diff --git a/liveusb/creator.py b/liveusb/creator.py index 5ba5fe1..21cab48 100755 --- a/liveusb/creator.py +++ b/liveusb/creator.py @@ -327,18 +327,44 @@ class LiveUSBCreator(object): """ Return a dictionary of proxy settings """ return None
- def blank_mbr(self): - """ Return whether the MBR is empty or not """ - drive = open(self._drive, 'rb') + def get_mbr(self): + parent = str(self.drive['parent']) + self.log.debug('Checking the MBR of %s' % parent) + drive = open(parent, 'rb') mbr = ''.join(['%02X' % ord(x) for x in drive.read(2)]) drive.close() self.log.debug('mbr = %r' % mbr) - return mbr == '0000' + return mbr + + def blank_mbr(self): + """ Return whether the MBR is empty or not """ + return self.get_mbr() == '0000' + + def _get_mbr_bin(self): + mbr = None + for mbr_bin in ('/usr/lib/syslinux/mbr.bin', + '/usr/share/syslinux/mbr.bin'): + if os.path.exists(mbr_bin): + mbr = mbr_bin + return mbr + + def mbr_matches_syslinux_bin(self): + """ + Return whether or not the MBR on the drive matches the system's + syslinux mbr.bin + """ + mbr_bin = open(self._get_mbr_bin(), 'rb') + mbr = ''.join(['%02X' % ord(x) for x in mbr_bin.read(2)]) + return mbr == self.get_mbr()
def reset_mbr(self): + parent = str(self.drive['parent']) if '/dev/loop' not in self.drive: - self.log.info(_('Resetting MBR...')) - self.popen('cat /usr/lib/syslinux/mbr.bin > %s' % self._drive) + self.log.info(_('Resetting Master Boot Record') + ' of %s' % parent) + mbr = self._get_mbr_bin() + self.popen('cat %s > %s' % (mbr, parent)) + else: + self.log.info(_('Drive is a loopback, skipping MBR reset'))
def bootable_partition(self): """ Ensure that the selected partition is flagged as bootable """ @@ -500,10 +526,11 @@ class LinuxLiveUSBCreator(LiveUSBCreator): # Ensure our master boot record is not empty if self.blank_mbr(): self.log.debug(_('Your MBR appears to be blank')) - # @@ FIXME: To do this properly, we first need to unmount the device, - # then reset the mbr, then remount. However, for some reason we - # are unable to re-mount the drive after resetting the MBR, and it - # tends to hose the USB stick as well. Maybe we need to rescan/reprobe + # @@ FIXME: To do this properly, we first need to unmount the + # device, then reset the mbr, then remount. However, for some + # reason we are unable to re-mount the drive after resetting the + # MBR, and it tends to hose the USB stick as well. Maybe we need + # to rescan/reprobe # the device with DBus/Hal? -luke # self.live.reset_mbr()
diff --git a/liveusb/gui.py b/liveusb/gui.py index 3853a69..99eb20d 100755 --- a/liveusb/gui.py +++ b/liveusb/gui.py @@ -251,6 +251,7 @@ class LiveUSBDialog(QtGui.QDialog, LiveUSBInterface): parent=self) self.connect_slots() self.confirmed = False + self.mbr_reset_confirmed = False
# Intercept all liveusb INFO log messages, and display them in the gui self.handler = LiveUSBLogHandler(lambda x: self.textEdit.append(x)) @@ -401,6 +402,22 @@ class LiveUSBDialog(QtGui.QDialog, LiveUSBInterface): self.live.overlay = self.overlaySlider.value() self.live.drive = self.get_selected_drive()
+ # Unmount the device and check the MBR + if self.live.blank_mbr() or not self.live.mbr_matches_syslinux_bin(): + if not self.mbr_reset_confirmed: + self.status(_("The Master Boot Record on your device is %r, " + "which doesn't match your systems syslinux " + "mbr.bin. Continuing will replace the MBR on " + "this device.") % self.live.get_mbr()) + self.mbr_reset_confirmed = True + self.enable_widgets(True) + return + if self.live.drive['mount']: + self.live.dest = self.live.drive['mount'] + self.live.unmount_device(force=True) + self.live.log.debug(_('Your MBR appears to be blank')) + self.live.reset_mbr() + try: self.live.mount_device() self._refresh_overlay_slider() # To reflect the drives free space
commit 621ca1694fdfa6c73fcbfd3d35d8dc05fd605228 Author: Luke Macken lmacken@redhat.com Date: Thu Jun 18 12:30:56 2009 -0400
Update a unit test to handle sha256 checksums in our liveusb.releases file
diff --git a/tests/test_creator.py b/tests/test_creator.py index dbd3194..8ac8b09 100644 --- a/tests/test_creator.py +++ b/tests/test_creator.py @@ -34,8 +34,10 @@ class TestLiveUSBCreator: for release in releases: assert release['name'] assert release['url'] - if release['sha1']: + if 'sha1' in release: assert len(release['sha1']) == 40 + elif 'sha256' in release: + assert len(release['sha256']) == 64
def test_mount_device(self): live = self._get_creator()
liveusb-creator@lists.stg.fedorahosted.org