crazycode-cap-recipes 0.3.37

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/LICENSE +20 -0
  2. data/README.textile +586 -0
  3. data/Rakefile +57 -0
  4. data/VERSION.yml +5 -0
  5. data/bin/cap-recipes +4 -0
  6. data/cap-recipes.gemspec +128 -0
  7. data/examples/advanced/deploy.rb +39 -0
  8. data/examples/advanced/deploy/experimental.rb +14 -0
  9. data/examples/advanced/deploy/production.rb +20 -0
  10. data/examples/simple/deploy.rb +36 -0
  11. data/lib/cap_recipes.rb +1 -0
  12. data/lib/cap_recipes/tasks/apache.rb +1 -0
  13. data/lib/cap_recipes/tasks/apache/install.rb +16 -0
  14. data/lib/cap_recipes/tasks/apache/manage.rb +26 -0
  15. data/lib/cap_recipes/tasks/aptitude.rb +1 -0
  16. data/lib/cap_recipes/tasks/aptitude/manage.rb +32 -0
  17. data/lib/cap_recipes/tasks/backgroundrb.rb +1 -0
  18. data/lib/cap_recipes/tasks/backgroundrb/hooks.rb +5 -0
  19. data/lib/cap_recipes/tasks/backgroundrb/manage.rb +64 -0
  20. data/lib/cap_recipes/tasks/bundler.rb +1 -0
  21. data/lib/cap_recipes/tasks/bundler/manage.rb +31 -0
  22. data/lib/cap_recipes/tasks/delayed_job.rb +1 -0
  23. data/lib/cap_recipes/tasks/delayed_job/hooks.rb +5 -0
  24. data/lib/cap_recipes/tasks/delayed_job/manage.rb +34 -0
  25. data/lib/cap_recipes/tasks/ec2/install.rb +32 -0
  26. data/lib/cap_recipes/tasks/ec2/manage.rb +32 -0
  27. data/lib/cap_recipes/tasks/gitosis.rb +1 -0
  28. data/lib/cap_recipes/tasks/gitosis/install.rb +58 -0
  29. data/lib/cap_recipes/tasks/gitosis/manage.rb +3 -0
  30. data/lib/cap_recipes/tasks/hudson.rb +1 -0
  31. data/lib/cap_recipes/tasks/hudson/manage.rb +33 -0
  32. data/lib/cap_recipes/tasks/jetty.rb +1 -0
  33. data/lib/cap_recipes/tasks/jetty/install.rb +33 -0
  34. data/lib/cap_recipes/tasks/jetty/manage.rb +34 -0
  35. data/lib/cap_recipes/tasks/jetty/web.rb +98 -0
  36. data/lib/cap_recipes/tasks/juggernaut.rb +3 -0
  37. data/lib/cap_recipes/tasks/juggernaut/hooks.rb +4 -0
  38. data/lib/cap_recipes/tasks/juggernaut/manage.rb +56 -0
  39. data/lib/cap_recipes/tasks/maven.rb +85 -0
  40. data/lib/cap_recipes/tasks/memcache.rb +3 -0
  41. data/lib/cap_recipes/tasks/memcache/hooks.rb +5 -0
  42. data/lib/cap_recipes/tasks/memcache/install.rb +15 -0
  43. data/lib/cap_recipes/tasks/memcache/manage.rb +37 -0
  44. data/lib/cap_recipes/tasks/mongodb.rb +1 -0
  45. data/lib/cap_recipes/tasks/mongodb/install.rb +137 -0
  46. data/lib/cap_recipes/tasks/mongodb/manage.rb +27 -0
  47. data/lib/cap_recipes/tasks/passenger.rb +1 -0
  48. data/lib/cap_recipes/tasks/passenger/install.rb +72 -0
  49. data/lib/cap_recipes/tasks/passenger/manage.rb +23 -0
  50. data/lib/cap_recipes/tasks/rails.rb +1 -0
  51. data/lib/cap_recipes/tasks/rails/hooks.rb +6 -0
  52. data/lib/cap_recipes/tasks/rails/manage.rb +51 -0
  53. data/lib/cap_recipes/tasks/ruby.rb +1 -0
  54. data/lib/cap_recipes/tasks/ruby/install.rb +16 -0
  55. data/lib/cap_recipes/tasks/rubygems.rb +1 -0
  56. data/lib/cap_recipes/tasks/rubygems/install.rb +22 -0
  57. data/lib/cap_recipes/tasks/rubygems/manage.rb +43 -0
  58. data/lib/cap_recipes/tasks/templates/hudson.erb +85 -0
  59. data/lib/cap_recipes/tasks/templates/mongod.conf.erb +89 -0
  60. data/lib/cap_recipes/tasks/templates/mongodb.init.erb +73 -0
  61. data/lib/cap_recipes/tasks/templates/mongodb.repo.erb +4 -0
  62. data/lib/cap_recipes/tasks/templates/mongos.init.erb +69 -0
  63. data/lib/cap_recipes/tasks/templates/tomcat.erb +95 -0
  64. data/lib/cap_recipes/tasks/thinking_sphinx.rb +1 -0
  65. data/lib/cap_recipes/tasks/thinking_sphinx/hooks.rb +4 -0
  66. data/lib/cap_recipes/tasks/thinking_sphinx/install.rb +17 -0
  67. data/lib/cap_recipes/tasks/thinking_sphinx/manage.rb +65 -0
  68. data/lib/cap_recipes/tasks/tomcat.rb +1 -0
  69. data/lib/cap_recipes/tasks/tomcat/install.rb +43 -0
  70. data/lib/cap_recipes/tasks/tomcat/manage.rb +34 -0
  71. data/lib/cap_recipes/tasks/tomcat/war.rb +98 -0
  72. data/lib/cap_recipes/tasks/utilities.rb +172 -0
  73. data/lib/cap_recipes/tasks/whenever.rb +1 -0
  74. data/lib/cap_recipes/tasks/whenever/hooks.rb +5 -0
  75. data/lib/cap_recipes/tasks/whenever/manage.rb +8 -0
  76. data/lib/cap_recipes/tasks/yum.rb +1 -0
  77. data/lib/cap_recipes/tasks/yum/manage.rb +30 -0
  78. data/lib/capify.rb +35 -0
  79. data/lib/templates/Capfile.tt +4 -0
  80. data/lib/templates/deploy.rb.tt +30 -0
  81. data/spec/cap/all/Capfile +2 -0
  82. data/spec/cap/helper.rb +3 -0
  83. data/spec/cap_recipes_spec.rb +56 -0
  84. data/spec/spec_helper.rb +37 -0
  85. data/specs.watchr +35 -0
  86. metadata +155 -0
@@ -0,0 +1 @@
1
+ Dir[File.join(File.dirname(__FILE__), 'thinking_sphinx/*.rb')].sort.each { |lib| require lib }
@@ -0,0 +1,4 @@
1
+ Capistrano::Configuration.instance(true).load do
2
+ after "deploy:update_code", "thinking_sphinx:symlink_config" # sym thinking_sphinx.yml on update code
3
+ after "deploy:restart" , "thinking_sphinx:restart" # restart thinking_sphinx on app restart
4
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../utilities')
2
+
3
+ Capistrano::Configuration.instance(true).load do
4
+ namespace :thinking_sphinx do
5
+ desc 'Installs sphinx and thinking_sphinx'
6
+ task :install, :roles => :app do
7
+ puts 'Installing thinking_sphinx'
8
+ utilities.apt_upgrade
9
+ utilities.apt_install 'build-essential libmysqlclient15-dev libmysql++-dev'
10
+ run "cd /tmp; #{sudo} wget http://www.sphinxsearch.com/downloads/sphinx-0.9.8.1.tar.gz"
11
+ run "cd /tmp; #{sudo} tar xvzf sphinx-0.9.8.1.tar.gz"
12
+ run "cd /tmp/sphinx-0.9.8.1/; #{sudo} ./configure --with-mysql-includes=/usr/include/mysql --with-mysql-libs=/usr/lib/mysql"
13
+ run "cd /tmp/sphinx-0.9.8.1/; #{sudo} make; #{sudo} make install"
14
+ sudo "gem install thinking-sphinx --source http://gemcutter.org --no-ri --no-rdoc"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,65 @@
1
+ Capistrano::Configuration.instance(true).load do
2
+ set :sphinx_role, :app
3
+
4
+ namespace :thinking_sphinx do
5
+ # ===============================================================
6
+ # PROCESS MANAGEMENT
7
+ # ===============================================================
8
+
9
+ desc "Starts the thinking sphinx searchd server"
10
+ task :start, :roles => sphinx_role do
11
+ utilities.with_role(sphinx_role) do
12
+ puts "Starting thinking sphinx searchd server"
13
+ rake = fetch(:rake, "rake")
14
+ rails_env = fetch(:rails_env, "production")
15
+
16
+ run "cd #{current_path}; #{rake} RAILS_ENV=#{rails_env} thinking_sphinx:configure"
17
+ run "cd #{current_path}; #{rake} RAILS_ENV=#{rails_env} ts:start"
18
+ end
19
+ end
20
+
21
+ desc "Stops the thinking sphinx searchd server"
22
+ task :stop, :roles => sphinx_role do
23
+ utilities.with_role(sphinx_role) do
24
+ puts "Stopping thinking sphinx searchd server"
25
+ rake = fetch(:rake, "rake")
26
+ rails_env = fetch(:rails_env, "production")
27
+
28
+ run "cd #{current_path}; #{rake} RAILS_ENV=#{rails_env} thinking_sphinx:configure"
29
+ run "cd #{current_path}; #{rake} RAILS_ENV=#{rails_env} ts:stop"
30
+ end
31
+ end
32
+
33
+ desc "Restarts the thinking sphinx searchd server"
34
+ task :restart, :roles => sphinx_role do
35
+ utilities.with_role(sphinx_role) do
36
+ thinking_sphinx.stop
37
+ thinking_sphinx.index
38
+ thinking_sphinx.start
39
+ end
40
+ end
41
+
42
+ # ===============================================================
43
+ # FILE MANAGEMENT
44
+ # ===============================================================
45
+
46
+ desc "Copies the shared/config/sphinx yaml to release/config/"
47
+ task :symlink_config, :roles => :app do
48
+ run "ln -s #{shared_path}/config/sphinx.yml #{release_path}/config/sphinx.yml"
49
+ end
50
+
51
+ desc "Displays the thinking sphinx log from the server"
52
+ task :tail, :roles => :app do
53
+ stream "tail -f #{shared_path}/log/searchd.log"
54
+ end
55
+
56
+ desc "Runs Thinking Sphinx indexer"
57
+ task :index, :roles => sphinx_role do
58
+ rake = fetch(:rake, "rake")
59
+ rails_env = fetch(:rails_env, "production")
60
+ puts "Updating search index"
61
+
62
+ run "cd #{current_path}; #{rake} RAILS_ENV=#{rails_env} ts:index"
63
+ end
64
+ end
65
+ end
@@ -0,0 +1 @@
1
+ Dir[File.join(File.dirname(__FILE__), 'tomcat/*.rb')].sort.each { |lib| require lib }
@@ -0,0 +1,43 @@
1
+ require 'fileutils'
2
+ require File.expand_path(File.dirname(__FILE__) + '/../utilities')
3
+
4
+ Capistrano::Configuration.instance(true).load do
5
+ default_run_options[:pty] = true
6
+ set :use_sudo, true
7
+
8
+ # TOMCAT SERVERS
9
+ _cset :tomcat_home, "/usr/local/apache-tomcat-6.0.29"
10
+ _cset :tomcat_ctrl, "/etc/init.d/tomcat"
11
+ _cset :java_home, "/usr/lib/jvm/java"
12
+
13
+ set :tomcat_user, do
14
+ user # default use current user.
15
+ end
16
+
17
+ #
18
+ # simple interactions with the tomcat server
19
+ #
20
+ namespace :tomcat do
21
+
22
+
23
+ desc "install tomcat"
24
+ task :install, :role => :app do
25
+ dir = File.dirname(tomcat_home)
26
+ basename = File.basename(tomcat_file)
27
+ basectl = File.basename(tomcat_ctrl)
28
+ utilities.sudo_upload "#{tomcat_file}", "#{dir}/#{basename}"
29
+ run "cd /tmp"
30
+ sudo "mkdir -p #{dir}"
31
+ sudo "tar -zvxf #{dir}/#{basename} -C #{dir}"
32
+ sudo "chown #{tomcat_user}:root #{tomcat_home} -R"
33
+
34
+ put utilities.render("tomcat", binding), "/tmp/tomcat.tmp"
35
+ sudo "cp /tmp/tomcat.tmp #{tomcat_ctrl}"
36
+ sudo "chmod a+x #{tomcat_ctrl}"
37
+ sudo "/sbin/chkconfig --add #{basectl}"
38
+ run "rm /tmp/tomcat.tmp"
39
+ sudo "rm #{dir}/#{basename}"
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,34 @@
1
+ Capistrano::Configuration.instance(true).load do
2
+ #
3
+ # simple interactions with the tomcat server
4
+ #
5
+ namespace :tomcat do
6
+
7
+ desc "start tomcat"
8
+ task :start do
9
+ sudo "#{tomcat_ctrl} start"
10
+ end
11
+
12
+ desc "stop tomcat"
13
+ task :stop do
14
+ sudo "#{tomcat_ctrl} stop"
15
+ end
16
+
17
+ desc "stop and start tomcat"
18
+ task :restart do
19
+ tomcat.stop
20
+ tomcat.start
21
+ end
22
+
23
+ desc "list tomcat process"
24
+ task :ps do
25
+ run "ps aux | grep tomcat | grep -v grep"
26
+ end
27
+
28
+ desc "tail :tomcat_home/logs/*.log and logs/catalina.out"
29
+ task :tail do
30
+ stream "tail -f #{tomcat_home}/logs/*.log #{tomcat_home}/logs/catalina.out"
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,98 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../utilities')
2
+
3
+ Capistrano::Configuration.instance(true).load do
4
+ # DEPLOYMENT SCHEME
5
+ set :scm, :none
6
+ set :deploy_via, :copy
7
+ set :use_sudo, true
8
+
9
+ _cset :deploy_to_parent, "/srv/applications"
10
+
11
+ default_run_options[:pty] = true
12
+
13
+ set :keep_releases, 5
14
+
15
+ set :repository do
16
+ fetch(:deploy_from)
17
+ end
18
+
19
+ set :deploy_from do
20
+ dir = "/tmp/prep_#{release_name}"
21
+ system("mkdir -p #{dir}")
22
+ dir
23
+ end
24
+
25
+ # this is capistrano's default location.
26
+ # depending on the permissions of the server
27
+ # you may need to create it and chown it over
28
+ # to :user (e.g. chown -R robotuser:robotuser /u)
29
+ set :deploy_to do
30
+ dir = "#{deploy_to_parent}/#{application}"
31
+ sudo "mkdir -p #{dir}"
32
+ sudo "chown #{user} #{dir}"
33
+ dir
34
+ end
35
+
36
+ #
37
+ # link the current/whatever.war into our webapps/whatever.war
38
+ #
39
+ #after 'deploy:setup' do
40
+ # cmd = "ln -s #{deploy_to}/current/`basename #{war}` #{tomcat_home}/webapps/`basename #{war}`"
41
+ # puts cmd
42
+ # sudo cmd
43
+ #end
44
+
45
+ # collect up our war into the deploy_from folder
46
+ # notice that all we're doing is a copy here,
47
+ # so it is pretty easy to swap this out for
48
+ # a wget command, which makes sense if you're
49
+ # using a continuous integration server like
50
+ # bamboo. (more on this later).
51
+ before 'deploy:update_code' do
52
+ unless(war.nil?)
53
+ puts "get war"
54
+ system("mkdir #{deploy_from}/webapp")
55
+ system("cp #{war} #{deploy_from}/webapp")
56
+ system("cd #{deploy_from}/webapp && jar xf `basename #{war}`")
57
+ system("rm -Rf #{deploy_from}/webapp/META-INF")
58
+ system("rm #{deploy_from}/webapp/`basename #{war}`")
59
+ puts system("ls -l #{deploy_from}")
60
+ end
61
+ end
62
+
63
+ #
64
+ # Disable all the default tasks that
65
+ # either don't apply, or I haven't made work.
66
+ #
67
+ namespace :deploy do
68
+ # restart tomcat
69
+ task :restart do
70
+ tomcat.restart
71
+ end
72
+
73
+ [ :upload, :cold, :start, :stop, :migrate, :migrations, :finalize_update ].each do |default_task|
74
+ desc "[internal] disabled"
75
+ task default_task do
76
+ # disabled
77
+ end
78
+ end
79
+
80
+ namespace :web do
81
+ [ :disable, :enable ].each do |default_task|
82
+ desc "[internal] disabled"
83
+ task default_task do
84
+ # disabled
85
+ end
86
+ end
87
+ end
88
+
89
+ namespace :pending do
90
+ [ :default, :diff ].each do |default_task|
91
+ desc "[internal] disabled"
92
+ task default_task do
93
+ # disabled
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,172 @@
1
+ require 'fileutils'
2
+
3
+ module Utilities
4
+ # set var
5
+ def _cset(name, *args, &block)
6
+ unless exists?(name)
7
+ set(name, *args, &block)
8
+ end
9
+ end
10
+
11
+ # render a template
12
+ def render(file, binding)
13
+ template = File.read("#{File.dirname(__FILE__)}/templates/#{file}.erb")
14
+ result = ERB.new(template).result(binding)
15
+ end
16
+
17
+ # utilities.config_gsub('/etc/example', /(.*)/im, "\\1")
18
+ def config_gsub(file, find, replace)
19
+ tmp="/tmp/#{File.basename(file)}"
20
+ get file, tmp
21
+ content=File.open(tmp).read
22
+ content.gsub!(find,replace)
23
+ put content, tmp
24
+ sudo "mv #{tmp} #{file}"
25
+ end
26
+
27
+
28
+ # utilities.ask('What is your name?', 'John')
29
+ def ask(question, default='')
30
+ question = "\n" + question.join("\n") if question.respond_to?(:uniq)
31
+ answer = Capistrano::CLI.ui.ask(space(question)).strip
32
+ answer.empty? ? default : answer
33
+ end
34
+
35
+ # utilities.yes?('Proceed with install?')
36
+ def yes?(question)
37
+ question = "\n" + question.join("\n") if question.respond_to?(:uniq)
38
+ question += ' (y/n)'
39
+ ask(question).downcase.include? 'y'
40
+ end
41
+
42
+ # utilities.apt_install %w[package1 package2]
43
+ # utilities.apt_install "package1 package2"
44
+ def apt_install(packages)
45
+ packages = packages.split(/\s+/) if packages.respond_to?(:split)
46
+ packages = Array(packages)
47
+ apt_get="DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive apt-get"
48
+ sudo "#{apt_get} -qyu --force-yes install #{packages.join(" ")}"
49
+ end
50
+
51
+ def apt_upgrade
52
+ apt_get="DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive apt-get"
53
+ sudo "#{apt_get} -qy update"
54
+ sudo "#{apt_get} -qyu --force-yes upgrade"
55
+ end
56
+ # utilities.yum_install %w[package1 package2]
57
+ # utilities.yum_install "package1 package2"
58
+ def yum_install(packages)
59
+ packages = packages.split(/\s+/) if packages.respond_to?(:split)
60
+ packages = Array(packages)
61
+ sudo "yum -y install #{packages.join(" ")}"
62
+ end
63
+
64
+ def yum_update
65
+ apt_get="DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive apt-get"
66
+ sudo "yum -y update"
67
+ end
68
+
69
+
70
+
71
+ # utilities.sudo_upload('/local/path/to/file', '/remote/path/to/destination', options)
72
+ def sudo_upload(from, to, options={}, &block)
73
+ top.upload from, "/tmp/#{File.basename(to)}", options, &block
74
+ sudo "mv /tmp/#{File.basename(to)} #{to}"
75
+ sudo "chmod #{options[:mode]} #{to}" if options[:mode]
76
+ sudo "chown #{options[:owner]} #{to}" if options[:owner]
77
+ end
78
+
79
+ # utilities.adduser('deploy')
80
+ def adduser(user, options={})
81
+ options[:shell] ||= '/bin/bash' # new accounts on ubuntu 6.06.1 have been getting /bin/sh
82
+ switches = '--disabled-password --gecos ""'
83
+ switches += " --shell=#{options[:shell]} " if options[:shell]
84
+ switches += ' --no-create-home ' if options[:nohome]
85
+ switches += " --ingroup #{options[:group]} " unless options[:group].nil?
86
+ invoke_command "grep '^#{user}:' /etc/passwd || sudo /usr/sbin/adduser #{user} #{switches}",
87
+ :via => run_method
88
+ end
89
+
90
+ # role = :app
91
+ def with_role(role, &block)
92
+ original, ENV['HOSTS'] = ENV['HOSTS'], find_servers(:roles => role).map{|d| d.host}.join(",")
93
+ begin
94
+ yield
95
+ ensure
96
+ ENV['HOSTS'] = original
97
+ end
98
+ end
99
+
100
+ # utilities.with_credentials(:user => 'xxxx', :password => 'secret')
101
+ # options = { :user => 'xxxxx', :password => 'xxxxx' }
102
+ def with_credentials(options={}, &block)
103
+ original_username, original_password = user, password
104
+ begin
105
+ set :user, options[:user] || original_username
106
+ set :password, options[:password] || original_password
107
+ yield
108
+ ensure
109
+ set :user, original_username
110
+ set :password, original_password
111
+ end
112
+ end
113
+
114
+ def space(str)
115
+ "\n#{'=' * 80}\n#{str}"
116
+ end
117
+
118
+ ##
119
+ # Run a command and ask for input when input_query is seen.
120
+ # Sends the response back to the server.
121
+ #
122
+ # +input_query+ is a regular expression that defaults to /^Password/.
123
+ # Can be used where +run+ would otherwise be used.
124
+ # run_with_input 'ssh-keygen ...', /^Are you sure you want to overwrite\?/
125
+ def run_with_input(shell_command, input_query=/^Password/, response=nil)
126
+ handle_command_with_input(:run, shell_command, input_query, response)
127
+ end
128
+
129
+ ##
130
+ # Run a command using sudo and ask for input when a regular expression is seen.
131
+ # Sends the response back to the server.
132
+ #
133
+ # See also +run_with_input+
134
+ # +input_query+ is a regular expression
135
+ def sudo_with_input(shell_command, input_query=/^Password/, response=nil)
136
+ handle_command_with_input(:sudo, shell_command, input_query, response)
137
+ end
138
+
139
+ def invoke_with_input(shell_command, input_query=/^Password/, response=nil)
140
+ handle_command_with_input(run_method, shell_command, input_query, response)
141
+ end
142
+
143
+ private
144
+
145
+ ##
146
+ # Does the actual capturing of the input and streaming of the output.
147
+ #
148
+ # local_run_method: run or sudo
149
+ # shell_command: The command to run
150
+ # input_query: A regular expression matching a request for input: /^Please enter your password/
151
+ def handle_command_with_input(local_run_method, shell_command, input_query, response=nil)
152
+ send(local_run_method, shell_command, {:pty => true}) do |channel, stream, data|
153
+
154
+ if data =~ input_query
155
+ if response
156
+ logger.info "#{data} #{"*"*(rand(10)+5)}", channel[:host]
157
+ channel.send_data "#{response}\n"
158
+ else
159
+ logger.info data, channel[:host]
160
+ response = ::Capistrano::CLI.password_prompt "#{data}"
161
+ channel.send_data "#{response}\n"
162
+ end
163
+ else
164
+ logger.info data, channel[:host]
165
+ end
166
+ end
167
+ end
168
+
169
+
170
+ end
171
+
172
+ Capistrano.plugin :utilities, Utilities