title: Upstart - how to send reload signal to script started as different user?
body: <p>I have python program (couple of scripts) that need to be run as daemon on remote machine which is CentOS 6.4. So, I thought Upstart is the way to go.</p>
  
  <p>Basic requirements are:</p>
  
  <ul>
  <li>Easy way to start/stop daemon app</li>
  <li>Respawn app if it crashes</li>
  <li>App must run under non-privileged user</li>
  <li>Be able to handle SIGHUP to reload config</li>
  </ul>
  
  <p>Upstart version on that server is 0.6.5, so stanzas <a href="http://upstart.ubuntu.com/cookbook/#setuid" rel="nofollow">setuid</a> and <a href="http://upstart.ubuntu.com/cookbook/#setgid" rel="nofollow">setgid</a> are not available (they appear only in 1.4). So I use <a href="http://upstart.ubuntu.com/cookbook/#run-a-job-as-a-different-user" rel="nofollow">official workaround</a> from cookbook. I am able to start/stop my app, but my main problem is that my app isn't receiving reload signal.</p>
  
  <p>I'll provide stripped scripts that can reproduce the issue.</p>
  
  <p>Python script (<code>app.py</code>):</p>
  
  <pre><code>import os
  import time
  import signal
  import logging
  
  logging.basicConfig(filename='hup.log', level=logging.INFO,
      format="%(asctime)s: %(levelname)s: %(message)s")
  log = logging.getLogger(__name__)
  
  
  running = True
  
  def run():
      log.info('PROGRAM STARTUP')
      log.info('Current pid: %d' % os.getpid())
  
      while running:
          log.info('Doing some hard work')
          time.sleep(10)
      else:
          log.info('PROGRAM TEARDOWN')
  
  def signal_handler(signum, frame):
      log.info("Received Signal: %s at frame: %s" % (signum, frame))
  
      if signum == signal.SIGTERM:
          log.info('Received request to terminate daemon (SIGTERM)')
          global running
          running = False
      elif signum == signal.SIGHUP:
          log.info('Received reload config request (SIGHUP)')
          pass  # reload config here
  
  
  signal.signal(signal.SIGHUP, signal_handler)
  signal.signal(signal.SIGTERM, signal_handler)
  
  run()
  </code></pre>
  
  <p>And Upstart config (<code>hup.conf</code>):</p>
  
  <pre><code>start on runlevel [2345]
  stop on runlevel [!2345]
  
  respawn
  respawn limit 10 5
  
  chdir /home/dev/prj/im
  
  script
      # activate the virtual environment
      . /home/dev/.virtualenvs/myvenv/bin/activate
  
      # This line runs script as root
      # exec python app.py
  
      # this is official workaround for running prcesses as different
      # user in upstart version prior to 1.4
      # Run as user 'dev'
      exec su -s /bin/sh -c 'exec "$0" "$@"' dev -- python app.py
  end script
  </code></pre>
  
  <p>Output (as you can see, actual process with <code>python app.py</code> is having different PID than upstart shows):</p>
  
  <pre><code>[dev@localhost ~]$ sudo start hup
  hup start/running, process 8608
  [dev@localhost ~]$ ps -elf | grep app.py
  F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
  4 S root      8608     1  0  80   0 - 16143 wait   19:53 ?        00:00:00 su -s /bin/sh -c exec "$0" "$@" dev -- python app.py
  4 S dev       8613  8608  0  80   0 -  7866 poll_s 19:53 ?        00:00:00 python app.py
  [dev@localhost ~]$ sudo reload hup
  [dev@localhost ~]$ sudo stop hup
  hup stop/waiting
  </code></pre>
  
  <p>Log shows no reload signal received:</p>
  
  <pre><code>2013-09-19 20:00:36,092: INFO: PROGRAM STARTUP
  2013-09-19 20:00:36,093: INFO: Current pid: 8613
  2013-09-19 20:00:36,093: INFO: Doing some hard work
  2013-09-19 20:00:45,287: INFO: Received Signal: 15 at frame: &lt;frame object at 0xba2dd0&gt;
  2013-09-19 20:00:45,287: INFO: Received request to terminate daemon (SIGTERM)
  2013-09-19 20:00:45,287: INFO: PROGRAM TEARDOWN
  </code></pre>
  
  <p>But when I uncomment the line in <code>hup.conf</code> with <code>exec python app.py</code> (and comment one with <code>exec su...</code>), everything works, except the app is running as root.</p>
  
  <pre><code>[dev@localhost ~]$ sudo start hup
  hup start/running, process 8811
  [dev@localhost ~]$ ps -elf | grep app.py
  F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
  4 S root      8811     1  0  80   0 -  8412 poll_s 20:13 ?        00:00:00 python app.py
  [dev@localhost ~]$ sudo reload hup
  [dev@localhost ~]$ sudo stop hup
  hup stop/waiting
  </code></pre>
  
  <p>Log file shows SIGHUP signal has been received:</p>
  
  <pre><code>2013-09-19 20:13:40,290: INFO: PROGRAM STARTUP
  2013-09-19 20:13:40,290: INFO: Current pid: 8811
  2013-09-19 20:13:40,291: INFO: Doing some hard work
  2013-09-19 20:13:59,739: INFO: Received Signal: 1 at frame: &lt;frame object at 0x7d44c0&gt;
  2013-09-19 20:13:59,739: INFO: Received reload config request (SIGHUP)
  2013-09-19 20:13:59,739: INFO: Doing some hard work
  2013-09-19 20:14:04,313: INFO: Received Signal: 15 at frame: &lt;frame object at 0x7d44c0&gt;
  2013-09-19 20:14:04,313: INFO: Received request to terminate daemon (SIGTERM)
  2013-09-19 20:14:04,313: INFO: PROGRAM TEARDOWN
  </code></pre>
  
  <p>My main question is how to make <code>reload</code> command work when I run script under different user on this old version of upstart?</p>