root / kamaki / cli.py @ 2f749e6e
History | View | Annotate | Download (11.6 kB)
1 | 5d1d131b | Giorgos Verigakis | #!/usr/bin/env python
|
---|---|---|---|
2 | 5d1d131b | Giorgos Verigakis | |
3 | 43ca98ee | Giorgos Verigakis | # Copyright 2011-2012 GRNET S.A. All rights reserved.
|
4 | 5d1d131b | Giorgos Verigakis | #
|
5 | 5d1d131b | Giorgos Verigakis | # Redistribution and use in source and binary forms, with or
|
6 | 5d1d131b | Giorgos Verigakis | # without modification, are permitted provided that the following
|
7 | 5d1d131b | Giorgos Verigakis | # conditions are met:
|
8 | 5d1d131b | Giorgos Verigakis | #
|
9 | 5d1d131b | Giorgos Verigakis | # 1. Redistributions of source code must retain the above
|
10 | 5d1d131b | Giorgos Verigakis | # copyright notice, this list of conditions and the following
|
11 | 5d1d131b | Giorgos Verigakis | # disclaimer.
|
12 | 5d1d131b | Giorgos Verigakis | #
|
13 | 5d1d131b | Giorgos Verigakis | # 2. Redistributions in binary form must reproduce the above
|
14 | 5d1d131b | Giorgos Verigakis | # copyright notice, this list of conditions and the following
|
15 | 5d1d131b | Giorgos Verigakis | # disclaimer in the documentation and/or other materials
|
16 | 5d1d131b | Giorgos Verigakis | # provided with the distribution.
|
17 | 5d1d131b | Giorgos Verigakis | #
|
18 | 5d1d131b | Giorgos Verigakis | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
19 | 5d1d131b | Giorgos Verigakis | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
20 | 5d1d131b | Giorgos Verigakis | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
21 | 5d1d131b | Giorgos Verigakis | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
22 | 5d1d131b | Giorgos Verigakis | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
23 | 5d1d131b | Giorgos Verigakis | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
24 | 5d1d131b | Giorgos Verigakis | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
25 | 5d1d131b | Giorgos Verigakis | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
26 | 5d1d131b | Giorgos Verigakis | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
27 | 5d1d131b | Giorgos Verigakis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
28 | 5d1d131b | Giorgos Verigakis | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29 | 5d1d131b | Giorgos Verigakis | # POSSIBILITY OF SUCH DAMAGE.
|
30 | 5d1d131b | Giorgos Verigakis | #
|
31 | 5d1d131b | Giorgos Verigakis | # The views and conclusions contained in the software and
|
32 | 5d1d131b | Giorgos Verigakis | # documentation are those of the authors and should not be
|
33 | 5d1d131b | Giorgos Verigakis | # interpreted as representing official policies, either expressed
|
34 | 5d1d131b | Giorgos Verigakis | # or implied, of GRNET S.A.
|
35 | 5d1d131b | Giorgos Verigakis | |
36 | 098ca087 | Giorgos Verigakis | from __future__ import print_function |
37 | 098ca087 | Giorgos Verigakis | |
38 | 435008b6 | Stavros Sachtouris | import gevent.monkey |
39 | 435008b6 | Stavros Sachtouris | #Monkey-patch everything for gevent early on
|
40 | 435008b6 | Stavros Sachtouris | gevent.monkey.patch_all() |
41 | 435008b6 | Stavros Sachtouris | |
42 | 5d1d131b | Giorgos Verigakis | import inspect |
43 | 5d1d131b | Giorgos Verigakis | import logging |
44 | 8378faf2 | Giorgos Verigakis | import sys |
45 | 5d1d131b | Giorgos Verigakis | |
46 | 8378faf2 | Giorgos Verigakis | from argparse import ArgumentParser |
47 | 57b8dd5a | Giorgos Verigakis | from base64 import b64encode |
48 | d83a2834 | Giorgos Verigakis | from os.path import abspath, basename, exists |
49 | 8378faf2 | Giorgos Verigakis | from sys import exit, stdout, stderr |
50 | 5d1d131b | Giorgos Verigakis | |
51 | 5f47b77d | Giorgos Verigakis | try:
|
52 | 5f47b77d | Giorgos Verigakis | from collections import OrderedDict |
53 | 5f47b77d | Giorgos Verigakis | except ImportError: |
54 | 5f47b77d | Giorgos Verigakis | from ordereddict import OrderedDict |
55 | 5f47b77d | Giorgos Verigakis | |
56 | e92440bd | Stavros Sachtouris | from colors import magenta, red, yellow, bold |
57 | b974d110 | Stavros Sachtouris | #from progress.bar import IncrementalBar
|
58 | 1ff49234 | Stavros Sachtouris | #from requests.exceptions import ConnectionError
|
59 | 6a0b1658 | Giorgos Verigakis | |
60 | 71ff5136 | Stavros Sachtouris | from . import clients
|
61 | 5f47b77d | Giorgos Verigakis | from .config import Config |
62 | b974d110 | Stavros Sachtouris | #from .utils import print_list, print_dict, print_items, format_size
|
63 | 5d1d131b | Giorgos Verigakis | |
64 | eb3ca8ca | Giorgos Verigakis | _commands = OrderedDict() |
65 | eb3ca8ca | Giorgos Verigakis | |
66 | b974d110 | Stavros Sachtouris | GROUPS = {} |
67 | a2e8e549 | Stavros Sachtouris | CLI_LOCATIONS = ['', 'kamaki', 'kamaki.commands'] |
68 | 653b0597 | Giorgos Verigakis | |
69 | 71ff5136 | Stavros Sachtouris | class CLIError(Exception): |
70 | 71ff5136 | Stavros Sachtouris | def __init__(self, message, status=0, details='', importance=0): |
71 | 71ff5136 | Stavros Sachtouris | """importance is set by the raiser
|
72 | 71ff5136 | Stavros Sachtouris | 0 is the lowest possible importance
|
73 | 71ff5136 | Stavros Sachtouris | Suggested values: 0, 1, 2, 3
|
74 | 71ff5136 | Stavros Sachtouris | """
|
75 | 71ff5136 | Stavros Sachtouris | super(CLIError, self).__init__(message, status, details) |
76 | 71ff5136 | Stavros Sachtouris | self.message = message
|
77 | 71ff5136 | Stavros Sachtouris | self.status = status
|
78 | 71ff5136 | Stavros Sachtouris | self.details = details
|
79 | 71ff5136 | Stavros Sachtouris | self.importance = importance
|
80 | 71ff5136 | Stavros Sachtouris | |
81 | c3659429 | Stavros Sachtouris | def __unicode__(self): |
82 | c3659429 | Stavros Sachtouris | return unicode(self.message) |
83 | c3659429 | Stavros Sachtouris | |
84 | b974d110 | Stavros Sachtouris | def command(group=None, name=None, syntax=None): |
85 | eb3ca8ca | Giorgos Verigakis | """Class decorator that registers a class as a CLI command."""
|
86 | 44b8928d | Giorgos Verigakis | |
87 | eb3ca8ca | Giorgos Verigakis | def decorator(cls): |
88 | eb3ca8ca | Giorgos Verigakis | grp, sep, cmd = cls.__name__.partition('_')
|
89 | eb3ca8ca | Giorgos Verigakis | if not sep: |
90 | eb3ca8ca | Giorgos Verigakis | grp, cmd = None, cls.__name__
|
91 | 44b8928d | Giorgos Verigakis | |
92 | b974d110 | Stavros Sachtouris | #cls.api = api
|
93 | eb3ca8ca | Giorgos Verigakis | cls.group = group or grp
|
94 | eb3ca8ca | Giorgos Verigakis | cls.name = name or cmd
|
95 | 44b8928d | Giorgos Verigakis | |
96 | f3ddb705 | Giorgos Verigakis | short_description, sep, long_description = cls.__doc__.partition('\n')
|
97 | f3ddb705 | Giorgos Verigakis | cls.description = short_description |
98 | f3ddb705 | Giorgos Verigakis | cls.long_description = long_description or short_description
|
99 | 44b8928d | Giorgos Verigakis | |
100 | f3ddb705 | Giorgos Verigakis | cls.syntax = syntax |
101 | eb3ca8ca | Giorgos Verigakis | if cls.syntax is None: |
102 | eb3ca8ca | Giorgos Verigakis | # Generate a syntax string based on main's arguments
|
103 | eb3ca8ca | Giorgos Verigakis | spec = inspect.getargspec(cls.main.im_func) |
104 | eb3ca8ca | Giorgos Verigakis | args = spec.args[1:]
|
105 | eb3ca8ca | Giorgos Verigakis | n = len(args) - len(spec.defaults or ()) |
106 | 9aece4ba | Stavros Sachtouris | required = ' '.join('<%s>' % x.replace('____', '[:').replace('___', ':').replace('__',']').replace('_', ' ') for x in args[:n]) |
107 | 9aece4ba | Stavros Sachtouris | optional = ' '.join('[%s]' % x.replace('____', '[:').replace('___', ':').replace('__', ']').replace('_', ' ') for x in args[n:]) |
108 | eb3ca8ca | Giorgos Verigakis | cls.syntax = ' '.join(x for x in [required, optional] if x) |
109 | 8ab2c986 | Giorgos Verigakis | if spec.varargs:
|
110 | 8ab2c986 | Giorgos Verigakis | cls.syntax += ' <%s ...>' % spec.varargs
|
111 | 44b8928d | Giorgos Verigakis | |
112 | eb3ca8ca | Giorgos Verigakis | if cls.group not in _commands: |
113 | eb3ca8ca | Giorgos Verigakis | _commands[cls.group] = OrderedDict() |
114 | eb3ca8ca | Giorgos Verigakis | _commands[cls.group][cls.name] = cls |
115 | eb3ca8ca | Giorgos Verigakis | return cls
|
116 | eb3ca8ca | Giorgos Verigakis | return decorator
|
117 | 5d1d131b | Giorgos Verigakis | |
118 | b974d110 | Stavros Sachtouris | def set_api_description(api, description): |
119 | b974d110 | Stavros Sachtouris | """Method to be called by api CLIs
|
120 | b974d110 | Stavros Sachtouris | Each CLI can set more than one api descriptions"""
|
121 | b974d110 | Stavros Sachtouris | GROUPS[api] = description |
122 | 8ab2c986 | Giorgos Verigakis | |
123 | b974d110 | Stavros Sachtouris | def main(): |
124 | 44b8928d | Giorgos Verigakis | |
125 | b974d110 | Stavros Sachtouris | def print_groups(): |
126 | b974d110 | Stavros Sachtouris | print('\nGroups:')
|
127 | b974d110 | Stavros Sachtouris | for group in _commands: |
128 | b974d110 | Stavros Sachtouris | description = GROUPS.get(group, '')
|
129 | b974d110 | Stavros Sachtouris | print(' ', group.ljust(12), description) |
130 | 43ca98ee | Giorgos Verigakis | |
131 | b974d110 | Stavros Sachtouris | def print_commands(group): |
132 | 098ca087 | Giorgos Verigakis | description = GROUPS.get(group, '')
|
133 | b974d110 | Stavros Sachtouris | if description:
|
134 | b974d110 | Stavros Sachtouris | print('\n' + description)
|
135 | b974d110 | Stavros Sachtouris | |
136 | b974d110 | Stavros Sachtouris | print('\nCommands:')
|
137 | b974d110 | Stavros Sachtouris | for name, cls in _commands[group].items(): |
138 | b974d110 | Stavros Sachtouris | print(' ', name.ljust(14), cls.description) |
139 | b974d110 | Stavros Sachtouris | |
140 | b974d110 | Stavros Sachtouris | def manage_logging_handlers(args): |
141 | b974d110 | Stavros Sachtouris | """This is mostly to handle logging for clients package"""
|
142 | b974d110 | Stavros Sachtouris | |
143 | b974d110 | Stavros Sachtouris | def add_handler(name, level, prefix=''): |
144 | b974d110 | Stavros Sachtouris | h = logging.StreamHandler() |
145 | b974d110 | Stavros Sachtouris | fmt = logging.Formatter(prefix + '%(message)s')
|
146 | b974d110 | Stavros Sachtouris | h.setFormatter(fmt) |
147 | b974d110 | Stavros Sachtouris | logger = logging.getLogger(name) |
148 | b974d110 | Stavros Sachtouris | logger.addHandler(h) |
149 | b974d110 | Stavros Sachtouris | logger.setLevel(level) |
150 | b974d110 | Stavros Sachtouris | |
151 | b974d110 | Stavros Sachtouris | if args.silent:
|
152 | b974d110 | Stavros Sachtouris | add_handler('', logging.CRITICAL)
|
153 | b974d110 | Stavros Sachtouris | elif args.debug:
|
154 | b974d110 | Stavros Sachtouris | add_handler('requests', logging.INFO, prefix='* ') |
155 | b974d110 | Stavros Sachtouris | add_handler('clients.send', logging.DEBUG, prefix='> ') |
156 | b974d110 | Stavros Sachtouris | add_handler('clients.recv', logging.DEBUG, prefix='< ') |
157 | b974d110 | Stavros Sachtouris | elif args.verbose:
|
158 | b974d110 | Stavros Sachtouris | add_handler('requests', logging.INFO, prefix='* ') |
159 | b974d110 | Stavros Sachtouris | add_handler('clients.send', logging.INFO, prefix='> ') |
160 | b974d110 | Stavros Sachtouris | add_handler('clients.recv', logging.INFO, prefix='< ') |
161 | b974d110 | Stavros Sachtouris | elif args.include:
|
162 | b974d110 | Stavros Sachtouris | add_handler('clients.recv', logging.INFO)
|
163 | b974d110 | Stavros Sachtouris | else:
|
164 | b974d110 | Stavros Sachtouris | add_handler('', logging.WARNING)
|
165 | b974d110 | Stavros Sachtouris | |
166 | b974d110 | Stavros Sachtouris | def load_groups(config): |
167 | b974d110 | Stavros Sachtouris | """load groups and import CLIs and Modules"""
|
168 | b974d110 | Stavros Sachtouris | loaded_modules = {} |
169 | b974d110 | Stavros Sachtouris | for api in config.apis(): |
170 | b974d110 | Stavros Sachtouris | api_cli = config.get(api, 'cli')
|
171 | b974d110 | Stavros Sachtouris | if None == api_cli or len(api_cli)==0: |
172 | 1ff49234 | Stavros Sachtouris | print('Warnig: No Command Line Interface "%s" given for API "%s"'%(api_cli, api))
|
173 | 1ff49234 | Stavros Sachtouris | print('\t(cli option in config file)')
|
174 | b974d110 | Stavros Sachtouris | continue
|
175 | b974d110 | Stavros Sachtouris | if not loaded_modules.has_key(api_cli): |
176 | 1ff49234 | Stavros Sachtouris | loaded_modules[api_cli] = False
|
177 | 1ff49234 | Stavros Sachtouris | for location in CLI_LOCATIONS: |
178 | 1ff49234 | Stavros Sachtouris | location += api_cli if location == '' else '.%s'%api_cli |
179 | b974d110 | Stavros Sachtouris | try:
|
180 | 1ff49234 | Stavros Sachtouris | __import__(location)
|
181 | 1ff49234 | Stavros Sachtouris | loaded_modules[api_cli] = True
|
182 | 1ff49234 | Stavros Sachtouris | break
|
183 | b974d110 | Stavros Sachtouris | except ImportError: |
184 | 1ff49234 | Stavros Sachtouris | pass
|
185 | 1ff49234 | Stavros Sachtouris | if not loaded_modules[api_cli]: |
186 | 1ff49234 | Stavros Sachtouris | print('Warning: failed to load Command Line Interface "%s" for API "%s"'%(api_cli, api))
|
187 | 1ff49234 | Stavros Sachtouris | print('\t(No suitable cli in known paths)')
|
188 | 1ff49234 | Stavros Sachtouris | continue
|
189 | b974d110 | Stavros Sachtouris | if not GROUPS.has_key(api): |
190 | b974d110 | Stavros Sachtouris | GROUPS[api] = 'No description (interface: %s)'%api_cli
|
191 | b974d110 | Stavros Sachtouris | |
192 | b974d110 | Stavros Sachtouris | def init_parser(exe): |
193 | b974d110 | Stavros Sachtouris | parser = ArgumentParser(add_help=False)
|
194 | b974d110 | Stavros Sachtouris | parser.prog = '%s <group> <command>' % exe
|
195 | b974d110 | Stavros Sachtouris | parser.add_argument('-h', '--help', dest='help', action='store_true', |
196 | b974d110 | Stavros Sachtouris | default=False,
|
197 | b974d110 | Stavros Sachtouris | help="Show this help message and exit")
|
198 | b974d110 | Stavros Sachtouris | parser.add_argument('--config', dest='config', metavar='PATH', |
199 | b974d110 | Stavros Sachtouris | help="Specify the path to the configuration file")
|
200 | b974d110 | Stavros Sachtouris | parser.add_argument('-d', '--debug', dest='debug', action='store_true', |
201 | b974d110 | Stavros Sachtouris | default=False,
|
202 | b974d110 | Stavros Sachtouris | help="Include debug output")
|
203 | b974d110 | Stavros Sachtouris | parser.add_argument('-i', '--include', dest='include', action='store_true', |
204 | b974d110 | Stavros Sachtouris | default=False,
|
205 | b974d110 | Stavros Sachtouris | help="Include protocol headers in the output")
|
206 | b974d110 | Stavros Sachtouris | parser.add_argument('-s', '--silent', dest='silent', action='store_true', |
207 | b974d110 | Stavros Sachtouris | default=False,
|
208 | b974d110 | Stavros Sachtouris | help="Silent mode, don't output anything")
|
209 | b974d110 | Stavros Sachtouris | parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', |
210 | b974d110 | Stavros Sachtouris | default=False,
|
211 | b974d110 | Stavros Sachtouris | help="Make the operation more talkative")
|
212 | b974d110 | Stavros Sachtouris | parser.add_argument('-V', '--version', dest='version', action='store_true', |
213 | b974d110 | Stavros Sachtouris | default=False,
|
214 | b974d110 | Stavros Sachtouris | help="Show version number and quit")
|
215 | b974d110 | Stavros Sachtouris | parser.add_argument('-o', dest='options', action='append', |
216 | b974d110 | Stavros Sachtouris | default=[], metavar="KEY=VAL",
|
217 | b974d110 | Stavros Sachtouris | help="Override a config value")
|
218 | b974d110 | Stavros Sachtouris | return parser
|
219 | b974d110 | Stavros Sachtouris | |
220 | 25062837 | Stavros Sachtouris | def find_term_in_args(arg_list, term_list): |
221 | 8e8af8ce | Stavros Sachtouris | """find an arg_list term in term_list. All other terms up to found
|
222 | 8e8af8ce | Stavros Sachtouris | term are rearanged at the end of arg_list, preserving relative order
|
223 | 8e8af8ce | Stavros Sachtouris | """
|
224 | 25062837 | Stavros Sachtouris | arg_tail = [] |
225 | 25062837 | Stavros Sachtouris | while len(arg_list) > 0: |
226 | 25062837 | Stavros Sachtouris | group = arg_list.pop(0)
|
227 | 8e8af8ce | Stavros Sachtouris | if group not in term_list: |
228 | 25062837 | Stavros Sachtouris | arg_tail.append(group) |
229 | 25062837 | Stavros Sachtouris | else:
|
230 | 25062837 | Stavros Sachtouris | arg_list += arg_tail |
231 | 25062837 | Stavros Sachtouris | return group
|
232 | 25062837 | Stavros Sachtouris | return None |
233 | 25062837 | Stavros Sachtouris | |
234 | b974d110 | Stavros Sachtouris | """Main Code"""
|
235 | 8378faf2 | Giorgos Verigakis | exe = basename(sys.argv[0])
|
236 | b974d110 | Stavros Sachtouris | parser = init_parser(exe) |
237 | 8378faf2 | Giorgos Verigakis | args, argv = parser.parse_known_args() |
238 | 8378faf2 | Giorgos Verigakis | |
239 | b974d110 | Stavros Sachtouris | #print version
|
240 | 8378faf2 | Giorgos Verigakis | if args.version:
|
241 | f3ddb705 | Giorgos Verigakis | import kamaki |
242 | 098ca087 | Giorgos Verigakis | print("kamaki %s" % kamaki.__version__)
|
243 | f3ddb705 | Giorgos Verigakis | exit(0) |
244 | d83a2834 | Giorgos Verigakis | |
245 | 8378faf2 | Giorgos Verigakis | config = Config(args.config) if args.config else Config() |
246 | 8378faf2 | Giorgos Verigakis | |
247 | b974d110 | Stavros Sachtouris | #load config options from command line
|
248 | 8378faf2 | Giorgos Verigakis | for option in args.options: |
249 | f3ddb705 | Giorgos Verigakis | keypath, sep, val = option.partition('=')
|
250 | f3ddb705 | Giorgos Verigakis | if not sep: |
251 | 098ca087 | Giorgos Verigakis | print("Invalid option '%s'" % option)
|
252 | f3ddb705 | Giorgos Verigakis | exit(1) |
253 | f3ddb705 | Giorgos Verigakis | section, sep, key = keypath.partition('.')
|
254 | f3ddb705 | Giorgos Verigakis | if not sep: |
255 | 098ca087 | Giorgos Verigakis | print("Invalid option '%s'" % option)
|
256 | f3ddb705 | Giorgos Verigakis | exit(1) |
257 | f3ddb705 | Giorgos Verigakis | config.override(section.strip(), key.strip(), val.strip()) |
258 | 44b8928d | Giorgos Verigakis | |
259 | b974d110 | Stavros Sachtouris | load_groups(config) |
260 | 25062837 | Stavros Sachtouris | group = find_term_in_args(argv, _commands) |
261 | 8378faf2 | Giorgos Verigakis | if not group: |
262 | eb3ca8ca | Giorgos Verigakis | parser.print_help() |
263 | f3ddb705 | Giorgos Verigakis | print_groups() |
264 | 8e8af8ce | Stavros Sachtouris | exit(0) |
265 | 8378faf2 | Giorgos Verigakis | |
266 | 8378faf2 | Giorgos Verigakis | parser.prog = '%s %s <command>' % (exe, group)
|
267 | 25062837 | Stavros Sachtouris | command = find_term_in_args(argv, _commands[group]) |
268 | 8378faf2 | Giorgos Verigakis | |
269 | 8378faf2 | Giorgos Verigakis | if not command: |
270 | eb3ca8ca | Giorgos Verigakis | parser.print_help() |
271 | f3ddb705 | Giorgos Verigakis | print_commands(group) |
272 | a1c50326 | Giorgos Verigakis | exit(0) |
273 | 8378faf2 | Giorgos Verigakis | |
274 | 8378faf2 | Giorgos Verigakis | cmd = _commands[group][command]() |
275 | 8378faf2 | Giorgos Verigakis | |
276 | 8378faf2 | Giorgos Verigakis | parser.prog = '%s %s %s' % (exe, group, command)
|
277 | 8378faf2 | Giorgos Verigakis | if cmd.syntax:
|
278 | 8378faf2 | Giorgos Verigakis | parser.prog += ' %s' % cmd.syntax
|
279 | f3ddb705 | Giorgos Verigakis | parser.description = cmd.description |
280 | eb3ca8ca | Giorgos Verigakis | parser.epilog = ''
|
281 | f3ddb705 | Giorgos Verigakis | if hasattr(cmd, 'update_parser'): |
282 | f3ddb705 | Giorgos Verigakis | cmd.update_parser(parser) |
283 | 44b8928d | Giorgos Verigakis | |
284 | b974d110 | Stavros Sachtouris | #check other args
|
285 | 8378faf2 | Giorgos Verigakis | args, argv = parser.parse_known_args() |
286 | e92440bd | Stavros Sachtouris | if group != argv[0]: |
287 | e92440bd | Stavros Sachtouris | errmsg = red('Invalid command group '+argv[0]) |
288 | e92440bd | Stavros Sachtouris | print(errmsg, file=stderr) |
289 | e92440bd | Stavros Sachtouris | exit(1) |
290 | e92440bd | Stavros Sachtouris | if command != argv[1]: |
291 | e92440bd | Stavros Sachtouris | errmsg = red('Invalid command "%s" in group "%s"'%(argv[1], argv[0])) |
292 | e92440bd | Stavros Sachtouris | print(errmsg, file=stderr) |
293 | e92440bd | Stavros Sachtouris | exit(1) |
294 | 44b8928d | Giorgos Verigakis | |
295 | 8378faf2 | Giorgos Verigakis | if args.help:
|
296 | eb3ca8ca | Giorgos Verigakis | parser.print_help() |
297 | a1c50326 | Giorgos Verigakis | exit(0) |
298 | 44b8928d | Giorgos Verigakis | |
299 | b974d110 | Stavros Sachtouris | manage_logging_handlers(args) |
300 | 8378faf2 | Giorgos Verigakis | cmd.args = args |
301 | 6a0b1658 | Giorgos Verigakis | cmd.config = config |
302 | 5d1d131b | Giorgos Verigakis | try:
|
303 | 8378faf2 | Giorgos Verigakis | ret = cmd.main(*argv[2:])
|
304 | a1c50326 | Giorgos Verigakis | exit(ret)
|
305 | a6757cbc | Giorgos Verigakis | except TypeError as e: |
306 | a6757cbc | Giorgos Verigakis | if e.args and e.args[0].startswith('main()'): |
307 | a6757cbc | Giorgos Verigakis | parser.print_help() |
308 | a1c50326 | Giorgos Verigakis | exit(1) |
309 | a6757cbc | Giorgos Verigakis | else:
|
310 | a6757cbc | Giorgos Verigakis | raise
|
311 | 71ff5136 | Stavros Sachtouris | except CLIError as err: |
312 | 71ff5136 | Stavros Sachtouris | errmsg = 'CLI Error '
|
313 | 71ff5136 | Stavros Sachtouris | errmsg += '(%s): '%err.status if err.status else ': ' |
314 | 71ff5136 | Stavros Sachtouris | errmsg += err.message if err.message else '' |
315 | 71ff5136 | Stavros Sachtouris | if err.importance == 1: |
316 | 71ff5136 | Stavros Sachtouris | errmsg = yellow(errmsg) |
317 | 71ff5136 | Stavros Sachtouris | elif err.importance == 2: |
318 | 71ff5136 | Stavros Sachtouris | errmsg = magenta(errmsg) |
319 | 71ff5136 | Stavros Sachtouris | elif err.importance > 2: |
320 | 71ff5136 | Stavros Sachtouris | errmsg = red(errmsg) |
321 | 71ff5136 | Stavros Sachtouris | print(errmsg, file=stderr) |
322 | b974d110 | Stavros Sachtouris | exit(1) |
323 | 5d1d131b | Giorgos Verigakis | |
324 | 5d1d131b | Giorgos Verigakis | if __name__ == '__main__': |
325 | a1c50326 | Giorgos Verigakis | main() |