[Kimchi-devel] [V2] UI: List iSCSI Servers & Targets

huoyuxin at linux.vnet.ibm.com huoyuxin at linux.vnet.ibm.com
Thu Aug 28 10:24:28 UTC 2014


From: Yu Xin Huo <huoyuxin at linux.vnet.ibm.com>

Signed-off-by: Yu Xin Huo <huoyuxin at linux.vnet.ibm.com>
---
 ui/css/theme-default/storage.css         |   69 +++++++++++++++++++++-
 ui/js/src/kimchi.api.js                  |   30 ++++++++++
 ui/js/src/kimchi.storagepool_add_main.js |   94 ++++++++++++++++++++++++++++++
 ui/pages/storagepool-add.html.tmpl       |   12 +++-
 4 files changed, 201 insertions(+), 4 deletions(-)

diff --git a/ui/css/theme-default/storage.css b/ui/css/theme-default/storage.css
index 4f439e8..1b71d82 100644
--- a/ui/css/theme-default/storage.css
+++ b/ui/css/theme-default/storage.css
@@ -315,7 +315,7 @@
 }
 
 .hide-content {
-    display: none;
+    display: none!important;
 }
 
 .volumeslist {
@@ -593,3 +593,70 @@
                 center no-repeat;
     padding: 0 20px 0 26px;
 }
+
+.storage-admin .filter-select {
+    display: inline-block;
+    position: relative;
+}
+
+#iscsiportId, .storage-admin .filter-select input {
+    border: 1px solid #CCCCCC;
+    border-radius: 1px;
+    font-size: 14px;
+    padding: 3px 3px 3px 10px;
+    height: 30px;
+}
+
+.storage-admin .filter-select input::-ms-clear {
+    display: none;
+}
+
+.storage-admin .filter-select .arrow {
+    display: inline-block;
+    vertical-align: middle;
+    position: relative;
+    left: -25px;
+}
+
+.storage-admin .filter-select .option {
+    border-style: solid;
+    border-color: #CCCCCC;
+    border-width: 0px 1px 1px 1px;
+    border-radius: 1px;
+    font-size: 14px;
+    background-color: white;
+    max-height: 140px;
+    overflow: auto;
+    color: #666666;
+    position: absolute;
+    z-index: 1000;
+}
+
+.storage-admin .filter-select .option .item {
+    padding: 5px 10px;
+    cursor: pointer;
+}
+
+.storage-admin .filter-select .option .item:hover {
+    background-color: #DDDDDD;
+}
+
+#iSCSIServer input {
+    width: 410px;
+}
+
+#iSCSIServer .option {
+    width: 423px;
+}
+
+#iscsiportId {
+    width: 60px;
+}
+
+#iSCSITarget input {
+    width: 493px;
+}
+
+#iSCSITarget .option {
+    width: 506px;
+}
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index 4562992..9de1b08 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -1098,5 +1098,35 @@ var kimchi = {
                 kimchi.message.error(data.responseJSON.reason);
             }
         });
+    },
+
+    getISCSIServers : function(suc, err) {
+        kimchi.requestJSON({
+            url : kimchi.url + 'storageservers?_target_type=iscsi',
+            type : 'GET',
+            contentType : 'application/json',
+            dataType : 'json',
+            resend : true,
+            success : suc,
+            error : err ? err : function(data) {
+                kimchi.message.error(data.responseJSON.reason);
+            }
+        });
+    },
+
+    getISCSITargets : function(server, port, suc, err) {
+        server = encodeURIComponent(server);
+        port = encodeURIComponent(port);
+        kimchi.requestJSON({
+            url : kimchi.url + 'storageservers/'+server+'/storagetargets?_target_type=iscsi&_server_port='+port,
+            type : 'GET',
+            contentType : 'application/json',
+            dataType : 'json',
+            resend : true,
+            success : suc,
+            error : err ? err : function(data) {
+                kimchi.message.error(data.responseJSON.reason);
+            }
+        });
     }
 };
diff --git a/ui/js/src/kimchi.storagepool_add_main.js b/ui/js/src/kimchi.storagepool_add_main.js
index ecbc682..affb714 100644
--- a/ui/js/src/kimchi.storagepool_add_main.js
+++ b/ui/js/src/kimchi.storagepool_add_main.js
@@ -34,6 +34,96 @@ kimchi.storagepool_add_main = function() {
     });
 };
 
+kimchi.storageFilterSelect = function(id, isUpdate) {
+    var input = $('input', '#'+id);
+    var options = $(".option", '#'+id);
+    $('.arrow', '#'+id).toggleClass("hide-content", options.children().length==0);
+    var filter = function(container, key){
+        container.children().each(function(){
+            $(this).css("display", $(this).text().indexOf(key)==-1 ? "none" : "");
+        });
+    };
+    if(!isUpdate){
+        $('.arrow', '#'+id).click(function(){
+            options.toggleClass("hide-content");
+        });
+        input.focus(function(){
+            options.removeClass("hide-content");
+        }).on("keyup", function(){
+            filter(options, input.val());
+        });
+    }
+    options.children().each(function(){
+        $(this).click(function(){
+            input.val($(this).text());
+            $('.option', '#'+id).addClass("hide-content");
+            filter(options, "");
+        });
+    });
+};
+
+kimchi.setupISCSI = function(){
+    var loadTargets = function(server, port, callback){
+        var isUpdate = $(".option", "#iSCSITarget").children().length > 0;
+        $(".option", "#iSCSITarget").empty();
+        $('input', "#iSCSITarget").attr("placeholder", "loading targets...");
+        kimchi.getISCSITargets(server, port, function(data){
+            if(data.length==0){
+                $('input', "#iSCSITarget").attr("placeholder", "no targets is got, please input one.");
+            }else{
+                for(var i=0; i<data.length; i++){
+                    var itemNode = $.parseHTML("<div class='item'>"+data[i].target+"</div>");
+                    $(".option", "#iSCSITarget").append(itemNode);
+                }
+                $('input', "#iSCSITarget").attr("placeholder", "");
+            }
+            kimchi.storageFilterSelect('iSCSITarget', isUpdate);
+            $('input', "#iSCSITarget").trigger("focus");
+            callback();
+        }, function(data){
+            $('input', "#iSCSITarget").attr("placeholder","failed to load targets.");
+            callback();
+            kimchi.message.error(data.responseJSON.reason);
+        });
+    };
+    var triggerLoadTarget = function(){
+        $('input', "#iSCSITarget").val("");
+        var server = $("#iscsiserverId").val().trim();
+        var port = $("#iscsiportId").val().trim();
+        if(server!="" && port!="" && !$("#iscsiserverId").hasClass("invalid-field") && !$("#iscsiportId").hasClass("invalid-field")){
+            $("#iscsiserverId").attr("disabled", true);
+            $("#iscsiportId").attr("disabled", true);
+            $('.arrow', '#iSCSIServer').addClass("hide-content");
+            loadTargets(server, port, function(){
+                $("#iscsiserverId").attr("disabled", false);
+                $("#iscsiportId").attr("disabled", false);
+                $('.arrow', '#iSCSIServer').removeClass("hide-content");
+            });
+        }
+    };
+    $("#iscsiserverId").change(function(){
+        triggerLoadTarget();
+    });
+    $("#iscsiportId").change(function(){
+        triggerLoadTarget();
+    });
+    var initISCSIServers = function(){
+        kimchi.getISCSIServers(function(data){
+            for(var i=0;i<data.length;i++){
+                var itemNode = $.parseHTML("<div class='item'>"+data[i].host+"</div>");
+                $(".option", "#iSCSIServer").append(itemNode);
+                $(itemNode).click(function(){
+                    $("#iscsiportId").val($(this).prop("port"));
+                    $("#iscsiserverId").val($(this).text());
+                    triggerLoadTarget();
+                }).prop("port", data[i].port);
+            }
+            kimchi.storageFilterSelect('iSCSIServer', false);
+         });
+    };
+    initISCSIServers();
+};
+
 kimchi.initStorageAddPage = function() {
     kimchi.listHostPartitions(function(data) {
         if (data.length > 0) {
@@ -160,6 +250,10 @@ kimchi.initStorageAddPage = function() {
     $('#iscsiportId').keyup(function(event) {
         $(this).toggleClass("invalid-field",!/^[0-9]+$/.test($(this).val()));
     });
+    $('#iscsiserverId').keyup(function(event) {
+        $(this).toggleClass("invalid-field",!kimchi.isServer($(this).val().trim()));
+    });
+    kimchi.setupISCSI();
 };
 
 /* Returns 'true' if all form fields were filled, 'false' if
diff --git a/ui/pages/storagepool-add.html.tmpl b/ui/pages/storagepool-add.html.tmpl
index 1eb2029..6b526a7 100644
--- a/ui/pages/storagepool-add.html.tmpl
+++ b/ui/pages/storagepool-add.html.tmpl
@@ -23,7 +23,7 @@
 <!DOCTYPE html>
 <html>
 <body>
-    <div class="window storage-window">
+    <div class="window storage-window storage-admin">
         <header>
             <h1 class="title">$_("Define a New Storage Pool")</h1>
             <div class="close">X</div>
@@ -111,7 +111,10 @@
                         <div class="field">
                             <p class="text-help">
                                 $_("iSCSI server IP or hostname. It should not be empty.")</p>
-                            <input id="iscsiserverId" placeholder="$_("Server")" type="text" class="text storage-base-input-width">
+                            <span class="filter-select" id="iSCSIServer">
+                            <div><input id="iscsiserverId" type="text" placeholder="$_("Server")"><a class="ui-icon ui-icon-triangle-1-s arrow hide-content"></a></div>
+                            <div class="option hide-content"></div>
+                            </span>
                             <input id="iscsiportId" placeholder="$_("Port")" type="text" class="text storage-port-width" maxlength="4">
                         </div>
                     </section>
@@ -119,7 +122,10 @@
                         <h2>4. $_("Target")</h2>
                         <div class="field">
                             <p class="text-help">$_("The iSCSI target on iSCSI server")</p>
-                            <input id="iscsiTargetId" type="text" class="text storage-base-input-width">
+                            <span class="filter-select" id="iSCSITarget">
+                            <div><input id="iscsiTargetId" type="text"><a class="ui-icon ui-icon-triangle-1-s arrow hide-content"></a></div>
+                            <div class="option hide-content"></div>
+                            </span>
                         </div>
                     </section>
                     <section class="form-section">
-- 
1.7.1




More information about the Kimchi-devel mailing list