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

Yu Xin Huo huoyuxin at linux.vnet.ibm.com
Tue Nov 4 09:52:50 UTC 2014


On 11/4/2014 2:16 AM, Aline Manera wrote:
>
> Just a minor comment below:
Addressed in v5.
>
> On 11/03/2014 06:45 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/button.css |    4 ++
>>   ui/css/theme-default/list.css   |   18 ++++++
>>   ui/js/src/kimchi.api.js         |   17 +++++-
>>   ui/js/src/kimchi.guest_main.js  |  111 
>> +++++++++++++++++++++++++++++++--------
>>   ui/pages/guest.html.tmpl        |    6 ++-
>>   ui/pages/i18n.json.tmpl         |    1 +
>>   6 files changed, 132 insertions(+), 25 deletions(-)
>>
>> diff --git a/ui/css/theme-default/button.css 
>> b/ui/css/theme-default/button.css
>> index 499bf4a..0df53a6 100644
>> --- a/ui/css/theme-default/button.css
>> +++ b/ui/css/theme-default/button.css
>> @@ -50,6 +50,10 @@
>>       cursor: pointer;
>>   }
>>
>> +.btn[disabled] {
>> +    opacity: 0.3;
>> +}
>> +
>>   .btn:not([disabled]):hover {
>>       box-shadow: -2px -2px 2px #dadada, 2px 2px 2px #fff, 3px 3px 
>> 3px white
>>                   inset, -3px -3px 3px rgba(0, 0, 0, .25) inset;
>> 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;
>
> The icon kimchi-loading15x15.gif has a better resolution than loading.gif
>
>> +    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..2fd5c55 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();
>> @@ -276,21 +323,41 @@ kimchi.createGuestLi = function(vmObject, 
>> prevScreenImage, openMenu) {
>>       }
>>
>>       //Setup action event handlers
>> -    guestActions.find("[name=vm-start]").on({click : kimchi.vmstart});
>> -    guestActions.find("[name=vm-poweroff]").on({click : 
>> kimchi.vmpoweroff});
>> -    if (vmRunningBool) {  //If the guest is not running, do not 
>> enable reset
>> -        guestActions.find("[name=vm-reset]").on({click : 
>> kimchi.vmreset});
>> -    }
>> -    if (vmRunningBool) {  //If the guest is not running, do not 
>> enable shutdown
>> -        guestActions.find("[name=vm-shutdown]").on({click : 
>> kimchi.vmshutdown});
>> -    }
>> -    guestActions.find("[name=vm-edit]").on({click : kimchi.vmedit});
>> -    guestActions.find("[name=vm-delete]").on({click : 
>> kimchi.vmdelete});
>> +    if(!vmObject.isCloning){
>> +        guestActions.find("[name=vm-start]").on({click : 
>> kimchi.vmstart});
>> +        guestActions.find("[name=vm-poweroff]").on({click : 
>> kimchi.vmpoweroff});
>> +        if (vmRunningBool) {  //If the guest is not running, do not 
>> enable reset
>> +            guestActions.find("[name=vm-reset]").on({click : 
>> kimchi.vmreset});
>> +        }
>> +        if (vmRunningBool) {  //If the guest is not running, do not 
>> enable shutdown
>> +            guestActions.find("[name=vm-shutdown]").on({click : 
>> kimchi.vmshutdown});
>> +        }
>> +        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(){
>> +            var guest = $(this).closest('li[name=guest]').attr("id");
>> +            kimchi.confirm({
>> +                title : i18n['KCHAPI6006M'],
>> +                content : i18n['KCHVM6010M'],
>> +                confirm : i18n['KCHAPI6002M'],
>> +                cancel : i18n['KCHAPI6003M']
>> +            }, function() {
>> +                kimchi.cloneGuest(guest, function(data){
>> +                    kimchi.listVmsAuto();
>> +                });
>> +            }, null);
>> +        });
>> +
>> +        //Maintain menu open state
>> +        var actionMenu=guestActions.find("div[name=actionmenu]");
>> +        if (openMenu) {
>> +            $('.popover', actionMenu).toggle();
>> +        }
>>
>> -    //Maintain menu open state
>> -    var actionMenu=guestActions.find("div[name=actionmenu]");
>> -    if (openMenu) {
>> -        $('.popover', actionMenu).toggle();
>> +    }else{
>> +        guestActions.find('.btn').attr('disabled', true);
>> + result.find('.guest-clone').removeClass('hide-content');
>> +        $('.popover', 
>> guestActions.find("div[name=actionmenu]")).remove();
>>       }
>>
>>       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>
>> diff --git a/ui/pages/i18n.json.tmpl b/ui/pages/i18n.json.tmpl
>> index 75f1e43..56abd36 100644
>> --- a/ui/pages/i18n.json.tmpl
>> +++ b/ui/pages/i18n.json.tmpl
>> @@ -128,6 +128,7 @@
>>       "KCHVM6007M": "$_("Note the guest OS may ignore this request. 
>> Would you like to continue?")",
>>       "KCHVM6008M": "$_("Virtual Machine delete Confirmation")",
>>       "KCHVM6009M": "$_("This virtual machine is not persistent. 
>> Power Off will delete it. Continue?")",
>> +    "KCHVM6010M": "$_("When the target guest has SCSI or iSCSI 
>> volumes, they will be cloned on default storage pool. The same will 
>> happen when the target pool does not have enough space to clone the 
>> volumes. Do you want to continue?")",
>>
>>       "KCHVMCD6001M": "$_("This CDROM will be detached permanently 
>> and you can re-attach it. Continue to detach it?")",
>>       "KCHVMCD6002M": "$_("Attach")",
>





More information about the Kimchi-devel mailing list