[Kimchi-devel] [PATCH v2] [Kimchi] Issue# 979 - Change boot order UI

bianca at linux.vnet.ibm.com bianca at linux.vnet.ibm.com
Mon Dec 26 18:15:42 UTC 2016


From: Socorro <socorro at 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 at 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  | 68 ++++++++++++++++++++++++++++++++++--
 ui/pages/guest-edit.html.tmpl        | 18 ++++++++--
 4 files changed, 191 insertions(+), 4 deletions(-)

diff --git a/ui/css/kimchi.css b/ui/css/kimchi.css
index fff3279..ae5e37b 100644
--- a/ui/css/kimchi.css
+++ b/ui/css/kimchi.css
@@ -1557,6 +1557,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 25d4d65..ea3ee9d 100644
--- a/ui/css/src/modules/_edit-guests.scss
+++ b/ui/css/src/modules/_edit-guests.scss
@@ -429,3 +429,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 bb82077..12c0770 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -26,6 +26,7 @@ kimchi.guest_edit_main = function() {
     var networkOptions = "";
 
     clearTimeout(kimchi.vmTimeout);
+    var bootOrderOptions = [];
 
     $('#modalWindow').on('hidden.bs.modal', function() {
         kimchi.setListVMAutoTimeout();
@@ -45,11 +46,12 @@ 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, "processor": 6, "bootOrder": 7
         var submit_map = {
             0: generalSubmit,
             3: permissionSubmit,
-            6: processorSubmit
+            6: processorSubmit,
+            7: bootOrderSubmit
         };
         var currentTab = $('#guest-edit-window li.active a[data-toggle="tab"]').data('id');
         var toSubmit = parseInt($('#'+currentTab).index());
@@ -967,6 +969,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['icon'] = guest['icon'] || 'plugins/kimchi/images/icon-vm.png';
         $('#form-guest-edit-general').fillWithObject(guest);
@@ -1032,6 +1070,7 @@ kimchi.guest_edit_main = function() {
         setupPermission();
         setupPCIDevice();
         setupSnapshot();
+        setupBootOrder(guest);
 
         kimchi.init_processor_tab(guest.cpu_info, $(saveButton));
         if ((kimchi.thisVMState === "running") || (kimchi.thisVMState === "paused")) {
@@ -1221,4 +1260,29 @@ kimchi.guest_edit_main = function() {
     if(kimchi.hostarch === s390xArch){
         $('#guest-edit-window ul li a[data-id="form-guest-edit-pci"],a[data-id="form-guest-edit-snapshot"]').parent().hide();
     }
+
+    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 d8a482c..5424250 100644
--- a/ui/pages/guest-edit.html.tmpl
+++ b/ui/pages/guest-edit.html.tmpl
@@ -30,7 +30,7 @@
     </div>
     <div class="modal-body">
     <span id="alert-modal-container"></span>
-<ul class="nav nav-tabs" role="tablist">
+  <ul class="nav nav-tabs" role="tablist">
     <li role="presentation" class="active"><a href="#form-guest-edit-general" aria-controls="form-guest-edit-general" role="tab" data-id="form-guest-edit-general" data-toggle="tab">$_("General")</a></li>
     <li role="presentation"><a href="#form-guest-edit-storage" aria-controls="form-guest-edit-storage" role="tab" data-id="form-guest-edit-storage" data-toggle="tab">$_("Storage")</a></li>
     <li role="presentation"><a href="#form-guest-edit-interface" aria-controls="form-guest-edit-interface" role="tab" data-id="form-guest-edit-interface" data-toggle="tab">$_("Interface")</a></li>
@@ -38,6 +38,7 @@
     <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-edit-processor" aria-controls="form-edit-processor" role="tab" data-id="form-edit-processor" data-toggle="tab">$_("Processor")</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">
@@ -197,7 +198,6 @@
                             $_("Current CPU must be equal or lower than the Maximum CPU value. If a topology is set, it must be also be a multiple of the 'threads' value.")
                         </p>
                     </div>
-
                     <div id="guest-max-processor-panel" class="form-group">
                         <label for="guest-edit-max-processor-textbox">$_("Max CPU")</label>
                         <p id="settings-readonly-help" class="hidden">$_("Unable to edit maximum CPU or CPU topology when editing a running or paused virtual machine.")</p>
@@ -231,6 +231,20 @@
                     </div>
                 </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>
+                      </p>
+                    </div>
+                </div>
+            </form>
         </div>
     </div>
     <div class="modal-footer">
-- 
2.9.3



More information about the Kimchi-devel mailing list