Merge lp:~milo/linaro-image-tools/multiple-boards-support into lp:linaro-image-tools/11.11

Proposed by Milo Casagrande
Status: Merged
Merged at revision: 537
Proposed branch: lp:~milo/linaro-image-tools/multiple-boards-support
Merge into: lp:linaro-image-tools/11.11
Diff against target: 3318 lines (+1824/-388)
15 files modified
linaro-hwpack-install (+20/-5)
linaro_image_tools/hwpack/builder.py (+35/-4)
linaro_image_tools/hwpack/config.py (+490/-205)
linaro_image_tools/hwpack/hardwarepack.py (+194/-25)
linaro_image_tools/hwpack/hardwarepack_format.py (+9/-0)
linaro_image_tools/hwpack/hwpack_convert.py (+15/-3)
linaro_image_tools/hwpack/hwpack_fields.py (+3/-0)
linaro_image_tools/hwpack/tests/__init__.py (+1/-0)
linaro_image_tools/hwpack/tests/test_config.py (+10/-8)
linaro_image_tools/hwpack/tests/test_config_v3.py (+738/-0)
linaro_image_tools/hwpack/tests/test_hardwarepack.py (+177/-86)
linaro_image_tools/hwpack/tests/test_hwpack_converter.py (+24/-0)
linaro_image_tools/media_create/boards.py (+27/-27)
linaro_image_tools/media_create/chroot_utils.py (+12/-2)
linaro_image_tools/media_create/tests/test_media_create.py (+69/-23)
To merge this branch: bzr merge lp:~milo/linaro-image-tools/multiple-boards-support
Reviewer Review Type Date Requested Status
Данило Шеган (community) Needs Fixing
Stevan Radaković Pending
Linaro Infrastructure Pending
Review via email: mp+115991@code.launchpad.net

Description of the change

Finally, after small and tricky problems, the final code.

Diff might be a little bit bigger than expected, bzr didn't like one merge and we had to remove some files, that had been renamed.

There are also small tweaks done in the converter.

What we have here is:
 - Multiple bootloaders in the hwpack and in the hwpack config, all V3
 - Multiple boards in the hwpack config V3
 - Safe handling of both old and new syntax in the Config class, with tests for both
 - New metadata format for new hwpack confing syntax (always YAML based, but slightly different from the hwpack config one, in order to be able to parse it easier inside the linaro-hwpack-install bash script)
 - Safe use of V2 hwpack configuration file and creation of V2 hwpack archive; safe use of a converted V3 configuration file and creation of a V3 hwpack archive: images get created, and boot (at least with pandaboard)

What we are missing at the moment:
 - Choosing the right bootloader: we need a real example of one, so that we can create a real hwpack archive, and test it out
 - With reference to the BP: we do not have yet the hwpack probing system, the board selection is still hardcoded (but it should'nt be hard to conver it), ther bootloader selection is not there.

It might also be good to know what is supposed to happen with the install, in order to understand if something is broken or not.

To post a comment you must log in.
Revision history for this message
Данило Шеган (danilo) wrote :
Download full text (12.8 KiB)

Hey Milo,

Thanks for putting the extra effort to make this happen. This includes
James as well :)

Overall, the changes are great.

My main gripe is that I am seeing a huge branch like this. I still
can't see why this was not done in several branches: one to parse the
new hwpack config, another to produce the new hwpacks and the third one
to port l-m-c to use them.

Also, a BP workitems are still out of date I believe.

> === modified file 'linaro-hwpack-convert'
> --- linaro-hwpack-convert 2012-07-19 15:21:06 +0000
> +++ linaro-hwpack-convert 2012-07-20 14:12:31 +0000
> @@ -31,6 +31,7 @@
> HwpackConverterException,
> check_and_validate_args,
> )
> +from linaro_image_tools.hwpack.builder import ConfigFileMissing
> from linaro_image_tools.__version__ import __version__

This change looks unnecessary (judging by the diff itself). If it's
not, something was badly broken before :)

> === modified file 'linaro-hwpack-install'
...
> @@ -111,6 +111,68 @@
> tar zxf "$HWPACK_TARBALL" -C "$HWPACK_DIR"
> echo "Done"
>
> +function query_v3_metadata {
> + python -c "import re
> +with open('${HWPACK_DIR}/metadata') as configv3:
> + config = {} # Will store decoded YAML in here
> + root = config # Current insert point for adding data
> + root_at_indent = {}
> + indent = 0
> + for line in configv3.readlines():
> + key_value = re.search('^(\s*)(\S.+):\s+(.+)\s*$', line)
> + key_match = re.search('^(\s*)(\S.+):\s*$', line)
> + list_item = re.search('^(\s*)-\s*(.+)\s*$', line)
> +
> + if key_value:
> + new_indent = len(key_value.group(1))
> + elif key_match:
> + new_indent = len(key_match.group(1))
> + elif list_item:
> + new_indent = len(list_item.group(1))
> +
> + if new_indent < indent: #Indent decreases: go back up config structure
> + root = root_at_indent[new_indent]
> + elif new_indent > indent: # Indent increases: reset root (insert point)
> + root_at_indent[indent] = root
> + root = root[key]
> + indent = new_indent
> +
> + if key_value: # key: value
> + key = key_value.group(2)
> + root[key] = key_value.group(3)
> + elif key_match: # key:
> + key = key_match.group(2)
> + root[key] = {}
> + elif list_item: # - value
> + # If the list has extra indentation then root == {}
> + # If the list doesn't have extra indentation, root = {key: {}}
> + # We need to create a list in that empty dictionary. Work out
> + # where it is, assign it to insert_point.
> + insert_point = None
> + if root == {}:
> + insert_point = root
> + keys = root.keys()
> + if len(keys) == 1:
> + insert_point = root[keys[0]]
> +
> + if insert_point == {}:
> + insert_point[''] = []
> +
> + insert_point[''].append(list_item.group(2))
> +
> + keys = '$1'.split(' ')
> + for key in keys:
> + if isinstance(config, list):
> + key = int(key)
> + config = config[key]
> + ...

review: Needs Fixing
543. By Milo Casagrande

Removed unnecessary import.

544. By Milo Casagrande

Renamed method and args.

Revision history for this message
Paul Sokolovsky (pfalcon) wrote :

I can relate to Danilo's note that this merge request is huge. I had a look by the end of day on Friday, I thought I'd take quite a time to review it.

Some comments (not necessarily shows a problem, just something which caught my attention, partly may be due to fact that I'm reading diff vs flat code).

1. Inline python code in shell script linaro-hwpack-install looks a bit hacky IMHO. That's why I'm telling me "don't hack with shell for anything serious, start with Python right away". Nope, I understand that rewriting the whole script would add just more diff noise, but I hope the alternative of making this a separate aux script was considered. And I'd at least add comment for "keys = '$1'.split(' ')" line that $1 is being replaced by shell (and probably at the beginning of sub-script that doublequotes should not be used).

2. hwpack/config.py: I'd add comments for the purpose of translate_v2_to_v3/translate_v2_metadata. Also, IMHO initting them in one go with literal dictionary (vs multiple subscript assignments spread around) would make it clearer. (Again, may be artifact of me looking at the diff.)

3. obfuscated_e and friends - thumbs up for initing it a the beginning of the function, but you touched it in may lines already, so might have been possible to rename it to something, well, less obfuscated ;-).

4. 1459 + """Loop recursively thorugh a dictionary looking for the specified key

Typo ("thorugh")

:param serach_key: The key to search.

Ditto

5. hwpack/tests/test_hardwarepack.py: I'm not sure what's the logic applied there, but many of the changes appear to be semantically-null, just code reformatting, or put another way, spurious changes in the contexts of the functionality being implemented and already large patch size.

Revision history for this message
James Tunnicliffe (dooferlad) wrote :

On 21 July 2012 07:55, Данило Шеган <email address hidden> wrote:

Thanks for the review. Enjoy your break :-)

>> === modified file 'linaro-hwpack-install'
> ...
>> @@ -111,6 +111,68 @@
>> tar zxf "$HWPACK_TARBALL" -C "$HWPACK_DIR"
>> echo "Done"
>>
>> +function query_v3_metadata {
>> + python -c "import re
...
>> + print config
>> + "
>> +}
>
> Since we have a requirement for Python, I don't think it's too much to
> add a depedency on python-yaml as well: it's not a big deal, and should
> allow us to simplify the code above by a significant margin.
>
> Especially since we are using only a few top-level config values.

The problem is that we need to bootstrap package installation. A few
lines down we actually add apt sources that would allow us to install
python-yaml, which then brings with it several more packages. We start
off from an ubuntu-minimal image (I think) and that doesn't seem to
have a full python install.

The following extra packages will be installed:
  libexpat1 libyaml-0-2 mime-support python python2.7
Suggested packages:
  python-doc python-tk python2.7-doc binutils
The following NEW packages will be installed:
  libexpat1 libyaml-0-2 mime-support python python-yaml python2.7
0 upgraded, 6 newly installed, 0 to remove and 99 not upgraded.
Need to get 2942 kB/3045 kB of archives.
After this operation, 9796 kB of additional disk space will be used.
WARNING: The following packages cannot be authenticated!
  libexpat1

We can't install these packages before we need python-yaml because we
inspect the metadata file for the architecture that the hardware pack
supports is the same as the architecture that dpkg is reporting.

The idea was to get enough YAML parsing done to pull out the values we
need in the shell script before re-implementing it in python
completely. It looks like it would have to be quite minimal python,
but that shouldn't be a problem (and probably make it a lot easier to
debug).

There is an alternative solution, which I hadn't thought of before -
we could pass parameters to linaro-hwpack-install from the main
linaro-media-create process (where we have a full python install and
all our config parsing magic) for the values we pull out of the
configuration files. Should be the least error prone and most reliable
way of getting those values.

>> @@ -125,7 +187,17 @@
>> "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_VERSION=`grep VERSION "${HWPACK_DIR}/metadata" | cut -d "=" -f2`
>> +if [ "$HWPACK_VERSION" = "" ]; then
>> + HWPACK_VERSION=$(query_v3_metadata 'version')
>> +fi
>> +
>
> Any reason not to use $hwpack_format above, just like it's done below?
> (I'd understand it if we used HWPACK_VERSION below as well, but like
> this, it doesn't make much sense to me)

Good point.

Will respond to other points after I have tidied this up.

--
James Tunnicliffe

Revision history for this message
Milo Casagrande (milo) wrote :
Download full text (6.7 KiB)

Hello Danilo,

thanks for the review!

On Sat, Jul 21, 2012 at 8:55 AM, Данило Шеган <email address hidden> wrote:
>
> My main gripe is that I am seeing a huge branch like this. I still
> can't see why this was not done in several branches: one to parse the
> new hwpack config, another to produce the new hwpacks and the third one
> to port l-m-c to use them.
>
> Also, a BP workitems are still out of date I believe.
>
>> === modified file 'linaro-hwpack-convert'
>> --- linaro-hwpack-convert 2012-07-19 15:21:06 +0000
>> +++ linaro-hwpack-convert 2012-07-20 14:12:31 +0000
>> @@ -31,6 +31,7 @@
>> HwpackConverterException,
>> check_and_validate_args,
>> )
>> +from linaro_image_tools.hwpack.builder import ConfigFileMissing
>> from linaro_image_tools.__version__ import __version__
>
> This change looks unnecessary (judging by the diff itself). If it's
> not, something was badly broken before :)

It is unnecessary, indeed.
Fixed and pushed.

>> logger = logging.getLogger(__name__)
>>
>> @@ -110,6 +117,22 @@
>> package.filepath, wanted_file)
>> return hwpack.add_file(target_path, tempfile_name)
>>
>> + def loop_bootloaders(self, dictionary):
>> + """Loop through the bootloaders dictionary searching for packages
>> + that should be installed, based on known keywords.
>> +
>> + :param dictionary: The bootloaders dictionary to loop through.
>
> Is the "dictionary" actually a bootloaders config section? If it is,
> what do you think of naming the method argument "bootloaders_config"?

Yes, it is the bootloaders section. Renamed to clearly state that.

>> + :return A list of packages, without duplicates."""
>> + boot_packages = []
>> + for key, value in dictionary.iteritems():
>> + if isinstance(value, dict):
>> + boot_packages.extend(self.loop_bootloaders(value))
>
> Wow, do we actually support recursive nesting of bootloaders?

Hmmm... kind of. The YAML structure could be something like this too:

boards:
 a_board:
  bootloaders: # this is specific for the board
   u_boot:
    file: a_file
bootloaders: # this is external, and is general for the whole hwpack config
 uefi:
  pacakge: a
 uboot:
  package: b

so we have multiple bootloaders section, each more specific than the others.

> Also,
> this method would probably be better named "find_bootloader_packages".

Done, and pushed.

>> === modified file 'linaro_image_tools/hwpack/hardwarepack.py'
>> @@ -127,6 +166,10 @@
>> self.samsung_bl2_len = samsung_bl2_len
>>
>> @classmethod
>> + def add_v3_config(self, bootloaders):
>> + self.bootloaders = bootloaders
>
> This is entirely unclear. What's going on here?

Basically, that method is called only during the construction of the
metadata file, starting from a Config object, during the build of the
hwpack archive. The args of that method should be specific to the v3
of the hwpack config.
If we are using a v3 hwpack config converted from a v2 config, we
might have a bootloaders section in the file (since it will not have a
boards section).

> Please add a docstring. Btw, are not the number of boards another new
> th...

Read more...

545. By Milo Casagrande

Fixed method name, typos, removed unnecessary comments.

Revision history for this message
Milo Casagrande (milo) wrote :

> > +class HardwarePackFormatV3(HardwarePackFormat):
> > + def __init__(self):
> > + super(HardwarePackFormatV3, self).__init__()
> > + self.format_as_string = "3.0"
> > + self.is_supported = True
> > + self.is_deprecated = False
> > + self.has_v2_fields = True
>
> Let's set is_deprecated for v2 formats, though let's just file a bug to
> do that next cycle after v3 stabilises a bit. At that same time, we
> should get rid of v1 format support since that's been deprecated for
> quite a while now.

Bug opened, it is 1027903.

546. By Milo Casagrande

Renamed method.

547. By Milo Casagrande

Fixed method name.

548. By Milo Casagrande

Fixed _get_v3_option.

Revision history for this message
Milo Casagrande (milo) wrote :

> > === modified file 'linaro_image_tools/hwpack/config.py'
>
> > + def _yes_no(self, value):
> > + """Convert value, treated as boolean, to string "yes" or "no"."""
>
> I'd prefer all the methods to have a name that reflects what they do:
> "bool_to_string" might be better.

Fixed.

> > +
> > + def _addr(self, value):
> > + """Convert value to 8 character hex string"""
>
> No reason to shorten this (it only saves a few characters).
> "hex_address" sounds better to me.

Fixed that too.

> > + 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)
> > + try:
> > + result = result.get(key)
> > + if result == None: # False is a valid boolean value...
>
> Please do not use inline comments. Also, I am not sure I understand the
> comment :)
>
> > + return None
> > + except ConfigParser.NoOptionError:
> > + return None
>
> I doubt we ever get here. result.get(key) should, by default, return
> None if the key doesn't exist. If you want to make this more explicit,
> you can instead pass the default value in:
>
> result = result.get(key, None)

This should now be fixed. Also, worth noting, we should never get a ConfigParser type of error, since there we are on a v3 hwpack, so it should be a YAML parser.

549. By Milo Casagrande

Merged from James.

550. By Milo Casagrande

Merged from James.

Revision history for this message
Milo Casagrande (milo) wrote :

With the latest merge with James fixes, basically all of the previous concerns have been addressed.
The only thing missing, but that does not change functionalities, is the getattr part, that we didn't really get what should be done.

Since there is nothing big, we will do the merge.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'linaro-hwpack-install'
2--- linaro-hwpack-install 2012-07-05 14:44:04 +0000
3+++ linaro-hwpack-install 2012-07-23 15:38:20 +0000
4@@ -41,7 +41,7 @@
5 FORCE_YES="no"
6 SOURCES_LIST_FILE="${TEMP_DIR}/sources.list"
7 APT_GET_OPTIONS="Dir::Etc::SourceList=${SOURCES_LIST_FILE}"
8-SUPPORTED_FORMATS="1.0 2.0" # A space-separated list of hwpack formats.
9+SUPPORTED_FORMATS="1.0 2.0 3.0" # A space-separated list of hwpack formats.
10
11 sudo="sudo"
12 if [ $(id -u) -eq 0 ]; then
13@@ -53,12 +53,15 @@
14 exit 1
15 }
16
17-usage_msg="Usage: $(basename $0) [--install-latest] [--force-yes] HWPACK_TARBALL"
18+usage_msg="Usage: $(basename $0) [--install-latest] [--force-yes] --hwpack-version <version> --hwpack-arch <architecture> --hwpack-name <name> HWPACK_TARBALL"
19 if [ $# -eq 0 ]; then
20 die $usage_msg
21 fi
22
23 HWPACK_TARBALL_FOUND="no"
24+HWPACK_VERSION=""
25+HWPACK_ARCH=""
26+HWPACK_NAME=""
27
28 while [ $# -gt 0 ]; do
29 case "$1" in
30@@ -68,6 +71,18 @@
31 --force-yes)
32 FORCE_YES="yes"
33 shift;;
34+ --hwpack-version)
35+ HWPACK_VERSION=$2
36+ shift;
37+ shift;;
38+ --hwpack-arch)
39+ HWPACK_ARCH=$2
40+ shift;
41+ shift;;
42+ --hwpack-name)
43+ HWPACK_NAME=$2
44+ shift;
45+ shift;;
46 --*)
47 die $usage_msg "\nUnrecognized option: \"$1\"";;
48 *)
49@@ -79,6 +94,9 @@
50 done
51
52 [ "$HWPACK_TARBALL_FOUND" = "no" ] && die $usage_msg
53+[ "$HWPACK_VERSION" = "" ] && die $usage_msg
54+[ "$HWPACK_ARCH" = "" ] && die $usage_msg
55+[ "$HWPACK_NAME" = "" ] && die $usage_msg
56
57 # Try to acquire fd #9 (i.e. /var/lock/hwpack) for 2 seconds.
58 # Using 9 as the file descriptor because of https://launchpad.net/bugs/249620
59@@ -125,7 +143,6 @@
60 "Try using a newer version of $(basename $0)."
61
62 # Check the architecture of the hwpack matches that of the host system.
63-HWPACK_ARCH=`grep ARCHITECTURE "${HWPACK_DIR}/metadata" | cut -d "=" -f2`
64 [ "$HWPACK_ARCH" == `dpkg --print-architecture` ] || \
65 die "Hardware pack architecture ($HWPACK_ARCH) does not match the host's architecture"
66
67@@ -209,8 +226,6 @@
68 # For "older" hwpacks that don't have a dependency package, we just
69 # manually install the contents of the hwpack.
70
71-HWPACK_NAME=`grep NAME "${HWPACK_DIR}/metadata" | cut -d "=" -f2`
72-HWPACK_VERSION=`grep VERSION "${HWPACK_DIR}/metadata" | cut -d "=" -f2`
73 dependency_package="hwpack-${HWPACK_NAME}"
74 if grep -q "^${dependency_package}=${HWPACK_VERSION}\$" "${HWPACK_DIR}"/manifest; then
75 DEP_PACKAGE_PRESENT="yes"
76
77=== modified file 'linaro_image_tools/hwpack/builder.py'
78--- linaro_image_tools/hwpack/builder.py 2012-06-13 14:53:32 +0000
79+++ linaro_image_tools/hwpack/builder.py 2012-07-23 15:38:20 +0000
80@@ -36,6 +36,13 @@
81 PackageFetcher,
82 )
83
84+from linaro_image_tools.hwpack.hwpack_fields import (
85+ PACKAGE_FIELD,
86+ SPL_PACKAGE_FIELD,
87+)
88+
89+PACKAGE_FIELDS = [PACKAGE_FIELD, SPL_PACKAGE_FIELD]
90+
91
92 logger = logging.getLogger(__name__)
93
94@@ -110,6 +117,22 @@
95 package.filepath, wanted_file)
96 return hwpack.add_file(target_path, tempfile_name)
97
98+ def find_bootloader_packages(self, bootloaders_config):
99+ """Loop through the bootloaders dictionary searching for packages
100+ that should be installed, based on known keywords.
101+
102+ :param bootloaders_config: The bootloaders dictionary to loop through.
103+ :return A list of packages, without duplicates."""
104+ boot_packages = []
105+ for key, value in bootloaders_config.iteritems():
106+ if isinstance(value, dict):
107+ boot_packages.extend(self.find_bootloader_packages(value))
108+ else:
109+ if key in PACKAGE_FIELDS:
110+ boot_packages.append(value)
111+ # Eliminate duplicates.
112+ return list(set(boot_packages))
113+
114 def build(self):
115 for architecture in self.config.architectures:
116 logger.info("Building for %s" % architecture)
117@@ -121,10 +144,18 @@
118 hwpack.add_apt_sources(sources)
119 sources = sources.values()
120 packages = self.config.packages[:]
121- if self.config.u_boot_package is not None:
122- packages.append(self.config.u_boot_package)
123- if self.config.spl_package is not None:
124- packages.append(self.config.spl_package)
125+ # Loop through multiple bootloaders.
126+ # In V3 of hwpack configuration, all the bootloaders info and
127+ # packages are in the bootloaders section.
128+ if self.config.format.format_as_string == '3.0':
129+ if self.config.bootloaders:
130+ packages.extend(self.find_bootloader_packages(
131+ self.config.bootloaders))
132+ else:
133+ if self.config.u_boot_package is not None:
134+ packages.append(self.config.u_boot_package)
135+ if self.config.spl_package is not None:
136+ packages.append(self.config.spl_package)
137 local_packages = [
138 FetchedPackage.from_deb(deb)
139 for deb in self.local_debs]
140
141=== modified file 'linaro_image_tools/hwpack/config.py'
142--- linaro_image_tools/hwpack/config.py 2012-06-13 14:53:32 +0000
143+++ linaro_image_tools/hwpack/config.py 2012-07-23 15:38:20 +0000
144@@ -20,14 +20,68 @@
145 # USA.
146
147 import ConfigParser
148+from operator import attrgetter
149 import re
150 import string
151+import yaml
152
153 from linaro_image_tools.hwpack.hardwarepack_format import (
154 HardwarePackFormatV1,
155 HardwarePackFormatV2,
156+ HardwarePackFormatV3,
157 )
158
159+from hwpack_fields import (
160+ ARCHITECTURES_FIELD,
161+ ARCHITECTURE_FIELD,
162+ ASSUME_INSTALLED_FIELD,
163+ BOARDS_FIELD,
164+ BOOTLOADERS_FIELD,
165+ BOOT_MIN_SIZE_FIELD,
166+ BOOT_SCRIPT_FIELD,
167+ DD_FIELD,
168+ DTB_ADDR_FIELD,
169+ DTB_FILE_FIELD,
170+ ENV_DD_FIELD,
171+ EXTRA_BOOT_OPTIONS_FIELD,
172+ EXTRA_SERIAL_OPTIONS_FIELD,
173+ FILE_FIELD,
174+ FORMAT_FIELD,
175+ INCLUDE_DEBS_FIELD,
176+ IN_BOOT_PART_FIELD,
177+ INITRD_ADDR_FIELD,
178+ INITRD_FILE_FIELD,
179+ KERNEL_ADDR_FIELD,
180+ KERNEL_FILE_FIELD,
181+ LOAD_ADDR_FIELD,
182+ LOADER_MIN_SIZE_FIELD,
183+ LOADER_START_FIELD,
184+ MAINTAINER_FIELD,
185+ MMC_ID_FIELD,
186+ NAME_FIELD,
187+ ORIGIN_FIELD,
188+ PACKAGE_FIELD,
189+ PACKAGES_FIELD,
190+ PARTITION_LAYOUT_FIELD,
191+ ROOT_MIN_SIZE_FIELD,
192+ SAMSUNG_BL1_LEN_FIELD,
193+ SAMSUNG_BL1_START_FIELD,
194+ SAMSUNG_BL2_LEN_FIELD,
195+ SAMSUNG_ENV_LEN_FIELD,
196+ SERIAL_TTY_FIELD,
197+ SNOWBALL_STARTUP_FILES_CONFIG_FIELD,
198+ SOURCES_FIELD,
199+ SPL_DD_FIELD,
200+ SPL_FILE_FIELD,
201+ SPL_IN_BOOT_PART_FIELD,
202+ SPL_PACKAGE_FIELD,
203+ SUPPORT_FIELD,
204+ WIRED_INTERFACES_FIELD,
205+ WIRELESS_INTERFACES_FIELD,
206+ DEFINED_PARTITION_LAYOUTS,
207+ VERSION_FIELD,
208+)
209+
210
211 class HwpackConfigError(Exception):
212 pass
213@@ -35,81 +89,101 @@
214
215 class Config(object):
216 """Encapsulation of a hwpack-create configuration."""
217+ translate_v2_to_v3 = {}
218+ translate_v2_metadata = {}
219
220 MAIN_SECTION = "hwpack"
221- NAME_KEY = "name"
222 NAME_REGEX = r"[a-z0-9][a-z0-9+\-.]+$"
223- INCLUDE_DEBS_KEY = "include-debs"
224- SUPPORT_KEY = "support"
225 SOURCES_ENTRY_KEY = "sources-entry"
226- PACKAGES_KEY = "packages"
227 PACKAGE_REGEX = NAME_REGEX
228 PATH_REGEX = r"\w[\w+\-./_]+$"
229 GLOB_REGEX = r"[\w+\-./_\*]+$"
230- ORIGIN_KEY = "origin"
231- MAINTAINER_KEY = "maintainer"
232- ARCHITECTURES_KEY = "architectures"
233+ INCLUDE_DEBS_KEY = "include-debs"
234+ translate_v2_to_v3[INCLUDE_DEBS_KEY] = INCLUDE_DEBS_FIELD
235+ translate_v2_metadata[ARCHITECTURES_FIELD] = "ARCHITECTURE"
236 ASSUME_INSTALLED_KEY = "assume-installed"
237+ translate_v2_to_v3[ASSUME_INSTALLED_KEY] = ASSUME_INSTALLED_FIELD
238 U_BOOT_PACKAGE_KEY = "u_boot_package"
239+ translate_v2_to_v3[U_BOOT_PACKAGE_KEY] = PACKAGE_FIELD
240 U_BOOT_FILE_KEY = "u_boot_file"
241+ translate_v2_to_v3[U_BOOT_FILE_KEY] = FILE_FIELD
242+ translate_v2_metadata[U_BOOT_FILE_KEY] = "U_BOOT"
243 SPL_FILE_KEY = "spl_file"
244- SERIAL_TTY_KEY = "serial_tty"
245- KERNEL_ADDR_KEY = "kernel_addr"
246- INITRD_ADDR_KEY = "initrd_addr"
247- LOAD_ADDR_KEY = "load_addr"
248- DTB_ADDR_KEY = "dtb_addr"
249- WIRED_INTERFACES_KEY = "wired_interfaces"
250- WIRELESS_INTERFACES_KEY = "wireless_interfaces"
251- PARTITION_LAYOUT_KEY = "partition_layout"
252- MMC_ID_KEY = "mmc_id"
253- FORMAT_KEY = "format"
254- BOOT_MIN_SIZE_KEY = "boot_min_size"
255- ROOT_MIN_SIZE_KEY = "root_min_size"
256- LOADER_MIN_SIZE_KEY = "loader_min_size"
257- LOADER_START_KEY = "loader_start"
258- SPL_PACKAGE_KEY = "spl_package"
259- VMLINUZ_KEY = "kernel_file"
260- INITRD_KEY = "initrd_file"
261- DTB_FILE_KEY = "dtb_file"
262- EXTRA_BOOT_OPTIONS_KEY = 'extra_boot_options'
263- BOOT_SCRIPT_KEY = 'boot_script'
264+ translate_v2_metadata[SPL_FILE_KEY] = "SPL"
265 UBOOT_IN_BOOT_PART_KEY = 'u_boot_in_boot_part'
266+ translate_v2_to_v3[UBOOT_IN_BOOT_PART_KEY] = IN_BOOT_PART_FIELD
267 UBOOT_DD_KEY = 'u_boot_dd'
268- SPL_IN_BOOT_PART_KEY = 'spl_in_boot_part'
269- SPL_DD_KEY = 'spl_dd'
270- ENV_DD_KEY = 'env_dd'
271- EXTRA_SERIAL_OPTS_KEY = 'extra_serial_options'
272- SNOWBALL_STARTUP_FILES_CONFIG_KEY = 'snowball_startup_files_config'
273- SAMSUNG_BL1_START_KEY = 'samsung_bl1_start'
274- SAMSUNG_BL1_LEN_KEY = 'samsung_bl1_len'
275- SAMSUNG_ENV_LEN_KEY = 'samsung_env_len'
276- SAMSUNG_BL2_LEN_KEY = 'samsung_bl2_len'
277-
278- DEFINED_PARTITION_LAYOUTS = [
279- 'bootfs16_rootfs',
280- 'bootfs_rootfs',
281- 'reserved_bootfs_rootfs',
282- ]
283-
284- def __init__(self, fp):
285+ translate_v2_to_v3[UBOOT_DD_KEY] = DD_FIELD
286+
287+ def __init__(self, fp, bootloader=None, board=None):
288 """Create a Config.
289
290 :param fp: a file-like object containing the configuration.
291 """
292+ obfuscated_e = None
293+ obfuscated_yaml_e = ""
294 try:
295 self.parser = ConfigParser.RawConfigParser()
296 self.parser.readfp(fp)
297 except ConfigParser.Error, e:
298 obfuscated_e = re.sub(r"([^ ]https://).+?(@)", r"\1***\2", str(e))
299- raise ConfigParser.Error(obfuscated_e)
300+
301+ if obfuscated_e:
302+ # obfuscated_e being set indicates that something went wrong.
303+ # It could be that the input is in fact YAML. Try the YAML
304+ # parser.
305+ try:
306+ fp.seek(0)
307+ self.parser = yaml.safe_load(fp)
308+ except yaml.YAMLError, e:
309+ obfuscated_yaml_e = re.sub(r"([^ ]https://).+?(@)",
310+ r"\1***\2", str(e))
311+ else:
312+ # If YAML parsed OK, we don't have an error.
313+ obfuscated_e = None
314+ self.set_board(board)
315+ self.set_bootloader(bootloader)
316+
317+ if obfuscated_e:
318+ # If INI parsing from ConfigParser or YAML parsing failed,
319+ # print both error messages.
320+ msg = ("Failed to parse hardware pack configuration. Tried to "
321+ "parse as both INI and YAML. INI parsing error:\n" +
322+ obfuscated_e + "\n" +
323+ "YAML parser error:\n" +
324+ obfuscated_yaml_e)
325+ raise ConfigParser.Error(msg)
326+
327+ def set_bootloader(self, bootloader):
328+ """Set bootloader used to look up configuration in bootloader section.
329+
330+ If bootloader is None / empty and there is only one bootloader
331+ available, use that.
332+ """
333+ if not bootloader:
334+ # Auto-detect bootloader. If there is a single bootloader specified
335+ # then use it, else, error.
336+ bootloaders = self.bootloaders
337+ if isinstance(bootloaders, dict):
338+ # We have a list of bootloaders in the expected format
339+ bootloaders = bootloaders.keys()
340+ if len(bootloaders) == 1:
341+ bootloader = bootloaders[0]
342+
343+ self.bootloader = bootloader
344+
345+ def set_board(self, board):
346+ """Set board used to look up per-board configuration"""
347+ self.board = board
348
349 def validate(self):
350 """Check that this configuration follows the schema.
351
352 :raises HwpackConfigError: if it does not.
353 """
354- if not self.parser.has_section(self.MAIN_SECTION):
355- raise HwpackConfigError("No [%s] section" % self.MAIN_SECTION)
356+ if isinstance(self.parser, ConfigParser.RawConfigParser):
357+ if not self.parser.has_section(self.MAIN_SECTION):
358+ raise HwpackConfigError("No [%s] section" % self.MAIN_SECTION)
359 self._validate_format()
360 self._validate_name()
361 self._validate_include_debs()
362@@ -153,88 +227,229 @@
363 self._validate_samsung_env_len()
364 self._validate_samsung_bl2_len()
365
366- self._validate_sections()
367+ self._validate_sources()
368
369 @property
370 def format(self):
371 """The format of the hardware pack. A subclass of HardwarePackFormat.
372 """
373- try:
374- format_string = self.parser.get(self.MAIN_SECTION, self.FORMAT_KEY)
375- except ConfigParser.NoOptionError:
376- # Default to 1.0 to aviod breaking existing hwpack files.
377- # When this code no longer supports 1.0, it effectively makes
378- # explicitly specifying format in hwpack files mandatory.
379- format_string = "1.0"
380+ if isinstance(self.parser, ConfigParser.RawConfigParser):
381+ try:
382+ format_string = self.parser.get(self.MAIN_SECTION,
383+ FORMAT_FIELD)
384+ except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
385+ # Default to 1.0 to aviod breaking existing hwpack files.
386+ # When this code no longer supports 1.0, it effectively makes
387+ # explicitly specifying format in hwpack files mandatory.
388+ format_string = "1.0"
389+ else:
390+ format_string = self.parser.get(FORMAT_FIELD)
391
392 if format_string == '1.0':
393 return HardwarePackFormatV1()
394 elif format_string == '2.0':
395 return HardwarePackFormatV2()
396+ elif format_string == 3.0 or format_string == '3.0':
397+ return HardwarePackFormatV3()
398 else:
399- raise HwpackConfigError("Format version '%s' is not supported." % \
400- format_string)
401+ raise HwpackConfigError("Format version '%s' is not supported." %
402+ format_string)
403
404 @property
405 def name(self):
406 """The name of the hardware pack. A str."""
407- return self.parser.get(self.MAIN_SECTION, self.NAME_KEY)
408+ return self._get_option(NAME_FIELD)
409+
410+ @property
411+ def version(self):
412+ return self._get_option(VERSION_FIELD)
413
414 @property
415 def include_debs(self):
416 """Whether the hardware pack should contain .debs. A bool."""
417 try:
418- if not self.parser.get(
419- self.MAIN_SECTION, self.INCLUDE_DEBS_KEY):
420+ if self._get_option(self.INCLUDE_DEBS_KEY) == None:
421 return True
422- return self.parser.getboolean(
423- self.MAIN_SECTION, self.INCLUDE_DEBS_KEY)
424+ try:
425+ return self._get_option_bool(self.INCLUDE_DEBS_KEY)
426+ except ValueError as e:
427+ raise HwpackConfigError("Invalid value for include-debs: %s" %
428+ e)
429 except ConfigParser.NoOptionError:
430 return True
431
432 @property
433+ def bootloaders(self):
434+ """Bootloaders available in the hardware pack"""
435+ return self._get_option(BOOTLOADERS_FIELD)
436+
437+ @property
438 def uboot_in_boot_part(self):
439 """Whether uboot binary should be put in the boot partition. A str."""
440- return self.parser.get(self.MAIN_SECTION, self.UBOOT_IN_BOOT_PART_KEY)
441+ return self._get_bootloader_option(self.UBOOT_IN_BOOT_PART_KEY)
442
443 @property
444 def uboot_dd(self):
445 """If the uboot binary should be dd:d to the boot partition
446 this field specifies the offset. An int."""
447- return self._get_option_from_main_section(self.UBOOT_DD_KEY)
448+ return self._get_bootloader_option(self.UBOOT_DD_KEY)
449
450 @property
451 def spl_in_boot_part(self):
452 """Whether spl binary should be put in the boot partition. A str."""
453- return self._get_option_from_main_section(self.SPL_IN_BOOT_PART_KEY)
454+ return self._get_bootloader_option(SPL_IN_BOOT_PART_FIELD)
455
456 @property
457 def spl_dd(self):
458 """If the spl binary should be dd:d to the boot partition
459 this field specifies the offset. An int."""
460- return self._get_option_from_main_section(self.SPL_DD_KEY)
461+ return self._get_bootloader_option(SPL_DD_FIELD)
462
463 @property
464 def env_dd(self):
465 """If the env should be dd:d to the boot partition. 'Yes' or 'No'."""
466- return self._get_option_from_main_section(self.ENV_DD_KEY)
467-
468- def _get_option_from_main_section(self, key):
469- """Get the value from the main section for the given key.
470+ return self._get_bootloader_option(ENV_DD_FIELD)
471+
472+ def _get_option_bool(self, key):
473+ """Gets a boolean value from the key."""
474+ if self.format.format_as_string == '3.0':
475+ value = self._get_option(key, convert_to="disable")
476+ if isinstance(value, bool):
477+ return value
478+ else:
479+ raise ValueError(value)
480+ else:
481+ try:
482+ return self.parser.getboolean(self.MAIN_SECTION, key)
483+ except ConfigParser.NoOptionError:
484+ return None
485+
486+ def _get_bootloader_option(self, key, join_list_with=False,
487+ convert_to=None):
488+ """Get an option inside the current bootloader section."""
489+ if self._is_v3:
490+ if not self.bootloader:
491+ raise ValueError("bootloader not set.")
492+ if not isinstance(key, list):
493+ keys = [key]
494+ keys = [BOOTLOADERS_FIELD, self.bootloader] + keys
495+ else:
496+ keys = key
497+
498+ return self._get_option(keys, join_list_with, convert_to)
499+
500+ def _bool_to_string(self, value):
501+ """Convert value, treated as boolean, to string "yes" or "no"."""
502+ if value:
503+ return "yes"
504+ else:
505+ return "no"
506+
507+ def _hex_addrress(self, value):
508+ """Convert value to 8 character hex string"""
509+ converted_value = value
510+ if not isinstance(value, str):
511+ converted_value = "0x%08x" % value
512+ return converted_value
513+
514+ def _v2_key_to_v3(self, key):
515+ """Convert V2 key to a V3 key"""
516+ if key in self.translate_v2_to_v3:
517+ key = self.translate_v2_to_v3[key]
518+ return key
519+
520+ def _get_v3_option(self, keys):
521+ """Find value in config dictionary based on supplied list (keys)."""
522+ result = self.parser
523+ for key in keys:
524+ key = self._v2_key_to_v3(key)
525+ if result is not None:
526+ result = result.get(key, None)
527+ return result
528+
529+ def get_option(self, name):
530+ """Return the value of an attribute by name.
531+
532+ Used when you can't use a property.
533+ """
534+ return attrgetter(name)(self)
535+
536+ def _get_option(self, key, join_list_with=False, convert_to=None):
537+ """Return value for the given key. Precedence to board specific values.
538
539 :param key: the key to return the value for.
540 :type key: str.
541+ :param join_list_with: Used to convert lists to strings.
542+ :type join_list_with: str
543+ :param convert_to: Used to convert stored value to another type.
544+ :type convert_to: type or function.
545 :return: the value for that key, or None if the key is not present
546 or the value is empty.
547 :rtype: str or None.
548 """
549- try:
550- result = self.parser.get(self.MAIN_SECTION, key)
551+ if self.format.format_as_string == "3.0":
552+ if not isinstance(key, list):
553+ keys = [key]
554+ else:
555+ keys = key
556+
557+ result = None # Just mark result as not set yet...
558+
559+ # If board is set, search board specific keys first
560+ if self.board:
561+ result = self._get_v3_option([BOARDS_FIELD, self.board] + keys)
562+
563+ # If a board specific value isn't found, look for a global one
564+ if result == None:
565+ result = self._get_v3_option(keys)
566+
567+ # If no value is found, bail early (return None)
568+ if result == None:
569+ return None
570+
571+ # <v3 compatibility: Lists of items can be converted to strings
572+ if join_list_with and isinstance(result, list):
573+ result = join_list_with.join(result)
574+
575+ # <v3 compatibility:
576+ # To aid code that is trying to keep the format of results the
577+ # same as before, we have some type conversions. By default
578+ # booleans are "yes" or "no", integers are converted to
579+ # strings.
580+ if not convert_to:
581+ if isinstance(result, int):
582+ if isinstance(result, bool):
583+ convert_to = self._bool_to_string
584+ else:
585+ convert_to = str
586+
587+ if convert_to and convert_to != "disable":
588+ if isinstance(result, list):
589+ new_list = []
590+ for item in result:
591+ new_list = convert_to(item)
592+ result = new_list
593+ else:
594+ result = convert_to(result)
595+ else:
596+ try:
597+ result = self.parser.get(self.MAIN_SECTION, key)
598+ except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
599+ # May be trying to read a metadata file, which has uppercase
600+ # keys, some of which need translating to different strings...
601+ if key in self.translate_v2_metadata:
602+ key = self.translate_v2_metadata[key]
603+ else:
604+ key = key.upper()
605+ try:
606+ result = self.parser.get(self.MAIN_SECTION, key)
607+ except (ConfigParser.NoOptionError,
608+ ConfigParser.NoSectionError):
609+ result = None
610 if not result:
611- return None
612- return result
613- except ConfigParser.NoOptionError:
614- return None
615+ result = None
616+
617+ return result
618
619 @property
620 def serial_tty(self):
621@@ -242,7 +457,7 @@
622
623 A str.
624 """
625- return self._get_option_from_main_section(self.SERIAL_TTY_KEY)
626+ return self._get_option(SERIAL_TTY_FIELD)
627
628 @property
629 def extra_boot_options(self):
630@@ -250,7 +465,8 @@
631
632 A str.
633 """
634- return self._get_option_from_main_section(self.EXTRA_BOOT_OPTIONS_KEY)
635+ return self._get_bootloader_option(EXTRA_BOOT_OPTIONS_FIELD,
636+ join_list_with=" ")
637
638 @property
639 def extra_serial_opts(self):
640@@ -258,7 +474,7 @@
641
642 A str.
643 """
644- return self._get_option_from_main_section(self.EXTRA_SERIAL_OPTS_KEY)
645+ return self._get_option(EXTRA_SERIAL_OPTIONS_FIELD, join_list_with=" ")
646
647 @property
648 def boot_script(self):
649@@ -266,7 +482,7 @@
650
651 A str.
652 """
653- return self._get_option_from_main_section(self.BOOT_SCRIPT_KEY)
654+ return self._get_option(BOOT_SCRIPT_FIELD)
655
656 @property
657 def snowball_startup_files_config(self):
658@@ -274,8 +490,7 @@
659
660 A str.
661 """
662- return self._get_option_from_main_section(
663- self.SNOWBALL_STARTUP_FILES_CONFIG_KEY)
664+ return self._get_option(SNOWBALL_STARTUP_FILES_CONFIG_FIELD)
665
666 @property
667 def kernel_addr(self):
668@@ -283,7 +498,8 @@
669
670 An int.
671 """
672- return self._get_option_from_main_section(self.KERNEL_ADDR_KEY)
673+ return self._get_option(KERNEL_ADDR_FIELD,
674+ convert_to=self._hex_addrress)
675
676 @property
677 def initrd_addr(self):
678@@ -291,7 +507,8 @@
679
680 An int.
681 """
682- return self._get_option_from_main_section(self.INITRD_ADDR_KEY)
683+ return self._get_option(INITRD_ADDR_FIELD,
684+ convert_to=self._hex_addrress)
685
686 @property
687 def load_addr(self):
688@@ -299,7 +516,7 @@
689
690 An int.
691 """
692- return self._get_option_from_main_section(self.LOAD_ADDR_KEY)
693+ return self._get_option(LOAD_ADDR_FIELD, convert_to=self._hex_addrress)
694
695 @property
696 def dtb_addr(self):
697@@ -307,7 +524,7 @@
698
699 An int.
700 """
701- return self._get_option_from_main_section(self.DTB_ADDR_KEY)
702+ return self._get_option(DTB_ADDR_FIELD, convert_to=self._hex_addrress)
703
704 @property
705 def wired_interfaces(self):
706@@ -315,7 +532,7 @@
707
708 A list of str.
709 """
710- return self._get_list_from_main_section(self.WIRED_INTERFACES_KEY)
711+ return self._get_list(WIRED_INTERFACES_FIELD)
712
713 @property
714 def wireless_interfaces(self):
715@@ -323,7 +540,7 @@
716
717 A list of str.
718 """
719- return self._get_list_from_main_section(self.WIRELESS_INTERFACES_KEY)
720+ return self._get_list(WIRELESS_INTERFACES_FIELD)
721
722 @property
723 def partition_layout(self):
724@@ -333,7 +550,7 @@
725
726 A str.
727 """
728- return self._get_option_from_main_section(self.PARTITION_LAYOUT_KEY)
729+ return self._get_option(PARTITION_LAYOUT_FIELD, join_list_with=" ")
730
731 @property
732 def mmc_id(self):
733@@ -341,7 +558,7 @@
734
735 An int.
736 """
737- return self._get_option_from_main_section(self.MMC_ID_KEY)
738+ return self._get_option(MMC_ID_FIELD)
739
740 @property
741 def root_min_size(self):
742@@ -349,7 +566,7 @@
743
744 An int.
745 """
746- return self._get_option_from_main_section(self.ROOT_MIN_SIZE_KEY)
747+ return self._get_option(ROOT_MIN_SIZE_FIELD)
748
749 @property
750 def boot_min_size(self):
751@@ -357,7 +574,7 @@
752
753 An int.
754 """
755- return self._get_option_from_main_section(self.BOOT_MIN_SIZE_KEY)
756+ return self._get_option(BOOT_MIN_SIZE_FIELD)
757
758 @property
759 def loader_min_size(self):
760@@ -365,7 +582,7 @@
761
762 An int.
763 """
764- return self._get_option_from_main_section(self.LOADER_MIN_SIZE_KEY)
765+ return self._get_option(LOADER_MIN_SIZE_FIELD)
766
767 @property
768 def loader_start(self):
769@@ -373,7 +590,7 @@
770
771 An int.
772 """
773- return self._get_option_from_main_section(self.LOADER_START_KEY)
774+ return self._get_option(LOADER_START_FIELD)
775
776 @property
777 def origin(self):
778@@ -381,7 +598,7 @@
779
780 A str or None if no origin should be recorded.
781 """
782- return self._get_option_from_main_section(self.ORIGIN_KEY)
783+ return self._get_option(ORIGIN_FIELD)
784
785 @property
786 def maintainer(self):
787@@ -389,7 +606,7 @@
788
789 A str or None if not maintainer should be recorded.
790 """
791- return self._get_option_from_main_section(self.MAINTAINER_KEY)
792+ return self._get_option(MAINTAINER_FIELD)
793
794 @property
795 def support(self):
796@@ -397,17 +614,21 @@
797
798 A str or None if no support level should be recorded.
799 """
800- return self._get_option_from_main_section(self.SUPPORT_KEY)
801+ return self._get_option(SUPPORT_FIELD)
802
803- def _get_list_from_main_section(self, key):
804- raw_values = self._get_option_from_main_section(key)
805- if raw_values is None:
806+ def _get_list(self, key):
807+ values = self._get_option(key)
808+ if values is None:
809 return []
810- values = re.split("\s+", raw_values)
811+
812+ if not isinstance(values, list):
813+ values = re.split("\s+", values)
814+
815 filtered_values = []
816 for value in values:
817 if value not in filtered_values:
818 filtered_values.append(value)
819+
820 return filtered_values
821
822 @property
823@@ -416,7 +637,7 @@
824
825 A list of str.
826 """
827- return self._get_list_from_main_section(self.PACKAGES_KEY)
828+ return self._get_list(PACKAGES_FIELD)
829
830 @property
831 def u_boot_package(self):
832@@ -424,7 +645,7 @@
833
834 A str.
835 """
836- return self._get_option_from_main_section(self.U_BOOT_PACKAGE_KEY)
837+ return self._get_bootloader_option(self.U_BOOT_PACKAGE_KEY)
838
839 @property
840 def u_boot_file(self):
841@@ -432,7 +653,7 @@
842
843 A str.
844 """
845- return self._get_option_from_main_section(self.U_BOOT_FILE_KEY)
846+ return self._get_bootloader_option(self.U_BOOT_FILE_KEY)
847
848 @property
849 def spl_file(self):
850@@ -440,7 +661,7 @@
851
852 A str.
853 """
854- return self._get_option_from_main_section(self.SPL_FILE_KEY)
855+ return self._get_bootloader_option(SPL_FILE_FIELD)
856
857 @property
858 def spl_package(self):
859@@ -448,7 +669,7 @@
860
861 A str.
862 """
863- return self._get_option_from_main_section(self.SPL_PACKAGE_KEY)
864+ return self._get_bootloader_option(SPL_PACKAGE_FIELD)
865
866 @property
867 def vmlinuz(self):
868@@ -456,7 +677,7 @@
869
870 A str.
871 """
872- return self._get_option_from_main_section(self.VMLINUZ_KEY)
873+ return self._get_option(KERNEL_FILE_FIELD)
874
875 @property
876 def initrd(self):
877@@ -464,7 +685,7 @@
878
879 A str.
880 """
881- return self._get_option_from_main_section(self.INITRD_KEY)
882+ return self._get_option(INITRD_FILE_FIELD)
883
884 @property
885 def dtb_file(self):
886@@ -472,7 +693,7 @@
887
888 A str.
889 """
890- return self._get_option_from_main_section(self.DTB_FILE_KEY)
891+ return self._get_option(DTB_FILE_FIELD)
892
893 @property
894 def samsung_bl1_start(self):
895@@ -480,7 +701,7 @@
896
897 A str.
898 """
899- return self._get_option_from_main_section(self.SAMSUNG_BL1_START_KEY)
900+ return self._get_option(SAMSUNG_BL1_START_FIELD)
901
902 @property
903 def samsung_bl1_len(self):
904@@ -488,7 +709,7 @@
905
906 A str.
907 """
908- return self._get_option_from_main_section(self.SAMSUNG_BL1_LEN_KEY)
909+ return self._get_option(SAMSUNG_BL1_LEN_FIELD)
910
911 @property
912 def samsung_env_len(self):
913@@ -496,7 +717,7 @@
914
915 A str.
916 """
917- return self._get_option_from_main_section(self.SAMSUNG_ENV_LEN_KEY)
918+ return self._get_option(SAMSUNG_ENV_LEN_FIELD)
919
920 @property
921 def samsung_bl2_len(self):
922@@ -504,7 +725,7 @@
923
924 A str.
925 """
926- return self._get_option_from_main_section(self.SAMSUNG_BL2_LEN_KEY)
927+ return self._get_option(SAMSUNG_BL2_LEN_FIELD)
928
929 @property
930 def architectures(self):
931@@ -512,7 +733,15 @@
932
933 A list of str.
934 """
935- return self._get_list_from_main_section(self.ARCHITECTURES_KEY)
936+ return self._get_list(ARCHITECTURES_FIELD)
937+
938+ @property
939+ def architecture(self):
940+ """The architectures to build the hwpack for.
941+
942+ A list of str.
943+ """
944+ return self._get_option(ARCHITECTURE_FIELD)
945
946 @property
947 def assume_installed(self):
948@@ -520,7 +749,7 @@
949
950 A list of str.
951 """
952- return self._get_list_from_main_section(self.ASSUME_INSTALLED_KEY)
953+ return self._get_list(self.ASSUME_INSTALLED_KEY)
954
955 @property
956 def sources(self):
957@@ -528,13 +757,16 @@
958
959 A dict mapping source identifiers to sources entries.
960 """
961- sources = {}
962- sections = self.parser.sections()
963- for section_name in sections:
964- if section_name == self.MAIN_SECTION:
965- continue
966- sources[section_name] = self.parser.get(
967- section_name, self.SOURCES_ENTRY_KEY)
968+ if self._is_v3:
969+ sources = self.parser.get(SOURCES_FIELD)
970+ else:
971+ sources = {}
972+ sections = self.parser.sections()
973+ for section_name in sections:
974+ if section_name == self.MAIN_SECTION:
975+ continue
976+ sources[section_name] = self.parser.get(
977+ section_name, self.SOURCES_ENTRY_KEY)
978 return sources
979
980 def _validate_format(self):
981@@ -575,19 +807,25 @@
982 def _validate_vmlinuz(self):
983 vmlinuz = self.vmlinuz
984 if not vmlinuz:
985- raise HwpackConfigError("No kernel_file in the [%s] section" % \
986- self.MAIN_SECTION)
987+ raise HwpackConfigError(self._not_found_message(KERNEL_FILE_FIELD))
988 self._assert_matches_pattern(
989 self.GLOB_REGEX, vmlinuz, "Invalid path: %s" % vmlinuz)
990
991 def _validate_initrd(self):
992 initrd = self.initrd
993 if not initrd:
994- raise HwpackConfigError("No initrd_file in the [%s] section" % \
995- self.MAIN_SECTION)
996+ raise HwpackConfigError(self._not_found_message(INITRD_FILE_FIELD))
997 self._assert_matches_pattern(
998 self.GLOB_REGEX, initrd, "Invalid path: %s" % initrd)
999
1000+ def _not_found_message(self, thing, v2_section=None):
1001+ if self._is_v3:
1002+ return "No " + thing + " found in the metadata"
1003+ else:
1004+ if not v2_section:
1005+ v2_section = self.MAIN_SECTION
1006+ return "No " + thing + " in the [" + v2_section + "] section"
1007+
1008 def _validate_dtb_file(self):
1009 dtb_file = self.dtb_file
1010 if dtb_file is not None:
1011@@ -624,36 +862,40 @@
1012 if len(serial_tty) < 4 or serial_tty[:3] != 'tty':
1013 raise HwpackConfigError("Invalid serial tty: %s" % serial_tty)
1014
1015- def _validate_addr(self, addr):
1016- return re.match(r"^0x[a-fA-F0-9]{8}$", addr)
1017+ def _validate_addr(self, key):
1018+ """Validate the address for the given key.
1019+ Assumptions:
1020+ 1. key name is of the form name_addr
1021+ 2. property name matches key name
1022+
1023+ Currently these assumptions are met and it seems reasonable to place
1024+ these restrictions on future code.
1025+ """
1026+ name = re.sub("_addr", "", key)
1027+
1028+ try:
1029+ addr = attrgetter(key)(self)
1030+ except TypeError:
1031+ raise HwpackConfigError("Invalid %s address: %s" %
1032+ (name, self._get_option(key)))
1033+
1034+ if addr == None:
1035+ return
1036+
1037+ if not re.match(r"^0x[a-fA-F0-9]{8}$", addr):
1038+ raise HwpackConfigError("Invalid %s address: %s" % (name, addr))
1039
1040 def _validate_kernel_addr(self):
1041- addr = self.kernel_addr
1042- if addr is None:
1043- return
1044- if not self._validate_addr(addr):
1045- raise HwpackConfigError("Invalid kernel address: %s" % addr)
1046+ self._validate_addr(KERNEL_ADDR_FIELD)
1047
1048 def _validate_initrd_addr(self):
1049- addr = self.initrd_addr
1050- if addr is None:
1051- return
1052- if not self._validate_addr(addr):
1053- raise HwpackConfigError("Invalid initrd address: %s" % addr)
1054+ self._validate_addr(INITRD_ADDR_FIELD)
1055
1056 def _validate_load_addr(self):
1057- addr = self.load_addr
1058- if addr is None:
1059- return
1060- if not self._validate_addr(addr):
1061- raise HwpackConfigError("Invalid load address: %s" % addr)
1062+ self._validate_addr(LOAD_ADDR_FIELD)
1063
1064 def _validate_dtb_addr(self):
1065- addr = self.dtb_addr
1066- if addr is None:
1067- return
1068- if not self._validate_addr(addr):
1069- raise HwpackConfigError("Invalid dtb address: %s" % addr)
1070+ self._validate_addr(DTB_ADDR_FIELD)
1071
1072 def _validate_wired_interfaces(self):
1073 pass
1074@@ -662,12 +904,19 @@
1075 pass
1076
1077 def _validate_partition_layout(self):
1078- if self.partition_layout not in self.DEFINED_PARTITION_LAYOUTS:
1079- raise HwpackConfigError(
1080- "Undefined partition layout %s in the [%s] section. "
1081- "Valid partition layouts are %s."
1082- % (self.partition_layout, self.MAIN_SECTION,
1083- ", ".join(self.DEFINED_PARTITION_LAYOUTS)))
1084+ if self.partition_layout not in DEFINED_PARTITION_LAYOUTS:
1085+ if self._is_v3:
1086+ message = ("Undefined partition layout %s. "
1087+ "Valid partition layouts are %s." %
1088+ (self.partition_layout,
1089+ ", ".join(DEFINED_PARTITION_LAYOUTS)))
1090+ else:
1091+ message = ("Undefined partition layout %s in the [%s] section."
1092+ " Valid partition layouts are %s." %
1093+ (self.partition_layout, self.MAIN_SECTION,
1094+ ", ".join(DEFINED_PARTITION_LAYOUTS)))
1095+
1096+ raise HwpackConfigError(message)
1097
1098 def _validate_mmc_id(self):
1099 mmc_id = self.mmc_id
1100@@ -725,14 +974,25 @@
1101 except ValueError:
1102 raise HwpackConfigError(
1103 "Invalid value for include-debs: %s"
1104- % self.parser.get("hwpack", "include-debs"))
1105+ % self.include_debs)
1106+
1107+ @property
1108+ def _is_v3(self):
1109+ """Checks if format is 3.0."""
1110+ return self.format.format_as_string == '3.0'
1111+
1112+ def _validate_bool(self, value):
1113+ """Checks if a value is boolean or not, represented by "yes" or "no".
1114+ """
1115+ if not isinstance(value, str):
1116+ return False
1117+ return string.lower(value) in ['yes', 'no']
1118
1119 def _validate_uboot_in_boot_part(self):
1120- uboot_in_boot_part = self.uboot_in_boot_part
1121- if string.lower(uboot_in_boot_part) not in ['yes', 'no']:
1122+ if not self._validate_bool(self.uboot_in_boot_part):
1123 raise HwpackConfigError(
1124 "Invalid value for u_boot_in_boot_part: %s"
1125- % self.parser.get("hwpack", "u_boot_in_boot_part"))
1126+ % self.uboot_in_boot_part)
1127
1128 def _validate_spl_in_boot_part(self):
1129 spl_in_boot_part = self.spl_in_boot_part
1130@@ -741,7 +1001,7 @@
1131 if string.lower(spl_in_boot_part) not in ['yes', 'no']:
1132 raise HwpackConfigError(
1133 "Invalid value for spl_in_boot_part: %s"
1134- % self.parser.get("hwpack", "spl_in_boot_part"))
1135+ % self.spl_in_boot_part)
1136
1137 def _validate_env_dd(self):
1138 env_dd = self.env_dd
1139@@ -750,7 +1010,7 @@
1140 if string.lower(env_dd) not in ['yes', 'no']:
1141 raise HwpackConfigError(
1142 "Invalid value for env_dd: %s"
1143- % self.parser.get("hwpack", "env_dd"))
1144+ % self.env_dd)
1145
1146 def _validate_uboot_dd(self):
1147 uboot_dd = self.uboot_dd
1148@@ -778,33 +1038,40 @@
1149 raise HwpackConfigError(
1150 "Invalid value for support: %s" % support)
1151
1152+ def _invalid_package_message(self, package_name, section_name, value):
1153+ if self._is_v3:
1154+ message = ("Invalid value in %s in the metadata: %s" %
1155+ (package_name, value))
1156+ else:
1157+ message = ("Invalid value in %s in the [%s] section: %s" %
1158+ (package_name, section_name, value))
1159+ return message
1160+
1161 def _validate_packages(self):
1162 packages = self.packages
1163 if not packages:
1164- raise HwpackConfigError(
1165- "No %s in the [%s] section"
1166- % (self.PACKAGES_KEY, self.MAIN_SECTION))
1167+ raise HwpackConfigError(self._not_found_message(PACKAGES_FIELD))
1168 for package in packages:
1169 self._assert_matches_pattern(
1170- self.PACKAGE_REGEX, package, "Invalid value in %s in the " \
1171- "[%s] section: %s" % (self.PACKAGES_KEY, self.MAIN_SECTION,
1172- package))
1173+ self.PACKAGE_REGEX, package,
1174+ self._invalid_package_message(
1175+ PACKAGES_FIELD, self.MAIN_SECTION, package))
1176
1177 def _validate_u_boot_package(self):
1178 u_boot_package = self.u_boot_package
1179 if u_boot_package is not None:
1180 self._assert_matches_pattern(
1181- self.PACKAGE_REGEX, u_boot_package, "Invalid value in %s in " \
1182- "the [%s] section: %s" % (
1183- self.U_BOOT_PACKAGE_KEY, self.MAIN_SECTION,
1184- u_boot_package))
1185+ self.PACKAGE_REGEX, u_boot_package,
1186+ self._invalid_package_message(
1187+ self.U_BOOT_PACKAGE_KEY, self.MAIN_SECTION,
1188+ u_boot_package))
1189
1190 def _validate_spl_package(self):
1191 spl_package = self.spl_package
1192 if spl_package is not None:
1193 self._assert_matches_pattern(
1194- self.PACKAGE_REGEX, spl_package, "Invalid value in %s in " \
1195- "the [%s] section: %s" % (self.SPL_PACKAGE_KEY,
1196+ self.PACKAGE_REGEX, spl_package,
1197+ self._invalid_package_message(SPL_PACKAGE_FIELD,
1198 self.MAIN_SECTION,
1199 spl_package))
1200
1201@@ -852,48 +1119,66 @@
1202 architectures = self.architectures
1203 if not architectures:
1204 raise HwpackConfigError(
1205- "No %s in the [%s] section"
1206- % (self.ARCHITECTURES_KEY, self.MAIN_SECTION))
1207+ self._not_found_message(ARCHITECTURES_FIELD))
1208
1209 def _validate_assume_installed(self):
1210 assume_installed = self.assume_installed
1211 for package in assume_installed:
1212 self._assert_matches_pattern(
1213- self.PACKAGE_REGEX, package, "Invalid value in %s in the " \
1214- "[%s] section: %s" % (self.ASSUME_INSTALLED_KEY,
1215- self.MAIN_SECTION, package))
1216-
1217- def _validate_section_sources_entry(self, section_name):
1218- try:
1219- sources_entry = self.parser.get(
1220- section_name, self.SOURCES_ENTRY_KEY)
1221- if not sources_entry:
1222+ self.PACKAGE_REGEX, package,
1223+ self._invalid_package_message(self.ASSUME_INSTALLED_KEY,
1224+ self.MAIN_SECTION, package))
1225+
1226+ def _message_start(self, key, section_name):
1227+ if self._is_v3:
1228+ message = "The %s, %s " % (key, section_name)
1229+ else:
1230+ message = "The %s in the [%s] section " % (key, section_name)
1231+ return message
1232+
1233+ def _validate_source(self, section_name):
1234+ if self._is_v3:
1235+ sources_entry = self._get_option([SOURCES_FIELD] + [section_name])
1236+ else:
1237+ try:
1238+ sources_entry = self.parser.get(
1239+ section_name, self.SOURCES_ENTRY_KEY)
1240+ except ConfigParser.NoOptionError:
1241+ raise HwpackConfigError(
1242+ "No %s in the [%s] section"
1243+ % (self.SOURCES_ENTRY_KEY, section_name))
1244+
1245+ if not sources_entry:
1246+ raise HwpackConfigError(
1247+ self._message_start(self.SOURCES_ENTRY_KEY, section_name) +
1248+ "is missing the URI")
1249+ if len(sources_entry.split(" ", 1)) < 2:
1250+ raise HwpackConfigError(
1251+ self._message_start(self.SOURCES_ENTRY_KEY, section_name) +
1252+ "is missing the distribution")
1253+ if sources_entry.startswith("deb"):
1254+ raise HwpackConfigError(
1255+ self._message_start(self.SOURCES_ENTRY_KEY, section_name) +
1256+ "shouldn't start with 'deb'")
1257+
1258+ def _validate_sources(self):
1259+ if self._is_v3:
1260+ source_dict = self.parser.get(SOURCES_FIELD)
1261+ if not source_dict:
1262+ return
1263+ if isinstance(source_dict, dict):
1264+ sources = source_dict.keys()
1265+ else:
1266 raise HwpackConfigError(
1267 "The %s in the [%s] section is missing the URI"
1268- % (self.SOURCES_ENTRY_KEY, section_name))
1269- if len(sources_entry.split(" ", 1)) < 2:
1270- raise HwpackConfigError(
1271- "The %s in the [%s] section is missing the distribution"
1272- % (self.SOURCES_ENTRY_KEY, section_name))
1273- if sources_entry.startswith("deb"):
1274- raise HwpackConfigError(
1275- "The %s in the [%s] section shouldn't start with 'deb'"
1276- % (self.SOURCES_ENTRY_KEY, section_name))
1277- except ConfigParser.NoOptionError:
1278- raise HwpackConfigError(
1279- "No %s in the [%s] section"
1280- % (self.SOURCES_ENTRY_KEY, section_name))
1281-
1282- def _validate_section(self, section_name):
1283- self._validate_section_sources_entry(section_name)
1284-
1285- def _validate_sections(self):
1286- sections = self.parser.sections()
1287+ % (self.SOURCES_ENTRY_KEY, source_dict))
1288+ else:
1289+ sources = self.parser.sections()
1290 found = False
1291- for section_name in sections:
1292- if section_name == self.MAIN_SECTION:
1293+ for source_name in sources:
1294+ if source_name == self.MAIN_SECTION:
1295 continue
1296- self._validate_section(section_name)
1297+ self._validate_source(source_name)
1298 found = True
1299 if not found:
1300 raise HwpackConfigError(
1301
1302=== modified file 'linaro_image_tools/hwpack/hardwarepack.py'
1303--- linaro_image_tools/hwpack/hardwarepack.py 2012-06-13 14:49:14 +0000
1304+++ linaro_image_tools/hwpack/hardwarepack.py 2012-07-23 15:38:20 +0000
1305@@ -32,6 +32,45 @@
1306 from linaro_image_tools.hwpack.hardwarepack_format import (
1307 HardwarePackFormatV1,
1308 )
1309+from linaro_image_tools.hwpack.hwpack_convert import (
1310+ dump,
1311+)
1312+
1313+from hwpack_fields import (
1314+ BOOTLOADERS_FIELD,
1315+ BOOT_MIN_SIZE_FIELD,
1316+ BOOT_SCRIPT_FIELD,
1317+ DTB_ADDR_FIELD,
1318+ DTB_FILE_FIELD,
1319+ EXTRA_SERIAL_OPTIONS_FIELD,
1320+ FILE_FIELD,
1321+ FORMAT_FIELD,
1322+ INITRD_ADDR_FIELD,
1323+ INITRD_FILE_FIELD,
1324+ KERNEL_ADDR_FIELD,
1325+ KERNEL_FILE_FIELD,
1326+ LOAD_ADDR_FIELD,
1327+ LOADER_MIN_SIZE_FIELD,
1328+ LOADER_START_FIELD,
1329+ MAINTAINER_FIELD,
1330+ METADATA_ARCH_FIELD,
1331+ METADATA_VERSION_FIELD,
1332+ MMC_ID_FIELD,
1333+ NAME_FIELD,
1334+ ORIGIN_FIELD,
1335+ PARTITION_LAYOUT_FIELD,
1336+ ROOT_MIN_SIZE_FIELD,
1337+ SAMSUNG_BL1_LEN_FIELD,
1338+ SAMSUNG_BL1_START_FIELD,
1339+ SAMSUNG_BL2_LEN_FIELD,
1340+ SAMSUNG_ENV_LEN_FIELD,
1341+ SERIAL_TTY_FIELD,
1342+ SNOWBALL_STARTUP_FILES_CONFIG_FIELD,
1343+ SPL_FILE_FIELD,
1344+ SUPPORT_FIELD,
1345+ WIRED_INTERFACES_FIELD,
1346+ WIRELESS_INTERFACES_FIELD,
1347+)
1348
1349
1350 class Metadata(object):
1351@@ -127,6 +166,13 @@
1352 self.samsung_bl2_len = samsung_bl2_len
1353
1354 @classmethod
1355+ def add_v3_config(self, bootloaders):
1356+ """Add fields that are specific to the v3 config format.
1357+
1358+ :param bootloaders: The bootloaders section of the hwpack."""
1359+ self.bootloaders = bootloaders
1360+
1361+ @classmethod
1362 def from_config(cls, config, version, architecture):
1363 """Create a Metadata from a Config object.
1364
1365@@ -153,39 +199,163 @@
1366 # Helper variable to adhere to the line length limit.
1367 snowball_startup_config = config.snowball_startup_files_config
1368 metadata.add_v2_config(
1369- serial_tty=config.serial_tty,
1370+ boot_min_size=config.boot_min_size,
1371+ boot_script=config.boot_script,
1372+ dtb_addr=config.dtb_addr,
1373+ dtb_file=config.dtb_file,
1374+ env_dd=config.env_dd,
1375+ extra_boot_options=config.extra_boot_options,
1376+ extra_serial_opts=config.extra_serial_opts,
1377+ initrd_addr=config.initrd_addr,
1378+ initrd=config.initrd,
1379 kernel_addr=config.kernel_addr,
1380- initrd_addr=config.initrd_addr,
1381 load_addr=config.load_addr,
1382- wired_interfaces=config.wired_interfaces,
1383- wireless_interfaces=config.wireless_interfaces,
1384+ loader_min_size=config.loader_min_size,
1385+ loader_start=config.loader_start,
1386+ mmc_id=config.mmc_id,
1387 partition_layout=config.partition_layout,
1388- mmc_id=config.mmc_id,
1389- boot_min_size=config.boot_min_size,
1390 root_min_size=config.root_min_size,
1391- loader_min_size=config.loader_min_size,
1392- loader_start=config.loader_start,
1393- vmlinuz=config.vmlinuz,
1394- initrd=config.initrd,
1395- dtb_file=config.dtb_file,
1396- dtb_addr=config.dtb_addr,
1397- extra_boot_options=config.extra_boot_options,
1398- boot_script=config.boot_script,
1399- uboot_in_boot_part=config.uboot_in_boot_part,
1400- uboot_dd=config.uboot_dd,
1401- spl_in_boot_part=config.spl_in_boot_part,
1402- spl_dd=config.spl_dd,
1403- env_dd=config.env_dd,
1404- extra_serial_opts=config.extra_serial_opts,
1405- snowball_startup_files_config=snowball_startup_config,
1406+ samsung_bl1_len=config.samsung_bl1_len,
1407 samsung_bl1_start=config.samsung_bl1_start,
1408- samsung_bl1_len=config.samsung_bl1_len,
1409+ samsung_bl2_len=config.samsung_bl2_len,
1410 samsung_env_len=config.samsung_env_len,
1411- samsung_bl2_len=config.samsung_bl2_len)
1412+ serial_tty=config.serial_tty,
1413+ snowball_startup_files_config=snowball_startup_config,
1414+ spl_dd=config.spl_dd,
1415+ spl_in_boot_part=config.spl_in_boot_part,
1416+ uboot_dd=config.uboot_dd,
1417+ uboot_in_boot_part=config.uboot_in_boot_part,
1418+ vmlinuz=config.vmlinuz,
1419+ wired_interfaces=config.wired_interfaces,
1420+ wireless_interfaces=config.wireless_interfaces,
1421+ )
1422+ if config.format.format_as_string == '3.0':
1423+ metadata.add_v3_config(config.bootloaders)
1424 return metadata
1425
1426 def __str__(self):
1427- """Get the contents of the metadata file."""
1428+ if self.format.format_as_string == '3.0':
1429+ return self.create_metadata_new()
1430+ else:
1431+ return self.create_metadata_old()
1432+
1433+ def set_config_value(self, dictionary, search_key, new_value):
1434+ """Loop recursively through a dictionary looking for the specified key
1435+ substituting its value.
1436+ In a metadata file, at least two fields from the Config class have
1437+ their value calculated during the build phase of the hardware pack.
1438+ Here those known fiels will be updated with the newly calculated
1439+ values.
1440+
1441+ :param dictionary: The dictionary to loop through.
1442+ :param search_key: The key to search.
1443+ :param new_value: The new value for the key.
1444+ """
1445+ for key, value in dictionary.iteritems():
1446+ if key == search_key:
1447+ dictionary[key] = new_value
1448+ break
1449+ elif isinstance(value, dict):
1450+ self.set_config_value(value, search_key, new_value)
1451+
1452+ def create_metadata_new(self):
1453+ """Get the contents of the metadata file.
1454+
1455+ The metadata file is almost an identical copy of the hwpack
1456+ configuration file. Only a couple of fields are different, and some
1457+ are missing.
1458+
1459+ :return A string.
1460+ """
1461+ metadata = ""
1462+ metadata += dump({FORMAT_FIELD: self.format.format_as_string})
1463+ metadata += dump({NAME_FIELD: self.name})
1464+ metadata += dump({METADATA_VERSION_FIELD: self.version})
1465+ # This is a single 'architecture' hwpack, each arch will get its own,
1466+ # it is not retrieved from the Config.
1467+ metadata += dump({METADATA_ARCH_FIELD: self.architecture})
1468+ if self.origin is not None:
1469+ metadata += dump({ORIGIN_FIELD: self.origin})
1470+ if self.maintainer is not None:
1471+ metadata += dump({MAINTAINER_FIELD: self.maintainer})
1472+ if self.support is not None:
1473+ metadata += dump({SUPPORT_FIELD: self.support})
1474+ if self.bootloaders is not None:
1475+ # XXX We need to do this, since some necessary values are set
1476+ # when the hwpack archive is built, and are not in the hwpack
1477+ # config. Since we know which are the keys we have to look for,
1478+ # we just loop through all of them.
1479+ if self.spl is not None:
1480+ self.set_config_value(self.bootloaders, SPL_FILE_FIELD,
1481+ self.spl)
1482+ if self.u_boot is not None:
1483+ self.set_config_value(self.bootloaders, FILE_FIELD,
1484+ self.u_boot)
1485+ metadata += dump({BOOTLOADERS_FIELD: self.bootloaders})
1486+ if self.serial_tty is not None:
1487+ metadata += dump({SERIAL_TTY_FIELD: self.serial_tty})
1488+ if self.kernel_addr is not None:
1489+ metadata += dump({KERNEL_ADDR_FIELD: self.kernel_addr})
1490+ if self.initrd_addr is not None:
1491+ metadata += dump({INITRD_ADDR_FIELD: self.initrd_addr})
1492+ if self.load_addr is not None:
1493+ metadata += dump({LOAD_ADDR_FIELD: self.load_addr})
1494+ if self.dtb_addr is not None:
1495+ metadata += dump({DTB_ADDR_FIELD: self.dtb_addr})
1496+ if self.wired_interfaces != []:
1497+ eth_interfaces = " ".join(self.wired_interfaces)
1498+ metadata += dump({WIRED_INTERFACES_FIELD: eth_interfaces})
1499+ if self.wireless_interfaces != []:
1500+ wifi_interfaces = " ".join(self.wireless_interfaces)
1501+ metadata += dump({WIRELESS_INTERFACES_FIELD: wifi_interfaces})
1502+ if self.partition_layout is not None:
1503+ metadata += dump({PARTITION_LAYOUT_FIELD: self.partition_layout})
1504+ if self.mmc_id is not None:
1505+ metadata += dump({MMC_ID_FIELD: self.mmc_id})
1506+ if self.boot_min_size is not None:
1507+ metadata += dump({BOOT_MIN_SIZE_FIELD: self.boot_min_size})
1508+ if self.root_min_size is not None:
1509+ metadata += dump({ROOT_MIN_SIZE_FIELD: self.root_min_size})
1510+ if self.loader_min_size is not None:
1511+ metadata += dump({LOADER_MIN_SIZE_FIELD: self.loader_min_size})
1512+ if self.loader_start is not None:
1513+ metadata += dump({LOADER_START_FIELD: self.loader_start})
1514+ if self.vmlinuz is not None:
1515+ metadata += dump({KERNEL_FILE_FIELD: self.vmlinuz})
1516+ if self.initrd is not None:
1517+ metadata += dump({INITRD_FILE_FIELD: self.initrd})
1518+ if self.dtb_file is not None:
1519+ # XXX In V3 this one should be a list, called dtb_files.
1520+ metadata += dump({DTB_FILE_FIELD: self.dtb_file})
1521+ if self.boot_script is not None:
1522+ metadata += dump({BOOT_SCRIPT_FIELD: self.boot_script})
1523+ if self.extra_serial_opts is not None:
1524+ # XXX Check why and where once we get a list once a string.
1525+ if isinstance(self.extra_serial_opts, list):
1526+ extra_serial_options = " ".join(self.extra_serial_opts)
1527+ else:
1528+ extra_serial_options = self.extra_serial_opts
1529+ metadata += dump({
1530+ EXTRA_SERIAL_OPTIONS_FIELD:
1531+ extra_serial_options})
1532+ if self.snowball_startup_files_config is not None:
1533+ metadata += dump({SNOWBALL_STARTUP_FILES_CONFIG_FIELD:
1534+ self.snowball_startup_files_config})
1535+ if self.samsung_bl1_start is not None:
1536+ metadata += dump({SAMSUNG_BL1_START_FIELD: self.samsung_bl1_start})
1537+ if self.samsung_bl1_len is not None:
1538+ metadata += dump({SAMSUNG_BL1_LEN_FIELD: self.samsung_bl1_len})
1539+ if self.samsung_env_len is not None:
1540+ metadata += dump({SAMSUNG_ENV_LEN_FIELD: self.samsung_env_len})
1541+ if self.samsung_bl2_len is not None:
1542+ metadata += dump({SAMSUNG_BL2_LEN_FIELD: self.samsung_bl2_len})
1543+ return metadata
1544+
1545+ def create_metadata_old(self):
1546+ """Get the contents of the metadata file.
1547+
1548+ Creates a metadata file for v1 and v2 of the hwpack config file.
1549+ """
1550 metadata = "NAME=%s\n" % self.name
1551 metadata += "VERSION=%s\n" % self.version
1552 metadata += "ARCHITECTURE=%s\n" % self.architecture
1553@@ -264,7 +434,6 @@
1554 metadata += "SAMSUNG_ENV_LEN=%s\n" % self.samsung_env_len
1555 if self.samsung_bl2_len is not None:
1556 metadata += "SAMSUNG_BL2_LEN=%s\n" % self.samsung_bl2_len
1557-
1558 return metadata
1559
1560
1561
1562=== modified file 'linaro_image_tools/hwpack/hardwarepack_format.py'
1563--- linaro_image_tools/hwpack/hardwarepack_format.py 2012-06-13 14:26:02 +0000
1564+++ linaro_image_tools/hwpack/hardwarepack_format.py 2012-07-23 15:38:20 +0000
1565@@ -57,3 +57,12 @@
1566 self.is_supported = True
1567 self.is_deprecated = False
1568 self.has_v2_fields = True
1569+
1570+
1571+class HardwarePackFormatV3(HardwarePackFormat):
1572+ def __init__(self):
1573+ super(HardwarePackFormatV3, self).__init__()
1574+ self.format_as_string = "3.0"
1575+ self.is_supported = True
1576+ self.is_deprecated = False
1577+ self.has_v2_fields = True
1578
1579=== modified file 'linaro_image_tools/hwpack/hwpack_convert.py'
1580--- linaro_image_tools/hwpack/hwpack_convert.py 2012-07-19 15:10:43 +0000
1581+++ linaro_image_tools/hwpack/hwpack_convert.py 2012-07-23 15:38:20 +0000
1582@@ -46,6 +46,7 @@
1583 SPL_FILE_FIELD,
1584 WIRED_INTERFACES_FIELD,
1585 WIRELESS_INTERFACES_FIELD,
1586+ INCLUDE_DEBS_FIELD,
1587 )
1588
1589 # This is the main section of an INI-style hwpack config file.
1590@@ -70,6 +71,7 @@
1591
1592 # Old field, the only one with a dash: since the format is new, convert it.
1593 ASSUME_INSTALLED_OLD = 'assume-installed'
1594+INCLUDE_DEBS_OLD = 'include-debs'
1595
1596 # The default bootloader for the bootloaders section.
1597 DEFAULT_BOOTLOADER = 'u_boot'
1598@@ -121,6 +123,8 @@
1599 self.wireless_interfaces = []
1600 # SPL entries
1601 self.spl = {}
1602+ # The list of packages that should be installed.
1603+ self.assume_installed = []
1604
1605 def _parse(self):
1606 """Parses the config file and stores its values."""
1607@@ -171,9 +175,14 @@
1608 elif key in UBOOT_KEYS:
1609 self._set_bootloaders(key, value)
1610 continue
1611- # Convert an old key into the new one.
1612+ # Create list.
1613 elif key == ASSUME_INSTALLED_OLD:
1614- key = ASSUME_INSTALLED_FIELD
1615+ self.parse_list_string(
1616+ self.assume_installed,
1617+ value)
1618+ continue
1619+ elif key == INCLUDE_DEBS_OLD:
1620+ key = INCLUDE_DEBS_FIELD
1621 self.hwpack[key] = value
1622 else:
1623 # Here we have only sources sections.
1624@@ -231,6 +240,9 @@
1625 if self.architectures:
1626 archs = {ARCHITECTURES_FIELD: self.architectures}
1627 converted += dump(archs)
1628+ if self.assume_installed:
1629+ installed = {ASSUME_INSTALLED_FIELD: self.assume_installed}
1630+ converted += dump(installed)
1631 if self.extra_serial_options:
1632 serial_options = {EXTRA_SERIAL_OPTIONS_FIELD:
1633 self.extra_serial_options}
1634@@ -271,7 +283,7 @@
1635
1636 :param python_object: The object to serialize.
1637 """
1638- return yaml.dump(python_object, default_flow_style=False, indent=True)
1639+ return yaml.dump(python_object, default_flow_style=False)
1640
1641
1642 def check_and_validate_args(args):
1643
1644=== modified file 'linaro_image_tools/hwpack/hwpack_fields.py'
1645--- linaro_image_tools/hwpack/hwpack_fields.py 2012-07-19 15:10:43 +0000
1646+++ linaro_image_tools/hwpack/hwpack_fields.py 2012-07-23 15:38:20 +0000
1647@@ -25,6 +25,7 @@
1648 # Try to keep it alphabetically sorted per section.
1649 #
1650 ARCHITECTURES_FIELD = 'architectures'
1651+ARCHITECTURE_FIELD = 'architecture'
1652 ASSUME_INSTALLED_FIELD = 'assume_installed'
1653 BOARDS_FIELD = 'boards'
1654 BOOTLOADERS_FIELD = 'bootloaders'
1655@@ -36,6 +37,7 @@
1656 DTB_FILES_FIELD = 'dtb_files'
1657 EXTRA_SERIAL_OPTIONS_FIELD = 'extra_serial_options'
1658 FORMAT_FIELD = 'format'
1659+INCLUDE_DEBS_FIELD = 'include_debs'
1660 INITRD_ADDR_FIELD = 'initrd_addr'
1661 INITRD_FILE_FIELD = 'initrd_file'
1662 KERNEL_ADDR_FIELD = 'kernel_addr'
1663@@ -55,6 +57,7 @@
1664 SUPPORT_FIELD = 'support'
1665 WIRED_INTERFACES_FIELD = 'wired_interfaces'
1666 WIRELESS_INTERFACES_FIELD = 'wireless_interfaces'
1667+VERSION_FIELD = 'version'
1668
1669 # Bootloaders specific fields
1670 DD_FIELD = 'dd'
1671
1672=== modified file 'linaro_image_tools/hwpack/tests/__init__.py'
1673--- linaro_image_tools/hwpack/tests/__init__.py 2012-07-19 07:49:47 +0000
1674+++ linaro_image_tools/hwpack/tests/__init__.py 2012-07-23 15:38:20 +0000
1675@@ -27,6 +27,7 @@
1676 'linaro_image_tools.hwpack.tests.test_better_tarfile',
1677 'linaro_image_tools.hwpack.tests.test_builder',
1678 'linaro_image_tools.hwpack.tests.test_config',
1679+ 'linaro_image_tools.hwpack.tests.test_config_v3',
1680 'linaro_image_tools.hwpack.tests.test_hardwarepack',
1681 'linaro_image_tools.hwpack.tests.test_hwpack_converter',
1682 'linaro_image_tools.hwpack.tests.test_packages',
1683
1684=== modified file 'linaro_image_tools/hwpack/tests/test_config.py'
1685--- linaro_image_tools/hwpack/tests/test_config.py 2012-06-13 14:32:49 +0000
1686+++ linaro_image_tools/hwpack/tests/test_config.py 2012-07-23 15:38:20 +0000
1687@@ -24,6 +24,9 @@
1688 from testtools import TestCase
1689
1690 from linaro_image_tools.hwpack.config import Config, HwpackConfigError
1691+from linaro_image_tools.hwpack.hwpack_fields import (
1692+ DEFINED_PARTITION_LAYOUTS,
1693+)
1694
1695
1696 class ConfigTests(TestCase):
1697@@ -72,7 +75,7 @@
1698
1699 def test_validate_no_name(self):
1700 config = self.get_config("[hwpack]\n")
1701- self.assertValidationError("No name in the [hwpack] section", config)
1702+ self.assertValidationError("Empty value for name", config)
1703
1704 def test_validate_empty_name(self):
1705 config = self.get_config("[hwpack]\nname = \n")
1706@@ -87,7 +90,8 @@
1707 "[hwpack]\nname = ahwpack\n"
1708 "include-debs = if you don't mind\n")
1709 self.assertValidationError(
1710- "Invalid value for include-debs: if you don't mind", config)
1711+ "Invalid value for include-debs: Not a boolean: if you don't mind",
1712+ config)
1713
1714 def test_validate_invalid_supported(self):
1715 config = self.get_config(
1716@@ -192,11 +196,9 @@
1717 self.assertEqual(None, config.validate())
1718
1719 def test_validate_supported_format(self):
1720- config = self.get_config(
1721- self.valid_start
1722- + "\nformat = 0.9\n")
1723- self.assertValidationError(
1724- "Format version '0.9' is not supported.", config)
1725+ contents = self.valid_start + "format = 0.9\n"
1726+ config = Config(StringIO(contents))
1727+ self.assertRaises(HwpackConfigError, config.validate)
1728
1729 def test_validate_invalid_u_boot_package_name(self):
1730 config = self.get_config(
1731@@ -307,7 +309,7 @@
1732 "Undefined partition layout %s in the [%s] section. "
1733 "Valid partition layouts are %s."
1734 % (partition_layout, 'hwpack',
1735- ", ".join(config.DEFINED_PARTITION_LAYOUTS)), config)
1736+ ", ".join(DEFINED_PARTITION_LAYOUTS)), config)
1737
1738 def test_validate_wired_interfaces(self):
1739 self.assertTrue("XXX What is an invalid interface name?")
1740
1741=== added file 'linaro_image_tools/hwpack/tests/test_config_v3.py'
1742--- linaro_image_tools/hwpack/tests/test_config_v3.py 1970-01-01 00:00:00 +0000
1743+++ linaro_image_tools/hwpack/tests/test_config_v3.py 2012-07-23 15:38:20 +0000
1744@@ -0,0 +1,738 @@
1745+# Copyright (C) 2010 - 2012 Linaro
1746+#
1747+# Author: James Tunnicliffe <james.tunnicliffe@linaro.org>
1748+#
1749+# This file is part of Linaro Image Tools.
1750+#
1751+# Linaro Image Tools is free software; you can redistribute it and/or
1752+# modify it under the terms of the GNU General Public License
1753+# as published by the Free Software Foundation; either version 2
1754+# of the License, or (at your option) any later version.
1755+#
1756+# Linaro Image Tools is distributed in the hope that it will be useful,
1757+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1758+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1759+# GNU General Public License for more details.
1760+#
1761+# You should have received a copy of the GNU General Public License
1762+# along with Linaro Image Tools; if not, write to the Free Software
1763+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
1764+# USA.
1765+
1766+import re
1767+from StringIO import StringIO
1768+from testtools import TestCase
1769+
1770+from linaro_image_tools.hwpack.config import Config, HwpackConfigError
1771+from linaro_image_tools.hwpack.hwpack_fields import (
1772+ DEFINED_PARTITION_LAYOUTS,
1773+)
1774+
1775+
1776+class ConfigTests(TestCase):
1777+
1778+ valid_start = (
1779+ "name: ahwpack\npackages: foo\narchitectures: armel\n")
1780+ valid_start_v3 = valid_start + "format: 3.0\n"
1781+ valid_complete_v3 = (valid_start_v3 +
1782+ "serial_tty: ttySAC1\n"
1783+ "partition_layout:\n"
1784+ " - bootfs_rootfs\n"
1785+ "boot_script: boot.scr\n"
1786+ "extra_serial_options:\n"
1787+ " - console=tty0\n"
1788+ " - console=ttyO2,115200n8\n"
1789+ "mmc_id: 0:1\n"
1790+ "kernel_file: boot/vmlinuz-*-linaro-omap\n"
1791+ "initrd_file: boot/initrd.img-*-linaro-omap\n"
1792+ "dtb_file: boot/dt-*-linaro-omap/omap4-panda.dtb\n"
1793+ "bootloaders:\n"
1794+ " u_boot:\n"
1795+ " package: u-boot-linaro-s5pv310\n"
1796+ " file: usr/lib/u-boot/smdkv310/u-boot.bin\n"
1797+ " spl_package: x-loader-omap4-panda\n"
1798+ " spl_file: usr/lib/x-loader/omap4430panda/MLO\n"
1799+ " in_boot_part: True\n"
1800+ " extra_boot_options:\n"
1801+ " - earlyprintk\n"
1802+ " - fixrtc\n"
1803+ " - nocompcache\n"
1804+ " - vram=48M\n"
1805+ " - omapfb.vram=0:24M\n"
1806+ " - mem=456M@0x80000000\n"
1807+ " - mem=512M@0xA0000000\n")
1808+ valid_end = "sources:\n sources-entry: foo bar\n"
1809+
1810+ def test_create(self):
1811+ config = Config(StringIO())
1812+ self.assertTrue(config is not None)
1813+
1814+ def get_config(self, contents):
1815+ if not re.search("\s*format\s*:", contents):
1816+ contents = "format: 3.0\n" + contents
1817+ return Config(StringIO(contents), bootloader="u_boot")
1818+
1819+ def assertConfigError(self, contents, f, *args, **kwargs):
1820+ e = self.assertRaises(HwpackConfigError, f, *args, **kwargs)
1821+ self.assertEqual(contents, str(e))
1822+
1823+ def assertValidationError(self, contents, validate_function):
1824+ self.assertConfigError(contents, validate_function)
1825+
1826+ def test_validate_empty_name(self):
1827+ config = self.get_config("name: ")
1828+ self.assertValidationError("Empty value for name",
1829+ config._validate_name)
1830+
1831+ def test_validate_invalid_name(self):
1832+ config = self.get_config("name: ~~\n")
1833+ self.assertValidationError("Invalid name: ~~",
1834+ config._validate_name)
1835+
1836+ def test_validate_invalid_include_debs(self):
1837+ config = self.get_config(
1838+ "name: ahwpack\n"
1839+ "include_debs: if you don't mind\n")
1840+ self.assertValidationError(
1841+ "Invalid value for include-debs: if you don't mind",
1842+ config._validate_include_debs)
1843+
1844+ def test_validate_invalid_supported(self):
1845+ config = self.get_config(
1846+ "name: ahwpack\nsupport: if you pay us\n")
1847+ self.assertValidationError(
1848+ "Invalid value for support: if you pay us",
1849+ config._validate_support)
1850+
1851+ def test_validate_no_packages(self):
1852+ config = self.get_config(
1853+ "name: ahwpack\n\n")
1854+ self.assertValidationError(
1855+ "No packages found in the metadata", config._validate_packages)
1856+
1857+ def test_validate_empty_packages(self):
1858+ config = self.get_config(
1859+ "name: ahwpack\npackages: \n")
1860+ self.assertValidationError(
1861+ "No packages found in the metadata", config._validate_packages)
1862+
1863+ def test_validate_invalid_package_name(self):
1864+ config = self.get_config(
1865+ "name: ahwpack\npackages: foo ~~ bar\n")
1866+ self.assertValidationError(
1867+ "Invalid value in packages in the metadata: ~~",
1868+ config._validate_packages)
1869+
1870+ def test_validate_no_architectures(self):
1871+ config = self.get_config(
1872+ "name: ahwpack\npackages: foo\n")
1873+ self.assertValidationError(
1874+ "No architectures found in the metadata",
1875+ config._validate_architectures)
1876+
1877+ def test_validate_empty_architectures(self):
1878+ config = self.get_config(
1879+ "name: ahwpack\npackages: foo\n"
1880+ "architectures: \n")
1881+ self.assertValidationError(
1882+ "No architectures found in the metadata",
1883+ config._validate_architectures)
1884+
1885+ def test_validate_invalid_package_name_in_assume_installed(self):
1886+ config = self.get_config(
1887+ "name: ahwpack\npackages: foo\n"
1888+ "architectures: armel\nassume_installed:\n - bar\n - ~~\n")
1889+ self.assertValidationError(
1890+ "Invalid value in assume-installed in the metadata: ~~",
1891+ config._validate_assume_installed)
1892+
1893+ def test_validate_other_section_empty_sources_entry(self):
1894+ config = self.get_config(
1895+ self.valid_start + "sources:\n ubuntu: \n")
1896+ self.assertValidationError(
1897+ "The sources-entry, ubuntu is missing the URI",
1898+ config._validate_sources)
1899+
1900+ def test_validate_other_section_only_uri_in_sources_entry(self):
1901+ config = self.get_config(
1902+ self.valid_start + "sources:\n ubuntu: foo\n")
1903+ self.assertValidationError(
1904+ "The sources-entry, ubuntu is missing the distribution",
1905+ config._validate_sources)
1906+
1907+ def test_validate_other_section_sources_entry_starting_with_deb(self):
1908+ config = self.get_config(self.valid_start +
1909+ "sources:\n ubuntu: deb http://example.org/ foo main\n")
1910+ self.assertValidationError(
1911+ "The sources-entry, ubuntu shouldn't start with 'deb'",
1912+ config._validate_sources)
1913+
1914+ def test_validate_other_section_sources_entry_starting_with_deb_src(self):
1915+ config = self.get_config(self.valid_start +
1916+ "sources:\n ubuntu: deb-src http://example.org/ foo main\n")
1917+ self.assertValidationError(
1918+ "The sources-entry, ubuntu shouldn't start with 'deb'",
1919+ config._validate_sources)
1920+
1921+ def test_validate_valid_config(self):
1922+ config = self.get_config(self.valid_complete_v3)
1923+ self.assertEqual(None, config.validate())
1924+
1925+ def test_validate_supported_format(self):
1926+ config = self.get_config(self.valid_start + "format: 0.9\n")
1927+ self.assertValidationError(
1928+ "Format version '0.9' is not supported.", config._validate_format)
1929+
1930+ def test_validate_invalid_u_boot_package_name(self):
1931+ config = self.get_config(self.valid_start_v3 +
1932+ "bootloaders:\n"
1933+ " u_boot:\n"
1934+ " package: ~~\n")
1935+ self.assertValidationError(
1936+ "Invalid value in u_boot_package in the metadata: ~~",
1937+ config._validate_u_boot_package)
1938+
1939+ def test_validate_invalid_u_boot_file(self):
1940+ config = self.get_config(self.valid_start_v3 +
1941+ "bootloaders:\n"
1942+ " u_boot:\n"
1943+ " file: ~~\n")
1944+ self.assertValidationError("Invalid path: ~~",
1945+ config._validate_u_boot_file)
1946+
1947+ def test_validate_invalid_kernel_file(self):
1948+ config = self.get_config(self.valid_start_v3 +
1949+ "kernel_file: ~~\n")
1950+ self.assertValidationError("Invalid path: ~~",
1951+ config._validate_vmlinuz)
1952+
1953+ def test_validate_empty_kernel_file(self):
1954+ config = self.get_config(self.valid_start_v3 +
1955+ "kernel_file: \n")
1956+ self.assertValidationError("No kernel_file found in the metadata",
1957+ config._validate_vmlinuz)
1958+
1959+ def test_validate_invalid_initrd_file(self):
1960+ config = self.get_config(self.valid_start_v3 +
1961+ "initrd_file: ~~\n")
1962+ self.assertValidationError("Invalid path: ~~", config._validate_initrd)
1963+
1964+ def test_validate_empty_initrd_file(self):
1965+ config = self.get_config(self.valid_start_v3 +
1966+ "kernel_file: \n")
1967+ self.assertValidationError("No initrd_file found in the metadata",
1968+ config._validate_initrd)
1969+
1970+ def test_validate_invalid_boot_script(self):
1971+ config = self.get_config(self.valid_start_v3 + "boot_script: ~~")
1972+ self.assertValidationError("Invalid path: ~~",
1973+ config._validate_boot_script)
1974+
1975+ def test_validate_invalid_dtb_file(self):
1976+ config = self.get_config(self.valid_start_v3 +
1977+ "dtb_file: ~~\n")
1978+ self.assertValidationError("Invalid path: ~~",
1979+ config._validate_dtb_file)
1980+
1981+ def test_validate_invalid_spl_package_name(self):
1982+ config = self.get_config(self.valid_start_v3 +
1983+ "bootloaders:\n"
1984+ " u_boot:\n"
1985+ " spl_package: ~~\n")
1986+ config.set_board("panda")
1987+ self.assertValidationError(
1988+ "Invalid value in spl_package in the metadata: ~~",
1989+ config._validate_spl_package)
1990+
1991+ def test_validate_invalid_spl_file(self):
1992+ config = self.get_config(self.valid_start_v3 +
1993+ "boards:\n"
1994+ " panda:\n"
1995+ " bootloaders:\n"
1996+ " u_boot:\n"
1997+ " spl_file: ~~\n")
1998+ config.set_board("panda")
1999+ self.assertValidationError("Invalid path: ~~",
2000+ config._validate_spl_file)
2001+
2002+ def test_validate_partition_layout(self):
2003+ partition_layout = 'apafs_bananfs'
2004+ config = self.get_config(self.valid_start_v3 +
2005+ "partition_layout: " + partition_layout)
2006+ self.assertValidationError(
2007+ "Undefined partition layout %s. "
2008+ "Valid partition layouts are %s."
2009+ % (partition_layout,
2010+ ", ".join(DEFINED_PARTITION_LAYOUTS)),
2011+ config._validate_partition_layout)
2012+
2013+ def test_validate_wired_interfaces(self):
2014+ self.assertTrue("XXX What is an invalid interface name?")
2015+
2016+ def test_validate_wireless_interfaces(self):
2017+ self.assertTrue("XXX What is an invalid interface name?")
2018+
2019+ def test_validate_u_boot_in_boot_part_bool(self):
2020+ config = self.get_config(
2021+ self.valid_start_v3 +
2022+ "bootloaders:\n"
2023+ " u_boot:\n"
2024+ " in_boot_part: Nope\n")
2025+ self.assertValidationError(
2026+ "Invalid value for u_boot_in_boot_part: Nope",
2027+ config._validate_uboot_in_boot_part)
2028+
2029+ def test_find_board_specific_variable(self):
2030+ config = self.get_config(
2031+ self.valid_start_v3 +
2032+ "boards:\n"
2033+ " panda:\n"
2034+ " bootloaders:\n"
2035+ " u_boot:\n"
2036+ " in_boot_part: Yes\n")
2037+
2038+ config.set_bootloader("u_boot")
2039+ config.set_board("panda")
2040+
2041+ config._validate_uboot_in_boot_part()
2042+ self.assertEqual(config.uboot_in_boot_part, "yes")
2043+
2044+ def test_board_specific_overwrites_global(self):
2045+ config = self.get_config(
2046+ self.valid_start_v3 +
2047+ "bootloaders:\n"
2048+ " u_boot:\n"
2049+ " in_boot_part: No\n"
2050+ "boards:\n"
2051+ " panda:\n"
2052+ " bootloaders:\n"
2053+ " u_boot:\n"
2054+ " in_boot_part: Yes\n")
2055+
2056+ config.set_bootloader("u_boot")
2057+ config.set_board("panda")
2058+
2059+ config._validate_uboot_in_boot_part()
2060+ self.assertEqual(config.uboot_in_boot_part, "yes")
2061+
2062+ def test_validate_serial_tty(self):
2063+ config = self.get_config(self.valid_start_v3 + "serial_tty: tty\n")
2064+ self.assertValidationError("Invalid serial tty: tty",
2065+ config._validate_serial_tty)
2066+
2067+ config = self.get_config(self.valid_start_v3 + "serial_tty: ttxSAC1\n")
2068+ self.assertValidationError("Invalid serial tty: ttxSAC1",
2069+ config._validate_serial_tty)
2070+
2071+ def test_validate_mmc_id(self):
2072+ config = self.get_config(self.valid_complete_v3 +
2073+ "mmc_id: x\n")
2074+ self.assertValidationError("Invalid mmc_id x", config._validate_mmc_id)
2075+
2076+ def test_validate_boot_min_size(self):
2077+ config = self.get_config(self.valid_complete_v3 +
2078+ "boot_min_size: x\n")
2079+ self.assertValidationError("Invalid boot min size x",
2080+ config._validate_boot_min_size)
2081+
2082+ def test_validate_root_min_size(self):
2083+ config = self.get_config(self.valid_complete_v3 +
2084+ "root_min_size: x\n")
2085+ self.assertValidationError("Invalid root min size x",
2086+ config._validate_root_min_size)
2087+
2088+ def test_validate_loader_min_size(self):
2089+ config = self.get_config(self.valid_complete_v3 +
2090+ "loader_min_size: x\n")
2091+ self.assertValidationError("Invalid loader min size x",
2092+ config._validate_loader_min_size)
2093+
2094+ def test_validate_kernel_addr(self):
2095+ # V3 change: All numerical inputs are good addresses (since YAML
2096+ # converts them to ingegers and we convert them back to the correct
2097+ # format). We don't need 8 digit hex values for addresses.
2098+ config = self.get_config(self.valid_complete_v3 +
2099+ "kernel_addr: 0x8000000\n")
2100+ config._validate_kernel_addr()
2101+ config = self.get_config(self.valid_complete_v3 +
2102+ "kernel_addr: 0x8000000x\n")
2103+ self.assertValidationError(
2104+ "Invalid kernel address: 0x8000000x", config._validate_kernel_addr)
2105+ config = self.get_config(self.valid_complete_v3 +
2106+ "kernel_addr: 80000000\n")
2107+ config._validate_kernel_addr()
2108+
2109+ def test_validate_initrd_addr(self):
2110+ # V3 change: All numerical inputs are good addresses (since YAML
2111+ # converts them to ingegers and we convert them back to the correct
2112+ # format). We don't need 8 digit hex values for addresses.
2113+ config = self.get_config(self.valid_complete_v3 +
2114+ "initrd_addr: 0x8000000\n")
2115+ config._validate_initrd_addr()
2116+ config = self.get_config(self.valid_complete_v3 +
2117+ "initrd_addr: 0x8000000x\n")
2118+ self.assertValidationError(
2119+ "Invalid initrd address: 0x8000000x", config._validate_initrd_addr)
2120+ config = self.get_config(self.valid_complete_v3 +
2121+ "initrd_addr: 80000000\n")
2122+ config._validate_initrd_addr()
2123+
2124+ def test_validate_load_addr(self):
2125+ # V3 change: All numerical inputs are good addresses (since YAML
2126+ # converts them to ingegers and we convert them back to the correct
2127+ # format). We don't need 8 digit hex values for addresses.
2128+ config = self.get_config(self.valid_complete_v3 +
2129+ "load_addr: 0x8000000\n")
2130+ config._validate_load_addr()
2131+ config = self.get_config(self.valid_complete_v3 +
2132+ "load_addr: 0x8000000x\n")
2133+ self.assertValidationError("Invalid load address: 0x8000000x",
2134+ config._validate_load_addr)
2135+ config = self.get_config(self.valid_complete_v3 +
2136+ "load_addr: 80000000\n")
2137+ config._validate_load_addr()
2138+
2139+ def test_validate_dtb_addr(self):
2140+ # V3 change: All numerical inputs are good addresses (since YAML
2141+ # converts them to ingegers and we convert them back to the correct
2142+ # format). We don't need 8 digit hex values for addresses.
2143+ config = self.get_config(self.valid_complete_v3 +
2144+ "dtb_addr: 0x8000000\n")
2145+ config._validate_dtb_addr()
2146+ config = self.get_config(self.valid_complete_v3 +
2147+ "dtb_addr: 0x8000000x\n")
2148+ self.assertValidationError("Invalid dtb address: 0x8000000x",
2149+ config._validate_dtb_addr)
2150+ config = self.get_config(self.valid_complete_v3 +
2151+ "dtb_addr: 80000000\n")
2152+ config._validate_dtb_addr()
2153+
2154+ def test_wired_interfaces(self):
2155+ config = self.get_config(self.valid_complete_v3 +
2156+ "wired_interfaces:\n - eth0\n" +
2157+ self.valid_end)
2158+ config.validate()
2159+ self.assertEqual(["eth0"], config.wired_interfaces)
2160+ config = self.get_config(self.valid_complete_v3 +
2161+ "wired_interfaces:\n"
2162+ " - eth0\n"
2163+ " - eth1\n"
2164+ " - usb2\n" +
2165+ self.valid_end)
2166+ config.validate()
2167+ self.assertEqual(["eth0", "eth1", "usb2"], config.wired_interfaces)
2168+
2169+ def test_wireless_interfaces(self):
2170+ config = self.get_config(self.valid_complete_v3 +
2171+ "wireless_interfaces:\n"
2172+ " - wlan0\n" +
2173+ self.valid_end)
2174+ config.validate()
2175+ self.assertEqual(["wlan0"], config.wireless_interfaces)
2176+ config = self.get_config(self.valid_complete_v3 +
2177+ "wireless_interfaces:\n"
2178+ " - wlan0\n"
2179+ " - wl1\n"
2180+ " - usb2\n" +
2181+ self.valid_end)
2182+ config.validate()
2183+ self.assertEqual(["wlan0", "wl1", "usb2"], config.wireless_interfaces)
2184+
2185+ def test_partition_layout(self):
2186+ config = self.get_config(self.valid_complete_v3 + self.valid_end)
2187+ config.validate()
2188+ self.assertEqual("bootfs_rootfs",
2189+ config.partition_layout)
2190+
2191+ def test_u_boot_file(self):
2192+ config = self.get_config(self.valid_complete_v3 + self.valid_end)
2193+ config.validate()
2194+ self.assertEqual("usr/lib/u-boot/smdkv310/u-boot.bin",
2195+ config.u_boot_file)
2196+
2197+ def test_u_boot_package(self):
2198+ config = self.get_config(self.valid_complete_v3 + self.valid_end)
2199+ config.validate()
2200+ self.assertEqual("u-boot-linaro-s5pv310",
2201+ config.u_boot_package)
2202+
2203+ def test_spl_file(self):
2204+ config = self.get_config(self.valid_complete_v3 + self.valid_end)
2205+ config.validate()
2206+ self.assertEqual("usr/lib/x-loader/omap4430panda/MLO",
2207+ config.spl_file)
2208+
2209+ def test_kernel_file(self):
2210+ config = self.get_config(self.valid_complete_v3 + self.valid_end)
2211+ config.validate()
2212+ self.assertEqual("boot/vmlinuz-*-linaro-omap",
2213+ config.vmlinuz)
2214+
2215+ def test_initrd_file(self):
2216+ config = self.get_config(self.valid_complete_v3 + self.valid_end)
2217+ config.validate()
2218+ self.assertEqual("boot/initrd.img-*-linaro-omap",
2219+ config.initrd)
2220+
2221+ def test_dtb_file(self):
2222+ config = self.get_config(self.valid_complete_v3 + self.valid_end)
2223+ config.validate()
2224+ self.assertEqual("boot/dt-*-linaro-omap/omap4-panda.dtb",
2225+ config.dtb_file)
2226+
2227+ def test_extra_boot_options(self):
2228+ config = self.get_config(self.valid_complete_v3 + self.valid_end)
2229+ config.validate()
2230+ self.assertEqual(
2231+ "earlyprintk fixrtc nocompcache vram=48M "
2232+ "omapfb.vram=0:24M mem=456M@0x80000000 mem=512M@0xA0000000",
2233+ config.extra_boot_options)
2234+
2235+ def test_extra_serial_opts(self):
2236+ config = self.get_config(self.valid_complete_v3 + self.valid_end)
2237+ config.validate()
2238+ self.assertEqual('console=tty0 console=ttyO2,115200n8',
2239+ config.extra_serial_opts)
2240+
2241+ def test_boot_script(self):
2242+ config = self.get_config(self.valid_complete_v3 + self.valid_end)
2243+ config.validate()
2244+ self.assertEqual("boot.scr",
2245+ config.boot_script)
2246+
2247+ def test_u_boot_in_boot_part(self):
2248+ config = self.get_config(self.valid_complete_v3 + self.valid_end)
2249+ config.validate()
2250+ self.assertEqual("yes",
2251+ config.uboot_in_boot_part)
2252+
2253+ def test_spl_package(self):
2254+ config = self.get_config(self.valid_complete_v3 + self.valid_end)
2255+ config.validate()
2256+ self.assertEqual("x-loader-omap4-panda",
2257+ config.spl_package)
2258+
2259+ def test_serial_tty(self):
2260+ config = self.get_config(self.valid_complete_v3 + self.valid_end)
2261+ config.validate()
2262+ self.assertEqual("ttySAC1", config.serial_tty)
2263+
2264+ def test_mmc_id(self):
2265+ config = self.get_config(self.valid_complete_v3 +
2266+ "mmc_id: 0:1\n" +
2267+ self.valid_end)
2268+ config.validate()
2269+ self.assertEqual("0:1", config.mmc_id)
2270+
2271+ def test_boot_min_size(self):
2272+ config = self.get_config(self.valid_complete_v3 +
2273+ "boot_min_size: 50\n" +
2274+ self.valid_end)
2275+ config.validate()
2276+ self.assertEqual("50", config.boot_min_size)
2277+
2278+ def test_root_min_size(self):
2279+ config = self.get_config(self.valid_complete_v3 +
2280+ "root_min_size: 50\n" +
2281+ self.valid_end)
2282+ config.validate()
2283+ self.assertEqual("50", config.root_min_size)
2284+
2285+ def test_loader_min_size(self):
2286+ config = self.get_config(self.valid_complete_v3 +
2287+ "loader_min_size: 2\n" +
2288+ self.valid_end)
2289+ config.validate()
2290+ self.assertEqual("2", config.loader_min_size)
2291+
2292+ def test_kernel_addr(self):
2293+ config = self.get_config(self.valid_complete_v3 +
2294+ "kernel_addr: 0x80000000\n" +
2295+ self.valid_end)
2296+ config.validate()
2297+ self.assertEqual("0x80000000", config.kernel_addr)
2298+ config = self.get_config(self.valid_complete_v3 +
2299+ "kernel_addr: 0x8aBcdEFf\n" +
2300+ self.valid_end)
2301+ config.validate()
2302+ self.assertEqual("0x8abcdeff", config.kernel_addr)
2303+
2304+ def test_initrd_addr(self):
2305+ config = self.get_config(self.valid_complete_v3 +
2306+ "initrd_addr: 0x80000000\n" +
2307+ self.valid_end)
2308+ config.validate()
2309+ self.assertEqual("0x80000000", config.initrd_addr)
2310+ config = self.get_config(self.valid_complete_v3 +
2311+ "initrd_addr: 0x8aBcdEFf\n" +
2312+ self.valid_end)
2313+ config.validate()
2314+ self.assertEqual("0x8abcdeff", config.initrd_addr)
2315+
2316+ def test_load_addr(self):
2317+ config = self.get_config(self.valid_complete_v3 +
2318+ "load_addr: 0x80000000\n" +
2319+ self.valid_end)
2320+ config.validate()
2321+ self.assertEqual("0x80000000", config.load_addr)
2322+ config = self.get_config(self.valid_complete_v3 +
2323+ "load_addr: 0x8aBcdEFf\n" +
2324+ self.valid_end)
2325+ config.validate()
2326+ self.assertEqual("0x8abcdeff", config.load_addr)
2327+
2328+ def test_dtb_addr(self):
2329+ config = self.get_config(self.valid_complete_v3 +
2330+ "dtb_addr: 0x80000000\n" +
2331+ self.valid_end)
2332+ config.validate()
2333+ self.assertEqual("0x80000000", config.dtb_addr)
2334+ config = self.get_config(self.valid_complete_v3 +
2335+ "dtb_addr: 0x8aBcdEFf\n" +
2336+ self.valid_end)
2337+ config.validate()
2338+ self.assertEqual("0x8abcdeff", config.dtb_addr)
2339+
2340+ def test_name(self):
2341+ config = self.get_config(
2342+ "name: ahwpack\n"
2343+ "packages: foo\n"
2344+ "architectures: armel\n")
2345+ self.assertEqual("ahwpack", config.name)
2346+
2347+ def test_include_debs(self):
2348+ config = self.get_config(self.valid_start + "include_debs: false\n")
2349+ self.assertEqual(False, config.include_debs)
2350+
2351+ def test_include_debs_defaults_true(self):
2352+ config = self.get_config(self.valid_start)
2353+ self.assertEqual(True, config.include_debs)
2354+
2355+ def test_include_debs_defaults_true_on_empty(self):
2356+ config = self.get_config(self.valid_start + "include_debs: \n")
2357+ self.assertEqual(True, config.include_debs)
2358+
2359+ def test_origin(self):
2360+ config = self.get_config(self.valid_start + "origin: linaro\n")
2361+ self.assertEqual("linaro", config.origin)
2362+
2363+ def test_origin_default_None(self):
2364+ config = self.get_config(self.valid_start)
2365+ self.assertEqual(None, config.origin)
2366+
2367+ def test_origin_None_on_empty(self):
2368+ config = self.get_config(self.valid_start + "origin: \n")
2369+ self.assertEqual(None, config.origin)
2370+
2371+ def test_maintainer(self):
2372+ maintainer = "Linaro Developers <linaro-dev@lists.linaro.org>"
2373+ config = self.get_config(
2374+ self.valid_start
2375+ + "maintainer: %s\n" % maintainer)
2376+ self.assertEqual(maintainer, config.maintainer)
2377+
2378+ def test_maintainer_default_None(self):
2379+ config = self.get_config(self.valid_start)
2380+ self.assertEqual(None, config.maintainer)
2381+
2382+ def test_maintainer_None_on_empty(self):
2383+ config = self.get_config(self.valid_start + "maintainer: \n")
2384+ self.assertEqual(None, config.maintainer)
2385+
2386+ def test_support_supported(self):
2387+ config = self.get_config(self.valid_start + "support: supported\n")
2388+ self.assertEqual("supported", config.support)
2389+
2390+ def test_support_unsupported(self):
2391+ config = self.get_config(self.valid_start + "support: unsupported\n")
2392+ self.assertEqual("unsupported", config.support)
2393+
2394+ def test_support_default_None(self):
2395+ config = self.get_config(self.valid_start)
2396+ self.assertEqual(None, config.support)
2397+
2398+ def test_support_None_on_empty(self):
2399+ config = self.get_config(self.valid_start + "support: \n")
2400+ self.assertEqual(None, config.support)
2401+
2402+ def test_packages(self):
2403+ config = self.get_config(
2404+ "name: ahwpack\n"
2405+ "packages:\n"
2406+ " - foo\n"
2407+ " - bar\n"
2408+ "architectures: armel\n")
2409+ self.assertEqual(["foo", "bar"], config.packages)
2410+
2411+ def test_packages_filters_duplicates(self):
2412+ config = self.get_config(
2413+ "name: ahwpack\n"
2414+ "packages:\n"
2415+ " - foo\n"
2416+ " - bar\n"
2417+ " - foo\n"
2418+ "architectures: armel\n")
2419+ self.assertEqual(["foo", "bar"], config.packages)
2420+
2421+ def test_sources_single(self):
2422+ config = self.get_config(
2423+ self.valid_start
2424+ + "sources:\n"
2425+ " ubuntu: http://example.org foo\n")
2426+ self.assertEqual({"ubuntu": "http://example.org foo"}, config.sources)
2427+
2428+ def test_sources_multiple(self):
2429+ config = self.get_config(
2430+ self.valid_start
2431+ + "sources:\n"
2432+ " ubuntu: http://example.org foo\n"
2433+ " linaro: http://example.org bar\n")
2434+ self.assertEqual(
2435+ {"ubuntu": "http://example.org foo",
2436+ "linaro": "http://example.org bar"},
2437+ config.sources)
2438+
2439+ def test_architectures(self):
2440+ config = self.get_config(
2441+ "hello: there\n"
2442+ "name: ahwpack\n"
2443+ "packages: foo\n"
2444+ "architectures:\n"
2445+ " - foo\n"
2446+ " - bar\n")
2447+ self.assertEqual(["foo", "bar"], config.architectures)
2448+
2449+ def test_architectures_filters_duplicates(self):
2450+ config = self.get_config(
2451+ "name: ahwpack\n"
2452+ "packages: foo\n"
2453+ "architectures:\n"
2454+ " - foo\n"
2455+ " - bar\n"
2456+ " - foo\n")
2457+ self.assertEqual(["foo", "bar"], config.architectures)
2458+
2459+ def test_assume_installed(self):
2460+ config = self.get_config(
2461+ "name: ahwpack\n"
2462+ "packages:\n"
2463+ " - foo\n"
2464+ "architectures:\n"
2465+ " - armel\n"
2466+ "assume_installed:\n"
2467+ " - foo\n"
2468+ " - bar\n")
2469+ self.assertEqual(["foo", "bar"], config.assume_installed)
2470+
2471+ def test_assume_installed_filters_duplicates(self):
2472+ config = self.get_config(
2473+ "name: ahwpack\n"
2474+ "packages:\n"
2475+ " - foo\n"
2476+ "architectures:\n"
2477+ " - armel\n"
2478+ "assume_installed:\n"
2479+ " - foo\n"
2480+ " - bar\n"
2481+ " - foo\n")
2482+ self.assertEqual(["foo", "bar"], config.assume_installed)
2483
2484=== modified file 'linaro_image_tools/hwpack/tests/test_hardwarepack.py'
2485--- linaro_image_tools/hwpack/tests/test_hardwarepack.py 2012-06-13 14:53:32 +0000
2486+++ linaro_image_tools/hwpack/tests/test_hardwarepack.py 2012-07-23 15:38:20 +0000
2487@@ -40,6 +40,7 @@
2488 from linaro_image_tools.hwpack.hardwarepack_format import (
2489 HardwarePackFormatV1,
2490 HardwarePackFormatV2,
2491+ HardwarePackFormatV3,
2492 )
2493
2494
2495@@ -87,174 +88,157 @@
2496
2497 def test_str(self):
2498 metadata = Metadata("ahwpack", "4", "armel")
2499- self.assertEqual(
2500- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n", str(metadata))
2501+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n")
2502+ self.assertEqual(expected_out, str(metadata))
2503
2504 def test_str_with_origin(self):
2505 metadata = Metadata("ahwpack", "4", "armel", origin="linaro")
2506- self.assertEqual(
2507- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\nORIGIN=linaro\n",
2508- str(metadata))
2509+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2510+ "ORIGIN=linaro\n")
2511+ self.assertEqual(expected_out, str(metadata))
2512
2513 def test_str_with_maintainer(self):
2514 metadata = Metadata(
2515 "ahwpack", "4", "armel", maintainer="Some Maintainer")
2516- self.assertEqual(
2517- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2518- "MAINTAINER=Some Maintainer\n",
2519- str(metadata))
2520+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2521+ "MAINTAINER=Some Maintainer\n")
2522+ self.assertEqual(expected_out, str(metadata))
2523
2524 def test_str_with_support(self):
2525 metadata = Metadata("ahwpack", "4", "armel", support="unsupported")
2526- self.assertEqual(
2527- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2528- "SUPPORT=unsupported\n",
2529- str(metadata))
2530+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2531+ "SUPPORT=unsupported\n")
2532+ self.assertEqual(expected_out, str(metadata))
2533
2534 def test_str_with_serial_tty(self):
2535 metadata = Metadata("ahwpack", "4", "armel",
2536 format=HardwarePackFormatV2())
2537 metadata.add_v2_config(serial_tty='ttyO2')
2538- self.assertEqual(
2539- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2540- "SERIAL_TTY=ttyO2\n",
2541- str(metadata))
2542+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2543+ "SERIAL_TTY=ttyO2\n")
2544+ self.assertEqual(expected_out, str(metadata))
2545
2546 def test_str_with_kernel_addr(self):
2547 metadata = Metadata("ahwpack", "4", "armel",
2548 format=HardwarePackFormatV2())
2549 metadata.add_v2_config(kernel_addr='0x80000000')
2550- self.assertEqual(
2551- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2552- "KERNEL_ADDR=0x80000000\n",
2553- str(metadata))
2554+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2555+ "KERNEL_ADDR=0x80000000\n")
2556+ self.assertEqual(expected_out, str(metadata))
2557
2558 def test_str_with_initrd_addr(self):
2559 metadata = Metadata("ahwpack", "4", "armel",
2560 format=HardwarePackFormatV2())
2561 metadata.add_v2_config(initrd_addr='0x80000000')
2562- self.assertEqual(
2563- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2564- "INITRD_ADDR=0x80000000\n",
2565- str(metadata))
2566+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2567+ "INITRD_ADDR=0x80000000\n")
2568+ self.assertEqual(expected_out, str(metadata))
2569
2570 def test_str_with_load_addr(self):
2571 metadata = Metadata("ahwpack", "4", "armel",
2572 format=HardwarePackFormatV2())
2573 metadata.add_v2_config(load_addr='0x80000000')
2574- self.assertEqual(
2575- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2576- "LOAD_ADDR=0x80000000\n",
2577- str(metadata))
2578+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2579+ "LOAD_ADDR=0x80000000\n")
2580+ self.assertEqual(expected_out, str(metadata))
2581
2582 def test_str_with_dtb_addr(self):
2583 metadata = Metadata("ahwpack", "4", "armel",
2584 format=HardwarePackFormatV2())
2585 metadata.add_v2_config(dtb_addr='0x80000000')
2586- self.assertEqual(
2587- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2588- "DTB_ADDR=0x80000000\n",
2589- str(metadata))
2590+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2591+ "DTB_ADDR=0x80000000\n")
2592+ self.assertEqual(expected_out, str(metadata))
2593
2594 def test_str_with_wired_interfaces(self):
2595 metadata = Metadata("ahwpack", "4", "armel",
2596 format=HardwarePackFormatV2())
2597 metadata.add_v2_config(wired_interfaces=['eth0', 'usb0'])
2598- self.assertEqual(
2599- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2600- "WIRED_INTERFACES=eth0 usb0\n",
2601- str(metadata))
2602+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2603+ "WIRED_INTERFACES=eth0 usb0\n")
2604+ self.assertEqual(expected_out, str(metadata))
2605
2606 def test_str_with_wireless_interfaces(self):
2607 metadata = Metadata("ahwpack", "4", "armel",
2608 format=HardwarePackFormatV2())
2609 metadata.add_v2_config(wireless_interfaces=['wlan0', 'wl0'])
2610- self.assertEqual(
2611- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2612- "WIRELESS_INTERFACES=wlan0 wl0\n",
2613- str(metadata))
2614+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2615+ "WIRELESS_INTERFACES=wlan0 wl0\n")
2616+ self.assertEqual(expected_out, str(metadata))
2617
2618 def test_str_with_partition_layout(self):
2619 metadata = Metadata("ahwpack", "4", "armel",
2620 format=HardwarePackFormatV2())
2621 metadata.add_v2_config(partition_layout='bootfs_rootfs')
2622- self.assertEqual(
2623- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2624- "PARTITION_LAYOUT=bootfs_rootfs\n",
2625- str(metadata))
2626+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2627+ "PARTITION_LAYOUT=bootfs_rootfs\n")
2628+ self.assertEqual(expected_out, str(metadata))
2629
2630 def test_str_with_mmc_id(self):
2631 metadata = Metadata("ahwpack", "4", "armel",
2632 format=HardwarePackFormatV2())
2633 metadata.add_v2_config(mmc_id='1')
2634- self.assertEqual(
2635- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2636- "MMC_ID=1\n",
2637- str(metadata))
2638+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2639+ "MMC_ID=1\n")
2640+ self.assertEqual(expected_out, str(metadata))
2641
2642 def test_str_with_boot_min_size(self):
2643 metadata = Metadata("ahwpack", "4", "armel",
2644 format=HardwarePackFormatV2())
2645 metadata.add_v2_config(boot_min_size='50')
2646- self.assertEqual(
2647- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2648- "BOOT_MIN_SIZE=50\n",
2649- str(metadata))
2650+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2651+ "BOOT_MIN_SIZE=50\n")
2652+ self.assertEqual(expected_out, str(metadata))
2653
2654 def test_str_with_root_min_size(self):
2655 metadata = Metadata("ahwpack", "4", "armel",
2656 format=HardwarePackFormatV2())
2657 metadata.add_v2_config(root_min_size='100')
2658- self.assertEqual(
2659- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2660- "ROOT_MIN_SIZE=100\n",
2661- str(metadata))
2662+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2663+ "ROOT_MIN_SIZE=100\n")
2664+ self.assertEqual(expected_out, str(metadata))
2665
2666 def test_str_with_loader_min_size(self):
2667 metadata = Metadata("ahwpack", "4", "armel",
2668 format=HardwarePackFormatV2())
2669 metadata.add_v2_config(loader_min_size='1')
2670- self.assertEqual(
2671- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2672- "LOADER_MIN_SIZE=1\n",
2673- str(metadata))
2674+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2675+ "LOADER_MIN_SIZE=1\n")
2676+ self.assertEqual(expected_out, str(metadata))
2677
2678 def test_str_with_kernel_file(self):
2679 metadata = Metadata("ahwpack", "4", "armel",
2680 format=HardwarePackFormatV2())
2681 metadata.add_v2_config(vmlinuz='boot/vmlinuz-3.0.0-1002-linaro-omap')
2682- self.assertEqual(
2683- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2684- "KERNEL_FILE=boot/vmlinuz-3.0.0-1002-linaro-omap\n",
2685- str(metadata))
2686+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2687+ "KERNEL_FILE=boot/vmlinuz-3.0.0-1002-linaro-omap\n")
2688+ self.assertEqual(expected_out, str(metadata))
2689
2690 def test_str_with_initrd_file(self):
2691 metadata = Metadata("ahwpack", "4", "armel",
2692 format=HardwarePackFormatV2())
2693 metadata.add_v2_config(initrd='boot/initrd.img-3.0.0-1002-linaro-omap')
2694- self.assertEqual(
2695- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2696- "INITRD_FILE=boot/initrd.img-3.0.0-1002-linaro-omap\n",
2697- str(metadata))
2698+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2699+ "INITRD_FILE=boot/initrd.img-3.0.0-1002-linaro-omap\n")
2700+ self.assertEqual(expected_out, str(metadata))
2701
2702 def test_str_with_dtb_file(self):
2703 metadata = Metadata("ahwpack", "4", "armel",
2704 format=HardwarePackFormatV2())
2705 metadata.add_v2_config(
2706 dtb_file='boot/dt-3.0.0-1002-linaro-omap/omap4-panda.dtb')
2707- self.assertEqual(
2708- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2709- "DTB_FILE=boot/dt-3.0.0-1002-linaro-omap/omap4-panda.dtb\n",
2710- str(metadata))
2711+ expected_out = ("NAME=ahwpack\nVERSION=4\n"
2712+ "ARCHITECTURE=armel\nDTB_FILE="
2713+ "boot/dt-3.0.0-1002-linaro-omap/omap4-panda.dtb\n")
2714+ self.assertEqual(expected_out, str(metadata))
2715
2716 def test_str_with_boot_script(self):
2717 metadata = Metadata("ahwpack", "4", "armel",
2718 format=HardwarePackFormatV2())
2719 metadata.add_v2_config(boot_script='boot.scr')
2720- self.assertEqual(
2721- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2722- "BOOT_SCRIPT=boot.scr\n",
2723- str(metadata))
2724+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2725+ "BOOT_SCRIPT=boot.scr\n")
2726+ self.assertEqual(expected_out, str(metadata))
2727
2728 def test_str_with_extra_boot_options(self):
2729 metadata = Metadata("ahwpack", "4", "armel",
2730@@ -263,21 +247,21 @@
2731 extra_boot_options=(
2732 'earlyprintk fixrtc nocompcache vram=48M omapfb.vram=0:24M '
2733 'mem=456M@0x80000000 mem=512M@0xA0000000'))
2734- self.assertEqual(
2735- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2736- "EXTRA_BOOT_OPTIONS=earlyprintk fixrtc nocompcache vram=48M "
2737- "omapfb.vram=0:24M mem=456M@0x80000000 mem=512M@0xA0000000\n",
2738- str(metadata))
2739+ expected_out = ("NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2740+ "EXTRA_BOOT_OPTIONS=earlyprintk fixrtc nocompcache "
2741+ "vram=48M omapfb.vram=0:24M "
2742+ "mem=456M@0x80000000 mem=512M@0xA0000000\n")
2743+ self.assertEqual(expected_out, str(metadata))
2744
2745 def test_str_with_extra_serial_options(self):
2746 metadata = Metadata("ahwpack", "4", "armel",
2747 format=HardwarePackFormatV2())
2748 metadata.add_v2_config(
2749 extra_serial_opts='console=tty0 console=ttyO2,115200n8')
2750- self.assertEqual(
2751- "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
2752- "EXTRA_SERIAL_OPTIONS=console=tty0 console=ttyO2,115200n8\n",
2753- str(metadata))
2754+ expected_out = ("NAME=ahwpack\nVERSION=4\n"
2755+ "ARCHITECTURE=armel\nEXTRA_SERIAL_OPTIONS="
2756+ "console=tty0 console=ttyO2,115200n8\n")
2757+ self.assertEqual(expected_out, str(metadata))
2758
2759 def test_from_config(self):
2760 class Config:
2761@@ -296,6 +280,113 @@
2762 self.assertEqual("i386", metadata.architecture)
2763
2764
2765+class NewMetadataTests(TestCase):
2766+
2767+ def setUp(self):
2768+ super(NewMetadataTests, self).setUp()
2769+
2770+ def test_format(self):
2771+ metadata = Metadata("ahwpack", "4", "armel",
2772+ format=HardwarePackFormatV3())
2773+ # Need to call also this one!
2774+ metadata.add_v2_config()
2775+ metadata.add_v3_config(bootloaders=None)
2776+ expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n"
2777+ "architecture: armel\n")
2778+ self.assertEqual(expected_out, str(metadata))
2779+
2780+ def test_section_bootloaders(self):
2781+ bootloaders = {'u_boot': {'file': 'a_file'}}
2782+ metadata = Metadata("ahwpack", "4", "armel",
2783+ format=HardwarePackFormatV3())
2784+ # Need to call also this one!
2785+ metadata.add_v2_config()
2786+ metadata.add_v3_config(bootloaders=bootloaders)
2787+ expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n"
2788+ "architecture: armel\nbootloaders:\n u_boot:\n"
2789+ " file: a_file\n")
2790+ self.assertEqual(expected_out, str(metadata))
2791+
2792+ def test_section_wireless(self):
2793+ metadata = Metadata("ahwpack", "4", "armel",
2794+ format=HardwarePackFormatV3())
2795+ wireless_list = ['wlan0', 'wl0']
2796+ # Need to call also this one!
2797+ metadata.add_v2_config(wireless_interfaces=wireless_list)
2798+ metadata.add_v3_config(bootloaders=None)
2799+ expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n"
2800+ "architecture: armel\nwireless_interfaces: wlan0 "
2801+ "wl0\n")
2802+ self.assertEqual(expected_out, str(metadata))
2803+
2804+ def test_section_wired(self):
2805+ metadata = Metadata("ahwpack", "4", "armel",
2806+ format=HardwarePackFormatV3())
2807+ wired_list = ['eth0', 'usb0']
2808+ # Need to call also this one!
2809+ metadata.add_v2_config(wired_interfaces=wired_list)
2810+ metadata.add_v3_config(bootloaders=None)
2811+ expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n"
2812+ "architecture: armel\nwired_interfaces: eth0 usb0\n")
2813+ self.assertEqual(expected_out, str(metadata))
2814+
2815+ def test_section_extra_serial_options(self):
2816+ metadata = Metadata("ahwpack", "4", "armel",
2817+ format=HardwarePackFormatV3())
2818+ options = ['option1', 'option2,option3']
2819+ # Need to call also this one!
2820+ metadata.add_v2_config(extra_serial_opts=options)
2821+ metadata.add_v3_config(bootloaders=None)
2822+ expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n"
2823+ "architecture: armel\nextra_serial_options: option1 "
2824+ "option2,option3\n")
2825+ self.assertEqual(expected_out, str(metadata))
2826+
2827+ def test_loop_through_for_spl(self):
2828+ bootloaders = {'u_boot': {'file': 'a_file', 'spl_file': 'some_value'}}
2829+ spl = 'spl-path'
2830+ metadata = Metadata("ahwpack", "4", "armel",
2831+ format=HardwarePackFormatV3())
2832+ # Need to call also this one!
2833+ metadata.add_v2_config()
2834+ metadata.add_v3_config(bootloaders=bootloaders)
2835+ metadata.spl = spl
2836+ expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n"
2837+ "architecture: armel\nbootloaders:\n u_boot:\n"
2838+ " file: a_file\n spl_file: spl-path\n")
2839+ self.assertEqual(expected_out, str(metadata))
2840+
2841+ def test_loop_through_for_uboot(self):
2842+ bootloaders = {'u_boot': {'file': 'a_file', 'spl_file': 'some_value'}}
2843+ u_boot = 'uboot-path'
2844+ metadata = Metadata("ahwpack", "4", "armel",
2845+ format=HardwarePackFormatV3())
2846+ # Need to call also this one!
2847+ metadata.add_v2_config()
2848+ metadata.add_v3_config(bootloaders=bootloaders)
2849+ metadata.u_boot = u_boot
2850+ expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n"
2851+ "architecture: armel\nbootloaders:\n u_boot:\n"
2852+ " file: uboot-path\n spl_file: some_value\n")
2853+ self.assertEqual(expected_out, str(metadata))
2854+
2855+ def test_loop_through_multiple_bootloaders(self):
2856+ bootloaders = {'u_boot': {'file': 'a_file', 'spl_file': 'some_value'},
2857+ 'uefi': {'spl_file': 'some_other_value'}}
2858+ spl = 'spl-path'
2859+ metadata = Metadata("ahwpack", "4", "armel",
2860+ format=HardwarePackFormatV3())
2861+ # Need to call also this one!
2862+ metadata.add_v2_config()
2863+ metadata.add_v3_config(bootloaders=bootloaders)
2864+ metadata.spl = spl
2865+ expected_out = ("format: '3.0'\nname: ahwpack\nversion: '4'\n"
2866+ "architecture: armel\nbootloaders:\n u_boot:\n"
2867+ " file: a_file\n spl_file: spl-path\n uefi:\n"
2868+ " spl_file: spl-path\n")
2869+ self.assertEqual(expected_out, str(metadata))
2870+
2871+
2872 class HardwarePackTests(TestCase):
2873
2874 def setUp(self):
2875
2876=== modified file 'linaro_image_tools/hwpack/tests/test_hwpack_converter.py'
2877--- linaro_image_tools/hwpack/tests/test_hwpack_converter.py 2012-07-19 15:21:06 +0000
2878+++ linaro_image_tools/hwpack/tests/test_hwpack_converter.py 2012-07-23 15:38:20 +0000
2879@@ -130,3 +130,27 @@
2880 converter = HwpackConverter(input_file, output_file)
2881 converter._parse()
2882 self.assertEqual(out_format, str(converter))
2883+
2884+ def test_assume_installed(self):
2885+ """Tests the correct creation of the extra_serial_options part."""
2886+ ini_format = ("[hwpack]\nformat=2.0\nassume-installed=install1 "
2887+ "install2")
2888+ out_format = ("format: '3.0'\nassume_installed:\n- install1\n- "
2889+ "install2\n")
2890+ input_file = self.useFixture(CreateTempFileFixture(ini_format)).\
2891+ get_file_name()
2892+ output_file = self.useFixture(CreateTempFileFixture()).get_file_name()
2893+ converter = HwpackConverter(input_file, output_file)
2894+ converter._parse()
2895+ self.assertEqual(out_format, str(converter))
2896+
2897+ def test_include_debs(self):
2898+ """Tests the correct creation of the extra_serial_options part."""
2899+ ini_format = ("[hwpack]\nformat=2.0\ninclude-debs=yes")
2900+ out_format = ("format: '3.0'\ninclude_debs: true\n")
2901+ input_file = self.useFixture(CreateTempFileFixture(ini_format)).\
2902+ get_file_name()
2903+ output_file = self.useFixture(CreateTempFileFixture()).get_file_name()
2904+ converter = HwpackConverter(input_file, output_file)
2905+ converter._parse()
2906+ self.assertEqual(out_format, str(converter))
2907
2908=== modified file 'linaro_image_tools/media_create/boards.py'
2909--- linaro_image_tools/media_create/boards.py 2012-06-13 14:41:42 +0000
2910+++ linaro_image_tools/media_create/boards.py 2012-07-23 15:38:20 +0000
2911@@ -36,6 +36,7 @@
2912 import shutil
2913 import string
2914 import logging
2915+from linaro_image_tools.hwpack.config import Config
2916
2917 from parted import Device
2918
2919@@ -43,7 +44,7 @@
2920
2921 from linaro_image_tools.media_create.partitions import (
2922 partition_mounted, SECTOR_SIZE, register_loopback)
2923-
2924+from StringIO import StringIO
2925
2926 KERNEL_GLOB = 'vmlinuz-*-%(kernel_flavor)s'
2927 INITRD_GLOB = 'initrd.img-*-%(kernel_flavor)s'
2928@@ -114,6 +115,7 @@
2929 class HardwarepackHandler(object):
2930 FORMAT_1 = '1.0'
2931 FORMAT_2 = '2.0'
2932+ FORMAT_3 = '3.0'
2933 FORMAT_MIXED = '1.0and2.0'
2934 metadata_filename = 'metadata'
2935 format_filename = 'FORMAT'
2936@@ -158,18 +160,18 @@
2937 if self.tempdir is not None and os.path.exists(self.tempdir):
2938 shutil.rmtree(self.tempdir)
2939
2940- def get_field(self, section, field):
2941+ def get_field(self, field):
2942 data = None
2943 hwpack_with_data = None
2944 for hwpack_tarfile in self.hwpack_tarfiles:
2945 metadata = hwpack_tarfile.extractfile(self.metadata_filename)
2946- # Use RawConfigParser which does not support the magical
2947- # interpolation behavior of ConfigParser so we don't mess up
2948- # metadata accidentally.
2949- parser = ConfigParser.RawConfigParser()
2950- parser.readfp(self.FakeSecHead(metadata))
2951+ lines = metadata.readlines()
2952+ if re.search("=", lines[0]) and not re.search(":", lines[0]):
2953+ # Probably V2 hardware pack without [hwpack] on the first line
2954+ lines = ["[hwpack]\n"] + lines
2955+ parser = Config(StringIO("".join(lines)))
2956 try:
2957- new_data = parser.get(section, field)
2958+ new_data = parser.get_option(field)
2959 if new_data is not None:
2960 assert data is None, "The metadata field '%s' is set to " \
2961 "'%s' and new value '%s' is found" % (field, data,
2962@@ -178,11 +180,12 @@
2963 hwpack_with_data = hwpack_tarfile
2964 except ConfigParser.NoOptionError:
2965 continue
2966+
2967 return data, hwpack_with_data
2968
2969 def get_format(self):
2970 format = None
2971- supported_formats = [self.FORMAT_1, self.FORMAT_2]
2972+ supported_formats = [self.FORMAT_1, self.FORMAT_2, self.FORMAT_3]
2973 for hwpack_tarfile in self.hwpack_tarfiles:
2974 format_file = hwpack_tarfile.extractfile(self.format_filename)
2975 format_string = format_file.read().strip()
2976@@ -196,8 +199,7 @@
2977 return format
2978
2979 def get_file(self, file_alias):
2980- file_name, hwpack_tarfile = self.get_field(self.main_section,
2981- file_alias)
2982+ file_name, hwpack_tarfile = self.get_field(file_alias)
2983 if file_name is not None:
2984 hwpack_tarfile.extract(file_name, self.tempdir)
2985 file_name = os.path.join(self.tempdir, file_name)
2986@@ -289,8 +291,7 @@
2987 def get_metadata_field(cls, field_name):
2988 """ Return the metadata value for field_name if it can be found.
2989 """
2990- data, _ = cls.hardwarepack_handler.get_field(
2991- cls.hardwarepack_handler.main_section, field_name)
2992+ data, _ = cls.hardwarepack_handler.get_field(field_name)
2993 return data
2994
2995 @classmethod
2996@@ -305,7 +306,7 @@
2997 if (cls.hwpack_format == cls.hardwarepack_handler.FORMAT_1):
2998 return
2999
3000- if (cls.hwpack_format == cls.hardwarepack_handler.FORMAT_2):
3001+ if (cls.hwpack_format != cls.hardwarepack_handler.FORMAT_1):
3002 # Clear V1 defaults.
3003 cls.kernel_addr = None
3004 cls.initrd_addr = None
3005@@ -334,19 +335,19 @@
3006 cls.serial_tty = cls.get_metadata_field('serial_tty')
3007 wired_interfaces = cls.get_metadata_field('wired_interfaces')
3008 if wired_interfaces is not None:
3009- cls.wired_interfaces = wired_interfaces.split(' ')
3010+ cls.wired_interfaces = wired_interfaces
3011 wireless_interfaces = cls.get_metadata_field(
3012 'wireless_interfaces')
3013 if wireless_interfaces is not None:
3014- cls.wireless_interfaces = wireless_interfaces.split(' ')
3015- cls.vmlinuz = cls.get_metadata_field('kernel_file')
3016- cls.initrd = cls.get_metadata_field('initrd_file')
3017+ cls.wireless_interfaces = wireless_interfaces
3018+ cls.vmlinuz = cls.get_metadata_field('vmlinuz')
3019+ cls.initrd = cls.get_metadata_field('initrd')
3020 cls.dtb_file = cls.get_metadata_field('dtb_file')
3021 cls.extra_boot_args_options = cls.get_metadata_field(
3022 'extra_boot_options')
3023 cls.boot_script = cls.get_metadata_field('boot_script')
3024 cls.extra_serial_opts = cls.get_metadata_field(
3025- 'extra_serial_options')
3026+ 'extra_serial_opts')
3027 cls.snowball_startup_files_config = cls.get_metadata_field(
3028 'snowball_startup_files_config')
3029
3030@@ -379,7 +380,7 @@
3031 align_up(int(loader_min_size) * 1024 ** 2,
3032 SECTOR_SIZE) / SECTOR_SIZE)
3033
3034- uboot_in_boot_part = cls.get_metadata_field('u_boot_in_boot_part')
3035+ uboot_in_boot_part = cls.get_metadata_field('uboot_in_boot_part')
3036 if uboot_in_boot_part is None:
3037 cls.uboot_in_boot_part = False
3038 elif string.lower(uboot_in_boot_part) == 'yes':
3039@@ -401,7 +402,7 @@
3040 elif string.lower(env_dd) == 'no':
3041 cls.env_dd = False
3042
3043- uboot_dd = cls.get_metadata_field('u_boot_dd')
3044+ uboot_dd = cls.get_metadata_field('uboot_dd')
3045 # Either uboot_dd is not specified, or it contains the dd offset.
3046 if uboot_dd is None:
3047 cls.uboot_dd = False
3048@@ -700,7 +701,7 @@
3049 boot_device_or_file, k_img_data, i_img_data,
3050 d_img_data):
3051 with cls.hardwarepack_handler:
3052- spl_file = cls.get_file('spl')
3053+ spl_file = cls.get_file('spl_file')
3054 if cls.spl_in_boot_part:
3055 assert spl_file is not None, (
3056 "SPL binary could not be found")
3057@@ -715,7 +716,7 @@
3058 if cls.spl_dd:
3059 cls._dd_file(spl_file, boot_device_or_file, cls.spl_dd)
3060
3061- uboot_file = cls.get_file('u_boot')
3062+ uboot_file = cls.get_file('u_boot_file')
3063 if cls.uboot_dd:
3064 cls._dd_file(uboot_file, boot_device_or_file, cls.uboot_dd)
3065
3066@@ -764,7 +765,6 @@
3067 if is_live:
3068 parts_dir = 'casper'
3069 uboot_parts_dir = os.path.join(chroot_dir, parts_dir)
3070-
3071 cmd_runner.run(['mkdir', '-p', boot_disk]).wait()
3072 with partition_mounted(boot_partition, boot_disk):
3073 if cls.uboot_in_boot_part:
3074@@ -781,7 +781,7 @@
3075 else:
3076 default = None
3077 # </legacy v1 support>
3078- uboot_bin = cls.get_file('u_boot', default=default)
3079+ uboot_bin = cls.get_file('u_boot_file', default=default)
3080 assert uboot_bin is not None, (
3081 "uboot binary could not be found")
3082
3083@@ -1277,7 +1277,7 @@
3084 # XXX: delete this method when hwpacks V1 can die
3085 assert cls.hwpack_format == HardwarepackHandler.FORMAT_1
3086 with cls.hardwarepack_handler:
3087- uboot_file = cls.get_file('u_boot', default=os.path.join(
3088+ uboot_file = cls.get_file('u_boot_file', default=os.path.join(
3089 chroot_dir, 'usr', 'lib', 'u-boot', cls.uboot_flavor,
3090 'u-boot.imx'))
3091 install_mx5_boot_loader(uboot_file, boot_device_or_file,
3092@@ -1778,7 +1778,7 @@
3093 default = _get_mlo_file(chroot_dir)
3094 except AssertionError:
3095 default = None
3096- mlo_file = cls.get_file('spl', default=default)
3097+ mlo_file = cls.get_file('spl_file', default=default)
3098 cmd_runner.run(["cp", "-v", mlo_file, boot_disk], as_root=True).wait()
3099 # XXX: Is this really needed?
3100 cmd_runner.run(["sync"]).wait()
3101
3102=== modified file 'linaro_image_tools/media_create/chroot_utils.py'
3103--- linaro_image_tools/media_create/chroot_utils.py 2012-06-13 14:11:28 +0000
3104+++ linaro_image_tools/media_create/chroot_utils.py 2012-07-23 15:38:20 +0000
3105@@ -25,7 +25,7 @@
3106 is_arm_host,
3107 find_command,
3108 )
3109-
3110+from linaro_image_tools.media_create.boards import HardwarepackHandler
3111
3112 # It'd be nice if we could use atexit here, but all the things we need to undo
3113 # have to happen right after install_hwpacks completes and the atexit
3114@@ -97,7 +97,17 @@
3115 print "-" * 60
3116 print "Installing (linaro-hwpack-install) %s in target rootfs." % (
3117 hwpack_basename)
3118- args = ['linaro-hwpack-install']
3119+
3120+ # Get infromation required by linaro-hwpack-install
3121+ with HardwarepackHandler([hwpack_file]) as hwpack:
3122+ version, _ = hwpack.get_field("version")
3123+ architecture, _ = hwpack.get_field("architecture")
3124+ name, _ = hwpack.get_field("name")
3125+
3126+ args = ['linaro-hwpack-install',
3127+ '--hwpack-version', version,
3128+ '--hwpack-arch', architecture,
3129+ '--hwpack-name', name]
3130 if hwpack_force_yes:
3131 args.append('--force-yes')
3132 args.append('/%s' % hwpack_basename)
3133
3134=== modified file 'linaro_image_tools/media_create/tests/test_media_create.py'
3135--- linaro_image_tools/media_create/tests/test_media_create.py 2012-07-17 15:33:19 +0000
3136+++ linaro_image_tools/media_create/tests/test_media_create.py 2012-07-23 15:38:20 +0000
3137@@ -216,22 +216,22 @@
3138
3139 def test_get_metadata(self):
3140 data = 'data to test'
3141- metadata = self.metadata + "TEST=%s\n" % data
3142+ metadata = self.metadata + "U_BOOT=%s\n" % data
3143 tarball = self.add_to_tarball(
3144 [('metadata', metadata)])
3145 hp = HardwarepackHandler([tarball])
3146 with hp:
3147- test_data, _ = hp.get_field(hp.main_section, 'test')
3148+ test_data, _ = hp.get_field('u_boot_file')
3149 self.assertEqual(test_data, data)
3150
3151 def test_preserves_formatters(self):
3152 data = '%s%d'
3153- metadata = self.metadata + "TEST=%s\n" % data
3154+ metadata = self.metadata + "U_BOOT=%s\n" % data
3155 tarball = self.add_to_tarball(
3156 [('metadata', metadata)])
3157 hp = HardwarepackHandler([tarball])
3158 with hp:
3159- test_data, _ = hp.get_field(hp.main_section, 'test')
3160+ test_data, _ = hp.get_field('u_boot_file')
3161 self.assertEqual(test_data, data)
3162
3163 def test_creates_tempdir(self):
3164@@ -252,15 +252,14 @@
3165
3166 def test_get_file(self):
3167 data = 'test file contents\n'
3168- metadata_file = 'TESTFILE'
3169 file_in_archive = 'testfile'
3170- metadata = self.metadata + "%s=%s\n" % (metadata_file, file_in_archive)
3171+ metadata = self.metadata + "%s=%s\n" % ('U_BOOT', file_in_archive)
3172 tarball = self.add_to_tarball(
3173 [('metadata', metadata),
3174 (file_in_archive, data)])
3175 hp = HardwarepackHandler([tarball])
3176 with hp:
3177- test_file = hp.get_file(metadata_file)
3178+ test_file = hp.get_file('u_boot_file')
3179 self.assertEquals(data, open(test_file, 'r').read())
3180
3181
3182@@ -272,7 +271,7 @@
3183 def __enter__(self):
3184 return self
3185
3186- def get_field(self, section, field):
3187+ def get_field(self, field):
3188 try:
3189 return self.metadata_dict[field], None
3190 except:
3191@@ -367,7 +366,7 @@
3192 class config(BoardConfig):
3193 pass
3194 config.set_metadata('ahwpack.tar.gz')
3195- self.assertEquals(data_to_set.split(' '), config.wired_interfaces)
3196+ self.assertEquals(data_to_set, config.wired_interfaces)
3197
3198 def test_sets_wireless_interfaces(self):
3199 self.useFixture(MockSomethingFixture(
3200@@ -382,7 +381,7 @@
3201 class config(BoardConfig):
3202 pass
3203 config.set_metadata('ahwpack.tar.gz')
3204- self.assertEquals(data_to_set.split(' '), config.wireless_interfaces)
3205+ self.assertEquals(data_to_set, config.wireless_interfaces)
3206
3207 def test_sets_mmc_id(self):
3208 self.useFixture(MockSomethingFixture(
3209@@ -3225,6 +3224,20 @@
3210
3211
3212 class TestInstallHWPack(TestCaseWithFixtures):
3213+ def create_minimal_v3_hwpack(self, location, name, version, architecture):
3214+ metadata = "\n".join([
3215+ "name: " + name,
3216+ "version: " + version,
3217+ "architecture: " + architecture,
3218+ "format: 3.0"
3219+ ])
3220+ print metadata
3221+ tar_file = tarfile.open(location, mode='w:gz')
3222+ tarinfo = tarfile.TarInfo("metadata")
3223+ tarinfo.size = len(metadata)
3224+ tar_file.addfile(tarinfo, StringIO(metadata))
3225+ tar_file.close()
3226+
3227 def mock_prepare_chroot(self, chroot_dir, tmp_dir):
3228 def fake_prepare_chroot(chroot_dir, tmp_dir):
3229 cmd_runner.run(['prepare_chroot %s %s' % (chroot_dir, tmp_dir)],
3230@@ -3278,12 +3291,23 @@
3231 sys, 'stdout', open('/dev/null', 'w')))
3232 fixture = self.useFixture(MockCmdRunnerPopenFixture())
3233 chroot_dir = 'chroot_dir'
3234+ hwpack_dir = tempfile.mkdtemp()
3235+ hwpack_file_name = 'hwpack.tgz'
3236+ hwpack_tgz_location = os.path.join(hwpack_dir, hwpack_file_name)
3237+ hwpack_name = "foo"
3238+ hwpack_version = "4"
3239+ hwpack_architecture = "armel"
3240+ self.create_minimal_v3_hwpack(hwpack_tgz_location, hwpack_name,
3241+ hwpack_version, hwpack_architecture)
3242 force_yes = False
3243- install_hwpack(chroot_dir, 'hwpack.tgz', force_yes)
3244+ install_hwpack(chroot_dir, hwpack_tgz_location, force_yes)
3245 self.assertEquals(
3246- ['%s cp hwpack.tgz %s' % (sudo_args, chroot_dir),
3247- '%s %s %s linaro-hwpack-install /hwpack.tgz'
3248- % (sudo_args, chroot_args, chroot_dir)],
3249+ ['%s cp %s %s' % (sudo_args, hwpack_tgz_location, chroot_dir),
3250+ '%s %s %s linaro-hwpack-install --hwpack-version %s '
3251+ '--hwpack-arch %s --hwpack-name %s /%s'
3252+ % (sudo_args, chroot_args, chroot_dir,
3253+ hwpack_version, hwpack_architecture, hwpack_name,
3254+ hwpack_file_name)],
3255 fixture.mock.commands_executed)
3256
3257 fixture.mock.calls = []
3258@@ -3303,9 +3327,23 @@
3259
3260 prefer_dir = preferred_tools_dir()
3261
3262+ hwpack_dir = tempfile.mkdtemp()
3263+ hwpack_file_names = ['hwpack1.tgz', 'hwpack2.tgz']
3264+ hwpack_tgz_locations = []
3265+ hwpack_names = []
3266+ for hwpack_file_name in hwpack_file_names:
3267+ hwpack_tgz_location = os.path.join(hwpack_dir, hwpack_file_name)
3268+ hwpack_tgz_locations.append(hwpack_tgz_location)
3269+ hwpack_names.append(hwpack_file_name)
3270+ hwpack_version = "4"
3271+ hwpack_architecture = "armel"
3272+ self.create_minimal_v3_hwpack(
3273+ hwpack_tgz_location, hwpack_file_name, hwpack_version,
3274+ hwpack_architecture)
3275+
3276 install_hwpacks(
3277- chroot_dir, tmp_dir, prefer_dir, force_yes, [], 'hwpack1.tgz',
3278- 'hwpack2.tgz')
3279+ chroot_dir, tmp_dir, prefer_dir, force_yes, [],
3280+ hwpack_tgz_locations[0], hwpack_tgz_locations[1])
3281 linaro_hwpack_install = find_command(
3282 'linaro-hwpack-install', prefer_dir=prefer_dir)
3283 expected = [
3284@@ -3313,19 +3351,27 @@
3285 'cp %(linaro_hwpack_install)s %(chroot_dir)s/usr/bin',
3286 'mount proc %(chroot_dir)s/proc -t proc',
3287 'chroot %(chroot_dir)s true',
3288- 'cp hwpack1.tgz %(chroot_dir)s',
3289- ('%(chroot_args)s %(chroot_dir)s linaro-hwpack-install '
3290- '--force-yes /hwpack1.tgz'),
3291- 'cp hwpack2.tgz %(chroot_dir)s',
3292- ('%(chroot_args)s %(chroot_dir)s linaro-hwpack-install '
3293- '--force-yes /hwpack2.tgz'),
3294+ 'cp %(hwpack1)s %(chroot_dir)s',
3295+ ('%(chroot_args)s %(chroot_dir)s linaro-hwpack-install '
3296+ '--hwpack-version %(hp_version)s '
3297+ '--hwpack-arch %(hp_arch)s --hwpack-name %(hp_name1)s'
3298+ ' --force-yes /hwpack1.tgz'),
3299+ 'cp %(hwpack2)s %(chroot_dir)s',
3300+ ('%(chroot_args)s %(chroot_dir)s linaro-hwpack-install '
3301+ '--hwpack-version %(hp_version)s '
3302+ '--hwpack-arch %(hp_arch)s --hwpack-name %(hp_name2)s'
3303+ ' --force-yes /hwpack2.tgz'),
3304 'rm -f %(chroot_dir)s/hwpack2.tgz',
3305 'rm -f %(chroot_dir)s/hwpack1.tgz',
3306 'umount -v %(chroot_dir)s/proc',
3307 'rm -f %(chroot_dir)s/usr/bin/linaro-hwpack-install']
3308 keywords = dict(
3309 chroot_dir=chroot_dir, tmp_dir=tmp_dir, chroot_args=chroot_args,
3310- linaro_hwpack_install=linaro_hwpack_install)
3311+ linaro_hwpack_install=linaro_hwpack_install,
3312+ hwpack1=hwpack_tgz_locations[0],
3313+ hwpack2=hwpack_tgz_locations[1],
3314+ hp_version=hwpack_version, hp_name1=hwpack_names[0],
3315+ hp_name2=hwpack_names[1], hp_arch=hwpack_architecture)
3316 expected = [
3317 "%s %s" % (sudo_args, line % keywords) for line in expected]
3318 self.assertEquals(expected, fixture.mock.commands_executed)

Subscribers

People subscribed via source and target branches