capistrano-runit-tasks 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +17 -0
- data/README +55 -41
- data/lib/capistrano-runit-tasks-templates/default_fcgi_runner.rhtml +3 -0
- data/lib/capistrano-runit-tasks-templates/default_log_runner.rhtml +2 -0
- data/lib/capistrano-runit-tasks.rb +14 -13
- data/lib/runit_command_helper.rb +52 -0
- data/lib/runit_runner_helper.rb +70 -23
- data/lib/runit_service_helper.rb +65 -0
- metadata +9 -2
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.
|
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.
|
16
|
-
|
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
|
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
|
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:
|
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
|
-
[
|
97
|
-
|
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.
|
102
|
-
|
103
|
-
|
104
|
-
|
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
|
-
|
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
|
-
|
113
|
-
|
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
|
-
|
124
|
-
|
125
|
-
|
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
|
-
*
|
142
|
-
*
|
143
|
-
*
|
144
|
-
*
|
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
|
@@ -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, '~/
|
7
|
-
set :fcgi_listener_base_port,
|
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
|
-
|
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
|
-
|
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
|
data/lib/runit_runner_helper.rb
CHANGED
@@ -1,32 +1,79 @@
|
|
1
|
-
|
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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
#
|
16
|
-
#
|
17
|
-
|
18
|
-
|
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 =
|
24
|
-
|
25
|
-
|
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
|
-
|
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.
|
7
|
-
date: 2006-03-
|
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: []
|