capistrano-runit-tasks 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.
data/ChangeLog ADDED
@@ -0,0 +1,17 @@
1
+ *0.2.0* (March 23rd 2006)
2
+
3
+ * Added RunitServiceHelper which adds service.add to allow easy creation of
4
+ services. Refactored other code to use new functionality.
5
+
6
+ * Made runner.create handle file based templates, changed it's API slightly
7
+
8
+ * Added RunitCommandHelper, which adds an sv command to send signals to
9
+ services e.g. sv.up. Can set :sv_command to :sv or :runsvctrl to choose
10
+ which binary to run on there server
11
+
12
+ * Changed default master_service_dir to ~/service to match the defendem.com
13
+ instructions
14
+
15
+ * Changed default fcgi_listener_base_port to 9000
16
+
17
+ * Added tests for 0.1.0
data/README CHANGED
@@ -10,12 +10,10 @@ make it easy to add other services in your deploy.rb.
10
10
 
11
11
  == Status
12
12
 
13
- capistrano-runit-tests 0.1.0 (known as cap-runit from now on) is the first
13
+ capistrano-runit-tests 0.2.0 (known as cap-runit from now on) is the second
14
14
  release of the library. It will need more work to be useful to everybody who
15
- uses runit. The intention of releasing it now is to find out which areas need
16
- improvement first and get working on them. It's was developed and tested with
17
- the Debian sarge version of runit, 1.0.5 so currently uses runsvctrl rather
18
- than sv.
15
+ uses runit. It supports both the sv and runsvctrl/runsvstat versions of runit.
16
+ Support for daemontools svc command will be added at a later date.
19
17
 
20
18
  The current version assumes you have a runit setup similar to the one created
21
19
  in http://www.defendem.com/read/chapter/5#page6, i.e. a supervised directory
@@ -30,7 +28,7 @@ Install the package via gems or .tgz / .zip and setup.rb.
30
28
 
31
29
  Include it in your deploy.rb with:
32
30
 
33
- require 'capistrano-runit-tasks'
31
+ require "capistrano-runit-tasks"
34
32
 
35
33
  Then run:
36
34
 
@@ -42,8 +40,8 @@ and point your webserver at the new listener.
42
40
 
43
41
  == Usage
44
42
 
45
- When you require 'runit-tasks' it replaces the following cap tasks with runit
46
- versions:
43
+ When you require "capistrano-runit-tasks" it replaces the following cap tasks
44
+ with runit versions:
47
45
 
48
46
  * cold_deploy
49
47
  * restart
@@ -72,7 +70,13 @@ Then adds the following tasks, helpers and variables:
72
70
  (Default: 1)
73
71
 
74
72
  [fcgi_listener_base_port] The base port number to use for the fcgi listeners.
75
- (Default: 8000)
73
+ (Default: 9000)
74
+
75
+ [sv_command] Either :sv or :runsvctrl
76
+ (Default: sv)
77
+
78
+ [runner_template_path] The path to search for custom templates.
79
+ (Default: templates/runit)
76
80
 
77
81
  cap-runit creates a directory for each listener you ask for. At the moment the
78
82
  directories are created by setup_service_dirs. Later versions should allow for
@@ -93,36 +97,48 @@ in deploy.rb you'll get foo-8500, foo-8501 etc.
93
97
  fcgi_count to yield each of the fcgi port numbers back to
94
98
  the calling block
95
99
 
96
- [runner.create] Creates runner scripts, see the rdoc or comments above
97
- the method for how it's used.
100
+ [fcgi_listener_dirs] Returns an array containing the path to each of the fcgi
101
+ listener dirs. This is useful when sending commands using
102
+ sv as it accepts an array of directories as an argument
103
+
104
+ [service.add] Adds a new service to the application, see the
105
+ documentation in RunitServiceHelper for more
106
+
107
+ [sv.<signal>] Sends the signal given to services you choose. See the
108
+ documentation in RunitCommandHelper for more details.
109
+
110
+ [runner.create] Creates runner scripts, see the documentation in
111
+ RunitRunnerHelper method for how it's used.
98
112
 
99
113
  == Logging
100
114
 
101
- The default tasks create a log directory under each service directory. For
102
- your own services, this has do be done manually for now. The intention
103
- is to make it automatic and then allow the generic template to be overridden
104
- easily.
115
+ The default tasks create a log directory under each service directory. You can
116
+ override the default log template as described below if you need something
117
+ different.
118
+
119
+ == Overriding the default templates
120
+
121
+ The directory pointed to by the runner_template_path variable is searched
122
+ before the directory containing the default templates. If you want to override
123
+ the default templates, create default_fcgi_runner.rhtml and/or
124
+ default_log_runner.rhtml and cap-runit will pick your custom versions first.
105
125
 
106
126
  == Adding your own services
107
127
 
108
- To add your own service directories and run scripts, add
109
- after_setup_service_dirs, after_spinner and after_restart tasks to your
110
- deploy.rb that look something like these:
128
+ The example below assumes you are creating a service called mailer.
111
129
 
112
- task :after_setup_service_dirs do
113
- puts 'Creating mailer service directory'
114
- mailer_service_dir = "#{deploy_to}/#{service_dir}/mailer"
115
- run "mkdir -p #{mailer_service_dir}/log/main"
130
+ To add your own service directories and run scripts, add a template to
131
+ templates/runit called mailer_runner with contents:
116
132
 
117
- mailer_run_template = <<-TEMPLATE
118
133
  #!/bin/sh -e
119
134
  export RAILS_ENV=production
120
135
  exec 2>&1 /usr/bin/env ruby <%= application_dir %>/current/script/mailer
121
- TEMPLATE
122
136
 
123
- runner.create :runner, mailer_service_dir,
124
- mailer_run_template, :application_dir => deploy_to
125
- runner.create :log, mailer_service_dir
137
+ Then, in your deploy.rb create after_setup_service_dirs, after_spinner and
138
+ after_restart tasks that look something like these:
139
+
140
+ task :after_setup_service_dirs do
141
+ service.add 'mailer'
126
142
  end
127
143
 
128
144
  task :after_spinner do
@@ -138,12 +154,10 @@ deploy.rb that look something like these:
138
154
 
139
155
  So the process is:
140
156
 
141
- * make the service directory
142
- * create a rhtml template for your runner (string only for now, sorry)
143
- * create a runner from the template
144
- * create the logger
145
-
146
- This is will be wrapped in a helper function at the earliest opportunity.
157
+ * create the runner template (and logger if you need, see docs)
158
+ * add the service
159
+ * add a spinner task to get runit to start supervising
160
+ * add the tasks to stop and start as needed
147
161
 
148
162
  == Switching from spinner/spawner/reaper
149
163
 
@@ -160,12 +174,12 @@ This again should be automated, the manual steps I used were:
160
174
 
161
175
  == TODO
162
176
 
163
- * Make runner.create use file based templates
164
- * Intead of run "runsvctrl ..." have an sv helper method like sv :up, svc_dir
165
- * Setting for sv program to use, runsvctrl or sv
166
- * Automatically create log directories with custom templates
167
- * add_service(path, runner, logger = nil) helper function
168
- e.g. add_service(path, {:template => 'my_runner', :port => 1234})
169
- Which would set a custom runner and a standard logger
170
177
  * Allow add_service to create more than one directory to be supervised
171
- * Add task to automate switching from spinner
178
+ * Add task to automate switching from spinner
179
+ * Make which servers the code runs on configurable
180
+ * Make the rails env configurable
181
+ * Allow creation of other files such as log/config
182
+ * Add support for daemontools svc command
183
+ * Make the RAILS_ENV configurable
184
+ * Add helper methods to make linking the services into the master service
185
+ directory easier
@@ -0,0 +1,3 @@
1
+ #!/bin/sh -e
2
+ export RAILS_ENV=production
3
+ exec 2>&1 /usr/bin/env spawn-fcgi -n -f <%= deploy_to %>/current/public/dispatch.fcgi -p <%= fcgi_port %>
@@ -0,0 +1,2 @@
1
+ #!/bin/sh -e
2
+ exec svlogd -t ./main
@@ -1,10 +1,14 @@
1
1
  require 'runit_runner_helper'
2
+ require 'runit_command_helper'
3
+ require 'runit_service_helper'
2
4
 
3
5
  Capistrano.configuration(:must_exist).load do
4
6
  set :service_dir, 'service'
5
7
  set :fcgi_count, 1
6
- set :master_service_dir, '~/services'
7
- set :fcgi_listener_base_port, 8000
8
+ set :master_service_dir, '~/service'
9
+ set :fcgi_listener_base_port, 9000
10
+ set :sv_command, :sv # can be :sv or :runsvctrl
11
+ set :runner_template_path, File.join('templates', 'runit')
8
12
 
9
13
  # We need our own task for this as the default cold_deploy
10
14
  # calls restart, which won't work until we've setup the
@@ -21,15 +25,11 @@ Capistrano.configuration(:must_exist).load do
21
25
 
22
26
  desc "Sets up services directories for supervising fcgi using runit"
23
27
  task :setup_service_dirs do
24
- puts 'Creating service directories'
25
28
  application_service_dir = "#{deploy_to}/#{service_dir}"
26
29
  run "mkdir -p #{application_service_dir}"
27
30
 
28
31
  each_fcgi_listener do |fcgi_listener_port|
29
- fcgi_service_dir = "#{application_service_dir}/#{fcgi_listener_port}"
30
- run "mkdir -p #{fcgi_service_dir}/log/main"
31
- runner.create :runner, fcgi_service_dir, :fcgi, :application_dir => deploy_to, :fcgi_port => fcgi_listener_port
32
- runner.create :log, fcgi_service_dir
32
+ service.add fcgi_listener_port, :template => :fcgi, :fcgi_port => fcgi_listener_port
33
33
  end
34
34
  end
35
35
 
@@ -43,12 +43,7 @@ Capistrano.configuration(:must_exist).load do
43
43
 
44
44
  desc "restart task for runit supervised fcgis"
45
45
  task :restart do
46
- each_fcgi_listener do |fcgi_listener_port|
47
- fcgi_service_dir = "#{deploy_to}/#{service_dir}/#{fcgi_listener_port}"
48
-
49
- # Signal USR2 is what reaper does
50
- run "runsvctrl 2 #{fcgi_service_dir}"
51
- end
46
+ sv.usr2 fcgi_listener_dirs
52
47
  end
53
48
 
54
49
  desc "Hook into after setup to create the runit service directory"
@@ -61,4 +56,10 @@ Capistrano.configuration(:must_exist).load do
61
56
  yield fcgi_listener_port
62
57
  end
63
58
  end
59
+
60
+ def fcgi_listener_dirs
61
+ dirs = []
62
+ each_fcgi_listener { |port| dirs << "#{deploy_to}/#{service_dir}/#{port}" }
63
+ dirs
64
+ end
64
65
  end
@@ -0,0 +1,52 @@
1
+ begin
2
+ require 'capistrano'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'capistrano'
6
+ end
7
+
8
+ # This module provides a facade to allow signals to be set to runit managed
9
+ # service directories from Capistrano. It uses the <tt>sv_command</tt> variable to decide
10
+ # which command to run on the server and currently supports both <tt>sv</tt> and <tt>runsvctrl</tt>.
11
+ #
12
+ # The <tt>:sv_command</tt> variable can be set to <tt>:sv</tt> or <tt>:runsvctrl</tt> to choose.
13
+ #
14
+ # The supported signals are shown in the <tt>SIGNALS</tt> constant below.
15
+ #
16
+ # Usage examples:
17
+ # * <tt>sv.usr2 "/path/to/service/dir"</tt>
18
+ # * <tt>sv.down ["foo1", "foo2"]</tt>
19
+ #
20
+ # As daemontools is very similar, support for that will be added at a later date.
21
+ #
22
+ # The methods are available through sv.<method name> in your deploy.rb
23
+ module RunitCommandHelper
24
+ SIGNALS = %w(up down once pause cont hup alarm interrupt quit usr1 usr2 term kill status)
25
+
26
+ SIGNALS.each do |signal|
27
+ if signal =~ /usr([1|2])/ then
28
+ cmd = $1
29
+ else
30
+ cmd = signal
31
+ end
32
+
33
+ define_method(signal) do |service_dirs|
34
+ service_dirs = service_dirs.join(" ") if service_dirs.is_a? Array
35
+ run "#{get_command(signal, cmd)} #{service_dirs}"
36
+ end
37
+ end
38
+
39
+ protected
40
+ def get_command(signal, cmd)
41
+ case configuration.sv_command
42
+ when :sv
43
+ "sv #{cmd}"
44
+ when :runsvctrl
45
+ signal == 'status' ? 'runsvstat' : "runsvctrl #{cmd}"
46
+ else
47
+ raise "Error: sv_command setting of #{configuration.sv_command} is unsupported"
48
+ end
49
+ end
50
+ end
51
+
52
+ Capistrano.plugin :sv, RunitCommandHelper
@@ -1,32 +1,79 @@
1
- require 'capistrano'
1
+ begin
2
+ require 'capistrano'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'capistrano'
6
+ end
2
7
 
8
+ # This module provides methods to ease creating run scripts in service directories.
9
+ #
10
+ # The methods are available through runner.<method name> in your deploy.rb
3
11
  module RunitRunnerHelper
4
- FCGI_TEMPLATE = <<-TEMPLATE
5
- #!/bin/sh -e
6
- export RAILS_ENV=production
7
- exec 2>&1 /usr/bin/env spawn-fcgi -n -f <%= application_dir %>/current/public/dispatch.fcgi -p <%= fcgi_port %>
8
- TEMPLATE
9
-
10
- LOG_TEMPLATE = <<-TEMPLATE
11
- #!/bin/sh -e
12
- exec svlogd -t ./main
13
- TEMPLATE
14
-
15
- # Wrapper to render a file from a string template (file template not supported yet)
16
- # and put it on the server at the given path. The file permissions are set to 0700.
17
- # options are passed through to the call to render.
18
- # runner_type can be :log or :runner
19
- def create(runner_type, path, template = nil, options = {})
20
- runner_path = "#{path}#{runner_type == :log ? '/log/run' : '/run'}"
21
- case runner_type
12
+ # Creates a runner from a template, puts it on the server at the given
13
+ # path and sets file permissions to 0700.
14
+ #
15
+ # * service_dir should be the path to your service directory, it should not
16
+ # include run or log/run, these are added by create.
17
+ # * template can be :log, :fcgi, the name of a file or a string.
18
+ # :log and :fcgi create the standard logger/fcgi templates,
19
+ # see get_template below for a list of places searched for template files.
20
+ # * If you're making a custom log runner, include :log_runner => true in the
21
+ # options so create knows to put the contents in service_dir/log/run, you
22
+ # don't need this if you're using the standard :log template.
23
+ # * options except for :log_runner are assumed to be for the template and
24
+ # are passed through to render.
25
+ def create(service_dir, template, options = {})
26
+ case template
22
27
  when :log
23
- template = LOG_TEMPLATE
24
- else
25
- template = FCGI_TEMPLATE if template == :fcgi
28
+ template = 'default_log_runner'
29
+ options.merge!(:log_runner => true)
30
+ when :fcgi
31
+ template = 'default_fcgi_runner'
26
32
  end
27
33
 
28
- put render(options.merge(:template => template)), runner_path, :mode => 0700
34
+ path = "#{service_dir}/#{options[:log_runner] ? 'log/run' : 'run'}"
35
+ options.delete(:log_runner)
36
+
37
+ options = add_default_options(options)
38
+
39
+ runner = render options.merge(:template => get_template(template))
40
+
41
+ put runner, path, :mode => 0700
29
42
  end
43
+
44
+ # Works out whether the given template is a file or string containing rhtml.
45
+ #
46
+ # Checks:
47
+ # * current directory
48
+ # * runner_templates path (defaults to templates/runit)
49
+ # * capistrano-runit-tasks-templates dir where cappy-runit is installed
50
+ # (the standard templates are here)
51
+ #
52
+ # If it can't find the file it assumes it's a one line string template and
53
+ # returns that
54
+ def get_template(template)
55
+ if template =~ /<%/ or template =~ /\n/
56
+ template
57
+ else
58
+ [ ".",
59
+ configuration.runner_template_path,
60
+ File.join(File.dirname(__FILE__), 'capistrano-runit-tasks-templates')
61
+ ].each do |dir|
62
+ if File.file?(File.join(dir, template))
63
+ return File.read(File.join(dir, template))
64
+ elsif File.file?(File.join(dir, template + ".rhtml"))
65
+ @file_template_full_path = File.join(dir, template + ".rhtml")
66
+ return File.read(File.join(dir, template + ".rhtml"))
67
+ end
68
+ end
69
+ end
70
+ template
71
+ end
72
+
73
+ protected
74
+ def add_default_options(options)
75
+ {:deploy_to => configuration.deploy_to}.merge(options)
76
+ end
30
77
  end
31
78
 
32
79
  Capistrano.plugin :runner, RunitRunnerHelper
@@ -0,0 +1,65 @@
1
+ begin
2
+ require 'capistrano'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'capistrano'
6
+ end
7
+
8
+ require 'runit_runner_helper'
9
+
10
+ # This module provides an easy method to create service directories in your application and have them
11
+ # populated with runner scripts.
12
+ #
13
+ # The methods are available through service.<method name> in your deploy.rb
14
+ module RunitServiceHelper
15
+ # Adds a service to the applications service directory and creates run and log/run scripts
16
+ #
17
+ # If no runner or logger options are passed, looks for a runner template called <service_name>_runner
18
+ # and a log runner template called <service_name>_log_runner. These should be in the templates directory set
19
+ # with runner_template_path in your deploy.rb.
20
+ #
21
+ # * If the runner template does not exist an exception will be raised
22
+ # * If the logger template does not exist the standard logger template will be used.
23
+ #
24
+ # If you want to use your own template or a string containing rhtml pass a :template option to the appropriate
25
+ # options hash.
26
+ #
27
+ # The default options will be passed through to the template as described in RunitRunnerHelper#create
28
+ def add(service_name, runner_options = {}, logger_options = {})
29
+ make_service_dir service_name
30
+ create_service(service_name, runner_options)
31
+ create_service(service_name, logger_options.merge(:log_runner => true))
32
+ end
33
+
34
+ # Returns the full path to the service directory given a service name.
35
+ # Doesn't check the service name is valid.
36
+ def service_dir(service_name)
37
+ "#{configuration.deploy_to}/#{configuration.service_dir}/#{service_name}"
38
+ end
39
+
40
+ protected
41
+ def create_service(service_name, options)
42
+ if options[:template].nil?
43
+ runner_template_path = options[:log_runner] ? "#{service_name.to_s}_log_runner" : "#{service_name.to_s}_runner"
44
+ runner_template = runner.get_template(runner_template_path)
45
+ if runner_template == runner_template_path # didn't find a template
46
+ if options[:log_runner]
47
+ # Just use the standard template
48
+ runner_template = :log
49
+ else
50
+ raise "Couldn't find runner template #{runner_template_path} and no runner template provided"
51
+ end
52
+ end
53
+ else
54
+ runner_template = options[:template]
55
+ end
56
+ options.delete(:template)
57
+ runner.create service_dir(service_name), runner_template, options
58
+ end
59
+
60
+ def make_service_dir(service_name)
61
+ run "mkdir -p #{service_dir(service_name)}/log/main"
62
+ end
63
+ end
64
+
65
+ Capistrano.plugin :service, RunitServiceHelper
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: capistrano-runit-tasks
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.0
7
- date: 2006-03-18 00:00:00 +00:00
6
+ version: 0.2.0
7
+ date: 2006-03-23 00:00:00 +00:00
8
8
  summary: Adds tasks to capistrano for use with the runit supervision scheme.
9
9
  require_paths:
10
10
  - lib
@@ -29,9 +29,15 @@ cert_chain:
29
29
  authors:
30
30
  - Chris McGrath
31
31
  files:
32
+ - lib/capistrano-runit-tasks-templates
32
33
  - lib/capistrano-runit-tasks.rb
34
+ - lib/runit_command_helper.rb
33
35
  - lib/runit_runner_helper.rb
36
+ - lib/runit_service_helper.rb
37
+ - lib/capistrano-runit-tasks-templates/default_fcgi_runner.rhtml
38
+ - lib/capistrano-runit-tasks-templates/default_log_runner.rhtml
34
39
  - README
40
+ - ChangeLog
35
41
  test_files: []
36
42
  rdoc_options:
37
43
  - "--title"
@@ -40,6 +46,7 @@ rdoc_options:
40
46
  - README
41
47
  extra_rdoc_files:
42
48
  - README
49
+ - ChangeLog
43
50
  executables: []
44
51
  extensions: []
45
52
  requirements: []