webficient-capistrano-recipes 0.1.1
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.rdoc +37 -0
- data/Rakefile +27 -0
- data/VERSION.yml +4 -0
- data/lib/capistrano_recipes.rb +10 -0
- data/lib/helpers.rb +9 -0
- data/lib/recipes/db.rb +67 -0
- data/lib/recipes/deploy.rb +30 -0
- data/lib/recipes/log.rb +30 -0
- data/lib/recipes/passenger.rb +20 -0
- metadata +82 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Webficient LLC, Phil Misiowiec
|
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.rdoc
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
=Capistrano Recipes
|
2
|
+
|
3
|
+
Useful Capistrano recipes including:
|
4
|
+
|
5
|
+
* Create MySQL database and user on server (via prompts)
|
6
|
+
* Create standalone copy of database.yml in shared path (via prompts)
|
7
|
+
* Log rotation and tailing commands
|
8
|
+
* Restart and profile Phusion Passenger application server
|
9
|
+
|
10
|
+
==Installation
|
11
|
+
|
12
|
+
Easy as pie...
|
13
|
+
|
14
|
+
Ensure you have the Capistrano and Capistrano extensions gems installed:
|
15
|
+
|
16
|
+
sudo gem install capistrano
|
17
|
+
sudo gem install capistrano-ext
|
18
|
+
|
19
|
+
Install this gem:
|
20
|
+
|
21
|
+
sudo gem install webficient-capistrano-recipes --source=http://gems.github.com
|
22
|
+
|
23
|
+
To setup the initial Capistrano deploy file, go to your Rails app folder via command line and enter:
|
24
|
+
|
25
|
+
capify .
|
26
|
+
|
27
|
+
Inside the newly created config/deploy.rb, add:
|
28
|
+
|
29
|
+
require 'capistrano_recipes'
|
30
|
+
|
31
|
+
If you're running Phusion Passenger (http://www.modrails.com) be sure you add this line to config/deploy.rb:
|
32
|
+
|
33
|
+
set :server, :passenger
|
34
|
+
|
35
|
+
==Copyright
|
36
|
+
|
37
|
+
Copyright (c) 2009 Webficient LLC, Phil Misiowiec. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "capistrano-recipes"
|
8
|
+
gem.summary = %Q{Capistrano recipes}
|
9
|
+
gem.email = "phil@webficient.com"
|
10
|
+
gem.homepage = "http://github.com/webficient/capistrano-recipes"
|
11
|
+
gem.authors = ["Phil Misiowiec"]
|
12
|
+
gem.add_dependency('capistrano', ['>= 2.5.5'])
|
13
|
+
gem.add_dependency('capistrano-ext', ['>= 1.2.1'])
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'rake/rdoctask'
|
21
|
+
Rake::RDocTask.new do |rdoc|
|
22
|
+
rdoc.rdoc_dir = 'rdoc'
|
23
|
+
rdoc.title = 'capistrano-recipes'
|
24
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
25
|
+
rdoc.rdoc_files.include('README*')
|
26
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
27
|
+
end
|
data/VERSION.yml
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
require 'capistrano/cli'
|
3
|
+
require 'capistrano/ext/multistage'
|
4
|
+
require 'helpers'
|
5
|
+
|
6
|
+
@@cap_config = Capistrano::Configuration.respond_to?(:instance) ?
|
7
|
+
Capistrano::Configuration.instance(:must_exist) :
|
8
|
+
Capistrano.configuration(:must_exist)
|
9
|
+
|
10
|
+
Dir.glob(File.join(File.dirname(__FILE__), '/recipes/*.rb')).each { |f| load f }
|
data/lib/helpers.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# =========================================================================
|
2
|
+
# These are helper methods that will be available to your recipes.
|
3
|
+
# =========================================================================
|
4
|
+
|
5
|
+
# Execute a rake task, example:
|
6
|
+
# run_rake log:clear
|
7
|
+
def run_rake(task)
|
8
|
+
run "cd #{current_path} && rake #{task} RAILS_ENV=#{stage}"
|
9
|
+
end
|
data/lib/recipes/db.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
@@cap_config.load do
|
4
|
+
|
5
|
+
before "deploy:setup" do
|
6
|
+
db.create_yaml if Capistrano::CLI.ui.agree("Would you like to create a custom database.yml on the server?")
|
7
|
+
end
|
8
|
+
|
9
|
+
after "deploy:update_code", "db:symlink"
|
10
|
+
|
11
|
+
namespace :db do
|
12
|
+
namespace :mysql do
|
13
|
+
desc "Create MySQL database and user for this environment using prompted values"
|
14
|
+
task :setup, :roles => :db, :only => { :primary => true } do
|
15
|
+
prepare_for_db_command
|
16
|
+
|
17
|
+
sql = <<-SQL
|
18
|
+
CREATE DATABASE #{db_name};
|
19
|
+
GRANT ALL PRIVILEGES ON #{db_name}.* TO #{db_user}@localhost IDENTIFIED BY '#{db_pass}';
|
20
|
+
SQL
|
21
|
+
|
22
|
+
run "mysql --user=#{db_admin_user} -p --execute=\"#{sql}\"" do |channel, stream, data|
|
23
|
+
if data =~ /^Enter password:/
|
24
|
+
pass = Capistrano::CLI.password_prompt "Enter database password for '#{db_admin_user}':"
|
25
|
+
channel.send_data "#{pass}\n"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "Create database.yml in shared path with settings for current stage and test env"
|
32
|
+
task :create_yaml do
|
33
|
+
set(:db_user) { Capistrano::CLI.ui.ask "Enter #{stage} database username:" }
|
34
|
+
set(:db_pass) { Capistrano::CLI.password_prompt "Enter #{stage} database password:" }
|
35
|
+
|
36
|
+
db_config = ERB.new <<-EOF
|
37
|
+
base: &base
|
38
|
+
adapter: mysql
|
39
|
+
username: #{db_user}
|
40
|
+
password: #{db_pass}
|
41
|
+
|
42
|
+
#{stage}:
|
43
|
+
database: #{application}_#{stage}
|
44
|
+
<<: *base
|
45
|
+
|
46
|
+
test:
|
47
|
+
database: #{application}_test
|
48
|
+
<<: *base
|
49
|
+
EOF
|
50
|
+
|
51
|
+
run "#{sudo} mkdir -p #{shared_path}/config; #{sudo} chmod 775 #{shared_path}/config"
|
52
|
+
put db_config.result, "#{shared_path}/config/database.yml"
|
53
|
+
end
|
54
|
+
|
55
|
+
desc "Create symlink for database yaml stored in shared path"
|
56
|
+
task :symlink do
|
57
|
+
run "#{sudo} ln -nfs #{shared_path}/config/database.yml #{current_release}/config/database.yml"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def prepare_for_db_command
|
62
|
+
set :db_name, "#{application}_#{stage}"
|
63
|
+
set(:db_admin_user) { Capistrano::CLI.ui.ask "Username with priviledged database access (to create db):" }
|
64
|
+
set(:db_user) { Capistrano::CLI.ui.ask "Enter #{stage} database username:" }
|
65
|
+
set(:db_pass) { Capistrano::CLI.password_prompt "Enter #{stage} database password:" }
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
@@cap_config.load do
|
2
|
+
namespace :deploy do
|
3
|
+
|
4
|
+
desc <<-DESC
|
5
|
+
Restarts your application. If you are running Phusion Passenger, you can \
|
6
|
+
explicitly set the server type:
|
7
|
+
|
8
|
+
set :server, :passenger
|
9
|
+
|
10
|
+
...which will touch tmp/restart.txt, a file monitored by Passenger.
|
11
|
+
Otherwise, this command will call the script/process/reaper \
|
12
|
+
script under the current path.
|
13
|
+
|
14
|
+
By default, this will be invoked via sudo as the `app' user. If \
|
15
|
+
you wish to run it as a different user, set the :runner variable to \
|
16
|
+
that user. If you are in an environment where you can't use sudo, set \
|
17
|
+
the :use_sudo variable to false:
|
18
|
+
|
19
|
+
set :use_sudo, false
|
20
|
+
DESC
|
21
|
+
task :restart, :roles => :app, :except => { :no_release => true } do
|
22
|
+
if exists?(:server) && fetch(:server).to_s.downcase == 'passenger'
|
23
|
+
passenger.bounce
|
24
|
+
else
|
25
|
+
try_runner "#{current_path}/script/process/reaper"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
data/lib/recipes/log.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
@@cap_config.load do
|
2
|
+
namespace :log do
|
3
|
+
|
4
|
+
desc "Tail application log file for the specified environment, e.g. cap staging log:tail"
|
5
|
+
task :tail, :roles => :app do
|
6
|
+
run "tail -f #{shared_path}/log/#{stage}.log" do |channel, stream, data|
|
7
|
+
puts "#{channel[:host]}: #{data}"
|
8
|
+
break if stream == :err
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
desc <<-DESC
|
13
|
+
Install log rotation script; optional args: days=7, size=5M, group (defaults to same value as :user)
|
14
|
+
DESC
|
15
|
+
task :rotate, :roles => :app do
|
16
|
+
rotate_script = %Q{#{shared_path}/log/#{stage}.log {
|
17
|
+
daily
|
18
|
+
rotate #{ENV['days'] || 7}
|
19
|
+
size #{ENV['size'] || "5M"}
|
20
|
+
compress
|
21
|
+
create 640 #{user} #{ENV['group'] || user}
|
22
|
+
missingok
|
23
|
+
}}
|
24
|
+
put rotate_script, "#{shared_path}/logrotate_script"
|
25
|
+
sudo "cp #{shared_path}/logrotate_script /etc/logrotate.d/#{application}"
|
26
|
+
run "rm #{shared_path}/logrotate_script"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
@@cap_config.load do
|
2
|
+
namespace :passenger do
|
3
|
+
|
4
|
+
desc "Restart Rails app running under Phusion Passenger by touching restart.txt"
|
5
|
+
task :bounce, :roles => :app do
|
6
|
+
run "touch #{current_path}/tmp/restart.txt"
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Inspect Phusion Passenger's memory usage. Assumes binaries are located in /opt/ruby-enterprise."
|
10
|
+
task :memory, :roles => :app do
|
11
|
+
run "#{sudo} /opt/ruby-enterprise/bin/passenger-memory-stats"
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Inspect Phusion Passenger's internal status. Assumes binaries are located in /opt/ruby-enterprise."
|
15
|
+
task :status, :roles => :app do
|
16
|
+
run "#{sudo} /opt/ruby-enterprise/bin/passenger-status"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: webficient-capistrano-recipes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Phil Misiowiec
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-30 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: capistrano
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.5.5
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: capistrano-ext
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.2.1
|
34
|
+
version:
|
35
|
+
description:
|
36
|
+
email: phil@webficient.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- LICENSE
|
43
|
+
- README.rdoc
|
44
|
+
files:
|
45
|
+
- LICENSE
|
46
|
+
- README.rdoc
|
47
|
+
- Rakefile
|
48
|
+
- VERSION.yml
|
49
|
+
- lib/capistrano_recipes.rb
|
50
|
+
- lib/helpers.rb
|
51
|
+
- lib/recipes/db.rb
|
52
|
+
- lib/recipes/deploy.rb
|
53
|
+
- lib/recipes/log.rb
|
54
|
+
- lib/recipes/passenger.rb
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: http://github.com/webficient/capistrano-recipes
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options:
|
59
|
+
- --charset=UTF-8
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.2.0
|
78
|
+
signing_key:
|
79
|
+
specification_version: 2
|
80
|
+
summary: Capistrano recipes
|
81
|
+
test_files: []
|
82
|
+
|