diff options
Diffstat (limited to 'bitbake/lib/bb/ui/crumbs/hobeventhandler.py')
-rw-r--r-- | bitbake/lib/bb/ui/crumbs/hobeventhandler.py | 624 |
1 files changed, 624 insertions, 0 deletions
diff --git a/bitbake/lib/bb/ui/crumbs/hobeventhandler.py b/bitbake/lib/bb/ui/crumbs/hobeventhandler.py new file mode 100644 index 0000000000..393c258e46 --- /dev/null +++ b/bitbake/lib/bb/ui/crumbs/hobeventhandler.py | |||
@@ -0,0 +1,624 @@ | |||
1 | # | ||
2 | # BitBake Graphical GTK User Interface | ||
3 | # | ||
4 | # Copyright (C) 2011 Intel Corporation | ||
5 | # | ||
6 | # Authored by Joshua Lock <josh@linux.intel.com> | ||
7 | # Authored by Dongxiao Xu <dongxiao.xu@intel.com> | ||
8 | # | ||
9 | # This program is free software; you can redistribute it and/or modify | ||
10 | # it under the terms of the GNU General Public License version 2 as | ||
11 | # published by the Free Software Foundation. | ||
12 | # | ||
13 | # This program is distributed in the hope that it will be useful, | ||
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | # GNU General Public License for more details. | ||
17 | # | ||
18 | # You should have received a copy of the GNU General Public License along | ||
19 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
21 | |||
22 | import gobject | ||
23 | import logging | ||
24 | import ast | ||
25 | from bb.ui.crumbs.runningbuild import RunningBuild | ||
26 | |||
27 | class HobHandler(gobject.GObject): | ||
28 | |||
29 | """ | ||
30 | This object does BitBake event handling for the hob gui. | ||
31 | """ | ||
32 | __gsignals__ = { | ||
33 | "package-formats-updated" : (gobject.SIGNAL_RUN_LAST, | ||
34 | gobject.TYPE_NONE, | ||
35 | (gobject.TYPE_PYOBJECT,)), | ||
36 | "config-updated" : (gobject.SIGNAL_RUN_LAST, | ||
37 | gobject.TYPE_NONE, | ||
38 | (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT,)), | ||
39 | "command-succeeded" : (gobject.SIGNAL_RUN_LAST, | ||
40 | gobject.TYPE_NONE, | ||
41 | (gobject.TYPE_INT,)), | ||
42 | "command-failed" : (gobject.SIGNAL_RUN_LAST, | ||
43 | gobject.TYPE_NONE, | ||
44 | (gobject.TYPE_STRING,)), | ||
45 | "parsing-warning" : (gobject.SIGNAL_RUN_LAST, | ||
46 | gobject.TYPE_NONE, | ||
47 | (gobject.TYPE_STRING,)), | ||
48 | "sanity-failed" : (gobject.SIGNAL_RUN_LAST, | ||
49 | gobject.TYPE_NONE, | ||
50 | (gobject.TYPE_STRING, gobject.TYPE_INT)), | ||
51 | "generating-data" : (gobject.SIGNAL_RUN_LAST, | ||
52 | gobject.TYPE_NONE, | ||
53 | ()), | ||
54 | "data-generated" : (gobject.SIGNAL_RUN_LAST, | ||
55 | gobject.TYPE_NONE, | ||
56 | ()), | ||
57 | "parsing-started" : (gobject.SIGNAL_RUN_LAST, | ||
58 | gobject.TYPE_NONE, | ||
59 | (gobject.TYPE_PYOBJECT,)), | ||
60 | "parsing" : (gobject.SIGNAL_RUN_LAST, | ||
61 | gobject.TYPE_NONE, | ||
62 | (gobject.TYPE_PYOBJECT,)), | ||
63 | "parsing-completed" : (gobject.SIGNAL_RUN_LAST, | ||
64 | gobject.TYPE_NONE, | ||
65 | (gobject.TYPE_PYOBJECT,)), | ||
66 | "recipe-populated" : (gobject.SIGNAL_RUN_LAST, | ||
67 | gobject.TYPE_NONE, | ||
68 | ()), | ||
69 | "package-populated" : (gobject.SIGNAL_RUN_LAST, | ||
70 | gobject.TYPE_NONE, | ||
71 | ()), | ||
72 | "network-passed" : (gobject.SIGNAL_RUN_LAST, | ||
73 | gobject.TYPE_NONE, | ||
74 | ()), | ||
75 | "network-failed" : (gobject.SIGNAL_RUN_LAST, | ||
76 | gobject.TYPE_NONE, | ||
77 | ()), | ||
78 | } | ||
79 | |||
80 | (GENERATE_CONFIGURATION, GENERATE_RECIPES, GENERATE_PACKAGES, GENERATE_IMAGE, POPULATE_PACKAGEINFO, SANITY_CHECK, NETWORK_TEST) = range(7) | ||
81 | (SUB_PATH_LAYERS, SUB_FILES_DISTRO, SUB_FILES_MACH, SUB_FILES_SDKMACH, SUB_MATCH_CLASS, SUB_PARSE_CONFIG, SUB_SANITY_CHECK, | ||
82 | SUB_GNERATE_TGTS, SUB_GENERATE_PKGINFO, SUB_BUILD_RECIPES, SUB_BUILD_IMAGE, SUB_NETWORK_TEST) = range(12) | ||
83 | |||
84 | def __init__(self, server, recipe_model, package_model): | ||
85 | super(HobHandler, self).__init__() | ||
86 | |||
87 | self.build = RunningBuild(sequential=True) | ||
88 | |||
89 | self.recipe_model = recipe_model | ||
90 | self.package_model = package_model | ||
91 | |||
92 | self.commands_async = [] | ||
93 | self.generating = False | ||
94 | self.current_phase = None | ||
95 | self.building = False | ||
96 | self.recipe_queue = [] | ||
97 | self.package_queue = [] | ||
98 | |||
99 | self.server = server | ||
100 | self.error_msg = "" | ||
101 | self.initcmd = None | ||
102 | self.parsing = False | ||
103 | |||
104 | def set_busy(self): | ||
105 | if not self.generating: | ||
106 | self.emit("generating-data") | ||
107 | self.generating = True | ||
108 | |||
109 | def clear_busy(self): | ||
110 | if self.generating: | ||
111 | self.emit("data-generated") | ||
112 | self.generating = False | ||
113 | |||
114 | def runCommand(self, commandline): | ||
115 | try: | ||
116 | result, error = self.server.runCommand(commandline) | ||
117 | if error: | ||
118 | raise Exception("Error running command '%s': %s" % (commandline, error)) | ||
119 | return result | ||
120 | except Exception as e: | ||
121 | self.commands_async = [] | ||
122 | self.clear_busy() | ||
123 | self.emit("command-failed", "Hob Exception - %s" % (str(e))) | ||
124 | return None | ||
125 | |||
126 | def run_next_command(self, initcmd=None): | ||
127 | if initcmd != None: | ||
128 | self.initcmd = initcmd | ||
129 | |||
130 | if self.commands_async: | ||
131 | self.set_busy() | ||
132 | next_command = self.commands_async.pop(0) | ||
133 | else: | ||
134 | self.clear_busy() | ||
135 | if self.initcmd != None: | ||
136 | self.emit("command-succeeded", self.initcmd) | ||
137 | return | ||
138 | |||
139 | if next_command == self.SUB_PATH_LAYERS: | ||
140 | self.runCommand(["findConfigFilePath", "bblayers.conf"]) | ||
141 | elif next_command == self.SUB_FILES_DISTRO: | ||
142 | self.runCommand(["findConfigFiles", "DISTRO"]) | ||
143 | elif next_command == self.SUB_FILES_MACH: | ||
144 | self.runCommand(["findConfigFiles", "MACHINE"]) | ||
145 | elif next_command == self.SUB_FILES_SDKMACH: | ||
146 | self.runCommand(["findConfigFiles", "MACHINE-SDK"]) | ||
147 | elif next_command == self.SUB_MATCH_CLASS: | ||
148 | self.runCommand(["findFilesMatchingInDir", "rootfs_", "classes"]) | ||
149 | elif next_command == self.SUB_PARSE_CONFIG: | ||
150 | self.runCommand(["enableDataTracking"]) | ||
151 | self.runCommand(["parseConfigurationFiles", "conf/.hob.conf", ""]) | ||
152 | self.runCommand(["disableDataTracking"]) | ||
153 | elif next_command == self.SUB_GNERATE_TGTS: | ||
154 | self.runCommand(["generateTargetsTree", "classes/image.bbclass", []]) | ||
155 | elif next_command == self.SUB_GENERATE_PKGINFO: | ||
156 | self.runCommand(["triggerEvent", "bb.event.RequestPackageInfo()"]) | ||
157 | elif next_command == self.SUB_SANITY_CHECK: | ||
158 | self.runCommand(["triggerEvent", "bb.event.SanityCheck()"]) | ||
159 | elif next_command == self.SUB_NETWORK_TEST: | ||
160 | self.runCommand(["triggerEvent", "bb.event.NetworkTest()"]) | ||
161 | elif next_command == self.SUB_BUILD_RECIPES: | ||
162 | self.clear_busy() | ||
163 | self.building = True | ||
164 | self.runCommand(["buildTargets", self.recipe_queue, self.default_task]) | ||
165 | self.recipe_queue = [] | ||
166 | elif next_command == self.SUB_BUILD_IMAGE: | ||
167 | self.clear_busy() | ||
168 | self.building = True | ||
169 | targets = [self.image] | ||
170 | if self.toolchain_packages: | ||
171 | self.set_var_in_file("TOOLCHAIN_TARGET_TASK", " ".join(self.toolchain_packages), "local.conf") | ||
172 | targets.append(self.toolchain) | ||
173 | if targets[0] == "hob-image": | ||
174 | self.set_var_in_file("LINGUAS_INSTALL", "", "local.conf") | ||
175 | hobImage = self.runCommand(["matchFile", "hob-image.bb"]) | ||
176 | if self.base_image != "Start with an empty image recipe": | ||
177 | baseImage = self.runCommand(["matchFile", self.base_image + ".bb"]) | ||
178 | version = self.runCommand(["generateNewImage", hobImage, baseImage, self.package_queue, True, ""]) | ||
179 | targets[0] += version | ||
180 | self.recipe_model.set_custom_image_version(version) | ||
181 | |||
182 | self.runCommand(["buildTargets", targets, self.default_task]) | ||
183 | |||
184 | def display_error(self): | ||
185 | self.clear_busy() | ||
186 | self.emit("command-failed", self.error_msg) | ||
187 | self.error_msg = "" | ||
188 | if self.building: | ||
189 | self.building = False | ||
190 | |||
191 | def handle_event(self, event): | ||
192 | if not event: | ||
193 | return | ||
194 | if self.building: | ||
195 | self.current_phase = "building" | ||
196 | self.build.handle_event(event) | ||
197 | |||
198 | if isinstance(event, bb.event.PackageInfo): | ||
199 | self.package_model.populate(event._pkginfolist) | ||
200 | self.emit("package-populated") | ||
201 | self.run_next_command() | ||
202 | |||
203 | elif isinstance(event, bb.event.SanityCheckPassed): | ||
204 | reparse = self.runCommand(["getVariable", "BB_INVALIDCONF"]) or None | ||
205 | if reparse is True: | ||
206 | self.set_var_in_file("BB_INVALIDCONF", False, "local.conf") | ||
207 | self.runCommand(["parseConfigurationFiles", "conf/.hob.conf", ""]) | ||
208 | self.run_next_command() | ||
209 | |||
210 | elif isinstance(event, bb.event.SanityCheckFailed): | ||
211 | self.emit("sanity-failed", event._msg, event._network_error) | ||
212 | |||
213 | elif isinstance(event, logging.LogRecord): | ||
214 | if not self.building: | ||
215 | if event.levelno >= logging.ERROR: | ||
216 | formatter = bb.msg.BBLogFormatter() | ||
217 | msg = formatter.format(event) | ||
218 | self.error_msg += msg + '\n' | ||
219 | elif event.levelno >= logging.WARNING and self.parsing == True: | ||
220 | formatter = bb.msg.BBLogFormatter() | ||
221 | msg = formatter.format(event) | ||
222 | warn_msg = msg + '\n' | ||
223 | self.emit("parsing-warning", warn_msg) | ||
224 | |||
225 | elif isinstance(event, bb.event.TargetsTreeGenerated): | ||
226 | self.current_phase = "data generation" | ||
227 | if event._model: | ||
228 | self.recipe_model.populate(event._model) | ||
229 | self.emit("recipe-populated") | ||
230 | elif isinstance(event, bb.event.ConfigFilesFound): | ||
231 | self.current_phase = "configuration lookup" | ||
232 | var = event._variable | ||
233 | values = event._values | ||
234 | values.sort() | ||
235 | self.emit("config-updated", var, values) | ||
236 | elif isinstance(event, bb.event.ConfigFilePathFound): | ||
237 | self.current_phase = "configuration lookup" | ||
238 | elif isinstance(event, bb.event.FilesMatchingFound): | ||
239 | self.current_phase = "configuration lookup" | ||
240 | # FIXME: hard coding, should at least be a variable shared between | ||
241 | # here and the caller | ||
242 | if event._pattern == "rootfs_": | ||
243 | formats = [] | ||
244 | for match in event._matches: | ||
245 | classname, sep, cls = match.rpartition(".") | ||
246 | fs, sep, format = classname.rpartition("_") | ||
247 | formats.append(format) | ||
248 | formats.sort() | ||
249 | self.emit("package-formats-updated", formats) | ||
250 | elif isinstance(event, bb.command.CommandCompleted): | ||
251 | self.current_phase = None | ||
252 | self.run_next_command() | ||
253 | elif isinstance(event, bb.command.CommandFailed): | ||
254 | self.commands_async = [] | ||
255 | self.display_error() | ||
256 | elif isinstance(event, (bb.event.ParseStarted, | ||
257 | bb.event.CacheLoadStarted, | ||
258 | bb.event.TreeDataPreparationStarted, | ||
259 | )): | ||
260 | message = {} | ||
261 | message["eventname"] = bb.event.getName(event) | ||
262 | message["current"] = 0 | ||
263 | message["total"] = None | ||
264 | message["title"] = "Parsing recipes" | ||
265 | self.emit("parsing-started", message) | ||
266 | if isinstance(event, bb.event.ParseStarted): | ||
267 | self.parsing = True | ||
268 | elif isinstance(event, (bb.event.ParseProgress, | ||
269 | bb.event.CacheLoadProgress, | ||
270 | bb.event.TreeDataPreparationProgress)): | ||
271 | message = {} | ||
272 | message["eventname"] = bb.event.getName(event) | ||
273 | message["current"] = event.current | ||
274 | message["total"] = event.total | ||
275 | message["title"] = "Parsing recipes" | ||
276 | self.emit("parsing", message) | ||
277 | elif isinstance(event, (bb.event.ParseCompleted, | ||
278 | bb.event.CacheLoadCompleted, | ||
279 | bb.event.TreeDataPreparationCompleted)): | ||
280 | message = {} | ||
281 | message["eventname"] = bb.event.getName(event) | ||
282 | message["current"] = event.total | ||
283 | message["total"] = event.total | ||
284 | message["title"] = "Parsing recipes" | ||
285 | self.emit("parsing-completed", message) | ||
286 | if isinstance(event, bb.event.ParseCompleted): | ||
287 | self.parsing = False | ||
288 | elif isinstance(event, bb.event.NetworkTestFailed): | ||
289 | self.emit("network-failed") | ||
290 | self.run_next_command() | ||
291 | elif isinstance(event, bb.event.NetworkTestPassed): | ||
292 | self.emit("network-passed") | ||
293 | self.run_next_command() | ||
294 | |||
295 | if self.error_msg and not self.commands_async: | ||
296 | self.display_error() | ||
297 | |||
298 | return | ||
299 | |||
300 | def init_cooker(self): | ||
301 | self.runCommand(["initCooker"]) | ||
302 | self.runCommand(["createConfigFile", ".hob.conf"]) | ||
303 | |||
304 | def reset_cooker(self): | ||
305 | self.runCommand(["enableDataTracking"]) | ||
306 | self.runCommand(["resetCooker"]) | ||
307 | self.runCommand(["disableDataTracking"]) | ||
308 | |||
309 | def set_extra_inherit(self, bbclass): | ||
310 | inherits = self.runCommand(["getVariable", "INHERIT"]) or "" | ||
311 | inherits = inherits + " " + bbclass | ||
312 | self.set_var_in_file("INHERIT", inherits, ".hob.conf") | ||
313 | |||
314 | def set_bblayers(self, bblayers): | ||
315 | self.set_var_in_file("BBLAYERS", " ".join(bblayers), "bblayers.conf") | ||
316 | |||
317 | def set_machine(self, machine): | ||
318 | if machine: | ||
319 | self.early_assign_var_in_file("MACHINE", machine, "local.conf") | ||
320 | |||
321 | def set_sdk_machine(self, sdk_machine): | ||
322 | self.set_var_in_file("SDKMACHINE", sdk_machine, "local.conf") | ||
323 | |||
324 | def set_image_fstypes(self, image_fstypes): | ||
325 | self.set_var_in_file("IMAGE_FSTYPES", image_fstypes, "local.conf") | ||
326 | |||
327 | def set_distro(self, distro): | ||
328 | self.set_var_in_file("DISTRO", distro, "local.conf") | ||
329 | |||
330 | def set_package_format(self, format): | ||
331 | package_classes = "" | ||
332 | for pkgfmt in format.split(): | ||
333 | package_classes += ("package_%s" % pkgfmt + " ") | ||
334 | self.set_var_in_file("PACKAGE_CLASSES", package_classes, "local.conf") | ||
335 | |||
336 | def set_bbthreads(self, threads): | ||
337 | self.set_var_in_file("BB_NUMBER_THREADS", threads, "local.conf") | ||
338 | |||
339 | def set_pmake(self, threads): | ||
340 | pmake = "-j %s" % threads | ||
341 | self.set_var_in_file("PARALLEL_MAKE", pmake, "local.conf") | ||
342 | |||
343 | def set_dl_dir(self, directory): | ||
344 | self.set_var_in_file("DL_DIR", directory, "local.conf") | ||
345 | |||
346 | def set_sstate_dir(self, directory): | ||
347 | self.set_var_in_file("SSTATE_DIR", directory, "local.conf") | ||
348 | |||
349 | def set_sstate_mirrors(self, url): | ||
350 | self.set_var_in_file("SSTATE_MIRRORS", url, "local.conf") | ||
351 | |||
352 | def set_extra_size(self, image_extra_size): | ||
353 | self.set_var_in_file("IMAGE_ROOTFS_EXTRA_SPACE", str(image_extra_size), "local.conf") | ||
354 | |||
355 | def set_rootfs_size(self, image_rootfs_size): | ||
356 | self.set_var_in_file("IMAGE_ROOTFS_SIZE", str(image_rootfs_size), "local.conf") | ||
357 | |||
358 | def set_incompatible_license(self, incompat_license): | ||
359 | self.set_var_in_file("INCOMPATIBLE_LICENSE", incompat_license, "local.conf") | ||
360 | |||
361 | def set_extra_setting(self, extra_setting): | ||
362 | self.set_var_in_file("EXTRA_SETTING", extra_setting, "local.conf") | ||
363 | |||
364 | def set_extra_config(self, extra_setting): | ||
365 | old_extra_setting = ast.literal_eval(self.runCommand(["getVariable", "EXTRA_SETTING"]) or "{}") | ||
366 | if extra_setting: | ||
367 | self.set_var_in_file("EXTRA_SETTING", extra_setting, "local.conf") | ||
368 | else: | ||
369 | self.remove_var_from_file("EXTRA_SETTING") | ||
370 | |||
371 | #remove not needed settings from conf | ||
372 | for key in old_extra_setting: | ||
373 | if key not in extra_setting: | ||
374 | self.remove_var_from_file(key) | ||
375 | for key in extra_setting.keys(): | ||
376 | value = extra_setting[key] | ||
377 | self.set_var_in_file(key, value, "local.conf") | ||
378 | |||
379 | def set_http_proxy(self, http_proxy): | ||
380 | self.set_var_in_file("http_proxy", http_proxy, "local.conf") | ||
381 | |||
382 | def set_https_proxy(self, https_proxy): | ||
383 | self.set_var_in_file("https_proxy", https_proxy, "local.conf") | ||
384 | |||
385 | def set_ftp_proxy(self, ftp_proxy): | ||
386 | self.set_var_in_file("ftp_proxy", ftp_proxy, "local.conf") | ||
387 | |||
388 | def set_socks_proxy(self, socks_proxy): | ||
389 | self.set_var_in_file("all_proxy", socks_proxy, "local.conf") | ||
390 | |||
391 | def set_cvs_proxy(self, host, port): | ||
392 | self.set_var_in_file("CVS_PROXY_HOST", host, "local.conf") | ||
393 | self.set_var_in_file("CVS_PROXY_PORT", port, "local.conf") | ||
394 | |||
395 | def request_package_info(self): | ||
396 | self.commands_async.append(self.SUB_GENERATE_PKGINFO) | ||
397 | self.run_next_command(self.POPULATE_PACKAGEINFO) | ||
398 | |||
399 | def trigger_sanity_check(self): | ||
400 | self.commands_async.append(self.SUB_SANITY_CHECK) | ||
401 | self.run_next_command(self.SANITY_CHECK) | ||
402 | |||
403 | def trigger_network_test(self): | ||
404 | self.commands_async.append(self.SUB_NETWORK_TEST) | ||
405 | self.run_next_command(self.NETWORK_TEST) | ||
406 | |||
407 | def generate_configuration(self): | ||
408 | self.commands_async.append(self.SUB_PARSE_CONFIG) | ||
409 | self.commands_async.append(self.SUB_PATH_LAYERS) | ||
410 | self.commands_async.append(self.SUB_FILES_DISTRO) | ||
411 | self.commands_async.append(self.SUB_FILES_MACH) | ||
412 | self.commands_async.append(self.SUB_FILES_SDKMACH) | ||
413 | self.commands_async.append(self.SUB_MATCH_CLASS) | ||
414 | self.run_next_command(self.GENERATE_CONFIGURATION) | ||
415 | |||
416 | def generate_recipes(self): | ||
417 | self.commands_async.append(self.SUB_PARSE_CONFIG) | ||
418 | self.commands_async.append(self.SUB_GNERATE_TGTS) | ||
419 | self.run_next_command(self.GENERATE_RECIPES) | ||
420 | |||
421 | def generate_packages(self, tgts, default_task="build"): | ||
422 | targets = [] | ||
423 | targets.extend(tgts) | ||
424 | self.recipe_queue = targets | ||
425 | self.default_task = default_task | ||
426 | self.commands_async.append(self.SUB_PARSE_CONFIG) | ||
427 | self.commands_async.append(self.SUB_BUILD_RECIPES) | ||
428 | self.run_next_command(self.GENERATE_PACKAGES) | ||
429 | |||
430 | def generate_image(self, image, base_image, toolchain, image_packages=[], toolchain_packages=[], default_task="build"): | ||
431 | self.image = image | ||
432 | self.base_image = base_image | ||
433 | self.toolchain = toolchain | ||
434 | self.package_queue = image_packages | ||
435 | self.toolchain_packages = toolchain_packages | ||
436 | self.default_task = default_task | ||
437 | self.commands_async.append(self.SUB_PARSE_CONFIG) | ||
438 | self.commands_async.append(self.SUB_BUILD_IMAGE) | ||
439 | self.run_next_command(self.GENERATE_IMAGE) | ||
440 | |||
441 | def generate_new_image(self, image, base_image, package_queue, description): | ||
442 | base_image = self.runCommand(["matchFile", self.base_image + ".bb"]) | ||
443 | self.runCommand(["generateNewImage", image, base_image, package_queue, False, description]) | ||
444 | |||
445 | def ensure_dir(self, directory): | ||
446 | self.runCommand(["ensureDir", directory]) | ||
447 | |||
448 | def build_succeeded_async(self): | ||
449 | self.building = False | ||
450 | |||
451 | def build_failed_async(self): | ||
452 | self.initcmd = None | ||
453 | self.commands_async = [] | ||
454 | self.building = False | ||
455 | |||
456 | def cancel_parse(self): | ||
457 | self.runCommand(["stateForceShutdown"]) | ||
458 | |||
459 | def cancel_build(self, force=False): | ||
460 | if force: | ||
461 | # Force the cooker to stop as quickly as possible | ||
462 | self.runCommand(["stateForceShutdown"]) | ||
463 | else: | ||
464 | # Wait for tasks to complete before shutting down, this helps | ||
465 | # leave the workdir in a usable state | ||
466 | self.runCommand(["stateShutdown"]) | ||
467 | |||
468 | def reset_build(self): | ||
469 | self.build.reset() | ||
470 | |||
471 | def get_logfile(self): | ||
472 | return self.server.runCommand(["getVariable", "BB_CONSOLELOG"])[0] | ||
473 | |||
474 | def get_topdir(self): | ||
475 | return self.runCommand(["getVariable", "TOPDIR"]) or "" | ||
476 | |||
477 | def _remove_redundant(self, string): | ||
478 | ret = [] | ||
479 | for i in string.split(): | ||
480 | if i not in ret: | ||
481 | ret.append(i) | ||
482 | return " ".join(ret) | ||
483 | |||
484 | def set_var_in_file(self, var, val, default_file=None): | ||
485 | self.runCommand(["enableDataTracking"]) | ||
486 | self.server.runCommand(["setVarFile", var, val, default_file, "set"]) | ||
487 | self.runCommand(["disableDataTracking"]) | ||
488 | |||
489 | def early_assign_var_in_file(self, var, val, default_file=None): | ||
490 | self.runCommand(["enableDataTracking"]) | ||
491 | self.server.runCommand(["setVarFile", var, val, default_file, "earlyAssign"]) | ||
492 | self.runCommand(["disableDataTracking"]) | ||
493 | |||
494 | def remove_var_from_file(self, var): | ||
495 | self.server.runCommand(["removeVarFile", var]) | ||
496 | |||
497 | def append_var_in_file(self, var, val, default_file=None): | ||
498 | self.server.runCommand(["setVarFile", var, val, default_file, "append"]) | ||
499 | |||
500 | def append_to_bbfiles(self, val): | ||
501 | bbfiles = self.runCommand(["getVariable", "BBFILES", "False"]) or "" | ||
502 | bbfiles = bbfiles.split() | ||
503 | if val not in bbfiles: | ||
504 | self.append_var_in_file("BBFILES", val, "local.conf") | ||
505 | |||
506 | def get_parameters(self): | ||
507 | # retrieve the parameters from bitbake | ||
508 | params = {} | ||
509 | params["core_base"] = self.runCommand(["getVariable", "COREBASE"]) or "" | ||
510 | hob_layer = params["core_base"] + "/meta-hob" | ||
511 | params["layer"] = self.runCommand(["getVariable", "BBLAYERS"]) or "" | ||
512 | params["layers_non_removable"] = self.runCommand(["getVariable", "BBLAYERS_NON_REMOVABLE"]) or "" | ||
513 | if hob_layer not in params["layer"].split(): | ||
514 | params["layer"] += (" " + hob_layer) | ||
515 | if hob_layer not in params["layers_non_removable"].split(): | ||
516 | params["layers_non_removable"] += (" " + hob_layer) | ||
517 | params["dldir"] = self.runCommand(["getVariable", "DL_DIR"]) or "" | ||
518 | params["machine"] = self.runCommand(["getVariable", "MACHINE"]) or "" | ||
519 | params["distro"] = self.runCommand(["getVariable", "DISTRO"]) or "defaultsetup" | ||
520 | params["pclass"] = self.runCommand(["getVariable", "PACKAGE_CLASSES"]) or "" | ||
521 | params["sstatedir"] = self.runCommand(["getVariable", "SSTATE_DIR"]) or "" | ||
522 | params["sstatemirror"] = self.runCommand(["getVariable", "SSTATE_MIRRORS"]) or "" | ||
523 | |||
524 | num_threads = self.runCommand(["getCpuCount"]) | ||
525 | if not num_threads: | ||
526 | num_threads = 1 | ||
527 | max_threads = 65536 | ||
528 | else: | ||
529 | try: | ||
530 | num_threads = int(num_threads) | ||
531 | max_threads = 16 * num_threads | ||
532 | except: | ||
533 | num_threads = 1 | ||
534 | max_threads = 65536 | ||
535 | params["max_threads"] = max_threads | ||
536 | |||
537 | bbthread = self.runCommand(["getVariable", "BB_NUMBER_THREADS"]) | ||
538 | if not bbthread: | ||
539 | bbthread = num_threads | ||
540 | else: | ||
541 | try: | ||
542 | bbthread = int(bbthread) | ||
543 | except: | ||
544 | bbthread = num_threads | ||
545 | params["bbthread"] = bbthread | ||
546 | |||
547 | pmake = self.runCommand(["getVariable", "PARALLEL_MAKE"]) | ||
548 | if not pmake: | ||
549 | pmake = num_threads | ||
550 | elif isinstance(pmake, int): | ||
551 | pass | ||
552 | else: | ||
553 | try: | ||
554 | pmake = int(pmake.lstrip("-j ")) | ||
555 | except: | ||
556 | pmake = num_threads | ||
557 | params["pmake"] = "-j %s" % pmake | ||
558 | |||
559 | params["image_addr"] = self.runCommand(["getVariable", "DEPLOY_DIR_IMAGE"]) or "" | ||
560 | |||
561 | image_extra_size = self.runCommand(["getVariable", "IMAGE_ROOTFS_EXTRA_SPACE"]) | ||
562 | if not image_extra_size: | ||
563 | image_extra_size = 0 | ||
564 | else: | ||
565 | try: | ||
566 | image_extra_size = int(image_extra_size) | ||
567 | except: | ||
568 | image_extra_size = 0 | ||
569 | params["image_extra_size"] = image_extra_size | ||
570 | |||
571 | image_rootfs_size = self.runCommand(["getVariable", "IMAGE_ROOTFS_SIZE"]) | ||
572 | if not image_rootfs_size: | ||
573 | image_rootfs_size = 0 | ||
574 | else: | ||
575 | try: | ||
576 | image_rootfs_size = int(image_rootfs_size) | ||
577 | except: | ||
578 | image_rootfs_size = 0 | ||
579 | params["image_rootfs_size"] = image_rootfs_size | ||
580 | |||
581 | image_overhead_factor = self.runCommand(["getVariable", "IMAGE_OVERHEAD_FACTOR"]) | ||
582 | if not image_overhead_factor: | ||
583 | image_overhead_factor = 1 | ||
584 | else: | ||
585 | try: | ||
586 | image_overhead_factor = float(image_overhead_factor) | ||
587 | except: | ||
588 | image_overhead_factor = 1 | ||
589 | params['image_overhead_factor'] = image_overhead_factor | ||
590 | |||
591 | params["incompat_license"] = self._remove_redundant(self.runCommand(["getVariable", "INCOMPATIBLE_LICENSE"]) or "") | ||
592 | params["sdk_machine"] = self.runCommand(["getVariable", "SDKMACHINE"]) or self.runCommand(["getVariable", "SDK_ARCH"]) or "" | ||
593 | |||
594 | params["image_fstypes"] = self._remove_redundant(self.runCommand(["getVariable", "IMAGE_FSTYPES"]) or "") | ||
595 | |||
596 | params["image_types"] = self._remove_redundant(self.runCommand(["getVariable", "IMAGE_TYPES"]) or "") | ||
597 | |||
598 | params["conf_version"] = self.runCommand(["getVariable", "CONF_VERSION"]) or "" | ||
599 | params["lconf_version"] = self.runCommand(["getVariable", "LCONF_VERSION"]) or "" | ||
600 | |||
601 | params["runnable_image_types"] = self._remove_redundant(self.runCommand(["getVariable", "RUNNABLE_IMAGE_TYPES"]) or "") | ||
602 | params["runnable_machine_patterns"] = self._remove_redundant(self.runCommand(["getVariable", "RUNNABLE_MACHINE_PATTERNS"]) or "") | ||
603 | params["deployable_image_types"] = self._remove_redundant(self.runCommand(["getVariable", "DEPLOYABLE_IMAGE_TYPES"]) or "") | ||
604 | params["kernel_image_type"] = self.runCommand(["getVariable", "KERNEL_IMAGETYPE"]) or "" | ||
605 | params["tmpdir"] = self.runCommand(["getVariable", "TMPDIR"]) or "" | ||
606 | params["distro_version"] = self.runCommand(["getVariable", "DISTRO_VERSION"]) or "" | ||
607 | params["target_os"] = self.runCommand(["getVariable", "TARGET_OS"]) or "" | ||
608 | params["target_arch"] = self.runCommand(["getVariable", "TARGET_ARCH"]) or "" | ||
609 | params["tune_pkgarch"] = self.runCommand(["getVariable", "TUNE_PKGARCH"]) or "" | ||
610 | params["bb_version"] = self.runCommand(["getVariable", "BB_MIN_VERSION"]) or "" | ||
611 | |||
612 | params["default_task"] = self.runCommand(["getVariable", "BB_DEFAULT_TASK"]) or "build" | ||
613 | |||
614 | params["socks_proxy"] = self.runCommand(["getVariable", "all_proxy"]) or "" | ||
615 | params["http_proxy"] = self.runCommand(["getVariable", "http_proxy"]) or "" | ||
616 | params["ftp_proxy"] = self.runCommand(["getVariable", "ftp_proxy"]) or "" | ||
617 | params["https_proxy"] = self.runCommand(["getVariable", "https_proxy"]) or "" | ||
618 | |||
619 | params["cvs_proxy_host"] = self.runCommand(["getVariable", "CVS_PROXY_HOST"]) or "" | ||
620 | params["cvs_proxy_port"] = self.runCommand(["getVariable", "CVS_PROXY_PORT"]) or "" | ||
621 | |||
622 | params["image_white_pattern"] = self.runCommand(["getVariable", "BBUI_IMAGE_WHITE_PATTERN"]) or "" | ||
623 | params["image_black_pattern"] = self.runCommand(["getVariable", "BBUI_IMAGE_BLACK_PATTERN"]) or "" | ||
624 | return params | ||