dust-deploy 0.4.4 → 0.4.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.
- data/changelog.md +10 -0
- data/lib/dust/recipes/duplicity.rb +3 -3
- data/lib/dust/recipes/pacemaker.rb +35 -0
- data/lib/dust/recipes/postgres.rb +86 -20
- data/lib/dust/recipes/sudoers.rb +46 -0
- data/lib/dust/recipes/zabbix_agent.rb +0 -34
- data/lib/dust/server.rb +24 -27
- data/lib/dust/version.rb +1 -1
- metadata +5 -3
data/changelog.md
CHANGED
@@ -1,6 +1,16 @@
|
|
1
1
|
Changelog
|
2
2
|
=============
|
3
3
|
|
4
|
+
0.4.5
|
5
|
+
------------
|
6
|
+
|
7
|
+
- node.write and node.append now not using echo for writing files on the server anymore.
|
8
|
+
this solves problems with binary files and files including backticks (`)
|
9
|
+
- adds pacemaker recipe, for basic setup and configuration of corosync/pacemaker
|
10
|
+
- adds sudoers recipe for maintaining your sudoers rules
|
11
|
+
- postgres recipe now checks if zabbix is installed, and if so configures the node for monitoring
|
12
|
+
|
13
|
+
|
4
14
|
0.4.4
|
5
15
|
------------
|
6
16
|
|
@@ -34,9 +34,9 @@ class Duplicity < Recipe
|
|
34
34
|
# add hostkey to known_hosts
|
35
35
|
if config['hostkey']
|
36
36
|
::Dust.print_msg 'checking if ssh key is in known_hosts'
|
37
|
-
unless ::Dust.print_result @node.exec("grep -q '#{config['hostkey']}'
|
38
|
-
@node.mkdir '
|
39
|
-
@node.append '
|
37
|
+
unless ::Dust.print_result @node.exec("grep -q '#{config['hostkey']}' /root/.ssh/known_hosts")[:exit_code] == 0
|
38
|
+
@node.mkdir '/root/.ssh', :indent => 2
|
39
|
+
@node.append '/root/.ssh/known_hosts', config['hostkey'], :indent => 2
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
class Pacemaker < Recipe
|
4
|
+
|
5
|
+
desc 'pacemaker:deploy', 'installs and configures corosync/pacemaker'
|
6
|
+
def deploy
|
7
|
+
# this recipe is only tested with ubuntu
|
8
|
+
return unless @node.uses_apt?
|
9
|
+
return unless @node.install_package 'pacemaker'
|
10
|
+
|
11
|
+
# return if no authkey is given
|
12
|
+
unless @config['authkey']
|
13
|
+
return ::Dust.print_failed 'no authkey given. generate it using "corosync-keygen" ' +
|
14
|
+
'and convert it to base64 using "base64 -w0 /etc/corosync/authkey"'
|
15
|
+
end
|
16
|
+
|
17
|
+
@node.collect_facts
|
18
|
+
|
19
|
+
# set defaults
|
20
|
+
@config['interface'] ||= 'eth0'
|
21
|
+
@config['mcastaddr'] ||= '226.13.37.1'
|
22
|
+
@config['mcastport'] ||= 5405
|
23
|
+
|
24
|
+
# set bindnetaddr to the ip address of @config['interface']
|
25
|
+
# unless it is specified manually in node config
|
26
|
+
@config['bindnetaddr'] ||= @node["ipaddress_#{@config['interface']}"]
|
27
|
+
|
28
|
+
# decode base64 authkey
|
29
|
+
@node.write '/etc/corosync/authkey', Base64.decode64(@config['authkey'])
|
30
|
+
@node.deploy_file "#{@template_path}/corosync.conf", '/etc/corosync/corosync.conf', :binding => binding
|
31
|
+
|
32
|
+
# not restarting automatically, because it provokes switching of ha services
|
33
|
+
#@node.restart_service 'corosync' if @options.restart
|
34
|
+
end
|
35
|
+
end
|
@@ -2,7 +2,26 @@ class Postgres < Recipe
|
|
2
2
|
desc 'postgres:deploy', 'installs and configures postgresql database'
|
3
3
|
def deploy
|
4
4
|
return ::Dust.print_failed 'no version specified' unless @config['version']
|
5
|
-
|
5
|
+
return ::Dust.print_failed 'os not supported' unless default_config
|
6
|
+
|
7
|
+
deploy_config
|
8
|
+
deploy_recovery
|
9
|
+
deploy_certificates
|
10
|
+
configure_sysctl
|
11
|
+
|
12
|
+
deploy_pacemaker_script if @node.package_installed? 'pacemaker'
|
13
|
+
configure_for_zabbix if zabbix_installed?
|
14
|
+
|
15
|
+
# reload/restart postgres if command line option is given
|
16
|
+
@node.restart_service @config['service-name'] if options.restart?
|
17
|
+
@node.reload_service @config['service-name'] if options.reload?
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# set default variables and make sure postgres is installed
|
24
|
+
def default_config
|
6
25
|
if @node.uses_emerge?
|
7
26
|
return unless @node.package_installed? 'postgresql-server'
|
8
27
|
@config['data-dir'] ||= "/var/lib/postgresql/#{@config['version']}/data"
|
@@ -18,10 +37,12 @@ class Postgres < Recipe
|
|
18
37
|
@config['service-name'] ||= 'postgresql'
|
19
38
|
|
20
39
|
else
|
21
|
-
return 'os not supported'
|
40
|
+
return ::Dust.print_failed 'os not supported yet'
|
22
41
|
end
|
42
|
+
end
|
23
43
|
|
24
|
-
|
44
|
+
# deploy standard postgres config
|
45
|
+
def deploy_config
|
25
46
|
@node.deploy_file "#{@template_path}/postgresql.conf", "#{@config['conf-dir']}/postgresql.conf", :binding => binding
|
26
47
|
@node.deploy_file "#{@template_path}/pg_hba.conf", "#{@config['conf-dir']}/pg_hba.conf", :binding => binding
|
27
48
|
@node.deploy_file "#{@template_path}/pg_ident.conf", "#{@config['conf-dir']}/pg_ident.conf", :binding => binding
|
@@ -29,22 +50,20 @@ class Postgres < Recipe
|
|
29
50
|
@node.chmod '644', "#{@config['conf-dir']}/postgresql.conf"
|
30
51
|
@node.chmod '644', "#{@config['conf-dir']}/pg_hba.conf"
|
31
52
|
@node.chmod '644', "#{@config['conf-dir']}/pg_ident.conf"
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
# copy recovery.conf to either recovery.conf or recovery.done
|
40
|
-
# depending on which file already exists.
|
53
|
+
end
|
54
|
+
|
55
|
+
# copy recovery.conf to either recovery.conf or recovery.done
|
56
|
+
# depending on which file already exists.
|
57
|
+
def deploy_recovery
|
41
58
|
if @node.file_exists? "#{@config['data-dir']}/recovery.conf", :quiet => true
|
42
59
|
@node.deploy_file "#{@template_path}/recovery.conf", "#{@config['data-dir']}/recovery.conf", :binding => binding
|
43
60
|
else
|
44
61
|
@node.deploy_file "#{@template_path}/recovery.conf", "#{@config['data-dir']}/recovery.done", :binding => binding
|
45
62
|
end
|
46
|
-
|
47
|
-
|
63
|
+
end
|
64
|
+
|
65
|
+
# deploy certificates to data-dir
|
66
|
+
def deploy_certificates
|
48
67
|
@node.deploy_file "#{@template_path}/server.crt", "#{@config['data-dir']}/server.crt", :binding => binding
|
49
68
|
@node.deploy_file "#{@template_path}/server.key", "#{@config['data-dir']}/server.key", :binding => binding
|
50
69
|
|
@@ -55,9 +74,11 @@ class Postgres < Recipe
|
|
55
74
|
@node.mkdir @config['archive-dir']
|
56
75
|
@node.chown @config['dbuser'], @config['archive-dir'] if @config['dbuser']
|
57
76
|
@node.chmod 'u+Xrw,g-rwx,o-rwx', @config['archive-dir']
|
77
|
+
end
|
58
78
|
|
59
|
-
|
60
|
-
|
79
|
+
# increase shm memory
|
80
|
+
def configure_sysctl
|
81
|
+
|
61
82
|
if @node.uses_apt?
|
62
83
|
::Dust.print_msg "setting postgres sysctl keys\n"
|
63
84
|
@node.collect_facts :quiet => true
|
@@ -83,11 +104,56 @@ class Postgres < Recipe
|
|
83
104
|
|
84
105
|
@node.write "/etc/sysctl.d/30-postgresql-shm.conf", file
|
85
106
|
end
|
86
|
-
|
87
|
-
# reload/restart postgres if command line option is given
|
88
|
-
@node.restart_service @config['service-name'] if options.restart?
|
89
|
-
@node.reload_service @config['service-name'] if options.reload?
|
90
107
|
end
|
91
108
|
|
109
|
+
def deploy_pacemaker_script
|
110
|
+
@node.deploy_file "#{@template_path}/pacemaker.sh", "#{@config['conf-dir']}/pacemaker.sh", :binding => binding
|
111
|
+
@node.chmod '755', "#{@config['conf-dir']}/pacemaker.sh"
|
112
|
+
end
|
113
|
+
|
114
|
+
# below this line is unfinished code, not in use yet
|
115
|
+
def zabbix_installed?
|
116
|
+
if @node.uses_emerge?
|
117
|
+
return @node.package_installed? 'zabbix', :quiet => true
|
118
|
+
else
|
119
|
+
return @node.package_installed? 'zabbix-agent', :quiet => true
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# adds zabbix user to postgres group
|
124
|
+
# creates zabbix user in postgres and grant access to postgres database
|
125
|
+
def configure_for_zabbix
|
126
|
+
::Dust.print_msg "configuring postgres for zabbix monitoring\n"
|
127
|
+
::Dust.print_msg 'adding zabbix user to postgres group', :indent => 2
|
128
|
+
::Dust.print_result @node.exec('usermod -a -G postgres zabbix')[:exit_code]
|
129
|
+
|
130
|
+
if is_master? :indent => 2
|
131
|
+
::Dust.print_msg 'checking if zabbix user exists in postgres', :indent => 3
|
132
|
+
ret = ::Dust.print_result @node.exec('psql -U postgres -c ' +
|
133
|
+
' "SELECT usename FROM pg_user WHERE usename = \'zabbix\'"' +
|
134
|
+
' postgres |grep -q zabbix')[:exit_code]
|
135
|
+
|
136
|
+
# if user was not found, create him
|
137
|
+
unless ret
|
138
|
+
::Dust.print_msg 'create zabbix user in postgres', :indent => 4
|
139
|
+
::Dust.print_result @node.exec('createuser -U postgres zabbix -RSD')[:exit_code]
|
140
|
+
end
|
141
|
+
|
142
|
+
::Dust.print_msg 'GRANT zabbix user access to postgres database', :indent => 3
|
143
|
+
::Dust.print_result( @node.exec('psql -U postgres -c "GRANT SELECT ON pg_stat_database TO zabbix" postgres')[:exit_code] )
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# checks if this server is a postgres master
|
148
|
+
def is_master? options = {}
|
149
|
+
::Dust.print_msg 'checking if this host is the postgres master: ', options
|
150
|
+
if @node.file_exists? "#{@config['data-dir']}/recovery.done", :quiet => true
|
151
|
+
::Dust.print_ok 'yes', :indent => 0
|
152
|
+
return true
|
153
|
+
else
|
154
|
+
::Dust.print_ok 'no', :indent => 0
|
155
|
+
return false
|
156
|
+
end
|
157
|
+
end
|
92
158
|
end
|
93
159
|
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class Sudoers < Recipe
|
2
|
+
desc 'sudoers:deploy', 'installs email aliases'
|
3
|
+
def deploy
|
4
|
+
return unless @node.install_package 'sudo'
|
5
|
+
|
6
|
+
remove_rules
|
7
|
+
|
8
|
+
@config.each do |name, rule|
|
9
|
+
::Dust.print_msg "deploying sudo rules '#{name}'\n"
|
10
|
+
|
11
|
+
# rulename: 'myrule'
|
12
|
+
if rule.is_a? String
|
13
|
+
file = "#{rule}\n"
|
14
|
+
|
15
|
+
# rulename: { user: [ user1, user2 ], command: [ cmd1, cmd2 ] }
|
16
|
+
else
|
17
|
+
unless rule['user'] and rule['command']
|
18
|
+
::Dust.print_failed 'user or command missing', :indent => 2
|
19
|
+
next
|
20
|
+
end
|
21
|
+
|
22
|
+
file = ''
|
23
|
+
rule['user'].each do |u|
|
24
|
+
rule['command'].each { |c| file.concat "#{u} #{c}\n" }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
deploy_rule name, file
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def remove_rules
|
37
|
+
@node.rm '/etc/sudoers.d/*'
|
38
|
+
end
|
39
|
+
|
40
|
+
def deploy_rule name, file
|
41
|
+
@node.write "/etc/sudoers.d/#{name}", file, :indent => 2
|
42
|
+
@node.chmod '0440', "/etc/sudoers.d/#{name}", :indent => 2
|
43
|
+
@node.chown 'root:root', "/etc/sudoers.d/#{name}", :indent => 2
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -38,38 +38,4 @@ class ZabbixAgent < Recipe
|
|
38
38
|
|
39
39
|
true
|
40
40
|
end
|
41
|
-
|
42
|
-
|
43
|
-
# below this line is unfinished code, not in use yet
|
44
|
-
|
45
|
-
# TODO (not yet finished)
|
46
|
-
desc 'zabbix_agent:postgres', 'configure postgres database for zabbix monitoring'
|
47
|
-
def postgres
|
48
|
-
next unless @node.uses_emerge? :quiet=>false
|
49
|
-
next unless @node.package_installed?('postgresql-@node')
|
50
|
-
|
51
|
-
::Dust.print_msg 'add zabbix system user to postgres group'
|
52
|
-
::Dust.print_result( @node.exec('usermod -a -G postgres zabbix')[:exit_code] )
|
53
|
-
|
54
|
-
::Dust.print_msg 'checking if zabbix user exists in postgres'
|
55
|
-
ret = ::Dust.print_result( @node.exec('psql -U postgres -c ' +
|
56
|
-
' "SELECT usename FROM pg_user WHERE usename = \'zabbix\'"' +
|
57
|
-
' postgres |grep -q zabbix')[:exit_code] )
|
58
|
-
|
59
|
-
# if user was not found, create him
|
60
|
-
unless ret
|
61
|
-
::Dust.print_msg 'create zabbix user in postgres', :indent => 2
|
62
|
-
::Dust.print_result( @node.exec('createuser -U postgres zabbix -RSD')[:exit_code] )
|
63
|
-
end
|
64
|
-
|
65
|
-
# TODO: only GRANT is this is a master
|
66
|
-
::Dust.print_msg 'GRANT zabbix user access to postgres database'
|
67
|
-
::Dust.print_result( @node.exec('psql -U postgres -c "GRANT SELECT ON pg_stat_database TO zabbix" postgres')[:exit_code] )
|
68
|
-
|
69
|
-
# reload postgresql
|
70
|
-
@node.reload_service('postgresql-9.0')
|
71
|
-
|
72
|
-
@node.disconnect
|
73
|
-
puts
|
74
|
-
end
|
75
41
|
end
|
data/lib/dust/server.rb
CHANGED
@@ -3,7 +3,8 @@ require 'net/ssh'
|
|
3
3
|
require 'net/scp'
|
4
4
|
require 'net/ssh/proxy/socks5'
|
5
5
|
require 'erb'
|
6
|
-
|
6
|
+
require 'tempfile'
|
7
|
+
|
7
8
|
module Dust
|
8
9
|
class Server
|
9
10
|
attr_reader :ssh
|
@@ -70,37 +71,34 @@ module Dust
|
|
70
71
|
end
|
71
72
|
|
72
73
|
|
73
|
-
def write
|
74
|
+
def write destination, content, options = {}
|
74
75
|
options = default_options.merge options
|
75
|
-
|
76
|
-
Dust.print_msg "deploying #{File.basename
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
if exec("cat << EOF > #{target}\n#{text}\nEOF")[:exit_code] != 0
|
85
|
-
Dust.print_failed '', options
|
86
|
-
return false
|
87
|
-
end
|
88
|
-
|
89
|
-
Dust.print_ok '', options
|
90
|
-
restorecon target, options # restore SELinux labels
|
76
|
+
|
77
|
+
Dust.print_msg "deploying #{File.basename destination}", options
|
78
|
+
|
79
|
+
f = Tempfile.new 'dust-write'
|
80
|
+
f.print content
|
81
|
+
f.close
|
82
|
+
|
83
|
+
Dust.print_result scp(f.path, destination, :quiet => true), options
|
84
|
+
f.unlink
|
91
85
|
end
|
92
86
|
|
93
|
-
def append
|
87
|
+
def append destination, newcontent, options = {}
|
94
88
|
options = default_options.merge options
|
95
|
-
|
96
|
-
Dust.print_msg "appending to #{File.basename
|
97
|
-
|
89
|
+
|
90
|
+
Dust.print_msg "appending to #{File.basename destination}", options
|
91
|
+
|
92
|
+
content = exec("cat #{destination}")[:stdout]
|
93
|
+
content.concat newcontent
|
94
|
+
|
95
|
+
Dust.print_result write(destination, content, :quiet => true), options
|
98
96
|
end
|
99
97
|
|
100
98
|
def scp source, destination, options = {}
|
101
99
|
options = default_options.merge options
|
102
100
|
|
103
|
-
Dust.print_msg "deploying #{File.basename
|
101
|
+
Dust.print_msg "deploying #{File.basename source}", options
|
104
102
|
@ssh.scp.upload! source, destination
|
105
103
|
Dust.print_ok '', options
|
106
104
|
restorecon destination, options # restore SELinux labels
|
@@ -109,7 +107,7 @@ module Dust
|
|
109
107
|
def symlink source, destination, options = {}
|
110
108
|
options = default_options.merge options
|
111
109
|
|
112
|
-
Dust.print_msg "symlinking #{File.basename
|
110
|
+
Dust.print_msg "symlinking #{File.basename source} to '#{destination}'", options
|
113
111
|
Dust.print_result exec("ln -s #{source} #{destination}")[:exit_code], options
|
114
112
|
restorecon destination, options # restore SELinux labels
|
115
113
|
end
|
@@ -117,14 +115,14 @@ module Dust
|
|
117
115
|
def chmod mode, file, options = {}
|
118
116
|
options = default_options.merge options
|
119
117
|
|
120
|
-
Dust.print_msg "setting mode of #{File.basename
|
118
|
+
Dust.print_msg "setting mode of #{File.basename file} to #{mode}", options
|
121
119
|
Dust.print_result exec("chmod -R #{mode} #{file}")[:exit_code], options
|
122
120
|
end
|
123
121
|
|
124
122
|
def chown user, file, options = {}
|
125
123
|
options = default_options.merge options
|
126
124
|
|
127
|
-
Dust.print_msg "setting owner of #{File.basename
|
125
|
+
Dust.print_msg "setting owner of #{File.basename file} to #{user}", options
|
128
126
|
Dust.print_result exec("chown -R #{user} #{file}")[:exit_code], options
|
129
127
|
end
|
130
128
|
|
@@ -150,7 +148,6 @@ module Dust
|
|
150
148
|
def restorecon path, options = {}
|
151
149
|
options = default_options.merge options
|
152
150
|
|
153
|
-
|
154
151
|
# if restorecon is not installed, just return true
|
155
152
|
ret = exec 'which restorecon'
|
156
153
|
return true unless ret[:exit_code] == 0
|
data/lib/dust/version.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 4
|
8
|
-
-
|
9
|
-
version: 0.4.
|
8
|
+
- 5
|
9
|
+
version: 0.4.5
|
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-01-
|
17
|
+
date: 2012-01-23 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -138,6 +138,7 @@ files:
|
|
138
138
|
- lib/dust/recipes/mysql.rb
|
139
139
|
- lib/dust/recipes/newrelic.rb
|
140
140
|
- lib/dust/recipes/nginx.rb
|
141
|
+
- lib/dust/recipes/pacemaker.rb
|
141
142
|
- lib/dust/recipes/packages.rb
|
142
143
|
- lib/dust/recipes/postgres.rb
|
143
144
|
- lib/dust/recipes/rc_local.rb
|
@@ -146,6 +147,7 @@ files:
|
|
146
147
|
- lib/dust/recipes/resolv_conf.rb
|
147
148
|
- lib/dust/recipes/ssh_authorized_keys.rb
|
148
149
|
- lib/dust/recipes/sshd.rb
|
150
|
+
- lib/dust/recipes/sudoers.rb
|
149
151
|
- lib/dust/recipes/unattended_upgrades.rb
|
150
152
|
- lib/dust/recipes/zabbix_agent.rb
|
151
153
|
- lib/dust/server.rb
|