diff options
author | David Reyna <David.Reyna@windriver.com> | 2015-01-16 16:42:41 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-01-21 14:37:39 +0000 |
commit | 6abcc6118d068266947d6fd5acf78f744ec02cb6 (patch) | |
tree | 0856e7ebcc0f6e1d95a44db9b022ef103d533003 /bitbake/lib | |
parent | d1dbf4c078e04fdc0f3b971f62cdefcba4904232 (diff) | |
download | poky-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')
-rw-r--r-- | bitbake/lib/toaster/toastergui/templates/projectconf.html | 649 | ||||
-rw-r--r-- | bitbake/lib/toaster/toastergui/urls.py | 1 | ||||
-rwxr-xr-x | bitbake/lib/toaster/toastergui/views.py | 106 |
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): |