def postgresql_conf_defaults(): """Return the postgresql.conf defaults, which we parse from config.yaml""" # We load defaults from the extra_pg_conf default in config.yaml, # which ensures that they never get out of sync. raw = helpers.config_yaml()["options"]["extra_pg_conf"]["default"] defaults = postgresql.parse_config(raw) # And recalculate some defaults, which could get out of sync. # Settings with mandatory minimums like wal_senders are handled # later, in ensure_viable_postgresql_conf(). ram = int(host.get_total_ram() / (1024 * 1024)) # Working in megabytes. # Default shared_buffers to 25% of ram, minimum 16MB, maximum 8GB, # per current best practice rules of thumb. Rest is cache. shared_buffers = max(min(math.ceil(ram * 0.25), 8192), 16) effective_cache_size = max(1, ram - shared_buffers) defaults["shared_buffers"] = "{} MB".format(shared_buffers) defaults["effective_cache_size"] = "{} MB".format(effective_cache_size) # PostgreSQL 10 introduces multiple password encryption methods. if postgresql.has_version("10"): # Change this to scram-sha-256 next LTS release, when we can # start assuming clients have libpq 10. The setting can of # course still be overridden in the config. defaults["password_encryption"] = "md5" else: defaults["password_encryption"] = True return defaults
def postgresql_conf_defaults(): '''Return the postgresql.conf defaults, which we parse from config.yaml''' # We load defaults from the extra_pg_conf default in config.yaml, # which ensures that they never get out of sync. raw = helpers.config_yaml()['options']['extra_pg_conf']['default'] defaults = postgresql.parse_config(raw) # And recalculate some defaults, which could get out of sync. # Settings with mandatory minimums like wal_senders are handled # later, in ensure_viable_postgresql_conf(). ram = int(host.get_total_ram() / (1024 * 1024)) # Working in megabytes. # Default shared_buffers to 25% of ram, minimum 16MB, maximum 8GB, # per current best practice rules of thumb. Rest is cache. shared_buffers = max(min(math.ceil(ram * 0.25), 8192), 16) effective_cache_size = max(1, ram - shared_buffers) defaults['shared_buffers'] = '{} MB'.format(shared_buffers) defaults['effective_cache_size'] = '{} MB'.format(effective_cache_size) return defaults
def postgresql_conf_overrides(): """User postgresql.conf overrides, from service configuration.""" config = hookenv.config() return postgresql.parse_config(config["extra_pg_conf"])
def test_parse_config(self): valid = [ (r"# A comment", dict()), (r"key_1 = value", dict(key_1="value")), (r"key_2 ='quoted valu3'", dict(key_2="quoted valu3")), (r"""key_3= 'foo "bar"'""", dict(key_3='foo "bar"')), (r"""key_4='''bar\''""", dict(key_4="'bar'")), (r"key_5=''", dict(key_5="")), (r"", dict()), (r" # Another comment ", dict()), (r"key_6='#'", dict(key_6="#")), (r"key_7=42", dict(key_7="42")), (r"key_8=3.142", dict(key_8="3.142")), (r"key_9=-1", dict(key_9="-1")), ] # The above examples all parse correctly. for raw, expected in valid: with self.subTest(raw=raw): self.assertDictEqual(postgresql.parse_config(raw), expected) # Concatenating them parses correctly to. combined_raw = [] combined_expected = {} for raw, expected in valid: combined_raw.append(raw) combined_expected.update(expected) self.assertDictEqual(postgresql.parse_config("\n".join(combined_raw)), combined_expected) with self.assertRaises(SyntaxError) as x: postgresql.parse_config("=") self.assertEqual(str(x.exception), "Missing key (line 1)") self.assertEqual(x.exception.lineno, 1) self.assertEqual(x.exception.text, "=") # We could be lazy here, since we are dealing with trusted input, # but meaningful error messages are helpful. with self.assertRaises(SyntaxError) as x: postgresql.parse_config("# comment\nkey=") self.assertEqual(str(x.exception), "Missing value (line 2)") with self.assertRaises(SyntaxError) as x: postgresql.parse_config("key='unterminated") self.assertEqual(str(x.exception), "Badly quoted value (line 1)") with self.assertRaises(SyntaxError) as x: postgresql.parse_config("key='unterminated 2 # comment") self.assertEqual(str(x.exception), "Badly quoted value (line 1)") with self.assertRaises(SyntaxError) as x: postgresql.parse_config("key='unte''''") self.assertEqual(str(x.exception), "Badly quoted value (line 1)") with self.assertRaises(SyntaxError) as x: postgresql.parse_config(r"key='\'") self.assertEqual(str(x.exception), "Badly quoted value (line 1)")
def test_parse_config(self): valid = [(r'# A comment', dict()), (r'key_1 = value', dict(key_1='value')), (r"key_2 ='quoted valu3'", dict(key_2='quoted valu3')), (r"""key_3= 'foo "bar"'""", dict(key_3='foo "bar"')), (r"""key_4='''bar\''""", dict(key_4="'bar'")), (r"key_5=''", dict(key_5='')), (r"", dict()), (r' # Another comment ', dict()), (r"key_6='#'", dict(key_6='#')), (r"key_7=42", dict(key_7='42')), (r"key_8=3.142", dict(key_8='3.142')), (r'key_9=-1', dict(key_9='-1'))] # The above examples all parse correctly. for raw, expected in valid: with self.subTest(raw=raw): self.assertDictEqual(postgresql.parse_config(raw), expected) # Concatenating them parses correctly to. combined_raw = [] combined_expected = {} for raw, expected in valid: combined_raw.append(raw) combined_expected.update(expected) self.assertDictEqual(postgresql.parse_config('\n'.join(combined_raw)), combined_expected) with self.assertRaises(SyntaxError) as x: postgresql.parse_config("=") self.assertEqual(str(x.exception), "Missing key '=' (line 1)") self.assertEqual(x.exception.lineno, 1) self.assertEqual(x.exception.text, "=") # We could be lazy here, since we are dealing with trusted input, # but meaningful error messages are helpful. with self.assertRaises(SyntaxError) as x: postgresql.parse_config('# comment\nkey=') self.assertEqual(str(x.exception), 'Missing value (line 2)') with self.assertRaises(SyntaxError) as x: postgresql.parse_config("key='unterminated") self.assertEqual(str(x.exception), r'''Badly quoted value "'unterminated" (line 1)''') with self.assertRaises(SyntaxError) as x: postgresql.parse_config("key='unterminated 2 # comment") self.assertEqual(str(x.exception), r'''Badly quoted value "'unterminated 2" (line 1)''') with self.assertRaises(SyntaxError) as x: postgresql.parse_config("key='unte''''") self.assertEqual(str(x.exception), r"""Badly quoted value "'unte''''" (line 1)""") with self.assertRaises(SyntaxError) as x: postgresql.parse_config(r"key='\'") self.assertEqual(str(x.exception), r'''Badly quoted value "'\\'" (line 1)''')
def postgresql_conf_overrides(): '''User postgresql.conf overrides, from service configuration.''' config = hookenv.config() return postgresql.parse_config(config['extra_pg_conf'])