deprec 1.9.3 → 2.0.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.
Files changed (188) hide show
  1. data/CHANGELOG +280 -0
  2. data/COPYING +19 -0
  3. data/LICENSE +339 -0
  4. data/README +152 -0
  5. data/THANKS +17 -0
  6. data/bin/depify +128 -0
  7. data/docs/EXAMPLE-installing_tracks.txt +41 -0
  8. data/docs/README.nagios +22 -0
  9. data/docs/README.rails +17 -0
  10. data/docs/config_gen_explained.txt +39 -0
  11. data/docs/{README.quickstart → deprec-1.x/deprec-1.x.quickstart} +4 -1
  12. data/docs/{building_edge_capistrano.txt → deprec-1.x/notes.txt} +6 -3
  13. data/docs/old/deprec_banner.gif +0 -0
  14. data/docs/windows_linux.txt +350 -0
  15. data/docs/xen/traffic_monitoring_with_vnstat.txt +95 -0
  16. data/docs/xen/xen-tools-notes.txt +31 -0
  17. data/docs/xen/xen_on_hardy.txt +39 -0
  18. data/lib/deprec.rb +8 -1
  19. data/lib/deprec/capistrano_extensions.rb +442 -0
  20. data/lib/deprec/recipes.rb +50 -233
  21. data/lib/deprec/recipes/aoe.rb +79 -0
  22. data/lib/deprec/recipes/app/mongrel.rb +213 -0
  23. data/lib/deprec/recipes/app/passenger.rb +197 -0
  24. data/lib/deprec/recipes/apt_mirror.rb +99 -0
  25. data/lib/deprec/recipes/ar_sendmail.rb +67 -0
  26. data/lib/deprec/recipes/canonical.rb +68 -0
  27. data/lib/deprec/recipes/db/mysql.rb +144 -0
  28. data/lib/deprec/recipes/db/postgresql.rb +104 -0
  29. data/lib/deprec/recipes/db/sqlite.rb +37 -0
  30. data/lib/deprec/recipes/ddclient.rb +51 -0
  31. data/lib/deprec/recipes/deprec.rb +199 -0
  32. data/lib/deprec/recipes/deprecated.rb +71 -0
  33. data/lib/deprec/recipes/example.rb +115 -0
  34. data/lib/deprec/recipes/git.rb +97 -0
  35. data/lib/deprec/recipes/gitosis.rb +48 -0
  36. data/lib/deprec/recipes/heartbeat.rb +138 -0
  37. data/lib/deprec/recipes/logrotate.rb +54 -0
  38. data/lib/deprec/recipes/lvm.rb +20 -0
  39. data/lib/deprec/recipes/memcache.rb +6 -2
  40. data/lib/deprec/recipes/monit.rb +143 -0
  41. data/lib/deprec/recipes/nagios.rb +305 -0
  42. data/lib/deprec/recipes/network.rb +93 -0
  43. data/lib/deprec/recipes/ntp.rb +103 -0
  44. data/lib/deprec/recipes/php.rb +58 -0
  45. data/lib/deprec/recipes/postfix.rb +115 -0
  46. data/lib/deprec/recipes/rails.rb +300 -55
  47. data/lib/deprec/recipes/ruby/mri.rb +55 -0
  48. data/lib/deprec/recipes/ruby/ree.rb +41 -0
  49. data/lib/deprec/recipes/sphinx.rb +86 -0
  50. data/lib/deprec/recipes/ssh.rb +85 -18
  51. data/lib/deprec/recipes/ssl.rb +55 -0
  52. data/lib/deprec/recipes/starling.rb +119 -0
  53. data/lib/deprec/recipes/svn.rb +163 -183
  54. data/lib/deprec/recipes/trac.rb +239 -62
  55. data/lib/deprec/recipes/ubuntu.rb +18 -100
  56. data/lib/deprec/recipes/users.rb +90 -0
  57. data/lib/deprec/recipes/utils.rb +58 -0
  58. data/lib/deprec/recipes/vnstat.rb +85 -0
  59. data/lib/deprec/recipes/web/apache.rb +119 -0
  60. data/lib/deprec/recipes/web/nginx.rb +172 -0
  61. data/lib/deprec/recipes/wordpress.rb +96 -0
  62. data/lib/deprec/recipes/wpmu.rb +103 -0
  63. data/lib/deprec/recipes/xen.rb +267 -0
  64. data/lib/deprec/recipes/xentools.rb +75 -0
  65. data/lib/deprec/templates/aoe/aoe-init +55 -0
  66. data/lib/deprec/templates/aoe/fence_aoemask +351 -0
  67. data/lib/deprec/templates/apache/namevirtualhosts.conf +5 -0
  68. data/lib/deprec/templates/apt/sources.list +18 -0
  69. data/lib/deprec/templates/apt_mirror/apt-mirror-cron +4 -0
  70. data/lib/deprec/templates/apt_mirror/mirror.list +33 -0
  71. data/lib/deprec/templates/ar_sendmail/logrotate.conf.erb +9 -0
  72. data/lib/deprec/templates/ar_sendmail/monit.conf.erb +5 -0
  73. data/lib/deprec/templates/ddclient/ddclient.conf.erb +11 -0
  74. data/lib/deprec/templates/ddclient/ddclient.erb +15 -0
  75. data/lib/deprec/templates/deprec/caprc.erb +14 -0
  76. data/lib/deprec/templates/heartbeat/authkeys.erb +2 -0
  77. data/lib/deprec/templates/heartbeat/ha.cf.erb +15 -0
  78. data/lib/deprec/templates/heartbeat/haresources.erb +1 -0
  79. data/lib/deprec/templates/logrotate/logrotate.conf.erb +32 -0
  80. data/lib/deprec/templates/mongrel/apache_vhost.erb +148 -0
  81. data/lib/deprec/templates/mongrel/logrotate.conf.erb +11 -0
  82. data/lib/deprec/{third_party/mongrel_cluster/resources/mongrel_cluster → templates/mongrel/mongrel_cluster-init-script} +19 -6
  83. data/lib/deprec/templates/mongrel/mongrel_cluster.yml.erb +10 -0
  84. data/lib/deprec/templates/mongrel/monit.conf.erb +17 -0
  85. data/lib/deprec/templates/mongrel/nginx_vhost.erb +41 -0
  86. data/lib/deprec/templates/monit/monit-init-script +104 -0
  87. data/lib/deprec/templates/monit/monitrc.erb +227 -0
  88. data/lib/deprec/templates/monit/nothing +0 -0
  89. data/lib/deprec/templates/mysql/create_databases.sql +20 -0
  90. data/lib/deprec/templates/mysql/database.yml.prod +6 -0
  91. data/lib/deprec/templates/mysql/database.yml.stage +6 -0
  92. data/lib/deprec/templates/mysql/my.cnf.erb +140 -0
  93. data/lib/deprec/templates/mysql/sphinx.conf.prod +542 -0
  94. data/lib/deprec/templates/mysql/sphinx.conf.stage +542 -0
  95. data/lib/deprec/templates/nagios/cgi.cfg.erb +321 -0
  96. data/lib/deprec/templates/nagios/check_linux_free_memory.pl +118 -0
  97. data/lib/deprec/templates/nagios/check_mongrel_cluster.rb +82 -0
  98. data/lib/deprec/templates/nagios/commands.cfg.erb +240 -0
  99. data/lib/deprec/templates/nagios/contacts.cfg.erb +57 -0
  100. data/lib/deprec/templates/nagios/hosts.cfg.erb +143 -0
  101. data/lib/deprec/templates/nagios/htpasswd.users +1 -0
  102. data/lib/deprec/templates/nagios/localhost.cfg.erb +157 -0
  103. data/lib/deprec/templates/nagios/nagios.cfg.erb +1274 -0
  104. data/lib/deprec/templates/nagios/nagios_apache_vhost.conf.erb +45 -0
  105. data/lib/deprec/templates/nagios/nrpe.cfg.erb +210 -0
  106. data/lib/deprec/templates/nagios/nrpe.xinetd.erb +16 -0
  107. data/lib/deprec/templates/nagios/resource.cfg.erb +34 -0
  108. data/lib/deprec/templates/nagios/services.cfg.erb +79 -0
  109. data/lib/deprec/templates/nagios/templates.cfg.erb +9 -0
  110. data/lib/deprec/templates/nagios/timeperiods.cfg.erb +94 -0
  111. data/lib/deprec/templates/network/hostname.erb +1 -0
  112. data/lib/deprec/templates/network/hosts.erb +2 -0
  113. data/lib/deprec/templates/network/interfaces.erb +18 -0
  114. data/lib/deprec/templates/network/resolv.conf.erb +6 -0
  115. data/lib/deprec/templates/nginx/logrotate.conf.erb +13 -0
  116. data/lib/deprec/templates/nginx/mime.types.erb +70 -0
  117. data/lib/deprec/templates/nginx/nginx-init-script +62 -0
  118. data/lib/deprec/templates/nginx/nginx.conf.erb +125 -0
  119. data/lib/deprec/templates/nginx/nginx.logrotate.d +12 -0
  120. data/lib/deprec/templates/nginx/nothing.conf +1 -0
  121. data/lib/deprec/templates/nginx/rails_nginx_vhost.conf.erb +41 -0
  122. data/lib/deprec/templates/ntp/ntp.conf.erb +42 -0
  123. data/lib/deprec/templates/passenger/apache_vhost.erb +21 -0
  124. data/lib/deprec/templates/passenger/passenger.conf.erb +21 -0
  125. data/lib/deprec/templates/passenger/passenger.load.erb +3 -0
  126. data/lib/deprec/templates/postfix/aliases.erb +3 -0
  127. data/lib/deprec/templates/postfix/dynamicmaps.cf.erb +8 -0
  128. data/lib/deprec/templates/{postfix_main.conf → postfix/main.cf.erb} +6 -8
  129. data/lib/deprec/templates/postfix/master.cf.erb +77 -0
  130. data/lib/deprec/templates/sphinx/monit.conf.erb +5 -0
  131. data/lib/deprec/templates/ssh/ssh_config.erb +50 -0
  132. data/lib/deprec/templates/ssh/sshd_config.erb +78 -0
  133. data/lib/deprec/templates/ssl/make-ssl-cert +138 -0
  134. data/lib/deprec/templates/ssl/ssl-cert-snakeoil.key +15 -0
  135. data/lib/deprec/templates/ssl/ssl-cert-snakeoil.pem +19 -0
  136. data/lib/deprec/templates/starling/monit.conf.erb +14 -0
  137. data/lib/deprec/templates/starling/starling-init-script.erb +71 -0
  138. data/lib/deprec/templates/subversion/svn.apache.vhost.erb +43 -0
  139. data/lib/deprec/templates/trac/apache_vhost.conf.erb +24 -0
  140. data/lib/deprec/templates/trac/nginx_vhost.conf.erb +26 -0
  141. data/lib/deprec/templates/trac/trac.ini.erb +169 -0
  142. data/lib/deprec/templates/trac/trac_deprec.png +0 -0
  143. data/lib/deprec/templates/trac/tracd-init.erb +43 -0
  144. data/lib/deprec/templates/trac/users.htdigest.erb +0 -0
  145. data/lib/deprec/templates/vnstat/config.php +57 -0
  146. data/lib/deprec/templates/wordpress/apache2_wordpress_vhost.conf.erb +31 -0
  147. data/lib/deprec/templates/wordpress/wp-config.php.erb +31 -0
  148. data/lib/deprec/templates/wpmu/apache_vhost.conf.erb +13 -0
  149. data/lib/deprec/templates/xen/network-bridge-wrapper +3 -0
  150. data/lib/deprec/templates/xen/xend-config.sxp.erb +195 -0
  151. data/lib/deprec/templates/xen/xend-init.erb +57 -0
  152. data/lib/deprec/templates/xen/xendomains.erb +137 -0
  153. data/lib/deprec/templates/xentools/15-disable-hwclock +40 -0
  154. data/lib/deprec/templates/xentools/40-setup-networking +145 -0
  155. data/lib/deprec/templates/xentools/xen-tools.conf.erb +276 -0
  156. data/lib/deprec/templates/xentools/xm.tmpl.erb +138 -0
  157. data/lib/deprec_cmd_completion.sh +26 -0
  158. data/lib/vmbuilder_plugins/all.rb +20 -0
  159. data/lib/vmbuilder_plugins/apt.rb +93 -0
  160. data/lib/vmbuilder_plugins/emerge.rb +76 -0
  161. data/lib/{deprec/third_party/vmbuilder/plugins → vmbuilder_plugins}/gem.rb +10 -17
  162. data/lib/{deprec/third_party/vmbuilder/plugins → vmbuilder_plugins}/std.rb +69 -19
  163. metadata +204 -55
  164. data/bin/deprec +0 -35
  165. data/docs/README.slicehost +0 -14
  166. data/docs/README.svn_trac +0 -19
  167. data/lib/deprec/capistrano_extensions/actor_extensions.rb +0 -89
  168. data/lib/deprec/capistrano_extensions/cli_extensions.rb +0 -38
  169. data/lib/deprec/capistrano_extensions/deprec_extensions.rb +0 -137
  170. data/lib/deprec/generators/deprec/USAGE +0 -11
  171. data/lib/deprec/generators/deprec/deprec_generator.rb +0 -24
  172. data/lib/deprec/generators/deprec/templates/deploy.rb +0 -90
  173. data/lib/deprec/generators/loader.rb +0 -20
  174. data/lib/deprec/recipes/apache.rb +0 -91
  175. data/lib/deprec/recipes/cache_svn.rb +0 -74
  176. data/lib/deprec/recipes/vmware.rb +0 -114
  177. data/lib/deprec/templates/trac.ini.erb +0 -106
  178. data/lib/deprec/third_party/THIRD_PARTY_README +0 -12
  179. data/lib/deprec/third_party/mongrel_cluster/LICENSE +0 -506
  180. data/lib/deprec/third_party/mongrel_cluster/recipes.rb +0 -96
  181. data/lib/deprec/third_party/railsmachine/LICENSE +0 -506
  182. data/lib/deprec/third_party/railsmachine/recipes/apache.rb +0 -92
  183. data/lib/deprec/third_party/railsmachine/recipes/mysql.rb +0 -73
  184. data/lib/deprec/third_party/railsmachine/recipes/templates/httpd-ssl.conf +0 -80
  185. data/lib/deprec/third_party/railsmachine/recipes/templates/httpd.conf +0 -57
  186. data/lib/deprec/third_party/vmbuilder/plugins.rb +0 -8
  187. data/lib/deprec/third_party/vmbuilder/plugins/apt.rb +0 -144
  188. data/resources/capistrano_include_dotfiles.patch +0 -17
@@ -0,0 +1,39 @@
1
+ #
2
+ # Install xen on ubuntu hardy
3
+ #
4
+ # ref: http://www.howtoforge.com/ubuntu-8.04-server-install-xen-from-ubuntu-repositories
5
+ #
6
+
7
+ # Install Xen packages
8
+ # apt-get install ubuntu-xen-server
9
+ #
10
+ # Installs these:
11
+ #
12
+ # binutils binutils-static bridge-utils debootstrap libasound2 libconfig-inifiles-perl libcurl3 libdirectfb-1.0-0 libsdl1.2debian
13
+ # libsdl1.2debian-alsa libtext-template-perl libxen3 libxml2 linux-image-2.6.24-16-xen linux-image-xen
14
+ # linux-restricted-modules-2.6.24-16-xen linux-restricted-modules-common linux-restricted-modules-xen
15
+ # linux-ubuntu-modules-2.6.24-16-xen linux-xen nvidia-kernel-common python-dev python-xen-3.2 python2.5-dev ubuntu-xen-server
16
+ # xen-docs-3.2 xen-hypervisor-3.2 xen-tools xen-utils-3.2
17
+
18
+ # before/after 'uname -a'
19
+ #
20
+ # Linux bb 2.6.24-16-server #1 SMP Thu Apr 10 13:15:38 UTC 2008 x86_64 GNU/Linux
21
+ # Linux bb 2.6.24-16-xen #1 SMP Thu Apr 10 14:35:03 UTC 2008 x86_64 GNU/Linux
22
+ #
23
+ # Stop apparmor # XXX investigate why
24
+ # /etc/init.d/apparmor stop
25
+ # update-rc.d -f apparmor remove
26
+
27
+ # mkdir /home/xen
28
+
29
+ # edit /etc/xen-tools/xen-tools.cfg
30
+
31
+ # create image with xen-tools
32
+ # xen-create-image --hostname=x1 --size=2Gb --swap=256Mb --ide --ip=192.168.1.51 --memory=256Mb --install-method=debootstrap --dist=hardy
33
+
34
+ # update /etc/xen/<domain>.cfg
35
+ #
36
+ # disk = [
37
+ # 'tap:aio:/home/xen/domains/xen1.example.com/swap.img,hda1,w',
38
+ # 'tap:aio:/home/xen/domains/xen1.example.com/disk.img,hda2,w',
39
+ # ]
@@ -1 +1,8 @@
1
- require "deprec/recipes"
1
+ unless Capistrano::Configuration.respond_to?(:instance)
2
+ abort "deprec2 requires Capistrano 2"
3
+ end
4
+
5
+ require "#{File.dirname(__FILE__)}/deprec/capistrano_extensions"
6
+ require "#{File.dirname(__FILE__)}/vmbuilder_plugins/all"
7
+ require "#{File.dirname(__FILE__)}/deprec/recipes"
8
+
@@ -0,0 +1,442 @@
1
+ # Copyright 2006-2008 by Mike Bailey. All rights reserved.
2
+ require 'capistrano'
3
+ require 'fileutils'
4
+
5
+ module Deprec2
6
+
7
+ # Temporarily modify ROLES if HOSTS not set
8
+ # Capistrano's default behaviour is for HOSTS to override ROLES
9
+ def for_roles(roles)
10
+ old_roles = ENV['ROLES']
11
+ ENV['ROLES'] = roles.to_s unless ENV['HOSTS']
12
+ yield
13
+ ENV['ROLES'] = old_roles.to_s unless ENV['HOSTS']
14
+ end
15
+
16
+ # Temporarily ignore ROLES and HOSTS
17
+ def ignoring_roles_and_hosts
18
+ old_roles = ENV['ROLES']
19
+ old_hosts = ENV['HOSTS']
20
+ ENV['ROLES'] = nil
21
+ ENV['HOSTS'] = nil
22
+ yield
23
+ ENV['ROLES'] = old_roles
24
+ ENV['HOSTS'] = old_hosts
25
+ end
26
+
27
+ DEPREC_TEMPLATES_BASE = File.join(File.dirname(__FILE__), 'templates')
28
+
29
+ # Render template (usually a config file)
30
+ #
31
+ # Usually we render it to a file on the local filesystem.
32
+ # This way, we keep a copy of the config file under source control.
33
+ # We can make manual changes if required and push to new hosts.
34
+ #
35
+ # If the options hash contains :path then it's written to that path.
36
+ # If it contains :remote => true, the file will instead be written to remote targets
37
+ # If options[:path] and options[:remote] are missing, it just returns the rendered
38
+ # template as a string (good for debugging).
39
+ #
40
+ # XXX I would like to get rid of :render_template_to_file
41
+ # XXX Perhaps pass an option to this function to write to remote
42
+ #
43
+ def render_template(app, options={})
44
+ template = options[:template]
45
+ path = options[:path] || nil
46
+ remote = options[:remote] || false
47
+ mode = options[:mode] || 0755
48
+ owner = options[:owner] || nil
49
+
50
+ # replace this with a check for the file
51
+ if ! template
52
+ puts "render_template() requires a value for the template!"
53
+ return false
54
+ end
55
+
56
+ # If local copies of deprec templates exist they will be used
57
+ # If you don't specify the location with the local_template_dir option
58
+ # it defaults to config/templates.
59
+ # e.g. config/templates/nginx/nginx.conf.erb
60
+ local_template = File.join(local_template_dir, app.to_s, template)
61
+ if File.exists?(local_template)
62
+ puts
63
+ puts "Using local template (#{local_template})"
64
+ template = ERB.new(IO.read(local_template), nil, '-')
65
+ else
66
+ template = ERB.new(IO.read(File.join(DEPREC_TEMPLATES_BASE, app.to_s, template)), nil, '-')
67
+ end
68
+ rendered_template = template.result(binding)
69
+
70
+ if remote
71
+ # render to remote machine
72
+ puts 'You need to specify a path to render the template to!' unless path
73
+ exit unless path
74
+ sudo "test -d #{File.dirname(path)} || sudo mkdir -p #{File.dirname(path)}"
75
+ std.su_put rendered_template, path, '/tmp/', :mode => mode
76
+ sudo "chown #{owner} #{path}" if defined?(owner)
77
+ elsif path
78
+ # render to local file
79
+ full_path = File.join('config', app.to_s, path)
80
+ path_dir = File.dirname(full_path)
81
+ if File.exists?(full_path)
82
+ if IO.read(full_path) == rendered_template
83
+ puts "[skip] File exists and is identical (#{full_path})."
84
+ return false
85
+ elsif overwrite?(full_path, rendered_template)
86
+ File.delete(full_path)
87
+ else
88
+ puts "[skip] Not overwriting #{full_path}"
89
+ return false
90
+ end
91
+ end
92
+ FileUtils.mkdir_p "#{path_dir}" if ! File.directory?(path_dir)
93
+ # added line above to make windows compatible
94
+ # system "mkdir -p #{path_dir}" if ! File.directory?(path_dir)
95
+ File.open(full_path, 'w'){|f| f.write rendered_template }
96
+ puts "[done] #{full_path} written"
97
+ else
98
+ # render to string
99
+ return rendered_template
100
+ end
101
+ end
102
+
103
+ def overwrite?(full_path, rendered_template)
104
+ if defined?(overwrite_all)
105
+ if overwrite_all == true
106
+ return true
107
+ else
108
+ return false
109
+ end
110
+ end
111
+
112
+ # XXX add :always and :never later - not sure how to set persistent value from here
113
+ # response = Capistrano::CLI.ui.ask "File exists. Overwrite? ([y]es, [n]o, [a]lways, n[e]ver)" do |q|
114
+ puts
115
+ response = Capistrano::CLI.ui.ask "File exists (#{full_path}).
116
+ Overwrite? ([y]es, [n]o, [d]iff)" do |q|
117
+ q.default = 'n'
118
+ end
119
+
120
+ case response
121
+ when 'y'
122
+ return true
123
+ when 'n'
124
+ return false
125
+ when 'd'
126
+ require 'tempfile'
127
+ tf = Tempfile.new("deprec_diff")
128
+ tf.puts(rendered_template)
129
+ tf.close
130
+ puts
131
+ puts "Running diff -u current_file new_file_if_you_overwrite"
132
+ puts
133
+ system "diff -u #{full_path} #{tf.path} | less"
134
+ puts
135
+ overwrite?(full_path, rendered_template)
136
+ # XXX add :always and :never later - not sure how to set persistent value from here
137
+ # when 'a'
138
+ # set :overwrite_all, true
139
+ # when 'e'
140
+ # set :overwrite_all, false
141
+ end
142
+
143
+ end
144
+
145
+ def render_template_to_file(template_name, destination_file_name, templates_dir = DEPREC_TEMPLATES_BASE)
146
+ template_name += '.conf' if File.extname(template_name) == '' # XXX this to be removed
147
+
148
+ file = File.join(templates_dir, template_name)
149
+ buffer = render :template => File.read(file)
150
+
151
+ temporary_location = "/tmp/#{template_name}"
152
+ put buffer, temporary_location
153
+ sudo "cp #{temporary_location} #{destination_file_name}"
154
+ delete temporary_location
155
+ end
156
+
157
+ # Copy configs to server(s). Note there is no :pull task. No changes should
158
+ # be made to configs on the servers so why would you need to pull them back?
159
+ def push_configs(app, files)
160
+ app = app.to_s
161
+ files.each do |file|
162
+ # If the file path is relative we will prepend a path to this projects
163
+ # own config directory for this service.
164
+ if file[:path][0,1] != '/'
165
+ full_remote_path = File.join(deploy_to, app, file[:path])
166
+ else
167
+ full_remote_path = file[:path]
168
+ end
169
+ full_local_path = File.join('config', app, file[:path])
170
+ sudo "test -d #{File.dirname(full_remote_path)} || sudo mkdir -p #{File.dirname(full_remote_path)}"
171
+ #
172
+ # XXX work this in to check for per-host variants of config files
173
+ #
174
+ # if any variants of this file exist for this host (they have -hostname at end)
175
+ # servers = find_servers_for_task(current_task)
176
+ # servers.each do |server|
177
+ # puts server(..., :hosts => server) # XXX find a way to restrict su_put to one host
178
+ # end
179
+ # else
180
+ # # just send them the normal way, it's quicker in parallel
181
+ std.su_put File.read(full_local_path), full_remote_path, '/tmp/', :mode=>file[:mode]
182
+ # end
183
+ #
184
+ sudo "chown #{file[:owner]} #{full_remote_path}"
185
+ end
186
+ end
187
+
188
+ def teardown_connections
189
+ sessions.keys.each do |server|
190
+ sessions[server].close
191
+ sessions.delete(server)
192
+ end
193
+ end
194
+
195
+ def append_to_file_if_missing(filename, value, options={})
196
+ # XXX sort out single quotes in 'value' - they'l break command!
197
+ # XXX if options[:requires_sudo] and :use_sudo then use sudo
198
+ sudo <<-END
199
+ sh -c '
200
+ grep -F "#{value}" #{filename} > /dev/null 2>&1 ||
201
+ echo "#{value}" >> #{filename}
202
+ '
203
+ END
204
+ end
205
+
206
+ # create new user account on target system
207
+ def useradd(user, options={})
208
+ options[:shell] ||= '/bin/bash' # new accounts on ubuntu 6.06.1 have been getting /bin/sh
209
+ switches = ''
210
+ switches += " --shell=#{options[:shell]} " if options[:shell]
211
+ switches += ' --create-home ' unless options[:homedir] == false
212
+ switches += " --gid #{options[:group]} " unless options[:group].nil?
213
+ invoke_command "grep '^#{user}:' /etc/passwd || sudo /usr/sbin/useradd #{switches} #{user}",
214
+ :via => run_method
215
+ end
216
+
217
+ # create a new group on target system
218
+ def groupadd(group, options={})
219
+ via = options.delete(:via) || run_method
220
+ # XXX I don't like specifying the path to groupadd - need to sort out paths before long
221
+ invoke_command "grep '#{group}:' /etc/group || sudo /usr/sbin/groupadd #{group}", :via => via
222
+ end
223
+
224
+ # add group to the list of groups this user belongs to
225
+ def add_user_to_group(user, group)
226
+ invoke_command "groups #{user} | grep ' #{group} ' || sudo /usr/sbin/usermod -G #{group} -a #{user}",
227
+ :via => run_method
228
+ end
229
+
230
+ # create directory if it doesn't already exist
231
+ # set permissions and ownership
232
+ # XXX move mode, path and
233
+ def mkdir(path, options={})
234
+ via = options.delete(:via) || :run
235
+ # XXX need to make sudo commands wrap the whole command (sh -c ?)
236
+ # XXX removed the extra 'sudo' from after the '||' - need something else
237
+ invoke_command "test -d #{path} || #{sudo if via == :sudo} mkdir -p #{path}"
238
+ invoke_command "chmod #{sprintf("%3o",options[:mode]||0755)} #{path}", :via => via if options[:mode]
239
+ invoke_command "chown -R #{options[:owner]} #{path}", :via => via if options[:owner]
240
+ groupadd(options[:group], :via => via) if options[:group]
241
+ invoke_command "chgrp -R #{options[:group]} #{path}", :via => via if options[:group]
242
+ end
243
+
244
+ def create_src_dir
245
+ mkdir(src_dir, :mode => 0775, :group => group_src, :via => :sudo)
246
+ end
247
+
248
+ # download source package if we don't already have it
249
+ def download_src(src_package, src_dir)
250
+ set_package_defaults(src_package)
251
+ create_src_dir
252
+ # check if file exists and if we have an MD5 hash or bytecount to compare
253
+ # against if so, compare and decide if we need to download again
254
+ if defined?(src_package[:md5sum])
255
+ md5_clause = " && echo '#{src_package[:md5sum]}' | md5sum -c - "
256
+ end
257
+ case src_package[:download_method]
258
+ # when getting source with git
259
+ when :git
260
+ # ensure git is installed
261
+ apt.install( {:base => %w(git-core)}, :stable) #TODO fix this to test ubuntu version <hardy might need specific git version for full git submodules support
262
+ package_dir = File.join(src_dir, src_package[:dir])
263
+ run "if [ -d #{package_dir} ]; then cd #{package_dir} && #{sudo} git checkout master && #{sudo} git pull && #{sudo} git submodule init && #{sudo} git submodule update; else #{sudo} git clone #{src_package[:url]} #{package_dir} && cd #{package_dir} && #{sudo} git submodule init && #{sudo} git submodule update ; fi"
264
+ # Checkout the revision wanted if defined
265
+ if src_package[:version]
266
+ run "cd #{package_dir} && git branch | grep '#{src_package[:version]}$' && #{sudo} git branch -D '#{src_package[:version]}'; exit 0"
267
+ run "cd #{package_dir} && #{sudo} git checkout -b #{src_package[:version]} #{src_package[:version]}"
268
+ end
269
+
270
+ # when getting source with wget
271
+ when :http
272
+ # ensure wget is installed
273
+ apt.install( {:base => %w(wget)}, :stable )
274
+ # XXX replace with invoke_command
275
+ run "cd #{src_dir} && test -f #{src_package[:filename]} #{md5_clause} || #{sudo} wget --quiet --timestamping #{src_package[:url]}"
276
+ else
277
+ puts "DOWNLOAD SRC: Download method not recognised. src_package[:download_method]: #{src_package[:download_method]}"
278
+ end
279
+ end
280
+
281
+ # unpack src and make it writable by the group
282
+ def unpack_src(src_package, src_dir)
283
+ set_package_defaults(src_package)
284
+ package_dir = File.join(src_dir, src_package[:dir])
285
+ case src_package[:download_method]
286
+ # when unpacking git sources - nothing to do
287
+ when :git
288
+ puts "UNPACK SRC: nothing to do for git installs"
289
+ when :http
290
+ sudo <<-EOF
291
+ bash -c '
292
+ cd #{src_dir};
293
+ test -d #{package_dir}.old && rm -fr #{package_dir}.old;
294
+ test -d #{package_dir} && mv #{package_dir} #{package_dir}.old;
295
+ #{src_package[:unpack]}
296
+ '
297
+ EOF
298
+ else
299
+ puts "UNPACK SRC: Download method not recognised. src_package[:download_method]: #{src_package[:download_method]} "
300
+ end
301
+ sudo <<-EOF
302
+ bash -c '
303
+ cd #{src_dir};
304
+ chgrp -R #{group} #{package_dir};
305
+ chmod -R g+w #{package_dir};
306
+ '
307
+ EOF
308
+ end
309
+
310
+ def set_package_defaults(pkg)
311
+ pkg[:filename] ||= File.basename(pkg[:url])
312
+ pkg[:dir] ||= pkg[:filename].sub(/(\.tgz|\.tar\.gz)/,'')
313
+ pkg[:download_method] ||= :http
314
+ pkg[:unpack] ||= "tar zxf #{pkg[:filename]};"
315
+ pkg[:configure] ||= './configure ;'
316
+ pkg[:make] ||= 'make;'
317
+ pkg[:install] ||= 'make install;'
318
+ end
319
+
320
+ # install package from source
321
+ def install_from_src(src_package, src_dir)
322
+ package_dir = File.join(src_dir, src_package[:dir])
323
+ unpack_src(src_package, src_dir)
324
+ apt.install( {:base => %w(build-essential)}, :stable )
325
+ # XXX replace with invoke_command
326
+ sudo <<-SUDO
327
+ sh -c '
328
+ cd #{package_dir};
329
+ #{src_package[:configure]}
330
+ #{src_package[:make]}
331
+ #{src_package[:install]}
332
+ #{src_package[:post_install]}
333
+ '
334
+ SUDO
335
+ end
336
+
337
+ def read_database_yml
338
+ db_config = YAML.load_file('config/database.yml')
339
+ set :db_user, db_config[rails_env]["username"]
340
+ set :db_password, db_config[rails_env]["password"]
341
+ set :db_name, db_config[rails_env]["database"]
342
+ end
343
+
344
+
345
+ ##
346
+ # Run a command and ask for input when input_query is seen.
347
+ # Sends the response back to the server.
348
+ #
349
+ # +input_query+ is a regular expression that defaults to /^Password/.
350
+ #
351
+ # Can be used where +run+ would otherwise be used.
352
+ #
353
+ # run_with_input 'ssh-keygen ...', /^Are you sure you want to overwrite\?/
354
+
355
+ def run_with_input(shell_command, input_query=/^Password/, response=nil)
356
+ handle_command_with_input(:run, shell_command, input_query, response)
357
+ end
358
+
359
+ ##
360
+ # Run a command using sudo and ask for input when a regular expression is seen.
361
+ # Sends the response back to the server.
362
+ #
363
+ # See also +run_with_input+
364
+ #
365
+ # +input_query+ is a regular expression
366
+
367
+ def sudo_with_input(shell_command, input_query=/^Password/, response=nil)
368
+ handle_command_with_input(:sudo, shell_command, input_query, response)
369
+ end
370
+
371
+ def invoke_with_input(shell_command, input_query=/^Password/, response=nil)
372
+ handle_command_with_input(run_method, shell_command, input_query, response)
373
+ end
374
+
375
+ ##
376
+ # Run a command using sudo and continuously pipe the results back to the console.
377
+ #
378
+ # Similar to the built-in +stream+, but for privileged users.
379
+
380
+ def sudo_stream(command)
381
+ sudo(command) do |ch, stream, out|
382
+ puts out if stream == :out
383
+ if stream == :err
384
+ puts "[err : #{ch[:host]}] #{out}"
385
+ break
386
+ end
387
+ end
388
+ end
389
+
390
+ # We don't need this. Put 'USER=root' on the command line instead.
391
+ #
392
+ # XXX Not working in deprec2
393
+ # ##
394
+ # # Run a command using the root account.
395
+ # #
396
+ # # Some linux distros/VPS providers only give you a root login when you install.
397
+ #
398
+ # def run_as_root(shell_command)
399
+ # std.connect_as_root do |tempuser|
400
+ # run shell_command
401
+ # end
402
+ # end
403
+ #
404
+ # ##
405
+ # # Run a task using root account.
406
+ # #
407
+ # # Some linux distros/VPS providers only give you a root login when you install.
408
+ # #
409
+ # # tempuser: contains the value replaced by 'root' for the duration of this call
410
+ #
411
+ # def as_root()
412
+ # std.connect_as_root do |tempuser|
413
+ # yield tempuser
414
+ # end
415
+ # end
416
+
417
+ private
418
+
419
+ ##
420
+ # Does the actual capturing of the input and streaming of the output.
421
+ #
422
+ # local_run_method: run or sudo
423
+ # shell_command: The command to run
424
+ # input_query: A regular expression matching a request for input: /^Please enter your password/
425
+
426
+ def handle_command_with_input(local_run_method, shell_command, input_query, response=nil)
427
+ send(local_run_method, shell_command) do |channel, stream, data|
428
+ logger.info data, channel[:host]
429
+ if data =~ input_query
430
+ if response
431
+ channel.send_data "#{response}\n"
432
+ else
433
+ response = ::Capistrano::CLI.password_prompt "#{data}"
434
+ channel.send_data "#{response}\n"
435
+ end
436
+ end
437
+ end
438
+ end
439
+
440
+ end
441
+
442
+ Capistrano.plugin :deprec2, Deprec2