chicken_soup 0.1.0 → 0.2.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.
Files changed (64) hide show
  1. data/.gitignore +2 -0
  2. data/.rspec +1 -0
  3. data/.rvmrc +1 -0
  4. data/chicken_soup.gemspec +3 -1
  5. data/lib/chicken_soup/capabilities.rb +21 -6
  6. data/lib/chicken_soup/capabilities/apache/apache-checks.rb +19 -0
  7. data/lib/chicken_soup/capabilities/apache/apache-defaults.rb +30 -0
  8. data/lib/chicken_soup/capabilities/apache/apache-tasks.rb +85 -0
  9. data/lib/chicken_soup/capabilities/bundler/bundler-checks.rb +19 -0
  10. data/lib/chicken_soup/capabilities/bundler/bundler-defaults.rb +14 -0
  11. data/lib/chicken_soup/capabilities/bundler/bundler-tasks.rb +35 -0
  12. data/lib/chicken_soup/capabilities/checks.rb +1 -1
  13. data/lib/chicken_soup/capabilities/defaults.rb +22 -5
  14. data/lib/chicken_soup/capabilities/{git.rb → git/git-defaults.rb} +2 -13
  15. data/lib/chicken_soup/capabilities/heroku/heroku-checks.rb +22 -0
  16. data/lib/chicken_soup/capabilities/heroku/heroku-defaults.rb +16 -0
  17. data/lib/chicken_soup/capabilities/{heroku.rb → heroku/heroku-tasks.rb} +5 -45
  18. data/lib/chicken_soup/capabilities/{mysql.rb → mysql/mysql-tasks.rb} +0 -0
  19. data/lib/chicken_soup/capabilities/nginx/nginx-checks.rb +19 -0
  20. data/lib/chicken_soup/capabilities/nginx/nginx-defaults.rb +21 -0
  21. data/lib/chicken_soup/capabilities/nginx/nginx-tasks.rb +85 -0
  22. data/lib/chicken_soup/capabilities/{passenger.rb → passenger/passenger-tasks.rb} +1 -1
  23. data/lib/chicken_soup/capabilities/postgres/postgres-checks.rb +17 -0
  24. data/lib/chicken_soup/capabilities/postgres/postgres-defaults.rb +15 -0
  25. data/lib/chicken_soup/capabilities/{postgres.rb → postgres/postgres-tasks.rb} +1 -1
  26. data/lib/chicken_soup/capabilities/rvm/rvm-checks.rb +21 -0
  27. data/lib/chicken_soup/capabilities/rvm/rvm-defaults.rb +13 -0
  28. data/lib/chicken_soup/capabilities/rvm/rvm-tasks.rb +6 -0
  29. data/lib/chicken_soup/capabilities/shared/db-checks.rb +19 -0
  30. data/lib/chicken_soup/capabilities/shared/db-defaults.rb +13 -0
  31. data/lib/chicken_soup/capabilities/shared/{db.rb → db-tasks.rb} +24 -11
  32. data/lib/chicken_soup/capabilities/shared/web_server-tasks.rb +99 -0
  33. data/lib/chicken_soup/capabilities/{svn.rb → svn/svn-defaults.rb} +0 -13
  34. data/lib/chicken_soup/capabilities/svn/svn-tasks.rb +12 -0
  35. data/lib/chicken_soup/capabilities/tasks.rb +12 -0
  36. data/lib/chicken_soup/capabilities/unix/unix-checks.rb +33 -0
  37. data/lib/chicken_soup/capabilities/unix/unix-defaults.rb +42 -0
  38. data/lib/chicken_soup/capabilities/{unix.rb → unix/unix-tasks.rb} +4 -83
  39. data/lib/chicken_soup/deploy.rb +0 -5
  40. data/lib/chicken_soup/environment.rb +10 -0
  41. data/lib/chicken_soup/environment/checks.rb +17 -2
  42. data/lib/chicken_soup/environment/defaults.rb +25 -3
  43. data/lib/chicken_soup/environment/tasks.rb +12 -0
  44. data/lib/chicken_soup/global.rb +77 -2
  45. data/lib/chicken_soup/notifiers.rb +7 -4
  46. data/lib/chicken_soup/notifiers/checks.rb +1 -1
  47. data/lib/chicken_soup/notifiers/defaults.rb +1 -2
  48. data/lib/chicken_soup/notifiers/email/email-checks.rb +26 -0
  49. data/lib/chicken_soup/notifiers/email/email-defaults.rb +50 -0
  50. data/lib/chicken_soup/notifiers/email/email-tasks.rb +37 -0
  51. data/lib/chicken_soup/notifiers/email/presenter.rb +56 -0
  52. data/lib/chicken_soup/notifiers/{git.rb → git/git-tasks.rb} +0 -0
  53. data/lib/chicken_soup/notifiers/{hoptoad.rb → hoptoad/hoptoad-tasks.rb} +0 -0
  54. data/lib/chicken_soup/notifiers/tasks.rb +12 -0
  55. data/lib/chicken_soup/templates/client_email.html.erb +21 -0
  56. data/lib/chicken_soup/templates/internal_email.html.erb +19 -0
  57. data/lib/chicken_soup/version.rb +1 -1
  58. data/lib/chicken_stock.rb +3 -3
  59. data/spec/support/focused.rb +10 -0
  60. metadata +91 -35
  61. data/lib/chicken_soup/capabilities/apache.rb +0 -235
  62. data/lib/chicken_soup/capabilities/bundler.rb +0 -68
  63. data/lib/chicken_soup/capabilities/rvm.rb +0 -42
  64. data/lib/chicken_soup/notifiers/email.rb +0 -109
@@ -0,0 +1,12 @@
1
+ ######################################################################
2
+ # SUBVERSION TASKS #
3
+ ######################################################################
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+ namespace :vc do
6
+ desc <<-DESC
7
+ DESC
8
+ task :log do
9
+ set :vc_log, `svn log -r #{previous_revision.to_i + 1}:#{current_revision}`
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+ before 'capabilities:load_tasks', 'load_capability_tasks'
3
+
4
+ namespace :capabilities do
5
+ desc <<-DESC
6
+ [internal] A helper task used to load all of the tasks associated with the
7
+ requested capabilities.
8
+ DESC
9
+ task :load_tasks do
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,33 @@
1
+ ######################################################################
2
+ # UNIX CHECKS #
3
+ ######################################################################
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+ namespace :capabilities do
6
+ namespace :check do
7
+ desc <<-DESC
8
+ [internal] Checks to see if all necessary unix environment variables have been set up.
9
+ DESC
10
+ task :unix do
11
+ required_variables = [
12
+ :user,
13
+ :deployment_username,
14
+ :manager_username,
15
+ :user_home,
16
+ :deployment_user_home,
17
+ :manager_user_home,
18
+ :deploy_base_dir,
19
+ :deploy_site_name,
20
+ :deploy_to,
21
+ :app_server_ip,
22
+ :web_server_ip,
23
+ :db_server_ip,
24
+ :web_server_name,
25
+ :app_server_name,
26
+ :db_server_name
27
+ ]
28
+
29
+ verify_variables(required_variables)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,42 @@
1
+ ######################################################################
2
+ # UNIX SERVER DEFAULTS #
3
+ ######################################################################
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+ namespace :capabilities do
6
+ namespace :defaults do
7
+ desc "[internal] Sets intelligent defaults for unix server deployments."
8
+ task :unix do
9
+ _cset :deployment_username, "deploy"
10
+ _cset :manager_username, "manage"
11
+ _cset :user, deployment_username
12
+
13
+ _cset :user_home, "/home/#{user}"
14
+ _cset :manager_user_home, "/home/#{manager_username}"
15
+ _cset :deployment_user_home, "/home/#{deployment_username}"
16
+ _cset :deploy_base_dir, "/var/www"
17
+ _cset :deploy_site_name, domain
18
+ set :deploy_to, "#{deploy_base_dir}/#{deploy_site_name}"
19
+
20
+ _cset :app_server_ip, default_server_ip
21
+ _cset :web_server_ip, default_server_ip
22
+ _cset :db_server_ip, default_server_ip
23
+
24
+ _cset :default_server_name, domain
25
+
26
+ _cset(:app_server_name) { default_server_name }
27
+ _cset(:web_server_name) { default_server_name }
28
+ _cset(:db_server_name) { default_server_name }
29
+
30
+ # Evidently roles can't be assigned in a namespace :-/
31
+ set_unix_server_roles
32
+ end
33
+ end
34
+ end
35
+
36
+ desc "[internal] This task is only here because `role` cannot be used within a `namespace`"
37
+ task :set_unix_server_roles do
38
+ role :web, web_server_name, :primary => true
39
+ role :app, app_server_name, :primary => true
40
+ role :db, db_server_name, :primary => true
41
+ end
42
+ end
@@ -52,18 +52,18 @@ Capistrano::Configuration.instance(:must_exist).load do
52
52
 
53
53
  namespace :os do
54
54
  namespace :users do
55
- namespace :root do
55
+ namespace :superuser do
56
56
  desc <<-DESC
57
- [internal] Switches Capistrano to use the root user for all subsequent SSH actions.
57
+ [internal] Switches Capistrano to use the superuser account for all subsequent SSH actions.
58
58
 
59
- It will prompt for the root user's password the first time it's needed.
59
+ It will prompt for the superuser's password the first time it's needed.
60
60
  DESC
61
61
  task :use do
62
62
  set_user_to("root")
63
63
  end
64
64
  end
65
65
 
66
- namespace :manager do
66
+ namespace :manage do
67
67
  desc <<-DESC
68
68
  [internal] Switches Capistrano to use the manager user for all subsequent SSH actions.
69
69
 
@@ -89,82 +89,3 @@ Capistrano::Configuration.instance(:must_exist).load do
89
89
  end
90
90
  end
91
91
  end
92
-
93
- ######################################################################
94
- # UNIX CHECKS #
95
- ######################################################################
96
- Capistrano::Configuration.instance(:must_exist).load do
97
- namespace :capabilities do
98
- namespace :check do
99
- desc <<-DESC
100
- [internal] Checks to see if all necessary unix environment variables have been set up.
101
- DESC
102
- task :unix do
103
- required_variables = [
104
- :user,
105
- :deployment_username,
106
- :manager_username,
107
- :user_home,
108
- :deployment_user_home,
109
- :manager_user_home,
110
- :deploy_dir,
111
- :deploy_name,
112
- :deploy_to,
113
- :app_server_ip,
114
- :web_server_ip,
115
- :db_server_ip,
116
- :web_server_name,
117
- :app_server_name,
118
- :db_server_name
119
- ]
120
-
121
- verify_variables(required_variables)
122
- end
123
- end
124
- end
125
- end
126
-
127
- ######################################################################
128
- # UNIX SERVER DEFAULTS #
129
- ######################################################################
130
- Capistrano::Configuration.instance(:must_exist).load do
131
- namespace :capabilities do
132
- namespace :defaults do
133
- desc "[internal] Sets intelligent defaults for unix server deployments."
134
- task :unix do
135
- _cset :deployment_username, "deploy"
136
- _cset :manager_username, "manager"
137
- _cset :user, deployment_username
138
-
139
- _cset :user_home, "/home/#{user}"
140
- _cset :manager_user_home, "/home/#{manager_username}"
141
- _cset :deployment_user_home, "/home/#{deployment_username}"
142
- _cset :deploy_dir, "/var/www"
143
- _cset :deploy_name, "#{application_short}.#{domain}"
144
- set :deploy_to, "#{deploy_dir}/#{deploy_name}"
145
-
146
- _cset :keep_releases, 15
147
-
148
- _cset :global_shared_files, ["config/database.yml"]
149
-
150
- _cset :app_server_ip, server_ip
151
- _cset :web_server_ip, server_ip
152
- _cset :db_server_ip, server_ip
153
-
154
- _cset :app_server_name, server_name
155
- _cset :web_server_name, server_name
156
- _cset :db_server_name, server_name
157
-
158
- # Evidently roles can't be assigned in a namespace :-/
159
- set_unix_server_roles
160
- end
161
- end
162
- end
163
-
164
- desc "[internal] This task is only here because `role` cannot be used within a `namespace`"
165
- task :set_unix_server_roles do
166
- role :web, web_server_name, :primary => true
167
- role :app, app_server_name, :primary => true
168
- role :db, db_server_name, :primary => true
169
- end
170
- end
@@ -2,11 +2,6 @@
2
2
  # DEPLOYMENT TASKS #
3
3
  ######################################################################
4
4
  Capistrano::Configuration.instance(:must_exist).load do
5
- before "deploy", "deploy:web:disable"
6
- after "deploy", "deploy:web:enable"
7
-
8
- before "deploy:migrate", "db:backup"
9
-
10
5
  namespace :deploy do
11
6
  desc <<-DESC
12
7
  [internal] The list of tasks used by `deploy`, `deploy:cold`, `deploy:subzero` and `deploy:initial`
@@ -4,4 +4,14 @@
4
4
  Capistrano::Configuration.instance(:must_exist).load do
5
5
  require 'chicken_soup/environment/defaults'
6
6
  require 'chicken_soup/environment/checks'
7
+ require 'chicken_soup/environment/tasks'
8
+
9
+ namespace :environment do
10
+ desc "[internal] Load the Chicken Soup environment"
11
+ task :init do
12
+ environment.defaults.default
13
+ environment.check
14
+ environment.load_tasks
15
+ end
16
+ end
7
17
  end
@@ -1,8 +1,23 @@
1
1
  ######################################################################
2
- # ENVIRONMENT CHECKS #
2
+ # ENVIRONMENT CHECKS
3
+ #
4
+ # Sets up a first-pass environment check for the deployment.
5
+ #
6
+ # First, an environment MUST be present in order for any deployment
7
+ # to happen. It's a safety measure that this is explicitly stated.
8
+ #
9
+ # It also checks to make sure that the :application and
10
+ # :application_short environment variables have been set.
11
+ #
12
+ # This happens before any of the capabilities have been added to the
13
+ # deployment and therefore that is all we know to check for at this
14
+ # point.
15
+ #
3
16
  ######################################################################
4
17
  Capistrano::Configuration.instance(:must_exist).load do
5
- on :start, 'environment:check', :except => ['staging', 'production']
18
+ on :start, 'environment:check', :except => ['staging', 'production']
19
+
20
+ after 'environment:check', 'capabilities:check', 'notifiers:check'
6
21
 
7
22
  namespace :environment do
8
23
  desc "[internal] Checks for environment variables shared among all deployment types."
@@ -1,9 +1,27 @@
1
1
  ######################################################################
2
- # ENVIRONMENT DEFAULTS #
2
+ # ENVIRONMENT DEFAULTS
3
+ #
4
+ # This is where all of the environment defaults for the tasks are set.
5
+ #
6
+ # None of these defaults are specific to any of the capabilities we
7
+ # will add in later.
8
+ #
9
+ # The main tasks of note are the :staging and :production tasks. Both
10
+ # of which will set the :rails_env variable so that the rest of the
11
+ # tasks know in what environment they are operating.
12
+ #
13
+ # Note: That these are the 'environment:defaults:staging' and
14
+ # 'environment:defaults:production' tasks and not the 'staging' and
15
+ # 'production' tasks.
16
+ #
17
+ # The latter should be set in the application's deploy.rb file.
18
+ #
3
19
  ######################################################################
4
20
  Capistrano::Configuration.instance(:must_exist).load do
5
- after 'production', 'environment:defaults:production', 'environment:defaults'
6
- after 'staging', 'environment:defaults:staging', 'environment:defaults'
21
+ after 'production', 'environment:defaults:production', 'environment:init'
22
+ after 'staging', 'environment:defaults:staging', 'environment:init'
23
+
24
+ after 'environment:defaults', 'capabilities:defaults', 'notifiers:defaults'
7
25
 
8
26
  namespace :environment do
9
27
  namespace :defaults do
@@ -24,6 +42,10 @@ Capistrano::Configuration.instance(:must_exist).load do
24
42
 
25
43
  _cset :copy_compression, :bz2
26
44
 
45
+ _cset :keep_releases, 15
46
+
47
+ _cset :global_shared_files, ["config/database.yml"]
48
+
27
49
  _cset(:application_short) {application}
28
50
  _cset(:application_underscored) {application.gsub(/-/, "_")}
29
51
  end
@@ -0,0 +1,12 @@
1
+ ######################################################################
2
+ # ENVIRONMENT TASKS #
3
+ ######################################################################
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+ after 'environment:load_tasks', 'capabilities:load_tasks', 'notifiers:load_tasks'
6
+
7
+ namespace :environment do
8
+ desc "[internal] A helper task used to load the tasks for all of the capabilities."
9
+ task :load_tasks do
10
+ end
11
+ end
12
+ end
@@ -1,8 +1,21 @@
1
+ ###
2
+ # Helper method to close all session connections to the remote servers
3
+ #
1
4
  def close_sessions
2
5
  sessions.values.each { |session| session.close }
3
6
  sessions.clear
4
7
  end
5
8
 
9
+ ###
10
+ # Forces all connections to switch to the user passed into it.
11
+ #
12
+ # It will forcibly terminate all open connections in order to accomplish this.
13
+ #
14
+ # @example Switch to the 'deploy' user:
15
+ # set_user_to 'deploy'
16
+ #
17
+ # @param [String] username The username you would like to begin using.
18
+ #
6
19
  def set_user_to(username)
7
20
  close_sessions
8
21
  set :user, username
@@ -10,8 +23,35 @@ def set_user_to(username)
10
23
  set(:user_home) { user == "root" ? "/root" : "/home/#{username}" }
11
24
  end
12
25
 
26
+ ###
27
+ # Helper method to run tasks in different contexts.
28
+ #
29
+ # The workflow is as follows:
30
+ # * Current user is saved
31
+ # * User is switched to the desired username passed in via the :as option
32
+ # * The task is run
33
+ # * The user is switched back to the original user
34
+ #
35
+ # By default the task hooks are prepared but the task itself is not executed.
36
+ # You can change this by passing :now as an option.
37
+ #
38
+ # Running a task 'now' does not create hooks. Standard calls to the task will
39
+ # be executed via the current user.
40
+ #
41
+ # @example Always run the task to install gems as the 'manage' user:
42
+ # run_task 'gems:install', :as => 'manage'
43
+ # @example Run the db migration task now as the 'deploy' user:
44
+ # run_task 'db:migrate', :as => 'deploy', :now => true
45
+ #
46
+ # @param [String] task_name The name of the task to run.
47
+ # @param [Hash] options Options to customize how the task is run. Valid options are:
48
+ # @option options [Boolean] :now - If present, the task will be executed immediately.
49
+ # @option options [String] :as - The name of the user you wish the task to be executed as.
50
+ #
51
+ # @todo Remove all previous hooks prior to adding new ones. Also disable hooks when running "now"
52
+ #
13
53
  def run_task(task_name, options = {})
14
- raise "#run_task must be passed an `:as` option so that it knows who to change the user to." unless options[:as]
54
+ abort "#run_task must be passed an `:as` option so that it knows who to change the user to." unless options[:as]
15
55
 
16
56
  original_username = exists?(:user) ? user : nil
17
57
 
@@ -25,19 +65,54 @@ def run_task(task_name, options = {})
25
65
  end
26
66
  end
27
67
 
68
+ ###
69
+ # Checks an array of items to see if they are currently set within the
70
+ # Capistrano scope. If any of them fail, Capistrano execution will terminate.
71
+ #
72
+ # @param [Array, #each] required_variables An iterable list of items which
73
+ # represent the names of Capistrano environment variables. Each item in this
74
+ # list is expected to be set.
75
+ #
76
+ # @raise [CapistranoGoBoom] Calls #abort on the Capistrano execution if any of
77
+ # the variables are not set.
78
+ #
79
+ # @example Using an array:
80
+ # verify_variables [:user, :deploy_base_dir, :app_server]
81
+ #
28
82
  def verify_variables(required_variables)
29
83
  required_variables.each do |expected_variable|
30
84
  abort( "You have not defined '#{expected_variable}' which is necessary for deployment." ) unless exists?(expected_variable)
31
85
  end
32
86
  end
33
87
 
34
- # Taken from the capistrano code.
88
+ ###
89
+ # @note Taken directly from the Capistrano codebase.
90
+ #
91
+ # Sets a variable only if it doesn't already exist.
92
+ #
35
93
  def _cset(name, *args, &block)
36
94
  unless exists?(name)
37
95
  set(name, *args, &block)
38
96
  end
39
97
  end
40
98
 
99
+ ###
100
+ # Runs a command on the remote server to see if the file currently exists.
101
+ #
102
+ # @param [String] file The filename (optionally including path) that is may
103
+ # or may not exist.
104
+ #
105
+ # @return [Boolean] Whether or not the file exists.
106
+ #
107
+ # @example File without path:
108
+ # remote_file_exists? 'server.log'
109
+ # @example File with path:
110
+ # remote_file_exists? '/var/www/myappdir/log/production.log'
111
+ #
41
112
  def remote_file_exists?(file)
42
113
  capture("if [ -f #{file} ]; then echo 'exists'; fi;").chomp == "exists"
43
114
  end
115
+
116
+ def require_if_exists(file)
117
+ require file if File.exists?(File.join(File.dirname(__FILE__), '..', "#{file}.rb"))
118
+ end
@@ -4,11 +4,14 @@
4
4
  Capistrano::Configuration.instance(:must_exist).load do
5
5
  require 'chicken_soup/notifiers/defaults'
6
6
  require "chicken_soup/notifiers/checks"
7
+ require "chicken_soup/notifiers/tasks"
7
8
 
8
- desc "[internal] This task is only here because `require` cannot be used within a `namespace`"
9
- task :load_notifiers do
10
- fetch(:notifiers).each do |notifier|
11
- require "chicken_soup/notifiers/#{notifier}"
9
+ ['defaults', 'checks', 'tasks'].each do |method|
10
+ desc "[internal] This task is only here because `require` cannot be used within a `namespace`"
11
+ task "load_notifier_#{method}".to_sym do
12
+ fetch(:notifiers).each do |notifier|
13
+ require_if_exists "chicken_soup/notifiers/#{notifier}/#{notifier}-#{method}"
14
+ end
12
15
  end
13
16
  end
14
17
  end