dust-deploy 0.7.6 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/changelog.md +28 -0
- data/lib/dust/recipes/iptables.rb +71 -50
- data/lib/dust/recipes/mysql.rb +13 -63
- data/lib/dust/recipes/postgres.rb +49 -85
- data/lib/dust/recipes/sysctl.rb +57 -10
- data/lib/dust/version.rb +1 -1
- metadata +4 -4
data/changelog.md
CHANGED
@@ -1,6 +1,34 @@
|
|
1
1
|
Changelog
|
2
2
|
=============
|
3
3
|
|
4
|
+
0.8.0
|
5
|
+
------------
|
6
|
+
|
7
|
+
- adds templates support for sysctl recipe (database, mysql and postgres templates are supported)
|
8
|
+
- removes automatic sysctl configuration from database recipes (mysql and postgres)
|
9
|
+
to preserve the way it was, you have to add the according database template to your sysctl configuration:
|
10
|
+
|
11
|
+
recipes:
|
12
|
+
postgres:
|
13
|
+
<your postgres configuration here>
|
14
|
+
|
15
|
+
sysctl:
|
16
|
+
templates: postgres
|
17
|
+
<your sysctl configuration here>
|
18
|
+
|
19
|
+
|
20
|
+
- iptables: fixes a small issue where custom chains in tables != filter were not cleared correctly
|
21
|
+
- iptables: support custom chains now
|
22
|
+
|
23
|
+
recipes:
|
24
|
+
iptables:
|
25
|
+
input:
|
26
|
+
rule_1: { ..., jump: CUSTOM }
|
27
|
+
custom:
|
28
|
+
custom_1: ...
|
29
|
+
|
30
|
+
|
31
|
+
|
4
32
|
0.7.6
|
5
33
|
------------
|
6
34
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'ipaddress'
|
2
2
|
|
3
3
|
class Iptables < Recipe
|
4
|
-
|
4
|
+
|
5
5
|
desc 'iptables:deploy', 'configures iptables firewall'
|
6
6
|
def deploy
|
7
7
|
# list of all tables and chains
|
@@ -17,22 +17,22 @@ class Iptables < Recipe
|
|
17
17
|
@tables['ipv6']['mangle'] = [ 'INPUT', 'OUTPUT', 'FORWARD', 'PREROUTING', 'POSTROUTING' ]
|
18
18
|
@tables['ipv6']['raw'] = [ 'OUTPUT', 'PREROUTING' ]
|
19
19
|
|
20
|
-
|
20
|
+
|
21
21
|
return unless install
|
22
|
-
|
22
|
+
|
23
23
|
[4, 6].each do |v|
|
24
|
-
@script = ''
|
24
|
+
@script = ''
|
25
25
|
@ip_version = v
|
26
|
-
|
26
|
+
|
27
27
|
::Dust.print_msg "generating ipv#{@ip_version} rules\n"
|
28
28
|
|
29
|
-
|
29
|
+
clear_all
|
30
30
|
populate_rule_defaults
|
31
31
|
generate_all_rules
|
32
|
-
|
32
|
+
|
33
33
|
deploy_script
|
34
34
|
apply_rules
|
35
|
-
|
35
|
+
|
36
36
|
puts
|
37
37
|
end
|
38
38
|
end
|
@@ -54,18 +54,20 @@ class Iptables < Recipe
|
|
54
54
|
return false unless @node.install_package 'iptables-ipv6' if @node.uses_rpm? and not @node.is_fedora?
|
55
55
|
true
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
# deletes all rules/chains
|
59
|
-
def
|
59
|
+
def clear_all
|
60
60
|
return if @node.uses_rpm?
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
61
|
+
|
62
|
+
@tables['ipv' + @ip_version.to_s].keys.each do |table|
|
63
|
+
# clear all rules
|
64
|
+
@script.concat "--flush --table #{table}\n"
|
65
|
+
|
66
|
+
# delete all custom chains
|
67
|
+
@script.concat "--delete-chain --table #{table}\n" unless @node.uses_rpm?
|
68
|
+
end
|
67
69
|
end
|
68
|
-
|
70
|
+
|
69
71
|
# inserts default values to chains, if not given
|
70
72
|
# table defaults to filter
|
71
73
|
# jump target to ACCEPT
|
@@ -81,11 +83,11 @@ class Iptables < Recipe
|
|
81
83
|
end
|
82
84
|
end
|
83
85
|
end
|
84
|
-
|
86
|
+
|
85
87
|
# generates all iptables rules
|
86
88
|
def generate_all_rules
|
87
89
|
@tables['ipv' + @ip_version.to_s].each do |table, chains|
|
88
|
-
@script.concat "*#{table}\n" if @node.uses_rpm?
|
90
|
+
@script.concat "*#{table}\n" if @node.uses_rpm?
|
89
91
|
set_chain_policies table
|
90
92
|
generate_rules_for_table table
|
91
93
|
end
|
@@ -93,21 +95,40 @@ class Iptables < Recipe
|
|
93
95
|
|
94
96
|
# set the chain default policies to DROP/ACCEPT
|
95
97
|
# according to whether chain is specified in config file
|
98
|
+
# and create custom chains
|
96
99
|
def set_chain_policies table
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
+
|
101
|
+
# build in chains
|
100
102
|
@tables['ipv' + @ip_version.to_s][table].each do |chain|
|
101
103
|
policy = get_chain_policy table, chain
|
102
|
-
#::Dust.print_msg "#{table}/#{chain} -> #{policy}", :indent => 4
|
103
104
|
|
104
105
|
if @node.uses_rpm?
|
105
106
|
@script.concat ":#{chain.upcase} #{policy} [0:0]\n"
|
106
107
|
else
|
107
108
|
@script.concat "--table #{table} --policy #{chain.upcase} #{policy}\n"
|
108
109
|
end
|
109
|
-
|
110
|
-
|
110
|
+
end
|
111
|
+
|
112
|
+
# custom chains
|
113
|
+
@config.each do |chain, chain_rules|
|
114
|
+
# filter out build in chains
|
115
|
+
next if @tables['ipv' + @ip_version.to_s][table].include? chain.upcase
|
116
|
+
|
117
|
+
# only continue if this chain is used in this table
|
118
|
+
chain_used_in_table = false
|
119
|
+
chain_rules.each do |name, rule|
|
120
|
+
if rule['table'].include? table
|
121
|
+
chain_used_in_table = true
|
122
|
+
break
|
123
|
+
end
|
124
|
+
end
|
125
|
+
next unless chain_used_in_table
|
126
|
+
|
127
|
+
if @node.uses_rpm?
|
128
|
+
@script.concat ":#{chain.upcase} - [0:0]\n"
|
129
|
+
else
|
130
|
+
@script.concat "--table #{table} --new-chain #{chain.upcase}\n"
|
131
|
+
end
|
111
132
|
end
|
112
133
|
end
|
113
134
|
|
@@ -130,12 +151,12 @@ class Iptables < Recipe
|
|
130
151
|
@config.each do |chain, chain_rules|
|
131
152
|
rules = get_rules_for_table chain_rules, table
|
132
153
|
next if rules.empty?
|
133
|
-
|
154
|
+
|
134
155
|
#::Dust.print_msg "#{::Dust.pink}#{chain}#{::Dust.none} rules\n", :indent => 3
|
135
156
|
rules.sort.each do |name, rule|
|
136
157
|
next unless rule['table'].include? table
|
137
158
|
next unless check_ip_version rule
|
138
|
-
|
159
|
+
|
139
160
|
::Dust.print_msg "adding rule: #{name}", :indent => 2
|
140
161
|
generate_iptables_string chain, rule
|
141
162
|
::Dust.print_ok
|
@@ -143,11 +164,11 @@ class Iptables < Recipe
|
|
143
164
|
end
|
144
165
|
@script.concat "COMMIT\n" if @node.uses_rpm?
|
145
166
|
end
|
146
|
-
|
167
|
+
|
147
168
|
def get_rules_for_table rules, table
|
148
169
|
rules.select { |name, rule| rule['table'].include? table }
|
149
170
|
end
|
150
|
-
|
171
|
+
|
151
172
|
# check if source and destination ip (if given)
|
152
173
|
# are valid ips for this ip version
|
153
174
|
def check_ip_version rule
|
@@ -161,8 +182,8 @@ class Iptables < Recipe
|
|
161
182
|
return false unless rule['ip-version'].include? @ip_version if rule['ip-version']
|
162
183
|
end
|
163
184
|
true
|
164
|
-
end
|
165
|
-
|
185
|
+
end
|
186
|
+
|
166
187
|
# generates the iptables string out of a rule
|
167
188
|
def generate_iptables_string chain, rule
|
168
189
|
parse_rule(rule).each do |r|
|
@@ -175,17 +196,17 @@ class Iptables < Recipe
|
|
175
196
|
def parse_rule r
|
176
197
|
with_dashes = {}
|
177
198
|
result = []
|
178
|
-
|
199
|
+
|
179
200
|
# map r[key] = value to '--key value'
|
180
201
|
r.each do |k, v|
|
181
202
|
next if k == 'ip-version' # skip ip-version, since its not iptables option
|
182
203
|
next if k == 'table' if @node.uses_rpm? # rpm-firewall takes table argument with *table
|
183
|
-
|
204
|
+
|
184
205
|
with_dashes[k] = r[k].map do |v|
|
185
206
|
value = v.to_s
|
186
207
|
if value.start_with? '!', '! '
|
187
208
|
# map '--key ! value' to '! --key value'
|
188
|
-
value.slice! '!'
|
209
|
+
value.slice! '!'
|
189
210
|
value.lstrip!
|
190
211
|
"! --#{k} #{value}"
|
191
212
|
else
|
@@ -194,11 +215,11 @@ class Iptables < Recipe
|
|
194
215
|
end
|
195
216
|
end
|
196
217
|
with_dashes.values.each { |a| result = result.combine a }
|
197
|
-
|
218
|
+
|
198
219
|
sort_rule_options result
|
199
220
|
end
|
200
|
-
|
201
|
-
# make sure the options are sorted in a way that works.
|
221
|
+
|
222
|
+
# make sure the options are sorted in a way that works.
|
202
223
|
def sort_rule_options rule
|
203
224
|
sorted = []
|
204
225
|
rule.each do |r|
|
@@ -228,22 +249,22 @@ class Iptables < Recipe
|
|
228
249
|
end
|
229
250
|
sorted.push r
|
230
251
|
end
|
231
|
-
|
232
|
-
sorted
|
252
|
+
|
253
|
+
sorted
|
233
254
|
end
|
234
|
-
|
235
|
-
def deploy_script
|
255
|
+
|
256
|
+
def deploy_script
|
236
257
|
target = get_target
|
237
|
-
|
258
|
+
|
238
259
|
prepend_cmd
|
239
|
-
prepend_header
|
240
|
-
|
260
|
+
prepend_header
|
261
|
+
|
241
262
|
@node.write target, @script, :quiet => true
|
242
263
|
|
243
264
|
if @node.uses_rpm?
|
244
265
|
@node.chmod '600', target
|
245
266
|
else
|
246
|
-
@node.chmod '700', target
|
267
|
+
@node.chmod '700', target
|
247
268
|
end
|
248
269
|
end
|
249
270
|
|
@@ -252,17 +273,17 @@ class Iptables < Recipe
|
|
252
273
|
@script.insert 0, "#!/bin/sh\n" unless @node.uses_rpm?
|
253
274
|
@script.insert 0, "# automatically generated by dust\n\n"
|
254
275
|
end
|
255
|
-
|
276
|
+
|
256
277
|
# prepend iptables command on non-centos-like machines
|
257
278
|
def prepend_cmd
|
258
279
|
@script.gsub! /^/, "#{cmd} " unless @node.uses_rpm?
|
259
280
|
end
|
260
|
-
|
281
|
+
|
261
282
|
# apply newly pushed rules
|
262
283
|
def apply_rules
|
263
284
|
if @options.restart?
|
264
285
|
::Dust.print_msg "applying ipv#{@ip_version} rules"
|
265
|
-
|
286
|
+
|
266
287
|
if @node.uses_rpm?
|
267
288
|
::Dust.print_result @node.exec("/etc/init.d/#{cmd} restart")[:exit_code]
|
268
289
|
|
@@ -282,12 +303,12 @@ class Iptables < Recipe
|
|
282
303
|
|
283
304
|
# set the target file depending on distribution
|
284
305
|
def get_target
|
285
|
-
target = "/etc/#{cmd}"
|
306
|
+
target = "/etc/#{cmd}"
|
286
307
|
target = "/etc/network/if-pre-up.d/#{cmd}" if @node.uses_apt?
|
287
308
|
target = "/etc/sysconfig/#{cmd}" if @node.uses_rpm?
|
288
309
|
target
|
289
310
|
end
|
290
|
-
|
311
|
+
|
291
312
|
def cmd
|
292
313
|
return 'iptables' if @ip_version == 4
|
293
314
|
return 'ip6tables' if @ip_version == 6
|
data/lib/dust/recipes/mysql.rb
CHANGED
@@ -5,7 +5,7 @@ class Mysql < Recipe
|
|
5
5
|
@node.install_package 'mysql-server'
|
6
6
|
|
7
7
|
@config = default_config.deep_merge @config
|
8
|
-
|
8
|
+
|
9
9
|
::Dust.print_msg "configuring mysql\n"
|
10
10
|
::Dust.print_ok "listen on #{@config['mysqld']['bind-address']}:#{@config['mysqld']['port']}", :indent => 2
|
11
11
|
|
@@ -14,22 +14,20 @@ class Mysql < Recipe
|
|
14
14
|
|
15
15
|
@node.write '/etc/mysql/my.cnf', generate_my_cnf
|
16
16
|
@node.chmod '644', '/etc/mysql/my.cnf'
|
17
|
-
|
18
|
-
configure_sysctl
|
19
|
-
|
17
|
+
|
20
18
|
@node.restart_service 'mysql' if options.restart?
|
21
19
|
@node.reload_service 'mysql' if options.reload?
|
22
20
|
end
|
23
|
-
|
21
|
+
|
24
22
|
desc 'mysql:status', 'displays status of the mysql daemon'
|
25
23
|
def status
|
26
24
|
return unless @node.package_installed? 'mysql-server'
|
27
25
|
@node.print_service_status 'mysql'
|
28
26
|
end
|
29
27
|
|
30
|
-
|
28
|
+
|
31
29
|
private
|
32
|
-
|
30
|
+
|
33
31
|
def default_config
|
34
32
|
{ 'client' => {
|
35
33
|
'port' => 3306,
|
@@ -45,7 +43,7 @@ class Mysql < Recipe
|
|
45
43
|
'user' => 'mysql',
|
46
44
|
'pid-file' => '/var/run/mysqld/mysqld.pid',
|
47
45
|
'socket' => '/var/run/mysqld/mysqld.sock',
|
48
|
-
'language' => '/usr/share/mysql/english',
|
46
|
+
'language' => '/usr/share/mysql/english',
|
49
47
|
'basedir' => '/usr',
|
50
48
|
'datadir' => '/var/lib/mysql',
|
51
49
|
'tmpdir' => '/tmp',
|
@@ -76,25 +74,25 @@ class Mysql < Recipe
|
|
76
74
|
}
|
77
75
|
}
|
78
76
|
end
|
79
|
-
|
77
|
+
|
80
78
|
def get_innodb_buffer_pool_size
|
81
79
|
# allocate 70% of the available ram to mysql
|
82
80
|
# but leave max 1gb to system
|
83
81
|
unless @config['mysqld']['innodb_buffer_pool_size']
|
84
82
|
::Dust.print_msg 'autoconfiguring innodb buffer size', :indent => 2
|
85
83
|
@node.collect_facts :quiet => true
|
86
|
-
|
84
|
+
|
87
85
|
# get system memory (in kb)
|
88
86
|
system_mem = ::Dust.convert_size @node['memorysize']
|
89
|
-
|
87
|
+
|
90
88
|
# allocate 80% of the available ram to mysql
|
91
89
|
buffer_pool = (system_mem * 0.7).to_i
|
92
|
-
|
90
|
+
|
93
91
|
::Dust.print_ok
|
94
92
|
"#{buffer_pool / 1024}M"
|
95
|
-
end
|
93
|
+
end
|
96
94
|
end
|
97
|
-
|
95
|
+
|
98
96
|
def generate_my_cnf
|
99
97
|
my_cnf = ''
|
100
98
|
@config.each do |category, config|
|
@@ -102,57 +100,9 @@ class Mysql < Recipe
|
|
102
100
|
config.each { |key, value| my_cnf.concat "#{key} = #{value}\n" }
|
103
101
|
my_cnf.concat "\n"
|
104
102
|
end
|
105
|
-
|
103
|
+
|
106
104
|
# add includedir
|
107
105
|
my_cnf.concat "!includedir /etc/mysql/conf.d/\n"
|
108
106
|
my_cnf
|
109
107
|
end
|
110
|
-
|
111
|
-
# increase shm memory
|
112
|
-
def configure_sysctl
|
113
|
-
if @node.uses_apt?
|
114
|
-
::Dust.print_msg "setting mysql sysctl keys\n"
|
115
|
-
@node.collect_facts :quiet => true
|
116
|
-
|
117
|
-
# make sure system allows more than innodb_buffer_pool_size of memory ram to be allocated
|
118
|
-
# shmmax = (convert_mysql_size(@config['mysqld']['innodb_buffer_pool_size']) * 1.1).to_i # TODO: 1.1?
|
119
|
-
|
120
|
-
# get pagesize
|
121
|
-
pagesize = @node.exec('getconf PAGESIZE')[:stdout].to_i || 4096
|
122
|
-
|
123
|
-
# use half of system memory for shmmax
|
124
|
-
shmmax = ::Dust.convert_size(@node['memorysize']) * 1024 / 2
|
125
|
-
shmall = shmmax / pagesize
|
126
|
-
|
127
|
-
::Dust.print_msg "setting shmmax to: #{shmmax}", :indent => 2
|
128
|
-
::Dust.print_result @node.exec("sysctl -w kernel.shmmax=#{shmmax}")[:exit_code]
|
129
|
-
::Dust.print_msg "setting shmall to: #{shmall}", :indent => 2
|
130
|
-
::Dust.print_result @node.exec("sysctl -w kernel.shmall=#{shmall}")[:exit_code]
|
131
|
-
::Dust.print_msg 'setting swappiness to 0', :indent => 2
|
132
|
-
::Dust.print_result @node.exec('sysctl -w vm.swappiness=0')[:exit_code]
|
133
|
-
|
134
|
-
file = ''
|
135
|
-
file += "kernel.shmmax=#{shmmax}\n"
|
136
|
-
file += "kernel.shmall=#{shmall}\n"
|
137
|
-
file += "vm.swappiness=0\n" # rather shrink cache then use swap as filesystem cache
|
138
|
-
|
139
|
-
@node.write "/etc/sysctl.d/30-mysql-shm.conf", file
|
140
|
-
|
141
|
-
else
|
142
|
-
::Dust.print_warning 'sysctl configuration not supported for your os'
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def convert_mysql_size s
|
147
|
-
case s[-1].chr
|
148
|
-
when 'K'
|
149
|
-
return (s[0..-2].to_f * 1024).to_i
|
150
|
-
when 'M'
|
151
|
-
return (s[0..-2].to_f * 1024 * 1024).to_i
|
152
|
-
when 'G'
|
153
|
-
return (s[0..-2].to_f * 1024 * 1024 * 1024).to_i
|
154
|
-
else
|
155
|
-
return s.to_i
|
156
|
-
end
|
157
|
-
end
|
158
108
|
end
|
@@ -3,21 +3,20 @@ class Postgres < Recipe
|
|
3
3
|
def deploy
|
4
4
|
return ::Dust.print_failed 'no version specified' unless @config['version']
|
5
5
|
return unless install_postgres
|
6
|
-
|
6
|
+
|
7
7
|
# default cluster on debian-like systems is 'main'
|
8
8
|
@config['cluster'] ||= 'main' if @node.uses_apt?
|
9
|
-
|
9
|
+
|
10
10
|
set_default_directories
|
11
11
|
deploy_config
|
12
12
|
deploy_recovery
|
13
13
|
deploy_certificates if @config['server.crt'] and @config['server.key']
|
14
14
|
create_archive
|
15
15
|
set_permissions
|
16
|
-
|
17
|
-
|
16
|
+
|
18
17
|
deploy_pacemaker_script if @node.package_installed? 'pacemaker', :quiet => true
|
19
18
|
configure_for_zabbix if zabbix_installed?
|
20
|
-
|
19
|
+
|
21
20
|
# reload/restart postgres if command line option is given
|
22
21
|
@node.restart_service @config['service_name'] if options.restart?
|
23
22
|
@node.reload_service @config['service_name'] if options.reload?
|
@@ -29,22 +28,22 @@ class Postgres < Recipe
|
|
29
28
|
set_default_directories
|
30
29
|
@node.print_service_status @config['service_name']
|
31
30
|
end
|
32
|
-
|
31
|
+
|
33
32
|
private
|
34
|
-
|
33
|
+
|
35
34
|
def install_postgres
|
36
|
-
if @node.uses_apt?
|
35
|
+
if @node.uses_apt?
|
37
36
|
package = "postgresql-#{@config['version']}"
|
38
|
-
elsif @node.uses_emerge?
|
37
|
+
elsif @node.uses_emerge?
|
39
38
|
package = 'postgresql-server'
|
40
39
|
else
|
41
40
|
return ::Dust.print_failed 'os not supported'
|
42
41
|
end
|
43
|
-
|
42
|
+
|
44
43
|
@node.install_package package
|
45
44
|
|
46
45
|
# also install the postgresql meta package
|
47
|
-
@node.install_package 'postgresql' if @node.uses_apt?
|
46
|
+
# @node.install_package 'postgresql' if @node.uses_apt?
|
48
47
|
end
|
49
48
|
|
50
49
|
# set conf-dir, archive-dir and data-dir as well as service-name
|
@@ -54,19 +53,19 @@ class Postgres < Recipe
|
|
54
53
|
@config['conf_directory'] ||= "/etc/postgresql-#{@config['version']}"
|
55
54
|
@config['archive_directory'] ||= "/var/lib/postgresql/#{@config['version']}/archive"
|
56
55
|
@config['service_name'] ||= "postgresql-#{@config['version']}"
|
57
|
-
@config['postgresql.conf']['data_directory'] ||= "/var/lib/postgresql/#{@config['version']}/data"
|
58
|
-
|
56
|
+
@config['postgresql.conf']['data_directory'] ||= "/var/lib/postgresql/#{@config['version']}/data"
|
57
|
+
|
59
58
|
elsif @node.uses_apt?
|
60
59
|
@config['postgresql.conf']['data_directory'] ||= "/var/lib/postgresql/#{@config['version']}/#{@config['cluster']}"
|
61
60
|
@config['conf_directory'] ||= "/etc/postgresql/#{@config['version']}/#{@config['cluster']}"
|
62
61
|
@config['archive_directory'] ||= "/var/lib/postgresql/#{@config['version']}/#{@config['cluster']}-archive"
|
63
62
|
@config['service_name'] ||= 'postgresql'
|
64
63
|
end
|
65
|
-
|
64
|
+
|
66
65
|
@config['postgresql.conf']['hba_file'] ||= "#{@config['conf_directory']}/pg_hba.conf"
|
67
|
-
@config['postgresql.conf']['ident_file'] ||= "#{@config['conf_directory']}/pg_ident.conf"
|
66
|
+
@config['postgresql.conf']['ident_file'] ||= "#{@config['conf_directory']}/pg_ident.conf"
|
68
67
|
end
|
69
|
-
|
68
|
+
|
70
69
|
# deploy postgresql.conf, pg_hba.conf and pg_ident.conf
|
71
70
|
def deploy_config
|
72
71
|
@node.write "#{@config['conf_directory']}/postgresql.conf", generate_postgresql_conf
|
@@ -76,7 +75,7 @@ class Postgres < Recipe
|
|
76
75
|
@node.chmod '644', "#{@config['conf_directory']}/pg_hba.conf"
|
77
76
|
@node.chmod '644', "#{@config['conf_directory']}/pg_ident.conf"
|
78
77
|
end
|
79
|
-
|
78
|
+
|
80
79
|
# copy recovery.conf to either recovery.conf or recovery.done
|
81
80
|
# depending on which file already exists.
|
82
81
|
def deploy_recovery
|
@@ -86,48 +85,13 @@ class Postgres < Recipe
|
|
86
85
|
@node.write "#{@config['postgresql.conf']['data_directory']}/recovery.done", generate_recovery_conf
|
87
86
|
end
|
88
87
|
end
|
89
|
-
|
90
|
-
# deploy certificates to data-dir
|
88
|
+
|
89
|
+
# deploy certificates to data-dir
|
91
90
|
def deploy_certificates
|
92
91
|
@node.deploy_file "#{@template_path}/#{@config['server.crt']}", "#{@config['postgresql.conf']['data_directory']}/server.crt", :binding => binding
|
93
92
|
@node.deploy_file "#{@template_path}/#{@config['server.key']}", "#{@config['postgresql.conf']['data_directory']}/server.key", :binding => binding
|
94
93
|
end
|
95
94
|
|
96
|
-
# increase shm memory
|
97
|
-
def configure_sysctl
|
98
|
-
if @node.uses_apt?
|
99
|
-
::Dust.print_msg "setting postgres sysctl keys\n"
|
100
|
-
@node.collect_facts :quiet => true
|
101
|
-
|
102
|
-
# get pagesize
|
103
|
-
pagesize = @node.exec('getconf PAGESIZE')[:stdout].to_i || 4096
|
104
|
-
|
105
|
-
# use half of system memory for shmmax
|
106
|
-
shmmax = ::Dust.convert_size(@node['memorysize']) * 1024 / 2
|
107
|
-
shmall = shmmax / pagesize
|
108
|
-
|
109
|
-
::Dust.print_msg "setting shmmax to: #{shmmax}", :indent => 2
|
110
|
-
::Dust.print_result @node.exec("sysctl -w kernel.shmmax=#{shmmax}")[:exit_code]
|
111
|
-
::Dust.print_msg "setting shmall to: #{shmall}", :indent => 2
|
112
|
-
::Dust.print_result @node.exec("sysctl -w kernel.shmall=#{shmall}")[:exit_code]
|
113
|
-
::Dust.print_msg 'setting overcommit memory to 2', :indent => 2
|
114
|
-
::Dust.print_result @node.exec('sysctl -w vm.overcommit_memory=2')[:exit_code]
|
115
|
-
::Dust.print_msg 'setting swappiness to 0', :indent => 2
|
116
|
-
::Dust.print_result @node.exec('sysctl -w vm.swappiness=0')[:exit_code]
|
117
|
-
|
118
|
-
file = ''
|
119
|
-
file += "kernel.shmmax=#{shmmax}\n"
|
120
|
-
file += "kernel.shmall=#{shmall}\n"
|
121
|
-
file += "vm.overcommit_memory=2\n" # don't allocate memory that's not there
|
122
|
-
file += "vm.swappiness=0\n" # rather shrink cache then use swap as filesystem cache
|
123
|
-
|
124
|
-
@node.write "/etc/sysctl.d/30-postgresql-shm.conf", file
|
125
|
-
|
126
|
-
else
|
127
|
-
::Dust.print_warning 'sysctl configuration not supported for your os'
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
95
|
# default settings for postgresql.conf
|
132
96
|
def default_postgres_conf
|
133
97
|
{ 'max_connections' => 100,
|
@@ -138,33 +102,33 @@ class Postgres < Recipe
|
|
138
102
|
'lc_time' => 'en_US.UTF-8',
|
139
103
|
'default_text_search_config' => 'pg_catalog.english' }
|
140
104
|
end
|
141
|
-
|
105
|
+
|
142
106
|
def generate_postgresql_conf
|
143
107
|
@config['postgresql.conf'] = default_postgres_conf.merge @config['postgresql.conf']
|
144
|
-
|
108
|
+
|
145
109
|
calculate_values
|
146
|
-
|
110
|
+
|
147
111
|
postgresql_conf = ''
|
148
112
|
@config['postgresql.conf'].each do |key, value|
|
149
113
|
value = "'#{value}'" if value.is_a? String # enclose strings in ''
|
150
114
|
postgresql_conf.concat "#{key} = #{value}\n"
|
151
115
|
end
|
152
|
-
|
116
|
+
|
153
117
|
postgresql_conf
|
154
118
|
end
|
155
|
-
|
119
|
+
|
156
120
|
def generate_recovery_conf
|
157
121
|
@config['recovery.conf'] ||= []
|
158
|
-
|
122
|
+
|
159
123
|
recovery_conf = ''
|
160
124
|
@config['recovery.conf'].each do |key, value|
|
161
125
|
value = "'#{value}'" if value.is_a? String # enclose strings in ''
|
162
126
|
recovery_conf.concat "#{key} = #{value}\n"
|
163
127
|
end
|
164
|
-
|
128
|
+
|
165
129
|
recovery_conf
|
166
130
|
end
|
167
|
-
|
131
|
+
|
168
132
|
def generate_pg_hba_conf
|
169
133
|
@config['pg_hba.conf'] ||= [ 'local all postgres trust' ]
|
170
134
|
@config['pg_hba.conf'].join "\n"
|
@@ -174,64 +138,64 @@ class Postgres < Recipe
|
|
174
138
|
@config['pg_ident.conf'] ||= []
|
175
139
|
@config['pg_ident.conf'].join "\n"
|
176
140
|
end
|
177
|
-
|
141
|
+
|
178
142
|
# try to find good values (but don't overwrite if set in config file) for
|
179
143
|
# shared_buffers, work_mem and maintenance_work_mem, effective_cache_size and wal_buffers
|
180
144
|
def calculate_values
|
181
145
|
@node.collect_facts :quiet => true
|
182
146
|
system_mem = ::Dust.convert_size(@node['memorysize']).to_f
|
183
|
-
|
147
|
+
|
184
148
|
::Dust.print_msg "calculating recommended settings for #{kb2mb system_mem} ram\n"
|
185
|
-
|
149
|
+
|
186
150
|
# every connection uses up to work_mem memory, so make sure that even if
|
187
151
|
# max_connections is reached, there's still a bit left.
|
188
152
|
# total available memory / (2 * max_connections)
|
189
153
|
@config['postgresql.conf']['work_mem'] ||= kb2mb(system_mem * 0.9 / @config['postgresql.conf']['max_connections'])
|
190
154
|
::Dust.print_ok "work_mem: #{@config['postgresql.conf']['work_mem']}", :indent => 2
|
191
|
-
|
155
|
+
|
192
156
|
# shared_buffers should be 0.2 - 0.3 of system ram
|
193
|
-
# unless ram is lower than 1gb, then less (32mb maybe)
|
157
|
+
# unless ram is lower than 1gb, then less (32mb maybe)
|
194
158
|
@config['postgresql.conf']['shared_buffers'] ||= kb2mb(system_mem * 0.25)
|
195
159
|
::Dust.print_ok "shared_buffers: #{@config['postgresql.conf']['shared_buffers']}", :indent => 2
|
196
|
-
|
197
|
-
# maintenance_work_mem, should be a lot higher than work_mem
|
160
|
+
|
161
|
+
# maintenance_work_mem, should be a lot higher than work_mem
|
198
162
|
# recommended value: 50mb for each 1gb of system ram
|
199
163
|
@config['postgresql.conf']['maintenance_work_mem'] ||= kb2mb(system_mem / 1024 * 50)
|
200
164
|
::Dust.print_ok "maintenance_work_mem: #{@config['postgresql.conf']['maintenance_work_mem']}", :indent => 2
|
201
|
-
|
165
|
+
|
202
166
|
# effective_cache_size between 0.6 and 0.8 of system ram
|
203
167
|
@config['postgresql.conf']['effective_cache_size'] ||= kb2mb(system_mem * 0.75)
|
204
168
|
::Dust.print_ok "effective_cache_size: #{@config['postgresql.conf']['effective_cache_size']}", :indent => 2
|
205
|
-
|
169
|
+
|
206
170
|
# wal_buffers should be between 2-16mb
|
207
171
|
@config['postgresql.conf']['wal_buffers'] ||= '12MB'
|
208
|
-
::Dust.print_ok "wal_buffers: #{@config['postgresql.conf']['wal_buffers']}", :indent => 2
|
172
|
+
::Dust.print_ok "wal_buffers: #{@config['postgresql.conf']['wal_buffers']}", :indent => 2
|
209
173
|
end
|
210
|
-
|
174
|
+
|
211
175
|
# converts plain kb value to "1234MB"
|
212
176
|
def kb2mb value
|
213
177
|
"#{(value / 1024).to_i}MB"
|
214
178
|
end
|
215
|
-
|
179
|
+
|
216
180
|
# give the configured dbuser the data_directory
|
217
181
|
def set_permissions
|
218
182
|
@node.chown @config['dbuser'], @config['postgresql.conf']['data_directory'] if @config['dbuser']
|
219
183
|
@node.chmod 'u+Xrw,g-rwx,o-rwx', @config['postgresql.conf']['data_directory']
|
220
184
|
end
|
221
|
-
|
185
|
+
|
222
186
|
# create archive dir
|
223
187
|
def create_archive
|
224
188
|
@node.mkdir @config['archive_directory']
|
225
189
|
@node.chown @config['dbuser'], @config['archive_directory'] if @config['dbuser']
|
226
190
|
@node.chmod 'u+Xrw,g-rwx,o-rwx', @config['archive_directory']
|
227
191
|
end
|
228
|
-
|
192
|
+
|
229
193
|
# deploy the pacemaker script
|
230
194
|
def deploy_pacemaker_script
|
231
195
|
@node.deploy_file "#{@template_path}/pacemaker.sh", "#{@config['conf_directory']}/pacemaker.sh", :binding => binding
|
232
196
|
@node.chmod '755', "#{@config['conf_directory']}/pacemaker.sh"
|
233
|
-
end
|
234
|
-
|
197
|
+
end
|
198
|
+
|
235
199
|
# check if zabbix is installed
|
236
200
|
def zabbix_installed?
|
237
201
|
if @node.uses_emerge?
|
@@ -240,7 +204,7 @@ class Postgres < Recipe
|
|
240
204
|
return @node.package_installed? 'zabbix-agent', :quiet => true
|
241
205
|
end
|
242
206
|
end
|
243
|
-
|
207
|
+
|
244
208
|
# configures postgres for zabbix monitoring:
|
245
209
|
# adds zabbix user to postgres group
|
246
210
|
# creates zabbix user in postgres and grant access to postgres database
|
@@ -248,24 +212,24 @@ class Postgres < Recipe
|
|
248
212
|
::Dust.print_msg "configuring postgres for zabbix monitoring\n"
|
249
213
|
::Dust.print_msg 'adding zabbix user to postgres group', :indent => 2
|
250
214
|
::Dust.print_result @node.exec('usermod -a -G postgres zabbix')[:exit_code]
|
251
|
-
|
215
|
+
|
252
216
|
if is_master? :indent => 2
|
253
217
|
::Dust.print_msg 'checking if zabbix user exists in postgres', :indent => 3
|
254
218
|
ret = ::Dust.print_result @node.exec('psql -U postgres -c ' +
|
255
219
|
' "SELECT usename FROM pg_user WHERE usename = \'zabbix\'"' +
|
256
220
|
' postgres |grep -q zabbix')[:exit_code]
|
257
|
-
|
221
|
+
|
258
222
|
# if user was not found, create him
|
259
223
|
unless ret
|
260
224
|
::Dust.print_msg 'create zabbix user in postgres', :indent => 4
|
261
225
|
::Dust.print_result @node.exec('createuser -U postgres zabbix -RSD')[:exit_code]
|
262
226
|
end
|
263
|
-
|
227
|
+
|
264
228
|
::Dust.print_msg 'GRANT zabbix user access to postgres database', :indent => 3
|
265
229
|
::Dust.print_result( @node.exec('psql -U postgres -c "GRANT SELECT ON pg_stat_database TO zabbix" postgres')[:exit_code] )
|
266
230
|
end
|
267
|
-
end
|
268
|
-
|
231
|
+
end
|
232
|
+
|
269
233
|
# checks if this server is a postgres master
|
270
234
|
def is_master? options = {}
|
271
235
|
::Dust.print_msg 'checking if this host is the postgres master: ', options
|
@@ -276,5 +240,5 @@ class Postgres < Recipe
|
|
276
240
|
::Dust.print_ok 'no', :indent => 0
|
277
241
|
return false
|
278
242
|
end
|
279
|
-
end
|
243
|
+
end
|
280
244
|
end
|
data/lib/dust/recipes/sysctl.rb
CHANGED
@@ -3,18 +3,65 @@ class Sysctl < Recipe
|
|
3
3
|
def deploy
|
4
4
|
# only debian derivatives are supported at the moment, since we need support for /etc/sysctl.d/
|
5
5
|
return ::Dust.print_warning 'sysctl configuration not supported for your linux distribution' unless @node.uses_apt?
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
|
7
|
+
# seperate templates from sysctls
|
8
|
+
sysctls = @config.clone
|
9
|
+
templates = sysctls.delete 'templates'
|
10
|
+
|
11
|
+
# apply template sysctls
|
12
|
+
if templates
|
13
|
+
templates.to_array.each do |template|
|
14
|
+
::Dust.print_msg "configuring sysctls for template #{template}\n"
|
15
|
+
apply template, self.send(template)
|
16
|
+
puts
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# apply plain sysctls
|
21
|
+
::Dust.print_msg "configuring plain sysctls\n"
|
22
|
+
apply 'dust', sysctls
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def apply name, sysctl
|
9
29
|
sysctl_conf = ''
|
10
|
-
|
11
|
-
::Dust.print_msg "setting #{key}
|
30
|
+
sysctl.each do |key, value|
|
31
|
+
::Dust.print_msg "setting #{key} = #{value}", :indent => 2
|
12
32
|
::Dust.print_result @node.exec("sysctl -w #{key}=#{value}")[:exit_code]
|
13
|
-
|
14
33
|
sysctl_conf.concat "#{key} = #{value}\n"
|
15
34
|
end
|
16
|
-
|
17
|
-
::Dust.print_msg
|
18
|
-
::Dust.print_result @node.write("/etc/sysctl.d/10
|
35
|
+
|
36
|
+
::Dust.print_msg "saving settings to /etc/sysctl.d/10-#{name}.conf", :indent => 2
|
37
|
+
::Dust.print_result @node.write("/etc/sysctl.d/10-#{name}.conf", sysctl_conf, :quiet => true)
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
### templates ###
|
42
|
+
|
43
|
+
# disable allocation of more ram than actually there for postgres
|
44
|
+
def postgres
|
45
|
+
database.merge 'vm.overcommit_memory' => 2
|
46
|
+
end
|
47
|
+
|
48
|
+
def mysql
|
49
|
+
database
|
50
|
+
end
|
51
|
+
|
52
|
+
# use half of the system memory for shmmax
|
53
|
+
# and set shmall according to pagesize
|
54
|
+
def database
|
55
|
+
@node.collect_facts :quiet => true
|
56
|
+
|
57
|
+
# get pagesize
|
58
|
+
pagesize = @node.exec('getconf PAGESIZE')[:stdout].to_i || 4096
|
59
|
+
|
60
|
+
# use half of system memory for shmmax
|
61
|
+
shmmax = ::Dust.convert_size(@node['memorysize']) * 1024 / 2
|
62
|
+
shmall = shmmax / pagesize
|
63
|
+
|
64
|
+
{ 'kernel.shmmax' => shmmax, 'kernel.shmall' => shmall }
|
19
65
|
end
|
20
|
-
|
66
|
+
|
67
|
+
end
|
data/lib/dust/version.rb
CHANGED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 8
|
8
|
+
- 0
|
9
|
+
version: 0.8.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- kris kechagia
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2012-
|
17
|
+
date: 2012-03-07 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|