postgresinator 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/postgresinator/built-in.rb +198 -0
- data/lib/postgresinator/check.rb +130 -0
- data/lib/postgresinator/config.rb +69 -118
- data/lib/postgresinator/db.rb +126 -0
- data/lib/postgresinator/examples/Capfile +1 -1
- data/lib/postgresinator/examples/Dockerfile +7 -6
- data/lib/postgresinator/examples/config/deploy/staging.rb +29 -50
- data/lib/postgresinator/examples/config/deploy.rb +8 -58
- data/lib/postgresinator/examples/pg_hba.conf.erb +5 -7
- data/lib/postgresinator/examples/postgresql.conf.erb +6 -6
- data/lib/postgresinator/examples/recovery.conf.erb +2 -2
- data/lib/postgresinator/pg.rb +117 -486
- data/lib/postgresinator.rb +4 -1
- metadata +25 -24
- data/lib/postgresinator/examples/config/deploy/staging_postgresinator.rb +0 -43
- data/lib/postgresinator/examples/config/deploy_postgresinator.rb +0 -1
@@ -0,0 +1,126 @@
|
|
1
|
+
namespace :pg do
|
2
|
+
namespace :db do
|
3
|
+
|
4
|
+
#desc "Idempotently setup one or more databases."
|
5
|
+
task :setup => ['pg:ensure_setup'] do
|
6
|
+
on roles(:db) do |host|
|
7
|
+
fetch(:postgres_databases).each do |database|
|
8
|
+
Rake::Task['pg:check:settings:database'].invoke(database[:name])
|
9
|
+
Rake::Task['pg:check:settings:database'].reenable
|
10
|
+
unless pg_role_exists?(database[:db_role])
|
11
|
+
info "Creating role #{database[:db_role]} on #{host}"
|
12
|
+
pg_create_role(database[:db_role], database[:pass])
|
13
|
+
end
|
14
|
+
unless pg_database_exists?(database[:name])
|
15
|
+
info "Creating database #{database[:name]} on #{host}"
|
16
|
+
pg_create_database(database)
|
17
|
+
pg_grant_database(database)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Restore 'dump_file' in /tmp on the master server into 'database_name'."
|
24
|
+
task :restore, [:dump_file, :database_name] => ['pg:ensure_setup'] do |t, args|
|
25
|
+
on roles(:db) do |host|
|
26
|
+
if pg_database_empty?(args.database_name)
|
27
|
+
clean = ""
|
28
|
+
else
|
29
|
+
pg_confirm_database_overwrite?(args.database_name) ? clean = "--clean" : exit(0)
|
30
|
+
end
|
31
|
+
pg_restore(host, args, clean)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "Dump 'database_name' into /tmp/'dump_file' on the master server."
|
36
|
+
task :dump, [:dump_file, :database_name] => ['pg:ensure_setup'] do |t, args|
|
37
|
+
on roles(:db) do |host|
|
38
|
+
if file_exists?("/tmp/#{args.dump_file}")
|
39
|
+
exit unless(pg_confirm_file_overwrite?(args.dump_file))
|
40
|
+
end
|
41
|
+
pg_dump(host, args)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "Enter psql interactive mode on the master."
|
46
|
+
task :interactive => 'pg:ensure_setup' do
|
47
|
+
on roles(:db) do |host|
|
48
|
+
info "Entering psql interactive mode inside #{host.properties.postgres_container_name} on #{host}"
|
49
|
+
system pg_interactive(host)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
namespace :interactive do
|
54
|
+
desc "Print the command to enter psql interactive mode on the master."
|
55
|
+
task :print => 'pg:ensure_setup' do
|
56
|
+
on roles(:db) do |host|
|
57
|
+
info ["You can paste the following command into a terminal on #{host}",
|
58
|
+
"to enter psql interactive mode for",
|
59
|
+
"#{host.properties.postgres_container_name}:"].join(' ')
|
60
|
+
info pg_interactive_print(host)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "List the databases from the master."
|
66
|
+
task :list => ['pg:ensure_setup'] do |t, args|
|
67
|
+
on roles(:db) do
|
68
|
+
pg_list_databases(host)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
namespace :list do
|
73
|
+
desc "List the roles from the master."
|
74
|
+
task :roles => ['pg:ensure_setup'] do |t, args|
|
75
|
+
on roles(:db) do
|
76
|
+
pg_list_roles(host)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
desc "Show the streaming replication status of each instance."
|
82
|
+
task :streaming => ['pg:ensure_setup'] do
|
83
|
+
on roles(:db) do |host|
|
84
|
+
info ""
|
85
|
+
info "Streaming status of #{host.properties.postgres_container_name} on #{host}:"
|
86
|
+
pg_streaming_master(host)
|
87
|
+
end
|
88
|
+
on roles(:db_slave, :in => :parallel) do
|
89
|
+
info ""
|
90
|
+
info "Streaming status of #{host.properties.postgres_container_name} on #{host}:"
|
91
|
+
pg_streaming_slave(host)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
def pg_confirm_file_overwrite?(dump_file)
|
97
|
+
warn "A file named #{dump_file} already exists on #{host} in /tmp. If you continue, you will overwrite it."
|
98
|
+
ask :yes_or_no, "Are you positive?"
|
99
|
+
case fetch(:yes_or_no).chomp.downcase
|
100
|
+
when "yes"
|
101
|
+
true
|
102
|
+
when "no"
|
103
|
+
false
|
104
|
+
else
|
105
|
+
warn "Please enter 'yes' or 'no'"
|
106
|
+
pg_confirm_file_overwrite?(dump_file)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def pg_confirm_database_overwrite?(database_name)
|
111
|
+
warn "There is already data in the database '#{database_name}' on #{host} in the container " +
|
112
|
+
"'#{host.properties.postgres_container_name}' which stores it's data in #{fetch(:postgres_data_path)} on the host."
|
113
|
+
warn "If you continue, you must be positive you want to overwrite the existing data."
|
114
|
+
ask :yes_or_no, "Are you positive?"
|
115
|
+
case fetch(:yes_or_no).chomp.downcase
|
116
|
+
when "yes"
|
117
|
+
true
|
118
|
+
when "no"
|
119
|
+
false
|
120
|
+
else
|
121
|
+
warn "Please enter 'yes' or 'no'"
|
122
|
+
pg_confirm_database_overwrite?(database_name)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -2,10 +2,11 @@
|
|
2
2
|
FROM ubuntu:12.04
|
3
3
|
MAINTAINER david amick <docker@davidamick.com>
|
4
4
|
|
5
|
-
RUN /bin/bash -
|
6
|
-
RUN /bin/bash -
|
5
|
+
RUN ["/bin/bash", "-c", "apt-get update -qq && apt-get install -qy postgresql-9.1 libpq-dev postgresql-contrib nodejs rsync"]
|
6
|
+
RUN ["/bin/bash", "-c", "/etc/init.d/postgresql start && /etc/init.d/postgresql stop"]
|
7
|
+
RUN ["/bin/bash", "-c", "usermod -a -G www-data postgres"]
|
8
|
+
RUN ["/bin/bash", "-c", "rm /etc/ssl/certs/ssl-cert-snakeoil.pem"]
|
9
|
+
RUN ["/bin/bash", "-c", "rm /etc/ssl/private/ssl-cert-snakeoil.key"]
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
ENTRYPOINT ["/usr/lib/postgresql/9.1/bin/postgres"]
|
11
|
-
CMD ["-D", "/var/lib/postgresql/9.1/main", "-c", "config_file=/etc/postgresql/9.1/main/postgresql.conf"]
|
11
|
+
ENTRYPOINT ["/bin/bash"]
|
12
|
+
CMD ["-l"]
|
@@ -1,50 +1,29 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
# --------------
|
31
|
-
# set :ssh_options, {
|
32
|
-
# keys: %w(/home/rlisowski/.ssh/id_rsa),
|
33
|
-
# forward_agent: false,
|
34
|
-
# auth_methods: %w(password)
|
35
|
-
# }
|
36
|
-
#
|
37
|
-
# And/or per server (overrides global)
|
38
|
-
# ------------------------------------
|
39
|
-
# server 'example.com',
|
40
|
-
# user: 'user_name',
|
41
|
-
# roles: %w{web app},
|
42
|
-
# ssh_options: {
|
43
|
-
# user: 'user_name', # overrides user setting above
|
44
|
-
# keys: %w(/home/user_name/.ssh/id_rsa),
|
45
|
-
# forward_agent: false,
|
46
|
-
# auth_methods: %w(publickey password)
|
47
|
-
# # password: 'please use keys'
|
48
|
-
# }
|
49
|
-
|
50
|
-
require './config/deploy/staging_postgresinator.rb'
|
1
|
+
##### postgresinator
|
2
|
+
### ------------------------------------------------------------------
|
3
|
+
set :domain, "my-app.example.com"
|
4
|
+
server fetch(:domain),
|
5
|
+
:user => fetch(:deployment_username),
|
6
|
+
:roles => ["app", "web", "db"],
|
7
|
+
:postgres_port => "5432"
|
8
|
+
server 'my-app-db-slave.example.com',
|
9
|
+
:user => fetch(:deployment_username),
|
10
|
+
:roles => ["db_slave"],
|
11
|
+
:no_release => true,
|
12
|
+
:postgres_port => "5433"
|
13
|
+
server 'my-app-db-slave2.example.com',
|
14
|
+
:user => fetch(:deployment_username),
|
15
|
+
:roles => ["db_slave"],
|
16
|
+
:no_release => true,
|
17
|
+
:postgres_port => "5433"
|
18
|
+
# only for override, let postgresinator setup postgres_container_name
|
19
|
+
#:postgres_container_name => "my_custom_name"
|
20
|
+
set :postgres_image_name, "snarlysodboxer/postgresql:0.0.1"
|
21
|
+
set :postgres_replicator_pass, "yourpassword"
|
22
|
+
set :postgres_databases, [
|
23
|
+
{
|
24
|
+
:name => "name",
|
25
|
+
:db_role => "role",
|
26
|
+
:pass => "pass"
|
27
|
+
}
|
28
|
+
]
|
29
|
+
### ------------------------------------------------------------------
|
@@ -1,60 +1,10 @@
|
|
1
|
-
# config valid only for Capistrano 3.1
|
1
|
+
# config valid only for Capistrano 3.2.1
|
2
2
|
lock '3.2.1'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
# set :deploy_to, '/var/www/my_app'
|
12
|
-
|
13
|
-
# Default value for :scm is :git
|
14
|
-
# set :scm, :git
|
15
|
-
|
16
|
-
# Default value for :format is :pretty
|
17
|
-
# set :format, :pretty
|
18
|
-
|
19
|
-
# Default value for :log_level is :debug
|
20
|
-
# set :log_level, :debug
|
21
|
-
|
22
|
-
# Default value for :pty is false
|
23
|
-
# set :pty, true
|
24
|
-
|
25
|
-
# Default value for :linked_files is []
|
26
|
-
# set :linked_files, %w{config/database.yml}
|
27
|
-
|
28
|
-
# Default value for linked_dirs is []
|
29
|
-
# set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
|
30
|
-
|
31
|
-
# Default value for default_env is {}
|
32
|
-
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
|
33
|
-
|
34
|
-
# Default value for keep_releases is 5
|
35
|
-
# set :keep_releases, 5
|
36
|
-
|
37
|
-
namespace :deploy do
|
38
|
-
|
39
|
-
desc 'Restart application'
|
40
|
-
task :restart do
|
41
|
-
on roles(:app), in: :sequence, wait: 5 do
|
42
|
-
# Your restart mechanism here, for example:
|
43
|
-
# execute :touch, release_path.join('tmp/restart.txt')
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
after :publishing, :restart
|
48
|
-
|
49
|
-
after :restart, :clear_cache do
|
50
|
-
on roles(:web), in: :groups, limit: 3, wait: 10 do
|
51
|
-
# Here we can do anything such as:
|
52
|
-
# within release_path do
|
53
|
-
# execute :rake, 'cache:clear'
|
54
|
-
# end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
require './config/deploy_postgresinator.rb'
|
4
|
+
##### postgresinator
|
5
|
+
### ------------------------------------------------------------------
|
6
|
+
set :application, "my_app_name"
|
7
|
+
set :preexisting_ssh_user, ENV['USER']
|
8
|
+
set :deployment_username, "deployer"
|
9
|
+
set :webserver_username, "www-data" # needed for intergration w/ deployinator
|
10
|
+
### ------------------------------------------------------------------
|
@@ -71,21 +71,19 @@
|
|
71
71
|
# (autovacuum, daily cronjob, replication, and similar tasks).
|
72
72
|
#
|
73
73
|
# Database administrative login by UNIX sockets
|
74
|
-
local all postgres
|
74
|
+
local all postgres trust
|
75
75
|
|
76
76
|
# TYPE DATABASE USER CIDR-ADDRESS METHOD
|
77
|
-
<% if
|
78
|
-
<%
|
79
|
-
|
80
|
-
hostssl replication replicator <%= server.ip %>/32 trust
|
81
|
-
<% end %>
|
77
|
+
<% if host.has_role?(:db) %>
|
78
|
+
<% roles(:db_slave).each do |host| %>
|
79
|
+
hostssl replication replicator <%= host.properties.ip %>/32 trust
|
82
80
|
<% end %>
|
83
81
|
<% end %>
|
84
82
|
host all postgres 172.16.0.0/12 trust # allow docker IPs for localhost access on the host
|
85
83
|
host all all 172.16.0.0/12 md5
|
86
84
|
|
87
85
|
# "local" is for Unix domain socket connections only
|
88
|
-
local all all ident
|
86
|
+
#local all all ident
|
89
87
|
# IPv4 local connections:
|
90
88
|
host all all 127.0.0.1/32 md5
|
91
89
|
# IPv6 local connections:
|
@@ -34,15 +34,15 @@
|
|
34
34
|
# The default values of these variables are driven from the -D command-line
|
35
35
|
# option or PGDATA environment variable, represented here as ConfigDir.
|
36
36
|
|
37
|
-
data_directory = '<%=
|
37
|
+
data_directory = '<%= fetch(:postgres_data_path) %>' # use data in another directory
|
38
38
|
# (change requires restart)
|
39
|
-
hba_file = '<%=
|
39
|
+
hba_file = '<%= fetch(:postgres_config_path) %>/pg_hba.conf' # host-based authentication file
|
40
40
|
# (change requires restart)
|
41
|
-
ident_file = '<%=
|
41
|
+
ident_file = '<%= fetch(:postgres_config_path) %>/pg_ident.conf' # ident configuration file
|
42
42
|
# (change requires restart)
|
43
43
|
|
44
44
|
# If external_pid_file is not explicitly set, no extra PID file is written.
|
45
|
-
external_pid_file = '
|
45
|
+
external_pid_file = '<%= fetch(:postgres_socket_path) %>/postgresql-9.1-main.pid' # write an extra PID file
|
46
46
|
# (change requires restart)
|
47
47
|
|
48
48
|
#------------------------------------------------------------------------------
|
@@ -59,7 +59,7 @@ wal_level = hot_standby
|
|
59
59
|
max_wal_senders = 3
|
60
60
|
checkpoint_segments = 8
|
61
61
|
wal_keep_segments = 8
|
62
|
-
<%
|
62
|
+
<% if host.has_role?(:db_slave) %>
|
63
63
|
hot_standby = on
|
64
64
|
<% end %>
|
65
65
|
port = 5432 # (change requires restart)
|
@@ -68,7 +68,7 @@ max_connections = 100 # (change requires restart)
|
|
68
68
|
# connection slot, plus lock space (see max_locks_per_transaction). You might
|
69
69
|
# also need to raise shared_buffers to support more connections.
|
70
70
|
#superuser_reserved_connections = 3 # (change requires restart)
|
71
|
-
unix_socket_directory = '
|
71
|
+
unix_socket_directory = '<%= fetch(:postgres_socket_path) %>' # (change requires restart)
|
72
72
|
#unix_socket_group = '' # (change requires restart)
|
73
73
|
#unix_socket_permissions = 0777 # begin with 0 to use octal notation
|
74
74
|
# (change requires restart)
|
@@ -1,3 +1,3 @@
|
|
1
1
|
standby_mode = 'on'
|
2
|
-
primary_conninfo = 'host=<%=
|
3
|
-
trigger_file = '<%=
|
2
|
+
primary_conninfo = 'host=<%= roles(:db).first.properties.ip %> port=<%= roles(:db).first.properties.postgres_port %> user=replicator password=<%= fetch(:postgres_replicator_pass) %> sslmode=require'
|
3
|
+
trigger_file = '<%= fetch(:postgres_data_path) %>/postgresql.trigger'
|