From patchwork Wed Jul 25 13:16:12 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milo Casagrande X-Patchwork-Id: 10232 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 9A13D23E02 for ; Wed, 25 Jul 2012 13:16:16 +0000 (UTC) Received: from mail-gh0-f180.google.com (mail-gh0-f180.google.com [209.85.160.180]) by fiordland.canonical.com (Postfix) with ESMTP id 1CA0CA18C7D for ; Wed, 25 Jul 2012 13:16:16 +0000 (UTC) Received: by ghbz12 with SMTP id z12so676858ghb.11 for ; Wed, 25 Jul 2012 06:16:15 -0700 (PDT) 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=noozxecsFleolznrygeWmBPVqd+iKaBzbiX0d9Xpk8I=; b=cTsqRA9028kvvpL6kIXYUX74A/2Y2pN4/9M34pVrstCKDGp0EjAXFqK4ujdRQpysIZ dDT9PmCZYeOa7aWG8XGqszmkZ525lWkIA+laFK7lESOBTB4pdhW9WaOnGfpSAPvwG2fq z+KY7zk06I1bkTjaQN6QRl9ywwE1AleUes7AD/REYgCUxCuwpQ/UkZ+kp2nJ3WdgR91U a1PBiDwbneSitADfKhFxCzQ3aU7OfntBPB+3D7hzUfic9uSQJn8GtYIWP/6ODPqW1PhJ FWy+zPZWTI6tcwq0QeJ4rjoqzIt6VzrDaOzVTgvZpkEeWkO2FXrdbKR82sLoehSKccDp DFLQ== Received: by 10.42.54.133 with SMTP id r5mr20133511icg.9.1343222175535; Wed, 25 Jul 2012 06:16:15 -0700 (PDT) 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.231.153.7 with SMTP id i7csp90784ibw; Wed, 25 Jul 2012 06:16:14 -0700 (PDT) Received: by 10.180.84.164 with SMTP id a4mr4584557wiz.12.1343222173104; Wed, 25 Jul 2012 06:16:13 -0700 (PDT) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id di4si3311076wib.26.2012.07.25.06.16.12 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 25 Jul 2012 06:16:13 -0700 (PDT) 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 1Su1Rk-0002Wc-D6 for ; Wed, 25 Jul 2012 13:16:12 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id 52F53E002D for ; Wed, 25 Jul 2012 13:16: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: 541 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~linaro-image-tools/linaro-image-tools/trunk] Rev 541: Merged lp:~milo/linaro-image-tools/hwpack-read. Message-Id: <20120725131612.30623.50356.launchpad@ackee.canonical.com> Date: Wed, 25 Jul 2012 13:16: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="15679"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: df480f1487c9b237467db4142f3c72237a7fa152 X-Gm-Message-State: ALoCoQlyo7KuvFJUJKUj8dExFHcgx13GEJ5Ju2sCDoCNbBMEHBZxJBBE0uzEF3PrATid1RUdz6KZ Merge authors: Milo Casagrande (milo) Related merge proposals: https://code.launchpad.net/~milo/linaro-image-tools/hwpack-read/+merge/116606 proposed by: Milo Casagrande (milo) review: Approve - James Tunnicliffe (dooferlad) ------------------------------------------------------------ revno: 541 [merge] committer: Milo Casagrande branch nick: trunk timestamp: Wed 2012-07-25 15:15:21 +0200 message: Merged lp:~milo/linaro-image-tools/hwpack-read. added: linaro_image_tools/hwpack/hwpack_reader.py linaro_image_tools/hwpack/tests/test_hwpack_reader.py modified: linaro-media-create linaro_image_tools/hwpack/tests/__init__.py linaro_image_tools/media_create/__init__.py linaro_image_tools/utils.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 === modified file 'linaro-media-create' --- linaro-media-create 2012-04-19 01:12:10 +0000 +++ linaro-media-create 2012-07-25 11:48:47 +0000 @@ -33,6 +33,10 @@ install_hwpacks, install_packages, ) +from linaro_image_tools.hwpack.hwpack_reader import ( + HwpackReader, + HwpackReaderError, + ) from linaro_image_tools.media_create.partitions import ( Media, setup_partitions, @@ -44,13 +48,15 @@ ) from linaro_image_tools.media_create import get_args_parser from linaro_image_tools.utils import ( + additional_option_checks, + check_file_integrity_and_log_errors, + check_required_args, ensure_command, + IncompatibleOptions, is_arm_host, - check_file_integrity_and_log_errors, + MissingRequiredOption, path_in_tarfile_exists, - IncompatibleOptions, prep_media_path, - additional_option_checks, ) # Just define the global variables @@ -107,6 +113,22 @@ print >> sys.stderr, "\nError:", e.value sys.exit(1) + if args.readhwpack: + try: + reader = HwpackReader(args.hwpacks) + print reader.get_supported_boards() + sys.exit(0) + except HwpackReaderError as e: + print >> sys.stderr, "\nError:", e.value + sys.exit(1) + + try: + check_required_args(args) + except MissingRequiredOption as e: + parser.print_help() + print >> sys.stderr, "\nError:", e.value + sys.exit(1) + board_config = board_configs[args.board] board_config.set_metadata(args.hwpacks) board_config.set_board(args.board) @@ -117,11 +139,12 @@ if media.is_block_device: if not board_config.supports_writing_to_mmc: - print "The board '%s' does not support the --mmc option. Please use "\ - "--image_file to create an image file for this board." % args.board + print ("The board '%s' does not support the --mmc option. " + "Please use --image_file to create an image file for this " + "board." % args.board) sys.exit(1) - if not confirm_device_selection_and_ensure_it_is_ready(args.device, - args.nocheck_mmc): + if not confirm_device_selection_and_ensure_it_is_ready( + args.device, args.nocheck_mmc): sys.exit(1) elif not args.should_format_rootfs or not args.should_format_bootfs: print ("Do not use --no-boot or --no-part in conjunction with " === added file 'linaro_image_tools/hwpack/hwpack_reader.py' --- linaro_image_tools/hwpack/hwpack_reader.py 1970-01-01 00:00:00 +0000 +++ linaro_image_tools/hwpack/hwpack_reader.py 2012-07-25 13:05:16 +0000 @@ -0,0 +1,192 @@ +# Copyright (C) 2012 Linaro +# +# Author: Milo Casagrande +# +# 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 linaro_image_tools.media_create.boards import HardwarepackHandler +from linaro_image_tools.hwpack.hwpack_fields import ( + FORMAT_FIELD, + NAME_FIELD, + BOARDS_FIELD, + BOOTLOADERS_FIELD, +) + +from os import linesep as LINE_SEP + +# Fields necessary for the string representation of the hardware pack supported +# boards and bootlaoders. +HALF_SEPARATOR = '+--------------------------------------' +ENDING = '+' +SEPARATOR = HALF_SEPARATOR * 2 + ENDING +FORMAT = '{:<80}' +CENTER_ALIGN = '{:^80}' +ELEMENT_FORMAT = '{:<39}| {:<39}' + + +class HwpackReaderError(Exception): + """General error raised by HwpackReader.""" + def __init__(self, value): + self.value = value + + def __str__(self): + return repr(self.value) + + +class Hwpack(object): + """A simple representation of an hardware pack and its value.""" + def __init__(self): + self._hwpack = None + self._boards = None + self._bootloaders = None + self._name = None + + @property + def hwpack(self): + """The hardware pack it refers to.""" + return self._hwpack + + def sethwpack(self, value): + """Sets the hwpack field.""" + self._hwpack = value + + @property + def boards(self): + """The boards field of this hardware pack.""" + return self._boards + + def setboards(self, value): + """Sets the boards field.""" + self._boards = value + + @property + def name(self): + """The name field of this hardware pack.""" + return self._name + + def setname(self, value): + """Sets the name field.""" + self._name = value + + @property + def bootloaders(self): + """The bootlaoders field of this hardware pack.""" + return self._bootloaders + + def setbootloaders(self, value): + """Sets the bootlaoders field.""" + self._bootloaders = value + + def __eq__(self, other): + """Equality method.""" + equal = False + if isinstance(other, Hwpack): + equal = (self.name == other.name and + self.boards == other.boards and + self.hwpack == other.hwpack and + self.bootloaders == other.bootloaders) + return equal + + def __hash__(self): + return hash(frozenset(self.bootloaders), frozenset(self.boards), + self.name, self.hwpack) + + def __str__(self): + """String representation of this hwapack supported elements.""" + string = FORMAT.format("Read hardware pack: %s" % self.hwpack) + string += LINE_SEP + string += FORMAT.format(SEPARATOR) + string += LINE_SEP + string += ELEMENT_FORMAT.format("Supported boards", + "Supported bootloaders") + string += LINE_SEP + string += FORMAT.format(SEPARATOR) + string += LINE_SEP + + if self.boards: + for key, value in self.boards.iteritems(): + if value.get(BOOTLOADERS_FIELD, None) is not None: + bootloaders = value.get(BOOTLOADERS_FIELD) + supported_bootloaders = bootloaders.keys() + else: + supported_bootloaders = self.bootloaders.keys() + string += ELEMENT_FORMAT.format(key, + ",".join(supported_bootloaders)) + string += LINE_SEP + else: + # If we pass a converted file with just a single board, we do not + # have the boards section, and we default to the name of the hwpack + if self.bootloaders: + supported_bootloaders = self.bootloaders.keys() + string += ELEMENT_FORMAT.format(self.name, + ",".join(supported_bootloaders)) + string += LINE_SEP + else: + string += CENTER_ALIGN.format("No supported boards and " + "bootloaders") + string += LINE_SEP + string += FORMAT.format(SEPARATOR) + return string + LINE_SEP + + +class HwpackReader(object): + """Reads the information contained in a hwpack """ + def __init__(self, hwpacks): + """Create a new instance. + + :param hwpacks: The list of hardware packs to read from.""" + self.hwpacks = hwpacks + # Where we store all the info from the hwpack. + self._supported_elements = [] + + @property + def supported_elements(self): + """Gets the supported elements of by all the hardwapare packs.""" + return self._supported_elements + + def _read_hwpacks_metadata(self): + """Reads the hardware pack metadata file, and prints information about + the supported boards and bootloaders.""" + for tarball in self.hwpacks: + with HardwarepackHandler([tarball]) as handler: + hwpack_format = handler.get_field(FORMAT_FIELD)[0] + if hwpack_format.format_as_string == "3.0": + local_hwpack = Hwpack() + local_hwpack.sethwpack(tarball) + local_hwpack.setname(handler.get_field(NAME_FIELD)[0]) + local_hwpack.setboards(handler.get_field(BOARDS_FIELD)[0]) + local_hwpack.setbootloaders( + handler.get_field(BOOTLOADERS_FIELD)[0]) + self.supported_elements.append(local_hwpack) + else: + raise HwpackReaderError("Hardwarepack '%s' cannot be " + "read, unsupported format." % + (tarball)) + + def get_supported_boards(self): + """Prints the necessary information. + + :return A string representation of the information.""" + self._read_hwpacks_metadata() + return str(self) + + def __str__(self): + """The string representation of this reader. It is a printable + representation of the necessary information.""" + hwpack_reader = "" + for element in self.supported_elements: + hwpack_reader += str(element) + return hwpack_reader === modified file 'linaro_image_tools/hwpack/tests/__init__.py' --- linaro_image_tools/hwpack/tests/__init__.py 2012-07-19 17:57:24 +0000 +++ linaro_image_tools/hwpack/tests/__init__.py 2012-07-25 09:00:58 +0000 @@ -30,6 +30,7 @@ 'linaro_image_tools.hwpack.tests.test_config_v3', 'linaro_image_tools.hwpack.tests.test_hardwarepack', 'linaro_image_tools.hwpack.tests.test_hwpack_converter', + 'linaro_image_tools.hwpack.tests.test_hwpack_reader', 'linaro_image_tools.hwpack.tests.test_packages', 'linaro_image_tools.hwpack.tests.test_script', 'linaro_image_tools.hwpack.tests.test_tarfile_matchers', === added file 'linaro_image_tools/hwpack/tests/test_hwpack_reader.py' --- linaro_image_tools/hwpack/tests/test_hwpack_reader.py 1970-01-01 00:00:00 +0000 +++ linaro_image_tools/hwpack/tests/test_hwpack_reader.py 2012-07-25 13:05:16 +0000 @@ -0,0 +1,114 @@ +# Copyright (C) 2012 Linaro +# +# Author: Milo Casagrande +# +# 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 . + +import tarfile +from StringIO import StringIO +from linaro_image_tools.testing import TestCaseWithFixtures +from linaro_image_tools.tests.fixtures import ( + CreateTempDirFixture, + ) + +from linaro_image_tools.media_create.tests.fixtures import ( + CreateTarballFixture, + ) + +from linaro_image_tools.hwpack.hwpack_reader import ( + Hwpack, + HwpackReader, + HwpackReaderError, + ) + + +class HwpackReaderTests(TestCaseWithFixtures): + """Test class for the hwpack reader.""" + + def setUp(self): + super(HwpackReaderTests, self).setUp() + self.metadata = ("format: 3.0\nversion: '1'\nname: test-hwpack\n" + "architecture: armel\norigin: Linaro") + self.hwpack = Hwpack() + self.hwpack.setname('test-hwpack') + self.tar_dir_fixture = CreateTempDirFixture() + self.useFixture(self.tar_dir_fixture) + self.tarball_fixture = CreateTarballFixture( + self.tar_dir_fixture.get_temp_dir()) + self.useFixture(self.tarball_fixture) + + def tearDown(self): + super(HwpackReaderTests, self).tearDown() + self.hwpack = None + self.metadata = "" + + def add_to_tarball(self, files, tarball=None): + if tarball is None: + tarball = self.tarball_fixture.get_tarball() + tar_file = tarfile.open(tarball, mode='w:gz') + for filename, data in files: + tarinfo = tarfile.TarInfo(filename) + tarinfo.size = len(data) + tar_file.addfile(tarinfo, StringIO(data)) + tar_file.close() + return tarball + + def test_hwpack_class(self): + hwpack = Hwpack() + hwpack.setname('test-hwpack') + hwpack.sethwpack('a_hwpack') + self.hwpack.sethwpack('a_hwpack') + self.assertEqual(self.hwpack, hwpack) + + def test_hwpack_class_not_equal(self): + hwpack = Hwpack() + hwpack.setname('test-hwpack') + hwpack.sethwpack('a_hwpack') + self.hwpack.sethwpack('b_hwpack') + self.assertNotEqual(self.hwpack, hwpack) + + def test_hwpack_metadata_read(self): + tarball = self.add_to_tarball([('metadata', self.metadata)]) + reader = HwpackReader([tarball]) + reader._read_hwpacks_metadata() + self.hwpack.sethwpack(tarball) + self.assertEqual(self.hwpack, reader.supported_elements[0]) + + def test_raise_exception(self): + new_metadata = ("format=2.0\nversion=4") + tarball = self.add_to_tarball([('metadata', new_metadata)]) + reader = HwpackReader([tarball]) + self.assertRaises(HwpackReaderError, reader._read_hwpacks_metadata) + + def test_hwpack_metadata_read_with_boards(self): + self.metadata += "\nboards:\n panda:\n support: supported\n" + tarball = self.add_to_tarball([('metadata', self.metadata)]) + reader = HwpackReader([tarball]) + reader._read_hwpacks_metadata() + self.hwpack.sethwpack(tarball) + self.hwpack.setboards({'panda': {'support': 'supported'}}) + self.assertEqual(self.hwpack, reader.supported_elements[0]) + + def test_hwpack_metadata_read_with_bootloaders(self): + self.metadata += ("\nboards:\n panda:\n support: supported\n " + "bootloaders:\n u_boot:\n file: a_file\n") + tarball = self.add_to_tarball([('metadata', self.metadata)]) + reader = HwpackReader([tarball]) + reader._read_hwpacks_metadata() + self.hwpack.sethwpack(tarball) + self.hwpack.setboards({'panda': {'support': 'supported', 'bootloaders': + {'u_boot': {'file': 'a_file'}}}}) + self.assertEqual(self.hwpack, reader.supported_elements[0]) === modified file 'linaro_image_tools/media_create/__init__.py' --- linaro_image_tools/media_create/__init__.py 2012-06-13 14:43:59 +0000 +++ linaro_image_tools/media_create/__init__.py 2012-07-25 11:36:00 +0000 @@ -92,7 +92,11 @@ '--output-directory', dest='directory', help='Directory where image and accessories should be written to.') parser.add_argument( - '--dev', required=True, dest='board', choices=KNOWN_BOARDS, + '--read-hwpack', dest='readhwpack', action='store_true', + help=('Read the hardware pack and print information about the ' + 'supported boards and bootloaders.')) + parser.add_argument( + '--dev', dest='board', choices=KNOWN_BOARDS, help='Generate an SD card or image for the given board.') parser.add_argument( '--rootfs', default='ext4', choices=['ext2', 'ext3', 'ext4', 'btrfs'], @@ -137,7 +141,7 @@ help=('The image size, specified in mega/giga bytes (e.g. 3000M or ' '3G); use with --image_file only')) parser.add_argument( - '--binary', default='binary-tar.tar.gz', required=True, + '--binary', default='binary-tar.tar.gz', required=False, help=('The tarball containing the rootfs used to create the bootable ' 'system.')) parser.add_argument( === modified file 'linaro_image_tools/utils.py' --- linaro_image_tools/utils.py 2012-06-13 14:55:34 +0000 +++ linaro_image_tools/utils.py 2012-07-25 11:39:20 +0000 @@ -306,6 +306,15 @@ """The hwpack parameter is not a regular file.""" +class MissingRequiredOption(Exception): + """A required option from the command line is missing.""" + def __init__(self, value): + self.value = value + + def __str__(self): + return repr(self.value) + + class IncompatibleOptions(Exception): def __init__(self, value): self.value = value @@ -331,3 +340,11 @@ if not os.path.isfile(hwpack): raise InvalidHwpackFile( "--hwpack argument (%s) is not a regular file" % hwpack) + + +def check_required_args(args): + """Check that the required args are passed.""" + if args.board is None: + raise MissingRequiredOption("--dev option is required") + if args.binary is None: + raise MissingRequiredOption("--binary option is required")