calmari日志提示OperationalError Permission denied

2015年11月06日 03:40

问题

在fedora22系统中部署calmari,使用calamari-ctl initialize启动calamari后,访问浏览器,浏览器提示500。查看日志文件/var/log/calmari/httpd_error.log,得到以下内容。
[Tue Nov 03 19:42:01.210895 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168] mod_wsgi (pid=8586): Exception occurred processing WSGI script '/opt/calamari/conf/calamari.wsgi'.
[Tue Nov 03 19:42:01.210915 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168] Traceback (most recent call last):
[Tue Nov 03 19:42:01.210931 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 255, in __call__
[Tue Nov 03 19:42:01.211007 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     response = self.get_response(request)
[Tue Nov 03 19:42:01.211018 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 178, in get_response
[Tue Nov 03 19:42:01.211032 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
[Tue Nov 03 19:42:01.211040 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 220, in handle_uncaught_exception
[Tue Nov 03 19:42:01.211050 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     if resolver.urlconf_module is None:
[Tue Nov 03 19:42:01.211056 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/core/urlresolvers.py", line 342, in urlconf_module
[Tue Nov 03 19:42:01.211066 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     self._urlconf_module = import_module(self.urlconf_name)
[Tue Nov 03 19:42:01.211080 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
[Tue Nov 03 19:42:01.211091 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     __import__(name)
[Tue Nov 03 19:42:01.211097 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/calamari_web-0.1-py2.7.egg/calamari_web/urls.py", line 20, in <module>
[Tue Nov 03 19:42:01.211109 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     url(r'^api/v1/', include('calamari_rest.urls.v1')),
[Tue Nov 03 19:42:01.211115 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/conf/urls/__init__.py", line 25, in include
[Tue Nov 03 19:42:01.211125 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     urlconf_module = import_module(urlconf_module)
[Tue Nov 03 19:42:01.211131 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
[Tue Nov 03 19:42:01.211139 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     __import__(name)
[Tue Nov 03 19:42:01.211145 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/calamari_rest_api-0.1-py2.7.egg/calamari_rest/urls/v1.py", line 3, in <module>
[Tue Nov 03 19:42:01.211156 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     import calamari_rest.views.v1
[Tue Nov 03 19:42:01.211162 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/calamari_rest_api-0.1-py2.7.egg/calamari_rest/views/v1.py", line 33, in <module>
[Tue Nov 03 19:42:01.211171 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     from graphite.render.datalib import fetchData
[Tue Nov 03 19:42:01.211177 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/graphite/render/datalib.py", line 20, in <module>
[Tue Nov 03 19:42:01.211187 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     from graphite.storage import STORE, LOCAL_STORE
[Tue Nov 03 19:42:01.211192 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/graphite/storage.py", line 7, in <module>
[Tue Nov 03 19:42:01.211201 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     from graphite.remote_storage import RemoteStore
[Tue Nov 03 19:42:01.211207 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/graphite/remote_storage.py", line 8, in <module>
[Tue Nov 03 19:42:01.211216 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     from graphite.util import unpickle
[Tue Nov 03 19:42:01.211221 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/graphite/util.py", line 71, in <module>
[Tue Nov 03 19:42:01.211230 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     defaultUser = User.objects.get(username='default')
[Tue Nov 03 19:42:01.211235 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/db/models/manager.py", line 143, in get
[Tue Nov 03 19:42:01.211245 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     return self.get_query_set().get(*args, **kwargs)
[Tue Nov 03 19:42:01.211251 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/db/models/query.py", line 382, in get
[Tue Nov 03 19:42:01.211259 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     num = len(clone)
[Tue Nov 03 19:42:01.211265 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/db/models/query.py", line 90, in __len__
[Tue Nov 03 19:42:01.211272 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     self._result_cache = list(self.iterator())
[Tue Nov 03 19:42:01.211282 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/db/models/query.py", line 301, in iterator
[Tue Nov 03 19:42:01.211290 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     for row in compiler.results_iter():
[Tue Nov 03 19:42:01.211295 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 775, in results_iter
[Tue Nov 03 19:42:01.211305 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     for rows in self.execute_sql(MULTI):
[Tue Nov 03 19:42:01.211310 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 839, in execute_sql
[Tue Nov 03 19:42:01.211318 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     cursor = self.connection.cursor()
[Tue Nov 03 19:42:01.211324 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/db/backends/__init__.py", line 326, in cursor
[Tue Nov 03 19:42:01.211333 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     cursor = util.CursorWrapper(self._cursor(), self)
[Tue Nov 03 19:42:01.211339 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 182, in _cursor
[Tue Nov 03 19:42:01.211348 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     self.connection = Database.connect(**conn_params)
[Tue Nov 03 19:42:01.211354 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]   File "/opt/calamari/venv/lib/python2.7/site-packages/psycopg2/__init__.py", line 167, in connect
[Tue Nov 03 19:42:01.211363 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168]     conn = _connect(dsn, connection_factory=connection_factory, async=async)
[Tue Nov 03 19:42:01.211376 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168] OperationalError: could not connect to server: Permission denied
[Tue Nov 03 19:42:01.211380 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168] \tIs the server running on host "localhost" (127.0.0.1) and accepting
[Tue Nov 03 19:42:01.211383 2015] [wsgi:error] [pid 8586] [remote 127.0.0.1:168] \tTCP/IP connections on port 5432?

解决

原因可能是postgresql自身访问限制、用户权限问题,检查后均被排除。查询资料得知,访问权限被selinux限制了。
  • 第一种方法是设置selinux去掉访问限制
sudo setsebool -P httpd_can_network_connect_db on
  • 第二种方法是关闭selinux
编辑/etc/selinux/config,将参数配为禁用,再重启系统。
SELINUX=disabled

相关

getsebool -a 查看selinux控制项
 

 

Tags: ceph;django
评论(0) 阅读(1659)

gettext国际化用法示例

2015年9月09日 16:36

  • 安装gettext
sudo yum install gettext
  • gettext工具
gettext: 进行translate。
 
xgettext: 从程序中抽取调用gettext进行本地化的字符串,生成一份.po结尾的配置文件。
 
msgfmt: 将配置好的本地化配置文件进行转换成gettext使用的格式。
  • 准备demo.py
#encoding=utf-8
import gettext

# demo对应mo文件名,locale为locale目录地址,zh_CN为locale目录下目录名
zh = gettext.translation("demo", "locale", languages=["zh_CN"])
# 激活_()
zh.install(True)
print _("hello world")
  • 生成po文件
 
从程序文件中抽取,使用gettext的字符串,生成po文件
xgettext -L python -o zh_CN.po demo.py
  • 编辑po文件
...
#修改编码为utf-8
"Content-Type: text/plain; charset=utf-8\n"
...

#加上翻译
#: demo.py:6
msgid "hello world"
msgstr "你好,世界"
  • 创建locale目录
mkdir -p locale/zh_CN/LC_MESSAGES
 
* 编译po文件
msgfmt -o ~/locale/zh_CN/LC_MESSAGES/demo.mo zh_CN.po
  • 查看结果
➜  ~  python demo.py
你好,世界
 

Tags: 国际化
评论(0) 阅读(2197)

净空法师:年轻时候好,是你前生所修的

2015年7月24日 08:57

经上常跟我们说:修财布施得财富。你过去世修得多,这一生得的财富多,发大财;你前生没有修财布施,这一生物质生活一定贫乏。你修法布施,这一生得聪明智慧;你修无畏布施,这一生得健康长寿。
 
有果,一定有因,因果丝毫不爽。一般讲,人在四十岁之前受前生业力影响大,四十岁之前的果报是前生的。
 
有些人年轻时候发达,那个福报是前生的。如果他发达的时候胡作妄为,不干好事情,中年以后逐渐就会衰败,甚至晚年潦倒不堪,非常的可怜,这一生没有修!
 
福报是前生的,这一生要是真正修得好,他的晚年好。所以四十岁以后是今生的力量大,前生的力量很薄弱,所以在四十岁是很大的转变!晚年好,是你今生所修的;年轻时候好,是你前生所修的,我们要明白这个道理。
 

评论(0) 阅读(1401)

django-restful请求的访问限制

2015年7月22日 15:17

login_required无效

用django的restful写成的请求处理,使用auth模块中装饰器进行访问限制,出现request无user属性的错误.
 
from django.views.generic import View
from django.contrib.auth.decorators import login_required

class TaskQueue(View):
    '''
    执行中的任务
    '''
    def __init__(self):
        self.manager = TaskQueueManager()

    def get(self, request):
        '''
        >> c.get("/task/queue/").content
        '''
        records = self.manager.list()
        return {"success": True, "msg": "", "data": records}

    @login_required
    def delete(self, request):
        '''
        >> c.delete("/task/queue/", json.dumps({"ids": [14]})).content
        '''
        params = json.loads(request.body)
        for id in params["ids"]:
            self.manager.delete(id)
        return {"success": True, "msg": ""}

查找原因

从django里拿到源码,调试后,发现View对象被赋给了装饰器的request.
 
def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
    """
    Decorator for views that checks that the user passes the given test,
    redirecting to the log-in page if necessary. The test should be a callable
    that takes the user object and returns True if the user passes.
    """

    def decorator(view_func):
        @wraps(view_func, assigned=available_attrs(view_func))
        # view对象传给料request
        def _wrapped_view(request, *args, **kwargs):
            if test_func(request.user):
                return view_func(request, *args, **kwargs)
            path = request.build_absolute_uri()
            resolved_login_url = resolve_url(login_url or settings.LOGIN_URL)
            # If the login url is the same scheme and net location then just
            # use the path as the "next" url.
            login_scheme, login_netloc = urlparse(resolved_login_url)[:2]
            current_scheme, current_netloc = urlparse(path)[:2]
            if ((not login_scheme or login_scheme == current_scheme) and
                    (not login_netloc or login_netloc == current_netloc)):
                path = request.get_full_path()
            from django.contrib.auth.views import redirect_to_login
            return redirect_to_login(
                path, resolved_login_url, redirect_field_name)
        return _wrapped_view
    return decorator


def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None):
    """
    Decorator for views that checks that the user is logged in, redirecting
    to the log-in page if necessary.
    """
    actual_decorator = user_passes_test(
        lambda u: u.is_authenticated(),
        login_url=login_url,
        redirect_field_name=redirect_field_name
    )
    if function:
        return actual_decorator(function)
    return actual_decorator

自定义login_required

解决的办法是进行自定义. 将user_passes_test和login_required拿出来,作如下修改
 
...
# 加上self
def _wrapped_view(self, request, *args, **kwargs):
    if test_func(request.user):
        # 加上self
        return view_func(self, request, *args, **kwargs)
...
 

 

评论(0) 阅读(1554)

如何得到yum的rpm包

2015年7月15日 18:02

  • 安装yum-utils
yum -y install yum-utils
  • 下载rpm
yumdownloader proxychains
得到proxychains-3.1-16.fc22.i686.rpm 、proxychains-3.1-16.fc22.x86_64.rpm两个文件
  • 下载源码
yumdownloader --source proxychains
得到文件proxychains-3.1-16.fc22.src.rpm
 

 

Tags: rpm
评论(0) 阅读(1239)

supervisor用法

2015年7月09日 18:12

以什么方式运行进程?将它做成服务,再以"service xxx start/stop"方式运行。
或者以"nohup xxx &"方式运行,需要停止时,先ps获得进程id,然后kill掉.
有什么好点的办法?supervisor正好解决这个问题。
  • 安装
sudo pip install supervisor
  • 创建配置文件
echo_supervisord_conf > /etc/supervisord.conf
  • 取消注释
打开/etc/supervisord.conf,取消下面两行注释,并修改files内容.
[include]
files = /etc/supervisor/*.ini
  • 新建配置目录
新建supervisor目录及test.ini文件
➜  /etc  tree supervisor
supervisor
└── test.ini
  • 配置内容
test.init内容
[program:test]
command=python -m SimpleHTTPServer 8000
directory=/home/wyq/
  • 运行
运行后,在浏览器访问8000端口
supervisord 
 
调试运行,此时需要先将test.ini中directory注释掉.
supervisord -d
supervisor也可指定配置文件
 
supervisord -c xxxx
  • 查看日志
tail -f supervisord.conf
  • 查看运行状态
➜  ~  supervisorctl status
test                             RUNNING   pid 4922, uptime 0:00:07
  • 停止任务
启动与重启参数为start/restart
 
➜  ~  supervisorctl stop test
test: stopped
➜  ~  supervisorctl status   
test                             STOPPED   Jul 09 04:32 PM
  • 停止
supervisorctl shutdown
 

评论(0) 阅读(1245)

利用setuptools的entry_point参数实现模块动态导入

2015年7月06日 14:34

setuptools提供了entry_points参数,允许在安装时,动态导入模块. 下面是简单示例.
  • 目录结构  
建立如下文件
➜  book  tree
.
├── book
│   ├── add.py
│   ├── __init__.py
│   ├── remove.py
│   └── update.py
└── setup.py
  • add.py内容  
remove.py、update.py与add.py相同
def make():
    print "add"
  • setup.py内容
from setuptools import setup, find_packages

setup(
    name = "book",
    version = "0.1",
    packages = find_packages(),
    entry_points={
        "book":[
            "add=book.add:make",  #add=模块:函数/类
            "update=book.update:make",
            "remove=book.remove:make",
        ]
    }
)
  • 编译成egg包
python setup.py bdist_egg
  • 安装到系统路径  
上面编译命令可以不用,直接用install安装
python setup.py install
  • 用法
from pkg_resources import iter_entry_points

for r in iter_entry_points("book"):
    m = r.load()
    m()
 

Tags: 模块化
评论(0) 阅读(1085)

apscheduler如何传递参数给job

2015年7月03日 10:17

import tornado
from apscheduler.schedulers.tornado import TornadoScheduler
sched = TornadoScheduler()


def job1(a, b, c):
    print "job1:", a,b,c


def job2(a, b, c):
    print "job2:", a,b,c

sched.add_job(job1, 'interval', seconds=1, args=["a", "b", "c"])
sched.add_job(job2, 'interval', seconds=1, kwargs={"a": "a", "b": "b", "c": "c"})
sched.start()

tornado.ioloop.IOLoop.instance().start()

Tags: apscheduler
评论(0) 阅读(2559)

apscheduler定时任务

2015年6月30日 16:50

使用apscheduler定时任务,可以使用interval任务+cron任务,interval定时更新cron配置信息,cron则实现作业计划。

通常用法

from apscheduler.schedulers.blocking import BlockingScheduler
sched = BlockingScheduler()

def my_job():
    print 'hello world'

# 使用修饰器
@sched.scheduled_job('cron', id='my_job_id', second=10)
def hello():
    print "hello decorate"

# 轮循
sched.add_job(my_job, 'interval', seconds=5)
# 定时计划
sched.add_job(my_job, 'cron', second=5, minute=1, hour=12, day_of_week=2)
sched.start()

在tarnado中用法

import tornado
from apscheduler.schedulers.tornado import TornadoScheduler
sched = TornadoScheduler()

def my_job():
    print sched.get_jobs()

sched.add_job(my_job, 'interval', seconds=5, id="1")
sched.start()

tornado.ioloop.IOLoop.instance().start()

任务触发器比较

很多情况下,任务是根据数据库调整触发时间,时间改变了,如何判断触发器是否变化?
生成新trigger然后,专程字符串比较比较
# 触发器比较
str(job.trigger) != str(trigger)
# 修改触发器
sched.reschedule_job(job.id, trigger=trigger)
 

Tags: apscheduler
评论(1) 阅读(4774)

什么是经验

2015年6月29日 11:14

    经是准则,道之常者;验是验证。通过亲身验证而掌握的准则,称为经验。工作经验、人生经验中如果不包含准则,只能称为心得体会。

    程序员这个行业最多五十年,真有准则吗? 假如一条规则寿命是五十年,可用一生,对我而言它可以称为准则。五十多年、无数科学研究,成果在哪里,有这样成果吗?当然有!

评论(0) 阅读(939)