Created
May 28, 2014 19:45
-
-
Save jonasbits/924f62743a0cceb5a2a4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Copyright (c) 2013 Alon Swartz <[email protected]> | |
# | |
# This file is part of Fab | |
# | |
# Fab is free software; you can redistribute it and/or modify it under the | |
# terms of the GNU Affero General Public License as published by the Free | |
# Software Foundation; either version 3 of the License, or (at your option) any | |
# later version. | |
""" | |
iso2usb: Create a bootable USB flash drive containing ISO image | |
Arguments: | |
iso_path Path to ISO (e.g., product.iso) | |
usb_device USB device path (e.g., /dev/sdc) | |
Options: | |
--force Not implemented, interactive confirmation required | |
Warnings: | |
- Be very sure the USB device is correct, abort if unsure!! | |
- If ISO is not hybrid mode, it will be converted after confirmation. | |
This will alter the image, you might want to make a copy before hand. | |
""" | |
import os | |
import sys | |
import stat | |
import getopt | |
import executil | |
def fatal(e): | |
print >> sys.stderr, 'Error: ' + str(e) | |
sys.exit(1) | |
def usage(e=None): | |
if e: | |
print >> sys.stderr, 'Error: ' + str(e) | |
cmd = os.path.basename(sys.argv[0]) | |
print >> sys.stderr, 'Syntax: %s iso_path usb_device' % cmd | |
print >> sys.stderr, __doc__.strip() | |
sys.exit(1) | |
class Error(Exception): | |
pass | |
class ISO: | |
def __init__(self, path): | |
self.path = os.path.realpath(path) | |
self.name = os.path.basename(self.path) | |
if not os.path.exists(self.path): | |
raise Error("iso path does not exist: %s" % self.path) | |
def make_hybrid(self): | |
executil.system("isohybrid", self.path) | |
if not self.is_hybrid: | |
raise Error("iso not verified as hybrid mode") | |
@property | |
def is_hybrid(self): | |
output = executil.getoutput("fdisk", "-l", self.path) | |
if "Hidden HPFS/NTFS" in output: | |
return True | |
if "Disk identifier: 0x00000000" in output: | |
return False | |
if "doesn't contain a valid partition table" in output: | |
return False | |
raise Error("unable to determine ISO hybrid status") | |
class USB: | |
def __init__(self, path): | |
self.path = path | |
if not os.path.exists(self.path): | |
raise Error("usb path does not exist: %s" % self.path) | |
if not self.is_block_device: | |
raise Error("usb path is not a block device: %s" % self.path) | |
if self.is_partition: | |
raise Error("usb path seems to be a partition: %s" % self.path) | |
if not self.is_usb_device: | |
raise Error("usb path is not verifiable as a usb device: %s" % self.path) | |
@property | |
def is_block_device(self): | |
mode = os.stat(self.path).st_mode | |
return stat.S_ISBLK(mode) | |
@property | |
def is_partition(self): | |
try: | |
int(self.path[-1]) | |
return True | |
except ValueError: | |
return False | |
@property | |
def is_usb_device(self): | |
if "usb" in self.name: | |
return True | |
return False | |
@property | |
def name(self): | |
cmd = ["udevadm", "info", "-q", "symlink", "-n", self.path] | |
output = executil.getoutput(*cmd) | |
return output.split(" ")[0] | |
def write_iso(self, iso_path): | |
cmd = ["dd", "if=%s" % iso_path, "of=%s" % self.path] | |
executil.system(*cmd) | |
def main(): | |
try: | |
opts, args = getopt.gnu_getopt(sys.argv[1:], 'h', ['help']) | |
except getopt.GetoptError, e: | |
usage(e) | |
for opt, val in opts: | |
if opt in ('-h', '--help'): | |
usage() | |
if not len(args) == 2: | |
usage() | |
if os.geteuid() != 0: | |
fatal("root privileges are required") | |
try: | |
iso = ISO(args[0]) | |
usb = USB(args[1]) | |
except Error, e: | |
fatal(e) | |
print "*" * 78 | |
print "iso: %s (hybrid: %s)" % (iso.name, iso.is_hybrid) | |
print "usb: %s (%s)" % (usb.name, usb.path) | |
print "*" * 78 | |
cont = raw_input("Is the above correct? (y/N): ").strip() | |
if not cont.lower() == "y": | |
fatal("aborting...") | |
if not iso.is_hybrid: | |
print "processing ISO for hybrid mode..." | |
iso.make_hybrid() | |
print "writing ISO to USB, this could take a while..." | |
usb.write_iso(iso.path) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment