Преглед на файлове

celery.bin.celeryd_detach: Experimental built-in support for daemonizing celeryd

Ask Solem преди 14 години
родител
ревизия
51c65cc414
променени са 1 файла, в които са добавени 161 реда и са изтрити 0 реда
  1. 161 0
      celery/bin/celeryd_detach.py

+ 161 - 0
celery/bin/celeryd_detach.py

@@ -0,0 +1,161 @@
+import os
+import sys
+
+from optparse import OptionParser, BadOptionError, make_option as Option
+
+from celery import __version__
+from celery.platforms import create_daemon_context
+
+OPTION_LIST = (
+        Option('-f', '--logfile', default=None,
+               action="store", dest="logfile",
+               help="Path to the logfile"),
+        Option('--pidfile', default="celeryd.pid",
+               action="store", dest="pidfile",
+               help="Path to the pidfile."),
+        Option('--uid', default=None,
+               action="store", dest="uid",
+               help="Effective user id to run as when detached."),
+        Option('--gid', default=None,
+               action="store", dest="gid",
+               help="Effective group id to run as when detached."),
+        Option('--umask', default=0,
+               action="store", type="int", dest="umask",
+               help="Umask of the process when detached."),
+        Option('--workdir', default=None,
+               action="store", dest="working_directory",
+               help="Directory to change to when detached."),
+        Option('--chroot', default=None,
+               action="store", dest="chroot_directory",
+               help="Change root directory to this path when detached."),
+)
+
+
+class detached(object):
+
+    def __init__(self, path, argv, logfile=None, pidfile=None, uid=None,
+            gid=None, umask=0, working_directory=None, chroot_directory=None):
+        self.path = path
+        self.argv = argv
+        self.logfile = logfile
+        self.pidfile = pidfile
+        self.uid = uid
+        self.gid = gid
+        self.umask = umask
+        self.working_directory = working_directory
+        self.chroot_directory = chroot_directory
+
+    def start(self):
+        context, on_stop = create_daemon_context(
+                                logfile=self.logfile,
+                                pidfile=self.pidfile,
+                                uid=self.uid,
+                                gid=self.gid,
+                                umask=self.umask,
+                                working_directory=self.working_directory,
+                                chroot_directory=self.chroot_directory)
+        context.open()
+        try:
+            os.execv(self.path, [self.path] + self.argv)
+        finally:
+            on_stop()
+
+
+class PartialOptionParser(OptionParser):
+
+    def __init__(self, *args, **kwargs):
+        self.leftovers = []
+        OptionParser.__init__(self, *args, **kwargs)
+
+    def _process_long_opt(self, rargs, values):
+        arg = rargs.pop(0)
+
+        if "=" in arg:
+            opt, next_arg = arg.split("=", 1)
+            rargs.insert(0, next_arg)
+            had_explicit_value = True
+        else:
+            opt = arg
+            had_explicit_value = False
+
+        try:
+            opt = self._match_long_opt(opt)
+            option = self._long_opt.get(opt)
+        except BadOptionError:
+            option = None
+
+        if option:
+            if option.takes_value():
+                nargs = option.nargs
+                if len(rargs) < nargs:
+                    if nargs == 1:
+                        self.error(_("%s option requires an argument") % opt)
+                    else:
+                        self.error(_("%s option requires %d arguments")
+                                % (opt, nargs))
+                elif nargs == 1:
+                    value = rargs.pop(0)
+                else:
+                    value = tuple(rargs[0:nargs])
+                    del rargs[0:nargs]
+
+            elif had_explicit_value:
+                self.error(_("%s option does not take a value") % opt)
+            else:
+                value = None
+            option.process(opt, value, values, self)
+        else:
+            self.leftovers.append(arg)
+
+    def _process_short_opts(self, rargs, values):
+        arg = rargs[0]
+        try:
+           OptionParser._process_short_opts(self, rargs, values)
+        except BadOptionError:
+            self.leftovers.append(arg)
+            if rargs and not rargs[0][0] == "-":
+                self.leftovers.append(rargs.pop(0))
+
+
+class detached_celeryd(object):
+    option_list = OPTION_LIST
+    usage = "%%prog [options] [celeryd options]"
+    version = __version__
+    description = ("Detaches Celery worker nodes.  See `celeryd --help` "
+                   "for the list of supported worker arguments.")
+    command = sys.executable
+    execv_path = sys.executable
+    execv_argv = ["-m", "celery.bin.celeryd"]
+
+    def Parser(self, prog_name):
+        return PartialOptionParser(prog=prog_name,
+                                   option_list=self.option_list,
+                                   usage=self.usage,
+                                   description=self.description,
+                                   version=self.version)
+
+    def parse_options(self, prog_name, argv):
+        parser = self.Parser(prog_name)
+        options, values = parser.parse_args(argv)
+        if options.logfile:
+            parser.leftovers.append("--logfile=%s" % (options.logfile, ))
+        if options.pidfile:
+            parser.leftovers.append("--pidfile=%s" % (options.pidfile, ))
+        print("LEFTOVERS: %r" % (parser.leftovers, ))
+        return options, values, parser.leftovers
+
+    def execute_from_commandline(self, argv=None):
+        if argv is None:
+            argv = sys.argv
+        prog_name = os.path.basename(argv[0])
+        options, values, leftovers = self.parse_options(prog_name, argv[1:])
+        detached(path=self.execv_path,
+                 argv=self.execv_argv + leftovers,
+                 **vars(options)).start()
+
+
+def main():
+    detached_celeryd().execute_from_commandline()
+
+if __name__ == "__main__":
+    main()