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 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: