コード例 #1
0
ファイル: service.py プロジェクト: stub42/postgresql-charm
def validate_postgresql_conf(conf):
    '''Block the unit and exit the hook if there is invalid configuration.

    We do strict validation to pick up errors in the users pg_extra_conf
    setting. If we put invalid config in postgresql.conf, then config
    reloads will not take effect and restarts will fail.

    I expect this isn't bulletproof and the operator can still shoot
    themselves in the foot with string settings that PostgreSQL cannot
    parse (eg. listen_address="** invalid **").

    It seems preferable to make bad configuration highly visible and
    block, rather than repair the situation with potentially dangerous
    settings and hope the operator notices the log messages.
    '''
    schema = postgresql.pg_settings_schema()
    for k, v in list(conf.items()):
        v = str(v)
        try:
            if k not in schema:
                raise ValueError('Unknown option {}'.format(k))

            r = schema[k]

            if r.vartype == 'bool':
                if v.lower() not in postgresql.VALID_BOOLS:
                    raise ValueError('Invalid boolean {!r}'.format(v, None))

            elif r.vartype == 'enum':
                v = v.lower()
                if v not in r.enumvals:
                    raise ValueError('Must be one of {}. Got {}'
                                     ''.format(','.join(r.enumvals), v))

            elif r.vartype == 'integer':
                if r.unit:
                    try:
                        v = postgresql.convert_unit(v, r.unit)
                    except ValueError:
                        raise ValueError('Invalid integer w/unit {!r}'
                                         ''.format(v))
                else:
                    try:
                        v = int(v)
                    except ValueError:
                        raise ValueError('Invalid integer {!r}'.format(v))

            elif r.vartype == 'real':
                try:
                    v = float(v)
                except ValueError:
                    raise ValueError('Invalid real {!r}'.format(v))

            if r.min_val and v < float(r.min_val):
                raise ValueError('{} below minimum {}'.format(v, r.min_val))
            elif r.max_val and v > float(r.max_val):
                raise ValueError('{} above maximum {}'.format(v, r.maxvalue))

        except ValueError as x:
            raise InvalidPgConfSetting(k, x)
コード例 #2
0
ファイル: service.py プロジェクト: stub42/postgresql-charm
def validate_postgresql_conf(conf):
    """Block the unit and exit the hook if there is invalid configuration.

    We do strict validation to pick up errors in the users pg_extra_conf
    setting. If we put invalid config in postgresql.conf, then config
    reloads will not take effect and restarts will fail.

    I expect this isn't bulletproof and the operator can still shoot
    themselves in the foot with string settings that PostgreSQL cannot
    parse (eg. listen_address="** invalid **").

    It seems preferable to make bad configuration highly visible and
    block, rather than repair the situation with potentially dangerous
    settings and hope the operator notices the log messages.
    """
    schema = postgresql.pg_settings_schema()
    for k, v in list(conf.items()):
        v = str(v)
        try:
            if k not in schema:
                raise ValueError("Unknown option {}".format(k))

            r = schema[k]

            if r.vartype == "bool":
                if v.lower() not in postgresql.VALID_BOOLS:
                    raise ValueError("Invalid boolean {!r}".format(v))

            elif r.vartype == "enum":
                v = v.lower()
                if v not in r.enumvals:
                    raise ValueError("Must be one of {}. Got {}".format(",".join(r.enumvals), v))

            elif r.vartype == "integer":
                if r.unit:
                    try:
                        v = postgresql.convert_unit(v, r.unit)
                    except ValueError:
                        raise ValueError("Invalid integer w/unit {!r}".format(v))
                else:
                    try:
                        v = int(v)
                    except ValueError:
                        raise ValueError("Invalid integer {!r}".format(v))

            elif r.vartype == "real":
                try:
                    v = float(v)
                except ValueError:
                    raise ValueError("Invalid real {!r}".format(v))

            if r.min_val and v < float(r.min_val):
                raise ValueError("{} below minimum {}".format(v, r.min_val))
            elif r.max_val and v > float(r.max_val):
                raise ValueError("{} above maximum {}".format(v, r.maxvalue))

        except ValueError as x:
            raise InvalidPgConfSetting(k, x)
コード例 #3
0
ファイル: service.py プロジェクト: stub42/postgresql-charm
def postgresql_conf_deprecated_overrides():
    '''Overrides from deprecated service configuration options.

    There are far too many knobs in postgresql.conf for the charm
    to duplicate each one in config.yaml, and they can change between
    versions. The old options that did this have all been deprecated,
    and users can specify them in the extra_pg_conf option.

    One day this method and the deprecated options will go away.
    '''
    config = hookenv.config()

    # These deprecated options mapped directly to postgresql.conf settings.
    # As you can see, it was unmaintainably long.
    simple_options = frozenset(['max_connections', 'max_prepared_transactions',
                                'ssl', 'log_min_duration_statement',
                                'log_checkpoints', 'log_connections',
                                'log_disconnections', 'log_temp_files',
                                'log_line_prefix', 'log_lock_waits',
                                'log_timezone', 'log_autovacuum_min_duration',
                                'autovacuum', 'autovacuum_analyze_threshold',
                                'autovacuum_vacuum_scale_factor',
                                'autovacuum_analyze_scale_factor',
                                'autovacuum_vacuum_cost_delay', 'search_path',
                                'standard_conforming_strings', 'hot_standby',
                                'hot_standby_feedback', 'wal_level',
                                'max_wal_senders', 'wal_keep_segments',
                                'archive_mode', 'archive_command',
                                'work_mem', 'maintenance_work_mem',
                                'shared_buffers', 'effective_cache_size',
                                'default_statistics_target', 'temp_buffers',
                                'wal_buffers', 'checkpoint_segments',
                                'checkpoint_completion_target',
                                'checkpoint_timeout', 'fsync',
                                'synchronous_commit', 'full_page_writes',
                                'random_page_cost'])

    in_use = helpers.deprecated_config_in_use()

    # Some deprecated options no longer exist in more recent PostgreSQL rels.
    valid_options = set(postgresql.pg_settings_schema().keys())

    # The simple deprecated options map directly to postgresql.conf settings.
    # Strip the deprecated options that no longer exist at all here.
    settings = {k: config[k] for k in in_use
                if k in simple_options and k in valid_options}

    # The listen_port and collapse_limit options were special.
    config_yaml_options = helpers.config_yaml()['options']
    defaults = {k: config_yaml_options[k]['default']
                for k in config_yaml_options}
    if config['listen_port'] not in (-1, defaults['listen_port']):
        settings['port'] = config['listen_port']
    if config['collapse_limit'] != defaults['collapse_limit']:
        settings['from_collapse_limit'] = config['collapse_limit']
        settings['join_collapse_limit'] = config['collapse_limit']

    return settings
コード例 #4
0
ファイル: service.py プロジェクト: stub42/postgresql-charm
def postgresql_conf_deprecated_overrides():
    """Overrides from deprecated service configuration options.

    There are far too many knobs in postgresql.conf for the charm
    to duplicate each one in config.yaml, and they can change between
    versions. The old options that did this have all been deprecated,
    and users can specify them in the extra_pg_conf option.

    One day this method and the deprecated options will go away.
    """
    config = hookenv.config()

    # These deprecated options mapped directly to postgresql.conf settings.
    # As you can see, it was unmaintainably long.
    simple_options = frozenset(
        [
            "max_connections",
            "max_prepared_transactions",
            "ssl",
            "log_min_duration_statement",
            "log_checkpoints",
            "log_connections",
            "log_disconnections",
            "log_temp_files",
            "log_line_prefix",
            "log_lock_waits",
            "log_timezone",
            "log_autovacuum_min_duration",
            "autovacuum",
            "autovacuum_analyze_threshold",
            "autovacuum_vacuum_scale_factor",
            "autovacuum_analyze_scale_factor",
            "autovacuum_vacuum_cost_delay",
            "search_path",
            "standard_conforming_strings",
            "hot_standby",
            "hot_standby_feedback",
            "wal_level",
            "max_wal_senders",
            "wal_keep_segments",
            "archive_mode",
            "archive_command",
            "work_mem",
            "maintenance_work_mem",
            "shared_buffers",
            "effective_cache_size",
            "default_statistics_target",
            "temp_buffers",
            "wal_buffers",
            "checkpoint_segments",
            "checkpoint_completion_target",
            "checkpoint_timeout",
            "fsync",
            "synchronous_commit",
            "full_page_writes",
            "random_page_cost",
        ]
    )

    in_use = helpers.deprecated_config_in_use()

    # Some deprecated options no longer exist in more recent PostgreSQL rels.
    valid_options = set(postgresql.pg_settings_schema().keys())

    # The simple deprecated options map directly to postgresql.conf settings.
    # Strip the deprecated options that no longer exist at all here.
    settings = {k: config[k] for k in in_use if k in simple_options and k in valid_options}

    # The listen_port and collapse_limit options were special.
    config_yaml_options = helpers.config_yaml()["options"]
    defaults = {k: config_yaml_options[k]["default"] for k in config_yaml_options}
    if config["listen_port"] not in (-1, defaults["listen_port"]):
        settings["port"] = config["listen_port"]
    if config["collapse_limit"] != defaults["collapse_limit"]:
        settings["from_collapse_limit"] = config["collapse_limit"]
        settings["join_collapse_limit"] = config["collapse_limit"]

    return settings