sethmlarson / virtualbox-python

Complete implementation of VirtualBox's COM API with a Pythonic interface.
https://pypi.org/project/virtualbox
Apache License 2.0
354 stars 75 forks source link

VirtualBox not working on Debian 9 #106

Closed noxdafox closed 6 years ago

noxdafox commented 6 years ago

It seems the issue #99 is not only related to #102

In [1]: import sys

In [2]: sys.abiflags = ''

In [3]: import virtualbox

In [4]: vbox = virtualbox.VirtualBox()

In [5]: vm = vbox.find_machine(vbox.machines[0].name)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/usr/local/lib/python3.5/dist-packages/virtualbox/library_base.py in _call_method(self, method, in_p)
    194         try:
--> 195             ret = method(*in_params)
    196         except Exception as exc:

/usr/lib/virtualbox/sdk/bindings/xpcom/python/xpcom/client/__init__.py in findMachine(self, Param1)

TypeError: internal error in PyXPCOM, parameter must be a bytes object

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
<ipython-input-5-65f32237fea6> in <module>()
----> 1 vm = vbox.find_machine(vbox.machines[0].name)

/usr/local/lib/python3.5/dist-packages/virtualbox/library.py in find_machine(self, name_or_id)
   7278             raise TypeError("name_or_id can only be an instance of type basestring")
   7279         machine = self._call("findMachine",
-> 7280                      in_p=[name_or_id])
   7281         machine = IMachine(machine)
   7282         return machine

/usr/local/lib/python3.5/dist-packages/virtualbox/library_base.py in _call(self, name, in_p)
    184         method = self._search_attr(name)
    185         if inspect.isfunction(method) or inspect.ismethod(method):
--> 186             return self._call_method(method, in_p=in_p)
    187         else:
    188             return method

/usr/local/lib/python3.5/dist-packages/virtualbox/library_base.py in _call_method(self, method, in_p)
    210 
    211             if errobj.msg is None:
--> 212                 errobj.msg = getattr(exc, 'msg', getattr(exc, 'message'))
    213             raise errobj
    214         return ret

AttributeError: 'TypeError' object has no attribute 'message'
noxdafox commented 6 years ago

This is funny: it seems the original error is due to input being str instead of the expected bytes.

Nevertheless, when using bytes, it complains of the opposite.

In [10]: vm = vbox.find_machine('IE11 - Win7')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/usr/local/lib/python3.5/dist-packages/virtualbox/library_base.py in _call_method(self, method, in_p)
    194         try:
--> 195             ret = method(*in_params)
    196         except Exception as exc:

/usr/lib/virtualbox/sdk/bindings/xpcom/python/xpcom/client/__init__.py in findMachine(self, Param1)

TypeError: internal error in PyXPCOM, parameter must be a bytes object
In [11]: vm = vbox.find_machine(b'IE11 - Win7')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/usr/local/lib/python3.5/dist-packages/virtualbox/library_base.py in _call_method(self, method, in_p)
    194         try:
--> 195             ret = method(*in_params)
    196         except Exception as exc:

/usr/lib/virtualbox/sdk/bindings/xpcom/python/xpcom/client/__init__.py in findMachine(self, Param1)

TypeError: This parameter must be a unicode object
sethmlarson commented 6 years ago

Did you install the VirtualBox SDK with Python 3.5 from the website? If not can you try removing and reinstalling it?

noxdafox commented 6 years ago

I believe it came altogether with the virtualbox debian package.

noxdafox@playground:~$ apt-file search /usr/lib/virtualbox/sdk/bindings/xpcom/python/xpcom/client/__init__.py
virtualbox: /usr/lib/virtualbox/sdk/bindings/xpcom/python/xpcom/client/__init__.py
sethmlarson commented 6 years ago

Instead of installing via Debian try installing via the website. Direct download to the 5.2.6 SDK. Uninstall the Debian package first.

This package is just the VirtualBox SDK right? Not the binaries for actual VirtualBox?

sethmlarson commented 6 years ago

I really need to write up concrete documentation for setting up the environment correctly. I've never tested installing the SDK via package manager, just from the website downloads.

noxdafox commented 6 years ago

Unfortunately not, this package is the virtualbox package.

It seems the debian package installs everything at once. There's no such virtualbox-sdk package.

sethmlarson commented 6 years ago

Try uninstalling and reinstalling from the website. :) Thanks for the help in debugging this!

noxdafox commented 6 years ago

I can't really uninstall this as I depend on the VBox shipped with Debian.

Nevertheless, I downloaded the sdk and replaced the installed bindings and the issue is still there.

sethmlarson commented 6 years ago

I'll fire up a Debian VM when I get home and try to reproduce this. Can you give me a list of exact packages I need to install to get this to happen? :)

noxdafox commented 6 years ago

Just install virtualbox and Python 3.

Note that VirtualBox OSE is not included in Debian 9 therefore you need to install from stretch backports.

More info here.

# echo "deb http://ftp.se.debian.org/debian/ stretch-backports main contrib" >> /etc/apt/sources.list

# apt update

# apt install virtualbox python3

# pip3 install pyvbox
sethmlarson commented 6 years ago

Okay thanks!

noxdafox commented 6 years ago

While investigating further I found this.

It seems the virtualbox debian package is broken and ships only the Python2 version, this would explain why it insists to find unicode parameters (Pyhton 3 has no unicode type anymore).

This might help clarifying also #102

sethmlarson commented 6 years ago

Nice find! I'll have to add this to the documentation somewhere! :)

sethmlarson commented 6 years ago

If I were you I'd raise an issue with Debian. Maybe they already switched to Python 3 for the next release?

noxdafox commented 6 years ago

I gave a try to the version from testing/buster and it messed all my environment as it pulled Python 3.6.

At the end, I was getting unable to import pyvbox error when trying to import virtualbox so I eventually gave up. This has become too time consuming.

sethmlarson commented 6 years ago

If you've still go some energy left you should try the installer on the website for Ubuntu/Debian. I used this method and use VirtualBox on my Ubuntu 17.10 installation daily. :) I would just uninstall all the packaged VirtualBox installations first.

Otherwise waiting for me to write up some installation instructions to ensure you've got a good environment is another option.

noxdafox commented 6 years ago

That was the first one I tried. Issue is the VNC plugin for that version was somehow mis-functioning (or rather not working at all).

sethmlarson commented 6 years ago

Forgive me because I don't know what the VNC plugin is, never used it.

Is the VNC plugin part of Guest Additions? For 5.2.6 it looks like they had a problem with the Guest Additions that's shipped with 5.2.6 and recommend upgrading. Look for the "Important" line right above the downloads on the Downloads page.

noxdafox commented 6 years ago

Nope the VNC is a separate extension working host-side.

It is shipped together with VirtualBox OSE packages and it works properly there. Yet I had no luck with the Oracle version.

noxdafox commented 6 years ago

BTW this is the error I get with VirtualBox 5.2.6 and pyvbox. This happens both with the one shipped via Debian testing/buster and the one installed from virtualbox.org with their SDK.

sudo dpkg -i virtualbox-5.2_5.2.6-120293~Debian~stretch_amd64.deb
 ...
sudo python3 vboxapisetup.py install
 ...
sudo pip3 install pyvbox

ipython3
Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import virtualbox
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-1-1856251cb791> in <module>()
----> 1 import virtualbox

/usr/local/lib/python3.5/dist-packages/virtualbox/__init__.py in <module>()
    243 
    244 # Lazy include...
--> 245 from virtualbox import pool  # noqa: F401
    246 from virtualbox import events  # noqa: F401

ImportError: No module named 'pyvbox'
sethmlarson commented 6 years ago

Could you try installing pyvbox in a virtualenv and trying the same?

Only reason I ask is because installing packages from PyPI with pip into a distribution version of Python is usually a no-no because package managers do all sorts of silly things when they distribute their packages.

noxdafox commented 6 years ago

The import error becomes different.

In [1]: import virtualbox
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-1-1856251cb791> in <module>()
----> 1 import virtualbox

~/development/virtualenvs/pyvbox/lib/python3.5/site-packages/virtualbox/__init__.py in <module>()
    243 
    244 # Lazy include...
--> 245 from virtualbox import pool  # noqa: F401
    246 from virtualbox import events  # noqa: F401

ImportError: cannot import name 'pool'
sethmlarson commented 6 years ago

Hmmm... I wonder why it doesn't like those imports. Could you try with non-ipython? I don't know much about how it does its magic.

noxdafox commented 6 years ago

Same.

python3
Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import virtualbox
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/noxdafox/development/virtualenvs/pyvbox/lib/python3.5/site-packages/virtualbox/__init__.py", line 245, in <module>
    from virtualbox import pool  # noqa: F401
ImportError: cannot import name 'pool'
>>>
sethmlarson commented 6 years ago

Could you tarball that whole venv up and attach it here?

noxdafox commented 6 years ago

Had to fool GitHub as it accepts only ZIP files (it just checks the extension tho). It's a tar.bz2.

pyvbox_tar_bz.zip

sethmlarson commented 6 years ago

I'm able to reproduce this issue, I'll work on a fix.

noxdafox commented 6 years ago

Good to know! Thanks for your time & dedication.

sethmlarson commented 6 years ago

Try installing 1.3.2 from PyPI! This was an issue with the name of the package being different from the name of the module. :)

noxdafox commented 6 years ago

This fixed the import error, thanks!

I still suffer from other issues though.

This happens with both VirtualBox PUEL and VirtualBox OSE (setting sys.abiflags = '').

In [1]: import virtualbox
   ...: vbox = virtualbox.VirtualBox()
   ...: vm = vbox.find_machine(vbox.machines[0].name)
   ...: session = vm.create_session()
   ...: h, w, _, _, _, _ = session.console.display.get_screen_resolution(0)
   ...: png = session.console.display.take_screen_shot_to_array(0, h, w, virtualbox.library.BitmapFormat.png)
   ...: 
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
~/development/virtualenvs/pyvbox/lib/python3.5/site-packages/virtualbox/library_base.py in _call_method(self, method, in_p)
    194         try:
--> 195             ret = method(*in_params)
    196         except Exception as exc:

/usr/lib/virtualbox/sdk/bindings/xpcom/python/xpcom/client/__init__.py in takeScreenShotToArray(self, Param1, Param2, Param3, Param4)

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position 0: invalid start byte

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
<ipython-input-1-a41323a6ea59> in <module>()
      4 session = vm.create_session()
      5 h, w, _, _, _, _ = session.console.display.get_screen_resolution(0)
----> 6 png = session.console.display.take_screen_shot_to_array(0, h, w, virtualbox.library.BitmapFormat.png)

~/development/virtualenvs/pyvbox/lib/python3.5/site-packages/virtualbox/library.py in take_screen_shot_to_array(self, screen_id, width, height, bitmap_format)
  23680             raise TypeError("bitmap_format can only be an instance of type BitmapFormat")
  23681         screen_data = self._call("takeScreenShotToArray",
> 23682                      in_p=[screen_id, width, height, bitmap_format])
  23683         return screen_data
  23684 

~/development/virtualenvs/pyvbox/lib/python3.5/site-packages/virtualbox/library_base.py in _call(self, name, in_p)
    184         method = self._search_attr(name)
    185         if inspect.isfunction(method) or inspect.ismethod(method):
--> 186             return self._call_method(method, in_p=in_p)
    187         else:
    188             return method

~/development/virtualenvs/pyvbox/lib/python3.5/site-packages/virtualbox/library_base.py in _call_method(self, method, in_p)
    210 
    211             if errobj.msg is None:
--> 212                 errobj.msg = getattr(exc, 'msg', getattr(exc, 'message'))
    213             raise errobj
    214         return ret

AttributeError: 'UnicodeDecodeError' object has no attribute 'message'

Maybe worth opening a new bug report as this is snowballing tho.

sethmlarson commented 6 years ago

This looks like it's an error with XPCOM. Could you open a new issue for this? :) Also can you post in that issue the contents of /usr/lib/virtualbox/sdk/bindings/xpcom/python/xpcom/client/__init__.py in that issue? :)

noxdafox commented 6 years ago

111