1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import sys
23 import re
24
25 from twisted.internet import reactor
26
27 from flumotion.admin.admin import AdminModel
28 from flumotion.admin import connections
29 from flumotion.common import log, errors
30
31 from flumotion.common import messages
32 from flumotion.configure import configure
33 from flumotion.twisted import pb as fpb
34
35 from flumotion.admin.command.commands import commands
36 from flumotion.common.options import OptionParser
37
39 sys.stderr.write('Error: ' + string + '\n')
40 sys.exit(1)
41
43 sys.stderr.write('Warning: ' + string + '\n')
44
46 for name, desc, argspecs, proc in commands:
47 sys.stdout.write(' %s -- %s\n' % (name, desc))
48 sys.stdout.write(' usage: %s' % name)
49 for spec in argspecs:
50 if len(spec) > 2:
51 sys.stdout.write(' [%s]' % spec[0].upper())
52 else:
53 sys.stdout.write(' %s' % spec[0].upper())
54 sys.stdout.write('\n')
55
56 -def usage(args, exitval=0):
57 print 'usage: %s [OPTIONS] -m MANAGER COMMAND COMMAND-ARGS...' % args[0]
58 print ''
59 print 'Available commands:'
60 print ''
61 command_usage()
62 print ''
63 print 'See %s -h for help on the available options.' % args[0]
64 sys.exit(exitval)
65
67 op = args[1]
68 matching = [x for x in commands if x[0] == op]
69 if not matching:
70 print 'Error: Unknown command: %s' % op
71 usage(args, exitval=1)
72 commandspec = matching[0]
73
74 argspecs = commandspec[2]
75 reqspecs = [spec for spec in argspecs if len(spec) < 3]
76 nreq = len(reqspecs)
77 optspecs = [spec for spec in argspecs if len(spec) == 3 or \
78 len(spec) > 3 and not spec[3]]
79 nopt = len(optspecs)
80
81 vararg = filter(lambda spec: len(spec) > 3 and spec[3], argspecs)
82
83
84 cargs = args[2:]
85
86 if len(cargs) < nreq or len(cargs) > nreq + nopt and not vararg:
87 print 'Error: Invalid arguments to operation %s: %r' % (op, cargs)
88 usage(args, exitval=1)
89
90 vals = []
91 for name, parse in reqspecs:
92 arg = cargs.pop(0)
93 try:
94 vals.append(parse(arg))
95 except Exception:
96 err('Error: Operation %s\'s arg %s="%s" could not be '
97 'parsed as type "%s"'
98 % (op, name, arg, parse.__name__))
99 for name, parse, default in optspecs:
100 if cargs:
101 arg = cargs.pop(0)
102 try:
103 vals.append(parse(arg))
104 except Exception:
105 err('Error: Operation %s\'s arg %s="%s" could not be '
106 'parsed as type "%s"'
107 % (op, name, arg, parse.__name__))
108 else:
109 vals.append(default)
110
111 if vararg:
112 vals.extend(cargs)
113
114 proc = commandspec[3]
115
116 def command(model, quit):
117 def print_traceback(failure):
118 import traceback
119 warn('Operation %s failed:' % op)
120 traceback.print_exc()
121 return failure
122 d = proc(model, quit, *vals)
123 d.addErrback(print_traceback)
124 return d
125
126 return command
127
142
143 d.addErrback(failed)
144
145 return d
146
147 pat = re.compile('^(([^:@]*)(:([^:@]+))?@)?([^:@]+)(:([0-9]+))?$')
148
150 parser = OptionParser(domain="flumotion-command")
151 parser.add_option('-u', '--usage',
152 action="store_true", dest="usage",
153 help="show a usage message")
154 parser.add_option('-m', '--manager',
155 action="store", type="string", dest="manager",
156 help="the manager to connect to, e.g. localhost:7531")
157 parser.add_option('', '--no-ssl',
158 action="store_true", dest="no_ssl",
159 help="disable encryption when connecting to the manager")
160
161 options, args = parser.parse_args(args)
162
163 if options.usage or not args[1:]:
164 usage(args)
165
166 connection = connections.parsePBConnectionInfo(options.manager,
167 not options.no_ssl)
168
169 command = parse_commands(args)
170 quit = lambda: reactor.callLater(0, reactor.stop)
171
172 d = setup_reactor(connection)
173
174 d.addCallback(lambda model: command(model, quit))
175
176
177 d.addErrback(lambda failure: quit())
178
179 reactor.run()
180