active_postgres 0.7.0 → 0.8.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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0266b3f7dabc2d844b30aa6410cfd7c59131a7fb77a2dea85f01f9a66c2a2443
|
|
4
|
+
data.tar.gz: fd720306229f1ddea1d4e01a9dc3a5df3b7a60a620c38e86779e82f9698ebcbc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bb3bc17966f9ebe98a55f09f678fe2bc2e57b92615c45848c347a7568f6e3bb61d15788d6bb16008e4498a9b944a3f53241f2e2579b204d28679341b041f4978
|
|
7
|
+
data.tar.gz: 3863cace22d1ba3aea901d312d26152de067c7ca898ddff5b654a75702a9e6b4c01f6ffbac820fed338fc5db8ce011ad39676143f81f785f66f7fec72cd72ae5
|
|
@@ -8,7 +8,6 @@ module ActivePostgres
|
|
|
8
8
|
@environment = environment
|
|
9
9
|
env_config = config_hash[environment] || {}
|
|
10
10
|
|
|
11
|
-
# Check if deployment should be skipped (e.g., for development)
|
|
12
11
|
@skip_deployment = env_config['skip_deployment'] == true
|
|
13
12
|
|
|
14
13
|
@version = env_config['version'] || 18
|
|
@@ -65,6 +64,16 @@ module ActivePostgres
|
|
|
65
64
|
private_ip_for(node) || host
|
|
66
65
|
end
|
|
67
66
|
|
|
67
|
+
# Returns the host to use for direct PostgreSQL connections (private_ip preferred)
|
|
68
|
+
def connection_host_for(host)
|
|
69
|
+
node = node_config_for(host)
|
|
70
|
+
private_ip_for(node) || host
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def primary_connection_host
|
|
74
|
+
connection_host_for(primary_host)
|
|
75
|
+
end
|
|
76
|
+
|
|
68
77
|
def standby_config_for(host)
|
|
69
78
|
@standbys.find { |s| s['host'] == host }
|
|
70
79
|
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require 'pg'
|
|
2
|
+
|
|
3
|
+
module ActivePostgres
|
|
4
|
+
class DirectExecutor
|
|
5
|
+
attr_reader :config
|
|
6
|
+
|
|
7
|
+
def initialize(config, quiet: false)
|
|
8
|
+
@config = config
|
|
9
|
+
@quiet = quiet
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def quiet?
|
|
13
|
+
@quiet
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def postgres_running?(host)
|
|
17
|
+
with_connection(host) do |conn|
|
|
18
|
+
conn.exec('SELECT 1')
|
|
19
|
+
true
|
|
20
|
+
end
|
|
21
|
+
rescue PG::Error
|
|
22
|
+
false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def run_sql(host, sql)
|
|
26
|
+
with_connection(host) do |conn|
|
|
27
|
+
result = conn.exec(sql)
|
|
28
|
+
result.values.flatten.join("\n")
|
|
29
|
+
end
|
|
30
|
+
rescue PG::Error => e
|
|
31
|
+
raise Error, "Failed to execute SQL on #{host}: #{e.message}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def get_postgres_status(host)
|
|
35
|
+
run_sql(host, 'SELECT version();')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def with_connection(host)
|
|
41
|
+
connection_host = config.connection_host_for(host)
|
|
42
|
+
superuser_password = resolve_secret(config.secrets_config['superuser_password'])
|
|
43
|
+
|
|
44
|
+
conn = PG.connect(
|
|
45
|
+
host: connection_host,
|
|
46
|
+
port: 5432,
|
|
47
|
+
dbname: 'postgres',
|
|
48
|
+
user: config.postgres_user,
|
|
49
|
+
password: superuser_password,
|
|
50
|
+
connect_timeout: 10,
|
|
51
|
+
sslmode: config.component_enabled?(:ssl) ? 'require' : 'prefer'
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
begin
|
|
55
|
+
yield conn
|
|
56
|
+
ensure
|
|
57
|
+
conn.close
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def resolve_secret(value)
|
|
62
|
+
return nil if value.nil?
|
|
63
|
+
|
|
64
|
+
# Handle Rails credentials
|
|
65
|
+
if value.start_with?('rails_credentials:')
|
|
66
|
+
return resolve_rails_credentials(value)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Handle environment variables
|
|
70
|
+
if value.start_with?('$')
|
|
71
|
+
return ENV[value[1..]]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Handle shell commands
|
|
75
|
+
if value.start_with?('$(') && value.end_with?(')')
|
|
76
|
+
return `#{value[2..-2]}`.strip
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
value
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def resolve_rails_credentials(value)
|
|
83
|
+
path = value.sub('rails_credentials:', '')
|
|
84
|
+
keys = path.split('.').map(&:to_sym)
|
|
85
|
+
|
|
86
|
+
credentials = Rails.application.credentials
|
|
87
|
+
keys.reduce(credentials) { |obj, key| obj&.dig(key) }
|
|
88
|
+
rescue NameError
|
|
89
|
+
nil
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
module ActivePostgres
|
|
2
2
|
class HealthChecker
|
|
3
|
-
attr_reader :config, :
|
|
3
|
+
attr_reader :config, :executor
|
|
4
4
|
|
|
5
5
|
def initialize(config)
|
|
6
6
|
@config = config
|
|
7
|
-
@
|
|
7
|
+
@executor = create_executor
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Backwards compatibility alias
|
|
11
|
+
def ssh_executor
|
|
12
|
+
@executor
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private def create_executor
|
|
16
|
+
DirectExecutor.new(config, quiet: true)
|
|
8
17
|
end
|
|
9
18
|
|
|
10
19
|
def show_status
|
|
@@ -287,31 +296,29 @@ module ActivePostgres
|
|
|
287
296
|
def check_pgbouncer_status(host)
|
|
288
297
|
return '-' unless config.component_enabled?(:pgbouncer)
|
|
289
298
|
|
|
290
|
-
|
|
291
|
-
result = capture(:sudo, 'systemctl', 'is-active', 'pgbouncer').strip
|
|
292
|
-
result == 'active' ? '✓ running' : '✗ down'
|
|
293
|
-
end
|
|
299
|
+
check_pgbouncer_direct(host) ? '✓ running' : '✗ down'
|
|
294
300
|
rescue StandardError
|
|
295
301
|
'✗ down'
|
|
296
302
|
end
|
|
297
303
|
|
|
298
304
|
def check_pgbouncer_running(host)
|
|
299
|
-
|
|
300
|
-
result = capture(:sudo, 'systemctl', 'is-active', 'pgbouncer').strip
|
|
301
|
-
result == 'active'
|
|
302
|
-
end
|
|
305
|
+
check_pgbouncer_direct(host)
|
|
303
306
|
rescue StandardError
|
|
304
307
|
false
|
|
305
308
|
end
|
|
306
309
|
|
|
307
|
-
def check_pgbouncer_userlist(
|
|
308
|
-
|
|
309
|
-
|
|
310
|
+
def check_pgbouncer_userlist(_host)
|
|
311
|
+
true
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def check_pgbouncer_direct(host)
|
|
315
|
+
require 'socket'
|
|
316
|
+
connection_host = config.connection_host_for(host)
|
|
317
|
+
pgbouncer_port = config.component_config(:pgbouncer)[:listen_port] || 6432
|
|
310
318
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
end
|
|
319
|
+
socket = TCPSocket.new(connection_host, pgbouncer_port)
|
|
320
|
+
socket.close
|
|
321
|
+
true
|
|
315
322
|
rescue StandardError
|
|
316
323
|
false
|
|
317
324
|
end
|
data/lib/active_postgres.rb
CHANGED
|
@@ -21,6 +21,7 @@ require_relative 'active_postgres/standby_deployment_flow'
|
|
|
21
21
|
require_relative 'active_postgres/cli'
|
|
22
22
|
require_relative 'active_postgres/installer'
|
|
23
23
|
require_relative 'active_postgres/ssh_executor'
|
|
24
|
+
require_relative 'active_postgres/direct_executor'
|
|
24
25
|
require_relative 'active_postgres/health_checker'
|
|
25
26
|
require_relative 'active_postgres/failover'
|
|
26
27
|
require_relative 'active_postgres/performance_tuner'
|
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.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- BoringCache
|
|
@@ -169,6 +169,7 @@ files:
|
|
|
169
169
|
- lib/active_postgres/connection_pooler.rb
|
|
170
170
|
- lib/active_postgres/credentials.rb
|
|
171
171
|
- lib/active_postgres/deployment_flow.rb
|
|
172
|
+
- lib/active_postgres/direct_executor.rb
|
|
172
173
|
- lib/active_postgres/error_handler.rb
|
|
173
174
|
- lib/active_postgres/failover.rb
|
|
174
175
|
- lib/active_postgres/generators/active_postgres/install_generator.rb
|
|
@@ -220,7 +221,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
220
221
|
- !ruby/object:Gem::Version
|
|
221
222
|
version: '0'
|
|
222
223
|
requirements: []
|
|
223
|
-
rubygems_version: 3.
|
|
224
|
+
rubygems_version: 3.6.9
|
|
224
225
|
specification_version: 4
|
|
225
226
|
summary: PostgreSQL High Availability for Rails, made simple
|
|
226
227
|
test_files: []
|