This patch fails in my test. I can see the boot order while editting a vm, but can edit the order itself.


On 09/13/2016 06:22 PM, Socorro Stoppler wrote:
From: Socorro <socorro@linux.vnet.ibm.com>

This patch adds the UI portion for supporting changing the guest boot order
via edit guest panel.  This was based off of what Samuel had prototyped.

Issue found in backend during test:
When updating the VM even with just changing the name, the bootorder gets reset to 'hd' only.
I tested this using the curl command and confirmed that indeed it does get reset to one entry only.
Issue written to address this:  https://github.com/kimchi-project/kimchi/issues/1012

Signed-off-by: Socorro <socorro@linux.vnet.ibm.com>
---
 ui/css/kimchi.css                    | 55 +++++++++++++++++++++++++++++
 ui/css/src/modules/_edit-guests.scss | 54 +++++++++++++++++++++++++++++
 ui/js/src/kimchi.guest_edit_main.js  | 67 ++++++++++++++++++++++++++++++++++--
 ui/pages/guest-edit.html.tmpl        | 14 ++++++++
 4 files changed, 188 insertions(+), 2 deletions(-)

diff --git a/ui/css/kimchi.css b/ui/css/kimchi.css
index 6cf2cc9..1804226 100644
--- a/ui/css/kimchi.css
+++ b/ui/css/kimchi.css
@@ -1436,6 +1436,61 @@ body.wok-gallery {
   overflow: visible;
 }

+ul {
+  cursor: default;
+}
+
+.boot-order {
+  display: block;
+  width: 85%;
+  font-size: 14px;
+  line-height: 1.42857;
+  color: #444;
+  overflow: hidden;
+  background-color: #fff;
+  background-image: none;
+  border: 1px solid #ccc;
+  border-radius: 3px;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+}
+
+.boot-order:focus,
+.boot-order.focus {
+  border-color: #66afe9;
+  outline: 0;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
+}
+
+.boot-order > li {
+  cursor: move;
+  /* fallback if grab cursor is unsupported */
+  cursor: grab;
+  cursor: -moz-grab;
+  cursor: -webkit-grab;
+  border-left: 0;
+  border-right: 0;
+}
+
+.boot-order > li:first-child {
+  border-top: 0;
+}
+
+.boot-order > li:last-child {
+  border-bottom: 0;
+}
+
+.boot-order > li.ui-sortable-helper {
+  cursor: grabbing;
+  cursor: -moz-grabbing;
+  cursor: -webkit-grabbing;
+  border: 1px solid #ccc !important;
+}
+
 /* Add Template Modal Window */
 .templates-modal .modal-dialog {
   width: 1100px;
diff --git a/ui/css/src/modules/_edit-guests.scss b/ui/css/src/modules/_edit-guests.scss
index b7e6941..3c55139 100644
--- a/ui/css/src/modules/_edit-guests.scss
+++ b/ui/css/src/modules/_edit-guests.scss
@@ -385,3 +385,57 @@
 #form-guest-storage-add .form-section .field {
     overflow: visible;
 }
+
+ul {
+  cursor: default;
+}
+
+.boot-order {
+  display: block;
+  width: 85%;
+  font-size: 14px;
+  line-height: 1.42857;
+  color: #444;
+  overflow: hidden;
+  background-color: #fff;
+  background-image: none;
+  border: 1px solid #ccc;
+  border-radius: 3px;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+}
+
+.boot-order:focus,
+.boot-order.focus {
+  border-color: #66afe9;
+  outline: 0;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
+}
+
+.boot-order > li {
+  cursor: move; /* fallback if grab cursor is unsupported */
+  cursor: grab;
+  cursor: -moz-grab;
+  cursor: -webkit-grab;
+  border-left: 0;
+  border-right: 0;
+}
+
+.boot-order > li:first-child {
+  border-top: 0;
+}
+
+.boot-order > li:last-child {
+  border-bottom: 0;
+}
+
+.boot-order > li.ui-sortable-helper {
+  cursor: grabbing;
+  cursor: -moz-grabbing;
+  cursor: -webkit-grabbing;
+  border: 1px solid #ccc !important;
+}
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
index dcaafb8..4487dc5 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -21,6 +21,7 @@ kimchi.guest_edit_main = function() {
     var guestEditForm = $('#form-guest-edit-general');
     var saveButton = $('#guest-edit-button-save');
     clearTimeout(kimchi.vmTimeout);
+    var bootOrderOptions = [];

     $('#modalWindow').on('hidden.bs.modal', function() {
         kimchi.setListVMAutoTimeout();
@@ -40,10 +41,11 @@ kimchi.guest_edit_main = function() {

     var submitForm = function(event) {

-        // tap map, "general": 0, "storage": 1, "interface": 2, "permission": 3, "password": 4
+        // tap map, "general": 0, "storage": 1, "interface": 2, "permission": 3, "pci": 4, "snapshot": 5, "bootOrder": 6
         var submit_map = {
             0: generalSubmit,
-            3: permissionSubmit
+            3: permissionSubmit,
+            6: bootOrderSubmit
         };
         var currentTab = $('#guest-edit-window li.active a[data-toggle="tab"]').data('id');
         var toSubmit = parseInt($('#'+currentTab).index());
@@ -729,6 +731,42 @@ kimchi.guest_edit_main = function() {
         }
     };

+    var setupBootOrder = function(guest) {
+        var guestBootOrder = guest['bootorder'];
+        $("#myList").empty();
+        $.each(guestBootOrder, function(index, value) {
+           var itemNode = $.parseHTML("<li class='list-group-item' " + "data-value=" + value + ">" + value + "</li>");
+           $("#myList").append(itemNode);
+        });
+
+        $('.boot-order').sortable({
+            items: 'li',
+            cursor: 'move',
+            opacity: 0.6,
+            containment: "parent",
+            start: function(event, ui) {
+                $(this).addClass('focus');
+            },
+            stop: function(event, ui) {
+                $(this).removeClass('focus');
+            },
+            change: function(event, ui) {
+                // callback once started changing order
+            },
+            update: function(event, ui) {
+                // callback once finished order
+                $(saveButton).prop('disabled', false);
+                bootOrderOptions = [];
+                $("#myList li").each(function() {
+                    bootOrderOptions.push($(this).text())
+                });
+                bootOrderOptions.forEach(function(entry) {
+                    console.log(entry);
+                });
+            }
+        });
+    };
+
     var initContent = function(guest) {
         guest['vcpus'] = guest.cpu_info['vcpus'];
         guest['max-processor'] = guest.cpu_info['maxvcpus'];
@@ -791,6 +829,7 @@ kimchi.guest_edit_main = function() {
         setupPermission();
         setupPCIDevice();
         setupSnapshot();
+        setupBootOrder(guest);

         wok.topic('kimchi/vmCDROMAttached').subscribe(onAttached);
         wok.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
@@ -956,4 +995,28 @@ kimchi.guest_edit_main = function() {
             }
         }
     };
+   
+    var bootOrderSubmit = function(event) {
+        //Format the strings to go in the array before passing in to the API
+        //"hd", "network", "cdrom"
+        var formattedBootOrderOptions = [];
+        for (var i=0; i<bootOrderOptions.length; i++) {
+            var str = bootOrderOptions[i].trim();
+            str = str.toLowerCase();
+            if (str === "hdd") {
+                str = "hd";
+            } else if (str === "cd-rom") {
+                str = "cdrom";
+            }
+            formattedBootOrderOptions.push(str);
+        }
+        var data = {
+            bootorder: formattedBootOrderOptions
+        };
+        kimchi.updateVM(kimchi.selectedGuest, data, function() {
+            wok.window.close();
+        }, function(err) {
+            wok.message.error(err.responseJSON.reason,'#alert-modal-container');
+        });
+    };
 };
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl
index a9a468e..fd05293 100644
--- a/ui/pages/guest-edit.html.tmpl
+++ b/ui/pages/guest-edit.html.tmpl
@@ -37,6 +37,7 @@
     <li role="presentation"><a href="#form-guest-edit-permission" aria-controls="form-guest-edit-permission" role="tab" data-id="form-guest-edit-permission" data-toggle="tab">Permission</a></li>
     <li role="presentation"><a href="#form-guest-edit-pci" aria-controls="form-guest-edit-pci" role="form-guest-edit-pci" data-id="form-guest-edit-pci" data-toggle="tab">Pci</a></li>
     <li role="presentation"><a href="#form-guest-edit-snapshot" aria-controls="form-guest-edit-snapshot" role="tab" data-id="form-guest-edit-snapshot" data-toggle="tab">Snapshot</a></li>
+    <li role="presentation"><a href="#form-guest-edit-boot-order" aria-controls="form-guest-edit-boot-order" role="tab" data-id="form-guest-edit-boot-order" data-toggle="tab">Boot Order</a></li>
   </ul>
         <div class="tab-content" id="guest-edit-tabs">
             <form role="tabpanel" class="tab-pane active" id="form-guest-edit-general">
@@ -182,6 +183,19 @@
                 <div class="task"></div>
                 <div class="body"></div>
             </form>
+            <form role="tabpanel" class="tab-pane" id="form-guest-edit-boot-order">
+                <div class="form-group">
+                    <div id="bootOrder">
+                        <ul id="myList" class="list-group boot-order">
+                            <li class="list-group-item" data-value="CD-ROM">CD-ROM</li>
+                            <li class="list-group-item" data-value="HDD">HDD</li>
+                            <li class="list-group-item" data-value="Network">Network</li>
+                        </ul>
+                        <p class="help-block">
+                            <i class="fa fa-info-circle"></i> $_("Change the boot order by dragging the items on the list.")</p>
+                    </div>
+                </div>
+            </form>
         </div>
     </div>
     <div class="modal-footer">

-- 

Ramon Nunes Medeiros
Kimchi Developer
Linux Technology Center Brazil
IBM Systems & Technology Group
Phone : +55 19 2132 7878
ramonn@br.ibm.com