在supervisord启动的Python进程下获取用户的主文件夹

时间:2015-05-04 23:44:13

标签: python django freebsd supervisord

我想将登录密码存储在Django配置中当前用户帐户的文件中。我使用推荐的便携方式获取主文件夹,如:

os.path.expanduser("~")

这在所有环境中都有效,无论是在本地还是在服务器上以gunicorn -D config.wsgi启动时都适用。

然而,我的问题是我引入了supervisord来控制gunicorn进程,现在这个函数不起作用,只返回/

这是supervisord.conf的相关部分

[program:kek_django]
command=.../venv/bin/gunicorn config.wsgi
directory=.../django
user=testuser

在此环境下,os.path.expanduser("〜")变为/

你能告诉我如何通过修复环境或用于检测主目录的函数来解决这个问题吗?

注意:操作系统是FreeBSD 10,如果相关的话

更新:os.environ在运行过程中报告以下内容:

'SUPERVISOR_SERVER_URL': 'unix:///var/run/supervisor/supervisor.sock',
'RC_PID': '84177',
'SERVER_SOFTWARE': 'gunicorn/19.3.0',
'SUPERVISOR_ENABLED': '1', 
'SUPERVISOR_PROCESS_NAME': 'test_django',
'PWD': '/',
'DJANGO_SETTINGS_MODULE': 'config.settings.production', 
'SUPERVISOR_GROUP_NAME': 'test_django', 
'PATH': '/sbin:/bin:/usr/sbin:/usr/bin',
'HOME': '/'

1 个答案:

答案 0 :(得分:2)

supervisord的{​​{3}}文档说:

  

supervisord运行子进程时没有执行shell,所以环境变量如USERPATHHOMESHELL,{{ 1}}等不会更改其默认值或以其他方式重新分配。当您从LOGNAME以root身份运行程序并且配置中包含supervisord节时,这一点尤为重要。与user=不同,cron不会尝试神圣和覆盖“基本”环境变量,例如supervisordUSERPATHHOME它对LOGNAME程序配置选项中定义的用户执行setuid。如果需要为特定程序设置可能由特定用户的shell调用设置的特定程序的环境变量,则必须在user=程序配置选项中明确执行。设置这些环境变量的示例如下所示。

environment=

所以,这是实际修复。 (如果你动态地构造[program:apache2] command=/home/chrism/bin/httpd -c "ErrorLog /dev/stdout" -DFOREGROUND user=chrism environment=HOME="/home/chrism",USER="chrism" 文件并且需要知道如何动态地查看这些值,我可以解释一下,但这很容易,而且我认为你无论如何都不需要它。)

supervisord.conf

如果这对您没有意义,请考虑:

如果您以root身份运行[program:kek_django] command=.../venv/bin/gunicorn config.wsgi directory=.../django user=testuser environment=HOME="/home/testuser" ,则它没有supervisord的{​​{1}}或其他任何内容。它所做的只是testuser,它只是改变了它的用户ID;它没有为shell或系统的任何其他部分提供任何设置HOME变量的机会。大多数类似的工具都有伪造它的解决方法,跟随着setuid(testuser)工作原理的磨砺脚步,但testuser故意选择不这样做。

或者,正如Subprocess Environment的文档所说:

  

在Unix上,如果设置了初始cron,则由环境变量HOME替换;否则,通过内置模块pwd在密码目录中查找当前用户的主目录。直接在密码目录中查找初始supervisord

快速查看expanduser表明它以最明显的方式做到了这一点。

因此,您的代码中有三个明显的变通方法:

  1. 使用~代替~user(如果需要,您甚至可以通过用户名以编程方式生成)。
  2. 编写您自己的~testuser函数,该函数只执行~而不检查expanduser
  3. 如果是pwd.getpwuid(os.getuid()).pw_dir,则在启动时手动将HOME设置为HOME