Whamcloud - gitweb
LU-1346 contrib: fix libcfs_cleanup script
[fs/lustre-release.git] / lustre / utils / Lustre / cmdline.py
1 #!/usr/bin/env python
2 # GPL HEADER START
3 #
4 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License version 2 only,
8 # as published by the Free Software Foundation.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # General Public License version 2 for more details (a copy is included
14 # in the LICENSE file that accompanied this code).
15 #
16 # You should have received a copy of the GNU General Public License
17 # version 2 along with this program; If not, see
18 # http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19 # copy of GPLv2].
20 #
21 # Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 # CA 95054 USA or visit www.sun.com if you need additional information or
23 # have any questions.
24 #
25 # GPL HEADER END
26 #
27
28 #
29 # Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
30 # Use is subject to license terms.
31 #
32
33 #
34 # This file is part of Lustre, http://www.lustre.org/
35 # Lustre is a trademark of Sun Microsystems, Inc.
36 #
37 # Author: Robert Read <rread@clusterfs.com>
38 #
39 # Standard the comand line handling for all the python tools.
40
41 import sys, getopt, types
42 import string
43 import error
44
45 class Options:
46     FLAG = 1
47     PARAM = 2
48     INTPARAM = 3
49     PARAMLIST = 4
50     def __init__(self, cmd, remain_help, options):
51         self.options = options
52         shorts = ""
53         longs = []
54         options.append(('help,h', "Print this help")) 
55         for opt in options:
56             long = self.long(opt)
57             short = self.short(opt)
58             if self.type(opt) in (Options.PARAM, Options.INTPARAM,
59                                   Options.PARAMLIST):
60                 if short: short = short + ':'
61                 if long:
62                     long = long + '='
63             if string.find(long, '_') >= 0:
64                 longs.append(string.replace(long, '_', '-'))
65             shorts = shorts + short
66             longs.append(long)
67         self.short_opts = shorts
68         self.long_opts = longs
69         self.cmd = cmd
70         self.remain_help = remain_help
71
72     def init_values(self):
73         values = {}
74         for opt in self.options:
75             values[self.key(opt)] = self.default(opt)
76         return values
77
78     def long(self, option):
79         n = string.find(option[0], ',')
80         if n < 0: return option[0]
81         else:     return option[0][0:n]
82
83     def key(self, option):
84         key = self.long(option)
85         return string.replace(key, '-', '_')
86         
87     def short(self, option):
88         n = string.find(option[0], ',')
89         if n < 0: return ''
90         else:     return option[0][n+1:]
91
92     def help(self, option):
93         return option[1]
94     
95     def type(self, option):
96         if len(option) >= 3:
97             return option[2]
98         return Options.FLAG
99     
100     def default(self, option):
101         if len(option) >= 4:
102             return option[3]
103         if self.type(option) == Options.PARAMLIST:
104             return []
105         return None
106
107     def lookup_option(self, key, key_func):
108         for opt in self.options:
109             if key_func(opt) == key:
110                 return opt
111
112     def lookup_short(self, key):
113         return self.lookup_option(key, self.short)
114
115     def lookup_long(self, key):
116         key = string.replace(key, '-', '_')
117         return self.lookup_option(key, self.long)
118
119     def handle_opts(self, opts):
120         values = self.init_values()
121         for o, a in opts:
122             if o[0:2] != '--':
123                 option = self.lookup_short(o[1:])
124             else:
125                 option = self.lookup_long(o[2:])
126             if self.type(option) == Options.PARAM:
127                 val = a
128             elif self.type(option) == Options.INTPARAM:
129                 try: 
130                     val = int(a)
131                 except ValueError, e:
132                     raise error.OptionError("option: '%s' expects integer value, got '%s' "  % (o,a))
133             elif self.type(option) == Options.PARAMLIST:
134                 val = values[self.key(option)];
135                 val.append(a)
136             else:
137                 val = 1
138             values[self.key(option)] = val
139         return values
140                 
141         
142     class option_wrapper:
143         def __init__(self, values):
144             self.__dict__['values'] = values
145         def __getattr__(self, name):
146             if self.values.has_key(name):
147                 return self.values[name]
148             else:
149                 raise error.OptionError("bad option name: " + name)
150         def __getitem__(self, name):
151             if self.values.has_key(name):
152                 return self.values[name]
153             else:
154                 raise error.OptionError("bad option name: " + name)
155         def __setattr__(self, name, value):
156             self.values[name] = value
157
158     def parse(self, argv):
159         try:
160             opts, args = getopt.getopt(argv, self.short_opts, self.long_opts)
161             values = self.handle_opts(opts)
162             if values["help"]:
163                 self.usage()
164                 sys.exit(0)
165             return self.option_wrapper(values), args
166         except getopt.error, e:
167             raise error.OptionError(str(e))
168
169     def usage(self):
170         ret = 'usage: %s [options] %s\n' % (self.cmd, self.remain_help)
171         for opt in self.options:
172             s = self.short(opt)
173             if s: str = "-%s|--%s" % (s,self.long(opt))
174             else: str = "--%s" % (self.long(opt),)
175             if self.type(opt) in (Options.PARAM, Options.INTPARAM):
176                 str = "%s <arg>" % (str,)
177             help = self.help(opt)
178             n = string.find(help, '\n')
179             if self.default(opt) != None:
180                 if n < 0:
181                     str = "%-15s  %s (default=%s)" %(str, help,
182                                                      self.default(opt))
183                 else:
184                     str = "%-15s  %s (default=%s)%s" %(str, help[0:n],
185                                                        self.default(opt),
186                                                        help[n:])
187             else:
188                 str = "%-15s  %s" %(str, help)
189             ret = ret + str + "\n"
190         print ret
191
192 # Test driver
193 if __name__ == "__main__":
194     cl = Options("test", "xml_file", [
195                   ('verbose,v', "verbose ", Options.FLAG, 0),
196                   ('cleanup,d', "shutdown"),
197                   ('gdb',     "Display gdb module file ", Options.FLAG, 0),
198                   ('device', "device path ", Options.PARAM),
199                   ('ldapurl', "LDAP server URL ", Options.PARAM),
200                   ('lustre', "Lustre source dir ", Options.PARAM),
201                   ('portals', "Portals source dir ", Options.PARAM),
202                   ('maxlevel', """Specify the maximum level
203                     Levels are aproximatly like:
204                             70 - mountpoint, echo_client, osc, mdc, lov""",
205                    Options.INTPARAM, 100),
206
207                   ])
208
209     conf, args = cl.parse(sys.argv[1:])
210
211     for key in conf.values.keys():
212         print "%-10s = %s" % (key, conf.values[key])