intrig-unicamp / mininet-wifi

Emulator for Software-Defined Wireless Networks
https://mn-wifi.readthedocs.io/
Other
446 stars 241 forks source link

ImportError: Cannot load backend 'TkAgg' which requires the 'tk' interactive framework, as 'headless' is currently running #415

Closed andynoack closed 2 years ago

andynoack commented 2 years ago

I am using mininet-wifi in an ubuntu docker container. When installing with

git clone https://github.com/intrig-unicamp/mininet-wifi; cd mininet-wifi; util/install.sh -Wlnfv6

I am confronted with the following traceback (python setup.py install):

Traceback (most recent call last):
  File "setup.py", line 11, in <module>
    from mn_wifi.net import VERSION
  File "/root/mininet-wifi/mn_wifi/net.py", line 32, in <module>
    from mn_wifi.telemetry import parseData, telemetry as run_telemetry
  File "/root/mininet-wifi/mn_wifi/telemetry.py", line 17, in <module>
    matplotlib.use('TkAgg')
  File "/usr/lib/python3/dist-packages/matplotlib/cbook/deprecation.py", line 307, in wrapper
    return func(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/matplotlib/__init__.py", line 1309, in use
    switch_backend(name)
  File "/usr/lib/python3/dist-packages/matplotlib/pyplot.py", line 233, in switch_backend
    raise ImportError(
ImportError: Cannot load backend 'TkAgg' which requires the 'tk' interactive framework, as 'headless' is currently running
make: *** [Makefile:59: install] Error 1

A stack overflow post [1] indicates that maybe matplotlib.pyplot is used before

import matplotlib
matplotlib.use('TKAgg')

in one of the source files. Is there anything I should change in my setup or does anyone know a solution for this problem? Many thanks in advance!

[1] https://stackoverflow.com/questions/55811545/importerror-cannot-load-backend-tkagg-which-requires-the-tk-interactive-fra

ramonfontes commented 2 years ago

humm.. this is strange. Which OS do you have?

Can you try to set the environment variable? e.g. export MPLBACKEND=TKAgg

Some indicate the use of MacOSX for MacOS.

So you can try changing https://github.com/intrig-unicamp/mininet-wifi/blob/b1e6a4723355133283ee34226e80c98a62949fc0/mn_wifi/telemetry.py#L17 and recompile the code with sudo make install

andynoack commented 2 years ago

For your info: I am using Linux as VM-Host and an Ubuntu VM (20.04 LTS via Vagrant) with Docker (also Ubuntu). I tried MPLBACKEND=TKAgg util/install.sh -Wlnfv6 but the error keeps the same. Up to now I have not tried to modify the source code yet.

ramonfontes commented 2 years ago

Up to now I have not tried to modify the source code yet.

Can you try this? This is an issue that I unfortunately cannot reproduce and it would be really great if you could help me to find the solution.

andynoack commented 2 years ago

I found a solution! Running the installation as DISPLAY=localhost:0.0 util/install.sh -Wlnfv6 solves the problem for me. I can, however, definitely confirm the bug for my (stock?) Ubuntu 20.04 docker environment. Furthermore, I need to add export DISPLAY=localhost:0.0 to the docker command line (CMD) to be able to run mininet-wifi. Otherwise the error "ImportError: Cannot load backend 'TkAgg' which requires the 'tk' interactive framework, as 'headless' is currently running" pops up again. The error might be connected to the used shell (bash).

Is it possible to add a check whether the environment variable DISPLAY is set and otherwise set it to a default value like DISPLAY=localhost:0.0? I don't know where the best place for this might be, because both the main application and the installer is affected. Maybe my use case (mininet-wifi in a docker) is so special that it does not concern most of the people. Feel free to close the issue if this is the case. Many thanks for dealing with my question!

ramonfontes commented 2 years ago

Thanks for sharing the solution. :)

I was wondering how can I reproduce the issue. Are there any reproducible steps you could share with me?

andynoack commented 2 years ago

Here you go:

Dockerfile (with my fix included):

FROM ubuntu
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -yq install mininet netcat net-tools iproute2 iputils-ping screen tcpdump screen psmisc tshark iptables dnsmasq nftables dnsutils wget sudo git tzdata aircrack-ng openssh-server crunch libnl-route-3-dev make python3-psutil
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 10
RUN cd ~; git clone https://github.com/intrig-unicamp/mininet-wifi; cd mininet-wifi; DISPLAY=localhost:0.0 util/install.sh -Wlnfv6
CMD export DISPLAY=localhost:0.0; /etc/init.d/openvswitch-switch start; screen -S mnwifi -d -m mn --wifi

Build with: docker build --rm --tag mnw .

Run with: docker run -d --rm --privileged -p 2222:22 -v /lib/modules:/lib/modules -v /sys/kernel/debug:/sys/kernel/debug mnw

By the while, this (TkAgg bug) only affects mininet-wifi but not mininet that I also use in this way.

ramonfontes commented 2 years ago

It seems to me that the problem is that you were using an interactive backend which was trying to open matplotlib. However, it failed because you have disconnected the x-server that was available in your host. That's why you had to export the Display.

By the while, this (TkAgg bug) only affects mininet-wifi but not mininet that I also use in this way.

Mininet does not use matplotlib

ramonfontes commented 2 years ago

Closing due to inactivity