[kupfer: 6/11] plugin.virtualbox: simplify and cleanup code



commit 29f6aa18b2d53c2b45a53684b151d4d790734a35
Author: Karol BÄ?dkowski <karol bedkowsk+gh gmail com>
Date:   Sun Oct 18 22:10:45 2009 +0200

    plugin.virtualbox: simplify and cleanup code
    
    - Move all constants to virtualbox_const.py
    - reduce number of functions (mainly for change state of vms).

 kupfer/plugin/virtualbox.py                 |   66 +++++++++-------------
 kupfer/plugin/virtualbox_const.py           |   25 ++++++++
 kupfer/plugin/virtualbox_ose_support.py     |   74 ++++++++++++++-----------
 kupfer/plugin/virtualbox_vboxapi_support.py |   80 ++++++++++++++++----------
 4 files changed, 144 insertions(+), 101 deletions(-)
---
diff --git a/kupfer/plugin/virtualbox.py b/kupfer/plugin/virtualbox.py
index e23a243..de59b94 100644
--- a/kupfer/plugin/virtualbox.py
+++ b/kupfer/plugin/virtualbox.py
@@ -6,8 +6,8 @@ from kupfer import pretty, plugin_support
 
 __kupfer_name__ = _("VirtualBox")
 __kupfer_sources__ = ("VBoxMachinesSource", )
-__description__ = _("Control Sun VirtualBox Virtual Machines")
-__version__ = "0.1"
+__description__ = _("Control Sun VirtualBox Virtual Machines. Support also VirtualBox OpenSource Edition.")
+__version__ = "0.2"
 __author__ = "Karol BÄ?dkowski <karol bedkowski gmail com>"
 __kupfer_settings__ = plugin_support.PluginSettings(
 		plugin_support.SETTING_PREFER_CATALOG,
@@ -21,6 +21,8 @@ except ImportError, err:
 	import virtualbox_ose_support as virtualbox_support
 	pretty.print_info(__name__, 'Using cli...', err)
 
+import virtualbox_const
+
 
 class VirtualMachine(Leaf):
 	def __init__(self, obj, name, description):
@@ -35,26 +37,31 @@ class VirtualMachine(Leaf):
 
 	def get_actions(self):
 		state = virtualbox_support.get_machine_state(self.object)
-		if state == virtualbox_support.VM_POWEROFF:
-			yield StartVM(_('Power On'), 'system-run', 'gui')
-			yield StartVM(_('Power On Headless'), 'system-run', 'headless', -5)
-		elif state == virtualbox_support.VM_POWERON:
-			yield StdVmAction(_('Send Power Off Signal'), 'system-shutdown', \
-					virtualbox_support.machine_acpipoweroff, -5)
-			yield StdVmAction(_('Pause'), 'pause', virtualbox_support.machine_pause)
-			yield StdVmAction(_('Reboot'), 'system-reboot', virtualbox_support.machine_reboot, -10)
-		else: # VM_PAUSED
-			yield StdVmAction(_('Resume'), 'resume', virtualbox_support.machine_resume)
-
-		if state in (virtualbox_support.VM_POWERON, virtualbox_support.VM_PAUSED):
-			yield StdVmAction(_('Save State'), 'system-supsend', virtualbox_support.machine_save)
-			yield StdVmAction(_('Power Off'), 'system-shutdown', virtualbox_support.machine_poweroff, -10)
-
-
-class _VMAction(Action):
-	def __init__(self, name, icon):
+		if state == virtualbox_const.VM_STATE_POWEROFF:
+			yield VMAction(_('Power On'), 'system-run', \
+					virtualbox_const.VM_START_NORMAL)
+			yield VMAction(_('Power On Headless'), 'system-run', \
+					virtualbox_const.VM_START_HEADLESS, -5)
+		elif state == virtualbox_const.VM_STATE_POWERON:
+			yield VMAction(_('Send Power Off Signal'), 'system-shutdown', \
+					virtualbox_const.VM_ACPI_POWEROFF, -5)
+			yield VMAction(_('Pause'), 'pause', virtualbox_const.VM_PAUSE)
+			yield VMAction(_('Reboot'), 'system-reboot', virtualbox_const.VM_REBOOT, -10)
+		else: # VM_STATE_PAUSED
+			yield VMAction(_('Resume'), 'resume', virtualbox_const.VM_RESUME)
+
+		if state in (virtualbox_const.VM_STATE_POWERON, virtualbox_const.VM_STATE_PAUSED):
+			yield VMAction(_('Save State'), 'system-supsend', virtualbox_const.VM_SAVE)
+			yield VMAction(_('Power Off'), 'system-shutdown', \
+					virtualbox_const.VM_POWEROFF, -10)
+
+
+class VMAction(Action):
+	def __init__(self, name, icon, command, rank_adjust=0):
 		Action.__init__(self, name)
 		self._icon = icon
+		self.rank_adjust = rank_adjust
+		self.command = command
 
 	def get_icon_name(self):
 		return self._icon
@@ -62,25 +69,8 @@ class _VMAction(Action):
 	def item_types(self):
 		yield VirtualMachine
 
-
-class StartVM(_VMAction):
-	def __init__(self, name, icon, mode, rank_adjust=0):
-		_VMAction.__init__(self, name, icon)
-		self.mode = mode
-		self.rank_adjust = rank_adjust
-
-	def activate(self, leaf):
-		virtualbox_support.machine_start(leaf.object, self.mode)
-
-
-class StdVmAction(_VMAction):
-	def __init__(self, name, icon, command, rank_adjust=0):
-		_VMAction.__init__(self, name, icon)
-		self.rank_adjust = rank_adjust
-		self.command = command
-
 	def activate(self, leaf):
-		self.command(leaf.object)
+		virtualbox_support.vm_action(self.command, leaf.object)
 
 
 class VBoxMachinesSource(AppLeafContentMixin, Source, PicklingHelperMixin, FilesystemWatchMixin):
diff --git a/kupfer/plugin/virtualbox_const.py b/kupfer/plugin/virtualbox_const.py
new file mode 100644
index 0000000..3ace381
--- /dev/null
+++ b/kupfer/plugin/virtualbox_const.py
@@ -0,0 +1,25 @@
+# -*- coding: UTF-8 -*-
+'''
+virtualbox_support.py
+
+Constants for VirtualBox
+'''
+__author__ = "Karol BÄ?dkowski <karol bedkowski gmail com>"
+__revision__ = '0.1'
+
+# virtual machine states
+VM_STATE_POWEROFF = 0
+VM_STATE_POWERON = 1
+VM_STATE_PAUSED = 2
+
+# virtual machine actions
+VM_START_NORMAL = 1
+VM_START_HEADLESS = 2
+VM_PAUSE = 3
+VM_POWEROFF = 4
+VM_ACPI_POWEROFF = 5
+VM_REBOOT = 6
+VM_RESUME = 7
+VM_SAVE = 8
+
+
diff --git a/kupfer/plugin/virtualbox_ose_support.py b/kupfer/plugin/virtualbox_ose_support.py
index 03a84f7..f8d9cb4 100644
--- a/kupfer/plugin/virtualbox_ose_support.py
+++ b/kupfer/plugin/virtualbox_ose_support.py
@@ -12,12 +12,8 @@ __author__ = "Karol BÄ?dkowski <karol bedkowski gmail com>"
 
 import os
 from xml.dom import minidom
-
 from kupfer import pretty, utils
-
-VM_POWEROFF = 0
-VM_POWERON = 1
-VM_PAUSED = 2
+import virtualbox_const
 
 _VBOX_CONFIG_DIR = os.path.expanduser('~/.VirtualBox/')
 _VBOX_CONFIG_FILE = os.path.join(_VBOX_CONFIG_DIR, 'VirtualBox.xml')
@@ -26,10 +22,20 @@ MONITORED_DIRS = (_VBOX_CONFIG_DIR, )
 IS_DYNAMIC = False
 ICON = "virtualbox-ose"
 
+# parameters for VBoxManage
+_ACTIONS = {
+		virtualbox_const.VM_POWEROFF: 'poweroff',
+		virtualbox_const.VM_ACPI_POWEROFF: 'acpipowerbutton',
+		virtualbox_const.VM_PAUSE: 'pause',
+		virtualbox_const.VM_REBOOT: 'reset',
+		virtualbox_const.VM_RESUME: 'resume',
+		virtualbox_const.VM_SAVE: 'savestate'
+}
+
 
 def get_machine_state(vm_uuid):
 	''' check vms state (on/off/paused) '''
-	state = VM_POWEROFF
+	state = virtualbox_const.VM_STATE_POWEROFF
 	try:
 		str_state = 'poweroff'
 		with os.popen('VBoxManage showvminfo %s --machinereadable' % vm_uuid) \
@@ -39,40 +45,39 @@ def get_machine_state(vm_uuid):
 					str_state = line.strip()[9:-1]
 					break
 		if str_state == 'paused':
-			state = VM_PAUSED
+			state = virtualbox_const.VM_STATE_PAUSED
 		elif str_state == 'running':
-			state = VM_POWERON
+			state = virtualbox_const.VM_STATE_POWERON
 
 	except IOError, err:
-		pretty.print_error(__name__, 'get_machine_state error ' + vm_uuid, err)
-		state = VM_POWEROFF
+		pretty.print_error(__name__, 'get_machine_state', vm_uuid, 'error', err)
+		state = virtualbox_const.VM_STATE_POWEROFF
 
 	return state
 
 
-def machine_start(vm_uuid, mode):
-	utils.launch_commandline('VBoxManage startvm ' + vm_uuid + ' --type ' + mode)
-
-def machine_poweroff(vm_uuid):
-	utils.launch_commandline('VBoxManage controlvm ' + vm_uuid+ ' poweroff')
-
-def machine_acpipoweroff(vm_uuid):
-	utils.launch_commandline('VBoxManage controlvm ' + vm_uuid+ ' acpipowerbutton')
-
-def machine_pause(vm_uuid):
-	utils.launch_commandline('VBoxManage controlvm ' + vm_uuid+ ' pause')
-
-def machine_reboot(vm_uuid):
-	utils.launch_commandline('VBoxManage controlvm ' + vm_uuid+ ' reset')
-
-def machine_resume(vm_uuid):
-	utils.launch_commandline('VBoxManage controlvm ' + vm_uuid+ ' resume')
-
-def machine_save(vm_uuid):
-	utils.launch_commandline('VBoxManage controlvm ' + vm_uuid+ ' savestate')
+def vm_action(action, vm_uuid):
+	''' change state of the virtual machine. Call VBoxManage.
+		@param action - one of the const VM_*
+		@param vm_uuid - virtual machine uuid
+	'''
+	if action == virtualbox_const.VM_START_NORMAL:
+		utils.launch_commandline('VBoxManage startvm ' + vm_uuid + \
+				' --type gui')
+	elif action == virtualbox_const.VM_START_HEADLESS:
+		utils.launch_commandline('VBoxManage startvm ' + vm_uuid + \
+				' --type headless')
+	else:
+		command = _ACTIONS[action]
+		utils.launch_commandline('VBoxManage controlvm ' + vm_uuid + ' ' + \
+				command)
 
 
 def _get_virtual_machines(config_file):
+	''' load (virtual machine uuid, path to vm config) from virtualbox 
+		configuration.
+		@param config_file - path to VirtualBox.xml file
+	'''
 	try:
 		dtree = minidom.parse(config_file)
 		machine_registry = dtree.getElementsByTagName('MachineRegistry')[0]
@@ -80,10 +85,15 @@ def _get_virtual_machines(config_file):
 			yield (machine.getAttribute('uuid')[1:-1], machine.getAttribute('src'))
 
 	except StandardError, err:
-		pretty.print_error(__name__, '_get_virtual_machines error', err)
+		pretty.print_error(__name__, '_get_virtual_machines', config_file, 
+				'error', err)
 
 
 def _get_machine_info(vm_uuid, config_file):
+	''' load information about virtual machines from its configuration file.
+		@param vm_uuid - uuid virtual machine
+		@param config_file - path to vm configuration file
+	'''
 	if not os.path.isfile(config_file):
 		return None, None
 
@@ -104,7 +114,7 @@ def _get_machine_info(vm_uuid, config_file):
 		return (name, description or os_type)
 
 	except StandardError, err:
-		pretty.print_error(__name__, '_get_machine_info error ' + vm_uuid + ' ' + \
+		pretty.print_error(__name__, '_get_machine_info', vm_uuid, 'error' + \
 				config_file, err)
 
 	return None, None
diff --git a/kupfer/plugin/virtualbox_vboxapi_support.py b/kupfer/plugin/virtualbox_vboxapi_support.py
index 170e705..f96fa1d 100644
--- a/kupfer/plugin/virtualbox_vboxapi_support.py
+++ b/kupfer/plugin/virtualbox_vboxapi_support.py
@@ -14,14 +14,23 @@ from kupfer import pretty
 
 import vboxapi
 
-VM_POWEROFF = 0
-VM_POWERON = 1
-VM_PAUSED = 2
+import virtualbox_const
 
 MONITORED_DIRS = None
 IS_DYNAMIC = False
 ICON = "VBox"
 
+
+_ACTIONS = {
+		virtualbox_const.VM_POWEROFF:		lambda c:c.powerDown(),
+		virtualbox_const.VM_ACPI_POWEROFF:	lambda c:c.powerButton(),
+		virtualbox_const.VM_PAUSE:			lambda c:c.pause(),
+		virtualbox_const.VM_REBOOT:			lambda c:c.reset(),
+		virtualbox_const.VM_RESUME:			lambda c:c.resume(),
+		virtualbox_const.VM_SAVE:			lambda c:c.saveState()
+}
+
+
 def _get_object_session():
 	''' get new session to vm '''
 	vbox, session = None, None
@@ -41,7 +50,7 @@ def _get_existing_session(vm_uuid):
 		session = vbox.mgr.getSessionObject(vbox.vbox)
 		vbox.vbox.openExistingSession(session, vm_uuid)
 	except Exception, err:
-		pretty.print_error(__name__, 'virtualbox: get session to %s error' %
+		pretty.print_error(__name__, 'virtualbox: get session to %s error' % \
 				vm_uuid, err)
 
 	return vbox, session
@@ -50,19 +59,22 @@ def get_machine_state(machine_id):
 	''' check vms state (on/off/paused) '''
 	
 	vbox, vbox_sess = _get_object_session()
-	state = VM_POWERON
+	if vbox_sess is None:
+		return virtualbox_const.VM_STATE_POWEROFF
+
+	state = virtualbox_const.VM_STATE_POWERON
 	try:
 		vbox.vbox.openExistingSession(vbox_sess, machine_id)
 		machine_state = vbox_sess.machine.state
 		if machine_state == vbox.constants.MachineState_Paused:
-			state = VM_PAUSED
+			state = virtualbox_const.VM_STATE_PAUSED
 		elif machine_state in (vbox.constants.MachineState_PoweredOff, 
 				vbox.constants.MachineState_Aborted,
 				vbox.constants.MachineState_Starting):
-			state = VM_POWEROFF
+			state = virtualbox_const.VM_STATE_POWEROFF
 	except Exception: # exception == machine is off (xpcom.Exception)
 		# silently set state to off
-		state = VM_POWEROFF
+		state = virtualbox_const.VM_STATE_POWEROFF
 
 	if vbox_sess.state == vbox.constants.SessionState_Open:
 		vbox_sess.close()
@@ -70,51 +82,57 @@ def get_machine_state(machine_id):
 	return state
 
 
-def machine_start(machine_uuid, mode):
+def _machine_start(vm_uuid, mode):
+	''' Start virtual machine 
+		@param vm_uuid - uuid of virtual machine
+		@param mode - mode: gui, headless
+	'''
 	vbox, session = _get_object_session()
 	if session:
 		try:
-			remote_sess = vbox.vbox.openRemoteSession(session, machine_uuid, mode, '')
+			remote_sess = vbox.vbox.openRemoteSession(session, vm_uuid, mode, '')
 			remote_sess.waitForCompletion(-1)
 		except Exception, err: 
-			pretty.print_error(__name__, "StartVM:", machine_uuid, "error", err)
+			pretty.print_error(__name__, "StartVM:", vm_uuid, "Mode ", mode, 
+					"error", err)
 
 		if session.state == vbox.constants.SessionState_Open:
 			session.close()
 
 
-def _execute_machine_action(machine_uuid, action):
-	vbox, session = _get_existing_session(machine_uuid)
+def _execute_machine_action(vm_uuid, action):
+	''' Start virtual machine 
+		@param vm_uuid - uuid of virtual machine
+		@param action - function called on vbox session
+	'''
+	vbox, session = _get_existing_session(vm_uuid)
 	try:
 		action(session.console)
 	except Exception, err: 
 		pretty.print_error(__name__, "_execute_machine_action:", repr(action),
-				" vm:", machine_uuid, "error", err)
+				" vm:", vm_uuid, "error", err)
 
 	if session.state == vbox.constants.SessionState_Open:
 		session.close()
 
 
-def machine_poweroff(machine_uuid):
-	_execute_machine_action(machine_uuid, lambda c:c.powerDown())
-
-def machine_acpipoweroff(machine_uuid):
-	_execute_machine_action(machine_uuid, lambda c:c.powerButton())
-
-def machine_pause(machine_uuid):
-	_execute_machine_action(machine_uuid, lambda c:c.pause())
-
-def machine_reboot(machine_uuid):
-	_execute_machine_action(machine_uuid, lambda c:c.reset())
-
-def machine_resume(machine_uuid):
-	_execute_machine_action(machine_uuid, lambda c:c.resume())
-
-def machine_save(machine_uuid):
-	_execute_machine_action(machine_uuid, lambda c:c.saveState())
+def vm_action(action, vm_uuid):
+	''' change state of the virtual machine 
+		@param action - one of the const VM_*
+		@param vm_uuid - virtual machine uuid
+	'''
+	if action == virtualbox_const.VM_START_NORMAL:
+		_machine_start(vm_uuid, 'gui')
+	elif action == virtualbox_const.VM_START_HEADLESS:
+		_machine_start(vm_uuid, 'headless')
+	else:
+		command = _ACTIONS[action]
+		_execute_machine_action(vm_uuid, command)
 
 
 def get_machines():
+	''' Get generator of items: (machine uuid, machine name, machine description)
+	'''
 	vbox, vbox_sess = _get_object_session()
 	if vbox_sess is None:
 		return



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]