factorylabs-fdlcap 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README +0 -0
- data/README.rdoc +7 -0
- data/Rakefile +68 -0
- data/VERSION +1 -0
- data/bin/fdlcap +4 -0
- data/fdlcap.gemspec +85 -0
- data/features/fdlcap.feature +9 -0
- data/features/step_definitions/fdlcap_steps.rb +0 -0
- data/features/support/env.rb +6 -0
- data/lib/fdlcap.rb +3 -0
- data/lib/fdlcap/autotagger.rb +9 -0
- data/lib/fdlcap/craken.rb +6 -0
- data/lib/fdlcap/database.rb +67 -0
- data/lib/fdlcap/delayed_job.rb +16 -0
- data/lib/fdlcap/deploy.rb +26 -0
- data/lib/fdlcap/geminstaller.rb +26 -0
- data/lib/fdlcap/newrelic.rb +6 -0
- data/lib/fdlcap/nginx.rb +125 -0
- data/lib/fdlcap/performance.rb +38 -0
- data/lib/fdlcap/rake.rb +19 -0
- data/lib/fdlcap/recipes.rb +35 -0
- data/lib/fdlcap/rsync.rb +40 -0
- data/lib/fdlcap/sass.rb +13 -0
- data/lib/fdlcap/slice.rb +35 -0
- data/lib/fdlcap/ssh.rb +30 -0
- data/lib/fdlcap/symlinks.rb +38 -0
- data/lib/fdlcap/templates/nginx.auth.conf.erb +9 -0
- data/lib/fdlcap/templates/nginx.conf.erb +57 -0
- data/lib/fdlcap/templates/nginx.vhost.conf.erb +85 -0
- data/lib/fdlcap/thin.rb +112 -0
- data/lib/fdlcap/thinking_sphinx.rb +9 -0
- data/test/fdlcap_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +128 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Factory Design Labs
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
File without changes
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "fdlcap"
|
8
|
+
gem.summary = %Q{a set of capistrano recipies we use regularly at Factory Design Labs}
|
9
|
+
gem.email = "interactive@factorylabs.com"
|
10
|
+
gem.homepage = "http://github.com/factorylabs/fdlcap"
|
11
|
+
gem.authors = ["Factory Design Labs"]
|
12
|
+
gem.add_dependency('engineyard-eycap', '>= 0.4.7')
|
13
|
+
gem.add_dependency('zilkey-auto_tagger', '>= 0.0.9')
|
14
|
+
gem.add_dependency('capistrano', '>= 2.5.5')
|
15
|
+
gem.add_dependency('capistrano-ext', '>= 1.2.1')
|
16
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
|
+
end
|
18
|
+
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'rake/testtask'
|
24
|
+
Rake::TestTask.new(:test) do |test|
|
25
|
+
test.libs << 'lib' << 'test'
|
26
|
+
test.pattern = 'test/**/*_test.rb'
|
27
|
+
test.verbose = true
|
28
|
+
end
|
29
|
+
|
30
|
+
begin
|
31
|
+
require 'rcov/rcovtask'
|
32
|
+
Rcov::RcovTask.new do |test|
|
33
|
+
test.libs << 'test'
|
34
|
+
test.pattern = 'test/**/*_test.rb'
|
35
|
+
test.verbose = true
|
36
|
+
end
|
37
|
+
rescue LoadError
|
38
|
+
task :rcov do
|
39
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
begin
|
44
|
+
require 'cucumber/rake/task'
|
45
|
+
Cucumber::Rake::Task.new(:features)
|
46
|
+
rescue LoadError
|
47
|
+
task :features do
|
48
|
+
abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
task :default => :test
|
53
|
+
|
54
|
+
require 'rake/rdoctask'
|
55
|
+
Rake::RDocTask.new do |rdoc|
|
56
|
+
if File.exist?('VERSION.yml')
|
57
|
+
config = YAML.load(File.read('VERSION.yml'))
|
58
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
59
|
+
else
|
60
|
+
version = ""
|
61
|
+
end
|
62
|
+
|
63
|
+
rdoc.rdoc_dir = 'rdoc'
|
64
|
+
rdoc.title = "fdlcap #{version}"
|
65
|
+
rdoc.rdoc_files.include('README*')
|
66
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
67
|
+
end
|
68
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/bin/fdlcap
ADDED
data/fdlcap.gemspec
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{fdlcap}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Factory Design Labs"]
|
9
|
+
s.date = %q{2009-06-25}
|
10
|
+
s.default_executable = %q{fdlcap}
|
11
|
+
s.email = %q{interactive@factorylabs.com}
|
12
|
+
s.executables = ["fdlcap"]
|
13
|
+
s.extra_rdoc_files = [
|
14
|
+
"LICENSE",
|
15
|
+
"README",
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"LICENSE",
|
20
|
+
"README",
|
21
|
+
"README.rdoc",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"bin/fdlcap",
|
25
|
+
"fdlcap.gemspec",
|
26
|
+
"features/fdlcap.feature",
|
27
|
+
"features/step_definitions/fdlcap_steps.rb",
|
28
|
+
"features/support/env.rb",
|
29
|
+
"lib/fdlcap.rb",
|
30
|
+
"lib/fdlcap/autotagger.rb",
|
31
|
+
"lib/fdlcap/craken.rb",
|
32
|
+
"lib/fdlcap/database.rb",
|
33
|
+
"lib/fdlcap/delayed_job.rb",
|
34
|
+
"lib/fdlcap/deploy.rb",
|
35
|
+
"lib/fdlcap/geminstaller.rb",
|
36
|
+
"lib/fdlcap/newrelic.rb",
|
37
|
+
"lib/fdlcap/nginx.rb",
|
38
|
+
"lib/fdlcap/performance.rb",
|
39
|
+
"lib/fdlcap/rake.rb",
|
40
|
+
"lib/fdlcap/recipes.rb",
|
41
|
+
"lib/fdlcap/rsync.rb",
|
42
|
+
"lib/fdlcap/sass.rb",
|
43
|
+
"lib/fdlcap/slice.rb",
|
44
|
+
"lib/fdlcap/ssh.rb",
|
45
|
+
"lib/fdlcap/symlinks.rb",
|
46
|
+
"lib/fdlcap/templates/nginx.auth.conf.erb",
|
47
|
+
"lib/fdlcap/templates/nginx.conf.erb",
|
48
|
+
"lib/fdlcap/templates/nginx.vhost.conf.erb",
|
49
|
+
"lib/fdlcap/thin.rb",
|
50
|
+
"lib/fdlcap/thinking_sphinx.rb",
|
51
|
+
"test/fdlcap_test.rb",
|
52
|
+
"test/test_helper.rb"
|
53
|
+
]
|
54
|
+
s.homepage = %q{http://github.com/factorylabs/fdlcap}
|
55
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
56
|
+
s.require_paths = ["lib"]
|
57
|
+
s.rubygems_version = %q{1.3.4}
|
58
|
+
s.summary = %q{a set of capistrano recipies we use regularly at Factory Design Labs}
|
59
|
+
s.test_files = [
|
60
|
+
"test/fdlcap_test.rb",
|
61
|
+
"test/test_helper.rb"
|
62
|
+
]
|
63
|
+
|
64
|
+
if s.respond_to? :specification_version then
|
65
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
66
|
+
s.specification_version = 3
|
67
|
+
|
68
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
69
|
+
s.add_runtime_dependency(%q<engineyard-eycap>, [">= 0.4.7"])
|
70
|
+
s.add_runtime_dependency(%q<zilkey-auto_tagger>, [">= 0.0.9"])
|
71
|
+
s.add_runtime_dependency(%q<capistrano>, [">= 2.5.5"])
|
72
|
+
s.add_runtime_dependency(%q<capistrano-ext>, [">= 1.2.1"])
|
73
|
+
else
|
74
|
+
s.add_dependency(%q<engineyard-eycap>, [">= 0.4.7"])
|
75
|
+
s.add_dependency(%q<zilkey-auto_tagger>, [">= 0.0.9"])
|
76
|
+
s.add_dependency(%q<capistrano>, [">= 2.5.5"])
|
77
|
+
s.add_dependency(%q<capistrano-ext>, [">= 1.2.1"])
|
78
|
+
end
|
79
|
+
else
|
80
|
+
s.add_dependency(%q<engineyard-eycap>, [">= 0.4.7"])
|
81
|
+
s.add_dependency(%q<zilkey-auto_tagger>, [">= 0.0.9"])
|
82
|
+
s.add_dependency(%q<capistrano>, [">= 2.5.5"])
|
83
|
+
s.add_dependency(%q<capistrano-ext>, [">= 1.2.1"])
|
84
|
+
end
|
85
|
+
end
|
File without changes
|
data/lib/fdlcap.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
# Run autotagger to get the right release
|
3
|
+
if exists?(:use_release_tagger)
|
4
|
+
before "deploy:update_code", "release_tagger:set_branch"
|
5
|
+
before "deploy:cleanup", "release_tagger:create_tag"
|
6
|
+
before "deploy:cleanup", "release_tagger:write_tag_to_shared"
|
7
|
+
before "deploy:cleanup", "release_tagger:print_latest_tags"
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
namespace :database do
|
3
|
+
desc "Push db remotely"
|
4
|
+
task :push_db_remotely, :roles => :db do
|
5
|
+
|
6
|
+
default_character_set = Object.const_defined?(:DEFAULT_CHARACTER_SET) ? Object::DEFAULT_CHARACTER_SET : "utf8"
|
7
|
+
|
8
|
+
local_env = ENV['LOCAL_ENV'] || "development"
|
9
|
+
|
10
|
+
all_db_info = YAML.load(File.read("config/database.yml"))
|
11
|
+
local_db_info = all_db_info[local_env]
|
12
|
+
remote_db_info = all_db_info[rails_env.to_s]
|
13
|
+
raise "Missing database.yml entry for #{local_env}" unless local_db_info
|
14
|
+
raise "Missing database.yml entry for #{rails_env.to_s}" unless remote_db_info
|
15
|
+
|
16
|
+
|
17
|
+
puts %{
|
18
|
+
|
19
|
+
! WARNING !: The remote database '#{remote_db_info["database"]}'
|
20
|
+
will be replaced with the contents of the local database '#{local_db_info["database"]}'.
|
21
|
+
A dump of the remote db will be placed in your remote home directory just prior
|
22
|
+
to it being replaced.
|
23
|
+
|
24
|
+
1) current REMOTE_DB ===> backed up to dump file, in ~/
|
25
|
+
2) LOCAL_DB ===> REMOTE_DB ...old REMOTE_DB contents are overwritten!!!
|
26
|
+
|
27
|
+
Even so, this is a very significant and potentially destructive operation. Please step
|
28
|
+
back and contemplate what you're about to do.
|
29
|
+
|
30
|
+
If you're really sure you want to continue, type "REPLACE #{remote_db_info["database"].upcase}":
|
31
|
+
}
|
32
|
+
|
33
|
+
if ($stdin.gets.strip != "REPLACE #{remote_db_info["database"].upcase}")
|
34
|
+
puts "No action taken, exiting"
|
35
|
+
exit(1)
|
36
|
+
else
|
37
|
+
puts "You confirmed that you want to continue, here we go"
|
38
|
+
end
|
39
|
+
|
40
|
+
dump_file_name = "#{local_db_info["database"]}.sql"
|
41
|
+
local_dump_file_gz_path = "/tmp/#{dump_file_name}.gz"
|
42
|
+
|
43
|
+
execute "time mysqldump -e -q --single-transaction --default_character_set=#{default_character_set} \
|
44
|
+
-u #{local_db_info["username"]} --password=#{local_db_info["password"]} \
|
45
|
+
--database #{local_db_info["database"]} | gzip > #{local_dump_file_gz_path}"
|
46
|
+
|
47
|
+
upload "#{local_dump_file_gz_path}", "#{dump_file_name}.gz", :via => :scp
|
48
|
+
|
49
|
+
execute "echo ^G^G^G^G^G"
|
50
|
+
|
51
|
+
run "gzip -df ~/#{dump_file_name}.gz"
|
52
|
+
run "perl -pi -e 's|#{local_db_info["database"]}|#{remote_db_info["database"]}|g' ~/#{dump_file_name}"
|
53
|
+
|
54
|
+
run "time mysqldump -e -q --single-transaction --default_character_set=#{default_character_set} \
|
55
|
+
-u #{remote_db_info["username"]} --password=#{remote_db_info["password"]} \
|
56
|
+
--database #{remote_db_info["database"]} | gzip > ~/#{remote_db_info["database"]}_#{Time.now.strftime("%Y-%m-%d_%H-%M-%S")}.sql.gz"
|
57
|
+
|
58
|
+
remote_host = remote_db_info["host"] || "localhost"
|
59
|
+
|
60
|
+
run "mysqladmin -u #{remote_db_info["username"]} --password=#{remote_db_info["password"]} -h #{remote_host} drop #{remote_db_info["database"]} -f"
|
61
|
+
run "mysqladmin -u #{remote_db_info["username"]} --password=#{remote_db_info["password"]} -h #{remote_host} create #{remote_db_info["database"]} --default_character_set=#{default_character_set}"
|
62
|
+
run "time mysql -u #{remote_db_info["username"]} --password=#{remote_db_info["password"]} -h #{remote_host} --database #{remote_db_info["database"]} --default_character_set=#{default_character_set} < ~/#{dump_file_name}"
|
63
|
+
run "rm ~/#{dump_file_name}"
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
namespace :delayed_job do
|
3
|
+
desc "Start delayed_job"
|
4
|
+
task :start, :only => {:delayed_job => true} do
|
5
|
+
sudo "/usr/bin/monit start all -g dj_#{application}"
|
6
|
+
end
|
7
|
+
desc "Stop delayed_job"
|
8
|
+
task :stop, :only => {:delayed_job => true} do
|
9
|
+
sudo "/usr/bin/monit stop all -g dj_#{application}"
|
10
|
+
end
|
11
|
+
desc "Restart delayed_job"
|
12
|
+
task :restart, :only => {:delayed_job => true} do
|
13
|
+
sudo "/usr/bin/monit restart all -g dj_#{application}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :web do
|
4
|
+
task :disable, :roles => :web, :except => { :no_release => true } do
|
5
|
+
on_rollback { run "rm #{shared_path}/system/maintenance.html" }
|
6
|
+
run "cp #{current_path}/public/maintenance.html #{shared_path}/system/maintenance.html"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
namespace :deploy do
|
11
|
+
desc "Pull files from a remote server"
|
12
|
+
task :download_file, :roles => :app, :except => { :no_release => true } do
|
13
|
+
ENV['FILES'].split(',').each do |file|
|
14
|
+
get "#{current_path}/#{file}", File.basename(file)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Clean up old releases
|
20
|
+
if exists?(:perform_cleanup)
|
21
|
+
after "deploy", "deploy:cleanup"
|
22
|
+
after "deploy:migrations" , "deploy:cleanup"
|
23
|
+
after "deploy:long" , "deploy:cleanup"
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
namespace :geminstaller do
|
3
|
+
desc "Run geminstaller"
|
4
|
+
task :run, :only => { :geminstaller => true } do
|
5
|
+
sudo "/usr/bin/geminstaller -c #{release_path}/config/geminstaller.yml --geminstaller-output=all --rubygems-output=all"
|
6
|
+
end
|
7
|
+
|
8
|
+
desc "Install geminstaller"
|
9
|
+
task :install, :only => { :geminstaller => true } do
|
10
|
+
sudo "gem install geminstaller"
|
11
|
+
sudo "gem source -a http://gems.github.com"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Configure Callbacks
|
17
|
+
#
|
18
|
+
# Run geminstaller to make sure gems are installed.
|
19
|
+
if exists?(:use_geminstaller)
|
20
|
+
after "deploy:setup", "geminstaller:install"
|
21
|
+
after "geminstaller:install", "geminstaller:run"
|
22
|
+
after "deploy:symlink", "geminstaller:run"
|
23
|
+
after "geminstaller:run", "deploy:migrate"
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/lib/fdlcap/nginx.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
|
2
|
+
#global vars
|
3
|
+
set(:can_configure_nginx, true)
|
4
|
+
set(:nginx_user, 'nginx')
|
5
|
+
set(:nginx_processes, 4)
|
6
|
+
set(:nginx_gzip_on, true)
|
7
|
+
set(:nginx_gzip_xml_on, false)
|
8
|
+
|
9
|
+
# app specific vars
|
10
|
+
set(:nginx_server_names, "_")
|
11
|
+
set(:nginx_far_future, false)
|
12
|
+
set(:nginx_default_app, true)
|
13
|
+
|
14
|
+
#http auth vars
|
15
|
+
set(:nginx_auth_ip_masks, ['192.168.0.0/254'])
|
16
|
+
set(:nginx_http_auth_app, false)
|
17
|
+
set(:nginx_auth_locations, [])
|
18
|
+
set(:nginx_http_auth_users, [])
|
19
|
+
|
20
|
+
namespace :nginx do
|
21
|
+
|
22
|
+
%w( start stop restart reload ).each do |cmd|
|
23
|
+
desc "#{cmd} your nginx servers"
|
24
|
+
task "#{cmd}".to_sym, :roles => :web do
|
25
|
+
default_run_options[:pty] = true
|
26
|
+
sudo "/etc/init.d/nginx #{cmd}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "Setup Nginx vhost config"
|
31
|
+
task :vhost, :roles => :web do
|
32
|
+
result = render_erb_template(File.dirname(__FILE__) + "/templates/nginx.vhost.conf.erb")
|
33
|
+
put result, "/tmp/nginx.vhost.conf"
|
34
|
+
sudo "mkdir -p /etc/nginx/vhosts"
|
35
|
+
sudo "cp /tmp/nginx.vhost.conf /etc/nginx/vhosts/#{application}.conf"
|
36
|
+
inform "You must edit nginx.conf to include the vhost config file."
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Setup Nginx vhost auth config"
|
40
|
+
task :vhost_auth, :roles => :web do
|
41
|
+
result = render_erb_template(File.dirname(__FILE__) + "/templates/nginx.auth.conf.erb")
|
42
|
+
put result, "/tmp/nginx.auth.conf"
|
43
|
+
sudo "mkdir -p /etc/nginx/vhosts"
|
44
|
+
sudo "cp /tmp/nginx.vhost.conf /etc/nginx/vhosts/#{application}.auth.conf"
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "Setup htpasswd file for nginx auth"
|
48
|
+
task :create_htpasswd, :roles => :web do
|
49
|
+
sudo "mkdir -p /etc/nginx/conf"
|
50
|
+
for user in nginx_http_auth_users
|
51
|
+
run "cd /etc/nginx/conf && htpasswd -b htpasswd #{user['name']} #{user['password']}"
|
52
|
+
# run <<-CMD
|
53
|
+
# cd /etc/nginx/conf;
|
54
|
+
# if [ ! -e /etc/nginx/conf/htpasswd ] ; then
|
55
|
+
# htpasswd -b -c htpasswd #{user['name']} #{user['password']};
|
56
|
+
# else
|
57
|
+
# htpasswd -b htpasswd #{user['name']} #{user['password']};
|
58
|
+
# fi
|
59
|
+
# CMD
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
desc "Setup Nginx.config"
|
64
|
+
task :conf, :roles => :web do
|
65
|
+
if can_configure_nginx
|
66
|
+
|
67
|
+
result = render_erb_template(File.dirname(__FILE__) + "/templates/nginx.conf.erb")
|
68
|
+
put result, "/tmp/nginx.conf"
|
69
|
+
sudo "cp /tmp/nginx.conf /etc/nginx/nginx.conf"
|
70
|
+
|
71
|
+
else
|
72
|
+
inform "Nginx configuration tasks have been disabled. Most likely you are deploying to engineyard which has it's own nginx conf setup."
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
desc "Setup Nginx vhost config and nginx.conf"
|
77
|
+
task :configure, :roles => :web do
|
78
|
+
if can_configure_nginx
|
79
|
+
|
80
|
+
conf
|
81
|
+
vhost
|
82
|
+
vhost_auth if nginx_auth_locations.length > 0 || nginx_http_auth_app
|
83
|
+
create_htpasswd if nginx_http_auth_users.length > 0
|
84
|
+
|
85
|
+
else
|
86
|
+
inform "Nginx configuration tasks have been disabled. Most likely you are deploying to engineyard which has it's own nginx conf setup."
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
class Capistrano::Configuration
|
93
|
+
|
94
|
+
##
|
95
|
+
# Print an informative message with asterisks.
|
96
|
+
|
97
|
+
def inform(message)
|
98
|
+
puts "#{'*' * (message.length + 4)}"
|
99
|
+
puts "* #{message} *"
|
100
|
+
puts "#{'*' * (message.length + 4)}"
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Read a file and evaluate it as an ERB template.
|
105
|
+
# Path is relative to this file's directory.
|
106
|
+
|
107
|
+
def render_erb_template(filename)
|
108
|
+
template = File.read(filename)
|
109
|
+
result = ERB.new(template).result(binding)
|
110
|
+
end
|
111
|
+
|
112
|
+
##
|
113
|
+
# Run a command and return the result as a string.
|
114
|
+
#
|
115
|
+
# TODO May not work properly on multiple servers.
|
116
|
+
|
117
|
+
def run_and_return(cmd)
|
118
|
+
output = []
|
119
|
+
run cmd do |ch, st, data|
|
120
|
+
output << data
|
121
|
+
end
|
122
|
+
return output.to_s
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
namespace :autoperf do
|
3
|
+
desc "get nginx log for load test"
|
4
|
+
task :fetch_log, :roles => :app do
|
5
|
+
# Grab the last 1000 requests from production Nginx log, and extract the request path (ex: /index)
|
6
|
+
run "tail -n 1000 /var/log/nginx/#{application}.access.log | awk '{print $7}' > /tmp/requests.log"
|
7
|
+
|
8
|
+
# Replace newlines with null terminator (httperf format)
|
9
|
+
run 'tr "\n" "\0" < /tmp/requests.log > /tmp/requests_httperf.log'
|
10
|
+
|
11
|
+
download "/tmp/requests_httperf.log", "config/autoperf/requests_httperf.log", :via => :scp
|
12
|
+
|
13
|
+
run "rm /tmp/requests_httperf.log"
|
14
|
+
end
|
15
|
+
|
16
|
+
task :run_test, :roles => :app do
|
17
|
+
run "cd #{current_path} && script/autoperf -c config/autoperf/primary.conf" do |channel, stream, data|
|
18
|
+
puts data if stream == :out
|
19
|
+
if stream == :err
|
20
|
+
puts "[Error: #{channel[:host]}] #{data}"
|
21
|
+
break
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
namespace :autobench do
|
28
|
+
|
29
|
+
task :test_search, :roles => :app do
|
30
|
+
url = "/vehicles/search?search[zip]=06108&search[radius]=10+Miles&search[view_type]=block&search[per_page]=10&search[year_from]=From+Year&search[year_to]=To+Year&search[model]=Model&search[price]=Price&search[color]=Color&search[mileage]=Mileage&commit=Search"
|
31
|
+
run "/usr/local/bin/autobench --single_host --host1=audivehiclesearch.com --uri1=#{url} --file=/tmp/test_search.bench.txt --low_rate=1 --high_rate=20 --rate_step=2 --num_call=2 --num_conn=200"
|
32
|
+
download "/tmp/test_search.bench.txt", "autobench/test_search.bench.txt", :via => :scp
|
33
|
+
run "rm /tmp/test_search.bench.txt"
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/lib/fdlcap/rake.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
desc "Execute an arbitrary rake task on slices with a specified role (ROLES=x,y,z TASK=p)"
|
3
|
+
task :rake do
|
4
|
+
task = ENV['TASK']
|
5
|
+
run "cd #{current_path} && rake #{task} RAILS_ENV=#{rails_env}"
|
6
|
+
end
|
7
|
+
|
8
|
+
desc "Execute an arbitrary runner command on slices with a specified role (ROLES=x,y,z CMD=p)"
|
9
|
+
task :runner do
|
10
|
+
cmd = ENV['CMD']
|
11
|
+
run "cd #{current_path} && script/runner -e #{rails_env} '#{cmd}'"
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Execute an arbitrary UNIX command on slices with a specified role (ROLES=x,y,z CMD=p)"
|
15
|
+
task :command do
|
16
|
+
cmd = ENV['CMD']
|
17
|
+
run "cd #{current_path} && #{cmd}"
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Set up configuration defaults
|
2
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
3
|
+
unless exists?(:stages)
|
4
|
+
set :stages, [ :staging, :production ]
|
5
|
+
end
|
6
|
+
|
7
|
+
unless exists?(:use_release_tagger) && exists?(:autotagger_stages)
|
8
|
+
set :autotagger_stages, [ :ci, :staging, :production ]
|
9
|
+
end
|
10
|
+
|
11
|
+
unless exists?(:default_stage)
|
12
|
+
set :default_stage, :staging
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Load fdlcap dependencies
|
17
|
+
require 'release_tagger'
|
18
|
+
require 'capistrano/ext/multistage'
|
19
|
+
require 'eycap/recipes'
|
20
|
+
|
21
|
+
# Load up custom recipes and callbacks
|
22
|
+
require 'fdlcap/recipes/autotagger'
|
23
|
+
require 'fdlcap/recipes/craken'
|
24
|
+
require 'fdlcap/recipes/database'
|
25
|
+
require 'fdlcap/recipes/delayed_job'
|
26
|
+
require 'fdlcap/recipes/deploy'
|
27
|
+
require 'fdlcap/recipes/geminstaller'
|
28
|
+
require 'fdlcap/recipes/newrelic'
|
29
|
+
require 'fdlcap/recipes/performance'
|
30
|
+
require 'fdlcap/recipes/rake'
|
31
|
+
require 'fdlcap/recipes/rsync'
|
32
|
+
require 'fdlcap/recipes/sass'
|
33
|
+
require 'fdlcap/recipes/ssh'
|
34
|
+
require 'fdlcap/recipes/slice'
|
35
|
+
require 'fdlcap/recipes/thinking_sphinx'
|
data/lib/fdlcap/rsync.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
class Capistrano::Configuration
|
2
|
+
def execute(command, failure_message = "Command failed")
|
3
|
+
puts "Executing: #{command}"
|
4
|
+
system(command) || raise(failure_message)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
9
|
+
namespace :rsync do
|
10
|
+
desc <<-DESC
|
11
|
+
use rsync to sync assets locally or between servers
|
12
|
+
DESC
|
13
|
+
task :pull_shared , :roles => :app do
|
14
|
+
servers = find_servers :roles => :app, :except => { :no_release => true }
|
15
|
+
server = servers.first
|
16
|
+
if server
|
17
|
+
symlink_dirs.each do |share|
|
18
|
+
execute( "rsync -P -a -h -e 'ssh -p #{server.port || 22}' #{user}@#{server.host}:#{shared_path}/#{share}/* #{share}", "unable to run rsync files")
|
19
|
+
end
|
20
|
+
else
|
21
|
+
puts 'no server found'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
desc <<-DESC
|
26
|
+
use rsync to sync assets locally or between servers
|
27
|
+
DESC
|
28
|
+
task :push_shared , :roles => :app do
|
29
|
+
servers = find_servers :roles => :app, :except => { :no_release => true }
|
30
|
+
server = servers.first
|
31
|
+
if server
|
32
|
+
symlink_dirs.each do |share|
|
33
|
+
execute( "rsync -P -a -h -e 'ssh -p #{server.port || 22}' #{share}/* #{user}@#{server.host}:#{shared_path}/#{share}/", "unable to run rsync files")
|
34
|
+
end
|
35
|
+
else
|
36
|
+
puts 'no server found'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/fdlcap/sass.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
namespace :sass do
|
3
|
+
desc 'Updates the stylesheets generated by Sass'
|
4
|
+
task :update, :roles => :app do
|
5
|
+
invoke_command "cd #{latest_release}; RAILS_ENV=#{rails_env} rake sass:update"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
# Generate all the stylesheets manually (from their Sass templates) before each restart.
|
10
|
+
if exists?(:use_sass)
|
11
|
+
before 'deploy:restart', 'sass:update'
|
12
|
+
end
|
13
|
+
end
|
data/lib/fdlcap/slice.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :slice do
|
4
|
+
|
5
|
+
desc "Copy the maintenance page from the public directory to the shared directory"
|
6
|
+
task :copy_maintenance_page, :roles => :app do
|
7
|
+
upload "public/maintenance.html","#{shared_path}/system/maintenance.html.custom", :via => :scp
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Tail the Rails import log for this environment"
|
11
|
+
task :tail_import_logs, :roles => :utility do
|
12
|
+
run "tail -f #{shared_path}/log/import-#{rails_env}.log" do |channel, stream, data|
|
13
|
+
puts # for an extra line break before the host name
|
14
|
+
puts "#{channel[:server]} -> #{data}"
|
15
|
+
break if stream == :err
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Tail the Rails log for this environment"
|
20
|
+
task :tail_logs, :roles => :utility do
|
21
|
+
run "tail -f #{shared_path}/log/#{rails_env}.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
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
# Deploy the custom maintenance page
|
31
|
+
if exists?(:use_custom_maintenance_page)
|
32
|
+
before "deploy:web:disable", "slice:copy_maintenance_page"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/lib/fdlcap/ssh.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
task :ssh do
|
3
|
+
role = (ENV['ROLE'] || :app).to_sym
|
4
|
+
servers = find_servers :roles => role
|
5
|
+
server = servers.first
|
6
|
+
if server
|
7
|
+
`echo '#{password}' | /usr/bin/pbcopy`
|
8
|
+
exec "/usr/bin/ssh #{user}@#{server.host} -p #{server.port || 22} "
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
#namespace :ssh do
|
13
|
+
task :tunnel do
|
14
|
+
remote_port = ENV['REMOTE_PORT'] || 80
|
15
|
+
local_port = ENV['LOCAL_PORT'] || 2000
|
16
|
+
role = (ENV['ROLE'] || :app).to_sym
|
17
|
+
|
18
|
+
servers = find_servers :roles => role
|
19
|
+
server = servers.first
|
20
|
+
if server
|
21
|
+
puts "Opening a tunnel from port #{local_port} locally to port #{remote_port} on #{server.host}"
|
22
|
+
Net::SSH.start(server.host, user, :password => password, :port => server.port) do |ssh|
|
23
|
+
ssh.forward.local(local_port, "127.0.0.1", remote_port)
|
24
|
+
ssh.loop { true }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
#end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
after "deploy:update_code", "symlinks:create"
|
2
|
+
|
3
|
+
set(:symlink_dirs, [])
|
4
|
+
set(:symlink_absolute_dirs, [])
|
5
|
+
|
6
|
+
namespace :symlinks do
|
7
|
+
|
8
|
+
desc <<-DESC
|
9
|
+
fix symlinks to shared directory
|
10
|
+
DESC
|
11
|
+
task :fix, :roles => [:app, :web] do
|
12
|
+
# for folders stored under public
|
13
|
+
symlink_dirs.each do |share|
|
14
|
+
run "rm -rf #{current_path}/#{share}"
|
15
|
+
run "mkdir -p #{shared_path}/#{share}"
|
16
|
+
run "ln -nfs #{shared_path}/#{share} #{current_path}/#{share}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
desc <<-DESC
|
21
|
+
create symlinks to shared directory
|
22
|
+
DESC
|
23
|
+
task :create, :roles => [:app, :web] do
|
24
|
+
# for folders stored under public
|
25
|
+
symlink_dirs.each do |share|
|
26
|
+
run "rm -rf #{release_path}/#{share}"
|
27
|
+
run "mkdir -p #{shared_path}/#{share}"
|
28
|
+
run "ln -nfs #{shared_path}/#{share} #{release_path}/#{share}"
|
29
|
+
end
|
30
|
+
|
31
|
+
symlink_absolute_dirs.each do |share|
|
32
|
+
run "rm -rf #{share[:symlink]}"
|
33
|
+
run "mkdir -p #{share[:source]}"
|
34
|
+
run "ln -nfs #{share[:source]} #{share[:symlink]}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# taken mostly from "The Rails Way" page 663
|
2
|
+
|
3
|
+
# user and group to run as
|
4
|
+
user <%= nginx_user %>;
|
5
|
+
# number of nginx workers
|
6
|
+
worker_processes <%= nginx_processes %>;
|
7
|
+
# pid of nginx master process
|
8
|
+
pid /var/run/nginx.pid;
|
9
|
+
|
10
|
+
error_log /var/log/nginx/default.error.log debug;
|
11
|
+
#error_log /var/log/nginx/error.log notice;
|
12
|
+
#error_log /var/log/nginx/error.log info;
|
13
|
+
|
14
|
+
# number of worker connections. 1024 is a good default
|
15
|
+
events {
|
16
|
+
worker_connections 1024;
|
17
|
+
use epoll; # linux only!
|
18
|
+
}
|
19
|
+
|
20
|
+
|
21
|
+
http {
|
22
|
+
# pull in mime-types. You can break out your config
|
23
|
+
# into as many include's as you want.
|
24
|
+
include /etc/nginx/mime.types;
|
25
|
+
# set a default type for the rare situation that nothing matches.
|
26
|
+
default_type application/octet-stream;
|
27
|
+
# configure log format
|
28
|
+
log_format main '$remote_addr - $remote_user [$time_local] $request '
|
29
|
+
'"$status" $body_bytes_sent "$http_referer" '
|
30
|
+
'"$http_user_agent" "$http_x_forwarded_for"';
|
31
|
+
|
32
|
+
# no sendfile on OS X
|
33
|
+
sendfile on;
|
34
|
+
tcp_nopush on;
|
35
|
+
tcp_nodelay on;
|
36
|
+
|
37
|
+
#keepalive_timeout 0;
|
38
|
+
keepalive_timeout 65;
|
39
|
+
|
40
|
+
<% if nginx_gzip_on %>
|
41
|
+
gzip on;
|
42
|
+
gzip_http_version 1.0;
|
43
|
+
gzip_comp_level 2;
|
44
|
+
gzip_proxied any;
|
45
|
+
|
46
|
+
<% if nginx_gzip_xml_on %>
|
47
|
+
# IE 6 doesn't pass compressed xml to flash. So if no flash xml consumption on site can add
|
48
|
+
# text/xml application/xml application/xml+rss
|
49
|
+
<% end %>
|
50
|
+
gzip_types text/plain text/html text/css application/x-javascript text/javascript;
|
51
|
+
<% end %>
|
52
|
+
|
53
|
+
access_log /var/log/nginx/nginx.default.access.log main;
|
54
|
+
error_log /var/log/nginx/nginx.default.error.log info;
|
55
|
+
|
56
|
+
include /etc/nginx/vhosts/*.conf;
|
57
|
+
}
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# location of mongrel servers to proxy too
|
2
|
+
upstream mongrel_<%= application.gsub('.', '_') %> {
|
3
|
+
<% mongrel_port.upto(mongrel_port + mongrel_servers) do |port| %>
|
4
|
+
server 127.0.0.1:<%= port %>;
|
5
|
+
<% end %>
|
6
|
+
}
|
7
|
+
|
8
|
+
server {
|
9
|
+
# port to listen on. Can also be set to an IP:PORT
|
10
|
+
listen 80 <%= "default" if nginx_default_app %>;
|
11
|
+
# set max size for file uploads to 50mb
|
12
|
+
client_max_body_size 50M;
|
13
|
+
# sets the domain[s] that this vhost server requests for
|
14
|
+
# if two apps are on this box remove the ip and setup your hosts file
|
15
|
+
server_name <%= nginx_server_names %>;
|
16
|
+
# doc root
|
17
|
+
root <%= current_path %>/public;
|
18
|
+
# vhost specific logs
|
19
|
+
access_log <%= shared_path %>/log/<%= application %>.access.log main;
|
20
|
+
error_log <%= shared_path %>/log/<%= application %>.error.log notice;
|
21
|
+
|
22
|
+
# this rewrites all the requests to the maintenance.thml page if it exists in the doc root.
|
23
|
+
# this is for capistrano's disable web task
|
24
|
+
if (-f $document_root/system/maintenance.html) {
|
25
|
+
rewrite ^(.*)$ /system/maintenance.html last;
|
26
|
+
break;
|
27
|
+
}
|
28
|
+
# block access to paths containing .svn
|
29
|
+
location ~* ^.*\.svn.*$ {
|
30
|
+
internal;
|
31
|
+
}
|
32
|
+
|
33
|
+
location / {
|
34
|
+
|
35
|
+
<%= "include /etc/nginx/vhosts/#{application}.auth.conf" if nginx_http_auth_app %>
|
36
|
+
|
37
|
+
index index.html index.htm;
|
38
|
+
# forward the user's IP address to Rails
|
39
|
+
proxy_set_header X-Real-IP $remote_addr;
|
40
|
+
# needed for HTTPS must add an additional server block to configure it.
|
41
|
+
# see "The Rails Way" page 665 for more info
|
42
|
+
proxy_set_header X-FORWARD_PROTO https;
|
43
|
+
# Forward information about the client and host
|
44
|
+
# Otherwise our Rails app wouldn't have access to it
|
45
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
46
|
+
proxy_set_header Host $http_host;
|
47
|
+
proxy_redirect false;
|
48
|
+
proxy_max_temp_file_size 0;
|
49
|
+
|
50
|
+
# use this as a reference for a full production deployment
|
51
|
+
# do not use on a dev box. this adds far futures expires.
|
52
|
+
<%= "#" if nginx_far_future %> location ~ ^/(images|javascripts|stylesheets)/ {
|
53
|
+
<%= "#" if nginx_far_future %> expires 10y;
|
54
|
+
<%= "#" if nginx_far_future %> }
|
55
|
+
|
56
|
+
# if file exists break execution and serve up file for example files in images, javascripts, and stylesheets
|
57
|
+
if (-f $request_filename) {
|
58
|
+
break;
|
59
|
+
}
|
60
|
+
# Rails page caching, if file path plus index.html exists break execution and serve up file
|
61
|
+
if (-f $request_filename/index.html) {
|
62
|
+
rewrite (.*) $1/index.html break;
|
63
|
+
}
|
64
|
+
# Rails page caching, if file.html exists break execution and serve up file
|
65
|
+
if (-f $request_filename.html) {
|
66
|
+
rewrite (.*) $1.html break;
|
67
|
+
}
|
68
|
+
# if file does not exist forward to mongrel
|
69
|
+
if (!-f $request_filename) {
|
70
|
+
proxy_pass http://mongrel_<%= application.gsub('.', '_') %>;
|
71
|
+
break;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
<% for location in nginx_auth_locations %>
|
75
|
+
location <%= location %> {
|
76
|
+
<%= "include /etc/nginx/vhosts/#{application}.auth.conf" %>
|
77
|
+
}
|
78
|
+
<% end %>
|
79
|
+
# must be an error so point to error page.
|
80
|
+
error_page 500 502 503 504 /500.html;
|
81
|
+
location = /500.html {
|
82
|
+
root <%= current_path %>/public;
|
83
|
+
}
|
84
|
+
|
85
|
+
}
|
data/lib/fdlcap/thin.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
set :thin_servers, 2
|
2
|
+
set :thin_port, 8000
|
3
|
+
set :thin_address, "127.0.0.1"
|
4
|
+
set :thin_environment, "production"
|
5
|
+
set :thin_conf, nil
|
6
|
+
set :thin_user, nil
|
7
|
+
set :thin_group, nil
|
8
|
+
set :thin_prefix, nil
|
9
|
+
set :thin_pid_file, nil
|
10
|
+
set :thin_log_file, nil
|
11
|
+
set :thin_config_script, nil
|
12
|
+
|
13
|
+
namespace :thin do
|
14
|
+
desc <<-DESC
|
15
|
+
Install Thin script on the app server. This uses the :use_sudo variable to determine whether to use sudo or not. By default, :use_sudo is
|
16
|
+
set to true.
|
17
|
+
DESC
|
18
|
+
task :install , :roles => :app do
|
19
|
+
send(run_method, "gem install thin")
|
20
|
+
send(run_method, "thin install")
|
21
|
+
end
|
22
|
+
|
23
|
+
desc <<-DESC
|
24
|
+
Configure thin processes on the app server. This uses the :use_sudo
|
25
|
+
variable to determine whether to use sudo or not. By default, :use_sudo is
|
26
|
+
set to true.
|
27
|
+
DESC
|
28
|
+
task :configure, :roles => :app do
|
29
|
+
set_conf
|
30
|
+
|
31
|
+
argv = []
|
32
|
+
argv << "thin"
|
33
|
+
argv << "-s #{thin_servers.to_s}"
|
34
|
+
argv << "-p #{thin_port.to_s}"
|
35
|
+
argv << "-e #{thin_environment}"
|
36
|
+
argv << "-a #{thin_address}"
|
37
|
+
argv << "-c #{current_path}"
|
38
|
+
argv << "-C #{thin_conf}"
|
39
|
+
argv << "-P #{thin_pid_file}" if thin_pid_file
|
40
|
+
argv << "-l #{thin_log_file}" if thin_log_file
|
41
|
+
argv << "--user #{thin_user}" if thin_user
|
42
|
+
argv << "--group #{thin_group}" if thin_group
|
43
|
+
argv << "--prefix #{thin_prefix}" if thin_prefix
|
44
|
+
argv << "config"
|
45
|
+
cmd = argv.join " "
|
46
|
+
send(run_method, cmd)
|
47
|
+
end
|
48
|
+
|
49
|
+
task :setup, :roles => :app do
|
50
|
+
thin.install
|
51
|
+
thin.configure
|
52
|
+
end
|
53
|
+
|
54
|
+
desc <<-DESC
|
55
|
+
Start Thin processes on the app server. This uses the :use_sudo variable to determine whether to use sudo or not. By default, :use_sudo is
|
56
|
+
set to true.
|
57
|
+
DESC
|
58
|
+
task :start , :roles => :app do
|
59
|
+
set_conf
|
60
|
+
cmd = "thin start -C #{thin_conf}"
|
61
|
+
send(run_method, cmd)
|
62
|
+
end
|
63
|
+
|
64
|
+
desc <<-DESC
|
65
|
+
Restart the Thin processes on the app server by starting and stopping the cluster. This uses the :use_sudo
|
66
|
+
variable to determine whether to use sudo or not. By default, :use_sudo is set to true.
|
67
|
+
DESC
|
68
|
+
task :restart , :roles => :app do
|
69
|
+
set_conf
|
70
|
+
cmd = "thin restart -C #{thin_conf}"
|
71
|
+
send(run_method, cmd)
|
72
|
+
end
|
73
|
+
|
74
|
+
desc <<-DESC
|
75
|
+
Stop the Thin processes on the app server. This uses the :use_sudo
|
76
|
+
variable to determine whether to use sudo or not. By default, :use_sudo is
|
77
|
+
set to true.
|
78
|
+
DESC
|
79
|
+
task :stop , :roles => :app do
|
80
|
+
set_conf
|
81
|
+
cmd = "thin stop -C #{thin_conf}"
|
82
|
+
send(run_method, cmd)
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
def set_conf
|
87
|
+
set :thin_conf, "/etc/thin/#{application}.yml" unless thin_conf
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
namespace :deploy do
|
92
|
+
desc <<-DESC
|
93
|
+
Restart the Thin processes on the app server by calling thin:restart.
|
94
|
+
DESC
|
95
|
+
task :restart, :roles => :app do
|
96
|
+
thin.restart
|
97
|
+
end
|
98
|
+
|
99
|
+
desc <<-DESC
|
100
|
+
Start the Thin processes on the app server by calling thin:start.
|
101
|
+
DESC
|
102
|
+
task :start, :roles => :app do
|
103
|
+
thin.start
|
104
|
+
end
|
105
|
+
|
106
|
+
desc <<-DESC
|
107
|
+
Stop the Thin processes on the app server by calling thin:stop.
|
108
|
+
DESC
|
109
|
+
task :stop, :roles => :app do
|
110
|
+
thin.stop
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
# Make sphinx happy
|
3
|
+
if exists?(:use_thinking_sphinx)
|
4
|
+
after "deploy:update_code", "deploy:symlink_configs"
|
5
|
+
after "deploy:symlink_configs", "thinking_sphinx:symlink"
|
6
|
+
after "thinking_sphinx:symlink", "sphinx:configure"
|
7
|
+
after "deploy:update", "sphinx:reindex"
|
8
|
+
end
|
9
|
+
end
|
data/test/fdlcap_test.rb
ADDED
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: factorylabs-fdlcap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Factory Design Labs
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-06-25 00:00:00 -07:00
|
13
|
+
default_executable: fdlcap
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: engineyard-eycap
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.4.7
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: zilkey-auto_tagger
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.0.9
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: capistrano
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.5.5
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: capistrano-ext
|
47
|
+
type: :runtime
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.2.1
|
54
|
+
version:
|
55
|
+
description:
|
56
|
+
email: interactive@factorylabs.com
|
57
|
+
executables:
|
58
|
+
- fdlcap
|
59
|
+
extensions: []
|
60
|
+
|
61
|
+
extra_rdoc_files:
|
62
|
+
- LICENSE
|
63
|
+
- README
|
64
|
+
- README.rdoc
|
65
|
+
files:
|
66
|
+
- LICENSE
|
67
|
+
- README
|
68
|
+
- README.rdoc
|
69
|
+
- Rakefile
|
70
|
+
- VERSION
|
71
|
+
- bin/fdlcap
|
72
|
+
- fdlcap.gemspec
|
73
|
+
- features/fdlcap.feature
|
74
|
+
- features/step_definitions/fdlcap_steps.rb
|
75
|
+
- features/support/env.rb
|
76
|
+
- lib/fdlcap.rb
|
77
|
+
- lib/fdlcap/autotagger.rb
|
78
|
+
- lib/fdlcap/craken.rb
|
79
|
+
- lib/fdlcap/database.rb
|
80
|
+
- lib/fdlcap/delayed_job.rb
|
81
|
+
- lib/fdlcap/deploy.rb
|
82
|
+
- lib/fdlcap/geminstaller.rb
|
83
|
+
- lib/fdlcap/newrelic.rb
|
84
|
+
- lib/fdlcap/nginx.rb
|
85
|
+
- lib/fdlcap/performance.rb
|
86
|
+
- lib/fdlcap/rake.rb
|
87
|
+
- lib/fdlcap/recipes.rb
|
88
|
+
- lib/fdlcap/rsync.rb
|
89
|
+
- lib/fdlcap/sass.rb
|
90
|
+
- lib/fdlcap/slice.rb
|
91
|
+
- lib/fdlcap/ssh.rb
|
92
|
+
- lib/fdlcap/symlinks.rb
|
93
|
+
- lib/fdlcap/templates/nginx.auth.conf.erb
|
94
|
+
- lib/fdlcap/templates/nginx.conf.erb
|
95
|
+
- lib/fdlcap/templates/nginx.vhost.conf.erb
|
96
|
+
- lib/fdlcap/thin.rb
|
97
|
+
- lib/fdlcap/thinking_sphinx.rb
|
98
|
+
- test/fdlcap_test.rb
|
99
|
+
- test/test_helper.rb
|
100
|
+
has_rdoc: false
|
101
|
+
homepage: http://github.com/factorylabs/fdlcap
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options:
|
104
|
+
- --charset=UTF-8
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: "0"
|
112
|
+
version:
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: "0"
|
118
|
+
version:
|
119
|
+
requirements: []
|
120
|
+
|
121
|
+
rubyforge_project:
|
122
|
+
rubygems_version: 1.2.0
|
123
|
+
signing_key:
|
124
|
+
specification_version: 3
|
125
|
+
summary: a set of capistrano recipies we use regularly at Factory Design Labs
|
126
|
+
test_files:
|
127
|
+
- test/fdlcap_test.rb
|
128
|
+
- test/test_helper.rb
|