Skip to content

Commit 6e4ea18

Browse files
committed
Merge pull request puppetlabs#100 from kbrezina/master
Support for tablespaces
2 parents 9fd7f1a + 8a01e19 commit 6e4ea18

File tree

7 files changed

+238
-5
lines changed

7 files changed

+238
-5
lines changed

manifests/database.pp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121

2222
define postgresql::database(
2323
$dbname = $title,
24-
$charset = 'UTF8')
24+
$charset = 'UTF8',
25+
$tablespace = undef)
2526
{
2627
include postgresql::params
2728

@@ -33,7 +34,14 @@
3334
$public_revoke_privilege = "ALL"
3435
}
3536

36-
$createdb_command = "${postgresql::params::createdb_path} --template=template0 --encoding '${charset}' ${locale_option} '${dbname}'"
37+
$createdb_command_tmp = "${postgresql::params::createdb_path} --template=template0 --encoding '${charset}' ${locale_option} '${dbname}'"
38+
39+
if($tablespace == undef) {
40+
$createdb_command = $createdb_command_tmp
41+
}
42+
else {
43+
$createdb_command = "${createdb_command_tmp} --tablespace='${tablespace}'"
44+
}
3745

3846
postgresql_psql { "Check for existence of db '$dbname'":
3947
command => "SELECT 1",

manifests/db.pp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# function in this module
1717
# [*charset*] - database charset. defaults to 'utf8'
1818
# [*grant*] - privilege to grant user. defaults to 'all'.
19+
# [*tablespace*] - database tablespace. default to use the template database's tablespace.
1920
#
2021
# Actions:
2122
#
@@ -35,13 +36,15 @@
3536
$user,
3637
$password,
3738
$charset = 'utf8',
38-
$grant = 'ALL'
39-
) {
39+
$grant = 'ALL',
40+
$tablespace = undef)
41+
{
4042

4143
postgresql::database { $name:
4244
# TODO: ensure is not yet supported
4345
#ensure => present,
4446
charset => $charset,
47+
tablespace => $tablespace,
4548
#provider => 'postgresql',
4649
require => Class['postgresql::server'],
4750
}

manifests/tablespace.pp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Define: postgresql::tablespace
2+
#
3+
# This module creates tablespace
4+
#
5+
# Parameters:
6+
# [*title*] - the name of a tablespace to be created. The name cannot begin with pg_, as such names are reserved for system tablespaces.
7+
# [*owner*] - the name of the user who will own the tablespace. If omitted, defaults to the user executing the command.
8+
# Only superusers can create tablespaces, but they can assign ownership of tablespaces to non-superusers.
9+
# [*location*] - The directory that will be used for the tablespace. The directory should be empty and must be owned by the PostgreSQL
10+
# system user. The directory must be specified by an absolute path name.
11+
#
12+
# Actions:
13+
#
14+
# Requires:
15+
#
16+
# class postgresql::server
17+
#
18+
# Sample Usage:
19+
#
20+
# postgresql::tablespace { 'dbspace':
21+
# location => '/data/dbs',
22+
# }
23+
#
24+
#
25+
define postgresql::tablespace(
26+
$location,
27+
$owner = undef,
28+
$spcname = $title)
29+
{
30+
include postgresql::params
31+
32+
if ($owner == undef) {
33+
$owner_section = ''
34+
}
35+
else {
36+
$owner_section = "OWNER ${owner}"
37+
}
38+
39+
$create_tablespace_command = "CREATE TABLESPACE ${spcname} ${owner_section} LOCATION '${location}'"
40+
41+
file { "${location}":
42+
ensure => directory,
43+
owner => 'postgres',
44+
group => 'postgres',
45+
mode => 700,
46+
}
47+
48+
postgresql_psql { "Create tablespace '${spcname}'":
49+
command => $create_tablespace_command,
50+
unless => "SELECT spcname FROM pg_tablespace WHERE spcname='${spcname}'",
51+
cwd => $postgresql::params::datadir,
52+
require => [Class['postgresql::server'], File["${location}"]],
53+
}
54+
}

spec/support/postgres_test_utils.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,18 @@ def sudo_and_log(vm, cmd)
1212
def sudo_psql_and_log(vm, psql_cmd, user = 'postgres')
1313
sudo_and_log(vm, "su #{user} -c 'psql #{psql_cmd}'")
1414
end
15-
end
15+
16+
def sudo_psql_and_expect_result(vm, psql_cmd, expected, user = 'postgres')
17+
result = sudo_and_log(vm, "su #{user} -c 'psql -t #{psql_cmd}'")
18+
19+
result.sub!(/stdin: is not a tty/, '')
20+
result.strip!
21+
22+
ok = result == expected
23+
@logger.debug("Expected: #{expected} => #{ok ? 'OK' : 'BAD'}")
24+
25+
if !ok
26+
raise "An unexpected result returned - result: '#{result}' / expected: '#{expected}'"
27+
end
28+
end
29+
end

spec/support/shared_examples/system_default_postgres.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,20 @@ def install_postgres
134134
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_pp}'; [ $? == 4 ]")
135135
end
136136
end
137+
138+
describe 'postgresql::tablespace' do
139+
it 'should idempotently create tablespaces and databases that are using them' do
140+
test_class = 'class {"postgresql_tests::system_default::test_tablespace": }'
141+
142+
# Run once to check for crashes
143+
sudo_and_log(vm, "puppet apply -e '#{test_class}'")
144+
145+
# Run again to check for idempotence
146+
sudo_and_log(vm, "puppet apply --detailed-exitcodes -e '#{test_class}'")
147+
148+
# Check that databases use correct tablespaces
149+
sudo_psql_and_expect_result(vm, '--command="select ts.spcname from pg_database db, pg_tablespace ts where db.dattablespace = ts.oid and db.datname = \'"\'tablespacedb1\'"\'"', 'tablespace1')
150+
sudo_psql_and_expect_result(vm, '--command="select ts.spcname from pg_database db, pg_tablespace ts where db.dattablespace = ts.oid and db.datname = \'"\'tablespacedb3\'"\'"', 'tablespace2')
151+
end
152+
end
137153
end
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# puppet-postgresql
2+
# For all details and documentation:
3+
# http://github.com/inkling/puppet-postgresql
4+
#
5+
# Copyright 2012- Inkling Systems, Inc.
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
class postgresql_tests::system_default::test_tablespace {
20+
21+
include postgresql::server
22+
23+
file { '/tmp':
24+
ensure => 'directory',
25+
}
26+
file { '/tmp/pg_tablespaces':
27+
ensure => 'directory',
28+
owner => 'postgres',
29+
group => 'postgres',
30+
mode => 700,
31+
require => File['/tmp'],
32+
}
33+
34+
postgresql::tablespace{ 'tablespace1':
35+
location => '/tmp/pg_tablespaces/space1',
36+
require => [Class['postgresql::server'], File['/tmp/pg_tablespaces']],
37+
}
38+
postgresql::database{ 'tablespacedb1':
39+
charset => 'utf8',
40+
tablespace => 'tablespace1',
41+
require => Postgresql::Tablespace['tablespace1'],
42+
}
43+
postgresql::db{ 'tablespacedb2':
44+
user => 'dbuser2',
45+
password => 'dbuser2',
46+
tablespace => 'tablespace1',
47+
require => Postgresql::Tablespace['tablespace1'],
48+
}
49+
50+
postgresql::database_user{ 'spcuser':
51+
password_hash => postgresql_password('spcuser', 'spcuser'),
52+
require => Class['postgresql::server'],
53+
}
54+
postgresql::tablespace{ 'tablespace2':
55+
location => '/tmp/pg_tablespaces/space2',
56+
owner => 'spcuser',
57+
require => [Postgresql::Database_user['spcuser'], File['/tmp/pg_tablespaces']],
58+
}
59+
postgresql::database{ 'tablespacedb3':
60+
charset => 'utf8',
61+
tablespace => 'tablespace2',
62+
require => Postgresql::Tablespace['tablespace2'],
63+
}
64+
65+
}

tests/postgresql_tablespace.pp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
class { 'postgresql::server':
2+
config_hash => {
3+
'ip_mask_deny_postgres_user' => '0.0.0.0/32',
4+
'ip_mask_allow_all_users' => '0.0.0.0/0',
5+
'listen_addresses' => '*',
6+
'manage_redhat_firewall' => true,
7+
'postgres_password' => 'postgres',
8+
},
9+
}
10+
11+
file { '/tmp':
12+
ensure => 'directory',
13+
}
14+
file { '/tmp/pg_tablespaces':
15+
ensure => 'directory',
16+
owner => 'postgres',
17+
group => 'postgres',
18+
mode => 700,
19+
require => File['/tmp'],
20+
}
21+
22+
postgresql::tablespace{ 'tablespace1':
23+
location => '/tmp/pg_tablespaces/space1',
24+
require => [Class['postgresql::server'], File['/tmp/pg_tablespaces']],
25+
}
26+
postgresql::database{ 'tablespacedb1':
27+
# TODO: ensure not yet supported
28+
#ensure => present,
29+
charset => 'utf8',
30+
require => Class['postgresql::server'],
31+
}
32+
postgresql::database{ 'tablespacedb2':
33+
# TODO: ensure not yet supported
34+
#ensure => present,
35+
charset => 'utf8',
36+
tablespace => 'tablespace1',
37+
require => Postgresql::Tablespace['tablespace1'],
38+
}
39+
postgresql::db{ 'tablespacedb3':
40+
# TODO: ensure not yet supported
41+
#ensure => present,
42+
user => 'dbuser1',
43+
password => 'dbuser1',
44+
require => Class['postgresql::server'],
45+
}
46+
postgresql::db{ 'tablespacedb4':
47+
# TODO: ensure not yet supported
48+
#ensure => present,
49+
user => 'dbuser2',
50+
password => 'dbuser2',
51+
tablespace => 'tablespace1',
52+
require => Postgresql::Tablespace['tablespace1'],
53+
}
54+
55+
postgresql::database_user{ 'spcuser':
56+
# TODO: ensure is not yet supported
57+
#ensure => present,
58+
password_hash => postgresql_password('spcuser', 'spcuser'),
59+
require => Class['postgresql::server'],
60+
}
61+
postgresql::tablespace{ 'tablespace2':
62+
location => '/tmp/pg_tablespaces/space2',
63+
owner => 'spcuser',
64+
require => [Postgresql::Database_user['spcuser'], File['/tmp/pg_tablespaces']],
65+
}
66+
postgresql::database{ 'tablespacedb5':
67+
# TODO: ensure not yet supported
68+
#ensure => present,
69+
charset => 'utf8',
70+
tablespace => 'tablespace2',
71+
require => Postgresql::Tablespace['tablespace2'],
72+
}
73+

0 commit comments

Comments
 (0)