From patchwork Fri Dec 7 15:03:12 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Milo Casagrande X-Patchwork-Id: 13417 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id DC6C423FC2 for ; Fri, 7 Dec 2012 15:03:16 +0000 (UTC) Received: from mail-ia0-f178.google.com (mail-ia0-f178.google.com [209.85.210.178]) by fiordland.canonical.com (Postfix) with ESMTP id 3A3BBA19868 for ; Fri, 7 Dec 2012 15:03:16 +0000 (UTC) Received: by mail-ia0-f178.google.com with SMTP id k25so778523iah.37 for ; Fri, 07 Dec 2012 07:03:15 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :content-type:mime-version:x-launchpad-project:x-launchpad-branch :x-launchpad-message-rationale:x-launchpad-branch-revision-number :x-launchpad-notification-type:to:from:subject:message-id:date :reply-to:sender:errors-to:precedence:x-generated-by :x-launchpad-hash:x-gm-message-state; bh=gq6rCFw6hm/KGpbrkg+q5fTWWtbVOewVuFb2ctZjGqY=; b=Qd6NdML2kpMpjAf+6kuipSc4JUY1qcXg3OmQvRgKjE60DS+m6lLn0iWrG4XFbfz9jc L4FfX2UFwYELBB0o/yIQRX5EmWMVvZsUPtEbl8YSj3k64UBJ8TiYzJCJA6qrmNfVbfUJ 7XjStnaWaNygUwBRivFmIpud2M4cBt5QzbPYEMZkCGCZUtR7RIO3geNkSg0IuQq+1vOU LJUzx0A5XyEqbR3Zfpx+NJ0rMG/y3C/u/iOCAalyQRMjW8fcHoQDRRzOZDJzK3+CIEnZ /Mwiu4rU9Xi+Cd/FWnjqqHAnkKPXTd5KjAjVnfMHPBF2nWI4nT437QuDUTW38wN7tyL8 f+SQ== Received: by 10.50.91.195 with SMTP id cg3mr9424102igb.57.1354892595602; Fri, 07 Dec 2012 07:03:15 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.67.148 with SMTP id n20csp479182igt; Fri, 7 Dec 2012 07:03:14 -0800 (PST) Received: by 10.180.87.225 with SMTP id bb1mr9080345wib.20.1354892594211; Fri, 07 Dec 2012 07:03:14 -0800 (PST) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id ht5si1938288wib.2.2012.12.07.07.03.13 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 07 Dec 2012 07:03:14 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) smtp.mail=bounces@canonical.com Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1TgzSK-0003QT-Oz for ; Fri, 07 Dec 2012 15:03:12 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id 9F0EBE04D5 for ; Fri, 7 Dec 2012 15:03:12 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: linaro-image-tools X-Launchpad-Branch: ~linaro-image-tools/linaro-image-tools/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 589 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~linaro-image-tools/linaro-image-tools/trunk] Rev 589: Hardwarepack handler refactoring. Message-Id: <20121207150312.25731.26478.launchpad@ackee.canonical.com> Date: Fri, 07 Dec 2012 15:03:12 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="16341"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: 570cfef7614bb26750d04b2570c01eb0aa6c274a X-Gm-Message-State: ALoCoQkqzpQx/sHVi+tYe/n/nWTmqpFt2JBmgNVMumsqr7VaRfrOqaY5n5y8Sgxlc4dq6KHMQwJs Merge authors: Milo Casagrande (milo) Related merge proposals: https://code.launchpad.net/~milo/linaro-image-tools/hwpack-handler/+merge/138225 proposed by: Milo Casagrande (milo) review: Approve - Данило Шеган (danilo) ------------------------------------------------------------ revno: 589 [merge] committer: Milo Casagrande branch nick: trunk timestamp: Fri 2012-12-07 15:56:08 +0100 message: Hardwarepack handler refactoring. added: linaro_image_tools/hwpack/handler.py modified: linaro_image_tools/hwpack/hwpack_fields.py linaro_image_tools/hwpack/hwpack_reader.py linaro_image_tools/media_create/boards.py linaro_image_tools/media_create/chroot_utils.py linaro_image_tools/media_create/tests/test_media_create.py --- lp:linaro-image-tools https://code.launchpad.net/~linaro-image-tools/linaro-image-tools/trunk You are subscribed to branch lp:linaro-image-tools. To unsubscribe from this branch go to https://code.launchpad.net/~linaro-image-tools/linaro-image-tools/trunk/+edit-subscription === added file 'linaro_image_tools/hwpack/handler.py' --- linaro_image_tools/hwpack/handler.py 1970-01-01 00:00:00 +0000 +++ linaro_image_tools/hwpack/handler.py 2012-12-07 09:37:42 +0000 @@ -0,0 +1,292 @@ +# Copyright (C) 2010, 2011, 2012 Linaro +# +# Author: Guilherme Salgado +# +# This file is part of Linaro Image Tools. +# +# Linaro Image Tools 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, either version 3 of the License, or +# (at your option) any later version. +# +# Linaro Image Tools 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 Linaro Image Tools. If not, see . + +from StringIO import StringIO +import ConfigParser +import logging +import os +import re +import shutil +import tarfile +import tempfile + +from linaro_image_tools.hwpack.config import Config +from linaro_image_tools.hwpack.builder import PackageUnpacker +from linaro_image_tools.utils import DEFAULT_LOGGER_NAME + + +logger = logging.getLogger(DEFAULT_LOGGER_NAME) + + +class HardwarepackHandler(object): + FORMAT_1 = '1.0' + FORMAT_2 = '2.0' + FORMAT_3 = '3.0' + FORMAT_MIXED = '1.0and2.0' + metadata_filename = 'metadata' + format_filename = 'FORMAT' + main_section = 'main' + hwpack_tarfiles = [] + tempdir = None + + def __init__(self, hwpacks, bootloader=None, board=None): + self.hwpacks = hwpacks + self.hwpack_tarfiles = [] + self.bootloader = bootloader + self.board = board + self.tempdirs = {} + # Used to store the config created from the metadata. + self.config = None + + class FakeSecHead(object): + """ Add a fake section header to the metadata file. + + This is done so we can use ConfigParser to parse the file. + """ + def __init__(self, fp): + self.fp = fp + self.sechead = '[%s]\n' % HardwarepackHandler.main_section + + def readline(self): + if self.sechead: + try: + return self.sechead + finally: + self.sechead = None + else: + return self.fp.readline() + + def __enter__(self): + self.tempdir = tempfile.mkdtemp() + for hwpack in self.hwpacks: + hwpack_tarfile = tarfile.open(hwpack, mode='r:gz') + self.hwpack_tarfiles.append(hwpack_tarfile) + return self + + def __exit__(self, type, value, traceback): + for hwpack_tarfile in self.hwpack_tarfiles: + if hwpack_tarfile is not None: + hwpack_tarfile.close() + self.hwpack_tarfiles = [] + if self.tempdir is not None and os.path.exists(self.tempdir): + shutil.rmtree(self.tempdir) + + for name in self.tempdirs: + tempdir = self.tempdirs[name] + if tempdir is not None and os.path.exists(tempdir): + shutil.rmtree(tempdir) + + def _get_config_from_metadata(self, metadata): + """ + Retrieves a Config object associated with the metadata. + + :param metadata: The metadata to parse. + :return: A Config instance. + """ + if not self.config: + lines = metadata.readlines() + if re.search("=", lines[0]) and not re.search(":", lines[0]): + # Probably V2 hardware pack without [hwpack] on the first line + lines = ["[hwpack]\n"] + lines + self.config = Config(StringIO("".join(lines))) + self.config.set_board(self.board) + self.config.set_bootloader(self.bootloader) + return self.config + + def get_field(self, field, return_keys=False): + data = None + hwpack_with_data = None + keys = None + for hwpack_tarfile in self.hwpack_tarfiles: + metadata = hwpack_tarfile.extractfile(self.metadata_filename) + parser = self._get_config_from_metadata(metadata) + try: + new_data = parser.get_option(field) + if new_data is not None: + assert data is None, "The metadata field '%s' is set to " \ + "'%s' and new value '%s' is found" % (field, data, + new_data) + data = new_data + hwpack_with_data = hwpack_tarfile + if return_keys: + keys = parser.get_last_used_keys() + except ConfigParser.NoOptionError: + continue + + if return_keys: + return data, hwpack_with_data, keys + return data, hwpack_with_data + + def get_format(self): + format = None + supported_formats = [self.FORMAT_1, self.FORMAT_2, self.FORMAT_3] + for hwpack_tarfile in self.hwpack_tarfiles: + format_file = hwpack_tarfile.extractfile(self.format_filename) + format_string = format_file.read().strip() + if not format_string in supported_formats: + raise AssertionError( + "Format version '%s' is not supported." % format_string) + if format is None: + format = format_string + elif format != format_string: + return self.FORMAT_MIXED + return format + + def get_file(self, file_alias): + """Get file(s) from a hwpack. + :param file_alias: Property name (not field name) which contains + file reference(s) + :return: path to a file or list of paths to files + """ + file_names, hwpack_tarfile, keys = self.get_field(file_alias, + return_keys=True) + if not file_names: + return file_names + single = False + if not isinstance(file_names, list): + single = True + file_names = [file_names] + out_files = [] + + # Depending on if board and/or bootloader were used to look up the + # file we are getting, we need to prepend those names to the path + # to get the correct extracted file from the hardware pack. + config_names = [("board", "boards"), ("bootloader", "bootloaders")] + base_path = "" + if keys: + # If keys is non-empty, we have a V3 config option that was + # modified by the bootloader and/or boot option... + for name, key in config_names: + if self.get_field(name): + value = self.get_field(name)[0] + if keys[0] == key: + base_path = os.path.join(base_path, value) + keys = keys[1:] + + for f in file_names: + # Check that the base path is needed. If the file doesn't exist, + # try without it (this provides fallback to V2 style directory + # layouts with a V3 config). + path_inc_board_and_bootloader = os.path.join(base_path, f) + if path_inc_board_and_bootloader in hwpack_tarfile.getnames(): + f = path_inc_board_and_bootloader + hwpack_tarfile.extract(f, self.tempdir) + f = os.path.join(self.tempdir, f) + out_files.append(f) + if single: + return out_files[0] + return out_files + + def list_packages(self): + """Return list of (package names, TarFile object containing them)""" + packages = [] + for tf in self.hwpack_tarfiles: + for name in tf.getnames(): + if name.startswith("pkgs/") and name.endswith(".deb"): + packages.append((tf, name)) + return packages + + def find_package_for(self, name, version=None, revision=None, + architecture=None): + """Find a package that matches the name, version, rev and arch given. + + Packages are named according to the debian specification: + http://www.debian.org/doc/manuals/debian-faq/ch-pkg_basics.en.html + _-_.deb + DebianRevisionNumber seems to be optional. + Use this spec to return a package matching the requirements given. + """ + for tar_file, package in self.list_packages(): + file_name = os.path.basename(package) + dpkg_chunks = re.search("^(.+)_(.+)_(.+)\.deb$", + file_name) + assert dpkg_chunks, "Could not split package file name into"\ + "__.deb" + + pkg_name = dpkg_chunks.group(1) + pkg_version = dpkg_chunks.group(2) + pkg_architecture = dpkg_chunks.group(3) + + ver_chunks = re.search("^(.+)-(.+)$", pkg_version) + if ver_chunks: + pkg_version = ver_chunks.group(1) + pkg_revision = ver_chunks.group(2) + else: + pkg_revision = None + + if name != pkg_name: + continue + if version != None and str(version) != pkg_version: + continue + if revision != None and str(revision) != pkg_revision: + continue + if (architecture != None and + str(architecture) != pkg_architecture): + continue + + # Got a matching package - return its path inside the tarball + return tar_file, package + + # Failed to find a matching package - return None + return None + + def get_file_from_package(self, file_path, package_name, + package_version=None, package_revision=None, + package_architecture=None): + """Extract named file from package specified by name, ver, rev, arch. + + File is extracted from the package matching the given specification + to a temporary directory. The absolute path to the extracted file is + returned. + """ + + package_info = self.find_package_for(package_name, + package_version, + package_revision, + package_architecture) + if package_info is None: + return None + tar_file, package = package_info + + # Avoid unpacking hardware pack more than once by assigning each one + # its own tempdir to unpack into. + # TODO: update logic that uses self.tempdir so we can get rid of this + # by sharing nicely. + if not package in self.tempdirs: + self.tempdirs[package] = tempfile.mkdtemp() + tempdir = self.tempdirs[package] + + # We extract everything in the hardware pack so we don't have to worry + # about chasing links (extract a link, find where it points to, extract + # that...). This is slower, but more reliable. + tar_file.extractall(tempdir) + package_path = os.path.join(tempdir, package) + + with PackageUnpacker() as self.package_unpacker: + extracted_file = self.package_unpacker.get_file(package_path, + file_path) + after_tmp = re.sub(self.package_unpacker.tempdir, "", + extracted_file).lstrip("/\\") + extract_dir = os.path.join(tempdir, "extracted", + os.path.dirname(after_tmp)) + os.makedirs(extract_dir) + shutil.move(extracted_file, extract_dir) + extracted_file = os.path.join(extract_dir, + os.path.basename(extracted_file)) + return extracted_file === modified file 'linaro_image_tools/hwpack/hwpack_fields.py' --- linaro_image_tools/hwpack/hwpack_fields.py 2012-10-02 14:53:56 +0000 +++ linaro_image_tools/hwpack/hwpack_fields.py 2012-12-07 09:37:42 +0000 @@ -86,10 +86,15 @@ METADATA_VERSION_FIELD = 'version' # The allowed partition layouts. +BOOTFS16 = 'bootfs16_rootfs' +BOOTFS = 'bootfs_rootfs' +RESERVED_BOOTFS = 'reserved_bootfs_rootfs' + DEFINED_PARTITION_LAYOUTS = [ - 'bootfs16_rootfs', - 'bootfs_rootfs', - 'reserved_bootfs_rootfs', ] + BOOTFS16, + BOOTFS, + RESERVED_BOOTFS, + ] # Supported bootloaders U_BOOT = 'u_boot' === modified file 'linaro_image_tools/hwpack/hwpack_reader.py' --- linaro_image_tools/hwpack/hwpack_reader.py 2012-07-25 13:05:16 +0000 +++ linaro_image_tools/hwpack/hwpack_reader.py 2012-12-05 13:01:06 +0000 @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with Linaro Image Tools. If not, see . -from linaro_image_tools.media_create.boards import HardwarepackHandler +from linaro_image_tools.hwpack.handler import HardwarepackHandler from linaro_image_tools.hwpack.hwpack_fields import ( FORMAT_FIELD, NAME_FIELD, === modified file 'linaro_image_tools/media_create/boards.py' --- linaro_image_tools/media_create/boards.py 2012-10-22 06:57:20 +0000 +++ linaro_image_tools/media_create/boards.py 2012-12-05 13:01:06 +0000 @@ -31,13 +31,8 @@ import tempfile import struct from binascii import crc32 -import tarfile -import ConfigParser -import shutil import string import logging -from linaro_image_tools.hwpack.config import Config -from linaro_image_tools.hwpack.builder import PackageUnpacker from parted import Device @@ -45,7 +40,8 @@ from linaro_image_tools.media_create.partitions import ( partition_mounted, SECTOR_SIZE, register_loopback) -from StringIO import StringIO + +from linaro_image_tools.hwpack.handler import HardwarepackHandler logger = logging.getLogger(__name__) @@ -115,264 +111,6 @@ return self.getter(cls) -class HardwarepackHandler(object): - FORMAT_1 = '1.0' - FORMAT_2 = '2.0' - FORMAT_3 = '3.0' - FORMAT_MIXED = '1.0and2.0' - metadata_filename = 'metadata' - format_filename = 'FORMAT' - main_section = 'main' - hwpack_tarfiles = [] - tempdir = None - - def __init__(self, hwpacks, bootloader=None, board=None): - self.hwpacks = hwpacks - self.hwpack_tarfiles = [] - self.bootloader = bootloader - self.board = board - self.tempdirs = {} - # Used to store the config created from the metadata. - self.config = None - - class FakeSecHead(object): - """ Add a fake section header to the metadata file. - - This is done so we can use ConfigParser to parse the file. - """ - def __init__(self, fp): - self.fp = fp - self.sechead = '[%s]\n' % HardwarepackHandler.main_section - - def readline(self): - if self.sechead: - try: - return self.sechead - finally: - self.sechead = None - else: - return self.fp.readline() - - def __enter__(self): - self.tempdir = tempfile.mkdtemp() - for hwpack in self.hwpacks: - hwpack_tarfile = tarfile.open(hwpack, mode='r:gz') - self.hwpack_tarfiles.append(hwpack_tarfile) - return self - - def __exit__(self, type, value, traceback): - for hwpack_tarfile in self.hwpack_tarfiles: - if hwpack_tarfile is not None: - hwpack_tarfile.close() - self.hwpack_tarfiles = [] - if self.tempdir is not None and os.path.exists(self.tempdir): - shutil.rmtree(self.tempdir) - - for name in self.tempdirs: - tempdir = self.tempdirs[name] - if tempdir is not None and os.path.exists(tempdir): - shutil.rmtree(tempdir) - - def _get_config_from_metadata(self, metadata): - """ - Retrieves a Config object associated with the metadata. - - :param metadata: The metadata to parse. - :return: A Config instance. - """ - if not self.config: - lines = metadata.readlines() - if re.search("=", lines[0]) and not re.search(":", lines[0]): - # Probably V2 hardware pack without [hwpack] on the first line - lines = ["[hwpack]\n"] + lines - self.config = Config(StringIO("".join(lines))) - self.config.set_board(self.board) - self.config.set_bootloader(self.bootloader) - return self.config - - def get_field(self, field, return_keys=False): - data = None - hwpack_with_data = None - keys = None - for hwpack_tarfile in self.hwpack_tarfiles: - metadata = hwpack_tarfile.extractfile(self.metadata_filename) - parser = self._get_config_from_metadata(metadata) - try: - new_data = parser.get_option(field) - if new_data is not None: - assert data is None, "The metadata field '%s' is set to " \ - "'%s' and new value '%s' is found" % (field, data, - new_data) - data = new_data - hwpack_with_data = hwpack_tarfile - if return_keys: - keys = parser.get_last_used_keys() - except ConfigParser.NoOptionError: - continue - - if return_keys: - return data, hwpack_with_data, keys - return data, hwpack_with_data - - def get_format(self): - format = None - supported_formats = [self.FORMAT_1, self.FORMAT_2, self.FORMAT_3] - for hwpack_tarfile in self.hwpack_tarfiles: - format_file = hwpack_tarfile.extractfile(self.format_filename) - format_string = format_file.read().strip() - if not format_string in supported_formats: - raise AssertionError( - "Format version '%s' is not supported." % format_string) - if format is None: - format = format_string - elif format != format_string: - return self.FORMAT_MIXED - return format - - def get_file(self, file_alias): - """Get file(s) from a hwpack. - :param file_alias: Property name (not field name) which contains - file reference(s) - :return: path to a file or list of paths to files - """ - file_names, hwpack_tarfile, keys = self.get_field(file_alias, - return_keys=True) - if not file_names: - return file_names - single = False - if not isinstance(file_names, list): - single = True - file_names = [file_names] - out_files = [] - - # Depending on if board and/or bootloader were used to look up the - # file we are getting, we need to prepend those names to the path - # to get the correct extracted file from the hardware pack. - config_names = [("board", "boards"), ("bootloader", "bootloaders")] - base_path = "" - if keys: - # If keys is non-empty, we have a V3 config option that was - # modified by the bootloader and/or boot option... - for name, key in config_names: - if self.get_field(name): - value = self.get_field(name)[0] - if keys[0] == key: - base_path = os.path.join(base_path, value) - keys = keys[1:] - - for f in file_names: - # Check that the base path is needed. If the file doesn't exist, - # try without it (this provides fallback to V2 style directory - # layouts with a V3 config). - path_inc_board_and_bootloader = os.path.join(base_path, f) - if path_inc_board_and_bootloader in hwpack_tarfile.getnames(): - f = path_inc_board_and_bootloader - hwpack_tarfile.extract(f, self.tempdir) - f = os.path.join(self.tempdir, f) - out_files.append(f) - if single: - return out_files[0] - return out_files - - def list_packages(self): - """Return list of (package names, TarFile object containing them)""" - packages = [] - for tf in self.hwpack_tarfiles: - for name in tf.getnames(): - if name.startswith("pkgs/") and name.endswith(".deb"): - packages.append((tf, name)) - return packages - - def find_package_for(self, name, version=None, revision=None, - architecture=None): - """Find a package that matches the name, version, rev and arch given. - - Packages are named according to the debian specification: - http://www.debian.org/doc/manuals/debian-faq/ch-pkg_basics.en.html - _-_.deb - DebianRevisionNumber seems to be optional. - Use this spec to return a package matching the requirements given. - """ - for tar_file, package in self.list_packages(): - file_name = os.path.basename(package) - dpkg_chunks = re.search("^(.+)_(.+)_(.+)\.deb$", - file_name) - assert dpkg_chunks, "Could not split package file name into"\ - "__.deb" - - pkg_name = dpkg_chunks.group(1) - pkg_version = dpkg_chunks.group(2) - pkg_architecture = dpkg_chunks.group(3) - - ver_chunks = re.search("^(.+)-(.+)$", pkg_version) - if ver_chunks: - pkg_version = ver_chunks.group(1) - pkg_revision = ver_chunks.group(2) - else: - pkg_revision = None - - if name != pkg_name: - continue - if version != None and str(version) != pkg_version: - continue - if revision != None and str(revision) != pkg_revision: - continue - if (architecture != None and - str(architecture) != pkg_architecture): - continue - - # Got a matching package - return its path inside the tarball - return tar_file, package - - # Failed to find a matching package - return None - return None - - def get_file_from_package(self, file_path, package_name, - package_version=None, package_revision=None, - package_architecture=None): - """Extract named file from package specified by name, ver, rev, arch. - - File is extracted from the package matching the given specification - to a temporary directory. The absolute path to the extracted file is - returned. - """ - - package_info = self.find_package_for(package_name, - package_version, - package_revision, - package_architecture) - if package_info is None: - return None - tar_file, package = package_info - - # Avoid unpacking hardware pack more than once by assigning each one - # its own tempdir to unpack into. - # TODO: update logic that uses self.tempdir so we can get rid of this - # by sharing nicely. - if not package in self.tempdirs: - self.tempdirs[package] = tempfile.mkdtemp() - tempdir = self.tempdirs[package] - - # We extract everything in the hardware pack so we don't have to worry - # about chasing links (extract a link, find where it points to, extract - # that...). This is slower, but more reliable. - tar_file.extractall(tempdir) - package_path = os.path.join(tempdir, package) - - with PackageUnpacker() as self.package_unpacker: - extracted_file = self.package_unpacker.get_file(package_path, - file_path) - after_tmp = re.sub(self.package_unpacker.tempdir, "", - extracted_file).lstrip("/\\") - extract_dir = os.path.join(tempdir, "extracted", - os.path.dirname(after_tmp)) - os.makedirs(extract_dir) - shutil.move(extracted_file, extract_dir) - extracted_file = os.path.join(extract_dir, - os.path.basename(extracted_file)) - return extracted_file - - class BoardConfig(object): board = None """The configuration used when building an image for a board.""" === modified file 'linaro_image_tools/media_create/chroot_utils.py' --- linaro_image_tools/media_create/chroot_utils.py 2012-10-04 09:12:57 +0000 +++ linaro_image_tools/media_create/chroot_utils.py 2012-12-05 13:01:06 +0000 @@ -25,7 +25,7 @@ is_arm_host, find_command, ) -from linaro_image_tools.media_create.boards import HardwarepackHandler +from linaro_image_tools.hwpack.handler import HardwarepackHandler # It'd be nice if we could use atexit here, but all the things we need to undo # have to happen right after install_hwpacks completes and the atexit === modified file 'linaro_image_tools/media_create/tests/test_media_create.py' --- linaro_image_tools/media_create/tests/test_media_create.py 2012-10-17 08:59:25 +0000 +++ linaro_image_tools/media_create/tests/test_media_create.py 2012-12-05 13:01:06 +0000 @@ -36,6 +36,7 @@ from testtools import TestCase from linaro_image_tools import cmd_runner +from linaro_image_tools.hwpack.handler import HardwarepackHandler from linaro_image_tools.hwpack.packages import PackageMaker import linaro_image_tools.media_create from linaro_image_tools.media_create import ( @@ -61,7 +62,6 @@ _get_file_matching, _get_mlo_file, _run_mkimage, - HardwarepackHandler, BoardConfig, ) from linaro_image_tools.media_create.android_boards import (