mirror of
https://git.yoctoproject.org/poky
synced 2026-02-10 10:43:02 +01:00
In order to remove hob-image.bb from meta-hob, a hob-image.bb should be created somewhere in the build directory. I've saved it in build/recipes/images directory, and moved the templates to recipes/images/custom (here are those templates saved by the user). The image is created when hob starts. Also it appends to BBFILES the directory where it is created. Removed images directory from meta-hob. [YOCTO #5118] (Bitbake rev: 4587297b51b7ca71d314bdb2c06f2061e7d4aa7d) Signed-off-by: Cristiana Voicu <cristiana.voicu@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
670 lines
28 KiB
Python
Executable File
670 lines
28 KiB
Python
Executable File
#!/usr/bin/env python
|
|
#
|
|
# BitBake Graphical GTK User Interface
|
|
#
|
|
# Copyright (C) 2012 Intel Corporation
|
|
#
|
|
# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
|
|
# Authored by Shane Wang <shane.wang@intel.com>
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License version 2 as
|
|
# published by the Free Software Foundation.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along
|
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
import gobject
|
|
import gtk
|
|
from bb.ui.crumbs.hobcolor import HobColors
|
|
from bb.ui.crumbs.hobwidget import hic, HobViewTable, HobAltButton, HobButton
|
|
from bb.ui.crumbs.hobpages import HobPage
|
|
import subprocess
|
|
from bb.ui.crumbs.hig.crumbsdialog import CrumbsDialog
|
|
from bb.ui.crumbs.hig.saveimagedialog import SaveImageDialog
|
|
|
|
#
|
|
# ImageDetailsPage
|
|
#
|
|
class ImageDetailsPage (HobPage):
|
|
|
|
class DetailBox (gtk.EventBox):
|
|
def __init__(self, widget = None, varlist = None, vallist = None, icon = None, button = None, button2=None, color = HobColors.LIGHT_GRAY):
|
|
gtk.EventBox.__init__(self)
|
|
|
|
# set color
|
|
style = self.get_style().copy()
|
|
style.bg[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(color, False, False)
|
|
self.set_style(style)
|
|
|
|
self.row = gtk.Table(1, 2, False)
|
|
self.row.set_border_width(10)
|
|
self.add(self.row)
|
|
|
|
total_rows = 0
|
|
if widget:
|
|
total_rows = 10
|
|
if varlist and vallist:
|
|
# pack the icon and the text on the left
|
|
total_rows += len(varlist)
|
|
self.table = gtk.Table(total_rows, 20, True)
|
|
self.table.set_row_spacings(6)
|
|
self.table.set_size_request(100, -1)
|
|
self.row.attach(self.table, 0, 1, 0, 1, xoptions=gtk.FILL|gtk.EXPAND, yoptions=gtk.FILL)
|
|
|
|
colid = 0
|
|
rowid = 0
|
|
self.line_widgets = {}
|
|
if icon:
|
|
self.table.attach(icon, colid, colid + 2, 0, 1)
|
|
colid = colid + 2
|
|
if widget:
|
|
self.table.attach(widget, colid, 20, 0, 10)
|
|
rowid = 10
|
|
if varlist and vallist:
|
|
for row in range(rowid, total_rows):
|
|
index = row - rowid
|
|
self.line_widgets[varlist[index]] = self.text2label(varlist[index], vallist[index])
|
|
self.table.attach(self.line_widgets[varlist[index]], colid, 20, row, row + 1)
|
|
# pack the button on the right
|
|
if button:
|
|
self.bbox = gtk.VBox()
|
|
self.bbox.pack_start(button, expand=True, fill=False)
|
|
if button2:
|
|
self.bbox.pack_start(button2, expand=True, fill=False)
|
|
self.bbox.set_size_request(150,-1)
|
|
self.row.attach(self.bbox, 1, 2, 0, 1, xoptions=gtk.FILL, yoptions=gtk.EXPAND)
|
|
|
|
def update_line_widgets(self, variable, value):
|
|
if len(self.line_widgets) == 0:
|
|
return
|
|
if not isinstance(self.line_widgets[variable], gtk.Label):
|
|
return
|
|
self.line_widgets[variable].set_markup(self.format_line(variable, value))
|
|
|
|
def wrap_line(self, inputs):
|
|
# wrap the long text of inputs
|
|
wrap_width_chars = 75
|
|
outputs = ""
|
|
tmps = inputs
|
|
less_chars = len(inputs)
|
|
while (less_chars - wrap_width_chars) > 0:
|
|
less_chars -= wrap_width_chars
|
|
outputs += tmps[:wrap_width_chars] + "\n "
|
|
tmps = inputs[less_chars:]
|
|
outputs += tmps
|
|
return outputs
|
|
|
|
def format_line(self, variable, value):
|
|
wraped_value = self.wrap_line(value)
|
|
markup = "<span weight=\'bold\'>%s</span>" % variable
|
|
markup += "<span weight=\'normal\' foreground=\'#1c1c1c\' font_desc=\'14px\'>%s</span>" % wraped_value
|
|
return markup
|
|
|
|
def text2label(self, variable, value):
|
|
# append the name:value to the left box
|
|
# such as "Name: hob-core-minimal-variant-2011-12-15-beagleboard"
|
|
label = gtk.Label()
|
|
label.set_alignment(0.0, 0.5)
|
|
label.set_markup(self.format_line(variable, value))
|
|
return label
|
|
|
|
class BuildDetailBox (gtk.EventBox):
|
|
def __init__(self, varlist = None, vallist = None, icon = None, color = HobColors.LIGHT_GRAY):
|
|
gtk.EventBox.__init__(self)
|
|
|
|
# set color
|
|
style = self.get_style().copy()
|
|
style.bg[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(color, False, False)
|
|
self.set_style(style)
|
|
|
|
self.hbox = gtk.HBox()
|
|
self.hbox.set_border_width(10)
|
|
self.add(self.hbox)
|
|
|
|
total_rows = 0
|
|
if varlist and vallist:
|
|
# pack the icon and the text on the left
|
|
total_rows += len(varlist)
|
|
self.table = gtk.Table(total_rows, 20, True)
|
|
self.table.set_row_spacings(6)
|
|
self.table.set_size_request(100, -1)
|
|
self.hbox.pack_start(self.table, expand=True, fill=True, padding=15)
|
|
|
|
colid = 0
|
|
rowid = 0
|
|
self.line_widgets = {}
|
|
if icon:
|
|
self.table.attach(icon, colid, colid + 2, 0, 1)
|
|
colid = colid + 2
|
|
if varlist and vallist:
|
|
for row in range(rowid, total_rows):
|
|
index = row - rowid
|
|
self.line_widgets[varlist[index]] = self.text2label(varlist[index], vallist[index])
|
|
self.table.attach(self.line_widgets[varlist[index]], colid, 20, row, row + 1)
|
|
|
|
def update_line_widgets(self, variable, value):
|
|
if len(self.line_widgets) == 0:
|
|
return
|
|
if not isinstance(self.line_widgets[variable], gtk.Label):
|
|
return
|
|
self.line_widgets[variable].set_markup(self.format_line(variable, value))
|
|
|
|
def wrap_line(self, inputs):
|
|
# wrap the long text of inputs
|
|
wrap_width_chars = 75
|
|
outputs = ""
|
|
tmps = inputs
|
|
less_chars = len(inputs)
|
|
while (less_chars - wrap_width_chars) > 0:
|
|
less_chars -= wrap_width_chars
|
|
outputs += tmps[:wrap_width_chars] + "\n "
|
|
tmps = inputs[less_chars:]
|
|
outputs += tmps
|
|
return outputs
|
|
|
|
def format_line(self, variable, value):
|
|
wraped_value = self.wrap_line(value)
|
|
markup = "<span weight=\'bold\'>%s</span>" % variable
|
|
markup += "<span weight=\'normal\' foreground=\'#1c1c1c\' font_desc=\'14px\'>%s</span>" % wraped_value
|
|
return markup
|
|
|
|
def text2label(self, variable, value):
|
|
# append the name:value to the left box
|
|
# such as "Name: hob-core-minimal-variant-2011-12-15-beagleboard"
|
|
label = gtk.Label()
|
|
label.set_alignment(0.0, 0.5)
|
|
label.set_markup(self.format_line(variable, value))
|
|
return label
|
|
|
|
def __init__(self, builder):
|
|
super(ImageDetailsPage, self).__init__(builder, "Image details")
|
|
|
|
self.image_store = []
|
|
self.button_ids = {}
|
|
self.details_bottom_buttons = gtk.HBox(False, 6)
|
|
self.image_saved = False
|
|
self.create_visual_elements()
|
|
self.name_field_template = ""
|
|
self.description_field_template = ""
|
|
|
|
def create_visual_elements(self):
|
|
# create visual elements
|
|
# create the toolbar
|
|
self.toolbar = gtk.Toolbar()
|
|
self.toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL)
|
|
self.toolbar.set_style(gtk.TOOLBAR_BOTH)
|
|
|
|
my_images_button = self.append_toolbar_button(self.toolbar,
|
|
"Images",
|
|
hic.ICON_IMAGES_DISPLAY_FILE,
|
|
hic.ICON_IMAGES_HOVER_FILE,
|
|
"Open previously built images",
|
|
self.my_images_button_clicked_cb)
|
|
settings_button = self.append_toolbar_button(self.toolbar,
|
|
"Settings",
|
|
hic.ICON_SETTINGS_DISPLAY_FILE,
|
|
hic.ICON_SETTINGS_HOVER_FILE,
|
|
"View additional build settings",
|
|
self.settings_button_clicked_cb)
|
|
|
|
self.details_top_buttons = self.add_onto_top_bar(self.toolbar)
|
|
|
|
def _remove_all_widget(self):
|
|
children = self.get_children() or []
|
|
for child in children:
|
|
self.remove(child)
|
|
children = self.box_group_area.get_children() or []
|
|
for child in children:
|
|
self.box_group_area.remove(child)
|
|
children = self.details_bottom_buttons.get_children() or []
|
|
for child in children:
|
|
self.details_bottom_buttons.remove(child)
|
|
|
|
def show_page(self, step):
|
|
self.build_succeeded = (step == self.builder.IMAGE_GENERATED)
|
|
image_addr = self.builder.parameters.image_addr
|
|
image_names = self.builder.parameters.image_names
|
|
if self.build_succeeded:
|
|
machine = self.builder.configuration.curr_mach
|
|
base_image = self.builder.recipe_model.get_selected_image()
|
|
layers = self.builder.configuration.layers
|
|
pkg_num = "%s" % len(self.builder.package_model.get_selected_packages())
|
|
log_file = self.builder.current_logfile
|
|
else:
|
|
pkg_num = "N/A"
|
|
log_file = None
|
|
|
|
# remove
|
|
for button_id, button in self.button_ids.items():
|
|
button.disconnect(button_id)
|
|
self._remove_all_widget()
|
|
|
|
# repack
|
|
self.pack_start(self.details_top_buttons, expand=False, fill=False)
|
|
self.pack_start(self.group_align, expand=True, fill=True)
|
|
|
|
self.build_result = None
|
|
if self.image_saved or (self.build_succeeded and self.builder.current_step == self.builder.IMAGE_GENERATING):
|
|
# building is the previous step
|
|
icon = gtk.Image()
|
|
pixmap_path = hic.ICON_INDI_CONFIRM_FILE
|
|
color = HobColors.RUNNING
|
|
pix_buffer = gtk.gdk.pixbuf_new_from_file(pixmap_path)
|
|
icon.set_from_pixbuf(pix_buffer)
|
|
varlist = [""]
|
|
if self.image_saved:
|
|
vallist = ["Your image recipe has been saved"]
|
|
else:
|
|
vallist = ["Your image is ready"]
|
|
self.build_result = self.BuildDetailBox(varlist=varlist, vallist=vallist, icon=icon, color=color)
|
|
self.box_group_area.pack_start(self.build_result, expand=False, fill=False)
|
|
|
|
self.buttonlist = ["Build new image", "Save image recipe", "Run image", "Deploy image"]
|
|
|
|
# Name
|
|
self.image_store = []
|
|
self.toggled_image = ""
|
|
default_image_size = 0
|
|
self.num_toggled = 0
|
|
i = 0
|
|
for image_name in image_names:
|
|
image_size = HobPage._size_to_string(os.stat(os.path.join(image_addr, image_name)).st_size)
|
|
|
|
image_attr = ("run" if (self.test_type_runnable(image_name) and self.test_mach_runnable(image_name)) else \
|
|
("deploy" if self.test_deployable(image_name) else ""))
|
|
is_toggled = (image_attr != "")
|
|
|
|
if not self.toggled_image:
|
|
if i == (len(image_names) - 1):
|
|
is_toggled = True
|
|
if is_toggled:
|
|
default_image_size = image_size
|
|
self.toggled_image = image_name
|
|
|
|
split_stuff = image_name.split('.')
|
|
if "rootfs" in split_stuff:
|
|
image_type = image_name[(len(split_stuff[0]) + len(".rootfs") + 1):]
|
|
else:
|
|
image_type = image_name[(len(split_stuff[0]) + 1):]
|
|
|
|
self.image_store.append({'name': image_name,
|
|
'type': image_type,
|
|
'size': image_size,
|
|
'is_toggled': is_toggled,
|
|
'action_attr': image_attr,})
|
|
|
|
i = i + 1
|
|
self.num_toggled += is_toggled
|
|
|
|
is_runnable = self.create_bottom_buttons(self.buttonlist, self.toggled_image)
|
|
|
|
# Generated image files info
|
|
varlist = ["Name: ", "Files created: ", "Directory: "]
|
|
vallist = []
|
|
|
|
vallist.append(image_name.split('.')[0])
|
|
vallist.append(', '.join(fileitem['type'] for fileitem in self.image_store))
|
|
vallist.append(image_addr)
|
|
|
|
view_files_button = HobAltButton("View files")
|
|
view_files_button.connect("clicked", self.view_files_clicked_cb, image_addr)
|
|
view_files_button.set_tooltip_text("Open the directory containing the image files")
|
|
open_log_button = None
|
|
if log_file:
|
|
open_log_button = HobAltButton("Open log")
|
|
open_log_button.connect("clicked", self.open_log_clicked_cb, log_file)
|
|
open_log_button.set_tooltip_text("Open the build's log file")
|
|
self.image_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=view_files_button, button2=open_log_button)
|
|
self.box_group_area.pack_start(self.image_detail, expand=False, fill=True)
|
|
|
|
# The default kernel box for the qemu images
|
|
self.sel_kernel = ""
|
|
self.kernel_detail = None
|
|
if 'qemu' in image_name:
|
|
self.sel_kernel = self.get_kernel_file_name()
|
|
|
|
# varlist = ["Kernel: "]
|
|
# vallist = []
|
|
# vallist.append(self.sel_kernel)
|
|
|
|
# change_kernel_button = HobAltButton("Change")
|
|
# change_kernel_button.connect("clicked", self.change_kernel_cb)
|
|
# change_kernel_button.set_tooltip_text("Change qemu kernel file")
|
|
# self.kernel_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=change_kernel_button)
|
|
# self.box_group_area.pack_start(self.kernel_detail, expand=True, fill=True)
|
|
|
|
# Machine, Image recipe and Layers
|
|
layer_num_limit = 15
|
|
varlist = ["Machine: ", "Image recipe: ", "Layers: "]
|
|
vallist = []
|
|
self.setting_detail = None
|
|
if self.build_succeeded:
|
|
vallist.append(machine)
|
|
if self.builder.recipe_model.is_custom_image():
|
|
if self.builder.configuration.initial_selected_image == self.builder.recipe_model.__custom_image__:
|
|
base_image ="New image recipe"
|
|
else:
|
|
base_image = self.builder.configuration.initial_selected_image + " (edited)"
|
|
vallist.append(base_image)
|
|
i = 0
|
|
for layer in layers:
|
|
if i > layer_num_limit:
|
|
break
|
|
varlist.append(" - ")
|
|
i += 1
|
|
vallist.append("")
|
|
i = 0
|
|
for layer in layers:
|
|
if i > layer_num_limit:
|
|
break
|
|
elif i == layer_num_limit:
|
|
vallist.append("and more...")
|
|
else:
|
|
vallist.append(layer)
|
|
i += 1
|
|
|
|
edit_config_button = HobAltButton("Edit configuration")
|
|
edit_config_button.set_tooltip_text("Edit machine and image recipe")
|
|
edit_config_button.connect("clicked", self.edit_config_button_clicked_cb)
|
|
self.setting_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=edit_config_button)
|
|
self.box_group_area.pack_start(self.setting_detail, expand=True, fill=True)
|
|
|
|
# Packages included, and Total image size
|
|
varlist = ["Packages included: ", "Total image size: "]
|
|
vallist = []
|
|
vallist.append(pkg_num)
|
|
vallist.append(default_image_size)
|
|
self.builder.configuration.image_size = default_image_size
|
|
self.builder.configuration.image_packages = self.builder.configuration.selected_packages
|
|
if self.build_succeeded:
|
|
edit_packages_button = HobAltButton("Edit packages")
|
|
edit_packages_button.set_tooltip_text("Edit the packages included in your image")
|
|
edit_packages_button.connect("clicked", self.edit_packages_button_clicked_cb)
|
|
else: # get to this page from "My images"
|
|
edit_packages_button = None
|
|
self.package_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=edit_packages_button)
|
|
self.box_group_area.pack_start(self.package_detail, expand=True, fill=True)
|
|
|
|
# pack the buttons at the bottom, at this time they are already created.
|
|
if self.build_succeeded:
|
|
self.box_group_area.pack_end(self.details_bottom_buttons, expand=False, fill=False)
|
|
else: # for "My images" page
|
|
self.details_separator = gtk.HSeparator()
|
|
self.box_group_area.pack_start(self.details_separator, expand=False, fill=False)
|
|
self.box_group_area.pack_start(self.details_bottom_buttons, expand=False, fill=False)
|
|
|
|
self.show_all()
|
|
if self.kernel_detail and (not is_runnable):
|
|
self.kernel_detail.hide()
|
|
self.image_saved = False
|
|
|
|
def view_files_clicked_cb(self, button, image_addr):
|
|
subprocess.call("xdg-open /%s" % image_addr, shell=True)
|
|
|
|
def open_log_clicked_cb(self, button, log_file):
|
|
if log_file:
|
|
log_file = "file:///" + log_file
|
|
gtk.show_uri(screen=button.get_screen(), uri=log_file, timestamp=0)
|
|
|
|
def refresh_package_detail_box(self, image_size):
|
|
self.package_detail.update_line_widgets("Total image size: ", image_size)
|
|
|
|
def test_type_runnable(self, image_name):
|
|
type_runnable = False
|
|
for t in self.builder.parameters.runnable_image_types:
|
|
if image_name.endswith(t):
|
|
type_runnable = True
|
|
break
|
|
return type_runnable
|
|
|
|
def test_mach_runnable(self, image_name):
|
|
mach_runnable = False
|
|
for t in self.builder.parameters.runnable_machine_patterns:
|
|
if t in image_name:
|
|
mach_runnable = True
|
|
break
|
|
return mach_runnable
|
|
|
|
def test_deployable(self, image_name):
|
|
if self.builder.configuration.curr_mach.startswith("qemu"):
|
|
return False
|
|
deployable = False
|
|
for t in self.builder.parameters.deployable_image_types:
|
|
if image_name.endswith(t):
|
|
deployable = True
|
|
break
|
|
return deployable
|
|
|
|
def get_kernel_file_name(self, kernel_addr=""):
|
|
kernel_name = ""
|
|
|
|
if not kernel_addr:
|
|
kernel_addr = self.builder.parameters.image_addr
|
|
|
|
files = [f for f in os.listdir(kernel_addr) if f[0] <> '.']
|
|
for check_file in files:
|
|
if check_file.endswith(".bin"):
|
|
name_splits = check_file.split(".")[0]
|
|
if self.builder.parameters.kernel_image_type in name_splits.split("-"):
|
|
kernel_name = check_file
|
|
break
|
|
|
|
return kernel_name
|
|
|
|
def show_builded_images_dialog(self, widget, primary_action=""):
|
|
title = primary_action if primary_action else "Your builded images"
|
|
dialog = CrumbsDialog(title, self.builder,
|
|
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
|
|
dialog.set_border_width(12)
|
|
|
|
label = gtk.Label()
|
|
label.set_use_markup(True)
|
|
label.set_alignment(0.0, 0.5)
|
|
label.set_padding(12,0)
|
|
if primary_action == "Run image":
|
|
label.set_markup("<span font_desc='12'>Select the image file you want to run:</span>")
|
|
elif primary_action == "Deploy image":
|
|
label.set_markup("<span font_desc='12'>Select the image file you want to deploy:</span>")
|
|
else:
|
|
label.set_markup("<span font_desc='12'>Select the image file you want to %s</span>" % primary_action)
|
|
dialog.vbox.pack_start(label, expand=False, fill=False)
|
|
|
|
# filter created images as action attribution (deploy or run)
|
|
action_attr = ""
|
|
action_images = []
|
|
for fileitem in self.image_store:
|
|
action_attr = fileitem['action_attr']
|
|
if (action_attr == 'run' and primary_action == "Run image") \
|
|
or (action_attr == 'deploy' and primary_action == "Deploy image"):
|
|
action_images.append(fileitem)
|
|
|
|
# pack the corresponding 'runnable' or 'deploy' radio_buttons, if there has no more than one file.
|
|
# assume that there does not both have 'deploy' and 'runnable' files in the same building result
|
|
# in possible as design.
|
|
curr_row = 0
|
|
rows = (len(action_images)) if len(action_images) < 10 else 10
|
|
table = gtk.Table(rows, 10, True)
|
|
table.set_row_spacings(6)
|
|
table.set_col_spacing(0, 12)
|
|
table.set_col_spacing(5, 12)
|
|
|
|
sel_parent_btn = None
|
|
for fileitem in action_images:
|
|
sel_btn = gtk.RadioButton(sel_parent_btn, fileitem['type'])
|
|
sel_parent_btn = sel_btn if not sel_parent_btn else sel_parent_btn
|
|
sel_btn.set_active(fileitem['is_toggled'])
|
|
sel_btn.connect('toggled', self.table_selected_cb, fileitem)
|
|
if curr_row < 10:
|
|
table.attach(sel_btn, 0, 4, curr_row, curr_row + 1, xpadding=24)
|
|
else:
|
|
table.attach(sel_btn, 5, 9, curr_row - 10, curr_row - 9, xpadding=24)
|
|
curr_row += 1
|
|
|
|
dialog.vbox.pack_start(table, expand=False, fill=False, padding=6)
|
|
|
|
button = dialog.add_button("Cancel", gtk.RESPONSE_CANCEL)
|
|
HobAltButton.style_button(button)
|
|
|
|
if primary_action:
|
|
button = dialog.add_button(primary_action, gtk.RESPONSE_YES)
|
|
HobButton.style_button(button)
|
|
|
|
dialog.show_all()
|
|
|
|
response = dialog.run()
|
|
dialog.destroy()
|
|
|
|
if response != gtk.RESPONSE_YES:
|
|
return
|
|
|
|
for fileitem in self.image_store:
|
|
if fileitem['is_toggled']:
|
|
if fileitem['action_attr'] == 'run':
|
|
self.builder.runqemu_image(fileitem['name'], self.sel_kernel)
|
|
elif fileitem['action_attr'] == 'deploy':
|
|
self.builder.deploy_image(fileitem['name'])
|
|
|
|
def table_selected_cb(self, tbutton, image):
|
|
image['is_toggled'] = tbutton.get_active()
|
|
if image['is_toggled']:
|
|
self.toggled_image = image['name']
|
|
|
|
def change_kernel_cb(self, widget):
|
|
kernel_path = self.builder.show_load_kernel_dialog()
|
|
if kernel_path and self.kernel_detail:
|
|
import os.path
|
|
self.sel_kernel = os.path.basename(kernel_path)
|
|
markup = self.kernel_detail.format_line("Kernel: ", self.sel_kernel)
|
|
label = ((self.kernel_detail.get_children()[0]).get_children()[0]).get_children()[0]
|
|
label.set_markup(markup)
|
|
|
|
def create_bottom_buttons(self, buttonlist, image_name):
|
|
# Create the buttons at the bottom
|
|
created = False
|
|
packed = False
|
|
self.button_ids = {}
|
|
is_runnable = False
|
|
|
|
# create button "Deploy image"
|
|
name = "Deploy image"
|
|
if name in buttonlist and self.test_deployable(image_name):
|
|
deploy_button = HobButton('Deploy image')
|
|
#deploy_button.set_size_request(205, 49)
|
|
deploy_button.set_tooltip_text("Burn a live image to a USB drive or flash memory")
|
|
deploy_button.set_flags(gtk.CAN_DEFAULT)
|
|
button_id = deploy_button.connect("clicked", self.deploy_button_clicked_cb)
|
|
self.button_ids[button_id] = deploy_button
|
|
self.details_bottom_buttons.pack_end(deploy_button, expand=False, fill=False)
|
|
created = True
|
|
packed = True
|
|
|
|
name = "Run image"
|
|
if name in buttonlist and self.test_type_runnable(image_name) and self.test_mach_runnable(image_name):
|
|
if created == True:
|
|
# separator
|
|
#label = gtk.Label(" or ")
|
|
#self.details_bottom_buttons.pack_end(label, expand=False, fill=False)
|
|
|
|
# create button "Run image"
|
|
run_button = HobAltButton("Run image")
|
|
else:
|
|
# create button "Run image" as the primary button
|
|
run_button = HobButton("Run image")
|
|
#run_button.set_size_request(205, 49)
|
|
run_button.set_flags(gtk.CAN_DEFAULT)
|
|
packed = True
|
|
run_button.set_tooltip_text("Start up an image with qemu emulator")
|
|
button_id = run_button.connect("clicked", self.run_button_clicked_cb)
|
|
self.button_ids[button_id] = run_button
|
|
self.details_bottom_buttons.pack_end(run_button, expand=False, fill=False)
|
|
created = True
|
|
is_runnable = True
|
|
|
|
name = "Save image recipe"
|
|
if name in buttonlist and self.builder.recipe_model.is_custom_image():
|
|
save_button = HobAltButton("Save image recipe")
|
|
save_button.set_tooltip_text("Keep your changes saving them as an image recipe")
|
|
save_button.set_sensitive(not self.image_saved)
|
|
button_id = save_button.connect("clicked", self.save_button_clicked_cb)
|
|
self.button_ids[button_id] = save_button
|
|
self.details_bottom_buttons.pack_end(save_button, expand=False, fill=False)
|
|
|
|
name = "Build new image"
|
|
if name in buttonlist:
|
|
# create button "Build new image"
|
|
if packed:
|
|
build_new_button = HobAltButton("Build new image")
|
|
else:
|
|
build_new_button = HobButton("Build new image")
|
|
build_new_button.set_flags(gtk.CAN_DEFAULT)
|
|
#build_new_button.set_size_request(205, 49)
|
|
self.details_bottom_buttons.pack_end(build_new_button, expand=False, fill=False)
|
|
build_new_button.set_tooltip_text("Create a new image from scratch")
|
|
button_id = build_new_button.connect("clicked", self.build_new_button_clicked_cb)
|
|
self.button_ids[button_id] = build_new_button
|
|
|
|
return is_runnable
|
|
|
|
def deploy_button_clicked_cb(self, button):
|
|
if self.toggled_image:
|
|
if self.num_toggled > 1:
|
|
self.set_sensitive(False)
|
|
self.show_builded_images_dialog(None, "Deploy image")
|
|
self.set_sensitive(True)
|
|
else:
|
|
self.builder.deploy_image(self.toggled_image)
|
|
|
|
def run_button_clicked_cb(self, button):
|
|
if self.toggled_image:
|
|
if self.num_toggled > 1:
|
|
self.set_sensitive(False)
|
|
self.show_builded_images_dialog(None, "Run image")
|
|
self.set_sensitive(True)
|
|
else:
|
|
self.builder.runqemu_image(self.toggled_image, self.sel_kernel)
|
|
|
|
def save_button_clicked_cb(self, button):
|
|
topdir = self.builder.get_topdir()
|
|
images_dir = topdir + "/recipes/images/custom/"
|
|
self.builder.ensure_dir(images_dir)
|
|
|
|
self.name_field_template = self.builder.image_configuration_page.custom_image_selected
|
|
if self.name_field_template:
|
|
image_path = self.builder.recipe_model.pn_path[self.name_field_template]
|
|
image_iter = self.builder.recipe_model.get_iter(image_path)
|
|
self.description_field_template = self.builder.recipe_model.get_value(image_iter, self.builder.recipe_model.COL_DESC)
|
|
else:
|
|
self.name_field_template = ""
|
|
|
|
dialog = SaveImageDialog(images_dir, self.name_field_template, self.description_field_template,
|
|
"Save image recipe", self.builder, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
|
|
response = dialog.run()
|
|
dialog.destroy()
|
|
|
|
def build_new_button_clicked_cb(self, button):
|
|
self.builder.initiate_new_build_async()
|
|
|
|
def edit_config_button_clicked_cb(self, button):
|
|
self.builder.show_configuration()
|
|
|
|
def edit_packages_button_clicked_cb(self, button):
|
|
self.builder.show_packages()
|
|
|
|
def my_images_button_clicked_cb(self, button):
|
|
self.builder.show_load_my_images_dialog()
|
|
|
|
def settings_button_clicked_cb(self, button):
|
|
# Create an advanced settings dialog
|
|
response, settings_changed = self.builder.show_simple_settings_dialog()
|
|
if not response:
|
|
return
|
|
if settings_changed:
|
|
self.builder.reparse_post_adv_settings()
|