Empact-deprec 1.99.21

Sign up to get free protection for your applications and to get access to all the features.
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