[Kimchi-devel] [v2] UI: Clone Guest
Aline Manera
alinefm at linux.vnet.ibm.com
Thu Oct 30 11:19:38 UTC 2014
On 10/30/2014 08:12 AM, Yu Xin Huo wrote:
> On 10/29/2014 2:39 AM, Aline Manera wrote:
>>
>> 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.
> For current long task design, the ongoing tasks will survive 'page
> switch', 'page refresh', 'logout/login'.
> So all tasks should be tracked only with information from '/tasks' API.
> Currently, in the response of '/tasks' API, there is no reliable way
> to get the original guest that is cloned from.
>
> Unless a reliable way to get the original target guest from '/tasks',
> we can only keep live tile to be default.
You are right! I had forgotten the switch tabs case.
So keep using the default icon.
>>
>> 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