[Kimchi-devel] [PATCH] [Wok] Sysmodules (SRIOV) tab initial implementation

André Luiz Teodoro andreteodoro.work at gmail.com
Thu Jan 14 12:33:49 UTC 2016


Please disregard this patch, it must be sent to Ginger list.

Tks

André Teodoro

On Thu, Jan 14, 2016 at 10:22 AM, <andreteodoro.work at gmail.com> wrote:

> From: Andre Teodoro <andreteodoro.work at gmail.com>
>
> Signed-off-by: Andre Teodoro <andreteodoro.work at gmail.com>
> ---
>  ui/config/tab-ext.xml                   |  23 +-
>  ui/css/ginger.css                       | 209 +++++++-
>  ui/css/src/ginger.scss                  |  70 ++-
>  ui/css/src/modules/_sysmodules.scss     | 126 +++++
>  ui/js/host-sysmodules.js                |  76 +++
>  ui/js/util.js                           | 871
> ++++++++++++++++----------------
>  ui/pages/tabs/host-sysmodules.html.tmpl |  88 ++++
>  7 files changed, 1012 insertions(+), 451 deletions(-)
>  create mode 100644 ui/css/src/modules/_sysmodules.scss
>  create mode 100644 ui/js/host-sysmodules.js
>  create mode 100644 ui/pages/tabs/host-sysmodules.html.tmpl
>
> diff --git a/ui/config/tab-ext.xml b/ui/config/tab-ext.xml
> index 2247666..f3efc95 100644
> --- a/ui/config/tab-ext.xml
> +++ b/ui/config/tab-ext.xml
> @@ -1,5 +1,5 @@
>  <?xml version="1.0" encoding="utf-8"?>
> -<!--
> +    <!--
>  Copyright IBM Corp, 2015
>
>  This library is free software; you can redistribute it and/or
> @@ -19,22 +19,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor,
> Boston, MA  02110-1301  USA
>  <tabs-ext>
>      <functionality>Host</functionality>
>      <tab>
> -        <access role="admin" mode="admin"/>
> -        <access role="user" mode="none"/>
> +        <access role="admin" mode="admin" />
> +        <access role="user" mode="none" />
>          <title>Administration</title>
>          <path>plugins/ginger/tabs/host-admin.html</path>
>      </tab>
>      <tab>
> -        <access role="admin" mode="admin"/>
> -        <access role="user" mode="none"/>
> +        <access role="admin" mode="admin" />
> +        <access role="user" mode="none" />
>          <title>Network</title>
>          <path>plugins/ginger/tabs/host-network.html</path>
>      </tab>
>      <tab>
> -        <access role="admin" mode="admin"/>
> -        <access role="user" mode="none"/>
> -
> +        <access role="admin" mode="admin" />
> +        <access role="user" mode="none" />
>          <title>Storage</title>
>          <path>plugins/ginger/tabs/host-storage.html</path>
>      </tab>
> -</tabs-ext>
> +    <tab>
> +        <access role="admin" mode="admin" />
> +        <access role="user" mode="none" />
> +        <title>System Modules</title>
> +        <path>plugins/ginger/tabs/host-sysmodules.html</path>
> +    </tab>
> +</tabs-ext>
> \ No newline at end of file
> diff --git a/ui/css/ginger.css b/ui/css/ginger.css
> index 560fb3c..725366f 100644
> --- a/ui/css/ginger.css
> +++ b/ui/css/ginger.css
> @@ -153,7 +153,9 @@
>    background-color: #008abf;
>  }
>
> -.ginger .modal-body .nav-tabs > li.active > a, .ginger .modal-body
> .nav-tabs > li.active > a:hover, .ginger .modal-body .nav-tabs > li.active
> > a:focus {
> +.ginger .modal-body .nav-tabs > li.active > a,
> +.ginger .modal-body .nav-tabs > li.active > a:hover,
> +.ginger .modal-body .nav-tabs > li.active > a:focus {
>    border-color: -moz-use-text-color -moz-use-text-color #008abf;
>  }
>
> @@ -948,49 +950,60 @@
>  #form-nw-vlan-ipv4,
>  #form-nw-vlan-general,
>  #form-nw-vlan-ipv6,
> -#form-nw-vlan-advance {
> +#form-nw-vlan-advance,
> +#form-nw-bond-general,
> +#form-nw-bond-ipv4,
> +#form-nw-bond-ipv6,
> +#form-nw-bond-advance {
>    margin: 15px 0 0;
>    width: 98%;
>  }
>
>  #nw-settings-window .tab-content,
> -#nw-vlan-window .tab-content {
> +#nw-vlan-window .tab-content,
> +#nw-bond-window .tab-content {
>    height: 559px;
>    overflow: auto;
>  }
>
>  #nw-settings-window .tab-content .tab-pane,
> -#nw-vlan-window .tab-content .tab-pane {
> +#nw-vlan-window .tab-content .tab-pane,
> +#nw-bond-window .tab-content .tab-pane {
>    position: relative;
>  }
>
>  #nw-settings-tabs .form-horizontal .control-label,
> -#nw-vlan-tabs .form-horizontal .control-label {
> +#nw-vlan-tabs .form-horizontal .control-label,
> +#nw-bond-tabs .form-horizontal .control-label {
>    text-align: left;
>    padding-top: 0px;
>  }
>
>  #nw-settings-tabs .bootgrid-table,
> -#nw-vlan-tabs .bootgrid-table {
> +#nw-vlan-tabs .bootgrid-table,
> +#nw-bond-tabs .bootgrid-table {
>    height: 140px;
>    width: 99%;
>    margin-left: 1%;
>  }
>
>  #nw-settings-tabs .bootgrid-table th > .column-header-anchor > .icon,
> -#nw-vlan-tabs .bootgrid-table th > .column-header-anchor > .icon {
> +#nw-vlan-tabs .bootgrid-table th > .column-header-anchor > .icon,
> +#nw-bond-tabs .bootgrid-table th > .column-header-anchor > .icon {
>    right: 40%;
>  }
>
>  #nw-settings-tabs .bootgrid-table thead,
> -#nw-vlan-tabs .bootgrid-table thead {
> +#nw-vlan-tabs .bootgrid-table thead,
> +#nw-bond-tabs .bootgrid-table thead {
>    display: block;
>    width: 100%;
>    padding: 0;
>  }
>
>  #nw-settings-tabs .bootgrid-table tbody,
> -#nw-vlan-tabs .bootgrid-table tbody {
> +#nw-vlan-tabs .bootgrid-table tbody,
> +#nw-bond-tabs .bootgrid-table tbody {
>    height: 120px;
>    overflow: auto;
>    position: absolute;
> @@ -999,13 +1012,15 @@
>  }
>
>  #nw-settings-tabs .bootgrid-table tr,
> -#nw-vlan-tabs .bootgrid-table tr {
> +#nw-vlan-tabs .bootgrid-table tr,
> +#nw-bond-tabs .bootgrid-table tr {
>    width: 100%;
>    display: inline-table;
>  }
>
>  #nw-settings-tabs .bootgrid-table th,
> -#nw-vlan-tabs .bootgrid-table th {
> +#nw-vlan-tabs .bootgrid-table th,
> +#nw-bond-tabs .bootgrid-table th {
>    background-color: #eee;
>  }
>
> @@ -1251,3 +1266,175 @@
>    margin: 0;
>    width: 160px;
>  }
> +
> +#host-sysmodules-root-container .accordion {
> +  margin: 12px 20px 12px 60px;
> +  padding-bottom: 18px;
> +  border-bottom: 1px solid #eee;
> +  overflow: visible;
> +  clear: both;
> +}
> +
> +#host-sysmodules-root-container .accordion:first-chld {
> +  margin-top: 24px;
> +}
> +
> +#host-sysmodules-root-container .accordion > h3 {
> +  margin: 0;
> +  padding: 0;
> +  font-size: 26px;
> +  font-weight: 300;
> +  height: 44px;
> +  display: block;
> +}
> +
> +#host-sysmodules-root-container .accordion > h3 a {
> +  color: #3a393b;
> +  text-decoration: none;
> +  display: block;
> +  padding: 6px 30px;
> +  margin-left: -30px;
> +  margin-right: -30px;
> +}
> +
> +#host-sysmodules-root-container .accordion > h3 a span.accordion-icon {
> +  margin-left: -52px;
> +  vertical-align: middle;
> +  display: inline-block;
> +  font: normal normal normal 32px/1 FontAwesome;
> +  text-rendering: auto;
> +  -webkit-font-smoothing: antialiased;
> +  color: #3a393b;
> +}
> +
> +#host-sysmodules-root-container .accordion > h3 a[aria-expanded="false"]
> span.accordion-icon:before {
> +  content: "\f01a";
> +}
> +
> +#host-sysmodules-root-container .accordion > h3 a[aria-expanded="true"]
> span.accordion-icon:before {
> +  content: "\f01b";
> +}
> +
> +#host-sysmodules-root-container .accordion > h3 a span.accordion-text {
> +  margin-left: 23px;
> +  display: inline-block;
> +  vertical-align: middle;
> +}
> +
> +#host-sysmodules-root-container .navbar-default.toolbar {
> +  background-color: #008abf !important;
> +}
> +
> +#sysmodules-content-area {
> +  padding: 0;
> +  list-style-type: none;
> +}
> +
> +#sysmodules-content-area .li:nth-child(even) {
> +  background-color: #fcfcfc;
> +}
> +
> +#sysmodules-content-area .li:nth-child(odd) {
> +  background-color: #fff;
> +}
> +
> +#sysmodules-content-area .header > span,
> +#sysmodules-content-area .header > div,
> +#sysmodules-content-area .body > span,
> +#sysmodules-content-area .body > div {
> +  padding: 6px 2px;
> +  display: inline-block;
> +  font-family: "Open Sans", Helvetica, Arial, "Lucida Grande", sans-serif;
> +}
> +
> +#sysmodules-content-area .header {
> +  border-top: 0 none;
> +}
> +
> +#sysmodules-content-area .header > span,
> +#sysmodules-content-area .header > div {
> +  vertical-align: bottom;
> +  height: 36px;
> +  font-weight: 300;
> +  font-size: 12.5pt;
> +  line-height: 1.42857;
> +  border-bottom: 0;
> +  border-top: 0;
> +}
> +
> +#sysmodules-content-area .body {
> +  border-top: 1px solid #eee;
> +}
> +
> +#sysmodules-content-area .body > span,
> +#sysmodules-content-area .body > div {
> +  vertical-align: middle;
> +  font-size: 11pt;
> +  line-height: 2.42857;
> +  font-weight: 400;
> +}
> +
> +#sysmodules-content-area .btn-group {
> +  margin-bottom: 20px;
> +}
> +
> +#sysmodules-content-area .column-name {
> +  width: 30%;
> +}
> +
> +#sysmodules-content-area .column-depends {
> +  width: 30%;
> +}
> +
> +#sysmodules-content-area .column-details {
> +  width: 12%;
> +  vertical-align: middle;
> +  text-align: center;
> +}
> +
> +#sysmodules-content-area .column-version {
> +  width: 14%;
> +}
> +
> +#sysmodules-content-area .column-actions {
> +  width: 14%;
> +}
> +
> +#sysmodules-content-area .sysmodules-details {
> +  width: 100%;
> +  padding: 22px;
> +  background: #ddd;
> +}
> +
> +#sysmodules-content-area .details-list {
> +  max-height: 285px;
> +  min-height: 140px;
> +  background: #fff;
> +  padding: 0;
> +  overflow-x: hidden;
> +  overflow-y: auto;
> +}
> +
> +#sysmodules-content-area .arrow-down,
> +#sysmodules-content-area .arrow-up {
> +  display: inline-block;
> +  font: normal normal normal 14px/1 FontAwesome;
> +  font-size: inherit;
> +  text-rendering: auto;
> +  -webkit-font-smoothing: antialiased;
> +  -moz-osx-font-smoothing: grayscale;
> +  cursor: pointer;
> +}
> +
> +#sysmodules-content-area .arrow-down:before {
> +  content: "\f078";
> +}
> +
> +#sysmodules-content-area .arrow-up:before {
> +  content: "\f077";
> +}
> +
> +#sysmodules-content-area .btn .fa-upload {
> +  margin-right: 10px;
> +  font-size: 20px;
> +}
> diff --git a/ui/css/src/ginger.scss b/ui/css/src/ginger.scss
> index 610ecea..862f298 100644
> --- a/ui/css/src/ginger.scss
> +++ b/ui/css/src/ginger.scss
> @@ -1,4 +1,4 @@
> -/*
> +    /*
>   * Copyright IBM Corp, 2015
>   *
>   * This library is free software; you can redistribute it and/or
> @@ -18,10 +18,8 @@
>
>  // Core variables
>  @import "../../../../../../../ui/css/src/modules/wok-variables";
> -
>  // Compass Mixins
>  @import
> "../../../../../../../ui/css/src/vendor/compass-mixins/lib/compass";
> -
>  .ui-tooltip {
>      width: "";
>      display: inline-block;
> @@ -144,14 +142,68 @@
>  }
>
>  .ginger {
> -  div.modal-footer {
> -    background-color: #008abf;
> -  }
> -  .modal-body .nav-tabs > li.active > a, .modal-body .nav-tabs >
> li.active > a:hover, .modal-body .nav-tabs > li.active > a:focus{
> -    border-color:-moz-use-text-color -moz-use-text-color #008abf;
> -  }
> +    div.modal-footer {
> +        background-color: #008abf;
> +    }
> +    .modal-body .nav-tabs > li.active > a,
> +    .modal-body .nav-tabs > li.active > a:hover,
> +    .modal-body .nav-tabs > li.active > a:focus {
> +        border-color: -moz-use-text-color -moz-use-text-color #008abf;
> +    }
> +}
> +
> + at mixin ginger-accordion() {
> +    margin: 12px 20px 12px 60px;
> +    padding-bottom: 18px;
> +    border-bottom: 1px solid $table-border-color;
> +    overflow: visible;
> +    clear: both;
> +    &:first-chld {
> +        margin-top: 24px;
> +    }
> +    > h3 {
> +        margin: 0;
> +        padding: 0;
> +        font-size: 26px;
> +        font-weight: 300;
> +        height: 44px;
> +        display: block;
> +        a {
> +            color: $brand-primary;
> +            text-decoration: none;
> +            display: block;
> +            padding: 6px 30px;
> +            margin-left: -30px;
> +            margin-right: -30px;
> +            span.accordion-icon {
> +                margin-left: -52px;
> +                vertical-align: middle;
> +                display: inline-block;
> +                font: normal normal normal 32px/1 FontAwesome;
> +                text-rendering: auto;
> +                -webkit-font-smoothing: antialiased;
> +                color: $brand-primary;
> +            }
> +            &[aria-expanded="false"] {
> +                span.accordion-icon:before {
> +                    content: "\f01a";
> +                }
> +            }
> +            &[aria-expanded="true"] {
> +                span.accordion-icon:before {
> +                    content: "\f01b";
> +                }
> +            }
> +            span.accordion-text {
> +                margin-left: 23px;
> +                display: inline-block;
> +                vertical-align: middle;
> +            }
> +        }
> +    }
>  }
>
>  @import "modules/administration";
>  @import "modules/network";
>  @import "modules/storage";
> + at import "modules/sysmodules";
> \ No newline at end of file
> diff --git a/ui/css/src/modules/_sysmodules.scss
> b/ui/css/src/modules/_sysmodules.scss
> new file mode 100644
> index 0000000..5858dcc
> --- /dev/null
> +++ b/ui/css/src/modules/_sysmodules.scss
> @@ -0,0 +1,126 @@
> +//
> +// Project Ginger
> +//
> +// Copyright IBM, Corp. 2016
> +//
> +// Code derived from Project Kimchi
> +//
> +// Licensed under the Apache License, Version 2.0 (the "License");
> +// you may not use this file except in compliance with the License.
> +// You may obtain a copy of the License at
> +//
> +//     http://www.apache.org/licenses/LICENSE-2.0
> +//
> +// Unless required by applicable law or agreed to in writing, software
> +// distributed under the License is distributed on an "AS IS" BASIS,
> +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> +// See the License for the specific language governing permissions and
> +// limitations under the License.
> +//
> +#host-sysmodules-root-container {
> +    .accordion {
> +        @include ginger-accordion();
> +    }
> +    .navbar-default.toolbar {
> +        background-color: $hosts-color !important;
> +    }
> +}
> +
> +#sysmodules-content-area {
> +    padding: 0;
> +    list-style-type: none;
> +    .li:nth-child(even) {
> +        background-color: #fcfcfc;
> +    }
> +    .li:nth-child(odd) {
> +        background-color: #fff;
> +    }
> +    .header,
> +    .body {
> +        > span,
> +        > div {
> +            padding: 6px 2px;
> +            display: inline-block;
> +            font-family: $font-family-sans-serif;
> +        }
> +    }
> +    .header {
> +        border-top: 0 none;
> +        > span,
> +        > div {
> +            vertical-align: bottom;
> +            height: 36px;
> +            font-weight: 300;
> +            font-size: 12.5pt;
> +            line-height: 1.42857;
> +            border-bottom: 0;
> +            border-top: 0;
> +        }
> +    }
> +    .body {
> +        border-top: 1px solid #eee;
> +        > span,
> +        > div {
> +            vertical-align: middle;
> +            font-size: 11pt;
> +            line-height: 2.42857;
> +            font-weight: 400;
> +        }
> +    }
> +    .btn-group {
> +        margin-bottom: 20px;
> +    }
> +    .actBtn {
> +        width: 115px;
> +    }
> +    .column-name {
> +        width: 30%;
> +    }
> +    .column-depends {
> +        width: 30%;
> +    }
> +    .column-details {
> +        width: 12%;
> +        vertical-align: middle;
> +        text-align: center;
> +    }
> +    .column-version {
> +        width: 14%;
> +    }
> +    .column-actions {
> +        width: 14%;
> +    }
> +    .sysmodules-details {
> +        width: 100%;
> +        padding: 22px;
> +        background: $table-bg-active;
> +    }
> +    .details-list {
> +        max-height: 285px;
> +        min-height: 140px;
> +        background: $table-bg;
> +        padding: 0;
> +        overflow-x: hidden;
> +        overflow-y: auto;
> +    }
> +    .arrow-down,
> +    .arrow-up {
> +        display: inline-block;
> +        font: normal normal normal 14px/1 FontAwesome;
> +        font-size: inherit;
> +        text-rendering: auto;
> +        -webkit-font-smoothing: antialiased;
> +        -moz-osx-font-smoothing: grayscale;
> +        cursor: pointer;
> +    }
> +    .arrow-down:before {
> +        content: "\f078";
> +    }
> +    .arrow-up:before {
> +        content: "\f077";
> +    }
> +    .btn .fa-upload {
> +        margin-right: 10px;
> +        font-size: 20px;
> +    }
> +}
> \ No newline at end of file
> diff --git a/ui/js/host-sysmodules.js b/ui/js/host-sysmodules.js
> new file mode 100644
> index 0000000..3644a02
> --- /dev/null
> +++ b/ui/js/host-sysmodules.js
> @@ -0,0 +1,76 @@
> +/*
> + * Copyright IBM Corp, 2016
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301  USA
> + */
> +
> +ginger.initSysmodules = function() {
> +    $(".content-area", "#gingerHostAdmin").css("height", "100%");
> +    ginger.loadSysmodules();
> +};
> +
> +ginger.loadSysmodules = function() {
> +    ginger.getSysmodules(function(data) {
> +        $("#sysmodules-body").empty();
> +        for (var i = 0; i < data.length; i++) {
> +            var tempNode =
> $.parseHTML(wok.substitute($("#sysmodulesItem").html(), data[i]));
> +            $("#sysmodules-body").append(tempNode);
> +
> +            $(".details-list", tempNode).append('Details');
> +
> +            $(".btn-unload").on("click", function(event) {
> +                event.preventDefault();
> +                event.stopImmediatePropagation();
> +                var sysmoduleItem = $(this).parent();
> +
> +                ginger.removeSysmodule(sysmoduleItem.prop("id"),
> function() {
> +                    sysmoduleItem.remove();
> +                }, function(error) {
> +                    wok.message.error('Unable to unload the module.');
> +                });
> +            });
> +        }
> +
> +        $('.load-modules-btn').on('click', function(event) {
> +            // TODO: Implement load modules action
> +        });
> +
> +        $('.arrow').on('click', function(event) {
> +            var that = $(this).parent().parent();
> +            var slide = $('.sysmodules-details',
> $(this).parent().parent());
> +            if (that.hasClass('in')) {
> +                that.css('height', 'auto');
> +                that.removeClass('in');
> +                ginger.changeArrow($('.arrow-down', that));
> +                slide.slideDown('slow');
> +            } else {
> +                slide.slideUp('slow', function() {
> +                    that.css('height', '');
> +                });
> +                that.addClass('in');
> +                ginger.changeArrow($('.arrow-up', that));
> +            }
> +        });
> +    });
> +
> +};
> +
> +ginger.changeArrow = function(obj) {
> +    if ($(obj).hasClass('arrow-down')) {
> +        $(obj).removeClass('arrow-down').addClass('arrow-up');
> +    } else {
> +        $(obj).removeClass('arrow-up').addClass('arrow-down');
> +    }
> +}
> \ No newline at end of file
> diff --git a/ui/js/util.js b/ui/js/util.js
> index ed12bd4..8e1cc17 100644
> --- a/ui/js/util.js
> +++ b/ui/js/util.js
> @@ -21,27 +21,27 @@ ginger.hostarch = null;
>  ginger.selectedInterface = null;
>
>  trackingTasks = [];
> -ginger.getFirmware = function(suc, err){
> +ginger.getFirmware = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/firmware',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        resend : true,
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/firmware',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        resend: true,
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  };
>
> -ginger.updateFirmware = function(content, suc, err){
> +ginger.updateFirmware = function(content, suc, err) {
>      $.ajax({
> -        url : "plugins/ginger/firmware",
> -        type : 'PUT',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        data : JSON.stringify(content),
> +        url: "plugins/ginger/firmware",
> +        type: 'PUT',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        data: JSON.stringify(content),
>          success: suc,
>          error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
> @@ -50,82 +50,82 @@ ginger.updateFirmware = function(content, suc, err){
>  };
>
>  ginger.fwProgress = function(suc, err, progress) {
> -    var taskID = -1;
> -    var onResponse = function(data) {
> -        taskID = data['id'];
> -        trackTask();
> -    };
> -
> -    var trackTask = function() {
> -        ginger.getTask(taskID, onTaskResponse, err);
> -    };
> -
> -    var onTaskResponse = function(result) {
> -        var taskStatus = result['status'];
> -        switch(taskStatus) {
> -        case 'running':
> -            progress && progress(result);
> -            setTimeout(function() {
> -                trackTask();
> -            }, 1000);
> -            break;
> -        case 'finished':
> -        case 'failed':
> -            suc(result);
> -            break;
> -        default:
> -            break;
> -        }
> +        var taskID = -1;
> +        var onResponse = function(data) {
> +            taskID = data['id'];
> +            trackTask();
> +        };
> +
> +        var trackTask = function() {
> +            ginger.getTask(taskID, onTaskResponse, err);
> +        };
> +
> +        var onTaskResponse = function(result) {
> +            var taskStatus = result['status'];
> +            switch (taskStatus) {
> +                case 'running':
> +                    progress && progress(result);
> +                    setTimeout(function() {
> +                        trackTask();
> +                    }, 1000);
> +                    break;
> +                case 'finished':
> +                case 'failed':
> +                    suc(result);
> +                    break;
> +                default:
> +                    break;
> +            }
> +        };
> +
> +        wok.requestJSON({
> +            url: 'plugins/ginger/fwprogress',
> +            type: "GET",
> +            contentType: "application/json",
> +            dataType: "json",
> +            success: onResponse,
> +            error: err
> +        });
> +    },
> +
> +
> +    ginger.listBackupArchives = function(suc, err) {
> +        wok.requestJSON({
> +            url: 'plugins/ginger/backup/archives',
> +            type: 'GET',
> +            contentType: 'application/json',
> +            dataType: 'json',
> +            resend: true,
> +            success: suc,
> +            error: err || function(data) {
> +                wok.message.error(data.responseJSON.reason);
> +            }
> +        });
>      };
>
> -    wok.requestJSON({
> -        url : 'plugins/ginger/fwprogress',
> -        type : "GET",
> -        contentType : "application/json",
> -        dataType : "json",
> -        success : onResponse,
> -        error : err
> -    });
> -},
> -
> -
> -ginger.listBackupArchives = function(suc, err){
> -    wok.requestJSON({
> -        url : 'plugins/ginger/backup/archives',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        resend : true,
> -        success : suc,
> -        error : err || function(data) {
> -            wok.message.error(data.responseJSON.reason);
> -        }
> -    });
> -};
> -
>  ginger.createBackupArchive = function(bak, suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/backup/archives',
> -        type : 'POST',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        data : JSON.stringify(bak),
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/backup/archives',
> +        type: 'POST',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        data: JSON.stringify(bak),
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  };
>
> -ginger.getBackupArchiveFile = function(id, suc, err){
> +ginger.getBackupArchiveFile = function(id, suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/backup/archives/' + encodeURIComponent(id)
> + '/file',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        resend : true,
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/backup/archives/' + encodeURIComponent(id) +
> '/file',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        resend: true,
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
> @@ -133,12 +133,12 @@ ginger.getBackupArchiveFile = function(id, suc, err){
>
>  ginger.deleteBackupArchive = function(id, suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/backup/archives/' + encodeURIComponent(id),
> -        type : 'DELETE',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/backup/archives/' + encodeURIComponent(id),
> +        type: 'DELETE',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
> @@ -146,13 +146,13 @@ ginger.deleteBackupArchive = function(id, suc, err) {
>
>  ginger.deleteBackupArchives = function(content, suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/backup/discard_archives',
> -        type : 'POST',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        data : JSON.stringify(content),
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/backup/discard_archives',
> +        type: 'POST',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        data: JSON.stringify(content),
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
> @@ -160,25 +160,25 @@ ginger.deleteBackupArchives = function(content, suc,
> err) {
>
>  ginger.getInterfaces = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/network/interfaces',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        resend : true,
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/network/interfaces',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        resend: true,
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  };
>
> -ginger.updateInterface = function(name, content, suc, err){
> +ginger.updateInterface = function(name, content, suc, err) {
>      $.ajax({
> -        url : 'plugins/ginger/network/interfaces/' +
> encodeURIComponent(name),
> -        type : 'PUT',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        data : JSON.stringify(content),
> +        url: 'plugins/ginger/network/interfaces/' +
> encodeURIComponent(name),
> +        type: 'PUT',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        data: JSON.stringify(content),
>          success: suc,
>          error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
> @@ -188,50 +188,50 @@ ginger.updateInterface = function(name, content,
> suc, err){
>
>  ginger.enableInterface = function(name, status, suc, err) {
>      wok.requestJSON({
> -        url : "plugins/ginger/network/interfaces/" + name +
> -              '/' + (status == "down" ? 'deactivate' : 'activate'),
> -        type : 'POST',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        success : suc,
> -        error : err
> +        url: "plugins/ginger/network/interfaces/" + name +
> +            '/' + (status == "down" ? 'deactivate' : 'activate'),
> +        type: 'POST',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: err
>      });
>  };
>
>  ginger.deleteInterface = function(name, suc, err) {
> -  wok.requestJSON({
> -      url : 'plugins/ginger/network/cfginterfaces/' + name,
> -      type : 'DELETE',
> -      contentType : 'application/json',
> -      dataType : 'json',
> -      success : suc,
> -      error : err || function(data) {
> -          wok.message.error(data.responseJSON.reason);
> -      }
> -  });
> +    wok.requestJSON({
> +        url: 'plugins/ginger/network/cfginterfaces/' + name,
> +        type: 'DELETE',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: err || function(data) {
> +            wok.message.error(data.responseJSON.reason);
> +        }
> +    });
>  };
>
> -ginger.getNetworkGlobals = function(suc, err){
> +ginger.getNetworkGlobals = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/network',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        resend : true,
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/network',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        resend: true,
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  };
>
> -ginger.updateNetworkGlobals = function(content, suc, err){
> +ginger.updateNetworkGlobals = function(content, suc, err) {
>      $.ajax({
> -        url : 'plugins/ginger/network',
> -        type : 'PUT',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        data : JSON.stringify(content),
> +        url: 'plugins/ginger/network',
> +        type: 'PUT',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        data: JSON.stringify(content),
>          success: suc,
>          error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
> @@ -241,12 +241,12 @@ ginger.updateNetworkGlobals = function(content, suc,
> err){
>
>  ginger.confirmNetworkUpdate = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/network/confirm_change',
> -        type : 'POST',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/network/confirm_change',
> +        type: 'POST',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
> @@ -254,55 +254,57 @@ ginger.confirmNetworkUpdate = function(suc, err) {
>
>  ginger.confirmInterfaceUpdate = function(name, suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/network/interfaces/' +
> encodeURIComponent(name) + '/confirm_change',
> -        type : 'POST',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/network/interfaces/' +
> encodeURIComponent(name) + '/confirm_change',
> +        type: 'POST',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  };
>
> -ginger.validateIp = function(ip){
> +ginger.validateIp = function(ip) {
>      var ipReg =
> /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
>      return ipReg.test(ip);
>  };
>
> -ginger.validateMask = function(mask){
> -    if(mask.indexOf('.')!=-1){
> +ginger.validateMask = function(mask) {
> +    if (mask.indexOf('.') != -1) {
>          var secs = mask.split('.');
>          var binMask = "";
> -        for(var i=0; i<secs.length; i++)
> +        for (var i = 0; i < secs.length; i++)
>              binMask += parseInt(secs[i]).toString(2);
>          return /^1+0+$/.test(binMask);
> -    }else{
> +    } else {
>          return mask > 0 && mask < 32;
>      }
>  };
>
> -ginger.getPowerProfiles = function(suc, err){
> +ginger.getPowerProfiles = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/powerprofiles',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        resend : true,
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/powerprofiles',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        resend: true,
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  };
>
> -ginger.activatePowerProfile = function(name, suc, err){
> +ginger.activatePowerProfile = function(name, suc, err) {
>      $.ajax({
> -        url : "plugins/ginger/powerprofiles/" + encodeURIComponent(name),
> -        type : 'PUT',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        data : JSON.stringify({ active: true }),
> +        url: "plugins/ginger/powerprofiles/" + encodeURIComponent(name),
> +        type: 'PUT',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        data: JSON.stringify({
> +            active: true
> +        }),
>          success: suc,
>          error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
> @@ -310,113 +312,113 @@ ginger.activatePowerProfile = function(name, suc,
> err){
>      });
>  };
>
> -ginger.getSANAdapters = function(suc, err){
> +ginger.getSANAdapters = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/san_adapters',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        resend : true,
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/san_adapters',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        resend: true,
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  };
>
> -ginger.getSensors = function(suc, err){
> +ginger.getSensors = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/sensors',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        resend : true,
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/sensors',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        resend: true,
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  };
>
> -ginger.getSEPSubscriptions = function(suc, err){
> +ginger.getSEPSubscriptions = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/ibm_sep',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        resend : true,
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/ibm_sep',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        resend: true,
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  };
>
> -ginger.deleteSubscription = function (hostname, suc, err) {
> +ginger.deleteSubscription = function(hostname, suc, err) {
>      wok.requestJSON({
> -        url : wok.url + 'plugins/ginger/ibm_sep/subscribers/' + hostname,
> -        type : 'DELETE',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        success : suc,
> -        error : err || function(data) {
> +        url: wok.url + 'plugins/ginger/ibm_sep/subscribers/' + hostname,
> +        type: 'DELETE',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  }
>
> -ginger.addSEPSubscription = function(subscription, suc, err){
> +ginger.addSEPSubscription = function(subscription, suc, err) {
>      wok.requestJSON({
> -        url : wok.url + 'plugins/ginger/ibm_sep/subscribers',
> -        type : 'POST',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        data : JSON.stringify(subscription),
> -        resend : true,
> -        success : suc,
> -        error : err || function(data) {
> +        url: wok.url + 'plugins/ginger/ibm_sep/subscribers',
> +        type: 'POST',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        data: JSON.stringify(subscription),
> +        resend: true,
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  };
>
> -ginger.getSEPStatus = function(suc, err){
> +ginger.getSEPStatus = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/ibm_sep',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        resend : true,
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/ibm_sep',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        resend: true,
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  };
>
> -ginger.startSEP = function(suc, err){
> +ginger.startSEP = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/ibm_sep/start',
> -        type : 'POST',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        resend : true,
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/ibm_sep/start',
> +        type: 'POST',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        resend: true,
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  };
>
> -ginger.stopSEP = function(suc, err){
> +ginger.stopSEP = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/ibm_sep/stop',
> -        type : 'POST',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        resend : true,
> -        success : suc,
> -        error : err || function(data) {
> +        url: 'plugins/ginger/ibm_sep/stop',
> +        type: 'POST',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        resend: true,
> +        success: suc,
> +        error: err || function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
> @@ -424,13 +426,13 @@ ginger.stopSEP = function(suc, err){
>
>  ginger.getUsers = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/users',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        resend : true,
> -        success : suc,
> -        error : function(data) {
> +        url: 'plugins/ginger/users',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        resend: true,
> +        success: suc,
> +        error: function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
> @@ -438,27 +440,27 @@ ginger.getUsers = function(suc, err) {
>
>  ginger.addUser = function(username, suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/users',
> -        type : 'POST',
> -        contentType : 'application/json',
> -        data : JSON.stringify(username),
> -        dataType : 'json',
> -        resend : true,
> -        success : suc,
> -        error :  err || function(data) {
> -             wok.message.error(data.responseJSON.reason);
> +        url: 'plugins/ginger/users',
> +        type: 'POST',
> +        contentType: 'application/json',
> +        data: JSON.stringify(username),
> +        dataType: 'json',
> +        resend: true,
> +        success: suc,
> +        error: err || function(data) {
> +            wok.message.error(data.responseJSON.reason);
>          }
>      });
>  }
>
> -ginger.deleteUser = function (username, suc, err) {
> +ginger.deleteUser = function(username, suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/users/' + username,
> -        type : 'DELETE',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        success : suc,
> -        error : function(data) {
> +        url: 'plugins/ginger/users/' + username,
> +        type: 'DELETE',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
> @@ -466,12 +468,12 @@ ginger.deleteUser = function (username, suc, err) {
>
>  ginger.getCapabilities = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/capabilities',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        success : suc,
> -        error : function(data) {
> +        url: 'plugins/ginger/capabilities',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
> @@ -480,16 +482,16 @@ ginger.getCapabilities = function(suc, err) {
>  /**
>   * Get the host information.
>   */
> -ginger.getHostDetails = function (suc,err) {
> -  wok.requestJSON({
> -      url : 'plugins/gingerbase/host',
> -      type : 'GET',
> -      resend: true,
> -      contentType : 'application/json',
> -      dataType : 'json',
> -      success : suc,
> -      error: err
> -  });
> +ginger.getHostDetails = function(suc, err) {
> +    wok.requestJSON({
> +        url: 'plugins/gingerbase/host',
> +        type: 'GET',
> +        resend: true,
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: err
> +    });
>  }
>
>  /**
> @@ -497,89 +499,103 @@ ginger.getHostDetails = function (suc,err) {
>   */
>  ginger.getPlugins = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins',
> -        type : 'GET',
> +        url: 'plugins',
> +        type: 'GET',
>          resend: true,
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        success : suc,
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
>          error: err
>      });
>  };
> -ginger.getFilesystems =  function(suc , err){
> -       wok.requestJSON({
> -        url : 'plugins/ginger/filesystems',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        success : suc,
> -        error : function(data) {
> +ginger.getFilesystems = function(suc, err) {
> +    wok.requestJSON({
> +        url: 'plugins/ginger/filesystems',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  }
> -ginger.getSwapdevices =  function(suc , err){
> -       wok.requestJSON({
> -        url : 'plugins/ginger/swaps',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        success : suc,
> -        error : function(data) {
> +ginger.getSwapdevices = function(suc, err) {
> +    wok.requestJSON({
> +        url: 'plugins/ginger/swaps',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  }
>
> -ginger.getVolumegroups =  function(suc , err){
> -       wok.requestJSON({
> -        url : 'plugins/ginger/vgs',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        success : suc,
> -        error : function(data) {
> +ginger.getVolumegroups = function(suc, err) {
> +    wok.requestJSON({
> +        url: 'plugins/ginger/vgs',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: function(data) {
> +            wok.message.error(data.responseJSON.reason);
> +        }
> +    });
> +}
> +ginger.getStgdevs = function(suc, err) {
> +    wok.requestJSON({
> +        url: 'plugins/ginger/stgdevs',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  }
> -ginger.getStgdevs =  function(suc , err){
> +
> +ginger.getFcpTapeDevices = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/stgdevs',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        success : suc,
> -        error : function(data) {
> +        url: 'plugins/gingers390x/lstapes',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  }
>
> -ginger.getFcpTapeDevices =  function(suc , err){
> +ginger.getSysmodules = function(suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/gingers390x/lstapes',
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        success : suc,
> -        error : function(data) {
> +        url: 'plugins/ginger/sysmodules',
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: function(data) {
>              wok.message.error(data.responseJSON.reason);
>          }
>      });
>  }
> +
>  ginger.formatDASDDevice = function(busId, settings, suc, err, progress) {
>      var onResponse = function(data) {
> -       taskID = data['id'];
> -       ginger.trackTask(taskID, suc, err, progress);
> +        taskID = data['id'];
> +        ginger.trackTask(taskID, suc, err, progress);
>      };
>
>      wok.requestJSON({
> -        url : '/plugins/ginger/dasddevs/'+busId+'/format',
> -        type : 'POST',
> -        contentType : 'application/json',
> -        data : JSON.stringify(settings),
> -        dataType : 'json',
> +        url: '/plugins/ginger/dasddevs/' + busId + '/format',
> +        type: 'POST',
> +        contentType: 'application/json',
> +        data: JSON.stringify(settings),
> +        dataType: 'json',
>          success: onResponse,
>          error: err
>      });
> @@ -587,11 +603,11 @@ ginger.formatDASDDevice = function(busId, settings,
> suc, err, progress) {
>
>  ginger.removeDASDDevice = function(busId, settings, suc, err, progress) {
>      wok.requestJSON({
> -        url : "/plugins/gingers390x/storagedevices/"+ busId +"/offline",
> -        type : 'POST',
> -        contentType : 'application/json',
> -        data : JSON.stringify(settings),
> -        dataType : 'json',
> +        url: "/plugins/gingers390x/storagedevices/" + busId + "/offline",
> +        type: 'POST',
> +        contentType: 'application/json',
> +        data: JSON.stringify(settings),
> +        dataType: 'json',
>          success: suc,
>          error: err
>      });
> @@ -599,11 +615,22 @@ ginger.removeDASDDevice = function(busId, settings,
> suc, err, progress) {
>
>  ginger.removeFCDevice = function(lunPath, settings, suc, err, progress) {
>      wok.requestJSON({
> -        url : "/plugins/gingers390x/fcluns/"+ lunPath,
> -        type : 'DELETE',
> -        contentType : 'application/json',
> -        data : JSON.stringify(settings),
> -        dataType : 'json',
> +        url: "/plugins/gingers390x/fcluns/" + lunPath,
> +        type: 'DELETE',
> +        contentType: 'application/json',
> +        data: JSON.stringify(settings),
> +        dataType: 'json',
> +        success: suc,
> +        error: err
> +    });
> +}
> +
> +ginger.removeSysmodule = function(moduleId, suc, err) {
> +    wok.requestJSON({
> +        url: 'plugins/ginger/sysmodules/' + moduleId,
> +        type: 'DELETE',
> +        contentType: 'application/json',
> +        dataType: 'json',
>          success: suc,
>          error: err
>      });
> @@ -611,45 +638,45 @@ ginger.removeFCDevice = function(lunPath, settings,
> suc, err, progress) {
>
>  ginger.getTask = function(taskId, suc, err) {
>      wok.requestJSON({
> -        url : 'plugins/ginger/tasks/' + encodeURIComponent(taskId),
> -        type : 'GET',
> -        contentType : 'application/json',
> -        dataType : 'json',
> -        success : suc,
> -        error : err
> +        url: 'plugins/ginger/tasks/' + encodeURIComponent(taskId),
> +        type: 'GET',
> +        contentType: 'application/json',
> +        dataType: 'json',
> +        success: suc,
> +        error: err
>      });
>  }
>  ginger.trackTask = function(taskID, suc, err, progress) {
>      var onTaskResponse = function(result) {
>          var taskStatus = result['status'];
> -        switch(taskStatus) {
> -        case 'running':
> -            progress && progress(result);
> -            setTimeout(function() {
> -                ginger.trackTask(taskID, suc, err, progress);
> -            }, 2000);
> -            break;
> -        case 'finished':
> -            suc && suc(result);
> -            break;
> -        case 'failed':
> -            err && err(result);
> -            break;
> -        default:
> -            break;
> +        switch (taskStatus) {
> +            case 'running':
> +                progress && progress(result);
> +                setTimeout(function() {
> +                    ginger.trackTask(taskID, suc, err, progress);
> +                }, 2000);
> +                break;
> +            case 'finished':
> +                suc && suc(result);
> +                break;
> +            case 'failed':
> +                err && err(result);
> +                break;
> +            default:
> +                break;
>          }
>      };
>
>      ginger.getTask(taskID, onTaskResponse, err);
> -    if(trackingTasks.indexOf(taskID) < 0)
> +    if (trackingTasks.indexOf(taskID) < 0)
>          trackingTasks.push(taskID);
>  }
>
> -ginger.trackdevices = function(trackDevicelist,removeItem) {
> +ginger.trackdevices = function(trackDevicelist, removeItem) {
>      "use strict";
>      trackDevicelist = jQuery.grep(trackDevicelist, function(value) {
> -          return value != removeItem;
> -        });
> +        return value != removeItem;
> +    });
>      return trackDevicelist;
>  };
>
> @@ -657,17 +684,17 @@ ginger.trackdevices =
> function(trackDevicelist,removeItem) {
>   * Create a network interface with new information.
>   */
>  ginger.createCfgInterface = function(settings, suc, err) {
> -  wok.requestJSON({
> -    url: 'plugins/ginger/network/cfginterfaces/',
> -    type: 'POST',
> -    contentType: 'application/json',
> -    data: JSON.stringify(settings),
> -    dataType: 'json',
> -    success: suc,
> -    error: err || function(data) {
> -      wok.message.error(data.responseJSON.reason);
> -    }
> -  });
> +    wok.requestJSON({
> +        url: 'plugins/ginger/network/cfginterfaces/',
> +        type: 'POST',
> +        contentType: 'application/json',
> +        data: JSON.stringify(settings),
> +        dataType: 'json',
> +        success: suc,
> +        error: err || function(data) {
> +            wok.message.error(data.responseJSON.reason);
> +        }
> +    });
>  }
>
>  /**
> @@ -678,74 +705,74 @@ ginger.createCfgInterface = function(settings, suc,
> err) {
>   * @param err callback for error
>   */
>  ginger.listCfgInterface = function(suc, err) {
> -    wok.requestJSON({
> -      url: 'plugins/ginger/network/cfginterfaces/',
> -      type: 'GET',
> -      contentType: 'application/json',
> -      dataType: 'json',
> -      success: suc,
> -      error: err
> -    });
> -}
> -/**
> - * Retrieve the information of a given network interface by its name from
> it's cfg file.
> - *
> - * @param interface name
> - * @param suc callback for success
> - * @param err callback for error
> - */
> +        wok.requestJSON({
> +            url: 'plugins/ginger/network/cfginterfaces/',
> +            type: 'GET',
> +            contentType: 'application/json',
> +            dataType: 'json',
> +            success: suc,
> +            error: err
> +        });
> +    }
> +    /**
> +     * Retrieve the information of a given network interface by its name
> from it's cfg file.
> +     *
> +     * @param interface name
> +     * @param suc callback for success
> +     * @param err callback for error
> +     */
>  ginger.retrieveCfgInterface = function(interface, suc, err) {
> +        wok.requestJSON({
> +            url: 'plugins/ginger/network/cfginterfaces/' + interface,
> +            type: 'GET',
> +            contentType: 'application/json',
> +            dataType: 'json',
> +            success: suc,
> +            error: err
> +        });
> +    }
> +    /**
> +     * Update a network interface with new information.
> +     */
> +ginger.updateCfgInterface = function(interface, settings, suc, err) {
>      wok.requestJSON({
> -      url: 'plugins/ginger/network/cfginterfaces/'+interface,
> -      type: 'GET',
> -      contentType: 'application/json',
> -      dataType: 'json',
> -      success: suc,
> -      error: err
> +        url: 'plugins/ginger/network/cfginterfaces/' +
> encodeURIComponent(interface),
> +        type: 'PUT',
> +        contentType: 'application/json',
> +        data: JSON.stringify(settings),
> +        dataType: 'json',
> +        success: suc,
> +        error: err
>      });
>  }
> -  /**
> -   * Update a network interface with new information.
> -   */
> -ginger.updateCfgInterface = function(interface, settings, suc, err) {
> -  wok.requestJSON({
> -    url: 'plugins/ginger/network/cfginterfaces/' +
> encodeURIComponent(interface),
> -    type: 'PUT',
> -    contentType: 'application/json',
> -    data: JSON.stringify(settings),
> -    dataType: 'json',
> -    success: suc,
> -    error: err
> -  });
> -}
>
> -ginger.disableclass =  function(clas){
> -  jQuery("."+clas).css('pointer-events', 'none')
> -  jQuery("."+clas).find("input, select, button, textarea,
> div").attr("disabled",true);
> -  jQuery("."+clas).css('opacity', '0.5')
> +ginger.disableclass = function(clas) {
> +    jQuery("." + clas).css('pointer-events', 'none')
> +    jQuery("." + clas).find("input, select, button, textarea,
> div").attr("disabled", true);
> +    jQuery("." + clas).css('opacity', '0.5')
>  }
>
> -ginger.enableclass =  function(clas){
> -  jQuery("."+clas).css('pointer-events', 'auto')
> -  jQuery("."+clas).find("input, select, button, textarea,
> div").attr("disabled",false);
> -  jQuery("."+clas).css('opacity', 'initial')
> +ginger.enableclass = function(clas) {
> +    jQuery("." + clas).css('pointer-events', 'auto')
> +    jQuery("." + clas).find("input, select, button, textarea,
> div").attr("disabled", false);
> +    jQuery("." + clas).css('opacity', 'initial')
>  }
>
>  ginger.isInteger = function(value) {
> -return !isNaN(value) &&
> -       parseInt(Number(value)) == value &&
> -       !isNaN(parseInt(value, 10));
> +    return !isNaN(value) &&
> +        parseInt(Number(value)) == value &&
> +        !isNaN(parseInt(value, 10));
>  }
>
>  ginger.isValidIPv6 = function(ipv6addr) {
> -  if
> (/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/.test(ipv6addr))
> {
> -      return true;
> -  } else {
> -      return false;
> -  }
> -  return false;
> +    if
> (/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/.test(ipv6addr))
> {
> +        return true;
> +    } else {
> +        return false;
> +    }
> +    return false;
>  }
>
>  ginger.isValidIPv6Prefix = function(prefix) {
> -  return prefix > 0 && prefix < 127;
> -}
> +    return prefix > 0 && prefix < 127;
> +}
> \ No newline at end of file
> diff --git a/ui/pages/tabs/host-sysmodules.html.tmpl
> b/ui/pages/tabs/host-sysmodules.html.tmpl
> new file mode 100644
> index 0000000..d7225de
> --- /dev/null
> +++ b/ui/pages/tabs/host-sysmodules.html.tmpl
> @@ -0,0 +1,88 @@
> +<!DOCTYPE html>
> +<!--
> +Copyright IBM Corp, 2016
> +
> +This library is free software; you can redistribute it and/or
> +modify it under the terms of the GNU Lesser General Public
> +License as published by the Free Software Foundation; either
> +version 2.1 of the License, or (at your option) any later version.
> +
> +This library is distributed in the hope that it will be useful,
> +but WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +Lesser General Public License for more details.
> +
> +You should have received a copy of the GNU Lesser General Public
> +License along with this library; if not, write to the Free Software
> +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301  USA
> +-->
> +#unicode UTF-8
> +#import gettext
> +#silent t = gettext.translation($lang.domain, $lang.localedir,
> languages=$lang.lang)
> +#silent _ = t.gettext
> +#silent _t = t.gettext
> +<html>
> +<head>
> +<link rel="stylesheet" type="text/css"
> href="plugins/ginger/css/ginger.css">
> +<script type="text/javascript" src="plugins/ginger/js/util.js"></script>
> +<script type="text/javascript"
> src="plugins/ginger/js/host-sysmodules.js"></script>
> +<script type="text/javascript"
> src="plugins/ginger/js/ginger-bootgrid.js"></script>
> +</head>
> +<body>
> +    <div id="host-sysmodules-root-container" class="ginger">
> +        <nav class="navbar navbar-default toolbar">
> +            <div class="container">
> +                <div id="toolbar"></div>
> +            </div>
> +        </nav>
> +        <div class="container">
> +            <div id="alert-container"></div>
> +            <div id="gingerHostAdmin" class="host-admin">
> +                <div class="panel-group accordion"
> id="sysmodules-accordion" role="tablist" aria-multiselectable="true">
> +                     <h3>
> +                        <a role="button" data-toggle="collapse"
> data-parent="#sysmodules-accordion" href="#sysmodules-content-area"
> aria-expanded="false" aria-controls="sysmodules-content-area" class="">
> +                            <span class="accordion-icon"></span><span
> class="accordion-text">$_("System Modules Management")</span>
> +                        </a>
> +                    </h3>
> +                    <div id="sysmodules-content-area"
> class="panel-collapse collapse in" role="tabpanel"
> aria-labelledby="headingOne">
> +                         <div class="sysmodules-actions btn-group"
> id="sysmodules-actions-
> +                         area">
> +                            <button class="btn btn-primary actBtn
> load-modules-btn" type="submit" data-toggle="modal"
> data-target="#loadModule"><i class="fa fa-download"></i> $_("Load
> Modules")</button>
> +                         </div>
> +                         <div class="wok-datagrid"
> id="sysmodules-datagrid">
> +                            <div class="wok-datagrid-header">
> +                                <span
> class="column-name">$_("Name")</span><!--
> +                                --><span
> class="column-depends">$_("Depends On")</span><!--
> +                                --><span
> class="column-version">$_("Version")</span><!--
> +                                --><span
> class="column-details">$_("Details")</span><!--
> +                                --><span class="column-actions"
> style="display:none">
> +                                    <span
> class="sr-only">Actions</span><!--
> +                                --></span>
> +                            </div>
> +                            <ul class="wok-datagrid-body"
> id="sysmodules-body"></ul>
> +                         </div>
> +                    </div>
> +                </div>
> +            </div>
> +        </div>
> +    </div>
> +<script id="sysmodulesItem" type="html/text">
> +    <li class="wok-datagrid-row in" name="sysmodulesBodyItem" id="{name}">
> +        <span class="column-name" title="{name}">{name}</span><!--
> +        --><span class="column-depends">{depends}</span><!--
> +        --><span class="column-version">{version}</span><!--
> +        --><span class="column-details">
> +            <div class="arrow arrow-down"></div>
> +        </span><!--
> +        --><span class="column-actions btn btn-link btn-unload"><i
> class="fa fa-upload"></i> $_("Unload")</span>
> +        <div class="sysmodules-details" style="display: none;">
> +            <div class="details-list" ></div>
> +        </div>
> +        <div class="clear"></div>
> +    </li>
> +</script>
> +<script>
> +    ginger.initSysmodules();
> +</script>
> +</body>
> +</html>
> --
> 1.8.3.1
>
>


-- 

André Teodoro
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ovirt.org/pipermail/kimchi-devel/attachments/20160114/620dac8c/attachment.html>


More information about the Kimchi-devel mailing list