From: ShaoHe Feng <shaohef(a)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(a)linux.vnet.ibm.com>
Signed-off-by: Zhou Zheng Sheng <zhshzhou(a)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