From patchwork Mon Jul 23 15:44:11 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Milo Casagrande X-Patchwork-Id: 10175 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 490BF23E56 for ; Mon, 23 Jul 2012 15:44:17 +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 A95B0A182A1 for ; Mon, 23 Jul 2012 15:44:16 +0000 (UTC) Received: by ghbz12 with SMTP id z12so5926165ghb.11 for ; Mon, 23 Jul 2012 08:44:16 -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=OzllbEFmH3G1KZuaSvb/QNfHsVrRvOkbOMJ2Xtmd2UM=; b=jFjS+NA5Wl47HIBL2cw3XkZ5+bDeJRvcp93N864b+uxzYHZH5qARCAlPKTGs1UG0sr Fp0qPWrHwA/Gb/zzXqGRhIYdMP2YS9/lAv92Vtc3ypUUa5vKUNaXAYQ/Y6FmKUbs36Y6 +iz/vPDJXVjgkXcAotpDcddV/0TJ7jqf3NCsZA9OgNyqiD5DfFcWiBeHuciJK4vzKzoa KPSz1/4B15k2uqN8GFG4iE2hynYJBk1sW1v/SezxHHBzyF03RWGCM6vKhk9VbEO01enT yqzMtkeEzBnp2tWp88nGR6K8cZUaDieYKS1ueyIWqGQRvyquP05udzEXSEwIHXMwmh90 mb6w== Received: by 10.50.15.202 with SMTP id z10mr10633510igc.67.1343058255908; Mon, 23 Jul 2012 08:44: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 i7csp57749ibw; Mon, 23 Jul 2012 08:44:13 -0700 (PDT) Received: by 10.180.81.133 with SMTP id a5mr31120252wiy.17.1343058252674; Mon, 23 Jul 2012 08:44:12 -0700 (PDT) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id u10si16603580wek.120.2012.07.23.08.44.12 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 23 Jul 2012 08:44:12 -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 1StKnr-0003gn-VG for ; Mon, 23 Jul 2012 15:44:11 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id DEE81E0040 for ; Mon, 23 Jul 2012 15:44:11 +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: 537 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~linaro-image-tools/linaro-image-tools/trunk] Rev 537: Merged lp:~milo/linaro-image-tools/multiple-boards-support, added new hwpack support. Message-Id: <20120723154411.6860.88353.launchpad@ackee.canonical.com> Date: Mon, 23 Jul 2012 15:44:11 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="15654"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: 41cc57b0da5312d60db9dd1067e4d70a28897b65 X-Gm-Message-State: ALoCoQkz2ixYhUh+NsKzf3on9D4QDpw7GTrLe4d4BOUkrADh+q1LN7OjmHrixEVLOVN2bvFUoZD5 Merge authors: James Tunnicliffe (dooferlad) Milo Casagrande (milo) Related merge proposals: https://code.launchpad.net/~milo/linaro-image-tools/multiple-boards-support/+merge/115991 proposed by: Milo Casagrande (milo) review: Needs Fixing - Данило Шеган (danilo) ------------------------------------------------------------ revno: 537 [merge] committer: Milo Casagrande branch nick: trunk timestamp: Mon 2012-07-23 17:43:08 +0200 message: Merged lp:~milo/linaro-image-tools/multiple-boards-support, added new hwpack support. added: linaro_image_tools/hwpack/tests/test_config_v3.py modified: linaro-hwpack-install linaro_image_tools/hwpack/builder.py linaro_image_tools/hwpack/config.py linaro_image_tools/hwpack/hardwarepack.py linaro_image_tools/hwpack/hardwarepack_format.py linaro_image_tools/hwpack/hwpack_convert.py linaro_image_tools/hwpack/hwpack_fields.py linaro_image_tools/hwpack/tests/__init__.py linaro_image_tools/hwpack/tests/test_config.py linaro_image_tools/hwpack/tests/test_hardwarepack.py linaro_image_tools/hwpack/tests/test_hwpack_converter.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 === modified file 'linaro-hwpack-install' --- linaro-hwpack-install 2012-07-05 14:44:04 +0000 +++ linaro-hwpack-install 2012-07-23 15:28:30 +0000 @@ -41,7 +41,7 @@ FORCE_YES="no" SOURCES_LIST_FILE="${TEMP_DIR}/sources.list" APT_GET_OPTIONS="Dir::Etc::SourceList=${SOURCES_LIST_FILE}" -SUPPORTED_FORMATS="1.0 2.0" # A space-separated list of hwpack formats. +SUPPORTED_FORMATS="1.0 2.0 3.0" # A space-separated list of hwpack formats. sudo="sudo" if [ $(id -u) -eq 0 ]; then @@ -53,12 +53,15 @@ exit 1 } -usage_msg="Usage: $(basename $0) [--install-latest] [--force-yes] HWPACK_TARBALL" +usage_msg="Usage: $(basename $0) [--install-latest] [--force-yes] --hwpack-version --hwpack-arch --hwpack-name HWPACK_TARBALL" if [ $# -eq 0 ]; then die $usage_msg fi HWPACK_TARBALL_FOUND="no" +HWPACK_VERSION="" +HWPACK_ARCH="" +HWPACK_NAME="" while [ $# -gt 0 ]; do case "$1" in @@ -68,6 +71,18 @@ --force-yes) FORCE_YES="yes" shift;; + --hwpack-version) + HWPACK_VERSION=$2 + shift; + shift;; + --hwpack-arch) + HWPACK_ARCH=$2 + shift; + shift;; + --hwpack-name) + HWPACK_NAME=$2 + shift; + shift;; --*) die $usage_msg "\nUnrecognized option: \"$1\"";; *) @@ -79,6 +94,9 @@ done [ "$HWPACK_TARBALL_FOUND" = "no" ] && die $usage_msg +[ "$HWPACK_VERSION" = "" ] && die $usage_msg +[ "$HWPACK_ARCH" = "" ] && die $usage_msg +[ "$HWPACK_NAME" = "" ] && die $usage_msg # Try to acquire fd #9 (i.e. /var/lock/hwpack) for 2 seconds. # Using 9 as the file descriptor because of https://launchpad.net/bugs/249620 @@ -125,7 +143,6 @@ "Try using a newer version of $(basename $0)." # Check the architecture of the hwpack matches that of the host system. -HWPACK_ARCH=`grep ARCHITECTURE "${HWPACK_DIR}/metadata" | cut -d "=" -f2` [ "$HWPACK_ARCH" == `dpkg --print-architecture` ] || \ die "Hardware pack architecture ($HWPACK_ARCH) does not match the host's architecture" @@ -209,8 +226,6 @@ # For "older" hwpacks that don't have a dependency package, we just # manually install the contents of the hwpack. -HWPACK_NAME=`grep NAME "${HWPACK_DIR}/metadata" | cut -d "=" -f2` -HWPACK_VERSION=`grep VERSION "${HWPACK_DIR}/metadata" | cut -d "=" -f2` dependency_package="hwpack-${HWPACK_NAME}" if grep -q "^${dependency_package}=${HWPACK_VERSION}\$" "${HWPACK_DIR}"/manifest; then DEP_PACKAGE_PRESENT="yes" === modified file 'linaro_image_tools/hwpack/builder.py' --- linaro_image_tools/hwpack/builder.py 2012-06-13 14:53:32 +0000 +++ linaro_image_tools/hwpack/builder.py 2012-07-23 15:36:00 +0000 @@ -36,6 +36,13 @@ PackageFetcher, ) +from linaro_image_tools.hwpack.hwpack_fields import ( + PACKAGE_FIELD, + SPL_PACKAGE_FIELD, +) + +PACKAGE_FIELDS = [PACKAGE_FIELD, SPL_PACKAGE_FIELD] + logger = logging.getLogger(__name__) @@ -110,6 +117,22 @@ package.filepath, wanted_file) return hwpack.add_file(target_path, tempfile_name) + def find_bootloader_packages(self, bootloaders_config): + """Loop through the bootloaders dictionary searching for packages + that should be installed, based on known keywords. + + :param bootloaders_config: The bootloaders dictionary to loop through. + :return A list of packages, without duplicates.""" + boot_packages = [] + for key, value in bootloaders_config.iteritems(): + if isinstance(value, dict): + boot_packages.extend(self.find_bootloader_packages(value)) + else: + if key in PACKAGE_FIELDS: + boot_packages.append(value) + # Eliminate duplicates. + return list(set(boot_packages)) + def build(self): for architecture in self.config.architectures: logger.info("Building for %s" % architecture) @@ -121,10 +144,18 @@ hwpack.add_apt_sources(sources) sources = sources.values() packages = self.config.packages[:] - if self.config.u_boot_package is not None: - packages.append(self.config.u_boot_package) - if self.config.spl_package is not None: - packages.append(self.config.spl_package) + # Loop through multiple bootloaders. + # In V3 of hwpack configuration, all the bootloaders info and + # packages are in the bootloaders section. + if self.config.format.format_as_string == '3.0': + if self.config.bootloaders: + packages.extend(self.find_bootloader_packages( + self.config.bootloaders)) + else: + if self.config.u_boot_package is not None: + packages.append(self.config.u_boot_package) + if self.config.spl_package is not None: + packages.append(self.config.spl_package) local_packages = [ FetchedPackage.from_deb(deb) for deb in self.local_debs] === modified file 'linaro_image_tools/hwpack/config.py' --- linaro_image_tools/hwpack/config.py 2012-06-13 14:53:32 +0000 +++ linaro_image_tools/hwpack/config.py 2012-07-23 14:14:31 +0000 @@ -20,14 +20,68 @@ # USA. import ConfigParser +from operator import attrgetter import re import string +import yaml from linaro_image_tools.hwpack.hardwarepack_format import ( HardwarePackFormatV1, HardwarePackFormatV2, + HardwarePackFormatV3, ) +from hwpack_fields import ( + ARCHITECTURES_FIELD, + ARCHITECTURE_FIELD, + ASSUME_INSTALLED_FIELD, + BOARDS_FIELD, + BOOTLOADERS_FIELD, + BOOT_MIN_SIZE_FIELD, + BOOT_SCRIPT_FIELD, + DD_FIELD, + DTB_ADDR_FIELD, + DTB_FILE_FIELD, + ENV_DD_FIELD, + EXTRA_BOOT_OPTIONS_FIELD, + EXTRA_SERIAL_OPTIONS_FIELD, + FILE_FIELD, + FORMAT_FIELD, + INCLUDE_DEBS_FIELD, + IN_BOOT_PART_FIELD, + INITRD_ADDR_FIELD, + INITRD_FILE_FIELD, + KERNEL_ADDR_FIELD, + KERNEL_FILE_FIELD, + LOAD_ADDR_FIELD, + LOADER_MIN_SIZE_FIELD, + LOADER_START_FIELD, + MAINTAINER_FIELD, + MMC_ID_FIELD, + NAME_FIELD, + ORIGIN_FIELD, + PACKAGE_FIELD, + PACKAGES_FIELD, + PARTITION_LAYOUT_FIELD, + ROOT_MIN_SIZE_FIELD, + SAMSUNG_BL1_LEN_FIELD, + SAMSUNG_BL1_START_FIELD, + SAMSUNG_BL2_LEN_FIELD, + SAMSUNG_ENV_LEN_FIELD, + SERIAL_TTY_FIELD, + SNOWBALL_STARTUP_FILES_CONFIG_FIELD, + SOURCES_FIELD, + SPL_DD_FIELD, + SPL_FILE_FIELD, + SPL_IN_BOOT_PART_FIELD, + SPL_PACKAGE_FIELD, + SUPPORT_FIELD, + WIRED_INTERFACES_FIELD, + WIRELESS_INTERFACES_FIELD, + DEFINED_PARTITION_LAYOUTS, + VERSION_FIELD, +) + class HwpackConfigError(Exception): pass @@ -35,81 +89,101 @@ class Config(object): """Encapsulation of a hwpack-create configuration.""" + translate_v2_to_v3 = {} + translate_v2_metadata = {} MAIN_SECTION = "hwpack" - NAME_KEY = "name" NAME_REGEX = r"[a-z0-9][a-z0-9+\-.]+$" - INCLUDE_DEBS_KEY = "include-debs" - SUPPORT_KEY = "support" SOURCES_ENTRY_KEY = "sources-entry" - PACKAGES_KEY = "packages" PACKAGE_REGEX = NAME_REGEX PATH_REGEX = r"\w[\w+\-./_]+$" GLOB_REGEX = r"[\w+\-./_\*]+$" - ORIGIN_KEY = "origin" - MAINTAINER_KEY = "maintainer" - ARCHITECTURES_KEY = "architectures" + INCLUDE_DEBS_KEY = "include-debs" + translate_v2_to_v3[INCLUDE_DEBS_KEY] = INCLUDE_DEBS_FIELD + translate_v2_metadata[ARCHITECTURES_FIELD] = "ARCHITECTURE" ASSUME_INSTALLED_KEY = "assume-installed" + translate_v2_to_v3[ASSUME_INSTALLED_KEY] = ASSUME_INSTALLED_FIELD U_BOOT_PACKAGE_KEY = "u_boot_package" + translate_v2_to_v3[U_BOOT_PACKAGE_KEY] = PACKAGE_FIELD U_BOOT_FILE_KEY = "u_boot_file" + translate_v2_to_v3[U_BOOT_FILE_KEY] = FILE_FIELD + translate_v2_metadata[U_BOOT_FILE_KEY] = "U_BOOT" SPL_FILE_KEY = "spl_file" - SERIAL_TTY_KEY = "serial_tty" - KERNEL_ADDR_KEY = "kernel_addr" - INITRD_ADDR_KEY = "initrd_addr" - LOAD_ADDR_KEY = "load_addr" - DTB_ADDR_KEY = "dtb_addr" - WIRED_INTERFACES_KEY = "wired_interfaces" - WIRELESS_INTERFACES_KEY = "wireless_interfaces" - PARTITION_LAYOUT_KEY = "partition_layout" - MMC_ID_KEY = "mmc_id" - FORMAT_KEY = "format" - BOOT_MIN_SIZE_KEY = "boot_min_size" - ROOT_MIN_SIZE_KEY = "root_min_size" - LOADER_MIN_SIZE_KEY = "loader_min_size" - LOADER_START_KEY = "loader_start" - SPL_PACKAGE_KEY = "spl_package" - VMLINUZ_KEY = "kernel_file" - INITRD_KEY = "initrd_file" - DTB_FILE_KEY = "dtb_file" - EXTRA_BOOT_OPTIONS_KEY = 'extra_boot_options' - BOOT_SCRIPT_KEY = 'boot_script' + translate_v2_metadata[SPL_FILE_KEY] = "SPL" UBOOT_IN_BOOT_PART_KEY = 'u_boot_in_boot_part' + translate_v2_to_v3[UBOOT_IN_BOOT_PART_KEY] = IN_BOOT_PART_FIELD UBOOT_DD_KEY = 'u_boot_dd' - SPL_IN_BOOT_PART_KEY = 'spl_in_boot_part' - SPL_DD_KEY = 'spl_dd' - ENV_DD_KEY = 'env_dd' - EXTRA_SERIAL_OPTS_KEY = 'extra_serial_options' - SNOWBALL_STARTUP_FILES_CONFIG_KEY = 'snowball_startup_files_config' - SAMSUNG_BL1_START_KEY = 'samsung_bl1_start' - SAMSUNG_BL1_LEN_KEY = 'samsung_bl1_len' - SAMSUNG_ENV_LEN_KEY = 'samsung_env_len' - SAMSUNG_BL2_LEN_KEY = 'samsung_bl2_len' - - DEFINED_PARTITION_LAYOUTS = [ - 'bootfs16_rootfs', - 'bootfs_rootfs', - 'reserved_bootfs_rootfs', - ] - - def __init__(self, fp): + translate_v2_to_v3[UBOOT_DD_KEY] = DD_FIELD + + def __init__(self, fp, bootloader=None, board=None): """Create a Config. :param fp: a file-like object containing the configuration. """ + obfuscated_e = None + obfuscated_yaml_e = "" try: self.parser = ConfigParser.RawConfigParser() self.parser.readfp(fp) except ConfigParser.Error, e: obfuscated_e = re.sub(r"([^ ]https://).+?(@)", r"\1***\2", str(e)) - raise ConfigParser.Error(obfuscated_e) + + if obfuscated_e: + # obfuscated_e being set indicates that something went wrong. + # It could be that the input is in fact YAML. Try the YAML + # parser. + try: + fp.seek(0) + self.parser = yaml.safe_load(fp) + except yaml.YAMLError, e: + obfuscated_yaml_e = re.sub(r"([^ ]https://).+?(@)", + r"\1***\2", str(e)) + else: + # If YAML parsed OK, we don't have an error. + obfuscated_e = None + self.set_board(board) + self.set_bootloader(bootloader) + + if obfuscated_e: + # If INI parsing from ConfigParser or YAML parsing failed, + # print both error messages. + msg = ("Failed to parse hardware pack configuration. Tried to " + "parse as both INI and YAML. INI parsing error:\n" + + obfuscated_e + "\n" + + "YAML parser error:\n" + + obfuscated_yaml_e) + raise ConfigParser.Error(msg) + + def set_bootloader(self, bootloader): + """Set bootloader used to look up configuration in bootloader section. + + If bootloader is None / empty and there is only one bootloader + available, use that. + """ + if not bootloader: + # Auto-detect bootloader. If there is a single bootloader specified + # then use it, else, error. + bootloaders = self.bootloaders + if isinstance(bootloaders, dict): + # We have a list of bootloaders in the expected format + bootloaders = bootloaders.keys() + if len(bootloaders) == 1: + bootloader = bootloaders[0] + + self.bootloader = bootloader + + def set_board(self, board): + """Set board used to look up per-board configuration""" + self.board = board def validate(self): """Check that this configuration follows the schema. :raises HwpackConfigError: if it does not. """ - if not self.parser.has_section(self.MAIN_SECTION): - raise HwpackConfigError("No [%s] section" % self.MAIN_SECTION) + if isinstance(self.parser, ConfigParser.RawConfigParser): + if not self.parser.has_section(self.MAIN_SECTION): + raise HwpackConfigError("No [%s] section" % self.MAIN_SECTION) self._validate_format() self._validate_name() self._validate_include_debs() @@ -153,88 +227,229 @@ self._validate_samsung_env_len() self._validate_samsung_bl2_len() - self._validate_sections() + self._validate_sources() @property def format(self): """The format of the hardware pack. A subclass of HardwarePackFormat. """ - try: - format_string = self.parser.get(self.MAIN_SECTION, self.FORMAT_KEY) - except ConfigParser.NoOptionError: - # Default to 1.0 to aviod breaking existing hwpack files. - # When this code no longer supports 1.0, it effectively makes - # explicitly specifying format in hwpack files mandatory. - format_string = "1.0" + if isinstance(self.parser, ConfigParser.RawConfigParser): + try: + format_string = self.parser.get(self.MAIN_SECTION, + FORMAT_FIELD) + except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): + # Default to 1.0 to aviod breaking existing hwpack files. + # When this code no longer supports 1.0, it effectively makes + # explicitly specifying format in hwpack files mandatory. + format_string = "1.0" + else: + format_string = self.parser.get(FORMAT_FIELD) if format_string == '1.0': return HardwarePackFormatV1() elif format_string == '2.0': return HardwarePackFormatV2() + elif format_string == 3.0 or format_string == '3.0': + return HardwarePackFormatV3() else: - raise HwpackConfigError("Format version '%s' is not supported." % \ - format_string) + raise HwpackConfigError("Format version '%s' is not supported." % + format_string) @property def name(self): """The name of the hardware pack. A str.""" - return self.parser.get(self.MAIN_SECTION, self.NAME_KEY) + return self._get_option(NAME_FIELD) + + @property + def version(self): + return self._get_option(VERSION_FIELD) @property def include_debs(self): """Whether the hardware pack should contain .debs. A bool.""" try: - if not self.parser.get( - self.MAIN_SECTION, self.INCLUDE_DEBS_KEY): + if self._get_option(self.INCLUDE_DEBS_KEY) == None: return True - return self.parser.getboolean( - self.MAIN_SECTION, self.INCLUDE_DEBS_KEY) + try: + return self._get_option_bool(self.INCLUDE_DEBS_KEY) + except ValueError as e: + raise HwpackConfigError("Invalid value for include-debs: %s" % + e) except ConfigParser.NoOptionError: return True @property + def bootloaders(self): + """Bootloaders available in the hardware pack""" + return self._get_option(BOOTLOADERS_FIELD) + + @property def uboot_in_boot_part(self): """Whether uboot binary should be put in the boot partition. A str.""" - return self.parser.get(self.MAIN_SECTION, self.UBOOT_IN_BOOT_PART_KEY) + return self._get_bootloader_option(self.UBOOT_IN_BOOT_PART_KEY) @property def uboot_dd(self): """If the uboot binary should be dd:d to the boot partition this field specifies the offset. An int.""" - return self._get_option_from_main_section(self.UBOOT_DD_KEY) + return self._get_bootloader_option(self.UBOOT_DD_KEY) @property def spl_in_boot_part(self): """Whether spl binary should be put in the boot partition. A str.""" - return self._get_option_from_main_section(self.SPL_IN_BOOT_PART_KEY) + return self._get_bootloader_option(SPL_IN_BOOT_PART_FIELD) @property def spl_dd(self): """If the spl binary should be dd:d to the boot partition this field specifies the offset. An int.""" - return self._get_option_from_main_section(self.SPL_DD_KEY) + return self._get_bootloader_option(SPL_DD_FIELD) @property def env_dd(self): """If the env should be dd:d to the boot partition. 'Yes' or 'No'.""" - return self._get_option_from_main_section(self.ENV_DD_KEY) - - def _get_option_from_main_section(self, key): - """Get the value from the main section for the given key. + return self._get_bootloader_option(ENV_DD_FIELD) + + def _get_option_bool(self, key): + """Gets a boolean value from the key.""" + if self.format.format_as_string == '3.0': + value = self._get_option(key, convert_to="disable") + if isinstance(value, bool): + return value + else: + raise ValueError(value) + else: + try: + return self.parser.getboolean(self.MAIN_SECTION, key) + except ConfigParser.NoOptionError: + return None + + def _get_bootloader_option(self, key, join_list_with=False, + convert_to=None): + """Get an option inside the current bootloader section.""" + if self._is_v3: + if not self.bootloader: + raise ValueError("bootloader not set.") + if not isinstance(key, list): + keys = [key] + keys = [BOOTLOADERS_FIELD, self.bootloader] + keys + else: + keys = key + + return self._get_option(keys, join_list_with, convert_to) + + def _bool_to_string(self, value): + """Convert value, treated as boolean, to string "yes" or "no".""" + if value: + return "yes" + else: + return "no" + + def _hex_addrress(self, value): + """Convert value to 8 character hex string""" + converted_value = value + if not isinstance(value, str): + converted_value = "0x%08x" % value + return converted_value + + def _v2_key_to_v3(self, key): + """Convert V2 key to a V3 key""" + if key in self.translate_v2_to_v3: + key = self.translate_v2_to_v3[key] + return key + + def _get_v3_option(self, keys): + """Find value in config dictionary based on supplied list (keys).""" + result = self.parser + for key in keys: + key = self._v2_key_to_v3(key) + if result is not None: + result = result.get(key, None) + return result + + def get_option(self, name): + """Return the value of an attribute by name. + + Used when you can't use a property. + """ + return attrgetter(name)(self) + + def _get_option(self, key, join_list_with=False, convert_to=None): + """Return value for the given key. Precedence to board specific values. :param key: the key to return the value for. :type key: str. + :param join_list_with: Used to convert lists to strings. + :type join_list_with: str + :param convert_to: Used to convert stored value to another type. + :type convert_to: type or function. :return: the value for that key, or None if the key is not present or the value is empty. :rtype: str or None. """ - try: - result = self.parser.get(self.MAIN_SECTION, key) + if self.format.format_as_string == "3.0": + if not isinstance(key, list): + keys = [key] + else: + keys = key + + result = None # Just mark result as not set yet... + + # If board is set, search board specific keys first + if self.board: + result = self._get_v3_option([BOARDS_FIELD, self.board] + keys) + + # If a board specific value isn't found, look for a global one + if result == None: + result = self._get_v3_option(keys) + + # If no value is found, bail early (return None) + if result == None: + return None + + # +# +# 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 2 +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. + +import re +from StringIO import StringIO +from testtools import TestCase + +from linaro_image_tools.hwpack.config import Config, HwpackConfigError +from linaro_image_tools.hwpack.hwpack_fields import ( + DEFINED_PARTITION_LAYOUTS, +) + + +class ConfigTests(TestCase): + + valid_start = ( + "name: ahwpack\npackages: foo\narchitectures: armel\n") + valid_start_v3 = valid_start + "format: 3.0\n" + valid_complete_v3 = (valid_start_v3 + + "serial_tty: ttySAC1\n" + "partition_layout:\n" + " - bootfs_rootfs\n" + "boot_script: boot.scr\n" + "extra_serial_options:\n" + " - console=tty0\n" + " - console=ttyO2,115200n8\n" + "mmc_id: 0:1\n" + "kernel_file: boot/vmlinuz-*-linaro-omap\n" + "initrd_file: boot/initrd.img-*-linaro-omap\n" + "dtb_file: boot/dt-*-linaro-omap/omap4-panda.dtb\n" + "bootloaders:\n" + " u_boot:\n" + " package: u-boot-linaro-s5pv310\n" + " file: usr/lib/u-boot/smdkv310/u-boot.bin\n" + " spl_package: x-loader-omap4-panda\n" + " spl_file: usr/lib/x-loader/omap4430panda/MLO\n" + " in_boot_part: True\n" + " extra_boot_options:\n" + " - earlyprintk\n" + " - fixrtc\n" + " - nocompcache\n" + " - vram=48M\n" + " - omapfb.vram=0:24M\n" + " - mem=456M@0x80000000\n" + " - mem=512M@0xA0000000\n") + valid_end = "sources:\n sources-entry: foo bar\n" + + def test_create(self): + config = Config(StringIO()) + self.assertTrue(config is not None) + + def get_config(self, contents): + if not re.search("\s*format\s*:", contents): + contents = "format: 3.0\n" + contents + return Config(StringIO(contents), bootloader="u_boot") + + def assertConfigError(self, contents, f, *args, **kwargs): + e = self.assertRaises(HwpackConfigError, f, *args, **kwargs) + self.assertEqual(contents, str(e)) + + def assertValidationError(self, contents, validate_function): + self.assertConfigError(contents, validate_function) + + def test_validate_empty_name(self): + config = self.get_config("name: ") + self.assertValidationError("Empty value for name", + config._validate_name) + + def test_validate_invalid_name(self): + config = self.get_config("name: ~~\n") + self.assertValidationError("Invalid name: ~~", + config._validate_name) + + def test_validate_invalid_include_debs(self): + config = self.get_config( + "name: ahwpack\n" + "include_debs: if you don't mind\n") + self.assertValidationError( + "Invalid value for include-debs: if you don't mind", + config._validate_include_debs) + + def test_validate_invalid_supported(self): + config = self.get_config( + "name: ahwpack\nsupport: if you pay us\n") + self.assertValidationError( + "Invalid value for support: if you pay us", + config._validate_support) + + def test_validate_no_packages(self): + config = self.get_config( + "name: ahwpack\n\n") + self.assertValidationError( + "No packages found in the metadata", config._validate_packages) + + def test_validate_empty_packages(self): + config = self.get_config( + "name: ahwpack\npackages: \n") + self.assertValidationError( + "No packages found in the metadata", config._validate_packages) + + def test_validate_invalid_package_name(self): + config = self.get_config( + "name: ahwpack\npackages: foo ~~ bar\n") + self.assertValidationError( + "Invalid value in packages in the metadata: ~~", + config._validate_packages) + + def test_validate_no_architectures(self): + config = self.get_config( + "name: ahwpack\npackages: foo\n") + self.assertValidationError( + "No architectures found in the metadata", + config._validate_architectures) + + def test_validate_empty_architectures(self): + config = self.get_config( + "name: ahwpack\npackages: foo\n" + "architectures: \n") + self.assertValidationError( + "No architectures found in the metadata", + config._validate_architectures) + + def test_validate_invalid_package_name_in_assume_installed(self): + config = self.get_config( + "name: ahwpack\npackages: foo\n" + "architectures: armel\nassume_installed:\n - bar\n - ~~\n") + self.assertValidationError( + "Invalid value in assume-installed in the metadata: ~~", + config._validate_assume_installed) + + def test_validate_other_section_empty_sources_entry(self): + config = self.get_config( + self.valid_start + "sources:\n ubuntu: \n") + self.assertValidationError( + "The sources-entry, ubuntu is missing the URI", + config._validate_sources) + + def test_validate_other_section_only_uri_in_sources_entry(self): + config = self.get_config( + self.valid_start + "sources:\n ubuntu: foo\n") + self.assertValidationError( + "The sources-entry, ubuntu is missing the distribution", + config._validate_sources) + + def test_validate_other_section_sources_entry_starting_with_deb(self): + config = self.get_config(self.valid_start + + "sources:\n ubuntu: deb http://example.org/ foo main\n") + self.assertValidationError( + "The sources-entry, ubuntu shouldn't start with 'deb'", + config._validate_sources) + + def test_validate_other_section_sources_entry_starting_with_deb_src(self): + config = self.get_config(self.valid_start + + "sources:\n ubuntu: deb-src http://example.org/ foo main\n") + self.assertValidationError( + "The sources-entry, ubuntu shouldn't start with 'deb'", + config._validate_sources) + + def test_validate_valid_config(self): + config = self.get_config(self.valid_complete_v3) + self.assertEqual(None, config.validate()) + + def test_validate_supported_format(self): + config = self.get_config(self.valid_start + "format: 0.9\n") + self.assertValidationError( + "Format version '0.9' is not supported.", config._validate_format) + + def test_validate_invalid_u_boot_package_name(self): + config = self.get_config(self.valid_start_v3 + + "bootloaders:\n" + " u_boot:\n" + " package: ~~\n") + self.assertValidationError( + "Invalid value in u_boot_package in the metadata: ~~", + config._validate_u_boot_package) + + def test_validate_invalid_u_boot_file(self): + config = self.get_config(self.valid_start_v3 + + "bootloaders:\n" + " u_boot:\n" + " file: ~~\n") + self.assertValidationError("Invalid path: ~~", + config._validate_u_boot_file) + + def test_validate_invalid_kernel_file(self): + config = self.get_config(self.valid_start_v3 + + "kernel_file: ~~\n") + self.assertValidationError("Invalid path: ~~", + config._validate_vmlinuz) + + def test_validate_empty_kernel_file(self): + config = self.get_config(self.valid_start_v3 + + "kernel_file: \n") + self.assertValidationError("No kernel_file found in the metadata", + config._validate_vmlinuz) + + def test_validate_invalid_initrd_file(self): + config = self.get_config(self.valid_start_v3 + + "initrd_file: ~~\n") + self.assertValidationError("Invalid path: ~~", config._validate_initrd) + + def test_validate_empty_initrd_file(self): + config = self.get_config(self.valid_start_v3 + + "kernel_file: \n") + self.assertValidationError("No initrd_file found in the metadata", + config._validate_initrd) + + def test_validate_invalid_boot_script(self): + config = self.get_config(self.valid_start_v3 + "boot_script: ~~") + self.assertValidationError("Invalid path: ~~", + config._validate_boot_script) + + def test_validate_invalid_dtb_file(self): + config = self.get_config(self.valid_start_v3 + + "dtb_file: ~~\n") + self.assertValidationError("Invalid path: ~~", + config._validate_dtb_file) + + def test_validate_invalid_spl_package_name(self): + config = self.get_config(self.valid_start_v3 + + "bootloaders:\n" + " u_boot:\n" + " spl_package: ~~\n") + config.set_board("panda") + self.assertValidationError( + "Invalid value in spl_package in the metadata: ~~", + config._validate_spl_package) + + def test_validate_invalid_spl_file(self): + config = self.get_config(self.valid_start_v3 + + "boards:\n" + " panda:\n" + " bootloaders:\n" + " u_boot:\n" + " spl_file: ~~\n") + config.set_board("panda") + self.assertValidationError("Invalid path: ~~", + config._validate_spl_file) + + def test_validate_partition_layout(self): + partition_layout = 'apafs_bananfs' + config = self.get_config(self.valid_start_v3 + + "partition_layout: " + partition_layout) + self.assertValidationError( + "Undefined partition layout %s. " + "Valid partition layouts are %s." + % (partition_layout, + ", ".join(DEFINED_PARTITION_LAYOUTS)), + config._validate_partition_layout) + + def test_validate_wired_interfaces(self): + self.assertTrue("XXX What is an invalid interface name?") + + def test_validate_wireless_interfaces(self): + self.assertTrue("XXX What is an invalid interface name?") + + def test_validate_u_boot_in_boot_part_bool(self): + config = self.get_config( + self.valid_start_v3 + + "bootloaders:\n" + " u_boot:\n" + " in_boot_part: Nope\n") + self.assertValidationError( + "Invalid value for u_boot_in_boot_part: Nope", + config._validate_uboot_in_boot_part) + + def test_find_board_specific_variable(self): + config = self.get_config( + self.valid_start_v3 + + "boards:\n" + " panda:\n" + " bootloaders:\n" + " u_boot:\n" + " in_boot_part: Yes\n") + + config.set_bootloader("u_boot") + config.set_board("panda") + + config._validate_uboot_in_boot_part() + self.assertEqual(config.uboot_in_boot_part, "yes") + + def test_board_specific_overwrites_global(self): + config = self.get_config( + self.valid_start_v3 + + "bootloaders:\n" + " u_boot:\n" + " in_boot_part: No\n" + "boards:\n" + " panda:\n" + " bootloaders:\n" + " u_boot:\n" + " in_boot_part: Yes\n") + + config.set_bootloader("u_boot") + config.set_board("panda") + + config._validate_uboot_in_boot_part() + self.assertEqual(config.uboot_in_boot_part, "yes") + + def test_validate_serial_tty(self): + config = self.get_config(self.valid_start_v3 + "serial_tty: tty\n") + self.assertValidationError("Invalid serial tty: tty", + config._validate_serial_tty) + + config = self.get_config(self.valid_start_v3 + "serial_tty: ttxSAC1\n") + self.assertValidationError("Invalid serial tty: ttxSAC1", + config._validate_serial_tty) + + def test_validate_mmc_id(self): + config = self.get_config(self.valid_complete_v3 + + "mmc_id: x\n") + self.assertValidationError("Invalid mmc_id x", config._validate_mmc_id) + + def test_validate_boot_min_size(self): + config = self.get_config(self.valid_complete_v3 + + "boot_min_size: x\n") + self.assertValidationError("Invalid boot min size x", + config._validate_boot_min_size) + + def test_validate_root_min_size(self): + config = self.get_config(self.valid_complete_v3 + + "root_min_size: x\n") + self.assertValidationError("Invalid root min size x", + config._validate_root_min_size) + + def test_validate_loader_min_size(self): + config = self.get_config(self.valid_complete_v3 + + "loader_min_size: x\n") + self.assertValidationError("Invalid loader min size x", + config._validate_loader_min_size) + + def test_validate_kernel_addr(self): + # V3 change: All numerical inputs are good addresses (since YAML + # converts them to ingegers and we convert them back to the correct + # format). We don't need 8 digit hex values for addresses. + config = self.get_config(self.valid_complete_v3 + + "kernel_addr: 0x8000000\n") + config._validate_kernel_addr() + config = self.get_config(self.valid_complete_v3 + + "kernel_addr: 0x8000000x\n") + self.assertValidationError( + "Invalid kernel address: 0x8000000x", config._validate_kernel_addr) + config = self.get_config(self.valid_complete_v3 + + "kernel_addr: 80000000\n") + config._validate_kernel_addr() + + def test_validate_initrd_addr(self): + # V3 change: All numerical inputs are good addresses (since YAML + # converts them to ingegers and we convert them back to the correct + # format). We don't need 8 digit hex values for addresses. + config = self.get_config(self.valid_complete_v3 + + "initrd_addr: 0x8000000\n") + config._validate_initrd_addr() + config = self.get_config(self.valid_complete_v3 + + "initrd_addr: 0x8000000x\n") + self.assertValidationError( + "Invalid initrd address: 0x8000000x", config._validate_initrd_addr) + config = self.get_config(self.valid_complete_v3 + + "initrd_addr: 80000000\n") + config._validate_initrd_addr() + + def test_validate_load_addr(self): + # V3 change: All numerical inputs are good addresses (since YAML + # converts them to ingegers and we convert them back to the correct + # format). We don't need 8 digit hex values for addresses. + config = self.get_config(self.valid_complete_v3 + + "load_addr: 0x8000000\n") + config._validate_load_addr() + config = self.get_config(self.valid_complete_v3 + + "load_addr: 0x8000000x\n") + self.assertValidationError("Invalid load address: 0x8000000x", + config._validate_load_addr) + config = self.get_config(self.valid_complete_v3 + + "load_addr: 80000000\n") + config._validate_load_addr() + + def test_validate_dtb_addr(self): + # V3 change: All numerical inputs are good addresses (since YAML + # converts them to ingegers and we convert them back to the correct + # format). We don't need 8 digit hex values for addresses. + config = self.get_config(self.valid_complete_v3 + + "dtb_addr: 0x8000000\n") + config._validate_dtb_addr() + config = self.get_config(self.valid_complete_v3 + + "dtb_addr: 0x8000000x\n") + self.assertValidationError("Invalid dtb address: 0x8000000x", + config._validate_dtb_addr) + config = self.get_config(self.valid_complete_v3 + + "dtb_addr: 80000000\n") + config._validate_dtb_addr() + + def test_wired_interfaces(self): + config = self.get_config(self.valid_complete_v3 + + "wired_interfaces:\n - eth0\n" + + self.valid_end) + config.validate() + self.assertEqual(["eth0"], config.wired_interfaces) + config = self.get_config(self.valid_complete_v3 + + "wired_interfaces:\n" + " - eth0\n" + " - eth1\n" + " - usb2\n" + + self.valid_end) + config.validate() + self.assertEqual(["eth0", "eth1", "usb2"], config.wired_interfaces) + + def test_wireless_interfaces(self): + config = self.get_config(self.valid_complete_v3 + + "wireless_interfaces:\n" + " - wlan0\n" + + self.valid_end) + config.validate() + self.assertEqual(["wlan0"], config.wireless_interfaces) + config = self.get_config(self.valid_complete_v3 + + "wireless_interfaces:\n" + " - wlan0\n" + " - wl1\n" + " - usb2\n" + + self.valid_end) + config.validate() + self.assertEqual(["wlan0", "wl1", "usb2"], config.wireless_interfaces) + + def test_partition_layout(self): + config = self.get_config(self.valid_complete_v3 + self.valid_end) + config.validate() + self.assertEqual("bootfs_rootfs", + config.partition_layout) + + def test_u_boot_file(self): + config = self.get_config(self.valid_complete_v3 + self.valid_end) + config.validate() + self.assertEqual("usr/lib/u-boot/smdkv310/u-boot.bin", + config.u_boot_file) + + def test_u_boot_package(self): + config = self.get_config(self.valid_complete_v3 + self.valid_end) + config.validate() + self.assertEqual("u-boot-linaro-s5pv310", + config.u_boot_package) + + def test_spl_file(self): + config = self.get_config(self.valid_complete_v3 + self.valid_end) + config.validate() + self.assertEqual("usr/lib/x-loader/omap4430panda/MLO", + config.spl_file) + + def test_kernel_file(self): + config = self.get_config(self.valid_complete_v3 + self.valid_end) + config.validate() + self.assertEqual("boot/vmlinuz-*-linaro-omap", + config.vmlinuz) + + def test_initrd_file(self): + config = self.get_config(self.valid_complete_v3 + self.valid_end) + config.validate() + self.assertEqual("boot/initrd.img-*-linaro-omap", + config.initrd) + + def test_dtb_file(self): + config = self.get_config(self.valid_complete_v3 + self.valid_end) + config.validate() + self.assertEqual("boot/dt-*-linaro-omap/omap4-panda.dtb", + config.dtb_file) + + def test_extra_boot_options(self): + config = self.get_config(self.valid_complete_v3 + self.valid_end) + config.validate() + self.assertEqual( + "earlyprintk fixrtc nocompcache vram=48M " + "omapfb.vram=0:24M mem=456M@0x80000000 mem=512M@0xA0000000", + config.extra_boot_options) + + def test_extra_serial_opts(self): + config = self.get_config(self.valid_complete_v3 + self.valid_end) + config.validate() + self.assertEqual('console=tty0 console=ttyO2,115200n8', + config.extra_serial_opts) + + def test_boot_script(self): + config = self.get_config(self.valid_complete_v3 + self.valid_end) + config.validate() + self.assertEqual("boot.scr", + config.boot_script) + + def test_u_boot_in_boot_part(self): + config = self.get_config(self.valid_complete_v3 + self.valid_end) + config.validate() + self.assertEqual("yes", + config.uboot_in_boot_part) + + def test_spl_package(self): + config = self.get_config(self.valid_complete_v3 + self.valid_end) + config.validate() + self.assertEqual("x-loader-omap4-panda", + config.spl_package) + + def test_serial_tty(self): + config = self.get_config(self.valid_complete_v3 + self.valid_end) + config.validate() + self.assertEqual("ttySAC1", config.serial_tty) + + def test_mmc_id(self): + config = self.get_config(self.valid_complete_v3 + + "mmc_id: 0:1\n" + + self.valid_end) + config.validate() + self.assertEqual("0:1", config.mmc_id) + + def test_boot_min_size(self): + config = self.get_config(self.valid_complete_v3 + + "boot_min_size: 50\n" + + self.valid_end) + config.validate() + self.assertEqual("50", config.boot_min_size) + + def test_root_min_size(self): + config = self.get_config(self.valid_complete_v3 + + "root_min_size: 50\n" + + self.valid_end) + config.validate() + self.assertEqual("50", config.root_min_size) + + def test_loader_min_size(self): + config = self.get_config(self.valid_complete_v3 + + "loader_min_size: 2\n" + + self.valid_end) + config.validate() + self.assertEqual("2", config.loader_min_size) + + def test_kernel_addr(self): + config = self.get_config(self.valid_complete_v3 + + "kernel_addr: 0x80000000\n" + + self.valid_end) + config.validate() + self.assertEqual("0x80000000", config.kernel_addr) + config = self.get_config(self.valid_complete_v3 + + "kernel_addr: 0x8aBcdEFf\n" + + self.valid_end) + config.validate() + self.assertEqual("0x8abcdeff", config.kernel_addr) + + def test_initrd_addr(self): + config = self.get_config(self.valid_complete_v3 + + "initrd_addr: 0x80000000\n" + + self.valid_end) + config.validate() + self.assertEqual("0x80000000", config.initrd_addr) + config = self.get_config(self.valid_complete_v3 + + "initrd_addr: 0x8aBcdEFf\n" + + self.valid_end) + config.validate() + self.assertEqual("0x8abcdeff", config.initrd_addr) + + def test_load_addr(self): + config = self.get_config(self.valid_complete_v3 + + "load_addr: 0x80000000\n" + + self.valid_end) + config.validate() + self.assertEqual("0x80000000", config.load_addr) + config = self.get_config(self.valid_complete_v3 + + "load_addr: 0x8aBcdEFf\n" + + self.valid_end) + config.validate() + self.assertEqual("0x8abcdeff", config.load_addr) + + def test_dtb_addr(self): + config = self.get_config(self.valid_complete_v3 + + "dtb_addr: 0x80000000\n" + + self.valid_end) + config.validate() + self.assertEqual("0x80000000", config.dtb_addr) + config = self.get_config(self.valid_complete_v3 + + "dtb_addr: 0x8aBcdEFf\n" + + self.valid_end) + config.validate() + self.assertEqual("0x8abcdeff", config.dtb_addr) + + def test_name(self): + config = self.get_config( + "name: ahwpack\n" + "packages: foo\n" + "architectures: armel\n") + self.assertEqual("ahwpack", config.name) + + def test_include_debs(self): + config = self.get_config(self.valid_start + "include_debs: false\n") + self.assertEqual(False, config.include_debs) + + def test_include_debs_defaults_true(self): + config = self.get_config(self.valid_start) + self.assertEqual(True, config.include_debs) + + def test_include_debs_defaults_true_on_empty(self): + config = self.get_config(self.valid_start + "include_debs: \n") + self.assertEqual(True, config.include_debs) + + def test_origin(self): + config = self.get_config(self.valid_start + "origin: linaro\n") + self.assertEqual("linaro", config.origin) + + def test_origin_default_None(self): + config = self.get_config(self.valid_start) + self.assertEqual(None, config.origin) + + def test_origin_None_on_empty(self): + config = self.get_config(self.valid_start + "origin: \n") + self.assertEqual(None, config.origin) + + def test_maintainer(self): + maintainer = "Linaro Developers " + config = self.get_config( + self.valid_start + + "maintainer: %s\n" % maintainer) + self.assertEqual(maintainer, config.maintainer) + + def test_maintainer_default_None(self): + config = self.get_config(self.valid_start) + self.assertEqual(None, config.maintainer) + + def test_maintainer_None_on_empty(self): + config = self.get_config(self.valid_start + "maintainer: \n") + self.assertEqual(None, config.maintainer) + + def test_support_supported(self): + config = self.get_config(self.valid_start + "support: supported\n") + self.assertEqual("supported", config.support) + + def test_support_unsupported(self): + config = self.get_config(self.valid_start + "support: unsupported\n") + self.assertEqual("unsupported", config.support) + + def test_support_default_None(self): + config = self.get_config(self.valid_start) + self.assertEqual(None, config.support) + + def test_support_None_on_empty(self): + config = self.get_config(self.valid_start + "support: \n") + self.assertEqual(None, config.support) + + def test_packages(self): + config = self.get_config( + "name: ahwpack\n" + "packages:\n" + " - foo\n" + " - bar\n" + "architectures: armel\n") + self.assertEqual(["foo", "bar"], config.packages) + + def test_packages_filters_duplicates(self): + config = self.get_config( + "name: ahwpack\n" + "packages:\n" + " - foo\n" + " - bar\n" + " - foo\n" + "architectures: armel\n") + self.assertEqual(["foo", "bar"], config.packages) + + def test_sources_single(self): + config = self.get_config( + self.valid_start + + "sources:\n" + " ubuntu: http://example.org foo\n") + self.assertEqual({"ubuntu": "http://example.org foo"}, config.sources) + + def test_sources_multiple(self): + config = self.get_config( + self.valid_start + + "sources:\n" + " ubuntu: http://example.org foo\n" + " linaro: http://example.org bar\n") + self.assertEqual( + {"ubuntu": "http://example.org foo", + "linaro": "http://example.org bar"}, + config.sources) + + def test_architectures(self): + config = self.get_config( + "hello: there\n" + "name: ahwpack\n" + "packages: foo\n" + "architectures:\n" + " - foo\n" + " - bar\n") + self.assertEqual(["foo", "bar"], config.architectures) + + def test_architectures_filters_duplicates(self): + config = self.get_config( + "name: ahwpack\n" + "packages: foo\n" + "architectures:\n" + " - foo\n" + " - bar\n" + " - foo\n") + self.assertEqual(["foo", "bar"], config.architectures) + + def test_assume_installed(self): + config = self.get_config( + "name: ahwpack\n" + "packages:\n" + " - foo\n" + "architectures:\n" + " - armel\n" + "assume_installed:\n" + " - foo\n" + " - bar\n") + self.assertEqual(["foo", "bar"], config.assume_installed) + + def test_assume_installed_filters_duplicates(self): + config = self.get_config( + "name: ahwpack\n" + "packages:\n" + " - foo\n" + "architectures:\n" + " - armel\n" + "assume_installed:\n" + " - foo\n" + " - bar\n" + " - foo\n") + self.assertEqual(["foo", "bar"], config.assume_installed) === modified file 'linaro_image_tools/hwpack/tests/test_hardwarepack.py' --- linaro_image_tools/hwpack/tests/test_hardwarepack.py 2012-06-13 14:53:32 +0000 +++ linaro_image_tools/hwpack/tests/test_hardwarepack.py 2012-07-19 14:50:45 +0000 @@ -40,6 +40,7 @@ from linaro_image_tools.hwpack.hardwarepack_format import ( HardwarePackFormatV1, HardwarePackFormatV2, + HardwarePackFormatV3, ) @@ -87,174 +88,157 @@ def test_str(self): metadata = Metadata("ahwpack", "4", "armel") - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n", str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_origin(self): metadata = Metadata("ahwpack", "4", "armel", origin="linaro") - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\nORIGIN=linaro\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "ORIGIN=linaro\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_maintainer(self): metadata = Metadata( "ahwpack", "4", "armel", maintainer="Some Maintainer") - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "MAINTAINER=Some Maintainer\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "MAINTAINER=Some Maintainer\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_support(self): metadata = Metadata("ahwpack", "4", "armel", support="unsupported") - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "SUPPORT=unsupported\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "SUPPORT=unsupported\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_serial_tty(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(serial_tty='ttyO2') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "SERIAL_TTY=ttyO2\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "SERIAL_TTY=ttyO2\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_kernel_addr(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(kernel_addr='0x80000000') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "KERNEL_ADDR=0x80000000\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "KERNEL_ADDR=0x80000000\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_initrd_addr(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(initrd_addr='0x80000000') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "INITRD_ADDR=0x80000000\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "INITRD_ADDR=0x80000000\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_load_addr(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(load_addr='0x80000000') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "LOAD_ADDR=0x80000000\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "LOAD_ADDR=0x80000000\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_dtb_addr(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(dtb_addr='0x80000000') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "DTB_ADDR=0x80000000\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "DTB_ADDR=0x80000000\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_wired_interfaces(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(wired_interfaces=['eth0', 'usb0']) - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "WIRED_INTERFACES=eth0 usb0\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "WIRED_INTERFACES=eth0 usb0\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_wireless_interfaces(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(wireless_interfaces=['wlan0', 'wl0']) - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "WIRELESS_INTERFACES=wlan0 wl0\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "WIRELESS_INTERFACES=wlan0 wl0\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_partition_layout(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(partition_layout='bootfs_rootfs') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "PARTITION_LAYOUT=bootfs_rootfs\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "PARTITION_LAYOUT=bootfs_rootfs\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_mmc_id(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(mmc_id='1') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "MMC_ID=1\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "MMC_ID=1\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_boot_min_size(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(boot_min_size='50') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "BOOT_MIN_SIZE=50\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "BOOT_MIN_SIZE=50\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_root_min_size(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(root_min_size='100') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "ROOT_MIN_SIZE=100\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "ROOT_MIN_SIZE=100\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_loader_min_size(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(loader_min_size='1') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "LOADER_MIN_SIZE=1\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "LOADER_MIN_SIZE=1\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_kernel_file(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(vmlinuz='boot/vmlinuz-3.0.0-1002-linaro-omap') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "KERNEL_FILE=boot/vmlinuz-3.0.0-1002-linaro-omap\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "KERNEL_FILE=boot/vmlinuz-3.0.0-1002-linaro-omap\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_initrd_file(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(initrd='boot/initrd.img-3.0.0-1002-linaro-omap') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "INITRD_FILE=boot/initrd.img-3.0.0-1002-linaro-omap\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "INITRD_FILE=boot/initrd.img-3.0.0-1002-linaro-omap\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_dtb_file(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config( dtb_file='boot/dt-3.0.0-1002-linaro-omap/omap4-panda.dtb') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "DTB_FILE=boot/dt-3.0.0-1002-linaro-omap/omap4-panda.dtb\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\n" + "ARCHITECTURE=armel\nDTB_FILE=" + "boot/dt-3.0.0-1002-linaro-omap/omap4-panda.dtb\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_boot_script(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config(boot_script='boot.scr') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "BOOT_SCRIPT=boot.scr\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "BOOT_SCRIPT=boot.scr\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_extra_boot_options(self): metadata = Metadata("ahwpack", "4", "armel", @@ -263,21 +247,21 @@ extra_boot_options=( 'earlyprintk fixrtc nocompcache vram=48M omapfb.vram=0:24M ' 'mem=456M@0x80000000 mem=512M@0xA0000000')) - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "EXTRA_BOOT_OPTIONS=earlyprintk fixrtc nocompcache vram=48M " - "omapfb.vram=0:24M mem=456M@0x80000000 mem=512M@0xA0000000\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" + "EXTRA_BOOT_OPTIONS=earlyprintk fixrtc nocompcache " + "vram=48M omapfb.vram=0:24M " + "mem=456M@0x80000000 mem=512M@0xA0000000\n") + self.assertEqual(expected_out, str(metadata)) def test_str_with_extra_serial_options(self): metadata = Metadata("ahwpack", "4", "armel", format=HardwarePackFormatV2()) metadata.add_v2_config( extra_serial_opts='console=tty0 console=ttyO2,115200n8') - self.assertEqual( - "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" - "EXTRA_SERIAL_OPTIONS=console=tty0 console=ttyO2,115200n8\n", - str(metadata)) + expected_out = ("NAME=ahwpack\nVERSION=4\n" + "ARCHITECTURE=armel\nEXTRA_SERIAL_OPTIONS=" + "console=tty0 console=ttyO2,115200n8\n") + self.assertEqual(expected_out, str(metadata)) def test_from_config(self): class Config: @@ -296,6 +280,113 @@ self.assertEqual("i386", metadata.architecture) +class NewMetadataTests(TestCase): + + def setUp(self): + super(NewMetadataTests, self).setUp() + + def test_format(self): + metadata = Metadata("ahwpack", "4", "armel", + format=HardwarePackFormatV3()) + # Need to call also this one! + metadata.add_v2_config() + metadata.add_v3_config(bootloaders=None) + expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n" + "architecture: armel\n") + self.assertEqual(expected_out, str(metadata)) + + def test_section_bootloaders(self): + bootloaders = {'u_boot': {'file': 'a_file'}} + metadata = Metadata("ahwpack", "4", "armel", + format=HardwarePackFormatV3()) + # Need to call also this one! + metadata.add_v2_config() + metadata.add_v3_config(bootloaders=bootloaders) + expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n" + "architecture: armel\nbootloaders:\n u_boot:\n" + " file: a_file\n") + self.assertEqual(expected_out, str(metadata)) + + def test_section_wireless(self): + metadata = Metadata("ahwpack", "4", "armel", + format=HardwarePackFormatV3()) + wireless_list = ['wlan0', 'wl0'] + # Need to call also this one! + metadata.add_v2_config(wireless_interfaces=wireless_list) + metadata.add_v3_config(bootloaders=None) + expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n" + "architecture: armel\nwireless_interfaces: wlan0 " + "wl0\n") + self.assertEqual(expected_out, str(metadata)) + + def test_section_wired(self): + metadata = Metadata("ahwpack", "4", "armel", + format=HardwarePackFormatV3()) + wired_list = ['eth0', 'usb0'] + # Need to call also this one! + metadata.add_v2_config(wired_interfaces=wired_list) + metadata.add_v3_config(bootloaders=None) + expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n" + "architecture: armel\nwired_interfaces: eth0 usb0\n") + self.assertEqual(expected_out, str(metadata)) + + def test_section_extra_serial_options(self): + metadata = Metadata("ahwpack", "4", "armel", + format=HardwarePackFormatV3()) + options = ['option1', 'option2,option3'] + # Need to call also this one! + metadata.add_v2_config(extra_serial_opts=options) + metadata.add_v3_config(bootloaders=None) + expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n" + "architecture: armel\nextra_serial_options: option1 " + "option2,option3\n") + self.assertEqual(expected_out, str(metadata)) + + def test_loop_through_for_spl(self): + bootloaders = {'u_boot': {'file': 'a_file', 'spl_file': 'some_value'}} + spl = 'spl-path' + metadata = Metadata("ahwpack", "4", "armel", + format=HardwarePackFormatV3()) + # Need to call also this one! + metadata.add_v2_config() + metadata.add_v3_config(bootloaders=bootloaders) + metadata.spl = spl + expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n" + "architecture: armel\nbootloaders:\n u_boot:\n" + " file: a_file\n spl_file: spl-path\n") + self.assertEqual(expected_out, str(metadata)) + + def test_loop_through_for_uboot(self): + bootloaders = {'u_boot': {'file': 'a_file', 'spl_file': 'some_value'}} + u_boot = 'uboot-path' + metadata = Metadata("ahwpack", "4", "armel", + format=HardwarePackFormatV3()) + # Need to call also this one! + metadata.add_v2_config() + metadata.add_v3_config(bootloaders=bootloaders) + metadata.u_boot = u_boot + expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n" + "architecture: armel\nbootloaders:\n u_boot:\n" + " file: uboot-path\n spl_file: some_value\n") + self.assertEqual(expected_out, str(metadata)) + + def test_loop_through_multiple_bootloaders(self): + bootloaders = {'u_boot': {'file': 'a_file', 'spl_file': 'some_value'}, + 'uefi': {'spl_file': 'some_other_value'}} + spl = 'spl-path' + metadata = Metadata("ahwpack", "4", "armel", + format=HardwarePackFormatV3()) + # Need to call also this one! + metadata.add_v2_config() + metadata.add_v3_config(bootloaders=bootloaders) + metadata.spl = spl + expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n" + "architecture: armel\nbootloaders:\n u_boot:\n" + " file: a_file\n spl_file: spl-path\n uefi:\n" + " spl_file: spl-path\n") + self.assertEqual(expected_out, str(metadata)) + + class HardwarePackTests(TestCase): def setUp(self): === modified file 'linaro_image_tools/hwpack/tests/test_hwpack_converter.py' --- linaro_image_tools/hwpack/tests/test_hwpack_converter.py 2012-07-19 15:21:06 +0000 +++ linaro_image_tools/hwpack/tests/test_hwpack_converter.py 2012-07-20 08:19:11 +0000 @@ -130,3 +130,27 @@ converter = HwpackConverter(input_file, output_file) converter._parse() self.assertEqual(out_format, str(converter)) + + def test_assume_installed(self): + """Tests the correct creation of the extra_serial_options part.""" + ini_format = ("[hwpack]\nformat=2.0\nassume-installed=install1 " + "install2") + out_format = ("format: '3.0'\nassume_installed:\n- install1\n- " + "install2\n") + input_file = self.useFixture(CreateTempFileFixture(ini_format)).\ + get_file_name() + output_file = self.useFixture(CreateTempFileFixture()).get_file_name() + converter = HwpackConverter(input_file, output_file) + converter._parse() + self.assertEqual(out_format, str(converter)) + + def test_include_debs(self): + """Tests the correct creation of the extra_serial_options part.""" + ini_format = ("[hwpack]\nformat=2.0\ninclude-debs=yes") + out_format = ("format: '3.0'\ninclude_debs: true\n") + input_file = self.useFixture(CreateTempFileFixture(ini_format)).\ + get_file_name() + output_file = self.useFixture(CreateTempFileFixture()).get_file_name() + converter = HwpackConverter(input_file, output_file) + converter._parse() + self.assertEqual(out_format, str(converter)) === modified file 'linaro_image_tools/media_create/boards.py' --- linaro_image_tools/media_create/boards.py 2012-06-13 14:41:42 +0000 +++ linaro_image_tools/media_create/boards.py 2012-07-23 15:28:30 +0000 @@ -36,6 +36,7 @@ import shutil import string import logging +from linaro_image_tools.hwpack.config import Config from parted import Device @@ -43,7 +44,7 @@ from linaro_image_tools.media_create.partitions import ( partition_mounted, SECTOR_SIZE, register_loopback) - +from StringIO import StringIO KERNEL_GLOB = 'vmlinuz-*-%(kernel_flavor)s' INITRD_GLOB = 'initrd.img-*-%(kernel_flavor)s' @@ -114,6 +115,7 @@ 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' @@ -158,18 +160,18 @@ if self.tempdir is not None and os.path.exists(self.tempdir): shutil.rmtree(self.tempdir) - def get_field(self, section, field): + def get_field(self, field): data = None hwpack_with_data = None for hwpack_tarfile in self.hwpack_tarfiles: metadata = hwpack_tarfile.extractfile(self.metadata_filename) - # Use RawConfigParser which does not support the magical - # interpolation behavior of ConfigParser so we don't mess up - # metadata accidentally. - parser = ConfigParser.RawConfigParser() - parser.readfp(self.FakeSecHead(metadata)) + 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 + parser = Config(StringIO("".join(lines))) try: - new_data = parser.get(section, field) + 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, @@ -178,11 +180,12 @@ hwpack_with_data = hwpack_tarfile except ConfigParser.NoOptionError: continue + return data, hwpack_with_data def get_format(self): format = None - supported_formats = [self.FORMAT_1, self.FORMAT_2] + 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() @@ -196,8 +199,7 @@ return format def get_file(self, file_alias): - file_name, hwpack_tarfile = self.get_field(self.main_section, - file_alias) + file_name, hwpack_tarfile = self.get_field(file_alias) if file_name is not None: hwpack_tarfile.extract(file_name, self.tempdir) file_name = os.path.join(self.tempdir, file_name) @@ -289,8 +291,7 @@ def get_metadata_field(cls, field_name): """ Return the metadata value for field_name if it can be found. """ - data, _ = cls.hardwarepack_handler.get_field( - cls.hardwarepack_handler.main_section, field_name) + data, _ = cls.hardwarepack_handler.get_field(field_name) return data @classmethod @@ -305,7 +306,7 @@ if (cls.hwpack_format == cls.hardwarepack_handler.FORMAT_1): return - if (cls.hwpack_format == cls.hardwarepack_handler.FORMAT_2): + if (cls.hwpack_format != cls.hardwarepack_handler.FORMAT_1): # Clear V1 defaults. cls.kernel_addr = None cls.initrd_addr = None @@ -334,19 +335,19 @@ cls.serial_tty = cls.get_metadata_field('serial_tty') wired_interfaces = cls.get_metadata_field('wired_interfaces') if wired_interfaces is not None: - cls.wired_interfaces = wired_interfaces.split(' ') + cls.wired_interfaces = wired_interfaces wireless_interfaces = cls.get_metadata_field( 'wireless_interfaces') if wireless_interfaces is not None: - cls.wireless_interfaces = wireless_interfaces.split(' ') - cls.vmlinuz = cls.get_metadata_field('kernel_file') - cls.initrd = cls.get_metadata_field('initrd_file') + cls.wireless_interfaces = wireless_interfaces + cls.vmlinuz = cls.get_metadata_field('vmlinuz') + cls.initrd = cls.get_metadata_field('initrd') cls.dtb_file = cls.get_metadata_field('dtb_file') cls.extra_boot_args_options = cls.get_metadata_field( 'extra_boot_options') cls.boot_script = cls.get_metadata_field('boot_script') cls.extra_serial_opts = cls.get_metadata_field( - 'extra_serial_options') + 'extra_serial_opts') cls.snowball_startup_files_config = cls.get_metadata_field( 'snowball_startup_files_config') @@ -379,7 +380,7 @@ align_up(int(loader_min_size) * 1024 ** 2, SECTOR_SIZE) / SECTOR_SIZE) - uboot_in_boot_part = cls.get_metadata_field('u_boot_in_boot_part') + uboot_in_boot_part = cls.get_metadata_field('uboot_in_boot_part') if uboot_in_boot_part is None: cls.uboot_in_boot_part = False elif string.lower(uboot_in_boot_part) == 'yes': @@ -401,7 +402,7 @@ elif string.lower(env_dd) == 'no': cls.env_dd = False - uboot_dd = cls.get_metadata_field('u_boot_dd') + uboot_dd = cls.get_metadata_field('uboot_dd') # Either uboot_dd is not specified, or it contains the dd offset. if uboot_dd is None: cls.uboot_dd = False @@ -700,7 +701,7 @@ boot_device_or_file, k_img_data, i_img_data, d_img_data): with cls.hardwarepack_handler: - spl_file = cls.get_file('spl') + spl_file = cls.get_file('spl_file') if cls.spl_in_boot_part: assert spl_file is not None, ( "SPL binary could not be found") @@ -715,7 +716,7 @@ if cls.spl_dd: cls._dd_file(spl_file, boot_device_or_file, cls.spl_dd) - uboot_file = cls.get_file('u_boot') + uboot_file = cls.get_file('u_boot_file') if cls.uboot_dd: cls._dd_file(uboot_file, boot_device_or_file, cls.uboot_dd) @@ -764,7 +765,6 @@ if is_live: parts_dir = 'casper' uboot_parts_dir = os.path.join(chroot_dir, parts_dir) - cmd_runner.run(['mkdir', '-p', boot_disk]).wait() with partition_mounted(boot_partition, boot_disk): if cls.uboot_in_boot_part: @@ -781,7 +781,7 @@ else: default = None # - uboot_bin = cls.get_file('u_boot', default=default) + uboot_bin = cls.get_file('u_boot_file', default=default) assert uboot_bin is not None, ( "uboot binary could not be found") @@ -1277,7 +1277,7 @@ # XXX: delete this method when hwpacks V1 can die assert cls.hwpack_format == HardwarepackHandler.FORMAT_1 with cls.hardwarepack_handler: - uboot_file = cls.get_file('u_boot', default=os.path.join( + uboot_file = cls.get_file('u_boot_file', default=os.path.join( chroot_dir, 'usr', 'lib', 'u-boot', cls.uboot_flavor, 'u-boot.imx')) install_mx5_boot_loader(uboot_file, boot_device_or_file, @@ -1778,7 +1778,7 @@ default = _get_mlo_file(chroot_dir) except AssertionError: default = None - mlo_file = cls.get_file('spl', default=default) + mlo_file = cls.get_file('spl_file', default=default) cmd_runner.run(["cp", "-v", mlo_file, boot_disk], as_root=True).wait() # XXX: Is this really needed? cmd_runner.run(["sync"]).wait() === modified file 'linaro_image_tools/media_create/chroot_utils.py' --- linaro_image_tools/media_create/chroot_utils.py 2012-06-13 14:11:28 +0000 +++ linaro_image_tools/media_create/chroot_utils.py 2012-07-23 14:10:35 +0000 @@ -25,7 +25,7 @@ is_arm_host, find_command, ) - +from linaro_image_tools.media_create.boards 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 @@ -97,7 +97,17 @@ print "-" * 60 print "Installing (linaro-hwpack-install) %s in target rootfs." % ( hwpack_basename) - args = ['linaro-hwpack-install'] + + # Get infromation required by linaro-hwpack-install + with HardwarepackHandler([hwpack_file]) as hwpack: + version, _ = hwpack.get_field("version") + architecture, _ = hwpack.get_field("architecture") + name, _ = hwpack.get_field("name") + + args = ['linaro-hwpack-install', + '--hwpack-version', version, + '--hwpack-arch', architecture, + '--hwpack-name', name] if hwpack_force_yes: args.append('--force-yes') args.append('/%s' % hwpack_basename) === modified file 'linaro_image_tools/media_create/tests/test_media_create.py' --- linaro_image_tools/media_create/tests/test_media_create.py 2012-07-17 15:33:19 +0000 +++ linaro_image_tools/media_create/tests/test_media_create.py 2012-07-23 15:28:30 +0000 @@ -216,22 +216,22 @@ def test_get_metadata(self): data = 'data to test' - metadata = self.metadata + "TEST=%s\n" % data + metadata = self.metadata + "U_BOOT=%s\n" % data tarball = self.add_to_tarball( [('metadata', metadata)]) hp = HardwarepackHandler([tarball]) with hp: - test_data, _ = hp.get_field(hp.main_section, 'test') + test_data, _ = hp.get_field('u_boot_file') self.assertEqual(test_data, data) def test_preserves_formatters(self): data = '%s%d' - metadata = self.metadata + "TEST=%s\n" % data + metadata = self.metadata + "U_BOOT=%s\n" % data tarball = self.add_to_tarball( [('metadata', metadata)]) hp = HardwarepackHandler([tarball]) with hp: - test_data, _ = hp.get_field(hp.main_section, 'test') + test_data, _ = hp.get_field('u_boot_file') self.assertEqual(test_data, data) def test_creates_tempdir(self): @@ -252,15 +252,14 @@ def test_get_file(self): data = 'test file contents\n' - metadata_file = 'TESTFILE' file_in_archive = 'testfile' - metadata = self.metadata + "%s=%s\n" % (metadata_file, file_in_archive) + metadata = self.metadata + "%s=%s\n" % ('U_BOOT', file_in_archive) tarball = self.add_to_tarball( [('metadata', metadata), (file_in_archive, data)]) hp = HardwarepackHandler([tarball]) with hp: - test_file = hp.get_file(metadata_file) + test_file = hp.get_file('u_boot_file') self.assertEquals(data, open(test_file, 'r').read()) @@ -272,7 +271,7 @@ def __enter__(self): return self - def get_field(self, section, field): + def get_field(self, field): try: return self.metadata_dict[field], None except: @@ -367,7 +366,7 @@ class config(BoardConfig): pass config.set_metadata('ahwpack.tar.gz') - self.assertEquals(data_to_set.split(' '), config.wired_interfaces) + self.assertEquals(data_to_set, config.wired_interfaces) def test_sets_wireless_interfaces(self): self.useFixture(MockSomethingFixture( @@ -382,7 +381,7 @@ class config(BoardConfig): pass config.set_metadata('ahwpack.tar.gz') - self.assertEquals(data_to_set.split(' '), config.wireless_interfaces) + self.assertEquals(data_to_set, config.wireless_interfaces) def test_sets_mmc_id(self): self.useFixture(MockSomethingFixture( @@ -3225,6 +3224,20 @@ class TestInstallHWPack(TestCaseWithFixtures): + def create_minimal_v3_hwpack(self, location, name, version, architecture): + metadata = "\n".join([ + "name: " + name, + "version: " + version, + "architecture: " + architecture, + "format: 3.0" + ]) + print metadata + tar_file = tarfile.open(location, mode='w:gz') + tarinfo = tarfile.TarInfo("metadata") + tarinfo.size = len(metadata) + tar_file.addfile(tarinfo, StringIO(metadata)) + tar_file.close() + def mock_prepare_chroot(self, chroot_dir, tmp_dir): def fake_prepare_chroot(chroot_dir, tmp_dir): cmd_runner.run(['prepare_chroot %s %s' % (chroot_dir, tmp_dir)], @@ -3278,12 +3291,23 @@ sys, 'stdout', open('/dev/null', 'w'))) fixture = self.useFixture(MockCmdRunnerPopenFixture()) chroot_dir = 'chroot_dir' + hwpack_dir = tempfile.mkdtemp() + hwpack_file_name = 'hwpack.tgz' + hwpack_tgz_location = os.path.join(hwpack_dir, hwpack_file_name) + hwpack_name = "foo" + hwpack_version = "4" + hwpack_architecture = "armel" + self.create_minimal_v3_hwpack(hwpack_tgz_location, hwpack_name, + hwpack_version, hwpack_architecture) force_yes = False - install_hwpack(chroot_dir, 'hwpack.tgz', force_yes) + install_hwpack(chroot_dir, hwpack_tgz_location, force_yes) self.assertEquals( - ['%s cp hwpack.tgz %s' % (sudo_args, chroot_dir), - '%s %s %s linaro-hwpack-install /hwpack.tgz' - % (sudo_args, chroot_args, chroot_dir)], + ['%s cp %s %s' % (sudo_args, hwpack_tgz_location, chroot_dir), + '%s %s %s linaro-hwpack-install --hwpack-version %s ' + '--hwpack-arch %s --hwpack-name %s /%s' + % (sudo_args, chroot_args, chroot_dir, + hwpack_version, hwpack_architecture, hwpack_name, + hwpack_file_name)], fixture.mock.commands_executed) fixture.mock.calls = [] @@ -3303,9 +3327,23 @@ prefer_dir = preferred_tools_dir() + hwpack_dir = tempfile.mkdtemp() + hwpack_file_names = ['hwpack1.tgz', 'hwpack2.tgz'] + hwpack_tgz_locations = [] + hwpack_names = [] + for hwpack_file_name in hwpack_file_names: + hwpack_tgz_location = os.path.join(hwpack_dir, hwpack_file_name) + hwpack_tgz_locations.append(hwpack_tgz_location) + hwpack_names.append(hwpack_file_name) + hwpack_version = "4" + hwpack_architecture = "armel" + self.create_minimal_v3_hwpack( + hwpack_tgz_location, hwpack_file_name, hwpack_version, + hwpack_architecture) + install_hwpacks( - chroot_dir, tmp_dir, prefer_dir, force_yes, [], 'hwpack1.tgz', - 'hwpack2.tgz') + chroot_dir, tmp_dir, prefer_dir, force_yes, [], + hwpack_tgz_locations[0], hwpack_tgz_locations[1]) linaro_hwpack_install = find_command( 'linaro-hwpack-install', prefer_dir=prefer_dir) expected = [ @@ -3313,19 +3351,27 @@ 'cp %(linaro_hwpack_install)s %(chroot_dir)s/usr/bin', 'mount proc %(chroot_dir)s/proc -t proc', 'chroot %(chroot_dir)s true', - 'cp hwpack1.tgz %(chroot_dir)s', - ('%(chroot_args)s %(chroot_dir)s linaro-hwpack-install ' - '--force-yes /hwpack1.tgz'), - 'cp hwpack2.tgz %(chroot_dir)s', - ('%(chroot_args)s %(chroot_dir)s linaro-hwpack-install ' - '--force-yes /hwpack2.tgz'), + 'cp %(hwpack1)s %(chroot_dir)s', + ('%(chroot_args)s %(chroot_dir)s linaro-hwpack-install ' + '--hwpack-version %(hp_version)s ' + '--hwpack-arch %(hp_arch)s --hwpack-name %(hp_name1)s' + ' --force-yes /hwpack1.tgz'), + 'cp %(hwpack2)s %(chroot_dir)s', + ('%(chroot_args)s %(chroot_dir)s linaro-hwpack-install ' + '--hwpack-version %(hp_version)s ' + '--hwpack-arch %(hp_arch)s --hwpack-name %(hp_name2)s' + ' --force-yes /hwpack2.tgz'), 'rm -f %(chroot_dir)s/hwpack2.tgz', 'rm -f %(chroot_dir)s/hwpack1.tgz', 'umount -v %(chroot_dir)s/proc', 'rm -f %(chroot_dir)s/usr/bin/linaro-hwpack-install'] keywords = dict( chroot_dir=chroot_dir, tmp_dir=tmp_dir, chroot_args=chroot_args, - linaro_hwpack_install=linaro_hwpack_install) + linaro_hwpack_install=linaro_hwpack_install, + hwpack1=hwpack_tgz_locations[0], + hwpack2=hwpack_tgz_locations[1], + hp_version=hwpack_version, hp_name1=hwpack_names[0], + hp_name2=hwpack_names[1], hp_arch=hwpack_architecture) expected = [ "%s %s" % (sudo_args, line % keywords) for line in expected] self.assertEquals(expected, fixture.mock.commands_executed)