diff options
| -rwxr-xr-x | bitbake/bin/toaster | 19 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/templates/base.html | 4 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/templates/landing.html | 2 | ||||
| -rwxr-xr-x | bitbake/lib/toaster/toastergui/views.py | 57 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/widgets.py | 4 |
5 files changed, 58 insertions, 28 deletions
diff --git a/bitbake/bin/toaster b/bitbake/bin/toaster index 762451df23..4036f0ad58 100755 --- a/bitbake/bin/toaster +++ b/bitbake/bin/toaster | |||
| @@ -18,9 +18,10 @@ | |||
| 18 | # along with this program. If not, see http://www.gnu.org/licenses/. | 18 | # along with this program. If not, see http://www.gnu.org/licenses/. |
| 19 | 19 | ||
| 20 | HELP=" | 20 | HELP=" |
| 21 | Usage: source toaster start|stop [webport=<address:port>] [noweb] | 21 | Usage: source toaster start|stop [webport=<address:port>] [noweb] [nobuild] |
| 22 | Optional arguments: | 22 | Optional arguments: |
| 23 | [noweb] Setup the environment for building with toaster but don't start the development server | 23 | [nobuild] Setup the environment for capturing builds with toaster but disable managed builds |
| 24 | [noweb] Setup the environment for capturing builds with toaster but don't start the web server | ||
| 24 | [webport] Set the development server (default: localhost:8000) | 25 | [webport] Set the development server (default: localhost:8000) |
| 25 | " | 26 | " |
| 26 | 27 | ||
| @@ -183,6 +184,7 @@ unset OE_ROOT | |||
| 183 | 184 | ||
| 184 | 185 | ||
| 185 | WEBSERVER=1 | 186 | WEBSERVER=1 |
| 187 | export TOASTER_BUILDSERVER=1 | ||
| 186 | ADDR_PORT="localhost:8000" | 188 | ADDR_PORT="localhost:8000" |
| 187 | unset CMD | 189 | unset CMD |
| 188 | for param in $*; do | 190 | for param in $*; do |
| @@ -190,6 +192,9 @@ for param in $*; do | |||
| 190 | noweb ) | 192 | noweb ) |
| 191 | WEBSERVER=0 | 193 | WEBSERVER=0 |
| 192 | ;; | 194 | ;; |
| 195 | nobuild ) | ||
| 196 | TOASTER_BUILDSERVER=0 | ||
| 197 | ;; | ||
| 193 | start ) | 198 | start ) |
| 194 | CMD=$param | 199 | CMD=$param |
| 195 | ;; | 200 | ;; |
| @@ -286,9 +291,13 @@ case $CMD in | |||
| 286 | return 4 | 291 | return 4 |
| 287 | fi | 292 | fi |
| 288 | export BITBAKE_UI='toasterui' | 293 | export BITBAKE_UI='toasterui' |
| 289 | $MANAGE runbuilds \ | 294 | if [ $TOASTER_BUILDSERVER -eq 1 ] ; then |
| 290 | </dev/null >>${BUILDDIR}/toaster_runbuilds.log 2>&1 \ | 295 | $MANAGE runbuilds \ |
| 291 | & echo $! >${BUILDDIR}/.runbuilds.pid | 296 | </dev/null >>${BUILDDIR}/toaster_runbuilds.log 2>&1 \ |
| 297 | & echo $! >${BUILDDIR}/.runbuilds.pid | ||
| 298 | else | ||
| 299 | echo "Toaster build server not started." | ||
| 300 | fi | ||
| 292 | 301 | ||
| 293 | # set fail safe stop system on terminal exit | 302 | # set fail safe stop system on terminal exit |
| 294 | trap stop_system SIGHUP | 303 | trap stop_system SIGHUP |
diff --git a/bitbake/lib/toaster/toastergui/templates/base.html b/bitbake/lib/toaster/toastergui/templates/base.html index edbd110c25..4f7206489b 100644 --- a/bitbake/lib/toaster/toastergui/templates/base.html +++ b/bitbake/lib/toaster/toastergui/templates/base.html | |||
| @@ -110,6 +110,7 @@ | |||
| 110 | All builds | 110 | All builds |
| 111 | </a> | 111 | </a> |
| 112 | </li> | 112 | </li> |
| 113 | {% if project_enable %} | ||
| 113 | <li id="navbar-all-projects" | 114 | <li id="navbar-all-projects" |
| 114 | {% if request.resolver_match.url_name == 'all-projects' %} | 115 | {% if request.resolver_match.url_name == 'all-projects' %} |
| 115 | class="active" | 116 | class="active" |
| @@ -119,6 +120,7 @@ | |||
| 119 | All projects | 120 | All projects |
| 120 | </a> | 121 | </a> |
| 121 | </li> | 122 | </li> |
| 123 | {% endif %} | ||
| 122 | {% endif %} | 124 | {% endif %} |
| 123 | <li id="navbar-docs"> | 125 | <li id="navbar-docs"> |
| 124 | <a target="_blank" href="http://www.yoctoproject.org/docs/latest/toaster-manual/toaster-manual.html"> | 126 | <a target="_blank" href="http://www.yoctoproject.org/docs/latest/toaster-manual/toaster-manual.html"> |
| @@ -127,7 +129,9 @@ | |||
| 127 | </a> | 129 | </a> |
| 128 | </li> | 130 | </li> |
| 129 | </ul> | 131 | </ul> |
| 132 | {% if project_enable %} | ||
| 130 | <a class="btn btn-default navbar-btn navbar-right" id="new-project-button" href="{% url 'newproject' %}">New project</a> | 133 | <a class="btn btn-default navbar-btn navbar-right" id="new-project-button" href="{% url 'newproject' %}">New project</a> |
| 134 | {% endif %} | ||
| 131 | </div> | 135 | </div> |
| 132 | </div> | 136 | </div> |
| 133 | </nav> | 137 | </nav> |
diff --git a/bitbake/lib/toaster/toastergui/templates/landing.html b/bitbake/lib/toaster/toastergui/templates/landing.html index cf7516dbc8..70c7359fad 100644 --- a/bitbake/lib/toaster/toastergui/templates/landing.html +++ b/bitbake/lib/toaster/toastergui/templates/landing.html | |||
| @@ -21,11 +21,13 @@ | |||
| 21 | </p> | 21 | </p> |
| 22 | 22 | ||
| 23 | {% if lvs_nos %} | 23 | {% if lvs_nos %} |
| 24 | {% if project_enable %} | ||
| 24 | <p class="top-air"> | 25 | <p class="top-air"> |
| 25 | <a class="btn btn-primary btn-lg" href="{% url 'newproject' %}"> | 26 | <a class="btn btn-primary btn-lg" href="{% url 'newproject' %}"> |
| 26 | Create your first Toaster project to run manage builds | 27 | Create your first Toaster project to run manage builds |
| 27 | </a> | 28 | </a> |
| 28 | </p> | 29 | </p> |
| 30 | {% endif %} | ||
| 29 | {% else %} | 31 | {% else %} |
| 30 | <div class="alert alert-info lead top-air"> | 32 | <div class="alert alert-info lead top-air"> |
| 31 | Toaster has no layer information. Without layer information, you cannot run builds. To generate layer information you can: | 33 | Toaster has no layer information. Without layer information, you cannot run builds. To generate layer information you can: |
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index 209b07dad8..34ed2b2e3c 100755 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py | |||
| @@ -49,6 +49,8 @@ import logging | |||
| 49 | 49 | ||
| 50 | logger = logging.getLogger("toaster") | 50 | logger = logging.getLogger("toaster") |
| 51 | 51 | ||
| 52 | # Project creation and managed build enable | ||
| 53 | project_enable = ('1' == os.environ.get('TOASTER_BUILDSERVER')) | ||
| 52 | 54 | ||
| 53 | class MimeTypeFinder(object): | 55 | class MimeTypeFinder(object): |
| 54 | # setting this to False enables additional non-standard mimetypes | 56 | # setting this to False enables additional non-standard mimetypes |
| @@ -65,6 +67,12 @@ class MimeTypeFinder(object): | |||
| 65 | guessed_type = 'application/octet-stream' | 67 | guessed_type = 'application/octet-stream' |
| 66 | return guessed_type | 68 | return guessed_type |
| 67 | 69 | ||
| 70 | # single point to add global values into the context before rendering | ||
| 71 | def toaster_render(request, page, context): | ||
| 72 | context['project_enable'] = project_enable | ||
| 73 | return render(request, page, context) | ||
| 74 | |||
| 75 | |||
| 68 | # all new sessions should come through the landing page; | 76 | # all new sessions should come through the landing page; |
| 69 | # determine in which mode we are running in, and redirect appropriately | 77 | # determine in which mode we are running in, and redirect appropriately |
| 70 | def landing(request): | 78 | def landing(request): |
| @@ -86,7 +94,7 @@ def landing(request): | |||
| 86 | 94 | ||
| 87 | context = {'lvs_nos' : Layer_Version.objects.all().count()} | 95 | context = {'lvs_nos' : Layer_Version.objects.all().count()} |
| 88 | 96 | ||
| 89 | return render(request, 'landing.html', context) | 97 | return toaster_render(request, 'landing.html', context) |
| 90 | 98 | ||
| 91 | def objtojson(obj): | 99 | def objtojson(obj): |
| 92 | from django.db.models.query import QuerySet | 100 | from django.db.models.query import QuerySet |
| @@ -519,7 +527,7 @@ def builddashboard( request, build_id ): | |||
| 519 | 'packagecount' : packageCount, | 527 | 'packagecount' : packageCount, |
| 520 | 'logmessages' : logmessages, | 528 | 'logmessages' : logmessages, |
| 521 | } | 529 | } |
| 522 | return render( request, template, context ) | 530 | return toaster_render( request, template, context ) |
| 523 | 531 | ||
| 524 | 532 | ||
| 525 | 533 | ||
| @@ -591,7 +599,7 @@ def task( request, build_id, task_id ): | |||
| 591 | build__completed_on__lt=task_object.build.completed_on).exclude( | 599 | build__completed_on__lt=task_object.build.completed_on).exclude( |
| 592 | order__isnull=True).exclude(outcome=Task.OUTCOME_NA).order_by('-build__completed_on') | 600 | order__isnull=True).exclude(outcome=Task.OUTCOME_NA).order_by('-build__completed_on') |
| 593 | 601 | ||
| 594 | return render( request, template, context ) | 602 | return toaster_render( request, template, context ) |
| 595 | 603 | ||
| 596 | def recipe(request, build_id, recipe_id, active_tab="1"): | 604 | def recipe(request, build_id, recipe_id, active_tab="1"): |
| 597 | template = "recipe.html" | 605 | template = "recipe.html" |
| @@ -618,7 +626,7 @@ def recipe(request, build_id, recipe_id, active_tab="1"): | |||
| 618 | 'package_count' : package_count, | 626 | 'package_count' : package_count, |
| 619 | 'tab_states' : tab_states, | 627 | 'tab_states' : tab_states, |
| 620 | } | 628 | } |
| 621 | return render(request, template, context) | 629 | return toaster_render(request, template, context) |
| 622 | 630 | ||
| 623 | def recipe_packages(request, build_id, recipe_id): | 631 | def recipe_packages(request, build_id, recipe_id): |
| 624 | template = "recipe_packages.html" | 632 | template = "recipe_packages.html" |
| @@ -663,7 +671,7 @@ def recipe_packages(request, build_id, recipe_id): | |||
| 663 | }, | 671 | }, |
| 664 | ] | 672 | ] |
| 665 | } | 673 | } |
| 666 | response = render(request, template, context) | 674 | response = toaster_render(request, template, context) |
| 667 | _set_parameters_values(pagesize, orderby, request) | 675 | _set_parameters_values(pagesize, orderby, request) |
| 668 | return response | 676 | return response |
| 669 | 677 | ||
| @@ -785,7 +793,7 @@ def dirinfo(request, build_id, target_id, file_path=None): | |||
| 785 | 'dir_list': dir_list, | 793 | 'dir_list': dir_list, |
| 786 | 'file_path': file_path, | 794 | 'file_path': file_path, |
| 787 | } | 795 | } |
| 788 | return render(request, template, context) | 796 | return toaster_render(request, template, context) |
| 789 | 797 | ||
| 790 | def _find_task_dep(task_object): | 798 | def _find_task_dep(task_object): |
| 791 | tdeps = Task_Dependency.objects.filter(task=task_object).filter(depends_on__order__gt=0) | 799 | tdeps = Task_Dependency.objects.filter(task=task_object).filter(depends_on__order__gt=0) |
| @@ -837,7 +845,7 @@ def configuration(request, build_id): | |||
| 837 | 'build': build, | 845 | 'build': build, |
| 838 | 'project': build.project, | 846 | 'project': build.project, |
| 839 | 'targets': Target.objects.filter(build=build_id)}) | 847 | 'targets': Target.objects.filter(build=build_id)}) |
| 840 | return render(request, template, context) | 848 | return toaster_render(request, template, context) |
| 841 | 849 | ||
| 842 | 850 | ||
| 843 | def configvars(request, build_id): | 851 | def configvars(request, build_id): |
| @@ -926,7 +934,7 @@ def configvars(request, build_id): | |||
| 926 | ], | 934 | ], |
| 927 | } | 935 | } |
| 928 | 936 | ||
| 929 | response = render(request, template, context) | 937 | response = toaster_render(request, template, context) |
| 930 | _set_parameters_values(pagesize, orderby, request) | 938 | _set_parameters_values(pagesize, orderby, request) |
| 931 | return response | 939 | return response |
| 932 | 940 | ||
| @@ -939,7 +947,7 @@ def bfile(request, build_id, package_id): | |||
| 939 | 'project': build.project, | 947 | 'project': build.project, |
| 940 | 'objects' : files | 948 | 'objects' : files |
| 941 | } | 949 | } |
| 942 | return render(request, template, context) | 950 | return toaster_render(request, template, context) |
| 943 | 951 | ||
| 944 | 952 | ||
| 945 | # A set of dependency types valid for both included and built package views | 953 | # A set of dependency types valid for both included and built package views |
| @@ -1092,7 +1100,7 @@ def package_built_detail(request, build_id, package_id): | |||
| 1092 | if paths.all().count() < 2: | 1100 | if paths.all().count() < 2: |
| 1093 | context['disable_sort'] = True; | 1101 | context['disable_sort'] = True; |
| 1094 | 1102 | ||
| 1095 | response = render(request, template, context) | 1103 | response = toaster_render(request, template, context) |
| 1096 | _set_parameters_values(pagesize, orderby, request) | 1104 | _set_parameters_values(pagesize, orderby, request) |
| 1097 | return response | 1105 | return response |
| 1098 | 1106 | ||
| @@ -1111,7 +1119,7 @@ def package_built_dependencies(request, build_id, package_id): | |||
| 1111 | 'other_deps' : dependencies['other_deps'], | 1119 | 'other_deps' : dependencies['other_deps'], |
| 1112 | 'dependency_count' : _get_package_dependency_count(package, -1, False) | 1120 | 'dependency_count' : _get_package_dependency_count(package, -1, False) |
| 1113 | } | 1121 | } |
| 1114 | return render(request, template, context) | 1122 | return toaster_render(request, template, context) |
| 1115 | 1123 | ||
| 1116 | 1124 | ||
| 1117 | def package_included_detail(request, build_id, target_id, package_id): | 1125 | def package_included_detail(request, build_id, target_id, package_id): |
| @@ -1157,7 +1165,7 @@ def package_included_detail(request, build_id, target_id, package_id): | |||
| 1157 | } | 1165 | } |
| 1158 | if paths.all().count() < 2: | 1166 | if paths.all().count() < 2: |
| 1159 | context['disable_sort'] = True | 1167 | context['disable_sort'] = True |
| 1160 | response = render(request, template, context) | 1168 | response = toaster_render(request, template, context) |
| 1161 | _set_parameters_values(pagesize, orderby, request) | 1169 | _set_parameters_values(pagesize, orderby, request) |
| 1162 | return response | 1170 | return response |
| 1163 | 1171 | ||
| @@ -1181,7 +1189,7 @@ def package_included_dependencies(request, build_id, target_id, package_id): | |||
| 1181 | 'reverse_count' : _get_package_reverse_dep_count(package, target_id), | 1189 | 'reverse_count' : _get_package_reverse_dep_count(package, target_id), |
| 1182 | 'dependency_count' : _get_package_dependency_count(package, target_id, True) | 1190 | 'dependency_count' : _get_package_dependency_count(package, target_id, True) |
| 1183 | } | 1191 | } |
| 1184 | return render(request, template, context) | 1192 | return toaster_render(request, template, context) |
| 1185 | 1193 | ||
| 1186 | def package_included_reverse_dependencies(request, build_id, target_id, package_id): | 1194 | def package_included_reverse_dependencies(request, build_id, target_id, package_id): |
| 1187 | template = "package_included_reverse_dependencies.html" | 1195 | template = "package_included_reverse_dependencies.html" |
| @@ -1232,7 +1240,7 @@ def package_included_reverse_dependencies(request, build_id, target_id, package_ | |||
| 1232 | } | 1240 | } |
| 1233 | if objects.all().count() < 2: | 1241 | if objects.all().count() < 2: |
| 1234 | context['disable_sort'] = True | 1242 | context['disable_sort'] = True |
| 1235 | response = render(request, template, context) | 1243 | response = toaster_render(request, template, context) |
| 1236 | _set_parameters_values(pagesize, orderby, request) | 1244 | _set_parameters_values(pagesize, orderby, request) |
| 1237 | return response | 1245 | return response |
| 1238 | 1246 | ||
| @@ -1365,6 +1373,9 @@ if True: | |||
| 1365 | 1373 | ||
| 1366 | # new project | 1374 | # new project |
| 1367 | def newproject(request): | 1375 | def newproject(request): |
| 1376 | if not project_enable: | ||
| 1377 | return redirect( landing ) | ||
| 1378 | |||
| 1368 | template = "newproject.html" | 1379 | template = "newproject.html" |
| 1369 | context = { | 1380 | context = { |
| 1370 | 'email': request.user.email if request.user.is_authenticated() else '', | 1381 | 'email': request.user.email if request.user.is_authenticated() else '', |
| @@ -1379,7 +1390,7 @@ if True: | |||
| 1379 | 1390 | ||
| 1380 | if request.method == "GET": | 1391 | if request.method == "GET": |
| 1381 | # render new project page | 1392 | # render new project page |
| 1382 | return render(request, template, context) | 1393 | return toaster_render(request, template, context) |
| 1383 | elif request.method == "POST": | 1394 | elif request.method == "POST": |
| 1384 | mandatory_fields = ['projectname', 'ptype'] | 1395 | mandatory_fields = ['projectname', 'ptype'] |
| 1385 | try: | 1396 | try: |
| @@ -1419,7 +1430,7 @@ if True: | |||
| 1419 | context['alert'] = "Your chosen username is already used" | 1430 | context['alert'] = "Your chosen username is already used" |
| 1420 | else: | 1431 | else: |
| 1421 | context['alert'] = str(e) | 1432 | context['alert'] = str(e) |
| 1422 | return render(request, template, context) | 1433 | return toaster_render(request, template, context) |
| 1423 | 1434 | ||
| 1424 | raise Exception("Invalid HTTP method for this page") | 1435 | raise Exception("Invalid HTTP method for this page") |
| 1425 | 1436 | ||
| @@ -1427,7 +1438,7 @@ if True: | |||
| 1427 | def project(request, pid): | 1438 | def project(request, pid): |
| 1428 | project = Project.objects.get(pk=pid) | 1439 | project = Project.objects.get(pk=pid) |
| 1429 | context = {"project": project} | 1440 | context = {"project": project} |
| 1430 | return render(request, "project.html", context) | 1441 | return toaster_render(request, "project.html", context) |
| 1431 | 1442 | ||
| 1432 | def jsunittests(request): | 1443 | def jsunittests(request): |
| 1433 | """ Provides a page for the js unit tests """ | 1444 | """ Provides a page for the js unit tests """ |
| @@ -1453,7 +1464,7 @@ if True: | |||
| 1453 | name="MACHINE", | 1464 | name="MACHINE", |
| 1454 | value="qemux86") | 1465 | value="qemux86") |
| 1455 | context = {'project': new_project} | 1466 | context = {'project': new_project} |
| 1456 | return render(request, "js-unit-tests.html", context) | 1467 | return toaster_render(request, "js-unit-tests.html", context) |
| 1457 | 1468 | ||
| 1458 | from django.views.decorators.csrf import csrf_exempt | 1469 | from django.views.decorators.csrf import csrf_exempt |
| 1459 | @csrf_exempt | 1470 | @csrf_exempt |
| @@ -1588,7 +1599,7 @@ if True: | |||
| 1588 | context = { | 1599 | context = { |
| 1589 | 'project': Project.objects.get(id=pid), | 1600 | 'project': Project.objects.get(id=pid), |
| 1590 | } | 1601 | } |
| 1591 | return render(request, template, context) | 1602 | return toaster_render(request, template, context) |
| 1592 | 1603 | ||
| 1593 | def layerdetails(request, pid, layerid): | 1604 | def layerdetails(request, pid, layerid): |
| 1594 | project = Project.objects.get(pk=pid) | 1605 | project = Project.objects.get(pk=pid) |
| @@ -1617,7 +1628,7 @@ if True: | |||
| 1617 | 'projectlayers': list(project_layers) | 1628 | 'projectlayers': list(project_layers) |
| 1618 | } | 1629 | } |
| 1619 | 1630 | ||
| 1620 | return render(request, 'layerdetails.html', context) | 1631 | return toaster_render(request, 'layerdetails.html', context) |
| 1621 | 1632 | ||
| 1622 | 1633 | ||
| 1623 | def get_project_configvars_context(): | 1634 | def get_project_configvars_context(): |
| @@ -1707,7 +1718,7 @@ if True: | |||
| 1707 | except (ProjectVariable.DoesNotExist, BuildEnvironment.DoesNotExist): | 1718 | except (ProjectVariable.DoesNotExist, BuildEnvironment.DoesNotExist): |
| 1708 | pass | 1719 | pass |
| 1709 | 1720 | ||
| 1710 | return render(request, "projectconf.html", context) | 1721 | return toaster_render(request, "projectconf.html", context) |
| 1711 | 1722 | ||
| 1712 | def _file_names_for_artifact(build, artifact_type, artifact_id): | 1723 | def _file_names_for_artifact(build, artifact_type, artifact_id): |
| 1713 | """ | 1724 | """ |
| @@ -1774,7 +1785,7 @@ if True: | |||
| 1774 | 1785 | ||
| 1775 | return response | 1786 | return response |
| 1776 | else: | 1787 | else: |
| 1777 | return render(request, "unavailable_artifact.html") | 1788 | return toaster_render(request, "unavailable_artifact.html") |
| 1778 | except (ObjectDoesNotExist, IOError): | 1789 | except (ObjectDoesNotExist, IOError): |
| 1779 | return render(request, "unavailable_artifact.html") | 1790 | return toaster_render(request, "unavailable_artifact.html") |
| 1780 | 1791 | ||
diff --git a/bitbake/lib/toaster/toastergui/widgets.py b/bitbake/lib/toaster/toastergui/widgets.py index 67c1ff9615..a1792d997f 100644 --- a/bitbake/lib/toaster/toastergui/widgets.py +++ b/bitbake/lib/toaster/toastergui/widgets.py | |||
| @@ -41,6 +41,7 @@ import types | |||
| 41 | import json | 41 | import json |
| 42 | import collections | 42 | import collections |
| 43 | import re | 43 | import re |
| 44 | import os | ||
| 44 | 45 | ||
| 45 | from toastergui.tablefilter import TableFilterMap | 46 | from toastergui.tablefilter import TableFilterMap |
| 46 | 47 | ||
| @@ -86,6 +87,9 @@ class ToasterTable(TemplateView): | |||
| 86 | context['table_name'] = type(self).__name__.lower() | 87 | context['table_name'] = type(self).__name__.lower() |
| 87 | context['empty_state'] = self.empty_state | 88 | context['empty_state'] = self.empty_state |
| 88 | 89 | ||
| 90 | # global variables | ||
| 91 | context['project_enable'] = ('1' == os.environ.get('TOASTER_BUILDSERVER')) | ||
| 92 | |||
| 89 | return context | 93 | return context |
| 90 | 94 | ||
| 91 | def get(self, request, *args, **kwargs): | 95 | def get(self, request, *args, **kwargs): |
