[PATCH 0/2] Live Migration UI

From: samhenri <samuel.guimaraes@eldorado.org.br> This patch addes Live Migration functionality to the new-ui. I'm attaching Socorro initial commit because I had to merge and resolve conflicts with the current new-ui version of Guests tab. The "Delete this VM when the migration is completed" checkbox is currently disabled because it wasn't working properly (trying to delete VM before migration was complete). Socorro Stoppler (1): Initial checkin for live migration UI support samhenri (1): Fixing Live Migration for the new-ui Guests tab src/wok/plugins/ginger | 2 +- src/wok/plugins/kimchi/ui/js/src/kimchi.api.js | 3 +- .../kimchi/ui/js/src/kimchi.guest_livemigration.js | 109 +++++++++++++++++++++ .../plugins/kimchi/ui/js/src/kimchi.guest_main.js | 41 +++++++- .../kimchi/ui/pages/guest-migration.html.tmpl | 67 +++++++++++++ src/wok/plugins/kimchi/ui/pages/guest.html.tmpl | 3 +- src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl | 2 + src/wok/plugins/kimchi/ui/pages/network.html.tmpl | 1 - 8 files changed, 219 insertions(+), 9 deletions(-) create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.guest_livemigration.js create mode 100644 src/wok/plugins/kimchi/ui/pages/guest-migration.html.tmpl -- 1.9.3

From: Socorro Stoppler <socorro@linux.vnet.ibm.com> Signed-off-by: Socorro Stoppler <socorro@linux.vnet.ibm.com> Signed-off-by: samhenri <samuel.guimaraes@eldorado.org.br> --- src/wok/plugins/ginger | 2 +- src/wok/plugins/kimchi/ui/js/src/kimchi.api.js | 3 +- .../plugins/kimchi/ui/js/src/kimchi.guest_main.js | 44 ++++++++++++++- .../kimchi/ui/pages/guest-migration.html.tmpl | 65 ++++++++++++++++++++++ src/wok/plugins/kimchi/ui/pages/guest.html.tmpl | 1 + 5 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 src/wok/plugins/kimchi/ui/pages/guest-migration.html.tmpl diff --git a/src/wok/plugins/ginger b/src/wok/plugins/ginger index a0cc2a3..84f36db 160000 --- a/src/wok/plugins/ginger +++ b/src/wok/plugins/ginger @@ -1 +1 @@ -Subproject commit a0cc2a369abf5ec93068924c3b681957d1c82cb3 +Subproject commit 84f36dbbfe63869fa97cd68e9abdeaffdf1846d9 diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js index cb6aaab..6cc8714 100644 --- a/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js +++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js @@ -1045,12 +1045,13 @@ var kimchi = { }); }, - migrateGuest: function(vm, suc, err) { + migrateGuest: function(vm, data, suc, err) { wok.requestJSON({ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + "/migrate", type : 'POST', contentType : 'application/json', dataType : 'json', + data : JSON.stringify(data), success : suc, error : err ? err : function(data) { wok.message.error(data.responseJSON.reason); diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js index 3287c00..de832ea 100644 --- a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js +++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js @@ -303,8 +303,24 @@ kimchi.listVmsAuto = function() { }, null, true); return guests; }; + var getMigratingGuests = function(){ + var guests = []; + kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/vms/.+/migrate'), function(tasks) { + for(var i=0;i<tasks.length;i++){ + var guestUri = tasks[i].target_uri; + var guestName = guestUri.split('/')[4] + guests.push($.extend({}, kimchi.sampleGuestObject, {name: guestName, isMigrating: true})); + if(kimchi.trackingTasks.indexOf(tasks[i].id)==-1) + kimchi.trackTask(tasks[i].id, null, function(err){ + wok.message.error(err.message); + }, null); + } + }, null, true); + return guests; + }; kimchi.listVMs(function(result, textStatus, jqXHR) { if (result && textStatus == "success") { + result = getMigratingGuests().concat(result); result = getCloningGuests().concat(result); result = getCreatingGuests().concat(result); if (result.length) { @@ -344,6 +360,26 @@ kimchi.listVmsAuto = function() { kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { var result = kimchi.guestElem.clone(); + var initializeMigratePanel = function() { + $("#migrateFormOk").on("click", function() { + //TODO: Get values from UI for remote_host, user, password + var data = { + "remote_host" : "ltc-hab1.aus.stglabs.ibm.com", + "user" : "root", + "password" : "passw0rd" + }; + //TODO: Need to get guest to be passed in here + kimchi.migrateGuest(guest, data, function(){ + kimchi.listVmsAuto(); + wok.window.close(); + }, function(err) { + wok.message.error(err.responseJSON.reason); + }); + }); + } + + initializeMigratePanel(); + //Setup the VM list entry var currentState = result.find('.guest-state'); var vmRunningBool = (vmObject.state == "running"); @@ -589,7 +625,7 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { } //Setup action event handlers - if (!(vmObject.isCloning || vmObject.isCreating)) { + if(!(vmObject.isCloning || vmObject.isCreating || vmObject.isMigrating)){ guestActions.find("[name=vm-start]").on("click", function(event) { event.preventDefault(); @@ -648,12 +684,18 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { }); }, null); }); + guestActions.find("[name=vm-migrate]").click(function(){ + var guest = $(this).closest('li[name=guest]').attr("id"); + wok.window.open('plugins/kimchi/guest-migration.html'); + }); } else { guestActions.find('.btn').attr('disabled', true); result.find('.guest-pending').removeClass('hide-content'); pendingText = result.find('.guest-pending .text') if (vmObject.isCloning) pendingText.text(i18n['KCHAPI6009M']); + else if(vmObject.isMigrating) + pendingText.text("Migrating"); else pendingText.text(i18n['KCHAPI6008M']); } diff --git a/src/wok/plugins/kimchi/ui/pages/guest-migration.html.tmpl b/src/wok/plugins/kimchi/ui/pages/guest-migration.html.tmpl new file mode 100644 index 0000000..278d22c --- /dev/null +++ b/src/wok/plugins/kimchi/ui/pages/guest-migration.html.tmpl @@ -0,0 +1,65 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2015 + * + * 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. + *# +#unicode UTF-8 +#import gettext +#from wok.cachebust import href +#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True) +#silent _ = t.gettext +#silent _t = t.gettext +<div id="migrate-guest-window" class="window modal-content"> + <div class="modal-header"> + <h4 class="modal-title" id="migrateModalLabel">$_("Migrate a Guest")</h4> + </div> + <div id="migrateInfo" class="modal-body"> + <div class="alert alert-warning" role="alert">Disclaimer: This process cannot be stopped after started, + can take a long time to complete and will turn off the VM on this Hypervisor when it is successfully + migrated to the remote destination. + </div> + <div class="form-group"> + <label for="remoteHostName">$_("Remote Server")</label> + <input type="text" class="form-control" id="remoteHostName" /> + <p class="help-block"> + <i class="fa fa-info-circle"></i> $_("IP Address or Hostname")</p> + </div> + <div class="alert alert-info" role="alert">The following fields are optional. Fill them if you want Kimchi to + setup a password-less ssh session between the localhost and the remote host. The setup process will only + be successful if the user has 'SUDO ALL' permission in the remote machine. + </div> + <div class="form-group"> + <label for="user">$_("User")</label> + <input type="text" class="form-control" id="user" /> + <p class="help-block"> + <i class="fa fa-info-circle"></i> $_("Username of the remote host")</p> + </div> + <div class="form-group"> + <label for="password">$_("Password")</label> + <input type="password" class="form-control" id="password" /> + <p class="help-block"> + <i class="fa fa-info-circle"></i> $_("Password of the user in the remote host")</p> + </div> + <div class="form-group"> + <input id="deleteVM" class="wok-checkbox" type="checkbox" value="" /> + <label for="deleteVM" id="labelDeleteVM">$_("Delete this VM when the migration is completed") </label> + </div> + </div> + <div class="modal-footer"> + <button type="submit" id="migrateFormOk" class="btn btn-default">$_("Start")</button> + <button type="button" id="migrateFormCancel" data-dismiss="modal" class="btn btn-default">$_("Cancel")</button> + </div> +</div> + diff --git a/src/wok/plugins/kimchi/ui/pages/guest.html.tmpl b/src/wok/plugins/kimchi/ui/pages/guest.html.tmpl index c2d9ba8..f5d28f1 100644 --- a/src/wok/plugins/kimchi/ui/pages/guest.html.tmpl +++ b/src/wok/plugins/kimchi/ui/pages/guest.html.tmpl @@ -62,6 +62,7 @@ <div class="progress-bar medium-grey cpu"></div> <div class="progress-bar light-grey cpu"></div> <div class="progress-bar cpu-progress-bar"></div> + <button class="button-big" name="vm-migrate"><span class="text">$_("Migrate")</span></button> </div> </span><!-- --><span class="item-hidden">$_("Processors Used")</span><!-- -- 1.9.3

From: samhenri <samuel.guimaraes@eldorado.org.br> Signed-off-by: samhenri <samuel.guimaraes@eldorado.org.br> --- .../kimchi/ui/js/src/kimchi.guest_livemigration.js | 109 +++++++++++++++++++++ .../plugins/kimchi/ui/js/src/kimchi.guest_main.js | 81 +++++++-------- .../kimchi/ui/pages/guest-migration.html.tmpl | 78 ++++++++------- src/wok/plugins/kimchi/ui/pages/guest.html.tmpl | 4 +- src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl | 2 + src/wok/plugins/kimchi/ui/pages/network.html.tmpl | 1 - 6 files changed, 188 insertions(+), 87 deletions(-) create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.guest_livemigration.js diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_livemigration.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_livemigration.js new file mode 100644 index 0000000..48ad302 --- /dev/null +++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_livemigration.js @@ -0,0 +1,109 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013-2015 + * + * 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. + */ + +kimchi.guest_livemigration_main = function() { + kimchi.setupLiveMigrationFormEvent(); + kimchi.initLiveMigrationDialog(); + console.log(kimchi.selectedGuest); +}; + +kimchi.startLiveMigration = function() { + var errorCallback = function() { + $("#migrateFormOk").prop("disabled", false); + $("#remoteHostName").removeAttr("readonly"); + $("#username").removeAttr("readonly"); + $("#password").removeAttr("readonly"); + $("#deleteVM").removeAttr("readonly"); + $("#deleteVM").prop("checked", false); + $("#migrateFormOk").text(i18n.KCHAPI6011M); + }; + var values = kimchi.getLiveMigrationDialogValues(); + var data = { + remote_host: values.remote_host, + user: values.user, + password: values.password + }; + kimchi.migrateGuest(kimchi.selectedGuest, data, function() { + kimchi.listVmsAuto(); + wok.window.close(); + }, function(err) { + wok.message.error(err.responseJSON.reason, "#alert-modal-container"); + errorCallback(); + }); +}; + +kimchi.initLiveMigrationDialog = function(okCallback) { + $("#migrateFormOk").on("click", function() { + $("#migrateFormOk").prop("disabled", true); + $("#remoteHostName").prop("readonly", "readonly"); + $("#username").prop("readonly", "readonly"); + $("#password").prop("readonly", "readonly"); + $("#deleteVM").prop("readonly", "readonly"); + $("#migrateFormOk").text(i18n.KCHAPI6010M); + kimchi.startLiveMigration(); + }); +}; + + +kimchi.getLiveMigrationDialogValues = function() { + var data = { + remote_host: $("#remoteHostName").val(), + user: $("#username").val(), + password: $("#password").val() + }; + return data; +}; + +kimchi.setupLiveMigrationFormEvent = function() { + $("#migrateFormOk").prop("disabled", true); + $("#remoteHostName").on("change keyup", function(event) { + if (!this.value) { + $(this).parent().addClass('has-error'); + } else { + $(this).parent().removeClass('has-error'); + } + kimchi.updateLiveMigrationButton(); + }); + $("#username").on("change keyup", function(event) { + if (this.value && !$("#password").val()) { + $("#username").parent().removeClass('has-warning'); + $("#password").parent().addClass('has-warning'); + } else { + $("#username").parent().removeClass('has-warning'); + $("#password").parent().removeClass('has-warning'); + } + kimchi.updateLiveMigrationButton(); + }); + $("#password").on("change keyup", function(event) { + if (this.value && !$("#username").val()) { + $("#username").parent().addClass('has-warning'); + } else { + $("#username").parent().removeClass('has-warning'); + $("#password").parent().removeClass('has-warning'); + kimchi.updateLiveMigrationButton(); + } + }); +}; + +kimchi.updateLiveMigrationButton = function() { + if ($("input[type='text']").parent().hasClass("has-error") || $("input[type='text']").parent().hasClass("has-warning")) { + $("#migrateFormOk").prop("disabled", true); + } else { + $("#migrateFormOk").prop("disabled", false); + } +}; \ No newline at end of file diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js index de832ea..2b0ef0c 100644 --- a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js +++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js @@ -229,6 +229,14 @@ kimchi.vmedit = function(event) { }); }; +kimchi.vmmigrate = function(event) { + var button = event.target; + var vm = $(button).closest('li[name=guest]'); + var vm_id = $(vm).attr("id"); + kimchi.selectedGuest = vm_id; + wok.window.open('plugins/kimchi/guest-migration.html'); +}; + kimchi.openVmConsole = function(event) { var button = event.target; var vm = $(button).closest('li[name=guest]'); @@ -303,24 +311,27 @@ kimchi.listVmsAuto = function() { }, null, true); return guests; }; - var getMigratingGuests = function(){ - var guests = []; - kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/vms/.+/migrate'), function(tasks) { - for(var i=0;i<tasks.length;i++){ - var guestUri = tasks[i].target_uri; - var guestName = guestUri.split('/')[4] - guests.push($.extend({}, kimchi.sampleGuestObject, {name: guestName, isMigrating: true})); - if(kimchi.trackingTasks.indexOf(tasks[i].id)==-1) - kimchi.trackTask(tasks[i].id, null, function(err){ - wok.message.error(err.message); - }, null); - } - }, null, true); - return guests; - }; + var getMigratingGuests = function() { + var guests = []; + kimchi.getTasksByFilter('status=running&target_uri=' + encodeURIComponent('^/vms/.+/migrate'), function(tasks) { + for (var i = 0; i < tasks.length; i++) { + var guestUri = tasks[i].target_uri; + var guestName = guestUri.split('/')[4] + guests.push($.extend({}, kimchi.sampleGuestObject, { + name: guestName, + isMigrating: true + })); + if (kimchi.trackingTasks.indexOf(tasks[i].id) == -1) + kimchi.trackTask(tasks[i].id, null, function(err) { + wok.message.error(err.message); + }, null); + } + }, null, true); + return guests; + }; kimchi.listVMs(function(result, textStatus, jqXHR) { if (result && textStatus == "success") { - result = getMigratingGuests().concat(result); + result = getMigratingGuests().concat(result); result = getCloningGuests().concat(result); result = getCreatingGuests().concat(result); if (result.length) { @@ -359,27 +370,6 @@ kimchi.listVmsAuto = function() { kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { var result = kimchi.guestElem.clone(); - - var initializeMigratePanel = function() { - $("#migrateFormOk").on("click", function() { - //TODO: Get values from UI for remote_host, user, password - var data = { - "remote_host" : "ltc-hab1.aus.stglabs.ibm.com", - "user" : "root", - "password" : "passw0rd" - }; - //TODO: Need to get guest to be passed in here - kimchi.migrateGuest(guest, data, function(){ - kimchi.listVmsAuto(); - wok.window.close(); - }, function(err) { - wok.message.error(err.responseJSON.reason); - }); - }); - } - - initializeMigratePanel(); - //Setup the VM list entry var currentState = result.find('.guest-state'); var vmRunningBool = (vmObject.state == "running"); @@ -399,7 +389,6 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { //Add the OS Type and Icon var osType = result.find('.distro-icon'); - console.log(vmObject); if (vmObject.icon == 'plugins/kimchi/images/icon-fedora.png') { osType.addClass('icon-fedora'); osType.attr('val', 'Fedora'); @@ -434,7 +423,7 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { //Setup the VM console thumbnail display var curImg = vmObject.icon; if (vmObject.screenshot) { - curImg = vmObject.screenshot.replace(/^\//,''); + curImg = vmObject.screenshot.replace(/^\//, ''); } var load_src = curImg || 'plugins/kimchi/images/icon-vm.png'; var tile_src = prevScreenImage || vmObject['load-src']; @@ -590,7 +579,7 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { result.addClass('inactive'); result.find('.distro-icon').addClass('inactive'); result.find('.vnc-link').css("display", "none"); - result.find('.column-vnc').html('--'); + result.find('.column-vnc').html('--'); //Hide PowerOff guestActions.find(".shutoff-hidden").hide(); //Hide Pause @@ -625,7 +614,7 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { } //Setup action event handlers - if(!(vmObject.isCloning || vmObject.isCreating || vmObject.isMigrating)){ + if (!(vmObject.isCloning || vmObject.isCreating || vmObject.isMigrating)) { guestActions.find("[name=vm-start]").on("click", function(event) { event.preventDefault(); @@ -684,17 +673,17 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { }); }, null); }); - guestActions.find("[name=vm-migrate]").click(function(){ - var guest = $(this).closest('li[name=guest]').attr("id"); - wok.window.open('plugins/kimchi/guest-migration.html'); - }); + guestActions.find("[name=vm-migrate]").on('click', function() { + event.preventDefault(); + kimchi.vmmigrate(event); + }); } else { guestActions.find('.btn').attr('disabled', true); result.find('.guest-pending').removeClass('hide-content'); pendingText = result.find('.guest-pending .text') if (vmObject.isCloning) pendingText.text(i18n['KCHAPI6009M']); - else if(vmObject.isMigrating) + else if (vmObject.isMigrating) pendingText.text("Migrating"); else pendingText.text(i18n['KCHAPI6008M']); diff --git a/src/wok/plugins/kimchi/ui/pages/guest-migration.html.tmpl b/src/wok/plugins/kimchi/ui/pages/guest-migration.html.tmpl index 278d22c..7cac2c5 100644 --- a/src/wok/plugins/kimchi/ui/pages/guest-migration.html.tmpl +++ b/src/wok/plugins/kimchi/ui/pages/guest-migration.html.tmpl @@ -21,45 +21,47 @@ #silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True) #silent _ = t.gettext #silent _t = t.gettext -<div id="migrate-guest-window" class="window modal-content"> - <div class="modal-header"> - <h4 class="modal-title" id="migrateModalLabel">$_("Migrate a Guest")</h4> - </div> - <div id="migrateInfo" class="modal-body"> - <div class="alert alert-warning" role="alert">Disclaimer: This process cannot be stopped after started, - can take a long time to complete and will turn off the VM on this Hypervisor when it is successfully - migrated to the remote destination. - </div> - <div class="form-group"> - <label for="remoteHostName">$_("Remote Server")</label> - <input type="text" class="form-control" id="remoteHostName" /> - <p class="help-block"> - <i class="fa fa-info-circle"></i> $_("IP Address or Hostname")</p> - </div> - <div class="alert alert-info" role="alert">The following fields are optional. Fill them if you want Kimchi to - setup a password-less ssh session between the localhost and the remote host. The setup process will only - be successful if the user has 'SUDO ALL' permission in the remote machine. +<!DOCTYPE html> +<html> +<body> + <div id="migrate-guest-window" class="window modal-content"> + <div class="modal-header"> + <h4 class="modal-title" id="migrateModalLabel">$_("Migrate a Guest")</h4> </div> - <div class="form-group"> - <label for="user">$_("User")</label> - <input type="text" class="form-control" id="user" /> - <p class="help-block"> - <i class="fa fa-info-circle"></i> $_("Username of the remote host")</p> + <div id="migrateInfo" class="modal-body"> + <span id="alert-modal-container"></span> + <div class="alert alert-warning" role="alert">$_("Disclaimer: This process cannot be stopped after started, can take a long time to complete and will turn off the VM on this Hypervisor when it is successfully migrated to the remote destination.")</div> + <div class="form-group"> + <label for="remoteHostName">$_("Remote Server")</label> + <input type="text" class="form-control" id="remoteHostName" /> + <p class="help-block"> + <i class="fa fa-info-circle"></i> $_("IP Address or Hostname")</p> + </div> + <div class="alert alert-info" role="alert">$_("The following fields are optional. Fill them if you want Kimchi to setup a password-less ssh session between the localhost and the remote host. The setup process will only be successful if the user has 'SUDO ALL' permission in the remote machine.")</div> + <div class="form-group"> + <label for="username">$_("User")</label> + <input type="text" class="form-control" id="username" /> + <p class="help-block"> + <i class="fa fa-info-circle"></i> $_("Username of the remote host")</p> + </div> + <div class="form-group"> + <label for="password">$_("Password")</label> + <input type="password" class="form-control" id="password" /> + <p class="help-block"> + <i class="fa fa-info-circle"></i> $_("Password of the user in the remote host")</p> + </div> + <div class="form-group"> + <input id="deleteVM" class="wok-checkbox" type="checkbox" value="" /> + <label for="deleteVM" id="labelDeleteVM">$_("Delete this VM when the migration is completed") </label> + </div> </div> - <div class="form-group"> - <label for="password">$_("Password")</label> - <input type="password" class="form-control" id="password" /> - <p class="help-block"> - <i class="fa fa-info-circle"></i> $_("Password of the user in the remote host")</p> + <div class="modal-footer"> + <button type="submit" id="migrateFormOk" class="btn btn-default">$_("Start")</button> + <button type="button" id="migrateFormCancel" data-dismiss="modal" class="btn btn-default">$_("Cancel")</button> </div> - <div class="form-group"> - <input id="deleteVM" class="wok-checkbox" type="checkbox" value="" /> - <label for="deleteVM" id="labelDeleteVM">$_("Delete this VM when the migration is completed") </label> - </div> - </div> - <div class="modal-footer"> - <button type="submit" id="migrateFormOk" class="btn btn-default">$_("Start")</button> - <button type="button" id="migrateFormCancel" data-dismiss="modal" class="btn btn-default">$_("Cancel")</button> </div> -</div> - + <script> + kimchi.guest_livemigration_main(); + </script> +</body> +</html> diff --git a/src/wok/plugins/kimchi/ui/pages/guest.html.tmpl b/src/wok/plugins/kimchi/ui/pages/guest.html.tmpl index f5d28f1..11feb5c 100644 --- a/src/wok/plugins/kimchi/ui/pages/guest.html.tmpl +++ b/src/wok/plugins/kimchi/ui/pages/guest.html.tmpl @@ -40,7 +40,8 @@ <li role="presentation"><a nwAct="connect-vnc" class='shutoff-disabled' name="vm-console" href="#"><i class="fa fa-list-alt"></i>$_("Connect VNC")</a></li> <!-- <li role="presentation"><a nwAct="view-vnc" class='shutoff-disabled' name="vm-view-vnc" href="#"><i class="fa fa-eye"></i>$_("View VNC Console")</a></li> --> <li role="presentation"><a nwAct="edit" name="vm-edit" href="#"><i class="fa fa-pencil"></i>$_("Edit")</a></li> - <li role="presentation"><a href="#" nwAct="clone" class='running-disabled' name="vm-clone"><i class="fa fa-copy"></i>$_("Clone")</a></li> + <li role="presentation"><a nwAct="clone" class='running-disabled' name="vm-clone" href="#"><i class="fa fa-copy"></i>$_("Clone")</a></li> + <li role="presentation"><a nwAct="migrate" name="vm-migrate" href="#"><i class="fa fa-exchange"></i>$_("Migrate")</a></li> <li role="presentation"><a nwAct="reset" class='shutoff-hidden non-persistent-disabled' name="vm-reset" href="#"><i class="fa fa-refresh"></i>$_("Reset")</a></li> <li role="presentation"><a nwAct="pause" class='pause-hidden non-persistent-disabled' name="vm-pause" href="#"><i class="fa fa-pause"></i>$_("Pause")</a></li> <li role="presentation"><a nwAct="resume" class='resume-hidden' name="vm-resume" href="#"><i class="fa fa-play-circle"></i>$_("Resume")</a></li> @@ -62,7 +63,6 @@ <div class="progress-bar medium-grey cpu"></div> <div class="progress-bar light-grey cpu"></div> <div class="progress-bar cpu-progress-bar"></div> - <button class="button-big" name="vm-migrate"><span class="text">$_("Migrate")</span></button> </div> </span><!-- --><span class="item-hidden">$_("Processors Used")</span><!-- diff --git a/src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl b/src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl index d356437..bee3ad1 100644 --- a/src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl +++ b/src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl @@ -43,6 +43,8 @@ "KCHAPI6007M": "$_("Save")", "KCHAPI6008M": "$_("Creating...")", "KCHAPI6009M": "$_("Cloning...")", + "KCHAPI6010M": "$_("Migrating...")", + "KCHAPI6011M": "$_("Start")", "KCHTMPL6001W": "$_("No ISO found")", diff --git a/src/wok/plugins/kimchi/ui/pages/network.html.tmpl b/src/wok/plugins/kimchi/ui/pages/network.html.tmpl index 722fc11..d607c39 100644 --- a/src/wok/plugins/kimchi/ui/pages/network.html.tmpl +++ b/src/wok/plugins/kimchi/ui/pages/network.html.tmpl @@ -25,7 +25,6 @@ <!DOCTYPE html> <html> <head> -<link rel="stylesheet" href="plugins/kimchi/css/theme-default.min.css"> <script src="plugins/kimchi/js/kimchi.min.js"></script> </head> <body> -- 1.9.3

As soon as I am able to test the live migration (testing environment is offline ATM) I'll test this patch set. Daniel On 11/27/2015 05:06 PM, sguimaraes943@gmail.com wrote:
From: samhenri <samuel.guimaraes@eldorado.org.br>
This patch addes Live Migration functionality to the new-ui.
I'm attaching Socorro initial commit because I had to merge and resolve conflicts with the current new-ui version of Guests tab. The "Delete this VM when the migration is completed" checkbox is currently disabled because it wasn't working properly (trying to delete VM before migration was complete).
Socorro Stoppler (1): Initial checkin for live migration UI support
samhenri (1): Fixing Live Migration for the new-ui Guests tab
src/wok/plugins/ginger | 2 +- src/wok/plugins/kimchi/ui/js/src/kimchi.api.js | 3 +- .../kimchi/ui/js/src/kimchi.guest_livemigration.js | 109 +++++++++++++++++++++ .../plugins/kimchi/ui/js/src/kimchi.guest_main.js | 41 +++++++- .../kimchi/ui/pages/guest-migration.html.tmpl | 67 +++++++++++++ src/wok/plugins/kimchi/ui/pages/guest.html.tmpl | 3 +- src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl | 2 + src/wok/plugins/kimchi/ui/pages/network.html.tmpl | 1 - 8 files changed, 219 insertions(+), 9 deletions(-) create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.guest_livemigration.js create mode 100644 src/wok/plugins/kimchi/ui/pages/guest-migration.html.tmpl
participants (2)
-
Daniel Henrique Barboza
-
sguimaraes943@gmail.com