Merge lp:~milo/linaro-image-tools/multiple-boards-support into lp:linaro-image-tools/11.11
- multiple-boards-support
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Данило Шеган (community) | Needs Fixing | ||
Stevan Radaković | Pending | ||
Linaro Infrastructure | Pending | ||
Review via email: mp+115991@code.launchpad.net |
Commit message
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-
- 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.
- 543. By Milo Casagrande
-
Removed unnecessary import.
- 544. By Milo Casagrande
-
Renamed method and args.
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-
2. hwpack/config.py: I'd add comments for the purpose of translate_
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/
James Tunnicliffe (dooferlad) wrote : | # |
On 21 July 2012 07:55, Данило Шеган <email address hidden> wrote:
Thanks for the review. Enjoy your break :-)
>> === modified file 'linaro-
> ...
>> @@ -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-
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_
>> +HWPACK_
>> +if [ "$HWPACK_VERSION" = "" ]; then
>> + HWPACK_
>> +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
Milo Casagrande (milo) wrote : | # |
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-
>> --- linaro-
>> +++ linaro-
>> @@ -31,6 +31,7 @@
>> HwpackConverter
>> check_and_
>> )
>> +from linaro_
>> from linaro_
>
> 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.
>>
>> @@ -110,6 +117,22 @@
>> package.filepath, wanted_file)
>> return hwpack.
>>
>> + def loop_bootloader
>> + """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_
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.
>> + if isinstance(value, dict):
>> + boot_packages.
>
> 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_bootloade
Done, and pushed.
>> === modified file 'linaro_
>> @@ -127,6 +166,10 @@
>> self.samsung_
>>
>> @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...
- 545. By Milo Casagrande
-
Fixed method name, typos, removed unnecessary comments.
Milo Casagrande (milo) wrote : | # |
> > +class HardwarePackFor
> > + def __init__(self):
> > + super(HardwareP
> > + self.format_
> > + 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.
Milo Casagrande (milo) wrote : | # |
> > === modified file 'linaro_
>
> > + 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_
> > + """Find value in config dictionary based on supplied list
> (keys)."""
> > + result = self.parser
> > + for key in keys:
> > + key = self._v2_
> > + 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.
> > + 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.
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
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) |
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' hwpack- convert 2012-07-19 15:21:06 +0000 hwpack- convert 2012-07-20 14:12:31 +0000 Exception, validate_ args, image_tools. hwpack. builder import ConfigFileMissing image_tools. __version_ _ import __version__
> --- linaro-
> +++ linaro-
> @@ -31,6 +31,7 @@
> HwpackConverter
> check_and_
> )
> +from linaro_
> from linaro_
This change looks unnecessary (judging by the diff itself). If it's
not, something was badly broken before :)
> === modified file 'linaro- hwpack- install' {HWPACK_ DIR}/metadata' ) as configv3: readlines( ): '^(\s*) (\S.+): \s+(.+) \s*$', line) '^(\s*) (\S.+): \s*$', line) '^(\s*) -\s*(.+ )\s*$', line) value.group( 1)) match.group( 1)) item.group( 1)) indent[ new_indent] indent[ indent] = root point[' '].append( list_item. group(2) )
...
> @@ -111,6 +111,68 @@
> tar zxf "$HWPACK_TARBALL" -C "$HWPACK_DIR"
> echo "Done"
>
> +function query_v3_metadata {
> + python -c "import re
> +with open('$
> + config = {} # Will store decoded YAML in here
> + root = config # Current insert point for adding data
> + root_at_indent = {}
> + indent = 0
> + for line in configv3.
> + key_value = re.search(
> + key_match = re.search(
> + list_item = re.search(
> +
> + if key_value:
> + new_indent = len(key_
> + elif key_match:
> + new_indent = len(key_
> + elif list_item:
> + new_indent = len(list_
> +
> + if new_indent < indent: #Indent decreases: go back up config structure
> + root = root_at_
> + elif new_indent > indent: # Indent increases: reset root (insert point)
> + root_at_
> + 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_
> +
> + keys = '$1'.split(' ')
> + for key in keys:
> + if isinstance(config, list):
> + key = int(key)
> + config = config[key]
> + ...