
From: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com> Signed-off-by: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com> --- ui/css/theme-default/list.css | 18 ++++++++++ ui/js/src/kimchi.api.js | 13 +++++++ ui/js/src/kimchi.guest_main.js | 68 +++++++++++++++++++++++++++++++++++----- ui/pages/guest.html.tmpl | 4 ++ 4 files changed, 95 insertions(+), 8 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..216a7dd 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -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..113ddfb 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,20 @@ 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})); + } + }, 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 +273,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()}); + } } @@ -286,6 +328,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 +340,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..304749c 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,6 +59,7 @@ <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-hidden" name="vm-clone"><span class="text">$_("Clone")</span></button> <button class="button-big running-disabled" 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> -- 1.7.1

Sorry, but I can't test it because the backend patches on ML ([Kimchi-devel] [WIP PATCH 0/5] Clone VMs) do not apply for me. Cristian, could you test it with your patches and provide feedbacks for Yu Xin? Or you can also rebase and resend your patches to ML. On 10/20/2014 07:56 AM, huoyuxin@linux.vnet.ibm.com wrote:
From: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com>
Signed-off-by: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com> --- ui/css/theme-default/list.css | 18 ++++++++++ ui/js/src/kimchi.api.js | 13 +++++++ ui/js/src/kimchi.guest_main.js | 68 +++++++++++++++++++++++++++++++++++----- ui/pages/guest.html.tmpl | 4 ++ 4 files changed, 95 insertions(+), 8 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..216a7dd 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -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..113ddfb 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,20 @@ 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})); + } + }, 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 +273,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()}); + } }
@@ -286,6 +328,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 +340,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..304749c 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,6 +59,7 @@ <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-hidden" name="vm-clone"><span class="text">$_("Clone")</span></button> <button class="button-big running-disabled" 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>

On 20-10-2014 07:56, huoyuxin@linux.vnet.ibm.com wrote:
+ <div class="guest-clone hide-content"> + <span class="icon"></span><span class="text">$_("Cloning") ...</span> + </div>
Instead of "Cloning ...", it should be "Cloning..." (notice the space between the text and the ellipsis).
+ <button class="button-big running-hidden" name="vm-clone"><span class="text">$_("Clone")</span></button>
I think it's better to use the class "running-disabled" instead of "running-hidden". At least the user knows there's a clone operation but it's not available at the moment, when the VM is running. Also, I cannot see a message when an error is raised inside the task. The cloning VM simply disappears (which is correct) and nothing else is shown. You can check the field 'message' in the task output, and if it has the value 'failed', display the field 'message' as an error.

On 22-10-2014 11:26, Crístian Viana wrote:
You can check the field 'message' in the task output, and if it has the value 'failed', display the field 'message' as an error.
I'm sorry, there's a mistake in the sentence above. Let me rewrite it correctly: /You can check the field '*status*' in the task output, and if it has the value 'failed', display the field 'message' as an error. /

On 10/22/2014 9:34 PM, Crístian Viana wrote:
On 22-10-2014 11:26, Crístian Viana wrote:
You can check the field 'message' in the task output, and if it has the value 'failed', display the field 'message' as an error.
I'm sorry, there's a mistake in the sentence above. Let me rewrite it correctly:
/You can check the field '*status*' in the task output, and if it has the value 'failed', display the field 'message' as an error. / Thanks, addressed in V2.
participants (4)
-
Aline Manera
-
Crístian Viana
-
huoyuxin@linux.vnet.ibm.com
-
Yu Xin Huo