Empact-deprec 1.99.21

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 (148) hide show
  1. data/CHANGELOG +170 -0
  2. data/COPYING +19 -0
  3. data/LICENSE +339 -0
  4. data/README +136 -0
  5. data/THANKS +5 -0
  6. data/bin/depify +133 -0
  7. data/docs/ANNOUNCE.deprec2 +47 -0
  8. data/docs/README.install +88 -0
  9. data/docs/README.nagios +28 -0
  10. data/docs/README.rails +20 -0
  11. data/docs/README.svn +31 -0
  12. data/docs/ROADMAP.txt +74 -0
  13. data/docs/deprec-1.x/deprec-1.x.quickstart +50 -0
  14. data/docs/deprec-1.x/notes.txt +12 -0
  15. data/docs/deprec_banner.gif +0 -0
  16. data/lib/deprec.rb +8 -0
  17. data/lib/deprec/capistrano_extensions.rb +378 -0
  18. data/lib/deprec/recipes.rb +40 -0
  19. data/lib/deprec/recipes/aoe.rb +117 -0
  20. data/lib/deprec/recipes/apache.rb +179 -0
  21. data/lib/deprec/recipes/ar_sendmail.rb +65 -0
  22. data/lib/deprec/recipes/canonical.rb +57 -0
  23. data/lib/deprec/recipes/deprec.rb +155 -0
  24. data/lib/deprec/recipes/deprecated.rb +71 -0
  25. data/lib/deprec/recipes/example.rb +115 -0
  26. data/lib/deprec/recipes/git.rb +168 -0
  27. data/lib/deprec/recipes/gitosis.rb +47 -0
  28. data/lib/deprec/recipes/god.rb +107 -0
  29. data/lib/deprec/recipes/heartbeat.rb +138 -0
  30. data/lib/deprec/recipes/iptables.rb +53 -0
  31. data/lib/deprec/recipes/logrotate.rb +51 -0
  32. data/lib/deprec/recipes/lvm.rb +20 -0
  33. data/lib/deprec/recipes/memcached.rb +102 -0
  34. data/lib/deprec/recipes/mongrel.rb +209 -0
  35. data/lib/deprec/recipes/monit.rb +130 -0
  36. data/lib/deprec/recipes/mysql.rb +115 -0
  37. data/lib/deprec/recipes/nagios.rb +302 -0
  38. data/lib/deprec/recipes/network.rb +84 -0
  39. data/lib/deprec/recipes/nginx.rb +154 -0
  40. data/lib/deprec/recipes/ntp.rb +96 -0
  41. data/lib/deprec/recipes/php.rb +99 -0
  42. data/lib/deprec/recipes/postfix.rb +105 -0
  43. data/lib/deprec/recipes/rails.rb +302 -0
  44. data/lib/deprec/recipes/ruby.rb +66 -0
  45. data/lib/deprec/recipes/sphinx.rb +83 -0
  46. data/lib/deprec/recipes/ssh.rb +93 -0
  47. data/lib/deprec/recipes/svn.rb +169 -0
  48. data/lib/deprec/recipes/swiftiply.rb +108 -0
  49. data/lib/deprec/recipes/thin.rb +201 -0
  50. data/lib/deprec/recipes/trac.rb +277 -0
  51. data/lib/deprec/recipes/ubuntu.rb +20 -0
  52. data/lib/deprec/recipes/users.rb +90 -0
  53. data/lib/deprec/recipes/utils.rb +39 -0
  54. data/lib/deprec/recipes/xen.rb +259 -0
  55. data/lib/deprec/templates/aoe/aoe-init +55 -0
  56. data/lib/deprec/templates/aoe/fence_aoemask +351 -0
  57. data/lib/deprec/templates/apache/httpd-vhost-app.conf.erb +144 -0
  58. data/lib/deprec/templates/apache/httpd.conf +465 -0
  59. data/lib/deprec/templates/apache/index.html.erb +37 -0
  60. data/lib/deprec/templates/apache/master.css +72 -0
  61. data/lib/deprec/templates/ar_sendmail/logrotate.conf.erb +9 -0
  62. data/lib/deprec/templates/ar_sendmail/monit.conf.erb +5 -0
  63. data/lib/deprec/templates/coraid/aoe-init +55 -0
  64. data/lib/deprec/templates/deprec/caprc.erb +14 -0
  65. data/lib/deprec/templates/god/god-init-script +71 -0
  66. data/lib/deprec/templates/god/god-notifications +0 -0
  67. data/lib/deprec/templates/god/god_mongrel.erb +81 -0
  68. data/lib/deprec/templates/god/god_mysql.erb +50 -0
  69. data/lib/deprec/templates/god/god_nginx.erb +61 -0
  70. data/lib/deprec/templates/god/god_thin.erb +80 -0
  71. data/lib/deprec/templates/heartbeat/authkeys.erb +2 -0
  72. data/lib/deprec/templates/heartbeat/ha.cf.erb +15 -0
  73. data/lib/deprec/templates/heartbeat/haresources.erb +1 -0
  74. data/lib/deprec/templates/iptables/iptables.up.erb +41 -0
  75. data/lib/deprec/templates/logrotate/logrotate.conf.erb +32 -0
  76. data/lib/deprec/templates/memcached/memcached-init-script +65 -0
  77. data/lib/deprec/templates/memcached/memcached.conf.erb +46 -0
  78. data/lib/deprec/templates/mongrel/logrotate.conf.erb +11 -0
  79. data/lib/deprec/templates/mongrel/mongrel_cluster-init-script +54 -0
  80. data/lib/deprec/templates/mongrel/mongrel_cluster.logrotate.d +14 -0
  81. data/lib/deprec/templates/mongrel/mongrel_cluster.yml.erb +10 -0
  82. data/lib/deprec/templates/mongrel/monit.conf.erb +17 -0
  83. data/lib/deprec/templates/monit/monit-init-script +104 -0
  84. data/lib/deprec/templates/monit/monitrc.erb +227 -0
  85. data/lib/deprec/templates/monit/nothing +0 -0
  86. data/lib/deprec/templates/mysql/create_databases.sql +20 -0
  87. data/lib/deprec/templates/mysql/database.yml.prod +6 -0
  88. data/lib/deprec/templates/mysql/database.yml.stage +6 -0
  89. data/lib/deprec/templates/mysql/my.cnf.erb +140 -0
  90. data/lib/deprec/templates/mysql/sphinx.conf.prod +542 -0
  91. data/lib/deprec/templates/mysql/sphinx.conf.stage +542 -0
  92. data/lib/deprec/templates/nagios/cgi.cfg.erb +321 -0
  93. data/lib/deprec/templates/nagios/commands.cfg.erb +240 -0
  94. data/lib/deprec/templates/nagios/contacts.cfg.erb +75 -0
  95. data/lib/deprec/templates/nagios/hosts.cfg.erb +70 -0
  96. data/lib/deprec/templates/nagios/htpasswd.users +1 -0
  97. data/lib/deprec/templates/nagios/localhost.cfg.erb +157 -0
  98. data/lib/deprec/templates/nagios/nagios.cfg.erb +1274 -0
  99. data/lib/deprec/templates/nagios/nagios_apache_vhost.conf.erb +45 -0
  100. data/lib/deprec/templates/nagios/nrpe.cfg.erb +208 -0
  101. data/lib/deprec/templates/nagios/nrpe.xinetd.erb +16 -0
  102. data/lib/deprec/templates/nagios/resource.cfg.erb +34 -0
  103. data/lib/deprec/templates/nagios/services.cfg.erb +7 -0
  104. data/lib/deprec/templates/nagios/templates.cfg.erb +190 -0
  105. data/lib/deprec/templates/nagios/timeperiods.cfg.erb +94 -0
  106. data/lib/deprec/templates/network/hostname.erb +1 -0
  107. data/lib/deprec/templates/network/hosts.erb +2 -0
  108. data/lib/deprec/templates/network/interfaces.erb +18 -0
  109. data/lib/deprec/templates/nginx/logrotate.conf.erb +13 -0
  110. data/lib/deprec/templates/nginx/mime.types.erb +70 -0
  111. data/lib/deprec/templates/nginx/nginx-init-script +62 -0
  112. data/lib/deprec/templates/nginx/nginx.conf.erb +53 -0
  113. data/lib/deprec/templates/nginx/nginx.logrotate.d +12 -0
  114. data/lib/deprec/templates/nginx/nothing.conf +1 -0
  115. data/lib/deprec/templates/nginx/rails_nginx_vhost.conf.erb +45 -0
  116. data/lib/deprec/templates/ntp/ntp.conf.erb +42 -0
  117. data/lib/deprec/templates/postfix/aliases.erb +3 -0
  118. data/lib/deprec/templates/postfix/dynamicmaps.cf.erb +8 -0
  119. data/lib/deprec/templates/postfix/main.cf.erb +41 -0
  120. data/lib/deprec/templates/postfix/master.cf.erb +77 -0
  121. data/lib/deprec/templates/rails/database.yml.erb +6 -0
  122. data/lib/deprec/templates/sphinx/monit.conf.erb +5 -0
  123. data/lib/deprec/templates/ssh/ssh_config.erb +50 -0
  124. data/lib/deprec/templates/ssh/sshd_config.erb +78 -0
  125. data/lib/deprec/templates/subversion/svn.apache.vhost.erb +43 -0
  126. data/lib/deprec/templates/swiftiply/swiftiply-init-script +61 -0
  127. data/lib/deprec/templates/swiftiply/swiftiply.yml.erb +11 -0
  128. data/lib/deprec/templates/thin/thin-init-script +51 -0
  129. data/lib/deprec/templates/thin/thin.yml.erb +11 -0
  130. data/lib/deprec/templates/trac/apache_vhost.conf.erb +24 -0
  131. data/lib/deprec/templates/trac/nginx_vhost.conf.erb +26 -0
  132. data/lib/deprec/templates/trac/trac.ini.erb +169 -0
  133. data/lib/deprec/templates/trac/trac_deprec.png +0 -0
  134. data/lib/deprec/templates/trac/tracd-init.erb +43 -0
  135. data/lib/deprec/templates/trac/users.htdigest.erb +0 -0
  136. data/lib/deprec/templates/xen/15-disable-hwclock +40 -0
  137. data/lib/deprec/templates/xen/network-bridge-wrapper +3 -0
  138. data/lib/deprec/templates/xen/xen-tools.conf.erb +220 -0
  139. data/lib/deprec/templates/xen/xend-config.sxp.erb +195 -0
  140. data/lib/deprec/templates/xen/xend-init.erb +69 -0
  141. data/lib/deprec/templates/xen/xendomains.erb +137 -0
  142. data/lib/deprec/templates/xen/xm.tmpl.erb +85 -0
  143. data/lib/vmbuilder_plugins/all.rb +20 -0
  144. data/lib/vmbuilder_plugins/apt.rb +93 -0
  145. data/lib/vmbuilder_plugins/emerge.rb +76 -0
  146. data/lib/vmbuilder_plugins/gem.rb +90 -0
  147. data/lib/vmbuilder_plugins/std.rb +203 -0
  148. metadata +207 -0
@@ -0,0 +1,31 @@
1
+ == svn
2
+
3
+ # Add the following to your deploy.rb (or ~/.caprc if always the same)
4
+ set :scm, 'your.svn.server'
5
+
6
+ # The run the following from the root the project you wish to import
7
+ cap deprec:svn:install
8
+ cap deprec:svn:setup
9
+
10
+
11
+ # XXX Not tested on deprec2
12
+ #
13
+ #
14
+ # Installs subversion and trac software on server.
15
+ # Creates subversion repository on server and imports project.
16
+ # Sets up trac installation for project.
17
+ #
18
+ # role :scm, 'deptest.deprecated.org'
19
+ #
20
+ # # install packages
21
+ # cap apache_install svn_install trac_install
22
+ #
23
+ # # import project
24
+ # cap svn_import_project
25
+ # cap trac_init
26
+ # cap trac_start
27
+ #
28
+ # # your project will be viewable at http://yourdomain:8000/
29
+ # # you can add other users with 'cap trac_user_add'
30
+
31
+
@@ -0,0 +1,74 @@
1
+ deprec 2.0 roadmap
2
+
3
+ # expectations/constraints
4
+
5
+ - all tasks should be re-runnable
6
+ - all install_ tasks should install required dependancies
7
+ - users should expect that standard cap commands will work
8
+
9
+
10
+ # interactive tools
11
+
12
+ deprec should make it easy to perform commonly use sysadmin tasks.
13
+ While automation brings great power it's still often quicker to
14
+ run 'semi automated' tasks that require some interactive input.
15
+
16
+ For example, adding a user account to a number of servers could be
17
+ made easier with a general purpose interactive recipe:
18
+
19
+ cap add_user
20
+ > username for new user? : fred
21
+ > password for new user? : ******
22
+ > retype password : ******
23
+ > user type for new user?
24
+ 1. default
25
+ 2. admin
26
+ ?: 2
27
+ creating...
28
+ server01 - created user 'fred' of type 'admin'
29
+ server02 - created user 'fred' of type 'admin'
30
+ server03 - created user 'fred' of type 'admin'
31
+ server04 - user 'fred' exists. Set type to 'admin'
32
+
33
+ * Note that the servers above were all servers mentioned in deploy.rb
34
+ for a project however there are many ways to get this list.
35
+
36
+
37
+ Plugin support for different distro's was too ambitious. I've tried other
38
+ distros and didn't like them much. I'm happy with Ubuntu at the moment and
39
+ # # plugin based support different distros, versions (and possibly OS's)
40
+ #
41
+ # While deprec was built to work with Ubuntu 6.06, some people have shown interest
42
+ # in using it with other distro's. I plan to move all of the Ubuntu specific code
43
+ # into a separate gem 'deprec_ubuntu' which deprec will load by default. This will
44
+ # mean anyone else can create and maintain plugins that allow the use of other linux
45
+ # distros (and perhaps other OS's).
46
+ #
47
+ # All platform dependent functions will be:
48
+ #
49
+ # - cap extensions, not tasks
50
+ # - plugins, not part of the deprec itself
51
+ # - loaded using gemplugins http://mongrel.rubyforge.org/gem_plugin_rdoc/index.html
52
+ #
53
+ # I'd like 'cap -T' to show the distros supported for each command when not arch independant.
54
+
55
+
56
+ # add lots more useful tasks
57
+
58
+ I'd like to extend deprec beyond just getting your rails app up and running.
59
+ Anything I need that takes some time to do right will go in. If you've got
60
+ something you want added then write it and let me know.
61
+
62
+ install and configure the following package groups:
63
+ - source control (svn, trac)
64
+ - mail (postfix, imap, mutt, mailx)
65
+
66
+
67
+ # don't rely on third party servers to be available when installing software
68
+
69
+ As I write, www.apache.org is serving at a crawling pace. I'd like to make it easy for
70
+ users to download and cache all required third party apps, gems, etc and have deprec
71
+ use these.
72
+
73
+ Currently you can drop the tarballs into /usr/local/src on the target server and
74
+ they'll get picked up automatically. I haven't looked at a simple way to cache the gems yet.
@@ -0,0 +1,50 @@
1
+ #
2
+ # Old notes - YMMV
3
+ #
4
+
5
+ == deprec quickstart (with svn, trac and deployment to apache/mongrel/mysql)
6
+
7
+ Here are instructions that will take a fresh install of Ubuntu Dapper (6.06.1 server), create a working rails app, create an SVN repository and trac installation for it and deploy it using apache, mongrel and mysql.
8
+
9
+ All commands below are run on your local host. You will *never* be requested
10
+ to log into the remote server manually. Capistrano does all the work.
11
+
12
+ - Mike
13
+
14
+ # Install deprec on workstation
15
+ sudo gem install deprec --include-dependencies
16
+ echo 'require "deprec/recipes"' >> ~/.caprc
17
+ echo "ssh_options[:keys] = %w(${HOME}/.ssh/id_dsa)" >> ~/.caprc
18
+ echo 'ssh_options[:paranoid] = false' >> ~/.caprc
19
+ echo 'ssh_options[:forward_agent] = true' >> ~/.caprc
20
+
21
+ # Create rails project on workstation and configure for deprec
22
+ # (alternatively use an existing project)
23
+ rails example
24
+ cd example
25
+ ./script/generate scaffold_resource person name:string age:integer
26
+ deprec --apply-to . --name example --domain www.example.com
27
+
28
+ # NOTE! Use following two commands if you only have 'root' account on server
29
+ # Some VPS services provide you with this when you sign up
30
+ cap change_root_password_as_root # '_as_root' means run this as 'root' user
31
+ cap setup_admin_account_as_root
32
+
33
+ # Copy your ssh keys to remote server to avoid having to type passwords
34
+ cap setup_ssh_keys
35
+
36
+ # Install all required software on remote server
37
+ cap install_rails_stack svn_install trac_install
38
+
39
+ # Import application into subversion respository and setup trac
40
+ cap svn_setup
41
+ cap trac_setup
42
+ cap trac_user_add # this command allows you to create other trac users
43
+ cap trac_start # trac is now available on http://www.example.com:9000/
44
+ cap trac_stop # if you had the need
45
+
46
+ # Deploy application
47
+ cap setup
48
+ cap deploy_with_migrations
49
+ cap apache_restart
50
+ # application is now running on http://www.example.com/people
@@ -0,0 +1,12 @@
1
+ # update timezone on gutsy
2
+ # dpkg-reconfigure tzdata
3
+
4
+
5
+ # Building Edge Capistrano
6
+ You can build an edge gem by cd'ing to that directory and doing:
7
+
8
+ 1. svn info. Find the line that says "Revision:" and mark the revision number.
9
+ 2. rake PKG_BUILD=<rev> gem. Replace <rev> with the revision number.
10
+ 3. Look in the pkg subdirectory. Install that gem file via "gem install pkg/<gem file>"
11
+
12
+ - Jamis
Binary file
@@ -0,0 +1,8 @@
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,378 @@
1
+ # Copyright 2006-2008 by Mike Bailey. All rights reserved.
2
+ require 'capistrano'
3
+ require 'fileutils'
4
+
5
+ module Deprec2
6
+ DEPREC_TEMPLATES_BASE = File.join(File.dirname(__FILE__), 'templates')
7
+
8
+ # Render template (usually a config file)
9
+ #
10
+ # Usually we render it to a file on the local filesystem.
11
+ # This way, we keep a copy of the config file under source control.
12
+ # We can make manual changes if required and push to new hosts.
13
+ #
14
+ # If the options hash contains :path then it's written to that path.
15
+ # If it contains :remote => true, the file will instead be written to remote targets
16
+ # If options[:path] and options[:remote] are missing, it just returns the rendered
17
+ # template as a string (good for debugging).
18
+ #
19
+ # XXX I would like to get rid of :render_template_to_file
20
+ # XXX Perhaps pass an option to this function to write to remote
21
+ #
22
+ def render_template(app, options={})
23
+ template = options[:template]
24
+ path = options[:path] || nil
25
+ remote = options[:remote] || false
26
+ mode = options[:mode] || 0755
27
+ owner = options[:owner] || nil
28
+
29
+ # replace this with a check for the file
30
+ if ! template
31
+ puts "render_template() requires a value for the template!"
32
+ return false
33
+ end
34
+
35
+ # If local copies of deprec templates exist they will be used
36
+ # If you don't specify the location with the local_template_dir option
37
+ # it defaults to config/templates.
38
+ # e.g. config/templates/nginx/nginx.conf.erb
39
+ local_template = File.join(local_template_dir, app.to_s, template)
40
+ if File.exists?(local_template)
41
+ puts
42
+ puts "Using local template (#{local_template})"
43
+ template = ERB.new(IO.read(local_template), nil, '-')
44
+ else
45
+ template = ERB.new(IO.read(File.join(DEPREC_TEMPLATES_BASE, app.to_s, template)), nil, '-')
46
+ end
47
+ rendered_template = template.result(binding)
48
+
49
+ if remote
50
+ # render to remote machine
51
+ puts 'You need to specify a path to render the template to!' unless path
52
+ exit unless path
53
+ sudo "test -d #{File.dirname(path)} || sudo mkdir -p #{File.dirname(path)}"
54
+ std.su_put rendered_template, path, '/tmp/', :mode => mode
55
+ sudo "chown #{owner} #{path}" if defined?(owner)
56
+ elsif path
57
+ # render to local file
58
+ full_path = File.join('config', app.to_s, path)
59
+ path_dir = File.dirname(full_path)
60
+ if File.exists?(full_path)
61
+ if IO.read(full_path) == rendered_template
62
+ puts "[skip] File exists and is identical (#{full_path})."
63
+ return false
64
+ elsif overwrite?(full_path, rendered_template)
65
+ File.delete(full_path)
66
+ else
67
+ puts "[skip] Not overwriting #{full_path}"
68
+ return false
69
+ end
70
+ end
71
+ FileUtils.mkdir_p "#{path_dir}" if ! File.directory?(path_dir)
72
+ # added line above to make windows compatible
73
+ # system "mkdir -p #{path_dir}" if ! File.directory?(path_dir)
74
+ File.open(full_path, 'w'){|f| f.write rendered_template }
75
+ puts "[done] #{full_path} written"
76
+ else
77
+ # render to string
78
+ return rendered_template
79
+ end
80
+ end
81
+
82
+ def overwrite?(full_path, rendered_template)
83
+ if defined?(overwrite_all)
84
+ if overwrite_all == true
85
+ return true
86
+ else
87
+ return false
88
+ end
89
+ end
90
+
91
+ # XXX add :always and :never later - not sure how to set persistent value from here
92
+ # response = Capistrano::CLI.ui.ask "File exists. Overwrite? ([y]es, [n]o, [a]lways, n[e]ver)" do |q|
93
+ puts
94
+ response = Capistrano::CLI.ui.ask "File exists (#{full_path}).
95
+ Overwrite? ([y]es, [n]o, [d]iff)" do |q|
96
+ q.default = 'n'
97
+ end
98
+
99
+ case response
100
+ when 'y'
101
+ return true
102
+ when 'n'
103
+ return false
104
+ when 'd'
105
+ require 'tempfile'
106
+ tf = Tempfile.new("deprec_diff")
107
+ tf.puts(rendered_template)
108
+ tf.close
109
+ puts
110
+ puts "Running diff -u current_file new_file_if_you_overwrite"
111
+ puts
112
+ system "diff -u #{full_path} #{tf.path} | less"
113
+ puts
114
+ overwrite?(full_path, rendered_template)
115
+ # XXX add :always and :never later - not sure how to set persistent value from here
116
+ # when 'a'
117
+ # set :overwrite_all, true
118
+ # when 'e'
119
+ # set :overwrite_all, false
120
+ end
121
+
122
+ end
123
+
124
+ def render_template_to_file(template_name, destination_file_name, templates_dir = DEPREC_TEMPLATES_BASE)
125
+ template_name += '.conf' if File.extname(template_name) == '' # XXX this to be removed
126
+
127
+ file = File.join(templates_dir, template_name)
128
+ buffer = render :template => File.read(file)
129
+
130
+ temporary_location = "/tmp/#{template_name}"
131
+ put buffer, temporary_location
132
+ sudo "cp #{temporary_location} #{destination_file_name}"
133
+ delete temporary_location
134
+ end
135
+
136
+ # Copy configs to server(s). Note there is no :pull task. No changes should
137
+ # be made to configs on the servers so why would you need to pull them back?
138
+ def push_configs(app, files)
139
+ app = app.to_s
140
+ files.each do |file|
141
+ # If the file path is relative we will prepend a path to this projects
142
+ # own config directory for this service.
143
+ if file[:path][0,1] != '/'
144
+ full_remote_path = File.join(deploy_to, app, file[:path])
145
+ else
146
+ full_remote_path = file[:path]
147
+ end
148
+ full_local_path = File.join('config', app, file[:path])
149
+ sudo "test -d #{File.dirname(full_remote_path)} || sudo mkdir -p #{File.dirname(full_remote_path)}"
150
+ #
151
+ # XXX work this in to check for per-host variants of config files
152
+ #
153
+ # if any variants of this file exist for this host (they have -hostname at end)
154
+ # servers = find_servers_for_task(current_task)
155
+ # servers.each do |server|
156
+ # puts server(..., :hosts => server) # XXX find a way to restrict su_put to one host
157
+ # end
158
+ # else
159
+ # # just send them the normal way, it's quicker in parallel
160
+ std.su_put File.read(full_local_path), full_remote_path, '/tmp/', :mode=>file[:mode]
161
+ # end
162
+ #
163
+ sudo "chown #{file[:owner]} #{full_remote_path}"
164
+ end
165
+ end
166
+
167
+ def teardown_connections
168
+ sessions.keys.each do |server|
169
+ sessions[server].close
170
+ sessions.delete(server)
171
+ end
172
+ end
173
+
174
+
175
+ def append_to_file_if_missing(filename, value, options={})
176
+ # XXX sort out single quotes in 'value' - they'l break command!
177
+ # XXX if options[:requires_sudo] and :use_sudo then use sudo
178
+ sudo <<-END
179
+ sh -c '
180
+ grep -F "#{value}" #{filename} > /dev/null 2>&1 ||
181
+ test ! -f #{filename} ||
182
+ echo "#{value}" >> #{filename}
183
+ '
184
+ END
185
+ end
186
+
187
+ # create new user account on target system
188
+ def useradd(user, options={})
189
+ options[:shell] ||= '/bin/bash' # new accounts on ubuntu 6.06.1 have been getting /bin/sh
190
+ switches = ''
191
+ switches += " --shell=#{options[:shell]} " if options[:shell]
192
+ switches += ' --create-home ' unless options[:homedir] == false
193
+ switches += " --gid #{options[:group]} " unless options[:group].nil?
194
+ invoke_command "grep '^#{user}:' /etc/passwd || sudo /usr/sbin/useradd #{switches} #{user}",
195
+ :via => run_method
196
+ end
197
+
198
+ # create a new group on target system
199
+ def groupadd(group, options={})
200
+ via = options.delete(:via) || run_method
201
+ # XXX I don't like specifying the path to groupadd - need to sort out paths before long
202
+ invoke_command "grep '#{group}:' /etc/group || sudo /usr/sbin/groupadd #{group}", :via => via
203
+ end
204
+
205
+ # add group to the list of groups this user belongs to
206
+ def add_user_to_group(user, group)
207
+ invoke_command "groups #{user} | grep ' #{group} ' || sudo /usr/sbin/usermod -G #{group} -a #{user}",
208
+ :via => run_method
209
+ end
210
+
211
+ # create directory if it doesn't already exist
212
+ # set permissions and ownership
213
+ # XXX move mode, path and
214
+ def mkdir(path, options={})
215
+ via = options.delete(:via) || :run
216
+ # XXX need to make sudo commands wrap the whole command (sh -c ?)
217
+ # XXX removed the extra 'sudo' from after the '||' - need something else
218
+ invoke_command "sh -c 'test -d #{path} || mkdir -p #{path}'", :via => via
219
+ invoke_command "chmod #{sprintf("%3o",options[:mode]||0755)} #{path}", :via => via if options[:mode]
220
+ invoke_command "chown -R #{options[:owner]} #{path}", :via => via if options[:owner]
221
+ groupadd(options[:group], :via => via) if options[:group]
222
+ invoke_command "chgrp -R #{options[:group]} #{path}", :via => via if options[:group]
223
+ end
224
+
225
+ def create_src_dir
226
+ mkdir(src_dir, :mode => 0775, :group => group_src, :via => :sudo)
227
+ end
228
+
229
+ # download source package if we don't already have it
230
+ def download_src(src_package, src_dir)
231
+ create_src_dir
232
+ # check if file exists and if we have an MD5 hash or bytecount to compare
233
+ # against if so, compare and decide if we need to download again
234
+ if defined?(src_package[:md5sum])
235
+ md5_clause = " && echo '#{src_package[:md5sum]}' | md5sum -c - "
236
+ end
237
+ apt.install( {:base => %w(wget)}, :stable )
238
+ # XXX replace with invoke_command
239
+ sudo <<-SUDO
240
+ sh -c "cd #{src_dir} && test -f #{src_package[:filename]} #{md5_clause} || wget --quiet --timestamping #{src_package[:url]}"
241
+ SUDO
242
+ end
243
+
244
+ # unpack src and make it writable by the group
245
+ def unpack_src(src_package, src_dir)
246
+ package_dir = File.join(src_dir, src_package[:dir])
247
+ # XXX replace with invoke_command
248
+ sudo <<-SUDO
249
+ sh -c '
250
+ cd #{src_dir};
251
+ test -d #{package_dir}.old && rm -fr #{package_dir}.old;
252
+ test -d #{package_dir} && mv #{package_dir} #{package_dir}.old;
253
+ #{src_package[:unpack]}
254
+ chgrp -R #{group} #{package_dir};
255
+ chmod -R g+w #{package_dir};
256
+ '
257
+ SUDO
258
+ end
259
+
260
+ # install package from source
261
+ def install_from_src(src_package, src_dir)
262
+ package_dir = File.join(src_dir, src_package[:dir])
263
+ unpack_src(src_package, src_dir)
264
+ apt.install( {:base => %w(build-essential)}, :stable )
265
+ # XXX replace with invoke_command
266
+ sudo <<-SUDO
267
+ sh -c '
268
+ cd #{package_dir};
269
+ #{src_package[:configure]}
270
+ #{src_package[:make]}
271
+ #{src_package[:install]}
272
+ #{src_package[:post_install]}
273
+ '
274
+ SUDO
275
+ end
276
+
277
+
278
+ ##
279
+ # Run a command and ask for input when input_query is seen.
280
+ # Sends the response back to the server.
281
+ #
282
+ # +input_query+ is a regular expression that defaults to /^Password/.
283
+ #
284
+ # Can be used where +run+ would otherwise be used.
285
+ #
286
+ # run_with_input 'ssh-keygen ...', /^Are you sure you want to overwrite\?/
287
+
288
+ def run_with_input(shell_command, input_query=/^Password/, response=nil)
289
+ handle_command_with_input(:run, shell_command, input_query, response)
290
+ end
291
+
292
+ ##
293
+ # Run a command using sudo and ask for input when a regular expression is seen.
294
+ # Sends the response back to the server.
295
+ #
296
+ # See also +run_with_input+
297
+ #
298
+ # +input_query+ is a regular expression
299
+
300
+ def sudo_with_input(shell_command, input_query=/^Password/, response=nil)
301
+ handle_command_with_input(:sudo, shell_command, input_query, response)
302
+ end
303
+
304
+ def invoke_with_input(shell_command, input_query=/^Password/, response=nil)
305
+ handle_command_with_input(run_method, shell_command, input_query, response)
306
+ end
307
+
308
+ ##
309
+ # Run a command using sudo and continuously pipe the results back to the console.
310
+ #
311
+ # Similar to the built-in +stream+, but for privileged users.
312
+
313
+ def sudo_stream(command)
314
+ sudo(command) do |ch, stream, out|
315
+ puts out if stream == :out
316
+ if stream == :err
317
+ puts "[err : #{ch[:host]}] #{out}"
318
+ break
319
+ end
320
+ end
321
+ end
322
+
323
+ # We don't need this. Put 'USER=root' on the command line instead.
324
+ #
325
+ # XXX Not working in deprec2
326
+ # ##
327
+ # # Run a command using the root account.
328
+ # #
329
+ # # Some linux distros/VPS providers only give you a root login when you install.
330
+ #
331
+ # def run_as_root(shell_command)
332
+ # std.connect_as_root do |tempuser|
333
+ # run shell_command
334
+ # end
335
+ # end
336
+ #
337
+ # ##
338
+ # # Run a task using root account.
339
+ # #
340
+ # # Some linux distros/VPS providers only give you a root login when you install.
341
+ # #
342
+ # # tempuser: contains the value replaced by 'root' for the duration of this call
343
+ #
344
+ # def as_root()
345
+ # std.connect_as_root do |tempuser|
346
+ # yield tempuser
347
+ # end
348
+ # end
349
+
350
+
351
+
352
+ private
353
+
354
+ ##
355
+ # Does the actual capturing of the input and streaming of the output.
356
+ #
357
+ # local_run_method: run or sudo
358
+ # shell_command: The command to run
359
+ # input_query: A regular expression matching a request for input: /^Please enter your password/
360
+
361
+ def handle_command_with_input(local_run_method, shell_command, input_query, response=nil)
362
+ send(local_run_method, shell_command) do |channel, stream, data|
363
+ logger.info data, channel[:host]
364
+ if data =~ input_query
365
+ if response
366
+ channel.send_data "#{response}\n"
367
+ else
368
+ response = ::Capistrano::CLI.password_prompt "#{data}"
369
+ channel.send_data "#{response}\n"
370
+ end
371
+ end
372
+ end
373
+ end
374
+
375
+
376
+ end
377
+
378
+ Capistrano.plugin :deprec2, Deprec2