blob: 27a898b657856f5218d91d5d884ac0f0d50a8f60 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001{% extends "baseprojectpage.html" %}
2{% load projecttags %}
3{% load humanize %}
4
Patrick Williamsf1e5d692016-03-30 15:21:19 -05005{% block title %} BitBake variables - {{project.name}} - Toaster {% endblock %}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05006{% block projectinfomain %}
7
8<h2>Bitbake variables</h2>
9
10 <div style="padding-left:19px;">
11
12 <dl class="dl-vertical">
13 {% if distro_defined %}
14 <dt>
15 <span class="js-config-var-name js-config-var-managed-name">DISTRO</span>
16 <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>
17 </dt>
18 <dd class="lead">
19 <span id="distro">{{distro}}</span>
20 <i class="icon-pencil" id="change-distro-icon"></i>
21 <form id="change-distro-form" style="display:none;">
22 <div class="input-append">
23 <span id="edit-distro-name-div" class="control-group">
24 <input type="text" id="new-distro" value="{{distro}}">
25 <button id="apply-change-distro" class="btn" type="button">Save</button>
26 <button id="cancel-change-distro" type="button" class="btn btn-link">Cancel</button>
27 </span>
28 <span class="help-block error" id="distro-error-message"></span>
29 </div>
30 </form>
31 </dd>
32 {% endif %}
33
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050034 {% if dl_dir_defined %}
35 <dt>
36 <span class="js-config-var-name js-config-var-managed-name">DL_DIR</span>
37 <i class="icon-question-sign get-help" title="Absolute path to the directory used to store downloads required for your builds. By default, Toaster projects share the same downloads directory.<br /><a href='http://www.yoctoproject.org/docs/2.1/ref-manual/ref-manual.html#var-DL_DIR' target='_blank'>Read more in the manual</a>"></i>
38 </dt>
39 <dd class="lead">
40 <span id="dl_dir"{% if dl_dir %}{%else%} class="muted"{%endif%}>{% if dl_dir %}{{dl_dir}}{%else%}Not set{%endif%}</span>
41 <i class="icon-pencil" id="change-dl_dir-icon"></i>
42 <form id="change-dl_dir-form" style="display:none;">
43 <div class="row-fluid">
44 <span class="help-block span4">To set DL_DIR type the absolute path of the download folder.</span>
45 </div>
46 <div class="input-append" id="validate-dl_dir">
47 <input type="text" class="input-xlarge" id="new-dl_dir" placeholder="Type absolute path of the DL_DIR folder">
48 <button id="apply-change-dl_dir" class="btn" type="button">Save</button>
49 <button id="cancel-change-dl_dir" type="button" class="btn btn-link">Cancel</button>
50 </br><span class="help-block error" id="hintError-dl_dir">A valid directory cannot include spaces or any of these characters: . \ ? % * : | " " < ></span>
51 </div>
52 </form>
53 </dd>
54 {% endif %}
55
Patrick Williamsc124f4f2015-09-15 14:41:29 -050056 {% if fstypes_defined %}
57 <dt>
58 <span class="js-config-var-name js-config-var-managed-name">IMAGE_FSTYPES</span>
59 <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>
60 </dt>
61 <dd class="lead">
62 <span id="image_fstypes">{{fstypes}}</span>
63 <i class="icon-pencil" id="change-image_fstypes-icon"></i>
64 <form id="change-image_fstypes-form" style="display:none;">
65 <input id="filter-image_fstypes" type="text" placeholder="Search image types" class="span4">
66 <div id="all-image_fstypes" class="scrolling">
67 </div>
Patrick Williamsf1e5d692016-03-30 15:21:19 -050068 <span class="help-block" id="fstypes-error-message">You must select at least one image type</span>
Patrick Williamsc124f4f2015-09-15 14:41:29 -050069 <button id="apply-change-image_fstypes" type="button" class="btn">Save</button>
70 <button id="cancel-change-image_fstypes" type="button" class="btn btn-link">Cancel</button>
71 </form>
72 </dd>
73 {% endif %}
74
75 {% if image_install_append_defined %}
76 <dt>
77 <span class="js-config-var-name js-config-var-managed-name">IMAGE_INSTALL_append</span>
78 <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>
79 </dt>
80 <dd class="lead">
81 <span id="image_install"{% if image_install_append %}{%else%} class="muted"{%endif%}>{% if image_install_append %}{{image_install_append}}{%else%}Not set{%endif%}</span>
82 <i class="icon-pencil" id="change-image_install-icon"></i>
83 <i class="icon-trash" id="delete-image_install-icon" {% if image_install_append %}{%else%}style="display:none;"{%endif%}></i>
84 <form id="change-image_install-form" style="display:none;">
85 <div class="row-fluid">
86 <span class="help-block span4">To set IMAGE_INSTALL_append to more than one package, type the package names separated by a space.</span>
87 </div>
88 <div class="input-append">
89 <input type="text" class="input-xlarge" id="new-image_install" placeholder="Type one or more package names">
90 <button id="apply-change-image_install" class="btn" type="button">Save</button>
91 <button id="cancel-change-image_install" type="button" class="btn btn-link">Cancel</button>
92 </div>
93 </form>
94 </dd>
95 {% endif %}
96
97 {% if package_classes_defined %}
98 <dt>
99 <span class="js-config-var-name js-config-var-managed-name">PACKAGE_CLASSES</span>
100 <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>
101 </dt>
102 <dd class="lead">
103 <span id="package_classes">{{package_classes}}</span>
104 <i id="change-package_classes-icon" class="icon-pencil"></i>
105 <form id="change-package_classes-form" style="display:none;">
106 <label>
107 Root file system package format
108 <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>
109 </label>
110 <select id="package_classes-select">
111 <option>package_deb</option>
112 <option>package_ipk</option>
113 <option>package_rpm</option>
114 </select>
115 <label>
116 Additional package formats
117 <i class="icon-question-sign get-help" title="Extra package formats to build"></i>
118 </label>
119 <label class="checkbox" id="package_class_1">
120 <input type="checkbox" id="package_class_1_input"> package_deb
121 </label>
122 <label class="checkbox" id="package_class_2">
123 <input type="checkbox" id="package_class_2_input"> package_ipk
124 </label>
125 <div style="padding-top:10px;">
126 <button id="apply-change-package_classes" type="button" class="btn">Save</button>
127 <button id="cancel-change-package_classes" type="button" class="btn btn-link">Cancel</button>
128 </div>
129 </form>
130 </dd>
131 {% endif %}
132
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500133 {% if sstate_dir_defined %}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500134 <dt>
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500135 <span class="js-config-var-name js-config-var-managed-name">SSTATE_DIR</span>
136 <i class="icon-question-sign get-help" title="Absolute path to the directory used to store shared state cache files. These files are reused across the builds, which makes the builds faster. By default, Toaster projects share the same cache directory.<br /><a href='http://www.yoctoproject.org/docs/2.1/ref-manual/ref-manual.html#var-SSTATE_DIR' target='_blank'>Read more in the manual</a>"></i>
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500137 </dt>
138 <dd class="lead">
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500139 <span id="sstate_dir"{% if sstate_dir %}{%else%} class="muted"{%endif%}>{% if sstate_dir %}{{sstate_dir}}{%else%}Not set{%endif%}</span>
140 <i class="icon-pencil" id="change-sstate_dir-icon"></i>
141 <form id="change-sstate_dir-form" style="display:none;">
142 <div class="row-fluid">
143 <span class="help-block span4">To set SSTATE_DIR type the absolute path of the download folder.</span>
144 </div>
145 <div class="input-append" id="validate-sstate_dir">
146 <input type="text" class="input-xlarge" id="new-sstate_dir" placeholder="Type absolute path of the SSTATE_DIR folder">
147 <span class="error">A valid directory name required</span>
148 <button id="apply-change-sstate_dir" class="btn" type="button">Save</button>
149 <button id="cancel-change-sstate_dir" type="button" class="btn btn-link">Cancel</button>
150 </br><p class="help-block error" id="hintError-sstate_dir">A valid directory cannot include spaces or any of these characters: . \ ? % * : | " " < ></span>
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500151 </div>
152 </form>
153 </dd>
154 {% endif %}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500155 </dl>
156
157 <!-- <ul class="unstyled configuration-list" id="configvar-list"> -->
158 <dl id="configvar-list">
159 <!-- the added configuration variables are inserted here -->
160 </dl>
161
162 <!-- pass the fstypes list, black list, and externally managed variables here -->
163 {% for fstype in vars_fstypes %}
164 <input type="hidden" class="js-checkbox-fstypes-list" value="{{fstype}}">
165 {% endfor %}
166 {% for b in vars_blacklist %}
167 <input type="hidden" class="js-config-blacklist-name" value="{{b}}">
168 {% endfor %}
169 {% for b in vars_managed %}
170 <input type="hidden" class="js-config-managed-name" value="{{b}}">
171 {% endfor %}
172
173 <div class="row-fluid">
174 <form id="variable-form">
175 <fieldset style="padding-left:0px;">
176 <legend>Add variable</legend>
177 <div class="span3" style="margin-left:0px;">
178 <span id="add-configvar-name-div" class="control-group">
179 <label>
180 Variable
181 <i title="" class="icon-question-sign get-help"
182 data-original-title="Variable names are case sensitive,
183 cannot have spaces, and can only include letters, numbers, underscores
184 and dashes"></i>
185 </label>
186 <input type="text" placeholder="Type variable name" id="variable">
187 <span class="help-block error" id="new-variable-error-message"></span>
188 </span>
189 <label>Value</label>
190 <input id="value" type="text" placeholder="Type variable value"><p>
191 <div>
192 <button id="add-configvar-button" class="btn save" type="button" disabled>Add variable</button>
193 </div>
194 </div>
195 <div class="span5 help-block">
196 <h5>Some variables are reserved from Toaster</h5>
197 <p>Toaster cannot set any variables that impact 1) the configuration of the build servers,
198 or 2) where artifacts produced by the build are stored. Such variables include: </p>
199 <p>
200 <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>
201 <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>
202 <code>CVS_PROXY_HOST</code>
203 <code>CVS_PROXY_PORT</code>
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500204 <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>
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500205 <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>
206 <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-TMPDIR" target="_blank">TMPDIR</a></code></p>
207 <p>Plus the following standard shell environment variables:</p>
208 <p><code>http_proxy</code> <code>ftp_proxy</code> <code>https_proxy</code> <code>all_proxy</code></p>
209 </div>
210 </fieldset>
211 </form>
212 </div>
213
214 </div>
215
216 <script>
217
218 // global variables
219 var do_reload=false;
220
221 // validate new variable name
222 function validate_new_variable() {
223 var variable = $("input#variable").val();
224 var value = $("input#value").val();
225
226 // presumed innocence
227 $('#new-variable-error-message').text("");
228 var error_msg = "";
229
230 var existing_configvars = document.getElementsByClassName('js-config-var-name');
231 for (var i = 0, length = existing_configvars.length; i < length; i++) {
232 if (existing_configvars[i].innerHTML.toUpperCase() == variable.toUpperCase()) {
233 error_msg = "This variable is already set in this page, edit its value instead";
234 }
235 }
236
237 var blacklist_configvars = document.getElementsByClassName('js-config-blacklist-name');
238 for (var i = 0, length = blacklist_configvars.length; i < length; i++) {
239 if (blacklist_configvars[i].value.toUpperCase() == variable.toUpperCase()) {
240 error_msg = "You cannot edit this variable in Toaster because it is set by the build servers";
241 }
242 }
243
244 var managed_configvars = document.getElementsByClassName('js-config-managed-name');
245 for (var i = 0, length = managed_configvars.length; i < length; i++) {
246 if (managed_configvars[i].value.toUpperCase() == variable.toUpperCase()) {
247 error_msg = "You cannot set this variable here. Please set it in the <a href=\"{% url 'project' project.id %}\">project main page</a>";
248 }
249 }
250
251 var bad_chars = /[^a-zA-Z0-9\-_]/.test(variable);
252 var has_spaces = (0 <= variable.indexOf(" "));
253 var only_spaces = (0 < variable.length) && (0 == variable.trim().length);
254
255 if (only_spaces) {
256 error_msg = "A valid variable name cannot include spaces";
257 } else if (bad_chars && has_spaces) {
258 error_msg = "A valid variable name can only include letters, numbers, underscores, dashes, and cannot include spaces";
259 } else if (bad_chars) {
260 error_msg = "A valid variable name can only include letters, numbers, underscores, and dashes";
261 }
262
263 if ("" != error_msg) {
264 $('#new-variable-error-message').html(error_msg);
265 $(".save").attr("disabled","disabled");
266
267 // add one (and only one) error class append
268 var d = document.getElementById("add-configvar-name-div");
269 d.className = d.className.replace(" error","");
270 d.className = d.className + " error";
271
272 return false;
273 } else if (0 == variable.length) {
274 $(".save").attr("disabled","disabled");
275 return false;
276 }
277
278 var d = document.getElementById("add-configvar-name-div");
279 d.className = d.className.replace(" error","");
280
281 // now set the "Save" enablement if 'value' also passes
282 if (value.trim().length > 0) {
283 $(".save").removeAttr("disabled");
284 } else {
285 $(".save").attr("disabled","disabled");
286 }
287
288 return true;
289 }
290
291 // validate distro name
292 function validate_distro_name() {
293 var value = $("input#new-distro").val();
294
295 // presumed innocence
296 $('#distro-error-message').text("");
297 var error_msg = "";
298
299 var has_spaces = (0 <= value.indexOf(" "));
300
301 if (has_spaces) {
302 error_msg = "A valid distro name cannot include spaces";
303 } else if (0 == value.length) {
304 error_msg = " ";
305 }
306
307 if ("" != error_msg) {
308 $('#distro-error-message').text(error_msg);
309 $("#apply-change-distro").attr("disabled","disabled");
310
311 // add one (and only one) error class append
312 var d = document.getElementById("edit-distro-name-div");
313 d.className = d.className.replace(" error","");
314 d.className = d.className + " error";
315
316 return false;
317 }
318
319 var d = document.getElementById("edit-distro-name-div");
320 d.className = d.className.replace(" error","");
321 $("#apply-change-distro").removeAttr("disabled");
322 return true;
323 }
324
325 // Test to insure at least one FS Type is checked
326 function enableFsTypesSave() {
327 var any_checked = 0;
328 $(".fs-checkbox-fstypes:checked").each(function(){
329 any_checked = 1;
330 });
331 if ( 0 == any_checked ) {
332 $("#apply-change-image_fstypes").attr("disabled","disabled");
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500333 $('#fstypes-error-message').show();
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500334 }
335 else {
336 $("#apply-change-image_fstypes").removeAttr("disabled");
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500337 $('#fstypes-error-message').hide();
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500338 }
339 }
340
341 // Preset or reset the Package Class checkbox labels
342 function updatePackageClassCheckboxes() {
343 $('#package_class_1, #package_class_2').hide();
344 if ($('select').val() == 'package_deb') {
345 $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_ipk');
346 $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_rpm');
347 }
348 if ($('select').val() == 'package_ipk') {
349 $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_deb');
350 $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_rpm');
351 }
352 if ($('select').val() == 'package_rpm') {
353 $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_deb');
354 $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_ipk');
355 }
356 $('#package_class_1, #package_class_2').fadeIn(1500);
357 }
358
359 // Re-assert handlers when the page is served and/or refreshed via Ajax
360 function setEventHandlersForDynamicElements() {
361
362 // change variable value
363 $('.js-icon-pencil-config_var').click(function (evt) {
364 var pk = evt.target.attributes["x-data"].value;
365 var current_val = $("span#config_var_value_"+pk).text();
366 $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_value_'+pk).hide();
367 $("#change-config_var-form_"+pk).slideDown();
368 $("input#new-config_var_"+pk).val(current_val);
369 });
370
371 $('.js-cancel-change-config_var').click(function (evt) {
372 var pk = evt.target.attributes["x-data"].value;
373 $("#change-config_var-form_"+pk).slideUp(function() {
374 $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_value_'+pk).show();
375 });
376 });
377
378 $(".js-new-config_var").on('input', function(){
379 if ($(this).val().length == 0) {
380 $(".js-apply-change-config_var").attr("disabled","disabled");
381 }
382 else {
383 $(".js-apply-change-config_var").removeAttr("disabled");
384 }
385 });
386
387 $('.js-apply-change-config_var').click(function (evt) {
388 var xdata = evt.target.attributes["x-data"].value.split(":");
389 var pk = xdata[0];
390 var variable = xdata[1];
391 var val = $('#new-config_var_'+pk).val();
392 postEditAjaxRequest({"configvarChange" : variable+':'+val});
393 $('#config_var_value_'+pk).parent().removeClass('muted');
394 $("#change-config_var-form_"+pk).slideUp(function() {
395 $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_value_'+pk).show();
396 });
397 });
398
399 // delete variable
400 $(".js-icon-trash-config_var").click(function (evt) {
401 var xdata = evt.target.attributes["x-data"].value.split(":");
402 var pk = xdata[0];
403
404 // hide the dangling trash tooltip
405 $('#config_var_trash_'+pk).hide();
406
407 // fade out the variable+value div, then refresh the variable list
408 $('#config_var_entry_'+pk).parent().parent().fadeOut(1000, function(){
409 postEditAjaxRequest({"configvarDel": evt.target.attributes["x-data"].value});
410 });
411
412 });
413
414 }
415
416 function onEditPageUpdate(data) {
417 // update targets
418 var i; var orightml = "";
419
420 var configvars_sorted = data.configvars.sort(function(a, b){return a[0] > b[0]});
421
422 var managed_configvars = document.getElementsByClassName('js-config-var-managed-name');
423
424 for (i = 0; i < configvars_sorted.length; i++) {
425 // skip if the variable name has a special context (not user defined)
426 var var_context=undefined;
427 for (var j = 0, length = managed_configvars.length; j < length; j++) {
428 if ((managed_configvars[j].innerHTML == configvars_sorted[i][0]) ||
429 (managed_configvars[j].value == configvars_sorted[i][0]) ) {
430 var_context='m';
431 }
432 }
433 if (var_context == undefined) {
434 orightml += '<div> <dt><span id="config_var_entry_'+configvars_sorted[i][2]+'" class="js-config-var-name"></span><i class="icon-trash js-icon-trash-config_var" id="config_var_trash_'+configvars_sorted[i][2]+'" x-data="'+configvars_sorted[i][2]+'"></i> </dt>'
435 orightml += '<dd class="lead">'
436 orightml += ' <span id="config_var_value_'+configvars_sorted[i][2]+'"></span>'
437 orightml += ' <i class="icon-pencil js-icon-pencil-config_var" x-data="'+configvars_sorted[i][2]+'"></i>'
438 orightml += ' <form id="change-config_var-form_'+configvars_sorted[i][2]+'" style="display:none;">'
439 orightml += ' <div class="input-append">'
440 orightml += ' <input type="text" class="input-xlarge js-new-config_var" id="new-config_var_'+configvars_sorted[i][2]+'" value="">'
441 orightml += ' <button class="btn js-apply-change-config_var" type="button" x-data="'+configvars_sorted[i][2]+':'+configvars_sorted[i][0]+'" disabled>Save</button>'
442 orightml += ' <button type="button" class="btn btn-link js-cancel-change-config_var" x-data="'+configvars_sorted[i][2]+'">Cancel</button>'
443 orightml += ' </div>'
444 orightml += ' </form>'
445 orightml += '</dd> </div>'
446 }
447 }
448
449 // update configvars list HTML framework
450 $("dl#configvar-list").html(orightml);
451
452 // insert the name/value pairs safely as non-HTML
453 for (i = 0; i < configvars_sorted.length; i++) {
454 $('#config_var_entry_'+configvars_sorted[i][2]).text(configvars_sorted[i][0]);
455 $('#config_var_value_'+configvars_sorted[i][2]).text(configvars_sorted[i][1]);
456 }
457
458 // Add the tooltips
459 $(".js-icon-trash-config_var").each( function(){ setDeleteTooltip($(this)); });
460 $(".js-icon-pencil-config_var").each(function(){ setChangeTooltip($(this)); });
461
462 // re-assert these event handlers
463 setEventHandlersForDynamicElements();
464 }
465
466 function onEditAjaxSuccess(data, textstatus) {
467 // console.log("XHR returned:", data, "(" + textstatus + ")");
468 if (data.error != "ok") {
469 alert("error on request:\n" + data.error);
470 return;
471 }
472
473 // delayed page reload?
474 if (do_reload) {
475 do_reload=false;
476 location.reload(true);
477 } else {
478 onEditPageUpdate(data);
479 }
480 }
481
482 function onEditAjaxError(jqXHR, textstatus, error) {
483 alert("XHR errored:\n" + error + "\n(" + textstatus + ")");
484 // re-assert the event handlers
485 }
486
487 /* ensure cookie exists {% csrf_token %} */
488 function postEditAjaxRequest(reqdata) {
489 var ajax = $.ajax({
490 type:"POST",
491 data: $.param(reqdata),
492 url:"{% url 'xhr_configvaredit' project.id%}",
493 headers: { 'X-CSRFToken': $.cookie("csrftoken")},
494 success: onEditAjaxSuccess,
495 error: onEditAjaxError,
496 })
497 }
498
499 function setDeleteTooltip(object) {
500 object.tooltip({ container: 'body', html: true, delay: {show: 400}, title: "Delete" });
501 }
502 function setChangeTooltip(object) {
503 object.tooltip({ container: 'body', html: true, delay: {show: 400}, title: "Change" });
504 }
505
506 $(document).ready(function() {
507
508 //
509 // Register handlers for static elements
510 //
511
512 {% if distro_defined %}
513 // change distro variable
514 $('#change-distro-icon').click(function() {
515 $('#change-distro-icon, #distro').hide();
516 $("#change-distro-form").slideDown();
517 $("#new-distro").val( $('#distro').text() );
518 });
519
520 $('#cancel-change-distro').click(function(){
521 $("#change-distro-form").slideUp(function() {
522 $('#distro, #change-distro-icon').show();
523
524 // reset any dangling error state
525 $('#distro-error-message').text("");
526 var d = document.getElementById("edit-distro-name-div");
527 d.className = d.className.replace(" error","");
528 });
529 });
530
531 // validate new distro name
532 $("input#new-distro").on('input', function (evt) {
533 validate_distro_name();
534 });
535
536 $('#apply-change-distro').click(function(){
537 //$('#repo').parent().removeClass('highlight-go');
538 var name = $('#new-distro').val();
539 postEditAjaxRequest({"configvarChange" : 'DISTRO:'+name});
540 $('#distro').text(name);
541 $("#change-distro-form").slideUp(function () {
542 $('#distro, #change-distro-icon').show();
543 });
544 });
545 {% endif %}
546
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500547 {% if dl_dir_defined %}
548
549 // change DL_DIR variable
550 $('#change-dl_dir-icon').click(function() {
551 $('#hintError-dl_dir').hide();
552 // preset the edit value
553 var current_val = $("span#dl_dir").text().trim();
554 if (current_val == "Not set") {
555 current_val="";
556 $("#apply-change-dl_dir").attr("disabled","disabled");
557 }
558 $("input#new-dl_dir").val(current_val);
559
560 $('#change-dl_dir-icon, #dl_dir').hide();
561 $("#change-dl_dir-form").slideDown();
562 });
563
564 $('#cancel-change-dl_dir').click(function(){
565 $("#change-dl_dir-form").slideUp(function() {
566 $('#dl_dir, #change-dl_dir-icon').show();
567 });
568 });
569
570 $("#new-dl_dir").on('input', function(){
571 if ($(this).val().trim().length == 0) {
572 $("#apply-change-dl_dir").attr("disabled","disabled");
573 }
574 else {
575 var input = $(this);
576 var re = /^\/([^ <>\\|":\.%\?\*]+)$/;
577 var invalidDir = re.test(input.val());
578 console.log(invalidDir);
579 if ( invalidDir ) {
580 $('#validate-dl_dir').removeClass('control-group error');
581 $("#apply-change-dl_dir").removeAttr("disabled");
582 $('#hintError-dl_dir').hide();
583 } else {
584 $('#validate-dl_dir').addClass('control-group error');
585 $("#apply-change-dl_dir").attr("disabled","disabled");
586 $('#hintError-dl_dir').show();
587 }
588 }
589 });
590
591 $('#apply-change-dl_dir').click(function(){
592 var value = $('#new-dl_dir').val().trim();
593 postEditAjaxRequest({"configvarChange" : 'DL_DIR:'+value});
594 $('#dl_dir').text(value);
595 $('#dl_dir').removeClass('muted');
596 $("#change-dl_dir-form").slideUp(function () {
597 $('#dl_dir, #change-dl_dir-icon').show();
598 });
599 });
600
601 {% endif %}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500602
603 {% if fstypes_defined %}
604 // change IMAGE_FSTYPES variable
605
606 $('#change-image_fstypes-icon').click(function() {
607 $('#change-image_fstypes-icon, #image_fstypes').hide();
608 $("#change-image_fstypes-form").slideDown();
609 // avoid false substring matches by including space separators
610 var html = "";
611 var fstypes = " " + document.getElementById("image_fstypes").innerHTML + " ";
612 var fstypes_list = document.getElementsByClassName('js-checkbox-fstypes-list');
613 // Add the checked boxes first
614 if (" " != fstypes) {
615 for (var i = 0, length = fstypes_list.length; i < length; i++) {
616 if (0 <= fstypes.indexOf(" "+fstypes_list[i].value+" ")) {
617 html += '<label class="checkbox"><input type="checkbox" class="fs-checkbox-fstypes" value="'+fstypes_list[i].value+'" checked="checked">'+fstypes_list[i].value+'</label>\n';
618 }
619 }
620 }
621 // Add the un-checked boxes second
622 for (var i = 0, length = fstypes_list.length; i < length; i++) {
623 if (0 > fstypes.indexOf(" "+fstypes_list[i].value+" ")) {
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500624 html += '<label class="checkbox"><input type="checkbox" class="fs-checkbox-fstypes" value="'+fstypes_list[i].value+'">'+fstypes_list[i].value+'</label>\n';
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500625 }
626 }
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500627 // Add the 'no search matches' line last
628 html += '<label id="no-match-fstypes">No image types found</label>\n';
629 // Display the list
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500630 document.getElementById("all-image_fstypes").innerHTML = html;
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500631 $('#no-match-fstypes').hide();
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500632
633 // Watch elements to disable Save when none are checked
634 $(".fs-checkbox-fstypes").each(function(){
635 $(this).click(function() {
636 enableFsTypesSave();
637 });
638 });
639
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500640 // clear the previous filter values and warning messages
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500641 $("input#filter-image_fstypes").val("");
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500642 $('#fstypes-error-message').hide();
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500643 });
644
645 $('#cancel-change-image_fstypes').click(function(){
646 $("#change-image_fstypes-form").slideUp(function() {
647 $('#image_fstypes, #change-image_fstypes-icon').show();
648 });
649 });
650
651 $('#filter-image_fstypes').on('input', function(){
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500652 var valThis = $(this).val().toLowerCase();
653 var matchCount=0;
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500654 $('#all-image_fstypes label').each(function(){
655 var text = $(this).text().toLowerCase();
656 var match = text.indexOf(valThis);
657 if (match >= 0) {
658 $(this).show();
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500659 matchCount += 1;
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500660 }
661 else {
662 $(this).hide();
663 }
664 });
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500665 if (matchCount === 0) {
666 $('#no-match-fstypes').show();
667 } else {
668 $('#no-match-fstypes').hide();
669 }
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500670 });
671
672 $('#apply-change-image_fstypes').click(function(){
673 // extract the selected fstypes and sort them
674 var fstypes_array = [];
675 var checkboxes = document.getElementsByClassName('fs-checkbox-fstypes');
676 $(".fs-checkbox-fstypes:checked").each(function(){
677 fstypes_array.push($(this).val());
678 });
679 fstypes_array.sort();
680
681 // now make a string of them
682 var fstypes = '';
683 for (var i = 0, length = fstypes_array.length; i < length; i++) {
684 fstypes += fstypes_array[i] + ' ';
685 }
686 fstypes = fstypes.trim();
687
688 postEditAjaxRequest({"configvarChange" : 'IMAGE_FSTYPES:'+fstypes});
689 $('#image_fstypes').text(fstypes);
690 $('#image_fstypes').parent().removeClass('muted');
691
692 $("#change-image_fstypes-form").slideUp(function() {
693 $('#image_fstypes, #change-image_fstypes-icon').show();
694 });
695 });
696 {% endif %}
697
698
699 {% if image_install_append_defined %}
700
701 // init IMAGE_INSTALL_append trash icon
702 setDeleteTooltip($('#delete-image_install-icon'));
703
704 // change IMAGE_INSTALL_append variable
705 $('#change-image_install-icon').click(function() {
706 // preset the edit value
707 var current_val = $("span#image_install").text().trim();
708 if (current_val == "Not set") {
709 current_val="";
710 $("#apply-change-image_install").attr("disabled","disabled");
711 } else {
712 // insure these non-empty values have single space prefix
713 current_val=" " + current_val;
714 }
715 $("input#new-image_install").val(current_val);
716
717 $('#change-image_install-icon, #delete-image_install-icon, #image_install').hide();
718 $("#change-image_install-form").slideDown();
719 });
720
721 $('#cancel-change-image_install').click(function(){
722 $("#change-image_install-form").slideUp(function() {
723 $('#image_install, #change-image_install-icon').show();
724 if ($("span#image_install").text() != "Not set") {
725 $('#delete-image_install-icon').show();
726 setDeleteTooltip($('#delete-image_install-icon'));
727 }
728 });
729 });
730
731 $("#new-image_install").on('input', function(){
732 if ($(this).val().trim().length == 0) {
733 $("#apply-change-image_install").attr("disabled","disabled");
734 }
735 else {
736 $("#apply-change-image_install").removeAttr("disabled");
737 }
738 });
739
740 $('#apply-change-image_install').click(function(){
741 // insure these non-empty values have single space prefix
742 var value = " " + $('#new-image_install').val().trim();
743 postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL_append:'+value});
744 $('#image_install').text(value);
745 $('#image_install').removeClass('muted');
746 $("#change-image_install-form").slideUp(function () {
747 $('#image_install, #change-image_install-icon').show();
748 if (value.length > -1) {
749 $('#delete-image_install-icon').show();
750 setDeleteTooltip($('#delete-image_install-icon'));
751 }
752 });
753 });
754
755 // delete IMAGE_INSTALL_append variable value
756 $('#delete-image_install-icon').click(function(){
757 $(this).tooltip('hide');
758 postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL_append:'+''});
759 $('#image_install').parent().fadeOut(1000, function(){
760 $('#image_install').addClass('muted');
761 $('#image_install').text('Not set');
762 $('#delete-image_install-icon').hide();
763 $('#image_install').parent().fadeIn(1000);
764 });
765 });
766 {% endif %}
767
768
769 {% if package_classes_defined %}
770 // change PACKAGE_CLASSES variable
771 $('#change-package_classes-icon').click(function() {
772 $('#change-package_classes-icon, #package_classes').hide();
773 $("#change-package_classes-form").slideDown();
774
775 // initialize the pulldown and checkboxes
776 var value = $("#package_classes").text();
777 if ( value.indexOf("package_deb") == 0 ) {
778 $("#package_classes-select").prop('selectedIndex', 0);
779 updatePackageClassCheckboxes();
780 if ( value.indexOf("_ipk") > 0 ) {
781 $("#package_class_1_input").attr("checked",true);
782 }
783 if ( value.indexOf("_rpm") > 0 ) {
784 $("#package_class_2_input").attr("checked",true);
785 }
786 }
787
788 if ( value.indexOf("package_ipk") == 0 ) {
789 $("#package_classes-select").prop('selectedIndex', 1);
790 updatePackageClassCheckboxes();
791 if ( value.indexOf("_deb") > 0 ) {
792 $("#package_class_1_input").attr("checked",true);
793 }
794 if ( value.indexOf("_rpm") > 0 ) {
795 $("#package_class_2_input").attr("checked",true);
796 }
797 }
798
799 if ( value.indexOf("package_rpm") == 0 ) {
800 $("#package_classes-select").prop('selectedIndex', 2);
801 updatePackageClassCheckboxes();
802 if ( value.indexOf("_deb") > 0 ) {
803 $("#package_class_1_input").attr("checked",true);
804 }
805 if ( value.indexOf("_ipk") > 0 ) {
806 $("#package_class_2_input").attr("checked",true);
807 }
808 }
809 });
810
811 $('#cancel-change-package_classes').click(function(){
812 $("#change-package_classes-form").slideUp(function() {
813 $('#package_classes, #change-package_classes-icon').show();
814 });
815 });
816
817 $('select').change(function() {
818 updatePackageClassCheckboxes();
819 });
820
821 $('#apply-change-package_classes').click(function(){
822 var e = document.getElementById("package_classes-select");
823 var val = e.options[e.selectedIndex].text;
824
825 pc1_checked = document.getElementById("package_class_1_input").checked;
826 pc2_checked = document.getElementById("package_class_2_input").checked;
827 if (val == "package_deb") {
828 if (pc1_checked) val = val + " package_ipk";
829 if (pc2_checked) val = val + " package_rpm";
830 }
831 if (val == "package_ipk") {
832 if (pc1_checked) val = val + " package_deb";
833 if (pc2_checked) val = val + " package_rpm";
834 }
835 if (val == "package_rpm") {
836 if (pc1_checked) val = val + " package_deb";
837 if (pc2_checked) val = val + " package_ipk";
838 }
839
840 $('#package_classes').text(val);
841 //$('#package_classes').parent().removeClass('muted');
842 postEditAjaxRequest({"configvarChange" : 'PACKAGE_CLASSES:'+val});
843 $("#change-package_classes-form").slideUp(function() {
844 $('#package_classes, #change-package_classes-icon').show();
845 });
846 });
847 {% endif %}
848
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500849 {% if sstate_dir_defined %}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500850
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500851 // change SSTATE_DIR variable
852 $('#change-sstate_dir-icon').click(function() {
853 $('#hintError-sstate_dir').hide();
854 // preset the edit value
855 var current_val = $("span#sstate_dir").text().trim();
856 if (current_val == "Not set") {
857 current_val="";
858 $("#apply-change-sstate_dir").attr("disabled","disabled");
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500859 }
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500860 $("input#new-sstate_dir").val(current_val);
861
862 $('#change-sstate_dir-icon, #sstate_dir').hide();
863 $("#change-sstate_dir-form").slideDown();
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500864 });
865
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500866 $('#cancel-change-sstate_dir').click(function(){
867 $("#change-sstate_dir-form").slideUp(function() {
868 $('#sstate_dir, #change-sstate_dir-icon').show();
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500869 });
870 });
871
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500872 $("#new-sstate_dir").on('input', function(){
873 if ($(this).val().trim().length == 0) {
874 $("#apply-change-sstate_dir").attr("disabled","disabled");
875 }
876 else {
877 var input = $(this);
878 var re = /^\/([^ <>\\|":\.%\?\*]+)$/;
879 var invalidDir = re.test(input.val());
880 console.log(invalidDir);
881 if ( invalidDir ) {
882 $('#validate-sstate_dir').removeClass('control-group error');
883 $("#apply-change-sstate_dir").removeAttr("disabled");
884 $('#hintError-sstate_dir').hide();
885 } else {
886 $('#validate-sstate_dir').addClass('control-group error');
887 $("#apply-change-sstate_dir").attr("disabled","disabled");
888 $('#hintError-sstate_dir').show();
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500889 }
890 }
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500891 });
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500892
893 $('#apply-change-sstate_dir').click(function(){
894 var value = $('#new-sstate_dir').val().trim();
895 postEditAjaxRequest({"configvarChange" : 'SSTATE_DIR:'+value});
896 $('#sstate_dir').text(value);
897 $('#sstate_dir').removeClass('muted');
898 $("#change-sstate_dir-form").slideUp(function () {
899 $('#sstate_dir, #change-sstate_dir-icon').show();
900 });
901 });
902
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500903 {% endif %}
904
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500905 // add new variable
906 $("button#add-configvar-button").click( function (evt) {
907 var variable = $("input#variable").val();
908 var value = $("input#value").val();
909
910 postEditAjaxRequest({"configvarAdd" : variable+':'+value});
911
912 // clear the previous values
913 $("input#variable").val("");
914 $("input#value").val("");
915 // Disable add button
916 $(".save").attr("disabled","disabled");
917
918 // Reload page if admin-removed core managed value is manually added back in
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500919 if (0 <= " DISTRO DL_DIR IMAGE_FSTYPES IMAGE_INSTALL_append PACKAGE_CLASSES SSTATE_DIR ".indexOf( " "+variable+" " )) {
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500920 // delayed reload to avoid race condition with postEditAjaxRequest
921 do_reload=true;
922 }
923 });
924
925 // validate new variable name and value
926 $("#variable, #value").on('input', function() {
927 validate_new_variable();
928 });
929
930 //
931 // draw and register the dynamic configuration variables and handlers
932 //
933
934 var data = {
935 configvars : []
936 };
937 {% for c in configvars %}
938 data.configvars.push([ "{{c.name}}","{{c.value}}","{{c.pk}}" ]);
939 {% if '' != vars_context|get_dict_value:c.name %}
940 data.vars_context[ "{{c.name}}" ] = "{{vars_context|get_dict_value:c.name }}";
941 {% endif %}
942 {% endfor %}
943
944 // draw these elements and assert their event handlers
945 onEditPageUpdate(data);
946 });
947
948 </script>
949
950{% endblock %}