Skip to content

Instantly share code, notes, and snippets.

@n2n3
Created January 9, 2011 10:29
Show Gist options
  • Save n2n3/771583 to your computer and use it in GitHub Desktop.
Save n2n3/771583 to your computer and use it in GitHub Desktop.
meego
#!/usr/bin/python -ttu
# vim: ai ts=4 sts=4 et sw=4
# Copyright (c) 2008 Intel Corporation
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; version 2 of the License
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc., 59
# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import sys
import os
import gettext
import re
import subprocess
import time
import select
_ = gettext.lgettext
PROG_NAME = "image-writer"
COLOR_BLACK = "\033[00m"
COLOR_RED = "\033[1;31m"
COLOR_BLUE = "\033[1;34m"
def main():
# Python version check
if sys.hexversion < 0x2040000:
print >> sys.stderr, _("Error: %s depends on a Python " \
"v2.4 or greater!") % (PROG_NAME)
sys.exit(1)
# Check for root priveleges
if not are_we_root():
print >> sys.stderr, _("%s must be run using " \
"root priveleges") % (PROG_NAME)
sys.exit(1)
# Parameters check
if len(sys.argv) != 2:
display_help()
sys.exit(1)
# Check image validity
image = os.path.realpath(os.path.abspath(sys.argv[1]))
if not is_valid_image(image):
sys.exit(1)
# Get USB drive
usbd=get_usb_disk()
if len(usbd)==0:
sys.exit(1)
# Unmount USB drive
if not umount_device(usbd):
sys.exit(1)
# Warn of pending USB content doom
msg = _("Warning: The USB drive (%s) will be completely erased!") % usbd
if not user_confirm (msg, COLOR_RED):
sys.exit(1)
# Write image to USB drive
if not write_image_to_disk (image, usbd):
sys.exit(1)
print _("You may now boot your mobile device with this USB drive\n")
return 0
#-----------------------------------------------------------------------
def display_help():
print _("\nUsage: image-writer <full-path-to-image>\n")
# ret True = running as root
def are_we_root():
if os.getuid() == 0:
return True
return False
def is_valid_image(image):
if not os.path.isfile(image):
print _("The image path does not point to a file")
return False;
if not (os.path.getsize(image) > (180*1024*1024)):
msg = _("The file specified does not appear to be " \
"large enough to be a valid image.")
if not user_confirm (msg):
return False;
return True
def user_confirm(msg, text_color=COLOR_BLACK,
confirm=_(" Do you want to continue anyway? (y/n) ")):
print _("%s%s%s") % (text_color, msg, COLOR_BLACK)
confirm_msg = _("%s%s%s") % (text_color, confirm, COLOR_BLACK)
name=""
while name!="n" and name!="y":
name = raw_input(confirm_msg)
name = name.lower()
if name=="n":
return False;
return True
def get_usb_disk():
usbd = ""
udisks = get_current_udisks();
if len(udisks)==0:
print _("No USB drives detected.")
print _("Please insert a USB drive large enough to store the " \
"given image")
return ""
elif len(udisks)==1:
usbd=udisks[0]
elif len(udisks)>0:
print _("\nMultiple USB drives discovered:")
i=1
for usbd in udisks:
print "%s) %s" % (i, usbd)
i+=1
sel_usb = ""
while sel_usb not in range (1,len(udisks)+1):
try:
sel_usb = int(raw_input(" Select the USB " \
"drive to use (1-%s): " % (len(udisks))))
except ValueError:
continue
usbd = udisks[sel_usb-1]
#print "Drive selected: '%s'" % (usbd)
return usbd
def get_current_udisks():
usb_devices = []
dirname = os.path.realpath(os.path.abspath('/sys/bus/scsi'))
work_list = get_usb_dir_tree(dirname)
usb_list = [ x for x in work_list if re.search(r'usb', x) ]
for filename in usb_list:
#print _("usb_list file is %s") % filename
device_dir = os.path.join('/sys/devices', filename)
block_dir = os.path.join(device_dir, 'block')
if (os.path.isdir(block_dir)) :
for result in os.listdir(block_dir):
#print result
usb_dev = os.path.join('/dev',result)
if os.path.exists(usb_dev):
usb_devices.append(usb_dev)
break
elif os.path.isdir(device_dir):
for device_file in os.listdir(device_dir):
full_path = os.path.join(device_dir, device_file)
result = re.search(r'^block:(?P<dev>.*)', device_file)
if result:
usb_dev = os.path.join('/dev', result.group('dev'))
if os.path.exists(usb_dev):
usb_devices.append(usb_dev)
break
return usb_devices
def get_usb_dir_tree(dirname):
file_set = set()
for filename in os.listdir(dirname):
full_path = os.path.join(dirname, filename)
if os.path.islink(full_path):
file_set.add(os.path.realpath(full_path))
elif os.path.isdir(full_path):
file_set.update(get_usb_dir_tree(full_path))
else:
file_set.add(full_path)
return file_set
def umount_device(device):
"""umount a device if it is mounted"""
dev_path = "%s1 " % os.path.realpath(os.path.abspath(device))
if is_mounted(dev_path):
print _("Unmounting %s...") % (dev_path) ,
result = os.system("umount %s" % (dev_path))
if result and is_mounted(dev_path):
print _("Failed.\n%s could not be unmounted") % device
return False
print _("Done.")
return True
def is_mounted (dirname):
mount_file = open('/proc/mounts', 'r')
for line in mount_file:
if line.find(dirname) == 0:
#return True (causes failures later)
return False
return False
def write_image_to_disk (image_filename, usb_disk):
# image write timings
# 200 == 78s
# 422 == 165s
# 1036 == 413s
size = os.path.getsize(image_filename)
print _("Source: %s") % image_filename
print _("Size: %s MB") % (int(size/(1024*1024)))
print _("Destination: %s") % usb_disk
#(tbd, get usb capacity): print _("Capacity: %s") % ("1GB")
# get time estimate based on image size (assume 10MB/sec)
totsec = int(size / (5*1024*1024))
min,sec = divmod(totsec, 60)
msg = _("Writing image (Est. %smin %ssec)... ") % (min,sec)
print _("%s%s%s") % (COLOR_BLUE, msg, COLOR_BLACK) ,
cmd = "dd bs=4096 if=%s of=%s" % (image_filename, usb_disk)
p = subprocess.Popen(cmd.split(),
stdout = subprocess.PIPE,
stderr = subprocess.STDOUT,
stdin = subprocess.PIPE,
close_fds = True)
# show progress (percentage ticking)
poll = select.poll()
poll.register(p.stdout, select.POLLIN)
interval = (totsec / 100.0)
perc = 0
while p.poll() == None:
print _("%s\b\b\b\b%2s%%%s") % (COLOR_BLUE, perc, COLOR_BLACK) ,
time.sleep(interval)
if perc < 99:
perc+=1
print _("%s\b\b\b\b100%%%s") % (COLOR_BLUE, COLOR_BLACK)
# show output of command
(sout,serr) = p.communicate()
for line in sout.split('\n'):
print line
result = p.returncode
if result != 0:
print _("Error: The image could not be written to the USB drive")
return False
print _("The image was successfully written to the USB drive")
return True
if __name__ == '__main__':
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment