source: proiecte/HadoopJUnit/hadoop-0.20.1/contrib/hod/hodlib/Common/setup.py @ 120

Last change on this file since 120 was 120, checked in by (none), 14 years ago

Added the mail files for the Hadoop JUNit Project

  • Property svn:executable set to *
File size: 44.7 KB
Line 
1#Licensed to the Apache Software Foundation (ASF) under one
2#or more contributor license agreements.  See the NOTICE file
3#distributed with this work for additional information
4#regarding copyright ownership.  The ASF licenses this file
5#to you under the Apache License, Version 2.0 (the
6#"License"); you may not use this file except in compliance
7#with the License.  You may obtain a copy of the License at
8
9#     http://www.apache.org/licenses/LICENSE-2.0
10
11#Unless required by applicable law or agreed to in writing, software
12#distributed under the License is distributed on an "AS IS" BASIS,
13#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#See the License for the specific language governing permissions and
15#limitations under the License.
16# $Id:setup.py 5158 2007-04-09 00:14:35Z zim $
17# $Id:setup.py 5158 2007-04-09 00:14:35Z zim $
18#
19#------------------------------------------------------------------------------
20
21"""'setup' provides for reading and verifing configuration files based on
22   Python's SafeConfigParser class."""
23
24import sys, os, re, pprint
25
26from ConfigParser import SafeConfigParser
27from optparse import OptionParser, IndentedHelpFormatter, OptionGroup
28from util import get_perms, replace_escapes
29from types import typeValidator, typeValidatorInstance, is_valid_type, \
30                  typeToString
31from hodlib.Hod.hod import hodHelp
32
33reEmailAddress = re.compile("^.*@.*$")
34reEmailDelimit = re.compile("@")
35reComma = re.compile("\s*,\s*")
36reDot = re.compile("\.")
37reCommentHack = re.compile("^.*?\s+#|;.*", flags=re.S)
38reCommentNewline = re.compile("\n|\r$")
39reKeyVal = r"(?<!\\)="
40reKeyVal = re.compile(reKeyVal)
41reKeyValList = r"(?<!\\),"
42reKeyValList = re.compile(reKeyValList)
43
44errorPrefix = 'error'
45requiredPerms = '0660'
46
47class definition:
48    def __init__(self):
49        """Generates a configuration definition object."""
50        self.__def = {}
51        self.__defOrder = []
52
53    def __repr__(self):
54        return pprint.pformat(self.__def) 
55
56    def __getitem__(self, section):
57        return self.__def[section]
58
59    def __iter__(self):
60        return iter(self.__def)
61
62    def sections(self):
63        """Returns a list of sections/groups."""
64       
65        if len(self.__defOrder):
66            return self.__defOrder
67        else: 
68            return self.__def.keys()
69     
70    def add_section(self, section):
71        """Add a configuration section / option group."""
72       
73        if self.__def.has_key(section):
74            raise Exception("Section already exists: '%s'" % section)
75        else:
76            self.__def[section] = {}
77
78    def add_def(self, section, var, type, desc, help = True, default = None, 
79                req = True, validate = True, short = None):
80        """ Add a variable definition.
81       
82            section  - section name
83            var      - variable name
84            type     - valid hodlib.types
85            desc     - description of variable
86            help     - display help for this variable
87            default  - default value
88            req      - bool, requried?
89            validate - bool, validate type value?
90            short    - short symbol (1 character),
91            help     - bool, display help?"""
92           
93        if self.__def.has_key(section):
94            if not is_valid_type(type):
95                raise Exception("Type (type) is invalid: %s.%s - '%s'" % (section, var, 
96                                                                type))
97            if not isinstance(desc, str):
98                raise Exception("Description (desc) must be a string: %s.%s - '%s'" % (
99                    section, var, desc))
100            if not isinstance(req, bool):
101                raise Exception("Required (req) must be a bool: %s.%s - '%s'" % (section, 
102                                                                       var, 
103                                                                       req))
104            if not isinstance(validate, bool):
105                raise Exception("Validate (validate) must be a bool: %s.%s - '%s'" % (
106                    section, var, validate))
107             
108            if self.__def[section].has_key(var):
109                raise Exception("Variable name already defined: '%s'" % var)
110            else:
111                self.__def[section][var] = { 'type'     : type,
112                                             'desc'     : desc,
113                                             'help'     : help,
114                                             'default'  : default,
115                                             'req'      : req,
116                                             'validate' : validate,
117                                             'short'    : short }               
118        else:   
119            raise Exception("Section does not exist: '%s'" % section)
120         
121    def add_defs(self, defList, defOrder=None):
122        """ Add a series of definitions.
123       
124            defList = { section0 : ((name0,
125                                     type0,
126                                     desc0,
127                                     help0,
128                                     default0,
129                                     req0,
130                                     validate0,
131                                     short0),
132                                  ....
133                                    (nameN,
134                                     typeN,
135                                     descN,
136                                     helpN,
137                                     defaultN,
138                                     reqN,
139                                     validateN,
140                                     shortN)),             
141                           ....
142                           
143                        sectionN : ... }
144                       
145            Where the short synmbol is optional and can only be one char."""
146                       
147        for section in defList.keys():
148            self.add_section(section)
149            for defTuple in defList[section]:
150                if isinstance(defTuple, tuple): 
151                    if len(defTuple) < 7:
152                        raise Exception(
153                            "section %s is missing an element: %s" % (
154                            section, pprint.pformat(defTuple)))
155                else:
156                    raise Exception("section %s of defList is not a tuple" % 
157                                    section)
158               
159                if len(defTuple) == 7:
160                    self.add_def(section, defTuple[0], defTuple[1], 
161                                 defTuple[2], defTuple[3], defTuple[4], 
162                                 defTuple[5], defTuple[6])
163                else:
164                    self.add_def(section, defTuple[0], defTuple[1], 
165                                 defTuple[2], defTuple[3], defTuple[4], 
166                                 defTuple[5], defTuple[6], defTuple[7])                     
167        if defOrder:
168            for section in defOrder:
169                if section in self.__def:
170                    self.__defOrder.append(section)
171                   
172            for section in self.__def:
173                if not section in defOrder:
174                    raise Exception(
175                        "section %s is missing from specified defOrder." % 
176                        section)
177           
178class baseConfig:
179    def __init__(self, configDef, originalDir=None):
180        self.__toString = typeToString()
181        self.__validated = False
182        self._configDef = configDef
183        self._options = None
184        self._mySections = []
185        self._dict = {}
186        self.configFile = None
187        self.__originalDir = originalDir
188
189        if self._configDef:
190            self._mySections = configDef.sections()
191
192    def __repr__(self):
193        """Returns a string representation of a config object including all
194           normalizations."""
195
196        print_string = '';
197        for section in self._mySections:
198            print_string = "%s[%s]\n" % (print_string, section)
199            options = self._dict[section].keys()
200            for option in options:
201                print_string = "%s%s = %s\n" % (print_string, option,
202                    self._dict[section][option])
203
204            print_string = "%s\n" % (print_string)
205
206        print_string = re.sub("\n\n$", "", print_string)
207
208        return print_string
209
210    def __getitem__(self, section):
211        """ Returns a dictionary of configuration name and values by section.
212        """
213        return self._dict[section]
214
215    def __setitem__(self, section, value):
216        self._dict[section] = value
217
218    def __iter__(self):
219        return iter(self._dict)
220
221    def has_key(self, section):
222        status = False
223        if section in self._dict:
224            status = True
225           
226        return status
227
228    # Prints configuration error messages
229    def var_error(self, section, option, *addData):
230        errorStrings = [] 
231        if not self._dict[section].has_key(option):
232          self._dict[section][option] = None
233        errorStrings.append("%s: invalid '%s' specified in section %s (--%s.%s): %s" % (
234            errorPrefix, option, section, section, option, self._dict[section][option]))
235
236        if addData:
237            errorStrings.append("%s: additional info: %s\n" % (errorPrefix,
238                addData[0]))
239        return errorStrings
240
241    def var_error_suggest(self, errorStrings):
242        if self.configFile:
243            errorStrings.append("Check your command line options and/or " + \
244                              "your configuration file %s" % self.configFile)
245   
246    def __get_args(self, section):
247        def __dummyToString(type, value):
248            return value
249       
250        toString = __dummyToString
251        if self.__validated:
252            toString = self.__toString
253           
254        args = []
255        if isinstance(self._dict[section], dict):
256            for option in self._dict[section]:
257                if section in self._configDef and \
258                option in self._configDef[section]:
259                  if self._configDef[section][option]['type'] == 'bool':
260                    if self._dict[section][option] == 'True' or \
261                        self._dict[section][option] == True:
262                        args.append("--%s.%s" % (section, option))
263                  else:
264                    args.append("--%s.%s" % (section, option))
265                    args.append(toString(
266                           self._configDef[section][option]['type'], 
267                           self._dict[section][option]))
268        else:
269            if section in self._configDef:
270              if self._configDef[section][option]['type'] == 'bool':
271                if self._dict[section] == 'True' or \
272                    self._dict[section] == True:
273                    args.append("--%s" % section)
274              else:
275                if self._dict[section] != 'config':
276                  args.append("--%s" % section)
277                  args.append(toString(self._configDef[section]['type'], 
278                                             self._dict[section]))
279                   
280        return args
281               
282    def values(self):
283        return self._dict.values()
284     
285    def keys(self):
286        return self._dict.keys()
287   
288    def get_args(self, exclude=None, section=None):
289        """Retrieve a tuple of config arguments."""
290       
291        args = []
292        if section:
293            args = self.__get_args(section)
294        else:
295            for section in self._dict:
296                if exclude:
297                    if not section in exclude:
298                        args.extend(self.__get_args(section))
299                else:
300                    args.extend(self.__get_args(section))
301       
302        return tuple(args)
303       
304    def verify(self):
305        """Verifies each configuration variable, using the configValidator
306           class, based on its type as defined by the dictionary configDef.
307           Upon encountering a problem an error is printed to STDERR and
308           false is returned."""
309       
310        oldDir = os.getcwd()
311        if self.__originalDir:
312          os.chdir(self.__originalDir)
313       
314        status = True
315        statusMsgs = []
316       
317        if self._configDef:
318            errorCount = 0
319            configValidator = typeValidator(self.__originalDir)
320
321            # foreach section and option by type string as defined in configDef
322            #   add value to be validated to validator
323            for section in self._mySections:
324                for option in self._configDef[section].keys():
325                    configVarName = "%s.%s" % (section, option)
326
327                    if self._dict[section].has_key(option):
328                        if self._configDef[section][option].has_key('validate'):
329                            if self._configDef[section][option]['validate']:
330                                # is the section.option needed to be validated?
331                                configValidator.add(configVarName,
332                                    self._configDef[section][option]['type'],
333                                    self._dict[section][option])
334                            else:
335                                # If asked not to validate, just normalize
336                                self[section][option] = \
337                                    configValidator.normalize(
338                                    self._configDef[section][option]['type'], 
339                                    self._dict[section][option])
340                            if self._configDef[section][option]['default'] != \
341                                None:
342                                self._configDef[section][option]['default'] = \
343                                    configValidator.normalize(
344                                    self._configDef[section][option]['type'],
345                                    self._configDef[section][option]['default']
346                                    )
347                                self._configDef[section][option]['default'] = \
348                                    self.__toString(
349                                    self._configDef[section][option]['type'], 
350                                    self._configDef[section][option]['default']
351                                    )
352                        else:       
353                            # This should not happen. Just in case, take this as 'to be validated' case.
354                            configValidator.add(configVarName,
355                                self._configDef[section][option]['type'],
356                                self._dict[section][option])
357                    elif self._configDef[section][option]['req']:
358                        statusMsgs.append("%s: %s.%s is not defined."
359                             % (errorPrefix, section, option))
360                        errorCount = errorCount + 1                         
361
362            configValidator.validate()
363
364            for valueInfo in configValidator.validatedInfo:
365                sectionsOptions = reDot.split(valueInfo['name'])
366
367                if valueInfo['isValid'] == 1:
368                    self._dict[sectionsOptions[0]][sectionsOptions[1]] = \
369                        valueInfo['normalized']
370                else:
371                    if valueInfo['errorData']:
372                        statusMsgs.extend(self.var_error(sectionsOptions[0],
373                            sectionsOptions[1], valueInfo['errorData']))
374                    else:
375                        statusMsgs.extend(self.var_error(sectionsOptions[0],
376                            sectionsOptions[1]))
377                    errorCount = errorCount + 1
378
379            if errorCount > 1:
380                statusMsgs.append( "%s: %s problems found." % (
381                    errorPrefix, errorCount))
382                self.var_error_suggest(statusMsgs)
383                status = False
384            elif errorCount > 0:
385                statusMsgs.append( "%s: %s problem found." % (
386                    errorPrefix, errorCount))
387                self.var_error_suggest(statusMsgs)
388                status = False
389       
390        self.__validated = True
391
392        if self.__originalDir:
393          os.chdir(oldDir)
394
395        return status,statusMsgs
396
397    def normalizeValue(self, section, option)  :
398      return typeValidatorInstance.normalize(
399                                  self._configDef[section][option]['type'],
400                                  self[section][option])
401
402    def validateValue(self, section, option):
403      # Validates a section.option and exits on error
404      valueInfo = typeValidatorInstance.verify(
405                                  self._configDef[section][option]['type'],
406                                  self[section][option])
407      if valueInfo['isValid'] == 1:
408        return []
409      else:
410        if valueInfo['errorData']:
411          return self.var_error(section, option, valueInfo['errorData'])
412        else:
413          return self.var_error(section, option)
414
415class config(SafeConfigParser, baseConfig):
416    def __init__(self, configFile, configDef=None, originalDir=None, 
417                 options=None, checkPerms=False):
418        """Constructs config object.
419
420           configFile - configuration file to read
421           configDef  - definition object
422           options    - options object
423           checkPerms - check file permission on config file, 0660
424
425           sample configuration file:
426
427            [snis]
428            modules_dir  = modules/       ; location of infoModules
429            md5_defs_dir = etc/md5_defs   ; location of infoTree md5 defs
430            info_store   = var/info       ; location of nodeInfo store
431            cam_daemon   = localhost:8200 ; cam daemon address"""
432
433
434        SafeConfigParser.__init__(self)
435        baseConfig.__init__(self, configDef, originalDir)
436
437        if(os.path.exists(configFile)):
438          self.configFile = configFile
439        else:
440          raise IOError
441       
442        self._options = options
443       
444        ## UNUSED CODE : checkPerms is never True
445  ## zim: this code is used if one instantiates config() with checkPerms set to
446  ## True.
447        if checkPerms: self.__check_perms()
448
449        self.read(configFile)
450
451        self._configDef = configDef
452        if not self._configDef:
453            self._mySections = self.sections()
454
455        self.__initialize_config_dict()
456
457    def __initialize_config_dict(self):
458        """ build a dictionary of config vars keyed by section name defined in
459           configDef, if options defined override config"""
460
461        for section in self._mySections:
462            items = self.items(section)
463            self._dict[section] = {}
464
465            # First fill self._dict with whatever is given in hodrc.
466            # Going by this, options given at the command line either override
467            # options in hodrc, or get appended to the list, like for
468            # hod.client-params. Note that after this dict has _only_ hodrc
469            # params
470            for keyValuePair in items:
471                # stupid commenting bug in ConfigParser class, lines without an
472                #  option value pair or section required that ; or # are at the
473                #  beginning of the line, :(
474                newValue = reCommentHack.sub("", keyValuePair[1])
475                newValue = reCommentNewline.sub("", newValue)
476                self._dict[section][keyValuePair[0]] = newValue
477            # end of filling with options given in hodrc
478            # now start filling in command line options
479            if self._options:   
480                for option in self._configDef[section].keys():
481                    if self._options[section].has_key(option):
482                        # the user has given an option
483                        compoundOpt = "%s.%s" %(section,option)
484                        if ( compoundOpt == \
485                              'gridservice-mapred.final-server-params' \
486                              or compoundOpt == \
487                                    'gridservice-hdfs.final-server-params' \
488                              or compoundOpt == \
489                                    'gridservice-mapred.server-params' \
490                              or compoundOpt == \
491                                    'gridservice-hdfs.server-params' \
492                              or compoundOpt == \
493                                    'hod.client-params' ):
494                 
495                           if ( compoundOpt == \
496                              'gridservice-mapred.final-server-params' \
497                              or compoundOpt == \
498                                    'gridservice-hdfs.final-server-params' ):
499                              overwrite = False
500                           else: overwrite = True
501
502                           # Append to the current list of values in self._dict
503                           if not self._dict[section].has_key(option):
504                             self._dict[section][option] = ""
505                           dictOpts = reKeyValList.split(self._dict[section][option])
506                           dictOptsKeyVals = {}
507                           for opt in dictOpts:
508                              if opt != '':
509                                # when dict _has_ params from hodrc
510                                if reKeyVal.search(opt):
511                                  (key, val) = reKeyVal.split(opt,1)
512                                  # we only consider the first '=' for splitting
513                                  # we do this to support passing params like
514                                  # mapred.child.java.opts=-Djava.library.path=some_dir
515                                  # Even in case of an invalid error like unescaped '=',
516                                  # we don't want to fail here itself. We leave such errors
517                                  # to be caught during validation which happens after this
518                                  dictOptsKeyVals[key] = val
519                                else: 
520                                  # this means an invalid option. Leaving it
521                                  #for config.verify to catch
522                                  dictOptsKeyVals[opt] = None
523                               
524                           cmdLineOpts = reKeyValList.split(self._options[section][option])
525
526                           for opt in cmdLineOpts:
527                              if reKeyVal.search(opt):
528                                # Same as for hodrc options. only consider
529                                # the first =
530                                ( key, val ) = reKeyVal.split(opt,1)
531                              else:
532                                key = opt
533                                val = None
534                              # whatever is given at cmdline overrides
535                              # what is given in hodrc only for non-final params
536                              if dictOptsKeyVals.has_key(key):
537                                if overwrite:
538                                  dictOptsKeyVals[key] = val
539                              else: dictOptsKeyVals[key] = val
540                             
541                           self._dict[section][option] = ""
542                           for key in dictOptsKeyVals:
543                              if self._dict[section][option] == "":
544                                if dictOptsKeyVals[key]:
545                                  self._dict[section][option] = key + "=" + \
546                                    dictOptsKeyVals[key]
547                                else: #invalid option. let config.verify catch
548                                  self._dict[section][option] = key
549                              else:
550                                if dictOptsKeyVals[key]:
551                                  self._dict[section][option] = \
552                                    self._dict[section][option] + "," + key + \
553                                      "=" + dictOptsKeyVals[key]
554                                else:  #invalid option. let config.verify catch
555                                  self._dict[section][option] = \
556                                    self._dict[section][option] + "," + key
557
558                        else:
559                             # for rest of the options, that don't need
560                            # appending business.
561                            # options = cmdline opts + defaults
562                            # dict    = hodrc opts only
563                            # only non default opts can overwrite any opt
564                            # currently in dict
565                           if not self._dict[section].has_key(option):
566                              # options not mentioned in hodrc
567                              self._dict[section][option] = \
568                                               self._options[section][option]
569                           elif self._configDef[section][option]['default'] != \
570                                               self._options[section][option]:
571                              # option mentioned in hodrc but user has given a
572                              # non-default option
573                              self._dict[section][option] = \
574                                               self._options[section][option]
575
576    ## UNUSED METHOD
577    ## zim: is too :)
578    def __check_perms(self):
579        perms = None
580        if self._options: 
581            try:
582                perms = get_perms(self.configFile)
583            except OSError, data:
584                self._options.print_help()
585                raise Exception("*** could not find config file: %s" % data)
586                sys.exit(1)
587        else:
588            perms = get_perms(self.configFile)
589               
590        if perms != requiredPerms:
591            error = "*** '%s' has invalid permission: %s should be %s\n" % \
592                (self.configFile, perms, requiredPerms)
593            raise Exception( error)
594            sys.exit(1)
595
596    def replace_escape_seqs(self):
597      """ replace any escaped characters """
598      replace_escapes(self)
599
600class formatter(IndentedHelpFormatter):
601    def format_option_strings(self, option):
602        """Return a comma-separated list of option strings & metavariables."""
603        if option.takes_value():
604            metavar = option.metavar or option.dest.upper()
605            short_opts = [sopt
606                          for sopt in option._short_opts]
607            long_opts = [self._long_opt_fmt % (lopt, metavar)
608                         for lopt in option._long_opts]
609        else:
610            short_opts = option._short_opts
611            long_opts = option._long_opts
612
613        if self.short_first:
614            opts = short_opts + long_opts
615        else:
616            opts = long_opts + short_opts
617
618        return ", ".join(opts)   
619
620class options(OptionParser, baseConfig):
621
622    def __init__(self, optionDef, usage, version, originalDir=None, 
623                 withConfig=False, defaultConfig=None, defaultLocation=None,
624                 name=None):
625        """Constructs and options object.
626         
627           optionDef     - definition object
628           usage         - usage statement
629           version       - version string
630           withConfig    - used in conjunction with a configuration file
631           defaultConfig - default configuration file
632       
633        """
634        OptionParser.__init__(self, usage=usage)
635        baseConfig.__init__(self, optionDef, originalDir)
636       
637        self.formatter = formatter(4, max_help_position=100, width=180, 
638                                   short_first=1)
639       
640        self.__name = name
641        self.__version = version
642        self.__withConfig = withConfig
643        self.__defaultConfig = defaultConfig
644        self.__defaultLoc = defaultLocation
645        self.args = []
646        self.__optionList = []
647        self.__compoundOpts = []
648        self.__shortMap = {}
649        self.__alphaString = 'abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVXYZ1234567890'
650        self.__alpha = []
651        self.__parsedOptions = {}
652        self.__reserved = [ 'h' ]
653       
654        self.__orig_grps = []
655        self.__orig_grp_lists = {}
656        self.__orig_option_list = []
657       
658        self.__display_grps = []
659        self.__display_grp_lists = {}
660        self.__display_option_list = [] 
661       
662        self.config = None
663       
664        if self.__withConfig:
665            self.__reserved.append('c')
666        self.__reserved.append('v')
667       
668        self.__gen_alpha()           
669
670        # build self.__optionList, so it contains all the options that are
671        # possible. the list elements are of the form section.option
672        for section in self._mySections:
673            if self.__withConfig and section == 'config':
674                raise Exception(
675                    "withConfig set 'config' cannot be used as a section name")
676            for option in self._configDef[section].keys():
677                if '.' in option:
678                    raise Exception("Options cannot contain: '.'")
679                elif self.__withConfig and option == 'config':
680                    raise Exception(
681                        "With config set, option config is not allowed.")
682                elif self.__withConfig and option == 'verbose-help':
683                    raise Exception(
684                        "With config set, option verbose-help is not allowed.")                 
685                self.__optionList.append(self.__splice_compound(section, 
686                                                                option))
687        self.__build_short_map()
688        self.__add_options()
689        self.__init_display_options() 
690       
691        (self.__parsedOptions, self.args) = self.parse_args()
692
693        # Now process the positional arguments only for the client side
694        if self.__name == 'hod':
695
696          hodhelp = hodHelp()
697
698          _operation = getattr(self.__parsedOptions,'hod.operation')
699          _script = getattr(self.__parsedOptions, 'hod.script')
700          nArgs = self.args.__len__()
701          if _operation:
702            # -o option is given
703            if nArgs != 0:
704              self.error('invalid syntax : command and operation(-o) cannot coexist')
705          elif nArgs == 0 and _script:
706            # for a script option, without subcommand: hod -s script ...
707            pass
708          elif nArgs == 0:
709            print "Usage: ",hodhelp.help()
710            sys.exit(0)
711          else:
712            # subcommand is given
713            cmdstr = self.args[0] # the subcommand itself
714            cmdlist = hodhelp.ops
715            if cmdstr not in cmdlist:
716              print "Usage: ", hodhelp.help()
717              sys.exit(2)
718
719            numNodes = None
720            clusterDir = None
721            # Check which subcommand. cmdstr  = subcommand itself now.
722            if cmdstr == "allocate":
723              clusterDir = getattr(self.__parsedOptions, 'hod.clusterdir')
724              numNodes = getattr(self.__parsedOptions, 'hod.nodecount')
725 
726              if not clusterDir or not numNodes:
727                print hodhelp.usage(cmdstr)
728                sys.exit(3)
729
730              cmdstr = cmdstr + ' ' + clusterDir + ' ' + numNodes
731
732              setattr(self.__parsedOptions,'hod.operation', cmdstr)
733 
734            elif cmdstr == "deallocate" or cmdstr == "info":
735              clusterDir = getattr(self.__parsedOptions, 'hod.clusterdir')
736
737              if not clusterDir:
738                print hodhelp.usage(cmdstr)
739                sys.exit(3)
740 
741              cmdstr = cmdstr + ' ' + clusterDir
742              setattr(self.__parsedOptions,'hod.operation', cmdstr)
743
744            elif cmdstr == "list":
745              setattr(self.__parsedOptions,'hod.operation', cmdstr)
746              pass
747 
748            elif cmdstr == "script":
749              clusterDir = getattr(self.__parsedOptions, 'hod.clusterdir')
750              numNodes = getattr(self.__parsedOptions, 'hod.nodecount')
751              originalDir = getattr(self.__parsedOptions, 'hod.original-dir')
752
753              if originalDir and clusterDir:
754                self.remove_exit_code_file(originalDir, clusterDir)
755
756              if not _script or not clusterDir or not numNodes:
757                print hodhelp.usage(cmdstr)
758                sys.exit(3)
759              pass
760
761            elif cmdstr == "help":
762              if nArgs == 1:
763                self.print_help()
764                sys.exit(0)
765              elif nArgs != 2:
766                self.print_help()
767                sys.exit(3)
768              elif self.args[1] == 'options':
769                self.print_options()
770                sys.exit(0)
771              cmdstr = cmdstr + ' ' + self.args[1]
772              setattr(self.__parsedOptions,'hod.operation', cmdstr)
773
774        # end of processing for arguments on the client side
775
776        if self.__withConfig:
777            self.config = self.__parsedOptions.config
778            if not self.config:
779                self.error("configuration file must be specified")
780            if not os.path.isabs(self.config):
781                # A relative path. Append the original directory which would be the
782                # current directory at the time of launch
783                try: 
784                    origDir = getattr(self.__parsedOptions, 'hod.original-dir')
785                    if origDir is not None:
786                        self.config = os.path.join(origDir, self.config)
787                        self.__parsedOptions.config = self.config
788                except AttributeError, e:
789                    self.error("hod.original-dir is not defined.\
790                                   Cannot get current directory")
791            if not os.path.exists(self.config):
792                if self.__defaultLoc and not re.search("/", self.config):
793                    self.__parsedOptions.config = os.path.join(
794                        self.__defaultLoc, self.config)
795        self.__build_dict()   
796
797    def norm_cluster_dir(self, orig_dir, directory):
798        directory = os.path.expanduser(directory)
799        if not os.path.isabs(directory):
800            directory = os.path.join(orig_dir, directory)
801        directory = os.path.abspath(directory)
802
803        return directory
804
805    def remove_exit_code_file(self, orig_dir, dir):
806        try:
807            dir = self.norm_cluster_dir(orig_dir, dir)
808            if os.path.exists(dir):
809                exit_code_file = os.path.join(dir, "script.exitcode")
810                if os.path.exists(exit_code_file):
811                    os.remove(exit_code_file)
812        except:
813            print >>sys.stderr, "Could not remove the script.exitcode file."
814   
815    def __init_display_options(self):
816        self.__orig_option_list = self.option_list[:]
817        optionListTitleMap = {}
818        for option in self.option_list:
819            optionListTitleMap[option._long_opts[0]] = option
820     
821        self.__orig_grps = self.option_groups[:]
822        for group in self.option_groups:
823            self.__orig_grp_lists[group.title] = group.option_list[:]
824                                   
825        groupTitleMap = {}
826        optionTitleMap = {}
827        for group in self.option_groups:
828            groupTitleMap[group.title] = group
829            optionTitleMap[group.title] = {}
830            for option in group.option_list:
831                (sectionName, optionName) = \
832                    self.__split_compound(option._long_opts[0])
833                optionTitleMap[group.title][optionName] = option
834         
835        for section in self._mySections:
836            for option in self._configDef[section]:
837                if self._configDef[section][option]['help']:
838                    if groupTitleMap.has_key(section):
839                        if not self.__display_grp_lists.has_key(section):
840                            self.__display_grp_lists[section] = []
841                        self.__display_grp_lists[section].append(
842                            optionTitleMap[section][option])
843                   
844                    try:   
845                        self.__display_option_list.append(
846                            optionListTitleMap["--" + self.__splice_compound(
847                            section, option)])
848                    except KeyError:
849                        pass
850        try:
851            self.__display_option_list.append(optionListTitleMap['--config'])
852        except KeyError:
853            pass
854         
855        self.__display_option_list.append(optionListTitleMap['--help'])
856        self.__display_option_list.append(optionListTitleMap['--verbose-help'])
857        self.__display_option_list.append(optionListTitleMap['--version'])
858                   
859        self.__display_grps = self.option_groups[:]             
860        for section in self._mySections:
861            if self.__display_grp_lists.has_key(section):
862                self.__orig_grp_lists[section] = \
863                    groupTitleMap[section].option_list
864            else:
865                try:
866                    self.__display_grps.remove(groupTitleMap[section])
867                except KeyError:
868                    pass
869               
870    def __gen_alpha(self):
871        assignedOptions = []
872        for section in self._configDef:
873            for option in self._configDef[section]:
874                if self._configDef[section][option]['short']:
875                    assignedOptions.append(
876                        self._configDef[section][option]['short'])
877       
878        for symbol in self.__alphaString:
879            if not symbol in assignedOptions:
880                self.__alpha.append(symbol)
881
882    def __splice_compound(self, section, option):
883        return "%s.%s" % (section, option)
884       
885    def __split_compound(self, compound):   
886        return compound.split('.')
887       
888    def __build_short_map(self):
889        """ build a short_map of parametername : short_option. This is done
890        only for those parameters that don't have short options already
891        defined in configDef.
892        If possible, the first letter in the option that is not already
893        used/reserved as a short option is allotted. Otherwise the first
894        letter in __alpha that isn't still used is allotted.
895        e.g. { 'hodring.java-home': 'T', 'resource_manager.batch-home': 'B' }
896        """
897
898        optionsKey = {}
899        for compound in self.__optionList:
900            (section, option) = self.__split_compound(compound)
901            if not optionsKey.has_key(section):
902                optionsKey[section] = []
903            optionsKey[section].append(option)
904       
905        for section in self._configDef.sections():
906            options = optionsKey[section]
907            options.sort()
908            for option in options:
909                if not self._configDef[section][option]['short']:
910                    compound = self.__splice_compound(section, option)
911                    shortOptions = self.__shortMap.values()
912                    for i in range(0, len(option)):
913                        letter = option[i]
914                        letter = letter.lower()
915                        if letter in self.__alpha:
916                            if not letter in shortOptions and \
917                                not letter in self.__reserved:
918                                self.__shortMap[compound] = letter
919                                break
920                    if not self.__shortMap.has_key(compound):
921                        for i in range(0, len(self.__alpha)):
922                            letter = self.__alpha[i]
923                            if not letter in shortOptions and \
924                                not letter in self.__reserved:
925                                self.__shortMap[compound] = letter
926
927    def __add_option(self, config, compoundOpt, section, option, group=None):
928        addMethod = self.add_option
929        if group: addMethod=group.add_option
930       
931        self.__compoundOpts.append(compoundOpt)
932       
933        if compoundOpt == 'gridservice-mapred.final-server-params' or \
934           compoundOpt == 'gridservice-hdfs.final-server-params' or \
935           compoundOpt == 'gridservice-mapred.server-params' or \
936           compoundOpt == 'gridservice-hdfs.server-params' or \
937           compoundOpt == 'hod.client-params':
938          _action = 'append'
939        elif config[section][option]['type'] == 'bool':
940          _action = 'store_true'
941        else:
942          _action = 'store'
943
944        if self.__shortMap.has_key(compoundOpt):
945          addMethod("-" + self.__shortMap[compoundOpt],
946                          "--" + compoundOpt, dest=compoundOpt, 
947                          action= _action, 
948                          metavar=config[section][option]['type'],
949                          default=config[section][option]['default'],
950                          help=config[section][option]['desc'])
951        else:
952          if config[section][option]['short']:
953            addMethod("-" + config[section][option]['short'], 
954                              "--" + compoundOpt, dest=compoundOpt, 
955                              action= _action,
956                              metavar=config[section][option]['type'],
957                              default=config[section][option]['default'],
958                              help=config[section][option]['desc'])   
959          else:
960            addMethod('', "--" + compoundOpt, dest=compoundOpt, 
961                              action= _action, 
962                              metavar=config[section][option]['type'],
963                              default=config[section][option]['default'],
964                              help=config[section][option]['desc'])   
965                           
966    def __add_options(self):
967        if self.__withConfig:
968            self.add_option("-c", "--config", dest='config', 
969                action='store', default=self.__defaultConfig, 
970                metavar='config_file',
971                help="Full path to configuration file.")
972
973        self.add_option("", "--verbose-help", 
974            action='help', default=None, 
975            metavar='flag',
976            help="Display verbose help information.")
977       
978        self.add_option("-v", "--version", 
979            action='version', default=None, 
980            metavar='flag',
981            help="Display version information.")
982       
983        self.version = self.__version
984 
985        if len(self._mySections) > 1:
986            for section in self._mySections:
987                group = OptionGroup(self, section)
988                for option in self._configDef[section]:
989                    compoundOpt = self.__splice_compound(section, option)
990                    self.__add_option(self._configDef, compoundOpt, section, 
991                                      option, group)
992                self.add_option_group(group)
993        else:
994            for section in self._mySections:
995                for option in self._configDef[section]:
996                    compoundOpt = self.__splice_compound(section, option)
997                    self.__add_option(self._configDef, compoundOpt, section, 
998                                      option)
999                   
1000    def __build_dict(self):
1001        if self.__withConfig:
1002            self._dict['config'] = str(getattr(self.__parsedOptions, 'config'))
1003        for compoundOption in dir(self.__parsedOptions):
1004            if compoundOption in self.__compoundOpts:
1005                (section, option) = self.__split_compound(compoundOption)
1006                if not self._dict.has_key(section):
1007                    self._dict[section] = {}
1008               
1009                if getattr(self.__parsedOptions, compoundOption):
1010                    _attr = getattr(self.__parsedOptions, compoundOption)
1011                    # when we have multi-valued parameters passed separately
1012                    # from command line, python optparser pushes them into a
1013                    # list. So converting all such lists to strings
1014                    if type(_attr) == type([]):
1015                      import string
1016                      _attr = string.join(_attr,',')
1017                    self._dict[section][option] = _attr
1018                   
1019        for section in self._configDef:
1020            for option in self._configDef[section]: 
1021                if self._configDef[section][option]['type'] == 'bool':
1022                    compoundOption = self.__splice_compound(section, option)
1023                    if not self._dict.has_key(section):
1024                        self._dict[section] = {}
1025                   
1026                    if option not in self._dict[section]:
1027                        self._dict[section][option] = False
1028 
1029    def __set_display_groups(self):
1030        if not '--verbose-help' in sys.argv:
1031            self.option_groups = self.__display_grps
1032            self.option_list = self.__display_option_list
1033            for group in self.option_groups:
1034                group.option_list = self.__display_grp_lists[group.title]
1035 
1036    def __unset_display_groups(self):
1037        if not '--verbose-help' in sys.argv:
1038            self.option_groups = self.__orig_grps
1039            self.option_list = self.__orig_option_list
1040            for group in self.option_groups:
1041                group.option_list = self.__orig_grp_lists[group.title]     
1042 
1043    def print_help(self, file=None):
1044        self.__set_display_groups()
1045        OptionParser.print_help(self, file)
1046        self.__unset_display_groups()
1047
1048    def print_options(self):
1049        _usage = self.usage
1050        self.set_usage('')
1051        self.print_help()
1052        self.set_usage(_usage)
1053                       
1054    def verify(self):
1055        return baseConfig.verify(self)
1056
1057    def replace_escape_seqs(self):
1058      replace_escapes(self)
Note: See TracBrowser for help on using the repository browser.