2008年01月17日 星期四 12:09
今天在升级一个django开发的系统到V2的时候,发现~/无法正确的展开成
/home/hackgou.(apache是以hackgou帐号执行的,)也不会展开成/root(apache是以root启动的)
觉得非常奇怪,就算是用os.path.expanduser('~/')也无济于事。
于是怀疑是os.envrion['HOME']不对,因为expanduser是需要这个变量来展开~/的。
于是使用setenv HOME /home/hackgou/
可是也不工作,后来在django/core/handlers/modpython.py的ModPythonHandler中
发现Django开发组已经注意到,mod_python不理会apache的setENV指令:
# mod_python fakes the environ, and thus doesn't process
SetEnv. This fixes that
os.environ.update(req.subprocess_env)
但是这个和SetEnv DJANGO_SETTINGS_MODULE app.settings
自相矛盾矛盾,真晕,自己不设置正确的,也不搭理管理员指定的,怎么办?
后来在http://code.google.com/p/modwsgi/wiki/ApplicationIssues找到一些类似的情况,
提到sudo的时候有bug,会导致HOME和root启动的HOME不一样,太好了,我就要这样的bug。
设置hackgou账号的sudo权限,然后用sudo来启动apache,果然所有的expanduser('~/')都顺利。
除此之外, 文中提到
import os, pwd
os.environ["HOME"] = pwd.getpwuid(os.getuid()).pw_dir
这样的代码,似乎可以解决这个问题,神啊,我很反感这种做法:
1.django中似乎没有地方可以放置这样的需要这个APP都需要的代码,我的DRY啊
2.Django修改环境变量似乎成了习惯,之前碰到个TIME_ZONE的问题,就是因为修改了APACHE的环境变量,导致
别的应用环境受到污染,要知道一个apache进程是很多应用共享的,
除了Djano还有别的应用,比如别的Django应用或者PHP,都有可能在一个相同的APACHE进程空间中处理,
说有可能是因为apache本身的一些设置会出现这些差别,跟py没有关系,
这样会导致他们的工作环境受到污染。这似乎没有好的方法可以解决这个问题,
对Django或者说对mod_python 的这种拖泥带水的做法感觉非常的不爽。
也不知道有没有更好的更彻底的解决方法?
如果谁知道,能够告诉我那是最好不过的了
--
关注LAMP平台、安全、及web开发的个人blog: http://hackgou.itbbq.com
PGP KeyID: hackgou#Gmail.com
PGP KeyServ: subkeys.pgp.net
2008年01月17日 星期四 12:27
本来就不要依赖环境变量, 自己把 ~/ 替换为你的目录吧, 可能的话, scgi/fcgi 替换调 mod_python 会更好些 2008/1/17 憨狗 <hackgou at gmail.com>: > 今天在升级一个django开发的系统到V2的时候,发现~/无法正确的展开成
2008年01月17日 星期四 13:25
> 本来就不要依赖环境变量, 嗯,没错,那也没有好的办法避免这种hard coding呢? > 自己把 ~/ 替换为你的目录吧, > > > 可能的话, scgi/fcgi 替换调 mod_python 会更好些 > > 2008/1/17 憨狗 <hackgou at gmail.com>: > > 今天在升级一个django开发的系统到V2的时候,发现~/无法正确的展开成 > _______________________________________________ > python-chinese > Post: send python-chinese at lists.python.cn > Subscribe: send subscribe to python-chinese-request at lists.python.cn > Unsubscribe: send unsubscribe to python-chinese-request at lists.python.cn > Detail Info: http://python.cn/mailman/listinfo/python-chinese -- 关注LAMP平台、安全、及web开发的个人blog: http://hackgou.itbbq.com PGP KeyID: hackgou#Gmail.com PGP KeyServ: subkeys.pgp.net
2008年01月17日 星期四 13:27
把这些弄独立出来, 比如都弄到 conf.py 2008/1/17 憨狗 <hackgou at gmail.com>: > > 本来就不要依赖环境变量, > 嗯,没错,那也没有好的办法避免这种hard coding呢? > >
2008年01月17日 星期四 13:37
2008/1/17 Jiahua Huang <jhuangjiahua at gmail.com>: > 把这些弄独立出来, > 比如都弄到 conf.py 然后再hard coding进去? :P > 2008/1/17 憨狗 <hackgou at gmail.com>: > > > 本来就不要依赖环境变量, > > 嗯,没错,那也没有好的办法避免这种hard coding呢? > > > > > > _______________________________________________ > python-chinese > Post: send python-chinese at lists.python.cn > Subscribe: send subscribe to python-chinese-request at lists.python.cn > Unsubscribe: send unsubscribe to python-chinese-request at lists.python.cn > Detail Info: http://python.cn/mailman/listinfo/python-chinese -- 关注LAMP平台、安全、及web开发的个人blog: http://hackgou.itbbq.com PGP KeyID: hackgou#Gmail.com PGP KeyServ: subkeys.pgp.net
2008年01月17日 星期四 13:41
conf.py 里 homedir = '/home/hackgou' 之类 2008/1/17 憨狗 <hackgou at gmail.com>: > 2008/1/17 Jiahua Huang <jhuangjiahua at gmail.com>: > > 把这些弄独立出来, > > 比如都弄到 conf.py > 然后再hard coding进去? :P >
2008年01月17日 星期四 13:48
×ÜÊǵÃhard codeһЩ¶«Î÷µÄ°É ±ÈÈçDBUSER DBPASSÖ®ÀàµÄ¡£ ¶àµã·¾¶Ò²Ã»Ê²Ã´¡£ On 1/17/08, Jiahua Huang <jhuangjiahua在gmail.com> wrote: > > conf.py Àï homedir = '/home/hackgou' Ö®Àà > > > 2008/1/17 º©¹· <hackgou在gmail.com>: > > 2008/1/17 Jiahua Huang <jhuangjiahua在gmail.com>: > > > °ÑÕâЩŪ¶ÀÁ¢³öÀ´£¬ > > > ±ÈÈ綼Ūµ½ conf.py > > È»ºóÔÙhard coding½øÈ¥£¿ :P > > > _______________________________________________ > python-chinese > Post: send python-chinese在lists.python.cn > Subscribe: send subscribe to python-chinese-request在lists.python.cn > Unsubscribe: send unsubscribe to python-chinese-request在lists.python.cn > Detail Info: http://python.cn/mailman/listinfo/python-chinese -------------- 下一部分 -------------- Ò»¸öHTML¸½¼þ±»ÒƳý... URL: http://python.cn/pipermail/python-chinese/attachments/20080117/44ff6207/attachment.html
2008年01月17日 星期四 13:59
2008/1/17 @@ <askfor在gmail.com>: > 总是得hard code一些东西的吧 比如DBUSER DBPASS之类的。 > 多点路径也没什么。 > 不是一个简单的hard coding的问题,关键是不要在程序中写死,易变或配置的东西应该独立出来,方便进行修改。 -- I like python! UliPad <>: http://code.google.com/p/ulipad/ meide < >: http://code.google.com/p/meide/ My Blog: http://www.donews.net/limodou
2008年01月17日 星期四 17:03
> 发现Django开发组已经注意到,mod_python不理会apache的setENV指令:
>
> # mod_python fakes the environ, and thus doesn't process
> SetEnv. This fixes that
> os.environ.update(req.subprocess_env)
>
> 但是这个和SetEnv DJANGO_SETTINGS_MODULE app.settings
> 自相矛盾矛盾,真晕,自己不设置正确的,也不搭理管理员指定的,怎么办?
这个并不自相矛盾,SetEnv不是mod_python处理的,而是mod_env处理的,处理的结果就在req.subprocess_env,只是mod_python并没有赋值给os.environ,所以Django要自己搞一下。问题就在于os.environ.update的时候还putenv了,一般来讲修改过环境变量要恢复回去,Django没有干这个事。给一个小补丁来干这个:
Index: modpython.py
===================================================================
--- modpython.py (revision 7003)
+++ modpython.py (working copy)
@@ -141,6 +141,8 @@
def __call__(self, req):
# mod_python fakes the environ, and thus doesn't process SetEnv.
This fixes that
+ # First save env, after finished restore
+ save_env = os.environ.copy()
os.environ.update(req.subprocess_env)
# now that the environ works we can see the correct settings, so
imports
@@ -166,6 +168,12 @@
response = self.apply_response_fixes(request, response)
finally:
dispatcher.send(signal=signals.request_finished)
+ osenv = os.environ
+ # restore env
+ for k in osenv.keys():
+ del osenv[k]
+ for k in sav_env:
+ osenv[k] = sav_env[k]
# Convert our custom HttpResponse object back into the mod_python
req.
req.content_type = response['Content-Type']
这样就可以把
import os, pwd
os.environ["HOME"] = pwd.getpwuid(os.getuid()).pw_dir
加到这里面,不违反DRY原则吧 ;-)
> 后来在http://code.google.com/p/modwsgi/wiki/ApplicationIssues找到一些类似的情况,
> 提到sudo的时候有bug,会导致HOME和root启动的HOME不一样,太好了,我就要这样的bug。
> 设置hackgou账号的sudo权限,然后用sudo来启动apache,果然所有的expanduser('~/')都顺利。
> 除此之外, 文中提到
>
> import os, pwd
> os.environ["HOME"] = pwd.getpwuid(os.getuid()).pw_dir
>
> 这样的代码,似乎可以解决这个问题,神啊,我很反感这种做法:
> 1.django中似乎没有地方可以放置这样的需要这个APP都需要的代码,我的DRY啊
> 2.Django修改环境变量似乎成了习惯,之前碰到个TIME_ZONE的问题,就是因为修改了APACHE的环境变量,导致
> 别的应用环境受到污染,要知道一个apache进程是很多应用共享的,
> 除了Djano还有别的应用,比如别的Django应用或者PHP,都有可能在一个相同的APACHE进程空间中处理,
> 说有可能是因为apache本身的一些设置会出现这些差别,跟py没有关系,
> 这样会导致他们的工作环境受到污染。这似乎没有好的方法可以解决这个问题,
> 对Django或者说对mod_python 的这种拖泥带水的做法感觉非常的不爽。
> 也不知道有没有更好的更彻底的解决方法?
> 如果谁知道,能够告诉我那是最好不过的了
>
2008年01月17日 星期四 22:44
> 这个并不自相矛盾,SetEnv不是mod_python处理的,而是mod_env处理的,处理的结果就在req.subprocess_env,只是mod_python并没有赋值给os.environ,所以Django要自己搞一下。问题就在于os.environ.update的时候还putenv了,一般来讲修改过环境变量要恢复回去,Django没有干这个事。给一个小补丁来干这个:
>
mod_env和mod_python如何处理environ我没有详查,但是经过测试:
未添加setenv时os.path.expanduser("~/")拿到的结果是None
setenv HOEM /home/hackgou之后,os.path.expanduser("~/")拿到的结果是/root,而不是/home/hackgou。
而只有以hackgou用户通过sudo 启动apache时,可以得到正确结果,
此时再设置setenv HOME /home/hackgou,已经不重要了。
> @@ -141,6 +141,8 @@
>
> def __call__(self, req):
> # mod_python fakes the environ, and thus doesn't process SetEnv.
> This fixes that
> + # First save env, after finished restore
> + save_env = os.environ.copy()
> os.environ.update(req.subprocess_env)
>
> # now that the environ works we can see the correct settings, so
> imports
> @@ -166,6 +168,12 @@
> response = self.apply_response_fixes(request, response)
> finally:
> dispatcher.send(signal=signals.request_finished)
> + osenv = os.environ
> + # restore env
> + for k in osenv.keys():
> + del osenv[k]
> + for k in sav_env:
> + osenv[k] = sav_env[k]
>
> # Convert our custom HttpResponse object back into the mod_python
> req.
> req.content_type = response['Content-Type']
>
> 这样就可以把
> import os, pwd
> os.environ["HOME"] = pwd.getpwuid(os.getuid()).pw_dir
>
> 加到这里面,不违反DRY原则吧 ;-)
这样的patch似乎是比较完美的解决办法,破坏现场后恢复现场。我还没有测试过,
不过看其应该没有问题!Very Good!
不知道这个patch有提交么?
另外一个问题,在apache的worker和prefork模式下,是否会影响其他应用,
因为我的理解是worker模式下应该会比较困难,因为所有线程共享相同的系统环境变量共享,
所以我认为相互间肯定会有污染,而在prefork模式下,我就不确定了!
理想状态下,是不应该干扰的。
之所以有这个问题,是因为曾经有过这样的情况:
apache同时支持mod_python和mod_php时。
php中获取本地时间有时候是洛杉矶LA时间有时候是上海时间,
这个服务器在上海,而Django应用的时区需要设置为LA,这个时候就互相影响:
如果这个处理php的进程还没有处理过Django的请求,那么它得到的本地时间是上海时间
如果这个处理php的进程已经处理过Django的请求,那么它得到的本地时间就是LA时间
如果在PHP中设定时区的话,效果是一样的,也会互相干扰。
如果给Django打上这个patch,在prefork情况下,效果如何?
vcc有没有什么建议讲来听听?
2008年01月18日 星期五 19:46
> 不知道这个patch有提交么? 没有提交,觉得Django设置的环境变量DJANGO_SETTINGS_MODULE一般不会影响到其他应用,如果没修改象时区这样设置的话实在没恢复的必要。 > 另外一个问题,在apache的worker和prefork模式下,是否会影响其他应用, > 因为我的理解是worker模式下应该会比较困难,因为所有线程共享相同的系统环境变量共享, > 所以我认为相互间肯定会有污染,而在prefork模式下,我就不确定了! > 理想状态下,是不应该干扰的。 > 之所以有这个问题,是因为曾经有过这样的情况: > apache同时支持mod_python和mod_php时。 > php中获取本地时间有时候是洛杉矶LA时间有时候是上海时间, > 这个服务器在上海,而Django应用的时区需要设置为LA,这个时候就互相影响: > 如果这个处理php的进程还没有处理过Django的请求,那么它得到的本地时间是上海时间 > 如果这个处理php的进程已经处理过Django的请求,那么它得到的本地时间就是LA时间 > > 如果在PHP中设定时区的话,效果是一样的,也会互相干扰。 > > 如果给Django打上这个patch,在prefork情况下,效果如何? prefork应该没问题。 最安全的做法是独立apache,然后透过proxy来对外服务,这样怎么改都不会有影响。 vcc _
Zeuux © 2025
京ICP备05028076号