caplets 1.0.0 → 1.0.2

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/CHANGELOG CHANGED
@@ -1,2 +1,7 @@
1
+ == 1.0.1
2
+ * bundle:install now uses `bundle check` to short-circuit if possible
3
+ * Add deploy:passenger:reload
4
+ * Add ssh, ssh:app, and ssh:web
5
+
1
6
  == 1.0.0
2
7
  * Initial public release
data/MODULES.md CHANGED
@@ -1,10 +1,9 @@
1
1
  Caplets Modules
2
2
  ===============
3
3
 
4
- caplets/deploy
5
- --------------
4
+ ## caplets/deploy
6
5
 
7
- #### Variables
6
+ ### Variables
8
7
 
9
8
  `:bin_cmd` - Command used to execute binaries within the context of the app.
10
9
  For instance, `caplets/bundle` sets this to `gem exec`. (default: `nil`)
@@ -24,12 +23,12 @@ caplets/deploy
24
23
 
25
24
  `:user` - UNIX user as which to login and run deploys. (default: `deploy`)
26
25
 
27
- ### caplets/bundle
26
+ ## caplets/bundle
28
27
 
29
28
  Bundler 0.9+ support. By default, run after every code update, this `bundle
30
29
  install`s gems into the project (not into system gems to avoid using `sudo`).
31
30
 
32
- #### Variables
31
+ ### Variables
33
32
 
34
33
  `:bundle_exclude` - Bundler groups to exclude from installation. Passed to
35
34
  bundler's `--without` switch. (default: `%w[development test]`)
@@ -39,16 +38,16 @@ install`s gems into the project (not into system gems to avoid using `sudo`).
39
38
  `:bundle_to` - Subdirectory of the application in which to put installed gems.
40
39
  Passed as an argument to `bundle install`. (default: `vendor/bundled_gems`)
41
40
 
42
- #### Tasks
41
+ ### Tasks
43
42
 
44
43
  `deploy:bundle:install` - Runs a `bundle install` to install needed gems from
45
44
  the application's Gemfile.
46
45
 
47
- #### Hooks
46
+ ### Hooks
48
47
 
49
48
  `deploy:bundle:install` after `deploy:update_code`
50
49
 
51
- ### caplets/db
50
+ ## caplets/db
52
51
 
53
52
  Tasks to support using ActiveRecord within your applications. This module
54
53
  adds functionality to write out your `database.yml` file and provides a
@@ -59,7 +58,7 @@ deployed to your DB server. This means you don't even have to list it in your
59
58
  deploy file. Instead, it expects to run your migrations from your `:primary
60
59
  :app` server.
61
60
 
62
- #### Variables
61
+ ### Variables
63
62
 
64
63
  `:db_host` - default: `localhost`
65
64
  `:db_adapter` - default: `mysql`
@@ -77,7 +76,7 @@ for your current `:environment`. If you'd rather, you can specify the entire
77
76
  environment key. Useful for adding access to slaves or other DBs.
78
77
  (default: {})
79
78
 
80
- #### Tasks
79
+ ### Tasks
81
80
 
82
81
  `deploy:db:config` - Write a generated `database.yml` to your project's config
83
82
  directory.
@@ -87,26 +86,26 @@ for your current `:environment`. If you'd rather, you can specify the entire
87
86
  `deploy:migrations` - Do a deploy with migrations, including doing a
88
87
  `web:disable` first and restarting (not reloading) the backends
89
88
 
90
- #### Hooks
89
+ ### Hooks
91
90
 
92
91
  `deploy:db:config` after `deploy:setup`
93
92
 
94
- ### caplets/git-tag
93
+ ## caplets/git-tag
95
94
 
96
95
  Automatically tag a revision on deploy.
97
96
 
98
- #### Tasks
97
+ ### Tasks
99
98
 
100
99
  `git:tag_current_release` - Tag the `:current_revision` with a tag like
101
100
  `deploy-<environment>-<timestamp>` and push it to the origin.
102
101
 
103
- #### Hooks
102
+ ### Hooks
104
103
 
105
104
  `git:tag_current_release` after `deploy:migrations`
106
105
  `git:tag_current_release` after `deploy:quick`
107
106
  `git:tag_current_release` after `deploy:rebuild`
108
107
 
109
- ### caplets/memcached
108
+ ## caplets/memcached
110
109
 
111
110
  Support for keeping track of memcached nodes and writing a `memcached.yml`
112
111
  config file based on the `:memcached` role.
@@ -121,18 +120,30 @@ dynamically based on those servers' `:private_ip`s. Otherwise:
121
120
  ### Tasks
122
121
 
123
122
  `deploy:memcached:config` - Write a generated `memcached.yml` to your
124
- projet's config directory.
123
+ project's config directory.
125
124
 
126
125
  ### Hooks
127
126
 
128
127
  `deploy:memcached:config` after `deploy:setup`
129
128
 
130
- ### caplets/mongrel
129
+ ## caplets/mongrel
131
130
 
132
- ### caplets/networkfs
131
+ ## caplets/networkfs
133
132
 
134
133
  ## caplets/passenger
135
134
 
135
+ ## caplets/ssh
136
+
137
+ Tasks that present a list of your configured servers, and provide quick SSH
138
+ access to any of them. The server list can optionally be narrowed down by
139
+ role.
140
+
141
+ ### Tasks
142
+
143
+ `ssh` - Connects to any configured server. (Usage: `cap <environment> ssh`)
144
+ `ssh:app` - Connects to any configured app server.
145
+ `ssh:web` - Connects to any configured web server.
146
+
136
147
  ## caplets/thinking-sphinx
137
148
 
138
149
  ## caplets/unicorn
data/lib/caplets/basic.rb CHANGED
@@ -9,3 +9,4 @@ config.instance_eval do
9
9
  end
10
10
 
11
11
  config.load 'caplets/deploy'
12
+ config.load 'caplets/ssh'
@@ -10,7 +10,7 @@ namespace :deploy do
10
10
  task :install, :roles => lambda { fetch(:bundle_roles) },
11
11
  :except => {:no_release => true} do
12
12
  without = fetch(:bundle_exclude).map{|g| "--without #{g}"}.join(' ')
13
- run_current "bundle install #{fetch(:bundle_to)} #{without}"
13
+ run_current "bundle check || bundle install #{fetch(:bundle_to)} #{without}"
14
14
  end
15
15
  end
16
16
  end
@@ -56,16 +56,13 @@ namespace :deploy do
56
56
 
57
57
  desc "Setup a Git-based deploy"
58
58
  task :setup, :except => {:no_release => true} do
59
- run_multi(
60
- "if [ -d #{fetch(:current_path)}/.git ]",
61
- "then cd #{fetch(:current_path)}",
62
- "#{try_sudo} git fetch",
63
- "else #{try_sudo} git clone #{fetch(:repository)} #{fetch(:current_path)}",
64
- "fi",
65
- "mkdir -p " + fetch(:required_children,[]).
66
- map {|dir| "#{fetch(:current_path)}/#{dir}" }.
67
- join(' ')
68
- )
59
+ run "if [ -d #{fetch(:current_path)}/.git ] ; "+
60
+ "then cd #{fetch(:current_path)} && #{try_sudo} git fetch ; "+
61
+ "else #{try_sudo} git clone #{fetch(:repository)} #{fetch(:current_path)} ; "+
62
+ "fi && "+
63
+ "mkdir -p " + fetch(:required_children,[]).
64
+ map {|dir| "#{fetch(:current_path)}/#{dir}" }.
65
+ join(' ')
69
66
  end
70
67
 
71
68
  desc <<-DESC
@@ -95,15 +92,15 @@ namespace :deploy do
95
92
 
96
93
  # Just timestamps, please
97
94
  task :finalize_update, :except => { :no_release => true } do
98
- if fetch(:normalize_asset_timestamps, false)
99
- stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
100
- asset_paths = %w(images stylesheets javascripts).map {|p|
101
- "#{latest_release}/public/#{p}"
102
- }.join(" ")
103
- run "find #{asset_paths} -exec touch -t #{stamp} {} ';'; true",
104
- :env => { "TZ" => "UTC" }
95
+ if fetch(:normalize_asset_timestamps, false)
96
+ stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
97
+ asset_paths = %w(images stylesheets javascripts).map {|p|
98
+ "#{latest_release}/public/#{p}"
99
+ }.join(" ")
100
+ run "find #{asset_paths} -exec touch -t #{stamp} {} ';'; true",
101
+ :env => { "TZ" => "UTC" }
102
+ end
105
103
  end
106
- end
107
104
 
108
105
  %w[start stop restart reload].each do |taskname|
109
106
  desc "#{taskname.capitalize} the application server(s)"
@@ -20,19 +20,22 @@ namespace :deploy do
20
20
  desc "Start the mongrel_cluster"
21
21
  task :start, :roles => :app do
22
22
  run "cd #{current_path} && " +
23
- "mongrel_rails cluster::start -C #{shared_path}/config/cluster.yml --clean"
23
+ fetch(:bin_cmd,'') +
24
+ " mongrel_rails cluster::start -C #{shared_path}/config/cluster.yml --clean"
24
25
  end
25
26
 
26
27
  desc "Stop the mongrel_cluster"
27
28
  task :stop, :roles => :app do
28
29
  run "cd #{current_path} && " +
29
- "mongrel_rails cluster::stop -C #{shared_path}/config/cluster.yml --clean"
30
+ fetch(:bin_cmd,'') +
31
+ " mongrel_rails cluster::stop -C #{shared_path}/config/cluster.yml --clean"
30
32
  end
31
33
 
32
34
  desc "Restart the mongrel_cluster"
33
35
  task :restart, :roles => :app do
34
36
  run "cd #{current_path} && " +
35
- "mongrel_rails cluster::restart -C #{shared_path}/config/cluster.yml --clean"
37
+ fetch(:bin_cmd,'') +
38
+ " mongrel_rails cluster::restart -C #{shared_path}/config/cluster.yml --clean"
36
39
  end
37
40
 
38
41
  desc "Restart the mongrel_cluster, as mongrel does not support reloading"
@@ -6,14 +6,11 @@ namespace :deploy do
6
6
  task :start, :roles => :app, :except => {:no_release => true} do; end
7
7
  task :stop, :roles => :app, :except => {:no_release => true} do; end
8
8
 
9
- desc 'Restart the Passenger processes by touching tmp/restart.txt'
10
- task :restart, :roles => :app, :except => {:no_release => true} do
11
- run "touch #{current_path}/tmp/restart.txt"
12
- end
13
-
14
- desc 'Restart the Passenger process by touching tmp/restart.txt'
15
- task :restart, :roles => :app, :except => {:no_release => true} do
16
- run "touch #{current_path}/tmp/restart.txt"
9
+ [:restart, :reload].each do |action|
10
+ desc 'Restart the Passenger processes by touching tmp/restart.txt'
11
+ task action, :roles => :app, :except => {:no_release => true} do
12
+ run "touch #{current_path}/tmp/restart.txt"
13
+ end
17
14
  end
18
15
  end # namespace :passenger
19
16
  end # namespace :deploy
@@ -0,0 +1,54 @@
1
+ module Caplets::SSH
2
+ def ssh_to_server(opts={})
3
+ servers = []
4
+ selected_role = opts[:role] ? opts[:role].to_sym : nil
5
+ task_roles = selected_role ? {selected_role => roles[selected_role]} :
6
+ roles.sort_by(&:to_s)
7
+
8
+ # Convert from an array of roles (i.e., servers grouped by role) to an
9
+ # array of server data hashes (i.e., roles grouped by server)
10
+ task_roles.each do |role_name, role|
11
+ role.servers.each do |role_server|
12
+ role_server_data = servers.detect { |s| s[:host] == role_server.host }
13
+ if role_server_data
14
+ role_server_data[:role_names] << role_name
15
+ else
16
+ servers << {:host => role_server.host, :role_names => [role_name]}
17
+ end
18
+ end
19
+ end
20
+
21
+ # Prompt for a server if needed
22
+ if servers.size > 1
23
+ env_desc = "#{fetch(:environment)} #{selected_role}".strip
24
+ puts "\nWhich #{env_desc} server?"
25
+ servers.each_with_index do |server, i|
26
+ server_desc = server[:host].dup
27
+ unless selected_role
28
+ server_desc << " (#{server[:role_names].join(', ')})"
29
+ end
30
+ puts " #{(i+1).to_s.rjust(2)}. #{server_desc}"
31
+ end
32
+ input = Capistrano::CLI.ui.
33
+ ask('> ', Integer) { |q| q.in = 1..servers.size }
34
+ host = servers[input - 1][:host]
35
+ else
36
+ host = servers.first[:host]
37
+ end
38
+
39
+ cmd = %|ssh -t #{fetch(:user)}@#{host} "cd #{fetch(:current_path)}; bash"|
40
+ puts "Connecting to #{host}..."
41
+ exec(cmd)
42
+ end
43
+ end
44
+ Capistrano::Configuration.send :include, Caplets::SSH
45
+
46
+ namespace :ssh do
47
+ desc 'SSH into any configured server'
48
+ task(:default) { ssh_to_server } # Usage: `cap production ssh`, etc.
49
+
50
+ [:app, :web].each do |role|
51
+ desc "SSH into any configured #{role} server"
52
+ task(role.to_sym) { ssh_to_server(:role => role) }
53
+ end
54
+ end
@@ -4,7 +4,8 @@ namespace :deploy do
4
4
  namespace :unicorn do
5
5
 
6
6
  def start_cmd
7
- "#{fetch(:_unicorn_cmd,'unicorn')} -D" +
7
+ fetch(:bin_cmd,'') +
8
+ " #{fetch(:_unicorn_cmd,'unicorn')} -D" +
8
9
  " -c config/unicorn.rb" +
9
10
  " -E #{fetch(:environment)}"
10
11
  end
data/lib/caplets/utils.rb CHANGED
@@ -1,7 +1,12 @@
1
1
  # This is just a collection of handy methods to use while writing tasks
2
2
  module Caplets::Utils
3
3
  def rake(cmd)
4
- run_current "RAILS_ENV=#{fetch(:environment)} rake #{cmd}"
4
+ run_current [
5
+ "RAILS_ENV=#{fetch(:environment)}",
6
+ fetch(:bin_cmd,''),
7
+ fetch(:rake, 'rake'),
8
+ cmd
9
+ ].join(' ')
5
10
  end
6
11
 
7
12
  def run_current(*cmds)
@@ -2,7 +2,7 @@ module Caplets
2
2
  module Version
3
3
  MAJOR = 1
4
4
  MINOR = 0
5
- TINY = 0
5
+ TINY = 2
6
6
  BUILD = nil
7
7
  STRING = [MAJOR,MINOR,TINY,BUILD].compact.join('.')
8
8
  end
@@ -9,7 +9,7 @@ namespace :deploy do
9
9
  load_file = "config/whenever/#{fetch(:environment)}.#{role}.rb"
10
10
  [ "cd #{fetch(:current_path)} &&",
11
11
  "if [ -f #{load_file} ] ; then",
12
- "#{fetch(:bin_cmd)} whenever",
12
+ "#{fetch(:bin_cmd,'')} whenever",
13
13
  "--update-crontab #{fetch(:application)}.#{fetch(:environment)}.#{role}",
14
14
  "--load-file #{load_file}",
15
15
  "--set environment=#{fetch(:environment)}",
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: caplets
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 19
4
5
  prerelease: false
5
6
  segments:
6
7
  - 1
7
8
  - 0
8
- - 0
9
- version: 1.0.0
9
+ - 2
10
+ version: 1.0.2
10
11
  platform: ruby
11
12
  authors:
12
13
  - Dean Strelau
@@ -14,16 +15,18 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-06-08 00:00:00 -04:00
18
+ date: 2010-10-27 00:00:00 -04:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: capistrano
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ">="
26
28
  - !ruby/object:Gem::Version
29
+ hash: 27
27
30
  segments:
28
31
  - 2
29
32
  - 5
@@ -51,6 +54,7 @@ files:
51
54
  - lib/caplets/mongrel.rb
52
55
  - lib/caplets/networkfs.rb
53
56
  - lib/caplets/passenger.rb
57
+ - lib/caplets/ssh.rb
54
58
  - lib/caplets/thinking-sphinx.rb
55
59
  - lib/caplets/unicorn.rb
56
60
  - lib/caplets/unicorn_rails.rb
@@ -74,23 +78,27 @@ rdoc_options: []
74
78
  require_paths:
75
79
  - lib
76
80
  required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
77
82
  requirements:
78
83
  - - ">="
79
84
  - !ruby/object:Gem::Version
85
+ hash: 3
80
86
  segments:
81
87
  - 0
82
88
  version: "0"
83
89
  required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
84
91
  requirements:
85
92
  - - ">="
86
93
  - !ruby/object:Gem::Version
94
+ hash: 3
87
95
  segments:
88
96
  - 0
89
97
  version: "0"
90
98
  requirements: []
91
99
 
92
100
  rubyforge_project:
93
- rubygems_version: 1.3.6
101
+ rubygems_version: 1.3.7
94
102
  signing_key:
95
103
  specification_version: 3
96
104
  summary: Capistrano super powers