summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster
diff options
context:
space:
mode:
authorDavid Reyna <David.Reyna@windriver.com>2015-01-16 16:42:41 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-01-21 14:37:39 +0000
commit6abcc6118d068266947d6fd5acf78f744ec02cb6 (patch)
tree0856e7ebcc0f6e1d95a44db9b022ef103d533003 /bitbake/lib/toaster
parentd1dbf4c078e04fdc0f3b971f62cdefcba4904232 (diff)
downloadpoky-6abcc6118d068266947d6fd5acf78f744ec02cb6.tar.gz
bitbake: toaster: project configuration variables page
Implement the project configuration variables page. AlexD made whitespace changes and a minor fix. [YOCTO #6588] (Bitbake rev: 909fa19f20e909820aa484967b7fe2a34d89ab49) Signed-off-by: David Reyna <David.Reyna@windriver.com> Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/toaster')
-rw-r--r--bitbake/lib/toaster/toastergui/templates/projectconf.html649
-rw-r--r--bitbake/lib/toaster/toastergui/urls.py1
-rwxr-xr-xbitbake/lib/toaster/toastergui/views.py106
3 files changed, 730 insertions, 26 deletions
diff --git a/bitbake/lib/toaster/toastergui/templates/projectconf.html b/bitbake/lib/toaster/toastergui/templates/projectconf.html
index e8b0c39f25..edcad1821f 100644
--- a/bitbake/lib/toaster/toastergui/templates/projectconf.html
+++ b/bitbake/lib/toaster/toastergui/templates/projectconf.html
@@ -3,60 +3,659 @@
3{% load humanize %} 3{% load humanize %}
4 4
5{% block localbreadcrumb %} 5{% block localbreadcrumb %}
6<li>Project configuration</li> 6<li>Configuration variables</li>
7{% endblock %} 7{% endblock %}
8 8
9{% block projectinfomain %} 9{% block projectinfomain %}
10 <div class="page-header"> 10 <div class="page-header">
11 <h1>Configuration Variables</h1> 11 <h1>Configuration variables</h1>
12 </div> 12 </div>
13 13
14 <div style="padding-left:19px;"> 14 <div style="padding-left:19px;">
15 15
16 <dl class="dl-vertical"> 16 <dl class="dl-vertical">
17 {% for c in configvars %}
18 <dt> 17 <dt>
19 {{c.name}} 18 <span class="js-config-var-name js-config-var-managed-name">DISTRO</span>
20 <i class="icon-question-sign get-help" title="{{c.desc}}"></i> 19 <i class="icon-question-sign get-help" title="The short name of the distribution. If the variable is blank, meta/conf/distro/defaultsetup.conf will be used. <br /><a href='http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-DISTRO' target='_blank'>Read more in the manual</a>"></i>
21 </dt> 20 </dt>
22 <dd class="lead"> 21 <dd class="lead">
23 <span id="distro">{{c.value}}</span> 22 <span id="distro">{{distro}}</span>
24 <i class="icon-pencil" id="change-distro-icon"></i> 23 <i class="icon-pencil" id="change-distro-icon"></i>
25 <form id="change-distro-form" style="display:none;"> 24 <form id="change-distro-form" style="display:none;">
26 <div class="input-append"> 25 <div class="input-append">
27 <input type="text" id="new-distro" value="poky tiny"> 26 <input type="text" id="new-distro" value="{{distro}}">
28 <button id="apply-change-distro" class="btn" type="button">Save</button> 27 <button id="apply-change-distro" class="btn" type="button">Save</button>
29 <button id="cancel-change-distro" type="button" class="btn btn-link">Cancel</button> 28 <button id="cancel-change-distro" type="button" class="btn btn-link">Cancel</button>
30 </div> 29 </div>
31 </form> 30 </form>
32 </dd> 31 </dd>
33 {% endfor %} 32 <dt>
33 <span class="js-config-var-name js-config-var-managed-name">IMAGE_FSTYPES</span>
34 <i class="icon-question-sign get-help" title="Formats of root file system images that you want to have created <br /><a href='http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-IMAGE_FSTYPES' target='_blank'>Read more in the manual</a>"></i>
35 </dt>
36 <dd class="lead">
37 <span id="image_fstypes">{{fstypes}}</span>
38 <i class="icon-pencil" id="change-image_fstypes-icon"></i>
39 <form id="change-image_fstypes-form" style="display:none;">
40 <input id="filter-image_fstypes" type="text" placeholder="Search image types" class="span4">
41 <div id="all-image_fstypes" class="scrolling">
42 </div>
43 <button id="apply-change-image_fstypes" type="button" class="btn">Save</button>
44 <button id="cancel-change-image_fstypes" type="button" class="btn btn-link">Cancel</button>
45 </form>
46 </dd>
47 <dt>
48 <span class="js-config-var-name js-config-var-managed-name">IMAGE_INSTALL_append</span>
49 <i class="icon-question-sign get-help" title="Specifies additional packages to install into an image. If your build creates more than one image, the packages will be installed in <strong>all of them</strong> <br /><a href='http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-IMAGE_INSTALL' target='_blank'>Read more in the manual</a>"></i>
50 </dt>
51 <dd class="lead muted">
52 <span id="image_install">{% if image_install_append %}{{image_install_append}}{%else%}Not set{%endif%}</span>
53 <i class="icon-pencil" id="change-image_install-icon"></i>
54 <i class="icon-trash" id="delete-image_install-icon" style="display:none;"></i>
55 <form id="change-image_install-form" style="display:none;">
56 <div class="row-fluid">
57 <span class="help-block span4">To set IMAGE_INSTALL_append to more than one package, type the package names separated by a space.</span>
58 </div>
59 <div class="input-append">
60 <input type="text" class="input-xlarge" id="new-image_install" placeholder="Type one or more package names">
61 <button id="apply-change-image_install" class="btn" type="button">Save</button>
62 <button id="cancel-change-image_install" type="button" class="btn btn-link">Cancel</button>
63 </div>
64 </form>
65 </dd>
66 <dt>
67 <span class="js-config-var-name js-config-var-managed-name">PACKAGE_CLASSES</span>
68 <i class="icon-question-sign get-help" title="Specifies the package manager to use when packaging data <br /><a href='http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-PACKAGE_CLASSES' target='_blank'>Read more in the manual</a>"></i>
69 </dt>
70 <dd class="lead">
71 <span id="package_classes">{{package_classes}}</span>
72 <i id="change-package_classes-icon" class="icon-pencil"></i>
73 <form id="change-package_classes-form" style="display:none;">
74 <label>
75 Root file system package format
76 <i class="icon-question-sign get-help" title="The package format used to generate the root file system. Options are <code>dev</code>, <code>ipk</code> and <code>rpm</code>"></i>
77 </label>
78 <select id="package_classes-select">
79 <option>package_dev</option>
80 <option>package_ipk</option>
81 <option>package_rpm</option>
82 </select>
83 <label>
84 Additional package formats
85 <i class="icon-question-sign get-help" title="Extra package formats to build"></i>
86 </label>
87 <label class="checkbox" id="package_class_1">
88 <input type="checkbox" id="package_class_1_input"> package_dev
89 </label>
90 <label class="checkbox" id="package_class_2">
91 <input type="checkbox" id="package_class_2_input"> package_ipk
92 </label>
93 <div style="padding-top:10px;">
94 <button id="apply-change-package_classes" type="button" class="btn">Save</button>
95 <button id="cancel-change-package_classes" type="button" class="btn btn-link">Cancel</button>
96 </div>
97 </form>
98 </dd>
99 <dt>
100 <span class="js-config-var-name js-config-var-managed-name">SDKMACHINE</span>
101 <i class="icon-question-sign get-help" title="Specifies the architecture (i.e. i686 or x86_64) for which to build SDK and ADT items <br /><a href='http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-SDKMACHINE' target='_blank'>Read more in the manual</a>"></i>
102 </dt>
103 <dd class="lead">
104 <span id="sdkmachine">{{sdk_machine}}</span>
105 <i id="change-sdkmachine-icon" class="icon-pencil"></i>
106 <form id="change-sdkmachine-form" style="display:none;">
107 <label class="radio">
108 <input type="radio" name="sdkmachine" value="i686">
109 i686
110 </label>
111 <label class="radio">
112 <input type="radio" name="sdkmachine" value="x86_64">
113 x86_64
114 </label>
115 <div style="padding-top:10px;">
116 <button id="apply-change-sdkmachine" type="button" class="btn">Save</button>
117 <button id="cancel-change-sdkmachine" type="button" class="btn btn-link">Cancel</button>
118 </div>
119 </form>
120 </dd>
34 121
122 </dl>
35 123
124 <!-- <ul class="unstyled configuration-list" id="configvar-list"> -->
125 <dl id="configvar-list">
126 <!-- the added configuration variables are inserted here -->
36 </dl> 127 </dl>
37 <form id="variable-form"> 128
129 <!-- pass the fstypes list, black list, and externally managed variables here -->
130 {% for fstype in vars_fstypes %}
131 <input type="hidden" class="js-checkbox-fstypes-list" value="{{fstype}}">
132 {% endfor %}
133 {% for b in vars_blacklist %}
134 <input type="hidden" class="js-config-blacklist-name" value="{{b}}">
135 {% endfor %}
136 {% for b in vars_managed %}
137 <input type="hidden" class="js-config-var-managed-name" value="{{b}}">
138 {% endfor %}
139
140 <div class="row-fluid">
141 <form id="variable-form">
38 <fieldset style="padding-left:0px;"> 142 <fieldset style="padding-left:0px;">
39 <legend>Add variable</legend> 143 <legend>Add variable</legend>
40 <label> 144 <div class="span3" style="margin-left:0px;">
41 Variable 145 <span id="add-configvar-name-div" class="control-group">
42 <i class="icon-question-sign get-help" title="Variable names are case sensitive, cannot have spaces, and can only include letters, numbers, underscores and dashes"></i> 146 <label>
43 </label> 147 Variable
44 <input id="variable" type="text" placeholder="Type variable name"> 148 <i title="" class="icon-question-sign get-help"
45 <label>Value</label> 149 data-original-title="Variable names are case sensitive,
46 <input id="value" type="text" placeholder="Type variable value"> 150 cannot have spaces, and can only include letters, numbers, underscores
47 <div style="display:block;margin-top:10px;"> 151 and dashes"></i>
48 <a href="#" class="btn save" disabled> 152 </label>
49 Add variable 153 <input type="text" placeholder="Type variable name" id="variable">
50 </a> 154 <span class="help-block error" id="new-variable-error-message"></span>
155 </span>
156 <label>Value</label>
157 <input id="value" type="text" placeholder="Type variable value"><p>
158 <div class="input-append" style="display:block;margin-top:10px;">
159 <button id="add-configvar-button" class="btn save" type="button" disabled>Add variable</button>
160 </div>
161 </div>
162 <div class="span5 help-block">
163 <h5>Some variables are reserved from Toaster</h5>
164 <p>Toaster cannot set any variables that impact 1) the configuration of the build servers,
165 or 2) where artifacts produced by the build are stored. Such variables include: </p>
166 <p>
167 <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-BB_DISKMON_DIRS" target="_blank">BB_DISKMON_DIRS</a></code>
168 <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-BB_NUMBER_THREADS" target="_blank">BB_NUMBER_THREADS</a></code>
169 <code>CVS_PROXY_HOST</code>
170 <code>CVS_PROXY_PORT</code>
171 <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-DL_DIR" target="_blank">DL_DIR</a></code>
172 <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-PARALLEL_MAKE" target="_blank">PARALLEL_MAKE</a></code>
173 <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-SSTATE_DIR" target="_blank">SSTATE_DIR</a></code>
174 <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-SSTATE_MIRRORS" target="_blank">SSTATE_MIRRORS</a></code>
175 <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-TMPDIR" target="_blank">TMPDIR</a></code></p>
176 <p>Plus the following standard shell environment variables:</p>
177 <p><code>http_proxy</code> <code>ftp_proxy</code> <code>https_proxy</code> <code>all_proxy</code></p>
51 </div> 178 </div>
52 </fieldset> 179 </fieldset>
53 </form> 180 </form>
54 <!--button id="add-variable" class="btn air"> 181 </div>
55 <i class="icon-plus"></i>
56 Add variable
57 </button-->
58 182
59 </div> 183 </div>
60 184
185 <script>
186
187 // validate new variable name
188 function validate_new_variable_name() {
189 var variable = $("input#variable")[0].value;
190 var value = $("input#value")[0].value;
191
192 // presumed innocence
193 $('#new-variable-error-message').html("");
194 var error_msg = ""
195
196 var existing_configvars = document.getElementsByClassName('js-config-var-name');
197 for (var i = 0, length = existing_configvars.length; i < length; i++) {
198 if (existing_configvars[i].innerHTML == variable) {
199 error_msg = "This variable is already set in this page, edit its value instead";
200 }
201 }
202
203 var blacklist_configvars = document.getElementsByClassName('js-config-blacklist-name');
204 for (var i = 0, length = blacklist_configvars.length; i < length; i++) {
205 if (blacklist_configvars[i].value == variable) {
206 error_msg = "You cannot edit this variable in Toaster because it is set by the build servers";
207 }
208 }
209
210 var bad_chars = /[^a-zA-Z0-9\-_]/.test(variable);
211 var has_spaces = (0 <= variable.indexOf(" "));
212 var only_spaces = (0 < variable.length) && (0 == variable.trim().length);
213
214 if (only_spaces) {
215 error_msg = "A valid variable name cannot include spaces";
216 } else if (bad_chars && has_spaces) {
217 error_msg = "A valid variable name can only include letters, numbers, underscores, dashes, and cannot include spaces";
218 } else if (bad_chars) {
219 error_msg = "A valid variable name can only include letters, numbers, underscores, and dashes";
220 }
221
222 if ("" != error_msg) {
223 $('#new-variable-error-message').html(error_msg);
224 $(".save").attr("disabled","disabled");
225
226 var d = document.getElementById("add-configvar-name-div");
227 d.className = d.className + " control-group error";
228
229 return false;
230 }
231
232 var d = document.getElementById("add-configvar-name-div");
233 d.className = d.className.replace(" control-group error","");
234 return true;
235 }
236
237 // Preset or reset the Package Class checkbox labels
238 function updatePackageClassCheckboxes() {
239 if ($('select').val() == 'package_dev') {
240 $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_ipk');
241 $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_rpm');
242 }
243 if ($('select').val() == 'package_ipk') {
244 $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_dev');
245 $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_rpm');
246 }
247 if ($('select').val() == 'package_rpm') {
248 $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_dev');
249 $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_ipk');
250 }
251 }
252
253 // Re-assert handlers when the page is served and/or refreshed via Ajax
254 function setEventHandlersForDynamicElements() {
255
256 // change variable value
257 $('.js-icon-pencil-config_var').click(function (evt) {
258 var pk = evt.target.attributes["x-data"].value;
259 var current_val = $("span#config_var_"+pk).html();
260 $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_'+pk).hide();
261 $("#change-config_var-form_"+pk).slideDown();
262 $("input#new-config_var_"+pk)[0].value = current_val;
263 });
264
265 $('.js-cancel-change-config_var').click(function (evt) {
266 var pk = evt.target.attributes["x-data"].value;
267 $("#change-config_var-form_"+pk).slideUp(function() {
268 $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_'+pk).show();
269 });
270 });
271
272 $(".js-new-config_var").keyup(function(){
273 if ($(this).val().length == 0) {
274 $(".js-apply-change-config_var").attr("disabled","disabled");
275 }
276 else {
277 $(".js-apply-change-config_var").removeAttr("disabled");
278 }
279 });
280
281 $('.js-apply-change-config_var').click(function (evt) {
282 var xdata = evt.target.attributes["x-data"].value.split(":");
283 var pk = xdata[0];
284 var variable = xdata[1];
285 var val = $('#new-config_var_'+pk).val();
286 postEditAjaxRequest({"configvarChange" : variable+':'+val});
287 $('#config_var_'+pk).parent().removeClass('muted');
288 $("#change-config_var-form_"+pk).slideUp(function() {
289 $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_'+pk).show();
290 });
291 });
292
293 // delete variable
294 $(".js-icon-trash-config_var").click(function (evt) {
295 var xdata = evt.target.attributes["x-data"].value.split(":");
296 var pk = xdata[0];
297 $('#config_var_entry_'+pk).slideUp(function() {
298 //$('#config_var_entry_'+pk).show();
299 });
300 postEditAjaxRequest({"configvarDel": evt.target.attributes["x-data"].value});
301 });
302
303 }
304
305 function onEditPageUpdate(data) {
306 // update targets
307 var i; var orightml = "";
308
309 var configvars_sorted = data.configvars.sort(function(a, b){return a[0] > b[0]});
310
311 var managed_configvars = document.getElementsByClassName('js-config-var-managed-name');
312
313 for (i = 0; i < configvars_sorted.length; i++) {
314 // skip if the variable name has a special context (not user defined)
315 var var_context=undefined;
316 for (var j = 0, length = managed_configvars.length; j < length; j++) {
317 if ((managed_configvars[j].innerHTML == configvars_sorted[i][0]) ||
318 (managed_configvars[j].value == configvars_sorted[i][0]) ) {
319 var_context='m';
320 }
321 }
322 if (var_context == undefined) {
323 orightml += '<dt id="config_var_entry_'+configvars_sorted[i][2]+'"><span class="js-config-var-name">'+configvars_sorted[i][0]+'</span><i class="icon-trash js-icon-trash-config_var" x-data="'+configvars_sorted[i][2]+'"></i> </dt>'
324 orightml += '<dd class="lead">'
325 orightml += ' <span id="config_var_'+configvars_sorted[i][2]+'">'+configvars_sorted[i][1]+'</span>'
326 orightml += ' <i class="icon-pencil js-icon-pencil-config_var" x-data="'+configvars_sorted[i][2]+'"></i>'
327 orightml += ' <form id="change-config_var-form_'+configvars_sorted[i][2]+'" style="display:none;">'
328 orightml += ' <div class="input-append">'
329 orightml += ' <input type="text" class="input-xlarge js-new-config_var" id="new-config_var_'+configvars_sorted[i][2]+'" value="">'
330 orightml += ' <button class="btn js-apply-change-config_var" type="button" x-data="'+configvars_sorted[i][2]+':'+configvars_sorted[i][0]+'" disabled>Save</button>'
331 orightml += ' <button type="button" class="btn btn-link js-cancel-change-config_var" x-data="'+configvars_sorted[i][2]+'">Cancel</button>'
332 orightml += ' </div>'
333 orightml += ' </form>'
334 orightml += '</dd>'
335 }
336 }
337
338 // update configvars list
339 $("dl#configvar-list").html(orightml);
340
341 // re-assert these event handlers
342 setEventHandlersForDynamicElements();
343 }
344
345 function onEditAjaxSuccess(data, textstatus) {
346 // console.log("XHR returned:", data, "(" + textstatus + ")");
347 if (data.error != "ok") {
348 alert("error on request:\n" + data.error);
349 return;
350 }
351 onEditPageUpdate(data);
352 }
353
354 function onEditAjaxError(jqXHR, textstatus, error) {
355 alert("XHR errored:\n" + error + "\n(" + textstatus + ")");
356 // re-assert the event handlers
357 }
358
359 function postEditAjaxRequest(reqdata) {
360 var ajax = $.ajax({
361 type:"POST",
362 data: $.param(reqdata),
363 url:"{% url 'xhr_configvaredit' project.id%}",
364 headers: { 'X-CSRFToken': $.cookie("csrftoken")},
365 success: onEditAjaxSuccess,
366 error: onEditAjaxError,
367 })
368 }
369
370
371 $(document).ready(function() {
372
373 //
374 // Register handlers for static elements
375 //
376
377 // change distro variable
378 $('#change-distro-icon').click(function() {
379 $('#change-distro-icon, #distro').hide();
380 $("#change-distro-form").slideDown();
381 });
382
383 $('#cancel-change-distro').click(function(){
384 $("#change-distro-form").slideUp(function() {
385 $('#distro, #change-distro-icon').show();
386 });
387 });
388
389 $("#new-distro").keyup(function(){
390 if ($(this).val().length == 0) {
391 $("#apply-change-distro").attr("disabled","disabled");
392 }
393 else {
394 $("#apply-change-distro").removeAttr("disabled");
395 }
396 });
397
398 $('#apply-change-distro').click(function(){
399 //$('#repo').parent().removeClass('highlight-go');
400 var name = $('#new-distro').val();
401 postEditAjaxRequest({"configvarChange" : 'DISTRO:'+name});
402 $('#distro').html(name);
403 $("#change-distro-form").slideUp(function () {
404 $('#distro, #change-distro-icon').show();
405 });
406 });
407
408
409 // change IMAGE_FSTYPES variable
410 $('#change-image_fstypes-icon').click(function() {
411 $('#change-image_fstypes-icon, #image_fstypes').hide();
412 $("#change-image_fstypes-form").slideDown();
413 // avoid false substring matches by including space separators
414 var html = "";
415 var fstypes = " " + document.getElementById("image_fstypes").innerHTML + " ";
416 var fstypes_list = document.getElementsByClassName('js-checkbox-fstypes-list');
417 // Add the checked boxes first
418 if (" " != fstypes) {
419 for (var i = 0, length = fstypes_list.length; i < length; i++) {
420 if (0 <= fstypes.indexOf(" "+fstypes_list[i].value+" ")) {
421 html += '<label class="checkbox"><input type="checkbox" class="fs-checkbox-fstypes" value="'+fstypes_list[i].value+'" checked="checked">'+fstypes_list[i].value+'</label>\n';
422 }
423 }
424 }
425 // Add the un-checked boxes second
426 for (var i = 0, length = fstypes_list.length; i < length; i++) {
427 if (0 > fstypes.indexOf(" "+fstypes_list[i].value+" ")) {
428 html += '<label class="checkbox"><input type="checkbox" class="fs-checkbox-fstypes" value="'+fstypes_list[i].value+'">'+fstypes_list[i].value+'</label>\n';
429 }
430 }
431 document.getElementById("all-image_fstypes").innerHTML = html;
432 });
433
434 $('#cancel-change-image_fstypes').click(function(){
435 $("#change-image_fstypes-form").slideUp(function() {
436 $('#image_fstypes, #change-image_fstypes-icon').show();
437 });
438 });
439
440 $('#apply-change-image_fstypes').click(function(){
441 var fstypes = '';
442 var checkboxes = document.getElementsByClassName('fs-checkbox-fstypes');
443 for (var i = 0, length = checkboxes.length; i < length; i++) {
444 if (checkboxes[i].checked) {
445 fstypes += checkboxes[i].value + ' ';
446 }
447 }
448 fstypes = fstypes.trim();
449
450 postEditAjaxRequest({"configvarChange" : 'IMAGE_FSTYPES:'+fstypes});
451 $('#image_fstypes').html(fstypes);
452 $('#image_fstypes').parent().removeClass('muted');
453
454 $("#change-image_fstypes-form").slideUp(function() {
455 $('#image_fstypes, #change-image_fstypes-icon').show();
456 });
457 });
458
459
460 // change IMAGE_INSTALL_append variable
461 $('#change-image_install-icon').click(function() {
462 $('#change-image_install-icon, #delete-image_install-icon, #image_install').hide();
463 $("#change-image_install-form").slideDown();
464 });
465
466 $('#cancel-change-image_install').click(function(){
467 $("#change-image_install-form").slideUp(function() {
468 $('#image_install, #change-image_install-icon').show();
469 });
470 });
471
472 $("#new-image_install").keyup(function(){
473 if ($(this).val().length == 0) {
474 $("#apply-change-image_install").attr("disabled","disabled");
475 }
476 else {
477 $("#apply-change-image_install").removeAttr("disabled");
478 }
479 });
480
481 $('#apply-change-image_install').click(function(){
482 var name = $('#new-image_install').val();
483 postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL_append:'+name});
484 $('#image_install').html(name);
485 $('#image_install').parent().removeClass('muted');
486 $("#change-image_install-form").slideUp(function () {
487 $('#image_install, #change-image_install-icon').show();
488 if (name.length > -1) {
489 $('#delete-image_install-icon').show();
490 }
491 });
492 });
493
494 // delete IMAGE_INSTALL_append variable value
495 $('#delete-image_install-icon').click(function(){
496 $(this).tooltip('hide');
497 postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL_append:'+''});
498 $('#image_install').parent().fadeOut(1000, function(){
499 $('#image_install').parent().addClass('muted');
500 $('#image_install').html('Not set');
501 $('#delete-image_install-icon').hide();
502 $('#image_install').parent().fadeIn(1000);
503 });
504 });
505
506
507 // change PACKAGE_CLASSES variable
508 $('#change-package_classes-icon').click(function() {
509 $('#change-package_classes-icon, #package_classes').hide();
510 $("#change-package_classes-form").slideDown();
511
512 // initialize the pulldown and checkboxes
513 var value = document.getElementById("package_classes").innerHTML;
514 if (0 == value.indexOf("package_dev")) {
515 $('select').selectedIndex = 0;
516 updatePackageClassCheckboxes();
517 if (0 < value.indexOf("package_ipk")) {document.getElementById("package_class_1_input").checked = true};
518 if (0 < value.indexOf("package_rpm")) {document.getElementById("package_class_2_input").checked = true};
519 }
520 if (0 == value.indexOf("package_ipk")) {
521 $('select').selectedIndex = 1;
522 updatePackageClassCheckboxes();
523 if (0 < value.indexOf("package_dev")) {document.getElementById("package_class_1_input").checked = true;};
524 if (0 < value.indexOf("package_rpm")) {document.getElementById("package_class_2_input").checked = true;};
525 }
526 if (0 == value.indexOf("package_rpm")) {
527 $('select').selectedIndex = 2;
528 updatePackageClassCheckboxes();
529 if (0 < value.indexOf("package_dev")) {document.getElementById("#package_class_1_input").checked = true;};
530 if (0 < value.indexOf("package_ipk")) {document.getElementById("#package_class_2_input").checked = true;};
531 }
532 });
533
534 $('#cancel-change-package_classes').click(function(){
535 $("#change-package_classes-form").slideUp(function() {
536 $('#package_classes, #change-package_classes-icon').show();
537 });
538 });
539
540 $('select').change(function() {
541 updatePackageClassCheckboxes();
542 });
543
544 $('#apply-change-package_classes').click(function(){
545 var e = document.getElementById("package_classes-select");
546 var val = e.options[e.selectedIndex].text;
547
548 pc1_checked = document.getElementById("package_class_1_input").checked;
549 pc2_checked = document.getElementById("package_class_2_input").checked;
550 if (val == "package_dev") {
551 if (pc1_checked) val = val + " package_ipk";
552 if (pc2_checked) val = val + " package_rpm";
553 }
554 if (val == "package_ipk") {
555 if (pc1_checked) val = val + " package_dev";
556 if (pc2_checked) val = val + " package_rpm";
557 }
558 if (val == "package_rpm") {
559 if (pc1_checked) val = val + " package_dev";
560 if (pc2_checked) val = val + " package_ipk";
561 }
562
563 $('#package_classes').html(val);
564 //$('#package_classes').parent().removeClass('muted');
565 postEditAjaxRequest({"configvarChange" : 'PACKAGE_CLASSES:'+val});
566 $("#change-package_classes-form").slideUp(function() {
567 $('#package_classes, #change-package_classes-icon').show();
568 });
569 });
570
571
572 // change SDKMACHINE variable
573 $('#change-sdkmachine-icon').click(function() {
574 var current_value = document.getElementById("sdkmachine").innerHTML;
575 var radios = document.getElementsByName('sdkmachine');
576 for (var i = 0, length = radios.length; i < length; i++) {
577 radios[i].checked = false;
578 if (radios[i].value == current_value) {
579 radios[i].checked = true;
580 }
581 }
582 $('#change-sdkmachine-icon, #sdkmachine').hide();
583 $("#change-sdkmachine-form").slideDown();
584 });
585
586 $('#cancel-change-sdkmachine').click(function(){
587 $("#change-sdkmachine-form").slideUp(function() {
588 $('#sdkmachine, #change-sdkmachine-icon').show();
589 });
590 });
591
592 $('#apply-change-sdkmachine').click(function(){
593 var value="";
594 var radios = document.getElementsByName('sdkmachine');
595 for (var i = 0, length = radios.length; i < length; i++) {
596 if (radios[i].checked) {
597 // do whatever you want with the checked radio
598 value=radios[i].value;
599 break;
600 }
601 }
602 postEditAjaxRequest({"configvarChange" : 'SDKMACHINE:'+value});
603 $('#sdkmachine').html(value);
604 $("#change-sdkmachine-form").slideUp(function() {
605 $('#sdkmachine, #change-sdkmachine-icon').show();
606 });
607
608 });
609
610
611 // add new variable
612 $("button#add-configvar-button").click( function (evt) {
613 var variable = $("input#variable")[0].value;
614 var value = $("input#value")[0].value;
615
616 if (validate_new_variable_name()) {
617 postEditAjaxRequest({"configvarAdd" : variable+':'+value});
618
619 // clear the previous values
620 $("input#variable")[0].value = "";
621 $("input#value")[0].value = "";
622
623 }
624 });
625
626 // validate new variable name
627 $("input#variable").focusout( function (evt) {
628 validate_new_variable_name();
629 });
630
631 //activate / deactivate save added variable button
632 $("#variable, #value").keyup(function() {
633 if ( $("#variable").val().length > 0 && $("#value").val().trim().length > 0 ) {
634 $(".save").removeAttr("disabled");
635 }
636 else {
637 $(".save").attr("disabled","disabled");
638 }
639 });
640
641 //
642 // draw and register the dynamic configuration variables and handlers
643 //
644
645 var data = {
646 configvars : []
647 };
648 {% for c in configvars %}
649 data.configvars.push([ "{{c.name}}","{{c.value}}","{{c.pk}}" ]);
650 {% if '' != vars_context|get_dict_value:c.name %}
651 data.vars_context[ "{{c.name}}" ] = "{{vars_context|get_dict_value:c.name }}";
652 {% endif %}
653 {% endfor %}
654
655 // draw these elements and assert their event handlers
656 onEditPageUpdate(data);
657 });
658
659 </script>
61 660
62{% endblock %} 661{% endblock %}
diff --git a/bitbake/lib/toaster/toastergui/urls.py b/bitbake/lib/toaster/toastergui/urls.py
index 5c969f814c..c74c7a651b 100644
--- a/bitbake/lib/toaster/toastergui/urls.py
+++ b/bitbake/lib/toaster/toastergui/urls.py
@@ -91,6 +91,7 @@ urlpatterns = patterns('toastergui.views',
91 url(r'^xhr_projectbuild/(?P<pid>\d+)/$', 'xhr_projectbuild', name='xhr_projectbuild'), 91 url(r'^xhr_projectbuild/(?P<pid>\d+)/$', 'xhr_projectbuild', name='xhr_projectbuild'),
92 url(r'^xhr_projectinfo/$', 'xhr_projectinfo', name='xhr_projectinfo'), 92 url(r'^xhr_projectinfo/$', 'xhr_projectinfo', name='xhr_projectinfo'),
93 url(r'^xhr_projectedit/(?P<pid>\d+)/$', 'xhr_projectedit', name='xhr_projectedit'), 93 url(r'^xhr_projectedit/(?P<pid>\d+)/$', 'xhr_projectedit', name='xhr_projectedit'),
94 url(r'^xhr_configvaredit/(?P<pid>\d+)/$', 'xhr_configvaredit', name='xhr_configvaredit'),
94 95
95 url(r'^xhr_datatypeahead/$', 'xhr_datatypeahead', name='xhr_datatypeahead'), 96 url(r'^xhr_datatypeahead/$', 'xhr_datatypeahead', name='xhr_datatypeahead'),
96 url(r'^xhr_importlayer/$', 'xhr_importlayer', name='xhr_importlayer'), 97 url(r'^xhr_importlayer/$', 'xhr_importlayer', name='xhr_importlayer'),
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index 4fae70b48b..5fcad63e45 100755
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -2270,6 +2270,55 @@ if toastermain.settings.MANAGED:
2270 return HttpResponse(jsonfilter({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json") 2270 return HttpResponse(jsonfilter({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json")
2271 2271
2272 2272
2273 def xhr_configvaredit(request, pid):
2274 try:
2275 prj = Project.objects.get(id = pid)
2276 # add conf variables
2277 if 'configvarAdd' in request.POST:
2278 t=request.POST['configvarAdd'].strip()
2279 if ":" in t:
2280 variable, value = t.split(":")
2281 else:
2282 variable = t
2283 value = ""
2284
2285 pt, created = ProjectVariable.objects.get_or_create(project = prj, name = variable, value = value)
2286 # change conf variables
2287 if 'configvarChange' in request.POST:
2288 t=request.POST['configvarChange'].strip()
2289 if ":" in t:
2290 variable, value = t.split(":")
2291 else:
2292 variable = t
2293 value = ""
2294
2295 try:
2296 pt = ProjectVariable.objects.get(project = prj, name = variable)
2297 pt.value=value
2298 pt.save()
2299 except ObjectDoesNotExist:
2300 print("the entry doesn't exist.")
2301 # remove conf variables
2302 if 'configvarDel' in request.POST:
2303 t=request.POST['configvarDel'].strip()
2304 pt = ProjectVariable.objects.get(pk = int(t)).delete()
2305
2306 # return all project settings
2307 vars_managed,vars_fstypes,vars_blacklist = get_project_configvars_context()
2308 return HttpResponse(json.dumps( {
2309 "error": "ok",
2310 'configvars' : map(lambda x: (x.name, x.value, x.pk), ProjectVariable.objects.filter(project_id = pid).all()),
2311 'distro' : ProjectVariable.objects.get(project = prj, name = "DISTRO").value,
2312 'fstypes' : ProjectVariable.objects.get(project = prj, name = "IMAGE_FSTYPES").value,
2313 'image_install_append': ProjectVariable.objects.get(project = prj, name = "IMAGE_INSTALL_append").value,
2314 'package_classes': ProjectVariable.objects.get(project = prj, name = "PACKAGE_CLASSES").value,
2315 'sdk_machine' : ProjectVariable.objects.get(project = prj, name = "SDKMACHINE").value,
2316 }), content_type = "application/json")
2317
2318 except Exception as e:
2319 return HttpResponse(json.dumps({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json")
2320
2321
2273 def xhr_importlayer(request): 2322 def xhr_importlayer(request):
2274 if (not request.POST.has_key('vcs_url') or 2323 if (not request.POST.has_key('vcs_url') or
2275 not request.POST.has_key('name') or 2324 not request.POST.has_key('name') or
@@ -2737,11 +2786,66 @@ if toastermain.settings.MANAGED:
2737 2786
2738 return render(request, template, context) 2787 return render(request, template, context)
2739 2788
2789
2790 def get_project_configvars_context():
2791 # Vars managed outside of this view
2792 vars_managed = {
2793 'MACHINE'
2794 }
2795
2796 vars_blacklist = {
2797 'DL_DR','PARALLEL_MAKE','BB_NUMBER_THREADS','SSTATE_DIR',
2798 'BB_DISKMON_DIRS','BB_NUMBER_THREADS','CVS_PROXY_HOST','CVS_PROXY_PORT',
2799 'DL_DIR','PARALLEL_MAKE','SSTATE_DIR','SSTATE_DIR','SSTATE_MIRRORS','TMPDIR',
2800 'all_proxy','ftp_proxy','http_proxy ','https_proxy'
2801 }
2802
2803 vars_fstypes = {
2804 'btrfs','cpio','cpio.gz','cpio.lz4','cpio.lzma','cpio.xz','cramfs',
2805 'elf','ext2','ext2.bz2','ext2.gz','ext2.lzma' 'ext3','ext3.gz','hddimg',
2806 'iso','jffs2','jffs2.sum','squashfs','squashfs-lzo','squashfs-xz','tar.bz2',
2807 'tar.lz4','tar.xz','tartar.gz','ubi','ubifs','vmdk'
2808 }
2809
2810 return(vars_managed,sorted(vars_fstypes),vars_blacklist)
2811
2740 def projectconf(request, pid): 2812 def projectconf(request, pid):
2741 template = "projectconf.html" 2813 template = "projectconf.html"
2814
2815 try:
2816 prj = Project.objects.get(id = pid)
2817 except Project.DoesNotExist:
2818 return HttpResponseNotFound("<h1>Project id " + pid + " is unavailable</h1>")
2819
2820 vars_managed,vars_fstypes,vars_blacklist = get_project_configvars_context()
2742 context = { 2821 context = {
2743 'configvars': ProjectVariable.objects.filter(project_id = pid), 2822 'configvars': ProjectVariable.objects.filter(project_id = pid).all(),
2823 'vars_managed': vars_managed,
2824 'vars_fstypes': vars_fstypes,
2825 'vars_blacklist': vars_blacklist,
2744 } 2826 }
2827
2828 try:
2829 context['distro'] = ProjectVariable.objects.get(project = prj, name = "DISTRO").value
2830 except ProjectVariable.DoesNotExist:
2831 pass
2832 try:
2833 context['fstypes'] = ProjectVariable.objects.get(project = prj, name = "IMAGE_FSTYPES").value
2834 except ProjectVariable.DoesNotExist:
2835 pass
2836 try:
2837 context['image_install_append'] = ProjectVariable.objects.get(project = prj, name = "IMAGE_INSTALL_append").value
2838 except ProjectVariable.DoesNotExist:
2839 pass
2840 try:
2841 context['package_classes'] = ProjectVariable.objects.get(project = prj, name = "PACKAGE_CLASSES").value
2842 except ProjectVariable.DoesNotExist:
2843 pass
2844 try:
2845 context['sdk_machine'] = ProjectVariable.objects.get(project = prj, name = "SDKMACHINE").value
2846 except ProjectVariable.DoesNotExist:
2847 pass
2848
2745 return render(request, template, context) 2849 return render(request, template, context)
2746 2850
2747 def projectbuilds(request, pid): 2851 def projectbuilds(request, pid):