[kupfer: 5/11] plugin.virtualbox: merge virtualbox and virtualbox_ose plugins
- From: Ulrik Sverdrup <usverdrup src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [kupfer: 5/11] plugin.virtualbox: merge virtualbox and virtualbox_ose plugins
- Date: Thu, 22 Oct 2009 16:37:04 +0000 (UTC)
commit f68cbef345ccaf73d141c8613766ad89cdce704e
Author: Karol BÄ?dkowski <karol bedkowsk+gh gmail com>
Date: Sat Oct 17 17:21:26 2009 +0200
plugin.virtualbox: merge virtualbox and virtualbox_ose plugins
- Create virtualbox_vboxapi_support.py for Sun VirtualBox, and
virtualbox_ose_support.py for VirtualBox OSE.
- Drop virtualbox_ose plugin
kupfer/plugin/virtualbox.py | 130 +++++---------------
kupfer/plugin/virtualbox_ose.py | 176 ---------------------------
kupfer/plugin/virtualbox_ose_support.py | 121 ++++++++++++++++++
kupfer/plugin/virtualbox_vboxapi_support.py | 128 +++++++++++++++++++
4 files changed, 282 insertions(+), 273 deletions(-)
---
diff --git a/kupfer/plugin/virtualbox.py b/kupfer/plugin/virtualbox.py
index cb9e645..e23a243 100644
--- a/kupfer/plugin/virtualbox.py
+++ b/kupfer/plugin/virtualbox.py
@@ -1,6 +1,7 @@
# -*- coding: UTF-8 -*-
from kupfer.objects import Leaf, Action, Source, AppLeafContentMixin
+from kupfer.helplib import PicklingHelperMixin, FilesystemWatchMixin
from kupfer import pretty, plugin_support
__kupfer_name__ = _("VirtualBox")
@@ -12,87 +13,43 @@ __kupfer_settings__ = plugin_support.PluginSettings(
plugin_support.SETTING_PREFER_CATALOG,
)
-import vboxapi
-
-VM_POWEROFF = 0
-VM_POWERON = 1
-VM_PAUSED = 2
-
-
-def _get_object_session():
- ''' get new session to vm '''
- vbox, session = None, None
- try:
- vbox = vboxapi.VirtualBoxManager(None, None)
- session = vbox.mgr.getSessionObject(vbox.vbox)
- except Exception, err:
- pretty.print_error(__name__, 'virtualbox: get session error ', err)
-
- return vbox, session
-
-def _get_existing_session(vm_uuid):
- ''' get existing session by machine uuid '''
- vbox, session = None, None
- try:
- vbox = vboxapi.VirtualBoxManager(None, None)
- 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' %
- vm_uuid, err)
-
- return vbox, session
-
-def _check_machine_state(vbox, vbox_sess, machine_id):
- ''' check vms state (on/off/paused) '''
- state = VM_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
- elif machine_state in (vbox.constants.MachineState_PoweredOff, vbox.constants.MachineState_Aborted,
- vbox.constants.MachineState_Starting):
- state = VM_POWEROFF
- except Exception, err: # exception == machine is off (xpcom.Exception)
- # silently set state to off
- state = VM_POWEROFF
-
- if vbox_sess.state == vbox.constants.SessionState_Open:
- vbox_sess.close()
-
- return state
+try:
+ import virtualbox_vboxapi_support as virtualbox_support
+ pretty.print_info(__name__, 'Using vboxapi...')
+except ImportError, err:
+ import virtualbox_ose_support as virtualbox_support
+ pretty.print_info(__name__, 'Using cli...', err)
class VirtualMachine(Leaf):
- def __init__(self, obj, name, state, description):
+ def __init__(self, obj, name, description):
Leaf.__init__(self, obj, name)
- self.state = state
self.description = description
def get_description(self):
return self.description
def get_icon_name(self):
- return "VBox"
+ return virtualbox_support.ICON
def get_actions(self):
- # actions depend on machine state
- if self.state == VM_POWEROFF:
+ 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 self.state == VM_POWERON:
+ elif state == virtualbox_support.VM_POWERON:
yield StdVmAction(_('Send Power Off Signal'), 'system-shutdown', \
- lambda c:c.powerButton(), -5)
- yield StdVmAction(_('Pause'), 'pause', lambda c:c.pause())
- yield StdVmAction(_('Reboot'), 'system-reboot', lambda c:c.reset(), -10)
+ 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', lambda c:c.resume())
+ 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)
- if self.state in (VM_POWERON, VM_PAUSED):
- yield StdVmAction(_('Save State'), 'system-supsend', lambda c:c.saveState())
- yield StdVmAction(_('Power Off'), 'system-shutdown', lambda c:c.powerDown(), -10)
class _VMAction(Action):
def __init__(self, name, icon):
@@ -113,17 +70,7 @@ class StartVM(_VMAction):
self.rank_adjust = rank_adjust
def activate(self, leaf):
- vbox, session = _get_object_session()
- if session:
- try:
- remote_sess = vbox.vbox.openRemoteSession(session, leaf.object, self.mode, '')
- remote_sess.waitForCompletion(-1)
- except Exception, err:
- pretty.print_error(__name__, "StartVM:", self.name,
- "vm:", leaf.name, "error", err)
-
- if session.state == vbox.constants.SessionState_Open:
- session.close()
+ virtualbox_support.machine_start(leaf.object, self.mode)
class StdVmAction(_VMAction):
@@ -133,43 +80,32 @@ class StdVmAction(_VMAction):
self.command = command
def activate(self, leaf):
- vbox, session = _get_existing_session(leaf.object)
- if session:
- try:
- self.command(session.console)
- except Exception, err:
- pretty.print_error(__name__, "StdVmAction:", self.name,
- "vm:", leaf.name, "error", err)
- if session.state == vbox.constants.SessionState_Open:
- session.close()
+ self.command(leaf.object)
-class VBoxMachinesSource(AppLeafContentMixin, Source):
- appleaf_content_id = 'Sun VirtualBox'
+class VBoxMachinesSource(AppLeafContentMixin, Source, PicklingHelperMixin, FilesystemWatchMixin):
+ appleaf_content_id = ('VirtualBox OSE', 'Sun VirtualBox')
def __init__(self, name=_("Sun VirtualBox Machines")):
Source.__init__(self, name)
+ self.unpickle_finish()
+
+ def unpickle_finish(self):
+ if virtualbox_support.MONITORED_DIRS:
+ self.monitor_token = self.monitor_directories(*virtualbox_support.MONITORED_DIRS)
def is_dynamic(self):
- return True
+ return virtualbox_support.IS_DYNAMIC
def get_items(self):
- vbox, vbox_sess = _get_object_session()
- if vbox_sess is None:
- return
-
- machines = vbox.getArray(vbox.vbox, 'machines')
- session = vbox.mgr.getSessionObject(vbox.vbox)
- for machine in machines:
- state = _check_machine_state(vbox, vbox_sess, machine.id)
- description = machine.description or machine.OSTypeId
- yield VirtualMachine(machine.id, machine.name, state, description)
+ for machine_id, machine_name, machine_desc in virtualbox_support.get_machines():
+ yield VirtualMachine(machine_id, machine_name, machine_desc)
def get_description(self):
return None
def get_icon_name(self):
- return "VBox"
+ return virtualbox_support.ICON
def provides(self):
yield VirtualMachine
diff --git a/kupfer/plugin/virtualbox_ose_support.py b/kupfer/plugin/virtualbox_ose_support.py
new file mode 100644
index 0000000..03a84f7
--- /dev/null
+++ b/kupfer/plugin/virtualbox_ose_support.py
@@ -0,0 +1,121 @@
+# -*- coding: UTF-8 -*-
+'''
+virtualbox_ose_support.py
+
+Control VirtualBox via command-line interface.
+Support both Sun VirtualBox and VirtualBox OpenSource Edition.
+'''
+from __future__ import with_statement
+
+__revision__ = "0.1"
+__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
+
+_VBOX_CONFIG_DIR = os.path.expanduser('~/.VirtualBox/')
+_VBOX_CONFIG_FILE = os.path.join(_VBOX_CONFIG_DIR, 'VirtualBox.xml')
+
+MONITORED_DIRS = (_VBOX_CONFIG_DIR, )
+IS_DYNAMIC = False
+ICON = "virtualbox-ose"
+
+
+def get_machine_state(vm_uuid):
+ ''' check vms state (on/off/paused) '''
+ state = VM_POWEROFF
+ try:
+ str_state = 'poweroff'
+ with os.popen('VBoxManage showvminfo %s --machinereadable' % vm_uuid) \
+ as pinfo:
+ for line in pinfo:
+ if line.startswith('VMState="'):
+ str_state = line.strip()[9:-1]
+ break
+ if str_state == 'paused':
+ state = VM_PAUSED
+ elif str_state == 'running':
+ state = VM_POWERON
+
+ except IOError, err:
+ pretty.print_error(__name__, 'get_machine_state error ' + vm_uuid, err)
+ state = VM_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 _get_virtual_machines(config_file):
+ try:
+ dtree = minidom.parse(config_file)
+ machine_registry = dtree.getElementsByTagName('MachineRegistry')[0]
+ for machine in machine_registry.getElementsByTagName('MachineEntry'):
+ yield (machine.getAttribute('uuid')[1:-1], machine.getAttribute('src'))
+
+ except StandardError, err:
+ pretty.print_error(__name__, '_get_virtual_machines error', err)
+
+
+def _get_machine_info(vm_uuid, config_file):
+ if not os.path.isfile(config_file):
+ return None, None
+
+ try:
+ dtree = minidom.parse(config_file)
+ machine_registry = dtree.getElementsByTagName('Machine')[0]
+
+ os_type = machine_registry.getAttribute('OSType')
+ name = machine_registry.getAttribute('name')
+
+ description = None
+ for machine_registry_child in machine_registry.childNodes:
+ if machine_registry_child.nodeName == 'Description':
+ if machine_registry_child.hasChildNodes():
+ description = machine_registry_child.firstChild.nodeValue
+ break
+
+ return (name, description or os_type)
+
+ except StandardError, err:
+ pretty.print_error(__name__, '_get_machine_info error ' + vm_uuid + ' ' + \
+ config_file, err)
+
+ return None, None
+
+
+def get_machines():
+ if os.path.isfile(_VBOX_CONFIG_FILE):
+ for vm_uuid, config in _get_virtual_machines(_VBOX_CONFIG_FILE):
+ name, description = _get_machine_info(vm_uuid, config)
+ if name:
+ yield (vm_uuid, name, description)
+
+
+
diff --git a/kupfer/plugin/virtualbox_vboxapi_support.py b/kupfer/plugin/virtualbox_vboxapi_support.py
new file mode 100644
index 0000000..170e705
--- /dev/null
+++ b/kupfer/plugin/virtualbox_vboxapi_support.py
@@ -0,0 +1,128 @@
+# -*- coding: UTF-8 -*-
+'''
+virtualbox_vboxapi_support.py
+
+Control VirtualBox via Python interface (vboxapi).
+Only (?) Sun VirtualBox (no OSE).
+'''
+__revision__ = "0.1"
+__author__ = "Karol BÄ?dkowski <karol bedkowski gmail com>"
+
+from kupfer import pretty
+
+#raise ImportError()
+
+import vboxapi
+
+VM_POWEROFF = 0
+VM_POWERON = 1
+VM_PAUSED = 2
+
+MONITORED_DIRS = None
+IS_DYNAMIC = False
+ICON = "VBox"
+
+def _get_object_session():
+ ''' get new session to vm '''
+ vbox, session = None, None
+ try:
+ vbox = vboxapi.VirtualBoxManager(None, None)
+ session = vbox.mgr.getSessionObject(vbox.vbox)
+ except Exception, err:
+ pretty.print_error(__name__, 'virtualbox: get session error ', err)
+
+ return vbox, session
+
+def _get_existing_session(vm_uuid):
+ ''' get existing session by machine uuid '''
+ vbox, session = None, None
+ try:
+ vbox = vboxapi.VirtualBoxManager(None, None)
+ 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' %
+ vm_uuid, err)
+
+ return vbox, session
+
+def get_machine_state(machine_id):
+ ''' check vms state (on/off/paused) '''
+
+ vbox, vbox_sess = _get_object_session()
+ state = VM_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
+ elif machine_state in (vbox.constants.MachineState_PoweredOff,
+ vbox.constants.MachineState_Aborted,
+ vbox.constants.MachineState_Starting):
+ state = VM_POWEROFF
+ except Exception: # exception == machine is off (xpcom.Exception)
+ # silently set state to off
+ state = VM_POWEROFF
+
+ if vbox_sess.state == vbox.constants.SessionState_Open:
+ vbox_sess.close()
+
+ return state
+
+
+def machine_start(machine_uuid, mode):
+ vbox, session = _get_object_session()
+ if session:
+ try:
+ remote_sess = vbox.vbox.openRemoteSession(session, machine_uuid, mode, '')
+ remote_sess.waitForCompletion(-1)
+ except Exception, err:
+ pretty.print_error(__name__, "StartVM:", machine_uuid, "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)
+ try:
+ action(session.console)
+ except Exception, err:
+ pretty.print_error(__name__, "_execute_machine_action:", repr(action),
+ " vm:", machine_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 get_machines():
+ vbox, vbox_sess = _get_object_session()
+ if vbox_sess is None:
+ return
+
+ machines = vbox.getArray(vbox.vbox, 'machines')
+ for machine in machines:
+ description = machine.description or machine.OSTypeId
+ yield (machine.id, machine.name, description)
+
+
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]