=== modified file 'lava_dispatcher/actions/android_install_binaries.py'
--- lava_dispatcher/actions/android_install_binaries.py	2012-09-30 17:01:44 +0000
+++ lava_dispatcher/actions/android_install_binaries.py	2012-11-09 20:26:45 +0000
@@ -18,6 +18,7 @@
 # along with this program; if not, see <http://www.gnu.org/licenses>.
 
 import logging
+
 from lava_dispatcher.actions import BaseAction, null_or_empty_schema
 
 
@@ -27,13 +28,10 @@
 
     def run(self):
         driver_tarball = self.client.config.android_binary_drivers
+        partition = self.client.config.root_part
+
         if driver_tarball is None:
             logging.error("android_binary_drivers not defined in any config")
             return
 
-        with self.client.target_device._as_master() as session:
-            session.run(
-                'mount /dev/disk/by-label/testrootfs /mnt/lava/system')
-            self.client.target_device.target_extract(
-                session, driver_tarball, '/mnt/lava/system', timeout=600)
-            session.run('umount /mnt/lava/system')
+        self.client.target_device.extract_tarball(driver_tarball, partition)

=== modified file 'lava_dispatcher/actions/android_install_cts_medias.py'
--- lava_dispatcher/actions/android_install_cts_medias.py	2012-10-25 06:33:00 +0000
+++ lava_dispatcher/actions/android_install_cts_medias.py	2012-11-09 20:26:45 +0000
@@ -39,12 +39,5 @@
             logging.error("The url for the cts media files is not specified")
             return
 
-        with self.client.target_device._as_master() as session:
-            if not session.has_partition_with_label('sdcard'):
-                return
-            session.run('mkdir -p /mnt/lava/sdcard')
-            session.run(
-                'mount /dev/disk/by-label/sdcard /mnt/lava/sdcard')
-            self.client.target_device.target_extract(
-                session, media_url, '/mnt/lava/sdcard', timeout=timeout)
-            session.run('umount /mnt/lava/sdcard')
+        partition = self.client.config.sdcard_part_android_org
+        self.client.target_device.extract_tarball(media_url, partition)

=== modified file 'lava_dispatcher/device/fastmodel.py'
--- lava_dispatcher/device/fastmodel.py	2012-10-23 17:45:15 +0000
+++ lava_dispatcher/device/fastmodel.py	2012-11-09 20:25:51 +0000
@@ -45,6 +45,7 @@
     )
 from lava_dispatcher.utils import (
     ensure_directory,
+    extract_targz,
     logging_spawn,
     logging_system,
     )
@@ -158,6 +159,13 @@
             ensure_directory(path)
             yield path
 
+    def extract_tarball(self, tarball_url, partition, directory='/'):
+        logging.info('extracting %s to target' % tarball_url)
+
+        with image_partition_mounted(self._sd_image, partition) as mntdir:
+            tb = download_image(tarball_url, self.context, decompress=False)
+            extract_targz(tb, '%s/%s' % (mntdir, directory))
+
     def _fix_perms(self):
         ''' The directory created for the image download/creation gets created
         with tempfile.mkdtemp which grants permission only to the creator of
@@ -268,7 +276,7 @@
     def get_device_version(self):
         cmd = '%s --version' % self._sim_binary
         try:
-            banner = subprocess.check_output(cmd, shell = True)
+            banner = subprocess.check_output(cmd, shell=True)
             return self._parse_fastmodel_version(banner)
         except subprocess.CalledProcessError:
             return "unknown"
@@ -280,6 +288,7 @@
         else:
             return "unknown"
 
+
 class _pexpect_drain(threading.Thread):
     ''' The simulator process can dump a lot of information to its console. If
     don't actively read from it, the pipe will get full and the process will

=== modified file 'lava_dispatcher/device/master.py'
--- lava_dispatcher/device/master.py	2012-11-13 09:59:11 +0000
+++ lava_dispatcher/device/master.py	2012-11-15 04:54:00 +0000
@@ -225,26 +225,30 @@
 
         raise RuntimeError('extracting %s on target failed' % tar_url)
 
-    @contextlib.contextmanager
-    def file_system(self, partition, directory):
-        logging.info('attempting to access master filesystem %r:%s' %
-            (partition, directory))
-
+    def get_partition(self, runner, partition):
         if partition == self.config.boot_part:
             partition = '/dev/disk/by-label/testboot'
         elif partition == self.config.root_part:
             partition = '/dev/disk/by-label/testrootfs'
-        elif partition != self.config.data_part_android_org:
+        elif partition == self.config.sdcard_part_android_org:
+            partition = '/dev/disk/by-label/sdcard'
+        elif partition == self.config.data_part_android_org:
+            lbl = _android_data_label(runner)
+            partition = '/dev/disk/by-label/%s' % lbl
+        else:
             raise RuntimeError(
                 'unknown master image partition(%d)' % partition)
+        return partition
+
+    @contextlib.contextmanager
+    def file_system(self, partition, directory):
+        logging.info('attempting to access master filesystem %r:%s' %
+            (partition, directory))
 
         assert directory != '/', "cannot mount entire partition"
 
         with self._as_master() as runner:
-            if partition == self.config.data_part_android_org:
-                lbl = _android_data_label(runner)
-                partition = '/dev/disk/by-label/%s' % lbl
-
+            partition = self.get_partition(runner, partition)
             runner.run('mount %s /mnt' % partition)
             try:
                 targetdir = os.path.join('/mnt/%s' % directory)
@@ -253,7 +257,8 @@
 
                 parent_dir, target_name = os.path.split(targetdir)
 
-                runner.run('tar -czf /tmp/fs.tgz -C %s %s' % (parent_dir, target_name))
+                runner.run('tar -czf /tmp/fs.tgz -C %s %s' %
+                    (parent_dir, target_name))
                 runner.run('cd /tmp')  # need to be in same dir as fs.tgz
                 self.proc.sendline('python -m SimpleHTTPServer 0 2>/dev/null')
                 match_id = self.proc.expect([
@@ -292,6 +297,17 @@
                     self.proc.sendcontrol('c')  # kill SimpleHTTPServer
                     runner.run('umount /mnt')
 
+    def extract_tarball(self, tarball_url, partition, directory='/'):
+        logging.info('extracting %s to target' % tarball_url)
+
+        with self._as_master() as runner:
+            partition = self.get_partition(runner, partition)
+            runner.run('mount %s /mnt' % partition)
+            try:
+                self.target_extract(runner, tarball_url, '/mnt/%s' % directory)
+            finally:
+                runner.run('umount /mnt')
+
     def _connect_carefully(self, cmd):
         retry_count = 0
         retry_limit = 3
@@ -418,7 +434,8 @@
         # Looking for reboot messages or if they are missing, the U-Boot
         # message will also indicate the reboot is done.
         match_id = self.proc.expect(
-            [pexpect.TIMEOUT, 'Restarting system.', 'The system is going down for reboot NOW',
+            [pexpect.TIMEOUT, 'Restarting system.',
+             'The system is going down for reboot NOW',
              'Will now restart', 'U-Boot'], timeout=120)
         if match_id == 0:
             raise OperationFailed("Soft reboot failed")

=== modified file 'lava_dispatcher/device/qemu.py'
--- lava_dispatcher/device/qemu.py	2012-10-22 17:56:18 +0000
+++ lava_dispatcher/device/qemu.py	2012-11-09 20:25:51 +0000
@@ -35,6 +35,7 @@
     )
 from lava_dispatcher.utils import (
     ensure_directory,
+    extract_targz,
     logging_spawn,
     )
 
@@ -61,6 +62,13 @@
             ensure_directory(path)
             yield path
 
+    def extract_tarball(self, tarball_url, partition, directory='/'):
+        logging.info('extracting %s to target' % tarball_url)
+
+        with image_partition_mounted(self._sd_image, partition) as mntdir:
+            tb = download_image(tarball_url, self.context, decompress=False)
+            extract_targz(tb, '%s/%s' % (mntdir, directory))
+
     def _power_off(self, proc):
         if proc is not None:
             proc.close()
@@ -80,7 +88,8 @@
 
     def get_device_version(self):
         try:
-            output = subprocess.check_output([self.context.config.default_qemu_binary, '--version'])
+            output = subprocess.check_output(
+                [self.context.config.default_qemu_binary, '--version'])
             matches = re.findall('[0-9]+\.[0-9a-z.+\-:~]+', output)
             return matches[-1]
         except subprocess.CalledProcessError:

=== modified file 'lava_dispatcher/device/target.py'
--- lava_dispatcher/device/target.py	2012-10-29 21:03:29 +0000
+++ lava_dispatcher/device/target.py	2012-11-09 20:25:51 +0000
@@ -63,7 +63,6 @@
         'TESTER_PS1_INCLUDES_RC': True,
     }
 
-
     def __init__(self, context, device_config):
         self.context = context
         self.config = device_config
@@ -77,7 +76,8 @@
     @property
     def scratch_dir(self):
         if self._scratch_dir is None:
-            self._scratch_dir = utils.mkdtemp(self.context.config.lava_image_tmpdir)
+            self._scratch_dir = utils.mkdtemp(
+                self.context.config.lava_image_tmpdir)
         return self._scratch_dir
 
     def power_on(self):
@@ -130,6 +130,14 @@
         """
         raise NotImplementedError('file_system')
 
+    def extract_tarball(self, tarball_url, partition, directory='/'):
+        """ This is similar to the file_system API but is optimized for the
+        scenario when you just need explode a potentially large tarball on
+        the target device. The file_system API isn't really suitable for this
+        when thinking about an implementation like master.py
+        """
+        raise NotImplementedError('extract_tarball')
+
     @contextlib.contextmanager
     def runner(self):
         """ Powers on the target, returning a CommandRunner object and will
@@ -181,6 +189,7 @@
                 # just no upstart or dash assumptions
                 self._customize_oe(mnt)
 
+
 class SerialIO(file):
     def __init__(self, logfile):
         self.serialio = StringIO()

