summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 @@
{% load humanize %}
{% block localbreadcrumb %}
-<li>Project configuration</li>
+<li>Configuration variables</li>
{% endblock %}
{% block projectinfomain %}
<div class="page-header">
- <h1>Configuration Variables</h1>
+ <h1>Configuration variables</h1>
</div>
<div style="padding-left:19px;">
<dl class="dl-vertical">
- {% for c in configvars %}
<dt>
- {{c.name}}
- <i class="icon-question-sign get-help" title="{{c.desc}}"></i>
+ <span class="js-config-var-name js-config-var-managed-name">DISTRO</span>
+ <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>
</dt>
<dd class="lead">
- <span id="distro">{{c.value}}</span>
+ <span id="distro">{{distro}}</span>
<i class="icon-pencil" id="change-distro-icon"></i>
<form id="change-distro-form" style="display:none;">
<div class="input-append">
- <input type="text" id="new-distro" value="poky tiny">
+ <input type="text" id="new-distro" value="{{distro}}">
<button id="apply-change-distro" class="btn" type="button">Save</button>
<button id="cancel-change-distro" type="button" class="btn btn-link">Cancel</button>
</div>
</form>
</dd>
- {% endfor %}
+ <dt>
+ <span class="js-config-var-name js-config-var-managed-name">IMAGE_FSTYPES</span>
+ <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>
+ </dt>
+ <dd class="lead">
+ <span id="image_fstypes">{{fstypes}}</span>
+ <i class="icon-pencil" id="change-image_fstypes-icon"></i>
+ <form id="change-image_fstypes-form" style="display:none;">
+ <input id="filter-image_fstypes" type="text" placeholder="Search image types" class="span4">
+ <div id="all-image_fstypes" class="scrolling">
+ </div>
+ <button id="apply-change-image_fstypes" type="button" class="btn">Save</button>
+ <button id="cancel-change-image_fstypes" type="button" class="btn btn-link">Cancel</button>
+ </form>
+ </dd>
+ <dt>
+ <span class="js-config-var-name js-config-var-managed-name">IMAGE_INSTALL_append</span>
+ <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>
+ </dt>
+ <dd class="lead muted">
+ <span id="image_install">{% if image_install_append %}{{image_install_append}}{%else%}Not set{%endif%}</span>
+ <i class="icon-pencil" id="change-image_install-icon"></i>
+ <i class="icon-trash" id="delete-image_install-icon" style="display:none;"></i>
+ <form id="change-image_install-form" style="display:none;">
+ <div class="row-fluid">
+ <span class="help-block span4">To set IMAGE_INSTALL_append to more than one package, type the package names separated by a space.</span>
+ </div>
+ <div class="input-append">
+ <input type="text" class="input-xlarge" id="new-image_install" placeholder="Type one or more package names">
+ <button id="apply-change-image_install" class="btn" type="button">Save</button>
+ <button id="cancel-change-image_install" type="button" class="btn btn-link">Cancel</button>
+ </div>
+ </form>
+ </dd>
+ <dt>
+ <span class="js-config-var-name js-config-var-managed-name">PACKAGE_CLASSES</span>
+ <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>
+ </dt>
+ <dd class="lead">
+ <span id="package_classes">{{package_classes}}</span>
+ <i id="change-package_classes-icon" class="icon-pencil"></i>
+ <form id="change-package_classes-form" style="display:none;">
+ <label>
+ Root file system package format
+ <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>
+ </label>
+ <select id="package_classes-select">
+ <option>package_dev</option>
+ <option>package_ipk</option>
+ <option>package_rpm</option>
+ </select>
+ <label>
+ Additional package formats
+ <i class="icon-question-sign get-help" title="Extra package formats to build"></i>
+ </label>
+ <label class="checkbox" id="package_class_1">
+ <input type="checkbox" id="package_class_1_input"> package_dev
+ </label>
+ <label class="checkbox" id="package_class_2">
+ <input type="checkbox" id="package_class_2_input"> package_ipk
+ </label>
+ <div style="padding-top:10px;">
+ <button id="apply-change-package_classes" type="button" class="btn">Save</button>
+ <button id="cancel-change-package_classes" type="button" class="btn btn-link">Cancel</button>
+ </div>
+ </form>
+ </dd>
+ <dt>
+ <span class="js-config-var-name js-config-var-managed-name">SDKMACHINE</span>
+ <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>
+ </dt>
+ <dd class="lead">
+ <span id="sdkmachine">{{sdk_machine}}</span>
+ <i id="change-sdkmachine-icon" class="icon-pencil"></i>
+ <form id="change-sdkmachine-form" style="display:none;">
+ <label class="radio">
+ <input type="radio" name="sdkmachine" value="i686">
+ i686
+ </label>
+ <label class="radio">
+ <input type="radio" name="sdkmachine" value="x86_64">
+ x86_64
+ </label>
+ <div style="padding-top:10px;">
+ <button id="apply-change-sdkmachine" type="button" class="btn">Save</button>
+ <button id="cancel-change-sdkmachine" type="button" class="btn btn-link">Cancel</button>
+ </div>
+ </form>
+ </dd>
+ </dl>
+ <!-- <ul class="unstyled configuration-list" id="configvar-list"> -->
+ <dl id="configvar-list">
+ <!-- the added configuration variables are inserted here -->
</dl>
- <form id="variable-form">
+
+ <!-- pass the fstypes list, black list, and externally managed variables here -->
+ {% for fstype in vars_fstypes %}
+ <input type="hidden" class="js-checkbox-fstypes-list" value="{{fstype}}">
+ {% endfor %}
+ {% for b in vars_blacklist %}
+ <input type="hidden" class="js-config-blacklist-name" value="{{b}}">
+ {% endfor %}
+ {% for b in vars_managed %}
+ <input type="hidden" class="js-config-var-managed-name" value="{{b}}">
+ {% endfor %}
+
+ <div class="row-fluid">
+ <form id="variable-form">
<fieldset style="padding-left:0px;">
<legend>Add variable</legend>
- <label>
- Variable
- <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>
- </label>
- <input id="variable" type="text" placeholder="Type variable name">
- <label>Value</label>
- <input id="value" type="text" placeholder="Type variable value">
- <div style="display:block;margin-top:10px;">
- <a href="#" class="btn save" disabled>
- Add variable
- </a>
+ <div class="span3" style="margin-left:0px;">
+ <span id="add-configvar-name-div" class="control-group">
+ <label>
+ Variable
+ <i title="" class="icon-question-sign get-help"
+ data-original-title="Variable names are case sensitive,
+ cannot have spaces, and can only include letters, numbers, underscores
+ and dashes"></i>
+ </label>
+ <input type="text" placeholder="Type variable name" id="variable">
+ <span class="help-block error" id="new-variable-error-message"></span>
+ </span>
+ <label>Value</label>
+ <input id="value" type="text" placeholder="Type variable value"><p>
+ <div class="input-append" style="display:block;margin-top:10px;">
+ <button id="add-configvar-button" class="btn save" type="button" disabled>Add variable</button>
+ </div>
+ </div>
+ <div class="span5 help-block">
+ <h5>Some variables are reserved from Toaster</h5>
+ <p>Toaster cannot set any variables that impact 1) the configuration of the build servers,
+ or 2) where artifacts produced by the build are stored. Such variables include: </p>
+ <p>
+ <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>
+ <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>
+ <code>CVS_PROXY_HOST</code>
+ <code>CVS_PROXY_PORT</code>
+ <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>
+ <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>
+ <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>
+ <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>
+ <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-TMPDIR" target="_blank">TMPDIR</a></code></p>
+ <p>Plus the following standard shell environment variables:</p>
+ <p><code>http_proxy</code> <code>ftp_proxy</code> <code>https_proxy</code> <code>all_proxy</code></p>
</div>
</fieldset>
- </form>
- <!--button id="add-variable" class="btn air">
- <i class="icon-plus"></i>
- Add variable
- </button-->
+ </form>
+ </div>
</div>
+ <script>
+
+ // validate new variable name
+ function validate_new_variable_name() {
+ var variable = $("input#variable")[0].value;
+ var value = $("input#value")[0].value;
+
+ // presumed innocence
+ $('#new-variable-error-message').html("");
+ var error_msg = ""
+
+ var existing_configvars = document.getElementsByClassName('js-config-var-name');
+ for (var i = 0, length = existing_configvars.length; i < length; i++) {
+ if (existing_configvars[i].innerHTML == variable) {
+ error_msg = "This variable is already set in this page, edit its value instead";
+ }
+ }
+
+ var blacklist_configvars = document.getElementsByClassName('js-config-blacklist-name');
+ for (var i = 0, length = blacklist_configvars.length; i < length; i++) {
+ if (blacklist_configvars[i].value == variable) {
+ error_msg = "You cannot edit this variable in Toaster because it is set by the build servers";
+ }
+ }
+
+ var bad_chars = /[^a-zA-Z0-9\-_]/.test(variable);
+ var has_spaces = (0 <= variable.indexOf(" "));
+ var only_spaces = (0 < variable.length) && (0 == variable.trim().length);
+
+ if (only_spaces) {
+ error_msg = "A valid variable name cannot include spaces";
+ } else if (bad_chars && has_spaces) {
+ error_msg = "A valid variable name can only include letters, numbers, underscores, dashes, and cannot include spaces";
+ } else if (bad_chars) {
+ error_msg = "A valid variable name can only include letters, numbers, underscores, and dashes";
+ }
+
+ if ("" != error_msg) {
+ $('#new-variable-error-message').html(error_msg);
+ $(".save").attr("disabled","disabled");
+
+ var d = document.getElementById("add-configvar-name-div");
+ d.className = d.className + " control-group error";
+
+ return false;
+ }
+
+ var d = document.getElementById("add-configvar-name-div");
+ d.className = d.className.replace(" control-group error","");
+ return true;
+ }
+
+ // Preset or reset the Package Class checkbox labels
+ function updatePackageClassCheckboxes() {
+ if ($('select').val() == 'package_dev') {
+ $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_ipk');
+ $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_rpm');
+ }
+ if ($('select').val() == 'package_ipk') {
+ $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_dev');
+ $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_rpm');
+ }
+ if ($('select').val() == 'package_rpm') {
+ $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_dev');
+ $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_ipk');
+ }
+ }
+
+ // Re-assert handlers when the page is served and/or refreshed via Ajax
+ function setEventHandlersForDynamicElements() {
+
+ // change variable value
+ $('.js-icon-pencil-config_var').click(function (evt) {
+ var pk = evt.target.attributes["x-data"].value;
+ var current_val = $("span#config_var_"+pk).html();
+ $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_'+pk).hide();
+ $("#change-config_var-form_"+pk).slideDown();
+ $("input#new-config_var_"+pk)[0].value = current_val;
+ });
+
+ $('.js-cancel-change-config_var').click(function (evt) {
+ var pk = evt.target.attributes["x-data"].value;
+ $("#change-config_var-form_"+pk).slideUp(function() {
+ $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_'+pk).show();
+ });
+ });
+
+ $(".js-new-config_var").keyup(function(){
+ if ($(this).val().length == 0) {
+ $(".js-apply-change-config_var").attr("disabled","disabled");
+ }
+ else {
+ $(".js-apply-change-config_var").removeAttr("disabled");
+ }
+ });
+
+ $('.js-apply-change-config_var').click(function (evt) {
+ var xdata = evt.target.attributes["x-data"].value.split(":");
+ var pk = xdata[0];
+ var variable = xdata[1];
+ var val = $('#new-config_var_'+pk).val();
+ postEditAjaxRequest({"configvarChange" : variable+':'+val});
+ $('#config_var_'+pk).parent().removeClass('muted');
+ $("#change-config_var-form_"+pk).slideUp(function() {
+ $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_'+pk).show();
+ });
+ });
+
+ // delete variable
+ $(".js-icon-trash-config_var").click(function (evt) {
+ var xdata = evt.target.attributes["x-data"].value.split(":");
+ var pk = xdata[0];
+ $('#config_var_entry_'+pk).slideUp(function() {
+ //$('#config_var_entry_'+pk).show();
+ });
+ postEditAjaxRequest({"configvarDel": evt.target.attributes["x-data"].value});
+ });
+
+ }
+
+ function onEditPageUpdate(data) {
+ // update targets
+ var i; var orightml = "";
+
+ var configvars_sorted = data.configvars.sort(function(a, b){return a[0] > b[0]});
+
+ var managed_configvars = document.getElementsByClassName('js-config-var-managed-name');
+
+ for (i = 0; i < configvars_sorted.length; i++) {
+ // skip if the variable name has a special context (not user defined)
+ var var_context=undefined;
+ for (var j = 0, length = managed_configvars.length; j < length; j++) {
+ if ((managed_configvars[j].innerHTML == configvars_sorted[i][0]) ||
+ (managed_configvars[j].value == configvars_sorted[i][0]) ) {
+ var_context='m';
+ }
+ }
+ if (var_context == undefined) {
+ 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>'
+ orightml += '<dd class="lead">'
+ orightml += ' <span id="config_var_'+configvars_sorted[i][2]+'">'+configvars_sorted[i][1]+'</span>'
+ orightml += ' <i class="icon-pencil js-icon-pencil-config_var" x-data="'+configvars_sorted[i][2]+'"></i>'
+ orightml += ' <form id="change-config_var-form_'+configvars_sorted[i][2]+'" style="display:none;">'
+ orightml += ' <div class="input-append">'
+ orightml += ' <input type="text" class="input-xlarge js-new-config_var" id="new-config_var_'+configvars_sorted[i][2]+'" value="">'
+ orightml += ' <button class="btn js-apply-change-config_var" type="button" x-data="'+configvars_sorted[i][2]+':'+configvars_sorted[i][0]+'" disabled>Save</button>'
+ orightml += ' <button type="button" class="btn btn-link js-cancel-change-config_var" x-data="'+configvars_sorted[i][2]+'">Cancel</button>'
+ orightml += ' </div>'
+ orightml += ' </form>'
+ orightml += '</dd>'
+ }
+ }
+
+ // update configvars list
+ $("dl#configvar-list").html(orightml);
+
+ // re-assert these event handlers
+ setEventHandlersForDynamicElements();
+ }
+
+ function onEditAjaxSuccess(data, textstatus) {
+ // console.log("XHR returned:", data, "(" + textstatus + ")");
+ if (data.error != "ok") {
+ alert("error on request:\n" + data.error);
+ return;
+ }
+ onEditPageUpdate(data);
+ }
+
+ function onEditAjaxError(jqXHR, textstatus, error) {
+ alert("XHR errored:\n" + error + "\n(" + textstatus + ")");
+ // re-assert the event handlers
+ }
+
+ function postEditAjaxRequest(reqdata) {
+ var ajax = $.ajax({
+ type:"POST",
+ data: $.param(reqdata),
+ url:"{% url 'xhr_configvaredit' project.id%}",
+ headers: { 'X-CSRFToken': $.cookie("csrftoken")},
+ success: onEditAjaxSuccess,
+ error: onEditAjaxError,
+ })
+ }
+
+
+ $(document).ready(function() {
+
+ //
+ // Register handlers for static elements
+ //
+
+ // change distro variable
+ $('#change-distro-icon').click(function() {
+ $('#change-distro-icon, #distro').hide();
+ $("#change-distro-form").slideDown();
+ });
+
+ $('#cancel-change-distro').click(function(){
+ $("#change-distro-form").slideUp(function() {
+ $('#distro, #change-distro-icon').show();
+ });
+ });
+
+ $("#new-distro").keyup(function(){
+ if ($(this).val().length == 0) {
+ $("#apply-change-distro").attr("disabled","disabled");
+ }
+ else {
+ $("#apply-change-distro").removeAttr("disabled");
+ }
+ });
+
+ $('#apply-change-distro').click(function(){
+ //$('#repo').parent().removeClass('highlight-go');
+ var name = $('#new-distro').val();
+ postEditAjaxRequest({"configvarChange" : 'DISTRO:'+name});
+ $('#distro').html(name);
+ $("#change-distro-form").slideUp(function () {
+ $('#distro, #change-distro-icon').show();
+ });
+ });
+
+
+ // change IMAGE_FSTYPES variable
+ $('#change-image_fstypes-icon').click(function() {
+ $('#change-image_fstypes-icon, #image_fstypes').hide();
+ $("#change-image_fstypes-form").slideDown();
+ // avoid false substring matches by including space separators
+ var html = "";
+ var fstypes = " " + document.getElementById("image_fstypes").innerHTML + " ";
+ var fstypes_list = document.getElementsByClassName('js-checkbox-fstypes-list');
+ // Add the checked boxes first
+ if (" " != fstypes) {
+ for (var i = 0, length = fstypes_list.length; i < length; i++) {
+ if (0 <= fstypes.indexOf(" "+fstypes_list[i].value+" ")) {
+ html += '<label class="checkbox"><input type="checkbox" class="fs-checkbox-fstypes" value="'+fstypes_list[i].value+'" checked="checked">'+fstypes_list[i].value+'</label>\n';
+ }
+ }
+ }
+ // Add the un-checked boxes second
+ for (var i = 0, length = fstypes_list.length; i < length; i++) {
+ if (0 > fstypes.indexOf(" "+fstypes_list[i].value+" ")) {
+ html += '<label class="checkbox"><input type="checkbox" class="fs-checkbox-fstypes" value="'+fstypes_list[i].value+'">'+fstypes_list[i].value+'</label>\n';
+ }
+ }
+ document.getElementById("all-image_fstypes").innerHTML = html;
+ });
+
+ $('#cancel-change-image_fstypes').click(function(){
+ $("#change-image_fstypes-form").slideUp(function() {
+ $('#image_fstypes, #change-image_fstypes-icon').show();
+ });
+ });
+
+ $('#apply-change-image_fstypes').click(function(){
+ var fstypes = '';
+ var checkboxes = document.getElementsByClassName('fs-checkbox-fstypes');
+ for (var i = 0, length = checkboxes.length; i < length; i++) {
+ if (checkboxes[i].checked) {
+ fstypes += checkboxes[i].value + ' ';
+ }
+ }
+ fstypes = fstypes.trim();
+
+ postEditAjaxRequest({"configvarChange" : 'IMAGE_FSTYPES:'+fstypes});
+ $('#image_fstypes').html(fstypes);
+ $('#image_fstypes').parent().removeClass('muted');
+
+ $("#change-image_fstypes-form").slideUp(function() {
+ $('#image_fstypes, #change-image_fstypes-icon').show();
+ });
+ });
+
+
+ // change IMAGE_INSTALL_append variable
+ $('#change-image_install-icon').click(function() {
+ $('#change-image_install-icon, #delete-image_install-icon, #image_install').hide();
+ $("#change-image_install-form").slideDown();
+ });
+
+ $('#cancel-change-image_install').click(function(){
+ $("#change-image_install-form").slideUp(function() {
+ $('#image_install, #change-image_install-icon').show();
+ });
+ });
+
+ $("#new-image_install").keyup(function(){
+ if ($(this).val().length == 0) {
+ $("#apply-change-image_install").attr("disabled","disabled");
+ }
+ else {
+ $("#apply-change-image_install").removeAttr("disabled");
+ }
+ });
+
+ $('#apply-change-image_install').click(function(){
+ var name = $('#new-image_install').val();
+ postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL_append:'+name});
+ $('#image_install').html(name);
+ $('#image_install').parent().removeClass('muted');
+ $("#change-image_install-form").slideUp(function () {
+ $('#image_install, #change-image_install-icon').show();
+ if (name.length > -1) {
+ $('#delete-image_install-icon').show();
+ }
+ });
+ });
+
+ // delete IMAGE_INSTALL_append variable value
+ $('#delete-image_install-icon').click(function(){
+ $(this).tooltip('hide');
+ postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL_append:'+''});
+ $('#image_install').parent().fadeOut(1000, function(){
+ $('#image_install').parent().addClass('muted');
+ $('#image_install').html('Not set');
+ $('#delete-image_install-icon').hide();
+ $('#image_install').parent().fadeIn(1000);
+ });
+ });
+
+
+ // change PACKAGE_CLASSES variable
+ $('#change-package_classes-icon').click(function() {
+ $('#change-package_classes-icon, #package_classes').hide();
+ $("#change-package_classes-form").slideDown();
+
+ // initialize the pulldown and checkboxes
+ var value = document.getElementById("package_classes").innerHTML;
+ if (0 == value.indexOf("package_dev")) {
+ $('select').selectedIndex = 0;
+ updatePackageClassCheckboxes();
+ if (0 < value.indexOf("package_ipk")) {document.getElementById("package_class_1_input").checked = true};
+ if (0 < value.indexOf("package_rpm")) {document.getElementById("package_class_2_input").checked = true};
+ }
+ if (0 == value.indexOf("package_ipk")) {
+ $('select').selectedIndex = 1;
+ updatePackageClassCheckboxes();
+ if (0 < value.indexOf("package_dev")) {document.getElementById("package_class_1_input").checked = true;};
+ if (0 < value.indexOf("package_rpm")) {document.getElementById("package_class_2_input").checked = true;};
+ }
+ if (0 == value.indexOf("package_rpm")) {
+ $('select').selectedIndex = 2;
+ updatePackageClassCheckboxes();
+ if (0 < value.indexOf("package_dev")) {document.getElementById("#package_class_1_input").checked = true;};
+ if (0 < value.indexOf("package_ipk")) {document.getElementById("#package_class_2_input").checked = true;};
+ }
+ });
+
+ $('#cancel-change-package_classes').click(function(){
+ $("#change-package_classes-form").slideUp(function() {
+ $('#package_classes, #change-package_classes-icon').show();
+ });
+ });
+
+ $('select').change(function() {
+ updatePackageClassCheckboxes();
+ });
+
+ $('#apply-change-package_classes').click(function(){
+ var e = document.getElementById("package_classes-select");
+ var val = e.options[e.selectedIndex].text;
+
+ pc1_checked = document.getElementById("package_class_1_input").checked;
+ pc2_checked = document.getElementById("package_class_2_input").checked;
+ if (val == "package_dev") {
+ if (pc1_checked) val = val + " package_ipk";
+ if (pc2_checked) val = val + " package_rpm";
+ }
+ if (val == "package_ipk") {
+ if (pc1_checked) val = val + " package_dev";
+ if (pc2_checked) val = val + " package_rpm";
+ }
+ if (val == "package_rpm") {
+ if (pc1_checked) val = val + " package_dev";
+ if (pc2_checked) val = val + " package_ipk";
+ }
+
+ $('#package_classes').html(val);
+ //$('#package_classes').parent().removeClass('muted');
+ postEditAjaxRequest({"configvarChange" : 'PACKAGE_CLASSES:'+val});
+ $("#change-package_classes-form").slideUp(function() {
+ $('#package_classes, #change-package_classes-icon').show();
+ });
+ });
+
+
+ // change SDKMACHINE variable
+ $('#change-sdkmachine-icon').click(function() {
+ var current_value = document.getElementById("sdkmachine").innerHTML;
+ var radios = document.getElementsByName('sdkmachine');
+ for (var i = 0, length = radios.length; i < length; i++) {
+ radios[i].checked = false;
+ if (radios[i].value == current_value) {
+ radios[i].checked = true;
+ }
+ }
+ $('#change-sdkmachine-icon, #sdkmachine').hide();
+ $("#change-sdkmachine-form").slideDown();
+ });
+
+ $('#cancel-change-sdkmachine').click(function(){
+ $("#change-sdkmachine-form").slideUp(function() {
+ $('#sdkmachine, #change-sdkmachine-icon').show();
+ });
+ });
+
+ $('#apply-change-sdkmachine').click(function(){
+ var value="";
+ var radios = document.getElementsByName('sdkmachine');
+ for (var i = 0, length = radios.length; i < length; i++) {
+ if (radios[i].checked) {
+ // do whatever you want with the checked radio
+ value=radios[i].value;
+ break;
+ }
+ }
+ postEditAjaxRequest({"configvarChange" : 'SDKMACHINE:'+value});
+ $('#sdkmachine').html(value);
+ $("#change-sdkmachine-form").slideUp(function() {
+ $('#sdkmachine, #change-sdkmachine-icon').show();
+ });
+
+ });
+
+
+ // add new variable
+ $("button#add-configvar-button").click( function (evt) {
+ var variable = $("input#variable")[0].value;
+ var value = $("input#value")[0].value;
+
+ if (validate_new_variable_name()) {
+ postEditAjaxRequest({"configvarAdd" : variable+':'+value});
+
+ // clear the previous values
+ $("input#variable")[0].value = "";
+ $("input#value")[0].value = "";
+
+ }
+ });
+
+ // validate new variable name
+ $("input#variable").focusout( function (evt) {
+ validate_new_variable_name();
+ });
+
+ //activate / deactivate save added variable button
+ $("#variable, #value").keyup(function() {
+ if ( $("#variable").val().length > 0 && $("#value").val().trim().length > 0 ) {
+ $(".save").removeAttr("disabled");
+ }
+ else {
+ $(".save").attr("disabled","disabled");
+ }
+ });
+
+ //
+ // draw and register the dynamic configuration variables and handlers
+ //
+
+ var data = {
+ configvars : []
+ };
+ {% for c in configvars %}
+ data.configvars.push([ "{{c.name}}","{{c.value}}","{{c.pk}}" ]);
+ {% if '' != vars_context|get_dict_value:c.name %}
+ data.vars_context[ "{{c.name}}" ] = "{{vars_context|get_dict_value:c.name }}";
+ {% endif %}
+ {% endfor %}
+
+ // draw these elements and assert their event handlers
+ onEditPageUpdate(data);
+ });
+
+ </script>
{% 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',
url(r'^xhr_projectbuild/(?P<pid>\d+)/$', 'xhr_projectbuild', name='xhr_projectbuild'),
url(r'^xhr_projectinfo/$', 'xhr_projectinfo', name='xhr_projectinfo'),
url(r'^xhr_projectedit/(?P<pid>\d+)/$', 'xhr_projectedit', name='xhr_projectedit'),
+ url(r'^xhr_configvaredit/(?P<pid>\d+)/$', 'xhr_configvaredit', name='xhr_configvaredit'),
url(r'^xhr_datatypeahead/$', 'xhr_datatypeahead', name='xhr_datatypeahead'),
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:
return HttpResponse(jsonfilter({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json")
+ def xhr_configvaredit(request, pid):
+ try:
+ prj = Project.objects.get(id = pid)
+ # add conf variables
+ if 'configvarAdd' in request.POST:
+ t=request.POST['configvarAdd'].strip()
+ if ":" in t:
+ variable, value = t.split(":")
+ else:
+ variable = t
+ value = ""
+
+ pt, created = ProjectVariable.objects.get_or_create(project = prj, name = variable, value = value)
+ # change conf variables
+ if 'configvarChange' in request.POST:
+ t=request.POST['configvarChange'].strip()
+ if ":" in t:
+ variable, value = t.split(":")
+ else:
+ variable = t
+ value = ""
+
+ try:
+ pt = ProjectVariable.objects.get(project = prj, name = variable)
+ pt.value=value
+ pt.save()
+ except ObjectDoesNotExist:
+ print("the entry doesn't exist.")
+ # remove conf variables
+ if 'configvarDel' in request.POST:
+ t=request.POST['configvarDel'].strip()
+ pt = ProjectVariable.objects.get(pk = int(t)).delete()
+
+ # return all project settings
+ vars_managed,vars_fstypes,vars_blacklist = get_project_configvars_context()
+ return HttpResponse(json.dumps( {
+ "error": "ok",
+ 'configvars' : map(lambda x: (x.name, x.value, x.pk), ProjectVariable.objects.filter(project_id = pid).all()),
+ 'distro' : ProjectVariable.objects.get(project = prj, name = "DISTRO").value,
+ 'fstypes' : ProjectVariable.objects.get(project = prj, name = "IMAGE_FSTYPES").value,
+ 'image_install_append': ProjectVariable.objects.get(project = prj, name = "IMAGE_INSTALL_append").value,
+ 'package_classes': ProjectVariable.objects.get(project = prj, name = "PACKAGE_CLASSES").value,
+ 'sdk_machine' : ProjectVariable.objects.get(project = prj, name = "SDKMACHINE").value,
+ }), content_type = "application/json")
+
+ except Exception as e:
+ return HttpResponse(json.dumps({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json")
+
+
def xhr_importlayer(request):
if (not request.POST.has_key('vcs_url') or
not request.POST.has_key('name') or
@@ -2737,11 +2786,66 @@ if toastermain.settings.MANAGED:
return render(request, template, context)
+
+ def get_project_configvars_context():
+ # Vars managed outside of this view
+ vars_managed = {
+ 'MACHINE'
+ }
+
+ vars_blacklist = {
+ 'DL_DR','PARALLEL_MAKE','BB_NUMBER_THREADS','SSTATE_DIR',
+ 'BB_DISKMON_DIRS','BB_NUMBER_THREADS','CVS_PROXY_HOST','CVS_PROXY_PORT',
+ 'DL_DIR','PARALLEL_MAKE','SSTATE_DIR','SSTATE_DIR','SSTATE_MIRRORS','TMPDIR',
+ 'all_proxy','ftp_proxy','http_proxy ','https_proxy'
+ }
+
+ vars_fstypes = {
+ 'btrfs','cpio','cpio.gz','cpio.lz4','cpio.lzma','cpio.xz','cramfs',
+ 'elf','ext2','ext2.bz2','ext2.gz','ext2.lzma' 'ext3','ext3.gz','hddimg',
+ 'iso','jffs2','jffs2.sum','squashfs','squashfs-lzo','squashfs-xz','tar.bz2',
+ 'tar.lz4','tar.xz','tartar.gz','ubi','ubifs','vmdk'
+ }
+
+ return(vars_managed,sorted(vars_fstypes),vars_blacklist)
+
def projectconf(request, pid):
template = "projectconf.html"
+
+ try:
+ prj = Project.objects.get(id = pid)
+ except Project.DoesNotExist:
+ return HttpResponseNotFound("<h1>Project id " + pid + " is unavailable</h1>")
+
+ vars_managed,vars_fstypes,vars_blacklist = get_project_configvars_context()
context = {
- 'configvars': ProjectVariable.objects.filter(project_id = pid),
+ 'configvars': ProjectVariable.objects.filter(project_id = pid).all(),
+ 'vars_managed': vars_managed,
+ 'vars_fstypes': vars_fstypes,
+ 'vars_blacklist': vars_blacklist,
}
+
+ try:
+ context['distro'] = ProjectVariable.objects.get(project = prj, name = "DISTRO").value
+ except ProjectVariable.DoesNotExist:
+ pass
+ try:
+ context['fstypes'] = ProjectVariable.objects.get(project = prj, name = "IMAGE_FSTYPES").value
+ except ProjectVariable.DoesNotExist:
+ pass
+ try:
+ context['image_install_append'] = ProjectVariable.objects.get(project = prj, name = "IMAGE_INSTALL_append").value
+ except ProjectVariable.DoesNotExist:
+ pass
+ try:
+ context['package_classes'] = ProjectVariable.objects.get(project = prj, name = "PACKAGE_CLASSES").value
+ except ProjectVariable.DoesNotExist:
+ pass
+ try:
+ context['sdk_machine'] = ProjectVariable.objects.get(project = prj, name = "SDKMACHINE").value
+ except ProjectVariable.DoesNotExist:
+ pass
+
return render(request, template, context)
def projectbuilds(request, pid):