<p>Toaster has no layer information. Without layer information, you cannot run builds. To generate layer information you can:</p>
<ul>
<li> <a href="http://www.yoctoproject.org/docs/latest/toaster-manual/toaster-manual.html#layer-source">Configure a layer source</a></li>
- <li> <a href="{% url 'importlayer' %}">Import a layer</a></li>
+ <li> <a href="{% url 'importlayer' project.id %}">Import a layer</a></li>
</ul>
</div>
</div>
<i class="icon-question-sign get-help get-help-blue" title="Type the name of one or more recipes you want to build, separated by a space. You can also specify a task by appending a semicolon and a task name to a recipe name, like so: <code>core-image-minimal:do_build</code>"></i>
<p>
- <a href="{% url 'all-targets' %}">View all compatible recipes</a>
+ <a href="{% url 'all-targets' project.id %}">View all compatible recipes</a>
<i class="icon-question-sign get-help get-help-blue heading-help" title="View all the recipes you can build with the release selected for this project, which is {[project.release.desc]}"></i>
{% if completedbuilds.count %}
| <a href="{% url 'projectbuilds' project.id %}">View all project builds ({{completedbuilds.count}})</a>
<p>
You can:
<ul>
- <li> <a href="{% url 'layers'%}">View all compatible layers available in Toaster</a>
- <li> <a href="{% url 'importlayer' %}">Import a layer</a>
+ <li> <a href="{% url 'all-layers' project.id %}">View all compatible layers available in Toaster</a>
+ <li> <a href="{% url 'importlayer' project.id %}">Import a layer</a>
<li> <a href="https://www.yoctoproject.org/docs/1.6.1/dev-manual/dev-manual.html#understanding-and-creating-layers" target="_blank">Read about layers in the manual</a>
</ul>
Or type a layer name below.
{% csrf_token %}
</form>
<p>
- <a href="{% url 'layers' %}">View all compatible layers</a>
+ <a href="{% url 'all-layers' project.id %}">View all compatible layers</a>
<i class="icon-question-sign get-help" title="View all the layers you can build with the release selected for this project, which is {[project.release.desc]}"></i>
|
- <a href="{% url 'importlayer' %}">Import layer</a></p>
+ <a href="{% url 'importlayer' project.id %}">Import layer</a></p>
<ul class="unstyled configuration-list">
<li ng-repeat="l in layers track by l.id" class="animate-repeat">
<a href="{[l.layerdetailurl]}" class="layer-info" data-toggle="tooltip" tooltip-placement="right" tooltip="{[l.giturl]} | {[l.branch.name]}">{[l.name]}</a>
{% csrf_token %}
</form>
<p>
- <a href="{% url 'all-targets' %}">View all compatible recipes</a>
+ <a href="{% url 'all-targets' project.id %}">View all compatible recipes</a>
<i class="icon-question-sign get-help" title="View all the recipes you can build with the release selected for this project, which is {[project.release.desc]}"></i>
</p>
<div ng-if="frequenttargets.length">
{% csrf_token %}
</form>
<p>
- <a href="{% url 'machines' %}" class="link">View all compatible machines</a>
+ <a href="{% url 'all-machines' project.id %}" class="link">View all compatible machines</a>
<i class="icon-question-sign get-help" title="View all the machines you can set with the release selected for this project, which is {[project.release.desc]}"></i>
</p>
</div>
scope.urls.xhr_build = "{% url 'xhr_projectbuild' project.id %}";
scope.urls.xhr_edit = "{% url 'xhr_projectedit' project.id %}";
scope.urls.xhr_datatypeahead = "{% url 'xhr_datatypeahead' %}";
- scope.urls.layers = "{% url 'layers' %}";
- scope.urls.targets = "{% url 'all-targets' %}";
- scope.urls.importlayer = "{% url 'importlayer'%}";
- scope.urls.layer = "{% url 'base_layerdetails' %}";
+ scope.urls.layers = "{% url 'all-layers' project.id %}";
+ scope.urls.targets = "{% url 'all-targets' project.id %}";
+ scope.urls.importlayer = "{% url 'importlayer' project.id %}";
+ scope.urls.layer = "{% url 'base_layerdetails' project.id %}";
scope.project = {{prj|json}};
scope.builds = {{builds|json}};
scope.layers = {{layers|json}};
# project URLs
url(r'^newproject/$', 'newproject', name='newproject'),
- url(r'^importlayer/$', 'importlayer', name='importlayer'),
- url(r'^layers/$', 'layers', name='layers'),
- url(r'^layer/(?P<layerid>\d+)/$', 'layerdetails', name='layerdetails'),
- url(r'^layer/$', lambda x: HttpResponseBadRequest(), name='base_layerdetails'),
- url(r'^targets/$', 'targets', name='all-targets'),
- url(r'^machines/$', 'machines', name='machines'),
url(r'^projects/$', 'projects', name='all-projects'),
url(r'^project/$', lambda x: HttpResponseBadRequest(), name='base_project'),
- url(r'^project/(?P<pid>\d+)/$', 'project', name='project'),
+
+ url(r'^project/(?P<pid>\d+)$', 'project', name='project'),
url(r'^project/(?P<pid>\d+)/configuration$', 'projectconf', name='projectconf'),
- url(r'^project/(?P<pid>\d+)/builds$', 'projectbuilds', name='projectbuilds'),
+ url(r'^project/(?P<pid>\d+)/builds/$', 'projectbuilds', name='projectbuilds'),
+
+ url(r'^project/(?P<pid>\d+)/layers/$', 'layers', name='all-layers'),
+ url(r'^project/(?P<pid>\d+)/layer/(?P<layerid>\d+)$', 'layerdetails', name='layerdetails'),
+ url(r'^project/(?P<pid>\d+)/layer/$', lambda x: HttpResponseBadRequest(), name='base_layerdetails'),
+
+ # the import layer is a project-specific functionality;
+ url(r'^project/(?P<pid>\d+)/importlayer$', 'importlayer', name='importlayer'),
+
+ url(r'^project/(?P<pid>\d+)/targets/$', 'targets', name='all-targets'),
+ url(r'^project/(?P<pid>\d+)/machines/$', 'machines', name='all-machines'),
url(r'^xhr_build/$', 'xhr_build', name='xhr_build'),
url(r'^xhr_projectbuild/(?P<pid>\d+)/$', 'xhr_projectbuild', name='xhr_projectbuild'),
def image_information_dir(request, build_id, target_id, packagefile_id):
# stubbed for now
return redirect(builds)
+ # the context processor that supplies data used across all the pages
+
+
+def managedcontextprocessor(request):
+ import subprocess
+ ret = {
+ "projects": Project.objects.all(),
+ "MANAGED" : toastermain.settings.MANAGED,
+ "DEBUG" : toastermain.settings.DEBUG,
+ "TOASTER_BRANCH": toastermain.settings.TOASTER_BRANCH,
+ "TOASTER_REVISION" : toastermain.settings.TOASTER_REVISION,
+ }
+ return ret
+
import toastermain.settings
class BadParameterException(Exception): pass # error thrown on invalid POST requests
- # the context processor that supplies data used across all the pages
- def managedcontextprocessor(request):
- import subprocess
- ret = {
- "projects": Project.objects.all(),
- "MANAGED" : toastermain.settings.MANAGED,
- "DEBUG" : toastermain.settings.DEBUG,
- "TOASTER_BRANCH": toastermain.settings.TOASTER_BRANCH,
- "TOASTER_REVISION" : toastermain.settings.TOASTER_REVISION,
- }
- if 'project_id' in request.session:
- try:
- ret['project'] = Project.objects.get(pk = request.session['project_id'])
- except Project.DoesNotExist:
- del request.session['project_id']
- return ret
-
class InvalidRequestException(Exception):
def __init__(self, response):
puser = None
# we use implicit knowledge of the current user's project to filter layer information, e.g.
- request.session['project_id'] = prj.id
+ pid = prj.id
from collections import Counter
freqtargets = []
"name" : x.layercommit.layer.name,
"giturl": x.layercommit.layer.vcs_url,
"url": x.layercommit.layer.layer_index_url,
- "layerdetailurl": reverse("layerdetails", args=(x.layercommit.pk,)),
+ "layerdetailurl": reverse("layerdetails", args=(prj.id, x.layercommit.pk,)),
# This branch name is actually the release
"branch" : { "name" : x.layercommit.get_vcs_reference(), "layersource" : x.layercommit.up_branch.layer_source.name if x.layercommit.up_branch != None else None}},
prj.projectlayer_set.all().order_by("id")),
try:
if request.method != "POST":
raise BadParameterException("invalid method")
- request.session['project_id'] = pid
+ pid = pid
prj = Project.objects.get(id = pid)
# return all project settings
return HttpResponse(jsonfilter( {
"error": "ok",
- "layers" : map(lambda x: {"id": x.layercommit.pk, "orderid" : x.pk, "name" : x.layercommit.layer.name, "giturl" : x.layercommit.layer.vcs_url, "url": x.layercommit.layer.layer_index_url, "layerdetailurl": reverse("layerdetails", args=(x.layercommit.pk,)), "branch" : { "name" : x.layercommit.get_vcs_reference(), "layersource" : x.layercommit.up_branch.layer_source.name}}, prj.projectlayer_set.all().select_related("layer").order_by("id")),
+ "layers" : map(lambda x: {"id": x.layercommit.pk, "orderid" : x.pk, "name" : x.layercommit.layer.name, "giturl" : x.layercommit.layer.vcs_url, "url": x.layercommit.layer.layer_index_url, "layerdetailurl": reverse("layerdetails", args=(prj.id, x.layercommit.pk,)), "branch" : { "name" : x.layercommit.get_vcs_reference(), "layersource" : x.layercommit.up_branch.layer_source.name}}, prj.projectlayer_set.all().select_related("layer").order_by("id")),
"builds" : _project_recent_build_list(prj),
"variables": map(lambda x: (x.name, x.value), prj.projectvariable_set.all()),
"machine": {"name": prj.projectvariable_set.get(name="MACHINE").value},
prj = None
if request.GET.has_key('project_id'):
prj = Project.objects.get(pk = request.GET['project_id'])
- elif 'project_id' in request.session:
- prj = Project.objects.get(pk = request.session['project_id'])
else:
raise Exception("No valid project selected")
# returns layer versions that would be deleted on the new release__pk
if request.GET['type'] == "versionlayers":
- if not 'project_id' in request.session:
- raise Exception("This call cannot makes no sense outside a project context")
retval = []
for i in prj.projectlayer_set.all():
- def importlayer(request):
+ def importlayer(request, pid):
template = "importlayer.html"
context = {
+ 'project': Project.objects.get(id=pid),
}
return render(request, template, context)
- def layers(request):
- if not 'project_id' in request.session:
- raise Exception("invalid page: cannot show page without a project")
+ def layers(request, pid):
template = "layers.html"
# define here what parameters the view needs in the GET portion in order to
mandatory_parameters = { 'count': pagesize, 'page' : 1, 'orderby' : orderby };
retval = _verify_parameters( request.GET, mandatory_parameters )
if retval:
- return _redirect_parameters( 'layers', request.GET, mandatory_parameters)
+ return _redirect_parameters( 'all-layers', request.GET, mandatory_parameters, pid=pid)
# boilerplate code that takes a request for an object type and returns a queryset
# for that object type. copypasta for all needed table searches
(filter_string, search_term, ordering_string) = _search_tuple(request, Layer_Version)
- prj = Project.objects.get(pk = request.session['project_id'])
+ prj = Project.objects.get(pk = pid)
queryset_all = prj.compatible_layerversions()
context = {
+ 'project' : prj,
'projectlayerset' : jsonfilter(map(lambda x: x.layercommit.id, prj.projectlayer_set.all())),
'objects' : layer_info,
'objectname' : "layers",
return response
- def layerdetails(request, layerid):
+ def layerdetails(request, pid, layerid):
template = "layerdetails.html"
limit = 10
machines = _build_page_range(Paginator(machines_query.order_by("name"), limit), request.GET.get('mpage', 1))
context = {
+ 'project' : Project.objects.get(pk=pid),
'layerversion': layer_version,
- 'layer_in_project' : ProjectLayer.objects.filter(project_id=request.session['project_id'],layercommit=layerid).count(),
+ 'layer_in_project' : ProjectLayer.objects.filter(project_id=pid,layercommit=layerid).count(),
'machines': machines,
'targets': targets,
'total_targets': Recipe.objects.filter(layer_version=layer_version).count(),
}
return render(request, template, context)
- def targets(request):
- if not 'project_id' in request.session:
- raise Exception("invalid page: cannot show page without a project")
-
+ def targets(request, pid):
template = 'targets.html'
(pagesize, orderby) = _get_parameters_values(request, 100, 'name:+')
mandatory_parameters = { 'count': pagesize, 'page' : 1, 'orderby' : orderby }
retval = _verify_parameters( request.GET, mandatory_parameters )
if retval:
- return _redirect_parameters( 'all-targets', request.GET, mandatory_parameters)
+ return _redirect_parameters( 'all-targets', request.GET, mandatory_parameters, pid = pid)
(filter_string, search_term, ordering_string) = _search_tuple(request, Recipe)
- prj = Project.objects.get(pk = request.session['project_id'])
+ prj = Project.objects.get(pk = pid)
queryset_all = Recipe.objects.filter(Q(layer_version__up_branch__name= prj.release.name) | Q(layer_version__build__in = prj.build_set.all())).filter(name__regex=r'.{1,}.*')
queryset_with_search = _get_queryset(Recipe, queryset_all, None, search_term, ordering_string, '-name')
e.vcs_link_url = e.vcs_link_url.replace('%branch%', e.preffered_layerversion.up_branch.name)
context = {
+ 'project' : prj,
'projectlayerset' : jsonfilter(map(lambda x: x.layercommit.id, prj.projectlayer_set.all().select_related("layercommit"))),
'objects' : target_info,
'objectname' : "recipes",
return response
- def machines(request):
- if not 'project_id' in request.session:
- raise Exception("invalid page: cannot show page without a project")
-
+ def machines(request, pid):
template = "machines.html"
# define here what parameters the view needs in the GET portion in order to
# be able to display something. 'count' and 'page' are mandatory for all views
mandatory_parameters = { 'count': pagesize, 'page' : 1, 'orderby' : orderby };
retval = _verify_parameters( request.GET, mandatory_parameters )
if retval:
- return _redirect_parameters( 'machines', request.GET, mandatory_parameters)
+ return _redirect_parameters( 'all-machines', request.GET, mandatory_parameters, pid = pid)
# boilerplate code that takes a request for an object type and returns a queryset
# for that object type. copypasta for all needed table searches
(filter_string, search_term, ordering_string) = _search_tuple(request, Machine)
- prj = Project.objects.get(pk = request.session['project_id'])
+ prj = Project.objects.get(pk = pid)
compatible_layers = prj.compatible_layerversions()
queryset_all = Machine.objects.filter(layer_version__in=compatible_layers)
# Make sure we only show machines / layers which are compatible
# with the current project
- project_layers = ProjectLayer.objects.filter(project_id=request.session['project_id']).values_list('layercommit',flat=True)
+ project_layers = ProjectLayer.objects.filter(project_id=pid).values_list('layercommit',flat=True)
# Now we need to weed out the layers which will appear as duplicated
# because they're from a layer source which doesn't need to be used
machine_info = _build_page_range(Paginator(queryset_all, request.GET.get('count', 100)),request.GET.get('page', 1))
context = {
+ 'project': prj,
'objects' : machine_info,
'projectlayerset' : jsonfilter(map(lambda x: x.layercommit.id, prj.projectlayer_set.all())),
'objectname' : "machines",
configvars = configvars.exclude(name = var)
context = {
+ 'project': prj,
'configvars': configvars,
'vars_managed': vars_managed,
'vars_fstypes': vars_fstypes,
else:
- # these are pages that are NOT available in interactive mode
- def managedcontextprocessor(request):
- return {
- "projects": [],
- "MANAGED" : toastermain.settings.MANAGED,
- "DEBUG" : toastermain.settings.DEBUG,
- "TOASTER_BRANCH": toastermain.settings.TOASTER_BRANCH,
- "TOASTER_REVISION" : toastermain.settings.TOASTER_REVISION,
- }
-
-
# shows the "all builds" page for interactive mode; this is the old code, simply moved
def builds(request):
template = 'build.html'