Home | History | Annotate | Download | only in bin
      1 """
      2 Wrapper around ConfigParser to manage testcases configuration.
      3 
      4 @author rsalveti (at] linux.vnet.ibm.com (Ricardo Salveti de Araujo)
      5 """
      6 
      7 from ConfigParser import ConfigParser
      8 from StringIO import StringIO
      9 from os import path
     10 import types, re, string
     11 from autotest_lib.client.common_lib import utils
     12 
     13 __all__ = ['config_loader']
     14 
     15 class config_loader:
     16     """
     17     Base class of the configuration parser
     18     """
     19     def __init__(self, cfg, tmpdir='/tmp', raise_errors=False):
     20         """
     21         Instantiate ConfigParser and provide the file like object that we'll
     22         use to read configuration data from.
     23         @param cfg: Where we'll get configuration data. It can be either:
     24                 * A URL containing the file
     25                 * A valid file path inside the filesystem
     26                 * A string containing configuration data
     27         @param tmpdir: Where we'll dump the temporary conf files.
     28         @param raise_errors: Whether config value absences will raise
     29                 ValueError exceptions.
     30         """
     31         # Base Parser
     32         self.parser = ConfigParser()
     33         # Raise errors when lacking values
     34         self.raise_errors = raise_errors
     35         # File is already a file like object
     36         if hasattr(cfg, 'read'):
     37             self.cfg = cfg
     38             self.parser.readfp(self.cfg)
     39         elif isinstance(cfg, types.StringTypes):
     40             # Config file is a URL. Download it to a temp dir
     41             if cfg.startswith('http') or cfg.startswith('ftp'):
     42                 self.cfg = path.join(tmpdir, path.basename(cfg))
     43                 utils.urlretrieve(cfg, self.cfg)
     44                 self.parser.read(self.cfg)
     45             # Config is a valid filesystem path to a file.
     46             elif path.exists(path.abspath(cfg)):
     47                 if path.isfile(cfg):
     48                     self.cfg = path.abspath(cfg)
     49                     self.parser.read(self.cfg)
     50                 else:
     51                     e_msg = 'Invalid config file path: %s' % cfg
     52                     raise IOError(e_msg)
     53             # Config file is just a string, convert it to a python file like
     54             # object using StringIO
     55             else:
     56                 self.cfg = StringIO(cfg)
     57                 self.parser.readfp(self.cfg)
     58 
     59 
     60     def get(self, section, option, default=None):
     61         """
     62         Get the value of a option.
     63 
     64         Section of the config file and the option name.
     65         You can pass a default value if the option doesn't exist.
     66 
     67         @param section: Configuration file section.
     68         @param option: Option we're looking after.
     69         @default: In case the option is not available and raise_errors is set
     70                 to False, return the default.
     71         """
     72         if not self.parser.has_option(section, option):
     73             if self.raise_errors:
     74                 raise ValueError('No value for option %s. Please check your '
     75                                  'config file "%s".' % (option, self.cfg))
     76             else:
     77                 return default
     78 
     79         return self.parser.get(section, option)
     80 
     81 
     82     def set(self, section, option, value):
     83         """
     84         Set an option.
     85 
     86         This change is not persistent unless saved with 'save()'.
     87         """
     88         if not self.parser.has_section(section):
     89             self.parser.add_section(section)
     90         return self.parser.set(section, option, value)
     91 
     92 
     93     def remove(self, section, option):
     94         """
     95         Remove an option.
     96         """
     97         if self.parser.has_section(section):
     98             self.parser.remove_option(section, option)
     99 
    100 
    101     def save(self):
    102         """
    103         Save the configuration file with all modifications
    104         """
    105         if not self.cfg:
    106             return
    107         fileobj = file(self.cfg, 'w')
    108         try:
    109             self.parser.write(fileobj)
    110         finally:
    111             fileobj.close()
    112 
    113 
    114     def check(self, section):
    115         """
    116         Check if the config file has valid values
    117         """
    118         if not self.parser.has_section(section):
    119             return False, "Section not found: %s"%(section)
    120 
    121         options = self.parser.items(section)
    122         for i in range(options.__len__()):
    123             param = options[i][0]
    124             aux = string.split(param, '.')
    125 
    126             if aux.__len__ < 2:
    127                 return False, "Invalid parameter syntax at %s"%(param)
    128 
    129             if not self.check_parameter(aux[0], options[i][1]):
    130                 return False, "Invalid value at %s"%(param)
    131 
    132         return True, None
    133 
    134 
    135     def check_parameter(self, param_type, parameter):
    136         """
    137         Check if a option has a valid value
    138         """
    139         if parameter == '' or parameter == None:
    140             return False
    141         elif param_type == "ip" and self.__isipaddress(parameter):
    142             return True
    143         elif param_type == "int" and self.__isint(parameter):
    144             return True
    145         elif param_type == "float" and self.__isfloat(parameter):
    146             return True
    147         elif param_type == "str" and self.__isstr(parameter):
    148             return True
    149 
    150         return False
    151 
    152 
    153     def __isipaddress(self, parameter):
    154         """
    155         Verify if the ip address is valid
    156 
    157         @param ip String: IP Address
    158         @return True if a valid IP Address or False
    159         """
    160         octet1 = "([1-9][0-9]{,1}|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
    161         octet = "([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
    162         pattern = "^" + octet1 + "\.(" + octet + "\.){2}" + octet + "$"
    163         if re.match(pattern, parameter) == None:
    164             return False
    165         else:
    166             return True
    167 
    168 
    169     def __isint(self, parameter):
    170         try:
    171             int(parameter)
    172         except Exception, e_stack:
    173             return False
    174         return True
    175 
    176 
    177     def __isfloat(self, parameter):
    178         try:
    179             float(parameter)
    180         except Exception, e_stack:
    181             return False
    182         return True
    183 
    184 
    185     def __isstr(self, parameter):
    186         try:
    187             str(parameter)
    188         except Exception, e_stack:
    189             return False
    190         return True
    191