CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/msfdb_helpers/pg_ctlcluster.rb
Views: 11766
1
require 'msfdb_helpers/db_interface'
2
3
module MsfdbHelpers
4
class PgCtlcluster < DbInterface
5
6
def initialize(db_path:, options:, localconf:, db_conf:)
7
@db = db_path
8
@options = options
9
@pg_version = get_postgres_version
10
@localconf = localconf
11
@db_conf = db_conf
12
@pg_cluster_conf_root = "#{@localconf}/.local/etc/postgresql"
13
ENV['PG_CLUSTER_CONF_ROOT'] = @pg_cluster_conf_root
14
super(options)
15
end
16
17
def init(msf_pass, msftest_pass)
18
puts "Creating database at #{@db}"
19
Dir.mkdir(@db)
20
FileUtils.mkdir_p(@pg_cluster_conf_root)
21
run_cmd("pg_createcluster --user=$(whoami) -l #{@db.shellescape}/log -d #{@db.shellescape} -s /tmp --encoding=UTF8 #{@pg_version} #{@options[:msf_db_name].shellescape} -- --username=$(whoami) --auth-host=trust --auth-local=trust")
22
File.open("#{@pg_cluster_conf_root}/#{@pg_version}/#{@options[:msf_db_name]}/postgresql.conf", 'a') do |f|
23
f.puts "port = #{@options[:db_port]}"
24
end
25
26
start
27
28
create_db_users(msf_pass, msftest_pass)
29
30
write_db_client_auth_config
31
restart
32
end
33
34
def delete
35
if exists?
36
stop
37
38
if @options[:delete_existing_data]
39
puts "Deleting all data at #{@db}"
40
run_cmd("pg_dropcluster #{@pg_version} #{@options[:msf_db_name].shellescape}")
41
FileUtils.rm_rf(@db)
42
FileUtils.rm_rf("#{@localconf}/.local/etc/postgresql")
43
FileUtils.rm_r(@db_conf, force: true)
44
end
45
else
46
puts "No data at #{@db}, doing nothing"
47
end
48
end
49
50
def start
51
print "Starting database at #{@db}..."
52
status = run_cmd("pg_ctlcluster #{@pg_version} #{@options[:msf_db_name].shellescape} start -- -o \"-p #{@options[:db_port]}\" -D #{@db.shellescape} -l #{@db.shellescape}/log")
53
case status
54
when 0
55
puts 'success'.green.bold.to_s
56
return true
57
when 2
58
puts "Database already started at #{@db}"
59
return true
60
else
61
puts 'failed'.red.bold.to_s
62
return false
63
end
64
end
65
66
def stop
67
run_cmd("pg_ctlcluster #{get_postgres_version} #{@options[:msf_db_name].shellescape} stop -- -o \"-p #{@options[:db_port]}\" -D #{@db.shellescape}")
68
end
69
70
def restart
71
run_cmd("pg_ctlcluster #{@pg_version} #{@options[:msf_db_name].shellescape} reload -- -o \"-p #{@options[:db_port]}\" -D #{@db.shellescape} -l #{@db.shellescape}/log")
72
end
73
74
def exists?
75
Dir.exist?(@db)
76
end
77
78
def status
79
if exists?
80
if run_cmd("pg_ctlcluster #{@pg_version} #{@options[:msf_db_name].shellescape} status -- -o \"-p #{@options[:db_port]}\" -D #{@db.shellescape}") == 0
81
DatabaseStatus::RUNNING
82
else
83
DatabaseStatus::INACTIVE
84
end
85
else
86
DatabaseStatus::NOT_FOUND
87
end
88
end
89
90
def write_db_client_auth_config
91
client_auth_config = "#{@pg_cluster_conf_root}/#{@pg_version}/#{@options[:msf_db_name]}/pg_hba.conf"
92
super(client_auth_config)
93
end
94
95
def self.requirements
96
%w[psql pg_ctlcluster pg_dropcluster pg_createcluster pg_config]
97
end
98
99
private
100
101
def get_postgres_version
102
output, _status = Open3.capture2('pg_config --version') # Example outputs
103
# PostgreSQL 12.6 (Ubuntu 12.6-0ubuntu0.20.04.1)
104
# PostgreSQL 13.2 (Debian 13.2-1)
105
# PostgreSQL 11.11
106
/PostgreSQL\s(?<version>\d+)\.\d+/ =~ output
107
version
108
end
109
110
def create_db_users(msf_pass, msftest_pass)
111
puts 'Creating database users'
112
run_psql("create user #{@options[:msf_db_user].shellescape} with password '#{msf_pass}'")
113
run_psql("create user #{@options[:msftest_db_user].shellescape} with password '#{msftest_pass}'")
114
run_psql("alter role #{@options[:msf_db_user].shellescape} createdb")
115
run_psql("alter role #{@options[:msftest_db_user].shellescape} createdb")
116
run_psql("alter role #{@options[:msf_db_user].shellescape} with password '#{msf_pass}'")
117
run_psql("alter role #{@options[:msftest_db_user].shellescape} with password '#{msftest_pass}'")
118
119
conn = PG.connect(host: @options[:db_host], dbname: 'postgres', port: @options[:db_port], user: @options[:msf_db_user], password: msf_pass)
120
conn.exec("CREATE DATABASE #{@options[:msf_db_name]}")
121
conn.exec("CREATE DATABASE #{@options[:msftest_db_name]}")
122
conn.finish
123
end
124
end
125
end
126
127