network script fails on 12.04.5 if python3 is not installed

Bug #1399481 reported by Jeff Lane 
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Checkbox Provider - Base
Fix Released
High
Jeff Lane 

Bug Description

This was seen on a test using 12.04.5. The network test throws a traceback as seen below:

Traceback (most recent call last):
  File "/tmp/nest-spmss8.23178394474d5c7a044e434f9a09cd32a68081c7f7fa6039badbb5caeae97dce/network", line 731, in <module>
    sys.exit(main())
  File "/tmp/nest-spmss8.23178394474d5c7a044e434f9a09cd32a68081c7f7fa6039badbb5caeae97dce/network", line 727, in main
    return args.func(args)
  File "/tmp/nest-spmss8.23178394474d5c7a044e434f9a09cd32a68081c7f7fa6039badbb5caeae97dce/network", line 545, in interface_test
    if not can_ping(args.interface, test_target):
  File "/tmp/nest-spmss8.23178394474d5c7a044e434f9a09cd32a68081c7f7fa6039badbb5caeae97dce/network", line 462, in can_ping
    stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
AttributeError: 'module' object has no attribute 'DEVNULL'

The line in question is this:

check_call(["ping", "-I", the_interface, "-c", "1", test_target],
                       stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

So I tried that out using ipython3 and ipython2 (on a 14.04.1 machine)
ipython3:
bladernr@klaatu:~$ ipython3
Python 3.4.0 (default, Apr 11 2014, 13:05:11)
<SNIP>
In [4]: subprocess.check_call(["ping", "-I", "eth0", "-c", "1", "192.168.0.10"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
Out[4]: 0

And now the same on ipython2:
bladernr@klaatu:~$ ipython
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
<SNIP>
In [1]: import subprocess

In [2]: subprocess.check_call(["ping", "-I", "eth0", "-c", "1", "192.168.0.10"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-2-2f3acc300507> in <module>()
----> 1 subprocess.check_call(["ping", "-I", "eth0", "-c", "1", "192.168.0.10"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

AttributeError: 'module' object has no attribute 'DEVNULL'

So this is an issue with the script apparently running in python2?

Looking at the script itself, it explicitly calls python3:

#!/usr/bin/env python3

Not sure what exactly is the cause here though :(

Related branches

Revision history for this message
Daniel Manrique (roadmr) wrote :

The cause is that subprocess.DEVNULL is not defined on 12.04.5's python 3.2.3 ;( Per the documentation:

subprocess.DEVNULL

    Special value that can be used as the stdin, stdout or stderr argument to Popen and indicates that the special file os.devnull will be used.

    New in version 3.3.

Also, behold:

ubuntu@precise-p3-test:~$ python3
Python 3.2.3 (default, Feb 27 2014, 21:31:18)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> subprocess.DEVNULL
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'DEVNULL'
>>>

To contrast, on 14.04:

roadmr@blackdog:~$ python3
Python 3.4.0 (default, Apr 11 2014, 13:05:11)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> subprocess.DEVNULL
-3
>>>

So work to do: figure out a way to replace subprocess.DEVNULL that's compatible with 3.2. Maybe:
try:
  null = subprocess.DEVNULL
except AttributeError:
  # oops, on 3.2
  null = os.devnull

subprocess.check_call(["ping", "-I", "eth0", "-c", "1", "192.168.0.10"], stdout=null, stderr=null)

I'm not sure if the semantics of using os.devnull (which seems to be what subprocess.DEVNULL does) are the same as simply using os.devnull; optionally, the integer value of subprocess.DEVNULL is -3, so we could simply assign that in the "except" block, but I worry that the rest of the code interpreting that value is also not present on 3.2.

Anyway, a simple way to reproduce this for me was to create a precise lxc container and install python3 in that, maybe it will come in handy:

sudo lxc-create -n precise-python3 -t ubuntu -- -r precise
sudo lxc-start -d -n precise-python3
sudo lxc-attach -n precise-python3

Changed in plainbox-provider-checkbox:
status: New → Triaged
importance: Undecided → High
Revision history for this message
Daniel Manrique (roadmr) wrote :

Two more notes. First, network is the only script where we do this, so it's the only one needing fixing.

Second, audio_settings.py suggests a technique to do this in a 3.2-compatible fashion:

            with open(os.devnull, 'wb') as DEVNULL:
                check_call(["pacmd", "move-sink-input", input_index, name],
                           stdout=DEVNULL)

So we can't simply pass os.devnull, it has to be opened first.

Revision history for this message
Jeff Lane  (bladernr) wrote :

Confirmed at least that this is broken on 12.04.5.

To recreate:
Install VM from 12.04.5 ISO (I used Server)
add hwcert public PPA
install canonical-certification-server
do the following:

# python3
verify version is 3.2.3

then these two python lines:

# import subprocess
# subprocess.check_call('ls', stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

This will result in a traceback (AttributeError) saying that module has no attribute 'DEVNULL'

Now repeat the above on a 14.04 system (Python3 version should be > 3.2.3, 14.04.1 shows 3.4.0)

this time the command should complete successfully and return a 0

Revision history for this message
Jeff Lane  (bladernr) wrote :

Hahah, you got yours in before I did... sigh.

Revision history for this message
Jeff Lane  (bladernr) wrote :

In any case, I realize (now) that DEVNULL is not defined in 3.2.3, question is, why has this not been seen until now? We've been using this test script on 12.04 for a long while... when was the change introduced that breaks it on older Python3 versions?

Jeff Lane  (bladernr)
Changed in plainbox-provider-checkbox:
assignee: nobody → Jeff Lane (bladernr)
status: Triaged → In Progress
Changed in plainbox-provider-checkbox:
status: In Progress → Fix Committed
milestone: none → 0.16
Changed in plainbox-provider-checkbox:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.