=== modified file 'linaro_image_tools/hwpack/builder.py'
--- linaro_image_tools/hwpack/builder.py	2012-07-23 15:36:00 +0000
+++ linaro_image_tools/hwpack/builder.py	2012-07-23 15:36:47 +0000
@@ -37,11 +37,18 @@
     )
 
 from linaro_image_tools.hwpack.hwpack_fields import (
+    FILE_FIELD,
     PACKAGE_FIELD,
+    SPL_FILE_FIELD,
     SPL_PACKAGE_FIELD,
 )
 
+# The fields that hold packages to be installed.
 PACKAGE_FIELDS = [PACKAGE_FIELD, SPL_PACKAGE_FIELD]
+# The fields that hold values that should be reset to newly calculated ones.
+# The values of the dictionary are the fields whose values should be reset.
+FIELDS_TO_CHANGE = {PACKAGE_FIELD: FILE_FIELD,
+                    SPL_PACKAGE_FIELD: SPL_FILE_FIELD}
 
 
 logger = logging.getLogger(__name__)
@@ -99,6 +106,9 @@
         self.format = self.config.format
         self.version = version
         self.local_debs = local_debs
+        self.package_unpacker = None
+        self.hwpack = None
+        self.packages = None
 
     def find_fetched_package(self, packages, wanted_package_name):
         wanted_package = None
@@ -111,11 +121,10 @@
                                 wanted_package_name)
         return wanted_package
 
-    def add_file_to_hwpack(self, package, wanted_file, package_unpacker,
-                           hwpack, target_path):
-        tempfile_name = package_unpacker.get_file(
+    def add_file_to_hwpack(self, package, wanted_file, target_path):
+        tempfile_name = self.package_unpacker.get_file(
             package.filepath, wanted_file)
-        return hwpack.add_file(target_path, tempfile_name)
+        return self.hwpack.add_file(target_path, tempfile_name)
 
     def find_bootloader_packages(self, bootloaders_config):
         """Loop through the bootloaders dictionary searching for packages
@@ -133,83 +142,140 @@
         # Eliminate duplicates.
         return list(set(boot_packages))
 
+    def _set_new_values(self, config_dictionary):
+        """Loop through the bootloaders sections of a hwpack, also from the
+        boards section, changing the necessary values with the newly calculated
+        ones.
+
+        :param config_dictionary: The dictionary from the Config we need to
+                                    look into.
+        """
+        remove_packages = []
+        for key, value in config_dictionary.iteritems():
+            if isinstance(value, dict):
+                self._set_new_values(value)
+            else:
+                if key in FIELDS_TO_CHANGE.keys():
+                    if key == PACKAGE_FIELD:
+                        # Need to use the correct path for the packages.
+                        path = self.hwpack.U_BOOT_DIR
+                    else:
+                        path = self.hwpack.SPL_DIR
+                    change_field = FIELDS_TO_CHANGE.get(key)
+                    boot_package = value
+                    boot_file = config_dictionary.get(change_field)
+                    if boot_package is not None and boot_file is not None:
+                        package = self.find_fetched_package(
+                                    self.packages,
+                                    boot_package)
+                        file_to_add = self.add_file_to_hwpack(
+                                            package, boot_file, path)
+                        config_dictionary[change_field] = file_to_add
+                        remove_packages.append(package)
+        # Clean up duplicates.
+        for package in remove_packages:
+            if package in self.packages:
+                self.packages.remove(package)
+
     def build(self):
         for architecture in self.config.architectures:
             logger.info("Building for %s" % architecture)
             metadata = Metadata.from_config(
                 self.config, self.version, architecture)
-            hwpack = HardwarePack(metadata)
+            self.hwpack = HardwarePack(metadata)
             sources = self.config.sources
             with LocalArchiveMaker() as local_archive_maker:
-                hwpack.add_apt_sources(sources)
+                self.hwpack.add_apt_sources(sources)
                 sources = sources.values()
-                packages = self.config.packages[:]
+                self.packages = self.config.packages[:]
                 # 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))
+                if self.format.format_as_string == '3.0':
+                    if self.config.bootloaders is not None:
+                        self.packages.extend(self.find_bootloader_packages(
+                                                self.config.bootloaders))
+                    if self.config.boards is not None:
+                        self.packages.extend(self.find_bootloader_packages(
+                                                self.config.boards))
                 else:
                     if self.config.u_boot_package is not None:
-                        packages.append(self.config.u_boot_package)
+                        self.packages.append(self.config.u_boot_package)
                     if self.config.spl_package is not None:
-                        packages.append(self.config.spl_package)
+                        self.packages.append(self.config.spl_package)
                 local_packages = [
                     FetchedPackage.from_deb(deb)
                     for deb in self.local_debs]
                 sources.append(
                     local_archive_maker.sources_entry_for_debs(
                         local_packages, LOCAL_ARCHIVE_LABEL))
-                packages.extend([lp.name for lp in local_packages])
+                self.packages.extend([lp.name for lp in local_packages])
                 logger.info("Fetching packages")
                 fetcher = PackageFetcher(
                     sources, architecture=architecture,
                     prefer_label=LOCAL_ARCHIVE_LABEL)
                 with fetcher:
-                    with PackageUnpacker() as package_unpacker:
+                    with PackageUnpacker() as self.package_unpacker:
                         fetcher.ignore_packages(self.config.assume_installed)
-                        packages = fetcher.fetch_packages(
-                            packages,
+                        self.packages = fetcher.fetch_packages(
+                            self.packages,
                             download_content=self.config.include_debs)
 
-                        u_boot_package = None
-                        if self.config.u_boot_file is not None:
-                            assert self.config.u_boot_package is not None
-                            u_boot_package = self.find_fetched_package(
-                                packages, self.config.u_boot_package)
-                            hwpack.metadata.u_boot = self.add_file_to_hwpack(
-                                u_boot_package, self.config.u_boot_file,
-                                package_unpacker, hwpack, hwpack.U_BOOT_DIR)
-
-                        spl_package = None
-                        if self.config.spl_file is not None:
-                            assert self.config.spl_package is not None
-                            spl_package = self.find_fetched_package(
-                                packages, self.config.spl_package)
-                            hwpack.metadata.spl = self.add_file_to_hwpack(
-                                spl_package, self.config.spl_file,
-                                package_unpacker, hwpack, hwpack.SPL_DIR)
-
-                        # u_boot_package and spl_package can be identical
-                        if (u_boot_package is not None and
-                            u_boot_package in packages):
-                            packages.remove(u_boot_package)
-                        if (spl_package is not None and
-                            spl_package in packages):
-                            packages.remove(spl_package)
+                        # On a v3 hwpack, all the values we need to check are
+                        # in the bootloaders and boards section, so we loop
+                        # through both of them changing what is necessary.
+                        if self.config.format.format_as_string == '3.0':
+                            if self.config.bootloaders is not None:
+                                self._set_new_values(self.config.bootloaders)
+                                metadata.bootloaders = self.config.bootloaders
+                            if self.config.boards is not None:
+                                self._set_new_values(self.config.boards)
+                                metadata.boards = self.config.boards
+                        else:
+                            u_boot_package = None
+                            if self.config.u_boot_file is not None:
+                                assert self.config.u_boot_package is not None
+                                u_boot_package = self.find_fetched_package(
+                                    self.packages,
+                                    self.config.u_boot_package)
+                                self.hwpack.metadata.u_boot = \
+                                    self.add_file_to_hwpack(
+                                        u_boot_package,
+                                        self.config.u_boot_file,
+                                        self.hwpack.U_BOOT_DIR)
+
+                            spl_package = None
+                            if self.config.spl_file is not None:
+                                assert self.config.spl_package is not None
+                                spl_package = self.find_fetched_package(
+                                    self.packages,
+                                    self.config.spl_package)
+                                self.hwpack.metadata.spl = \
+                                    self.add_file_to_hwpack(
+                                        spl_package,
+                                        self.config.spl_file,
+                                        self.hwpack.SPL_DIR)
+
+                            # u_boot_package and spl_package can be identical
+                            if (u_boot_package is not None and
+                                u_boot_package in self.packages):
+                                self.packages.remove(u_boot_package)
+                            if (spl_package is not None and
+                                spl_package in self.packages):
+                                self.packages.remove(spl_package)
 
                         logger.debug("Adding packages to hwpack")
-                        hwpack.add_packages(packages)
+                        self.hwpack.add_packages(self.packages)
                         for local_package in local_packages:
-                            if local_package not in packages:
+                            if local_package not in self.packages:
                                 logger.warning(
                                     "Local package '%s' not included",
                                     local_package.name)
-                        hwpack.add_dependency_package(self.config.packages)
-                        with open(hwpack.filename(), 'w') as f:
-                            hwpack.to_file(f)
-                            logger.info("Wrote %s" % hwpack.filename())
-                        with open(hwpack.filename('.manifest.txt'), 'w') as f:
-                            f.write(hwpack.manifest_text())
+                        self.hwpack.add_dependency_package(
+                                self.config.packages)
+                        with open(self.hwpack.filename(), 'w') as f:
+                            self.hwpack.to_file(f)
+                            logger.info("Wrote %s" % self.hwpack.filename())
+                        with open(self.hwpack.filename('.manifest.txt'),
+                                    'w') as f:
+                            f.write(self.hwpack.manifest_text())

=== modified file 'linaro_image_tools/hwpack/config.py'
--- linaro_image_tools/hwpack/config.py	2012-07-23 14:14:31 +0000
+++ linaro_image_tools/hwpack/config.py	2012-07-23 14:44:37 +0000
@@ -284,6 +284,11 @@
         return self._get_option(BOOTLOADERS_FIELD)
 
     @property
+    def boards(self):
+        """Multiple boards available in the hardware pack."""
+        return self._get_option(BOARDS_FIELD)
+
+    @property
     def uboot_in_boot_part(self):
         """Whether uboot binary should be put in the boot partition. A str."""
         return self._get_bootloader_option(self.UBOOT_IN_BOOT_PART_KEY)

=== modified file 'linaro_image_tools/hwpack/hardwarepack.py'
--- linaro_image_tools/hwpack/hardwarepack.py	2012-07-23 12:04:44 +0000
+++ linaro_image_tools/hwpack/hardwarepack.py	2012-07-23 14:44:37 +0000
@@ -37,13 +37,13 @@
 )
 
 from hwpack_fields import (
+    BOARDS_FIELD,
     BOOTLOADERS_FIELD,
     BOOT_MIN_SIZE_FIELD,
     BOOT_SCRIPT_FIELD,
     DTB_ADDR_FIELD,
     DTB_FILE_FIELD,
     EXTRA_SERIAL_OPTIONS_FIELD,
-    FILE_FIELD,
     FORMAT_FIELD,
     INITRD_ADDR_FIELD,
     INITRD_FILE_FIELD,
@@ -66,7 +66,6 @@
     SAMSUNG_ENV_LEN_FIELD,
     SERIAL_TTY_FIELD,
     SNOWBALL_STARTUP_FILES_CONFIG_FIELD,
-    SPL_FILE_FIELD,
     SUPPORT_FIELD,
     WIRED_INTERFACES_FIELD,
     WIRELESS_INTERFACES_FIELD,
@@ -166,10 +165,13 @@
         self.samsung_bl2_len = samsung_bl2_len
 
     @classmethod
-    def add_v3_config(self, bootloaders):
+    def add_v3_config(self, boards=None, bootloaders=None):
         """Add fields that are specific to the v3 config format.
+        These fields are not present in the earlier config files.
 
+        :param boards: The boards section of the hwpack.
         :param bootloaders: The bootloaders section of the hwpack."""
+        self.boards = boards
         self.bootloaders = bootloaders
 
     @classmethod
@@ -230,7 +232,8 @@
                 wireless_interfaces=config.wireless_interfaces,
                 )
         if config.format.format_as_string == '3.0':
-            metadata.add_v3_config(config.bootloaders)
+            metadata.add_v3_config(boards=config.boards,
+                                    bootloaders=config.bootloaders)
         return metadata
 
     def __str__(self):
@@ -239,25 +242,6 @@
         else:
             return self.create_metadata_old()
 
-    def set_config_value(self, dictionary, search_key, new_value):
-        """Loop recursively through a dictionary looking for the specified key
-        substituting its value.
-        In a metadata file, at least two fields from the Config class have
-        their value calculated during the build phase of the hardware pack.
-        Here those known fiels will be updated with the newly calculated
-        values.
-
-        :param dictionary: The dictionary to loop through.
-        :param search_key: The key to search.
-        :param new_value: The new value for the key.
-        """
-        for key, value in dictionary.iteritems():
-            if key == search_key:
-                dictionary[key] = new_value
-                break
-            elif isinstance(value, dict):
-                self.set_config_value(value, search_key, new_value)
-
     def create_metadata_new(self):
         """Get the contents of the metadata file.
 
@@ -280,17 +264,9 @@
             metadata += dump({MAINTAINER_FIELD: self.maintainer})
         if self.support is not None:
             metadata += dump({SUPPORT_FIELD: self.support})
+        if self.boards is not None:
+            metadata += dump({BOARDS_FIELD: self.boards})
         if self.bootloaders is not None:
-            # XXX We need to do this, since some necessary values are set
-            # when the hwpack archive is built, and are not in the hwpack
-            # config. Since we know which are the keys we have to look for,
-            # we just loop through all of them.
-            if self.spl is not None:
-                self.set_config_value(self.bootloaders, SPL_FILE_FIELD,
-                                               self.spl)
-            if self.u_boot is not None:
-                self.set_config_value(self.bootloaders, FILE_FIELD,
-                                                self.u_boot)
             metadata += dump({BOOTLOADERS_FIELD: self.bootloaders})
         if self.serial_tty is not None:
             metadata += dump({SERIAL_TTY_FIELD: self.serial_tty})

=== modified file 'linaro_image_tools/hwpack/tests/test_hardwarepack.py'
--- linaro_image_tools/hwpack/tests/test_hardwarepack.py	2012-07-19 14:50:45 +0000
+++ linaro_image_tools/hwpack/tests/test_hardwarepack.py	2012-07-23 14:44:37 +0000
@@ -342,50 +342,6 @@
                         "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):
 

