active_postgres 0.9.4 → 0.9.5
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.
- checksums.yaml +4 -4
- data/lib/active_postgres/components/pgbackrest.rb +1 -1
- data/lib/active_postgres/components/pgbouncer.rb +152 -9
- data/lib/active_postgres/configuration.rb +36 -0
- data/lib/active_postgres/secrets.rb +2 -0
- data/lib/active_postgres/version.rb +1 -1
- data/templates/pgbackrest.conf.erb +2 -1
- data/templates/pgbouncer.ini.erb +2 -1
- data/templates/pgbouncer_follow_dns_primary.sh.erb +39 -0
- data/templates/postgres_log_archive.sh.erb +37 -6
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8f31b928d75edd1c1c63a6534023a3c7255f4bce000487da5fb39ddd0bd357fb
|
|
4
|
+
data.tar.gz: ee835da34ead4b417ac2c5087e9fae0db12641c7dddb44e91fe795d083f4e61a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 81cc77508c361ab128d840dbaac52ae9f3fc50b431fa971aaede91fc573ed9186521a53f8098e038515b6c96c82141100fd7ce797b0eae5c4b2840bd01330212
|
|
7
|
+
data.tar.gz: bcdeb64f655cbc0e702f5b70fc3c749daa103ac74945a9432627aeff6926de9b1974fa52547b32e1d99acec687d30b252473a15a75ffadd299e6bc951e9e2bf2
|
|
@@ -212,7 +212,7 @@ module ActivePostgres
|
|
|
212
212
|
env_content = log_archive_env(pgbackrest_config, log_archive_config, host)
|
|
213
213
|
cron_content = log_archive_cron(log_archive_config)
|
|
214
214
|
|
|
215
|
-
install_apt_packages(host, '
|
|
215
|
+
install_apt_packages(host, 's3cmd')
|
|
216
216
|
|
|
217
217
|
ssh_executor.upload_file(host, env_content, LOG_ARCHIVE_ENV_FILE, mode: '640', owner: "root:#{postgres_user}")
|
|
218
218
|
|
|
@@ -8,12 +8,16 @@ module ActivePostgres
|
|
|
8
8
|
is_standby = config.standby_hosts.include?(host)
|
|
9
9
|
install_on_host(host, is_standby: is_standby)
|
|
10
10
|
end
|
|
11
|
+
|
|
12
|
+
pgbouncer_app_hosts.each do |app_host|
|
|
13
|
+
install_on_app_host(app_host)
|
|
14
|
+
end
|
|
11
15
|
end
|
|
12
16
|
|
|
13
17
|
def uninstall
|
|
14
18
|
puts 'Uninstalling PgBouncer...'
|
|
15
19
|
|
|
16
|
-
config.all_hosts.each do |host|
|
|
20
|
+
(config.all_hosts + pgbouncer_app_hosts.map { |app_host| app_host.fetch('host') }).each do |host|
|
|
17
21
|
ssh_executor.execute_on_host(host) do
|
|
18
22
|
execute :sudo, 'systemctl', 'disable', '--now', 'pgbouncer-follow-primary.timer', '||', 'true'
|
|
19
23
|
execute :sudo, 'rm', '-f', '/usr/local/bin/pgbouncer-follow-primary',
|
|
@@ -29,7 +33,7 @@ module ActivePostgres
|
|
|
29
33
|
def restart
|
|
30
34
|
puts 'Restarting PgBouncer...'
|
|
31
35
|
|
|
32
|
-
config.all_hosts.each do |host|
|
|
36
|
+
(config.all_hosts + pgbouncer_app_hosts.map { |app_host| app_host.fetch('host') }).each do |host|
|
|
33
37
|
ssh_executor.execute_on_host(host) do
|
|
34
38
|
execute :sudo, 'systemctl', 'restart', 'pgbouncer'
|
|
35
39
|
end
|
|
@@ -46,6 +50,15 @@ module ActivePostgres
|
|
|
46
50
|
execute :sudo, 'systemctl', 'reload', 'pgbouncer'
|
|
47
51
|
end
|
|
48
52
|
end
|
|
53
|
+
|
|
54
|
+
pgbouncer_app_hosts.each do |app_host|
|
|
55
|
+
host = app_host.fetch('host')
|
|
56
|
+
create_userlist_from_primary(host)
|
|
57
|
+
|
|
58
|
+
ssh_executor.execute_on_host(host) do
|
|
59
|
+
execute :sudo, 'systemctl', 'reload', 'pgbouncer'
|
|
60
|
+
end
|
|
61
|
+
end
|
|
49
62
|
end
|
|
50
63
|
|
|
51
64
|
def install_on_standby(standby_host)
|
|
@@ -55,6 +68,12 @@ module ActivePostgres
|
|
|
55
68
|
|
|
56
69
|
private
|
|
57
70
|
|
|
71
|
+
def pgbouncer_app_hosts
|
|
72
|
+
return config.pgbouncer_app_hosts if config.respond_to?(:pgbouncer_app_hosts)
|
|
73
|
+
|
|
74
|
+
[]
|
|
75
|
+
end
|
|
76
|
+
|
|
58
77
|
def install_on_host(host, is_standby: false)
|
|
59
78
|
puts " Installing PgBouncer on #{host}..."
|
|
60
79
|
|
|
@@ -106,6 +125,45 @@ module ActivePostgres
|
|
|
106
125
|
install_follow_primary(host, pgbouncer_config) if follow_primary
|
|
107
126
|
end
|
|
108
127
|
|
|
128
|
+
def install_on_app_host(app_host)
|
|
129
|
+
host = app_host.fetch('host')
|
|
130
|
+
puts " Installing PgBouncer on app host #{host}..."
|
|
131
|
+
|
|
132
|
+
user_config = config.component_config(:pgbouncer)
|
|
133
|
+
max_connections = get_postgres_max_connections(config.primary_host)
|
|
134
|
+
optimal_pool = ConnectionPooler.calculate_optimal_pool_sizes(max_connections)
|
|
135
|
+
|
|
136
|
+
pgbouncer_config = optimal_pool.merge(user_config)
|
|
137
|
+
pgbouncer_config[:database_host] = app_host_value(app_host, :database_host) || pgbouncer_primary_record
|
|
138
|
+
pgbouncer_config[:database_port] = app_host_value(app_host, :database_port) || pgbouncer_config[:database_port] || 5432
|
|
139
|
+
pgbouncer_config[:listen_addr] = app_host_value(app_host, :listen_addr) || pgbouncer_config[:app_listen_addr] || '127.0.0.1'
|
|
140
|
+
pgbouncer_config[:listen_port] = app_host_value(app_host, :listen_port) || pgbouncer_config[:app_listen_port] ||
|
|
141
|
+
pgbouncer_config[:listen_port] || 6432
|
|
142
|
+
ssl_enabled = config.component_enabled?(:ssl)
|
|
143
|
+
has_ca_cert = ssl_enabled && secrets.resolve('ssl_chain')
|
|
144
|
+
secrets_obj = secrets
|
|
145
|
+
_ = pgbouncer_config
|
|
146
|
+
_ = has_ca_cert
|
|
147
|
+
_ = secrets_obj
|
|
148
|
+
|
|
149
|
+
puts " Calculated app pool settings for max_connections=#{max_connections}"
|
|
150
|
+
|
|
151
|
+
install_apt_packages(host, 'pgbouncer', 'postgresql-client')
|
|
152
|
+
|
|
153
|
+
upload_template(host, 'pgbouncer.ini.erb', '/etc/pgbouncer/pgbouncer.ini', binding, mode: '644')
|
|
154
|
+
|
|
155
|
+
setup_app_ssl_certs(host) if ssl_enabled
|
|
156
|
+
|
|
157
|
+
create_userlist_from_primary(host)
|
|
158
|
+
|
|
159
|
+
ssh_executor.execute_on_host(host) do
|
|
160
|
+
execute :sudo, 'systemctl', 'enable', 'pgbouncer'
|
|
161
|
+
execute :sudo, 'systemctl', 'restart', 'pgbouncer'
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
install_follow_dns_primary(host, pgbouncer_config)
|
|
165
|
+
end
|
|
166
|
+
|
|
109
167
|
def follow_primary_for?(host, is_standby:, user_config:)
|
|
110
168
|
if is_standby
|
|
111
169
|
standby_config = config.standby_config_for(host) || {}
|
|
@@ -135,6 +193,32 @@ module ActivePostgres
|
|
|
135
193
|
end
|
|
136
194
|
end
|
|
137
195
|
|
|
196
|
+
def setup_app_ssl_certs(host)
|
|
197
|
+
puts ' Setting up SSL certificates for app PgBouncer...'
|
|
198
|
+
|
|
199
|
+
ssl_cert = secrets.resolve('ssl_cert')
|
|
200
|
+
ssl_key = secrets.resolve('ssl_key')
|
|
201
|
+
ssl_chain = secrets.resolve('ssl_chain')
|
|
202
|
+
|
|
203
|
+
unless ssl_cert && ssl_key
|
|
204
|
+
raise Error, 'PgBouncer app_hosts require ssl_cert and ssl_key secrets when ssl is enabled'
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
full_cert = if ssl_chain
|
|
208
|
+
"#{ssl_cert.strip}\n#{ssl_chain.strip}\n"
|
|
209
|
+
else
|
|
210
|
+
ssl_cert
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
ssh_executor.execute_on_host(host) do
|
|
214
|
+
execute :sudo, 'mkdir', '-p', '/etc/pgbouncer'
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
ssh_executor.upload_file(host, full_cert, '/etc/pgbouncer/server.crt', mode: '644', owner: 'postgres:postgres')
|
|
218
|
+
ssh_executor.upload_file(host, ssl_key, '/etc/pgbouncer/server.key', mode: '600', owner: 'postgres:postgres')
|
|
219
|
+
ssh_executor.upload_file(host, ssl_chain, '/etc/pgbouncer/ca.crt', mode: '644', owner: 'postgres:postgres') if ssl_chain
|
|
220
|
+
end
|
|
221
|
+
|
|
138
222
|
def get_postgres_max_connections(host)
|
|
139
223
|
# Try to get max_connections from running PostgreSQL
|
|
140
224
|
postgres_user = config.postgres_user
|
|
@@ -154,18 +238,43 @@ module ActivePostgres
|
|
|
154
238
|
def create_userlist(host)
|
|
155
239
|
puts ' Creating PgBouncer userlist with database users...'
|
|
156
240
|
|
|
157
|
-
|
|
158
|
-
app_user = config.app_user
|
|
159
|
-
users_to_add = [postgres_user, (app_user if app_user != postgres_user)].compact
|
|
160
|
-
pgbouncer = self
|
|
241
|
+
component = self
|
|
161
242
|
|
|
162
243
|
ssh_executor.execute_on_host(host) do
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
pgbouncer.send(:write_userlist_file, backend, userlist_entries)
|
|
244
|
+
userlist_entries = component.send(:userlist_entries_from_backend, self)
|
|
245
|
+
component.send(:write_userlist_file, self, userlist_entries)
|
|
166
246
|
end
|
|
167
247
|
end
|
|
168
248
|
|
|
249
|
+
def create_userlist_from_primary(host)
|
|
250
|
+
puts ' Creating app PgBouncer userlist from primary database users...'
|
|
251
|
+
|
|
252
|
+
userlist_entries = nil
|
|
253
|
+
component = self
|
|
254
|
+
|
|
255
|
+
ssh_executor.execute_on_host(config.primary_host) do
|
|
256
|
+
userlist_entries = component.send(:userlist_entries_from_backend, self)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
ssh_executor.execute_on_host(host) do
|
|
260
|
+
component.send(:write_userlist_file, self, userlist_entries || [])
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def userlist_entries_from_backend(backend)
|
|
265
|
+
postgres_user = config.postgres_user
|
|
266
|
+
users_to_add = pgbouncer_database_users
|
|
267
|
+
|
|
268
|
+
users_to_add.filter_map { |user| fetch_user_hash(backend, user, postgres_user) }
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def pgbouncer_database_users
|
|
272
|
+
postgres_user = config.postgres_user
|
|
273
|
+
app_user = config.app_user
|
|
274
|
+
|
|
275
|
+
[postgres_user, (app_user if app_user != postgres_user)].compact
|
|
276
|
+
end
|
|
277
|
+
|
|
169
278
|
def fetch_user_hash(backend, user, postgres_user)
|
|
170
279
|
sql = build_user_hash_sql(user)
|
|
171
280
|
|
|
@@ -241,6 +350,40 @@ module ActivePostgres
|
|
|
241
350
|
execute :sudo, 'systemctl', 'start', 'pgbouncer-follow-primary.service'
|
|
242
351
|
end
|
|
243
352
|
end
|
|
353
|
+
|
|
354
|
+
def install_follow_dns_primary(host, pgbouncer_config)
|
|
355
|
+
interval = pgbouncer_config[:follow_primary_interval] || 5
|
|
356
|
+
interval = interval.to_i
|
|
357
|
+
interval = 5 if interval <= 0
|
|
358
|
+
primary_record = pgbouncer_config[:database_host]
|
|
359
|
+
_ = interval
|
|
360
|
+
_ = primary_record
|
|
361
|
+
_ = pgbouncer_config
|
|
362
|
+
|
|
363
|
+
upload_template(host, 'pgbouncer_follow_dns_primary.sh.erb', '/usr/local/bin/pgbouncer-follow-primary',
|
|
364
|
+
binding, mode: '755', owner: 'root:root')
|
|
365
|
+
upload_template(host, 'pgbouncer-follow-primary.service.erb',
|
|
366
|
+
'/etc/systemd/system/pgbouncer-follow-primary.service', binding, mode: '644', owner: 'root:root')
|
|
367
|
+
upload_template(host, 'pgbouncer-follow-primary.timer.erb',
|
|
368
|
+
'/etc/systemd/system/pgbouncer-follow-primary.timer', binding, mode: '644', owner: 'root:root')
|
|
369
|
+
|
|
370
|
+
ssh_executor.execute_on_host(host) do
|
|
371
|
+
execute :sudo, 'systemctl', 'daemon-reload'
|
|
372
|
+
execute :sudo, 'systemctl', 'enable', '--now', 'pgbouncer-follow-primary.timer'
|
|
373
|
+
execute :sudo, 'systemctl', 'start', 'pgbouncer-follow-primary.service'
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
def pgbouncer_primary_record
|
|
378
|
+
return config.pgbouncer_primary_record if config.respond_to?(:pgbouncer_primary_record)
|
|
379
|
+
|
|
380
|
+
dns_failover = config.component_config(:repmgr)[:dns_failover] || {}
|
|
381
|
+
dns_failover[:primary_record] || config.primary_replication_host
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def app_host_value(app_host, key)
|
|
385
|
+
app_host[key.to_s] || app_host[key]
|
|
386
|
+
end
|
|
244
387
|
end
|
|
245
388
|
end
|
|
246
389
|
end
|
|
@@ -39,6 +39,35 @@ module ActivePostgres
|
|
|
39
39
|
[primary_host] + standby_hosts
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
def pgbouncer_app_hosts
|
|
43
|
+
hosts = component_config(:pgbouncer)[:app_hosts] || component_config(:pgbouncer)['app_hosts'] || []
|
|
44
|
+
hosts = [hosts] unless hosts.is_a?(Array)
|
|
45
|
+
|
|
46
|
+
hosts.filter_map do |entry|
|
|
47
|
+
case entry
|
|
48
|
+
when String
|
|
49
|
+
entry.strip.empty? ? nil : { 'host' => entry.strip }
|
|
50
|
+
when Hash
|
|
51
|
+
host = entry['host'] || entry[:host] || entry['ip'] || entry[:ip]
|
|
52
|
+
next if host.to_s.strip.empty?
|
|
53
|
+
|
|
54
|
+
entry.merge('host' => host.to_s.strip)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def pgbouncer_primary_record
|
|
60
|
+
pgbouncer = component_config(:pgbouncer)
|
|
61
|
+
explicit = pgbouncer[:primary_record] || pgbouncer['primary_record']
|
|
62
|
+
return explicit.to_s.strip unless explicit.to_s.strip.empty?
|
|
63
|
+
|
|
64
|
+
dns_failover = component_config(:repmgr)[:dns_failover] || component_config(:repmgr)['dns_failover'] || {}
|
|
65
|
+
record = dns_failover[:primary_record] || dns_failover['primary_record']
|
|
66
|
+
return record.to_s.strip unless record.to_s.strip.empty?
|
|
67
|
+
|
|
68
|
+
primary_replication_host
|
|
69
|
+
end
|
|
70
|
+
|
|
42
71
|
def primary_host
|
|
43
72
|
@primary['host']
|
|
44
73
|
end
|
|
@@ -114,6 +143,13 @@ module ActivePostgres
|
|
|
114
143
|
end
|
|
115
144
|
end
|
|
116
145
|
|
|
146
|
+
if component_enabled?(:pgbouncer)
|
|
147
|
+
pgbouncer_app_hosts.each do |app_host|
|
|
148
|
+
host = app_host['host'] || app_host[:host]
|
|
149
|
+
raise Error, 'pgbouncer.app_hosts entries must include host' if host.to_s.strip.empty?
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
117
153
|
if component_enabled?(:repmgr)
|
|
118
154
|
dns_failover = component_config(:repmgr)[:dns_failover]
|
|
119
155
|
if dns_failover && dns_failover[:enabled]
|
|
@@ -96,6 +96,8 @@ module ActivePostgres
|
|
|
96
96
|
return if defined?(::Rails) && ::Rails.respond_to?(:application) && ::Rails.application
|
|
97
97
|
|
|
98
98
|
@rails_boot_attempted = true
|
|
99
|
+
ENV['RAILS_ENV'] ||= config.environment
|
|
100
|
+
ENV['BORING_ENVIRONMENT'] ||= config.environment
|
|
99
101
|
|
|
100
102
|
# Try loading just the Rails application (without full initialization)
|
|
101
103
|
# This makes Rails.application available for credential access
|
|
@@ -57,6 +57,8 @@ log-path=/var/log/pgbackrest
|
|
|
57
57
|
|
|
58
58
|
# Process settings
|
|
59
59
|
process-max=<%= pgbackrest_config[:process_max] || 2 %>
|
|
60
|
+
archive-async=y
|
|
61
|
+
spool-path=/var/spool/pgbackrest
|
|
60
62
|
|
|
61
63
|
# Start/Stop (for consistent backups)
|
|
62
64
|
start-fast=y
|
|
@@ -68,4 +70,3 @@ pg1-port=5432
|
|
|
68
70
|
pg1-socket-path=/var/run/postgresql
|
|
69
71
|
pg1-user=<%= config.postgres_user %>
|
|
70
72
|
|
|
71
|
-
|
data/templates/pgbouncer.ini.erb
CHANGED
|
@@ -36,6 +36,8 @@ client_idle_timeout = <%= pgbouncer_config[:client_idle_timeout] || 0 %>
|
|
|
36
36
|
client_login_timeout = <%= pgbouncer_config[:client_login_timeout] || 60 %>
|
|
37
37
|
query_timeout = <%= pgbouncer_config[:query_timeout] || 0 %>
|
|
38
38
|
query_wait_timeout = <%= pgbouncer_config[:query_wait_timeout] || 120 %>
|
|
39
|
+
dns_max_ttl = <%= pgbouncer_config[:dns_max_ttl] || 5 %>
|
|
40
|
+
dns_nxdomain_ttl = <%= pgbouncer_config[:dns_nxdomain_ttl] || 15 %>
|
|
39
41
|
|
|
40
42
|
# Logging and administration
|
|
41
43
|
admin_users = <%= pgbouncer_config[:admin_users] || config.postgres_user %>
|
|
@@ -62,4 +64,3 @@ pidfile = <%= pgbouncer_config[:pidfile] %>
|
|
|
62
64
|
logfile = <%= pgbouncer_config[:logfile] %>
|
|
63
65
|
<% end %>
|
|
64
66
|
|
|
65
|
-
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
PRIMARY_RECORD="<%= primary_record %>"
|
|
5
|
+
PGBOUNCER_INI="/etc/pgbouncer/pgbouncer.ini"
|
|
6
|
+
PGBOUNCER_SERVICE="pgbouncer"
|
|
7
|
+
STATE_DIR="/var/lib/active-postgres"
|
|
8
|
+
STATE_FILE="${STATE_DIR}/pgbouncer-primary-ip"
|
|
9
|
+
LOG_TAG="pgbouncer-follow-primary"
|
|
10
|
+
|
|
11
|
+
resolved_ip=$(getent ahostsv4 "$PRIMARY_RECORD" | awk '{print $1; exit}' || true)
|
|
12
|
+
if [[ -z "$resolved_ip" ]]; then
|
|
13
|
+
/usr/bin/logger -t "$LOG_TAG" "Could not resolve ${PRIMARY_RECORD}"
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
current_host=$(awk -F'host=' '/^\\* = host=/{print $2}' "$PGBOUNCER_INI" | awk '{print $1}')
|
|
18
|
+
previous_ip=""
|
|
19
|
+
if [[ -f "$STATE_FILE" ]]; then
|
|
20
|
+
previous_ip=$(cat "$STATE_FILE")
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
changed=0
|
|
24
|
+
if [[ "$current_host" != "$PRIMARY_RECORD" ]]; then
|
|
25
|
+
/usr/bin/sed -i -E "s/^(\\* = host=)[^ ]+/\\1${PRIMARY_RECORD}/" "$PGBOUNCER_INI"
|
|
26
|
+
changed=1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
if [[ "$previous_ip" != "$resolved_ip" ]]; then
|
|
30
|
+
changed=1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
/usr/bin/install -d -m 0755 "$STATE_DIR"
|
|
34
|
+
printf "%s\n" "$resolved_ip" > "$STATE_FILE"
|
|
35
|
+
|
|
36
|
+
if [[ "$changed" == "1" ]]; then
|
|
37
|
+
/usr/bin/systemctl restart "$PGBOUNCER_SERVICE"
|
|
38
|
+
/usr/bin/logger -t "$LOG_TAG" "Refreshed PgBouncer primary target ${PRIMARY_RECORD} (${resolved_ip})"
|
|
39
|
+
fi
|
|
@@ -46,12 +46,43 @@ if [[ ${#tar_paths[@]} -eq 0 ]]; then
|
|
|
46
46
|
exit 0
|
|
47
47
|
fi
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
set +e
|
|
50
|
+
tar --warning=no-file-changed --ignore-failed-read -czf "$archive" -C / "${tar_paths[@]}"
|
|
51
|
+
tar_status=$?
|
|
52
|
+
set -e
|
|
50
53
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if [[ -n "${AWS_ENDPOINT_URL:-}" ]]; then
|
|
54
|
-
aws_args+=(--endpoint-url "$AWS_ENDPOINT_URL")
|
|
54
|
+
if [[ $tar_status -gt 1 ]]; then
|
|
55
|
+
exit "$tar_status"
|
|
55
56
|
fi
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
if [[ ! -s "$archive" ]]; then
|
|
59
|
+
exit 0
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
destination="s3://${AWS_BUCKET}/${PREFIX%/}/${NODE}/${DATE_PATH}/$(basename "$archive")"
|
|
63
|
+
if command -v aws >/dev/null 2>&1; then
|
|
64
|
+
aws_args=(s3 cp "$archive" "$destination" --only-show-errors)
|
|
65
|
+
if [[ -n "${AWS_ENDPOINT_URL:-}" ]]; then
|
|
66
|
+
aws_args+=(--endpoint-url "$AWS_ENDPOINT_URL")
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
aws "${aws_args[@]}"
|
|
70
|
+
elif command -v s3cmd >/dev/null 2>&1; then
|
|
71
|
+
s3cmd_args=(
|
|
72
|
+
--access_key="$AWS_ACCESS_KEY_ID"
|
|
73
|
+
--secret_key="$AWS_SECRET_ACCESS_KEY"
|
|
74
|
+
--region="${AWS_DEFAULT_REGION:-us-east-1}"
|
|
75
|
+
--no-progress
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
if [[ -n "${AWS_ENDPOINT_URL:-}" ]]; then
|
|
79
|
+
endpoint="${AWS_ENDPOINT_URL#https://}"
|
|
80
|
+
endpoint="${endpoint#http://}"
|
|
81
|
+
s3cmd_args+=(--host="$endpoint" --host-bucket="${endpoint}/%(bucket)")
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
s3cmd "${s3cmd_args[@]}" put "$archive" "$destination"
|
|
85
|
+
else
|
|
86
|
+
echo "missing aws or s3cmd command for PostgreSQL log archive" >&2
|
|
87
|
+
exit 1
|
|
88
|
+
fi
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_postgres
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- BoringCache
|
|
@@ -199,6 +199,7 @@ files:
|
|
|
199
199
|
- templates/pgbouncer-follow-primary.service.erb
|
|
200
200
|
- templates/pgbouncer-follow-primary.timer.erb
|
|
201
201
|
- templates/pgbouncer.ini.erb
|
|
202
|
+
- templates/pgbouncer_follow_dns_primary.sh.erb
|
|
202
203
|
- templates/pgbouncer_follow_primary.sh.erb
|
|
203
204
|
- templates/postgres_log_archive.sh.erb
|
|
204
205
|
- templates/postgresql.conf.erb
|