|
@@ -8,7 +8,7 @@ from textwrap import wrap
|
|
|
from anyjson import deserialize
|
|
|
|
|
|
from celery import __version__
|
|
|
-from celery.utils import term as t
|
|
|
+from celery.utils import term
|
|
|
|
|
|
|
|
|
commands = {}
|
|
@@ -26,17 +26,41 @@ def command(fun):
|
|
|
class Command(object):
|
|
|
help = ""
|
|
|
args = ""
|
|
|
+ version = __version__
|
|
|
+
|
|
|
option_list = (
|
|
|
+ Option("--quiet", "-q", action="store_true", dest="quiet",
|
|
|
+ default=False),
|
|
|
Option("--conf", dest="conf",
|
|
|
help="Celery config module name (default: celeryconfig)"),
|
|
|
Option("--loader", dest="loader",
|
|
|
help="Celery loaders module name (default: default)"),
|
|
|
+ Option("--no-color", "-C", dest="no_color", action="store_true",
|
|
|
+ help="Don't colorize output."),
|
|
|
)
|
|
|
|
|
|
+ def __init__(self, no_color=False):
|
|
|
+ self.colored = term.colored(enabled=not no_color)
|
|
|
+
|
|
|
+ def __call__(self, *args, **kwargs):
|
|
|
+ try:
|
|
|
+ self.run(*args, **kwargs)
|
|
|
+ except Error, exc:
|
|
|
+ self.error(self.colored.red("Error: %s" % exc))
|
|
|
+
|
|
|
+ def error(self, s):
|
|
|
+ return self.out(s, fh=sys.stderr)
|
|
|
+
|
|
|
+ def out(self, s, fh=sys.stdout):
|
|
|
+ s = str(s)
|
|
|
+ if not s.endswith("\n"):
|
|
|
+ s += "\n"
|
|
|
+ sys.stdout.write(s)
|
|
|
+
|
|
|
def create_parser(self, prog_name, command):
|
|
|
return OptionParser(prog=prog_name,
|
|
|
usage=self.usage(command),
|
|
|
- version=self.get_version(),
|
|
|
+ version=self.version,
|
|
|
option_list=self.option_list)
|
|
|
|
|
|
def run_from_argv(self, argv):
|
|
@@ -49,24 +73,43 @@ class Command(object):
|
|
|
os.environ["CELERY_LOADER"] = options.loader
|
|
|
if options.conf:
|
|
|
os.environ["CELERY_CONFIG_MODULE"] = options.conf
|
|
|
+ self.colored = term.colored(enabled=not options.no_color)
|
|
|
self(*args, **options.__dict__)
|
|
|
|
|
|
- def __call__(self, *args, **kwargs):
|
|
|
- try:
|
|
|
- self.run(*args, **kwargs)
|
|
|
- except Error, exc:
|
|
|
- sys.stderr.write(t.colored(t.red(
|
|
|
- t.bold("Error: %s\n" % (exc, )))))
|
|
|
-
|
|
|
def run(self, *args, **kwargs):
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
- def get_version(self):
|
|
|
- return __version__
|
|
|
-
|
|
|
def usage(self, command):
|
|
|
return "%%prog %s [options] %s" % (command, self.args)
|
|
|
|
|
|
+ def prettify_list(self, n):
|
|
|
+ c = self.colored
|
|
|
+ if not n:
|
|
|
+ return "- empty -"
|
|
|
+ return "\n".join(str(c.reset(c.white("*"), " %s" % (item, )))
|
|
|
+ for item in n)
|
|
|
+
|
|
|
+ def prettify_dict_ok_error(self, n):
|
|
|
+ c = self.colored
|
|
|
+ if "ok" in n:
|
|
|
+ return (c.green("OK"),
|
|
|
+ indent(self.prettify(n["ok"])[1]))
|
|
|
+ elif "error" in n:
|
|
|
+ return (c.red("ERROR"),
|
|
|
+ indent(self.prettify(n["error"])[1]))
|
|
|
+
|
|
|
+
|
|
|
+ def prettify(self, n):
|
|
|
+ OK = str(self.colored.green("OK"))
|
|
|
+ if isinstance(n, list):
|
|
|
+ return OK, self.prettify_list(n)
|
|
|
+ if isinstance(n, dict):
|
|
|
+ if "ok" in n or "error" in n:
|
|
|
+ return self.prettify_dict_ok_error(n)
|
|
|
+ if isinstance(n, basestring):
|
|
|
+ return OK, unicode(n)
|
|
|
+ return OK, pformat(n)
|
|
|
+
|
|
|
|
|
|
class apply(Command):
|
|
|
args = "<task_name>"
|
|
@@ -111,9 +154,28 @@ class apply(Command):
|
|
|
eta=kw.get("eta"),
|
|
|
expires=expires)
|
|
|
|
|
|
- print(res.task_id)
|
|
|
+ self.out(res.task_id)
|
|
|
apply = command(apply)
|
|
|
|
|
|
+
|
|
|
+class result(Command):
|
|
|
+ args = "<task_id>"
|
|
|
+ option_list = Command.option_list + (
|
|
|
+ Option("--task", "-t", dest="task"),
|
|
|
+ )
|
|
|
+
|
|
|
+ def run(self, task_id, *args, **kwargs):
|
|
|
+ from celery import registry
|
|
|
+ from celery.result import AsyncResult
|
|
|
+ result_cls = AsyncResult
|
|
|
+ task = kwargs.get("task")
|
|
|
+
|
|
|
+ if task:
|
|
|
+ result_cls = registry.tasks[task].AsyncResult
|
|
|
+ result = result_cls(task_id)
|
|
|
+ self.out(self.prettify(result.get())[1])
|
|
|
+result = command(result)
|
|
|
+
|
|
|
class inspect(Command):
|
|
|
choices = {"active": 10,
|
|
|
"scheduled": 1.0,
|
|
@@ -126,8 +188,6 @@ class inspect(Command):
|
|
|
"diagnose": 2.0,
|
|
|
"ping": 0.2}
|
|
|
option_list = Command.option_list + (
|
|
|
- Option("--quiet", "-q", action="store_true", dest="quiet",
|
|
|
- default=False),
|
|
|
Option("--timeout", "-t", type="float", dest="timeout",
|
|
|
default=None,
|
|
|
help="Timeout in seconds (float) waiting for reply"),
|
|
@@ -153,11 +213,11 @@ class inspect(Command):
|
|
|
destination = map(str.strip, destination.split(","))
|
|
|
|
|
|
def on_reply(message_data):
|
|
|
+ c = self.colored
|
|
|
node = message_data.keys()[0]
|
|
|
reply = message_data[node]
|
|
|
- status, preply = prettify(reply)
|
|
|
- self.say("->", t.cyan(node, ": ") + t.reset() + status,
|
|
|
- indent(preply))
|
|
|
+ status, preply = self.prettify(reply)
|
|
|
+ self.say("->", c.cyan(node, ": ") + status, indent(preply))
|
|
|
|
|
|
self.say("<-", command)
|
|
|
i = inspect(destination=destination,
|
|
@@ -169,40 +229,15 @@ class inspect(Command):
|
|
|
return replies
|
|
|
|
|
|
def say(self, direction, title, body=""):
|
|
|
+ c = self.colored
|
|
|
if direction == "<-" and self.quiet:
|
|
|
return
|
|
|
- dirstr = not self.quiet and t.bold(t.white(direction), " ") or ""
|
|
|
- print(t.colored(dirstr, title))
|
|
|
+ dirstr = not self.quiet and c.bold(c.white(direction), " ") or ""
|
|
|
+ self.out(c.reset(dirstr, title))
|
|
|
if body and not self.quiet:
|
|
|
- print(body)
|
|
|
+ self.out(body)
|
|
|
inspect = command(inspect)
|
|
|
|
|
|
-def prettify_list(n):
|
|
|
- if not n:
|
|
|
- return "- empty -"
|
|
|
- return "\n".join(t.colored(t.white("*"), t.reset(), " %s" % (item, ))
|
|
|
- for item in n)
|
|
|
-
|
|
|
-OK = t.colored(t.green("OK"))
|
|
|
-ERROR = t.colored(t.red("ERROR"))
|
|
|
-def prettify_dict_ok_error(n):
|
|
|
- if "ok" in n:
|
|
|
- return (OK,
|
|
|
- indent(prettify(n["ok"])[1]))
|
|
|
- elif "error" in n:
|
|
|
- return (ERROR,
|
|
|
- indent(prettify(n["error"])[1]))
|
|
|
-
|
|
|
-
|
|
|
-def prettify(n):
|
|
|
- if isinstance(n, list):
|
|
|
- return OK, prettify_list(n)
|
|
|
- if isinstance(n, dict):
|
|
|
- if "ok" in n or "error" in n:
|
|
|
- return prettify_dict_ok_error(n)
|
|
|
- if isinstance(n, basestring):
|
|
|
- return OK, unicode(n)
|
|
|
- return OK, pformat(n)
|
|
|
|
|
|
|
|
|
def indent(s, n=4):
|
|
@@ -211,19 +246,20 @@ def indent(s, n=4):
|
|
|
|
|
|
|
|
|
class status(Command):
|
|
|
+ option_list = inspect.option_list
|
|
|
|
|
|
def run(self, *args, **kwargs):
|
|
|
- replies = inspect().run("ping", quiet=True)
|
|
|
+ replies = inspect(no_color=kwargs.get("no_color", False)) \
|
|
|
+ .run("ping", **dict(kwargs, quiet=True))
|
|
|
if not replies:
|
|
|
raise Error("No nodes replied within time constraint")
|
|
|
nodecount = len(replies)
|
|
|
- print("\n%s %s online." % (nodecount,
|
|
|
- nodecount > 1 and "nodes" or "node"))
|
|
|
+ if not kwargs.get("quiet", False):
|
|
|
+ self.out("\n%s %s online." % (nodecount,
|
|
|
+ nodecount > 1 and "nodes" or "node"))
|
|
|
status = command(status)
|
|
|
|
|
|
|
|
|
-
|
|
|
-
|
|
|
class help(Command):
|
|
|
|
|
|
def usage(self, command):
|
|
@@ -238,7 +274,7 @@ class help(Command):
|
|
|
"Available commands:"]
|
|
|
for command in list(sorted(commands.keys())):
|
|
|
usage.append(" %s" % command)
|
|
|
- print("\n".join(usage))
|
|
|
+ self.out("\n".join(usage))
|
|
|
help = command(help)
|
|
|
|
|
|
|
|
@@ -255,7 +291,10 @@ class celeryctl(object):
|
|
|
cls = self.commands["help"]
|
|
|
argv.insert(1, "help")
|
|
|
cls = self.commands.get(command) or self.commands["help"]
|
|
|
- cls().run_from_argv(argv)
|
|
|
+ try:
|
|
|
+ cls().run_from_argv(argv)
|
|
|
+ except Error:
|
|
|
+ return self.execute("help", argv)
|
|
|
|
|
|
def execute_from_commandline(self, argv=None):
|
|
|
if argv is None:
|
|
@@ -264,11 +303,15 @@ class celeryctl(object):
|
|
|
command = argv[1]
|
|
|
except IndexError:
|
|
|
command = "help"
|
|
|
+ argv.insert(1, "help")
|
|
|
return self.execute(command, argv)
|
|
|
|
|
|
|
|
|
def main():
|
|
|
- celeryctl().execute_from_commandline()
|
|
|
+ try:
|
|
|
+ celeryctl().execute_from_commandline()
|
|
|
+ except KeyboardInterrupt:
|
|
|
+ pass
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
main()
|