1
0
mirror of https://git.yoctoproject.org/poky synced 2026-06-02 13:29:49 +00:00

bitbake: toaster: Add distro selection support

Add the ability to select a distro in the project page,
based on values from the Layer Index. Add a distro selection
page with the add layer feature, based on the add machine
page.

[YOCTO #10632]

(Bitbake rev: a156a4eff67cdc3943494f5be72b96e3db656250)

Signed-off-by: David Reyna <David.Reyna@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
David Reyna
2017-06-27 13:44:30 -07:00
committed by Richard Purdie
parent 43aaa802c3
commit 4f2baebf36
12 changed files with 325 additions and 3 deletions
+10 -3
View File
@@ -874,6 +874,12 @@ class XhrProject(View):
machinevar.value = request.POST['machineName']
machinevar.save()
# Distro name change
if 'distroName' in request.POST:
distrovar = prj.projectvariable_set.get(name="DISTRO")
distrovar.value = request.POST['distroName']
distrovar.save()
return JsonResponse({"error": "ok"})
def get(self, request, *args, **kwargs):
@@ -960,10 +966,11 @@ class XhrProject(View):
except ProjectVariable.DoesNotExist:
data["machine"] = None
try:
data["distro"] = project.projectvariable_set.get(
name="DISTRO").value
data["distro"] = {"name":
project.projectvariable_set.get(
name="DISTRO").value}
except ProjectVariable.DoesNotExist:
data["distro"] = "-- not set yet"
data["distro"] = None
data['error'] = "ok"
@@ -15,6 +15,13 @@ function projectPageInit(ctx) {
var machineInputForm = $("#machine-input-form");
var invalidMachineNameHelp = $("#invalid-machine-name-help");
var distroChangeInput = $("#distro-change-input");
var distroChangeBtn = $("#distro-change-btn");
var distroForm = $("#select-distro-form");
var distroChangeFormToggle = $("#change-distro-toggle");
var distroNameTitle = $("#project-distro-name");
var distroChangeCancel = $("#cancel-distro-change");
var freqBuildBtn = $("#freq-build-btn");
var freqBuildList = $("#freq-build-list");
@@ -26,6 +33,7 @@ function projectPageInit(ctx) {
var currentLayerAddSelection;
var currentMachineAddSelection = "";
var currentDistroAddSelection = "";
var urlParams = libtoaster.parseUrlParams();
@@ -45,6 +53,17 @@ function projectPageInit(ctx) {
updateMachineName(prjInfo.machine.name);
}
/* If we're receiving a distro set from the url and it's different from
* our current distro then activate set machine sequence.
*/
if (urlParams.hasOwnProperty('setDistro') &&
urlParams.setDistro !== prjInfo.distro.name){
distroChangeInput.val(urlParams.setDistro);
distroChangeBtn.click();
} else {
updateDistroName(prjInfo.distro.name);
}
/* Now we're really ready show the page */
$("#project-page").show();
@@ -278,6 +297,60 @@ function projectPageInit(ctx) {
});
/* Change distro functionality */
distroChangeFormToggle.click(function(){
distroForm.slideDown();
distroNameTitle.hide();
$(this).hide();
});
distroChangeCancel.click(function(){
distroForm.slideUp(function(){
distroNameTitle.show();
distroChangeFormToggle.show();
});
});
function updateDistroName(distroName){
distroChangeInput.val(distroName);
distroNameTitle.text(distroName);
}
libtoaster.makeTypeahead(distroChangeInput,
libtoaster.ctx.distrosTypeAheadUrl,
{ }, function(item){
currentDistroAddSelection = item.name;
distroChangeBtn.removeAttr("disabled");
});
distroChangeBtn.click(function(e){
e.preventDefault();
/* We accept any value regardless of typeahead selection or not */
if (distroChangeInput.val().length === 0)
return;
currentDistroAddSelection = distroChangeInput.val();
libtoaster.editCurrentProject(
{ distroName : currentDistroAddSelection },
function(){
/* Success machine changed */
updateDistroName(currentDistroAddSelection);
distroChangeCancel.click();
/* Show the alert message */
var message = $('<span>You have changed the distro to: <strong><span id="notify-machine-name"></span></strong></span>');
message.find("#notify-machine-name").text(currentDistroAddSelection);
libtoaster.showChangeNotification(message);
},
function(){
/* Failed machine changed */
console.warn("Failed to change distro");
});
});
/* Change release functionality */
function updateProjectRelease(release){
releaseTitle.text(release.description);
+91
View File
@@ -23,6 +23,7 @@ from toastergui.widgets import ToasterTable
from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project
from orm.models import CustomImageRecipe, Package, Target, Build, LogMessage, Task
from orm.models import CustomImagePackage, Package_DependencyManager
from orm.models import Distro
from django.db.models import Q, Max, Sum, Count, When, Case, Value, IntegerField
from django.conf.urls import url
from django.core.urlresolvers import reverse, resolve
@@ -1536,3 +1537,93 @@ class ProjectBuildsTable(BuildsTable):
context['build_in_progress_none_completed'] = False
return context
class DistrosTable(ToasterTable):
"""Table of Distros in Toaster"""
def __init__(self, *args, **kwargs):
super(DistrosTable, self).__init__(*args, **kwargs)
self.empty_state = "Toaster has no distro information for this project. Sadly, distro information cannot be obtained from builds, so this page will remain empty."
self.title = "Compatible Distros"
self.default_orderby = "name"
def get_context_data(self, **kwargs):
context = super(DistrosTable, self).get_context_data(**kwargs)
context['project'] = Project.objects.get(pk=kwargs['pid'])
return context
def setup_filters(self, *args, **kwargs):
project = Project.objects.get(pk=kwargs['pid'])
in_current_project_filter = TableFilter(
"in_current_project",
"Filter by project Distros"
)
in_project_action = TableFilterActionToggle(
"in_project",
"Distro provided by layers added to this project",
ProjectFilters.in_project(self.project_layers)
)
not_in_project_action = TableFilterActionToggle(
"not_in_project",
"Distros provided by layers not added to this project",
ProjectFilters.not_in_project(self.project_layers)
)
in_current_project_filter.add_action(in_project_action)
in_current_project_filter.add_action(not_in_project_action)
self.add_filter(in_current_project_filter)
def setup_queryset(self, *args, **kwargs):
prj = Project.objects.get(pk = kwargs['pid'])
self.queryset = prj.get_all_compatible_distros()
self.queryset = self.queryset.order_by(self.default_orderby)
self.static_context_extra['current_layers'] = \
self.project_layers = \
prj.get_project_layer_versions(pk=True)
def setup_columns(self, *args, **kwargs):
self.add_column(title="Distro",
hideable=False,
orderable=True,
field_name="name")
self.add_column(title="Description",
field_name="description")
layer_link_template = '''
<a href="{% url 'layerdetails' extra.pid data.layer_version.id %}">
{{data.layer_version.layer.name}}</a>
'''
self.add_column(title="Layer",
static_data_name="layer_version__layer__name",
static_data_template=layer_link_template,
orderable=True)
self.add_column(title="Git revision",
help_text="The Git branch, tag or commit. For the layers from the OpenEmbedded layer source, the revision is always the branch compatible with the Yocto Project version you selected for this project",
hidden=True,
field_name="layer_version__get_vcs_reference")
wrtemplate_file_template = '''<code>conf/machine/{{data.name}}.conf</code>
<a href="{{data.get_vcs_machine_file_link_url}}" target="_blank"><span class="glyphicon glyphicon-new-window"></i></a>'''
self.add_column(title="Distro file",
hidden=True,
static_data_name="templatefile",
static_data_template=wrtemplate_file_template)
self.add_column(title="Select",
help_text="Sets the selected distro to the project",
hideable=False,
filter_name="in_current_project",
static_data_name="add-del-layers",
static_data_template='{% include "distro_btn.html" %}')
@@ -49,6 +49,7 @@
recipesTypeAheadUrl: {% url 'xhr_recipestypeahead' project.id as paturl%}{{paturl|json}},
layersTypeAheadUrl: {% url 'xhr_layerstypeahead' project.id as paturl%}{{paturl|json}},
machinesTypeAheadUrl: {% url 'xhr_machinestypeahead' project.id as paturl%}{{paturl|json}},
distrosTypeAheadUrl: {% url 'xhr_distrostypeahead' project.id as paturl%}{{paturl|json}},
projectBuildsUrl: {% url 'projectbuilds' project.id as pburl %}{{pburl|json}},
xhrCustomRecipeUrl : "{% url 'xhr_customrecipe' %}",
projectId : {{project.id}},
@@ -32,6 +32,7 @@ $(document).ready(function(){
<li><a href="{% url 'projectsoftwarerecipes' project.id %}">Software recipes</a></li>
<li><a href="{% url 'projectmachines' project.id %}">Machines</a></li>
<li><a href="{% url 'projectlayers' project.id %}">Layers</a></li>
<li><a href="{% url 'projectdistros' project.id %}">Distros</a></li>
<li class="nav-header">Extra configuration</li>
<li><a href="{% url 'projectconf' project.id %}">BitBake variables</a></li>
@@ -0,0 +1,20 @@
<a href="{% url 'project' extra.pid %}?setDistro={{data.name}}" class="btn btn-default btn-block layer-exists-{{data.layer_version.id}}"
{% if data.layer_version.pk not in extra.current_layers %}
style="display:none;"
{% endif %}>
Set distro</a>
<a class="btn btn-default btn-block layerbtn layer-add-{{data.layer_version.id}}" data-layer='{
"id": {{data.layer_version.id}},
"name": "{{data.layer_version.layer.name}}",
"xhrLayerUrl": "{% url "xhr_layer" extra.pid data.pk %}",
"layerdetailurl": "{%url 'layerdetails' extra.pid data.layer_version.id %}"
}' data-directive="add"
{% if data.layer_version.pk in extra.current_layers %}
style="display:none;"
{% endif %}
>
<span class="glyphicon glyphicon-plus"></span>
Add layer
<span class="glyphicon glyphicon-question-sign get-help" title="To select this distro, you must first add the {{data.layer_version.layer.name}} layer to your project"></i>
</a>
@@ -77,6 +77,22 @@
</form>
</div>
<div class="well well-transparent" id="distro-section">
<h3>Distro</h3>
<p class="lead"><span id="project-distro-name"></span> <span class="glyphicon glyphicon-edit" id="change-distro-toggle"></span></p>
<form id="select-distro-form" style="display:none;" class="form-inline">
<span class="help-block">Distro suggestions come from the Layer Index</a></span>
<div class="form-group">
<input class="form-control" id="distro-change-input" autocomplete="off" value="" data-provide="typeahead" data-minlength="1" data-autocomplete="off" type="text">
</div>
<button id="distro-change-btn" class="btn btn-default" type="button">Save</button>
<a href="#" id="cancel-distro-change" class="btn btn-link">Cancel</a>
<p class="form-link"><a href="{% url 'projectdistros' project.id %}">View compatible distros</a></p>
</form>
</div>
<div class="well well-transparent">
<h3>Most built recipes</h3>
@@ -100,6 +100,36 @@ class MachinesTypeAhead(ToasterTypeAhead):
return results
class DistrosTypeAhead(ToasterTypeAhead):
""" Typeahead for all the distros available in the current project's
configuration """
def __init__(self):
super(DistrosTypeAhead, self).__init__()
def apply_search(self, search_term, prj, request):
distros = prj.get_available_distros()
distros = distros.order_by("name")
primary_results = distros.filter(name__istartswith=search_term)
secondary_results = distros.filter(name__icontains=search_term).exclude(pk__in=primary_results)
tertiary_results = distros.filter(layer_version__layer__name__icontains=search_term).exclude(pk__in=primary_results).exclude(pk__in=secondary_results)
results = []
for distro in list(primary_results) + list(secondary_results) + list(tertiary_results):
detail = "[ %s ]" % (distro.layer_version.layer.name)
needed_fields = {
'id' : distro.pk,
'name' : distro.name,
'detail' : detail,
}
results.append(needed_fields)
return results
class RecipesTypeAhead(ToasterTypeAhead):
""" Typeahead for all the recipes available in the current project's
configuration """
+8
View File
@@ -158,6 +158,11 @@ urlpatterns = [
name=tables.LayerMachinesTable.__name__.lower()),
url(r'^project/(?P<pid>\d+)/distros/$',
tables.DistrosTable.as_view(template_name="generic-toastertable-page.html"),
name="projectdistros"),
url(r'^project/(?P<pid>\d+)/customrecipe/(?P<custrecipeid>\d+)/selectpackages/$',
tables.SelectPackagesTable.as_view(), name="recipeselectpackages"),
@@ -187,6 +192,9 @@ urlpatterns = [
typeaheads.GitRevisionTypeAhead.as_view(),
name='xhr_gitrevtypeahead'),
url(r'^xhr_typeahead/(?P<pid>\d+)/distros$',
typeaheads.DistrosTypeAhead.as_view(), name='xhr_distrostypeahead'),
url(r'^xhr_testreleasechange/(?P<pid>\d+)$', views.xhr_testreleasechange,
name='xhr_testreleasechange'),
url(r'^xhr_configvaredit/(?P<pid>\d+)$', views.xhr_configvaredit,