4

I have an application that presents a form and generates a PDF file with pdflatex which is returned to the browser as a file attachment. It works when I invoke the application server manually, but when the server process is started by Supervisord, it breaks...

Django throws an OSError:

[Errno 2] No such file or directory
Request Method: POST
Request URL:    http://apps.xxxxxxxx.com/pdf/view/1/85/
Django Version: 1.4.5
Exception Type: OSError
Exception Value:    
[Errno 2] No such file or directory
Exception Location: /usr/lib/python2.7/subprocess.py in _execute_child, line 1249
Python Executable:  /home/ubuntu/Envs/venv/bin/python
Python Version: 2.7.3

The error is thrown by this line : subprocess.call(shlex.split(proc_string), stdout=open(os.devnull, 'wb'))

The full traceback:

Traceback:
File "/home/ubuntu/Envs/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/home/ubuntu/CURRENT/project/appname/apps/catpdf/views.py" in render_preview
  114.             subprocess.call(shlex.split(proc_string), stdout=open(os.devnull, 'wb'))
File "/usr/lib/python2.7/subprocess.py" in call
  493.     return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.7/subprocess.py" in __init__
  679.                             errread, errwrite)
File "/usr/lib/python2.7/subprocess.py" in _execute_child
  1249.                 raise child_exception

Exception Type: OSError at /pdf/view/1/85/
Exception Value: [Errno 2] No such file or directory

This is unusual because when I tested the application using the Django dev server, or invoking Gunicorn from the command line with gunicorn wsgi:app -- the file is returned successfully. The servers are always behind nginx.

Here's the section of code that's throwing error (subprocess.call line):

        output = t.render(cont)
        oname = ''.join([slugify(context['qb_full_name']), datetime.datetime.now().strftime("%Y%m%d_%H%M")])
        out_f = open(''.join([os.path.join(rnddir, oname), '.tex']), "w")
        out_f.write(output.encode('utf-8'))
        out_f.close()
        #jname = ''.join(['-jobname=', oname])
        proc_string = ' '.join(['pdflatex', '-output-directory', rnddir, os.path.abspath(out_f.name)])
        subprocess.call(shlex.split(proc_string), stdout=open(os.devnull, 'wb'))
        fname = os.path.join(rnddir, ''.join([oname, '.pdf']))
        pdf = open(fname, 'r')
        for s in signatures:
            os.unlink(s)
        response = http.HttpResponse(FixedFileWrapper(pdf), content_type=mimetypes.guess_type(fname)[0])
        response['Content-Disposition'] = 'attachment; filename="%s"' % os.path.basename(fname)
        response['Content-Length'] = os.path.getsize(fname)
        return response

Local vars from django debug:

out_f   
<closed file u'/home/ubuntu/CURRENT/project/appname/apps/catpdf/rendered/customer-name20130509_1541.tex', mode 'w' at 0x4211780>
signatures  
['/home/ubuntu/CURRENT/project/appname/apps/catpdf/tmp/tmpyJrUYO.pdf',
 '/home/ubuntu/CURRENT/project/appname/apps/catpdf/tmp/tmpLGMaRT.pdf']
rnddir
'/home/ubuntu/CURRENT/project/appname/apps/catpdf/rendered'
proc_string 
u'pdflatex -output-directory /home/ubuntu/CURRENT/project/appname/apps/catpdf/rendered /home/ubuntu/CURRENT/project/appname/apps/catpdf/rendered/customer-name20130509_1541.tex'

supervisor configuration:

[program:gunicorn]
directory=%(ENV_HOME)s/CURRENT/project
user=ubuntu
command=gunicorn --preload wsgi:appname
environment=PATH="/home/ubuntu/Envs/venv/bin"
stdout_logfile = %(ENV_HOME)s/CURRENT/logs/guni-access.log
stderr_logfile = %(ENV_HOME)s/CURRENT/logs/guni-error.log
autostart=True
autorestart=True
priority=997
kevins
  • 472
  • 6
  • 17

1 Answers1

4

You are overwriting the PATH environment variable. You need to use the absolute path to pdflatex for call to find it.

Thomas Fenzl
  • 4,342
  • 1
  • 17
  • 25
  • Ahhh, that would make sense. I'll see if that fixes it – kevins May 09 '13 at 16:21
  • Thanks! What would be the best way of handling this situation - hardcoding absolute paths, or is there another way to configure supervisor/gunicorn? – kevins May 09 '13 at 16:36
  • I would use a hardcoded path to gunicorn in the supervisor configuration and not modify the PATH variable. – Thomas Fenzl May 09 '13 at 16:38
  • Is is possible to append to path in a supervisor config like done in bash files `PATH=PATH:/home/ubuntu/Envs/venv/bin/program/`? – kevins May 10 '13 at 16:31
  • 2
    I don't think so. I couldn't put together a config file that did that, and only found an (oldish) mailing list entry that says variables are not expanded in configurations: https://lists.supervisord.org/pipermail/supervisor-users/2008-March/000203.html – Thomas Fenzl May 10 '13 at 20:43
  • Same here. Adding gunicorn to the `PATH` didn't solve the issue for me. Any success with running airflow (1.10) with systemd ? – vikram2784 Dec 05 '18 at 12:03