[Kimchi-devel] [v2] UI: Clone Guest

Aline Manera alinefm at linux.vnet.ibm.com
Tue Oct 28 18:39:31 UTC 2014


Some comments/suggestions:

1) Instead of displaying the default icon in the new entry, we could get 
that information from the target guest and create a new input using it.
So the cloning entry will have the same icon from the target guest.

2) I'd suggest to display the actions buttons disabled instead of 
removing them from the user view.

3) +1 for the progress bar suggested by Paulo

4) +1 for the static warning message also suggested by Paulo (see my 
other email for details)


On 10/24/2014 07:15 AM, huoyuxin at linux.vnet.ibm.com wrote:
> 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/list.css  |   18 ++++++++++
>   ui/js/src/kimchi.api.js        |   17 ++++++++-
>   ui/js/src/kimchi.guest_main.js |   73 +++++++++++++++++++++++++++++++++++----
>   ui/pages/guest.html.tmpl       |    6 +++-
>   4 files changed, 103 insertions(+), 11 deletions(-)
>
> diff --git a/ui/css/theme-default/list.css b/ui/css/theme-default/list.css
> index 8ffee69..fc3017b 100644
> --- a/ui/css/theme-default/list.css
> +++ b/ui/css/theme-default/list.css
> @@ -275,3 +275,21 @@
>       text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
>       padding-left: 10px;
>   }
> +
> +.guest-clone {
> +    margin: 10px;
> +}
> +
> +.guest-clone .icon {
> +    background: url('../../images/theme-default/loading.gif') no-repeat;
> +    display: inline-block;
> +    width: 20px;
> +    height: 20px;
> +    vertical-align: middle;
> +}
> +
> +.guest-clone .text {
> +    color: #666666;
> +    margin-left: 5px;
> +    text-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #FFFFFF;
> +}
> diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
> index 5895a07..2f90219 100644
> --- a/ui/js/src/kimchi.api.js
> +++ b/ui/js/src/kimchi.api.js
> @@ -695,10 +695,10 @@ var kimchi = {
>                   }, 2000);
>                   break;
>               case 'finished':
> -                suc(result);
> +                suc && suc(result);
>                   break;
>               case 'failed':
> -                err(result);
> +                err && err(result);
>                   break;
>               default:
>                   break;
> @@ -1233,5 +1233,18 @@ var kimchi = {
>               success : suc,
>               error : err
>           });
> +    },
> +
> +    cloneGuest: function(vm, suc, err) {
> +        kimchi.requestJSON({
> +            url : kimchi.url + 'vms/'+encodeURIComponent(vm)+"/clone",
> +            type : 'POST',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            success : suc,
> +            error : err ? err : function(data) {
> +                kimchi.message.error(data.responseJSON.reason);
> +            }
> +        });
>       }
>   };
> diff --git a/ui/js/src/kimchi.guest_main.js b/ui/js/src/kimchi.guest_main.js
> index dbe8753..ecc3b7a 100644
> --- a/ui/js/src/kimchi.guest_main.js
> +++ b/ui/js/src/kimchi.guest_main.js
> @@ -15,6 +15,34 @@
>    * See the License for the specific language governing permissions and
>    * limitations under the License.
>    */
> +kimchi.sampleGuestObject = {
> +    "name": "",
> +    "uuid": "",
> +    "state": "shutoff",
> +    "persistent": true,
> +    "icon": null,
> +    "cpus": 0,
> +    "memory": 0,
> +    "stats": {
> +        "net_throughput": 0,
> +        "io_throughput_peak": 100,
> +        "cpu_utilization": 0,
> +        "io_throughput": 0,
> +        "net_throughput_peak": 100
> +    },
> +    "screenshot": null,
> +    "graphics": {
> +        "passwd": null,
> +        "passwdValidTo": null,
> +        "type": "vnc",
> +        "port": null,
> +        "listen": "127.0.0.1"
> +    },
> +    "users": [],
> +    "groups": [],
> +    "access": "full"
> +};
> +
>
>   kimchi.vmstart = function(event) {
>       var button=$(this);
> @@ -173,8 +201,24 @@ kimchi.listVmsAuto = function() {
>       if (kimchi.vmTimeout) {
>           clearTimeout(kimchi.vmTimeout);
>       }
> +    var getCloningGuests = function(){
> +        var guests = [];
> +        kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/vms/*'), function(tasks) {
> +            for(var i=0;i<tasks.length;i++){
> +                var guestUri = tasks[i].target_uri;
> +                var guestName = guestUri.substring(guestUri.lastIndexOf('/')+1, guestUri.length);
> +                guests.push($.extend({}, kimchi.sampleGuestObject, {name: guestName, isCloning: true}));
> +                if(kimchi.trackingTasks.indexOf(tasks[i].id)==-1)
> +                    kimchi.trackTask(tasks[i].id, null, function(err){
> +                        kimchi.message.error(err.message);
> +                    }, null);
> +            }
> +        }, null, true);
> +        return guests;
> +    };
>       kimchi.listVMs(function(result, textStatus, jqXHR) {
>           if (result && textStatus=="success") {
> +            result = getCloningGuests().concat(result);
>               if(result.length) {
>                   var listHtml = '';
>                   var guestTemplate = kimchi.guestTemplate;
> @@ -233,14 +277,16 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) {
>       imgLoad.attr('src',load_src);
>
>       //Link the stopped tile to the start action, the running tile to open the console
> -    if (vmRunningBool) {
> -        liveTile.off("click", kimchi.vmstart);
> -        liveTile.on("click", kimchi.openVmConsole);
> -    }
> -    else {
> -        liveTile.off("click", kimchi.openVmConsole);
> -        liveTile.on("click", kimchi.vmstart);
> -        liveTile.hover(function(event){$(this).find('.overlay').show()}, function(event){$(this).find('.overlay').hide()});
> +    if(!vmObject.isCloning){
> +        if (vmRunningBool) {
> +            liveTile.off("click", kimchi.vmstart);
> +            liveTile.on("click", kimchi.openVmConsole);
> +        }
> +        else {
> +            liveTile.off("click", kimchi.openVmConsole);
> +            liveTile.on("click", kimchi.vmstart);
> +            liveTile.hover(function(event){$(this).find('.overlay').show()}, function(event){$(this).find('.overlay').hide()});
> +        }
>       }
>
>
> @@ -257,6 +303,7 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) {
>       //Setup the VM Actions
>       var guestActions=result.find("div[name=guest-actions]");
>       guestActions.find(".shutoff-disabled").prop('disabled', !vmRunningBool );
> +    guestActions.find(".running-disabled").prop('disabled', vmRunningBool );
>
>       if (vmRunningBool) {
>           guestActions.find(".running-hidden").hide();
> @@ -286,6 +333,11 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) {
>       }
>       guestActions.find("[name=vm-edit]").on({click : kimchi.vmedit});
>       guestActions.find("[name=vm-delete]").on({click : kimchi.vmdelete});
> +    guestActions.find("[name=vm-clone]").click(function(){
> +        kimchi.cloneGuest($(this).closest('li[name=guest]').attr("id"), function(data){
> +            kimchi.listVmsAuto();
> +        });
> +    });
>
>       //Maintain menu open state
>       var actionMenu=guestActions.find("div[name=actionmenu]");
> @@ -293,6 +345,11 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) {
>           $('.popover', actionMenu).toggle();
>       }
>
> +    if(vmObject.isCloning){
> +        guestActions.children().hide();
> +        result.find('.guest-clone').removeClass('hide-content');
> +    }
> +
>       return result;
>   };
>
> diff --git a/ui/pages/guest.html.tmpl b/ui/pages/guest.html.tmpl
> index 43fb350..74206fd 100644
> --- a/ui/pages/guest.html.tmpl
> +++ b/ui/pages/guest.html.tmpl
> @@ -26,6 +26,9 @@
>                   <div class="guest-general">
>                       <h2 class="title" title="{name}">{name}</h2>
>                   </div>
> +                <div class="guest-clone hide-content">
> +                    <span class="icon"></span><span class="text">$_("Cloning")...</span>
> +                </div>
>               </div>
>               <div name="cpu_utilization" class="sortable">
>                   <div class="circleGauge"></div>
> @@ -56,7 +59,8 @@
>                           <span class="text">$_("Actions")</span><span class="arrow"></span>
>                           <div class="popover actionsheet right-side" style="width: 250px">
>                               <button class="button-big shutoff-disabled" name="vm-console" ><span class="text">$_("Connect")</span></button>
> -                            <button class="button-big running-disabled" name="vm-edit"><span class="text">$_("Edit")</span></button>
> +                            <button class="button-big running-disabled" name="vm-clone"><span class="text">$_("Clone")</span></button>
> +                            <button class="button-big" name="vm-edit"><span class="text">$_("Edit")</span></button>
>                               <button class="button-big shutoff-hidden" name="vm-reset"><span class="text">$_("Reset")</span></button>
>                               <button class="button-big shutoff-hidden" name="vm-shutdown"><span class="text">$_("Shut Down")</span></button>
>                               <button class="button-big running-hidden" name="vm-start"><span class="text">$_("Start")</span></button>




More information about the Kimchi-devel mailing list