capistrano-runit-tasks 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +171 -0
- data/lib/capistrano-runit-tasks.rb +64 -0
- data/lib/runit_runner_helper.rb +32 -0
- metadata +56 -0
data/README
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
= Capistrano runit tasks
|
2
|
+
|
3
|
+
Adds tasks to Capistrano for use with the runit supervision scheme.
|
4
|
+
|
5
|
+
This library extends Capistrano to allow processes to be supervised using the
|
6
|
+
runit package. It replaces some of the standard tasks with runit versions and
|
7
|
+
includes tasks and helpers to create the service directory layout and populate
|
8
|
+
it with run scripts. It currently only supports fcgi listeners, but tries to
|
9
|
+
make it easy to add other services in your deploy.rb.
|
10
|
+
|
11
|
+
== Status
|
12
|
+
|
13
|
+
capistrano-runit-tests 0.1.0 (known as cap-runit from now on) is the first
|
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.
|
19
|
+
|
20
|
+
The current version assumes you have a runit setup similar to the one created
|
21
|
+
in http://www.defendem.com/read/chapter/5#page6, i.e. a supervised directory
|
22
|
+
where links can be created to get tasks monitored.
|
23
|
+
|
24
|
+
== Quick Start
|
25
|
+
|
26
|
+
This assumes you're creating a fresh install, not migrating an app from
|
27
|
+
spinner/spawner/reaper.
|
28
|
+
|
29
|
+
Install the package via gems or .tgz / .zip and setup.rb.
|
30
|
+
|
31
|
+
Include it in your deploy.rb with:
|
32
|
+
|
33
|
+
require 'capistrano-runit-tasks'
|
34
|
+
|
35
|
+
Then run:
|
36
|
+
|
37
|
+
* cap setup
|
38
|
+
* cap cold_deploy
|
39
|
+
|
40
|
+
This sets up one fcgi listener on port 8000. Make sure your database is setup
|
41
|
+
and point your webserver at the new listener.
|
42
|
+
|
43
|
+
== Usage
|
44
|
+
|
45
|
+
When you require 'runit-tasks' it replaces the following cap tasks with runit
|
46
|
+
versions:
|
47
|
+
|
48
|
+
* cold_deploy
|
49
|
+
* restart
|
50
|
+
* spinner
|
51
|
+
|
52
|
+
Then adds the following tasks, helpers and variables:
|
53
|
+
|
54
|
+
=== Tasks
|
55
|
+
|
56
|
+
[setup_service_dirs] Creates the skeleton directory structure for the services
|
57
|
+
|
58
|
+
[after_setup] Calls setup_service_dirs so they're created as part of
|
59
|
+
the standard cap setup
|
60
|
+
|
61
|
+
=== Variables
|
62
|
+
|
63
|
+
[service_dir] Change this if you want to change the name
|
64
|
+
of the service directory in the app on the server(s).
|
65
|
+
(Default: service)
|
66
|
+
|
67
|
+
[master_service_dir] Supervised directory where cap-runit will link the
|
68
|
+
service directories to to start the service.
|
69
|
+
(Default: ~/services)
|
70
|
+
|
71
|
+
[fcgi_count] Number of fcgi listener service dirs to create.
|
72
|
+
(Default: 1)
|
73
|
+
|
74
|
+
[fcgi_listener_base_port] The base port number to use for the fcgi listeners.
|
75
|
+
(Default: 8000)
|
76
|
+
|
77
|
+
cap-runit creates a directory for each listener you ask for. At the moment the
|
78
|
+
directories are created by setup_service_dirs. Later versions should allow for
|
79
|
+
dynamic creation / deletion.
|
80
|
+
|
81
|
+
The directories are named after the port number the fcgi listener will run on.
|
82
|
+
If you specified 8500 for the base port and 3 for the fcgi_count then
|
83
|
+
service/8500, service/8501 and service/8502 directories will be created and
|
84
|
+
populated with run scripts that launch the fcgis on the corresponding port.
|
85
|
+
|
86
|
+
When the service directories are linked into the master service dir to run,
|
87
|
+
they are named <application>-<port number>. So if :application is set to "foo"
|
88
|
+
in deploy.rb you'll get foo-8500, foo-8501 etc.
|
89
|
+
|
90
|
+
=== Helpers
|
91
|
+
|
92
|
+
[each_fcgi_listener] Uses the values for fcgi_listener_base_port and
|
93
|
+
fcgi_count to yield each of the fcgi port numbers back to
|
94
|
+
the calling block
|
95
|
+
|
96
|
+
[runner.create] Creates runner scripts, see the rdoc or comments above
|
97
|
+
the method for how it's used.
|
98
|
+
|
99
|
+
== Logging
|
100
|
+
|
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.
|
105
|
+
|
106
|
+
== Adding your own services
|
107
|
+
|
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:
|
111
|
+
|
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"
|
116
|
+
|
117
|
+
mailer_run_template = <<-TEMPLATE
|
118
|
+
#!/bin/sh -e
|
119
|
+
export RAILS_ENV=production
|
120
|
+
exec 2>&1 /usr/bin/env ruby <%= application_dir %>/current/script/mailer
|
121
|
+
TEMPLATE
|
122
|
+
|
123
|
+
runner.create :runner, mailer_service_dir,
|
124
|
+
mailer_run_template, :application_dir => deploy_to
|
125
|
+
runner.create :log, mailer_service_dir
|
126
|
+
end
|
127
|
+
|
128
|
+
task :after_spinner do
|
129
|
+
mailer_service_dir = "#{deploy_to}/#{service_dir}/mailer"
|
130
|
+
run "ln -sf #{mailer_service_dir} #{master_service_dir}/#{application}-mailer"
|
131
|
+
end
|
132
|
+
|
133
|
+
task :after_restart do
|
134
|
+
mailer_service_dir = "#{deploy_to}/#{service_dir}/mailer"
|
135
|
+
run "runsvctrl down #{mailer_service_dir}"
|
136
|
+
run "runsvctrl up #{mailer_service_dir}"
|
137
|
+
end
|
138
|
+
|
139
|
+
So the process is:
|
140
|
+
|
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.
|
147
|
+
|
148
|
+
== Switching from spinner/spawner/reaper
|
149
|
+
|
150
|
+
This again should be automated, the manual steps I used were:
|
151
|
+
|
152
|
+
* Modify deploy.rb and do a test deploy to a new directory on a different port
|
153
|
+
* Check the deploy worked ok
|
154
|
+
* Revert deploy.rb
|
155
|
+
* cap setup_service_dirs to create the structure (Won't touch what's running)
|
156
|
+
* Kill the spinner process
|
157
|
+
* use script/process/reaper to kill the running fcgis
|
158
|
+
* cap cold_deploy to start the service
|
159
|
+
* Check everything is running OK
|
160
|
+
|
161
|
+
== TODO
|
162
|
+
|
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
|
+
* Allow add_service to create more than one directory to be supervised
|
171
|
+
* Add task to automate switching from spinner
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'runit_runner_helper'
|
2
|
+
|
3
|
+
Capistrano.configuration(:must_exist).load do
|
4
|
+
set :service_dir, 'service'
|
5
|
+
set :fcgi_count, 1
|
6
|
+
set :master_service_dir, '~/services'
|
7
|
+
set :fcgi_listener_base_port, 8000
|
8
|
+
|
9
|
+
# We need our own task for this as the default cold_deploy
|
10
|
+
# calls restart, which won't work until we've setup the
|
11
|
+
# symlink, perhaps we could add a test to restart to check if the
|
12
|
+
# link exists, but that's beyond my current (very bad) shell-foo
|
13
|
+
desc "Used only for deploying when the services haven't been setup"
|
14
|
+
task :cold_deploy do
|
15
|
+
transaction do
|
16
|
+
update_code
|
17
|
+
symlink
|
18
|
+
end
|
19
|
+
spinner
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Sets up services directories for supervising fcgi using runit"
|
23
|
+
task :setup_service_dirs do
|
24
|
+
puts 'Creating service directories'
|
25
|
+
application_service_dir = "#{deploy_to}/#{service_dir}"
|
26
|
+
run "mkdir -p #{application_service_dir}"
|
27
|
+
|
28
|
+
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
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "Links created service dir into master service dir so runit starts the fcgi"
|
37
|
+
task :spinner do
|
38
|
+
each_fcgi_listener do |fcgi_listener_port|
|
39
|
+
fcgi_service_dir = "#{deploy_to}/#{service_dir}/#{fcgi_listener_port}"
|
40
|
+
run "ln -sf #{fcgi_service_dir} #{master_service_dir}/#{application}-#{fcgi_listener_port}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "restart task for runit supervised fcgis"
|
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
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "Hook into after setup to create the runit service directory"
|
55
|
+
task :after_setup do
|
56
|
+
setup_service_dirs
|
57
|
+
end
|
58
|
+
|
59
|
+
def each_fcgi_listener
|
60
|
+
fcgi_listener_base_port.upto(fcgi_listener_base_port + fcgi_count - 1) do |fcgi_listener_port|
|
61
|
+
yield fcgi_listener_port
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
|
3
|
+
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
|
22
|
+
when :log
|
23
|
+
template = LOG_TEMPLATE
|
24
|
+
else
|
25
|
+
template = FCGI_TEMPLATE if template == :fcgi
|
26
|
+
end
|
27
|
+
|
28
|
+
put render(options.merge(:template => template)), runner_path, :mode => 0700
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Capistrano.plugin :runner, RunitRunnerHelper
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: capistrano-runit-tasks
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.1.0
|
7
|
+
date: 2006-03-18 00:00:00 +00:00
|
8
|
+
summary: Adds tasks to capistrano for use with the runit supervision scheme.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: chris@octopod.info
|
12
|
+
homepage: http://cappy-runit.rubyforge.org
|
13
|
+
rubyforge_project: cappy-runit
|
14
|
+
description:
|
15
|
+
autorequire: capistrano-runit-tasks
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
signing_key:
|
28
|
+
cert_chain:
|
29
|
+
authors:
|
30
|
+
- Chris McGrath
|
31
|
+
files:
|
32
|
+
- lib/capistrano-runit-tasks.rb
|
33
|
+
- lib/runit_runner_helper.rb
|
34
|
+
- README
|
35
|
+
test_files: []
|
36
|
+
rdoc_options:
|
37
|
+
- "--title"
|
38
|
+
- Capistrano runit tasks documentation
|
39
|
+
- "--main"
|
40
|
+
- README
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
requirements: []
|
46
|
+
dependencies:
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: capistrano
|
49
|
+
version_requirement:
|
50
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
51
|
+
requirements:
|
52
|
+
-
|
53
|
+
- ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.1.0
|
56
|
+
version:
|