[PATCH V2 0/3] VM shutdown support in backend

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> V1 -> V2 update a new domain state pmsuspended ShaoHe Feng (3): VM shutdown support in backend VM shutdown support in UI New domain state pmsuspended docs/API.md | 3 +++ src/kimchi/control/vms.py | 1 + src/kimchi/i18n.py | 1 + src/kimchi/mockmodel.py | 3 +++ src/kimchi/model/vms.py | 11 ++++++++++- ui/js/src/kimchi.api.js | 11 +++++++++++ ui/js/src/kimchi.guest_main.js | 23 +++++++++++++++++++++++ ui/pages/guest.html.tmpl | 1 + ui/pages/i18n.html.tmpl | 2 ++ 9 files changed, 55 insertions(+), 1 deletion(-) -- 1.9.0

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> Shutdown command stop guest graceful. Guest os will react to a shutdown request after the the request is issued. The differences from power off are that the guests disk storage will be in a stable state rather than having the (virtual) power cord pulled. Note that the guest OS may ignore the request, so the vm is not stopped. Additionally, the hypervisor may check and support the VM 'on_poweroff' XML setting resulting in a domain that reboots instead of shutting down. For kimchi will not set 'on_poweroff' for VM XML configure. So kimchi will not check the 'on_poweroff' setting of VM. So if VM is create by other management tool and set 'on_poweroff' as reboot, kimchi still will call this shutdown command. Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> Signed-off-by: Zhou Zheng Sheng <zhshzhou@linux.vnet.ibm.com> --- docs/API.md | 3 +++ src/kimchi/control/vms.py | 1 + src/kimchi/i18n.py | 1 + src/kimchi/mockmodel.py | 3 +++ src/kimchi/model/vms.py | 8 ++++++++ 5 files changed, 16 insertions(+) diff --git a/docs/API.md b/docs/API.md index 716c983..0394824 100644 --- a/docs/API.md +++ b/docs/API.md @@ -110,6 +110,9 @@ the following general conventions: * start: Power on a VM * poweroff: Power off a VM forcefully. Note this action may produce undesirable results, for example unflushed disk cache in the guest. +* shutdown: Shut down a VM graceful. This action issue shutdown request to guest. + And the guest will react this request. Note the guest OS may ignore + the request. * reset: Reset a VM immediately without the guest OS shutdown. It emulates the power reset button on a machine. Note that there is a risk of data loss caused by reset without the guest OS shutdown. diff --git a/src/kimchi/control/vms.py b/src/kimchi/control/vms.py index ea810e4..c7a1ff7 100644 --- a/src/kimchi/control/vms.py +++ b/src/kimchi/control/vms.py @@ -39,6 +39,7 @@ class VM(Resource): setattr(self, ident, node(model, self.ident)) self.start = self.generate_action_handler('start') self.poweroff = self.generate_action_handler('poweroff') + self.shutdown = self.generate_action_handler('shutdown') self.reset = self.generate_action_handler('reset') self.connect = self.generate_action_handler('connect') diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py index 3fc3013..1f8703e 100644 --- a/src/kimchi/i18n.py +++ b/src/kimchi/i18n.py @@ -86,6 +86,7 @@ messages = { "KCHVM0026E": _("Group name must be a string"), "KCHVM0027E": _("User %(user)s does not exist"), "KCHVM0028E": _("Group %(group)s does not exist"), + "KCHVM0029E": _("Unable to shutdown virtual machine %(name)s. Details: %(err)s"), "KCHVMIF0001E": _("Interface %(iface)s does not exist in virtual machine %(name)s"), "KCHVMIF0002E": _("Network %(network)s specified for virtual machine %(name)s does not exist"), diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py index 8c7d7bb..1bf0000 100644 --- a/src/kimchi/mockmodel.py +++ b/src/kimchi/mockmodel.py @@ -132,6 +132,9 @@ class MockModel(object): def vm_poweroff(self, name): self._get_vm(name).info['state'] = 'shutoff' + def vm_shutdown(self, name): + self._get_vm(name).info['state'] = 'shutoff' + def vm_reset(self, name): pass diff --git a/src/kimchi/model/vms.py b/src/kimchi/model/vms.py index 90e9537..98e4a9f 100644 --- a/src/kimchi/model/vms.py +++ b/src/kimchi/model/vms.py @@ -439,6 +439,14 @@ class VMModel(object): raise OperationFailed("KCHVM0020E", {'name': name, 'err': e.get_error_message()}) + def shutdown(self, name): + dom = self.get_vm(name, self.conn) + try: + dom.shutdown() + except libvirt.libvirtError as e: + raise OperationFailed("KCHVM0029E", + {'name': name, 'err': e.get_error_message()}) + def reset(self, name): dom = self.get_vm(name, self.conn) try: -- 1.9.0

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> Add a shutdown API and shutdown botton in UI. Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 11 +++++++++++ ui/js/src/kimchi.guest_main.js | 23 +++++++++++++++++++++++ ui/pages/guest.html.tmpl | 1 + ui/pages/i18n.html.tmpl | 2 ++ 4 files changed, 37 insertions(+) diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index e96a67a..29a5770 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -230,6 +230,17 @@ var kimchi = { }); }, + shutdownVM : function(vm, suc, err) { + kimchi.requestJSON({ + url : kimchi.url + 'vms/' + encodeURIComponent(vm) + '/shutdown', + type : 'POST', + contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); + }, + resetVM : function(vm, suc, err) { kimchi.requestJSON({ url : kimchi.url + 'vms/' + encodeURIComponent(vm) + '/reset', diff --git a/ui/js/src/kimchi.guest_main.js b/ui/js/src/kimchi.guest_main.js index 891e717..510e7f9 100644 --- a/ui/js/src/kimchi.guest_main.js +++ b/ui/js/src/kimchi.guest_main.js @@ -64,6 +64,26 @@ kimchi.vmpoweroff = function(event) { } }; +kimchi.vmshutdown = function(event){ + var vm=$(this).closest('li[name=guest]'); + var vm_id=vm.attr("id"); + var settings = { + title : i18n['KCHVM6006M'], + content : i18n['KCHVM6007M'], + confirm : i18n['KCHAPI6002M'], + cancel : i18n['KCHAPI6003M'] + }; + kimchi.confirm(settings, function() { + kimchi.shutdownVM(vm_id, function(result) { + kimchi.listVmsAuto(); + }, function(err) { + kimchi.message.error(err.responseJSON.reason); + } + ); + }, function() { + }); +}; + kimchi.vmreset = function(event){ var vm=$(this).closest('li[name=guest]'); var vm_id=vm.attr("id"); @@ -270,6 +290,9 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { 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-media]").on({click : kimchi.vmmedia}); guestActions.find("[name=vm-edit]").on({click : kimchi.vmedit}); guestActions.find("[name=vm-delete]").on({click : kimchi.vmdelete}); diff --git a/ui/pages/guest.html.tmpl b/ui/pages/guest.html.tmpl index 588b7b0..c7335c8 100644 --- a/ui/pages/guest.html.tmpl +++ b/ui/pages/guest.html.tmpl @@ -59,6 +59,7 @@ <button class="button-big shutoff-disabled" name="vm-media"><span class="text">$_("Manage Media")</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> <button class="button-big running-hidden" name="vm-start"><span class="text">$_("Start")</span></button> <button class="button-big shutoff-hidden" name="vm-poweroff"><span class="text">$_("Power Off")</span></button> <a class="button-big red " name="vm-delete">$_("Delete")</a> diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl index 6588dff..98da828 100644 --- a/ui/pages/i18n.html.tmpl +++ b/ui/pages/i18n.html.tmpl @@ -132,6 +132,8 @@ var i18n = { 'KCHVM6004M': "$_("Reset Confirmation")", 'KCHVM6005M': "$_("There is a risk of data loss caused by reset without" " the guest OS shutdown. Would you like to continue?")", + 'KCHVM6006M': "$_("Shut Down Confirmation")", + 'KCHVM6007M': "$_("Note the guest OS may ignore this request. Would you like to continue?")", 'KCHVMCD6001M': "$_("This CDROM will be detached permanently and you can re-attach it. Continue to detach it?")", 'KCHVMCD6002M': "$_("Attach")", -- 1.9.0

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> libvirt introduces a new domain state pmsuspended to represent the domain which has been suspended by guest power management, e.g. (entered itno s3 state). Because a "running" state could be confused in this case, one will see the guest is paused actually while playing. And state "paused" is for the domain which was paused by virDomainSuspend. update this state in kimchi Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- src/kimchi/model/vms.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/kimchi/model/vms.py b/src/kimchi/model/vms.py index 98e4a9f..f0fa706 100644 --- a/src/kimchi/model/vms.py +++ b/src/kimchi/model/vms.py @@ -48,7 +48,8 @@ DOM_STATE_MAP = {0: 'nostate', 3: 'paused', 4: 'shutdown', 5: 'shutoff', - 6: 'crashed'} + 6: 'crashed', + 7: 'pmsuspended'} GUESTS_STATS_INTERVAL = 5 VM_STATIC_UPDATE_PARAMS = {'name': './name'} -- 1.9.0

On 04/22/2014 12:41 PM, shaohef@linux.vnet.ibm.com wrote:
From: ShaoHe Feng <shaohef@linux.vnet.ibm.com>
V1 -> V2 update a new domain state pmsuspended
ShaoHe Feng (3): VM shutdown support in backend VM shutdown support in UI New domain state pmsuspended
docs/API.md | 3 +++ src/kimchi/control/vms.py | 1 + src/kimchi/i18n.py | 1 + src/kimchi/mockmodel.py | 3 +++ src/kimchi/model/vms.py | 11 ++++++++++- ui/js/src/kimchi.api.js | 11 +++++++++++ ui/js/src/kimchi.guest_main.js | 23 +++++++++++++++++++++++ ui/pages/guest.html.tmpl | 1 + ui/pages/i18n.html.tmpl | 2 ++ 9 files changed, 55 insertions(+), 1 deletion(-)
I could not apply this patch. Needs rebase.
participants (2)
-
Aline Manera
-
shaohef@linux.vnet.ibm.com