diff options
Diffstat (limited to 'bitbake/lib')
8 files changed, 186 insertions, 92 deletions
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py index 75e6ea3996..0b83b991b9 100644 --- a/bitbake/lib/toaster/orm/models.py +++ b/bitbake/lib/toaster/orm/models.py | |||
@@ -503,33 +503,37 @@ class Build(models.Model): | |||
503 | return Recipe.objects.filter(criteria) \ | 503 | return Recipe.objects.filter(criteria) \ |
504 | .select_related('layer_version', 'layer_version__layer') | 504 | .select_related('layer_version', 'layer_version__layer') |
505 | 505 | ||
506 | def get_custom_image_recipe_names(self): | ||
507 | """ | ||
508 | Get the names of custom image recipes for this build's project | ||
509 | as a list; this is used to screen out custom image recipes from the | ||
510 | recipes for the build by name, and to distinguish image recipes from | ||
511 | custom image recipes | ||
512 | """ | ||
513 | custom_image_recipes = \ | ||
514 | CustomImageRecipe.objects.filter(project=self.project) | ||
515 | return custom_image_recipes.values_list('name', flat=True) | ||
516 | |||
517 | def get_image_recipes(self): | 506 | def get_image_recipes(self): |
518 | """ | 507 | """ |
519 | Returns a queryset of image recipes related to this build, sorted | 508 | Returns a list of image Recipes (custom and built-in) related to this |
520 | by name | 509 | build, sorted by name; note that this has to be done in two steps, as |
510 | there's no way to get all the custom image recipes and image recipes | ||
511 | in one query | ||
521 | """ | 512 | """ |
522 | criteria = Q(is_image=True) | 513 | custom_image_recipes = self.get_custom_image_recipes() |
523 | return self.get_recipes().filter(criteria).order_by('name') | 514 | custom_image_recipe_names = custom_image_recipes.values_list('name', flat=True) |
515 | |||
516 | not_custom_image_recipes = ~Q(name__in=custom_image_recipe_names) & \ | ||
517 | Q(is_image=True) | ||
518 | |||
519 | built_image_recipes = self.get_recipes().filter(not_custom_image_recipes) | ||
520 | |||
521 | # append to the custom image recipes and sort | ||
522 | customisable_image_recipes = list( | ||
523 | itertools.chain(custom_image_recipes, built_image_recipes) | ||
524 | ) | ||
525 | |||
526 | return sorted(customisable_image_recipes, key=lambda recipe: recipe.name) | ||
524 | 527 | ||
525 | def get_custom_image_recipes(self): | 528 | def get_custom_image_recipes(self): |
526 | """ | 529 | """ |
527 | Returns a queryset of custom image recipes related to this build, | 530 | Returns a queryset of CustomImageRecipes related to this build, |
528 | sorted by name | 531 | sorted by name |
529 | """ | 532 | """ |
530 | custom_image_recipe_names = self.get_custom_image_recipe_names() | 533 | built_recipe_names = self.get_recipes().values_list('name', flat=True) |
531 | criteria = Q(is_image=True) & Q(name__in=custom_image_recipe_names) | 534 | criteria = Q(name__in=built_recipe_names) & Q(project=self.project) |
532 | return self.get_recipes().filter(criteria).order_by('name') | 535 | queryset = CustomImageRecipe.objects.filter(criteria).order_by('name') |
536 | return queryset | ||
533 | 537 | ||
534 | def get_outcome_text(self): | 538 | def get_outcome_text(self): |
535 | return Build.BUILD_OUTCOME[int(self.outcome)][1] | 539 | return Build.BUILD_OUTCOME[int(self.outcome)][1] |
@@ -1380,6 +1384,9 @@ class Layer(models.Model): | |||
1380 | 1384 | ||
1381 | # LayerCommit class is synced with layerindex.LayerBranch | 1385 | # LayerCommit class is synced with layerindex.LayerBranch |
1382 | class Layer_Version(models.Model): | 1386 | class Layer_Version(models.Model): |
1387 | """ | ||
1388 | A Layer_Version either belongs to a single project or no project | ||
1389 | """ | ||
1383 | search_allowed_fields = ["layer__name", "layer__summary", "layer__description", "layer__vcs_url", "dirpath", "up_branch__name", "commit", "branch"] | 1390 | search_allowed_fields = ["layer__name", "layer__summary", "layer__description", "layer__vcs_url", "dirpath", "up_branch__name", "commit", "branch"] |
1384 | build = models.ForeignKey(Build, related_name='layer_version_build', default = None, null = True) | 1391 | build = models.ForeignKey(Build, related_name='layer_version_build', default = None, null = True) |
1385 | layer = models.ForeignKey(Layer, related_name='layer_version_layer') | 1392 | layer = models.ForeignKey(Layer, related_name='layer_version_layer') |
diff --git a/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js b/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js index 1ae0d34e90..cb9ed4da05 100644 --- a/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js +++ b/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js | |||
@@ -12,6 +12,7 @@ for the new custom image. This will manage the addition of radio buttons | |||
12 | to select the base image (or remove the radio buttons, if there is only a | 12 | to select the base image (or remove the radio buttons, if there is only a |
13 | single base image available). | 13 | single base image available). |
14 | */ | 14 | */ |
15 | |||
15 | function newCustomImageModalInit(){ | 16 | function newCustomImageModalInit(){ |
16 | 17 | ||
17 | var newCustomImgBtn = $("#create-new-custom-image-btn"); | 18 | var newCustomImgBtn = $("#create-new-custom-image-btn"); |
@@ -21,7 +22,8 @@ function newCustomImageModalInit(){ | |||
21 | var nameInput = imgCustomModal.find('input'); | 22 | var nameInput = imgCustomModal.find('input'); |
22 | 23 | ||
23 | var invalidNameMsg = "Image names cannot contain spaces or capital letters. The only allowed special character is dash (-)."; | 24 | var invalidNameMsg = "Image names cannot contain spaces or capital letters. The only allowed special character is dash (-)."; |
24 | var duplicateNameMsg = "An image with this name already exists. Image names must be unique."; | 25 | var duplicateNameMsg = "A recipe with this name already exists. Image names must be unique."; |
26 | var duplicateImageInProjectMsg = "An image with this name already exists in this project." | ||
25 | var invalidBaseRecipeIdMsg = "Please select an image to customise."; | 27 | var invalidBaseRecipeIdMsg = "Please select an image to customise."; |
26 | 28 | ||
27 | // capture clicks on radio buttons inside the modal; when one is selected, | 29 | // capture clicks on radio buttons inside the modal; when one is selected, |
@@ -51,9 +53,12 @@ function newCustomImageModalInit(){ | |||
51 | if (ret.error === "invalid-name") { | 53 | if (ret.error === "invalid-name") { |
52 | showNameError(invalidNameMsg); | 54 | showNameError(invalidNameMsg); |
53 | return; | 55 | return; |
54 | } else if (ret.error === "already-exists") { | 56 | } else if (ret.error === "recipe-already-exists") { |
55 | showNameError(duplicateNameMsg); | 57 | showNameError(duplicateNameMsg); |
56 | return; | 58 | return; |
59 | } else if (ret.error === "image-already-exists") { | ||
60 | showNameError(duplicateImageInProjectMsg); | ||
61 | return; | ||
57 | } | 62 | } |
58 | } else { | 63 | } else { |
59 | imgCustomModal.modal('hide'); | 64 | imgCustomModal.modal('hide'); |
@@ -112,13 +117,13 @@ function newCustomImageModalSetRecipes(baseRecipes) { | |||
112 | var imageSelector = $('#new-custom-image-modal [data-role="image-selector"]'); | 117 | var imageSelector = $('#new-custom-image-modal [data-role="image-selector"]'); |
113 | var imageSelectRadiosContainer = $('#new-custom-image-modal [data-role="image-selector-radios"]'); | 118 | var imageSelectRadiosContainer = $('#new-custom-image-modal [data-role="image-selector-radios"]'); |
114 | 119 | ||
120 | // remove any existing radio buttons + labels | ||
121 | imageSelector.remove('[data-role="image-radio"]'); | ||
122 | |||
115 | if (baseRecipes.length === 1) { | 123 | if (baseRecipes.length === 1) { |
116 | // hide the radio button container | 124 | // hide the radio button container |
117 | imageSelector.hide(); | 125 | imageSelector.hide(); |
118 | 126 | ||
119 | // remove any radio buttons + labels | ||
120 | imageSelector.remove('[data-role="image-radio"]'); | ||
121 | |||
122 | // set the single recipe ID on the modal as it's the only one | 127 | // set the single recipe ID on the modal as it's the only one |
123 | // we can build from | 128 | // we can build from |
124 | imgCustomModal.data('recipe', baseRecipes[0].id); | 129 | imgCustomModal.data('recipe', baseRecipes[0].id); |
diff --git a/bitbake/lib/toaster/toastergui/templates/base.html b/bitbake/lib/toaster/toastergui/templates/base.html index 192f9fb556..210cf3360c 100644 --- a/bitbake/lib/toaster/toastergui/templates/base.html +++ b/bitbake/lib/toaster/toastergui/templates/base.html | |||
@@ -43,7 +43,6 @@ | |||
43 | recipesTypeAheadUrl: {% url 'xhr_recipestypeahead' project.id as paturl%}{{paturl|json}}, | 43 | recipesTypeAheadUrl: {% url 'xhr_recipestypeahead' project.id as paturl%}{{paturl|json}}, |
44 | layersTypeAheadUrl: {% url 'xhr_layerstypeahead' project.id as paturl%}{{paturl|json}}, | 44 | layersTypeAheadUrl: {% url 'xhr_layerstypeahead' project.id as paturl%}{{paturl|json}}, |
45 | machinesTypeAheadUrl: {% url 'xhr_machinestypeahead' project.id as paturl%}{{paturl|json}}, | 45 | machinesTypeAheadUrl: {% url 'xhr_machinestypeahead' project.id as paturl%}{{paturl|json}}, |
46 | |||
47 | projectBuildsUrl: {% url 'projectbuilds' project.id as pburl %}{{pburl|json}}, | 46 | projectBuildsUrl: {% url 'projectbuilds' project.id as pburl %}{{pburl|json}}, |
48 | xhrCustomRecipeUrl : "{% url 'xhr_customrecipe' %}", | 47 | xhrCustomRecipeUrl : "{% url 'xhr_customrecipe' %}", |
49 | projectId : {{project.id}}, | 48 | projectId : {{project.id}}, |
diff --git a/bitbake/lib/toaster/toastergui/templates/basebuildpage.html b/bitbake/lib/toaster/toastergui/templates/basebuildpage.html index 4a8e2a7abd..0d8c8820da 100644 --- a/bitbake/lib/toaster/toastergui/templates/basebuildpage.html +++ b/bitbake/lib/toaster/toastergui/templates/basebuildpage.html | |||
@@ -1,7 +1,7 @@ | |||
1 | {% extends "base.html" %} | 1 | {% extends "base.html" %} |
2 | {% load projecttags %} | 2 | {% load projecttags %} |
3 | {% load project_url_tag %} | 3 | {% load project_url_tag %} |
4 | {% load queryset_to_list_filter %} | 4 | {% load objects_to_dictionaries_filter %} |
5 | {% load humanize %} | 5 | {% load humanize %} |
6 | {% block pagecontent %} | 6 | {% block pagecontent %} |
7 | <!-- breadcrumbs --> | 7 | <!-- breadcrumbs --> |
@@ -81,33 +81,40 @@ | |||
81 | </p> | 81 | </p> |
82 | </li> | 82 | </li> |
83 | 83 | ||
84 | <li> | 84 | {% with build.get_custom_image_recipes as custom_image_recipes %} |
85 | <!-- edit custom image built during this build --> | 85 | {% if custom_image_recipes.count > 0 %} |
86 | <p class="navbar-btn" data-role="edit-custom-image-trigger"> | 86 | <!-- edit custom image built during this build --> |
87 | <button class="btn btn-block">Edit custom image</button> | 87 | <li> |
88 | </p> | 88 | <p class="navbar-btn" data-role="edit-custom-image-trigger"> |
89 | {% include 'editcustomimage_modal.html' %} | 89 | <button class="btn btn-block">Edit custom image</button> |
90 | <script> | 90 | {% include 'editcustomimage_modal.html' %} |
91 | $(document).ready(function () { | 91 | <script> |
92 | var editableCustomImageRecipes = {{ build.get_custom_image_recipes | queryset_to_list:"id,name" | json }}; | 92 | var editableCustomImageRecipes = {{ custom_image_recipes | objects_to_dictionaries:"id,name" | json }}; |
93 | |||
94 | // edit custom image which was built during this build | ||
95 | var editCustomImageModal = $('#edit-custom-image-modal'); | ||
96 | var editCustomImageTrigger = $('[data-role="edit-custom-image-trigger"]'); | ||
97 | 93 | ||
98 | editCustomImageTrigger.click(function () { | 94 | $(document).ready(function () { |
99 | // if there is a single editable custom image, go direct to the edit | 95 | var editCustomImageTrigger = $('[data-role="edit-custom-image-trigger"]'); |
100 | // page for it; if there are multiple editable custom images, show | 96 | var editCustomImageModal = $('#edit-custom-image-modal'); |
101 | // dialog to select one of them for editing | ||
102 | 97 | ||
103 | // single editable custom image | 98 | // edit custom image which was built during this build |
104 | 99 | editCustomImageTrigger.click(function () { | |
105 | // multiple editable custom images | 100 | // single editable custom image: redirect to the edit page |
106 | editCustomImageModal.modal('show'); | 101 | // for that image |
107 | }); | 102 | if (editableCustomImageRecipes.length === 1) { |
108 | }); | 103 | var url = '{% url "customrecipe" build.project.id custom_image_recipes.first.id %}'; |
109 | </script> | 104 | document.location.href = url; |
110 | </li> | 105 | } |
106 | // multiple editable custom images: show modal to select | ||
107 | // one of them for editing | ||
108 | else { | ||
109 | editCustomImageModal.modal('show'); | ||
110 | } | ||
111 | }); | ||
112 | }); | ||
113 | </script> | ||
114 | </p> | ||
115 | </li> | ||
116 | {% endif %} | ||
117 | {% endwith %} | ||
111 | 118 | ||
112 | <li> | 119 | <li> |
113 | <!-- new custom image from image recipe in this build --> | 120 | <!-- new custom image from image recipe in this build --> |
@@ -119,7 +126,7 @@ | |||
119 | // imageRecipes includes both custom image recipes and built-in | 126 | // imageRecipes includes both custom image recipes and built-in |
120 | // image recipes, any of which can be used as the basis for a | 127 | // image recipes, any of which can be used as the basis for a |
121 | // new custom image | 128 | // new custom image |
122 | var imageRecipes = {{ build.get_image_recipes | queryset_to_list:"id,name" | json }}; | 129 | var imageRecipes = {{ build.get_image_recipes | objects_to_dictionaries:"id,name" | json }}; |
123 | 130 | ||
124 | $(document).ready(function () { | 131 | $(document).ready(function () { |
125 | var newCustomImageModal = $('#new-custom-image-modal'); | 132 | var newCustomImageModal = $('#new-custom-image-modal'); |
@@ -131,6 +138,7 @@ | |||
131 | if (!imageRecipes.length) { | 138 | if (!imageRecipes.length) { |
132 | return; | 139 | return; |
133 | } | 140 | } |
141 | |||
134 | newCustomImageModalSetRecipes(imageRecipes); | 142 | newCustomImageModalSetRecipes(imageRecipes); |
135 | newCustomImageModal.modal('show'); | 143 | newCustomImageModal.modal('show'); |
136 | }); | 144 | }); |
diff --git a/bitbake/lib/toaster/toastergui/templates/editcustomimage_modal.html b/bitbake/lib/toaster/toastergui/templates/editcustomimage_modal.html index fd998f63eb..8046c08fb5 100644 --- a/bitbake/lib/toaster/toastergui/templates/editcustomimage_modal.html +++ b/bitbake/lib/toaster/toastergui/templates/editcustomimage_modal.html | |||
@@ -1,23 +1,71 @@ | |||
1 | <!-- | 1 | <!-- |
2 | modal dialog shown on the build dashboard, for editing an existing custom image | 2 | modal dialog shown on the build dashboard, for editing an existing custom image; |
3 | only shown if more than one custom image was built, so the user needs to | ||
4 | choose which one to edit | ||
5 | |||
6 | required context: | ||
7 | build - a Build object | ||
3 | --> | 8 | --> |
4 | <div class="modal hide fade in" aria-hidden="false" id="edit-custom-image-modal"> | 9 | <div class="modal hide fade in" aria-hidden="false" id="edit-custom-image-modal"> |
5 | <div class="modal-header"> | 10 | <div class="modal-header"> |
6 | <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | 11 | <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> |
7 | <h3>Select custom image to edit</h3> | 12 | <h3>Which image do you want to edit?</h3> |
8 | </div> | 13 | </div> |
14 | |||
9 | <div class="modal-body"> | 15 | <div class="modal-body"> |
10 | <div class="row-fluid"> | 16 | <div class="row-fluid"> |
11 | <span class="help-block"> | 17 | {% for recipe in build.get_custom_image_recipes %} |
12 | Explanation of what this modal is for | 18 | <label class="radio"> |
13 | </span> | 19 | {{recipe.name}} |
14 | </div> | 20 | <input type="radio" class="form-control" name="select-custom-image" |
15 | <div class="control-group controls"> | 21 | data-url="{% url 'customrecipe' build.project.id recipe.id %}"> |
16 | <input type="text" class="huge" placeholder="input box" required> | 22 | </label> |
17 | <span class="help-block error" style="display:none">Error text</span> | 23 | {% endfor %} |
18 | </div> | 24 | </div> |
25 | <span class="help-block error" id="invalid-custom-image-help" style="display:none"> | ||
26 | Please select a custom image to edit. | ||
27 | </span> | ||
19 | </div> | 28 | </div> |
29 | |||
20 | <div class="modal-footer"> | 30 | <div class="modal-footer"> |
21 | <button class="btn btn-primary btn-large" disabled>Action</button> | 31 | <button class="btn btn-primary btn-large" data-url="#" |
32 | data-action="edit-custom-image" disabled> | ||
33 | Edit custom image | ||
34 | </button> | ||
22 | </div> | 35 | </div> |
23 | </div> | 36 | </div> |
37 | |||
38 | <script> | ||
39 | $(document).ready(function () { | ||
40 | var editCustomImageButton = $('[data-action="edit-custom-image"]'); | ||
41 | var error = $('#invalid-custom-image-help'); | ||
42 | var radios = $('[name="select-custom-image"]'); | ||
43 | |||
44 | // return custom image radio buttons which are selected | ||
45 | var getSelectedRadios = function () { | ||
46 | return $('[name="select-custom-image"]:checked'); | ||
47 | }; | ||
48 | |||
49 | radios.change(function () { | ||
50 | if (getSelectedRadios().length === 1) { | ||
51 | editCustomImageButton.removeAttr('disabled'); | ||
52 | error.hide(); | ||
53 | } | ||
54 | else { | ||
55 | editCustomImageButton.attr('disabled', 'disabled'); | ||
56 | error.show(); | ||
57 | } | ||
58 | }); | ||
59 | |||
60 | editCustomImageButton.click(function () { | ||
61 | var selectedRadios = getSelectedRadios(); | ||
62 | |||
63 | if (selectedRadios.length === 1) { | ||
64 | document.location.href = selectedRadios.first().attr('data-url'); | ||
65 | } | ||
66 | else { | ||
67 | error.show(); | ||
68 | } | ||
69 | }); | ||
70 | }); | ||
71 | </script> | ||
diff --git a/bitbake/lib/toaster/toastergui/templatetags/objects_to_dictionaries_filter.py b/bitbake/lib/toaster/toastergui/templatetags/objects_to_dictionaries_filter.py new file mode 100644 index 0000000000..0dcc7d2714 --- /dev/null +++ b/bitbake/lib/toaster/toastergui/templatetags/objects_to_dictionaries_filter.py | |||
@@ -0,0 +1,35 @@ | |||
1 | from django import template | ||
2 | import json | ||
3 | |||
4 | register = template.Library() | ||
5 | |||
6 | def objects_to_dictionaries(iterable, fields): | ||
7 | """ | ||
8 | Convert an iterable into a list of dictionaries; fields should be set | ||
9 | to a comma-separated string of properties for each item included in the | ||
10 | resulting list; e.g. for a queryset: | ||
11 | |||
12 | {{ queryset | objects_to_dictionaries:"id,name" }} | ||
13 | |||
14 | will return a list like | ||
15 | |||
16 | [{'id': 1, 'name': 'foo'}, ...] | ||
17 | |||
18 | providing queryset has id and name fields | ||
19 | |||
20 | This is mostly to support serialising querysets or lists of model objects | ||
21 | to JSON | ||
22 | """ | ||
23 | objects = [] | ||
24 | |||
25 | if fields: | ||
26 | fields_list = [field.strip() for field in fields.split(',')] | ||
27 | for item in iterable: | ||
28 | out = {} | ||
29 | for field in fields_list: | ||
30 | out[field] = getattr(item, field) | ||
31 | objects.append(out) | ||
32 | |||
33 | return objects | ||
34 | |||
35 | register.filter('objects_to_dictionaries', objects_to_dictionaries) | ||
diff --git a/bitbake/lib/toaster/toastergui/templatetags/queryset_to_list_filter.py b/bitbake/lib/toaster/toastergui/templatetags/queryset_to_list_filter.py deleted file mode 100644 index dfc094b591..0000000000 --- a/bitbake/lib/toaster/toastergui/templatetags/queryset_to_list_filter.py +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | from django import template | ||
2 | import json | ||
3 | |||
4 | register = template.Library() | ||
5 | |||
6 | def queryset_to_list(queryset, fields): | ||
7 | """ | ||
8 | Convert a queryset to a list; fields can be set to a comma-separated | ||
9 | string of fields for each record included in the resulting list; if | ||
10 | omitted, all fields are included for each record, e.g. | ||
11 | |||
12 | {{ queryset | queryset_to_list:"id,name" }} | ||
13 | |||
14 | will return a list like | ||
15 | |||
16 | [{'id': 1, 'name': 'foo'}, ...] | ||
17 | |||
18 | (providing queryset has id and name fields) | ||
19 | """ | ||
20 | if fields: | ||
21 | fields_list = [field.strip() for field in fields.split(',')] | ||
22 | return list(queryset.values(*fields_list)) | ||
23 | else: | ||
24 | return list(queryset.values()) | ||
25 | |||
26 | register.filter('queryset_to_list', queryset_to_list) | ||
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index 942dc31ae9..bd5bf63341 100755 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py | |||
@@ -507,6 +507,7 @@ def builddashboard( request, build_id ): | |||
507 | 507 | ||
508 | context = { | 508 | context = { |
509 | 'build' : build, | 509 | 'build' : build, |
510 | 'project' : build.project, | ||
510 | 'hasImages' : hasImages, | 511 | 'hasImages' : hasImages, |
511 | 'ntargets' : ntargets, | 512 | 'ntargets' : ntargets, |
512 | 'targets' : targets, | 513 | 'targets' : targets, |
@@ -797,6 +798,7 @@ eans multiple licenses exist that cover different parts of the source', | |||
797 | context = { | 798 | context = { |
798 | 'objectname': variant, | 799 | 'objectname': variant, |
799 | 'build' : build, | 800 | 'build' : build, |
801 | 'project' : build.project, | ||
800 | 'target' : Target.objects.filter( pk = target_id )[ 0 ], | 802 | 'target' : Target.objects.filter( pk = target_id )[ 0 ], |
801 | 'objects' : packages, | 803 | 'objects' : packages, |
802 | 'packages_sum' : packages_sum[ 'installed_size__sum' ], | 804 | 'packages_sum' : packages_sum[ 'installed_size__sum' ], |
@@ -937,7 +939,10 @@ def dirinfo(request, build_id, target_id, file_path=None): | |||
937 | if head != sep: | 939 | if head != sep: |
938 | dir_list.insert(0, head) | 940 | dir_list.insert(0, head) |
939 | 941 | ||
940 | context = { 'build': Build.objects.get(pk=build_id), | 942 | build = Build.objects.get(pk=build_id) |
943 | |||
944 | context = { 'build': build, | ||
945 | 'project': build.project, | ||
941 | 'target': Target.objects.get(pk=target_id), | 946 | 'target': Target.objects.get(pk=target_id), |
942 | 'packages_sum': packages_sum['installed_size__sum'], | 947 | 'packages_sum': packages_sum['installed_size__sum'], |
943 | 'objects': objects, | 948 | 'objects': objects, |
@@ -1211,6 +1216,7 @@ def tasks_common(request, build_id, variant, task_anchor): | |||
1211 | 'filter_search_display': filter_search_display, | 1216 | 'filter_search_display': filter_search_display, |
1212 | 'mainheading': title_variant, | 1217 | 'mainheading': title_variant, |
1213 | 'build': build, | 1218 | 'build': build, |
1219 | 'project': build.project, | ||
1214 | 'objects': task_objects, | 1220 | 'objects': task_objects, |
1215 | 'default_orderby' : default_orderby, | 1221 | 'default_orderby' : default_orderby, |
1216 | 'search_term': search_term, | 1222 | 'search_term': search_term, |
@@ -1282,6 +1288,7 @@ def recipes(request, build_id): | |||
1282 | context = { | 1288 | context = { |
1283 | 'objectname': 'recipes', | 1289 | 'objectname': 'recipes', |
1284 | 'build': build, | 1290 | 'build': build, |
1291 | 'project': build.project, | ||
1285 | 'objects': recipes, | 1292 | 'objects': recipes, |
1286 | 'default_orderby' : 'name:+', | 1293 | 'default_orderby' : 'name:+', |
1287 | 'recipe_deps' : deps, | 1294 | 'recipe_deps' : deps, |
@@ -1366,10 +1373,12 @@ def configuration(request, build_id): | |||
1366 | 'MACHINE', 'DISTRO', 'DISTRO_VERSION', 'TUNE_FEATURES', 'TARGET_FPU') | 1373 | 'MACHINE', 'DISTRO', 'DISTRO_VERSION', 'TUNE_FEATURES', 'TARGET_FPU') |
1367 | context = dict(Variable.objects.filter(build=build_id, variable_name__in=var_names)\ | 1374 | context = dict(Variable.objects.filter(build=build_id, variable_name__in=var_names)\ |
1368 | .values_list('variable_name', 'variable_value')) | 1375 | .values_list('variable_name', 'variable_value')) |
1376 | build = Build.objects.get(pk=build_id) | ||
1369 | context.update({'objectname': 'configuration', | 1377 | context.update({'objectname': 'configuration', |
1370 | 'object_search_display':'variables', | 1378 | 'object_search_display':'variables', |
1371 | 'filter_search_display':'variables', | 1379 | 'filter_search_display':'variables', |
1372 | 'build': Build.objects.get(pk=build_id), | 1380 | 'build': build, |
1381 | 'project': build.project, | ||
1373 | 'targets': Target.objects.filter(build=build_id)}) | 1382 | 'targets': Target.objects.filter(build=build_id)}) |
1374 | return render(request, template, context) | 1383 | return render(request, template, context) |
1375 | 1384 | ||
@@ -1406,12 +1415,15 @@ def configvars(request, build_id): | |||
1406 | file_filter += '/bitbake.conf' | 1415 | file_filter += '/bitbake.conf' |
1407 | build_dir=re.sub("/tmp/log/.*","",Build.objects.get(pk=build_id).cooker_log_path) | 1416 | build_dir=re.sub("/tmp/log/.*","",Build.objects.get(pk=build_id).cooker_log_path) |
1408 | 1417 | ||
1418 | build = Build.objects.get(pk=build_id) | ||
1419 | |||
1409 | context = { | 1420 | context = { |
1410 | 'objectname': 'configvars', | 1421 | 'objectname': 'configvars', |
1411 | 'object_search_display':'BitBake variables', | 1422 | 'object_search_display':'BitBake variables', |
1412 | 'filter_search_display':'variables', | 1423 | 'filter_search_display':'variables', |
1413 | 'file_filter': file_filter, | 1424 | 'file_filter': file_filter, |
1414 | 'build': Build.objects.get(pk=build_id), | 1425 | 'build': build, |
1426 | 'project': build.project, | ||
1415 | 'objects' : variables, | 1427 | 'objects' : variables, |
1416 | 'total_count':queryset_with_search.count(), | 1428 | 'total_count':queryset_with_search.count(), |
1417 | 'default_orderby' : 'variable_name:+', | 1429 | 'default_orderby' : 'variable_name:+', |
@@ -1480,6 +1492,7 @@ def bpackage(request, build_id): | |||
1480 | context = { | 1492 | context = { |
1481 | 'objectname': 'packages built', | 1493 | 'objectname': 'packages built', |
1482 | 'build': build, | 1494 | 'build': build, |
1495 | 'project': build.project, | ||
1483 | 'objects' : packages, | 1496 | 'objects' : packages, |
1484 | 'default_orderby' : 'name:+', | 1497 | 'default_orderby' : 'name:+', |
1485 | 'tablecols':[ | 1498 | 'tablecols':[ |
@@ -1554,7 +1567,12 @@ def bpackage(request, build_id): | |||
1554 | def bfile(request, build_id, package_id): | 1567 | def bfile(request, build_id, package_id): |
1555 | template = 'bfile.html' | 1568 | template = 'bfile.html' |
1556 | files = Package_File.objects.filter(package = package_id) | 1569 | files = Package_File.objects.filter(package = package_id) |
1557 | context = {'build': Build.objects.get(pk=build_id), 'objects' : files} | 1570 | build = Build.objects.get(pk=build_id) |
1571 | context = { | ||
1572 | 'build': build, | ||
1573 | 'project': build.project, | ||
1574 | 'objects' : files | ||
1575 | } | ||
1558 | return render(request, template, context) | 1576 | return render(request, template, context) |
1559 | 1577 | ||
1560 | 1578 | ||