def _format_defaults(opt): "Return a list of formatted default values." if isinstance(opt, cfg.MultiStrOpt): if opt.sample_default is not None: defaults = opt.sample_default elif not opt.default: defaults = [''] else: defaults = opt.default else: if opt.sample_default is not None: default_str = str(opt.sample_default) elif opt.default is None: default_str = '<None>' elif (isinstance(opt, cfg.StrOpt) or isinstance(opt, cfg.IPOpt) or isinstance(opt, cfg.HostnameOpt)): default_str = opt.default elif isinstance(opt, cfg.BoolOpt): default_str = str(opt.default).lower() elif isinstance(opt, (cfg.IntOpt, cfg.FloatOpt, cfg.PortOpt)): default_str = str(opt.default) elif isinstance(opt, (cfg.ListOpt, cfg._ConfigFileOpt, cfg._ConfigDirOpt)): default_str = ','.join(opt.default) elif isinstance(opt, cfg.DictOpt): sorted_items = sorted(opt.default.items(), key=operator.itemgetter(0)) default_str = ','.join(['%s:%s' % i for i in sorted_items]) else: LOG.warning(_LW('Unknown option type: %s'), repr(opt)) default_str = str(opt.default) defaults = [default_str] results = [] for default_str in defaults: if default_str.strip() != default_str: default_str = '"%s"' % default_str results.append(default_str) return results
def _format_defaults(opt): "Return a list of formatted default values." if isinstance(opt, cfg.MultiStrOpt): if opt.sample_default is not None: defaults = opt.sample_default elif not opt.default: defaults = [''] else: defaults = opt.default else: if opt.sample_default is not None: default_str = str(opt.sample_default) elif opt.default is None: default_str = '<None>' elif (isinstance(opt, (cfg.StrOpt, cfg.IPOpt, cfg.HostnameOpt, cfg.URIOpt))): default_str = opt.default elif isinstance(opt, cfg.BoolOpt): default_str = str(opt.default).lower() elif isinstance(opt, (cfg.IntOpt, cfg.FloatOpt, cfg.PortOpt)): default_str = str(opt.default) elif isinstance(opt, (cfg.ListOpt, cfg._ConfigFileOpt, cfg._ConfigDirOpt)): default_str = ','.join(opt.default) elif isinstance(opt, cfg.DictOpt): sorted_items = sorted(opt.default.items(), key=operator.itemgetter(0)) default_str = ','.join(['%s:%s' % i for i in sorted_items]) else: LOG.warning(_LW('Unknown option type: %s'), repr(opt)) default_str = str(opt.default) defaults = [default_str] results = [] for default_str in defaults: if default_str.strip() != default_str: default_str = '"%s"' % default_str results.append(default_str) return results
def format(self, opt, group_name, minimal=False): """Format a description of an option to the output file. :param opt: a cfg.Opt instance """ if not opt.help: LOG.warning(_LW('"%s" is missing a help string'), opt.dest) opt_type = _format_type_name(opt.type) opt_prefix = '' if (opt.deprecated_for_removal and not opt.help.startswith('DEPRECATED')): opt_prefix = 'DEPRECATED: ' if opt.help: help_text = u'%s%s (%s)' % (opt_prefix, opt.help, opt_type) else: help_text = u'(%s)' % opt_type lines = self._format_help(help_text) if getattr(opt.type, 'min', None) is not None: lines.append('# Minimum value: %d\n' % opt.type.min) if getattr(opt.type, 'max', None) is not None: lines.append('# Maximum value: %d\n' % opt.type.max) if getattr(opt.type, 'choices', None): choices_text = ', '.join( [self._get_choice_text(choice) for choice in opt.type.choices]) lines.append('# Allowed values: %s\n' % choices_text) try: if opt.mutable: lines.append( '# Note: This option can be changed without restarting.\n') except AttributeError as err: # NOTE(dhellmann): keystoneauth defines its own Opt class, # and neutron (at least) returns instances of those # classes instead of oslo_config Opt instances. The new # mutable attribute is the first property where the API # isn't supported in the external class, so we can use # this failure to emit a warning. See # https://bugs.launchpad.net/keystoneauth/+bug/1548433 for # more details. import warnings if not isinstance(opt, cfg.Opt): warnings.warn( 'Incompatible option class for %s (%r): %s' % (opt.dest, opt.__class__, err), ) else: warnings.warn('Failed to fully format sample for %s: %s' % (opt.dest, err)) for d in opt.deprecated_opts: lines.append('# Deprecated group/name - [%s]/%s\n' % (d.group or group_name, d.name or opt.dest)) if opt.deprecated_for_removal: if opt.deprecated_since: lines.append( '# This option is deprecated for removal since %s.\n' % (opt.deprecated_since)) else: lines.append('# This option is deprecated for removal.\n') lines.append( '# Its value may be silently ignored in the future.\n') if opt.deprecated_reason: lines.extend( self._format_help('Reason: ' + opt.deprecated_reason)) if opt.advanced: lines.append( '# Advanced Option: intended for advanced users and not used\n' '# by the majority of users, and might have a significant\n' '# effect on stability and/or performance.\n') if hasattr(opt.type, 'format_defaults'): defaults = opt.type.format_defaults(opt.default, opt.sample_default) else: LOG.debug( "The type for option %(name)s which is %(type)s is not a " "subclass of types.ConfigType and doesn't provide a " "'format_defaults' method. A default formatter is not " "available so the best-effort formatter will be used.", { 'type': opt.type, 'name': opt.name }) defaults = _format_defaults(opt) for default_str in defaults: if default_str: default_str = ' ' + default_str if minimal: lines.append('%s =%s\n' % (opt.dest, default_str)) else: lines.append('#%s =%s\n' % (opt.dest, default_str)) self.writelines(lines)
def format(self, opt, group_name, namespace, minimal=False, summarize=False): """Format a description of an option to the output file. :param opt: a cfg.Opt instance :param group_name: name of the group to which the opt is assigned :param minimal: enable option by default, marking it as required :param summarize: output a summarized description of the opt :returns: a formatted opt description string """ if not opt.help: LOG.warning(_LW('"%s" is missing a help string'), opt.dest) opt_type = _format_type_name(opt.type) opt_prefix = '' if (opt.deprecated_for_removal and not opt.help.startswith('DEPRECATED')): opt_prefix = 'DEPRECATED: ' if opt.help: # an empty line signifies a new paragraph. We only want the # summary line if summarize: _split = opt.help.split('\n\n') opt_help = _split[0].rstrip(':').rstrip('.') if len(_split) > 1: opt_help += '. For more information, refer to the ' opt_help += 'documentation.' else: opt_help = opt.help help_text = u'%s%s (%s)' % (opt_prefix, opt_help, opt_type) else: help_text = u'(%s)' % opt_type lines = self._format_help(help_text) if getattr(opt.type, 'min', None) is not None: lines.append('# Minimum value: %d\n' % opt.type.min) if getattr(opt.type, 'max', None) is not None: lines.append('# Maximum value: %d\n' % opt.type.max) if getattr(opt.type, 'choices', None): choices_text = ', '.join([self._get_choice_text(choice) for choice in opt.type.choices]) lines.append('# Allowed values: %s\n' % choices_text) try: if opt.mutable: lines.append( '# Note: This option can be changed without restarting.\n' ) except AttributeError as err: # NOTE(dhellmann): keystoneauth defines its own Opt class, # and neutron (at least) returns instances of those # classes instead of oslo_config Opt instances. The new # mutable attribute is the first property where the API # isn't supported in the external class, so we can use # this failure to emit a warning. See # https://bugs.launchpad.net/keystoneauth/+bug/1548433 for # more details. import warnings if not isinstance(opt, cfg.Opt): warnings.warn( 'Incompatible option class for %s (%r): %s' % (opt.dest, opt.__class__, err), ) else: warnings.warn('Failed to fully format sample for %s: %s' % (opt.dest, err)) for d in opt.deprecated_opts: lines.append('# Deprecated group/name - [%s]/%s\n' % (d.group or group_name, d.name or opt.dest)) if opt.deprecated_for_removal: if opt.deprecated_since: lines.append( '# This option is deprecated for removal since %s.\n' % ( opt.deprecated_since)) else: lines.append( '# This option is deprecated for removal.\n') lines.append( '# Its value may be silently ignored in the future.\n') if opt.deprecated_reason: lines.extend( self._format_help('Reason: ' + opt.deprecated_reason)) if opt.advanced: lines.append( '# Advanced Option: intended for advanced users and not used\n' '# by the majority of users, and might have a significant\n' '# effect on stability and/or performance.\n' ) if hasattr(opt.type, 'format_defaults'): defaults = opt.type.format_defaults(opt.default, opt.sample_default) else: LOG.debug( "The type for option %(name)s which is %(type)s is not a " "subclass of types.ConfigType and doesn't provide a " "'format_defaults' method. A default formatter is not " "available so the best-effort formatter will be used.", {'type': opt.type, 'name': opt.name}) for default_str in defaults: if type(opt) in [cfg.MultiOpt, cfg.MultiStrOpt]: lines.append('# from .%s.%s.%s (multiopt)\n' % (group_name.lower(), namespace, opt.dest)) lines.append('{{ if not .%s.%s.%s }}#%s = {{ .%s.%s.%s | default "%s" }}{{ else }}{{ range .%s.%s.%s }}%s = {{ . }}{{ end }}{{ end }}\n' % (group_name.lower(), namespace, opt.dest, opt.dest, group_name.lower(), namespace, opt.dest, default_str.replace('"', r'\"'), group_name.lower(), namespace, opt.dest, opt.dest)) else: lines.append('# from .%s.%s.%s\n' % (group_name.lower(), namespace, opt.dest)) if minimal: lines.append('%s = {{ .%s.%s.%s | default "%s" }}\n' % (opt.dest, group_name.lower(), namespace, opt.dest, default_str.replace('"', r'\"'))) else: lines.append('{{ if not .%s.%s.%s }}#{{ end }}%s = {{ .%s.%s.%s | default "%s" }}\n' % (group_name.lower(), namespace, opt.dest, opt.dest, group_name.lower(), namespace, opt.dest, default_str.replace('"', r'\"'))) self.writelines(lines)
def format(self, opt, group_name, minimal=False): """Format a description of an option to the output file. :param opt: a cfg.Opt instance """ if not opt.help: LOG.warning(_LW('"%s" is missing a help string'), opt.dest) opt_type = _format_type_name(opt.type) opt_prefix = '' if (opt.deprecated_for_removal and not opt.help.startswith('DEPRECATED')): opt_prefix = 'DEPRECATED: ' if opt.help: help_text = u'%s%s (%s)' % (opt_prefix, opt.help, opt_type) else: help_text = u'(%s)' % opt_type lines = self._format_help(help_text) if getattr(opt.type, 'min', None) is not None: lines.append('# Minimum value: %d\n' % opt.type.min) if getattr(opt.type, 'max', None) is not None: lines.append('# Maximum value: %d\n' % opt.type.max) if getattr(opt.type, 'choices', None): choices_text = ', '.join([self._get_choice_text(choice) for choice in opt.type.choices]) lines.append('# Allowed values: %s\n' % choices_text) try: if opt.mutable: lines.append( '# Note: This option can be changed without restarting.\n' ) except AttributeError as err: # NOTE(dhellmann): keystoneauth defines its own Opt class, # and neutron (at least) returns instances of those # classes instead of oslo_config Opt instances. The new # mutable attribute is the first property where the API # isn't supported in the external class, so we can use # this failure to emit a warning. See # https://bugs.launchpad.net/keystoneauth/+bug/1548433 for # more details. import warnings if not isinstance(opt, cfg.Opt): warnings.warn( 'Incompatible option class for %s (%r): %s' % (opt.dest, opt.__class__, err), ) else: warnings.warn('Failed to fully format sample for %s: %s' % (opt.dest, err)) for d in opt.deprecated_opts: lines.append('# Deprecated group/name - [%s]/%s\n' % (d.group or group_name, d.name or opt.dest)) if opt.deprecated_for_removal: if opt.deprecated_since: lines.append( '# This option is deprecated for removal since %s.\n' % ( opt.deprecated_since)) else: lines.append( '# This option is deprecated for removal.\n') lines.append( '# Its value may be silently ignored in the future.\n') if opt.deprecated_reason: lines.extend( self._format_help('Reason: ' + opt.deprecated_reason)) if hasattr(opt.type, 'format_defaults'): defaults = opt.type.format_defaults(opt.default, opt.sample_default) else: LOG.debug( "The type for option %(name)s which is %(type)s is not a " "subclass of types.ConfigType and doesn't provide a " "'format_defaults' method. A default formatter is not " "available so the best-effort formatter will be used.", {'type': opt.type, 'name': opt.name}) defaults = _format_defaults(opt) for default_str in defaults: if default_str: default_str = ' ' + default_str if minimal: lines.append('%s =%s\n' % (opt.dest, default_str)) else: lines.append('#%s =%s\n' % (opt.dest, default_str)) self.writelines(lines)