Merge lp:~salgado/linaro-image-tools/bug-789093 into lp:~salgado/linaro-image-tools/trunk
- bug-789093
- Merge into trunk
Proposed by
Guilherme Salgado
Status: | Superseded |
---|---|
Proposed branch: | lp:~salgado/linaro-image-tools/bug-789093 |
Merge into: | lp:~salgado/linaro-image-tools/trunk |
Diff against target: |
4734 lines (+3510/-287) 18 files modified
fetch_image.py (+79/-0) fetch_image_ui.py (+1714/-0) linaro-android-media-create (+2/-1) linaro-hwpack-install (+1/-1) linaro-image-indexer (+2/-4) linaro-media-create (+1/-0) linaro_image_tools/FetchImage.py (+174/-152) linaro_image_tools/fetch_image_settings.yaml (+4/-0) linaro_image_tools/hwpack/config.py (+71/-9) linaro_image_tools/hwpack/hardwarepack.py (+16/-2) linaro_image_tools/hwpack/tests/test_config.py (+45/-6) linaro_image_tools/hwpack/tests/test_hardwarepack.py (+27/-0) linaro_image_tools/media_create/android_boards.py (+64/-4) linaro_image_tools/media_create/boards.py (+359/-88) linaro_image_tools/media_create/partitions.py (+21/-9) linaro_image_tools/media_create/rootfs.py (+15/-1) linaro_image_tools/media_create/tests/test_media_create.py (+914/-9) setup.py (+1/-1) |
To merge this branch: | bzr merge lp:~salgado/linaro-image-tools/bug-789093 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Linaro Maintainers | Pending | ||
Review via email: mp+68248@code.launchpad.net |
Commit message
Description of the change
Make sure rootfs.
world-readable
To post a comment you must log in.
- 377. By Guilherme Salgado
-
Make sure rootfs.
move_contents( ) doesn't skip files that are not world-readable
Unmerged revisions
- 377. By Guilherme Salgado
-
Make sure rootfs.
move_contents( ) doesn't skip files that are not world-readable
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'fetch_image.py' | |||
2 | --- fetch_image.py 1970-01-01 00:00:00 +0000 | |||
3 | +++ fetch_image.py 2011-07-18 14:39:34 +0000 | |||
4 | @@ -0,0 +1,79 @@ | |||
5 | 1 | #!/usr/bin/env python | ||
6 | 2 | # Copyright (C) 2010, 2011 Linaro | ||
7 | 3 | # | ||
8 | 4 | # Author: James Tunnicliffe <james.tunnicliffe@linaro.org> | ||
9 | 5 | # | ||
10 | 6 | # This file is part of Linaro Image Tools. | ||
11 | 7 | # | ||
12 | 8 | # Linaro Image Tools is free software; you can redistribute it and/or | ||
13 | 9 | # modify it under the terms of the GNU General Public License | ||
14 | 10 | # as published by the Free Software Foundation; either version 2 | ||
15 | 11 | # of the License, or (at your option) any later version. | ||
16 | 12 | # | ||
17 | 13 | # Linaro Image Tools is distributed in the hope that it will be useful, | ||
18 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | 16 | # GNU General Public License for more details. | ||
21 | 17 | # | ||
22 | 18 | # You should have received a copy of the GNU General Public License | ||
23 | 19 | # along with Linaro Image Tools; if not, write to the Free Software | ||
24 | 20 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, | ||
25 | 21 | # USA. | ||
26 | 22 | |||
27 | 23 | import sys | ||
28 | 24 | import os | ||
29 | 25 | import linaro_image_tools.FetchImage as FetchImage | ||
30 | 26 | import logging | ||
31 | 27 | |||
32 | 28 | |||
33 | 29 | def main(): | ||
34 | 30 | file_handler = FetchImage.FileHandler() | ||
35 | 31 | config = FetchImage.FetchImageConfig() | ||
36 | 32 | |||
37 | 33 | # Unfortunately we need to do a bit of a hack here and look for some | ||
38 | 34 | # options before performing a full options parse. | ||
39 | 35 | clean_cache = ("--clean-cache" in sys.argv[1:] | ||
40 | 36 | or "-x" in sys.argv[1:]) | ||
41 | 37 | |||
42 | 38 | force_download = ("--force-download" in sys.argv[1:] | ||
43 | 39 | or "-d" in sys.argv[1:]) | ||
44 | 40 | |||
45 | 41 | if clean_cache: | ||
46 | 42 | file_handler.clean_cache() | ||
47 | 43 | |||
48 | 44 | # If the settings file and server index need updating, grab them | ||
49 | 45 | file_handler.update_files_from_server(force_download) | ||
50 | 46 | |||
51 | 47 | # Load settings YAML, which defines the parameters we ask for and | ||
52 | 48 | # acceptable responses from the user | ||
53 | 49 | config.read_config(file_handler.settings_file) | ||
54 | 50 | |||
55 | 51 | # Using the settings that the YAML defines as what we need for a build, | ||
56 | 52 | # generate a command line parser and parse the command line | ||
57 | 53 | config.parse_args(sys.argv[1:]) | ||
58 | 54 | |||
59 | 55 | if config.args['platform'] == "snapshot": | ||
60 | 56 | config.args['release_or_snapshot'] = "snapshot" | ||
61 | 57 | else: | ||
62 | 58 | config.args['release_or_snapshot'] = "release" | ||
63 | 59 | |||
64 | 60 | # Using the config we have, look up URLs to download data from in the | ||
65 | 61 | # server index | ||
66 | 62 | db = FetchImage.DB(file_handler.index_file) | ||
67 | 63 | |||
68 | 64 | image_url, hwpack_url = db.get_image_and_hwpack_urls(config.args) | ||
69 | 65 | |||
70 | 66 | if(image_url and hwpack_url): | ||
71 | 67 | |||
72 | 68 | tools_dir = os.path.dirname(__file__) | ||
73 | 69 | if tools_dir == '': | ||
74 | 70 | tools_dir = None | ||
75 | 71 | |||
76 | 72 | file_handler.create_media(image_url, hwpack_url, | ||
77 | 73 | config.args, tools_dir) | ||
78 | 74 | else: | ||
79 | 75 | logging.error( | ||
80 | 76 | "Unable to find files that match the parameters specified") | ||
81 | 77 | |||
82 | 78 | if __name__ == '__main__': | ||
83 | 79 | main() | ||
84 | 0 | 80 | ||
85 | === added file 'fetch_image_ui.py' | |||
86 | --- fetch_image_ui.py 1970-01-01 00:00:00 +0000 | |||
87 | +++ fetch_image_ui.py 2011-07-18 14:39:34 +0000 | |||
88 | @@ -0,0 +1,1714 @@ | |||
89 | 1 | #!/usr/bin/env python | ||
90 | 2 | # Copyright (C) 2010, 2011 Linaro | ||
91 | 3 | # | ||
92 | 4 | # Author: James Tunnicliffe <james.tunnicliffe@linaro.org> | ||
93 | 5 | # | ||
94 | 6 | # This file is part of Linaro Image Tools. | ||
95 | 7 | # | ||
96 | 8 | # Linaro Image Tools is free software; you can redistribute it and/or | ||
97 | 9 | # modify it under the terms of the GNU General Public License | ||
98 | 10 | # as published by the Free Software Foundation; either version 2 | ||
99 | 11 | # of the License, or (at your option) any later version. | ||
100 | 12 | # | ||
101 | 13 | # Linaro Image Tools is distributed in the hope that it will be useful, | ||
102 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
103 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
104 | 16 | # GNU General Public License for more details. | ||
105 | 17 | # | ||
106 | 18 | # You should have received a copy of the GNU General Public License | ||
107 | 19 | # along with Linaro Image Tools; if not, write to the Free Software | ||
108 | 20 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, | ||
109 | 21 | # USA. | ||
110 | 22 | |||
111 | 23 | import wx | ||
112 | 24 | import wx.wizard | ||
113 | 25 | import wx.wizard as wiz | ||
114 | 26 | import sys | ||
115 | 27 | import re | ||
116 | 28 | import os | ||
117 | 29 | import linaro_image_tools.FetchImage as FetchImage | ||
118 | 30 | import string | ||
119 | 31 | import unittest | ||
120 | 32 | import operator | ||
121 | 33 | import Queue | ||
122 | 34 | import time | ||
123 | 35 | import datetime | ||
124 | 36 | |||
125 | 37 | |||
126 | 38 | def add_button(bind_to, | ||
127 | 39 | sizer, | ||
128 | 40 | label, | ||
129 | 41 | style, | ||
130 | 42 | select_event, | ||
131 | 43 | hover_event, | ||
132 | 44 | unhover_event): | ||
133 | 45 | |||
134 | 46 | """Create a radio button with event bindings.""" | ||
135 | 47 | if(style != None): | ||
136 | 48 | radio_button = wx.RadioButton(bind_to, label=label, style=style) | ||
137 | 49 | else: | ||
138 | 50 | radio_button = wx.RadioButton(bind_to, label=label) | ||
139 | 51 | |||
140 | 52 | sizer.Add(radio_button, 0, wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, 5) | ||
141 | 53 | bind_to.Bind(wx.EVT_RADIOBUTTON, select_event, radio_button) | ||
142 | 54 | wx.EVT_ENTER_WINDOW(radio_button, hover_event) | ||
143 | 55 | wx.EVT_LEAVE_WINDOW(radio_button, unhover_event) | ||
144 | 56 | |||
145 | 57 | return radio_button | ||
146 | 58 | |||
147 | 59 | |||
148 | 60 | class ReleaseOrSnapshotPage(wiz.PyWizardPage): | ||
149 | 61 | """Ask the user if they want to use a release or a snapshot""" | ||
150 | 62 | |||
151 | 63 | def __init__(self, parent, config): | ||
152 | 64 | wiz.PyWizardPage.__init__(self, parent) | ||
153 | 65 | self.config = config | ||
154 | 66 | self.settings = self.config.settings | ||
155 | 67 | self.sizer = wx.BoxSizer(wx.VERTICAL) | ||
156 | 68 | self.next = None | ||
157 | 69 | self.prev = None | ||
158 | 70 | |||
159 | 71 | self.sizer.Add(wx.StaticText(self, -1, | ||
160 | 72 | """This Wizard will write an operating system of your choosing to | ||
161 | 73 | either a disk image or to an MMC card. First we need to know if | ||
162 | 74 | your priority is stability or the latest and greatest features.""")) | ||
163 | 75 | |||
164 | 76 | self.box1 = wx.BoxSizer(wx.VERTICAL) | ||
165 | 77 | |||
166 | 78 | self.button_text = {'release': "I would like to run stable, " | ||
167 | 79 | "tested software.", | ||
168 | 80 | 'snapshot': "I would like to run untested, but " | ||
169 | 81 | "more up-to-date software."} | ||
170 | 82 | |||
171 | 83 | add_button(self, self.box1, self.button_text['release'], | ||
172 | 84 | wx.RB_GROUP, self.event_radio_button_select, None, None) | ||
173 | 85 | |||
174 | 86 | # Save the setting for the default selected value | ||
175 | 87 | self.settings['release_or_snapshot'] = "release" | ||
176 | 88 | |||
177 | 89 | add_button(self, self.box1, self.button_text['snapshot'], None, | ||
178 | 90 | self.event_radio_button_select, None, None) | ||
179 | 91 | |||
180 | 92 | self.sizer.Add(self.box1, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
181 | 93 | |||
182 | 94 | self.SetSizerAndFit(self.sizer) | ||
183 | 95 | self.sizer.Fit(self) | ||
184 | 96 | self.Move((50, 50)) | ||
185 | 97 | |||
186 | 98 | def event_radio_button_select(self, event): | ||
187 | 99 | self.radio_selected = event.GetEventObject().GetLabel() | ||
188 | 100 | # The radio button can be release, snapshot or "latest snapshot" | ||
189 | 101 | if(self.radio_selected == self.button_text['release']): | ||
190 | 102 | self.settings['release_or_snapshot'] = "release" | ||
191 | 103 | else: | ||
192 | 104 | self.settings['release_or_snapshot'] = "snapshot" | ||
193 | 105 | |||
194 | 106 | def SetNext(self, next): | ||
195 | 107 | self.next = next | ||
196 | 108 | |||
197 | 109 | def GetNext(self): | ||
198 | 110 | return self.next | ||
199 | 111 | |||
200 | 112 | |||
201 | 113 | class AboutMyHardwarePage(wiz.WizardPageSimple): | ||
202 | 114 | """Ask the user about their hardware. This only asks about the board, not | ||
203 | 115 | any specific hardware packs because there can be multiple names for the | ||
204 | 116 | same hardware pack or sometimes a hardware pack is only available in the | ||
205 | 117 | releases or snapshots repository. We whittle down the choice as we go | ||
206 | 118 | and the user can chose a hardare pack (if they don't like the default) | ||
207 | 119 | under advanced options in the Linaro Media Create options | ||
208 | 120 | page""" | ||
209 | 121 | |||
210 | 122 | def __init__(self, parent, config, db, width): | ||
211 | 123 | wiz.WizardPageSimple.__init__(self, parent) | ||
212 | 124 | self.settings = config.settings | ||
213 | 125 | self.db = db | ||
214 | 126 | self.sizer = wx.BoxSizer(wx.VERTICAL) | ||
215 | 127 | self.box1 = wx.BoxSizer(wx.VERTICAL) | ||
216 | 128 | self.box2 = wx.BoxSizer(wx.VERTICAL) | ||
217 | 129 | |||
218 | 130 | header = wx.StaticText(self, | ||
219 | 131 | label="Please select the hardware that you " | ||
220 | 132 | "would like to build an image for from " | ||
221 | 133 | "the following list") | ||
222 | 134 | |||
223 | 135 | header.Wrap(width - 10) # -10 because boarder below is 5 pixels wide | ||
224 | 136 | |||
225 | 137 | #--- Hardware Combo Box --- | ||
226 | 138 | # Make sure that the displayed release is the one set in settings if | ||
227 | 139 | # no selection is made | ||
228 | 140 | if "panda" in self.settings['choice']['hardware'].keys(): | ||
229 | 141 | default_hardware = "panda" | ||
230 | 142 | else: | ||
231 | 143 | default_hardware = self.settings['choice']['hardware'].keys()[-1] | ||
232 | 144 | |||
233 | 145 | self.settings['hardware'] = default_hardware | ||
234 | 146 | self.settings['compatable_hwpacks'] = ( | ||
235 | 147 | self.settings['choice']['hwpack'][self.settings['hardware']]) | ||
236 | 148 | |||
237 | 149 | self.cb_hardware = wx.ComboBox(self, | ||
238 | 150 | value=self.settings['choice'] | ||
239 | 151 | ['hardware'] | ||
240 | 152 | [default_hardware], | ||
241 | 153 | style=wx.CB_DROPDOWN | wx.CB_READONLY) | ||
242 | 154 | |||
243 | 155 | self.Bind(wx.EVT_COMBOBOX, | ||
244 | 156 | self.event_combo_box_hardware, | ||
245 | 157 | self.cb_hardware) | ||
246 | 158 | self.box1.Add(self.cb_hardware, 0, | ||
247 | 159 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, 5) | ||
248 | 160 | |||
249 | 161 | self.sizer.Add(header) | ||
250 | 162 | self.sizer.Add(self.box1, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
251 | 163 | self.sizer.Add(self.box2, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
252 | 164 | self.SetSizerAndFit(self.sizer) | ||
253 | 165 | self.sizer.Fit(self) | ||
254 | 166 | self.Move((50, 50)) | ||
255 | 167 | |||
256 | 168 | def on_page_changing(self): | ||
257 | 169 | self.update_hardware_box() | ||
258 | 170 | |||
259 | 171 | def update_hardware_box(self): | ||
260 | 172 | self.cb_hardware.Clear() | ||
261 | 173 | |||
262 | 174 | sorted_hardware_names = sorted(self.settings['choice']['hardware'] | ||
263 | 175 | .iteritems(), | ||
264 | 176 | key=operator.itemgetter(1)) | ||
265 | 177 | |||
266 | 178 | table = self.settings['release_or_snapshot'] + "_hwpacks" | ||
267 | 179 | |||
268 | 180 | for device_name, human_readable_name in sorted_hardware_names: | ||
269 | 181 | for hwpack in self.settings['choice']['hwpack'][device_name]: | ||
270 | 182 | if self.db.hardware_is_available_in_table(table, hwpack): | ||
271 | 183 | self.cb_hardware.Append(human_readable_name, device_name) | ||
272 | 184 | break | ||
273 | 185 | |||
274 | 186 | #--- Event(s) --- | ||
275 | 187 | def event_combo_box_hardware(self, event): | ||
276 | 188 | self.settings['hardware'] = (event | ||
277 | 189 | .GetEventObject() | ||
278 | 190 | .GetClientData(event.GetSelection()) | ||
279 | 191 | .encode('ascii')) | ||
280 | 192 | |||
281 | 193 | self.settings['compatable_hwpacks'] = ( | ||
282 | 194 | self.settings['choice']['hwpack'][self.settings['hardware']]) | ||
283 | 195 | #--- END event(s) --- | ||
284 | 196 | |||
285 | 197 | |||
286 | 198 | class SelectStableRelease(wiz.WizardPageSimple): | ||
287 | 199 | """Ask the user which Linaro release they would like to run.""" | ||
288 | 200 | def __init__(self, parent, config, db, width): | ||
289 | 201 | wiz.WizardPageSimple.__init__(self, parent) | ||
290 | 202 | self.settings = config.settings | ||
291 | 203 | self.db = db | ||
292 | 204 | self.sizer = wx.BoxSizer(wx.VERTICAL) | ||
293 | 205 | self.wizard = parent | ||
294 | 206 | |||
295 | 207 | header = wx.StaticText(self, label="Please select the stable Linaro " | ||
296 | 208 | "release you would like to use") | ||
297 | 209 | |||
298 | 210 | header.Wrap(width - 10) # -10 because boarder below is 5 pixels wide | ||
299 | 211 | |||
300 | 212 | self.sizer.Add(header) | ||
301 | 213 | self.box1 = wx.BoxSizer(wx.VERTICAL) | ||
302 | 214 | |||
303 | 215 | platforms = [] | ||
304 | 216 | for key, value in self.settings['choice']['platform'].items(): | ||
305 | 217 | platforms.append(key) | ||
306 | 218 | |||
307 | 219 | default_release = self.settings['UI']['translate'][platforms[-1]] | ||
308 | 220 | self.cb_release = wx.ComboBox(self, | ||
309 | 221 | value=default_release, | ||
310 | 222 | style=wx.CB_DROPDOWN | wx.CB_READONLY) | ||
311 | 223 | self.Bind(wx.EVT_COMBOBOX, | ||
312 | 224 | self.event_combo_box_release, | ||
313 | 225 | self.cb_release) | ||
314 | 226 | |||
315 | 227 | if(default_release in self.settings['UI']['translate']): | ||
316 | 228 | default_release = self.settings['UI']['translate'][default_release] | ||
317 | 229 | self.settings['platform'] = ( | ||
318 | 230 | self.settings['UI']['reverse-translate'][default_release]) | ||
319 | 231 | |||
320 | 232 | for item in platforms: | ||
321 | 233 | if(item in self.settings['UI']['translate']): | ||
322 | 234 | new_item = self.settings['UI']['translate'][item] | ||
323 | 235 | item = new_item | ||
324 | 236 | |||
325 | 237 | self.cb_release.Append(item, item.upper()) | ||
326 | 238 | |||
327 | 239 | self.cb_build = wx.ComboBox(self, | ||
328 | 240 | style=wx.CB_DROPDOWN | wx.CB_READONLY) | ||
329 | 241 | self.Bind(wx.EVT_COMBOBOX, self.event_combo_box_build, self.cb_build) | ||
330 | 242 | |||
331 | 243 | self.box1.Add(self.cb_release, 0, | ||
332 | 244 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, 5) | ||
333 | 245 | self.box1.Add(self.cb_build, 0, | ||
334 | 246 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, 5) | ||
335 | 247 | self.sizer.Add(self.box1, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
336 | 248 | self.SetSizerAndFit(self.sizer) | ||
337 | 249 | self.sizer.Fit(self) | ||
338 | 250 | self.Move((50, 50)) | ||
339 | 251 | |||
340 | 252 | def update_build_box(self): | ||
341 | 253 | """Depending on what hardware has been chosen, the OS list may be | ||
342 | 254 | restricted. Filter out anything that is unavailable.""" | ||
343 | 255 | self.cb_build.Clear() | ||
344 | 256 | |||
345 | 257 | builds = self.db.get_builds(self.settings['platform']) | ||
346 | 258 | self.cb_build.SetValue("No build available") | ||
347 | 259 | |||
348 | 260 | for build in builds: | ||
349 | 261 | if(self.db.hardware_is_available_for_platform_build( | ||
350 | 262 | self.settings['compatable_hwpacks'], | ||
351 | 263 | self.settings['platform'], | ||
352 | 264 | build) | ||
353 | 265 | and self.db.build_is_available_for_platform_image( | ||
354 | 266 | "release_binaries", | ||
355 | 267 | self.settings['platform'], | ||
356 | 268 | self.settings['image'], | ||
357 | 269 | build)): | ||
358 | 270 | |||
359 | 271 | self.cb_build.Append(build) | ||
360 | 272 | self.cb_build.SetValue(build) | ||
361 | 273 | self.settings['release_build'] = build | ||
362 | 274 | |||
363 | 275 | available_hwpacks = ( | ||
364 | 276 | self.db.get_available_hwpacks_for_hardware_build_plaform( | ||
365 | 277 | self.settings['compatable_hwpacks'], | ||
366 | 278 | self.settings['platform'], | ||
367 | 279 | self.settings['release_build'])) | ||
368 | 280 | |||
369 | 281 | if len(available_hwpacks): | ||
370 | 282 | self.settings['hwpack'] = available_hwpacks[0] | ||
371 | 283 | self.wizard.FindWindowById(wx.ID_FORWARD).Enable() | ||
372 | 284 | else: | ||
373 | 285 | self.wizard.FindWindowById(wx.ID_FORWARD).Disable() | ||
374 | 286 | |||
375 | 287 | def update_release_and_build_boxes(self): | ||
376 | 288 | """Depending on what hardware has been chosen, some builds may be | ||
377 | 289 | unavailable...""" | ||
378 | 290 | self.cb_release.Clear() | ||
379 | 291 | |||
380 | 292 | default_release = None | ||
381 | 293 | for platform, value in self.settings['choice']['platform'].items(): | ||
382 | 294 | if(self.db.hardware_is_available_for_platform( | ||
383 | 295 | self.settings['compatable_hwpacks'], | ||
384 | 296 | platform) | ||
385 | 297 | and len(self.db.execute_return_list( | ||
386 | 298 | 'select * from release_binaries ' | ||
387 | 299 | 'where platform == ? and image == ?', | ||
388 | 300 | (platform, self.settings['image'])))): | ||
389 | 301 | |||
390 | 302 | if(platform in self.settings['UI']['translate']): | ||
391 | 303 | platform = self.settings['UI']['translate'][platform] | ||
392 | 304 | |||
393 | 305 | self.cb_release.Append(platform, platform.upper()) | ||
394 | 306 | if not default_release or default_release < platform: | ||
395 | 307 | default_release = platform | ||
396 | 308 | |||
397 | 309 | self.settings['platform'] = ( | ||
398 | 310 | self.settings['UI']['reverse-translate'][default_release]) | ||
399 | 311 | self.cb_release.SetValue(default_release) | ||
400 | 312 | self.update_build_box() | ||
401 | 313 | |||
402 | 314 | #--- Event(s) --- | ||
403 | 315 | def event_combo_box_release(self, evt): | ||
404 | 316 | str = evt.GetString().encode('ascii').lower() | ||
405 | 317 | if(str in self.settings['UI']['reverse-translate']): | ||
406 | 318 | str = self.settings['UI']['reverse-translate'][str] | ||
407 | 319 | self.settings['platform'] = str | ||
408 | 320 | |||
409 | 321 | self.update_build_box() | ||
410 | 322 | |||
411 | 323 | def event_combo_box_build(self, evt): | ||
412 | 324 | self.settings['release_build'] = evt.GetString().encode('ascii') | ||
413 | 325 | #--- END event(s) --- | ||
414 | 326 | |||
415 | 327 | |||
416 | 328 | class SelectSnapshot(wiz.WizardPageSimple): | ||
417 | 329 | """Present the user with a calendar widget and a list of builds available | ||
418 | 330 | on the selected date so they can chose a snapshot. Filter out days when | ||
419 | 331 | their chosen hardware does not have an available build.""" | ||
420 | 332 | |||
421 | 333 | def __init__(self, parent, config, db, width): | ||
422 | 334 | wiz.WizardPageSimple.__init__(self, parent) | ||
423 | 335 | self.settings = config.settings | ||
424 | 336 | self.db = db | ||
425 | 337 | self.wizard = parent | ||
426 | 338 | self.width = width | ||
427 | 339 | self.sizer = wx.BoxSizer(wx.VERTICAL) | ||
428 | 340 | |||
429 | 341 | header = wx.StaticText(self, | ||
430 | 342 | label="Builds are created most days. First " | ||
431 | 343 | "please select the day on which the " | ||
432 | 344 | "build you would like to use was built," | ||
433 | 345 | " then, if there was more than one " | ||
434 | 346 | "build that day you will be able to " | ||
435 | 347 | "select the build number.") | ||
436 | 348 | header.Wrap(width - 10) # -10 because boarder below is 5 pixels wide | ||
437 | 349 | |||
438 | 350 | box1 = wx.BoxSizer(wx.VERTICAL) | ||
439 | 351 | self.sizer.Add(header) | ||
440 | 352 | |||
441 | 353 | # Set today as the default build date in settings | ||
442 | 354 | # (matches the date picker) | ||
443 | 355 | self.today = wx.DateTime() | ||
444 | 356 | self.today.SetToCurrent() | ||
445 | 357 | self.settings['build_date'] = self.today.FormatISODate().encode('ascii') | ||
446 | 358 | |||
447 | 359 | dpc = wx.DatePickerCtrl(self, size=(120, -1), | ||
448 | 360 | style=wx.DP_DEFAULT) | ||
449 | 361 | self.Bind(wx.EVT_DATE_CHANGED, self.on_date_changed, dpc) | ||
450 | 362 | |||
451 | 363 | #--- Build number Combo Box --- | ||
452 | 364 | # Make sure that the displayed build is the one set in settings if no | ||
453 | 365 | # selection is made | ||
454 | 366 | self.settings['build_number'] = 0 | ||
455 | 367 | self.update_build() | ||
456 | 368 | self.cb_build = wx.ComboBox(self, | ||
457 | 369 | style=wx.CB_DROPDOWN | wx.CB_READONLY) | ||
458 | 370 | self.Bind(wx.EVT_COMBOBOX, self.event_combo_box_build, self.cb_build) | ||
459 | 371 | |||
460 | 372 | #--- Layout --- | ||
461 | 373 | # -- Combo boxes for hardware and image selection -- | ||
462 | 374 | |||
463 | 375 | grid2 = wx.FlexGridSizer(0, 2, 0, 0) | ||
464 | 376 | grid2.Add(dpc, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
465 | 377 | grid2.Add(self.cb_build, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
466 | 378 | |||
467 | 379 | box1.Add(grid2, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
468 | 380 | |||
469 | 381 | self.sizer.Add(box1, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
470 | 382 | |||
471 | 383 | self.help_text = wx.StaticText(self) | ||
472 | 384 | self.sizer.Add(self.help_text, 1, wx.EXPAND, 5) | ||
473 | 385 | |||
474 | 386 | self.SetSizer(self.sizer) | ||
475 | 387 | self.sizer.Fit(self) | ||
476 | 388 | self.Move((50, 50)) | ||
477 | 389 | |||
478 | 390 | def update_platform(self): | ||
479 | 391 | build_and_date = self.settings['snapshot_build'].split(":") | ||
480 | 392 | |||
481 | 393 | if len(build_and_date) == 2: | ||
482 | 394 | self.settings['platform'] = ( | ||
483 | 395 | self.db.execute_return_list( | ||
484 | 396 | "select platform from snapshot_binaries " | ||
485 | 397 | "where date == ? and build == ?", | ||
486 | 398 | (build_and_date[0], build_and_date[1]))) | ||
487 | 399 | |||
488 | 400 | if len(self.settings['platform']) > 0: | ||
489 | 401 | self.settings['platform'] = self.settings['platform'][0][0] | ||
490 | 402 | |||
491 | 403 | def update_build(self): | ||
492 | 404 | small_date = re.sub('-', '', self.settings['build_date']) | ||
493 | 405 | self.settings['snapshot_build'] = (small_date | ||
494 | 406 | + ":" | ||
495 | 407 | + str(self.settings['build_number'])) | ||
496 | 408 | |||
497 | 409 | def fill_build_combo_box_for_date(self, date): | ||
498 | 410 | """Every time a date is chosen, this function should be called. It will | ||
499 | 411 | check to see if a compatible build is available. If there isn't, it | ||
500 | 412 | will search for one and provide some help text to tell the user when | ||
501 | 413 | compatable builds were built.""" | ||
502 | 414 | # Re-populate the build combo box | ||
503 | 415 | |||
504 | 416 | self.cb_build.Clear() | ||
505 | 417 | |||
506 | 418 | builds = self.db.get_binary_builds_on_day_from_db( | ||
507 | 419 | self.settings['image'], | ||
508 | 420 | date, | ||
509 | 421 | self.settings['compatable_hwpacks']) | ||
510 | 422 | |||
511 | 423 | if len(builds): | ||
512 | 424 | max = 0 | ||
513 | 425 | for item in builds: | ||
514 | 426 | #Always get a tuple, only interested in the first entry | ||
515 | 427 | item = item[0] | ||
516 | 428 | self.cb_build.Append(item, item.upper()) | ||
517 | 429 | |||
518 | 430 | if item > max: | ||
519 | 431 | max = item | ||
520 | 432 | |||
521 | 433 | self.cb_build.SetValue(max) | ||
522 | 434 | self.wizard.FindWindowById(wx.ID_FORWARD).Enable() | ||
523 | 435 | self.help_text.SetLabel("") | ||
524 | 436 | |||
525 | 437 | else: | ||
526 | 438 | self.cb_build.SetValue("No builds available") | ||
527 | 439 | future_date, past_date = self.db.get_next_prev_day_with_builds( | ||
528 | 440 | self.settings['image'], | ||
529 | 441 | date, | ||
530 | 442 | self.settings['compatable_hwpacks']) | ||
531 | 443 | |||
532 | 444 | help_text = None | ||
533 | 445 | |||
534 | 446 | if future_date and past_date: | ||
535 | 447 | help_text = ("There are no builds that match your " | ||
536 | 448 | "specifications available on the selected date. " | ||
537 | 449 | "The previous build was on " + past_date + | ||
538 | 450 | " and the next build was on " + future_date + ".") | ||
539 | 451 | elif future_date: | ||
540 | 452 | help_text = ("There are no builds that match your " | ||
541 | 453 | "specifications available on the selected date. " | ||
542 | 454 | "The next build was on " + future_date + | ||
543 | 455 | " and I couldn't find a past build (looked one " | ||
544 | 456 | "year back from the selected date).") | ||
545 | 457 | elif past_date: | ||
546 | 458 | help_text = ("There are no builds that match your " | ||
547 | 459 | "specifications available on the selected date. " | ||
548 | 460 | "The previous build was on " + past_date) | ||
549 | 461 | if date != self.today.FormatISODate().encode('ascii'): | ||
550 | 462 | help_text += (" and I couldn't find a future build (I " | ||
551 | 463 | "looked up to one year forward from the " | ||
552 | 464 | "selected date).") | ||
553 | 465 | else: | ||
554 | 466 | help_text = ("I could not find any builds that match your " | ||
555 | 467 | "specifications close to the selected date (I " | ||
556 | 468 | "looked forward and back one year from the " | ||
557 | 469 | "selected date).") | ||
558 | 470 | |||
559 | 471 | self.help_text.SetLabel(help_text) | ||
560 | 472 | self.help_text.Wrap(self.width - 10) | ||
561 | 473 | self.wizard.FindWindowById(wx.ID_FORWARD).Disable() | ||
562 | 474 | |||
563 | 475 | #--- Event(s) --- | ||
564 | 476 | def on_date_changed(self, evt): | ||
565 | 477 | self.settings['build_date'] = evt.GetDate().FormatISODate().encode('ascii') | ||
566 | 478 | self.fill_build_combo_box_for_date(self.settings['build_date']) | ||
567 | 479 | self.update_build() | ||
568 | 480 | |||
569 | 481 | def event_combo_box_build(self, evt): | ||
570 | 482 | self.settings['build_number'] = evt.GetString().encode('ascii').lower() | ||
571 | 483 | self.update_build() | ||
572 | 484 | #--- END event(s) --- | ||
573 | 485 | |||
574 | 486 | |||
575 | 487 | class SelectOS(wiz.WizardPageSimple): | ||
576 | 488 | """Ask the user which OS they would like to run. Filter out any choices | ||
577 | 489 | that are unavailable due to previous choices.""" | ||
578 | 490 | def __init__(self, parent, config, db, width): | ||
579 | 491 | wiz.WizardPageSimple.__init__(self, parent) | ||
580 | 492 | self.settings = config.settings | ||
581 | 493 | self.wizard = parent | ||
582 | 494 | self.db = db | ||
583 | 495 | self.width = width | ||
584 | 496 | self.sizer = wx.BoxSizer(wx.VERTICAL) | ||
585 | 497 | self.settings['image'] = None | ||
586 | 498 | |||
587 | 499 | header = wx.StaticText(self, label="Please select the operating " | ||
588 | 500 | "system you would like to run on " | ||
589 | 501 | "your hardware.") | ||
590 | 502 | header.Wrap(width - 10) # -10 because boarder below is 5 pixels wide | ||
591 | 503 | |||
592 | 504 | self.box1 = wx.BoxSizer(wx.VERTICAL) | ||
593 | 505 | self.sizer.Add(header) | ||
594 | 506 | |||
595 | 507 | self.cb_image = wx.ComboBox(self, | ||
596 | 508 | style=wx.CB_DROPDOWN | wx.CB_READONLY) | ||
597 | 509 | self.Bind(wx.EVT_COMBOBOX, self.event_combo_box_os, self.cb_image) | ||
598 | 510 | |||
599 | 511 | #--- Layout --- | ||
600 | 512 | # -- Combo boxes for hardware and image selection -- | ||
601 | 513 | self.box1.Add(self.cb_image, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
602 | 514 | |||
603 | 515 | self.sizer.Add(self.box1, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
604 | 516 | |||
605 | 517 | self.help_text = wx.StaticText(self) | ||
606 | 518 | self.sizer.Add(self.help_text, 1, wx.EXPAND, 5) | ||
607 | 519 | |||
608 | 520 | self.SetSizer(self.sizer) | ||
609 | 521 | self.sizer.Fit(self) | ||
610 | 522 | self.Move((50, 50)) | ||
611 | 523 | |||
612 | 524 | def get_human_os_name(self, item): | ||
613 | 525 | """Given an OS name from the database, return a human name (either | ||
614 | 526 | translated from the YAML settings, or just prettified) and if it is a | ||
615 | 527 | LEB OS or not""" | ||
616 | 528 | |||
617 | 529 | item = re.sub("linaro-", "", item) # Remove any linaro- decoration | ||
618 | 530 | |||
619 | 531 | human_name = item | ||
620 | 532 | |||
621 | 533 | if item in self.settings['UI']['descriptions']: | ||
622 | 534 | human_name = self.settings['UI']['descriptions'][item] | ||
623 | 535 | else: | ||
624 | 536 | # Make human_name look nicer... | ||
625 | 537 | human_name = string.capwords(item) | ||
626 | 538 | |||
627 | 539 | leb_search = re.search("^LEB:\s*(.*)$", human_name) | ||
628 | 540 | |||
629 | 541 | if leb_search: | ||
630 | 542 | return leb_search.group(1), True | ||
631 | 543 | |||
632 | 544 | return human_name, False | ||
633 | 545 | |||
634 | 546 | def fill_os_list(self): | ||
635 | 547 | """Filter the list of OS's from the config file based on the users | ||
636 | 548 | preferences so all choices in the list are valid (i.e. their hardware | ||
637 | 549 | is supported for the build they have chosen).""" | ||
638 | 550 | |||
639 | 551 | # select unique image from snapshot_binaries/release_binaries to | ||
640 | 552 | # generate list | ||
641 | 553 | os_list = None | ||
642 | 554 | if self.settings['release_or_snapshot'] == "release": | ||
643 | 555 | os_list = self.db.get_os_list_from('release_binaries') | ||
644 | 556 | else: | ||
645 | 557 | os_list = self.db.get_os_list_from('snapshot_binaries') | ||
646 | 558 | |||
647 | 559 | self.cb_image.Clear() | ||
648 | 560 | |||
649 | 561 | printed_tag = None | ||
650 | 562 | last_name = None | ||
651 | 563 | current_image_setting_valid = False | ||
652 | 564 | |||
653 | 565 | for state in ["LEB", "other"]: | ||
654 | 566 | for item in os_list: | ||
655 | 567 | if item == "old": | ||
656 | 568 | # Old is a directory that sometimes hangs around, | ||
657 | 569 | # but isn't one we want to display | ||
658 | 570 | continue | ||
659 | 571 | |||
660 | 572 | # Save the original, untouched image name for use later. | ||
661 | 573 | # We give it a more human name for display | ||
662 | 574 | original = item | ||
663 | 575 | item = re.sub("linaro-", "", item) | ||
664 | 576 | |||
665 | 577 | os_hardware_combo_available = ( | ||
666 | 578 | self.db.image_hardware_combo_available( | ||
667 | 579 | self.settings['release_or_snapshot'], | ||
668 | 580 | original, | ||
669 | 581 | self.settings['compatable_hwpacks'])) | ||
670 | 582 | |||
671 | 583 | if os_hardware_combo_available: | ||
672 | 584 | human_name, is_LEB = self.get_human_os_name(item) | ||
673 | 585 | |||
674 | 586 | if item == self.settings['image']: | ||
675 | 587 | current_image_setting_valid = True | ||
676 | 588 | |||
677 | 589 | if state == "LEB" and is_LEB: | ||
678 | 590 | |||
679 | 591 | if printed_tag != state: | ||
680 | 592 | self.cb_image.Append( | ||
681 | 593 | "- Linaro Supported Releases -") | ||
682 | 594 | printed_tag = state | ||
683 | 595 | |||
684 | 596 | self.cb_image.Append(human_name, original) | ||
685 | 597 | |||
686 | 598 | if self.settings['image'] == None: | ||
687 | 599 | self.settings['image'] = original | ||
688 | 600 | |||
689 | 601 | elif state != "LEB" and not is_LEB: | ||
690 | 602 | if printed_tag != state: | ||
691 | 603 | self.cb_image.Append( | ||
692 | 604 | "- Community Supported Releases -") | ||
693 | 605 | printed_tag = state | ||
694 | 606 | |||
695 | 607 | self.cb_image.Append(human_name, original) | ||
696 | 608 | |||
697 | 609 | last_name = original | ||
698 | 610 | |||
699 | 611 | if( self.settings['image'] != None | ||
700 | 612 | and current_image_setting_valid == False): | ||
701 | 613 | # If we have an image setting, but it doesn't match the OS list, we | ||
702 | 614 | # have switched OS list. It may be that adding/removing "linaro-" | ||
703 | 615 | # from the name will get a match. | ||
704 | 616 | |||
705 | 617 | if re.search("linaro-", self.settings['image']): | ||
706 | 618 | test_name = re.sub("linaro-", "", self.settings['image']) | ||
707 | 619 | else: | ||
708 | 620 | test_name = "linaro-" + self.settings['image'] | ||
709 | 621 | |||
710 | 622 | if test_name in os_list: | ||
711 | 623 | # Success! We have translated the name and can retain the | ||
712 | 624 | # "old setting" | ||
713 | 625 | self.settings['image'] = test_name | ||
714 | 626 | current_image_setting_valid = True | ||
715 | 627 | |||
716 | 628 | if( self.settings['image'] == None | ||
717 | 629 | or current_image_setting_valid == False): | ||
718 | 630 | # This should only get hit if there are no LEBs available | ||
719 | 631 | self.settings['image'] = last_name | ||
720 | 632 | |||
721 | 633 | assert self.settings['image'] | ||
722 | 634 | |||
723 | 635 | # Make sure the visible selected value matches the saved setting | ||
724 | 636 | self.cb_image.SetValue( | ||
725 | 637 | self.get_human_os_name(self.settings['image'])[0]) | ||
726 | 638 | |||
727 | 639 | #--- Event(s) --- | ||
728 | 640 | def event_combo_box_os(self, evt): | ||
729 | 641 | self.settings['image'] = self.cb_image.GetClientData( | ||
730 | 642 | evt.GetSelection()) | ||
731 | 643 | |||
732 | 644 | if self.settings['image']: # Is None for items that aren't an OS | ||
733 | 645 | self.wizard.FindWindowById(wx.ID_FORWARD).Enable() | ||
734 | 646 | image = re.sub("linaro-", "", self.settings['image']) | ||
735 | 647 | |||
736 | 648 | if image + "::long" in self.settings['UI']['descriptions']: | ||
737 | 649 | self.help_text.SetLabel(self.settings['UI'] | ||
738 | 650 | ['descriptions'] | ||
739 | 651 | [image + "::long"]) | ||
740 | 652 | else: | ||
741 | 653 | self.help_text.SetLabel("") | ||
742 | 654 | |||
743 | 655 | else: # Have selected help text | ||
744 | 656 | self.wizard.FindWindowById(wx.ID_FORWARD).Disable() | ||
745 | 657 | self.help_text.SetLabel("Please select an operating system to run " | ||
746 | 658 | "on your chosen hardware.") | ||
747 | 659 | |||
748 | 660 | self.help_text.Wrap(self.width - 10) | ||
749 | 661 | #--- END event(s) --- | ||
750 | 662 | |||
751 | 663 | |||
752 | 664 | class LMC_settings(wiz.WizardPageSimple): | ||
753 | 665 | """Present the user with, intially, the choice of writing the file system | ||
754 | 666 | they are going to have created to a file, or directly to a device. Ask | ||
755 | 667 | which file/device to write to. | ||
756 | 668 | |||
757 | 669 | If writing to a device, the user is asked to tick a box saying that they | ||
758 | 670 | understand that the device they have chosen will be erased. | ||
759 | 671 | |||
760 | 672 | If the user ticks the advanced box, more options are shown.""" | ||
761 | 673 | |||
762 | 674 | def __init__(self, parent, config, db, width): | ||
763 | 675 | wiz.WizardPageSimple.__init__(self, parent) | ||
764 | 676 | self.settings = config.settings | ||
765 | 677 | self.wizard = parent | ||
766 | 678 | self.sizer = wx.BoxSizer(wx.VERTICAL) | ||
767 | 679 | self.yes_use_mmc = False | ||
768 | 680 | self.db = db | ||
769 | 681 | |||
770 | 682 | self.settings['path_selected'] = "" | ||
771 | 683 | |||
772 | 684 | header = wx.StaticText(self, | ||
773 | 685 | label="Media Creation Settings\n\n" | ||
774 | 686 | "Please select if you would like to write the " | ||
775 | 687 | "file system I am about to create to a memory " | ||
776 | 688 | "card, or to a file on the local file system.") | ||
777 | 689 | header.Wrap(width - 10) # -10 because boarder below is 5 pixels wide | ||
778 | 690 | |||
779 | 691 | #--- Build some widgets --- | ||
780 | 692 | #-- Target file system -- | ||
781 | 693 | file_systems = ["ext3", "ext4", "btrfs", "ext2"] | ||
782 | 694 | default_target = file_systems[0] | ||
783 | 695 | self.settings['rootfs'] = default_target | ||
784 | 696 | cb_rootfs = wx.ComboBox(self, | ||
785 | 697 | value=default_target, | ||
786 | 698 | style=wx.CB_DROPDOWN | wx.CB_READONLY) | ||
787 | 699 | |||
788 | 700 | for item in file_systems: | ||
789 | 701 | cb_rootfs.Append(item, item.upper()) | ||
790 | 702 | |||
791 | 703 | self.Bind(wx.EVT_COMBOBOX, self.event_combo_box_rootfs, cb_rootfs) | ||
792 | 704 | |||
793 | 705 | #-- Image size spinner | ||
794 | 706 | self.image_size_spinner = wx.SpinCtrl(self, -1, "") | ||
795 | 707 | self.Bind(wx.EVT_SPINCTRL, | ||
796 | 708 | self.event_image_size, | ||
797 | 709 | self.image_size_spinner) | ||
798 | 710 | |||
799 | 711 | #-- Swap size spinner | ||
800 | 712 | self.swap_size_spinner = wx.SpinCtrl(self, -1, "") | ||
801 | 713 | self.Bind(wx.EVT_SPINCTRL, | ||
802 | 714 | self.event_swap_size, | ||
803 | 715 | self.swap_size_spinner) | ||
804 | 716 | |||
805 | 717 | #--- Layout --- | ||
806 | 718 | self.sizer.Add(header, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
807 | 719 | box1 = wx.BoxSizer(wx.VERTICAL) | ||
808 | 720 | file_dev_grid = wx.FlexGridSizer(0, 2, 0, 0) | ||
809 | 721 | box1.Add(file_dev_grid, 0, wx.EXPAND) | ||
810 | 722 | grid1 = wx.FlexGridSizer(0, 2, 0, 0) | ||
811 | 723 | |||
812 | 724 | # self.settings['write_to_file_or_device'] should match the first | ||
813 | 725 | # button below... | ||
814 | 726 | self.settings['write_to_file_or_device'] = "file" | ||
815 | 727 | add_button(self, | ||
816 | 728 | file_dev_grid, | ||
817 | 729 | "Write to file", | ||
818 | 730 | wx.RB_GROUP, | ||
819 | 731 | self.event_radio_button_select, | ||
820 | 732 | None, None) | ||
821 | 733 | |||
822 | 734 | add_button(self, | ||
823 | 735 | file_dev_grid, | ||
824 | 736 | "Write to device", | ||
825 | 737 | None, | ||
826 | 738 | self.event_radio_button_select, | ||
827 | 739 | None, None) | ||
828 | 740 | |||
829 | 741 | self.help_text_values = {"device": "Please select a device to write " | ||
830 | 742 | "the file system to:", | ||
831 | 743 | |||
832 | 744 | "file": "Please select a file to write the " | ||
833 | 745 | "file system to:"} | ||
834 | 746 | |||
835 | 747 | self.help_text = wx.StaticText( | ||
836 | 748 | self, | ||
837 | 749 | label=self.help_text_values[ | ||
838 | 750 | self.settings['write_to_file_or_device']]) | ||
839 | 751 | self.help_text.Wrap(width - 10) | ||
840 | 752 | |||
841 | 753 | #-- File/dev picker -- | ||
842 | 754 | file_browse_button = wx.Button(self, -1, "Browse") | ||
843 | 755 | file_browse_grid = wx.FlexGridSizer(0, 2, 0, 0) | ||
844 | 756 | self.file_path_and_name = wx.TextCtrl(self, -1, "", size=(300, -1)) | ||
845 | 757 | |||
846 | 758 | file_browse_grid.Add(self.file_path_and_name, 0, wx.EXPAND) | ||
847 | 759 | file_browse_grid.Add(file_browse_button, 0, wx.EXPAND) | ||
848 | 760 | |||
849 | 761 | self.Bind(wx.EVT_BUTTON, | ||
850 | 762 | self.event_open_file_control, | ||
851 | 763 | file_browse_button) | ||
852 | 764 | |||
853 | 765 | self.Bind(wx.EVT_TEXT, | ||
854 | 766 | self.event_file_path_and_name, | ||
855 | 767 | self.file_path_and_name) | ||
856 | 768 | |||
857 | 769 | box1.Add(self.help_text, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
858 | 770 | |||
859 | 771 | box1.Add(file_browse_grid, 0, wx.EXPAND) | ||
860 | 772 | |||
861 | 773 | cb1 = wx.CheckBox(self, -1, "Show advanced options") | ||
862 | 774 | self.Bind(wx.EVT_CHECKBOX, self.event_show_advanced_options, cb1) | ||
863 | 775 | box1.Add(cb1) | ||
864 | 776 | |||
865 | 777 | #-- Combo boxes for hardware and image selection -- | ||
866 | 778 | optional_settings_box_title = wx.StaticBox( | ||
867 | 779 | self, | ||
868 | 780 | label=" Optional Settings ") | ||
869 | 781 | |||
870 | 782 | self.optional_settings_box = wx.StaticBoxSizer( | ||
871 | 783 | optional_settings_box_title, | ||
872 | 784 | wx.VERTICAL) | ||
873 | 785 | |||
874 | 786 | self.box2 = wx.BoxSizer(wx.VERTICAL) | ||
875 | 787 | |||
876 | 788 | self.box2.AddWindow(self.optional_settings_box, | ||
877 | 789 | 0, | ||
878 | 790 | border=2, | ||
879 | 791 | flag=wx.ALL | wx.EXPAND) | ||
880 | 792 | |||
881 | 793 | grid1.Add(cb_rootfs, 0, wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, 5) | ||
882 | 794 | |||
883 | 795 | grid1.Add(wx.StaticText(self, | ||
884 | 796 | label="The root file system of the image"), | ||
885 | 797 | 0, | ||
886 | 798 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
887 | 799 | 5) | ||
888 | 800 | |||
889 | 801 | # We want to sub-devide the cell, to add another grid sizer... | ||
890 | 802 | file_size_grid = wx.FlexGridSizer(0, 2, 0, 0) | ||
891 | 803 | |||
892 | 804 | grid1.Add(file_size_grid, | ||
893 | 805 | 0, | ||
894 | 806 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP) | ||
895 | 807 | |||
896 | 808 | # Add a spinner that allows us to type/click a numerical value (defined above) | ||
897 | 809 | file_size_grid.Add(self.image_size_spinner, | ||
898 | 810 | 0, | ||
899 | 811 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
900 | 812 | 5) | ||
901 | 813 | |||
902 | 814 | # Add a choice of MB or GB for size input | ||
903 | 815 | units = ["GB", "MB"] | ||
904 | 816 | self.size_unit = units[0] # Set the default unit | ||
905 | 817 | unit_choice = wx.Choice(self, -1, (100, 50), choices=units) | ||
906 | 818 | self.Bind(wx.EVT_CHOICE, self.event_chose_unit, unit_choice) | ||
907 | 819 | file_size_grid.Add(unit_choice, 0, wx.ALIGN_RIGHT | wx.TOP, 5) | ||
908 | 820 | |||
909 | 821 | # Back out of the extra grid, add some help text | ||
910 | 822 | grid1.Add(wx.StaticText( | ||
911 | 823 | self, | ||
912 | 824 | label="Writing to file only: Image file size"), | ||
913 | 825 | 0, | ||
914 | 826 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
915 | 827 | 5) | ||
916 | 828 | |||
917 | 829 | # The swap size (MB only) | ||
918 | 830 | grid1.Add(self.swap_size_spinner, | ||
919 | 831 | 0, | ||
920 | 832 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
921 | 833 | 5) | ||
922 | 834 | |||
923 | 835 | grid1.Add(wx.StaticText(self, label="Swap file size in MB"), | ||
924 | 836 | 0, | ||
925 | 837 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
926 | 838 | 5) | ||
927 | 839 | |||
928 | 840 | self.cb_hwpacks = wx.ComboBox( | ||
929 | 841 | self, | ||
930 | 842 | value=self.settings['compatable_hwpacks'][0], | ||
931 | 843 | style=wx.CB_DROPDOWN | wx.CB_READONLY) | ||
932 | 844 | |||
933 | 845 | self.Bind(wx.EVT_COMBOBOX, | ||
934 | 846 | self.event_combo_box_hwpack, | ||
935 | 847 | self.cb_hwpacks) | ||
936 | 848 | |||
937 | 849 | grid1.Add(self.cb_hwpacks, | ||
938 | 850 | 0, | ||
939 | 851 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
940 | 852 | 5) | ||
941 | 853 | |||
942 | 854 | grid1.Add(wx.StaticText(self, label="Compatible hardware packs"), | ||
943 | 855 | 0, | ||
944 | 856 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
945 | 857 | 5) | ||
946 | 858 | |||
947 | 859 | self.optional_settings_box.Add(grid1, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
948 | 860 | |||
949 | 861 | confirm_mmc_usage_title = wx.StaticBox(self, label=" Are you sure? ") | ||
950 | 862 | |||
951 | 863 | self.confirm_mmc_usage_box = wx.StaticBoxSizer(confirm_mmc_usage_title, | ||
952 | 864 | wx.VERTICAL) | ||
953 | 865 | cb2 = wx.CheckBox( | ||
954 | 866 | self, | ||
955 | 867 | -1, | ||
956 | 868 | "Yes, erase and use the device I have selected above.") | ||
957 | 869 | |||
958 | 870 | self.Bind(wx.EVT_CHECKBOX, self.event_use_mmc_tickbox, cb2) | ||
959 | 871 | self.confirm_mmc_usage_box.Add(cb2) | ||
960 | 872 | |||
961 | 873 | self.box3 = wx.BoxSizer(wx.VERTICAL) | ||
962 | 874 | self.box3.AddWindow(self.confirm_mmc_usage_box, | ||
963 | 875 | 0, | ||
964 | 876 | border=2, | ||
965 | 877 | flag=wx.ALL | wx.EXPAND) | ||
966 | 878 | |||
967 | 879 | self.sizer.Add(box1, 0, wx.ALIGN_LEFT | wx.ALL, 0) | ||
968 | 880 | self.sizer.Add(self.box2, 0, wx.ALIGN_LEFT | wx.ALL, 0) | ||
969 | 881 | self.sizer.Add(self.box3, 0, wx.ALIGN_LEFT | wx.ALL, 0) | ||
970 | 882 | self.SetSizer(self.sizer) | ||
971 | 883 | self.sizer.Fit(self) | ||
972 | 884 | self.Move((50, 50)) | ||
973 | 885 | |||
974 | 886 | def on_activate(self): | ||
975 | 887 | self.update_forward_active_and_mmc_confirm_box_visible() | ||
976 | 888 | self.set_hwpacks_for_hardware() | ||
977 | 889 | |||
978 | 890 | def set_hwpacks_for_hardware(self): | ||
979 | 891 | self.cb_hwpacks.Clear() | ||
980 | 892 | |||
981 | 893 | if self.settings['release_or_snapshot'] == "snapshot": | ||
982 | 894 | self.settings['build'] = self.settings['snapshot_build'] | ||
983 | 895 | |||
984 | 896 | date_and_build = self.settings['build'].split(":") | ||
985 | 897 | |||
986 | 898 | compatable_hwpacks = ( | ||
987 | 899 | self.db.get_available_hwpacks_for_hardware_snapshot_build( | ||
988 | 900 | self.settings['compatable_hwpacks'], | ||
989 | 901 | self.settings['platform'], | ||
990 | 902 | date_and_build[0], | ||
991 | 903 | date_and_build[1])) | ||
992 | 904 | else: | ||
993 | 905 | self.settings['build'] = self.settings['release_build'] | ||
994 | 906 | compatable_hwpacks = ( | ||
995 | 907 | self.db.get_available_hwpacks_for_hardware_build_plaform( | ||
996 | 908 | self.settings['compatable_hwpacks'], | ||
997 | 909 | self.settings['platform'], | ||
998 | 910 | self.settings['build'])) | ||
999 | 911 | |||
1000 | 912 | for hwpack in compatable_hwpacks: | ||
1001 | 913 | self.cb_hwpacks.Append(hwpack) | ||
1002 | 914 | |||
1003 | 915 | self.cb_hwpacks.SetStringSelection(compatable_hwpacks[0]) | ||
1004 | 916 | self.settings['hwpack'] = compatable_hwpacks[0] | ||
1005 | 917 | |||
1006 | 918 | def update_forward_active_and_mmc_confirm_box_visible(self): | ||
1007 | 919 | if( self.settings['path_selected'] | ||
1008 | 920 | and self.settings['path_selected'] != ""): | ||
1009 | 921 | |||
1010 | 922 | if ( self.settings['write_to_file_or_device'] == "file" | ||
1011 | 923 | or self.settings['write_to_file_or_device'] == "device" | ||
1012 | 924 | and self.yes_use_mmc): | ||
1013 | 925 | self.wizard.FindWindowById(wx.ID_FORWARD).Enable() | ||
1014 | 926 | else: | ||
1015 | 927 | self.wizard.FindWindowById(wx.ID_FORWARD).Disable() | ||
1016 | 928 | else: | ||
1017 | 929 | self.wizard.FindWindowById(wx.ID_FORWARD).Disable() | ||
1018 | 930 | |||
1019 | 931 | if self.settings['write_to_file_or_device'] == "device": | ||
1020 | 932 | self.box3.Show(self.confirm_mmc_usage_box, True) | ||
1021 | 933 | else: | ||
1022 | 934 | self.box3.Hide(self.confirm_mmc_usage_box, True) | ||
1023 | 935 | |||
1024 | 936 | # --- Event Handlers --- | ||
1025 | 937 | def event_open_file_control(self, event): | ||
1026 | 938 | if self.settings['write_to_file_or_device'] == "file": | ||
1027 | 939 | |||
1028 | 940 | dlg = wx.FileDialog(self, | ||
1029 | 941 | message="Save file as ...", | ||
1030 | 942 | defaultDir=os.getcwd(), | ||
1031 | 943 | defaultFile="", | ||
1032 | 944 | style=wx.SAVE) | ||
1033 | 945 | |||
1034 | 946 | elif self.settings['write_to_file_or_device'] == "device": | ||
1035 | 947 | dlg = wx.FileDialog(self, | ||
1036 | 948 | message="Choose a device", | ||
1037 | 949 | defaultDir=os.getcwd(), | ||
1038 | 950 | defaultFile="", | ||
1039 | 951 | style=wx.OPEN | wx.CHANGE_DIR) | ||
1040 | 952 | |||
1041 | 953 | if dlg.ShowModal() == wx.ID_OK: | ||
1042 | 954 | self.settings['path_selected'] = dlg.GetPaths()[0] | ||
1043 | 955 | self.file_path_and_name.SetValue(self.settings['path_selected']) | ||
1044 | 956 | |||
1045 | 957 | dlg.Destroy() | ||
1046 | 958 | self.update_forward_active_and_mmc_confirm_box_visible() | ||
1047 | 959 | |||
1048 | 960 | def event_file_path_and_name(self, event): | ||
1049 | 961 | self.settings['path_selected'] = event.GetString() | ||
1050 | 962 | self.update_forward_active_and_mmc_confirm_box_visible() | ||
1051 | 963 | |||
1052 | 964 | def event_combo_box_hwpack(self, event): | ||
1053 | 965 | self.settings['hwpack'] = event.GetString().encode('ascii') | ||
1054 | 966 | |||
1055 | 967 | def event_combo_box_rootfs(self, evt): | ||
1056 | 968 | self.settings['rootfs'] = evt.GetString().encode('ascii').lower() | ||
1057 | 969 | |||
1058 | 970 | def event_radio_button_select(self, event): | ||
1059 | 971 | """Search the label of the button that has been selected to work out | ||
1060 | 972 | what we are writing to.""" | ||
1061 | 973 | setting_search = re.search( | ||
1062 | 974 | "write to (\w+)", | ||
1063 | 975 | event | ||
1064 | 976 | .GetEventObject() | ||
1065 | 977 | .GetLabel() | ||
1066 | 978 | .encode('ascii') | ||
1067 | 979 | .lower()) | ||
1068 | 980 | |||
1069 | 981 | assert setting_search | ||
1070 | 982 | |||
1071 | 983 | self.settings['write_to_file_or_device'] = setting_search.group(1) | ||
1072 | 984 | |||
1073 | 985 | self.help_text.SetLabel( | ||
1074 | 986 | self.help_text_values[self.settings['write_to_file_or_device']]) | ||
1075 | 987 | |||
1076 | 988 | self.update_forward_active_and_mmc_confirm_box_visible() | ||
1077 | 989 | |||
1078 | 990 | def event_show_advanced_options(self, event): | ||
1079 | 991 | if event.IsChecked(): | ||
1080 | 992 | self.box2.Show(self.optional_settings_box, True) | ||
1081 | 993 | else: | ||
1082 | 994 | self.box2.Hide(self.optional_settings_box, True) | ||
1083 | 995 | |||
1084 | 996 | def event_pick_file_path(self, evt): | ||
1085 | 997 | self.settings['path_selected'] = os.path.abspath(evt.GetPath()) | ||
1086 | 998 | self.update_forward_active_and_mmc_confirm_box_visible() | ||
1087 | 999 | |||
1088 | 1000 | def update_image_size_setting(self): | ||
1089 | 1001 | if(self.image_size_spinner.GetValue() > 0): | ||
1090 | 1002 | self.settings['image_size'] = (str(self.image_size_spinner | ||
1091 | 1003 | .GetValue()) | ||
1092 | 1004 | + self.size_unit[0]) | ||
1093 | 1005 | else: | ||
1094 | 1006 | self.settings['image_size'] = None | ||
1095 | 1007 | |||
1096 | 1008 | def event_image_size(self, event): | ||
1097 | 1009 | self.update_image_size_setting() | ||
1098 | 1010 | |||
1099 | 1011 | def event_chose_unit(self, event): | ||
1100 | 1012 | self.size_unit = event.GetString() | ||
1101 | 1013 | self.update_image_size_setting() | ||
1102 | 1014 | |||
1103 | 1015 | def event_swap_size(self, event): | ||
1104 | 1016 | self.settings['swap_file'] = str(self.image_size_spinner.GetValue()) | ||
1105 | 1017 | |||
1106 | 1018 | def event_use_mmc_tickbox(self, event): | ||
1107 | 1019 | self.yes_use_mmc = event.IsChecked() | ||
1108 | 1020 | self.update_forward_active_and_mmc_confirm_box_visible() | ||
1109 | 1021 | |||
1110 | 1022 | |||
1111 | 1023 | class RunLMC(wiz.WizardPageSimple): | ||
1112 | 1024 | """Present the user with some information about their choices and a button | ||
1113 | 1025 | to start linaro-media-create. The linaro-media-create process is started in | ||
1114 | 1026 | a new thread and important events are communicated back to the UI through a | ||
1115 | 1027 | queue.""" | ||
1116 | 1028 | |||
1117 | 1029 | def __init__(self, parent, config, db, width): | ||
1118 | 1030 | wiz.WizardPageSimple.__init__(self, parent) | ||
1119 | 1031 | self.settings = config.settings | ||
1120 | 1032 | self.sizer = wx.BoxSizer(wx.VERTICAL) | ||
1121 | 1033 | self.db = db | ||
1122 | 1034 | self.width = width | ||
1123 | 1035 | self.wizard = parent | ||
1124 | 1036 | |||
1125 | 1037 | header = wx.StaticText(self, label="""Installing...""") | ||
1126 | 1038 | header.Wrap(width - 10) # -10 because boarder below is 5 pixels wide | ||
1127 | 1039 | |||
1128 | 1040 | self.sizer.Add(header) | ||
1129 | 1041 | self.box1 = wx.BoxSizer(wx.VERTICAL) | ||
1130 | 1042 | |||
1131 | 1043 | # We expect to print 4 lines of information, reserve space using blank | ||
1132 | 1044 | # lines. | ||
1133 | 1045 | self.settings_summary_text = wx.StaticText(self, label="\n\n\n\n") | ||
1134 | 1046 | self.settings_summary_text.Wrap(width - 10) | ||
1135 | 1047 | |||
1136 | 1048 | self.box1.Add(self.settings_summary_text, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
1137 | 1049 | |||
1138 | 1050 | self.start_button = wx.Button(self, 10, "Start", (20, 20)) | ||
1139 | 1051 | self.Bind(wx.EVT_BUTTON, self.start_lmc, self.start_button) | ||
1140 | 1052 | |||
1141 | 1053 | self.start_button.SetToolTipString("Start creating an image, using the" | ||
1142 | 1054 | "above settings.") | ||
1143 | 1055 | |||
1144 | 1056 | self.start_button.SetSize(self.start_button.GetBestSize()) | ||
1145 | 1057 | self.box1.Add(self.start_button, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
1146 | 1058 | |||
1147 | 1059 | self.download_guage = wx.Gauge(self, | ||
1148 | 1060 | -1, | ||
1149 | 1061 | 1000, | ||
1150 | 1062 | size=(self.width * 2 / 3, 25)) | ||
1151 | 1063 | |||
1152 | 1064 | self.status_grid = wx.FlexGridSizer(0, 2) | ||
1153 | 1065 | |||
1154 | 1066 | self.status_grid.Add(wx.StaticText(self, label="Downloading files"), | ||
1155 | 1067 | 0, | ||
1156 | 1068 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
1157 | 1069 | 5) | ||
1158 | 1070 | |||
1159 | 1071 | self.downloading_files_status = wx.StaticText(self, label="") | ||
1160 | 1072 | |||
1161 | 1073 | self.status_grid.Add(self.downloading_files_status, | ||
1162 | 1074 | 0, | ||
1163 | 1075 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
1164 | 1076 | 5) | ||
1165 | 1077 | |||
1166 | 1078 | self.status_grid.Add(self.download_guage, | ||
1167 | 1079 | 0, | ||
1168 | 1080 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
1169 | 1081 | 5) | ||
1170 | 1082 | |||
1171 | 1083 | self.downloading_files_info = wx.StaticText(self, label="") | ||
1172 | 1084 | |||
1173 | 1085 | self.status_grid.Add(self.downloading_files_info, | ||
1174 | 1086 | 0, | ||
1175 | 1087 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
1176 | 1088 | 5) | ||
1177 | 1089 | |||
1178 | 1090 | self.status_grid.Add(wx.StaticText(self, label="Unpacking downloads"), | ||
1179 | 1091 | 0, | ||
1180 | 1092 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
1181 | 1093 | 5) | ||
1182 | 1094 | |||
1183 | 1095 | self.unpacking_files_status = wx.StaticText(self, label="") | ||
1184 | 1096 | |||
1185 | 1097 | self.status_grid.Add(self.unpacking_files_status, | ||
1186 | 1098 | 0, | ||
1187 | 1099 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
1188 | 1100 | 5) | ||
1189 | 1101 | |||
1190 | 1102 | self.status_grid.Add(wx.StaticText(self, label="Installing packages"), | ||
1191 | 1103 | 0, | ||
1192 | 1104 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
1193 | 1105 | 5) | ||
1194 | 1106 | |||
1195 | 1107 | self.installing_packages_status = wx.StaticText(self, label="") | ||
1196 | 1108 | |||
1197 | 1109 | self.status_grid.Add(self.installing_packages_status, | ||
1198 | 1110 | 0, | ||
1199 | 1111 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
1200 | 1112 | 5) | ||
1201 | 1113 | |||
1202 | 1114 | self.status_grid.Add(wx.StaticText(self, label="Create file system"), | ||
1203 | 1115 | 0, | ||
1204 | 1116 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
1205 | 1117 | 5) | ||
1206 | 1118 | |||
1207 | 1119 | self.create_file_system_status = wx.StaticText(self, label="") | ||
1208 | 1120 | |||
1209 | 1121 | self.status_grid.Add(self.create_file_system_status, | ||
1210 | 1122 | 0, | ||
1211 | 1123 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
1212 | 1124 | 5) | ||
1213 | 1125 | |||
1214 | 1126 | self.status_grid.Add(wx.StaticText(self, label="Populate file system"), | ||
1215 | 1127 | 0, | ||
1216 | 1128 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
1217 | 1129 | 5) | ||
1218 | 1130 | |||
1219 | 1131 | self.populate_file_system_status = wx.StaticText(self, label="") | ||
1220 | 1132 | |||
1221 | 1133 | self.status_grid.Add(self.populate_file_system_status, | ||
1222 | 1134 | 0, | ||
1223 | 1135 | wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, | ||
1224 | 1136 | 5) | ||
1225 | 1137 | |||
1226 | 1138 | self.sizer.Add(self.box1, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
1227 | 1139 | self.sizer.Add(self.status_grid, 0, wx.ALIGN_LEFT | wx.ALL, 5) | ||
1228 | 1140 | self.SetSizerAndFit(self.sizer) | ||
1229 | 1141 | self.sizer.Fit(self) | ||
1230 | 1142 | self.Move((50, 50)) | ||
1231 | 1143 | |||
1232 | 1144 | def on_activate(self): | ||
1233 | 1145 | """Called just before the page is displayed to update the text based on | ||
1234 | 1146 | the users preferences.""" | ||
1235 | 1147 | |||
1236 | 1148 | # The build is stored in different forms depending on if we are using a | ||
1237 | 1149 | # release or snapshot but from here on in it is a common value | ||
1238 | 1150 | if self.settings['release_or_snapshot'] == "snapshot": | ||
1239 | 1151 | self.settings['build'] = self.settings['snapshot_build'] | ||
1240 | 1152 | else: | ||
1241 | 1153 | self.settings['build'] = self.settings['release_build'] | ||
1242 | 1154 | |||
1243 | 1155 | settings_summary = ("Press start to create an image with the " | ||
1244 | 1156 | "following settings:\n") | ||
1245 | 1157 | settings_summary += "Operating System: " + self.settings['image'] + "\n" | ||
1246 | 1158 | settings_summary += "Hardware: " + self.settings['hardware'] + "\n" | ||
1247 | 1159 | |||
1248 | 1160 | # Assumption is that a file may be in a long path, we don't know how | ||
1249 | 1161 | # big the font is and we don't want to allow the path to run off the | ||
1250 | 1162 | # end of the line, so if a file is chosen, just show the file name. | ||
1251 | 1163 | # Devices are (probably) /dev/some_short_name and the user really needs | ||
1252 | 1164 | # to check them, so we show the whole thing. | ||
1253 | 1165 | path = self.settings['path_selected'] | ||
1254 | 1166 | if self.settings['write_to_file_or_device'] == "file": | ||
1255 | 1167 | path = self.settings['path_selected'].split(os.sep)[-1] | ||
1256 | 1168 | |||
1257 | 1169 | settings_summary += ( "Writing image to " | ||
1258 | 1170 | + self.settings['write_to_file_or_device'] | ||
1259 | 1171 | + " " | ||
1260 | 1172 | + path) | ||
1261 | 1173 | |||
1262 | 1174 | self.settings_summary_text.SetLabel(settings_summary) | ||
1263 | 1175 | self.settings_summary_text.Wrap(self.width - 10) | ||
1264 | 1176 | |||
1265 | 1177 | def start_lmc(self, event): | ||
1266 | 1178 | """Start a thread that runs linaro-media-create and a timer, which | ||
1267 | 1179 | checks for UI updates every 100ms""" | ||
1268 | 1180 | |||
1269 | 1181 | if self.settings['write_to_file_or_device'] == "file": | ||
1270 | 1182 | self.settings['image_file'] = self.settings['path_selected'] | ||
1271 | 1183 | elif self.settings['write_to_file_or_device'] == "device": | ||
1272 | 1184 | self.settings['mmc'] = self.settings['path_selected'] | ||
1273 | 1185 | else: | ||
1274 | 1186 | assert False, ("self.config.settings['write_to_file_or_device'] " | ||
1275 | 1187 | "was an unexpected value" | ||
1276 | 1188 | + self.settings['write_to_file_or_device']) | ||
1277 | 1189 | |||
1278 | 1190 | image_url, hwpack_url = self.db.get_image_and_hwpack_urls(self.settings) | ||
1279 | 1191 | |||
1280 | 1192 | # Currently the UI is blocked when LMC is running, so grey out the | ||
1281 | 1193 | # buttons to indicate to the user that they won't work! | ||
1282 | 1194 | self.wizard.FindWindowById(wx.ID_BACKWARD).Disable() | ||
1283 | 1195 | self.wizard.FindWindowById(wx.ID_CANCEL).Disable() | ||
1284 | 1196 | |||
1285 | 1197 | if(image_url and hwpack_url): | ||
1286 | 1198 | |||
1287 | 1199 | self.file_handler = FetchImage.FileHandler() | ||
1288 | 1200 | |||
1289 | 1201 | self.timer = wx.Timer(self) | ||
1290 | 1202 | self.Bind(wx.EVT_TIMER, self.timer_ping, self.timer) | ||
1291 | 1203 | self.timer.Start(milliseconds=100, oneShot=True) | ||
1292 | 1204 | |||
1293 | 1205 | tools_dir = os.path.dirname(__file__) | ||
1294 | 1206 | if tools_dir == '': | ||
1295 | 1207 | tools_dir = None | ||
1296 | 1208 | |||
1297 | 1209 | self.start_button.Disable() | ||
1298 | 1210 | self.event_queue = Queue.Queue() | ||
1299 | 1211 | self.lmc_thread = self.file_handler.LinaroMediaCreate( | ||
1300 | 1212 | image_url, | ||
1301 | 1213 | hwpack_url, | ||
1302 | 1214 | self.file_handler, | ||
1303 | 1215 | self.event_queue, | ||
1304 | 1216 | self.settings, | ||
1305 | 1217 | tools_dir) | ||
1306 | 1218 | self.lmc_thread.start() | ||
1307 | 1219 | else: | ||
1308 | 1220 | print >> sys.stderr, ("Unable to find files that match the" | ||
1309 | 1221 | "parameters specified") | ||
1310 | 1222 | |||
1311 | 1223 | def timer_ping(self, event): | ||
1312 | 1224 | """During start_lmc a timer is started to poll for events from | ||
1313 | 1225 | linaro-media-create every 100ms. This is the function which is called | ||
1314 | 1226 | to do that polling.""" | ||
1315 | 1227 | |||
1316 | 1228 | while not self.event_queue.empty(): | ||
1317 | 1229 | event = self.event_queue.get() | ||
1318 | 1230 | |||
1319 | 1231 | if event[0] == "start": | ||
1320 | 1232 | self.event_start(event[1]) | ||
1321 | 1233 | |||
1322 | 1234 | elif event[0] == "end": | ||
1323 | 1235 | self.event_end(event[1]) | ||
1324 | 1236 | |||
1325 | 1237 | elif event == "terminate": | ||
1326 | 1238 | # Process complete. Enable next button. | ||
1327 | 1239 | self.wizard.FindWindowById(wx.ID_FORWARD).Enable() | ||
1328 | 1240 | self.populate_file_system_status.SetLabel("Done") | ||
1329 | 1241 | return # Even if queue isn't empty, stop processing it | ||
1330 | 1242 | |||
1331 | 1243 | elif event[0] == "update": | ||
1332 | 1244 | self.event_update(event[1], event[2], event[3]) | ||
1333 | 1245 | |||
1334 | 1246 | else: | ||
1335 | 1247 | print >> sys.stderr, "timer_ping: Unhandled event", event | ||
1336 | 1248 | |||
1337 | 1249 | self.timer.Start(milliseconds=50, oneShot=True) | ||
1338 | 1250 | |||
1339 | 1251 | def unsigned_packages_query(self, package_list): | ||
1340 | 1252 | message = ('In order to continue, I need to install some unsigned' | ||
1341 | 1253 | 'packages into the image. Is this OK? The packages are:' | ||
1342 | 1254 | '\n\n' + package_list) | ||
1343 | 1255 | |||
1344 | 1256 | dlg = wx.MessageDialog(self, | ||
1345 | 1257 | message, | ||
1346 | 1258 | 'Install Unsigned Packages Into Image?', | ||
1347 | 1259 | wx.YES_NO | wx.NO_DEFAULT) | ||
1348 | 1260 | |||
1349 | 1261 | choice = dlg.ShowModal() | ||
1350 | 1262 | dlg.Destroy() | ||
1351 | 1263 | |||
1352 | 1264 | return choice == wx.ID_YES | ||
1353 | 1265 | |||
1354 | 1266 | #--- Event(s) --- | ||
1355 | 1267 | def event_start(self, event): | ||
1356 | 1268 | if event == "download OS": | ||
1357 | 1269 | self.downloading_files_status.SetLabel("Downloading OS") | ||
1358 | 1270 | elif event == "download hwpack": | ||
1359 | 1271 | self.downloading_files_status.SetLabel("Downloading Hardware Pack") | ||
1360 | 1272 | elif event == "unpack": | ||
1361 | 1273 | self.unpacking_files_status.SetLabel("Running") | ||
1362 | 1274 | elif event == "installing packages": | ||
1363 | 1275 | self.installing_packages_status.SetLabel("Running") | ||
1364 | 1276 | |||
1365 | 1277 | elif re.search('^unverified_packages:', event): | ||
1366 | 1278 | # Get rid of event ID and whitespace invariance | ||
1367 | 1279 | packages = " ".join(event.split()[1:]) | ||
1368 | 1280 | install_unsigned_packages = self.unsigned_packages_query(packages) | ||
1369 | 1281 | |||
1370 | 1282 | if install_unsigned_packages == False: | ||
1371 | 1283 | self.file_handler.kill_create_media() | ||
1372 | 1284 | sys.exit(1) | ||
1373 | 1285 | else: | ||
1374 | 1286 | self.lmc_thread.send_to_create_process("y") | ||
1375 | 1287 | |||
1376 | 1288 | elif event == "create file system": | ||
1377 | 1289 | self.create_file_system_status.SetLabel("Running") | ||
1378 | 1290 | elif event == "populate file system": | ||
1379 | 1291 | self.populate_file_system_status.SetLabel("Running") | ||
1380 | 1292 | else: | ||
1381 | 1293 | print "Unhandled start event:", event | ||
1382 | 1294 | |||
1383 | 1295 | def event_end(self, event): | ||
1384 | 1296 | if event == "download OS": | ||
1385 | 1297 | self.downloading_files_status.SetLabel("Done (1/2)") | ||
1386 | 1298 | elif event == "download hwpack": | ||
1387 | 1299 | self.downloading_files_status.SetLabel("Done") | ||
1388 | 1300 | elif event == "unpack": | ||
1389 | 1301 | self.unpacking_files_status.SetLabel("Done") | ||
1390 | 1302 | elif event == "installing packages": | ||
1391 | 1303 | self.installing_packages_status.SetLabel("Done") | ||
1392 | 1304 | elif event == "create file system": | ||
1393 | 1305 | self.create_file_system_status.SetLabel("Done") | ||
1394 | 1306 | elif event == "populate file system": | ||
1395 | 1307 | self.populate_file_system_status.SetLabel("Done") | ||
1396 | 1308 | else: | ||
1397 | 1309 | print "Unhhandled end event:", event | ||
1398 | 1310 | |||
1399 | 1311 | def event_update(self, task, update_type, value): | ||
1400 | 1312 | if task == "download": | ||
1401 | 1313 | if update_type == "name": | ||
1402 | 1314 | self.downloading_files_status.SetLabel("Downloading") | ||
1403 | 1315 | self.old_time = time.time() | ||
1404 | 1316 | self.old_bytes_downloaded = 0 | ||
1405 | 1317 | |||
1406 | 1318 | elif update_type == "progress": | ||
1407 | 1319 | self.total_bytes_downloaded += value | ||
1408 | 1320 | |||
1409 | 1321 | time_difference = time.time() - self.old_time | ||
1410 | 1322 | |||
1411 | 1323 | if time_difference > 1.0: | ||
1412 | 1324 | self.old_time = time.time() | ||
1413 | 1325 | |||
1414 | 1326 | # More than a second has passed since we calculated data | ||
1415 | 1327 | # rate | ||
1416 | 1328 | speed = ( float( self.total_bytes_downloaded | ||
1417 | 1329 | - self.old_bytes_downloaded) | ||
1418 | 1330 | / time_difference) | ||
1419 | 1331 | |||
1420 | 1332 | self.old_bytes_downloaded = self.total_bytes_downloaded | ||
1421 | 1333 | |||
1422 | 1334 | self.speeds.append(speed) | ||
1423 | 1335 | |||
1424 | 1336 | average_speed = 0 | ||
1425 | 1337 | speeds_accumulated = 0 | ||
1426 | 1338 | for speed in reversed(self.speeds): | ||
1427 | 1339 | average_speed += speed | ||
1428 | 1340 | speeds_accumulated += 1 | ||
1429 | 1341 | |||
1430 | 1342 | if speeds_accumulated == 6: | ||
1431 | 1343 | break # do rolling average of 6 seconds | ||
1432 | 1344 | |||
1433 | 1345 | average_speed /= speeds_accumulated | ||
1434 | 1346 | |||
1435 | 1347 | time_remaining = ( ( self.total_bytes_to_download | ||
1436 | 1348 | - self.total_bytes_downloaded) | ||
1437 | 1349 | / speed) | ||
1438 | 1350 | |||
1439 | 1351 | pretty_time = str(datetime.timedelta(seconds=int( | ||
1440 | 1352 | time_remaining))) | ||
1441 | 1353 | |||
1442 | 1354 | # Following table assumes we don't get past TBps internet | ||
1443 | 1355 | # connections soon :-) | ||
1444 | 1356 | units = ["Bps", "kBps", "MBps", "GBps", "TBps"] | ||
1445 | 1357 | units_index = 0 | ||
1446 | 1358 | while speed > 1024: | ||
1447 | 1359 | speed /= 1024 | ||
1448 | 1360 | units_index += 1 | ||
1449 | 1361 | |||
1450 | 1362 | info = "Downloading at {0:.1f} {1}".format( | ||
1451 | 1363 | speed, | ||
1452 | 1364 | units[units_index]) | ||
1453 | 1365 | |||
1454 | 1366 | self.downloading_files_status.SetLabel(info) | ||
1455 | 1367 | |||
1456 | 1368 | info = "{0} remaining".format( | ||
1457 | 1369 | pretty_time) | ||
1458 | 1370 | |||
1459 | 1371 | self.downloading_files_info.SetLabel(info) | ||
1460 | 1372 | |||
1461 | 1373 | self.download_guage.SetValue( 1000 | ||
1462 | 1374 | * self.total_bytes_downloaded | ||
1463 | 1375 | / self.total_bytes_to_download) | ||
1464 | 1376 | |||
1465 | 1377 | elif update_type == "total bytes": | ||
1466 | 1378 | self.total_bytes_to_download = value | ||
1467 | 1379 | self.total_bytes_downloaded = 0 | ||
1468 | 1380 | self.speeds = [] # keep an array of speeds used to calculate | ||
1469 | 1381 | # the estimated time remaining - by not just using the | ||
1470 | 1382 | # current speed we can stop the ETA bouncing around too much. | ||
1471 | 1383 | |||
1472 | 1384 | def event_combo_box_release(self, evt): | ||
1473 | 1385 | pass | ||
1474 | 1386 | |||
1475 | 1387 | def event_combo_box_build(self, evt): | ||
1476 | 1388 | pass | ||
1477 | 1389 | #--- END event(s) --- | ||
1478 | 1390 | |||
1479 | 1391 | |||
1480 | 1392 | class TestDriveWizard(wx.wizard.Wizard): | ||
1481 | 1393 | def __init__(self, title): | ||
1482 | 1394 | wx.wizard.Wizard.__init__(self, None, -1, title, wx.NullBitmap) | ||
1483 | 1395 | self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.on_page_changing) | ||
1484 | 1396 | self.done_startup = False | ||
1485 | 1397 | |||
1486 | 1398 | def on_page_changing(self, evt): | ||
1487 | 1399 | 'Executed before the page changes.' | ||
1488 | 1400 | |||
1489 | 1401 | if self.done_startup == False: | ||
1490 | 1402 | self.pages['lmc_settings'].box2.Hide( | ||
1491 | 1403 | self.pages['lmc_settings'].optional_settings_box, | ||
1492 | 1404 | True) | ||
1493 | 1405 | |||
1494 | 1406 | self.pages['lmc_settings'].box3.Hide( | ||
1495 | 1407 | self.pages['lmc_settings'].confirm_mmc_usage_box, | ||
1496 | 1408 | True) | ||
1497 | 1409 | |||
1498 | 1410 | self.done_startup = True | ||
1499 | 1411 | |||
1500 | 1412 | page = evt.GetPage() | ||
1501 | 1413 | |||
1502 | 1414 | if evt.GetDirection(): # If going forwards... | ||
1503 | 1415 | # Always enable back button if going forwards | ||
1504 | 1416 | self.wizard.FindWindowById(wx.ID_BACKWARD).Enable() | ||
1505 | 1417 | |||
1506 | 1418 | # If going from a select snapshot or select release page, record | ||
1507 | 1419 | # which we were on so the back button of the next page works | ||
1508 | 1420 | if(self.config.settings['release_or_snapshot'] == "release"): | ||
1509 | 1421 | self.pages['select_os'].SetNext(self.pages['select_release']) | ||
1510 | 1422 | self.pages['select_release'].SetPrev(self.pages['select_os']) | ||
1511 | 1423 | |||
1512 | 1424 | self.pages['select_release'].SetNext(self.pages['lmc_settings']) | ||
1513 | 1425 | self.pages['lmc_settings'].SetPrev(self.pages['select_release']) | ||
1514 | 1426 | else: | ||
1515 | 1427 | self.pages['select_os'].SetNext(self.pages['select_snapshot']) | ||
1516 | 1428 | self.pages['select_snapshot'].SetPrev(self.pages['select_os']) | ||
1517 | 1429 | |||
1518 | 1430 | if(page == self.pages['select_os']): | ||
1519 | 1431 | self.pages['select_snapshot'].fill_build_combo_box_for_date( | ||
1520 | 1432 | self.config.settings['build_date']) | ||
1521 | 1433 | |||
1522 | 1434 | self.pages['select_snapshot'].SetNext(self.pages['lmc_settings']) | ||
1523 | 1435 | self.pages['lmc_settings'].SetPrev(self.pages['select_snapshot']) | ||
1524 | 1436 | |||
1525 | 1437 | if page == self.pages['hardware_details']: | ||
1526 | 1438 | self.pages['select_os'].fill_os_list() | ||
1527 | 1439 | |||
1528 | 1440 | if page == self.pages['release_or_snapshot']: | ||
1529 | 1441 | self.pages['hardware_details'].on_page_changing() | ||
1530 | 1442 | |||
1531 | 1443 | # If about to move into the release selection, make sure the list | ||
1532 | 1444 | # is populated only with releases that are valid with our current | ||
1533 | 1445 | # selection | ||
1534 | 1446 | if( page == self.pages['select_os'] | ||
1535 | 1447 | and self.config.settings['release_or_snapshot'] == "release"): | ||
1536 | 1448 | self.pages['select_release'].update_release_and_build_boxes() | ||
1537 | 1449 | |||
1538 | 1450 | if page == self.pages['select_snapshot']: | ||
1539 | 1451 | # Execute when exiting page | ||
1540 | 1452 | self.pages['select_snapshot'].update_platform() | ||
1541 | 1453 | |||
1542 | 1454 | if( page == self.pages['select_snapshot'] | ||
1543 | 1455 | or page == self.pages['select_release']): | ||
1544 | 1456 | self.pages['lmc_settings'].on_activate() | ||
1545 | 1457 | |||
1546 | 1458 | if page == self.pages['lmc_settings']: | ||
1547 | 1459 | # Forward stays disabled until LMC has finished running | ||
1548 | 1460 | self.wizard.FindWindowById(wx.ID_FORWARD).Disable() | ||
1549 | 1461 | self.pages['run_lmc'].on_activate() | ||
1550 | 1462 | |||
1551 | 1463 | else: # Always enable the forward button if reversing into a page | ||
1552 | 1464 | self.wizard.FindWindowById(wx.ID_FORWARD).Enable() | ||
1553 | 1465 | |||
1554 | 1466 | def go(self): | ||
1555 | 1467 | file_handler = FetchImage.FileHandler() | ||
1556 | 1468 | self.config = FetchImage.FetchImageConfig() | ||
1557 | 1469 | self.config.settings["force_download"] = False | ||
1558 | 1470 | self.config.settings['compatable_hwpacks'] = ['foo'] | ||
1559 | 1471 | |||
1560 | 1472 | # If the settings file and server index need updating, grab them | ||
1561 | 1473 | file_handler.update_files_from_server() | ||
1562 | 1474 | |||
1563 | 1475 | # Load settings YAML, which defines the parameters we ask for and | ||
1564 | 1476 | # acceptable responses from the user | ||
1565 | 1477 | self.config.read_config(file_handler.settings_file) | ||
1566 | 1478 | |||
1567 | 1479 | # Using the config we have, look up URLs to download data from in | ||
1568 | 1480 | # the server index | ||
1569 | 1481 | db = FetchImage.DB(file_handler.index_file) | ||
1570 | 1482 | |||
1571 | 1483 | # Create the wizard and the pages | ||
1572 | 1484 | self.wizard = wiz.Wizard(self, -1, "Linaro Media Builder") | ||
1573 | 1485 | |||
1574 | 1486 | self.pages = {} | ||
1575 | 1487 | self.pages['release_or_snapshot'] = ReleaseOrSnapshotPage(self.wizard, | ||
1576 | 1488 | self.config) | ||
1577 | 1489 | self.wizard.FitToPage(self.pages['release_or_snapshot']) | ||
1578 | 1490 | (width, height) = self.wizard.GetSize() | ||
1579 | 1491 | |||
1580 | 1492 | self.pages['hardware_details'] = AboutMyHardwarePage(self.wizard, | ||
1581 | 1493 | self.config, | ||
1582 | 1494 | db, | ||
1583 | 1495 | width) | ||
1584 | 1496 | |||
1585 | 1497 | self.pages['select_release'] = SelectStableRelease(self.wizard, | ||
1586 | 1498 | self.config, | ||
1587 | 1499 | db, | ||
1588 | 1500 | width) | ||
1589 | 1501 | |||
1590 | 1502 | self.pages['select_snapshot'] = SelectSnapshot(self.wizard, | ||
1591 | 1503 | self.config, | ||
1592 | 1504 | db, | ||
1593 | 1505 | width) | ||
1594 | 1506 | |||
1595 | 1507 | self.pages['select_os'] = SelectOS(self.wizard, | ||
1596 | 1508 | self.config, | ||
1597 | 1509 | db, | ||
1598 | 1510 | width) | ||
1599 | 1511 | |||
1600 | 1512 | self.pages['lmc_settings'] = LMC_settings(self.wizard, | ||
1601 | 1513 | self.config, | ||
1602 | 1514 | db, | ||
1603 | 1515 | width) | ||
1604 | 1516 | |||
1605 | 1517 | self.pages['run_lmc'] = RunLMC(self.wizard, | ||
1606 | 1518 | self.config, | ||
1607 | 1519 | db, | ||
1608 | 1520 | width) | ||
1609 | 1521 | |||
1610 | 1522 | self.pages['release_or_snapshot'].SetNext( | ||
1611 | 1523 | self.pages['hardware_details']) | ||
1612 | 1524 | |||
1613 | 1525 | self.pages['hardware_details'].SetPrev( | ||
1614 | 1526 | self.pages['release_or_snapshot']) | ||
1615 | 1527 | |||
1616 | 1528 | self.pages['hardware_details'].SetNext(self.pages['select_os']) | ||
1617 | 1529 | self.pages['select_os'].SetPrev(self.pages['hardware_details']) | ||
1618 | 1530 | # Select OS goes to select build, which is customised for | ||
1619 | 1531 | # releases or snapshots | ||
1620 | 1532 | self.pages['lmc_settings'].SetNext(self.pages['run_lmc']) | ||
1621 | 1533 | self.pages['run_lmc'].SetPrev(self.pages['lmc_settings']) | ||
1622 | 1534 | |||
1623 | 1535 | for (name, page) in self.pages.items(): | ||
1624 | 1536 | self.wizard.GetPageAreaSizer().Add(page) | ||
1625 | 1537 | |||
1626 | 1538 | self.wizard.RunWizard(self.pages['release_or_snapshot']) | ||
1627 | 1539 | |||
1628 | 1540 | |||
1629 | 1541 | def run(): | ||
1630 | 1542 | """Wrapper around the full wizard. Is encapsulated in its own function to | ||
1631 | 1543 | allow a restart to be performed, as described in __main___, easily""" | ||
1632 | 1544 | app = wx.PySimpleApp() # Start the application | ||
1633 | 1545 | if app: | ||
1634 | 1546 | pass # We don't use this directly. Stop pyflakes complaining! | ||
1635 | 1547 | |||
1636 | 1548 | w = TestDriveWizard('Simple Wizard') | ||
1637 | 1549 | return w.go() | ||
1638 | 1550 | |||
1639 | 1551 | |||
1640 | 1552 | class TestURLLookupFunctions(unittest.TestCase): | ||
1641 | 1553 | |||
1642 | 1554 | def setUp(self): | ||
1643 | 1555 | self.file_handler = FetchImage.FileHandler() | ||
1644 | 1556 | self.file_handler.update_files_from_server() | ||
1645 | 1557 | self.config = FetchImage.FetchImageConfig() | ||
1646 | 1558 | self.config.settings["force_download"] = False | ||
1647 | 1559 | |||
1648 | 1560 | # Load settings YAML, which defines the parameters we ask for and | ||
1649 | 1561 | # acceptable responses from the user | ||
1650 | 1562 | self.config.read_config(self.file_handler.settings_file) | ||
1651 | 1563 | |||
1652 | 1564 | # Using the config we have, look up URLs to download data from in the | ||
1653 | 1565 | # server index | ||
1654 | 1566 | self.db = FetchImage.DB(self.file_handler.index_file) | ||
1655 | 1567 | |||
1656 | 1568 | def test_url_lookup(self): | ||
1657 | 1569 | self.settings = self.config.settings | ||
1658 | 1570 | self.settings['release_or_snapshot'] = "snapshot" | ||
1659 | 1571 | |||
1660 | 1572 | #--- Test first with a snapshot build lookup --- | ||
1661 | 1573 | # -- Fix a build date -- | ||
1662 | 1574 | # We only need to look up a single snapshot date. Start with today and | ||
1663 | 1575 | # go with the day in the DB, build 0 | ||
1664 | 1576 | today = wx.DateTime() | ||
1665 | 1577 | today.SetToCurrent() | ||
1666 | 1578 | |||
1667 | 1579 | # -- Don't iterate through platforms for snapshot -- | ||
1668 | 1580 | |||
1669 | 1581 | # -- Select hardware -- | ||
1670 | 1582 | for self.settings['hardware'] in ( | ||
1671 | 1583 | self.settings['choice']['hardware'].keys()): | ||
1672 | 1584 | |||
1673 | 1585 | compatable_hwpacks = self.settings['choice']['hwpack'][ | ||
1674 | 1586 | self.settings['hardware']] | ||
1675 | 1587 | |||
1676 | 1588 | future_date, past_date = self.db.get_next_prev_day_with_builds( | ||
1677 | 1589 | "linaro-alip", | ||
1678 | 1590 | today.FormatISODate().encode('ascii'), | ||
1679 | 1591 | compatable_hwpacks) | ||
1680 | 1592 | |||
1681 | 1593 | if past_date == None: | ||
1682 | 1594 | # Some hardware packs are not available in the snapshot repo, | ||
1683 | 1595 | # so just skip if they aren't | ||
1684 | 1596 | continue | ||
1685 | 1597 | |||
1686 | 1598 | builds = self.db.get_binary_builds_on_day_from_db( | ||
1687 | 1599 | "linaro-alip", | ||
1688 | 1600 | past_date, | ||
1689 | 1601 | compatable_hwpacks) | ||
1690 | 1602 | |||
1691 | 1603 | self.assertTrue(len(builds)) | ||
1692 | 1604 | # If the above assert fails, either the DB is empty, or | ||
1693 | 1605 | # db.get_binary_builds_on_day_from_db failed | ||
1694 | 1606 | |||
1695 | 1607 | small_date = re.sub('-', '', past_date) | ||
1696 | 1608 | self.settings['build'] = small_date + ":" + "0" | ||
1697 | 1609 | |||
1698 | 1610 | # -- Iterate through hardware packs -- | ||
1699 | 1611 | for self.settings['hwpack'] in compatable_hwpacks: | ||
1700 | 1612 | |||
1701 | 1613 | # If hardware pack is available... | ||
1702 | 1614 | if(self.settings['hwpack'] | ||
1703 | 1615 | in self.db.get_hwpacks('snapshot_hwpacks')): | ||
1704 | 1616 | |||
1705 | 1617 | # -- Iterate through images | ||
1706 | 1618 | os_list = self.db.get_os_list_from('snapshot_binaries') | ||
1707 | 1619 | |||
1708 | 1620 | for self.settings['image'] in os_list: | ||
1709 | 1621 | if re.search('old', self.settings['image']): | ||
1710 | 1622 | # Directories with old in the name are of no | ||
1711 | 1623 | # interest to us | ||
1712 | 1624 | continue | ||
1713 | 1625 | |||
1714 | 1626 | # -- Check build which matches these parameters | ||
1715 | 1627 | # (builds that don't match are excluded in UI) -- | ||
1716 | 1628 | if( len(self.db.execute_return_list( | ||
1717 | 1629 | 'select * from snapshot_hwpacks ' | ||
1718 | 1630 | 'where hardware == ? ' | ||
1719 | 1631 | 'and date == ? ' | ||
1720 | 1632 | 'and build == ?', | ||
1721 | 1633 | (self.settings['hwpack'], | ||
1722 | 1634 | small_date, | ||
1723 | 1635 | "0"))) | ||
1724 | 1636 | and len(self.db.execute_return_list( | ||
1725 | 1637 | 'select * from snapshot_binaries ' | ||
1726 | 1638 | 'where image == ? ' | ||
1727 | 1639 | 'and date == ? ' | ||
1728 | 1640 | 'and build == ?', | ||
1729 | 1641 | (self.settings['image'], | ||
1730 | 1642 | small_date, | ||
1731 | 1643 | "0")))): | ||
1732 | 1644 | |||
1733 | 1645 | # - Run the function under test! - | ||
1734 | 1646 | image_url, hwpack_url = ( | ||
1735 | 1647 | self.db.get_image_and_hwpack_urls(self.settings)) | ||
1736 | 1648 | |||
1737 | 1649 | self.assertTrue(image_url) | ||
1738 | 1650 | self.assertTrue(hwpack_url) | ||
1739 | 1651 | |||
1740 | 1652 | #--- Now test release build lookup --- | ||
1741 | 1653 | self.settings['release_or_snapshot'] = "release" | ||
1742 | 1654 | # -- Select hardware -- | ||
1743 | 1655 | for self.settings['hardware'] in ( | ||
1744 | 1656 | self.settings['choice']['hardware'].keys()): | ||
1745 | 1657 | compatable_hwpacks = ( | ||
1746 | 1658 | self.settings['choice']['hwpack'][self.settings['hardware']]) | ||
1747 | 1659 | |||
1748 | 1660 | # -- Iterate through hardware packs -- | ||
1749 | 1661 | for self.settings['hwpack'] in compatable_hwpacks: | ||
1750 | 1662 | |||
1751 | 1663 | # If hardware pack is available... | ||
1752 | 1664 | if(self.settings['hwpack'] | ||
1753 | 1665 | in self.db.get_hwpacks('release_hwpacks')): | ||
1754 | 1666 | |||
1755 | 1667 | # -- Iterate through images | ||
1756 | 1668 | os_list = self.db.get_os_list_from('release_binaries') | ||
1757 | 1669 | |||
1758 | 1670 | for self.settings['image'] in os_list: | ||
1759 | 1671 | if re.search('old', self.settings['image']): | ||
1760 | 1672 | # Directories with old in the name are of no | ||
1761 | 1673 | # interest to us | ||
1762 | 1674 | continue | ||
1763 | 1675 | |||
1764 | 1676 | for platform, ignore in ( | ||
1765 | 1677 | self.settings['choice']['platform'].items()): | ||
1766 | 1678 | self.settings['platform'] = platform | ||
1767 | 1679 | |||
1768 | 1680 | # -- Iterate through available builds -- | ||
1769 | 1681 | builds = self.db.get_builds( | ||
1770 | 1682 | self.settings['platform'], | ||
1771 | 1683 | self.settings['image']) | ||
1772 | 1684 | |||
1773 | 1685 | for build in builds: | ||
1774 | 1686 | self.settings['build'] = build | ||
1775 | 1687 | |||
1776 | 1688 | # -- Check build which matches these parameters | ||
1777 | 1689 | #(builds that don't match are excluded in UI)-- | ||
1778 | 1690 | if( len(self.db.execute_return_list( | ||
1779 | 1691 | 'select * from release_hwpacks ' | ||
1780 | 1692 | 'where platform == ? ' | ||
1781 | 1693 | 'and hardware == ? ' | ||
1782 | 1694 | 'and build == ?', | ||
1783 | 1695 | (self.settings['platform'], | ||
1784 | 1696 | self.settings['hwpack'], | ||
1785 | 1697 | self.settings['build']))) | ||
1786 | 1698 | and len(self.db.execute_return_list( | ||
1787 | 1699 | 'select * from release_binaries ' | ||
1788 | 1700 | 'where platform == ? ' | ||
1789 | 1701 | 'and image == ? ' | ||
1790 | 1702 | 'and build == ?', | ||
1791 | 1703 | (self.settings['platform'], | ||
1792 | 1704 | self.settings['image'], | ||
1793 | 1705 | self.settings['build'])))): | ||
1794 | 1706 | |||
1795 | 1707 | # - Run the function under test! - | ||
1796 | 1708 | image_url, hwpack_url = ( | ||
1797 | 1709 | self.db.get_image_and_hwpack_urls(self.settings)) | ||
1798 | 1710 | self.assertTrue(image_url) | ||
1799 | 1711 | self.assertTrue(hwpack_url) | ||
1800 | 1712 | |||
1801 | 1713 | if __name__ == '__main__': | ||
1802 | 1714 | run() | ||
1803 | 0 | 1715 | ||
1804 | === modified file 'linaro-android-media-create' | |||
1805 | --- linaro-android-media-create 2011-05-26 09:16:35 +0000 | |||
1806 | +++ linaro-android-media-create 2011-07-18 14:39:34 +0000 | |||
1807 | @@ -133,12 +133,13 @@ | |||
1808 | 133 | unpack_android_binary_tarball(args.system, SYSTEM_DIR) | 133 | unpack_android_binary_tarball(args.system, SYSTEM_DIR) |
1809 | 134 | unpack_android_binary_tarball(args.userdata, DATA_DIR) | 134 | unpack_android_binary_tarball(args.userdata, DATA_DIR) |
1810 | 135 | 135 | ||
1812 | 136 | # Create partitions | 136 | # Create partitions |
1813 | 137 | boot_partition, system_partition, cache_partition, \ | 137 | boot_partition, system_partition, cache_partition, \ |
1814 | 138 | data_partition, sdcard_partition = setup_android_partitions( \ | 138 | data_partition, sdcard_partition = setup_android_partitions( \ |
1815 | 139 | board_config, media, args.image_size, args.boot_label, | 139 | board_config, media, args.image_size, args.boot_label, |
1816 | 140 | args.should_create_partitions, args.should_align_boot_part) | 140 | args.should_create_partitions, args.should_align_boot_part) |
1817 | 141 | 141 | ||
1818 | 142 | board_config.populate_raw_partition(args.device, BOOT_DIR) | ||
1819 | 142 | populate_partition(BOOT_DIR + "/boot", BOOT_DISK, boot_partition) | 143 | populate_partition(BOOT_DIR + "/boot", BOOT_DISK, boot_partition) |
1820 | 143 | board_config.populate_boot_script(boot_partition, BOOT_DISK, args.consoles) | 144 | board_config.populate_boot_script(boot_partition, BOOT_DISK, args.consoles) |
1821 | 144 | populate_partition(SYSTEM_DIR + "/system", SYSTEM_DISK, system_partition) | 145 | populate_partition(SYSTEM_DIR + "/system", SYSTEM_DISK, system_partition) |
1822 | 145 | 146 | ||
1823 | === modified file 'linaro-hwpack-install' | |||
1824 | --- linaro-hwpack-install 2011-01-29 16:35:06 +0000 | |||
1825 | +++ linaro-hwpack-install 2011-07-18 14:39:34 +0000 | |||
1826 | @@ -36,7 +36,7 @@ | |||
1827 | 36 | FORCE_YES="no" | 36 | FORCE_YES="no" |
1828 | 37 | SOURCES_LIST_FILE="${TEMP_DIR}/sources.list" | 37 | SOURCES_LIST_FILE="${TEMP_DIR}/sources.list" |
1829 | 38 | APT_GET_OPTIONS="Dir::Etc::SourceList=${SOURCES_LIST_FILE}" | 38 | APT_GET_OPTIONS="Dir::Etc::SourceList=${SOURCES_LIST_FILE}" |
1831 | 39 | SUPPORTED_FORMATS="1.0" # A space-separated list of hwpack formats. | 39 | SUPPORTED_FORMATS="1.0 2.0" # A space-separated list of hwpack formats. |
1832 | 40 | 40 | ||
1833 | 41 | sudo="sudo" | 41 | sudo="sudo" |
1834 | 42 | if [ $(id -u) -eq 0 ]; then | 42 | if [ $(id -u) -eq 0 ]; then |
1835 | 43 | 43 | ||
1836 | === renamed file 'linaro_image_tools/index_server.py' => 'linaro-image-indexer' | |||
1837 | --- linaro_image_tools/index_server.py 2011-06-17 18:04:47 +0000 | |||
1838 | +++ linaro-image-indexer 2011-07-18 14:39:34 +0000 | |||
1839 | @@ -22,10 +22,10 @@ | |||
1840 | 22 | 22 | ||
1841 | 23 | import os | 23 | import os |
1842 | 24 | import re | 24 | import re |
1843 | 25 | import FetchImage | ||
1844 | 26 | import urlparse | 25 | import urlparse |
1845 | 27 | import logging | 26 | import logging |
1846 | 28 | import bz2 | 27 | import bz2 |
1847 | 28 | import linaro_image_tools.FetchImage | ||
1848 | 29 | 29 | ||
1849 | 30 | RELEASES_WWW_DOCUMENT_ROOT = "/srv/releases.linaro.org/www/platform/" | 30 | RELEASES_WWW_DOCUMENT_ROOT = "/srv/releases.linaro.org/www/platform/" |
1850 | 31 | RELEASE_URL = "http://releases.linaro.org/platform/" | 31 | RELEASE_URL = "http://releases.linaro.org/platform/" |
1851 | @@ -41,7 +41,7 @@ | |||
1852 | 41 | def __init__(self): | 41 | def __init__(self): |
1853 | 42 | self.reset() | 42 | self.reset() |
1854 | 43 | self.db_file_name = "server_index" | 43 | self.db_file_name = "server_index" |
1856 | 44 | self.db = FetchImage.DB(self.db_file_name) | 44 | self.db = linaro_image_tools.FetchImage.DB(self.db_file_name) |
1857 | 45 | 45 | ||
1858 | 46 | def crawl(self): | 46 | def crawl(self): |
1859 | 47 | self.db.set_url_parse_info(self.url_parse) | 47 | self.db.set_url_parse_info(self.url_parse) |
1860 | @@ -89,8 +89,6 @@ | |||
1861 | 89 | url_chunks_): | 89 | url_chunks_): |
1862 | 90 | 90 | ||
1863 | 91 | if(not id_ in self.url_parse): | 91 | if(not id_ in self.url_parse): |
1864 | 92 | |||
1865 | 93 | print base_dir_ | ||
1866 | 94 | self.url_parse[id_] = {"base_dir": base_dir_, | 92 | self.url_parse[id_] = {"base_dir": base_dir_, |
1867 | 95 | "base_url": base_url_, | 93 | "base_url": base_url_, |
1868 | 96 | "url_validator": url_validator_, | 94 | "url_validator": url_validator_, |
1869 | 97 | 95 | ||
1870 | === modified file 'linaro-media-create' | |||
1871 | --- linaro-media-create 2011-06-21 09:16:28 +0000 | |||
1872 | +++ linaro-media-create 2011-07-18 14:39:34 +0000 | |||
1873 | @@ -104,6 +104,7 @@ | |||
1874 | 104 | ROOT_DISK = os.path.join(TMP_DIR, 'root-disc') | 104 | ROOT_DISK = os.path.join(TMP_DIR, 'root-disc') |
1875 | 105 | 105 | ||
1876 | 106 | board_config = board_configs[args.board] | 106 | board_config = board_configs[args.board] |
1877 | 107 | board_config.set_metadata(args.hwpacks) | ||
1878 | 107 | 108 | ||
1879 | 108 | ensure_required_commands(args) | 109 | ensure_required_commands(args) |
1880 | 109 | 110 | ||
1881 | 110 | 111 | ||
1882 | === modified file 'linaro_image_tools/FetchImage.py' | |||
1883 | --- linaro_image_tools/FetchImage.py 2011-06-17 18:04:47 +0000 | |||
1884 | +++ linaro_image_tools/FetchImage.py 2011-07-18 14:39:34 +0000 | |||
1885 | @@ -52,15 +52,6 @@ | |||
1886 | 52 | "image-tools", | 52 | "image-tools", |
1887 | 53 | "fetch_image") | 53 | "fetch_image") |
1888 | 54 | 54 | ||
1889 | 55 | class DummyEventHandler(): | ||
1890 | 56 | """Just a sink for events if no event handler is provided to | ||
1891 | 57 | create_media""" | ||
1892 | 58 | def event_start(self, event): | ||
1893 | 59 | pass | ||
1894 | 60 | |||
1895 | 61 | def event_end(self, event): | ||
1896 | 62 | pass | ||
1897 | 63 | |||
1898 | 64 | def has_key_and_evaluates_True(self, dictionary, key): | 55 | def has_key_and_evaluates_True(self, dictionary, key): |
1899 | 65 | return bool(key in dictionary and dictionary[key]) | 56 | return bool(key in dictionary and dictionary[key]) |
1900 | 66 | 57 | ||
1901 | @@ -72,17 +63,15 @@ | |||
1902 | 72 | list.append(setting_name) | 63 | list.append(setting_name) |
1903 | 73 | list.append(dictionary[key]) | 64 | list.append(dictionary[key]) |
1904 | 74 | 65 | ||
1910 | 75 | def create_media(self, image_url, hwpack_url, settings, tools_dir, | 66 | def build_lmc_command(self, |
1911 | 76 | run_in_gui=False, event_handler=None): | 67 | binary_file, |
1912 | 77 | """Create a command line for linaro-media-create based on the settings | 68 | hwpack_file, |
1913 | 78 | provided then run linaro-media-create, either in a separate thread | 69 | settings, |
1914 | 79 | (GUI mode) or in the current one (CLI mode).""" | 70 | tools_dir, |
1915 | 71 | run_in_gui=False): | ||
1916 | 80 | 72 | ||
1917 | 81 | import linaro_image_tools.utils | 73 | import linaro_image_tools.utils |
1918 | 82 | 74 | ||
1919 | 83 | if event_handler == None: | ||
1920 | 84 | event_handler = self.DummyEventHandler() | ||
1921 | 85 | |||
1922 | 86 | args = [] | 75 | args = [] |
1923 | 87 | args.append("pkexec") | 76 | args.append("pkexec") |
1924 | 88 | 77 | ||
1925 | @@ -100,41 +89,6 @@ | |||
1926 | 100 | if run_in_gui: | 89 | if run_in_gui: |
1927 | 101 | args.append("--nocheck-mmc") | 90 | args.append("--nocheck-mmc") |
1928 | 102 | 91 | ||
1929 | 103 | event_handler.event_start("download OS") | ||
1930 | 104 | try: | ||
1931 | 105 | binary_file = self.download(image_url, | ||
1932 | 106 | settings["force_download"], | ||
1933 | 107 | show_wx_progress=run_in_gui, | ||
1934 | 108 | wx_progress_title= | ||
1935 | 109 | "Downloading file 1 of 2") | ||
1936 | 110 | except Exception: | ||
1937 | 111 | # Download error. Hardly matters what, we can't continue. | ||
1938 | 112 | print "Unexpected error:", sys.exc_info()[0] | ||
1939 | 113 | logging.error("Unable to download " + image_url + " - aborting.") | ||
1940 | 114 | event_handler.event_end("download OS") | ||
1941 | 115 | |||
1942 | 116 | if binary_file == None: # User hit cancel when downloading | ||
1943 | 117 | sys.exit(0) | ||
1944 | 118 | |||
1945 | 119 | event_handler.event_start("download hwpack") | ||
1946 | 120 | try: | ||
1947 | 121 | hwpack_file = self.download(hwpack_url, | ||
1948 | 122 | settings["force_download"], | ||
1949 | 123 | show_wx_progress=run_in_gui, | ||
1950 | 124 | wx_progress_title= | ||
1951 | 125 | "Downloading file 2 of 2") | ||
1952 | 126 | except Exception: | ||
1953 | 127 | # Download error. Hardly matters what, we can't continue. | ||
1954 | 128 | print "Unexpected error:", sys.exc_info()[0] | ||
1955 | 129 | logging.error("Unable to download " + hwpack_url + " - aborting.") | ||
1956 | 130 | event_handler.event_end("download hwpack") | ||
1957 | 131 | |||
1958 | 132 | if hwpack_file == None: # User hit cancel when downloading | ||
1959 | 133 | sys.exit(0) | ||
1960 | 134 | |||
1961 | 135 | logging.info("Have downloaded OS binary to", binary_file, | ||
1962 | 136 | "and hardware pack to", hwpack_file) | ||
1963 | 137 | |||
1964 | 138 | if 'rootfs' in settings and settings['rootfs']: | 92 | if 'rootfs' in settings and settings['rootfs']: |
1965 | 139 | args.append("--rootfs") | 93 | args.append("--rootfs") |
1966 | 140 | args.append(settings['rootfs']) | 94 | args.append(settings['rootfs']) |
1967 | @@ -157,34 +111,74 @@ | |||
1968 | 157 | args.append("--hwpack") | 111 | args.append("--hwpack") |
1969 | 158 | args.append(hwpack_file) | 112 | args.append(hwpack_file) |
1970 | 159 | 113 | ||
1982 | 160 | logging.info(args) | 114 | logging.info(" ".join(args)) |
1983 | 161 | 115 | ||
1984 | 162 | if run_in_gui: | 116 | return args |
1985 | 163 | self.lmcargs = args | 117 | |
1986 | 164 | self.event_handler = event_handler | 118 | def create_media(self, image_url, hwpack_url, settings, tools_dir): |
1987 | 165 | self.started_lmc = False | 119 | """Create a command line for linaro-media-create based on the settings |
1988 | 166 | return | 120 | provided then run linaro-media-create, either in a separate thread |
1989 | 167 | 121 | (GUI mode) or in the current one (CLI mode).""" | |
1990 | 168 | else: | 122 | |
1991 | 169 | self.create_process = subprocess.Popen(args) | 123 | to_download = [(image_url, "OS"), |
1992 | 170 | self.create_process.wait() | 124 | (hwpack_url, "hwpack")] |
1993 | 125 | downloaded_files = self.download_files(to_download, | ||
1994 | 126 | settings) | ||
1995 | 127 | |||
1996 | 128 | args = self.build_lmc_command(downloaded_files['OS'], | ||
1997 | 129 | downloaded_files['hwpack'], | ||
1998 | 130 | settings, | ||
1999 | 131 | tools_dir) | ||
2000 | 132 | |||
2001 | 133 | self.create_process = subprocess.Popen(args) | ||
2002 | 134 | self.create_process.wait() | ||
2003 | 171 | 135 | ||
2004 | 172 | class LinaroMediaCreate(threading.Thread): | 136 | class LinaroMediaCreate(threading.Thread): |
2005 | 173 | """Thread class for running linaro-media-create""" | 137 | """Thread class for running linaro-media-create""" |
2007 | 174 | def __init__(self, event_handler, lmcargs, event_queue): | 138 | def __init__(self, |
2008 | 139 | image_url, | ||
2009 | 140 | hwpack_url, | ||
2010 | 141 | file_handler, | ||
2011 | 142 | event_queue, | ||
2012 | 143 | settings, | ||
2013 | 144 | tools_dir): | ||
2014 | 145 | |||
2015 | 175 | threading.Thread.__init__(self) | 146 | threading.Thread.__init__(self) |
2019 | 176 | self.event_handler = event_handler | 147 | |
2020 | 177 | self.lmcargs = lmcargs | 148 | self.image_url = image_url |
2021 | 178 | self.event_queue = event_queue | 149 | self.hwpack_url = hwpack_url |
2022 | 150 | self.file_handler = file_handler | ||
2023 | 151 | self.event_queue = event_queue | ||
2024 | 152 | self.settings = settings | ||
2025 | 153 | self.tools_dir = tools_dir | ||
2026 | 179 | 154 | ||
2027 | 180 | def run(self): | 155 | def run(self): |
2035 | 181 | """Start linaro-media-create and look for lines in the output that: | 156 | """ |
2036 | 182 | 1. Tell us that an event has happened that we can use to update the | 157 | 1. Download required files. |
2037 | 183 | UI progress. | 158 | 2. Build linaro-media-create command |
2038 | 184 | 2. Tell us that linaro-media-create is asking a question that needs | 159 | 3. Start linaro-media-create and look for lines in the output that: |
2039 | 185 | to be re-directed to the GUI""" | 160 | 1. Tell us that an event has happened that we can use to update |
2040 | 186 | 161 | the UI progress. | |
2041 | 187 | self.create_process = subprocess.Popen(self.lmcargs, | 162 | 2. Tell us that linaro-media-create is asking a question that |
2042 | 163 | needs to be re-directed to the GUI | ||
2043 | 164 | """ | ||
2044 | 165 | |||
2045 | 166 | to_download = [(self.image_url, "OS"), | ||
2046 | 167 | (self.hwpack_url, "hwpack")] | ||
2047 | 168 | |||
2048 | 169 | downloaded_files = self.file_handler.download_files( | ||
2049 | 170 | to_download, | ||
2050 | 171 | self.settings, | ||
2051 | 172 | self.event_queue) | ||
2052 | 173 | |||
2053 | 174 | lmc_command = self.file_handler.build_lmc_command( | ||
2054 | 175 | downloaded_files['OS'], | ||
2055 | 176 | downloaded_files['hwpack'], | ||
2056 | 177 | self.settings, | ||
2057 | 178 | self.tools_dir, | ||
2058 | 179 | True) | ||
2059 | 180 | |||
2060 | 181 | self.create_process = subprocess.Popen(lmc_command, | ||
2061 | 188 | stdin=subprocess.PIPE, | 182 | stdin=subprocess.PIPE, |
2062 | 189 | stdout=subprocess.PIPE, | 183 | stdout=subprocess.PIPE, |
2063 | 190 | stderr=subprocess.STDOUT) | 184 | stderr=subprocess.STDOUT) |
2064 | @@ -262,18 +256,6 @@ | |||
2065 | 262 | print >> self.create_process.stdin, text | 256 | print >> self.create_process.stdin, text |
2066 | 263 | self.waiting_for_event_response = False | 257 | self.waiting_for_event_response = False |
2067 | 264 | 258 | ||
2068 | 265 | def start_lmc_gui_thread(self, event_queue): | ||
2069 | 266 | self.lmc_thread = self.LinaroMediaCreate(self.event_handler, | ||
2070 | 267 | self.lmcargs, event_queue) | ||
2071 | 268 | self.lmc_thread.start() | ||
2072 | 269 | |||
2073 | 270 | def kill_create_media(self): | ||
2074 | 271 | pass # TODO: Something! | ||
2075 | 272 | # Need to make sure all child processes are terminated. | ||
2076 | 273 | |||
2077 | 274 | def send_to_create_process(self, text): | ||
2078 | 275 | self.lmc_thread.send_to_create_process(text) | ||
2079 | 276 | |||
2080 | 277 | def name_and_path_from_url(self, url): | 259 | def name_and_path_from_url(self, url): |
2081 | 278 | """Return the file name and the path at which the file will be stored | 260 | """Return the file name and the path at which the file will be stored |
2082 | 279 | on the local system based on the URL we are downloading from""" | 261 | on the local system based on the URL we are downloading from""" |
2083 | @@ -290,34 +272,94 @@ | |||
2084 | 290 | 272 | ||
2085 | 291 | return file_name, file_path | 273 | return file_name, file_path |
2086 | 292 | 274 | ||
2109 | 293 | def create_wx_progress(self, title, message): | 275 | def urllib2_open(self, url): |
2110 | 294 | """Create a standard WX progrss dialog""" | 276 | maxtries = 10 |
2111 | 295 | import wx | 277 | for trycount in range(0, maxtries): |
2112 | 296 | self.dlg = wx.ProgressDialog(title, | 278 | try: |
2113 | 297 | message, | 279 | response = urllib2.urlopen(url) |
2114 | 298 | maximum=1000, | 280 | except: |
2115 | 299 | parent=None, | 281 | if trycount < maxtries - 1: |
2116 | 300 | style=wx.PD_CAN_ABORT | 282 | print "Unable to connect to", url, "retrying in 5 seconds..." |
2117 | 301 | | wx.PD_APP_MODAL | 283 | time.sleep(5) |
2118 | 302 | | wx.PD_ELAPSED_TIME | 284 | continue |
2119 | 303 | | wx.PD_AUTO_HIDE | 285 | else: |
2120 | 304 | | wx.PD_REMAINING_TIME) | 286 | print "Connect failed:", url |
2121 | 305 | 287 | raise | |
2122 | 306 | def timer_ping(self): | 288 | return None |
2123 | 307 | self.update_wx_process(self.download_count) | 289 | else: |
2124 | 308 | 290 | return response | |
2125 | 309 | def update_wx_progress(self, count): | 291 | |
2126 | 310 | self.download_count = count | 292 | return None |
2127 | 311 | (self.do_download, skip) = self.dlg.Update(count) | 293 | |
2128 | 312 | 294 | def download_files(self, | |
2129 | 313 | def download(self, url, force_download=False, | 295 | downloads_list, |
2130 | 314 | show_wx_progress=False, wx_progress_title=None): | 296 | settings, |
2131 | 297 | event_queue=None): | ||
2132 | 298 | """ | ||
2133 | 299 | Download files specified in the downloads_list, which is a list of | ||
2134 | 300 | url, name tuples. | ||
2135 | 301 | """ | ||
2136 | 302 | |||
2137 | 303 | downloaded_files = {} | ||
2138 | 304 | |||
2139 | 305 | bytes_to_download = 0 | ||
2140 | 306 | |||
2141 | 307 | for url, name in downloads_list: | ||
2142 | 308 | file_name, file_path = self.name_and_path_from_url(url) | ||
2143 | 309 | |||
2144 | 310 | file_name = file_path + os.sep + file_name | ||
2145 | 311 | if os.path.exists(file_name): | ||
2146 | 312 | continue # If file already exists, don't download it | ||
2147 | 313 | |||
2148 | 314 | response = self.urllib2_open(url) | ||
2149 | 315 | if response: | ||
2150 | 316 | bytes_to_download += int(response.info() | ||
2151 | 317 | .getheader('Content-Length').strip()) | ||
2152 | 318 | response.close() | ||
2153 | 319 | |||
2154 | 320 | if event_queue: | ||
2155 | 321 | event_queue.put(("update", | ||
2156 | 322 | "download", | ||
2157 | 323 | "total bytes", | ||
2158 | 324 | bytes_to_download)) | ||
2159 | 325 | |||
2160 | 326 | for url, name in downloads_list: | ||
2161 | 327 | if event_queue: | ||
2162 | 328 | event_queue.put(("start", "download " + name)) | ||
2163 | 329 | event_queue.put(("update", | ||
2164 | 330 | "download", | ||
2165 | 331 | "name", | ||
2166 | 332 | name)) | ||
2167 | 333 | |||
2168 | 334 | path = None | ||
2169 | 335 | try: | ||
2170 | 336 | path = self.download(url, | ||
2171 | 337 | event_queue, | ||
2172 | 338 | settings["force_download"]) | ||
2173 | 339 | except Exception: | ||
2174 | 340 | # Download error. Hardly matters what, we can't continue. | ||
2175 | 341 | print "Unexpected error:", sys.exc_info()[0] | ||
2176 | 342 | logging.error("Unable to download " + url + " - aborting.") | ||
2177 | 343 | |||
2178 | 344 | if event_queue: | ||
2179 | 345 | event_queue.put(("end", "download " + name)) | ||
2180 | 346 | |||
2181 | 347 | if path == None: # User hit cancel when downloading | ||
2182 | 348 | sys.exit(0) | ||
2183 | 349 | |||
2184 | 350 | downloaded_files[name] = path | ||
2185 | 351 | logging.info("Have downloaded {0} to {1}".format(name, path)) | ||
2186 | 352 | |||
2187 | 353 | return downloaded_files | ||
2188 | 354 | |||
2189 | 355 | def download(self, | ||
2190 | 356 | url, | ||
2191 | 357 | event_queue, | ||
2192 | 358 | force_download=False): | ||
2193 | 315 | """Downloads the file requested buy URL to the local cache and returns | 359 | """Downloads the file requested buy URL to the local cache and returns |
2194 | 316 | the full path to the downloaded file""" | 360 | the full path to the downloaded file""" |
2195 | 317 | 361 | ||
2196 | 318 | file_name, file_path = self.name_and_path_from_url(url) | 362 | file_name, file_path = self.name_and_path_from_url(url) |
2197 | 319 | |||
2198 | 320 | just_file_name = file_name | ||
2199 | 321 | file_name = file_path + os.sep + file_name | 363 | file_name = file_path + os.sep + file_name |
2200 | 322 | 364 | ||
2201 | 323 | if not os.path.isdir(file_path): | 365 | if not os.path.isdir(file_path): |
2202 | @@ -328,23 +370,9 @@ | |||
2203 | 328 | "--force-download to override).") | 370 | "--force-download to override).") |
2204 | 329 | return file_name | 371 | return file_name |
2205 | 330 | 372 | ||
2207 | 331 | logging.info("Fetching", url) | 373 | logging.info("Fetching " + url) |
2208 | 332 | 374 | ||
2224 | 333 | maxtries = 10 | 375 | response = self.urllib2_open(url) |
2210 | 334 | for trycount in range(0, maxtries): | ||
2211 | 335 | try: | ||
2212 | 336 | response = urllib2.urlopen(url) | ||
2213 | 337 | except: | ||
2214 | 338 | if trycount < maxtries - 1: | ||
2215 | 339 | print "Unable to download", url, "retrying in 5 seconds..." | ||
2216 | 340 | time.sleep(5) | ||
2217 | 341 | continue | ||
2218 | 342 | else: | ||
2219 | 343 | print "Download failed for some reason:", url | ||
2220 | 344 | raise | ||
2221 | 345 | return | ||
2222 | 346 | else: | ||
2223 | 347 | break | ||
2225 | 348 | 376 | ||
2226 | 349 | self.do_download = True | 377 | self.do_download = True |
2227 | 350 | file_out = open(file_name, 'w') | 378 | file_out = open(file_name, 'w') |
2228 | @@ -356,28 +384,22 @@ | |||
2229 | 356 | 384 | ||
2230 | 357 | if show_progress: | 385 | if show_progress: |
2231 | 358 | chunk_size = download_size_in_bytes / 1000 | 386 | chunk_size = download_size_in_bytes / 1000 |
2238 | 359 | if show_wx_progress: | 387 | if not event_queue: |
2233 | 360 | if wx_progress_title == None: | ||
2234 | 361 | wx_progress_title = "Downloading File" | ||
2235 | 362 | self.create_wx_progress(wx_progress_title, | ||
2236 | 363 | "Downloading " + just_file_name) | ||
2237 | 364 | else: | ||
2239 | 365 | print "Fetching", url | 388 | print "Fetching", url |
2240 | 366 | else: | 389 | else: |
2241 | 367 | chunk_size = download_size_in_bytes | 390 | chunk_size = download_size_in_bytes |
2242 | 368 | 391 | ||
2243 | 369 | if show_progress and show_wx_progress: | ||
2244 | 370 | # Just update the download box before we get the first % | ||
2245 | 371 | self.update_wx_progress(0) | ||
2246 | 372 | |||
2247 | 373 | printed_progress = False | 392 | printed_progress = False |
2248 | 374 | while self.do_download: | 393 | while self.do_download: |
2249 | 375 | chunk = response.read(chunk_size) | 394 | chunk = response.read(chunk_size) |
2250 | 376 | if len(chunk): | 395 | if len(chunk): |
2251 | 377 | # Print a % download complete so we don't get too bored | 396 | # Print a % download complete so we don't get too bored |
2252 | 378 | if show_progress: | 397 | if show_progress: |
2255 | 379 | if show_wx_progress: | 398 | if event_queue: |
2256 | 380 | self.update_wx_progress(chunks_downloaded) | 399 | event_queue.put(("update", |
2257 | 400 | "download", | ||
2258 | 401 | "progress", | ||
2259 | 402 | len(chunk))) | ||
2260 | 381 | else: | 403 | else: |
2261 | 382 | # Have 1000 chunks so div by 10 to get %... | 404 | # Have 1000 chunks so div by 10 to get %... |
2262 | 383 | sys.stdout.write("\r%d%%" % (chunks_downloaded / 10)) | 405 | sys.stdout.write("\r%d%%" % (chunks_downloaded / 10)) |
2263 | @@ -400,7 +422,7 @@ | |||
2264 | 400 | 422 | ||
2265 | 401 | return file_name | 423 | return file_name |
2266 | 402 | 424 | ||
2268 | 403 | def download_if_old(self, url, force_download, show_wx_progress=False): | 425 | def download_if_old(self, url, event_queue, force_download): |
2269 | 404 | file_name, file_path = self.name_and_path_from_url(url) | 426 | file_name, file_path = self.name_and_path_from_url(url) |
2270 | 405 | 427 | ||
2271 | 406 | file_path_and_name = file_path + os.sep + file_name | 428 | file_path_and_name = file_path + os.sep + file_name |
2272 | @@ -411,25 +433,25 @@ | |||
2273 | 411 | force_download = (force_download == True | 433 | force_download = (force_download == True |
2274 | 412 | or ( time.mktime(time.localtime()) | 434 | or ( time.mktime(time.localtime()) |
2275 | 413 | - os.path.getmtime(file_path_and_name) | 435 | - os.path.getmtime(file_path_and_name) |
2277 | 414 | > 60 * 60 * 24)) | 436 | > 60 * 60)) |
2278 | 415 | except OSError: | 437 | except OSError: |
2279 | 416 | force_download = True # File not found... | 438 | force_download = True # File not found... |
2280 | 417 | 439 | ||
2282 | 418 | return self.download(url, force_download, show_wx_progress) | 440 | return self.download(url, event_queue, force_download) |
2283 | 419 | 441 | ||
2284 | 420 | def update_files_from_server(self, force_download=False, | 442 | def update_files_from_server(self, force_download=False, |
2286 | 421 | show_wx_progress=False): | 443 | event_queue=None): |
2287 | 422 | 444 | ||
2290 | 423 | settings_url = "http://z.nanosheep.org/fetch_image_settings.yaml" | 445 | settings_url = "http://releases.linaro.org/fetch_image/fetch_image_settings.yaml" |
2291 | 424 | server_index_url = "http://z.nanosheep.org/server_index.bz2" | 446 | server_index_url = "http://releases.linaro.org/fetch_image/server_index.bz2" |
2292 | 425 | 447 | ||
2293 | 426 | self.settings_file = self.download_if_old(settings_url, | 448 | self.settings_file = self.download_if_old(settings_url, |
2296 | 427 | force_download, | 449 | event_queue, |
2297 | 428 | show_wx_progress) | 450 | force_download) |
2298 | 429 | 451 | ||
2299 | 430 | self.index_file = self.download_if_old(server_index_url, | 452 | self.index_file = self.download_if_old(server_index_url, |
2302 | 431 | force_download, | 453 | event_queue, |
2303 | 432 | show_wx_progress) | 454 | force_download) |
2304 | 433 | 455 | ||
2305 | 434 | zip_search = re.search(r"^(.*)\.bz2$", self.index_file) | 456 | zip_search = re.search(r"^(.*)\.bz2$", self.index_file) |
2306 | 435 | 457 | ||
2307 | @@ -484,9 +506,9 @@ | |||
2308 | 484 | self.settings['UI']['reverse-translate'][value] = key | 506 | self.settings['UI']['reverse-translate'][value] = key |
2309 | 485 | 507 | ||
2310 | 486 | def parse_args(self, args): | 508 | def parse_args(self, args): |
2314 | 487 | parser = argparse.ArgumentParser(description= | 509 | parser = argparse.ArgumentParser(description="Create a board image, " |
2315 | 488 | "Create a board image, first " | 510 | "first downloading any required " |
2316 | 489 | "downloading any required files.") | 511 | "files.") |
2317 | 490 | 512 | ||
2318 | 491 | for (key, value) in self.settings['choice'].items(): | 513 | for (key, value) in self.settings['choice'].items(): |
2319 | 492 | parser.add_argument( | 514 | parser.add_argument( |
2320 | @@ -983,7 +1005,7 @@ | |||
2321 | 983 | loop_date_increment = -one_day | 1005 | loop_date_increment = -one_day |
2322 | 984 | 1006 | ||
2323 | 985 | test_date[in_the] = current_date | 1007 | test_date[in_the] = current_date |
2325 | 986 | 1008 | ||
2326 | 987 | while test_date[in_the] <= max_search_date: | 1009 | while test_date[in_the] <= max_search_date: |
2327 | 988 | test_date[in_the] += loop_date_increment | 1010 | test_date[in_the] += loop_date_increment |
2328 | 989 | 1011 | ||
2329 | 990 | 1012 | ||
2330 | === modified file 'linaro_image_tools/fetch_image_settings.yaml' | |||
2331 | --- linaro_image_tools/fetch_image_settings.yaml 2011-06-17 18:04:47 +0000 | |||
2332 | +++ linaro_image_tools/fetch_image_settings.yaml 2011-07-18 14:39:34 +0000 | |||
2333 | @@ -45,6 +45,7 @@ | |||
2334 | 45 | # u8500: U8500 | 45 | # u8500: U8500 |
2335 | 46 | overo: Overo | 46 | overo: Overo |
2336 | 47 | smdkv310: S5PV310 | 47 | smdkv310: S5PV310 |
2337 | 48 | origen: Origen | ||
2338 | 48 | 49 | ||
2339 | 49 | hwpack: | 50 | hwpack: |
2340 | 50 | beagle: | 51 | beagle: |
2341 | @@ -88,6 +89,9 @@ | |||
2342 | 88 | - lt-s5pv310 | 89 | - lt-s5pv310 |
2343 | 89 | - s5pv310 | 90 | - s5pv310 |
2344 | 90 | 91 | ||
2345 | 92 | origen: | ||
2346 | 93 | - lt-origen | ||
2347 | 94 | |||
2348 | 91 | image: | 95 | image: |
2349 | 92 | - alip | 96 | - alip |
2350 | 93 | - developer | 97 | - developer |
2351 | 94 | 98 | ||
2352 | === modified file 'linaro_image_tools/hwpack/config.py' | |||
2353 | --- linaro_image_tools/hwpack/config.py 2011-06-20 13:46:16 +0000 | |||
2354 | +++ linaro_image_tools/hwpack/config.py 2011-07-18 14:39:34 +0000 | |||
2355 | @@ -22,7 +22,7 @@ | |||
2356 | 22 | import ConfigParser | 22 | import ConfigParser |
2357 | 23 | import re | 23 | import re |
2358 | 24 | 24 | ||
2360 | 25 | from hardwarepack_format import ( | 25 | from linaro_image_tools.hwpack.hardwarepack_format import ( |
2361 | 26 | HardwarePackFormatV1, | 26 | HardwarePackFormatV1, |
2362 | 27 | HardwarePackFormatV2, | 27 | HardwarePackFormatV2, |
2363 | 28 | ) | 28 | ) |
2364 | @@ -42,7 +42,7 @@ | |||
2365 | 42 | SOURCES_ENTRY_KEY = "sources-entry" | 42 | SOURCES_ENTRY_KEY = "sources-entry" |
2366 | 43 | PACKAGES_KEY = "packages" | 43 | PACKAGES_KEY = "packages" |
2367 | 44 | PACKAGE_REGEX = NAME_REGEX | 44 | PACKAGE_REGEX = NAME_REGEX |
2369 | 45 | PATH_REGEX = r"[a-z0-9][a-z0-9+\-./]+$" | 45 | PATH_REGEX = r"[a-z0-9][a-z0-9+\-./_]+$" |
2370 | 46 | ORIGIN_KEY = "origin" | 46 | ORIGIN_KEY = "origin" |
2371 | 47 | MAINTAINER_KEY = "maintainer" | 47 | MAINTAINER_KEY = "maintainer" |
2372 | 48 | ARCHITECTURES_KEY = "architectures" | 48 | ARCHITECTURES_KEY = "architectures" |
2373 | @@ -58,6 +58,16 @@ | |||
2374 | 58 | PARTITION_LAYOUT_KEY = "partition_layout" | 58 | PARTITION_LAYOUT_KEY = "partition_layout" |
2375 | 59 | MMC_ID_KEY = "mmc_id" | 59 | MMC_ID_KEY = "mmc_id" |
2376 | 60 | FORMAT_KEY = "format" | 60 | FORMAT_KEY = "format" |
2377 | 61 | BOOT_MIN_SIZE_KEY = "boot_min_size" | ||
2378 | 62 | ROOT_MIN_SIZE_KEY = "root_min_size" | ||
2379 | 63 | LOADER_MIN_SIZE_KEY = "loader_min_size" | ||
2380 | 64 | |||
2381 | 65 | DEFINED_PARTITION_LAYOUTS = [ | ||
2382 | 66 | 'bootfs16_rootfs', | ||
2383 | 67 | 'bootfs_rootfs', | ||
2384 | 68 | #'reserved_bootfs_rootfs', | ||
2385 | 69 | ] | ||
2386 | 70 | |||
2387 | 61 | 71 | ||
2388 | 62 | def __init__(self, fp): | 72 | def __init__(self, fp): |
2389 | 63 | """Create a Config. | 73 | """Create a Config. |
2390 | @@ -93,6 +103,9 @@ | |||
2391 | 93 | self._validate_wireless_interfaces() | 103 | self._validate_wireless_interfaces() |
2392 | 94 | self._validate_partition_layout() | 104 | self._validate_partition_layout() |
2393 | 95 | self._validate_mmc_id() | 105 | self._validate_mmc_id() |
2394 | 106 | self._validate_boot_min_size() | ||
2395 | 107 | self._validate_root_min_size() | ||
2396 | 108 | self._validate_loader_min_size() | ||
2397 | 96 | 109 | ||
2398 | 97 | self._validate_sections() | 110 | self._validate_sections() |
2399 | 98 | 111 | ||
2400 | @@ -217,6 +230,30 @@ | |||
2401 | 217 | return self._get_option_from_main_section(self.MMC_ID_KEY) | 230 | return self._get_option_from_main_section(self.MMC_ID_KEY) |
2402 | 218 | 231 | ||
2403 | 219 | @property | 232 | @property |
2404 | 233 | def root_min_size(self): | ||
2405 | 234 | """Minimum size of the root partition, in MiB. | ||
2406 | 235 | |||
2407 | 236 | An int. | ||
2408 | 237 | """ | ||
2409 | 238 | return self._get_option_from_main_section(self.ROOT_MIN_SIZE_KEY) | ||
2410 | 239 | |||
2411 | 240 | @property | ||
2412 | 241 | def boot_min_size(self): | ||
2413 | 242 | """Minimum size of the boot partition, in MiB. | ||
2414 | 243 | |||
2415 | 244 | An int. | ||
2416 | 245 | """ | ||
2417 | 246 | return self._get_option_from_main_section(self.BOOT_MIN_SIZE_KEY) | ||
2418 | 247 | |||
2419 | 248 | @property | ||
2420 | 249 | def loader_min_size(self): | ||
2421 | 250 | """Minimum size of the optional loader partition, in MiB. | ||
2422 | 251 | |||
2423 | 252 | An int. | ||
2424 | 253 | """ | ||
2425 | 254 | return self._get_option_from_main_section(self.LOADER_MIN_SIZE_KEY) | ||
2426 | 255 | |||
2427 | 256 | @property | ||
2428 | 220 | def origin(self): | 257 | def origin(self): |
2429 | 221 | """The origin that should be recorded in the hwpack. | 258 | """The origin that should be recorded in the hwpack. |
2430 | 222 | 259 | ||
2431 | @@ -375,17 +412,12 @@ | |||
2432 | 375 | pass | 412 | pass |
2433 | 376 | 413 | ||
2434 | 377 | def _validate_partition_layout(self): | 414 | def _validate_partition_layout(self): |
2441 | 378 | defined_partition_layouts = [ | 415 | if self.partition_layout not in self.DEFINED_PARTITION_LAYOUTS: |
2436 | 379 | #'bootfs16_rootfs', | ||
2437 | 380 | 'bootfs_rootfs', | ||
2438 | 381 | #'reserved_bootfs_rootfs', | ||
2439 | 382 | ] | ||
2440 | 383 | if self.partition_layout not in defined_partition_layouts: | ||
2442 | 384 | raise HwpackConfigError( | 416 | raise HwpackConfigError( |
2443 | 385 | "Undefined partition layout %s in the [%s] section. " | 417 | "Undefined partition layout %s in the [%s] section. " |
2444 | 386 | "Valid partition layouts are %s." | 418 | "Valid partition layouts are %s." |
2445 | 387 | % (self.partition_layout, self.MAIN_SECTION, | 419 | % (self.partition_layout, self.MAIN_SECTION, |
2447 | 388 | ", ".join(defined_partition_layouts))) | 420 | ", ".join(self.DEFINED_PARTITION_LAYOUTS))) |
2448 | 389 | 421 | ||
2449 | 390 | def _validate_mmc_id(self): | 422 | def _validate_mmc_id(self): |
2450 | 391 | mmc_id = self.mmc_id | 423 | mmc_id = self.mmc_id |
2451 | @@ -396,6 +428,36 @@ | |||
2452 | 396 | except: | 428 | except: |
2453 | 397 | raise HwpackConfigError("Invalid mmc id %s" % (mmc_id)) | 429 | raise HwpackConfigError("Invalid mmc id %s" % (mmc_id)) |
2454 | 398 | 430 | ||
2455 | 431 | def _validate_root_min_size(self): | ||
2456 | 432 | root_min_size = self.root_min_size | ||
2457 | 433 | if root_min_size is None: | ||
2458 | 434 | return | ||
2459 | 435 | try: | ||
2460 | 436 | assert int(root_min_size) > 0 | ||
2461 | 437 | except: | ||
2462 | 438 | raise HwpackConfigError( | ||
2463 | 439 | "Invalid root min size %s" % (root_min_size)) | ||
2464 | 440 | |||
2465 | 441 | def _validate_boot_min_size(self): | ||
2466 | 442 | boot_min_size = self.boot_min_size | ||
2467 | 443 | if boot_min_size is None: | ||
2468 | 444 | return | ||
2469 | 445 | try: | ||
2470 | 446 | assert int(boot_min_size) > 0 | ||
2471 | 447 | except: | ||
2472 | 448 | raise HwpackConfigError( | ||
2473 | 449 | "Invalid boot min size %s" % (boot_min_size)) | ||
2474 | 450 | |||
2475 | 451 | def _validate_loader_min_size(self): | ||
2476 | 452 | loader_min_size = self.loader_min_size | ||
2477 | 453 | if loader_min_size is None: | ||
2478 | 454 | return | ||
2479 | 455 | try: | ||
2480 | 456 | assert int(loader_min_size) > 0 | ||
2481 | 457 | except: | ||
2482 | 458 | raise HwpackConfigError( | ||
2483 | 459 | "Invalid loader min size %s" % (loader_min_size)) | ||
2484 | 460 | |||
2485 | 399 | def _validate_include_debs(self): | 461 | def _validate_include_debs(self): |
2486 | 400 | try: | 462 | try: |
2487 | 401 | self.include_debs | 463 | self.include_debs |
2488 | 402 | 464 | ||
2489 | === modified file 'linaro_image_tools/hwpack/hardwarepack.py' | |||
2490 | --- linaro_image_tools/hwpack/hardwarepack.py 2011-06-20 13:46:16 +0000 | |||
2491 | +++ linaro_image_tools/hwpack/hardwarepack.py 2011-07-18 14:39:34 +0000 | |||
2492 | @@ -80,7 +80,8 @@ | |||
2493 | 80 | def add_v2_config(self, serial_tty=None, kernel_addr=None, initrd_addr=None, | 80 | def add_v2_config(self, serial_tty=None, kernel_addr=None, initrd_addr=None, |
2494 | 81 | load_addr=None, fdt=None, wired_interfaces=[], | 81 | load_addr=None, fdt=None, wired_interfaces=[], |
2495 | 82 | wireless_interfaces=[], partition_layout=None, | 82 | wireless_interfaces=[], partition_layout=None, |
2497 | 83 | mmc_id=None): | 83 | mmc_id=None, boot_min_size=None, root_min_size=None, |
2498 | 84 | loader_min_size=None): | ||
2499 | 84 | """Add fields that are specific to the new format. | 85 | """Add fields that are specific to the new format. |
2500 | 85 | 86 | ||
2501 | 86 | These fields are not present in earlier config files. | 87 | These fields are not present in earlier config files. |
2502 | @@ -94,6 +95,9 @@ | |||
2503 | 94 | self.wireless_interfaces = wireless_interfaces | 95 | self.wireless_interfaces = wireless_interfaces |
2504 | 95 | self.partition_layout = partition_layout | 96 | self.partition_layout = partition_layout |
2505 | 96 | self.mmc_id = mmc_id | 97 | self.mmc_id = mmc_id |
2506 | 98 | self.boot_min_size = boot_min_size | ||
2507 | 99 | self.root_min_size = root_min_size | ||
2508 | 100 | self.loader_min_size = loader_min_size | ||
2509 | 97 | 101 | ||
2510 | 98 | @classmethod | 102 | @classmethod |
2511 | 99 | def from_config(cls, config, version, architecture): | 103 | def from_config(cls, config, version, architecture): |
2512 | @@ -126,7 +130,10 @@ | |||
2513 | 126 | wired_interfaces=config.wired_interfaces, | 130 | wired_interfaces=config.wired_interfaces, |
2514 | 127 | wireless_interfaces=config.wireless_interfaces, | 131 | wireless_interfaces=config.wireless_interfaces, |
2515 | 128 | partition_layout=config.partition_layout, | 132 | partition_layout=config.partition_layout, |
2517 | 129 | mmc_id=config.mmc_id) | 133 | mmc_id=config.mmc_id, |
2518 | 134 | boot_min_size=config.boot_min_size, | ||
2519 | 135 | root_min_size=config.root_min_size, | ||
2520 | 136 | loader_min_size=config.loader_min_size) | ||
2521 | 130 | return metadata | 137 | return metadata |
2522 | 131 | 138 | ||
2523 | 132 | def __str__(self): | 139 | def __str__(self): |
2524 | @@ -163,6 +170,13 @@ | |||
2525 | 163 | metadata += "PARTITION_LAYOUT=%s\n" % self.partition_layout | 170 | metadata += "PARTITION_LAYOUT=%s\n" % self.partition_layout |
2526 | 164 | if self.mmc_id is not None: | 171 | if self.mmc_id is not None: |
2527 | 165 | metadata += "MMC_ID=%s\n" % self.mmc_id | 172 | metadata += "MMC_ID=%s\n" % self.mmc_id |
2528 | 173 | if self.boot_min_size is not None: | ||
2529 | 174 | metadata += "BOOT_MIN_SIZE=%s\n" % self.boot_min_size | ||
2530 | 175 | if self.root_min_size is not None: | ||
2531 | 176 | metadata += "ROOT_MIN_SIZE=%s\n" % self.root_min_size | ||
2532 | 177 | if self.loader_min_size is not None: | ||
2533 | 178 | metadata += "LOADER_MIN_SIZE=%s\n" % self.loader_min_size | ||
2534 | 179 | |||
2535 | 166 | return metadata | 180 | return metadata |
2536 | 167 | 181 | ||
2537 | 168 | 182 | ||
2538 | 169 | 183 | ||
2539 | === modified file 'linaro_image_tools/hwpack/tests/test_config.py' | |||
2540 | --- linaro_image_tools/hwpack/tests/test_config.py 2011-06-17 12:28:43 +0000 | |||
2541 | +++ linaro_image_tools/hwpack/tests/test_config.py 2011-07-18 14:39:34 +0000 | |||
2542 | @@ -216,13 +216,16 @@ | |||
2543 | 216 | self.assertValidationError("Invalid path: ~~", config) | 216 | self.assertValidationError("Invalid path: ~~", config) |
2544 | 217 | 217 | ||
2545 | 218 | def test_validate_partition_layout(self): | 218 | def test_validate_partition_layout(self): |
2550 | 219 | config = self.get_config(self.valid_start_v2 + | 219 | partition_layout = 'apafs_bananfs' |
2551 | 220 | "u-boot-package = u-boot-linaro-s5pv310\n" \ | 220 | config = self.get_config(self.valid_start_v2 + "u-boot-package = " \ |
2552 | 221 | "u-boot-file = u-boot.bin\n" \ | 221 | "u-boot-linaro-s5pv310\nu-boot-file = " \ |
2553 | 222 | "partition_layout = apafs_bananfs\n") | 222 | "u-boot.bin\npartition_layout = %s\n" % \ |
2554 | 223 | partition_layout) | ||
2555 | 223 | self.assertValidationError( | 224 | self.assertValidationError( |
2558 | 224 | "Undefined partition layout apafs_bananfs in the [hwpack] " \ | 225 | "Undefined partition layout %s in the [%s] section. " |
2559 | 225 | "section. Valid partition layouts are bootfs_rootfs.", config) | 226 | "Valid partition layouts are %s." |
2560 | 227 | % (partition_layout, 'hwpack', | ||
2561 | 228 | ", ".join(config.DEFINED_PARTITION_LAYOUTS)), config) | ||
2562 | 226 | 229 | ||
2563 | 227 | def test_validate_wired_interfaces(self): | 230 | def test_validate_wired_interfaces(self): |
2564 | 228 | self.assertTrue("XXX What is an invalid interface name?") | 231 | self.assertTrue("XXX What is an invalid interface name?") |
2565 | @@ -246,6 +249,21 @@ | |||
2566 | 246 | "mmc_id = x\n") | 249 | "mmc_id = x\n") |
2567 | 247 | self.assertValidationError("Invalid mmc id x", config) | 250 | self.assertValidationError("Invalid mmc id x", config) |
2568 | 248 | 251 | ||
2569 | 252 | def test_validate_boot_min_size(self): | ||
2570 | 253 | config = self.get_config(self.valid_complete_v2 + | ||
2571 | 254 | "boot_min_size = x\n") | ||
2572 | 255 | self.assertValidationError("Invalid boot min size x", config) | ||
2573 | 256 | |||
2574 | 257 | def test_validate_root_min_size(self): | ||
2575 | 258 | config = self.get_config(self.valid_complete_v2 + | ||
2576 | 259 | "root_min_size = x\n") | ||
2577 | 260 | self.assertValidationError("Invalid root min size x", config) | ||
2578 | 261 | |||
2579 | 262 | def test_validate_loader_min_size(self): | ||
2580 | 263 | config = self.get_config(self.valid_complete_v2 + | ||
2581 | 264 | "loader_min_size = x\n") | ||
2582 | 265 | self.assertValidationError("Invalid loader min size x", config) | ||
2583 | 266 | |||
2584 | 249 | def test_validate_kernel_addr(self): | 267 | def test_validate_kernel_addr(self): |
2585 | 250 | config = self.get_config(self.valid_complete_v2 + | 268 | config = self.get_config(self.valid_complete_v2 + |
2586 | 251 | "kernel_addr = 0x8000000\n") | 269 | "kernel_addr = 0x8000000\n") |
2587 | @@ -327,6 +345,27 @@ | |||
2588 | 327 | config.validate() | 345 | config.validate() |
2589 | 328 | self.assertEqual("1", config.mmc_id) | 346 | self.assertEqual("1", config.mmc_id) |
2590 | 329 | 347 | ||
2591 | 348 | def test_boot_min_size(self): | ||
2592 | 349 | config = self.get_config(self.valid_complete_v2 + | ||
2593 | 350 | "boot_min_size = 50\n" + | ||
2594 | 351 | self.valid_end) | ||
2595 | 352 | config.validate() | ||
2596 | 353 | self.assertEqual("50", config.boot_min_size) | ||
2597 | 354 | |||
2598 | 355 | def test_root_min_size(self): | ||
2599 | 356 | config = self.get_config(self.valid_complete_v2 + | ||
2600 | 357 | "root_min_size = 50\n" + | ||
2601 | 358 | self.valid_end) | ||
2602 | 359 | config.validate() | ||
2603 | 360 | self.assertEqual("50", config.root_min_size) | ||
2604 | 361 | |||
2605 | 362 | def test_loader_min_size(self): | ||
2606 | 363 | config = self.get_config(self.valid_complete_v2 + | ||
2607 | 364 | "loader_min_size = 2\n" + | ||
2608 | 365 | self.valid_end) | ||
2609 | 366 | config.validate() | ||
2610 | 367 | self.assertEqual("2", config.loader_min_size) | ||
2611 | 368 | |||
2612 | 330 | def test_kernel_addr(self): | 369 | def test_kernel_addr(self): |
2613 | 331 | config = self.get_config(self.valid_complete_v2 + | 370 | config = self.get_config(self.valid_complete_v2 + |
2614 | 332 | "kernel_addr = 0x80000000\n" + | 371 | "kernel_addr = 0x80000000\n" + |
2615 | 333 | 372 | ||
2616 | === modified file 'linaro_image_tools/hwpack/tests/test_hardwarepack.py' | |||
2617 | --- linaro_image_tools/hwpack/tests/test_hardwarepack.py 2011-06-17 15:10:49 +0000 | |||
2618 | +++ linaro_image_tools/hwpack/tests/test_hardwarepack.py 2011-07-18 14:39:34 +0000 | |||
2619 | @@ -183,6 +183,33 @@ | |||
2620 | 183 | "MMC_ID=1\n", | 183 | "MMC_ID=1\n", |
2621 | 184 | str(metadata)) | 184 | str(metadata)) |
2622 | 185 | 185 | ||
2623 | 186 | def test_str_with_boot_min_size(self): | ||
2624 | 187 | metadata = Metadata("ahwpack", "4", "armel", | ||
2625 | 188 | format=HardwarePackFormatV2()) | ||
2626 | 189 | metadata.add_v2_config(boot_min_size='50') | ||
2627 | 190 | self.assertEqual( | ||
2628 | 191 | "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" | ||
2629 | 192 | "BOOT_MIN_SIZE=50\n", | ||
2630 | 193 | str(metadata)) | ||
2631 | 194 | |||
2632 | 195 | def test_str_with_root_min_size(self): | ||
2633 | 196 | metadata = Metadata("ahwpack", "4", "armel", | ||
2634 | 197 | format=HardwarePackFormatV2()) | ||
2635 | 198 | metadata.add_v2_config(root_min_size='100') | ||
2636 | 199 | self.assertEqual( | ||
2637 | 200 | "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" | ||
2638 | 201 | "ROOT_MIN_SIZE=100\n", | ||
2639 | 202 | str(metadata)) | ||
2640 | 203 | |||
2641 | 204 | def test_str_with_loader_min_size(self): | ||
2642 | 205 | metadata = Metadata("ahwpack", "4", "armel", | ||
2643 | 206 | format=HardwarePackFormatV2()) | ||
2644 | 207 | metadata.add_v2_config(loader_min_size='1') | ||
2645 | 208 | self.assertEqual( | ||
2646 | 209 | "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n" | ||
2647 | 210 | "LOADER_MIN_SIZE=1\n", | ||
2648 | 211 | str(metadata)) | ||
2649 | 212 | |||
2650 | 186 | def test_from_config(self): | 213 | def test_from_config(self): |
2651 | 187 | class Config: | 214 | class Config: |
2652 | 188 | name = "foo" | 215 | name = "foo" |
2653 | 189 | 216 | ||
2654 | === modified file 'linaro_image_tools/media_create/android_boards.py' | |||
2655 | --- linaro_image_tools/media_create/android_boards.py 2011-04-22 15:09:08 +0000 | |||
2656 | +++ linaro_image_tools/media_create/android_boards.py 2011-07-18 14:39:34 +0000 | |||
2657 | @@ -28,6 +28,8 @@ | |||
2658 | 28 | from linaro_image_tools.media_create.boards import PART_ALIGN_S | 28 | from linaro_image_tools.media_create.boards import PART_ALIGN_S |
2659 | 29 | from linaro_image_tools.media_create.boards import BeagleConfig | 29 | from linaro_image_tools.media_create.boards import BeagleConfig |
2660 | 30 | from linaro_image_tools.media_create.boards import PandaConfig | 30 | from linaro_image_tools.media_create.boards import PandaConfig |
2661 | 31 | from linaro_image_tools.media_create.boards import SnowballSdConfig | ||
2662 | 32 | from linaro_image_tools.media_create.boards import SnowballEmmcConfig | ||
2663 | 31 | from linaro_image_tools.media_create.boards import ( | 33 | from linaro_image_tools.media_create.boards import ( |
2664 | 32 | align_up, | 34 | align_up, |
2665 | 33 | align_partition, | 35 | align_partition, |
2666 | @@ -37,6 +39,7 @@ | |||
2667 | 37 | from linaro_image_tools import cmd_runner | 39 | from linaro_image_tools import cmd_runner |
2668 | 38 | import os | 40 | import os |
2669 | 39 | 41 | ||
2670 | 42 | |||
2671 | 40 | class AndroidBoardConfig(object): | 43 | class AndroidBoardConfig(object): |
2672 | 41 | @classmethod | 44 | @classmethod |
2673 | 42 | def _get_bootargs(cls, consoles): | 45 | def _get_bootargs(cls, consoles): |
2674 | @@ -78,7 +81,7 @@ | |||
2675 | 78 | as_root=True).wait() | 81 | as_root=True).wait() |
2676 | 79 | 82 | ||
2677 | 80 | boot_env = cls._get_boot_env(consoles) | 83 | boot_env = cls._get_boot_env(consoles) |
2679 | 81 | cmdline_filepath = os.path.join(boot_disk, "cmdline") | 84 | cmdline_filepath = os.path.join(boot_disk, "cmdline") |
2680 | 82 | cmdline_file = open(cmdline_filepath, 'r') | 85 | cmdline_file = open(cmdline_filepath, 'r') |
2681 | 83 | android_kernel_cmdline = cmdline_file.read() | 86 | android_kernel_cmdline = cmdline_file.read() |
2682 | 84 | boot_env['bootargs'] = boot_env['bootargs'] + ' ' + \ | 87 | boot_env['bootargs'] = boot_env['bootargs'] + ' ' + \ |
2683 | @@ -96,7 +99,8 @@ | |||
2684 | 96 | pass | 99 | pass |
2685 | 97 | 100 | ||
2686 | 98 | @classmethod | 101 | @classmethod |
2688 | 99 | def get_sfdisk_cmd(cls, should_align_boot_part=False): | 102 | def get_sfdisk_cmd(cls, should_align_boot_part=False, |
2689 | 103 | start_addr=0, extra_part=False): | ||
2690 | 100 | if cls.fat_size == 32: | 104 | if cls.fat_size == 32: |
2691 | 101 | partition_type = '0x0C' | 105 | partition_type = '0x0C' |
2692 | 102 | else: | 106 | else: |
2693 | @@ -116,7 +120,7 @@ | |||
2694 | 116 | 120 | ||
2695 | 117 | # can only start on sector 1 (sector 0 is MBR / partition table) | 121 | # can only start on sector 1 (sector 0 is MBR / partition table) |
2696 | 118 | boot_start, boot_end, boot_len = align_partition( | 122 | boot_start, boot_end, boot_len = align_partition( |
2698 | 119 | 1, BOOT_MIN_SIZE_S, boot_align, PART_ALIGN_S) | 123 | start_addr + 1, BOOT_MIN_SIZE_S, boot_align, PART_ALIGN_S) |
2699 | 120 | # apparently OMAP3 ROMs require the vfat length to be an even number | 124 | # apparently OMAP3 ROMs require the vfat length to be an even number |
2700 | 121 | # of sectors (multiple of 1 KiB); decrease the length if it's odd, | 125 | # of sectors (multiple of 1 KiB); decrease the length if it's odd, |
2701 | 122 | # there should still be enough room | 126 | # there should still be enough room |
2702 | @@ -131,12 +135,28 @@ | |||
2703 | 131 | _cache_end + 1, USERDATA_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) | 135 | _cache_end + 1, USERDATA_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) |
2704 | 132 | sdcard_start, _sdcard_end, _sdcard_len = align_partition( | 136 | sdcard_start, _sdcard_end, _sdcard_len = align_partition( |
2705 | 133 | _userdata_end + 1, SDCARD_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) | 137 | _userdata_end + 1, SDCARD_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) |
2707 | 134 | 138 | ||
2708 | 139 | # Snowball board needs a raw partition added to the beginning of image. | ||
2709 | 140 | # If extra_part is True an extra primary partition will be added. | ||
2710 | 141 | # Due to a maximum of 4 primary partitions cache data will be placed in | ||
2711 | 142 | # a extended partition | ||
2712 | 143 | if extra_part == True: | ||
2713 | 144 | assert start_addr > 0, ("Not possible to add extra partition" \ | ||
2714 | 145 | "when boot partition starts at '0'") | ||
2715 | 146 | return '%s,%s,%s,*\n%s,%s,L\n%s,-,E\n%s,%s,L\n%s,%s,L\n%s,,,-' % ( | ||
2716 | 147 | boot_start, boot_len, partition_type, system_start, _system_len, | ||
2717 | 148 | cache_start, cache_start, _cache_len, userdata_start, | ||
2718 | 149 | _userdata_len, sdcard_start) | ||
2719 | 150 | |||
2720 | 135 | return '%s,%s,%s,*\n%s,%s,L\n%s,%s,L\n%s,-,E\n%s,%s,L\n%s,,,-' % ( | 151 | return '%s,%s,%s,*\n%s,%s,L\n%s,%s,L\n%s,-,E\n%s,%s,L\n%s,,,-' % ( |
2721 | 136 | boot_start, boot_len, partition_type, system_start, _system_len, | 152 | boot_start, boot_len, partition_type, system_start, _system_len, |
2722 | 137 | cache_start, _cache_len, userdata_start, userdata_start, | 153 | cache_start, _cache_len, userdata_start, userdata_start, |
2723 | 138 | _userdata_len, sdcard_start) | 154 | _userdata_len, sdcard_start) |
2724 | 139 | 155 | ||
2725 | 156 | @classmethod | ||
2726 | 157 | def populate_raw_partition(cls, media, boot_dir): | ||
2727 | 158 | super(AndroidBoardConfig, cls).populate_raw_partition(boot_dir, media) | ||
2728 | 159 | |||
2729 | 140 | 160 | ||
2730 | 141 | class AndroidOmapConfig(AndroidBoardConfig): | 161 | class AndroidOmapConfig(AndroidBoardConfig): |
2731 | 142 | pass | 162 | pass |
2732 | @@ -149,10 +169,50 @@ | |||
2733 | 149 | 169 | ||
2734 | 150 | class AndroidPandaConfig(AndroidOmapConfig, PandaConfig): | 170 | class AndroidPandaConfig(AndroidOmapConfig, PandaConfig): |
2735 | 151 | _extra_serial_opts = 'console=tty0 console=ttyO2,115200n8' | 171 | _extra_serial_opts = 'console=tty0 console=ttyO2,115200n8' |
2736 | 172 | extra_boot_args_options = ( | ||
2737 | 173 | 'earlyprintk fixrtc nocompcache vram=48M ' | ||
2738 | 174 | 'omapfb.vram=0:24M,1:24M mem=456M@0x80000000 mem=512M@0xA0000000') | ||
2739 | 152 | android_specific_args = 'init=/init androidboot.console=ttyO2' | 175 | android_specific_args = 'init=/init androidboot.console=ttyO2' |
2740 | 153 | 176 | ||
2741 | 154 | 177 | ||
2742 | 178 | class AndroidSnowballSdConfig(AndroidBoardConfig, SnowballSdConfig): | ||
2743 | 179 | extra_boot_args_options = ( | ||
2744 | 180 | 'earlyprintk rootdelay=1 fixrtc nocompcache ' | ||
2745 | 181 | 'mem=128M@0 mali.mali_mem=64M@128M mem=24M@192M hwmem=167M@216M ' | ||
2746 | 182 | 'mem_issw=1M@383M mem=640M@384M vmalloc=256M') | ||
2747 | 183 | _extra_serial_opts = 'console=tty0 console=ttyO2,115200n8' | ||
2748 | 184 | android_specific_args = 'init=/init androidboot.console=ttyAMA2' | ||
2749 | 185 | |||
2750 | 186 | |||
2751 | 187 | class AndroidSnowballEmmcConfig(AndroidBoardConfig, SnowballEmmcConfig): | ||
2752 | 188 | extra_boot_args_options = ( | ||
2753 | 189 | 'earlyprintk rootdelay=1 fixrtc nocompcache ' | ||
2754 | 190 | 'mem=128M@0 mali.mali_mem=64M@128M mem=24M@192M hwmem=167M@216M ' | ||
2755 | 191 | 'mem_issw=1M@383M mem=640M@384M vmalloc=256M') | ||
2756 | 192 | _extra_serial_opts = 'console=tty0 console=ttyAMA2,115200n8' | ||
2757 | 193 | android_specific_args = 'init=/init androidboot.console=ttyAMA2' | ||
2758 | 194 | |||
2759 | 195 | @classmethod | ||
2760 | 196 | def get_sfdisk_cmd(cls, should_align_boot_part=False): | ||
2761 | 197 | |||
2762 | 198 | LOADER_MIN_SIZE_S = align_up( | ||
2763 | 199 | 1 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE | ||
2764 | 200 | |||
2765 | 201 | loader_start, loader_end, loader_len = align_partition( | ||
2766 | 202 | SnowballEmmcConfig.SNOWBALL_LOADER_START_S, | ||
2767 | 203 | LOADER_MIN_SIZE_S, 1, PART_ALIGN_S) | ||
2768 | 204 | |||
2769 | 205 | command = super(AndroidSnowballEmmcConfig, cls).get_sfdisk_cmd( | ||
2770 | 206 | should_align_boot_part=True, start_addr=loader_end, | ||
2771 | 207 | extra_part=True) | ||
2772 | 208 | |||
2773 | 209 | return '%s,%s,0xDA\n%s' % ( | ||
2774 | 210 | loader_start, loader_len, command) | ||
2775 | 211 | |||
2776 | 212 | |||
2777 | 155 | android_board_configs = { | 213 | android_board_configs = { |
2778 | 156 | 'beagle': AndroidBeagleConfig, | 214 | 'beagle': AndroidBeagleConfig, |
2779 | 157 | 'panda': AndroidPandaConfig, | 215 | 'panda': AndroidPandaConfig, |
2780 | 216 | 'snowball_sd': AndroidSnowballSdConfig, | ||
2781 | 217 | 'snowball_emmc': AndroidSnowballEmmcConfig, | ||
2782 | 158 | } | 218 | } |
2783 | 159 | 219 | ||
2784 | === modified file 'linaro_image_tools/media_create/boards.py' | |||
2785 | --- linaro_image_tools/media_create/boards.py 2011-05-26 20:19:23 +0000 | |||
2786 | +++ linaro_image_tools/media_create/boards.py 2011-07-18 14:39:34 +0000 | |||
2787 | @@ -31,11 +31,15 @@ | |||
2788 | 31 | import tempfile | 31 | import tempfile |
2789 | 32 | import struct | 32 | import struct |
2790 | 33 | from binascii import crc32 | 33 | from binascii import crc32 |
2791 | 34 | import tarfile | ||
2792 | 35 | import ConfigParser | ||
2793 | 36 | import shutil | ||
2794 | 34 | 37 | ||
2795 | 35 | from linaro_image_tools import cmd_runner | 38 | from linaro_image_tools import cmd_runner |
2796 | 36 | 39 | ||
2797 | 37 | from linaro_image_tools.media_create.partitions import SECTOR_SIZE | 40 | from linaro_image_tools.media_create.partitions import SECTOR_SIZE |
2798 | 38 | 41 | ||
2799 | 42 | |||
2800 | 39 | KERNEL_GLOB = 'vmlinuz-*-%(kernel_flavor)s' | 43 | KERNEL_GLOB = 'vmlinuz-*-%(kernel_flavor)s' |
2801 | 40 | INITRD_GLOB = 'initrd.img-*-%(kernel_flavor)s' | 44 | INITRD_GLOB = 'initrd.img-*-%(kernel_flavor)s' |
2802 | 41 | DTB_GLOB = 'dt-*-%(kernel_flavor)s/%(dtb_name)s' | 45 | DTB_GLOB = 'dt-*-%(kernel_flavor)s/%(dtb_name)s' |
2803 | @@ -58,21 +62,11 @@ | |||
2804 | 58 | # align on 4 MiB | 62 | # align on 4 MiB |
2805 | 59 | PART_ALIGN_S = 4 * 1024 * 1024 / SECTOR_SIZE | 63 | PART_ALIGN_S = 4 * 1024 * 1024 / SECTOR_SIZE |
2806 | 60 | 64 | ||
2807 | 65 | |||
2808 | 61 | def align_up(value, align): | 66 | def align_up(value, align): |
2809 | 62 | """Round value to the next multiple of align.""" | 67 | """Round value to the next multiple of align.""" |
2810 | 63 | return (value + align - 1) / align * align | 68 | return (value + align - 1) / align * align |
2811 | 64 | 69 | ||
2812 | 65 | # optional bootloader partition; at least 1 MiB; in theory, an i.MX5x | ||
2813 | 66 | # bootloader partition could hold RedBoot, FIS table, RedBoot config, kernel, | ||
2814 | 67 | # and initrd, but we typically use U-Boot which is about 167 KiB as of | ||
2815 | 68 | # 2011/02/11 and currently doesn't even store its environment there, so this | ||
2816 | 69 | # should be enough | ||
2817 | 70 | LOADER_MIN_SIZE_S = align_up(1 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE | ||
2818 | 71 | # boot partition; at least 50 MiB; XXX this shouldn't be hardcoded | ||
2819 | 72 | BOOT_MIN_SIZE_S = align_up(50 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE | ||
2820 | 73 | # root partition; at least 50 MiB; XXX this shouldn't be hardcoded | ||
2821 | 74 | ROOT_MIN_SIZE_S = align_up(50 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE | ||
2822 | 75 | |||
2823 | 76 | # Samsung v310 implementation notes and terminology | 70 | # Samsung v310 implementation notes and terminology |
2824 | 77 | # | 71 | # |
2825 | 78 | # * BL0, BL1 etc. are the various bootloaders in order of execution | 72 | # * BL0, BL1 etc. are the various bootloaders in order of execution |
2826 | @@ -104,6 +98,7 @@ | |||
2827 | 104 | assert SAMSUNG_V310_BL2_LEN * SECTOR_SIZE == 512 * 1024, ( | 98 | assert SAMSUNG_V310_BL2_LEN * SECTOR_SIZE == 512 * 1024, ( |
2828 | 105 | "BL1 expects BL2 (u-boot) to be 512 KiB") | 99 | "BL1 expects BL2 (u-boot) to be 512 KiB") |
2829 | 106 | 100 | ||
2830 | 101 | |||
2831 | 107 | def align_partition(min_start, min_length, start_alignment, end_alignment): | 102 | def align_partition(min_start, min_length, start_alignment, end_alignment): |
2832 | 108 | """Compute partition start and end offsets based on specified constraints. | 103 | """Compute partition start and end offsets based on specified constraints. |
2833 | 109 | 104 | ||
2834 | @@ -125,10 +120,103 @@ | |||
2835 | 125 | """A descriptor that provides @property behavior on class methods.""" | 120 | """A descriptor that provides @property behavior on class methods.""" |
2836 | 126 | def __init__(self, getter): | 121 | def __init__(self, getter): |
2837 | 127 | self.getter = getter | 122 | self.getter = getter |
2838 | 123 | |||
2839 | 128 | def __get__(self, instance, cls): | 124 | def __get__(self, instance, cls): |
2840 | 129 | return self.getter(cls) | 125 | return self.getter(cls) |
2841 | 130 | 126 | ||
2842 | 131 | 127 | ||
2843 | 128 | class HardwarepackHandler(object): | ||
2844 | 129 | FORMAT_1 = '1.0' | ||
2845 | 130 | FORMAT_2 = '2.0' | ||
2846 | 131 | FORMAT_MIXED = '1.0and2.0' | ||
2847 | 132 | metadata_filename = 'metadata' | ||
2848 | 133 | format_filename = 'FORMAT' | ||
2849 | 134 | main_section = 'main' | ||
2850 | 135 | hwpack_tarfiles = [] | ||
2851 | 136 | tempdir = None | ||
2852 | 137 | |||
2853 | 138 | def __init__(self, hwpacks): | ||
2854 | 139 | self.hwpacks = hwpacks | ||
2855 | 140 | self.hwpack_tarfiles = [] | ||
2856 | 141 | |||
2857 | 142 | class FakeSecHead(object): | ||
2858 | 143 | """ Add a fake section header to the metadata file. | ||
2859 | 144 | |||
2860 | 145 | This is done so we can use ConfigParser to parse the file. | ||
2861 | 146 | """ | ||
2862 | 147 | def __init__(self, fp): | ||
2863 | 148 | self.fp = fp | ||
2864 | 149 | self.sechead = '[%s]\n' % HardwarepackHandler.main_section | ||
2865 | 150 | |||
2866 | 151 | def readline(self): | ||
2867 | 152 | if self.sechead: | ||
2868 | 153 | try: | ||
2869 | 154 | return self.sechead | ||
2870 | 155 | finally: | ||
2871 | 156 | self.sechead = None | ||
2872 | 157 | else: | ||
2873 | 158 | return self.fp.readline() | ||
2874 | 159 | |||
2875 | 160 | def __enter__(self): | ||
2876 | 161 | self.tempdir = tempfile.mkdtemp() | ||
2877 | 162 | for hwpack in self.hwpacks: | ||
2878 | 163 | hwpack_tarfile = tarfile.open(hwpack, mode='r:gz') | ||
2879 | 164 | self.hwpack_tarfiles.append(hwpack_tarfile) | ||
2880 | 165 | return self | ||
2881 | 166 | |||
2882 | 167 | def __exit__(self, type, value, traceback): | ||
2883 | 168 | for hwpack_tarfile in self.hwpack_tarfiles: | ||
2884 | 169 | if hwpack_tarfile is not None: | ||
2885 | 170 | hwpack_tarfile.close() | ||
2886 | 171 | self.hwpack_tarfiles = [] | ||
2887 | 172 | if self.tempdir is not None and os.path.exists(self.tempdir): | ||
2888 | 173 | shutil.rmtree(self.tempdir) | ||
2889 | 174 | |||
2890 | 175 | def get_field(self, section, field): | ||
2891 | 176 | data = None | ||
2892 | 177 | hwpack_with_data = None | ||
2893 | 178 | for hwpack_tarfile in self.hwpack_tarfiles: | ||
2894 | 179 | metadata = hwpack_tarfile.extractfile(self.metadata_filename) | ||
2895 | 180 | # Use RawConfigParser which does not support the magical interpolation | ||
2896 | 181 | # behavior of ConfigParser so we don't mess up metadata accidentally. | ||
2897 | 182 | parser = ConfigParser.RawConfigParser() | ||
2898 | 183 | parser.readfp(self.FakeSecHead(metadata)) | ||
2899 | 184 | try: | ||
2900 | 185 | new_data = parser.get(section, field) | ||
2901 | 186 | if new_data is not None: | ||
2902 | 187 | assert data is None, "The metadata field '%s' is set to " \ | ||
2903 | 188 | "'%s' and new value '%s' is found" % (field, data, new_data) | ||
2904 | 189 | data = new_data | ||
2905 | 190 | hwpack_with_data = hwpack_tarfile | ||
2906 | 191 | except ConfigParser.NoOptionError: | ||
2907 | 192 | continue | ||
2908 | 193 | return data, hwpack_with_data | ||
2909 | 194 | |||
2910 | 195 | def get_format(self): | ||
2911 | 196 | format = None | ||
2912 | 197 | supported_formats = [self.FORMAT_1, self.FORMAT_2] | ||
2913 | 198 | for hwpack_tarfile in self.hwpack_tarfiles: | ||
2914 | 199 | format_file = hwpack_tarfile.extractfile(self.format_filename) | ||
2915 | 200 | format_string = format_file.read().strip() | ||
2916 | 201 | if not format_string in supported_formats: | ||
2917 | 202 | raise AssertionError( | ||
2918 | 203 | "Format version '%s' is not supported." % \ | ||
2919 | 204 | format_string) | ||
2920 | 205 | if format is None: | ||
2921 | 206 | format = format_string | ||
2922 | 207 | elif format != format_string: | ||
2923 | 208 | return self.FORMAT_MIXED | ||
2924 | 209 | return format | ||
2925 | 210 | |||
2926 | 211 | def get_file(self, file_alias): | ||
2927 | 212 | file_name, hwpack_tarfile = self.get_field(self.main_section, | ||
2928 | 213 | file_alias) | ||
2929 | 214 | if file_name is not None: | ||
2930 | 215 | hwpack_tarfile.extract(file_name, self.tempdir) | ||
2931 | 216 | file_name = os.path.join(self.tempdir, file_name) | ||
2932 | 217 | return file_name | ||
2933 | 218 | |||
2934 | 219 | |||
2935 | 132 | class BoardConfig(object): | 220 | class BoardConfig(object): |
2936 | 133 | """The configuration used when building an image for a board.""" | 221 | """The configuration used when building an image for a board.""" |
2937 | 134 | # These attributes may not need to be redefined on some subclasses. | 222 | # These attributes may not need to be redefined on some subclasses. |
2938 | @@ -138,12 +226,17 @@ | |||
2939 | 138 | mmc_option = '0:1' | 226 | mmc_option = '0:1' |
2940 | 139 | mmc_part_offset = 0 | 227 | mmc_part_offset = 0 |
2941 | 140 | fat_size = 32 | 228 | fat_size = 32 |
2944 | 141 | extra_serial_opts = '' | 229 | _extra_serial_opts = '' |
2945 | 142 | live_serial_opts = '' | 230 | _live_serial_opts = '' |
2946 | 143 | extra_boot_args_options = None | 231 | extra_boot_args_options = None |
2947 | 144 | supports_writing_to_mmc = True | 232 | supports_writing_to_mmc = True |
2948 | 233 | LOADER_MIN_SIZE_S = align_up(1 * 1024**2, SECTOR_SIZE) / SECTOR_SIZE | ||
2949 | 234 | BOOT_MIN_SIZE_S = align_up(50 * 1024**2, SECTOR_SIZE) / SECTOR_SIZE | ||
2950 | 235 | ROOT_MIN_SIZE_S = align_up(50 * 1024**2, SECTOR_SIZE) / SECTOR_SIZE | ||
2951 | 145 | 236 | ||
2953 | 146 | # These attributes must be defined on all subclasses. | 237 | # These attributes must be defined on all subclasses for backwards |
2954 | 238 | # compatibility with hwpacks v1 format. Hwpacks v2 format allows these to | ||
2955 | 239 | # be specified in the hwpack metadata. | ||
2956 | 147 | kernel_addr = None | 240 | kernel_addr = None |
2957 | 148 | initrd_addr = None | 241 | initrd_addr = None |
2958 | 149 | load_addr = None | 242 | load_addr = None |
2959 | @@ -152,6 +245,88 @@ | |||
2960 | 152 | kernel_flavors = None | 245 | kernel_flavors = None |
2961 | 153 | boot_script = None | 246 | boot_script = None |
2962 | 154 | serial_tty = None | 247 | serial_tty = None |
2963 | 248 | wired_interfaces = None | ||
2964 | 249 | wireless_interfaces = None | ||
2965 | 250 | mmc_id = None | ||
2966 | 251 | |||
2967 | 252 | hardwarepack_handler = None | ||
2968 | 253 | |||
2969 | 254 | @classmethod | ||
2970 | 255 | def get_metadata_field(cls, target, field_name): | ||
2971 | 256 | """ Return the metadata value for field_name if it can be found. | ||
2972 | 257 | """ | ||
2973 | 258 | data, _ = cls.hardwarepack_handler.get_field( | ||
2974 | 259 | cls.hardwarepack_handler.main_section, field_name) | ||
2975 | 260 | return data | ||
2976 | 261 | |||
2977 | 262 | @classmethod | ||
2978 | 263 | def set_metadata(cls, hwpacks): | ||
2979 | 264 | cls.hardwarepack_handler = HardwarepackHandler(hwpacks) | ||
2980 | 265 | with cls.hardwarepack_handler: | ||
2981 | 266 | if (cls.hardwarepack_handler.get_format() == | ||
2982 | 267 | cls.hardwarepack_handler.FORMAT_1): | ||
2983 | 268 | return | ||
2984 | 269 | |||
2985 | 270 | if (cls.hardwarepack_handler.get_format() == | ||
2986 | 271 | cls.hardwarepack_handler.FORMAT_2): | ||
2987 | 272 | # Clear V1 defaults. | ||
2988 | 273 | cls.kernel_addr = None | ||
2989 | 274 | cls.initrd_addr = None | ||
2990 | 275 | cls.load_addr = None | ||
2991 | 276 | cls.serial_tty = None | ||
2992 | 277 | cls.fat_size = None | ||
2993 | 278 | cls.BOOT_MIN_SIZE_S = None | ||
2994 | 279 | cls.ROOT_MIN_SIZE_S = None | ||
2995 | 280 | cls.LOADER_MIN_SIZE_S = None | ||
2996 | 281 | |||
2997 | 282 | # Set new values from metadata. | ||
2998 | 283 | cls.kernel_addr = cls.get_metadata_field( | ||
2999 | 284 | cls.kernel_addr, 'kernel_addr') | ||
3000 | 285 | cls.initrd_addr = cls.get_metadata_field( | ||
3001 | 286 | cls.initrd_addr, 'initrd_addr') | ||
3002 | 287 | cls.load_addr = cls.get_metadata_field( | ||
3003 | 288 | cls.load_addr, 'load_addr') | ||
3004 | 289 | cls.serial_tty = cls.get_metadata_field( | ||
3005 | 290 | cls.serial_tty, 'serial_tty') | ||
3006 | 291 | cls.wired_interfaces = cls.get_metadata_field( | ||
3007 | 292 | cls.wired_interfaces, 'wired_interfaces') | ||
3008 | 293 | cls.wireless_interfaces = cls.get_metadata_field( | ||
3009 | 294 | cls.wireless_interfaces, 'wireless_interfaces') | ||
3010 | 295 | cls.mmc_id = cls.get_metadata_field( | ||
3011 | 296 | cls.mmc_id, 'mmc_id') | ||
3012 | 297 | |||
3013 | 298 | partition_layout = cls.get_metadata_field(cls.fat_size, 'partition_layout') | ||
3014 | 299 | if partition_layout == 'bootfs_rootfs' or partition_layout is None: | ||
3015 | 300 | cls.fat_size = 32 | ||
3016 | 301 | elif partition_layout == 'bootfs16_rootfs': | ||
3017 | 302 | cls.fat_size = 16 | ||
3018 | 303 | else: | ||
3019 | 304 | raise AssertionError("Unknown partition layout '%s'." % partition_layout) | ||
3020 | 305 | |||
3021 | 306 | boot_min_size = cls.get_metadata_field( | ||
3022 | 307 | cls.BOOT_MIN_SIZE_S, 'boot_min_size') | ||
3023 | 308 | if boot_min_size is not None: | ||
3024 | 309 | cls.BOOT_MIN_SIZE_S = align_up(int(boot_min_size) * 1024**2, | ||
3025 | 310 | SECTOR_SIZE) / SECTOR_SIZE | ||
3026 | 311 | root_min_size = cls.get_metadata_field( | ||
3027 | 312 | cls.ROOT_MIN_SIZE_S, 'root_min_size') | ||
3028 | 313 | if root_min_size is not None: | ||
3029 | 314 | cls.ROOT_MIN_SIZE_S = align_up(int(root_min_size) * 1024**2, | ||
3030 | 315 | SECTOR_SIZE) / SECTOR_SIZE | ||
3031 | 316 | loader_min_size = cls.get_metadata_field( | ||
3032 | 317 | cls.LOADER_MIN_SIZE_S, 'loader_min_size') | ||
3033 | 318 | if loader_min_size is not None: | ||
3034 | 319 | cls.LOADER_MIN_SIZE_S = align_up(int(loader_min_size) * 1024**2, | ||
3035 | 320 | SECTOR_SIZE) / SECTOR_SIZE | ||
3036 | 321 | |||
3037 | 322 | |||
3038 | 323 | @classmethod | ||
3039 | 324 | def get_file(cls, file_alias, default=None): | ||
3040 | 325 | file_in_hwpack = cls.hardwarepack_handler.get_file(file_alias) | ||
3041 | 326 | if file_in_hwpack is not None: | ||
3042 | 327 | return file_in_hwpack | ||
3043 | 328 | else: | ||
3044 | 329 | return default | ||
3045 | 155 | 330 | ||
3046 | 156 | @classmethod | 331 | @classmethod |
3047 | 157 | def get_sfdisk_cmd(cls, should_align_boot_part=False): | 332 | def get_sfdisk_cmd(cls, should_align_boot_part=False): |
3048 | @@ -167,9 +342,6 @@ | |||
3049 | 167 | else: | 342 | else: |
3050 | 168 | partition_type = '0x0E' | 343 | partition_type = '0x0E' |
3051 | 169 | 344 | ||
3052 | 170 | BOOT_MIN_SIZE_S = align_up(50 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE | ||
3053 | 171 | ROOT_MIN_SIZE_S = align_up(50 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE | ||
3054 | 172 | |||
3055 | 173 | # align on sector 63 for compatibility with broken versions of x-loader | 345 | # align on sector 63 for compatibility with broken versions of x-loader |
3056 | 174 | # unless align_boot_part is set | 346 | # unless align_boot_part is set |
3057 | 175 | boot_align = 63 | 347 | boot_align = 63 |
3058 | @@ -178,7 +350,7 @@ | |||
3059 | 178 | 350 | ||
3060 | 179 | # can only start on sector 1 (sector 0 is MBR / partition table) | 351 | # can only start on sector 1 (sector 0 is MBR / partition table) |
3061 | 180 | boot_start, boot_end, boot_len = align_partition( | 352 | boot_start, boot_end, boot_len = align_partition( |
3063 | 181 | 1, BOOT_MIN_SIZE_S, boot_align, PART_ALIGN_S) | 353 | 1, cls.BOOT_MIN_SIZE_S, boot_align, PART_ALIGN_S) |
3064 | 182 | # apparently OMAP3 ROMs require the vfat length to be an even number | 354 | # apparently OMAP3 ROMs require the vfat length to be an even number |
3065 | 183 | # of sectors (multiple of 1 KiB); decrease the length if it's odd, | 355 | # of sectors (multiple of 1 KiB); decrease the length if it's odd, |
3066 | 184 | # there should still be enough room | 356 | # there should still be enough room |
3067 | @@ -189,7 +361,7 @@ | |||
3068 | 189 | # instruct the use of all remaining space; XXX if we had some root size | 361 | # instruct the use of all remaining space; XXX if we had some root size |
3069 | 190 | # config, we could do something more sensible | 362 | # config, we could do something more sensible |
3070 | 191 | root_start, _root_end, _root_len = align_partition( | 363 | root_start, _root_end, _root_len = align_partition( |
3072 | 192 | boot_end + 1, ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) | 364 | boot_end + 1, cls.ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) |
3073 | 193 | 365 | ||
3074 | 194 | return '%s,%s,%s,*\n%s,,,-' % ( | 366 | return '%s,%s,%s,*\n%s,,,-' % ( |
3075 | 195 | boot_start, boot_len, partition_type, root_start) | 367 | boot_start, boot_len, partition_type, root_start) |
3076 | @@ -299,10 +471,12 @@ | |||
3077 | 299 | if cls.uboot_in_boot_part: | 471 | if cls.uboot_in_boot_part: |
3078 | 300 | assert cls.uboot_flavor is not None, ( | 472 | assert cls.uboot_flavor is not None, ( |
3079 | 301 | "uboot_in_boot_part is set but not uboot_flavor") | 473 | "uboot_in_boot_part is set but not uboot_flavor") |
3084 | 302 | uboot_bin = os.path.join(chroot_dir, 'usr', 'lib', 'u-boot', | 474 | with cls.hardwarepack_handler: |
3085 | 303 | cls.uboot_flavor, 'u-boot.bin') | 475 | uboot_bin = cls.get_file('u_boot', default=os.path.join( |
3086 | 304 | cmd_runner.run( | 476 | chroot_dir, 'usr', 'lib', 'u-boot', cls.uboot_flavor, |
3087 | 305 | ['cp', '-v', uboot_bin, boot_disk], as_root=True).wait() | 477 | 'u-boot.bin')) |
3088 | 478 | cmd_runner.run( | ||
3089 | 479 | ['cp', '-v', uboot_bin, boot_disk], as_root=True).wait() | ||
3090 | 306 | 480 | ||
3091 | 307 | cls.make_boot_files( | 481 | cls.make_boot_files( |
3092 | 308 | uboot_parts_dir, is_live, is_lowmem, consoles, chroot_dir, | 482 | uboot_parts_dir, is_live, is_lowmem, consoles, chroot_dir, |
3093 | @@ -337,9 +511,14 @@ | |||
3094 | 337 | "No kernel found matching %s for flavors %s" % ( | 511 | "No kernel found matching %s for flavors %s" % ( |
3095 | 338 | KERNEL_GLOB, " ".join(cls.kernel_flavors))) | 512 | KERNEL_GLOB, " ".join(cls.kernel_flavors))) |
3096 | 339 | 513 | ||
3097 | 514 | @classmethod | ||
3098 | 515 | def populate_raw_partition(cls, media, boot_dir): | ||
3099 | 516 | # Override in subclass if needed | ||
3100 | 517 | pass | ||
3101 | 518 | |||
3102 | 340 | 519 | ||
3103 | 341 | class OmapConfig(BoardConfig): | 520 | class OmapConfig(BoardConfig): |
3105 | 342 | kernel_flavors = ['linaro-omap4', 'linaro-omap', 'omap4'] | 521 | kernel_flavors = ['linaro-omap4', 'linaro-lt-omap', 'linaro-omap', 'omap4'] |
3106 | 343 | uboot_in_boot_part = True | 522 | uboot_in_boot_part = True |
3107 | 344 | 523 | ||
3108 | 345 | # XXX: Here we define these things as dynamic properties because our | 524 | # XXX: Here we define these things as dynamic properties because our |
3109 | @@ -471,8 +650,8 @@ | |||
3110 | 471 | 650 | ||
3111 | 472 | class Ux500Config(BoardConfig): | 651 | class Ux500Config(BoardConfig): |
3112 | 473 | serial_tty = 'ttyAMA2' | 652 | serial_tty = 'ttyAMA2' |
3115 | 474 | extra_serial_opts = 'console=tty0 console=%s,115200n8' % serial_tty | 653 | _extra_serial_opts = 'console=tty0 console=%s,115200n8' |
3116 | 475 | live_serial_opts = 'serialtty=%s' % serial_tty | 654 | _live_serial_opts = 'serialtty=%s' |
3117 | 476 | kernel_addr = '0x00100000' | 655 | kernel_addr = '0x00100000' |
3118 | 477 | initrd_addr = '0x08000000' | 656 | initrd_addr = '0x08000000' |
3119 | 478 | load_addr = '0x00008000' | 657 | load_addr = '0x00008000' |
3120 | @@ -485,6 +664,14 @@ | |||
3121 | 485 | 'hwmem=48M@302M mem=152M@360M') | 664 | 'hwmem=48M@302M mem=152M@360M') |
3122 | 486 | mmc_option = '1:1' | 665 | mmc_option = '1:1' |
3123 | 487 | 666 | ||
3124 | 667 | @classproperty | ||
3125 | 668 | def live_serial_opts(cls): | ||
3126 | 669 | return cls._live_serial_opts % cls.serial_tty | ||
3127 | 670 | |||
3128 | 671 | @classproperty | ||
3129 | 672 | def extra_serial_opts(cls): | ||
3130 | 673 | return cls._extra_serial_opts % cls.serial_tty | ||
3131 | 674 | |||
3132 | 488 | @classmethod | 675 | @classmethod |
3133 | 489 | def _make_boot_files(cls, boot_env, chroot_dir, boot_dir, | 676 | def _make_boot_files(cls, boot_env, chroot_dir, boot_dir, |
3134 | 490 | boot_device_or_file, k_img_data, i_img_data, | 677 | boot_device_or_file, k_img_data, i_img_data, |
3135 | @@ -517,7 +704,7 @@ | |||
3136 | 517 | and u-boot.''' | 704 | and u-boot.''' |
3137 | 518 | # Boot ROM looks for a boot table of contents (TOC) at 0x20000 | 705 | # Boot ROM looks for a boot table of contents (TOC) at 0x20000 |
3138 | 519 | # Actually, it first looks at address 0, but that's where l-m-c | 706 | # Actually, it first looks at address 0, but that's where l-m-c |
3140 | 520 | # puts the MBR, so the boot loader skips that address. | 707 | # puts the MBR, so the boot loader skips that address. |
3141 | 521 | supports_writing_to_mmc = False | 708 | supports_writing_to_mmc = False |
3142 | 522 | SNOWBALL_LOADER_START_S = (128 * 1024) / SECTOR_SIZE | 709 | SNOWBALL_LOADER_START_S = (128 * 1024) / SECTOR_SIZE |
3143 | 523 | SNOWBALL_STARTUP_FILES_CONFIG = 'startfiles.cfg' | 710 | SNOWBALL_STARTUP_FILES_CONFIG = 'startfiles.cfg' |
3144 | @@ -537,20 +724,20 @@ | |||
3145 | 537 | This is done since the boot rom always boots off the internal memory; | 724 | This is done since the boot rom always boots off the internal memory; |
3146 | 538 | there simply is no point to having a loader partition on SD card. | 725 | there simply is no point to having a loader partition on SD card. |
3147 | 539 | """ | 726 | """ |
3149 | 540 | # boot ROM expects bootloader at 0x20000, which is sector 0x100 | 727 | # boot ROM expects bootloader at 0x20000, which is sector 0x100 |
3150 | 541 | # with the usual SECTOR_SIZE of 0x200. | 728 | # with the usual SECTOR_SIZE of 0x200. |
3151 | 542 | # (sector 0 is MBR / partition table) | 729 | # (sector 0 is MBR / partition table) |
3152 | 543 | loader_start, loader_end, loader_len = align_partition( | 730 | loader_start, loader_end, loader_len = align_partition( |
3155 | 544 | SnowballEmmcConfig.SNOWBALL_LOADER_START_S, | 731 | SnowballEmmcConfig.SNOWBALL_LOADER_START_S, |
3156 | 545 | LOADER_MIN_SIZE_S, 1, PART_ALIGN_S) | 732 | cls.LOADER_MIN_SIZE_S, 1, PART_ALIGN_S) |
3157 | 546 | 733 | ||
3158 | 547 | boot_start, boot_end, boot_len = align_partition( | 734 | boot_start, boot_end, boot_len = align_partition( |
3160 | 548 | loader_end + 1, BOOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) | 735 | loader_end + 1, cls.BOOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) |
3161 | 549 | # we ignore _root_end / _root_len and return an sfdisk command to | 736 | # we ignore _root_end / _root_len and return an sfdisk command to |
3162 | 550 | # instruct the use of all remaining space; XXX if we had some root size | 737 | # instruct the use of all remaining space; XXX if we had some root size |
3163 | 551 | # config, we could do something more sensible | 738 | # config, we could do something more sensible |
3164 | 552 | root_start, _root_end, _root_len = align_partition( | 739 | root_start, _root_end, _root_len = align_partition( |
3166 | 553 | boot_end + 1, ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) | 740 | boot_end + 1, cls.ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) |
3167 | 554 | 741 | ||
3168 | 555 | return '%s,%s,0xDA\n%s,%s,0x0C,*\n%s,,,-' % ( | 742 | return '%s,%s,0xDA\n%s,%s,0x0C,*\n%s,,,-' % ( |
3169 | 556 | loader_start, loader_len, boot_start, boot_len, root_start) | 743 | loader_start, loader_len, boot_start, boot_len, root_start) |
3170 | @@ -562,15 +749,22 @@ | |||
3171 | 562 | make_uImage(cls.load_addr, k_img_data, boot_dir) | 749 | make_uImage(cls.load_addr, k_img_data, boot_dir) |
3172 | 563 | boot_script_path = os.path.join(boot_dir, cls.boot_script) | 750 | boot_script_path = os.path.join(boot_dir, cls.boot_script) |
3173 | 564 | make_boot_script(boot_env, boot_script_path) | 751 | make_boot_script(boot_env, boot_script_path) |
3174 | 752 | cls.populate_raw_partition(chroot_dir, boot_device_or_file) | ||
3175 | 753 | |||
3176 | 754 | @classmethod | ||
3177 | 755 | def populate_raw_partition(cls, chroot_dir, boot_device_or_file): | ||
3178 | 756 | # Populate created raw partition with TOC and startup files. | ||
3179 | 757 | config_files_path = os.path.join(chroot_dir, 'boot') | ||
3180 | 565 | _, toc_filename = tempfile.mkstemp() | 758 | _, toc_filename = tempfile.mkstemp() |
3181 | 566 | atexit.register(os.unlink, toc_filename) | ||
3182 | 567 | config_files_path = os.path.join(chroot_dir, 'boot') | ||
3183 | 568 | new_files = cls.get_file_info(config_files_path) | 759 | new_files = cls.get_file_info(config_files_path) |
3184 | 569 | with open(toc_filename, 'wb') as toc: | 760 | with open(toc_filename, 'wb') as toc: |
3185 | 570 | cls.create_toc(toc, new_files) | 761 | cls.create_toc(toc, new_files) |
3186 | 571 | cls.install_snowball_boot_loader(toc_filename, new_files, | 762 | cls.install_snowball_boot_loader(toc_filename, new_files, |
3187 | 572 | boot_device_or_file, | 763 | boot_device_or_file, |
3188 | 573 | cls.SNOWBALL_LOADER_START_S) | 764 | cls.SNOWBALL_LOADER_START_S) |
3189 | 765 | cls.delete_file(toc_filename) | ||
3190 | 766 | cls.delete_file(os.path.join(config_files_path, | ||
3191 | 767 | cls.SNOWBALL_STARTUP_FILES_CONFIG)) | ||
3192 | 574 | 768 | ||
3193 | 575 | @classmethod | 769 | @classmethod |
3194 | 576 | def install_snowball_boot_loader(cls, toc_file_name, files, | 770 | def install_snowball_boot_loader(cls, toc_file_name, files, |
3195 | @@ -584,13 +778,21 @@ | |||
3196 | 584 | for file in files: | 778 | for file in files: |
3197 | 585 | # XXX We need checks that these files do not overwrite each | 779 | # XXX We need checks that these files do not overwrite each |
3198 | 586 | # other. This code assumes that offset and file sizes are ok. | 780 | # other. This code assumes that offset and file sizes are ok. |
3199 | 781 | filename = file['filename'] | ||
3200 | 587 | if (file['offset'] % SECTOR_SIZE) != 0: | 782 | if (file['offset'] % SECTOR_SIZE) != 0: |
3201 | 588 | seek_bytes = start_sector * SECTOR_SIZE + file['offset'] | 783 | seek_bytes = start_sector * SECTOR_SIZE + file['offset'] |
3203 | 589 | _dd(file['filename'], boot_device_or_file, block_size=1, | 784 | _dd(filename, boot_device_or_file, block_size=1, |
3204 | 590 | seek=seek_bytes) | 785 | seek=seek_bytes) |
3205 | 591 | else: | 786 | else: |
3208 | 592 | seek_sectors = start_sector + file['offset']/SECTOR_SIZE | 787 | seek_sectors = start_sector + file['offset'] / SECTOR_SIZE |
3209 | 593 | _dd(file['filename'], boot_device_or_file, seek=seek_sectors) | 788 | _dd(filename, boot_device_or_file, seek=seek_sectors) |
3210 | 789 | cls.delete_file(filename) | ||
3211 | 790 | |||
3212 | 791 | @classmethod | ||
3213 | 792 | def delete_file(cls, file_path): | ||
3214 | 793 | cmd = ["rm", "%s" % file_path] | ||
3215 | 794 | proc = cmd_runner.run(cmd, as_root=True) | ||
3216 | 795 | proc.wait() | ||
3217 | 594 | 796 | ||
3218 | 595 | @classmethod | 797 | @classmethod |
3219 | 596 | def create_toc(cls, f, files): | 798 | def create_toc(cls, f, files): |
3220 | @@ -605,6 +807,8 @@ | |||
3221 | 605 | # i; int; load_address, | 807 | # i; int; load_address, |
3222 | 606 | # 12s; string of char; name | 808 | # 12s; string of char; name |
3223 | 607 | # http://igloocommunity.org/support/index.php/ConfigPartitionOverview | 809 | # http://igloocommunity.org/support/index.php/ConfigPartitionOverview |
3224 | 810 | assert len(file['section_name']) < 12, ( | ||
3225 | 811 | "Section name %s too large" % file['section_name']) | ||
3226 | 608 | flags = 0 | 812 | flags = 0 |
3227 | 609 | load_adress = file['align'] | 813 | load_adress = file['align'] |
3228 | 610 | data = struct.pack('<IIIii12s', file['offset'], file['size'], | 814 | data = struct.pack('<IIIii12s', file['offset'], file['size'], |
3229 | @@ -642,12 +846,20 @@ | |||
3230 | 642 | 846 | ||
3231 | 643 | class Mx5Config(BoardConfig): | 847 | class Mx5Config(BoardConfig): |
3232 | 644 | serial_tty = 'ttymxc0' | 848 | serial_tty = 'ttymxc0' |
3235 | 645 | extra_serial_opts = 'console=tty0 console=%s,115200n8' % serial_tty | 849 | _extra_serial_opts = 'console=tty0 console=%s,115200n8' |
3236 | 646 | live_serial_opts = 'serialtty=%s' % serial_tty | 850 | _live_serial_opts = 'serialtty=%s' |
3237 | 647 | boot_script = 'boot.scr' | 851 | boot_script = 'boot.scr' |
3238 | 648 | mmc_part_offset = 1 | 852 | mmc_part_offset = 1 |
3239 | 649 | mmc_option = '0:2' | 853 | mmc_option = '0:2' |
3240 | 650 | 854 | ||
3241 | 855 | @classproperty | ||
3242 | 856 | def live_serial_opts(cls): | ||
3243 | 857 | return cls._live_serial_opts % cls.serial_tty | ||
3244 | 858 | |||
3245 | 859 | @classproperty | ||
3246 | 860 | def extra_serial_opts(cls): | ||
3247 | 861 | return cls._extra_serial_opts % cls.serial_tty | ||
3248 | 862 | |||
3249 | 651 | @classmethod | 863 | @classmethod |
3250 | 652 | def get_sfdisk_cmd(cls, should_align_boot_part=None): | 864 | def get_sfdisk_cmd(cls, should_align_boot_part=None): |
3251 | 653 | """Return the sfdisk command to partition the media. | 865 | """Return the sfdisk command to partition the media. |
3252 | @@ -663,15 +875,15 @@ | |||
3253 | 663 | # onwards, so it's safer to just start at the first sector, sector 1 | 875 | # onwards, so it's safer to just start at the first sector, sector 1 |
3254 | 664 | # (sector 0 is MBR / partition table) | 876 | # (sector 0 is MBR / partition table) |
3255 | 665 | loader_start, loader_end, loader_len = align_partition( | 877 | loader_start, loader_end, loader_len = align_partition( |
3257 | 666 | 1, LOADER_MIN_SIZE_S, 1, PART_ALIGN_S) | 878 | 1, cls.LOADER_MIN_SIZE_S, 1, PART_ALIGN_S) |
3258 | 667 | 879 | ||
3259 | 668 | boot_start, boot_end, boot_len = align_partition( | 880 | boot_start, boot_end, boot_len = align_partition( |
3261 | 669 | loader_end + 1, BOOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) | 881 | loader_end + 1, cls.BOOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) |
3262 | 670 | # we ignore _root_end / _root_len and return a sfdisk command to | 882 | # we ignore _root_end / _root_len and return a sfdisk command to |
3263 | 671 | # instruct the use of all remaining space; XXX if we had some root size | 883 | # instruct the use of all remaining space; XXX if we had some root size |
3264 | 672 | # config, we could do something more sensible | 884 | # config, we could do something more sensible |
3265 | 673 | root_start, _root_end, _root_len = align_partition( | 885 | root_start, _root_end, _root_len = align_partition( |
3267 | 674 | boot_end + 1, ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) | 886 | boot_end + 1, cls.ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) |
3268 | 675 | 887 | ||
3269 | 676 | return '%s,%s,0xDA\n%s,%s,0x0C,*\n%s,,,-' % ( | 888 | return '%s,%s,0xDA\n%s,%s,0x0C,*\n%s,,,-' % ( |
3270 | 677 | loader_start, loader_len, boot_start, boot_len, root_start) | 889 | loader_start, loader_len, boot_start, boot_len, root_start) |
3271 | @@ -680,9 +892,12 @@ | |||
3272 | 680 | def _make_boot_files(cls, boot_env, chroot_dir, boot_dir, | 892 | def _make_boot_files(cls, boot_env, chroot_dir, boot_dir, |
3273 | 681 | boot_device_or_file, k_img_data, i_img_data, | 893 | boot_device_or_file, k_img_data, i_img_data, |
3274 | 682 | d_img_data): | 894 | d_img_data): |
3278 | 683 | uboot_file = os.path.join( | 895 | with cls.hardwarepack_handler: |
3279 | 684 | chroot_dir, 'usr', 'lib', 'u-boot', cls.uboot_flavor, 'u-boot.imx') | 896 | uboot_file = cls.get_file('u_boot', default=os.path.join( |
3280 | 685 | install_mx5_boot_loader(uboot_file, boot_device_or_file) | 897 | chroot_dir, 'usr', 'lib', 'u-boot', cls.uboot_flavor, |
3281 | 898 | 'u-boot.imx')) | ||
3282 | 899 | install_mx5_boot_loader(uboot_file, boot_device_or_file, | ||
3283 | 900 | cls.LOADER_MIN_SIZE_S) | ||
3284 | 686 | make_uImage(cls.load_addr, k_img_data, boot_dir) | 901 | make_uImage(cls.load_addr, k_img_data, boot_dir) |
3285 | 687 | make_uInitrd(i_img_data, boot_dir) | 902 | make_uInitrd(i_img_data, boot_dir) |
3286 | 688 | make_dtb(d_img_data, boot_dir) | 903 | make_dtb(d_img_data, boot_dir) |
3287 | @@ -730,8 +945,8 @@ | |||
3288 | 730 | uboot_flavor = 'ca9x4_ct_vxp' | 945 | uboot_flavor = 'ca9x4_ct_vxp' |
3289 | 731 | uboot_in_boot_part = True | 946 | uboot_in_boot_part = True |
3290 | 732 | serial_tty = 'ttyAMA0' | 947 | serial_tty = 'ttyAMA0' |
3293 | 733 | extra_serial_opts = 'console=tty0 console=%s,38400n8' % serial_tty | 948 | _extra_serial_opts = 'console=tty0 console=%s,38400n8' |
3294 | 734 | live_serial_opts = 'serialtty=%s' % serial_tty | 949 | _live_serial_opts = 'serialtty=%s' |
3295 | 735 | kernel_addr = '0x60008000' | 950 | kernel_addr = '0x60008000' |
3296 | 736 | initrd_addr = '0x81000000' | 951 | initrd_addr = '0x81000000' |
3297 | 737 | load_addr = kernel_addr | 952 | load_addr = kernel_addr |
3298 | @@ -741,6 +956,14 @@ | |||
3299 | 741 | # only allows for FAT16 | 956 | # only allows for FAT16 |
3300 | 742 | fat_size = 16 | 957 | fat_size = 16 |
3301 | 743 | 958 | ||
3302 | 959 | @classproperty | ||
3303 | 960 | def live_serial_opts(cls): | ||
3304 | 961 | return cls._live_serial_opts % cls.serial_tty | ||
3305 | 962 | |||
3306 | 963 | @classproperty | ||
3307 | 964 | def extra_serial_opts(cls): | ||
3308 | 965 | return cls._extra_serial_opts % cls.serial_tty | ||
3309 | 966 | |||
3310 | 744 | @classmethod | 967 | @classmethod |
3311 | 745 | def _make_boot_files(cls, boot_env, chroot_dir, boot_dir, | 968 | def _make_boot_files(cls, boot_env, chroot_dir, boot_dir, |
3312 | 746 | boot_device_or_file, k_img_data, i_img_data, | 969 | boot_device_or_file, k_img_data, i_img_data, |
3313 | @@ -748,17 +971,10 @@ | |||
3314 | 748 | make_uImage(cls.load_addr, k_img_data, boot_dir) | 971 | make_uImage(cls.load_addr, k_img_data, boot_dir) |
3315 | 749 | make_uInitrd(i_img_data, boot_dir) | 972 | make_uInitrd(i_img_data, boot_dir) |
3316 | 750 | 973 | ||
3328 | 751 | class SMDKV310Config(BoardConfig): | 974 | class SamsungConfig(BoardConfig): |
3329 | 752 | uboot_flavor = 'smdkv310' | 975 | @classproperty |
3330 | 753 | serial_tty = 'ttySAC1' | 976 | def extra_serial_opts(cls): |
3331 | 754 | extra_serial_opts = 'console=%s,115200n8' % serial_tty | 977 | return cls._extra_serial_opts % cls.serial_tty |
3321 | 755 | kernel_addr = '0x40007000' | ||
3322 | 756 | initrd_addr = '0x42000000' | ||
3323 | 757 | load_addr = '0x40008000' | ||
3324 | 758 | kernel_flavors = ['s5pv310'] | ||
3325 | 759 | boot_script = 'boot.scr' | ||
3326 | 760 | mmc_part_offset = 1 | ||
3327 | 761 | mmc_option = '0:2' | ||
3332 | 762 | 978 | ||
3333 | 763 | @classmethod | 979 | @classmethod |
3334 | 764 | def get_sfdisk_cmd(cls, should_align_boot_part=False): | 980 | def get_sfdisk_cmd(cls, should_align_boot_part=False): |
3335 | @@ -773,46 +989,23 @@ | |||
3336 | 773 | 989 | ||
3337 | 774 | # FAT boot partition | 990 | # FAT boot partition |
3338 | 775 | boot_start, boot_end, boot_len = align_partition( | 991 | boot_start, boot_end, boot_len = align_partition( |
3340 | 776 | loaders_end + 1, BOOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) | 992 | loaders_end + 1, cls.BOOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) |
3341 | 777 | 993 | ||
3342 | 778 | # root partition | 994 | # root partition |
3343 | 779 | # we ignore _root_end / _root_len and return a sfdisk command to | 995 | # we ignore _root_end / _root_len and return a sfdisk command to |
3344 | 780 | # instruct the use of all remaining space; XXX if we had some root size | 996 | # instruct the use of all remaining space; XXX if we had some root size |
3345 | 781 | # config, we could do something more sensible | 997 | # config, we could do something more sensible |
3346 | 782 | root_start, _root_end, _root_len = align_partition( | 998 | root_start, _root_end, _root_len = align_partition( |
3348 | 783 | boot_end + 1, ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) | 999 | boot_end + 1, cls.ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) |
3349 | 784 | 1000 | ||
3350 | 785 | return '%s,%s,0xDA\n%s,%s,0x0C,*\n%s,,,-' % ( | 1001 | return '%s,%s,0xDA\n%s,%s,0x0C,*\n%s,,,-' % ( |
3351 | 786 | loaders_start, loaders_len, boot_start, boot_len, root_start) | 1002 | loaders_start, loaders_len, boot_start, boot_len, root_start) |
3352 | 787 | 1003 | ||
3353 | 788 | @classmethod | 1004 | @classmethod |
3354 | 789 | def _get_boot_env(cls, is_live, is_lowmem, consoles, rootfs_uuid, | ||
3355 | 790 | d_img_data): | ||
3356 | 791 | boot_env = super(SMDKV310Config, cls)._get_boot_env( | ||
3357 | 792 | is_live, is_lowmem, consoles, rootfs_uuid, d_img_data) | ||
3358 | 793 | |||
3359 | 794 | boot_env["ethact"] = "smc911x-0" | ||
3360 | 795 | boot_env["ethaddr"] = "00:40:5c:26:0a:5b" | ||
3361 | 796 | |||
3362 | 797 | return boot_env | ||
3363 | 798 | |||
3364 | 799 | @classmethod | ||
3365 | 800 | def _make_boot_files(cls, boot_env, chroot_dir, boot_dir, | 1005 | def _make_boot_files(cls, boot_env, chroot_dir, boot_dir, |
3366 | 801 | boot_device_or_file, k_img_data, i_img_data, | 1006 | boot_device_or_file, k_img_data, i_img_data, |
3367 | 802 | d_img_data): | 1007 | d_img_data): |
3381 | 803 | spl_file = os.path.join( | 1008 | cls.install_samsung_boot_loader(chroot_dir, boot_device_or_file) |
3369 | 804 | chroot_dir, 'usr', 'lib', 'u-boot', cls.uboot_flavor, | ||
3370 | 805 | 'v310_mmc_spl.bin') | ||
3371 | 806 | # XXX need to check that the length of spl_file is smaller than | ||
3372 | 807 | # SAMSUNG_V310_BL1_LEN | ||
3373 | 808 | _dd(spl_file, boot_device_or_file, seek=SAMSUNG_V310_BL1_START) | ||
3374 | 809 | |||
3375 | 810 | uboot_file = os.path.join( | ||
3376 | 811 | chroot_dir, 'usr', 'lib', 'u-boot', cls.uboot_flavor, 'u-boot.bin') | ||
3377 | 812 | # XXX need to check that the length of uboot_file is smaller than | ||
3378 | 813 | # SAMSUNG_V310_BL2_LEN | ||
3379 | 814 | _dd(uboot_file, boot_device_or_file, seek=SAMSUNG_V310_BL2_START) | ||
3380 | 815 | |||
3382 | 816 | env_size = SAMSUNG_V310_ENV_LEN * SECTOR_SIZE | 1009 | env_size = SAMSUNG_V310_ENV_LEN * SECTOR_SIZE |
3383 | 817 | env_file = make_flashable_env(boot_env, env_size) | 1010 | env_file = make_flashable_env(boot_env, env_size) |
3384 | 818 | _dd(env_file, boot_device_or_file, seek=SAMSUNG_V310_ENV_START) | 1011 | _dd(env_file, boot_device_or_file, seek=SAMSUNG_V310_ENV_START) |
3385 | @@ -825,6 +1018,84 @@ | |||
3386 | 825 | boot_script_path = os.path.join(boot_dir, cls.boot_script) | 1018 | boot_script_path = os.path.join(boot_dir, cls.boot_script) |
3387 | 826 | make_boot_script(boot_env, boot_script_path) | 1019 | make_boot_script(boot_env, boot_script_path) |
3388 | 827 | 1020 | ||
3389 | 1021 | @classmethod | ||
3390 | 1022 | def _get_samsung_spl(cls, chroot_dir): | ||
3391 | 1023 | spl_dir = os.path.join( | ||
3392 | 1024 | chroot_dir, 'usr', 'lib', 'u-boot', cls.uboot_flavor) | ||
3393 | 1025 | old_spl_path = os.path.join(spl_dir, 'v310_mmc_spl.bin') | ||
3394 | 1026 | new_spl_path = os.path.join(spl_dir, 'u-boot-mmc-spl.bin') | ||
3395 | 1027 | |||
3396 | 1028 | spl_file = old_spl_path | ||
3397 | 1029 | # The new upstream u-boot filename has changed | ||
3398 | 1030 | if not os.path.exists(spl_file): | ||
3399 | 1031 | spl_file = new_spl_path | ||
3400 | 1032 | |||
3401 | 1033 | if not os.path.exists(spl_file): | ||
3402 | 1034 | # missing SPL loader | ||
3403 | 1035 | raise AssertionError("Couldn't find the SPL file, tried %s and %s" | ||
3404 | 1036 | % (old_spl_path, new_spl_path)) | ||
3405 | 1037 | return spl_file | ||
3406 | 1038 | |||
3407 | 1039 | @classmethod | ||
3408 | 1040 | def _get_samsung_uboot(cls, chroot_dir): | ||
3409 | 1041 | uboot_file = os.path.join( | ||
3410 | 1042 | chroot_dir, 'usr', 'lib', 'u-boot', cls.uboot_flavor, | ||
3411 | 1043 | 'u-boot.bin') | ||
3412 | 1044 | return uboot_file | ||
3413 | 1045 | |||
3414 | 1046 | @classmethod | ||
3415 | 1047 | def install_samsung_boot_loader(cls, chroot_dir, boot_device_or_file): | ||
3416 | 1048 | spl_file = cls._get_samsung_spl(chroot_dir) | ||
3417 | 1049 | bl1_max_size = SAMSUNG_V310_BL1_LEN * SECTOR_SIZE | ||
3418 | 1050 | assert os.path.getsize(spl_file) <= bl1_max_size, ( | ||
3419 | 1051 | "%s is larger than %s" % (spl_file, bl1_max_size)) | ||
3420 | 1052 | _dd(spl_file, boot_device_or_file, seek=SAMSUNG_V310_BL1_START) | ||
3421 | 1053 | |||
3422 | 1054 | with cls.hardwarepack_handler: | ||
3423 | 1055 | uboot_file = cls.get_file( | ||
3424 | 1056 | 'u_boot', default=cls._get_samsung_uboot(chroot_dir)) | ||
3425 | 1057 | bl2_max_size = SAMSUNG_V310_BL2_LEN * SECTOR_SIZE | ||
3426 | 1058 | assert os.path.getsize(uboot_file) <= bl2_max_size, ( | ||
3427 | 1059 | "%s is larger than %s" % (uboot_file, bl2_max_size)) | ||
3428 | 1060 | _dd(uboot_file, boot_device_or_file, seek=SAMSUNG_V310_BL2_START) | ||
3429 | 1061 | |||
3430 | 1062 | |||
3431 | 1063 | class SMDKV310Config(SamsungConfig): | ||
3432 | 1064 | uboot_flavor = 'smdkv310' | ||
3433 | 1065 | serial_tty = 'ttySAC1' | ||
3434 | 1066 | _extra_serial_opts = 'console=%s,115200n8' | ||
3435 | 1067 | kernel_addr = '0x40007000' | ||
3436 | 1068 | initrd_addr = '0x42000000' | ||
3437 | 1069 | load_addr = '0x40008000' | ||
3438 | 1070 | kernel_flavors = ['s5pv310'] | ||
3439 | 1071 | boot_script = 'boot.scr' | ||
3440 | 1072 | mmc_part_offset = 1 | ||
3441 | 1073 | mmc_option = '0:2' | ||
3442 | 1074 | |||
3443 | 1075 | @classmethod | ||
3444 | 1076 | def _get_boot_env(cls, is_live, is_lowmem, consoles, rootfs_uuid, | ||
3445 | 1077 | d_img_data): | ||
3446 | 1078 | boot_env = super(SamsungConfig, cls)._get_boot_env( | ||
3447 | 1079 | is_live, is_lowmem, consoles, rootfs_uuid, d_img_data) | ||
3448 | 1080 | |||
3449 | 1081 | boot_env["ethact"] = "smc911x-0" | ||
3450 | 1082 | boot_env["ethaddr"] = "00:40:5c:26:0a:5b" | ||
3451 | 1083 | |||
3452 | 1084 | return boot_env | ||
3453 | 1085 | |||
3454 | 1086 | |||
3455 | 1087 | class OrigenConfig(SamsungConfig): | ||
3456 | 1088 | uboot_flavor = 'origen' | ||
3457 | 1089 | serial_tty = 'ttySAC2' | ||
3458 | 1090 | _extra_serial_opts = 'console=%s,115200n8' | ||
3459 | 1091 | kernel_addr = '0x40007000' | ||
3460 | 1092 | initrd_addr = '0x42000000' | ||
3461 | 1093 | load_addr = '0x40008000' | ||
3462 | 1094 | kernel_flavors = ['origen'] | ||
3463 | 1095 | boot_script = 'boot.scr' | ||
3464 | 1096 | mmc_part_offset = 1 | ||
3465 | 1097 | mmc_option = '0:2' | ||
3466 | 1098 | |||
3467 | 828 | 1099 | ||
3468 | 829 | board_configs = { | 1100 | board_configs = { |
3469 | 830 | 'beagle': BeagleConfig, | 1101 | 'beagle': BeagleConfig, |
3470 | @@ -837,9 +1108,10 @@ | |||
3471 | 837 | 'efikamx': EfikamxConfig, | 1108 | 'efikamx': EfikamxConfig, |
3472 | 838 | 'efikasb': EfikasbConfig, | 1109 | 'efikasb': EfikasbConfig, |
3473 | 839 | 'mx51evk': Mx51evkConfig, | 1110 | 'mx51evk': Mx51evkConfig, |
3475 | 840 | 'mx53loco' : Mx53LoCoConfig, | 1111 | 'mx53loco': Mx53LoCoConfig, |
3476 | 841 | 'overo': OveroConfig, | 1112 | 'overo': OveroConfig, |
3477 | 842 | 'smdkv310': SMDKV310Config, | 1113 | 'smdkv310': SMDKV310Config, |
3478 | 1114 | 'origen': OrigenConfig, | ||
3479 | 843 | } | 1115 | } |
3480 | 844 | 1116 | ||
3481 | 845 | 1117 | ||
3482 | @@ -961,13 +1233,13 @@ | |||
3483 | 961 | return tmpfile | 1233 | return tmpfile |
3484 | 962 | 1234 | ||
3485 | 963 | 1235 | ||
3487 | 964 | def install_mx5_boot_loader(imx_file, boot_device_or_file): | 1236 | def install_mx5_boot_loader(imx_file, boot_device_or_file, loader_min_size): |
3488 | 965 | # bootloader partition starts at +1s but we write the file at +2s, so we | 1237 | # bootloader partition starts at +1s but we write the file at +2s, so we |
3489 | 966 | # need to check that the bootloader partition minus 1s is at least as large | 1238 | # need to check that the bootloader partition minus 1s is at least as large |
3490 | 967 | # as the u-boot binary; note that the real bootloader partition might be | 1239 | # as the u-boot binary; note that the real bootloader partition might be |
3491 | 968 | # larger than LOADER_MIN_SIZE_S, but if u-boot is larger it's a sign we | 1240 | # larger than LOADER_MIN_SIZE_S, but if u-boot is larger it's a sign we |
3492 | 969 | # need to bump LOADER_MIN_SIZE_S | 1241 | # need to bump LOADER_MIN_SIZE_S |
3494 | 970 | max_size = (LOADER_MIN_SIZE_S - 1) * SECTOR_SIZE | 1242 | max_size = (loader_min_size - 1) * SECTOR_SIZE |
3495 | 971 | assert os.path.getsize(imx_file) <= max_size, ( | 1243 | assert os.path.getsize(imx_file) <= max_size, ( |
3496 | 972 | "%s is larger than guaranteed bootloader partition size" % imx_file) | 1244 | "%s is larger than guaranteed bootloader partition size" % imx_file) |
3497 | 973 | _dd(imx_file, boot_device_or_file, seek=2) | 1245 | _dd(imx_file, boot_device_or_file, seek=2) |
3498 | @@ -1008,4 +1280,3 @@ | |||
3499 | 1008 | ["cp", "-v", boot_script_path, "%s/boot.ini" % boot_disk], | 1280 | ["cp", "-v", boot_script_path, "%s/boot.ini" % boot_disk], |
3500 | 1009 | as_root=True) | 1281 | as_root=True) |
3501 | 1010 | proc.wait() | 1282 | proc.wait() |
3502 | 1011 | |||
3503 | 1012 | 1283 | ||
3504 | === modified file 'linaro_image_tools/media_create/partitions.py' | |||
3505 | --- linaro_image_tools/media_create/partitions.py 2011-05-31 06:45:22 +0000 | |||
3506 | +++ linaro_image_tools/media_create/partitions.py 2011-07-18 14:39:34 +0000 | |||
3507 | @@ -3,7 +3,7 @@ | |||
3508 | 3 | # Author: Guilherme Salgado <guilherme.salgado@linaro.org> | 3 | # Author: Guilherme Salgado <guilherme.salgado@linaro.org> |
3509 | 4 | # | 4 | # |
3510 | 5 | # This file is part of Linaro Image Tools. | 5 | # This file is part of Linaro Image Tools. |
3512 | 6 | # | 6 | # |
3513 | 7 | # Linaro Image Tools is free software: you can redistribute it and/or modify | 7 | # Linaro Image Tools is free software: you can redistribute it and/or modify |
3514 | 8 | # it under the terms of the GNU General Public License as published by | 8 | # it under the terms of the GNU General Public License as published by |
3515 | 9 | # the Free Software Foundation, either version 3 of the License, or | 9 | # the Free Software Foundation, either version 3 of the License, or |
3516 | @@ -28,6 +28,7 @@ | |||
3517 | 28 | Device, | 28 | Device, |
3518 | 29 | Disk, | 29 | Disk, |
3519 | 30 | PARTITION_NORMAL, | 30 | PARTITION_NORMAL, |
3520 | 31 | PARTITION_EXTENDED, | ||
3521 | 31 | ) | 32 | ) |
3522 | 32 | 33 | ||
3523 | 33 | from linaro_image_tools import cmd_runner | 34 | from linaro_image_tools import cmd_runner |
3524 | @@ -71,9 +72,8 @@ | |||
3525 | 71 | bootfs = partitions[0] | 72 | bootfs = partitions[0] |
3526 | 72 | system = partitions[1] | 73 | system = partitions[1] |
3527 | 73 | cache = partitions[2] | 74 | cache = partitions[2] |
3531 | 74 | data = partitions[4] | 75 | data = partitions[3] |
3532 | 75 | sdcard = partitions[5] | 76 | sdcard = partitions[4] |
3530 | 76 | |||
3533 | 77 | 77 | ||
3534 | 78 | print "\nFormating boot partition\n" | 78 | print "\nFormating boot partition\n" |
3535 | 79 | proc = cmd_runner.run( | 79 | proc = cmd_runner.run( |
3536 | @@ -98,6 +98,7 @@ | |||
3537 | 98 | 98 | ||
3538 | 99 | return bootfs, system, cache, data, sdcard | 99 | return bootfs, system, cache, data, sdcard |
3539 | 100 | 100 | ||
3540 | 101 | |||
3541 | 101 | # I wonder if it'd make sense to convert this into a small shim which calls | 102 | # I wonder if it'd make sense to convert this into a small shim which calls |
3542 | 102 | # the appropriate function for the given type of device? I think it's still | 103 | # the appropriate function for the given type of device? I think it's still |
3543 | 103 | # small enough that there's not much benefit in doing that, but if it grows we | 104 | # small enough that there's not much benefit in doing that, but if it grows we |
3544 | @@ -296,18 +297,28 @@ | |||
3545 | 296 | # Here we can use parted.Device to read the partitions because we're | 297 | # Here we can use parted.Device to read the partitions because we're |
3546 | 297 | # reading from a regular file rather than a block device. If it was a | 298 | # reading from a regular file rather than a block device. If it was a |
3547 | 298 | # block device we'd need root rights. | 299 | # block device we'd need root rights. |
3548 | 300 | vfat_partition = None | ||
3549 | 299 | disk = Disk(Device(image_file)) | 301 | disk = Disk(Device(image_file)) |
3550 | 300 | partition_info = [] | 302 | partition_info = [] |
3551 | 301 | for partition in disk.partitions: | 303 | for partition in disk.partitions: |
3555 | 302 | geometry = partition.geometry | 304 | # Will ignore any partitions before boot and of type EXTENDED |
3556 | 303 | partition_info.append((geometry.start * SECTOR_SIZE, | 305 | if 'boot' in partition.getFlagsAsString(): |
3557 | 304 | geometry.length * SECTOR_SIZE)) | 306 | vfat_partition = partition |
3558 | 307 | geometry = partition.geometry | ||
3559 | 308 | partition_info.append((geometry.start * SECTOR_SIZE, | ||
3560 | 309 | geometry.length * SECTOR_SIZE)) | ||
3561 | 310 | elif (vfat_partition is not None and | ||
3562 | 311 | partition.type != PARTITION_EXTENDED): | ||
3563 | 312 | geometry = partition.geometry | ||
3564 | 313 | partition_info.append((geometry.start * SECTOR_SIZE, | ||
3565 | 314 | geometry.length * SECTOR_SIZE)) | ||
3566 | 305 | # NB: don't use vfat_partition.nextPartition() as that might return | 315 | # NB: don't use vfat_partition.nextPartition() as that might return |
3567 | 306 | # a partition of type PARTITION_FREESPACE; it's much easier to | 316 | # a partition of type PARTITION_FREESPACE; it's much easier to |
3568 | 307 | # iterate disk.partitions which only returns | 317 | # iterate disk.partitions which only returns |
3569 | 308 | # parted.PARTITION_NORMAL partitions | 318 | # parted.PARTITION_NORMAL partitions |
3572 | 309 | 319 | assert vfat_partition is not None, ( | |
3573 | 310 | assert len(partition_info) == 6 | 320 | "Couldn't find boot partition on %s" % image_file) |
3574 | 321 | assert len(partition_info) == 5 | ||
3575 | 311 | return partition_info | 322 | return partition_info |
3576 | 312 | 323 | ||
3577 | 313 | 324 | ||
3578 | @@ -347,6 +358,7 @@ | |||
3579 | 347 | return boot_partition, system_partition, cache_partition, \ | 358 | return boot_partition, system_partition, cache_partition, \ |
3580 | 348 | data_partition, sdcard_partition | 359 | data_partition, sdcard_partition |
3581 | 349 | 360 | ||
3582 | 361 | |||
3583 | 350 | def get_boot_and_root_partitions_for_media(media, board_config): | 362 | def get_boot_and_root_partitions_for_media(media, board_config): |
3584 | 351 | """Return the device files for the boot and root partitions of media. | 363 | """Return the device files for the boot and root partitions of media. |
3585 | 352 | 364 | ||
3586 | 353 | 365 | ||
3587 | === modified file 'linaro_image_tools/media_create/rootfs.py' | |||
3588 | --- linaro_image_tools/media_create/rootfs.py 2011-04-05 09:26:47 +0000 | |||
3589 | +++ linaro_image_tools/media_create/rootfs.py 2011-07-18 14:39:34 +0000 | |||
3590 | @@ -19,6 +19,7 @@ | |||
3591 | 19 | 19 | ||
3592 | 20 | import glob | 20 | import glob |
3593 | 21 | import os | 21 | import os |
3594 | 22 | import subprocess | ||
3595 | 22 | import tempfile | 23 | import tempfile |
3596 | 23 | 24 | ||
3597 | 24 | from linaro_image_tools import cmd_runner | 25 | from linaro_image_tools import cmd_runner |
3598 | @@ -107,13 +108,26 @@ | |||
3599 | 107 | flash_kernel, "UBOOT_PART=%s" % target_boot_dev) | 108 | flash_kernel, "UBOOT_PART=%s" % target_boot_dev) |
3600 | 108 | 109 | ||
3601 | 109 | 110 | ||
3602 | 111 | def _list_files(directory): | ||
3603 | 112 | """List the files and dirs under the given directory. | ||
3604 | 113 | |||
3605 | 114 | Runs as root because we want to list everything, including stuff that may | ||
3606 | 115 | not be world-readable. | ||
3607 | 116 | """ | ||
3608 | 117 | p = cmd_runner.run( | ||
3609 | 118 | ['find', directory, '-maxdepth', '1', '-mindepth', '1'], | ||
3610 | 119 | stdout=subprocess.PIPE, as_root=True) | ||
3611 | 120 | stdout, _ = p.communicate() | ||
3612 | 121 | return stdout.split() | ||
3613 | 122 | |||
3614 | 123 | |||
3615 | 110 | def move_contents(from_, root_disk): | 124 | def move_contents(from_, root_disk): |
3616 | 111 | """Move everything under from_ to the given root disk. | 125 | """Move everything under from_ to the given root disk. |
3617 | 112 | 126 | ||
3618 | 113 | Uses sudo for moving. | 127 | Uses sudo for moving. |
3619 | 114 | """ | 128 | """ |
3620 | 115 | assert os.path.isdir(from_), "%s is not a directory" % from_ | 129 | assert os.path.isdir(from_), "%s is not a directory" % from_ |
3622 | 116 | files = glob.glob(os.path.join(from_, '*')) | 130 | files = _list_files(from_) |
3623 | 117 | mv_cmd = ['mv'] | 131 | mv_cmd = ['mv'] |
3624 | 118 | mv_cmd.extend(sorted(files)) | 132 | mv_cmd.extend(sorted(files)) |
3625 | 119 | mv_cmd.append(root_disk) | 133 | mv_cmd.append(root_disk) |
3626 | 120 | 134 | ||
3627 | === modified file 'linaro_image_tools/media_create/tests/test_media_create.py' | |||
3628 | --- linaro_image_tools/media_create/tests/test_media_create.py 2011-06-14 09:45:13 +0000 | |||
3629 | +++ linaro_image_tools/media_create/tests/test_media_create.py 2011-07-18 14:39:34 +0000 | |||
3630 | @@ -28,7 +28,10 @@ | |||
3631 | 28 | import textwrap | 28 | import textwrap |
3632 | 29 | import time | 29 | import time |
3633 | 30 | import types | 30 | import types |
3634 | 31 | import struct | ||
3635 | 32 | import tarfile | ||
3636 | 31 | 33 | ||
3637 | 34 | from StringIO import StringIO | ||
3638 | 32 | from testtools import TestCase | 35 | from testtools import TestCase |
3639 | 33 | 36 | ||
3640 | 34 | from linaro_image_tools import cmd_runner | 37 | from linaro_image_tools import cmd_runner |
3641 | @@ -38,9 +41,11 @@ | |||
3642 | 38 | boards, | 41 | boards, |
3643 | 39 | partitions, | 42 | partitions, |
3644 | 40 | rootfs, | 43 | rootfs, |
3645 | 44 | android_boards, | ||
3646 | 41 | ) | 45 | ) |
3647 | 42 | from linaro_image_tools.media_create.boards import ( | 46 | from linaro_image_tools.media_create.boards import ( |
3649 | 43 | LOADER_MIN_SIZE_S, | 47 | SAMSUNG_V310_BL1_START, |
3650 | 48 | SAMSUNG_V310_BL2_START, | ||
3651 | 44 | SECTOR_SIZE, | 49 | SECTOR_SIZE, |
3652 | 45 | align_up, | 50 | align_up, |
3653 | 46 | align_partition, | 51 | align_partition, |
3654 | @@ -56,6 +61,11 @@ | |||
3655 | 56 | _get_file_matching, | 61 | _get_file_matching, |
3656 | 57 | _get_mlo_file, | 62 | _get_mlo_file, |
3657 | 58 | _run_mkimage, | 63 | _run_mkimage, |
3658 | 64 | HardwarepackHandler, | ||
3659 | 65 | BoardConfig, | ||
3660 | 66 | ) | ||
3661 | 67 | from linaro_image_tools.media_create.android_boards import ( | ||
3662 | 68 | android_board_configs, | ||
3663 | 59 | ) | 69 | ) |
3664 | 60 | from linaro_image_tools.media_create.chroot_utils import ( | 70 | from linaro_image_tools.media_create.chroot_utils import ( |
3665 | 61 | copy_file, | 71 | copy_file, |
3666 | @@ -113,6 +123,359 @@ | |||
3667 | 113 | sudo_args = " ".join(cmd_runner.SUDO_ARGS) | 123 | sudo_args = " ".join(cmd_runner.SUDO_ARGS) |
3668 | 114 | 124 | ||
3669 | 115 | 125 | ||
3670 | 126 | class TestHardwarepackHandler(TestCaseWithFixtures): | ||
3671 | 127 | def setUp(self): | ||
3672 | 128 | super(TestHardwarepackHandler, self).setUp() | ||
3673 | 129 | self.tar_dir_fixture = CreateTempDirFixture() | ||
3674 | 130 | self.useFixture(self.tar_dir_fixture) | ||
3675 | 131 | |||
3676 | 132 | self.tarball_fixture = CreateTarballFixture( | ||
3677 | 133 | self.tar_dir_fixture.get_temp_dir()) | ||
3678 | 134 | self.useFixture(self.tarball_fixture) | ||
3679 | 135 | |||
3680 | 136 | self.metadata = ( | ||
3681 | 137 | "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\nORIGIN=linaro\n") | ||
3682 | 138 | |||
3683 | 139 | def add_to_tarball(self, files, tarball=None): | ||
3684 | 140 | if tarball is None: | ||
3685 | 141 | tarball = self.tarball_fixture.get_tarball() | ||
3686 | 142 | tar_file = tarfile.open(tarball, mode='w:gz') | ||
3687 | 143 | for filename, data in files: | ||
3688 | 144 | tarinfo = tarfile.TarInfo(filename) | ||
3689 | 145 | tarinfo.size = len(data) | ||
3690 | 146 | tar_file.addfile(tarinfo, StringIO(data)) | ||
3691 | 147 | tar_file.close() | ||
3692 | 148 | return tarball | ||
3693 | 149 | |||
3694 | 150 | def test_get_format_1(self): | ||
3695 | 151 | data = '1.0' | ||
3696 | 152 | format = "%s\n" % data | ||
3697 | 153 | tarball = self.add_to_tarball( | ||
3698 | 154 | [('FORMAT', format), ('metadata', self.metadata)]) | ||
3699 | 155 | hp = HardwarepackHandler([tarball]) | ||
3700 | 156 | with hp: | ||
3701 | 157 | self.assertEquals(hp.get_format(), data) | ||
3702 | 158 | |||
3703 | 159 | def test_get_format_2(self): | ||
3704 | 160 | data = '2.0' | ||
3705 | 161 | format = "%s\n" % data | ||
3706 | 162 | tarball = self.add_to_tarball( | ||
3707 | 163 | [('FORMAT', format), ('metadata', self.metadata)]) | ||
3708 | 164 | hp = HardwarepackHandler([tarball]) | ||
3709 | 165 | with hp: | ||
3710 | 166 | self.assertEquals(hp.get_format(), data) | ||
3711 | 167 | |||
3712 | 168 | def test_get_unknown_format_raises(self): | ||
3713 | 169 | data = '9.9' | ||
3714 | 170 | format = "%s\n" % data | ||
3715 | 171 | tarball = self.add_to_tarball( | ||
3716 | 172 | [('FORMAT', format), ('metadata', self.metadata)]) | ||
3717 | 173 | hp = HardwarepackHandler([tarball]) | ||
3718 | 174 | with hp: | ||
3719 | 175 | self.assertRaises(AssertionError, hp.get_format) | ||
3720 | 176 | |||
3721 | 177 | def test_mixed_formats(self): | ||
3722 | 178 | format1 = "%s\n" % '1.0' | ||
3723 | 179 | format2 = "%s\n" % '2.0' | ||
3724 | 180 | tarball1 = self.add_to_tarball( | ||
3725 | 181 | [('FORMAT', format1), ('metadata', self.metadata)], | ||
3726 | 182 | tarball=self.tarball_fixture.get_tarball()) | ||
3727 | 183 | tarball_fixture2 = CreateTarballFixture( | ||
3728 | 184 | self.tar_dir_fixture.get_temp_dir(), reldir='tarfile2', | ||
3729 | 185 | filename='secondtarball.tar.gz') | ||
3730 | 186 | self.useFixture(tarball_fixture2) | ||
3731 | 187 | tarball2 = self.add_to_tarball( | ||
3732 | 188 | [('FORMAT', format2), ('metadata', self.metadata)], | ||
3733 | 189 | tarball=tarball_fixture2.get_tarball()) | ||
3734 | 190 | hp = HardwarepackHandler([tarball2, tarball1]) | ||
3735 | 191 | with hp: | ||
3736 | 192 | self.assertEquals(hp.get_format(), '1.0and2.0') | ||
3737 | 193 | |||
3738 | 194 | def test_identical_formats_ok(self): | ||
3739 | 195 | format1 = "%s\n" % '2.0' | ||
3740 | 196 | format2 = "%s\n" % '2.0' | ||
3741 | 197 | tarball1 = self.add_to_tarball( | ||
3742 | 198 | [('FORMAT', format1), ('metadata', self.metadata)], | ||
3743 | 199 | tarball=self.tarball_fixture.get_tarball()) | ||
3744 | 200 | tarball_fixture2 = CreateTarballFixture( | ||
3745 | 201 | self.tar_dir_fixture.get_temp_dir(), reldir='tarfile2', | ||
3746 | 202 | filename='secondtarball.tar.gz') | ||
3747 | 203 | self.useFixture(tarball_fixture2) | ||
3748 | 204 | tarball2 = self.add_to_tarball( | ||
3749 | 205 | [('FORMAT', format2), ('metadata', self.metadata)], | ||
3750 | 206 | tarball=tarball_fixture2.get_tarball()) | ||
3751 | 207 | hp = HardwarepackHandler([tarball1, tarball2]) | ||
3752 | 208 | with hp: | ||
3753 | 209 | self.assertEquals(hp.get_format(), '2.0') | ||
3754 | 210 | |||
3755 | 211 | def test_get_metadata(self): | ||
3756 | 212 | data = 'data to test' | ||
3757 | 213 | metadata = self.metadata + "TEST=%s\n" % data | ||
3758 | 214 | tarball = self.add_to_tarball( | ||
3759 | 215 | [('metadata', metadata)]) | ||
3760 | 216 | hp = HardwarepackHandler([tarball]) | ||
3761 | 217 | with hp: | ||
3762 | 218 | test_data, _ = hp.get_field(hp.main_section, 'test') | ||
3763 | 219 | self.assertEqual(test_data, data) | ||
3764 | 220 | |||
3765 | 221 | def test_preserves_formatters(self): | ||
3766 | 222 | data = '%s%d' | ||
3767 | 223 | metadata = self.metadata + "TEST=%s\n" % data | ||
3768 | 224 | tarball = self.add_to_tarball( | ||
3769 | 225 | [('metadata', metadata)]) | ||
3770 | 226 | hp = HardwarepackHandler([tarball]) | ||
3771 | 227 | with hp: | ||
3772 | 228 | test_data, _ = hp.get_field(hp.main_section, 'test') | ||
3773 | 229 | self.assertEqual(test_data, data) | ||
3774 | 230 | |||
3775 | 231 | def test_creates_tempdir(self): | ||
3776 | 232 | tarball = self.add_to_tarball( | ||
3777 | 233 | [('metadata', self.metadata)]) | ||
3778 | 234 | hp = HardwarepackHandler([tarball]) | ||
3779 | 235 | with hp: | ||
3780 | 236 | self.assertTrue(os.path.exists(hp.tempdir)) | ||
3781 | 237 | |||
3782 | 238 | def test_tempfiles_are_removed(self): | ||
3783 | 239 | tempdir = None | ||
3784 | 240 | tarball = self.add_to_tarball( | ||
3785 | 241 | [('metadata', self.metadata)]) | ||
3786 | 242 | hp = HardwarepackHandler([tarball]) | ||
3787 | 243 | with hp: | ||
3788 | 244 | tempdir = hp.tempdir | ||
3789 | 245 | self.assertFalse(os.path.exists(tempdir)) | ||
3790 | 246 | |||
3791 | 247 | def test_get_file(self): | ||
3792 | 248 | data = 'test file contents\n' | ||
3793 | 249 | metadata_file = 'TESTFILE' | ||
3794 | 250 | file_in_archive = 'testfile' | ||
3795 | 251 | metadata = self.metadata + "%s=%s\n" % (metadata_file, file_in_archive) | ||
3796 | 252 | tarball = self.add_to_tarball( | ||
3797 | 253 | [('metadata', metadata), | ||
3798 | 254 | (file_in_archive, data)]) | ||
3799 | 255 | hp = HardwarepackHandler([tarball]) | ||
3800 | 256 | with hp: | ||
3801 | 257 | test_file = hp.get_file(metadata_file) | ||
3802 | 258 | self.assertEquals(data, open(test_file, 'r').read()) | ||
3803 | 259 | |||
3804 | 260 | |||
3805 | 261 | class TestSetMetadata(TestCaseWithFixtures): | ||
3806 | 262 | |||
3807 | 263 | class MockHardwarepackHandler(HardwarepackHandler): | ||
3808 | 264 | metadata_dict = {} | ||
3809 | 265 | |||
3810 | 266 | def __enter__(self): | ||
3811 | 267 | return self | ||
3812 | 268 | |||
3813 | 269 | def get_field(self, section, field): | ||
3814 | 270 | try: | ||
3815 | 271 | return self.metadata_dict[field], None | ||
3816 | 272 | except: | ||
3817 | 273 | return None, None | ||
3818 | 274 | |||
3819 | 275 | def get_format(self): | ||
3820 | 276 | return '2.0' | ||
3821 | 277 | |||
3822 | 278 | def get_file(self, file_alias): | ||
3823 | 279 | return None | ||
3824 | 280 | |||
3825 | 281 | def test_does_not_set_if_old_format(self): | ||
3826 | 282 | self.useFixture(MockSomethingFixture( | ||
3827 | 283 | linaro_image_tools.media_create.boards, 'HardwarepackHandler', | ||
3828 | 284 | self.MockHardwarepackHandler)) | ||
3829 | 285 | |||
3830 | 286 | class config(BoardConfig): | ||
3831 | 287 | pass | ||
3832 | 288 | config.set_metadata('ahwpack.tar.gz') | ||
3833 | 289 | self.assertEquals(None, config.kernel_addr) | ||
3834 | 290 | |||
3835 | 291 | def test_sets_kernel_addr(self): | ||
3836 | 292 | self.useFixture(MockSomethingFixture( | ||
3837 | 293 | linaro_image_tools.media_create.boards, 'HardwarepackHandler', | ||
3838 | 294 | self.MockHardwarepackHandler)) | ||
3839 | 295 | field_to_test = 'kernel_addr' | ||
3840 | 296 | data_to_set = '0x8123ABCD' | ||
3841 | 297 | self.MockHardwarepackHandler.metadata_dict = { | ||
3842 | 298 | field_to_test: data_to_set, | ||
3843 | 299 | } | ||
3844 | 300 | class config(BoardConfig): | ||
3845 | 301 | pass | ||
3846 | 302 | config.set_metadata('ahwpack.tar.gz') | ||
3847 | 303 | self.assertEquals(data_to_set, config.kernel_addr) | ||
3848 | 304 | |||
3849 | 305 | def test_sets_initrd_addr(self): | ||
3850 | 306 | self.useFixture(MockSomethingFixture( | ||
3851 | 307 | linaro_image_tools.media_create.boards, 'HardwarepackHandler', | ||
3852 | 308 | self.MockHardwarepackHandler)) | ||
3853 | 309 | field_to_test = 'initrd_addr' | ||
3854 | 310 | data_to_set = '0x8123ABCD' | ||
3855 | 311 | self.MockHardwarepackHandler.metadata_dict = { | ||
3856 | 312 | field_to_test: data_to_set, | ||
3857 | 313 | } | ||
3858 | 314 | class config(BoardConfig): | ||
3859 | 315 | pass | ||
3860 | 316 | config.set_metadata('ahwpack.tar.gz') | ||
3861 | 317 | self.assertEquals(data_to_set, config.initrd_addr) | ||
3862 | 318 | |||
3863 | 319 | def test_sets_load_addr(self): | ||
3864 | 320 | self.useFixture(MockSomethingFixture( | ||
3865 | 321 | linaro_image_tools.media_create.boards, 'HardwarepackHandler', | ||
3866 | 322 | self.MockHardwarepackHandler)) | ||
3867 | 323 | field_to_test = 'load_addr' | ||
3868 | 324 | data_to_set = '0x8123ABCD' | ||
3869 | 325 | self.MockHardwarepackHandler.metadata_dict = { | ||
3870 | 326 | field_to_test: data_to_set, | ||
3871 | 327 | } | ||
3872 | 328 | class config(BoardConfig): | ||
3873 | 329 | pass | ||
3874 | 330 | config.set_metadata('ahwpack.tar.gz') | ||
3875 | 331 | self.assertEquals(data_to_set, config.load_addr) | ||
3876 | 332 | |||
3877 | 333 | def test_sets_serial_tty(self): | ||
3878 | 334 | self.useFixture(MockSomethingFixture( | ||
3879 | 335 | linaro_image_tools.media_create.boards, 'HardwarepackHandler', | ||
3880 | 336 | self.MockHardwarepackHandler)) | ||
3881 | 337 | field_to_test = 'serial_tty' | ||
3882 | 338 | data_to_set = 'ttyAA' | ||
3883 | 339 | self.MockHardwarepackHandler.metadata_dict = { | ||
3884 | 340 | field_to_test: data_to_set, | ||
3885 | 341 | } | ||
3886 | 342 | class config(BoardConfig): | ||
3887 | 343 | pass | ||
3888 | 344 | config.set_metadata('ahwpack.tar.gz') | ||
3889 | 345 | self.assertEquals(data_to_set, config.serial_tty) | ||
3890 | 346 | |||
3891 | 347 | def test_sets_wired_interfaces(self): | ||
3892 | 348 | self.useFixture(MockSomethingFixture( | ||
3893 | 349 | linaro_image_tools.media_create.boards, 'HardwarepackHandler', | ||
3894 | 350 | self.MockHardwarepackHandler)) | ||
3895 | 351 | field_to_test = 'wired_interfaces' | ||
3896 | 352 | data_to_set = 'eth0 eth1' | ||
3897 | 353 | self.MockHardwarepackHandler.metadata_dict = { | ||
3898 | 354 | field_to_test: data_to_set, | ||
3899 | 355 | } | ||
3900 | 356 | class config(BoardConfig): | ||
3901 | 357 | pass | ||
3902 | 358 | config.set_metadata('ahwpack.tar.gz') | ||
3903 | 359 | self.assertEquals(data_to_set, config.wired_interfaces) | ||
3904 | 360 | |||
3905 | 361 | def test_sets_wireless_interfaces(self): | ||
3906 | 362 | self.useFixture(MockSomethingFixture( | ||
3907 | 363 | linaro_image_tools.media_create.boards, 'HardwarepackHandler', | ||
3908 | 364 | self.MockHardwarepackHandler)) | ||
3909 | 365 | field_to_test = 'wireless_interfaces' | ||
3910 | 366 | data_to_set = 'wlan0 wl1' | ||
3911 | 367 | self.MockHardwarepackHandler.metadata_dict = { | ||
3912 | 368 | field_to_test: data_to_set, | ||
3913 | 369 | } | ||
3914 | 370 | class config(BoardConfig): | ||
3915 | 371 | pass | ||
3916 | 372 | config.set_metadata('ahwpack.tar.gz') | ||
3917 | 373 | self.assertEquals(data_to_set, config.wireless_interfaces) | ||
3918 | 374 | |||
3919 | 375 | def test_sets_mmc_id(self): | ||
3920 | 376 | self.useFixture(MockSomethingFixture( | ||
3921 | 377 | linaro_image_tools.media_create.boards, 'HardwarepackHandler', | ||
3922 | 378 | self.MockHardwarepackHandler)) | ||
3923 | 379 | field_to_test = 'mmc_id' | ||
3924 | 380 | data_to_set = '1' | ||
3925 | 381 | self.MockHardwarepackHandler.metadata_dict = { | ||
3926 | 382 | field_to_test: data_to_set, | ||
3927 | 383 | } | ||
3928 | 384 | class config(BoardConfig): | ||
3929 | 385 | pass | ||
3930 | 386 | config.set_metadata('ahwpack.tar.gz') | ||
3931 | 387 | self.assertEquals(data_to_set, config.mmc_id) | ||
3932 | 388 | |||
3933 | 389 | def test_sets_boot_min_size(self): | ||
3934 | 390 | self.useFixture(MockSomethingFixture( | ||
3935 | 391 | linaro_image_tools.media_create.boards, 'HardwarepackHandler', | ||
3936 | 392 | self.MockHardwarepackHandler)) | ||
3937 | 393 | field_to_test = 'boot_min_size' | ||
3938 | 394 | data_to_set = '100' | ||
3939 | 395 | expected = align_up(int(data_to_set) * 1024 * 1024, | ||
3940 | 396 | SECTOR_SIZE) / SECTOR_SIZE | ||
3941 | 397 | self.MockHardwarepackHandler.metadata_dict = { | ||
3942 | 398 | field_to_test: data_to_set, | ||
3943 | 399 | } | ||
3944 | 400 | class config(BoardConfig): | ||
3945 | 401 | pass | ||
3946 | 402 | config.set_metadata('ahwpack.tar.gz') | ||
3947 | 403 | self.assertEquals(expected, config.BOOT_MIN_SIZE_S) | ||
3948 | 404 | |||
3949 | 405 | def test_sets_root_min_size(self): | ||
3950 | 406 | self.useFixture(MockSomethingFixture( | ||
3951 | 407 | linaro_image_tools.media_create.boards, 'HardwarepackHandler', | ||
3952 | 408 | self.MockHardwarepackHandler)) | ||
3953 | 409 | field_to_test = 'root_min_size' | ||
3954 | 410 | data_to_set = '3' | ||
3955 | 411 | expected = align_up(int(data_to_set) * 1024 * 1024, | ||
3956 | 412 | SECTOR_SIZE) / SECTOR_SIZE | ||
3957 | 413 | self.MockHardwarepackHandler.metadata_dict = { | ||
3958 | 414 | field_to_test: data_to_set, | ||
3959 | 415 | } | ||
3960 | 416 | class config(BoardConfig): | ||
3961 | 417 | pass | ||
3962 | 418 | config.set_metadata('ahwpack.tar.gz') | ||
3963 | 419 | self.assertEquals(expected, config.ROOT_MIN_SIZE_S) | ||
3964 | 420 | |||
3965 | 421 | def test_sets_loader_min_size(self): | ||
3966 | 422 | self.useFixture(MockSomethingFixture( | ||
3967 | 423 | linaro_image_tools.media_create.boards, 'HardwarepackHandler', | ||
3968 | 424 | self.MockHardwarepackHandler)) | ||
3969 | 425 | field_to_test = 'loader_min_size' | ||
3970 | 426 | data_to_set = '2' | ||
3971 | 427 | expected = align_up(int(data_to_set) * 1024 * 1024, | ||
3972 | 428 | SECTOR_SIZE) / SECTOR_SIZE | ||
3973 | 429 | self.MockHardwarepackHandler.metadata_dict = { | ||
3974 | 430 | field_to_test: data_to_set, | ||
3975 | 431 | } | ||
3976 | 432 | class config(BoardConfig): | ||
3977 | 433 | pass | ||
3978 | 434 | config.set_metadata('ahwpack.tar.gz') | ||
3979 | 435 | self.assertEquals(expected, config.LOADER_MIN_SIZE_S) | ||
3980 | 436 | |||
3981 | 437 | def test_sets_partition_layout_32(self): | ||
3982 | 438 | self.useFixture(MockSomethingFixture( | ||
3983 | 439 | linaro_image_tools.media_create.boards, 'HardwarepackHandler', | ||
3984 | 440 | self.MockHardwarepackHandler)) | ||
3985 | 441 | field_to_test = 'partition_layout' | ||
3986 | 442 | data_to_set = 'bootfs_rootfs' | ||
3987 | 443 | self.MockHardwarepackHandler.metadata_dict = { | ||
3988 | 444 | field_to_test: data_to_set, | ||
3989 | 445 | } | ||
3990 | 446 | class config(BoardConfig): | ||
3991 | 447 | pass | ||
3992 | 448 | config.set_metadata('ahwpack.tar.gz') | ||
3993 | 449 | self.assertEquals(32, config.fat_size) | ||
3994 | 450 | |||
3995 | 451 | def test_sets_partition_layout_16(self): | ||
3996 | 452 | self.useFixture(MockSomethingFixture( | ||
3997 | 453 | linaro_image_tools.media_create.boards, 'HardwarepackHandler', | ||
3998 | 454 | self.MockHardwarepackHandler)) | ||
3999 | 455 | field_to_test = 'partition_layout' | ||
4000 | 456 | data_to_set = 'bootfs16_rootfs' | ||
4001 | 457 | self.MockHardwarepackHandler.metadata_dict = { | ||
4002 | 458 | field_to_test: data_to_set, | ||
4003 | 459 | } | ||
4004 | 460 | class config(BoardConfig): | ||
4005 | 461 | pass | ||
4006 | 462 | config.set_metadata('ahwpack.tar.gz') | ||
4007 | 463 | self.assertEquals(16, config.fat_size) | ||
4008 | 464 | |||
4009 | 465 | def test_sets_partition_layout_raises(self): | ||
4010 | 466 | self.useFixture(MockSomethingFixture( | ||
4011 | 467 | linaro_image_tools.media_create.boards, 'HardwarepackHandler', | ||
4012 | 468 | self.MockHardwarepackHandler)) | ||
4013 | 469 | field_to_test = 'partition_layout' | ||
4014 | 470 | data_to_set = 'bootfs_bogus_rootfs' | ||
4015 | 471 | self.MockHardwarepackHandler.metadata_dict = { | ||
4016 | 472 | field_to_test: data_to_set, | ||
4017 | 473 | } | ||
4018 | 474 | class config(BoardConfig): | ||
4019 | 475 | pass | ||
4020 | 476 | self.assertRaises(AssertionError, config.set_metadata, 'ahwpack.tar.gz') | ||
4021 | 477 | |||
4022 | 478 | |||
4023 | 116 | class TestGetMLOFile(TestCaseWithFixtures): | 479 | class TestGetMLOFile(TestCaseWithFixtures): |
4024 | 117 | 480 | ||
4025 | 118 | def test_mlo_from_new_xloader(self): | 481 | def test_mlo_from_new_xloader(self): |
4026 | @@ -150,6 +513,325 @@ | |||
4027 | 150 | AssertionError, _get_mlo_file, tempdir) | 513 | AssertionError, _get_mlo_file, tempdir) |
4028 | 151 | 514 | ||
4029 | 152 | 515 | ||
4030 | 516 | def _create_uboot_dir(root, flavor): | ||
4031 | 517 | path = os.path.join(root, 'usr', 'lib', 'u-boot', flavor) | ||
4032 | 518 | os.makedirs(path) | ||
4033 | 519 | return path | ||
4034 | 520 | |||
4035 | 521 | |||
4036 | 522 | class TestGetSMDKSPL(TestCaseWithFixtures): | ||
4037 | 523 | config = boards.SMDKV310Config | ||
4038 | 524 | |||
4039 | 525 | def test_no_file_present(self): | ||
4040 | 526 | tempdir = self.useFixture(CreateTempDirFixture()).get_temp_dir() | ||
4041 | 527 | self.assertRaises( | ||
4042 | 528 | AssertionError, self.config._get_samsung_spl, tempdir) | ||
4043 | 529 | |||
4044 | 530 | def test_old_file_present(self): | ||
4045 | 531 | tempdir = self.useFixture(CreateTempDirFixture()).get_temp_dir() | ||
4046 | 532 | path = _create_uboot_dir(tempdir, self.config.uboot_flavor) | ||
4047 | 533 | spl_path = os.path.join(path, 'v310_mmc_spl.bin') | ||
4048 | 534 | open(spl_path, 'w').close() | ||
4049 | 535 | self.assertEquals(spl_path, self.config._get_samsung_spl(tempdir)) | ||
4050 | 536 | |||
4051 | 537 | def test_new_file_present(self): | ||
4052 | 538 | tempdir = self.useFixture(CreateTempDirFixture()).get_temp_dir() | ||
4053 | 539 | path = _create_uboot_dir(tempdir, self.config.uboot_flavor) | ||
4054 | 540 | spl_path = os.path.join(path, 'u-boot-mmc-spl.bin') | ||
4055 | 541 | open(spl_path, 'w').close() | ||
4056 | 542 | self.assertEquals(spl_path, self.config._get_samsung_spl(tempdir)) | ||
4057 | 543 | |||
4058 | 544 | def test_prefers_old_path(self): | ||
4059 | 545 | tempdir = self.useFixture(CreateTempDirFixture()).get_temp_dir() | ||
4060 | 546 | path = _create_uboot_dir(tempdir, self.config.uboot_flavor) | ||
4061 | 547 | old_spl_path = os.path.join(path, 'v310_mmc_spl.bin') | ||
4062 | 548 | new_spl_path = os.path.join(path, 'u-boot-mmc-spl.bin') | ||
4063 | 549 | open(old_spl_path, 'w').close() | ||
4064 | 550 | open(new_spl_path, 'w').close() | ||
4065 | 551 | self.assertEquals(old_spl_path, self.config._get_samsung_spl(tempdir)) | ||
4066 | 552 | |||
4067 | 553 | |||
4068 | 554 | class TestGetSMDKUboot(TestCaseWithFixtures): | ||
4069 | 555 | config = boards.SMDKV310Config | ||
4070 | 556 | |||
4071 | 557 | def test_uses_uboot_flavour(self): | ||
4072 | 558 | chroot_dir = "chroot" | ||
4073 | 559 | uboot_file = os.path.join(chroot_dir, 'usr', 'lib', 'u-boot', | ||
4074 | 560 | self.config.uboot_flavor, 'u-boot.bin') | ||
4075 | 561 | self.assertEquals( | ||
4076 | 562 | uboot_file, self.config._get_samsung_uboot(chroot_dir)) | ||
4077 | 563 | |||
4078 | 564 | |||
4079 | 565 | class TestGetOrigenSPL(TestCaseWithFixtures): | ||
4080 | 566 | config = boards.OrigenConfig | ||
4081 | 567 | |||
4082 | 568 | def test_no_file_present(self): | ||
4083 | 569 | tempdir = self.useFixture(CreateTempDirFixture()).get_temp_dir() | ||
4084 | 570 | self.assertRaises( | ||
4085 | 571 | AssertionError, self.config._get_samsung_spl, tempdir) | ||
4086 | 572 | |||
4087 | 573 | def test_new_file_present(self): | ||
4088 | 574 | tempdir = self.useFixture(CreateTempDirFixture()).get_temp_dir() | ||
4089 | 575 | path = _create_uboot_dir(tempdir, self.config.uboot_flavor) | ||
4090 | 576 | spl_path = os.path.join(path, 'u-boot-mmc-spl.bin') | ||
4091 | 577 | open(spl_path, 'w').close() | ||
4092 | 578 | self.assertEquals(spl_path, self.config._get_samsung_spl(tempdir)) | ||
4093 | 579 | |||
4094 | 580 | |||
4095 | 581 | class TestGetOrigenUboot(TestGetSMDKUboot): | ||
4096 | 582 | config = boards.OrigenConfig | ||
4097 | 583 | |||
4098 | 584 | |||
4099 | 585 | class TestCreateToc(TestCaseWithFixtures): | ||
4100 | 586 | ''' Tests boards.SnowballEmmcConfig.create_toc()''' | ||
4101 | 587 | |||
4102 | 588 | def setUp(self): | ||
4103 | 589 | ''' Create a temporary directory to work in''' | ||
4104 | 590 | super(TestCreateToc, self).setUp() | ||
4105 | 591 | self.tempdir = self.useFixture(CreateTempDirFixture()).get_temp_dir() | ||
4106 | 592 | #Create the test's input data structures | ||
4107 | 593 | zero = '\x00\x00\x00\x00' | ||
4108 | 594 | line1 = zero + zero + zero + zero + zero + 'b' + zero + zero + \ | ||
4109 | 595 | '\x00\x00\x00' | ||
4110 | 596 | maxint = '\xFF\xFF\xFF\x7F' | ||
4111 | 597 | minint = '\xFF\xFF\xFF\xFF' | ||
4112 | 598 | line2 = maxint + maxint + zero + minint + minint + \ | ||
4113 | 599 | 'hello' + zero + '\x00\x00\x00' | ||
4114 | 600 | line3 = '\x01\x00\x00\x00' '\x64\x00\x00\x00' + zero + \ | ||
4115 | 601 | '\x05\x00\x00\x00' '\x05\x00\x00\x00' \ | ||
4116 | 602 | 'hello' + zero + '\x00\x00\x00' | ||
4117 | 603 | self.expected = line1 + line2 + line3 | ||
4118 | 604 | |||
4119 | 605 | def create_files_structure(self, src_data): | ||
4120 | 606 | ''' Creates the data structure that the tested function | ||
4121 | 607 | needs as input''' | ||
4122 | 608 | files = [] | ||
4123 | 609 | for line in src_data: | ||
4124 | 610 | files.append({'section_name': line[5], | ||
4125 | 611 | 'filename': 'N/A', | ||
4126 | 612 | 'align': line[3], | ||
4127 | 613 | 'offset': line[0], | ||
4128 | 614 | 'size': line[1], | ||
4129 | 615 | 'load_adress': 'N/A'}) | ||
4130 | 616 | return files | ||
4131 | 617 | |||
4132 | 618 | def test_create_toc_normal_case(self): | ||
4133 | 619 | ''' Creates a toc file, and then reads the created | ||
4134 | 620 | file and compares it to precomputed data''' | ||
4135 | 621 | correct_data = [(0, 0, 0, 0, 0, 'b'), | ||
4136 | 622 | (0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, -1, -1, 'hello'), | ||
4137 | 623 | (1, 100, 1000, 5, 10, 'hello')] | ||
4138 | 624 | files = self.create_files_structure(correct_data) | ||
4139 | 625 | filename = os.path.join(self.tempdir, 'toc') | ||
4140 | 626 | with open(filename, 'w') as f: | ||
4141 | 627 | boards.SnowballEmmcConfig.create_toc(f, files) | ||
4142 | 628 | with open(filename, 'r') as f: | ||
4143 | 629 | actual = f.read() | ||
4144 | 630 | self.assertEquals(96, len(actual)) | ||
4145 | 631 | for i in range(len(actual)): | ||
4146 | 632 | self.assertEquals(self.expected[i], actual[i], 'Mismatch at ix' \ | ||
4147 | 633 | ' %d, ref=%c, actual=%c' % (i, self.expected[i], actual[i])) | ||
4148 | 634 | |||
4149 | 635 | def test_create_toc_error_too_large_section_name(self): | ||
4150 | 636 | '''Verify that trying to write past the end of the | ||
4151 | 637 | section name field raises an exception''' | ||
4152 | 638 | illegal_name_data = [(0, 0, 0, 0, 0, 'Too_longName')] | ||
4153 | 639 | files = self.create_files_structure(illegal_name_data) | ||
4154 | 640 | with open(os.path.join(self.tempdir, 'toc'), 'w') as f: | ||
4155 | 641 | self.assertRaises(AssertionError, | ||
4156 | 642 | boards.SnowballEmmcConfig.create_toc, | ||
4157 | 643 | f, files) | ||
4158 | 644 | |||
4159 | 645 | def test_create_toc_error_negative_unsigned(self): | ||
4160 | 646 | '''Verify that trying to write a negative number to an unsigned | ||
4161 | 647 | field raises an exception''' | ||
4162 | 648 | illegal_unsigned_data = [(-3, 0, 0, 0, 0, 'xxx')] | ||
4163 | 649 | files = self.create_files_structure(illegal_unsigned_data) | ||
4164 | 650 | with open(os.path.join(self.tempdir, 'toc'), 'w') as f: | ||
4165 | 651 | self.assertRaises(struct.error, | ||
4166 | 652 | boards.SnowballEmmcConfig.create_toc, | ||
4167 | 653 | f, files) | ||
4168 | 654 | |||
4169 | 655 | |||
4170 | 656 | class TestSnowballBootFiles(TestCaseWithFixtures): | ||
4171 | 657 | ''' Tests boards.SnowballEmmcConfig.install_snowball_boot_loader()''' | ||
4172 | 658 | ''' Tests boards.SnowballEmmcConfig._make_boot_files()''' | ||
4173 | 659 | ''' Tests boards.SnowballEmmcConfig.get_file_info()''' | ||
4174 | 660 | |||
4175 | 661 | def setUp(self): | ||
4176 | 662 | ''' Create temporary directory to work in''' | ||
4177 | 663 | super(TestSnowballBootFiles, self).setUp() | ||
4178 | 664 | self.tempdir = self.useFixture(CreateTempDirFixture()).get_temp_dir() | ||
4179 | 665 | self.temp_bootdir_path = os.path.join(self.tempdir, 'boot') | ||
4180 | 666 | if not os.path.exists(self.temp_bootdir_path): | ||
4181 | 667 | os.makedirs(self.temp_bootdir_path) | ||
4182 | 668 | |||
4183 | 669 | def setupFiles(self): | ||
4184 | 670 | ''' Adds some files in the temp dir that the tested function | ||
4185 | 671 | can use as input: | ||
4186 | 672 | * A config file, which the tested function reads to | ||
4187 | 673 | discover which binary files should be written to | ||
4188 | 674 | the loader partition. | ||
4189 | 675 | * Test versions of the binary files themselves, | ||
4190 | 676 | containing dummy data. | ||
4191 | 677 | Returns the expected value that the tested function should | ||
4192 | 678 | return, given these input files. ''' | ||
4193 | 679 | src_data = [('ISSW', 'boot_image_issw.bin', -1, 0, '5'), | ||
4194 | 680 | ('X-LOADER', 'boot_image_x-loader.bin', -1, 0, '6'), | ||
4195 | 681 | ('MEM_INIT', 'mem_init.bin', 0, 0x160000, '7'), | ||
4196 | 682 | ('PWR_MGT', 'power_management.bin', 0, 0x170000, '8'), | ||
4197 | 683 | ('NORMAL', 'u-boot.bin', 0, 0xBA0000, '9'), | ||
4198 | 684 | ('UBOOT_ENV', 'u-boot-env.bin', 0, 0x00C1F000, '10')] | ||
4199 | 685 | # Create a config file | ||
4200 | 686 | cfg_file = os.path.join(self.temp_bootdir_path, | ||
4201 | 687 | boards.SnowballEmmcConfig.SNOWBALL_STARTUP_FILES_CONFIG) | ||
4202 | 688 | with open(cfg_file, 'w') as f: | ||
4203 | 689 | for line in src_data: | ||
4204 | 690 | # Write comments, so we test that the parser can read them | ||
4205 | 691 | f.write('#Yet another comment\n') | ||
4206 | 692 | f.write('%s %s %i %#x %s\n' % line) | ||
4207 | 693 | expected = [] | ||
4208 | 694 | # Define dummy binary files, containing nothing but their own | ||
4209 | 695 | # section names. | ||
4210 | 696 | for line in src_data: | ||
4211 | 697 | with open(os.path.join(self.temp_bootdir_path, line[1]), 'w') as f: | ||
4212 | 698 | f.write(line[0]) | ||
4213 | 699 | #define the expected values read from the config file | ||
4214 | 700 | expected = [] | ||
4215 | 701 | ofs = [boards.SnowballEmmcConfig.TOC_SIZE, | ||
4216 | 702 | boards.SnowballEmmcConfig.TOC_SIZE + len('ISSW'), 0x160000, | ||
4217 | 703 | 0x170000, 0xBA0000, 0xC1F000] | ||
4218 | 704 | size = [len('ISSW'), len('X-LOADER'), len('MEM_INIT'), \ | ||
4219 | 705 | len('PWR_MGT'), len('NORMAL'), len('UBOOT_ENV')] | ||
4220 | 706 | i = 0 | ||
4221 | 707 | for line in src_data: | ||
4222 | 708 | filename = os.path.join(self.temp_bootdir_path, line[1]) | ||
4223 | 709 | expected.append({'section_name': line[0], | ||
4224 | 710 | 'filename': filename, | ||
4225 | 711 | 'align': int(line[2]), | ||
4226 | 712 | 'offset': ofs[i], | ||
4227 | 713 | 'size': long(size[i]), | ||
4228 | 714 | 'load_adress': line[4]}) | ||
4229 | 715 | i += 1 | ||
4230 | 716 | return expected | ||
4231 | 717 | |||
4232 | 718 | def test_file_name_size(self): | ||
4233 | 719 | ''' Test using a to large toc file ''' | ||
4234 | 720 | _, toc_filename = tempfile.mkstemp() | ||
4235 | 721 | atexit.register(os.unlink, toc_filename) | ||
4236 | 722 | filedata = 'X' | ||
4237 | 723 | bytes = boards.SnowballEmmcConfig.TOC_SIZE + 1 | ||
4238 | 724 | tmpfile = open(toc_filename, 'wb') | ||
4239 | 725 | for n in xrange(bytes): | ||
4240 | 726 | tmpfile.write(filedata) | ||
4241 | 727 | tmpfile.close() | ||
4242 | 728 | files = self.setupFiles() | ||
4243 | 729 | self.assertRaises(AssertionError, | ||
4244 | 730 | boards.SnowballEmmcConfig.install_snowball_boot_loader, | ||
4245 | 731 | toc_filename, files, "boot_device_or_file", | ||
4246 | 732 | boards.SnowballEmmcConfig.SNOWBALL_LOADER_START_S) | ||
4247 | 733 | |||
4248 | 734 | def test_install_snowball_boot_loader_toc(self): | ||
4249 | 735 | fixture = self.useFixture(MockCmdRunnerPopenFixture()) | ||
4250 | 736 | toc_filename = self.createTempFileAsFixture() | ||
4251 | 737 | files = self.setupFiles() | ||
4252 | 738 | boards.SnowballEmmcConfig.install_snowball_boot_loader(toc_filename, | ||
4253 | 739 | files, "boot_device_or_file", | ||
4254 | 740 | boards.SnowballEmmcConfig.SNOWBALL_LOADER_START_S) | ||
4255 | 741 | expected = [ | ||
4256 | 742 | '%s dd if=%s of=boot_device_or_file bs=512 conv=notrunc' \ | ||
4257 | 743 | ' seek=%s' % (sudo_args, toc_filename, | ||
4258 | 744 | boards.SnowballEmmcConfig.SNOWBALL_LOADER_START_S), | ||
4259 | 745 | '%s dd if=%s/boot_image_issw.bin of=boot_device_or_file bs=512' \ | ||
4260 | 746 | ' conv=notrunc seek=257' % (sudo_args, self.temp_bootdir_path), | ||
4261 | 747 | '%s rm %s/boot_image_issw.bin' % (sudo_args, | ||
4262 | 748 | self.temp_bootdir_path), | ||
4263 | 749 | '%s dd if=%s/boot_image_x-loader.bin of=boot_device_or_file' \ | ||
4264 | 750 | ' bs=1 conv=notrunc seek=131588' | ||
4265 | 751 | % (sudo_args, self.temp_bootdir_path), | ||
4266 | 752 | '%s rm %s/boot_image_x-loader.bin' % (sudo_args, | ||
4267 | 753 | self.temp_bootdir_path), | ||
4268 | 754 | '%s dd if=%s/mem_init.bin of=boot_device_or_file bs=512' \ | ||
4269 | 755 | ' conv=notrunc seek=3072' % (sudo_args, self.temp_bootdir_path), | ||
4270 | 756 | '%s rm %s/mem_init.bin' % (sudo_args, self.temp_bootdir_path), | ||
4271 | 757 | '%s dd if=%s/power_management.bin of=boot_device_or_file bs=512' \ | ||
4272 | 758 | ' conv=notrunc seek=3200' % (sudo_args, self.temp_bootdir_path), | ||
4273 | 759 | '%s rm %s/power_management.bin' % (sudo_args, | ||
4274 | 760 | self.temp_bootdir_path), | ||
4275 | 761 | '%s dd if=%s/u-boot.bin of=boot_device_or_file bs=512' \ | ||
4276 | 762 | ' conv=notrunc seek=24064' % (sudo_args, self.temp_bootdir_path), | ||
4277 | 763 | '%s rm %s/u-boot.bin' % (sudo_args, self.temp_bootdir_path), | ||
4278 | 764 | '%s dd if=%s/u-boot-env.bin of=boot_device_or_file bs=512' | ||
4279 | 765 | ' conv=notrunc seek=25080' % (sudo_args, self.temp_bootdir_path), | ||
4280 | 766 | '%s rm %s/u-boot-env.bin' % (sudo_args, self.temp_bootdir_path)] | ||
4281 | 767 | |||
4282 | 768 | self.assertEqual(expected, fixture.mock.commands_executed) | ||
4283 | 769 | |||
4284 | 770 | def test_snowball_make_boot_files(self): | ||
4285 | 771 | fixture = self.useFixture(MockCmdRunnerPopenFixture()) | ||
4286 | 772 | self.useFixture(MockSomethingFixture(tempfile, 'mkstemp', | ||
4287 | 773 | lambda: (-1, '/tmp/temp_snowball_make_boot_files'))) | ||
4288 | 774 | self.setupFiles() | ||
4289 | 775 | k_img_file = os.path.join(self.tempdir, 'vmlinuz-1-ux500') | ||
4290 | 776 | i_img_file = os.path.join(self.tempdir, 'initrd.img-1-ux500') | ||
4291 | 777 | |||
4292 | 778 | boot_env = board_configs['snowball_emmc']._get_boot_env( | ||
4293 | 779 | is_live=False, is_lowmem=False, consoles=[], | ||
4294 | 780 | rootfs_uuid="test_boot_env_uuid", d_img_data=None) | ||
4295 | 781 | boards.SnowballEmmcConfig._make_boot_files(boot_env, self.tempdir, | ||
4296 | 782 | self.temp_bootdir_path, 'boot_device_or_file', k_img_file, | ||
4297 | 783 | i_img_file, None) | ||
4298 | 784 | expected = [ | ||
4299 | 785 | '%s mkimage -A arm -O linux -T kernel -C none -a 0x00008000 -e' \ | ||
4300 | 786 | ' 0x00008000 -n Linux -d %s %s/boot/uImage' % (sudo_args, | ||
4301 | 787 | k_img_file, self.tempdir), | ||
4302 | 788 | '%s cp /tmp/temp_snowball_make_boot_files %s/boot/boot.txt' | ||
4303 | 789 | % (sudo_args, self.tempdir), | ||
4304 | 790 | '%s mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n boot' \ | ||
4305 | 791 | ' script -d %s/boot/boot.txt %s/boot/flash.scr' | ||
4306 | 792 | % (sudo_args, self.tempdir, self.tempdir), | ||
4307 | 793 | '%s dd if=/tmp/temp_snowball_make_boot_files' \ | ||
4308 | 794 | ' of=boot_device_or_file bs=512 conv=notrunc seek=256' | ||
4309 | 795 | % (sudo_args), | ||
4310 | 796 | '%s dd if=%s/boot/boot_image_issw.bin of=boot_device_or_file' \ | ||
4311 | 797 | ' bs=512 conv=notrunc seek=257' % (sudo_args, self.tempdir), | ||
4312 | 798 | '%s rm %s/boot_image_issw.bin' % (sudo_args, | ||
4313 | 799 | self.temp_bootdir_path), | ||
4314 | 800 | '%s dd if=%s/boot/boot_image_x-loader.bin of=boot_device_or_file' \ | ||
4315 | 801 | ' bs=1 conv=notrunc seek=131588' % (sudo_args, self.tempdir), | ||
4316 | 802 | '%s rm %s/boot_image_x-loader.bin' % (sudo_args, | ||
4317 | 803 | self.temp_bootdir_path), | ||
4318 | 804 | '%s dd if=%s/boot/mem_init.bin of=boot_device_or_file bs=512' \ | ||
4319 | 805 | ' conv=notrunc seek=3072' % (sudo_args, self.tempdir), | ||
4320 | 806 | '%s rm %s/mem_init.bin' % (sudo_args, self.temp_bootdir_path), | ||
4321 | 807 | '%s dd if=%s/boot/power_management.bin of=boot_device_or_file' \ | ||
4322 | 808 | ' bs=512 conv=notrunc seek=3200' % (sudo_args, self.tempdir), | ||
4323 | 809 | '%s rm %s/power_management.bin' % (sudo_args, | ||
4324 | 810 | self.temp_bootdir_path), | ||
4325 | 811 | '%s dd if=%s/boot/u-boot.bin of=boot_device_or_file bs=512' \ | ||
4326 | 812 | ' conv=notrunc seek=24064' % (sudo_args, self.tempdir), | ||
4327 | 813 | '%s rm %s/u-boot.bin' % (sudo_args, self.temp_bootdir_path), | ||
4328 | 814 | '%s dd if=%s/boot/u-boot-env.bin of=boot_device_or_file bs=512' \ | ||
4329 | 815 | ' conv=notrunc seek=25080' % (sudo_args, self.tempdir), | ||
4330 | 816 | '%s rm %s/u-boot-env.bin' % (sudo_args, self.temp_bootdir_path), | ||
4331 | 817 | '%s rm /tmp/temp_snowball_make_boot_files' % (sudo_args), | ||
4332 | 818 | '%s rm %s/startfiles.cfg' % (sudo_args, self.temp_bootdir_path)] | ||
4333 | 819 | |||
4334 | 820 | self.assertEqual(expected, fixture.mock.commands_executed) | ||
4335 | 821 | |||
4336 | 822 | def test_missing_files(self): | ||
4337 | 823 | '''When the files cannot be read, an IOError should be raised''' | ||
4338 | 824 | self.assertRaises(IOError, | ||
4339 | 825 | boards.SnowballEmmcConfig.get_file_info, | ||
4340 | 826 | self.tempdir) | ||
4341 | 827 | |||
4342 | 828 | def test_normal_case(self): | ||
4343 | 829 | expected = self.setupFiles() | ||
4344 | 830 | actual = boards.SnowballEmmcConfig.get_file_info( | ||
4345 | 831 | self.temp_bootdir_path) | ||
4346 | 832 | self.assertEquals(expected, actual) | ||
4347 | 833 | |||
4348 | 834 | |||
4349 | 153 | class TestBootSteps(TestCaseWithFixtures): | 835 | class TestBootSteps(TestCaseWithFixtures): |
4350 | 154 | 836 | ||
4351 | 155 | def setUp(self): | 837 | def setUp(self): |
4352 | @@ -199,6 +881,10 @@ | |||
4353 | 199 | def test_mx5_steps(self): | 881 | def test_mx5_steps(self): |
4354 | 200 | class SomeMx5Config(boards.Mx5Config): | 882 | class SomeMx5Config(boards.Mx5Config): |
4355 | 201 | uboot_flavor = 'uboot_flavor' | 883 | uboot_flavor = 'uboot_flavor' |
4356 | 884 | SomeMx5Config.hardwarepack_handler = ( | ||
4357 | 885 | TestSetMetadata.MockHardwarepackHandler('ahwpack.tar.gz')) | ||
4358 | 886 | SomeMx5Config.hardwarepack_handler.get_format = ( | ||
4359 | 887 | lambda: '1.0') | ||
4360 | 202 | self.make_boot_files(SomeMx5Config) | 888 | self.make_boot_files(SomeMx5Config) |
4361 | 203 | expected = [ | 889 | expected = [ |
4362 | 204 | 'install_mx5_boot_loader', 'make_uImage', 'make_uInitrd', | 890 | 'install_mx5_boot_loader', 'make_uImage', 'make_uInitrd', |
4363 | @@ -206,9 +892,40 @@ | |||
4364 | 206 | self.assertEqual(expected, self.funcs_calls) | 892 | self.assertEqual(expected, self.funcs_calls) |
4365 | 207 | 893 | ||
4366 | 208 | def test_smdkv310_steps(self): | 894 | def test_smdkv310_steps(self): |
4367 | 895 | def mock_func_creator(name): | ||
4368 | 896 | return classmethod( | ||
4369 | 897 | lambda *args, **kwargs: self.funcs_calls.append(name)) | ||
4370 | 898 | |||
4371 | 899 | self.useFixture(MockSomethingFixture( | ||
4372 | 900 | linaro_image_tools.media_create.boards.SMDKV310Config, | ||
4373 | 901 | 'install_samsung_boot_loader', | ||
4374 | 902 | mock_func_creator('install_samsung_boot_loader'))) | ||
4375 | 903 | boards.SMDKV310Config.hardwarepack_handler = ( | ||
4376 | 904 | TestSetMetadata.MockHardwarepackHandler('ahwpack.tar.gz')) | ||
4377 | 905 | boards.SMDKV310Config.hardwarepack_handler.get_format = ( | ||
4378 | 906 | lambda: '1.0') | ||
4379 | 209 | self.make_boot_files(boards.SMDKV310Config) | 907 | self.make_boot_files(boards.SMDKV310Config) |
4380 | 210 | expected = [ | 908 | expected = [ |
4382 | 211 | '_dd', '_dd', 'make_flashable_env', '_dd', 'make_uImage', | 909 | 'install_samsung_boot_loader', 'make_flashable_env', '_dd', 'make_uImage', |
4383 | 910 | 'make_uInitrd', 'make_boot_script'] | ||
4384 | 911 | self.assertEqual(expected, self.funcs_calls) | ||
4385 | 912 | |||
4386 | 913 | def test_origen_steps(self): | ||
4387 | 914 | def mock_func_creator(name): | ||
4388 | 915 | return classmethod( | ||
4389 | 916 | lambda *args, **kwargs: self.funcs_calls.append(name)) | ||
4390 | 917 | |||
4391 | 918 | self.useFixture(MockSomethingFixture( | ||
4392 | 919 | linaro_image_tools.media_create.boards.OrigenConfig, | ||
4393 | 920 | 'install_samsung_boot_loader', | ||
4394 | 921 | mock_func_creator('install_samsung_boot_loader'))) | ||
4395 | 922 | boards.OrigenConfig.hardwarepack_handler = ( | ||
4396 | 923 | TestSetMetadata.MockHardwarepackHandler('ahwpack.tar.gz')) | ||
4397 | 924 | boards.OrigenConfig.hardwarepack_handler.get_format = ( | ||
4398 | 925 | lambda: '1.0') | ||
4399 | 926 | self.make_boot_files(boards.OrigenConfig) | ||
4400 | 927 | expected = [ | ||
4401 | 928 | 'install_samsung_boot_loader', 'make_flashable_env', '_dd', 'make_uImage', | ||
4402 | 212 | 'make_uInitrd', 'make_boot_script'] | 929 | 'make_uInitrd', 'make_boot_script'] |
4403 | 213 | self.assertEqual(expected, self.funcs_calls) | 930 | self.assertEqual(expected, self.funcs_calls) |
4404 | 214 | 931 | ||
4405 | @@ -354,6 +1071,23 @@ | |||
4406 | 354 | '1,8191,0xDA\n8192,106496,0x0C,*\n114688,,,-', | 1071 | '1,8191,0xDA\n8192,106496,0x0C,*\n114688,,,-', |
4407 | 355 | board_configs['smdkv310'].get_sfdisk_cmd()) | 1072 | board_configs['smdkv310'].get_sfdisk_cmd()) |
4408 | 356 | 1073 | ||
4409 | 1074 | def test_origen(self): | ||
4410 | 1075 | self.assertEquals( | ||
4411 | 1076 | '1,8191,0xDA\n8192,106496,0x0C,*\n114688,,,-', | ||
4412 | 1077 | board_configs['origen'].get_sfdisk_cmd()) | ||
4413 | 1078 | |||
4414 | 1079 | def test_panda_android(self): | ||
4415 | 1080 | self.assertEqual( | ||
4416 | 1081 | '63,270272,0x0C,*\n270336,524288,L\n794624,524288,L\n' \ | ||
4417 | 1082 | '1318912,-,E\n1318912,1048576,L\n2367488,,,-', | ||
4418 | 1083 | android_boards.AndroidPandaConfig.get_sfdisk_cmd()) | ||
4419 | 1084 | |||
4420 | 1085 | def test_snowball_emmc_android(self): | ||
4421 | 1086 | self.assertEqual( | ||
4422 | 1087 | '256,7936,0xDA\n8192,262144,0x0C,*\n270336,524288,L\n' \ | ||
4423 | 1088 | '794624,-,E\n794624,524288,L\n1318912,1048576,L\n2367488,,,-', | ||
4424 | 1089 | android_boards.AndroidSnowballEmmcConfig.get_sfdisk_cmd()) | ||
4425 | 1090 | |||
4426 | 357 | 1091 | ||
4427 | 358 | class TestGetBootCmd(TestCase): | 1092 | class TestGetBootCmd(TestCase): |
4428 | 359 | 1093 | ||
4429 | @@ -396,6 +1130,18 @@ | |||
4430 | 396 | 'ethaddr': '00:40:5c:26:0a:5b'} | 1130 | 'ethaddr': '00:40:5c:26:0a:5b'} |
4431 | 397 | self.assertEqual(expected, boot_commands) | 1131 | self.assertEqual(expected, boot_commands) |
4432 | 398 | 1132 | ||
4433 | 1133 | def test_origen(self): | ||
4434 | 1134 | boot_commands = board_configs['origen']._get_boot_env( | ||
4435 | 1135 | is_live=False, is_lowmem=False, consoles=[], | ||
4436 | 1136 | rootfs_uuid="deadbeef", d_img_data=None) | ||
4437 | 1137 | expected = { | ||
4438 | 1138 | 'bootargs': 'console=ttySAC2,115200n8 root=UUID=deadbeef ' | ||
4439 | 1139 | 'rootwait ro', | ||
4440 | 1140 | 'bootcmd': 'fatload mmc 0:2 0x40007000 uImage; ' | ||
4441 | 1141 | 'fatload mmc 0:2 0x42000000 uInitrd; ' | ||
4442 | 1142 | 'bootm 0x40007000 0x42000000'} | ||
4443 | 1143 | self.assertEqual(expected, boot_commands) | ||
4444 | 1144 | |||
4445 | 399 | def test_ux500(self): | 1145 | def test_ux500(self): |
4446 | 400 | boot_commands = board_configs['ux500']._get_boot_env( | 1146 | boot_commands = board_configs['ux500']._get_boot_env( |
4447 | 401 | is_live=False, is_lowmem=False, consoles=[], | 1147 | is_live=False, is_lowmem=False, consoles=[], |
4448 | @@ -509,6 +1255,41 @@ | |||
4449 | 509 | self.assertEqual(expected, boot_commands) | 1255 | self.assertEqual(expected, boot_commands) |
4450 | 510 | 1256 | ||
4451 | 511 | 1257 | ||
4452 | 1258 | class TestGetBootCmdAndroid(TestCase): | ||
4453 | 1259 | def test_panda(self): | ||
4454 | 1260 | # XXX: To fix bug 697824 we have to change class attributes of our | ||
4455 | 1261 | # OMAP board configs, and some tests do that so to make sure they | ||
4456 | 1262 | # don't interfere with us we'll reset that before doing anything. | ||
4457 | 1263 | config = android_board_configs['panda'] | ||
4458 | 1264 | config.serial_tty = config._serial_tty | ||
4459 | 1265 | boot_commands = config._get_boot_env(consoles=[]) | ||
4460 | 1266 | expected = { | ||
4461 | 1267 | 'bootargs': 'console=tty0 console=ttyO2,115200n8 ' | ||
4462 | 1268 | 'rootwait ro earlyprintk fixrtc ' | ||
4463 | 1269 | 'nocompcache vram=48M omapfb.vram=0:24M,1:24M ' | ||
4464 | 1270 | 'mem=456M@0x80000000 mem=512M@0xA0000000 ' | ||
4465 | 1271 | 'init=/init androidboot.console=ttyO2', | ||
4466 | 1272 | 'bootcmd': 'fatload mmc 0:1 0x80200000 uImage; ' | ||
4467 | 1273 | 'fatload mmc 0:1 0x81600000 uInitrd; ' | ||
4468 | 1274 | 'bootm 0x80200000 0x81600000'} | ||
4469 | 1275 | self.assertEqual(expected, boot_commands) | ||
4470 | 1276 | |||
4471 | 1277 | def test_android_snowball_emmc(self): | ||
4472 | 1278 | boot_commands = (android_boards.AndroidSnowballEmmcConfig. | ||
4473 | 1279 | _get_boot_env(consoles=[])) | ||
4474 | 1280 | expected = { | ||
4475 | 1281 | 'bootargs': 'console=tty0 console=ttyAMA2,115200n8 ' | ||
4476 | 1282 | 'rootwait ro earlyprintk ' | ||
4477 | 1283 | 'rootdelay=1 fixrtc nocompcache ' | ||
4478 | 1284 | 'mem=128M@0 mali.mali_mem=64M@128M mem=24M@192M ' | ||
4479 | 1285 | 'hwmem=167M@216M mem_issw=1M@383M mem=640M@384M ' | ||
4480 | 1286 | 'vmalloc=256M init=/init androidboot.console=ttyAMA2', | ||
4481 | 1287 | 'bootcmd': 'fatload mmc 1:1 0x00100000 uImage; ' | ||
4482 | 1288 | 'fatload mmc 1:1 0x08000000 uInitrd; ' | ||
4483 | 1289 | 'bootm 0x00100000 0x08000000'} | ||
4484 | 1290 | self.assertEqual(expected, boot_commands) | ||
4485 | 1291 | |||
4486 | 1292 | |||
4487 | 512 | class TestUnpackBinaryTarball(TestCaseWithFixtures): | 1293 | class TestUnpackBinaryTarball(TestCaseWithFixtures): |
4488 | 513 | 1294 | ||
4489 | 514 | def setUp(self): | 1295 | def setUp(self): |
4490 | @@ -607,7 +1388,8 @@ | |||
4491 | 607 | def test_install_mx5_boot_loader(self): | 1388 | def test_install_mx5_boot_loader(self): |
4492 | 608 | fixture = self._mock_Popen() | 1389 | fixture = self._mock_Popen() |
4493 | 609 | imx_file = self.createTempFileAsFixture() | 1390 | imx_file = self.createTempFileAsFixture() |
4495 | 610 | install_mx5_boot_loader(imx_file, "boot_device_or_file") | 1391 | install_mx5_boot_loader(imx_file, "boot_device_or_file", |
4496 | 1392 | BoardConfig.LOADER_MIN_SIZE_S) | ||
4497 | 611 | expected = [ | 1393 | expected = [ |
4498 | 612 | '%s dd if=%s of=boot_device_or_file bs=512 ' | 1394 | '%s dd if=%s of=boot_device_or_file bs=512 ' |
4499 | 613 | 'conv=notrunc seek=2' % (sudo_args, imx_file)] | 1395 | 'conv=notrunc seek=2' % (sudo_args, imx_file)] |
4500 | @@ -616,9 +1398,10 @@ | |||
4501 | 616 | def test_install_mx5_boot_loader_too_large(self): | 1398 | def test_install_mx5_boot_loader_too_large(self): |
4502 | 617 | self.useFixture(MockSomethingFixture( | 1399 | self.useFixture(MockSomethingFixture( |
4503 | 618 | os.path, "getsize", | 1400 | os.path, "getsize", |
4505 | 619 | lambda s: (LOADER_MIN_SIZE_S - 1) * SECTOR_SIZE + 1)) | 1401 | lambda s: (BoardConfig.LOADER_MIN_SIZE_S - 1) * SECTOR_SIZE + 1)) |
4506 | 620 | self.assertRaises(AssertionError, | 1402 | self.assertRaises(AssertionError, |
4508 | 621 | install_mx5_boot_loader, "imx_file", "boot_device_or_file") | 1403 | install_mx5_boot_loader, "imx_file", "boot_device_or_file", |
4509 | 1404 | BoardConfig.LOADER_MIN_SIZE_S) | ||
4510 | 622 | 1405 | ||
4511 | 623 | def test_install_omap_boot_loader(self): | 1406 | def test_install_omap_boot_loader(self): |
4512 | 624 | fixture = self._mock_Popen() | 1407 | fixture = self._mock_Popen() |
4513 | @@ -630,6 +1413,58 @@ | |||
4514 | 630 | '%s cp -v chroot_dir/MLO boot_disk' % sudo_args, 'sync'] | 1413 | '%s cp -v chroot_dir/MLO boot_disk' % sudo_args, 'sync'] |
4515 | 631 | self.assertEqual(expected, fixture.mock.commands_executed) | 1414 | self.assertEqual(expected, fixture.mock.commands_executed) |
4516 | 632 | 1415 | ||
4517 | 1416 | def test_install_smdk_u_boot(self): | ||
4518 | 1417 | fixture = self._mock_Popen() | ||
4519 | 1418 | uboot_flavor = boards.SMDKV310Config.uboot_flavor | ||
4520 | 1419 | self.useFixture(MockSomethingFixture( | ||
4521 | 1420 | boards.SMDKV310Config, '_get_samsung_spl', | ||
4522 | 1421 | classmethod(lambda cls, chroot_dir: "%s/%s/SPL" % ( | ||
4523 | 1422 | chroot_dir, uboot_flavor)))) | ||
4524 | 1423 | self.useFixture(MockSomethingFixture( | ||
4525 | 1424 | boards.SMDKV310Config, '_get_samsung_uboot', | ||
4526 | 1425 | classmethod(lambda cls, chroot_dir: "%s/%s/uboot" % ( | ||
4527 | 1426 | chroot_dir, uboot_flavor)))) | ||
4528 | 1427 | boards.SMDKV310Config.hardwarepack_handler = ( | ||
4529 | 1428 | TestSetMetadata.MockHardwarepackHandler('ahwpack.tar.gz')) | ||
4530 | 1429 | boards.SMDKV310Config.hardwarepack_handler.get_format = ( | ||
4531 | 1430 | lambda: '1.0') | ||
4532 | 1431 | self.useFixture(MockSomethingFixture(os.path, 'getsize', | ||
4533 | 1432 | lambda file: 1)) | ||
4534 | 1433 | boards.SMDKV310Config.install_samsung_boot_loader( | ||
4535 | 1434 | "chroot_dir", "boot_disk") | ||
4536 | 1435 | expected = [ | ||
4537 | 1436 | '%s dd if=chroot_dir/%s/SPL of=boot_disk bs=512 conv=notrunc ' | ||
4538 | 1437 | 'seek=%d' % (sudo_args, uboot_flavor, SAMSUNG_V310_BL1_START), | ||
4539 | 1438 | '%s dd if=chroot_dir/%s/uboot of=boot_disk bs=512 conv=notrunc ' | ||
4540 | 1439 | 'seek=%d' % (sudo_args, uboot_flavor, SAMSUNG_V310_BL2_START)] | ||
4541 | 1440 | self.assertEqual(expected, fixture.mock.commands_executed) | ||
4542 | 1441 | |||
4543 | 1442 | def test_install_origen_u_boot(self): | ||
4544 | 1443 | fixture = self._mock_Popen() | ||
4545 | 1444 | uboot_flavor = boards.OrigenConfig.uboot_flavor | ||
4546 | 1445 | self.useFixture(MockSomethingFixture( | ||
4547 | 1446 | boards.OrigenConfig, '_get_samsung_spl', | ||
4548 | 1447 | classmethod(lambda cls, chroot_dir: "%s/%s/SPL" % ( | ||
4549 | 1448 | chroot_dir, uboot_flavor)))) | ||
4550 | 1449 | self.useFixture(MockSomethingFixture( | ||
4551 | 1450 | boards.OrigenConfig, '_get_samsung_uboot', | ||
4552 | 1451 | classmethod(lambda cls, chroot_dir: "%s/%s/uboot" % ( | ||
4553 | 1452 | chroot_dir, uboot_flavor)))) | ||
4554 | 1453 | boards.OrigenConfig.hardwarepack_handler = ( | ||
4555 | 1454 | TestSetMetadata.MockHardwarepackHandler('ahwpack.tar.gz')) | ||
4556 | 1455 | boards.OrigenConfig.hardwarepack_handler.get_format = ( | ||
4557 | 1456 | lambda: '1.0') | ||
4558 | 1457 | self.useFixture(MockSomethingFixture(os.path, 'getsize', | ||
4559 | 1458 | lambda file: 1)) | ||
4560 | 1459 | boards.OrigenConfig.install_samsung_boot_loader( | ||
4561 | 1460 | "chroot_dir", "boot_disk") | ||
4562 | 1461 | expected = [ | ||
4563 | 1462 | '%s dd if=chroot_dir/%s/SPL of=boot_disk bs=512 conv=notrunc ' | ||
4564 | 1463 | 'seek=%d' % (sudo_args, uboot_flavor, SAMSUNG_V310_BL1_START), | ||
4565 | 1464 | '%s dd if=chroot_dir/%s/uboot of=boot_disk bs=512 conv=notrunc ' | ||
4566 | 1465 | 'seek=%d' % (sudo_args, uboot_flavor, SAMSUNG_V310_BL2_START)] | ||
4567 | 1466 | self.assertEqual(expected, fixture.mock.commands_executed) | ||
4568 | 1467 | |||
4569 | 633 | def test_get_plain_boot_script_contents(self): | 1468 | def test_get_plain_boot_script_contents(self): |
4570 | 634 | boot_env = {'bootargs': 'mybootargs', 'bootcmd': 'mybootcmd'} | 1469 | boot_env = {'bootargs': 'mybootargs', 'bootcmd': 'mybootcmd'} |
4571 | 635 | boot_script_data = get_plain_boot_script_contents(boot_env) | 1470 | boot_script_data = get_plain_boot_script_contents(boot_env) |
4572 | @@ -820,6 +1655,25 @@ | |||
4573 | 820 | [('1,8191,0xDA\n8192,106496,0x0C,*\n114688,,,-', HEADS, | 1655 | [('1,8191,0xDA\n8192,106496,0x0C,*\n114688,,,-', HEADS, |
4574 | 821 | SECTORS, '', self.media.path)], sfdisk_fixture.mock.calls) | 1656 | SECTORS, '', self.media.path)], sfdisk_fixture.mock.calls) |
4575 | 822 | 1657 | ||
4576 | 1658 | def test_create_partitions_for_origen(self): | ||
4577 | 1659 | # For this board we create a one cylinder partition at the beginning. | ||
4578 | 1660 | popen_fixture = self.useFixture(MockCmdRunnerPopenFixture()) | ||
4579 | 1661 | sfdisk_fixture = self.useFixture(MockRunSfdiskCommandsFixture()) | ||
4580 | 1662 | |||
4581 | 1663 | create_partitions( | ||
4582 | 1664 | board_configs['origen'], self.media, HEADS, SECTORS, '') | ||
4583 | 1665 | |||
4584 | 1666 | self.assertEqual( | ||
4585 | 1667 | ['%s parted -s %s mklabel msdos' % (sudo_args, self.media.path), | ||
4586 | 1668 | 'sync'], | ||
4587 | 1669 | popen_fixture.mock.commands_executed) | ||
4588 | 1670 | # Notice that we create all partitions in a single sfdisk run because | ||
4589 | 1671 | # every time we run sfdisk it actually repartitions the device, | ||
4590 | 1672 | # erasing any partitions created previously. | ||
4591 | 1673 | self.assertEqual( | ||
4592 | 1674 | [('1,8191,0xDA\n8192,106496,0x0C,*\n114688,,,-', HEADS, | ||
4593 | 1675 | SECTORS, '', self.media.path)], sfdisk_fixture.mock.calls) | ||
4594 | 1676 | |||
4595 | 823 | def test_create_partitions_for_beagle(self): | 1677 | def test_create_partitions_for_beagle(self): |
4596 | 824 | popen_fixture = self.useFixture(MockCmdRunnerPopenFixture()) | 1678 | popen_fixture = self.useFixture(MockCmdRunnerPopenFixture()) |
4597 | 825 | sfdisk_fixture = self.useFixture(MockRunSfdiskCommandsFixture()) | 1679 | sfdisk_fixture = self.useFixture(MockRunSfdiskCommandsFixture()) |
4598 | @@ -893,13 +1747,21 @@ | |||
4599 | 893 | (63 * SECTOR_SIZE, 32768 * SECTOR_SIZE), | 1747 | (63 * SECTOR_SIZE, 32768 * SECTOR_SIZE), |
4600 | 894 | (32831 * SECTOR_SIZE, 65536 * SECTOR_SIZE), | 1748 | (32831 * SECTOR_SIZE, 65536 * SECTOR_SIZE), |
4601 | 895 | (98367 * SECTOR_SIZE, 65536 * SECTOR_SIZE), | 1749 | (98367 * SECTOR_SIZE, 65536 * SECTOR_SIZE), |
4602 | 896 | (294975 * SECTOR_SIZE, (self.android_image_size - | ||
4603 | 897 | 294975 * SECTOR_SIZE)), | ||
4604 | 898 | ((294975 + ext_part_size) * SECTOR_SIZE, | 1750 | ((294975 + ext_part_size) * SECTOR_SIZE, |
4605 | 899 | (131072 - ext_part_size) * SECTOR_SIZE), | 1751 | (131072 - ext_part_size) * SECTOR_SIZE), |
4606 | 900 | ((426047 + ext_part_size) * SECTOR_SIZE, | 1752 | ((426047 + ext_part_size) * SECTOR_SIZE, |
4607 | 901 | self.android_image_size - (426047 + ext_part_size) * SECTOR_SIZE) | 1753 | self.android_image_size - (426047 + ext_part_size) * SECTOR_SIZE) |
4608 | 902 | ] | 1754 | ] |
4609 | 1755 | |||
4610 | 1756 | self.android_snowball_offsets_and_sizes = [ | ||
4611 | 1757 | (8192 * SECTOR_SIZE, 24639 * SECTOR_SIZE), | ||
4612 | 1758 | (32831 * SECTOR_SIZE, 65536 * SECTOR_SIZE), | ||
4613 | 1759 | ((98367 + ext_part_size)* SECTOR_SIZE, | ||
4614 | 1760 | (65536 - ext_part_size) * SECTOR_SIZE), | ||
4615 | 1761 | (294975 * SECTOR_SIZE, 131072 * SECTOR_SIZE), | ||
4616 | 1762 | ((426047 + ext_part_size) * SECTOR_SIZE, | ||
4617 | 1763 | self.android_image_size - (426047 + ext_part_size) * SECTOR_SIZE) | ||
4618 | 1764 | ] | ||
4619 | 903 | 1765 | ||
4620 | 904 | def tearDown(self): | 1766 | def tearDown(self): |
4621 | 905 | super(TestPartitionSetup, self).tearDown() | 1767 | super(TestPartitionSetup, self).tearDown() |
4622 | @@ -916,6 +1778,13 @@ | |||
4623 | 916 | '63,32768,0x0C,*\n32831,65536,L\n98367,65536,L\n294975,-,E\n' \ | 1778 | '63,32768,0x0C,*\n32831,65536,L\n98367,65536,L\n294975,-,E\n' \ |
4624 | 917 | '294975,131072,L\n426047,,,-', '%s' % self.android_image_size) | 1779 | '294975,131072,L\n426047,,,-', '%s' % self.android_image_size) |
4625 | 918 | 1780 | ||
4626 | 1781 | def _create_snowball_android_tmpfile(self): | ||
4627 | 1782 | # raw, boot, system, cache, (extended), userdata and sdcard partitions | ||
4628 | 1783 | return self._create_qemu_img_with_partitions( | ||
4629 | 1784 | '256,7936,0xDA\n8192,24639,0x0C,*\n32831,65536,L\n' \ | ||
4630 | 1785 | '98367,-,E\n98367,65536,L\n294975,131072,L\n' \ | ||
4631 | 1786 | '426047,,,-', '%s' % self.android_image_size) | ||
4632 | 1787 | |||
4633 | 919 | def test_convert_size_no_suffix(self): | 1788 | def test_convert_size_no_suffix(self): |
4634 | 920 | self.assertEqual(524288, convert_size_to_bytes('524288')) | 1789 | self.assertEqual(524288, convert_size_to_bytes('524288')) |
4635 | 921 | 1790 | ||
4636 | @@ -945,6 +1814,15 @@ | |||
4637 | 945 | self.android_offsets_and_sizes): | 1814 | self.android_offsets_and_sizes): |
4638 | 946 | self.assertEqual(device_pair, expected_pair) | 1815 | self.assertEqual(device_pair, expected_pair) |
4639 | 947 | 1816 | ||
4640 | 1817 | def test_calculate_snowball_android_partition_size_and_offset(self): | ||
4641 | 1818 | tmpfile = self._create_snowball_android_tmpfile() | ||
4642 | 1819 | device_info = calculate_android_partition_size_and_offset(tmpfile) | ||
4643 | 1820 | # We use map(None, ...) since it would catch if the lists are not of | ||
4644 | 1821 | # equal length and zip() would not in all cases. | ||
4645 | 1822 | for device_pair, expected_pair in map(None, device_info, | ||
4646 | 1823 | self.android_snowball_offsets_and_sizes): | ||
4647 | 1824 | self.assertEqual(device_pair, expected_pair) | ||
4648 | 1825 | |||
4649 | 948 | def test_partition_numbering(self): | 1826 | def test_partition_numbering(self): |
4650 | 949 | # another Linux partition at +24 MiB after the boot/root parts | 1827 | # another Linux partition at +24 MiB after the boot/root parts |
4651 | 950 | tmpfile = self._create_qemu_img_with_partitions( | 1828 | tmpfile = self._create_qemu_img_with_partitions( |
4652 | @@ -1054,7 +1932,7 @@ | |||
4653 | 1054 | 1932 | ||
4654 | 1055 | # get_boot_and_root_loopback_devices will also setup two exit handlers | 1933 | # get_boot_and_root_loopback_devices will also setup two exit handlers |
4655 | 1056 | # to de-register the loopback devices set up above. | 1934 | # to de-register the loopback devices set up above. |
4657 | 1057 | self.assertEqual(6, len(atexit_fixture.mock.funcs)) | 1935 | self.assertEqual(5, len(atexit_fixture.mock.funcs)) |
4658 | 1058 | popen_fixture.mock.calls = [] | 1936 | popen_fixture.mock.calls = [] |
4659 | 1059 | atexit_fixture.mock.run_funcs() | 1937 | atexit_fixture.mock.run_funcs() |
4660 | 1060 | # We did not really run losetup above (as it requires root) so here we | 1938 | # We did not really run losetup above (as it requires root) so here we |
4661 | @@ -1065,7 +1943,6 @@ | |||
4662 | 1065 | '%s losetup -d ' % sudo_args, | 1943 | '%s losetup -d ' % sudo_args, |
4663 | 1066 | '%s losetup -d ' % sudo_args, | 1944 | '%s losetup -d ' % sudo_args, |
4664 | 1067 | '%s losetup -d ' % sudo_args, | 1945 | '%s losetup -d ' % sudo_args, |
4665 | 1068 | '%s losetup -d ' % sudo_args, | ||
4666 | 1069 | '%s losetup -d ' % sudo_args], | 1946 | '%s losetup -d ' % sudo_args], |
4667 | 1070 | popen_fixture.mock.commands_executed) | 1947 | popen_fixture.mock.commands_executed) |
4668 | 1071 | 1948 | ||
4669 | @@ -1159,6 +2036,9 @@ | |||
4670 | 1159 | 2036 | ||
4671 | 1160 | self.config = c | 2037 | self.config = c |
4672 | 1161 | self.config.boot_script = 'boot_script' | 2038 | self.config.boot_script = 'boot_script' |
4673 | 2039 | self.config.hardwarepack_handler = \ | ||
4674 | 2040 | TestSetMetadata.MockHardwarepackHandler('ahwpack.tar.gz') | ||
4675 | 2041 | self.config.hardwarepack_handler.get_format = lambda: '1.0' | ||
4676 | 1162 | self.popen_fixture = self.useFixture(MockCmdRunnerPopenFixture()) | 2042 | self.popen_fixture = self.useFixture(MockCmdRunnerPopenFixture()) |
4677 | 1163 | self.useFixture(MockSomethingFixture( | 2043 | self.useFixture(MockSomethingFixture( |
4678 | 1164 | self.config, 'make_boot_files', self.save_args)) | 2044 | self.config, 'make_boot_files', self.save_args)) |
4679 | @@ -1241,6 +2121,14 @@ | |||
4680 | 1241 | os.makedirs(contents_bin) | 2121 | os.makedirs(contents_bin) |
4681 | 1242 | os.makedirs(contents_etc) | 2122 | os.makedirs(contents_etc) |
4682 | 1243 | 2123 | ||
4683 | 2124 | # Must mock rootfs._list_files() because populate_rootfs() uses its | ||
4684 | 2125 | # return value but since we mock cmd_runner.run() _list_files() would | ||
4685 | 2126 | # return an invalid value. | ||
4686 | 2127 | def mock_list_files(directory): | ||
4687 | 2128 | return [contents_bin, contents_etc] | ||
4688 | 2129 | self.useFixture(MockSomethingFixture( | ||
4689 | 2130 | rootfs, '_list_files', mock_list_files)) | ||
4690 | 2131 | |||
4691 | 1244 | populate_rootfs( | 2132 | populate_rootfs( |
4692 | 1245 | contents_dir, root_disk, partition='/dev/rootfs', | 2133 | contents_dir, root_disk, partition='/dev/rootfs', |
4693 | 1246 | rootfs_type='ext3', rootfs_uuid='uuid', should_create_swap=True, | 2134 | rootfs_type='ext3', rootfs_uuid='uuid', should_create_swap=True, |
4694 | @@ -1282,10 +2170,27 @@ | |||
4695 | 1282 | fixture.mock.commands_executed[0]) | 2170 | fixture.mock.commands_executed[0]) |
4696 | 1283 | self.assertEqual('UBOOT_PART=/dev/mmcblk0p1', open(tmpfile).read()) | 2171 | self.assertEqual('UBOOT_PART=/dev/mmcblk0p1', open(tmpfile).read()) |
4697 | 1284 | 2172 | ||
4698 | 2173 | def test_list_files(self): | ||
4699 | 2174 | tempdir = self.useFixture(CreateTempDirFixture()).tempdir | ||
4700 | 2175 | # We don't want to mock cmd_runner.run() because we're testing the | ||
4701 | 2176 | # command that it runs, but we need to monkey-patch SUDO_ARGS because | ||
4702 | 2177 | # we don't want to use 'sudo' in tests. | ||
4703 | 2178 | orig_sudo_args = cmd_runner.SUDO_ARGS | ||
4704 | 2179 | def restore_sudo_args(): | ||
4705 | 2180 | cmd_runner.SUDO_ARGS = orig_sudo_args | ||
4706 | 2181 | self.addCleanup(restore_sudo_args) | ||
4707 | 2182 | cmd_runner.SUDO_ARGS = [] | ||
4708 | 2183 | file1 = self.createTempFileAsFixture(dir=tempdir) | ||
4709 | 2184 | self.assertEqual([file1], rootfs._list_files(tempdir)) | ||
4710 | 2185 | |||
4711 | 1285 | def test_move_contents(self): | 2186 | def test_move_contents(self): |
4712 | 1286 | tempdir = self.useFixture(CreateTempDirFixture()).tempdir | 2187 | tempdir = self.useFixture(CreateTempDirFixture()).tempdir |
4713 | 1287 | popen_fixture = self.useFixture(MockCmdRunnerPopenFixture()) | 2188 | popen_fixture = self.useFixture(MockCmdRunnerPopenFixture()) |
4714 | 1288 | file1 = self.createTempFileAsFixture(dir=tempdir) | 2189 | file1 = self.createTempFileAsFixture(dir=tempdir) |
4715 | 2190 | def mock_list_files(directory): | ||
4716 | 2191 | return [file1] | ||
4717 | 2192 | self.useFixture(MockSomethingFixture( | ||
4718 | 2193 | rootfs, '_list_files', mock_list_files)) | ||
4719 | 1289 | 2194 | ||
4720 | 1290 | move_contents(tempdir, '/tmp/') | 2195 | move_contents(tempdir, '/tmp/') |
4721 | 1291 | 2196 | ||
4722 | 1292 | 2197 | ||
4723 | === modified file 'setup.py' | |||
4724 | --- setup.py 2011-05-26 20:32:40 +0000 | |||
4725 | +++ setup.py 2011-07-18 14:39:34 +0000 | |||
4726 | @@ -5,7 +5,7 @@ | |||
4727 | 5 | 5 | ||
4728 | 6 | DistUtilsExtra.auto.setup( | 6 | DistUtilsExtra.auto.setup( |
4729 | 7 | name="linaro-image-tools", | 7 | name="linaro-image-tools", |
4731 | 8 | version="0.4.8.1", | 8 | version="2011.06-1.1", |
4732 | 9 | description="Tools to create and write Linaro images", | 9 | description="Tools to create and write Linaro images", |
4733 | 10 | url="https://launchpad.net/linaro-image-tools", | 10 | url="https://launchpad.net/linaro-image-tools", |
4734 | 11 | license="GPL v3 or later", | 11 | license="GPL v3 or later", |