views:

55

answers:

2

I'm running into some trouble with deploying Django on the passenger_wsgi module with virtualenv. The Python code in the passenger_wsgi.py file, which should fix my problem is:

import os, sys
INTERP = '/home/login/.virtualenvs/env_name/bin/python'
if sys.executable != INTERP:
    os.execl(INTERP, INTERP, *sys.argv)

The first three lines I understand, but I only have a veeeery vague idea about the fourth one and that's the one that happens to be giving me an error:

/home/login/.virtualenvs/env_name/bin/python: can't find '__main__.py' in ''

So what is os.execl doing here exactly? And what does that error message mean?

A: 
>>> import os
>>> help(os.execl)


execl(file, *args)
    execl(file, *args)

    Execute the executable file with argument list args, replacing the
    current process.

This might help with your problem: http://ubuntuforums.org/showthread.php?t=1493979

kanaka
Thanks, but I still don't get it... Why do I have to put in the value of INTERP as both the filename and one of the arguments? And what does "replacing the current process" mean exactly? What about the error message, what does that mean?
Monika Sulik
@Monika Sulik : replacing the current process mean that the exec* command don't kill and create a new process ,they just replace the process from which the command have been called , the process ID doesn't change, but the data, heap and stack of the calling process are replaced by those of the new process.
singularity
@singularity - thanks, that really did clear at least the process thing up for me :)
Monika Sulik
+1  A: 

maybe you should do it like this:

os.execl(INTERP, *sys.argv) # don't pass again the interpreter path. 

i think this doc is wrong : http://wiki.dreamhost.com/Passenger_WSGI

about exec:

The exec functions of Unix-like operating systems are a collection of functions that causes the running process to be completely replaced by the program passed as an argument to the function.

os.execl(path, arg0, arg1, ...)
os.execle(path, arg0, arg1, ..., env)
os.execlp(file, arg0, arg1, ...)
os.execlpe(file, arg0, arg1, ..., env)
os.execv(path, args)
os.execve(path, args, env)
os.execvp(file, args)
os.execvpe(file, args, env)

from : http://docs.python.org/library/os.html

The “l” and “v” variants of the exec*() functions differ in how command-line arguments are passed. The “l” variants are perhaps the easiest to work with if the number of parameters is fixed when the code is written; the individual parameters simply become additional parameters to the execl*() functions. The “v” variants are good when the number of parameters is variable, with the arguments being passed in a list or tuple as the args parameter. In either case, the arguments to the child process should start with the name of the command being run, but this is not enforced.

Edit:

i just did what you were doing in a python shell and i get the same error:

>>> import os
>>> import sys
>>> os.execl('/home/login/projects/virtual/bin/python', '/home/login/projects/virtual/bin/python', *sys.argv)
/home/login/projects/virtual/bin/python: can't find '__main__.py' in ''
singularity
Thanks... I read that bit of the docs and didn't quite get it either though. Passing the INTERP argument once gets rid of the error, but not of the problem. Although it did help me to understand what exactly is happening ;-P The problem is that when INTERP is passed just once, the python process does seem to be replaced, but when I print sys.executable in the new process it's still says '/usr/bin/python', which is obviously not what I want.
Monika Sulik
Yep, that's how I'm debugging it - in the shell... no errors appear in the error.log (apparently passenger is very difficult to debug because the error logging sucks). And as django isn't working when there are errors in passenger_wsgi.py I don't get any errors sent via e-mail either.
Monika Sulik
Right... I've voted your answer up because experimenting with os.execl(INTERP, *sys.argv) is the best lead I have at the moment. The interesting thing is that it seems that when I do that, it doesn't actually change sys.executable to whatever I have in INTERP (which I'm assuming is the point?), but always changes it to '/usr/bin/python'. So even if INTERP = '/usr/bin/python2.7' rather than the path to the virtualenv, running that command makes sys.executable = '/usr/bin/python'
Monika Sulik
it's normal the sys.executable will not change , you can try running a python interpreter of a virtual environment and you will see that sys.executable == '/usr/bin/python', that because sys.executable don't give you the interpreter that's being run but give you the system default interpreter.
singularity
Actually no - when I run an interpreter via putting in something like /home/user/.virtualenv/env_name/bin/python2.7 into the command line then when I print sys.executable that's exactly what it says.
Monika Sulik