=== modified file 'linaro_image_tools/hwpack/builder.py'
@@ -97,7 +97,7 @@
def __init__(self, config_path, version, local_debs):
try:
with open(config_path) as fp:
- self.config = Config(fp)
+ self.config = Config(fp, allow_unset_bootloader=True)
except IOError, e:
if e.errno == errno.ENOENT:
raise ConfigFileMissing(config_path)
@@ -109,6 +109,7 @@
self.package_unpacker = None
self.hwpack = None
self.packages = None
+ self.packages_added_to_hwpack = []
def find_fetched_package(self, packages, wanted_package_name):
wanted_package = None
@@ -122,8 +123,13 @@
return wanted_package
def add_file_to_hwpack(self, package, wanted_file, target_path):
+ if (package.name, target_path) in self.packages_added_to_hwpack:
+ # Don't bother adding the same package more than once.
+ return
+
tempfile_name = self.package_unpacker.get_file(
package.filepath, wanted_file)
+ self.packages_added_to_hwpack.append((package.name, target_path))
return self.hwpack.add_file(target_path, tempfile_name)
def find_bootloader_packages(self, bootloaders_config):
@@ -150,7 +156,6 @@
: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)
@@ -171,11 +176,6 @@
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:
=== modified file 'linaro_image_tools/hwpack/config.py'
@@ -117,11 +117,14 @@
BOOTLOADER_DD_KEY = 'u_boot_dd'
translate_v2_to_v3[BOOTLOADER_DD_KEY] = DD_FIELD
- def __init__(self, fp, bootloader=None, board=None):
+ def __init__(self, fp, bootloader=None, board=None,
+ allow_unset_bootloader=False):
"""Create a Config.
:param fp: a file-like object containing the configuration.
"""
+ self.allow_unset_bootloader = allow_unset_bootloader
+ self.bootloader = None
obfuscated_e = None
obfuscated_yaml_e = ""
try:
@@ -178,6 +181,23 @@
"""Set board used to look up per-board configuration"""
self.board = board
+ def get_bootloader_list(self):
+ if isinstance(self.bootloaders, dict):
+ # We have a list of bootloaders in the expected format
+ return self.bootloaders.keys()
+ return []
+
+ def validate_bootloader_fields(self):
+ self._validate_bootloader_package()
+ self._validate_bootloader_file()
+ self._validate_spl_package()
+ self._validate_spl_file()
+ self._validate_bootloader_file_in_boot_part()
+ self._validate_bootloader_dd()
+ self._validate_spl_in_boot_part()
+ self._validate_spl_dd()
+ self._validate_env_dd()
+
def validate(self):
"""Check that this configuration follows the schema.
@@ -196,8 +216,15 @@
self._validate_assume_installed()
if self.format.has_v2_fields:
- self._validate_bootloader_package()
- self._validate_bootloader_file()
+ # Check config for all bootloaders if one isn't specified.
+ if self.bootloader == None and self._is_v3:
+ for bootloader in self.get_bootloader_list():
+ self.set_bootloader(bootloader)
+ self.validate_bootloader_fields()
+ self.set_bootloader(None)
+ else:
+ self.validate_bootloader_fields()
+
self._validate_serial_tty()
self._validate_kernel_addr()
self._validate_initrd_addr()
@@ -210,19 +237,12 @@
self._validate_root_min_size()
self._validate_loader_min_size()
self._validate_loader_start()
- self._validate_spl_package()
- self._validate_spl_file()
self._validate_vmlinuz()
self._validate_initrd()
self._validate_dtb_file()
self._validate_mmc_id()
self._validate_extra_boot_options()
self._validate_boot_script()
- self._validate_bootloader_file_in_boot_part()
- self._validate_bootloader_dd()
- self._validate_spl_in_boot_part()
- self._validate_spl_dd()
- self._validate_env_dd()
self._validate_extra_serial_opts()
self._validate_snowball_startup_files_config()
self._validate_samsung_bl1_start()
@@ -342,6 +362,8 @@
"""Get an option inside the current bootloader section."""
if self._is_v3:
if not self.bootloader:
+ if self.allow_unset_bootloader:
+ return None
raise ValueError("bootloader not set.")
if not isinstance(key, list):
keys = [key]
=== modified file 'linaro_image_tools/hwpack/testing.py'
@@ -336,18 +336,18 @@
def __init__(self, metadata, packages, sources,
packages_without_content=None,
- package_spec=None):
+ package_spec=None, format="1.0"):
self.metadata = metadata
self.packages = packages
self.sources = sources
self.packages_without_content = packages_without_content or []
self.package_spec = package_spec
+ self.format = format + "\n"
def match(self, path):
- tf = tarfile.open(name=path, mode="r:gz")
- try:
+ with tarfile.open(name=path, mode="r:gz") as tf:
matchers = []
- matchers.append(HardwarePackHasFile("FORMAT", content="1.0\n"))
+ matchers.append(HardwarePackHasFile("FORMAT", content=self.format))
matchers.append(HardwarePackHasFile(
"metadata", content=str(self.metadata)))
manifest_lines = []
@@ -398,8 +398,6 @@
matchers.append(HardwarePackHasFile(
"sources.list.d.gpg", type=tarfile.DIRTYPE))
return MatchesAll(*matchers).match(tf)
- finally:
- tf.close()
def __str__(self):
return "Is a valid hardware pack."
=== modified file 'linaro_image_tools/hwpack/tests/test_config.py'
@@ -66,8 +66,8 @@
e = self.assertRaises(HwpackConfigError, f, *args, **kwargs)
self.assertEqual(contents, str(e))
- def assertValidationError(self, contents, config):
- self.assertConfigError(contents, config.validate)
+ def assertValidationError(self, contents, config, function="validate"):
+ self.assertConfigError(contents, config.get_option(function))
def test_validate_no_hwpack_section(self):
config = self.get_config("")
@@ -219,7 +219,8 @@
"u-boot-file = u-boot.bin\n" \
"partition_layout = bootfs_rootfs\n"\
"kernel_file = ~~\n")
- self.assertValidationError("Invalid path: ~~", config)
+ self.assertValidationError("Invalid path: ~~", config,
+ "_validate_vmlinuz")
def test_validate_empty_kernel_file(self):
config = self.get_config(self.valid_start_v2 +
@@ -228,7 +229,7 @@
"partition_layout = bootfs_rootfs\n"\
"kernel_file = \n")
self.assertValidationError("No kernel_file in the [hwpack] section",
- config)
+ config, "_validate_vmlinuz")
def test_validate_invalid_initrd_file(self):
config = self.get_config(
@@ -238,7 +239,8 @@
"partition_layout = bootfs_rootfs\n"\
"kernel_file = boot/vmlinuz-3.0.0-1002-linaro-omap\n"\
"initrd_file = ~~\n")
- self.assertValidationError("Invalid path: ~~", config)
+ self.assertValidationError("Invalid path: ~~", config,
+ "_validate_initrd")
def test_validate_empty_initrd_file(self):
config = self.get_config(
@@ -249,7 +251,7 @@
"kernel_file = boot/vmlinuz-3.0.0-1002-linaro-omap\n"\
"initrd_file = \n")
self.assertValidationError("No initrd_file in the [hwpack] section",
- config)
+ config, "_validate_initrd")
def test_validate_invalid_boot_script(self):
config = self.get_config(
@@ -309,7 +311,8 @@
"Undefined partition layout %s in the [%s] section. "
"Valid partition layouts are %s."
% (partition_layout, 'hwpack',
- ", ".join(DEFINED_PARTITION_LAYOUTS)), config)
+ ", ".join(DEFINED_PARTITION_LAYOUTS)), config,
+ "_validate_partition_layout")
def test_validate_wired_interfaces(self):
self.assertTrue("XXX What is an invalid interface name?")
@@ -350,13 +353,15 @@
self.valid_start_v2 +
"u_boot_package = u-boot-linaro-s5pv310\n" \
"u_boot_file = u-boot.bin\nserial_tty=tty\n")
- self.assertValidationError("Invalid serial tty: tty", config)
+ self.assertValidationError("Invalid serial tty: tty", config,
+ "_validate_serial_tty")
config = self.get_config(
self.valid_start_v2 +
"u_boot_package = u-boot-linaro-s5pv310\n" \
"u_boot_file = u-boot.bin\n" \
"serial_tty=ttxSAC1\n")
- self.assertValidationError("Invalid serial tty: ttxSAC1", config)
+ self.assertValidationError("Invalid serial tty: ttxSAC1", config,
+ "_validate_serial_tty")
def test_validate_mmc_id(self):
config = self.get_config(self.valid_complete_v2 +
=== modified file 'linaro_image_tools/hwpack/tests/test_config_v3.py'
@@ -315,6 +315,23 @@
config._validate_bootloader_file_in_boot_part()
self.assertEqual(config.bootloader_file_in_boot_part, "yes")
+ def test_multiple_bootloaders(self):
+ config = self.get_config(
+ self.valid_start_v3 +
+ "bootloaders:\n"
+ " u_boot:\n"
+ " in_boot_part: No\n"
+ " anotherboot:\n"
+ " in_boot_part: Yes\n")
+
+ config.set_bootloader("u_boot")
+ config._validate_bootloader_file_in_boot_part()
+ self.assertEqual(config.bootloader_file_in_boot_part, "no")
+
+ config.set_bootloader("anotherboot")
+ config._validate_bootloader_file_in_boot_part()
+ self.assertEqual(config.bootloader_file_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",
=== modified file 'linaro_image_tools/hwpack/tests/test_script.py'
@@ -31,8 +31,11 @@
DummyFetchedPackage,
IsHardwarePack,
)
+from linaro_image_tools.hwpack.config import Config
from linaro_image_tools.testing import TestCaseWithFixtures
from linaro_image_tools.utils import find_command
+import os
+from StringIO import StringIO
class ScriptTests(TestCaseWithFixtures):
@@ -40,7 +43,26 @@
def setUp(self):
super(ScriptTests, self).setUp()
- self.script_path = find_command("linaro-hwpack-create")
+
+ # Work out root of checkout.
+ # We do this here because when running in PyCharm
+ # the assumption in find_command that os.path.isabs(__file__) is
+ # only true when not running from a Bazaar checkout is broken.
+ # Thankfully find_command allows us to work around this by specifying
+ # prefer_dir.
+ dir = os.path.dirname(__file__)
+ while True:
+ path = os.path.join(dir, "linaro-hwpack-create")
+ if dir == "/" or dir == "":
+ # Didn't find linaro-media-create. Continue as if we haven't
+ # tried to work out prefer_dir.
+ dir = None
+ break
+ if os.path.exists(path) and os.access(path, os.X_OK):
+ break
+ dir = os.path.split(dir)[0]
+
+ self.script_path = find_command("linaro-hwpack-create", prefer_dir=dir)
self.useFixture(ChdirToTempdirFixture())
def run_script(self, args, expected_returncode=0):
@@ -92,6 +114,70 @@
{"ubuntu": source.sources_entry},
package_spec=package_name))
+ def test_builds_a_v3_hwpack_from_config_with_2_bootloaders(self):
+ config_v3 = ("format: 3.0\n"
+ "name: ahwpack\n"
+ "architectures: armel\n"
+ "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"
+ "packages:\n"
+ " - %s\n"
+ " - %s\n")
+ bootloader_config = (" package: %s\n"
+ " in_boot_part: %s\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")
+
+ config_v3 += ("bootloaders:\n"
+ " u_boot:\n" + bootloader_config +
+ " u_boot_2:\n" + bootloader_config)
+
+ config_v3 += ("sources:\n"
+ " ubuntu: %s\n")
+
+ package_names = ['foo', 'bar']
+ available_packages = []
+ for package_name in package_names:
+ available_packages.append(
+ DummyFetchedPackage(package_name, "1.1", architecture="armel"))
+ source = self.useFixture(AptSourceFixture(available_packages))
+
+ config_v3 = config_v3 % (package_names[0], package_names[1],
+ package_names[0], "True",
+ package_names[1], "False",
+ source.sources_entry)
+
+ config_file_fixture = self.useFixture(ConfigFileFixture(config_v3))
+ self.run_script([config_file_fixture.filename, "1.0"])
+
+ # We now need a real config object to test against the configuration
+ # in the hardware pack we have created.
+ config = Config(StringIO(config_v3))
+ config.set_bootloader("u_boot")
+ metadata = Metadata.from_config(config, "1.0", "armel")
+ self.assertThat(
+ "hwpack_ahwpack_1.0_armel.tar.gz",
+ IsHardwarePack(
+ metadata, available_packages,
+ {"ubuntu": source.sources_entry},
+ package_spec=",".join(package_names),
+ format="3.0"))
+
def test_log_output(self):
package_name = 'foo'
architecture = 'armel'