diff options
author | Tudor Florea <tudor.florea@enea.com> | 2015-10-09 22:59:03 +0200 |
---|---|---|
committer | Tudor Florea <tudor.florea@enea.com> | 2015-10-09 22:59:03 +0200 |
commit | 972dcfcdbfe75dcfeb777150c136576cf1a71e99 (patch) | |
tree | 97a61cd7e293d7ae9d56ef7ed0f81253365bb026 /bitbake/lib/bb/ui/crumbs/builder.py | |
download | poky-972dcfcdbfe75dcfeb777150c136576cf1a71e99.tar.gz |
initial commit for Enea Linux 5.0 arm
Signed-off-by: Tudor Florea <tudor.florea@enea.com>
Diffstat (limited to 'bitbake/lib/bb/ui/crumbs/builder.py')
-rwxr-xr-x | bitbake/lib/bb/ui/crumbs/builder.py | 1475 |
1 files changed, 1475 insertions, 0 deletions
diff --git a/bitbake/lib/bb/ui/crumbs/builder.py b/bitbake/lib/bb/ui/crumbs/builder.py new file mode 100755 index 0000000000..455af320e8 --- /dev/null +++ b/bitbake/lib/bb/ui/crumbs/builder.py | |||
@@ -0,0 +1,1475 @@ | |||
1 | #!/usr/bin/env python | ||
2 | # | ||
3 | # BitBake Graphical GTK User Interface | ||
4 | # | ||
5 | # Copyright (C) 2011-2012 Intel Corporation | ||
6 | # | ||
7 | # Authored by Joshua Lock <josh@linux.intel.com> | ||
8 | # Authored by Dongxiao Xu <dongxiao.xu@intel.com> | ||
9 | # Authored by Shane Wang <shane.wang@intel.com> | ||
10 | # | ||
11 | # This program is free software; you can redistribute it and/or modify | ||
12 | # it under the terms of the GNU General Public License version 2 as | ||
13 | # published by the Free Software Foundation. | ||
14 | # | ||
15 | # This program is distributed in the hope that it will be useful, | ||
16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | # GNU General Public License for more details. | ||
19 | # | ||
20 | # You should have received a copy of the GNU General Public License along | ||
21 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
23 | |||
24 | import glib | ||
25 | import gtk, gobject | ||
26 | import copy | ||
27 | import os | ||
28 | import subprocess | ||
29 | import shlex | ||
30 | import re | ||
31 | import logging | ||
32 | import sys | ||
33 | import signal | ||
34 | import time | ||
35 | from bb.ui.crumbs.imageconfigurationpage import ImageConfigurationPage | ||
36 | from bb.ui.crumbs.recipeselectionpage import RecipeSelectionPage | ||
37 | from bb.ui.crumbs.packageselectionpage import PackageSelectionPage | ||
38 | from bb.ui.crumbs.builddetailspage import BuildDetailsPage | ||
39 | from bb.ui.crumbs.imagedetailspage import ImageDetailsPage | ||
40 | from bb.ui.crumbs.sanitycheckpage import SanityCheckPage | ||
41 | from bb.ui.crumbs.hobwidget import hwc, HobButton, HobAltButton | ||
42 | from bb.ui.crumbs.persistenttooltip import PersistentTooltip | ||
43 | import bb.ui.crumbs.utils | ||
44 | from bb.ui.crumbs.hig.crumbsmessagedialog import CrumbsMessageDialog | ||
45 | from bb.ui.crumbs.hig.simplesettingsdialog import SimpleSettingsDialog | ||
46 | from bb.ui.crumbs.hig.advancedsettingsdialog import AdvancedSettingsDialog | ||
47 | from bb.ui.crumbs.hig.deployimagedialog import DeployImageDialog | ||
48 | from bb.ui.crumbs.hig.layerselectiondialog import LayerSelectionDialog | ||
49 | from bb.ui.crumbs.hig.imageselectiondialog import ImageSelectionDialog | ||
50 | from bb.ui.crumbs.hig.parsingwarningsdialog import ParsingWarningsDialog | ||
51 | from bb.ui.crumbs.hig.propertydialog import PropertyDialog | ||
52 | |||
53 | hobVer = 20120808 | ||
54 | |||
55 | class Configuration: | ||
56 | '''Represents the data structure of configuration.''' | ||
57 | |||
58 | @classmethod | ||
59 | def parse_proxy_string(cls, proxy): | ||
60 | pattern = "^\s*((http|https|ftp|socks|cvs)://)?((\S+):(\S+)@)?([^\s:]+)(:(\d+))?/?" | ||
61 | match = re.search(pattern, proxy) | ||
62 | if match: | ||
63 | return match.group(2), match.group(4), match.group(5), match.group(6), match.group(8) | ||
64 | else: | ||
65 | return None, None, None, "", "" | ||
66 | |||
67 | @classmethod | ||
68 | def make_host_string(cls, prot, user, passwd, host, default_prot=""): | ||
69 | if host == None or host == "": | ||
70 | return "" | ||
71 | |||
72 | passwd = passwd or "" | ||
73 | |||
74 | if user != None and user != "": | ||
75 | if prot == None or prot == "": | ||
76 | prot = default_prot | ||
77 | return prot + "://" + user + ":" + passwd + "@" + host | ||
78 | else: | ||
79 | if prot == None or prot == "": | ||
80 | return host | ||
81 | else: | ||
82 | return prot + "://" + host | ||
83 | |||
84 | @classmethod | ||
85 | def make_port_string(cls, port): | ||
86 | port = port or "" | ||
87 | return port | ||
88 | |||
89 | @classmethod | ||
90 | def make_proxy_string(cls, prot, user, passwd, host, port, default_prot=""): | ||
91 | if host == None or host == "":# or port == None or port == "": | ||
92 | return "" | ||
93 | |||
94 | return Configuration.make_host_string(prot, user, passwd, host, default_prot) + (":" + Configuration.make_port_string(port) if port else "") | ||
95 | |||
96 | def __init__(self): | ||
97 | self.curr_mach = "" | ||
98 | self.selected_image = None | ||
99 | # settings | ||
100 | self.curr_distro = "" | ||
101 | self.dldir = self.sstatedir = self.sstatemirror = "" | ||
102 | self.pmake = self.bbthread = 0 | ||
103 | self.curr_package_format = "" | ||
104 | self.image_rootfs_size = self.image_extra_size = 0 | ||
105 | self.image_overhead_factor = 1 | ||
106 | self.incompat_license = "" | ||
107 | self.curr_sdk_machine = "" | ||
108 | self.conf_version = self.lconf_version = "" | ||
109 | self.extra_setting = {} | ||
110 | self.toolchain_build = False | ||
111 | self.image_fstypes = "" | ||
112 | self.image_size = None | ||
113 | self.image_packages = [] | ||
114 | # bblayers.conf | ||
115 | self.layers = [] | ||
116 | # image/recipes/packages | ||
117 | self.clear_selection() | ||
118 | |||
119 | self.user_selected_packages = [] | ||
120 | |||
121 | self.default_task = "build" | ||
122 | |||
123 | # proxy settings | ||
124 | self.enable_proxy = None | ||
125 | self.same_proxy = False | ||
126 | self.proxies = { | ||
127 | "http" : [None, None, None, "", ""], # protocol : [prot, user, passwd, host, port] | ||
128 | "https" : [None, None, None, "", ""], | ||
129 | "ftp" : [None, None, None, "", ""], | ||
130 | "socks" : [None, None, None, "", ""], | ||
131 | "cvs" : [None, None, None, "", ""], | ||
132 | } | ||
133 | |||
134 | def clear_selection(self): | ||
135 | self.selected_recipes = [] | ||
136 | self.selected_packages = [] | ||
137 | self.initial_selected_image = None | ||
138 | self.initial_selected_packages = [] | ||
139 | self.initial_user_selected_packages = [] | ||
140 | |||
141 | def split_proxy(self, protocol, proxy): | ||
142 | entry = [] | ||
143 | prot, user, passwd, host, port = Configuration.parse_proxy_string(proxy) | ||
144 | entry.append(prot) | ||
145 | entry.append(user) | ||
146 | entry.append(passwd) | ||
147 | entry.append(host) | ||
148 | entry.append(port) | ||
149 | self.proxies[protocol] = entry | ||
150 | |||
151 | def combine_proxy(self, protocol): | ||
152 | entry = self.proxies[protocol] | ||
153 | return Configuration.make_proxy_string(entry[0], entry[1], entry[2], entry[3], entry[4], protocol) | ||
154 | |||
155 | def combine_host_only(self, protocol): | ||
156 | entry = self.proxies[protocol] | ||
157 | return Configuration.make_host_string(entry[0], entry[1], entry[2], entry[3], protocol) | ||
158 | |||
159 | def combine_port_only(self, protocol): | ||
160 | entry = self.proxies[protocol] | ||
161 | return Configuration.make_port_string(entry[4]) | ||
162 | |||
163 | def update(self, params): | ||
164 | # settings | ||
165 | self.curr_distro = params["distro"] | ||
166 | self.dldir = params["dldir"] | ||
167 | self.sstatedir = params["sstatedir"] | ||
168 | self.sstatemirror = params["sstatemirror"] | ||
169 | self.pmake = int(params["pmake"].split()[1]) | ||
170 | self.bbthread = params["bbthread"] | ||
171 | self.curr_package_format = " ".join(params["pclass"].split("package_")).strip() | ||
172 | self.image_rootfs_size = params["image_rootfs_size"] | ||
173 | self.image_extra_size = params["image_extra_size"] | ||
174 | self.image_overhead_factor = params['image_overhead_factor'] | ||
175 | self.incompat_license = params["incompat_license"] | ||
176 | self.curr_sdk_machine = params["sdk_machine"] | ||
177 | self.conf_version = params["conf_version"] | ||
178 | self.lconf_version = params["lconf_version"] | ||
179 | self.image_fstypes = params["image_fstypes"] | ||
180 | # self.extra_setting/self.toolchain_build | ||
181 | # bblayers.conf | ||
182 | self.layers = params["layer"].split() | ||
183 | self.layers_non_removable = params["layers_non_removable"].split() | ||
184 | self.default_task = params["default_task"] | ||
185 | |||
186 | # proxy settings | ||
187 | self.enable_proxy = params["http_proxy"] != "" or params["https_proxy"] != "" \ | ||
188 | or params["ftp_proxy"] != "" or params["socks_proxy"] != "" \ | ||
189 | or params["cvs_proxy_host"] != "" or params["cvs_proxy_port"] != "" | ||
190 | self.split_proxy("http", params["http_proxy"]) | ||
191 | self.split_proxy("https", params["https_proxy"]) | ||
192 | self.split_proxy("ftp", params["ftp_proxy"]) | ||
193 | self.split_proxy("socks", params["socks_proxy"]) | ||
194 | self.split_proxy("cvs", params["cvs_proxy_host"] + ":" + params["cvs_proxy_port"]) | ||
195 | |||
196 | def save(self, handler, defaults=False): | ||
197 | # bblayers.conf | ||
198 | handler.set_var_in_file("BBLAYERS", self.layers, "bblayers.conf") | ||
199 | # local.conf | ||
200 | if not defaults: | ||
201 | handler.early_assign_var_in_file("MACHINE", self.curr_mach, "local.conf") | ||
202 | handler.set_var_in_file("DISTRO", self.curr_distro, "local.conf") | ||
203 | handler.set_var_in_file("DL_DIR", self.dldir, "local.conf") | ||
204 | handler.set_var_in_file("SSTATE_DIR", self.sstatedir, "local.conf") | ||
205 | sstate_mirror_list = self.sstatemirror.split("\\n ") | ||
206 | sstate_mirror_list_modified = [] | ||
207 | for mirror in sstate_mirror_list: | ||
208 | if mirror != "": | ||
209 | mirror = mirror + "\\n" | ||
210 | sstate_mirror_list_modified.append(mirror) | ||
211 | handler.set_var_in_file("SSTATE_MIRRORS", sstate_mirror_list_modified, "local.conf") | ||
212 | handler.set_var_in_file("PARALLEL_MAKE", "-j %s" % self.pmake, "local.conf") | ||
213 | handler.set_var_in_file("BB_NUMBER_THREADS", self.bbthread, "local.conf") | ||
214 | handler.set_var_in_file("PACKAGE_CLASSES", " ".join(["package_" + i for i in self.curr_package_format.split()]), "local.conf") | ||
215 | handler.set_var_in_file("IMAGE_ROOTFS_SIZE", self.image_rootfs_size, "local.conf") | ||
216 | handler.set_var_in_file("IMAGE_EXTRA_SPACE", self.image_extra_size, "local.conf") | ||
217 | handler.set_var_in_file("INCOMPATIBLE_LICENSE", self.incompat_license, "local.conf") | ||
218 | handler.set_var_in_file("SDKMACHINE", self.curr_sdk_machine, "local.conf") | ||
219 | handler.set_var_in_file("CONF_VERSION", self.conf_version, "local.conf") | ||
220 | handler.set_var_in_file("LCONF_VERSION", self.lconf_version, "bblayers.conf") | ||
221 | handler.set_extra_config(self.extra_setting) | ||
222 | handler.set_var_in_file("TOOLCHAIN_BUILD", self.toolchain_build, "local.conf") | ||
223 | handler.set_var_in_file("IMAGE_FSTYPES", self.image_fstypes, "local.conf") | ||
224 | if not defaults: | ||
225 | # image/recipes/packages | ||
226 | handler.set_var_in_file("__SELECTED_IMAGE__", self.selected_image, "local.conf") | ||
227 | handler.set_var_in_file("DEPENDS", self.selected_recipes, "local.conf") | ||
228 | handler.set_var_in_file("IMAGE_INSTALL", self.user_selected_packages, "local.conf") | ||
229 | # proxy | ||
230 | if self.enable_proxy == True: | ||
231 | handler.set_var_in_file("http_proxy", self.combine_proxy("http"), "local.conf") | ||
232 | handler.set_var_in_file("https_proxy", self.combine_proxy("https"), "local.conf") | ||
233 | handler.set_var_in_file("ftp_proxy", self.combine_proxy("ftp"), "local.conf") | ||
234 | handler.set_var_in_file("all_proxy", self.combine_proxy("socks"), "local.conf") | ||
235 | handler.set_var_in_file("CVS_PROXY_HOST", self.combine_host_only("cvs"), "local.conf") | ||
236 | handler.set_var_in_file("CVS_PROXY_PORT", self.combine_port_only("cvs"), "local.conf") | ||
237 | else: | ||
238 | handler.set_var_in_file("http_proxy", "", "local.conf") | ||
239 | handler.set_var_in_file("https_proxy", "", "local.conf") | ||
240 | handler.set_var_in_file("ftp_proxy", "", "local.conf") | ||
241 | handler.set_var_in_file("all_proxy", "", "local.conf") | ||
242 | handler.set_var_in_file("CVS_PROXY_HOST", "", "local.conf") | ||
243 | handler.set_var_in_file("CVS_PROXY_PORT", "", "local.conf") | ||
244 | |||
245 | def __str__(self): | ||
246 | s = "VERSION: '%s', BBLAYERS: '%s', MACHINE: '%s', DISTRO: '%s', DL_DIR: '%s'," % \ | ||
247 | (hobVer, " ".join(self.layers), self.curr_mach, self.curr_distro, self.dldir ) | ||
248 | s += "SSTATE_DIR: '%s', SSTATE_MIRROR: '%s', PARALLEL_MAKE: '-j %s', BB_NUMBER_THREADS: '%s', PACKAGE_CLASSES: '%s', " % \ | ||
249 | (self.sstatedir, self.sstatemirror, self.pmake, self.bbthread, " ".join(["package_" + i for i in self.curr_package_format.split()])) | ||
250 | s += "IMAGE_ROOTFS_SIZE: '%s', IMAGE_EXTRA_SPACE: '%s', INCOMPATIBLE_LICENSE: '%s', SDKMACHINE: '%s', CONF_VERSION: '%s', " % \ | ||
251 | (self.image_rootfs_size, self.image_extra_size, self.incompat_license, self.curr_sdk_machine, self.conf_version) | ||
252 | s += "LCONF_VERSION: '%s', EXTRA_SETTING: '%s', TOOLCHAIN_BUILD: '%s', IMAGE_FSTYPES: '%s', __SELECTED_IMAGE__: '%s', " % \ | ||
253 | (self.lconf_version, self.extra_setting, self.toolchain_build, self.image_fstypes, self.selected_image) | ||
254 | s += "DEPENDS: '%s', IMAGE_INSTALL: '%s', enable_proxy: '%s', use_same_proxy: '%s', http_proxy: '%s', " % \ | ||
255 | (self.selected_recipes, self.user_selected_packages, self.enable_proxy, self.same_proxy, self.combine_proxy("http")) | ||
256 | s += "https_proxy: '%s', ftp_proxy: '%s', all_proxy: '%s', CVS_PROXY_HOST: '%s', CVS_PROXY_PORT: '%s'" % \ | ||
257 | (self.combine_proxy("https"), self.combine_proxy("ftp"), self.combine_proxy("socks"), | ||
258 | self.combine_host_only("cvs"), self.combine_port_only("cvs")) | ||
259 | return s | ||
260 | |||
261 | class Parameters: | ||
262 | '''Represents other variables like available machines, etc.''' | ||
263 | |||
264 | def __init__(self): | ||
265 | # Variables | ||
266 | self.max_threads = 65535 | ||
267 | self.core_base = "" | ||
268 | self.image_addr = "" | ||
269 | self.image_types = [] | ||
270 | self.runnable_image_types = [] | ||
271 | self.runnable_machine_patterns = [] | ||
272 | self.deployable_image_types = [] | ||
273 | self.tmpdir = "" | ||
274 | |||
275 | self.all_machines = [] | ||
276 | self.all_package_formats = [] | ||
277 | self.all_distros = [] | ||
278 | self.all_sdk_machines = [] | ||
279 | self.all_layers = [] | ||
280 | self.image_names = [] | ||
281 | self.image_white_pattern = "" | ||
282 | self.image_black_pattern = "" | ||
283 | |||
284 | # for build log to show | ||
285 | self.bb_version = "" | ||
286 | self.target_arch = "" | ||
287 | self.target_os = "" | ||
288 | self.distro_version = "" | ||
289 | self.tune_pkgarch = "" | ||
290 | |||
291 | def update(self, params): | ||
292 | self.max_threads = params["max_threads"] | ||
293 | self.core_base = params["core_base"] | ||
294 | self.image_addr = params["image_addr"] | ||
295 | self.image_types = params["image_types"].split() | ||
296 | self.runnable_image_types = params["runnable_image_types"].split() | ||
297 | self.runnable_machine_patterns = params["runnable_machine_patterns"].split() | ||
298 | self.deployable_image_types = params["deployable_image_types"].split() | ||
299 | self.tmpdir = params["tmpdir"] | ||
300 | self.image_white_pattern = params["image_white_pattern"] | ||
301 | self.image_black_pattern = params["image_black_pattern"] | ||
302 | self.kernel_image_type = params["kernel_image_type"] | ||
303 | # for build log to show | ||
304 | self.bb_version = params["bb_version"] | ||
305 | self.target_arch = params["target_arch"] | ||
306 | self.target_os = params["target_os"] | ||
307 | self.distro_version = params["distro_version"] | ||
308 | self.tune_pkgarch = params["tune_pkgarch"] | ||
309 | |||
310 | def hob_conf_filter(fn, data): | ||
311 | if fn.endswith("/local.conf"): | ||
312 | distro = data.getVar("DISTRO_HOB") | ||
313 | if distro: | ||
314 | if distro != "defaultsetup": | ||
315 | data.setVar("DISTRO", distro) | ||
316 | else: | ||
317 | data.delVar("DISTRO") | ||
318 | |||
319 | keys = ["MACHINE_HOB", "SDKMACHINE_HOB", "PACKAGE_CLASSES_HOB", \ | ||
320 | "BB_NUMBER_THREADS_HOB", "PARALLEL_MAKE_HOB", "DL_DIR_HOB", \ | ||
321 | "SSTATE_DIR_HOB", "SSTATE_MIRRORS_HOB", "INCOMPATIBLE_LICENSE_HOB"] | ||
322 | for key in keys: | ||
323 | var_hob = data.getVar(key) | ||
324 | if var_hob: | ||
325 | data.setVar(key.split("_HOB")[0], var_hob) | ||
326 | return | ||
327 | |||
328 | if fn.endswith("/bblayers.conf"): | ||
329 | layers = data.getVar("BBLAYERS_HOB") | ||
330 | if layers: | ||
331 | data.setVar("BBLAYERS", layers) | ||
332 | return | ||
333 | |||
334 | class Builder(gtk.Window): | ||
335 | |||
336 | (INITIAL_CHECKS, | ||
337 | MACHINE_SELECTION, | ||
338 | RCPPKGINFO_POPULATING, | ||
339 | RCPPKGINFO_POPULATED, | ||
340 | BASEIMG_SELECTED, | ||
341 | RECIPE_SELECTION, | ||
342 | PACKAGE_GENERATING, | ||
343 | PACKAGE_GENERATED, | ||
344 | PACKAGE_SELECTION, | ||
345 | FAST_IMAGE_GENERATING, | ||
346 | IMAGE_GENERATING, | ||
347 | IMAGE_GENERATED, | ||
348 | MY_IMAGE_OPENED, | ||
349 | BACK, | ||
350 | END_NOOP) = range(15) | ||
351 | |||
352 | (SANITY_CHECK, | ||
353 | IMAGE_CONFIGURATION, | ||
354 | RECIPE_DETAILS, | ||
355 | BUILD_DETAILS, | ||
356 | PACKAGE_DETAILS, | ||
357 | IMAGE_DETAILS, | ||
358 | END_TAB) = range(7) | ||
359 | |||
360 | __step2page__ = { | ||
361 | INITIAL_CHECKS : SANITY_CHECK, | ||
362 | MACHINE_SELECTION : IMAGE_CONFIGURATION, | ||
363 | RCPPKGINFO_POPULATING : IMAGE_CONFIGURATION, | ||
364 | RCPPKGINFO_POPULATED : IMAGE_CONFIGURATION, | ||
365 | BASEIMG_SELECTED : IMAGE_CONFIGURATION, | ||
366 | RECIPE_SELECTION : RECIPE_DETAILS, | ||
367 | PACKAGE_GENERATING : BUILD_DETAILS, | ||
368 | PACKAGE_GENERATED : PACKAGE_DETAILS, | ||
369 | PACKAGE_SELECTION : PACKAGE_DETAILS, | ||
370 | FAST_IMAGE_GENERATING : BUILD_DETAILS, | ||
371 | IMAGE_GENERATING : BUILD_DETAILS, | ||
372 | IMAGE_GENERATED : IMAGE_DETAILS, | ||
373 | MY_IMAGE_OPENED : IMAGE_DETAILS, | ||
374 | END_NOOP : None, | ||
375 | } | ||
376 | |||
377 | SANITY_CHECK_MIN_DISPLAY_TIME = 5 | ||
378 | |||
379 | def __init__(self, hobHandler, recipe_model, package_model): | ||
380 | super(Builder, self).__init__() | ||
381 | |||
382 | self.hob_image = "hob-image" | ||
383 | |||
384 | # handler | ||
385 | self.handler = hobHandler | ||
386 | |||
387 | # logger | ||
388 | self.logger = logging.getLogger("BitBake") | ||
389 | self.consolelog = None | ||
390 | self.current_logfile = None | ||
391 | |||
392 | # configuration and parameters | ||
393 | self.configuration = Configuration() | ||
394 | self.parameters = Parameters() | ||
395 | |||
396 | # build step | ||
397 | self.current_step = None | ||
398 | self.previous_step = None | ||
399 | |||
400 | self.stopping = False | ||
401 | |||
402 | # recipe model and package model | ||
403 | self.recipe_model = recipe_model | ||
404 | self.package_model = package_model | ||
405 | |||
406 | # Indicate whether user has customized the image | ||
407 | self.customized = False | ||
408 | |||
409 | # Indicate whether the UI is working | ||
410 | self.sensitive = True | ||
411 | |||
412 | # Indicate whether the sanity check ran | ||
413 | self.sanity_checked = False | ||
414 | |||
415 | # save parsing warnings | ||
416 | self.parsing_warnings = [] | ||
417 | |||
418 | # create visual elements | ||
419 | self.create_visual_elements() | ||
420 | |||
421 | # connect the signals to functions | ||
422 | self.connect("delete-event", self.destroy_window_cb) | ||
423 | self.recipe_model.connect ("recipe-selection-changed", self.recipelist_changed_cb) | ||
424 | self.package_model.connect("package-selection-changed", self.packagelist_changed_cb) | ||
425 | self.handler.connect("config-updated", self.handler_config_updated_cb) | ||
426 | self.handler.connect("package-formats-updated", self.handler_package_formats_updated_cb) | ||
427 | self.handler.connect("parsing-started", self.handler_parsing_started_cb) | ||
428 | self.handler.connect("parsing", self.handler_parsing_cb) | ||
429 | self.handler.connect("parsing-completed", self.handler_parsing_completed_cb) | ||
430 | self.handler.build.connect("build-started", self.handler_build_started_cb) | ||
431 | self.handler.build.connect("build-succeeded", self.handler_build_succeeded_cb) | ||
432 | self.handler.build.connect("build-failed", self.handler_build_failed_cb) | ||
433 | self.handler.build.connect("build-aborted", self.handler_build_aborted_cb) | ||
434 | self.handler.build.connect("task-started", self.handler_task_started_cb) | ||
435 | self.handler.build.connect("disk-full", self.handler_disk_full_cb) | ||
436 | self.handler.build.connect("log-error", self.handler_build_failure_cb) | ||
437 | self.handler.build.connect("log-warning", self.handler_build_failure_cb) | ||
438 | self.handler.build.connect("log", self.handler_build_log_cb) | ||
439 | self.handler.build.connect("no-provider", self.handler_no_provider_cb) | ||
440 | self.handler.connect("generating-data", self.handler_generating_data_cb) | ||
441 | self.handler.connect("data-generated", self.handler_data_generated_cb) | ||
442 | self.handler.connect("command-succeeded", self.handler_command_succeeded_cb) | ||
443 | self.handler.connect("command-failed", self.handler_command_failed_cb) | ||
444 | self.handler.connect("parsing-warning", self.handler_parsing_warning_cb) | ||
445 | self.handler.connect("sanity-failed", self.handler_sanity_failed_cb) | ||
446 | self.handler.connect("recipe-populated", self.handler_recipe_populated_cb) | ||
447 | self.handler.connect("package-populated", self.handler_package_populated_cb) | ||
448 | |||
449 | self.handler.append_to_bbfiles("${TOPDIR}/recipes/images/custom/*.bb") | ||
450 | self.handler.append_to_bbfiles("${TOPDIR}/recipes/images/*.bb") | ||
451 | self.initiate_new_build_async() | ||
452 | |||
453 | signal.signal(signal.SIGINT, self.event_handle_SIGINT) | ||
454 | |||
455 | def create_visual_elements(self): | ||
456 | self.set_title("Hob") | ||
457 | self.set_icon_name("applications-development") | ||
458 | self.set_resizable(True) | ||
459 | |||
460 | try: | ||
461 | window_width = self.get_screen().get_width() | ||
462 | window_height = self.get_screen().get_height() | ||
463 | except AttributeError: | ||
464 | print "Please set DISPLAY variable before running Hob." | ||
465 | sys.exit(1) | ||
466 | |||
467 | if window_width >= hwc.MAIN_WIN_WIDTH: | ||
468 | window_width = hwc.MAIN_WIN_WIDTH | ||
469 | window_height = hwc.MAIN_WIN_HEIGHT | ||
470 | self.set_size_request(window_width, window_height) | ||
471 | |||
472 | self.vbox = gtk.VBox(False, 0) | ||
473 | self.vbox.set_border_width(0) | ||
474 | self.add(self.vbox) | ||
475 | |||
476 | # create pages | ||
477 | self.image_configuration_page = ImageConfigurationPage(self) | ||
478 | self.recipe_details_page = RecipeSelectionPage(self) | ||
479 | self.build_details_page = BuildDetailsPage(self) | ||
480 | self.package_details_page = PackageSelectionPage(self) | ||
481 | self.image_details_page = ImageDetailsPage(self) | ||
482 | self.sanity_check_page = SanityCheckPage(self) | ||
483 | self.display_sanity_check = False | ||
484 | self.sanity_check_post_func = False | ||
485 | self.had_network_error = False | ||
486 | |||
487 | self.nb = gtk.Notebook() | ||
488 | self.nb.set_show_tabs(False) | ||
489 | self.nb.insert_page(self.sanity_check_page, None, self.SANITY_CHECK) | ||
490 | self.nb.insert_page(self.image_configuration_page, None, self.IMAGE_CONFIGURATION) | ||
491 | self.nb.insert_page(self.recipe_details_page, None, self.RECIPE_DETAILS) | ||
492 | self.nb.insert_page(self.build_details_page, None, self.BUILD_DETAILS) | ||
493 | self.nb.insert_page(self.package_details_page, None, self.PACKAGE_DETAILS) | ||
494 | self.nb.insert_page(self.image_details_page, None, self.IMAGE_DETAILS) | ||
495 | self.vbox.pack_start(self.nb, expand=True, fill=True) | ||
496 | |||
497 | self.show_all() | ||
498 | self.nb.set_current_page(0) | ||
499 | |||
500 | def sanity_check_timeout(self): | ||
501 | # The minimum time for showing the 'sanity check' page has passe | ||
502 | # If someone set the 'sanity_check_post_step' meanwhile, execute it now | ||
503 | self.display_sanity_check = False | ||
504 | if self.sanity_check_post_func: | ||
505 | temp = self.sanity_check_post_func | ||
506 | self.sanity_check_post_func = None | ||
507 | temp() | ||
508 | return False | ||
509 | |||
510 | def show_sanity_check_page(self): | ||
511 | # This window must stay on screen for at least 5 seconds, according to the design document | ||
512 | self.nb.set_current_page(self.SANITY_CHECK) | ||
513 | self.sanity_check_post_step = None | ||
514 | self.display_sanity_check = True | ||
515 | self.sanity_check_page.start() | ||
516 | gobject.timeout_add(self.SANITY_CHECK_MIN_DISPLAY_TIME * 1000, self.sanity_check_timeout) | ||
517 | |||
518 | def execute_after_sanity_check(self, func): | ||
519 | if not self.display_sanity_check: | ||
520 | func() | ||
521 | else: | ||
522 | self.sanity_check_post_func = func | ||
523 | |||
524 | def generate_configuration(self): | ||
525 | if not self.sanity_checked: | ||
526 | self.show_sanity_check_page() | ||
527 | self.handler.generate_configuration() | ||
528 | |||
529 | def initiate_new_build_async(self): | ||
530 | self.configuration.selected_image = None | ||
531 | self.switch_page(self.MACHINE_SELECTION) | ||
532 | self.handler.init_cooker() | ||
533 | self.handler.set_extra_inherit("image_types") | ||
534 | self.generate_configuration() | ||
535 | |||
536 | def update_config_async(self): | ||
537 | self.set_user_config() | ||
538 | self.generate_configuration() | ||
539 | self.switch_page(self.MACHINE_SELECTION) | ||
540 | |||
541 | def sanity_check(self): | ||
542 | self.handler.trigger_sanity_check() | ||
543 | |||
544 | def populate_recipe_package_info_async(self): | ||
545 | self.switch_page(self.RCPPKGINFO_POPULATING) | ||
546 | # Parse recipes | ||
547 | self.set_user_config() | ||
548 | self.handler.generate_recipes() | ||
549 | |||
550 | def generate_packages_async(self, log = False): | ||
551 | self.switch_page(self.PACKAGE_GENERATING) | ||
552 | if log: | ||
553 | self.current_logfile = self.handler.get_logfile() | ||
554 | self.do_log(self.current_logfile) | ||
555 | # Build packages | ||
556 | _, all_recipes = self.recipe_model.get_selected_recipes() | ||
557 | self.set_user_config() | ||
558 | self.handler.reset_build() | ||
559 | self.handler.generate_packages(all_recipes, self.configuration.default_task) | ||
560 | |||
561 | def restore_initial_selected_packages(self): | ||
562 | self.package_model.set_selected_packages(self.configuration.initial_user_selected_packages, True) | ||
563 | self.package_model.set_selected_packages(self.configuration.initial_selected_packages) | ||
564 | for package in self.configuration.selected_packages: | ||
565 | if package not in self.configuration.initial_selected_packages: | ||
566 | self.package_model.exclude_item(self.package_model.find_path_for_item(package)) | ||
567 | |||
568 | def fast_generate_image_async(self, log = False): | ||
569 | self.switch_page(self.FAST_IMAGE_GENERATING) | ||
570 | if log: | ||
571 | self.current_logfile = self.handler.get_logfile() | ||
572 | self.do_log(self.current_logfile) | ||
573 | # Build packages | ||
574 | _, all_recipes = self.recipe_model.get_selected_recipes() | ||
575 | self.set_user_config() | ||
576 | self.handler.reset_build() | ||
577 | self.handler.generate_packages(all_recipes, self.configuration.default_task) | ||
578 | |||
579 | def generate_image_async(self, cont = False): | ||
580 | self.switch_page(self.IMAGE_GENERATING) | ||
581 | self.handler.reset_build() | ||
582 | if not cont: | ||
583 | self.current_logfile = self.handler.get_logfile() | ||
584 | self.do_log(self.current_logfile) | ||
585 | # Build image | ||
586 | self.set_user_config() | ||
587 | toolchain_packages = [] | ||
588 | base_image = None | ||
589 | if self.configuration.toolchain_build: | ||
590 | toolchain_packages = self.package_model.get_selected_packages_toolchain() | ||
591 | if self.configuration.selected_image == self.recipe_model.__custom_image__: | ||
592 | packages = self.package_model.get_selected_packages() | ||
593 | image = self.hob_image | ||
594 | base_image = self.configuration.initial_selected_image | ||
595 | else: | ||
596 | packages = [] | ||
597 | image = self.configuration.selected_image | ||
598 | self.handler.generate_image(image, | ||
599 | base_image, | ||
600 | packages, | ||
601 | toolchain_packages, | ||
602 | self.configuration.default_task) | ||
603 | |||
604 | def generate_new_image(self, image, description): | ||
605 | base_image = self.configuration.initial_selected_image | ||
606 | if base_image == self.recipe_model.__custom_image__: | ||
607 | base_image = None | ||
608 | packages = self.package_model.get_selected_packages() | ||
609 | self.handler.generate_new_image(image, base_image, packages, description) | ||
610 | |||
611 | def ensure_dir(self, directory): | ||
612 | self.handler.ensure_dir(directory) | ||
613 | |||
614 | def get_parameters_sync(self): | ||
615 | return self.handler.get_parameters() | ||
616 | |||
617 | def request_package_info_async(self): | ||
618 | self.handler.request_package_info() | ||
619 | |||
620 | def cancel_build_sync(self, force=False): | ||
621 | self.handler.cancel_build(force) | ||
622 | |||
623 | def cancel_parse_sync(self): | ||
624 | self.handler.cancel_parse() | ||
625 | |||
626 | def switch_page(self, next_step): | ||
627 | # Main Workflow (Business Logic) | ||
628 | self.nb.set_current_page(self.__step2page__[next_step]) | ||
629 | |||
630 | if next_step == self.MACHINE_SELECTION: # init step | ||
631 | self.image_configuration_page.show_machine() | ||
632 | |||
633 | elif next_step == self.RCPPKGINFO_POPULATING: | ||
634 | # MACHINE CHANGED action or SETTINGS CHANGED | ||
635 | # show the progress bar | ||
636 | self.image_configuration_page.show_info_populating() | ||
637 | |||
638 | elif next_step == self.RCPPKGINFO_POPULATED: | ||
639 | self.image_configuration_page.show_info_populated() | ||
640 | |||
641 | elif next_step == self.BASEIMG_SELECTED: | ||
642 | self.image_configuration_page.show_baseimg_selected() | ||
643 | |||
644 | elif next_step == self.RECIPE_SELECTION: | ||
645 | if self.recipe_model.get_selected_image() == self.recipe_model.__custom_image__: | ||
646 | self.recipe_details_page.set_recipe_curr_tab(self.recipe_details_page.ALL) | ||
647 | else: | ||
648 | self.recipe_details_page.set_recipe_curr_tab(self.recipe_details_page.INCLUDED) | ||
649 | |||
650 | elif next_step == self.PACKAGE_SELECTION: | ||
651 | self.configuration.initial_selected_packages = self.configuration.selected_packages | ||
652 | self.configuration.initial_user_selected_packages = self.configuration.user_selected_packages | ||
653 | self.package_details_page.set_title("Edit packages") | ||
654 | if self.recipe_model.get_selected_image() == self.recipe_model.__custom_image__: | ||
655 | self.package_details_page.set_packages_curr_tab(self.package_details_page.ALL) | ||
656 | else: | ||
657 | self.package_details_page.set_packages_curr_tab(self.package_details_page.INCLUDED) | ||
658 | self.package_details_page.show_page(self.current_logfile) | ||
659 | |||
660 | |||
661 | elif next_step == self.PACKAGE_GENERATING or next_step == self.FAST_IMAGE_GENERATING: | ||
662 | # both PACKAGE_GENERATING and FAST_IMAGE_GENERATING share the same page | ||
663 | self.build_details_page.show_page(next_step) | ||
664 | |||
665 | elif next_step == self.PACKAGE_GENERATED: | ||
666 | self.package_details_page.set_title("Step 2 of 2: Edit packages") | ||
667 | if self.recipe_model.get_selected_image() == self.recipe_model.__custom_image__: | ||
668 | self.package_details_page.set_packages_curr_tab(self.package_details_page.ALL) | ||
669 | else: | ||
670 | self.package_details_page.set_packages_curr_tab(self.package_details_page.INCLUDED) | ||
671 | self.package_details_page.show_page(self.current_logfile) | ||
672 | |||
673 | elif next_step == self.IMAGE_GENERATING: | ||
674 | # after packages are generated, selected_packages need to | ||
675 | # be updated in package_model per selected_image in recipe_model | ||
676 | self.build_details_page.show_page(next_step) | ||
677 | |||
678 | elif next_step == self.IMAGE_GENERATED: | ||
679 | self.image_details_page.show_page(next_step) | ||
680 | |||
681 | elif next_step == self.MY_IMAGE_OPENED: | ||
682 | self.image_details_page.show_page(next_step) | ||
683 | |||
684 | self.previous_step = self.current_step | ||
685 | self.current_step = next_step | ||
686 | |||
687 | def set_user_config_proxies(self): | ||
688 | if self.configuration.enable_proxy == True: | ||
689 | self.handler.set_http_proxy(self.configuration.combine_proxy("http")) | ||
690 | self.handler.set_https_proxy(self.configuration.combine_proxy("https")) | ||
691 | self.handler.set_ftp_proxy(self.configuration.combine_proxy("ftp")) | ||
692 | self.handler.set_socks_proxy(self.configuration.combine_proxy("socks")) | ||
693 | self.handler.set_cvs_proxy(self.configuration.combine_host_only("cvs"), self.configuration.combine_port_only("cvs")) | ||
694 | elif self.configuration.enable_proxy == False: | ||
695 | self.handler.set_http_proxy("") | ||
696 | self.handler.set_https_proxy("") | ||
697 | self.handler.set_ftp_proxy("") | ||
698 | self.handler.set_socks_proxy("") | ||
699 | self.handler.set_cvs_proxy("", "") | ||
700 | |||
701 | def set_user_config_extra(self): | ||
702 | self.handler.set_rootfs_size(self.configuration.image_rootfs_size) | ||
703 | self.handler.set_extra_size(self.configuration.image_extra_size) | ||
704 | self.handler.set_incompatible_license(self.configuration.incompat_license) | ||
705 | self.handler.set_sdk_machine(self.configuration.curr_sdk_machine) | ||
706 | self.handler.set_image_fstypes(self.configuration.image_fstypes) | ||
707 | self.handler.set_extra_config(self.configuration.extra_setting) | ||
708 | self.handler.set_extra_inherit("packageinfo image_types") | ||
709 | self.set_user_config_proxies() | ||
710 | |||
711 | def set_user_config(self): | ||
712 | # set bb layers | ||
713 | self.handler.set_bblayers(self.configuration.layers) | ||
714 | # set local configuration | ||
715 | self.handler.set_machine(self.configuration.curr_mach) | ||
716 | self.handler.set_package_format(self.configuration.curr_package_format) | ||
717 | self.handler.set_distro(self.configuration.curr_distro) | ||
718 | self.handler.set_dl_dir(self.configuration.dldir) | ||
719 | self.handler.set_sstate_dir(self.configuration.sstatedir) | ||
720 | self.handler.set_sstate_mirrors(self.configuration.sstatemirror) | ||
721 | self.handler.set_pmake(self.configuration.pmake) | ||
722 | self.handler.set_bbthreads(self.configuration.bbthread) | ||
723 | self.set_user_config_extra() | ||
724 | |||
725 | def update_recipe_model(self, selected_image, selected_recipes): | ||
726 | self.recipe_model.set_selected_image(selected_image) | ||
727 | self.recipe_model.set_selected_recipes(selected_recipes) | ||
728 | |||
729 | def update_package_model(self, selected_packages, user_selected_packages=None): | ||
730 | if user_selected_packages: | ||
731 | left = self.package_model.set_selected_packages(user_selected_packages, True) | ||
732 | self.configuration.user_selected_packages += left | ||
733 | left = self.package_model.set_selected_packages(selected_packages) | ||
734 | self.configuration.selected_packages += left | ||
735 | |||
736 | def update_configuration_parameters(self, params): | ||
737 | if params: | ||
738 | self.configuration.update(params) | ||
739 | self.parameters.update(params) | ||
740 | |||
741 | def set_base_image(self): | ||
742 | self.configuration.initial_selected_image = self.configuration.selected_image | ||
743 | if self.configuration.selected_image != self.recipe_model.__custom_image__: | ||
744 | self.hob_image = self.configuration.selected_image + "-edited" | ||
745 | |||
746 | def reset(self): | ||
747 | self.configuration.curr_mach = "" | ||
748 | self.configuration.clear_selection() | ||
749 | self.image_configuration_page.switch_machine_combo() | ||
750 | self.switch_page(self.MACHINE_SELECTION) | ||
751 | |||
752 | # Callback Functions | ||
753 | def handler_config_updated_cb(self, handler, which, values): | ||
754 | if which == "distro": | ||
755 | self.parameters.all_distros = values | ||
756 | elif which == "machine": | ||
757 | self.parameters.all_machines = values | ||
758 | self.image_configuration_page.update_machine_combo() | ||
759 | elif which == "machine-sdk": | ||
760 | self.parameters.all_sdk_machines = values | ||
761 | |||
762 | def handler_package_formats_updated_cb(self, handler, formats): | ||
763 | self.parameters.all_package_formats = formats | ||
764 | |||
765 | def switch_to_image_configuration_helper(self): | ||
766 | self.sanity_check_page.stop() | ||
767 | self.switch_page(self.IMAGE_CONFIGURATION) | ||
768 | self.image_configuration_page.switch_machine_combo() | ||
769 | |||
770 | def show_network_error_dialog_helper(self): | ||
771 | self.sanity_check_page.stop() | ||
772 | self.show_network_error_dialog() | ||
773 | |||
774 | def handler_command_succeeded_cb(self, handler, initcmd): | ||
775 | if initcmd == self.handler.GENERATE_CONFIGURATION: | ||
776 | if not self.configuration.curr_mach: | ||
777 | self.configuration.curr_mach = self.handler.runCommand(["getVariable", "HOB_MACHINE"]) or "" | ||
778 | self.update_configuration_parameters(self.get_parameters_sync()) | ||
779 | if not self.sanity_checked: | ||
780 | self.sanity_check() | ||
781 | self.sanity_checked = True | ||
782 | elif initcmd == self.handler.SANITY_CHECK: | ||
783 | if self.had_network_error: | ||
784 | self.had_network_error = False | ||
785 | self.execute_after_sanity_check(self.show_network_error_dialog_helper) | ||
786 | else: | ||
787 | # Switch to the 'image configuration' page now, but we might need | ||
788 | # to wait for the minimum display time of the sanity check page | ||
789 | self.execute_after_sanity_check(self.switch_to_image_configuration_helper) | ||
790 | elif initcmd in [self.handler.GENERATE_RECIPES, | ||
791 | self.handler.GENERATE_PACKAGES, | ||
792 | self.handler.GENERATE_IMAGE]: | ||
793 | self.update_configuration_parameters(self.get_parameters_sync()) | ||
794 | self.request_package_info_async() | ||
795 | elif initcmd == self.handler.POPULATE_PACKAGEINFO: | ||
796 | if self.current_step == self.RCPPKGINFO_POPULATING: | ||
797 | self.switch_page(self.RCPPKGINFO_POPULATED) | ||
798 | self.rcppkglist_populated() | ||
799 | return | ||
800 | |||
801 | self.rcppkglist_populated() | ||
802 | if self.current_step == self.FAST_IMAGE_GENERATING: | ||
803 | self.generate_image_async(True) | ||
804 | |||
805 | def show_error_dialog(self, msg): | ||
806 | lbl = "<b>Hob found an error</b>" | ||
807 | dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_ERROR, msg) | ||
808 | button = dialog.add_button("Close", gtk.RESPONSE_OK) | ||
809 | HobButton.style_button(button) | ||
810 | response = dialog.run() | ||
811 | dialog.destroy() | ||
812 | |||
813 | def show_warning_dialog(self): | ||
814 | dialog = ParsingWarningsDialog(title = "View warnings", | ||
815 | warnings = self.parsing_warnings, | ||
816 | parent = None, | ||
817 | flags = gtk.DIALOG_DESTROY_WITH_PARENT | ||
818 | | gtk.DIALOG_NO_SEPARATOR) | ||
819 | response = dialog.run() | ||
820 | dialog.destroy() | ||
821 | |||
822 | def show_network_error_dialog(self): | ||
823 | lbl = "<b>Hob cannot connect to the network</b>" | ||
824 | msg = msg + "Please check your network connection. If you are using a proxy server, please make sure it is configured correctly." | ||
825 | dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_ERROR, msg) | ||
826 | button = dialog.add_button("Close", gtk.RESPONSE_OK) | ||
827 | HobButton.style_button(button) | ||
828 | button = dialog.add_button("Proxy settings", gtk.RESPONSE_CANCEL) | ||
829 | HobButton.style_button(button) | ||
830 | res = dialog.run() | ||
831 | dialog.destroy() | ||
832 | if res == gtk.RESPONSE_CANCEL: | ||
833 | res, settings_changed = self.show_simple_settings_dialog(SimpleSettingsDialog.PROXIES_PAGE_ID) | ||
834 | if not res: | ||
835 | return | ||
836 | if settings_changed: | ||
837 | self.reparse_post_adv_settings() | ||
838 | |||
839 | def handler_command_failed_cb(self, handler, msg): | ||
840 | if msg: | ||
841 | self.show_error_dialog(msg) | ||
842 | self.reset() | ||
843 | |||
844 | def handler_parsing_warning_cb(self, handler, warn_msg): | ||
845 | self.parsing_warnings.append(warn_msg) | ||
846 | |||
847 | def handler_sanity_failed_cb(self, handler, msg, network_error): | ||
848 | self.reset() | ||
849 | if network_error: | ||
850 | # Mark this in an internal field. The "network error" dialog will be | ||
851 | # shown later, when a SanityCheckPassed event will be handled | ||
852 | # (as sent by sanity.bbclass) | ||
853 | self.had_network_error = True | ||
854 | else: | ||
855 | msg = msg.replace("your local.conf", "Settings") | ||
856 | self.show_error_dialog(msg) | ||
857 | self.reset() | ||
858 | |||
859 | def window_sensitive(self, sensitive): | ||
860 | self.image_configuration_page.machine_combo.set_sensitive(sensitive) | ||
861 | self.image_configuration_page.machine_combo.child.set_sensitive(sensitive) | ||
862 | self.image_configuration_page.image_combo.set_sensitive(sensitive) | ||
863 | self.image_configuration_page.image_combo.child.set_sensitive(sensitive) | ||
864 | self.image_configuration_page.layer_button.set_sensitive(sensitive) | ||
865 | self.image_configuration_page.layer_info_icon.set_sensitive(sensitive) | ||
866 | self.image_configuration_page.toolbar.set_sensitive(sensitive) | ||
867 | self.image_configuration_page.view_adv_configuration_button.set_sensitive(sensitive) | ||
868 | self.image_configuration_page.config_build_button.set_sensitive(sensitive) | ||
869 | |||
870 | self.recipe_details_page.set_sensitive(sensitive) | ||
871 | self.package_details_page.set_sensitive(sensitive) | ||
872 | self.build_details_page.set_sensitive(sensitive) | ||
873 | self.image_details_page.set_sensitive(sensitive) | ||
874 | |||
875 | if sensitive: | ||
876 | self.window.set_cursor(None) | ||
877 | else: | ||
878 | self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) | ||
879 | self.sensitive = sensitive | ||
880 | |||
881 | |||
882 | def handler_generating_data_cb(self, handler): | ||
883 | self.window_sensitive(False) | ||
884 | |||
885 | def handler_data_generated_cb(self, handler): | ||
886 | self.window_sensitive(True) | ||
887 | |||
888 | def rcppkglist_populated(self): | ||
889 | selected_image = self.configuration.selected_image | ||
890 | selected_recipes = self.configuration.selected_recipes[:] | ||
891 | selected_packages = self.configuration.selected_packages[:] | ||
892 | user_selected_packages = self.configuration.user_selected_packages[:] | ||
893 | |||
894 | self.image_configuration_page.update_image_combo(self.recipe_model, selected_image) | ||
895 | self.image_configuration_page.update_image_desc() | ||
896 | self.update_recipe_model(selected_image, selected_recipes) | ||
897 | self.update_package_model(selected_packages, user_selected_packages) | ||
898 | |||
899 | def recipelist_changed_cb(self, recipe_model): | ||
900 | self.recipe_details_page.refresh_selection() | ||
901 | |||
902 | def packagelist_changed_cb(self, package_model): | ||
903 | self.package_details_page.refresh_selection() | ||
904 | |||
905 | def handler_recipe_populated_cb(self, handler): | ||
906 | self.image_configuration_page.update_progress_bar("Populating recipes", 0.99) | ||
907 | |||
908 | def handler_package_populated_cb(self, handler): | ||
909 | self.image_configuration_page.update_progress_bar("Populating packages", 1.0) | ||
910 | |||
911 | def handler_parsing_started_cb(self, handler, message): | ||
912 | if self.current_step != self.RCPPKGINFO_POPULATING: | ||
913 | return | ||
914 | |||
915 | fraction = 0 | ||
916 | if message["eventname"] == "TreeDataPreparationStarted": | ||
917 | fraction = 0.6 + fraction | ||
918 | self.image_configuration_page.stop_button.set_sensitive(False) | ||
919 | self.image_configuration_page.update_progress_bar("Generating dependency tree", fraction) | ||
920 | else: | ||
921 | self.image_configuration_page.stop_button.set_sensitive(True) | ||
922 | self.image_configuration_page.update_progress_bar(message["title"], fraction) | ||
923 | |||
924 | def handler_parsing_cb(self, handler, message): | ||
925 | if self.current_step != self.RCPPKGINFO_POPULATING: | ||
926 | return | ||
927 | |||
928 | fraction = message["current"] * 1.0/message["total"] | ||
929 | if message["eventname"] == "TreeDataPreparationProgress": | ||
930 | fraction = 0.6 + 0.38 * fraction | ||
931 | self.image_configuration_page.update_progress_bar("Generating dependency tree", fraction) | ||
932 | else: | ||
933 | fraction = 0.6 * fraction | ||
934 | self.image_configuration_page.update_progress_bar(message["title"], fraction) | ||
935 | |||
936 | def handler_parsing_completed_cb(self, handler, message): | ||
937 | if self.current_step != self.RCPPKGINFO_POPULATING: | ||
938 | return | ||
939 | |||
940 | if message["eventname"] == "TreeDataPreparationCompleted": | ||
941 | fraction = 0.98 | ||
942 | else: | ||
943 | fraction = 0.6 | ||
944 | self.image_configuration_page.update_progress_bar("Generating dependency tree", fraction) | ||
945 | |||
946 | def handler_build_started_cb(self, running_build): | ||
947 | if self.current_step == self.FAST_IMAGE_GENERATING: | ||
948 | fraction = 0 | ||
949 | elif self.current_step == self.IMAGE_GENERATING: | ||
950 | if self.previous_step == self.FAST_IMAGE_GENERATING: | ||
951 | fraction = 0.9 | ||
952 | else: | ||
953 | fraction = 0 | ||
954 | elif self.current_step == self.PACKAGE_GENERATING: | ||
955 | fraction = 0 | ||
956 | self.build_details_page.update_progress_bar("Build Started: ", fraction) | ||
957 | self.build_details_page.show_configurations(self.configuration, self.parameters) | ||
958 | |||
959 | def build_succeeded(self): | ||
960 | if self.current_step == self.FAST_IMAGE_GENERATING: | ||
961 | fraction = 0.9 | ||
962 | elif self.current_step == self.IMAGE_GENERATING: | ||
963 | fraction = 1.0 | ||
964 | version = "" | ||
965 | self.parameters.image_names = [] | ||
966 | selected_image = self.recipe_model.get_selected_image() | ||
967 | if selected_image == self.recipe_model.__custom_image__: | ||
968 | if self.configuration.initial_selected_image != selected_image: | ||
969 | version = self.recipe_model.get_custom_image_version() | ||
970 | linkname = self.hob_image + version + "-" + self.configuration.curr_mach | ||
971 | else: | ||
972 | linkname = selected_image + '-' + self.configuration.curr_mach | ||
973 | image_extension = self.get_image_extension() | ||
974 | for image_type in self.parameters.image_types: | ||
975 | if image_type in image_extension: | ||
976 | real_types = image_extension[image_type] | ||
977 | else: | ||
978 | real_types = [image_type] | ||
979 | for real_image_type in real_types: | ||
980 | linkpath = self.parameters.image_addr + '/' + linkname + '.' + real_image_type | ||
981 | if os.path.exists(linkpath): | ||
982 | self.parameters.image_names.append(os.readlink(linkpath)) | ||
983 | elif self.current_step == self.PACKAGE_GENERATING: | ||
984 | fraction = 1.0 | ||
985 | self.build_details_page.update_progress_bar("Build Completed: ", fraction) | ||
986 | self.handler.build_succeeded_async() | ||
987 | self.stopping = False | ||
988 | |||
989 | if self.current_step == self.PACKAGE_GENERATING: | ||
990 | self.switch_page(self.PACKAGE_GENERATED) | ||
991 | elif self.current_step == self.IMAGE_GENERATING: | ||
992 | self.switch_page(self.IMAGE_GENERATED) | ||
993 | |||
994 | def build_failed(self): | ||
995 | if self.stopping: | ||
996 | status = "stop" | ||
997 | message = "Build stopped: " | ||
998 | fraction = self.build_details_page.progress_bar.get_fraction() | ||
999 | stop_to_next_edit = "" | ||
1000 | if self.current_step == self.FAST_IMAGE_GENERATING: | ||
1001 | stop_to_next_edit = "image configuration" | ||
1002 | elif self.current_step == self.IMAGE_GENERATING: | ||
1003 | if self.previous_step == self.FAST_IMAGE_GENERATING: | ||
1004 | stop_to_next_edit = "image configuration" | ||
1005 | else: | ||
1006 | stop_to_next_edit = "packages" | ||
1007 | elif self.current_step == self.PACKAGE_GENERATING: | ||
1008 | stop_to_next_edit = "recipes" | ||
1009 | button = self.build_details_page.show_stop_page(stop_to_next_edit.split(' ')[0]) | ||
1010 | self.set_default(button) | ||
1011 | else: | ||
1012 | fail_to_next_edit = "" | ||
1013 | if self.current_step == self.FAST_IMAGE_GENERATING: | ||
1014 | fail_to_next_edit = "image configuration" | ||
1015 | fraction = 0.9 | ||
1016 | elif self.current_step == self.IMAGE_GENERATING: | ||
1017 | if self.previous_step == self.FAST_IMAGE_GENERATING: | ||
1018 | fail_to_next_edit = "image configuration" | ||
1019 | else: | ||
1020 | fail_to_next_edit = "packages" | ||
1021 | fraction = 1.0 | ||
1022 | elif self.current_step == self.PACKAGE_GENERATING: | ||
1023 | fail_to_next_edit = "recipes" | ||
1024 | fraction = 1.0 | ||
1025 | self.build_details_page.show_fail_page(fail_to_next_edit.split(' ')[0]) | ||
1026 | status = "fail" | ||
1027 | message = "Build failed: " | ||
1028 | self.build_details_page.update_progress_bar(message, fraction, status) | ||
1029 | self.build_details_page.show_back_button() | ||
1030 | self.build_details_page.hide_stop_button() | ||
1031 | self.handler.build_failed_async() | ||
1032 | self.stopping = False | ||
1033 | |||
1034 | def handler_build_succeeded_cb(self, running_build): | ||
1035 | if not self.stopping: | ||
1036 | self.build_succeeded() | ||
1037 | else: | ||
1038 | self.build_failed() | ||
1039 | |||
1040 | |||
1041 | def handler_build_failed_cb(self, running_build): | ||
1042 | self.build_failed() | ||
1043 | |||
1044 | def handler_build_aborted_cb(self, running_build): | ||
1045 | self.build_failed() | ||
1046 | |||
1047 | def handler_no_provider_cb(self, running_build, msg): | ||
1048 | dialog = CrumbsMessageDialog(self, glib.markup_escape_text(msg), gtk.MESSAGE_INFO) | ||
1049 | button = dialog.add_button("Close", gtk.RESPONSE_OK) | ||
1050 | HobButton.style_button(button) | ||
1051 | dialog.run() | ||
1052 | dialog.destroy() | ||
1053 | self.build_failed() | ||
1054 | |||
1055 | def handler_task_started_cb(self, running_build, message): | ||
1056 | fraction = message["current"] * 1.0/message["total"] | ||
1057 | title = "Build packages" | ||
1058 | if self.current_step == self.FAST_IMAGE_GENERATING: | ||
1059 | if message["eventname"] == "sceneQueueTaskStarted": | ||
1060 | fraction = 0.27 * fraction | ||
1061 | elif message["eventname"] == "runQueueTaskStarted": | ||
1062 | fraction = 0.27 + 0.63 * fraction | ||
1063 | elif self.current_step == self.IMAGE_GENERATING: | ||
1064 | title = "Build image" | ||
1065 | if self.previous_step == self.FAST_IMAGE_GENERATING: | ||
1066 | if message["eventname"] == "sceneQueueTaskStarted": | ||
1067 | fraction = 0.27 + 0.63 + 0.03 * fraction | ||
1068 | elif message["eventname"] == "runQueueTaskStarted": | ||
1069 | fraction = 0.27 + 0.63 + 0.03 + 0.07 * fraction | ||
1070 | else: | ||
1071 | if message["eventname"] == "sceneQueueTaskStarted": | ||
1072 | fraction = 0.2 * fraction | ||
1073 | elif message["eventname"] == "runQueueTaskStarted": | ||
1074 | fraction = 0.2 + 0.8 * fraction | ||
1075 | elif self.current_step == self.PACKAGE_GENERATING: | ||
1076 | if message["eventname"] == "sceneQueueTaskStarted": | ||
1077 | fraction = 0.2 * fraction | ||
1078 | elif message["eventname"] == "runQueueTaskStarted": | ||
1079 | fraction = 0.2 + 0.8 * fraction | ||
1080 | self.build_details_page.update_progress_bar(title + ": ", fraction) | ||
1081 | self.build_details_page.update_build_status(message["current"], message["total"], message["task"]) | ||
1082 | |||
1083 | def handler_disk_full_cb(self, running_build): | ||
1084 | self.disk_full = True | ||
1085 | |||
1086 | def handler_build_failure_cb(self, running_build): | ||
1087 | self.build_details_page.show_issues() | ||
1088 | |||
1089 | def handler_build_log_cb(self, running_build, func, obj): | ||
1090 | if hasattr(self.logger, func): | ||
1091 | getattr(self.logger, func)(obj) | ||
1092 | |||
1093 | def destroy_window_cb(self, widget, event): | ||
1094 | if not self.sensitive: | ||
1095 | return True | ||
1096 | elif self.handler.building: | ||
1097 | self.stop_build() | ||
1098 | return True | ||
1099 | else: | ||
1100 | gtk.main_quit() | ||
1101 | |||
1102 | def event_handle_SIGINT(self, signal, frame): | ||
1103 | for w in gtk.window_list_toplevels(): | ||
1104 | if w.get_modal(): | ||
1105 | w.response(gtk.RESPONSE_DELETE_EVENT) | ||
1106 | sys.exit(0) | ||
1107 | |||
1108 | def build_packages(self): | ||
1109 | _, all_recipes = self.recipe_model.get_selected_recipes() | ||
1110 | if not all_recipes: | ||
1111 | lbl = "<b>No selections made</b>" | ||
1112 | msg = "You have not made any selections" | ||
1113 | msg = msg + " so there isn't anything to bake at this time." | ||
1114 | dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_INFO, msg) | ||
1115 | button = dialog.add_button("Close", gtk.RESPONSE_OK) | ||
1116 | HobButton.style_button(button) | ||
1117 | dialog.run() | ||
1118 | dialog.destroy() | ||
1119 | return | ||
1120 | self.generate_packages_async(True) | ||
1121 | |||
1122 | def build_image(self): | ||
1123 | selected_packages = self.package_model.get_selected_packages() | ||
1124 | if not selected_packages: | ||
1125 | lbl = "<b>No selections made</b>" | ||
1126 | msg = "You have not made any selections" | ||
1127 | msg = msg + " so there isn't anything to bake at this time." | ||
1128 | dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_INFO, msg) | ||
1129 | button = dialog.add_button("Close", gtk.RESPONSE_OK) | ||
1130 | HobButton.style_button(button) | ||
1131 | dialog.run() | ||
1132 | dialog.destroy() | ||
1133 | return | ||
1134 | self.generate_image_async(True) | ||
1135 | |||
1136 | def just_bake(self): | ||
1137 | selected_image = self.recipe_model.get_selected_image() | ||
1138 | selected_packages = self.package_model.get_selected_packages() or [] | ||
1139 | |||
1140 | # If no base image and no selected packages don't build anything | ||
1141 | if not (selected_packages or selected_image != self.recipe_model.__custom_image__): | ||
1142 | lbl = "<b>No selections made</b>" | ||
1143 | msg = "You have not made any selections" | ||
1144 | msg = msg + " so there isn't anything to bake at this time." | ||
1145 | dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_INFO, msg) | ||
1146 | button = dialog.add_button("Close", gtk.RESPONSE_OK) | ||
1147 | HobButton.style_button(button) | ||
1148 | dialog.run() | ||
1149 | dialog.destroy() | ||
1150 | return | ||
1151 | |||
1152 | self.fast_generate_image_async(True) | ||
1153 | |||
1154 | def show_recipe_property_dialog(self, properties): | ||
1155 | information = {} | ||
1156 | dialog = PropertyDialog(title = properties["name"] +' '+ "properties", | ||
1157 | parent = self, | ||
1158 | information = properties, | ||
1159 | flags = gtk.DIALOG_DESTROY_WITH_PARENT | ||
1160 | | gtk.DIALOG_NO_SEPARATOR) | ||
1161 | |||
1162 | dialog.set_modal(False) | ||
1163 | |||
1164 | button = dialog.add_button("Close", gtk.RESPONSE_NO) | ||
1165 | HobAltButton.style_button(button) | ||
1166 | button.connect("clicked", lambda w: dialog.destroy()) | ||
1167 | |||
1168 | dialog.run() | ||
1169 | |||
1170 | def show_packages_property_dialog(self, properties): | ||
1171 | information = {} | ||
1172 | dialog = PropertyDialog(title = properties["name"] +' '+ "properties", | ||
1173 | parent = self, | ||
1174 | information = properties, | ||
1175 | flags = gtk.DIALOG_DESTROY_WITH_PARENT | ||
1176 | | gtk.DIALOG_NO_SEPARATOR) | ||
1177 | |||
1178 | dialog.set_modal(False) | ||
1179 | |||
1180 | button = dialog.add_button("Close", gtk.RESPONSE_NO) | ||
1181 | HobAltButton.style_button(button) | ||
1182 | button.connect("clicked", lambda w: dialog.destroy()) | ||
1183 | |||
1184 | dialog.run() | ||
1185 | |||
1186 | def show_layer_selection_dialog(self): | ||
1187 | dialog = LayerSelectionDialog(title = "Layers", | ||
1188 | layers = copy.deepcopy(self.configuration.layers), | ||
1189 | layers_non_removable = copy.deepcopy(self.configuration.layers_non_removable), | ||
1190 | all_layers = self.parameters.all_layers, | ||
1191 | parent = self, | ||
1192 | flags = gtk.DIALOG_MODAL | ||
1193 | | gtk.DIALOG_DESTROY_WITH_PARENT | ||
1194 | | gtk.DIALOG_NO_SEPARATOR) | ||
1195 | button = dialog.add_button("Cancel", gtk.RESPONSE_NO) | ||
1196 | HobAltButton.style_button(button) | ||
1197 | button = dialog.add_button("OK", gtk.RESPONSE_YES) | ||
1198 | HobButton.style_button(button) | ||
1199 | response = dialog.run() | ||
1200 | if response == gtk.RESPONSE_YES: | ||
1201 | self.configuration.layers = dialog.layers | ||
1202 | # DO refresh layers | ||
1203 | if dialog.layers_changed: | ||
1204 | self.update_config_async() | ||
1205 | dialog.destroy() | ||
1206 | |||
1207 | def get_image_extension(self): | ||
1208 | image_extension = {} | ||
1209 | for type in self.parameters.image_types: | ||
1210 | ext = self.handler.runCommand(["getVariable", "IMAGE_EXTENSION_%s" % type]) | ||
1211 | if ext: | ||
1212 | image_extension[type] = ext.split(' ') | ||
1213 | |||
1214 | return image_extension | ||
1215 | |||
1216 | def show_load_my_images_dialog(self): | ||
1217 | image_extension = self.get_image_extension() | ||
1218 | dialog = ImageSelectionDialog(self.parameters.image_addr, self.parameters.image_types, | ||
1219 | "Open My Images", self, | ||
1220 | gtk.FILE_CHOOSER_ACTION_SAVE, None, | ||
1221 | image_extension) | ||
1222 | button = dialog.add_button("Cancel", gtk.RESPONSE_NO) | ||
1223 | HobAltButton.style_button(button) | ||
1224 | button = dialog.add_button("Open", gtk.RESPONSE_YES) | ||
1225 | HobButton.style_button(button) | ||
1226 | response = dialog.run() | ||
1227 | if response == gtk.RESPONSE_YES: | ||
1228 | if not dialog.image_names: | ||
1229 | lbl = "<b>No selections made</b>" | ||
1230 | msg = "You have not made any selections" | ||
1231 | crumbs_dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_INFO, msg) | ||
1232 | button = crumbs_dialog.add_button("Close", gtk.RESPONSE_OK) | ||
1233 | HobButton.style_button(button) | ||
1234 | crumbs_dialog.run() | ||
1235 | crumbs_dialog.destroy() | ||
1236 | dialog.destroy() | ||
1237 | return | ||
1238 | |||
1239 | self.parameters.image_addr = dialog.image_folder | ||
1240 | self.parameters.image_names = dialog.image_names[:] | ||
1241 | self.switch_page(self.MY_IMAGE_OPENED) | ||
1242 | |||
1243 | dialog.destroy() | ||
1244 | |||
1245 | def show_adv_settings_dialog(self, tab=None): | ||
1246 | dialog = AdvancedSettingsDialog(title = "Advanced configuration", | ||
1247 | configuration = copy.deepcopy(self.configuration), | ||
1248 | all_image_types = self.parameters.image_types, | ||
1249 | all_package_formats = self.parameters.all_package_formats, | ||
1250 | all_distros = self.parameters.all_distros, | ||
1251 | all_sdk_machines = self.parameters.all_sdk_machines, | ||
1252 | max_threads = self.parameters.max_threads, | ||
1253 | parent = self, | ||
1254 | flags = gtk.DIALOG_MODAL | ||
1255 | | gtk.DIALOG_DESTROY_WITH_PARENT | ||
1256 | | gtk.DIALOG_NO_SEPARATOR) | ||
1257 | button = dialog.add_button("Cancel", gtk.RESPONSE_NO) | ||
1258 | HobAltButton.style_button(button) | ||
1259 | button = dialog.add_button("Save", gtk.RESPONSE_YES) | ||
1260 | HobButton.style_button(button) | ||
1261 | dialog.set_save_button(button) | ||
1262 | response = dialog.run() | ||
1263 | settings_changed = False | ||
1264 | if response == gtk.RESPONSE_YES: | ||
1265 | self.configuration = dialog.configuration | ||
1266 | self.configuration.save(self.handler, True) # remember settings | ||
1267 | settings_changed = dialog.settings_changed | ||
1268 | dialog.destroy() | ||
1269 | return response == gtk.RESPONSE_YES, settings_changed | ||
1270 | |||
1271 | def show_simple_settings_dialog(self, tab=None): | ||
1272 | dialog = SimpleSettingsDialog(title = "Settings", | ||
1273 | configuration = copy.deepcopy(self.configuration), | ||
1274 | all_image_types = self.parameters.image_types, | ||
1275 | all_package_formats = self.parameters.all_package_formats, | ||
1276 | all_distros = self.parameters.all_distros, | ||
1277 | all_sdk_machines = self.parameters.all_sdk_machines, | ||
1278 | max_threads = self.parameters.max_threads, | ||
1279 | parent = self, | ||
1280 | flags = gtk.DIALOG_MODAL | ||
1281 | | gtk.DIALOG_DESTROY_WITH_PARENT | ||
1282 | | gtk.DIALOG_NO_SEPARATOR, | ||
1283 | handler = self.handler) | ||
1284 | button = dialog.add_button("Cancel", gtk.RESPONSE_NO) | ||
1285 | HobAltButton.style_button(button) | ||
1286 | button = dialog.add_button("Save", gtk.RESPONSE_YES) | ||
1287 | HobButton.style_button(button) | ||
1288 | if tab: | ||
1289 | dialog.switch_to_page(tab) | ||
1290 | response = dialog.run() | ||
1291 | settings_changed = False | ||
1292 | if response == gtk.RESPONSE_YES: | ||
1293 | self.configuration = dialog.configuration | ||
1294 | self.configuration.save(self.handler, True) # remember settings | ||
1295 | settings_changed = dialog.settings_changed | ||
1296 | if dialog.proxy_settings_changed: | ||
1297 | self.set_user_config_proxies() | ||
1298 | elif dialog.proxy_test_ran: | ||
1299 | # The user might have modified the proxies in the "Proxy" | ||
1300 | # tab, which in turn made the proxy settings modify in bb. | ||
1301 | # If "Cancel" was pressed, restore the previous proxy | ||
1302 | # settings inside bb. | ||
1303 | self.set_user_config_proxies() | ||
1304 | dialog.destroy() | ||
1305 | return response == gtk.RESPONSE_YES, settings_changed | ||
1306 | |||
1307 | def reparse_post_adv_settings(self): | ||
1308 | if not self.configuration.curr_mach: | ||
1309 | self.update_config_async() | ||
1310 | else: | ||
1311 | self.configuration.clear_selection() | ||
1312 | # DO reparse recipes | ||
1313 | self.populate_recipe_package_info_async() | ||
1314 | |||
1315 | def deploy_image(self, image_name): | ||
1316 | if not image_name: | ||
1317 | lbl = "<b>Please select an image to deploy.</b>" | ||
1318 | dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_INFO) | ||
1319 | button = dialog.add_button("Close", gtk.RESPONSE_OK) | ||
1320 | HobButton.style_button(button) | ||
1321 | dialog.run() | ||
1322 | dialog.destroy() | ||
1323 | return | ||
1324 | |||
1325 | image_path = os.path.join(self.parameters.image_addr, image_name) | ||
1326 | dialog = DeployImageDialog(title = "Usb Image Maker", | ||
1327 | image_path = image_path, | ||
1328 | parent = self, | ||
1329 | flags = gtk.DIALOG_MODAL | ||
1330 | | gtk.DIALOG_DESTROY_WITH_PARENT | ||
1331 | | gtk.DIALOG_NO_SEPARATOR) | ||
1332 | button = dialog.add_button("Close", gtk.RESPONSE_NO) | ||
1333 | HobAltButton.style_button(button) | ||
1334 | button = dialog.add_button("Make usb image", gtk.RESPONSE_YES) | ||
1335 | HobButton.style_button(button) | ||
1336 | response = dialog.run() | ||
1337 | dialog.destroy() | ||
1338 | |||
1339 | def show_load_kernel_dialog(self): | ||
1340 | dialog = gtk.FileChooserDialog("Load Kernel Files", self, | ||
1341 | gtk.FILE_CHOOSER_ACTION_SAVE) | ||
1342 | button = dialog.add_button("Cancel", gtk.RESPONSE_NO) | ||
1343 | HobAltButton.style_button(button) | ||
1344 | button = dialog.add_button("Open", gtk.RESPONSE_YES) | ||
1345 | HobButton.style_button(button) | ||
1346 | filter = gtk.FileFilter() | ||
1347 | filter.set_name("Kernel Files") | ||
1348 | filter.add_pattern("*.bin") | ||
1349 | dialog.add_filter(filter) | ||
1350 | |||
1351 | dialog.set_current_folder(self.parameters.image_addr) | ||
1352 | |||
1353 | response = dialog.run() | ||
1354 | kernel_path = "" | ||
1355 | if response == gtk.RESPONSE_YES: | ||
1356 | kernel_path = dialog.get_filename() | ||
1357 | |||
1358 | dialog.destroy() | ||
1359 | |||
1360 | return kernel_path | ||
1361 | |||
1362 | def runqemu_image(self, image_name, kernel_name): | ||
1363 | if not image_name or not kernel_name: | ||
1364 | lbl = "<b>Please select %s to launch in QEMU.</b>" % ("a kernel" if image_name else "an image") | ||
1365 | dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_INFO) | ||
1366 | button = dialog.add_button("Close", gtk.RESPONSE_OK) | ||
1367 | HobButton.style_button(button) | ||
1368 | dialog.run() | ||
1369 | dialog.destroy() | ||
1370 | return | ||
1371 | |||
1372 | kernel_path = os.path.join(self.parameters.image_addr, kernel_name) | ||
1373 | image_path = os.path.join(self.parameters.image_addr, image_name) | ||
1374 | |||
1375 | source_env_path = os.path.join(self.parameters.core_base, "oe-init-build-env") | ||
1376 | tmp_path = self.parameters.tmpdir | ||
1377 | cmdline = bb.ui.crumbs.utils.which_terminal() | ||
1378 | if os.path.exists(image_path) and os.path.exists(kernel_path) \ | ||
1379 | and os.path.exists(source_env_path) and os.path.exists(tmp_path) \ | ||
1380 | and cmdline: | ||
1381 | cmdline += "\' bash -c \"export OE_TMPDIR=" + tmp_path + "; " | ||
1382 | cmdline += "source " + source_env_path + " " + os.getcwd() + "; " | ||
1383 | cmdline += "runqemu " + kernel_path + " " + image_path + "\"\'" | ||
1384 | subprocess.Popen(shlex.split(cmdline)) | ||
1385 | else: | ||
1386 | lbl = "<b>Path error</b>" | ||
1387 | msg = "One of your paths is wrong," | ||
1388 | msg = msg + " please make sure the following paths exist:\n" | ||
1389 | msg = msg + "image path:" + image_path + "\n" | ||
1390 | msg = msg + "kernel path:" + kernel_path + "\n" | ||
1391 | msg = msg + "source environment path:" + source_env_path + "\n" | ||
1392 | msg = msg + "tmp path: " + tmp_path + "." | ||
1393 | msg = msg + "You may be missing either xterm or vte for terminal services." | ||
1394 | dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_ERROR, msg) | ||
1395 | button = dialog.add_button("Close", gtk.RESPONSE_OK) | ||
1396 | HobButton.style_button(button) | ||
1397 | dialog.run() | ||
1398 | dialog.destroy() | ||
1399 | |||
1400 | def show_packages(self): | ||
1401 | self.package_details_page.refresh_tables() | ||
1402 | self.switch_page(self.PACKAGE_SELECTION) | ||
1403 | |||
1404 | def show_recipes(self): | ||
1405 | self.switch_page(self.RECIPE_SELECTION) | ||
1406 | |||
1407 | def show_image_details(self): | ||
1408 | self.switch_page(self.IMAGE_GENERATED) | ||
1409 | |||
1410 | def show_configuration(self): | ||
1411 | self.switch_page(self.BASEIMG_SELECTED) | ||
1412 | |||
1413 | def stop_build(self): | ||
1414 | if self.stopping: | ||
1415 | lbl = "<b>Force Stop build?</b>" | ||
1416 | msg = "You've already selected Stop once," | ||
1417 | msg = msg + " would you like to 'Force Stop' the build?\n\n" | ||
1418 | msg = msg + "This will stop the build as quickly as possible but may" | ||
1419 | msg = msg + " well leave your build directory in an unusable state" | ||
1420 | msg = msg + " that requires manual steps to fix." | ||
1421 | dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_WARNING, msg) | ||
1422 | button = dialog.add_button("Cancel", gtk.RESPONSE_CANCEL) | ||
1423 | HobAltButton.style_button(button) | ||
1424 | button = dialog.add_button("Force Stop", gtk.RESPONSE_YES) | ||
1425 | HobButton.style_button(button) | ||
1426 | else: | ||
1427 | lbl = "<b>Stop build?</b>" | ||
1428 | msg = "Are you sure you want to stop this" | ||
1429 | msg = msg + " build?\n\n'Stop' will stop the build as soon as all in" | ||
1430 | msg = msg + " progress build tasks are finished. However if a" | ||
1431 | msg = msg + " lengthy compilation phase is in progress this may take" | ||
1432 | msg = msg + " some time.\n\n" | ||
1433 | msg = msg + "'Force Stop' will stop the build as quickly as" | ||
1434 | msg = msg + " possible but may well leave your build directory in an" | ||
1435 | msg = msg + " unusable state that requires manual steps to fix." | ||
1436 | dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_WARNING, msg) | ||
1437 | button = dialog.add_button("Cancel", gtk.RESPONSE_CANCEL) | ||
1438 | HobAltButton.style_button(button) | ||
1439 | button = dialog.add_button("Force stop", gtk.RESPONSE_YES) | ||
1440 | HobAltButton.style_button(button) | ||
1441 | button = dialog.add_button("Stop", gtk.RESPONSE_OK) | ||
1442 | HobButton.style_button(button) | ||
1443 | response = dialog.run() | ||
1444 | dialog.destroy() | ||
1445 | if response != gtk.RESPONSE_CANCEL: | ||
1446 | self.stopping = True | ||
1447 | if response == gtk.RESPONSE_OK: | ||
1448 | self.build_details_page.progress_bar.set_stop_title("Stopping the build....") | ||
1449 | self.build_details_page.progress_bar.set_rcstyle("stop") | ||
1450 | self.cancel_build_sync() | ||
1451 | elif response == gtk.RESPONSE_YES: | ||
1452 | self.cancel_build_sync(True) | ||
1453 | |||
1454 | def do_log(self, consolelogfile = None): | ||
1455 | if consolelogfile: | ||
1456 | bb.utils.mkdirhier(os.path.dirname(consolelogfile)) | ||
1457 | if self.consolelog: | ||
1458 | self.logger.removeHandler(self.consolelog) | ||
1459 | self.consolelog = None | ||
1460 | self.consolelog = logging.FileHandler(consolelogfile) | ||
1461 | bb.msg.addDefaultlogFilter(self.consolelog) | ||
1462 | format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") | ||
1463 | self.consolelog.setFormatter(format) | ||
1464 | |||
1465 | self.logger.addHandler(self.consolelog) | ||
1466 | |||
1467 | def get_topdir(self): | ||
1468 | return self.handler.get_topdir() | ||
1469 | |||
1470 | def wait(self, delay): | ||
1471 | time_start = time.time() | ||
1472 | time_end = time_start + delay | ||
1473 | while time_end > time.time(): | ||
1474 | while gtk.events_pending(): | ||
1475 | gtk.main_iteration() | ||