diff --git a/.travis.yml b/.travis.yml index fd0f42a..2881fe1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,12 +8,9 @@ before_install: - '[ "$TEST_PEP8" == "1" ] || sudo ./tests/test_env/deploy.sh' -python: - - "2.7" - install: - pip install -e . - - "if [[ $TEST_PEP8 == '1' ]]; then pip install pep8; fi" + - "if [[ $TEST_PEP8 == '1' ]]; then pip install pycodestyle; fi" - pip install passlib - pip install coveralls @@ -21,11 +18,23 @@ # #script: # - coverage run --source=ldapcherry setup.py test -script: "if [[ $TEST_PEP8 == '1' ]]; then pep8 --repeat --show-source --exclude=.venv,.tox,dist,docs,build,*.egg,tests,misc,setup.py . scripts/ldapcherryd; else coverage run --source=ldapcherry setup.py test; fi" +script: "if [[ $TEST_PEP8 == '1' ]]; then pycodestyle --repeat --show-source --exclude=.venv,.tox,dist,docs,build,*.egg,tests,misc,setup.py . scripts/ldapcherryd; else coverage run --source=ldapcherry setup.py test; fi" matrix: include: - python: "2.7" env: TEST_PEP8=1 + - python: "2.7" + env: TEST_PEP8=0 + - python: "3.5" + env: TEST_PEP8=0 + - python: "3.6" + env: TEST_PEP8=0 + - python: "3.4" + env: TEST_PEP8=0 + - python: "3.7" + env: TEST_PEP8=0 + + after_success: - coveralls after_failure: diff --git a/ldapcherry/cli.py b/ldapcherry/cli.py new file mode 100755 index 0000000..0b11a05 --- /dev/null +++ b/ldapcherry/cli.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# vim:set expandtab tabstop=4 shiftwidth=4: +# The MIT License (MIT) +# LdapCherry +# Copyright (c) 2014 Carpentier Pierre-Francois + +"""The CherryPy daemon.""" + +import sys +import os.path + +import cherrypy +from cherrypy.process import plugins, servers +from cherrypy import Application +from ldapcherry import LdapCherry + + +def start(configfile=None, daemonize=False, environment=None, + fastcgi=False, scgi=False, pidfile=None, + cgi=False, debug=False): + """Subscribe all engine plugins and start the engine.""" + sys.path = [''] + sys.path + + # monkey patching cherrypy to disable config interpolation + def new_as_dict(self, raw=True, vars=None): + """Convert an INI file to a dictionary""" + # Load INI file into a dict + result = {} + for section in self.sections(): + if section not in result: + result[section] = {} + for option in self.options(section): + value = self.get(section, option, raw=raw, vars=vars) + try: + value = cherrypy.lib.reprconf.unrepr(value) + except Exception: + x = sys.exc_info()[1] + msg = ("Config error in section: %r, option: %r, " + "value: %r. Config values must be valid Python." % + (section, option, value)) + raise ValueError(msg, x.__class__.__name__, x.args) + result[section][option] = value + return result + cherrypy.lib.reprconf.Parser.as_dict = new_as_dict + + instance = LdapCherry() + app = cherrypy.tree.mount(instance, '/', configfile) + cherrypy.config.update(configfile) + instance.reload(app.config, debug) + + engine = cherrypy.engine + + # Turn off autoreload + cherrypy.config.update({'engine.autoreload.on': False}) + + if environment is not None: + cherrypy.config.update({'environment': environment}) + + # Only daemonize if asked to. + if daemonize: + # Don't print anything to stdout/sterr. + cherrypy.config.update({'log.screen': False}) + plugins.Daemonizer(engine).subscribe() + + if pidfile: + plugins.PIDFile(engine, pidfile).subscribe() + + if hasattr(engine, "signal_handler"): + engine.signal_handler.subscribe() + if hasattr(engine, "console_control_handler"): + engine.console_control_handler.subscribe() + + if (fastcgi and (scgi or cgi)) or (scgi and cgi): + cherrypy.log.error("You may only specify one of the cgi, fastcgi, and " + "scgi options.", 'ENGINE') + sys.exit(1) + elif fastcgi or scgi or cgi: + # Turn off the default HTTP server (which is subscribed by default). + cherrypy.server.unsubscribe() + + addr = cherrypy.server.bind_addr + if fastcgi: + f = servers.FlupFCGIServer(application=cherrypy.tree, + bindAddress=addr) + elif scgi: + f = servers.FlupSCGIServer(application=cherrypy.tree, + bindAddress=addr) + else: + f = servers.FlupCGIServer(application=cherrypy.tree, + bindAddress=addr) + s = servers.ServerAdapter(engine, httpserver=f, bind_addr=addr) + s.subscribe() + + # Always start the engine; this will start all other services + try: + engine.start() + except: + # Assume the error has been logged already via bus.log. + sys.exit(1) + else: + engine.block() + + +def main(): + from optparse import OptionParser + + p = OptionParser() + p.add_option('-c', '--config', dest='config', + help="specify config file") + p.add_option('-d', action="store_true", dest='daemonize', + help="run the server as a daemon") + p.add_option('-e', '--environment', dest='environment', default=None, + help="apply the given config environment") + p.add_option('-f', action="store_true", dest='fastcgi', + help="start a fastcgi server instead" + " of the default HTTP server") + p.add_option('-s', action="store_true", dest='scgi', + help="start a scgi server instead of the default HTTP server") + p.add_option('-x', action="store_true", dest='cgi', + help="start a cgi server instead of the default HTTP server") + p.add_option('-p', '--pidfile', dest='pidfile', default=None, + help="store the process id in the given file") + p.add_option('-P', '--Path', action="append", dest='Path', + help="add the given paths to sys.path") + p.add_option('-D', '--debug', action="store_true", dest='debug', + help="debug to stderr in foreground") + options, args = p.parse_args() + + if options.Path: + for p in options.Path: + sys.path.insert(0, p) + + if options.config is None: + print('-c|--config is mandatory') + exit(1) + + if not os.path.isfile(options.config): + print('configuration file "' + options.config + '" doesn\'t exist') + exit(1) + + start(options.config, options.daemonize, + options.environment, options.fastcgi, options.scgi, + options.pidfile, options.cgi, options.debug) + +if __name__ == '__main__': + main() diff --git a/scripts/ldapcherryd b/scripts/ldapcherryd deleted file mode 100755 index 1547caf..0000000 --- a/scripts/ldapcherryd +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# vim:set expandtab tabstop=4 shiftwidth=4: -# The MIT License (MIT) -# LdapCherry -# Copyright (c) 2014 Carpentier Pierre-Francois - -"""The CherryPy daemon.""" - -import sys -import os.path - -import cherrypy -from cherrypy.process import plugins, servers -from cherrypy import Application -from ldapcherry import LdapCherry - - -def start(configfile=None, daemonize=False, environment=None, - fastcgi=False, scgi=False, pidfile=None, - cgi=False, debug=False): - """Subscribe all engine plugins and start the engine.""" - sys.path = [''] + sys.path - - # monkey patching cherrypy to disable config interpolation - def new_as_dict(self, raw=True, vars=None): - """Convert an INI file to a dictionary""" - # Load INI file into a dict - result = {} - for section in self.sections(): - if section not in result: - result[section] = {} - for option in self.options(section): - value = self.get(section, option, raw=raw, vars=vars) - try: - value = cherrypy.lib.reprconf.unrepr(value) - except Exception: - x = sys.exc_info()[1] - msg = ("Config error in section: %r, option: %r, " - "value: %r. Config values must be valid Python." % - (section, option, value)) - raise ValueError(msg, x.__class__.__name__, x.args) - result[section][option] = value - return result - cherrypy.lib.reprconf.Parser.as_dict = new_as_dict - - instance = LdapCherry() - app = cherrypy.tree.mount(instance, '/', configfile) - cherrypy.config.update(configfile) - instance.reload(app.config, debug) - - engine = cherrypy.engine - - # Turn off autoreload - cherrypy.config.update({'engine.autoreload.on': False}) - - if environment is not None: - cherrypy.config.update({'environment': environment}) - - # Only daemonize if asked to. - if daemonize: - # Don't print anything to stdout/sterr. - cherrypy.config.update({'log.screen': False}) - plugins.Daemonizer(engine).subscribe() - - if pidfile: - plugins.PIDFile(engine, pidfile).subscribe() - - if hasattr(engine, "signal_handler"): - engine.signal_handler.subscribe() - if hasattr(engine, "console_control_handler"): - engine.console_control_handler.subscribe() - - if (fastcgi and (scgi or cgi)) or (scgi and cgi): - cherrypy.log.error("You may only specify one of the cgi, fastcgi, and " - "scgi options.", 'ENGINE') - sys.exit(1) - elif fastcgi or scgi or cgi: - # Turn off the default HTTP server (which is subscribed by default). - cherrypy.server.unsubscribe() - - addr = cherrypy.server.bind_addr - if fastcgi: - f = servers.FlupFCGIServer(application=cherrypy.tree, - bindAddress=addr) - elif scgi: - f = servers.FlupSCGIServer(application=cherrypy.tree, - bindAddress=addr) - else: - f = servers.FlupCGIServer(application=cherrypy.tree, - bindAddress=addr) - s = servers.ServerAdapter(engine, httpserver=f, bind_addr=addr) - s.subscribe() - - # Always start the engine; this will start all other services - try: - engine.start() - except: - # Assume the error has been logged already via bus.log. - sys.exit(1) - else: - engine.block() - - -if __name__ == '__main__': - from optparse import OptionParser - - p = OptionParser() - p.add_option('-c', '--config', dest='config', - help="specify config file") - p.add_option('-d', action="store_true", dest='daemonize', - help="run the server as a daemon") - p.add_option('-e', '--environment', dest='environment', default=None, - help="apply the given config environment") - p.add_option('-f', action="store_true", dest='fastcgi', - help="start a fastcgi server instead" - " of the default HTTP server") - p.add_option('-s', action="store_true", dest='scgi', - help="start a scgi server instead of the default HTTP server") - p.add_option('-x', action="store_true", dest='cgi', - help="start a cgi server instead of the default HTTP server") - p.add_option('-p', '--pidfile', dest='pidfile', default=None, - help="store the process id in the given file") - p.add_option('-P', '--Path', action="append", dest='Path', - help="add the given paths to sys.path") - p.add_option('-D', '--debug', action="store_true", dest='debug', - help="debug to stderr in foreground") - options, args = p.parse_args() - - if options.Path: - for p in options.Path: - sys.path.insert(0, p) - - if options.config is None: - print('-c|--config is mandatory') - exit(1) - - if not os.path.isfile(options.config): - print('configuration file "' + options.config + '" doesn\'t exist') - exit(1) - - start(options.config, options.daemonize, - options.environment, options.fastcgi, options.scgi, - options.pidfile, options.cgi, options.debug) diff --git a/setup.py b/setup.py index d47a27f..ace0cdc 100755 --- a/setup.py +++ b/setup.py @@ -29,8 +29,12 @@ 'Mako' ], elif sys.version_info[0] == 3: - print('unsupported version') - exit(1) + install_requires = [ + 'CherryPy >= 3.0.0', + 'python-ldap', + 'PyYAML', + 'Mako' + ], else: print('unsupported version') exit(1) @@ -120,7 +124,9 @@ 'ldapcherry.ppolicy' ], data_files=resources_files, - scripts=['scripts/ldapcherryd'], + entry_points = { + 'console_scripts': ['ldapcherryd = ldapcherry.cli:main'] + }, url='https://github.com/kakwa/ldapcherry', license=license, description=small_description,