capitate 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,10 @@
1
+ == 0.2.6 2008-02-29
2
+
3
+ * Fix SSH connect debug when connecting to more than 1 server.
4
+ * Added monit restart (hup) recipe.
5
+ * Mysql setup task, showing sql. Setting to :db role only.
6
+ * Capistrano patch: execute_on_servers_without_capitate(options, &block) to rescue Capistrano::NoMatchingServersError, and ignore as non-fatal
7
+
1
8
  == 0.2.5 2008-02-28
2
9
 
3
10
  * Adding application configuration for mongrel cluster monit setup.
data/Manifest.txt CHANGED
@@ -68,6 +68,7 @@ lib/recipes/centos/sphinx.rb
68
68
  lib/recipes/docs.rb
69
69
  lib/recipes/memcached.rb
70
70
  lib/recipes/mongrel_cluster.rb
71
+ lib/recipes/monit.rb
71
72
  lib/recipes/mysql.rb
72
73
  lib/recipes/nginx.rb
73
74
  lib/recipes/rails.rb
@@ -15,7 +15,8 @@ h2. Namespaces
15
15
  * "memcached:monit":memcached-monit.html (1)
16
16
  * "mongrel-cluster:centos":mongrel-cluster-centos.html (1)
17
17
  * "mongrel-cluster:monit":mongrel-cluster-monit.html (1)
18
- * "monit:centos":monit-centos.html (2)
18
+ * "monit":monit.html (3)
19
+ * "monit:centos":monit-centos.html (1)
19
20
  * "mysql":mysql.html (1)
20
21
  * "mysql:centos":mysql-centos.html (1)
21
22
  * "mysql:monit":mysql-monit.html (1)
@@ -15,6 +15,7 @@ h3(#mongrel:cluster:monit:setup). mongrel:cluster:monit:setup
15
15
  Create monit configuration for mongrel cluster.
16
16
 
17
17
  *mongrel_application*: Name of application (monit group). _Defaults to <tt>"mongrel_cluster_#{fetch(:application)}"</tt>_
18
+ *mongrel_bin_path*: Path to mongrel command. _Defaults to <tt>/usr/bin/mongrel_rails</tt>_
18
19
  *mongrel_size*: Number of mongrels.
19
20
 
20
21
  @set :mongrel_size, 3@
@@ -6,7 +6,6 @@ h1. monit:centos
6
6
  h2. Tasks
7
7
 
8
8
  * "monit:centos:install":#monit:centos:install
9
- * "monit:centos:restart":#monit:centos:restart
10
9
 
11
10
 
12
11
  h2. Task documentation
@@ -37,13 +36,3 @@ Install monit.
37
36
 
38
37
 
39
38
 
40
- h3(#monit:centos:restart). monit:centos:restart
41
-
42
- Monit HUP.
43
-
44
- *monit_pid_path*: Path to monit pid.
45
-
46
- @set :monit_pid_path, "/var/run/monit.pid"@
47
-
48
-
49
-
@@ -5,4 +5,41 @@ h1. monit
5
5
 
6
6
  h2. Namespaces
7
7
 
8
- * "monit:centos":monit-centos.html (2)
8
+ * "monit:centos":monit-centos.html (1)
9
+
10
+
11
+ h2. Tasks
12
+
13
+ * "monit:monitor_all":#monit:monitor_all
14
+ * "monit:restart":#monit:restart
15
+ * "monit:unmonitor_all":#monit:unmonitor_all
16
+
17
+
18
+ h2. Task documentation
19
+
20
+ h3(#monit:monitor_all). monit:monitor_all
21
+
22
+ Monitor all.
23
+
24
+ *monit_bin_path*: Path to monit bin. _Defaults to <tt>monit</tt>_
25
+
26
+
27
+
28
+ h3(#monit:restart). monit:restart
29
+
30
+ Restart (HUP) monit process.
31
+
32
+ HUP's the process from the pid file, if it exists.
33
+
34
+ *monit_pid_path*: Path to monit pid file. _Defaults to <tt>/var/run/monit.pid</tt>_
35
+
36
+
37
+
38
+ h3(#monit:unmonitor_all). monit:unmonitor_all
39
+
40
+ Unmonitor all.
41
+
42
+ *monit_bin_path*: Path to monit bin. _Defaults to <tt>monit</tt>_
43
+
44
+
45
+
@@ -12,7 +12,7 @@ h2. Task documentation
12
12
 
13
13
  h3(#nginx:mongrel:setup). nginx:mongrel:setup
14
14
 
15
- Create and update the nginx vhost include.
15
+ Generate the nginx vhost include (for a mongrel setup).
16
16
 
17
17
  *mongrel_application*: Mongrel application. _Defaults to <tt>:application</tt>_
18
18
  *mongrel_size*: Number of mongrels.
@@ -1,84 +1,107 @@
1
1
  # Patch to add ability to clear sessions/connections.
2
- module Capistrano::Configuration::Connections
2
+ module Capitate
3
+ module CapExt
4
+ module Connections
3
5
 
4
- # Set the user to something new (but save the old user; reset_user will set it back).
5
- # Takes care of invalidating current connections. Will force a re-login.
6
- #
7
- # ==== Options
8
- # +new_user+:: User to become
9
- #
10
- # ==== Examples
11
- # set_user("nginx")
12
- # # Do something as user nginx
13
- #
14
- def set_user(new_user)
15
- previous_user = fetch(:user)
6
+ def self.included(base) #:nodoc:
7
+ base.send :alias_method, :execute_on_servers_without_capitate, :execute_on_servers
8
+ base.send :alias_method, :execute_on_servers, :execute_on_servers_with_capitate
9
+ end
10
+
11
+ # Determines the set of servers within the current task's scope and
12
+ # establishes connections to them, and then yields that list of
13
+ # servers.
14
+ #
15
+ # Overriden to handle NoMatchingServersError as NON-FATAL
16
+ #
17
+ def execute_on_servers_with_capitate(options={}, &block)
18
+ begin
19
+ execute_on_servers_without_capitate(options, &block)
20
+ rescue Capistrano::NoMatchingServersError => e
21
+ logger.important "`#{current_task.fully_qualified_name}' is only run for servers matching #{current_task.options.inspect}, but no servers matched"
22
+ end
23
+ end
24
+
25
+ # Set the user to something new (but save the old user; reset_user will set it back).
26
+ # Takes care of invalidating current connections. Will force a re-login.
27
+ #
28
+ # ==== Options
29
+ # +new_user+:: User to become
30
+ #
31
+ # ==== Examples
32
+ # set_user("nginx")
33
+ # # Do something as user nginx
34
+ #
35
+ def set_user(new_user)
36
+ previous_user = fetch(:user)
16
37
 
17
- return if previous_user == new_user
18
- set :previous_user, previous_user
38
+ return if previous_user == new_user
39
+ set :previous_user, previous_user
19
40
 
20
- set :user, new_user
21
- clear_sessions
22
- end
41
+ set :user, new_user
42
+ clear_sessions
43
+ end
23
44
 
24
- # Reset to the old user.
25
- # Takes care of invalidating current connections. Will force a re-login.
26
- #
27
- # ==== Examples
28
- # # User is "root"
29
- # set_user("nginx")
30
- # # Do something as user nginx
31
- # reset_user
32
- # # User is now root
33
- #
34
- def reset_user
35
- return unless exists?(:previous_user)
36
- set :user, fetch(:previous_user)
37
- unset :previous_user
38
- clear_sessions
39
- end
45
+ # Reset to the old user.
46
+ # Takes care of invalidating current connections. Will force a re-login.
47
+ #
48
+ # ==== Examples
49
+ # # User is "root"
50
+ # set_user("nginx")
51
+ # # Do something as user nginx
52
+ # reset_user
53
+ # # User is now root
54
+ #
55
+ def reset_user
56
+ return unless exists?(:previous_user)
57
+ set :user, fetch(:previous_user)
58
+ unset :previous_user
59
+ clear_sessions
60
+ end
40
61
 
41
- # Yields the previous user.
42
- #
43
- # ==== Options
44
- # +new_user+:: User to become
45
- #
46
- # ==== Examples
47
- # new_user("nginx") do |old_user|
48
- # # Do something as user nginx
49
- # end
50
- # # Now as user old_user
51
- #
52
- def with_user(new_user, &block)
53
- begin
54
- set_user(new_user)
55
- yield exists?(:previous_user) ? fetch(:previous_user) : nil
56
- ensure
57
- reset_user
58
- end
62
+ # Yields the previous user.
63
+ #
64
+ # ==== Options
65
+ # +new_user+:: User to become
66
+ #
67
+ # ==== Examples
68
+ # new_user("nginx") do |old_user|
69
+ # # Do something as user nginx
70
+ # end
71
+ # # Now as user old_user
72
+ #
73
+ def with_user(new_user, &block)
74
+ begin
75
+ set_user(new_user)
76
+ yield exists?(:previous_user) ? fetch(:previous_user) : nil
77
+ ensure
78
+ reset_user
79
+ end
59
80
 
60
- clear_sessions
61
- end
81
+ clear_sessions
82
+ end
62
83
 
63
- # Close all open sessions.
64
- # Will force user to re-login.
65
- def clear_sessions
66
- sessions.each do |key, session|
67
- logger.info "Closing: #{key}"
68
- session.close
69
- end
70
- sessions.clear
71
- reset_password
72
- end
84
+ # Close all open sessions.
85
+ # Will force user to re-login.
86
+ def clear_sessions
87
+ sessions.each do |key, session|
88
+ logger.info "Closing: #{key}"
89
+ session.close
90
+ end
91
+ sessions.clear
92
+ reset_password
93
+ end
73
94
 
74
- # Reset the password.
75
- # Display the current user that is asking for the password.
76
- def reset_password
77
- set :password, Proc.new {
78
- Capistrano::CLI.password_prompt("Password (for user: #{user}): ")
79
- }
80
- end
95
+ # Reset the password.
96
+ # Display the current user that is asking for the password.
97
+ def reset_password
98
+ set :password, Proc.new {
99
+ Capistrano::CLI.password_prompt("Password (for user: #{user}): ")
100
+ }
101
+ end
81
102
 
103
+ end
104
+ end
82
105
  end
83
106
 
84
107
  # Debug connections
@@ -87,9 +110,13 @@ class Capistrano::SSH
87
110
  class << self
88
111
 
89
112
  def connect_with_logging(server, options={}, &block)
90
- puts "=== Connecting to #{server} with user: #{options[:user]}"
113
+ @connect_mutex ||= Mutex.new
91
114
 
92
- connect_without_logging(server, options, &block)
115
+ @connect_mutex.synchronize do
116
+ puts "=== Connecting to #{server} with user: #{server.user || options[:user]}"
117
+ end
118
+
119
+ connect_without_logging(server, options, &block)
93
120
  end
94
121
 
95
122
  alias_method_chain :connect, :logging
@@ -2,7 +2,7 @@ module Capitate #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 2
5
- TINY = 5
5
+ TINY = 6
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
data/lib/capitate.rb CHANGED
@@ -32,7 +32,10 @@ class Capistrano::Configuration
32
32
  include Capitate::CapExt::Variables
33
33
  include Capitate::CapExt::RunVia
34
34
  include Capitate::CapExt::Roles
35
+ include Capitate::CapExt::Connections
35
36
  end
36
37
 
38
+ #module Capistrano::Configuration::Connections; end
39
+
37
40
  require 'capitate/task_node'
38
41
 
@@ -55,6 +55,7 @@ task :install do
55
55
  #
56
56
  nginx.monit.install
57
57
  mysql.monit.install
58
+ memcached.monit.install
58
59
 
59
60
  # Gem installs
60
61
  gems.install([ "rake", "mysql -- --with-mysql-include=/usr/include/mysql --with-mysql-lib=/usr/lib/mysql --with-mysql-config",
@@ -38,6 +38,9 @@ namespace :mongrel do
38
38
  end
39
39
 
40
40
  run "mkdir -p #{mongrel_config_dir}"
41
+
42
+ set :mongrel_pid_path, "#{mongrel_pid_dir}/#{mongrel_application}.pid"
43
+ set :mongrel_log_path, "log/#{mongrel_application}.log"
41
44
 
42
45
  put template.load("mongrel/mongrel_cluster.initd.erb"), "/tmp/#{mongrel_initscript_name}.initd"
43
46
  put template.load("mongrel/mongrel_cluster.yml.erb"), "#{mongrel_config_dir}/mongrel_cluster.yml"
@@ -47,20 +47,6 @@ namespace :monit do
47
47
  script.sh("monit/cert.sh")
48
48
  end
49
49
 
50
- desc <<-DESC
51
- Monit HUP.
52
-
53
- *monit_pid_path*: Path to monit pid.\n
54
- @set :monit_pid_path, "/var/run/monit.pid"@\n
55
- DESC
56
- task :restart do
57
-
58
- # Settings
59
- fetch_or_default(:monit_pid_path, "/var/run/monit.pid")
60
-
61
- sudo "kill -HUP `cat #{monit_pid_path}`"
62
- end
63
-
64
50
  end
65
51
 
66
52
  end
@@ -9,6 +9,7 @@ namespace :mongrel do
9
9
  Create monit configuration for mongrel cluster.
10
10
 
11
11
  *mongrel_application*: Name of application (monit group). _Defaults to <tt>"mongrel_cluster_\#{fetch(:application)}"</tt>_
12
+ *mongrel_bin_path*: Path to mongrel command. _Defaults to <tt>/usr/bin/mongrel_rails</tt>_
12
13
  *mongrel_size*: Number of mongrels.\n
13
14
  @set :mongrel_size, 3@\n
14
15
  *mongrel_port*: Starting port for mongrels. If there are 3 mongrels with port 9000, then instances
@@ -30,6 +31,7 @@ namespace :mongrel do
30
31
  fetch(:mongrel_size)
31
32
  fetch(:mongrel_port)
32
33
  fetch_or_default(:mongrel_application, Proc.new { "mongrel_cluster_#{fetch(:application)}" })
34
+ fetch_or_default(:mongrel_bin_path, "/usr/bin/mongrel_rails")
33
35
  fetch_or_default(:mongrel_config_script, nil)
34
36
  fetch_or_default(:monit_conf_dir, "/etc/monit")
35
37
 
@@ -37,7 +39,7 @@ namespace :mongrel do
37
39
  ports = (0...mongrel_size).collect { |i| mongrel_port + i }
38
40
  ports.each do |port|
39
41
 
40
- pid_path = "#{shared_path}/pids/mongrel.#{port}.pid"
42
+ pid_path = "#{shared_path}/pids/#{mongrel_application}.#{port}.pid"
41
43
 
42
44
  default_options = [
43
45
  [ "-d" ],
@@ -48,7 +50,7 @@ namespace :mongrel do
48
50
  [ "--group", user ],
49
51
  [ "-p", port ],
50
52
  [ "-P", pid_path ],
51
- [ "-l", "log/mongrel.#{port}.log" ]
53
+ [ "-l", "log/#{mongrel_application}.#{port}.log" ]
52
54
  ]
53
55
 
54
56
  default_options << [ "-S", mongrel_config_script ] if mongrel_config_script
@@ -57,7 +59,7 @@ namespace :mongrel do
57
59
  #start_options = "-d -e production -a 127.0.0.1 -c #{current_path} --user #{user} --group #{user} -p #{port} -P #{pid_path} -l log/mongrel.#{port}.log"
58
60
  stop_options = "-p #{port} -P #{pid_path}"
59
61
 
60
- processes << { :port => port, :start_options => start_options, :stop_options => stop_options, :name => "/usr/bin/mongrel_rails", :pid_path => pid_path }
62
+ processes << { :port => port, :start_options => start_options, :stop_options => stop_options, :name => mongrel_bin_path, :pid_path => pid_path }
61
63
  end
62
64
 
63
65
  set :processes, processes
@@ -0,0 +1,39 @@
1
+ namespace :monit do
2
+
3
+ desc <<-DESC
4
+ Restart (HUP) monit process.
5
+
6
+ HUP's the process from the pid file, if it exists.
7
+
8
+ *monit_pid_path*: Path to monit pid file. _Defaults to <tt>/var/run/monit.pid</tt>_
9
+ DESC
10
+ task :restart do
11
+ fetch_or_default(:monit_pid_path, "/var/run/monit.pid")
12
+
13
+ run_via %{sh -c "[ ! -e '#{monit_pid_path}' ] || kill -HUP `cat #{monit_pid_path}`"}
14
+
15
+ end
16
+
17
+ desc <<-DESC
18
+ Unmonitor all.
19
+
20
+ *monit_bin_path*: Path to monit bin. _Defaults to <tt>monit</tt>_
21
+ DESC
22
+ task :unmonitor_all do
23
+ fetch_or_default(:monit_bin_path, "monit")
24
+
25
+ run_via "#{monit_bin_path} unmonitor all"
26
+ end
27
+
28
+ desc <<-DESC
29
+ Monitor all.
30
+
31
+ *monit_bin_path*: Path to monit bin. _Defaults to <tt>monit</tt>_
32
+ DESC
33
+ task :monitor_all do
34
+ fetch_or_default(:monit_bin_path, "monit")
35
+
36
+ run_via "#{monit_bin_path} monitor all"
37
+ end
38
+
39
+ end
data/lib/recipes/mysql.rb CHANGED
@@ -38,7 +38,7 @@ namespace :mysql do
38
38
  *mysql_admin_password*: Mysql admin password (to use to connect). Defaults to password prompt.\n
39
39
  @set :mysql_admin_password, prompt.password('Mysql admin password: '))@
40
40
  DESC
41
- task :setup do
41
+ task :setup, :roles => :db do
42
42
 
43
43
  # Settings
44
44
  fetch(:db_name)
@@ -56,10 +56,14 @@ namespace :mysql do
56
56
  mysql_grant_locations << role.host
57
57
  end unless roles[role_name].blank?
58
58
  end
59
- set :mysql_grant_locations, mysql_grant_locations
60
- end
59
+ set :mysql_grant_locations, mysql_grant_locations.uniq!
60
+ end
61
+
62
+ sql = template.load("mysql/install_db.sql.erb")
63
+
64
+ logger.trace "Running sql:\n#{sql}"
61
65
 
62
- put template.load("mysql/install_db.sql.erb"), "/tmp/install_db_#{application}.sql"
66
+ put sql, "/tmp/install_db_#{application}.sql"
63
67
  run "mysql -u root -p#{mysql_admin_password} < /tmp/install_db_#{application}.sql"
64
68
  end
65
69
 
data/lib/recipes/nginx.rb CHANGED
@@ -25,7 +25,7 @@ namespace :nginx do
25
25
 
26
26
  namespace :mongrel do
27
27
  desc <<-DESC
28
- Create and update the nginx vhost include.
28
+ Generate the nginx vhost include (for a mongrel setup).
29
29
 
30
30
  *mongrel_application*: Mongrel application. _Defaults to <tt>:application</tt>_
31
31
  *mongrel_size*: Number of mongrels.\n
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  cwd: <%= current_path %>
3
- log_file: log/mongrel.log
3
+ log_file: <%= mongrel_log_path %>
4
4
  port: "<%= mongrel_port %>"
5
5
  environment: production
6
6
  address: 127.0.0.1
7
- pid_file: <%= mongrel_pid_dir %>/mongrel.pid
7
+ pid_file: <%= mongrel_pid_path %>
8
8
  servers: <%= mongrel_size %>
9
9
  user: <%= user %>
10
10
  group: <%= user %>
@@ -1,5 +1,4 @@
1
- <% mysql_grant_locations.each do |location| %>
2
- GRANT <%= mysql_grant_priv_type %> ON <%= db_name %>.* TO '<%= db_user %>'@'<%= location %>' IDENTIFIED BY '<%= db_pass %>';
1
+ <% mysql_grant_locations.each do |location| %>GRANT <%= mysql_grant_priv_type %> ON <%= db_name %>.* TO '<%= db_user %>'@'<%= location %>' IDENTIFIED BY '<%= db_pass %>';
3
2
  <% end %>
4
3
 
5
4
  CREATE DATABASE IF NOT EXISTS <%= db_name %>;
data/website/index.html CHANGED
@@ -38,7 +38,7 @@
38
38
 
39
39
  <div id="version" class="clickable box" onclick='document.location = "http://rubyforge.org/projects/capitate"; return false'>
40
40
  <p>Get Version</p>
41
- <a href="http://rubyforge.org/projects/capitate" class="numbers">0.2.5</a>
41
+ <a href="http://rubyforge.org/projects/capitate" class="numbers">0.2.6</a>
42
42
  </div>
43
43
 
44
44
  <div id="recipes">
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capitate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  platform: ""
6
6
  authors:
7
7
  - Gabriel Handford
@@ -135,6 +135,7 @@ files:
135
135
  - lib/recipes/docs.rb
136
136
  - lib/recipes/memcached.rb
137
137
  - lib/recipes/mongrel_cluster.rb
138
+ - lib/recipes/monit.rb
138
139
  - lib/recipes/mysql.rb
139
140
  - lib/recipes/nginx.rb
140
141
  - lib/recipes/rails.rb