engineyard-eycap 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +84 -0
- data/Manifest.txt +25 -0
- data/README.txt +63 -0
- data/Rakefile +33 -0
- data/lib/capistrano/recipes/deploy/strategy/filtered_remote_cache.rb +48 -0
- data/lib/eycap/lib/ey_logger.rb +124 -0
- data/lib/eycap/lib/ey_logger_hooks.rb +14 -0
- data/lib/eycap/recipes/backgroundrb.rb +23 -0
- data/lib/eycap/recipes/database.rb +37 -0
- data/lib/eycap/recipes/deploy.rb +90 -0
- data/lib/eycap/recipes/ferret.rb +20 -0
- data/lib/eycap/recipes/juggernaut.rb +18 -0
- data/lib/eycap/recipes/memcached.rb +20 -0
- data/lib/eycap/recipes/mongrel.rb +28 -0
- data/lib/eycap/recipes/monit.rb +17 -0
- data/lib/eycap/recipes/nginx.rb +36 -0
- data/lib/eycap/recipes/slice.rb +21 -0
- data/lib/eycap/recipes/solr.rb +37 -0
- data/lib/eycap/recipes/sphinx.rb +34 -0
- data/lib/eycap/recipes/templates/maintenance.rhtml +53 -0
- data/lib/eycap/recipes/tomcat.rb +16 -0
- data/lib/eycap/recipes.rb +23 -0
- data/lib/eycap.rb +3 -0
- data/test/test_eycap.rb +11 -0
- data/test/test_helper.rb +2 -0
- metadata +98 -0
data/History.txt
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
== HEAD / 0000-00-00
|
2
|
+
* rake install_gem_no_doc for faster install
|
3
|
+
|
4
|
+
== 0.3.3 / 2008-05-07
|
5
|
+
* add ey_logger to log deploys to server
|
6
|
+
|
7
|
+
== 0.3.2 / 2008-04-29
|
8
|
+
* adding db:clone_to_local task to take a dump on the slice, fetch it, and load it into your dev db on your workstation
|
9
|
+
* only clone from replica database
|
10
|
+
* remove call to variable in task desc
|
11
|
+
* fix ferret symlinking
|
12
|
+
* gemspec for github
|
13
|
+
|
14
|
+
== 0.3.1 / 2008-03-17
|
15
|
+
* Make the custom maintenance pages actually work!
|
16
|
+
|
17
|
+
== 0.3.0 / 2008-03-05
|
18
|
+
* Adding custom maintenance pages is now as easy as copying a custom html file to #{shared_path}/system/maintenance.html.custom
|
19
|
+
|
20
|
+
== 0.2.10 / 2008-03-02
|
21
|
+
* Symlink memcached.yml only on :memcached => true, except :no_release => true
|
22
|
+
|
23
|
+
== 0.2.9 / 2008-02-27
|
24
|
+
* Fix a bug with ultrasphinx:configure running on multiple hosts
|
25
|
+
|
26
|
+
== 0.2.8 / 2008-02-20
|
27
|
+
* Add tasks for solr starting,stopping, and log tailing.
|
28
|
+
* Add monit namespace and make appservers php/merb compatible
|
29
|
+
* Make ultrasphinx symlinking a little smarter
|
30
|
+
* Add tomcat tasks for spongecell
|
31
|
+
|
32
|
+
== 0.2.6 / 2008-02-14
|
33
|
+
* Make mongrel restarts only apply to mongrel slices
|
34
|
+
|
35
|
+
== 0.2.5 / 2008-02-11
|
36
|
+
* Added db cloning task
|
37
|
+
|
38
|
+
== 0.2.4 / 2008-02-06
|
39
|
+
* Symlink memcached.yml in on deploy if you enable the callback
|
40
|
+
|
41
|
+
== 0.2.3 / 2008-02-01
|
42
|
+
* Make log tailing environmentally aware. Also add tasks to tail mongrel logs
|
43
|
+
|
44
|
+
== 0.2.2 / 2008-01-25
|
45
|
+
* sphinx:configure ultrasphinx configuration task
|
46
|
+
|
47
|
+
== 0.2.1 / 2008-01-25
|
48
|
+
* override default deploy recipe start/stop tasks
|
49
|
+
|
50
|
+
== 0.2.0 / 2008-01-23
|
51
|
+
* sphinx:symlink ultrasphinx configuration directory
|
52
|
+
|
53
|
+
== 0.1.9 / 2008-01-21
|
54
|
+
* Correct memcached tasks.
|
55
|
+
|
56
|
+
== 0.1.8 / 2008-01-20
|
57
|
+
* Add memcached tasks
|
58
|
+
|
59
|
+
== 0.1.7 / 2008-01-19
|
60
|
+
* fix symlink_configs task
|
61
|
+
|
62
|
+
== 0.1.6 / 2008-01-19
|
63
|
+
* add restart tasks for backgroundrb
|
64
|
+
|
65
|
+
== 0.1.5 / 2008-01-18
|
66
|
+
* fixed bug in filtered_remote_cache that prevented a changed checkout URL from taking over the cache
|
67
|
+
|
68
|
+
== 0.1.4 / 2008-01-17
|
69
|
+
* added sphinx:[reindex|start|stop|restart] matches only app servers with :sphinx => true
|
70
|
+
|
71
|
+
== 0.1.3 / 2008-01-17
|
72
|
+
* filtered_remote_cache to removes the cached copy of the source URL changed
|
73
|
+
|
74
|
+
== 0.1.2 / 2008-01-15
|
75
|
+
* added filtered_remote_cache capistrano deployment strategy
|
76
|
+
|
77
|
+
== 0.1.1 / 2008-01-15
|
78
|
+
* removed database tasks until problem with 'defer' is solved
|
79
|
+
|
80
|
+
== 0.1.0 / 2008-01-14
|
81
|
+
* Bugfix for empty :application variable
|
82
|
+
|
83
|
+
== 0.0.1 / 2008-01-14
|
84
|
+
* Initial release
|
data/Manifest.txt
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
lib/capistrano/recipes/deploy/strategy/filtered_remote_cache.rb
|
6
|
+
lib/eycap.rb
|
7
|
+
lib/eycap/lib/ey_logger.rb
|
8
|
+
lib/eycap/lib/ey_logger_hooks.rb
|
9
|
+
lib/eycap/recipes.rb
|
10
|
+
lib/eycap/recipes/backgroundrb.rb
|
11
|
+
lib/eycap/recipes/database.rb
|
12
|
+
lib/eycap/recipes/deploy.rb
|
13
|
+
lib/eycap/recipes/ferret.rb
|
14
|
+
lib/eycap/recipes/juggernaut.rb
|
15
|
+
lib/eycap/recipes/memcached.rb
|
16
|
+
lib/eycap/recipes/mongrel.rb
|
17
|
+
lib/eycap/recipes/monit.rb
|
18
|
+
lib/eycap/recipes/nginx.rb
|
19
|
+
lib/eycap/recipes/slice.rb
|
20
|
+
lib/eycap/recipes/solr.rb
|
21
|
+
lib/eycap/recipes/sphinx.rb
|
22
|
+
lib/eycap/recipes/templates/maintenance.rhtml
|
23
|
+
lib/eycap/recipes/tomcat.rb
|
24
|
+
test/test_eycap.rb
|
25
|
+
test/test_helper.rb
|
data/README.txt
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
= eycap
|
2
|
+
|
3
|
+
== DESCRIPTION:
|
4
|
+
|
5
|
+
Engine Yard capistrano tasks for use specifically with Engine Yard slices. They include convenience methods for managed a database, mongrel, nginx or other services.
|
6
|
+
|
7
|
+
Also included is a deployment strategy, :filtered_remote_cache, which speeds up deployment like :remote_cache, but filters out .svn directory which are a security risk and write slowly to shared disks.
|
8
|
+
|
9
|
+
== REQUIREMENTS:
|
10
|
+
|
11
|
+
* capistrano (http://capify.org) > 2.0.0, but recommended with > 2.2.0
|
12
|
+
|
13
|
+
== INSTALL:
|
14
|
+
|
15
|
+
$ gem sources -a http://gems.github.com/ (you only need to do this once)
|
16
|
+
$ gem install engineyard-eycap
|
17
|
+
|
18
|
+
== SOURCE:
|
19
|
+
|
20
|
+
eycaps git repo is available on GitHub, which can be browsed at:
|
21
|
+
|
22
|
+
http://github.com/engineyard/eycap
|
23
|
+
|
24
|
+
and cloned from:
|
25
|
+
|
26
|
+
git://github.com/engineyard/eycap.git
|
27
|
+
|
28
|
+
== USAGE:
|
29
|
+
|
30
|
+
= Include in capistrano
|
31
|
+
|
32
|
+
In your deploy.rb, simply include this line at the top:
|
33
|
+
|
34
|
+
require 'eycap/recipes'
|
35
|
+
|
36
|
+
= Filtered remote cache
|
37
|
+
|
38
|
+
To use filtered_remote_cache, simply:
|
39
|
+
|
40
|
+
set :deploy_via, :filtered_remote_cache
|
41
|
+
|
42
|
+
== LICENSE:
|
43
|
+
|
44
|
+
Copyright (c) 2008 Engine Yard
|
45
|
+
|
46
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
47
|
+
a copy of this software and associated documentation files (the
|
48
|
+
"Software"), to deal in the Software without restriction, including
|
49
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
50
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
51
|
+
permit persons to whom the Software is furnished to do so, subject to
|
52
|
+
the following conditions:
|
53
|
+
|
54
|
+
The above copyright notice and this permission notice shall be
|
55
|
+
included in all copies or substantial portions of the Software.
|
56
|
+
|
57
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
58
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
59
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
60
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
61
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
62
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
63
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'hoe'
|
3
|
+
require './lib/eycap'
|
4
|
+
|
5
|
+
Hoe.new('eycap', Eycap::VERSION) do |p|
|
6
|
+
p.author = 'Engine Yard'
|
7
|
+
p.email = 'tech@engineyard.com'
|
8
|
+
p.summary = 'Capistrano tasks for Engine Yard slices'
|
9
|
+
p.description = 'A bunch of useful recipes to help deployment to Engine Yard slices'
|
10
|
+
p.url = 'http://eycap.rubyforge.org'
|
11
|
+
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
12
|
+
p.extra_deps << ['capistrano', '>= 2.2.0']
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Open an irb session preloaded with this library"
|
16
|
+
task :console do
|
17
|
+
sh "irb -rubygems -r ./lib/eycap.rb"
|
18
|
+
end
|
19
|
+
|
20
|
+
task :coverage do
|
21
|
+
system("rm -fr coverage")
|
22
|
+
system("rcov test/test_*.rb")
|
23
|
+
system("open coverage/index.html")
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Upload site to Rubyforge"
|
27
|
+
task :site do
|
28
|
+
end
|
29
|
+
|
30
|
+
desc 'Install the package as a gem.'
|
31
|
+
task :install_gem_no_doc => [:clean, :package] do
|
32
|
+
sh "#{'sudo ' unless Hoe::WINDOZE}gem install --local --no-rdoc --no-ri pkg/*.gem"
|
33
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'capistrano/recipes/deploy/strategy/remote'
|
2
|
+
|
3
|
+
module Capistrano
|
4
|
+
module Deploy
|
5
|
+
module Strategy
|
6
|
+
|
7
|
+
# Implements the deployment strategy that keeps a cached checkout of
|
8
|
+
# the source code on each remote server. Each deploy simply updates the
|
9
|
+
# cached checkout, and then filters a copy through tar to remove unwanted .svn directories,
|
10
|
+
# finally leaving a pristeen, export-like copy at the destination.
|
11
|
+
class FilteredRemoteCache < Remote
|
12
|
+
# Executes the SCM command for this strategy and writes the REVISION
|
13
|
+
# mark file to each host.
|
14
|
+
def deploy!
|
15
|
+
update_repository_cache
|
16
|
+
tar_copy_repository_cache
|
17
|
+
end
|
18
|
+
|
19
|
+
def check!
|
20
|
+
super.check do |d|
|
21
|
+
d.remote.writable(shared_path)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def repository_cache
|
28
|
+
configuration[:repository_cache] || "/var/cache/engineyard/#{configuration[:application]}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def update_repository_cache
|
32
|
+
logger.trace "checking if the cached copy URL matches this deploy, then updating it"
|
33
|
+
command = "if [ -d #{repository_cache} ] && ! [ `svn info #{repository_cache} | grep URL | awk '{print $2}'` = '#{configuration[:repository]}' ]; then " +
|
34
|
+
"rm -rf #{repository_cache} && #{source.checkout(revision, repository_cache)}; " +
|
35
|
+
"elif [ -d #{repository_cache} ]; then #{source.sync(revision, repository_cache)}; " +
|
36
|
+
"else #{source.checkout(revision, repository_cache)}; fi"
|
37
|
+
scm_run(command)
|
38
|
+
end
|
39
|
+
|
40
|
+
def tar_copy_repository_cache
|
41
|
+
logger.trace "copying and filtering .svn via tar from cached version to #{configuration[:release_path]}"
|
42
|
+
run "mkdir #{configuration[:release_path]} && tar c --exclude=#{configuration[:filter_spec] || ".svn"} -C #{repository_cache} . | tar xC #{configuration[:release_path]} && #{mark}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
module Capistrano
|
3
|
+
|
4
|
+
class Logger
|
5
|
+
|
6
|
+
def ey_log(level, message, line_prefix = nil)
|
7
|
+
EYLogger.log(level, message, line_prefix) if EYLogger.setup?
|
8
|
+
log_without_ey_logging(level, message, line_prefix)
|
9
|
+
end
|
10
|
+
|
11
|
+
unless method_defined?(:log_without_ey_logging)
|
12
|
+
alias_method :log_without_ey_logging, :log
|
13
|
+
alias_method :log, :ey_log
|
14
|
+
end
|
15
|
+
|
16
|
+
def close
|
17
|
+
device.close if @needs_close
|
18
|
+
EYLogger.close if EYLogger.setup?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class EYLogger
|
23
|
+
|
24
|
+
# Sets up the EYLogger to beging capturing capistrano's logging. You should pass the capistrno configuration
|
25
|
+
# and the deploy type as a string. The deploy type is for reporting purposes only but must be included.
|
26
|
+
def self.setup(configuration, deploy_type, options = {})
|
27
|
+
@_configuration = configuration
|
28
|
+
@_deploy_type = deploy_type.gsub(/:/, "_")
|
29
|
+
@_log_path = options[:deploy_log_path] || Dir.tmpdir
|
30
|
+
@_log_path << "/" unless @_log_path =~ /\/$/
|
31
|
+
FileUtils.mkdir_p(@_log_path)
|
32
|
+
@_setup = true
|
33
|
+
@_success = true
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.log(level, message, line_prefix=nil)
|
37
|
+
return nil unless setup?
|
38
|
+
@release_name = @_configuration[:release_name] if @release_name.nil?
|
39
|
+
@_log_file_path = @_log_path + @release_name + ".log" unless @_log_file_path
|
40
|
+
@_deploy_log_file = File.open(@_log_file_path, "w") if @_deploy_log_file.nil?
|
41
|
+
|
42
|
+
indent = "%*s" % [Logger::MAX_LEVEL, "*" * (Logger::MAX_LEVEL - level)]
|
43
|
+
message.each do |line|
|
44
|
+
if line_prefix
|
45
|
+
@_deploy_log_file << "#{indent} [#{line_prefix}] #{line.strip}\n"
|
46
|
+
else
|
47
|
+
@_deploy_log_file << "#{indent} #{line.strip}\n"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.post_process
|
53
|
+
unless ::Interrupt === $!
|
54
|
+
puts "\n\nPlease wait while the log file is processed\n"
|
55
|
+
# Should dump the stack trace of an exception if there is one
|
56
|
+
error = $!
|
57
|
+
unless error.nil?
|
58
|
+
@_deploy_log_file << error.message << "\n"
|
59
|
+
@_deploy_log_file << error.backtrace.join("\n")
|
60
|
+
@_success = false
|
61
|
+
end
|
62
|
+
self.close
|
63
|
+
|
64
|
+
hooks = [:any]
|
65
|
+
hooks << self.successful? ? :success : :failure
|
66
|
+
puts "Executing Post Processing Hooks"
|
67
|
+
hooks.each do |h|
|
68
|
+
@_post_process_hooks[h].each do |key|
|
69
|
+
@_configuration.parent.find_and_execute_task(key)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
puts "Finished Post Processing Hooks"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Adds a post processing hook.
|
77
|
+
#
|
78
|
+
# Provide a task name to execute. These tasks are executed after capistrano has actually run its course.
|
79
|
+
#
|
80
|
+
# Takes a key to control when the hook is executed.'
|
81
|
+
# :any - always executed
|
82
|
+
# :success - only execute on success
|
83
|
+
# :failure - only execute on failure
|
84
|
+
#
|
85
|
+
# ==== Example
|
86
|
+
# Capistrano::EYLogger.post_process_hook( "ey_logger:upload_log_to_slice", :any)
|
87
|
+
#
|
88
|
+
def self.post_process_hook(task, key = :any)
|
89
|
+
@_post_process_hooks ||= Hash.new{|h,k| h[k] = []}
|
90
|
+
@_post_process_hooks[key] << task
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.setup?
|
94
|
+
!!@_setup
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.deploy_type
|
98
|
+
@_deploy_type
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.successful?
|
102
|
+
!!@_success
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.failure?
|
106
|
+
!@_success
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.log_file_path
|
110
|
+
@_log_file_path
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.remote_log_file_name
|
114
|
+
@_log_file_name ||= "#{@_configuration[:release_name]}-#{@_deploy_type}-#{self.successful? ? "SUCCESS" : "FAILURE"}.log"
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.close
|
118
|
+
@_deploy_log_file.flush unless @_deploy_log_file.nil?
|
119
|
+
@_deploy_log_file.close unless @_deploy_log_file.nil?
|
120
|
+
@_setup = false
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "ey_logger")
|
2
|
+
|
3
|
+
# These tasks are setup to use with the logger as post commit hooks.
|
4
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
5
|
+
namespace :ey_logger do
|
6
|
+
task :upload_log_to_slice, :except => { :no_release => true} do
|
7
|
+
logger = Capistrano::EYLogger
|
8
|
+
run "mkdir -p #{shared_path}/deploy_logs"
|
9
|
+
put File.open(logger.log_file_path).read, "#{shared_path}/deploy_logs/#{logger.remote_log_file_name}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
Capistrano::EYLogger.post_process_hook("ey_logger:upload_log_to_slice")
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :bdrb do
|
4
|
+
desc "After update_code you want to reindex"
|
5
|
+
task :reindex, :roles => :app, :only => {:backgroundrb => true} do
|
6
|
+
run "/engineyard/bin/searchd #{application} reindex"
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Start Backgroundrb"
|
10
|
+
task :start, :roles => :app, :only => {:backgroundrb => true} do
|
11
|
+
sudo "/usr/bin/monit start all -g backgroundrb_#{application}"
|
12
|
+
end
|
13
|
+
desc "Stop Backgroundrb"
|
14
|
+
task :stop, :roles => :app, :only => {:backgroundrb => true} do
|
15
|
+
sudo "/usr/bin/monit stop all -g backgroundrb_#{application}"
|
16
|
+
end
|
17
|
+
desc "Restart Backgroundrb"
|
18
|
+
task :restart, :roles => :app, :only => {:backgroundrb => true} do
|
19
|
+
sudo "/usr/bin/monit restart all -g backgroundrb_#{application}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :db do
|
4
|
+
task :backup_name, :only => { :primary => true } do
|
5
|
+
now = Time.now
|
6
|
+
run "mkdir -p #{shared_path}/db_backups"
|
7
|
+
backup_time = [now.year,now.month,now.day,now.hour,now.min,now.sec].join('-')
|
8
|
+
set :backup_file, "#{shared_path}/db_backups/#{environment_database}-snapshot-#{backup_time}.sql"
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Clone Production Database to Staging Database."
|
12
|
+
task :clone_prod_to_staging, :roles => :db, :only => { :primary => true } do
|
13
|
+
backup_name
|
14
|
+
on_rollback { run "rm -f #{backup_file}" }
|
15
|
+
run "mysqldump --add-drop-table -u #{dbuser} -h #{production_dbhost}-replica -p#{dbpass} #{production_database} > #{backup_file}"
|
16
|
+
run "mysql -u #{dbuser} -p#{dbpass} -h #{staging_dbhost} #{staging_database} < #{backup_file}"
|
17
|
+
run "rm -f #{backup_file}"
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Backup your database to shared_path+/db_backups"
|
21
|
+
task :dump, :roles => :db, :only => {:primary => true} do
|
22
|
+
backup_name
|
23
|
+
run "mysqldump --add-drop-table -u #{dbuser} -h #{environment_dbhost}-replica -p#{dbpass} #{environment_database} | bzip2 -c > #{backup_file}.bz2"
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Sync your production database to your local workstation"
|
27
|
+
task :clone_to_local, :roles => :db, :only => {:primary => true} do
|
28
|
+
backup_name
|
29
|
+
dump
|
30
|
+
get "#{backup_file}.bz2", "/tmp/#{application}.sql.gz"
|
31
|
+
development_info = YAML.load_file("config/database.yml")['development']
|
32
|
+
run_str = "bzcat /tmp/#{application}.sql.gz | mysql -u #{development_info['username']} -p#{development_info['password']} -h #{development_info['host']} #{development_info['database']}"
|
33
|
+
%x!#{run_str}!
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "lib", "ey_logger.rb")
|
2
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
3
|
+
|
4
|
+
namespace :deploy do
|
5
|
+
# This is here to hook into the logger for deploy and deploy:long tasks
|
6
|
+
["deploy", "deploy:long"].each do |tsk|
|
7
|
+
before(tsk) do
|
8
|
+
Capistrano::EYLogger.setup( self, tsk )
|
9
|
+
at_exit{ Capistrano::EYLogger.post_process if Capistrano::EYLogger.setup? }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Link the database.yml and mongrel_cluster.yml files into the current release path."
|
14
|
+
task :symlink_configs, :roles => :app, :except => {:no_release => true} do
|
15
|
+
run <<-CMD
|
16
|
+
cd #{release_path} &&
|
17
|
+
ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml &&
|
18
|
+
ln -nfs #{shared_path}/config/mongrel_cluster.yml #{release_path}/config/mongrel_cluster.yml
|
19
|
+
CMD
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Display the maintenance.html page while deploying with migrations. Then it restarts and enables the site again."
|
23
|
+
task :long do
|
24
|
+
transaction do
|
25
|
+
update_code
|
26
|
+
web.disable
|
27
|
+
symlink
|
28
|
+
migrate
|
29
|
+
end
|
30
|
+
|
31
|
+
restart
|
32
|
+
web.enable
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "Restart the Mongrel processes on the app slices."
|
36
|
+
task :restart, :roles => :app do
|
37
|
+
mongrel.restart
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "Start the Mongrel processes on the app slices."
|
41
|
+
task :spinner, :roles => :app do
|
42
|
+
mongrel.start
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "Start the Mongrel processes on the app slices."
|
46
|
+
task :start, :roles => :app do
|
47
|
+
mongrel.start
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "Stop the Mongrel processes on the app slices."
|
51
|
+
task :stop, :roles => :app do
|
52
|
+
mongrel.stop
|
53
|
+
end
|
54
|
+
|
55
|
+
namespace :web do
|
56
|
+
desc <<-DESC
|
57
|
+
Present a maintenance page to visitors. Disables your application's web \
|
58
|
+
interface by writing a "maintenance.html" file to each web server. The \
|
59
|
+
servers must be configured to detect the presence of this file, and if \
|
60
|
+
it is present, always display it instead of performing the request.
|
61
|
+
|
62
|
+
By default, the maintenance page will just say the site is down for \
|
63
|
+
"maintenance", and will be back "shortly", but you can customize the \
|
64
|
+
page by specifying the REASON and UNTIL environment variables:
|
65
|
+
|
66
|
+
$ cap deploy:web:disable \\
|
67
|
+
REASON="hardware upgrade" \\
|
68
|
+
UNTIL="12pm Central Time"
|
69
|
+
|
70
|
+
Further customization copy your html file to shared_path+'/system/maintenance.html.custom'.
|
71
|
+
If this file exists it will be used instead of the default capistrano ugly page
|
72
|
+
DESC
|
73
|
+
task :disable, :roles => :web, :except => { :no_release => true } do
|
74
|
+
maint_file = "#{shared_path}/system/maintenance.html"
|
75
|
+
require 'erb'
|
76
|
+
on_rollback { run "rm #{shared_path}/system/maintenance.html" }
|
77
|
+
|
78
|
+
reason = ENV['REASON']
|
79
|
+
deadline = ENV['UNTIL']
|
80
|
+
|
81
|
+
template = File.read(File.join(File.dirname(__FILE__), "templates", "maintenance.rhtml"))
|
82
|
+
result = ERB.new(template).result(binding)
|
83
|
+
|
84
|
+
put result, "#{shared_path}/system/maintenance.html.tmp", :mode => 0644
|
85
|
+
run "if [ -f #{shared_path}/system/maintenance.html.custom ]; then cp #{shared_path}/system/maintenance.html.custom #{maint_file}; else cp #{shared_path}/system/maintenance.html.tmp #{maint_file}; fi"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :ferret do
|
4
|
+
desc "After update_code you want to symlink the index and ferret_server.yml file into place"
|
5
|
+
task :symlink_configs, :roles => :app, :except => {:no_release => true} do
|
6
|
+
run <<-CMD
|
7
|
+
cd #{release_path} &&
|
8
|
+
ln -nfs #{shared_path}/config/ferret_server.yml #{release_path}/config/ferret_server.yml &&
|
9
|
+
if [ -d #{release_path}/index ]; then mv #{release_path}/index #{release_path}/index.bak; fi &&
|
10
|
+
ln -nfs #{shared_path}/index #{release_path}/index
|
11
|
+
CMD
|
12
|
+
end
|
13
|
+
[:start,:stop,:restart].each do |op|
|
14
|
+
desc "#{op} ferret server"
|
15
|
+
task op, :roles => :app, :except => {:no_release => true} do
|
16
|
+
sudo "/usr/bin/monit #{op} all -g ferret_#{application}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :juggernaut do
|
4
|
+
desc "After update_code you want to symlink the juggernaut.yml file into place"
|
5
|
+
task :symlink_configs, :roles => :app, :except => {:no_release => true} do
|
6
|
+
run <<-CMD
|
7
|
+
cd #{release_path} &&
|
8
|
+
ln -nfs #{shared_path}/config/juggernaut.yml #{release_path}/config/juggernaut.yml
|
9
|
+
CMD
|
10
|
+
end
|
11
|
+
[:start,:stop,:restart].each do |op|
|
12
|
+
desc "#{op} juggernaut server"
|
13
|
+
task op, :roles => :app, :except => {:no_release => true} do
|
14
|
+
sudo "/usr/bin/monit #{op} all -g juggernaut_#{application}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
namespace :memcached do
|
3
|
+
desc "Start memcached"
|
4
|
+
task :start, :roles => :app, :only => {:memcached => true} do
|
5
|
+
sudo "/etc/init.d/memcached start"
|
6
|
+
end
|
7
|
+
desc "Stop memcached"
|
8
|
+
task :stop, :roles => :app, :only => {:memcached => true} do
|
9
|
+
sudo "/etc/init.d/memcached stop"
|
10
|
+
end
|
11
|
+
desc "Restart memcached"
|
12
|
+
task :restart, :roles => :app, :only => {:memcached => true} do
|
13
|
+
sudo "/etc/init.d/memcached restart"
|
14
|
+
end
|
15
|
+
desc "Symlink the memcached.yml file into place if it exists"
|
16
|
+
task :symlink_configs, :roles => :app, :only => {:memcached => true }, :except => { :no_release => true } do
|
17
|
+
run "if [ -f #{shared_path}/config/memcached.yml ]; then ln -nfs #{shared_path}/config/memcached.yml #{release_path}/config/memcached.yml; fi"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
namespace :mongrel do
|
3
|
+
desc <<-DESC
|
4
|
+
Start Mongrel processes on the app server. This uses the :use_sudo variable to determine whether to use sudo or not. By default, :use_sudo is
|
5
|
+
set to true.
|
6
|
+
DESC
|
7
|
+
task :start, :roles => :app do
|
8
|
+
sudo "/usr/bin/monit start all -g #{monit_group}"
|
9
|
+
end
|
10
|
+
|
11
|
+
desc <<-DESC
|
12
|
+
Restart the Mongrel processes on the app server by starting and stopping the cluster. This uses the :use_sudo
|
13
|
+
variable to determine whether to use sudo or not. By default, :use_sudo is set to true.
|
14
|
+
DESC
|
15
|
+
task :restart, :roles => :app do
|
16
|
+
sudo "/usr/bin/monit restart all -g #{monit_group}"
|
17
|
+
end
|
18
|
+
|
19
|
+
desc <<-DESC
|
20
|
+
Stop the Mongrel processes on the app server. This uses the :use_sudo
|
21
|
+
variable to determine whether to use sudo or not. By default, :use_sudo is
|
22
|
+
set to true.
|
23
|
+
DESC
|
24
|
+
task :stop, :roles => :app do
|
25
|
+
sudo "/usr/bin/monit stop all -g #{monit_group}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :monit do
|
4
|
+
desc "Get the status of your mongrels"
|
5
|
+
task :status, :roles => :app do
|
6
|
+
@monit_output ||= { }
|
7
|
+
sudo "/usr/bin/monit status" do |channel, stream, data|
|
8
|
+
@monit_output[channel[:server].to_s] ||= [ ]
|
9
|
+
@monit_output[channel[:server].to_s].push(data.chomp)
|
10
|
+
end
|
11
|
+
@monit_output.each do |k,v|
|
12
|
+
puts "#{k} -> #{'*'*55}"
|
13
|
+
puts v.join("\n")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :nginx do
|
4
|
+
desc "Start Nginx on the app slices."
|
5
|
+
task :start, :roles => :app do
|
6
|
+
sudo "/etc/init.d/nginx start"
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Restart the Nginx processes on the app slices."
|
10
|
+
task :restart , :roles => :app do
|
11
|
+
sudo "/etc/init.d/nginx restart"
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Stop the Nginx processes on the app slices."
|
15
|
+
task :stop , :roles => :app do
|
16
|
+
sudo "/etc/init.d/nginx stop"
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Tail the nginx access logs for this application"
|
20
|
+
task :tail, :roles => :app do
|
21
|
+
run "tail -f /var/log/engineyard/nginx/#{application}.access.log" do |channel, stream, data|
|
22
|
+
puts "#{channel[:server]}: #{data}" unless data =~ /^10\.[01]\.0/ # skips lb pull pages
|
23
|
+
break if stream == :err
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Tail the nginx error logs on the app slices"
|
28
|
+
task :tail_error, :roles => :app do
|
29
|
+
run "tail -f /var/log/engineyard/nginx/error.log" do |channel, stream, data|
|
30
|
+
puts "#{channel[:server]}: #{data}" unless data =~ /^10\.[01]\.0/ # skips lb pull pages
|
31
|
+
break if stream == :err
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :slice do
|
4
|
+
desc "Tail the Rails production log for this environment"
|
5
|
+
task :tail_production_logs, :roles => :app do
|
6
|
+
run "tail -f #{shared_path}/log/#{rails_env}.log" do |channel, stream, data|
|
7
|
+
puts # for an extra line break before the host name
|
8
|
+
puts "#{channel[:server]} -> #{data}"
|
9
|
+
break if stream == :err
|
10
|
+
end
|
11
|
+
end
|
12
|
+
desc "Tail the Mongrel logs this environment"
|
13
|
+
task :tail_mongrel_logs, :roles => :app do
|
14
|
+
run "tail -f #{shared_path}/log/mongrel*.log" do |channel, stream, data|
|
15
|
+
puts # for an extra line break before the host name
|
16
|
+
puts "#{channel[:server]} -> #{data}"
|
17
|
+
break if stream == :err
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :solr do
|
4
|
+
desc "After update_code you want to symlink the index and ferret_server.yml file into place"
|
5
|
+
task :symlink_configs, :roles => :app, :except => {:no_release => true} do
|
6
|
+
run <<-CMD
|
7
|
+
cd #{release_path} && ln -nfs #{shared_path}/config/solr.yml #{release_path}/config/solr.yml
|
8
|
+
CMD
|
9
|
+
end
|
10
|
+
|
11
|
+
[:start,:stop,:restart].each do |op|
|
12
|
+
desc "#{op} ferret server"
|
13
|
+
task op, :roles => :app, :only => {:solr => true} do
|
14
|
+
sudo "/usr/bin/monit #{op} all -g solr_#{application}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
namespace :tail do
|
19
|
+
desc "Tail the Solr logs this environment"
|
20
|
+
task :logs, :roles => :app, :only => {:solr => true} do
|
21
|
+
run "tail -f /var/log/engineyard/solr/#{application}.log" do |channel, stream, data|
|
22
|
+
puts # for an extra line break before the host name
|
23
|
+
puts "#{channel[:server]} -> #{data}"
|
24
|
+
break if stream == :err
|
25
|
+
end
|
26
|
+
end
|
27
|
+
desc "Tail the Solr error logs this environment"
|
28
|
+
task :errors, :roles => :app, :only => {:solr => true} do
|
29
|
+
run "tail -f /var/log/engineyard/solr/#{application}.err.log" do |channel, stream, data|
|
30
|
+
puts # for an extra line break before the host name
|
31
|
+
puts "#{channel[:server]} -> #{data}"
|
32
|
+
break if stream == :err
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :sphinx do
|
4
|
+
desc "After update_code you want to configure, then reindex"
|
5
|
+
task :configure, :roles => :app, :only => {:sphinx => true}, :except => {:no_release => true} do
|
6
|
+
run "/engineyard/bin/searchd #{application} configure"
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "After configure you want to reindex"
|
10
|
+
task :reindex, :roles => :app, :only => {:sphinx => true} do
|
11
|
+
run "/engineyard/bin/searchd #{application} reindex"
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Start Sphinx Searchd"
|
15
|
+
task :start, :roles => :app, :only => {:sphinx => true} do
|
16
|
+
sudo "/usr/bin/monit start all -g sphinx_#{application}"
|
17
|
+
end
|
18
|
+
desc "Stop Sphinx Searchd"
|
19
|
+
task :stop, :roles => :app, :only => {:sphinx => true} do
|
20
|
+
sudo "/usr/bin/monit stop all -g sphinx_#{application}"
|
21
|
+
end
|
22
|
+
desc "Restart Sphinx Searchd"
|
23
|
+
task :restart, :roles => :app, :only => {:sphinx => true} do
|
24
|
+
sudo "/usr/bin/monit restart all -g sphinx_#{application}"
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Symlink the sphinx config file"
|
28
|
+
task :symlink, :roles => :app, :only => {:sphinx => true}, :except => {:no_release => true} do
|
29
|
+
run "if [ -d #{release_path}/config/ultrasphinx ]; then mv #{release_path}/config/ultrasphinx #{release_path}/config/ultrasphinx.bak; fi"
|
30
|
+
run "ln -nfs #{shared_path}/config/ultrasphinx #{release_path}/config/ultrasphinx"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
|
2
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
3
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
4
|
+
|
5
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
6
|
+
|
7
|
+
<head>
|
8
|
+
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
9
|
+
<title>System down for maintenance</title>
|
10
|
+
|
11
|
+
<style type="text/css">
|
12
|
+
div.outer {
|
13
|
+
position: absolute;
|
14
|
+
left: 50%;
|
15
|
+
top: 50%;
|
16
|
+
width: 500px;
|
17
|
+
height: 300px;
|
18
|
+
margin-left: -260px;
|
19
|
+
margin-top: -150px;
|
20
|
+
}
|
21
|
+
|
22
|
+
.DialogBody {
|
23
|
+
margin: 0;
|
24
|
+
padding: 10px;
|
25
|
+
text-align: left;
|
26
|
+
border: 1px solid #ccc;
|
27
|
+
border-right: 1px solid #999;
|
28
|
+
border-bottom: 1px solid #999;
|
29
|
+
background-color: #fff;
|
30
|
+
}
|
31
|
+
|
32
|
+
body { background-color: #fff; }
|
33
|
+
</style>
|
34
|
+
</head>
|
35
|
+
|
36
|
+
<body>
|
37
|
+
|
38
|
+
<div class="outer">
|
39
|
+
<div class="DialogBody" style="text-align: center;">
|
40
|
+
<div style="text-align: center; width: 200px; margin: 0 auto;">
|
41
|
+
<p style="color: red; font-size: 16px; line-height: 20px;">
|
42
|
+
The system is down for <%= reason ? reason : "maintenance" %>
|
43
|
+
as of <%= Time.now.strftime("%H:%M %Z") %>.
|
44
|
+
</p>
|
45
|
+
<p style="color: #666;">
|
46
|
+
It'll be back <%= deadline ? deadline : "shortly" %>.
|
47
|
+
</p>
|
48
|
+
</div>
|
49
|
+
</div>
|
50
|
+
</div>
|
51
|
+
|
52
|
+
</body>
|
53
|
+
</html>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
namespace :tomcat do
|
3
|
+
desc "Start tomcat"
|
4
|
+
task :start, :roles => :app, :only => {:tomcat => true} do
|
5
|
+
sudo "/etc/init.d/tomcat start"
|
6
|
+
end
|
7
|
+
desc "Stop tomcat"
|
8
|
+
task :stop, :roles => :app, :only => {:tomcat => true} do
|
9
|
+
sudo "/etc/init.d/tomcat stop"
|
10
|
+
end
|
11
|
+
desc "Restart tomcat"
|
12
|
+
task :restart, :roles => :app, :only => {:tomcat => true} do
|
13
|
+
sudo "/etc/init.d/tomcat restart"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'eycap/lib/ey_logger'
|
2
|
+
require 'eycap/lib/ey_logger_hooks'
|
3
|
+
require 'eycap/recipes/database'
|
4
|
+
require 'eycap/recipes/ferret'
|
5
|
+
require 'eycap/recipes/mongrel'
|
6
|
+
require 'eycap/recipes/nginx'
|
7
|
+
require 'eycap/recipes/slice'
|
8
|
+
require 'eycap/recipes/deploy'
|
9
|
+
require 'eycap/recipes/sphinx'
|
10
|
+
require 'eycap/recipes/backgroundrb'
|
11
|
+
require 'eycap/recipes/memcached'
|
12
|
+
require 'eycap/recipes/solr'
|
13
|
+
require 'eycap/recipes/monit'
|
14
|
+
require 'eycap/recipes/tomcat'
|
15
|
+
require 'eycap/recipes/juggernaut'
|
16
|
+
|
17
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
18
|
+
|
19
|
+
default_run_options[:pty] = true if respond_to?(:default_run_options)
|
20
|
+
set :keep_releases, 3
|
21
|
+
set :runner, defer { user }
|
22
|
+
|
23
|
+
end
|
data/lib/eycap.rb
ADDED
data/test/test_eycap.rb
ADDED
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: engineyard-eycap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Engine Yard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-05-12 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: capistrano
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.2.0
|
23
|
+
version:
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: hoe
|
26
|
+
version_requirement:
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ">="
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: 1.5.1
|
32
|
+
version:
|
33
|
+
description: A bunch of useful recipes to help deployment to Engine Yard slices
|
34
|
+
email: tech@engineyard.com
|
35
|
+
executables: []
|
36
|
+
|
37
|
+
extensions: []
|
38
|
+
|
39
|
+
extra_rdoc_files:
|
40
|
+
- History.txt
|
41
|
+
- Manifest.txt
|
42
|
+
- README.txt
|
43
|
+
files:
|
44
|
+
- History.txt
|
45
|
+
- Manifest.txt
|
46
|
+
- README.txt
|
47
|
+
- Rakefile
|
48
|
+
- lib/capistrano/recipes/deploy/strategy/filtered_remote_cache.rb
|
49
|
+
- lib/eycap.rb
|
50
|
+
- lib/eycap/lib/ey_logger.rb
|
51
|
+
- lib/eycap/lib/ey_logger_hooks.rb
|
52
|
+
- lib/eycap/recipes.rb
|
53
|
+
- lib/eycap/recipes/backgroundrb.rb
|
54
|
+
- lib/eycap/recipes/database.rb
|
55
|
+
- lib/eycap/recipes/deploy.rb
|
56
|
+
- lib/eycap/recipes/ferret.rb
|
57
|
+
- lib/eycap/recipes/juggernaut.rb
|
58
|
+
- lib/eycap/recipes/memcached.rb
|
59
|
+
- lib/eycap/recipes/mongrel.rb
|
60
|
+
- lib/eycap/recipes/monit.rb
|
61
|
+
- lib/eycap/recipes/nginx.rb
|
62
|
+
- lib/eycap/recipes/slice.rb
|
63
|
+
- lib/eycap/recipes/solr.rb
|
64
|
+
- lib/eycap/recipes/sphinx.rb
|
65
|
+
- lib/eycap/recipes/templates/maintenance.rhtml
|
66
|
+
- lib/eycap/recipes/tomcat.rb
|
67
|
+
- test/test_eycap.rb
|
68
|
+
- test/test_helper.rb
|
69
|
+
has_rdoc: true
|
70
|
+
homepage: http://eycap.rubyforge.org
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options:
|
73
|
+
- --main
|
74
|
+
- README.txt
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: "0"
|
82
|
+
version:
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: "0"
|
88
|
+
version:
|
89
|
+
requirements: []
|
90
|
+
|
91
|
+
rubyforge_project: eycap
|
92
|
+
rubygems_version: 1.0.1
|
93
|
+
signing_key:
|
94
|
+
specification_version: 2
|
95
|
+
summary: Capistrano tasks for Engine Yard slices
|
96
|
+
test_files:
|
97
|
+
- test/test_eycap.rb
|
98
|
+
- test/test_helper.rb
|