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.
@@ -0,0 +1,198 @@
1
+ set :postgres_templates_path, "templates/postgres"
2
+ set :postgres_config_files, ["postgresql.conf", "pg_hba.conf"]
3
+ set :postgres_recovery_conf, ["recovery.conf"]
4
+ set :postgres_root_path, -> { shared_path.join('postgres') }
5
+ set :postgres_data_path, -> { fetch(:postgres_root_path).join('data') }
6
+ set :postgres_config_path, -> { fetch(:postgres_root_path).join('conf') }
7
+ set :postgres_socket_path, -> { fetch(:postgres_root_path).join('run') }
8
+ set :postgres_recovery_conf, -> { "#{fetch(:postgres_data_path)}/recovery.conf" }
9
+ set :postgres_ssl_key, -> { "#{fetch(:postgres_data_path)}/server.key" }
10
+ set :postgres_ssl_csr, -> { "#{fetch(:postgres_data_path)}/server.csr" }
11
+ set :postgres_ssl_crt, -> { "#{fetch(:postgres_data_path)}/server.crt" }
12
+ set :postgres_log_level, "info"
13
+
14
+ def pg_run(host)
15
+ execute("docker", "run", "--detach", "--tty", "--user", "postgres",
16
+ "--name", host.properties.postgres_container_name,
17
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
18
+ "--expose", "5432",
19
+ "--publish", "0.0.0.0:#{host.properties.postgres_port}:5432",
20
+ "--restart", "always",
21
+ "--entrypoint", "/usr/lib/postgresql/9.1/bin/postgres",
22
+ fetch(:postgres_image_name),
23
+ "-D", shared_path.join('postgres', 'data'),
24
+ "-c", "config_file=#{shared_path.join('postgres', 'conf', 'postgresql.conf')}")
25
+ end
26
+ def pg_init(host)
27
+ execute("docker", "run", "--rm", "--user", "root",
28
+ "--volume", "#{fetch(:postgres_data_path)}:/postgresql-data:rw",
29
+ "--entrypoint", "/usr/bin/rsync",
30
+ fetch(:postgres_image_name), "-ah", "/var/lib/postgresql/9.1/main/", "/postgresql-data/")
31
+ end
32
+ def pg_replicate(host)
33
+ execute("docker", "run", "--rm", "--user", "postgres",
34
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
35
+ "--entrypoint", "/usr/bin/pg_basebackup",
36
+ fetch(:postgres_image_name),
37
+ "-w", "-h", fetch(:domain), "-p", fetch(:master_container_port),
38
+ "-U", "replicator", "-D", fetch(:postgres_data_path), "-v", "-x")
39
+ end
40
+ def pg_ssl_key(host)
41
+ execute("docker", "run", "--rm", "--user", "root",
42
+ "--entrypoint", "/usr/bin/openssl",
43
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
44
+ fetch(:postgres_image_name), "req", "-nodes", "-newkey", "rsa:2048",
45
+ "-keyout", fetch(:postgres_ssl_key),
46
+ "-out", fetch(:postgres_ssl_csr),
47
+ "-subj", "\"/C=US/ST=Oregon/L=Portland/O=My Company/OU=Operations/CN=localhost\"")
48
+ end
49
+ def pg_ssl_crt(host)
50
+ execute("docker", "run", "--rm", "--user", "root",
51
+ "--entrypoint", "/usr/bin/openssl",
52
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
53
+ fetch(:postgres_image_name), "req", "-x509", "-text",
54
+ "-in", fetch(:postgres_ssl_csr),
55
+ "-key", fetch(:postgres_ssl_key),
56
+ "-out", fetch(:postgres_ssl_crt))
57
+ end
58
+ def pg_restore(host, args, clean)
59
+ SSHKit.config.output_verbosity = "debug"
60
+ execute("docker", "run", "--rm",
61
+ "--volume", "/tmp:/tmp:rw",
62
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
63
+ "--entrypoint", "/bin/bash",
64
+ fetch(:postgres_image_name),
65
+ "-c", "'/usr/bin/pg_restore", "-U", "postgres",
66
+ "--host", fetch(:postgres_socket_path), clean,
67
+ "-d", args.database_name, "-F", "tar", "-v", "/tmp/#{args.dump_file}'")
68
+ SSHKit.config.output_verbosity = fetch(:postgres_log_level)
69
+ end
70
+ def pg_dump(host, args)
71
+ SSHKit.config.output_verbosity = "debug"
72
+ execute("docker", "run", "--rm",
73
+ "--volume", "/tmp:/tmp:rw",
74
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
75
+ "--entrypoint", "/bin/bash",
76
+ fetch(:postgres_image_name),
77
+ "-c", "'/usr/bin/pg_dump", "-U", "postgres",
78
+ "--host", fetch(:postgres_socket_path), "-F", "tar",
79
+ "-v", args.database_name, ">", "/tmp/#{args.dump_file}'")
80
+ SSHKit.config.output_verbosity = fetch(:postgres_log_level)
81
+ end
82
+ def pg_interactive(host)
83
+ [
84
+ "ssh", "-t", "#{host}", "\"docker", "run", "--rm", "--interactive", "--tty",
85
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
86
+ "--entrypoint", "/bin/bash",
87
+ "#{fetch(:postgres_image_name)}",
88
+ "-lic", "'/usr/bin/psql", "-U", "postgres",
89
+ "--host", "#{fetch(:postgres_socket_path)}'\""
90
+ ].join(' ')
91
+ end
92
+ def pg_interactive_print(host)
93
+ [
94
+ "docker", "run", "--rm", "--interactive", "--tty",
95
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
96
+ "--entrypoint", "/bin/bash",
97
+ "#{fetch(:postgres_image_name)}",
98
+ "-lic", "'/usr/bin/psql", "-U", "postgres",
99
+ "--host", "#{fetch(:postgres_socket_path)}'"
100
+ ].join(' ')
101
+ end
102
+ def pg_list_databases(host)
103
+ capture("docker", "run", "--rm",
104
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
105
+ "--entrypoint", "/bin/bash",
106
+ fetch(:postgres_image_name),
107
+ "-c", "'/usr/bin/psql", "-U", "postgres",
108
+ "--host", fetch(:postgres_socket_path),
109
+ "-a", "-c", "\"\\l\"'").lines.each { |l| info l }
110
+ end
111
+ def pg_list_roles(host)
112
+ capture("docker", "run", "--rm",
113
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
114
+ "--entrypoint", "/bin/bash",
115
+ fetch(:postgres_image_name),
116
+ "-c", "'/usr/bin/psql", "-U", "postgres",
117
+ "--host", fetch(:postgres_socket_path),
118
+ "-c", "\"\\du\"'").lines.each { |l| info l }
119
+ end
120
+ def pg_streaming_master(host)
121
+ capture("echo", "\"SELECT", "*", "FROM", "pg_stat_replication;\"", "|",
122
+ "docker", "run", "--rm", "--interactive",
123
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
124
+ "--entrypoint", "/bin/bash",
125
+ fetch(:postgres_image_name),
126
+ "-c", "'/usr/bin/psql", "-U", "postgres", "-xa",
127
+ "--host", "#{fetch(:postgres_socket_path)}'").lines.each { |l| info l }
128
+ end
129
+ def pg_streaming_slave(host)
130
+ capture("echo", "\"SELECT", "now()", "-", "pg_last_xact_replay_timestamp()",
131
+ "AS", "replication_delay;\"", "|",
132
+ "docker", "run", "--rm", "--interactive",
133
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
134
+ "--entrypoint", "/bin/bash",
135
+ fetch(:postgres_image_name),
136
+ "-c", "'/usr/bin/psql", "-U", "postgres",
137
+ "--host", "#{fetch(:postgres_socket_path)}'").lines.each { |l| info l }
138
+ end
139
+ def pg_create_role(db_role, password)
140
+ execute("echo", "\"CREATE", "ROLE", "\\\"#{db_role}\\\"",
141
+ "WITH", "LOGIN", "ENCRYPTED", "PASSWORD", "'#{password}'",
142
+ "REPLICATION", "CREATEDB;\"", "|",
143
+ "docker", "run", "--rm", "--interactive",
144
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
145
+ "--entrypoint", "/bin/bash",
146
+ fetch(:postgres_image_name),
147
+ "-c", "'/usr/bin/psql", "-U", "postgres",
148
+ "--host", "#{fetch(:postgres_socket_path)}'")
149
+ end
150
+ def pg_create_database(database)
151
+ execute("echo", "\"CREATE", "DATABASE", "\\\"#{database[:name]}\\\"",
152
+ "WITH", "OWNER", "\\\"#{database[:db_role]}\\\"", "TEMPLATE",
153
+ "template0", "ENCODING", "'UTF8';\"", "|",
154
+ "docker", "run", "--rm", "--interactive",
155
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
156
+ "--entrypoint", "/bin/bash",
157
+ fetch(:postgres_image_name),
158
+ "-c", "'/usr/bin/psql", "-U", "postgres",
159
+ "--host", "#{fetch(:postgres_socket_path)}'")
160
+ end
161
+ def pg_grant_database(database)
162
+ execute("echo", "\"GRANT", "ALL", "PRIVILEGES", "ON", "DATABASE",
163
+ "\\\"#{database[:name]}\\\"", "to", "\\\"#{database[:db_role]}\\\";\"", "|",
164
+ "docker", "run", "--rm", "--interactive",
165
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
166
+ "--entrypoint", "/bin/bash",
167
+ fetch(:postgres_image_name),
168
+ "-c", "'/usr/bin/psql", "-U", "postgres",
169
+ "--host", "#{fetch(:postgres_socket_path)}'")
170
+ end
171
+ def pg_role_exists?(db_role)
172
+ test("echo", "\"SELECT", "*", "FROM", "pg_user",
173
+ "WHERE", "usename", "=", "'#{db_role}';\"", "|",
174
+ "docker", "run", "--rm", "--interactive",
175
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
176
+ "--entrypoint", "/bin/bash",
177
+ fetch(:postgres_image_name),
178
+ "-c", "'/usr/bin/psql", "-U", "postgres",
179
+ "--host", "#{fetch(:postgres_socket_path)}'", "|",
180
+ "grep", "-q", "'#{db_role}'")
181
+ end
182
+ def pg_database_exists?(database_name)
183
+ test("docker", "run", "--rm",
184
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
185
+ "--entrypoint", "/bin/bash",
186
+ fetch(:postgres_image_name),
187
+ "-c", "'/usr/bin/psql", "-U", "postgres",
188
+ "--host", fetch(:postgres_socket_path), "-lqt", "|",
189
+ "cut", "-d\\|", "-f1", "|", "grep", "-w", "#{database_name}'")
190
+ end
191
+ def pg_database_empty?(database_name)
192
+ test("docker", "run", "--rm", "--tty",
193
+ "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
194
+ "--entrypoint", "/bin/bash", fetch(:postgres_image_name), "-lc",
195
+ "'/usr/bin/psql", "-U", "postgres", "-d", database_name,
196
+ "--host", fetch(:postgres_socket_path),
197
+ "-c", "\"\\dt\"", "|", "grep", "-qi", "\"no relations found\"'")
198
+ end
@@ -0,0 +1,130 @@
1
+ namespace :pg do
2
+ namespace :check do
3
+
4
+ #desc 'Ensure all postgresinator specific settings are set, and warn and exit if not.'
5
+ before 'pg:setup', :settings do
6
+ require 'resolv' unless defined?(Resolv)
7
+ run_locally do
8
+ {
9
+ (File.dirname(__FILE__) + "/examples/config/deploy.rb") => 'config/deploy.rb',
10
+ (File.dirname(__FILE__) + "/examples/config/deploy/staging.rb") => "config/deploy/#{fetch(:stage)}.rb"
11
+ }.each do |abs, rel|
12
+ Rake::Task['deployinator:settings'].invoke(abs, rel)
13
+ Rake::Task['deployinator:settings'].reenable
14
+ end
15
+ end
16
+ on roles(:db, :db_slave, :in => :parallel) do |host|
17
+ unless host.properties.respond_to?(:postgres_port)
18
+ fatal "#{host} does not have postgres_port set." and exit
19
+ end
20
+ unless host.properties.respond_to?(:ip)
21
+ host.properties.set :ip, Resolv.getaddress(host.to_s)
22
+ end
23
+ end
24
+ on roles(:db) do |host|
25
+ unless host.properties.respond_to?(:postgres_container_name)
26
+ host.properties.set :postgres_container_name, "#{fetch(:domain)}-postgres-master_#{host.properties.postgres_port}"
27
+ end
28
+ end
29
+ on roles(:db_slave, :in => :parallel) do |host|
30
+ unless host.properties.respond_to?(:postgres_container_name)
31
+ host.properties.set :postgres_container_name, "#{fetch(:domain)}-postgres-slave_#{host.properties.postgres_port}"
32
+ end
33
+ end
34
+ run_locally do
35
+ unless roles(:db).length == 1
36
+ fatal "You can't set more than one master! (set only one host in the :db role.)"
37
+ fatal roles(:db)
38
+ exit
39
+ end
40
+ end
41
+ end
42
+
43
+ namespace :settings do
44
+ desc 'Print example postgresinator specific settings for comparison.'
45
+ task :print do
46
+ set :print_all, true
47
+ Rake::Task['pg:check:settings'].invoke
48
+ end
49
+
50
+ task :database, [:database_name] do |t, args|
51
+ run_locally do
52
+ database_found = false
53
+ fetch(:postgres_databases).each do |database|
54
+ next unless database[:name] == args.database_name
55
+ database_found = true
56
+ end
57
+ fatal "Database #{args.domain} not found in the configuration" and exit unless database_found
58
+ end
59
+ end
60
+
61
+ task :domain, [:domain] do |t, args|
62
+ run_locally do
63
+ unless roles(:db, :db_slave).select { |host| host.to_s == args.domain }.length == 1
64
+ fatal "Server domain #{args.domain} not found in the configuration" and exit
65
+ end
66
+ end
67
+ end
68
+
69
+ task :postgres_uid_gid do
70
+ on roles(:db) do
71
+ set :postgres_uid, -> {
72
+ capture("docker", "run", "--rm", "--tty",
73
+ "--entrypoint", "/usr/bin/id",
74
+ fetch(:postgres_image_name), "-u", "postgres").strip
75
+ }
76
+ set :postgres_gid, -> {
77
+ capture("docker", "run", "--rm", "--tty",
78
+ "--entrypoint", "/usr/bin/id",
79
+ fetch(:postgres_image_name), "-g", "postgres").strip
80
+ }
81
+ end
82
+ end
83
+ end
84
+
85
+ task :file_permissions => ['pg:ensure_setup', 'postgresinator:deployment_user', 'postgresinator:webserver_user'] do
86
+ on roles(:db, :db_slave, :in => :parallel) do |host|
87
+ as "root" do
88
+ execute "mkdir", "-p", fetch(:postgres_data_path),
89
+ fetch(:postgres_socket_path), fetch(:postgres_config_path)
90
+ ["#{fetch(:deploy_to)}/..", fetch(:deploy_to), shared_path].each do |dir|
91
+ execute("chown", "#{fetch(:deployment_user_id)}:#{unix_user_get_gid(fetch(:webserver_username))}", dir.to_s)
92
+ execute("chmod", "2750", dir.to_s)
93
+ end
94
+ # chown everything
95
+ execute("chown", "-R", "#{fetch(:postgres_uid)}:#{fetch(:postgres_gid)}",
96
+ fetch(:postgres_root_path))
97
+ # chmod data_path
98
+ execute "find", fetch(:postgres_data_path), "-type", "d",
99
+ "-exec", "chmod", "2700", "{}", "+"
100
+ execute "find", fetch(:postgres_data_path), "-type", "f",
101
+ "-exec", "chmod", "0600", "{}", "+"
102
+ # chmod everything but data_path
103
+ execute "find", fetch(:postgres_root_path), "-type", "d",
104
+ "-not", "-path", "\"#{fetch(:postgres_data_path)}\"",
105
+ "-not", "-path", "\"#{fetch(:postgres_data_path)}/*\"",
106
+ "-exec", "chmod", "2775", "{}", "+"
107
+ execute "find", fetch(:postgres_root_path), "-type", "f",
108
+ "-not", "-path", "\"#{fetch(:postgres_data_path)}\"",
109
+ "-not", "-path", "\"#{fetch(:postgres_data_path)}/*\"",
110
+ "-exec", "chmod", "0660", "{}", "+"
111
+ end
112
+ end
113
+ end
114
+ after 'pg:install_config_files', 'pg:check:file_permissions'
115
+
116
+ task :firewall => ['pg:ensure_setup', 'postgresinator:deployment_user'] do
117
+ on roles(:db, :db_slave, :in => :parallel) do |host|
118
+ as "root" do
119
+ if test "ufw", "status"
120
+ success = test("ufw", "allow", "#{host.properties.postgres_port}/tcp")
121
+ fatal "Error during opening UFW firewall" and exit unless success
122
+ else
123
+ warn "Uncomplicated Firewall does not appear to be installed, making no firewall action."
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ end
130
+ end
@@ -1,155 +1,106 @@
1
- require 'resolv'
2
- require 'hashie'
1
+ module Capistrano
2
+ module TaskEnhancements
3
+ alias_method :pg_original_default_tasks, :default_tasks
4
+ def default_tasks
5
+ pg_original_default_tasks + [
6
+ 'postgresinator:write_built_in',
7
+ 'postgresinator:write_example_configs',
8
+ 'postgresinator:write_example_configs:in_place'
9
+ ]
10
+ end
11
+ end
12
+ end
3
13
 
4
14
  namespace :postgresinator do
5
15
 
6
- desc 'Write example config files'
16
+ set :example, "_example"
17
+
18
+ desc "Write example config files (with '_example' appended to their names)."
7
19
  task :write_example_configs do
8
20
  run_locally do
9
- execute "mkdir", "-p", "config/deploy", "templates/postgresql"
21
+ execute "mkdir", "-p", "config/deploy", fetch(:postgres_templates_path, 'templates/postgres')
10
22
  {
11
- 'examples/Capfile' => 'Capfile_example',
12
- 'examples/config/deploy.rb' => 'config/deploy_example.rb',
13
- 'examples/config/deploy_postgresinator.rb' => 'config/deploy_postgresinator_example.rb',
14
- 'examples/config/deploy/staging.rb' => 'config/deploy/staging_example.rb',
15
- 'examples/config/deploy/staging_postgresinator.rb' => 'config/deploy/staging_postgresinator_example.rb',
16
- 'examples/Dockerfile' => 'templates/postgresql/Dockerfile_example',
17
- 'examples/postgresql.conf.erb' => 'templates/postgresql/postgresql_example.conf.erb',
18
- 'examples/pg_hba.conf.erb' => 'templates/postgresql/pg_hba_example.conf.erb',
19
- 'examples/recovery.conf.erb' => 'templates/postgresql/recovery_example.conf.erb'
23
+ 'examples/Capfile' => "Capfile#{fetch(:example)}",
24
+ 'examples/config/deploy.rb' => "config/deploy#{fetch(:example)}.rb",
25
+ 'examples/config/deploy/staging.rb' => "config/deploy/staging#{fetch(:example)}.rb",
26
+ 'examples/Dockerfile' => "#{fetch(:postgres_templates_path, 'templates/postgres')}/Dockerfile#{fetch(:example)}",
27
+ 'examples/postgresql.conf.erb' => "#{fetch(:postgres_templates_path, 'templates/postgres')}/postgresql#{fetch(:example)}.conf.erb",
28
+ 'examples/pg_hba.conf.erb' => "#{fetch(:postgres_templates_path, 'templates/postgres')}/pg_hba#{fetch(:example)}.conf.erb",
29
+ 'examples/recovery.conf.erb' => "#{fetch(:postgres_templates_path, 'templates/postgres')}/recovery#{fetch(:example)}.conf.erb"
20
30
  }.each do |source, destination|
21
31
  config = File.read(File.dirname(__FILE__) + "/#{source}")
22
32
  File.open("./#{destination}", 'w') { |f| f.write(config) }
23
33
  info "Wrote '#{destination}'"
24
34
  end
25
- info "Now remove the '_example' portion of their names or diff with existing files and add the needed lines."
35
+ unless fetch(:example).empty?
36
+ info "Now remove the '#{fetch(:example)}' portion of their names or diff with existing files and add the needed lines."
37
+ end
26
38
  end
27
39
  end
28
40
 
29
- end
30
-
31
- namespace :config do
32
-
33
- # TODO refactor to load all settings via capistrano configs
34
- task :load_settings do
35
- cluster = Hashie::Mash.new()
36
- cluster.image = {}
37
- set :pg_image_name, -> { fetch(:postgres_image_name) }
38
- cluster.image.name = fetch(:pg_image_name)
39
- set :pg_config_files, -> { fetch(:postgres_config_files) }
40
- cluster.image.config_files = fetch(:pg_config_files)
41
- set :pg_data_path, -> { fetch(:postgres_data_path) }
42
- cluster.image.data_path = fetch(:pg_data_path)
43
- set :pg_conf_path, -> { fetch(:postgres_conf_path) }
44
- cluster.image.conf_path = fetch(:pg_conf_path)
45
- set :pg_sock_path, -> { fetch(:postgres_sock_path) }
46
- cluster.image.sock_path = fetch(:pg_sock_path)
47
- set :pg_uid, -> { fetch(:postgres_uid) }
48
- cluster.image.postgres_uid = fetch(:pg_uid)
49
- set :pg_gid, -> { fetch(:postgres_gid) }
50
- cluster.image.postgres_gid = fetch(:pg_gid)
51
- set :pg_databases, -> { fetch(:databases) }
52
- cluster.databases = fetch(:pg_databases)
53
- set :pg_servers, -> { fetch(:servers) }
54
- cluster.servers = fetch(:pg_servers)
55
-
56
- cluster.ssh_user = ENV["USER"]
57
- cluster.servers.each do |server|
58
- server.ip = Resolv.getaddress(server.domain)
59
- master_or_slave = server.master ? "master" : "slave"
60
- server.master_domain = cluster.servers.collect { |s| s.domain if s.master }.first
61
- server.master_ip = Resolv.getaddress(server.master_domain)
62
- server.master_port = cluster.servers.collect { |s| s.port if s.master }.first
63
- server.container_name = "#{server.master_domain}-postgres-#{server.port}-#{master_or_slave}"
64
- server.data_path = "/#{server.container_name}-data"
65
- server.conf_path = "/#{server.container_name}-conf"
66
- server.docker_run_command = [
67
- "--detach", "--tty", "--user", "postgres",
68
- "--name", server.container_name,
69
- "--volume", cluster.image.sock_path,
70
- "--volume", "#{server.data_path}:#{cluster.image.data_path}:rw",
71
- "--volume", "#{server.conf_path}:#{cluster.image.conf_path}:rw",
72
- "--expose", "5432",
73
- "--publish", "0.0.0.0:#{server.port}:5432",
74
- "--restart", "always",
75
- cluster.image.name
76
- ]
77
- server.docker_init_command = [
78
- "--rm", "--user", "root",
79
- "--volume", "#{server.data_path}:/postgresql-data:rw",
80
- "--entrypoint", "/usr/bin/rsync",
81
- cluster.image.name, "-ah", "#{cluster.image.data_path}/", "/postgresql-data/"
82
- ]
83
- server.docker_replicate_command = [
84
- "--rm", "--user", "postgres",
85
- "--volume", "#{server.data_path}:#{cluster.image.data_path}:rw",
86
- "--entrypoint", "/usr/bin/pg_basebackup",
87
- cluster.image.name,
88
- "-w", "-h", server.master_domain, "-p", server.master_port,
89
- "-U", "replicator", "-D", cluster.image.data_path, "-v", "-x"
90
- ]
41
+ desc 'Write example config files (will overwrite any existing config files).'
42
+ namespace :write_example_configs do
43
+ task :in_place do
44
+ set :example, ""
45
+ Rake::Task['postgresinator:write_example_configs'].invoke
91
46
  end
92
- @cluster = cluster
93
47
  end
94
48
 
95
- task :ensure_cluster_data_uniqueness do
96
- cluster = @cluster
49
+ desc 'Write a file showing the built-in overridable settings.'
50
+ task :write_built_in do
97
51
  run_locally do
98
- names = cluster.servers.collect { |s| s.container_name }
99
- fatal "The container names in this cluster are not unique" and raise unless names == names.uniq
100
-
101
- masters = cluster.servers.collect { |s| s.domain if s.master }
102
- fatal "You can't set more than one master" and raise unless masters.compact.length == 1
52
+ {
53
+ 'built-in.rb' => 'built-in.rb',
54
+ }.each do |source, destination|
55
+ config = File.read(File.dirname(__FILE__) + "/#{source}")
56
+ File.open("./#{destination}", 'w') { |f| f.write(config) }
57
+ info "Wrote '#{destination}'"
58
+ end
59
+ info "Now examine the file and copy-paste into your deploy.rb or <stage>.rb and customize."
103
60
  end
104
61
  end
105
62
 
106
- task :config_file_not_found, [:config_file] do |t, args|
107
- cluster = @cluster
108
- run_locally do
109
- config_file_found = false
110
- cluster.image.config_files.each do |config_file|
111
- next unless config_file == args.config_file
112
- config_file_found = true
63
+ # These are the only two tasks using :preexisting_ssh_user
64
+ namespace :deployment_user do
65
+ #desc "Setup or re-setup the deployment user, idempotently"
66
+ task :setup do
67
+ on roles(:all) do |h|
68
+ on "#{fetch(:preexisting_ssh_user)}@#{h}" do |host|
69
+ as :root do
70
+ deployment_user_setup(fetch(:postgres_templates_path))
71
+ end
72
+ end
113
73
  end
114
- fatal "Config file #{args.config_file} not found in the configuration" and raise unless config_file_found
115
- config_template_found = test("ls", "-A", "templates/postgresql/#{args.config_file}.erb")
116
- fatal "Config template file templates/postgresql/#{args.config_file}.erb not found locally" and raise unless config_template_found
117
74
  end
118
75
  end
119
76
 
120
- task :database_not_found, [:database_name] do |t, args|
121
- cluster = @cluster
122
- run_locally do
123
- database_found = false
124
- cluster.databases.each do |database|
125
- next unless database.name == args.database_name
126
- database_found = true
77
+ task :deployment_user do
78
+ on roles(:all) do |h|
79
+ on "#{fetch(:preexisting_ssh_user)}@#{h}" do |host|
80
+ as :root do
81
+ if unix_user_exists?(fetch(:deployment_username))
82
+ info "User #{fetch(:deployment_username)} already exists. You can safely re-setup the user with 'postgresinator:deployment_user:setup'."
83
+ else
84
+ Rake::Task['postgresinator:deployment_user:setup'].invoke
85
+ end
86
+ end
127
87
  end
128
- fatal "Database #{args.domain} not found in the configuration" and raise unless database_found
129
88
  end
130
89
  end
131
90
 
132
- task :domain_not_found, [:domain] do |t, args|
133
- cluster = @cluster
134
- run_locally do
135
- domain_found = false
136
- cluster.servers.each do |server|
137
- next unless server.domain == args.domain
138
- domain_found = true
91
+ task :webserver_user do
92
+ on roles(:all) do
93
+ as :root do
94
+ unix_user_add(fetch(:webserver_username)) unless unix_user_exists?(fetch(:webserver_username))
139
95
  end
140
- fatal "Server domain #{args.domain} not found in the configuration" and raise unless domain_found
141
96
  end
142
97
  end
143
98
 
144
- task :role_not_found, [:role_name] do |t, args|
145
- cluster = @cluster
146
- run_locally do
147
- role_found = false
148
- cluster.databases.each do |database|
149
- next unless database.db_role == args.role_name
150
- role_found = true
99
+ task :file_permissions => [:deployment_user, :webserver_user] do
100
+ on roles(:app) do
101
+ as :root do
102
+ setup_file_permissions
151
103
  end
152
- fatal "Role #{args.role_name} not found in the configuration" and raise unless role_found
153
104
  end
154
105
  end
155
106