cherrypy没有正确地进行守护

时间:2016-01-27 07:53:45

标签: python daemon cherrypy

我是cherrypy的新手,我尝试使用这个框架开发一个小应用程序。我的问题是,这个应用程序可以很好地服务,浏览器可以在umbemonizer模式下工作时访问。但是当我使用cherrypy.process.plugins.Daemonizer()编写代码时,cherrypy在后台启动,并且它在特定端口上侦听,但是浏览器将拒绝连接(iptables或ufw已经关闭但仍然无法访问)。令人难以置信的是,当我以守护进程模式启动它时,我仍然可以启动一个未经授权的进程,并且它们在同一个端口上进行侦听。我想知道为什么会这样,以及如何解决它?

简单地说:随着Daemonizer启动,cherrypy听了指定端口,但浏览器连接被拒绝;没有Daemonizer,cherrypy的效果非常好。

非常感谢

使用我的代码



from optparse import OptionParser
from cherrypy.process.plugins import Daemonizer
from cherrypy.process.plugins import PIDFile
import cherrypy
import json
import urllib
import datetime
try:
    import cPickle as pickle
except:
    import pickle
import time
import base64
import os
import sys

'''
cherrypy class
'''

class Index(object):
    @cherrypy.expose
    def index(self):
        return "Say hello to the yellow elephant"


class System(object):
    @cherrypy.expose
    def env(self, token):
        local_token = Token()
        if local_token.AuthToken(token) is True:
            env = get_env()
            return json.dumps(env)
        return '{"errcode", "Invalid token"}'


class Jmx(object):
    @cherrypy.expose
    def get(self, token, host, port, qry):
        local_token = Token()
        if local_token.AuthToken(token) is True:
            url = 'http://' + host + ':' + port + '/jmx?qry=' + qry
            jmx = urllib.urlopen(url)
            jmx_data = jmx.read().replace('\n', '')
            jmx.close()
            return jmx_data
        return '{"errcode", "Invalid token"}'


"""
command uses base64 encode by using http post method
"""

class Command(object):
    def __init__(self):
        self.fname = datetime.datetime.now().strftime('%Y-%m-%d_%M-%M-%S') + '.log'

    @cherrypy.expose
    def run(self, token, command):
        local_token = Token()
        command = base64.b64decode(command)
        if local_token.AuthToken(token) is True:
            os.popen(command + ' 2>&1 > /usr/lib/agent/output/' + self.fname)
        return '{"errcode", "Invalid token"}'

    @cherrypy.expose
    def readlog(self, token):
        local_token = Token()
        if local_token.AuthToken(token) is True:
            log = open('/usr/lib/agent/output/' + self.fname)
            lines = log.readlines()
            log.close()
            return json.dumps(lines, ensure_ascii=False)
        return '{"errcode", "Invalid token"}'

"""
First time access from central, it will create a new token on slave node, the token is pickle.dump(cacl_mysql_passwd(conf['agent']['secret']))
By token created , if central makes change to secret, the slave node will be inaccessible!!!
"""
class Token(object):
    def AuthToken(self, token):
        if(os.path.isfile('/usr/lib/agent/key/authenticate.key')) is False:
            return self.CreateToken(token)
        else:
            try:
                k = open('/usr/lib/agent/key/authenticate.key', 'rb')
                tokenizer = pickle.load(k)
                k.close()
                if token == tokenizer:
                    return True
                else:
                    return False
            except IOError, e:
                return '{"errcode":"' + str(e).replace('\n', '<br/>') + '"}'

    @cherrypy.expose
    def CreateToken(self, token):
        if(os.path.isfile('/usr/lib/agent/key/authenticate.key')) is False:
            try:
                k = open('/usr/lib/agent/key/authenticate.key', 'wb')
                pickle.dump(token, k)
                k.close()
                return True
            except IOError, e:
                return '{"Exception":"' + str(e).replace('\n', '<br/>') + '"}'
        else:
            return '{"errcode":"token exists"}'


class Controller:
    def __init__(self, pidfile='/var/run/agent/agent.pid', host='0.0.0.0', port=30050):
        self.port = port
        self.host = host
        self.pidfile = pidfile
        self.settings = {
            'global': {
                'server.socket_port': port,
                'server.socket_host': host,
                'server.socket_file': '',
                'server.socket_queue_size': 5,
                'server.protocol_version': 'HTTP/1.1',
                'server.log_to_screen': True,
                'server.log_file': '',
                'server.reverse_dns': False,
                'server.thread_pool': 10,
                'server.environment': 'production',
                'engine.timeout_monitor.on': False
            }
        }

    def start(self):
        if os.path.exists(self.pidfile):
            sys.stderr.write('PID file exists, server running?\n')
            sys.exit(1)
        else:
            Daemonizer(cherrypy.engine, stdin='/dev/stdin', stdout='/dev/stdout', stderr='/dev/stderr').subscribe()
            PIDFile(cherrypy.engine, self.pidfile).subscribe()
            cherrypy.tree.mount(Index(), '/')
            cherrypy.tree.mount(System(), '/system')
            cherrypy.tree.mount(Command(), '/command')
            cherrypy.tree.mount(Jmx(), '/jmx')
            cherrypy.config.update(self.settings)
            cherrypy.engine.start()
            cherrypy.engine.block()

    def stop(self):
        cherrypy.config.update(self.settings)
        if os.path.exists(self.pidfile):
            cherrypy.engine.stop()
            cherrypy.engine.exit()
            try:
                process = open(self.pidfile).read().strip()
                if process != 0:
                    os.popen('kill -9 %s' % process)
                    os.remove(self.pidfile)
            except IOError, e:
                sys.stderr.write(str(e))
        else:
            sys.stderr.write('PID file does not exist, server gone?\n')
            sys.exit(1)


if '__main__' == __name__:
    cherrypy.engine.autoreload.stop()
    cherrypy.engine.autoreload.unsubscribe()
    syntax = 'Syntax: %prog -b 192.168.1.1 -s start'
    parser = OptionParser(usage=syntax)
    ip = os.popen('hostname -i').read().strip()
    hostname = os.popen('hostname --fqdn').read().strip()
    parser.add_option('-b', '--bind', action='store', type='string', dest='bind', default=ip, help='Inner network IP address, default value is hostname -i')
    parser.add_option('-s', '--signal', action='store', type='string', dest='signal', help='Valid signal is {start|stop|restart}')
    options, args = parser.parse_args()

    if len(sys.argv) == 1:
        print 'Use %s -h or --help for help.' % sys.argv[0]
    else:
        if options.signal == '':
            print 'Must give -s option\'s value'
        else:
            daemon = Controller(pidfile='/var/run/agent/agent.pid', host=options.bind)
            if 'start' == options.signal:
                daemon.start()
            elif 'stop' == options.signal:
                daemon.stop()
            else:
                print 'Invalid signal'
                sys.exit(1)
&#13;
&#13;
&#13;

0 个答案:

没有答案