diff --git a/devstack/cfg.py b/devstack/cfg.py index 82ba6dd2..24674c83 100644 --- a/devstack/cfg.py +++ b/devstack/cfg.py @@ -40,47 +40,7 @@ PW_PROMPTS = { } -class IgnoreMissingConfigParser(ConfigParser.RawConfigParser): - DEF_INT = 0 - DEF_FLOAT = 0.0 - DEF_BOOLEAN = False - - def __init__(self): - ConfigParser.RawConfigParser.__init__(self) - - def get(self, section, option): - value = None - try: - value = ConfigParser.RawConfigParser.get(self, section, option) - except ConfigParser.NoSectionError, e: - pass - except ConfigParser.NoOptionError, e: - pass - return value - - def getboolean(self, section, option): - value = self.get(section, option) - if value is None: - #not there so don't let the parent blowup - return IgnoreMissingConfigParser.DEF_BOOLEAN - return ConfigParser.RawConfigParser.getboolean(self, section, option) - - def getfloat(self, section, option): - value = self.get(section, option) - if value is None: - #not there so don't let the parent blowup - return IgnoreMissingConfigParser.DEF_FLOAT - return ConfigParser.RawConfigParser.getfloat(self, section, option) - - def getint(self, section, option): - value = self.get(section, option) - if value is None: - #not there so don't let the parent blowup - return IgnoreMissingConfigParser.DEF_INT - return ConfigParser.RawConfigParser.getint(self, section, option) - - -class EnvConfigParser(ConfigParser.RawConfigParser): +class StackConfigParser(ConfigParser.RawConfigParser): def __init__(self): ConfigParser.RawConfigParser.__init__(self) self.pws = dict() @@ -207,3 +167,45 @@ class EnvConfigParser(ConfigParser.RawConfigParser): #store for later... self.db_dsns[dbname] = dsn return dsn + + +class IgnoreMissingConfigParser(ConfigParser.RawConfigParser): + DEF_INT = 0 + DEF_FLOAT = 0.0 + DEF_BOOLEAN = False + + def __init__(self): + ConfigParser.RawConfigParser.__init__(self) + #make option names case sensitive + self.optionxform = str + + def get(self, section, option): + value = None + try: + value = ConfigParser.RawConfigParser.get(self, section, option) + except ConfigParser.NoSectionError, e: + pass + except ConfigParser.NoOptionError, e: + pass + return value + + def getboolean(self, section, option): + value = self.get(section, option) + if value is None: + #not there so don't let the parent blowup + return IgnoreMissingConfigParser.DEF_BOOLEAN + return ConfigParser.RawConfigParser.getboolean(self, section, option) + + def getfloat(self, section, option): + value = self.get(section, option) + if value is None: + #not there so don't let the parent blowup + return IgnoreMissingConfigParser.DEF_FLOAT + return ConfigParser.RawConfigParser.getfloat(self, section, option) + + def getint(self, section, option): + value = self.get(section, option) + if value is None: + #not there so don't let the parent blowup + return IgnoreMissingConfigParser.DEF_INT + return ConfigParser.RawConfigParser.getint(self, section, option) diff --git a/devstack/components/glance.py b/devstack/components/glance.py index 3873ec0f..8fab5faa 100644 --- a/devstack/components/glance.py +++ b/devstack/components/glance.py @@ -121,9 +121,6 @@ class GlanceInstaller(comp.PythonInstallComponent): #then extract known configs that #will need locations/directories/files made (or touched)... with io.BytesIO(contents) as stream: - #for paste files we might not be doing this 100% right - #since it seems like the paste config format is not the same as - #the python config parser format.... config = cfg.IgnoreMissingConfigParser() config.readfp(stream) if config.getboolean('image_cache_enabled', CFG_SECTION): diff --git a/devstack/components/keystone.py b/devstack/components/keystone.py index b59c5613..29a341c8 100644 --- a/devstack/components/keystone.py +++ b/devstack/components/keystone.py @@ -137,9 +137,6 @@ class KeystoneInstaller(comp.PythonInstallComponent): #then extract known configs that #will need locations/directories/files made (or touched)... with io.BytesIO(contents) as stream: - #for paste files we might not be doing this 100% right - #since it seems like the paste config format is not the same as - #the python config parser format.... config = cfg.IgnoreMissingConfigParser() config.readfp(stream) log_filename = config.get('log_file', CFG_SECTION) diff --git a/devstack/components/nova.py b/devstack/components/nova.py index 4f4b3612..091d55f2 100644 --- a/devstack/components/nova.py +++ b/devstack/components/nova.py @@ -324,10 +324,25 @@ class NovaInstaller(comp.PythonInstallComponent): def _config_adjust(self, contents, config_fn): if config_fn == PASTE_CONF and settings.KEYSTONE in self.instances: - #it seems like paste actually uses it own custom config parser - #which looks like the python config parser files format but actually isn't - #great (not) - contents = utils.adjust_paste_config(contents, PASTE_PIPELINE_KEYSTONE_ADJUST) + newcontents = contents + with io.BytesIO(contents) as stream: + config = cfg.IgnoreMissingConfigParser() + config.readfp(stream) + mods = 0 + for section in PASTE_PIPELINE_KEYSTONE_ADJUST.keys(): + if config.has_section(section): + section_vals = PASTE_PIPELINE_KEYSTONE_ADJUST.get(section) + for (k, v) in section_vals.items(): + config.set(section, k, v) + mods += 1 + if mods > 0: + with io.BytesIO() as outputstream: + config.write(outputstream) + outputstream.flush() + #TODO can we write to contents here directly? + new_data = ['# Adjusted %s' % (config_fn), outputstream.getvalue()] + newcontents = utils.joinlinesep(*new_data) + contents = newcontents return contents def _get_source_config(self, config_fn): diff --git a/devstack/components/swift_keystone.py b/devstack/components/swift_keystone.py index 5e8c32c7..eeec7bc0 100644 --- a/devstack/components/swift_keystone.py +++ b/devstack/components/swift_keystone.py @@ -61,10 +61,10 @@ class SwiftKeystoneInstaller(comp.PythonInstallComponent): }] def _get_config_files(self): - return CONFIGS + return list(CONFIGS) def _get_pkgs(self): - return REQ_PKGS + return list(REQ_PKGS) def _post_install(self): pass diff --git a/devstack/progs/common.py b/devstack/progs/common.py index a82ee7df..e356ae5c 100644 --- a/devstack/progs/common.py +++ b/devstack/progs/common.py @@ -136,7 +136,7 @@ def get_action_cls(action_name, component_name): def get_config(): cfg_fn = sh.canon_path(settings.STACK_CONFIG_LOCATION) - config_instance = cfg.EnvConfigParser() + config_instance = cfg.StackConfigParser() config_instance.read(cfg_fn) return config_instance diff --git a/devstack/utils.py b/devstack/utils.py index c50f70cb..08881487 100644 --- a/devstack/utils.py +++ b/devstack/utils.py @@ -45,38 +45,6 @@ def load_template(component, fn): return (full_pth, contents) -def adjust_paste_config(contents, section_rep): - lines = contents.splitlines() - for section in section_rep.keys(): - section_str = "[" + section.strip() + "]" - section_replacements = section_rep.get(section) - if not section_replacements: - continue - LOG.debug("Looking for section %s" % (section)) - matching = False - for i in range(len(lines)): - line = lines[i] - if matching and line.startswith("["): - #new section - LOG.debug("Finished section named %s ending at line %s" % (section, (i + 1))) - break - elif matching: - for (key, rep) in section_replacements.items(): - #does not handle multi-lines values (fix that?) - pieces = line.split("=", 1) - if len(pieces) == 2: - pot_key = pieces[0].strip() - if pot_key == key: - new_line = "%s = %s" % (key, rep) - LOG.debug("Replacing paste line %s with %s for line %s" % (line, new_line, (i + 1))) - lines[i] = new_line - elif not matching and section_str == line.strip(): - #found the section - matching = True - LOG.debug("Found section named %s starting at line %s" % (section, (i + 1))) - return joinlinesep(*lines) - - def execute_template(*cmds, **kargs): params_replacements = kargs.pop('params', None) tracewriter = kargs.pop('tracewriter', None)