threetee-capistrano-offroad 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +24 -0
- data/README +339 -0
- data/lib/capistrano-offroad.rb +8 -0
- data/lib/capistrano-offroad/modules/daemontools.rb +75 -0
- data/lib/capistrano-offroad/modules/defaults.rb +9 -0
- data/lib/capistrano-offroad/modules/django.rb +58 -0
- data/lib/capistrano-offroad/modules/monit.rb +51 -0
- data/lib/capistrano-offroad/modules/supervisord.rb +94 -0
- data/lib/capistrano-offroad/reset.rb +26 -0
- data/lib/capistrano-offroad/utils.rb +67 -0
- data/lib/capistrano-offroad/version.rb +14 -0
- metadata +98 -0
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2010, Maciej Pasternacki <maciej@pasternacki.net>
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
* Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
* Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
* Neither the name of the copyright holder nor the
|
12
|
+
names of its contributors may be used to endorse or promote products
|
13
|
+
derived from this software without specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
16
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL MACIEJ PASTERNACKI BE LIABLE FOR ANY
|
19
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
20
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
21
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
22
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
24
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README
ADDED
@@ -0,0 +1,339 @@
|
|
1
|
+
Capistrano-offroad
|
2
|
+
==================
|
3
|
+
|
4
|
+
Author: Maciej Pasternacki <maciej@pasternacki.net>
|
5
|
+
Date: 2010-05-28 Fri
|
6
|
+
|
7
|
+
|
8
|
+
Capistrano-offroad is a support package for using Capistrano with
|
9
|
+
non-rails projects. It contains basic reset of Rails-specific tasks,
|
10
|
+
a handful of utility functions, and modules with recipes.
|
11
|
+
|
12
|
+
Capistrano-offroad is available on terms of BSD license. See LICENSE
|
13
|
+
file for details.
|
14
|
+
|
15
|
+
Table of Contents
|
16
|
+
=================
|
17
|
+
1 Installation
|
18
|
+
1.1 System-wide installation
|
19
|
+
1.2 Project-local installation
|
20
|
+
2 Usage
|
21
|
+
3 Features
|
22
|
+
3.1 Reset
|
23
|
+
3.2 Utilities
|
24
|
+
3.2.1 `:run' dependency type
|
25
|
+
3.2.2 `set_from_env_or_ask'
|
26
|
+
3.2.3 `offroad_modules'
|
27
|
+
3.3 Version
|
28
|
+
3.3.1 `require_version'
|
29
|
+
3.4 Modules
|
30
|
+
3.4.1 defaults
|
31
|
+
3.4.2 django
|
32
|
+
3.4.3 supervisord
|
33
|
+
3.4.4 daemontools
|
34
|
+
3.4.5 monit
|
35
|
+
|
36
|
+
|
37
|
+
1 Installation
|
38
|
+
~~~~~~~~~~~~~~~
|
39
|
+
|
40
|
+
1.1 System-wide installation
|
41
|
+
=============================
|
42
|
+
|
43
|
+
Capistrano-offroad is available as a Ruby Gem, so in most cases you
|
44
|
+
should simply call:
|
45
|
+
|
46
|
+
gem install capistrano-offroad
|
47
|
+
|
48
|
+
This requires fairly recent version of Ruby gems (1.3.6 or later),
|
49
|
+
so it's possible you'll need to upgrade rubygems itself:
|
50
|
+
|
51
|
+
gem update --system
|
52
|
+
|
53
|
+
You can also download source code directly from Github page
|
54
|
+
[http://github.com/mpasternacki/capistrano-offroad] and install it by
|
55
|
+
rebuilding the gem manually.
|
56
|
+
|
57
|
+
1.2 Project-local installation
|
58
|
+
===============================
|
59
|
+
|
60
|
+
You can download source code from Github and use it as a Git
|
61
|
+
submodule, or just drop it into your code base in whatever way
|
62
|
+
suits you. Then, you should add to you Capfile the magic line
|
63
|
+
adding capistrano-offroad's `lib/' subdirectory to the require
|
64
|
+
path.
|
65
|
+
|
66
|
+
$:.unshift File.join( File.dirname(__FILE__), 'relative/path/to/capistrano-offroad/lib' )
|
67
|
+
|
68
|
+
2 Usage
|
69
|
+
~~~~~~~~
|
70
|
+
|
71
|
+
When you've got capistrano-offroad on your require path, whether
|
72
|
+
globally from a gem, or by extending require path, you simply
|
73
|
+
`require' it.
|
74
|
+
|
75
|
+
require 'capistrano-offroad'
|
76
|
+
|
77
|
+
For some reason, this line should appear *after* the
|
78
|
+
`set :application' declaration.
|
79
|
+
|
80
|
+
After that, you either `require' desired modules yourself, or use
|
81
|
+
`offroad_modules' helper function.
|
82
|
+
|
83
|
+
require 'capistrano-offroad/modules/defaults'
|
84
|
+
require 'capistrano-offroad/modules/django'
|
85
|
+
|
86
|
+
offroad_modules 'defaults', 'django'
|
87
|
+
|
88
|
+
3 Features
|
89
|
+
~~~~~~~~~~~
|
90
|
+
|
91
|
+
3.1 Reset
|
92
|
+
==========
|
93
|
+
By default, capistrano-offroad empties Rails-specific tasks:
|
94
|
+
`deploy:migrate', `deploy:start', `deploy:stop', `deploy:restart'.
|
95
|
+
|
96
|
+
The `:deploy:finalize_update' task is cut down to only run `chgrp'
|
97
|
+
and `chmod' when `:group_writable' setting is true. `chgrp'
|
98
|
+
behaviour can be modified by setting `:group_writable' to:
|
99
|
+
- `:no_chgrp' - don't run `chgrp' command
|
100
|
+
- `:sudo_chgrp' - use `sudo' to make sure `chgrp' has proper permissions
|
101
|
+
|
102
|
+
The setting `:shared_children' is set to an empty list. This gives
|
103
|
+
comfortable enough blank slate for working on non-rails projects,
|
104
|
+
without redefining all the workflow that is already present in
|
105
|
+
Capistrano.
|
106
|
+
|
107
|
+
3.2 Utilities
|
108
|
+
==============
|
109
|
+
By default, two extensions to Capistrano are defined.
|
110
|
+
|
111
|
+
3.2.1 `:run' dependency type
|
112
|
+
-----------------------------
|
113
|
+
Usage:
|
114
|
+
depend :remote, :run, "full shell command"=
|
115
|
+
|
116
|
+
When running `cap deploy:check', run the supplied shell command.
|
117
|
+
If its exit status is non-zero, the dependency has failed.
|
118
|
+
|
119
|
+
3.2.2 `set_from_env_or_ask'
|
120
|
+
----------------------------
|
121
|
+
Usage:
|
122
|
+
set_from_env_or_ask :setting_name, "Query prompt: "
|
123
|
+
|
124
|
+
If there is `SETTING_NAME' (uppercased first argument) in
|
125
|
+
environment (i.e. supplied from command line), set `:setting_name'
|
126
|
+
to value of this environment variable.
|
127
|
+
|
128
|
+
If the environment variable is not defined, ask user interactively
|
129
|
+
for a value, using query prompt supplied as a second argument.
|
130
|
+
|
131
|
+
3.2.3 `offroad_modules'
|
132
|
+
------------------------
|
133
|
+
Loads capistrano-offroad modules named as arguments. Convenience
|
134
|
+
function, so that user doesn't have to type `require' lines by himself.
|
135
|
+
|
136
|
+
3.3 Version
|
137
|
+
============
|
138
|
+
Three constants defining version of capistrano-offroad are defined:
|
139
|
+
|
140
|
+
CapistranoOffroad::VERSION::MAJOR
|
141
|
+
CapistranoOffroad::VERSION::MINOR
|
142
|
+
CapistranoOffroad::VERSION::TINY
|
143
|
+
|
144
|
+
Convenience string constant with full version number, separated
|
145
|
+
with dots, is provided:
|
146
|
+
|
147
|
+
CapistranoOffroad::VERSION::STRING
|
148
|
+
|
149
|
+
3.3.1 `require_version'
|
150
|
+
------------------------
|
151
|
+
A helper function, which can be used in Capfile to enforce a minimum
|
152
|
+
version of capistrano-offroad:
|
153
|
+
|
154
|
+
CapistranoOffroad::VERSION.require_version(major, minor=0, tiny=0)
|
155
|
+
|
156
|
+
3.4 Modules
|
157
|
+
============
|
158
|
+
Modules are packs of recipes and helpers for dealing with specific
|
159
|
+
software.
|
160
|
+
|
161
|
+
To load a module, either use the `require' function:
|
162
|
+
|
163
|
+
require 'capistrano-offroad/modules/module-name'
|
164
|
+
|
165
|
+
or use supplied `offroad_modules' helper function:
|
166
|
+
|
167
|
+
offroad_modules "foo", "bar", "baz", ...
|
168
|
+
|
169
|
+
When using a module, it is advised to at least browse through its
|
170
|
+
source to know what to expect.
|
171
|
+
|
172
|
+
Following modules are defined:
|
173
|
+
|
174
|
+
3.4.1 defaults
|
175
|
+
---------------
|
176
|
+
|
177
|
+
Contains my personal defaults for settings. For me it's part of
|
178
|
+
reset, but I moved it out to a separate module, because other
|
179
|
+
users may have different opinions. The settings are:
|
180
|
+
|
181
|
+
set :scm, :git
|
182
|
+
set :ssh_options, { :forward_agent => true }
|
183
|
+
set :use_sudo, false
|
184
|
+
set :deploy_to, "/srv/#{application}"
|
185
|
+
|
186
|
+
3.4.2 django
|
187
|
+
-------------
|
188
|
+
Settings, utilities and recipes for deploying [Django] projects.
|
189
|
+
|
190
|
+
[Django]: http://djangoproject.org/
|
191
|
+
|
192
|
+
* Settings
|
193
|
+
Following settings are defined.
|
194
|
+
+ :python
|
195
|
+
Python interpreter command. Defaults to "python".
|
196
|
+
|
197
|
+
Module also adds a dependency on this command to `deploy:check'.
|
198
|
+
+ :django_project_subdirectory
|
199
|
+
Directory in your repository that contains Django project (one
|
200
|
+
with the the `manage.py' file). Defaults to "project".
|
201
|
+
+ :django_use_south
|
202
|
+
Assume [South] is used for database migrations. Defaults to false.
|
203
|
+
|
204
|
+
[South]: http://south.aeracode.org/
|
205
|
+
|
206
|
+
+ :django_databases
|
207
|
+
This setting can be set to a list of database names (for
|
208
|
+
Django-1.2 multi-database support), against which Capistrano
|
209
|
+
will run syncdb/migrations. If unset or false, syncdb/migrations
|
210
|
+
will be run with default database only (as for pre-1.2 Django).
|
211
|
+
* Functions and utilities
|
212
|
+
django_manage cmd, options={}
|
213
|
+
Runs the `manage.py' command `cmd'. Optional keyword argument
|
214
|
+
`:path' provides path to a Capistrano release where the command
|
215
|
+
should be run. It defaults to `:latest_release'.
|
216
|
+
|
217
|
+
`:python_module' dependency type is defined to name Python
|
218
|
+
modules in `deploy:check' dependencies:
|
219
|
+
|
220
|
+
depend :remote, :python_module, "MySQLdb"
|
221
|
+
* Tasks
|
222
|
+
+ django:manage
|
223
|
+
Run custom Django management command in latest release.
|
224
|
+
|
225
|
+
Pass the management command and arguments in COMMAND="..."
|
226
|
+
variable. If COMMAND variable is not provided, Capistrano will
|
227
|
+
ask for a command.
|
228
|
+
|
229
|
+
+ deploy:migrate
|
230
|
+
Runs `manage.py syncdb' in the latest release. If
|
231
|
+
`:django_use_south' is true, it `--migrate' switch is used.
|
232
|
+
- TODO make it run in specified release, as vanilla Rails `deploy:migrate'
|
233
|
+
+ TODO separate `python' module
|
234
|
+
Stuff that is not Django-specific should be moved to a separate
|
235
|
+
`python' module that could be used with Python-related
|
236
|
+
non-Django projects. The `python' module would be automatically
|
237
|
+
loaded by `django' module.
|
238
|
+
|
239
|
+
|
240
|
+
3.4.3 supervisord
|
241
|
+
------------------
|
242
|
+
Control processes with [the supervisor daemon].
|
243
|
+
|
244
|
+
|
245
|
+
[the supervisor daemon]: http://supervisord.org/
|
246
|
+
|
247
|
+
* Settings
|
248
|
+
set :supervisord_path, "" # directory where supervisord binaries reside
|
249
|
+
set :supervisord_command, "supervisord"
|
250
|
+
set :supervisorctl_command, "supervisorctl"
|
251
|
+
set :supervisord_conf, "supervisord_conf"
|
252
|
+
set :supervisord_pidfile, "supervisord.pid"
|
253
|
+
set :supervisord_start_group, nil # process group to start on deploy:start - nil means all processes
|
254
|
+
set :supervisord_stop_group, nil # process group to stop on deploy:stop - nil means all processes
|
255
|
+
|
256
|
+
* Utilities
|
257
|
+
supervisorctl(cmd, options={})
|
258
|
+
Run a `supervisorctl' command specified as first argument. If
|
259
|
+
optional keyword argument `:try_start' is true (the default, you
|
260
|
+
may specify as false), start `supervisord' if not already
|
261
|
+
running.
|
262
|
+
|
263
|
+
* Tasks
|
264
|
+
+ Standard tasks
|
265
|
+
Stock Capistrano tasks `deploy:start', `deploy:stop',
|
266
|
+
`deploy:restart' are defined. They optionally accept `GROUP' or
|
267
|
+
`PROGRAM' environment variables, which can specify a single,
|
268
|
+
specific process group or a single process name to start, stop
|
269
|
+
or restart.
|
270
|
+
+ deploy:status
|
271
|
+
Runs `supervisorctl status'.
|
272
|
+
+ deploy:processes
|
273
|
+
Runs `pstree' with root in supervisord if supervisord is
|
274
|
+
running.
|
275
|
+
+ deploy:reload_supervisord
|
276
|
+
Reloads supervisor daemon's config. Starts it if not started.
|
277
|
+
+ deploy:run_supervisorctl
|
278
|
+
Runs supplied supervisorctl command. Command should be provided
|
279
|
+
in COMMAND variable; if no variable is provided,
|
280
|
+
capistrano-offroad will ask for the command.
|
281
|
+
|
282
|
+
|
283
|
+
3.4.4 daemontools
|
284
|
+
------------------
|
285
|
+
Recipes and settings for controlling processes with Dan
|
286
|
+
Bernstein's [daemontools]. It expects that `run' script lives in
|
287
|
+
top level of your repository.
|
288
|
+
|
289
|
+
*WARNING*: this is legacy code, used only in old projects and not
|
290
|
+
very well supported.
|
291
|
+
|
292
|
+
Also, this is probably not the best way to deal with the problem -
|
293
|
+
it would be easier to manage, start and restart with the `run'
|
294
|
+
script in the `:deploy_to' root, which would `cd' to `current' and
|
295
|
+
`exec ./run'. If anybody wants to write a patch to support that,
|
296
|
+
it would be great :)
|
297
|
+
|
298
|
+
[daemontools]: http://cr.yp.to/daemontools.html
|
299
|
+
|
300
|
+
* Settings
|
301
|
+
set :svscan_root, "/service"
|
302
|
+
set :supervise_name, "#{application}"
|
303
|
+
* Utilities
|
304
|
+
`svc' function runs `svc' with supplied arguments for the
|
305
|
+
supervised directory.
|
306
|
+
* Tasks
|
307
|
+
- `daemontools:create_symlink' - creates a symlink in `:svscan_root'
|
308
|
+
- `daemontools:remove_symlink' - removes symlink from
|
309
|
+
`:svscan_root' and stops the app
|
310
|
+
- `daemontools:status' - displays `svstat' output for current release
|
311
|
+
- `daemontools:relstatus' - displays `svstat' output for all
|
312
|
+
releases (use it after restart to make sure that previous
|
313
|
+
release has actually stopped)
|
314
|
+
- `deploy:start', `deploy:stop', `deploy:restart' - standard
|
315
|
+
Capistrano tasks
|
316
|
+
- `deploy:symlink' internal target is redefined; `on_rollback'
|
317
|
+
handler is currently broken
|
318
|
+
|
319
|
+
|
320
|
+
3.4.5 monit
|
321
|
+
------------
|
322
|
+
Module to run processes with monit.
|
323
|
+
*This is legacy, unsupported, unused code*. Use it (and monit) on
|
324
|
+
your own risk. I'm leaving it in only because the code is already
|
325
|
+
written and it would be waste to throw it away only because monit
|
326
|
+
sucks.
|
327
|
+
* Settings
|
328
|
+
set :monit_group, nil # process group to start/stop/reload
|
329
|
+
set :monit_command, "monit"
|
330
|
+
|
331
|
+
* Tasks
|
332
|
+
- `deploy:start', `deploy:stop', `deploy:restart' - standard
|
333
|
+
Capistrano tasks. They accept an extra optional variable
|
334
|
+
PROCESS which, if given, specifies a single process to start,
|
335
|
+
stop or restart. If PROCESS is not given, all processes (of
|
336
|
+
`:monit_group' group, if configured) are started/stopped/restarted.
|
337
|
+
- `deploy:status' - displays `monit summary' output
|
338
|
+
- `deploy:status:full' - displays `monit status' output
|
339
|
+
- `deploy:reload_monit' - reloads monit configuration
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Running via demontools
|
2
|
+
require 'capistrano'
|
3
|
+
|
4
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
5
|
+
set :svscan_root, "/service"
|
6
|
+
set :supervise_name, "#{application}"
|
7
|
+
|
8
|
+
def svc(cmd)
|
9
|
+
sudo "svc #{cmd} #{svscan_root}/#{supervise_name}"
|
10
|
+
end
|
11
|
+
|
12
|
+
namespace :daemontools do
|
13
|
+
desc "Create symlink in svscan directory"
|
14
|
+
task :create_symlink, :except => { :no_release => true } do
|
15
|
+
sudo "ln -s -v #{current_path} #{svscan_root}/#{supervise_name}"
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "[internal] Remove symlink from svscan directory"
|
19
|
+
task :do_remove_symlink, :except => { :no_release => true } do
|
20
|
+
sudo "rm -v #{svscan_root}/#{supervise_name}"
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Remove symlink from svscan directory and stop supervise"
|
24
|
+
task :remove_symlink, :except => { :no_release => true } do
|
25
|
+
do_remove_symlink
|
26
|
+
sudo "svc -x -t #{current_path}"
|
27
|
+
end
|
28
|
+
|
29
|
+
desc "Supervise status of current release"
|
30
|
+
task :status, :except => { :no_release => true } do
|
31
|
+
sudo "svstat #{svscan_root}/#{supervise_name}"
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Supervise status of all releases"
|
35
|
+
task :relstatus, :except => { :no_release => true } do
|
36
|
+
sudo "svstat #{releases_path}/*"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
namespace :deploy do
|
41
|
+
desc "Start service (svc -u)"
|
42
|
+
task :start, :except => { :no_release => true } do
|
43
|
+
svc "-u"
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Stop service (svc -d)"
|
47
|
+
task :stop, :except => { :no_release => true } do
|
48
|
+
svc "-d"
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "Restart service (svc -t)"
|
52
|
+
task :restart, :except => { :no_release => true } do
|
53
|
+
svc "-t"
|
54
|
+
end
|
55
|
+
|
56
|
+
desc <<-DESC
|
57
|
+
[internal] Symlink latest release to current, taking daemontools into accont.
|
58
|
+
|
59
|
+
WARNING: rollback is broken!
|
60
|
+
DESC
|
61
|
+
task :symlink, :except => { :no_release => true } do
|
62
|
+
on_rollback { run "rm -f #{current_path}; ln -s #{previous_release} #{current_path}; true" } # FIXME!
|
63
|
+
run "rm -f #{current_path}"
|
64
|
+
sleep 5
|
65
|
+
sudo "svc -t -x #{previous_release}"
|
66
|
+
run "ln -s #{latest_release} #{current_path}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
before "deploy:cleanup" do
|
71
|
+
# needed, by default I don't use sudo, but we need one to remove
|
72
|
+
# supervise/ directories.
|
73
|
+
set :run_method, :sudo
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# My defaults for deployment, may or may nat be useful for anyone else.
|
2
|
+
require 'capistrano'
|
3
|
+
|
4
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
5
|
+
set :scm, :git
|
6
|
+
set :ssh_options, { :forward_agent => true }
|
7
|
+
set :use_sudo, false
|
8
|
+
set :deploy_to, "/srv/#{application}"
|
9
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Django deployment
|
2
|
+
|
3
|
+
require 'capistrano'
|
4
|
+
|
5
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
6
|
+
|
7
|
+
set :python, "python"
|
8
|
+
|
9
|
+
set :django_project_subdirectory, "project"
|
10
|
+
set :django_use_south, false
|
11
|
+
set :django_databases, nil
|
12
|
+
|
13
|
+
depend :remote, :command, "#{python}"
|
14
|
+
|
15
|
+
def django_manage(cmd, options={})
|
16
|
+
path = options.delete(:path) || "#{latest_release}"
|
17
|
+
run "cd #{path}/#{django_project_subdirectory}; #{python} manage.py #{cmd}", options
|
18
|
+
end
|
19
|
+
|
20
|
+
namespace :django do
|
21
|
+
desc <<EOF
|
22
|
+
Run custom Django management command in latest release.
|
23
|
+
|
24
|
+
Pass the management command and arguments in COMMAND="..." variable.
|
25
|
+
If COMMAND variable is not provided, Capistrano will ask for a command.
|
26
|
+
EOF
|
27
|
+
task :manage, :except => { :no_release => true } do
|
28
|
+
set_from_env_or_ask :command, "Enter management command"
|
29
|
+
django_manage "#{command}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
namespace :deploy do
|
34
|
+
desc "Run manage.py syncdb in latest release."
|
35
|
+
task :migrate, :roles => :db, :only => { :primary => true } do
|
36
|
+
# FIXME: path, see default railsy deploy:migrate
|
37
|
+
m = if fetch(:django_use_south, false) then "--migrate" else "" end
|
38
|
+
if fetch(:django_databases, nil)
|
39
|
+
fetch(:django_databases, nil).each { |db|
|
40
|
+
django_manage "syncdb --noinput #{m} --database=#{db}"
|
41
|
+
}
|
42
|
+
else
|
43
|
+
django_manage "syncdb --noinput #{m}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# depend :remote, :python_module, "module_name"
|
49
|
+
# runs #{python} and tries to import module_name.
|
50
|
+
class Capistrano::Deploy::RemoteDependency
|
51
|
+
def python_module(module_name, options={})
|
52
|
+
@message ||= "Cannot import `#{module_name}'"
|
53
|
+
python = configuration.fetch(:python, "python")
|
54
|
+
try("#{python} -c 'import #{module_name}'", options)
|
55
|
+
self
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
|
3
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
4
|
+
set :monit_group, nil # process group to start/stop/reload
|
5
|
+
set :monit_command, "monit"
|
6
|
+
|
7
|
+
def _monit_args()
|
8
|
+
if fetch :monit_group, nil then
|
9
|
+
return " -g #{monit_group} "
|
10
|
+
else
|
11
|
+
return ""
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
namespace :deploy do
|
16
|
+
desc "Start processes"
|
17
|
+
task :start, :except => { :no_release => true } do
|
18
|
+
process = ENV['PROCESS'] || 'all'
|
19
|
+
sudo "#{monit_command} #{_monit_args} start #{process}"
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Stop processes"
|
23
|
+
task :stop, :except => { :no_release => true } do
|
24
|
+
process = ENV['PROCESS'] || 'all'
|
25
|
+
sudo "#{monit_command} #{_monit_args} stop #{process}"
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "Restart processes"
|
29
|
+
task :restart, :except => { :no_release => true } do
|
30
|
+
process = ENV['PROCESS'] || 'all'
|
31
|
+
sudo "#{monit_command} #{_monit_args} restart #{process}"
|
32
|
+
end
|
33
|
+
|
34
|
+
namespace :status do
|
35
|
+
desc "Status summary"
|
36
|
+
task :default, :except => { :no_release => true } do
|
37
|
+
sudo "#{monit_command} #{_monit_args} summary"
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "Full status"
|
41
|
+
task :full, :except => { :no_release => true } do
|
42
|
+
sudo "#{monit_command} #{_monit_args} status"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Reload monit"
|
47
|
+
task :reload_monit, :except => { :no_release => true } do
|
48
|
+
sudo "#{monit_command} reload"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
|
3
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
4
|
+
set :supervisord_path, "" # directory where supervisord binaries reside
|
5
|
+
set :supervisord_command, "supervisord"
|
6
|
+
set :supervisorctl_command, "supervisorctl"
|
7
|
+
set :supervisord_conf, "supervisord_conf"
|
8
|
+
set :supervisord_pidfile, "supervisord.pid"
|
9
|
+
set :supervisord_start_group, nil # process group to start on deploy:start - nil means all processes
|
10
|
+
set :supervisord_stop_group, nil # process group to stop on deploy:stop - nil means all processes
|
11
|
+
|
12
|
+
namespace :deploy do
|
13
|
+
def supervisord_pidfile_path ; "#{shared_path}/#{supervisord_pidfile}" end
|
14
|
+
def supervisord_pid ; "`cat #{supervisord_pidfile_path}`" end
|
15
|
+
|
16
|
+
# Run supervisorctl command `cmd'.
|
17
|
+
# If options[:try_start] is true (default) and supervisord is not running, start it.
|
18
|
+
# If just started supervisord, and options[:run_when_started] is false (default), skip running supervisorctl
|
19
|
+
def supervisorctl(cmd, options={})
|
20
|
+
try_start = options.delete(:try_start) {|k| true}
|
21
|
+
|
22
|
+
full_command = "#{supervisord_path}#{supervisorctl_command} -c #{current_path}/#{supervisord_conf} #{cmd}"
|
23
|
+
after_start = (full_command if options.delete(:run_when_started)) || ""
|
24
|
+
|
25
|
+
if not try_start then
|
26
|
+
run full_command, options
|
27
|
+
else
|
28
|
+
run <<-EOF, options
|
29
|
+
if test -f #{shared_path}/#{supervisord_pidfile}
|
30
|
+
&& ps #{supervisord_pid} > /dev/null ;
|
31
|
+
then
|
32
|
+
echo "supervisord seems to be up, good" ;
|
33
|
+
#{full_command} ;
|
34
|
+
else
|
35
|
+
echo "starting supervisord" ;
|
36
|
+
#{sudo :as => deploy_user} #{supervisord_path}#{supervisord_command} -c #{current_path}/#{supervisord_conf} ;
|
37
|
+
#{after_start}
|
38
|
+
fi
|
39
|
+
EOF
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def _target(var)
|
44
|
+
group_name = ENV['GROUP']
|
45
|
+
group_name ||= fetch var
|
46
|
+
prog_name = ENV['PROGRAM']
|
47
|
+
prog_name ||= 'all'
|
48
|
+
|
49
|
+
if ['', nil].include? group_name then
|
50
|
+
prog_name
|
51
|
+
else
|
52
|
+
"'#{group_name}:*'"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
desc "Start processes"
|
57
|
+
task :start, :except => { :no_release => true } do
|
58
|
+
to_start = _target(:supervisord_start_group)
|
59
|
+
supervisorctl "start #{to_start}", :try_start => true
|
60
|
+
end
|
61
|
+
|
62
|
+
desc "Stop processes"
|
63
|
+
task :stop, :except => { :no_release => true } do
|
64
|
+
to_stop = _target(:supervisord_stop_group)
|
65
|
+
supervisorctl "stop #{to_stop}", :try_start => false
|
66
|
+
end
|
67
|
+
|
68
|
+
desc "Restart processes"
|
69
|
+
task :restart, :except => { :no_release => true } do
|
70
|
+
to_restart = _target(:supervisord_start_group)
|
71
|
+
supervisorctl "restart #{to_restart}"
|
72
|
+
end
|
73
|
+
|
74
|
+
desc "Display status of processes"
|
75
|
+
task :status, :except => { :no_release => true } do
|
76
|
+
supervisorctl "status", :try_start => false
|
77
|
+
end
|
78
|
+
|
79
|
+
desc "Display detailed list of processes"
|
80
|
+
task :processes, :except => { :no_release => true } do
|
81
|
+
run "test -f #{supervisord_pidfile_path} && pstree -a #{supervisord_pid}"
|
82
|
+
end
|
83
|
+
|
84
|
+
desc "Reload supervisor daemon"
|
85
|
+
task :reload_supervisord, :except => { :no_release => true } do
|
86
|
+
supervisorctl "reload"
|
87
|
+
end
|
88
|
+
|
89
|
+
task :run_supervisorctl, :except => { :no_release => true } do
|
90
|
+
set_from_env_or_ask :command, "supervisorctl command: "
|
91
|
+
supervisorctl "#{command}", :try_start => false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Reset Rails-specific stuff.
|
2
|
+
|
3
|
+
require 'capistrano'
|
4
|
+
|
5
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
6
|
+
set :shared_children, %w()
|
7
|
+
|
8
|
+
namespace :deploy do
|
9
|
+
task :finalize_update, :except => { :no_release => true } do
|
10
|
+
if fetch(:group_writable, true)
|
11
|
+
if :no_chgrp == fetch(:group_writable, true)
|
12
|
+
# skip step
|
13
|
+
elsif :sudo_chgrp == fetch(:group_writable, true)
|
14
|
+
sudo "chgrp -R #{deploy_group} #{latest_release}"
|
15
|
+
else
|
16
|
+
run "chgrp -R #{deploy_group} #{latest_release}"
|
17
|
+
end
|
18
|
+
run "chmod -R g+w #{latest_release}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
task :migrate do end
|
22
|
+
task :start do end
|
23
|
+
task :stop do end
|
24
|
+
task :restart do end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Small extensions to Capistrano
|
2
|
+
|
3
|
+
require 'capistrano'
|
4
|
+
|
5
|
+
# depend :remote, :run, "whole command with args"
|
6
|
+
# runs command, if return code <> 0, dependency fails.
|
7
|
+
class Capistrano::Deploy::RemoteDependency
|
8
|
+
def run(command, options={})
|
9
|
+
@message ||= "Cannot run `#{command}'"
|
10
|
+
try(command, options)
|
11
|
+
self
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Capistrano::Configuration
|
16
|
+
# set_from_env_or_ask :variable, "Please enter variable name: "
|
17
|
+
# If there is VARIABLE in enviroment, set :variable to it, otherwise
|
18
|
+
# ask user for a value
|
19
|
+
def set_from_env_or_ask(sym, question)
|
20
|
+
if ENV.has_key? sym.to_s.upcase then
|
21
|
+
set sym, ENV[sym.to_s.upcase]
|
22
|
+
else
|
23
|
+
set sym do Capistrano::CLI.ui.ask question end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def delayed_warning(short, long=nil)
|
28
|
+
@_offroad_util_warnings ||= []
|
29
|
+
@_offroad_util_warnings.push short
|
30
|
+
puts <<EOF
|
31
|
+
|
32
|
+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
33
|
+
BIG FAT WARNING:
|
34
|
+
EOF
|
35
|
+
puts short
|
36
|
+
puts long if long
|
37
|
+
puts <<EOF
|
38
|
+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
39
|
+
|
40
|
+
EOF
|
41
|
+
end
|
42
|
+
|
43
|
+
def _offroad_emit_warnings()
|
44
|
+
if @_offroad_util_warnings
|
45
|
+
puts <<-"EOF"
|
46
|
+
|
47
|
+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
48
|
+
|
49
|
+
#{@_offroad_util_warnings.length} WARNING(S) LOGGED
|
50
|
+
READ VERY CAREFULLY, FOR I SHALL WRITE THIS ONLY ONCE
|
51
|
+
SCROLL UP FOR DETAILS
|
52
|
+
|
53
|
+
EOF
|
54
|
+
@_offroad_util_warnings.each { |w| puts " - #{w}" }
|
55
|
+
puts <<EOF
|
56
|
+
|
57
|
+
YOU HAVE BEEN WARNED
|
58
|
+
EOF
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
64
|
+
on :exit do
|
65
|
+
_offroad_emit_warnings
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module CapistranoOffroad
|
2
|
+
module VERSION
|
3
|
+
MAJOR = 0
|
4
|
+
MINOR = 1
|
5
|
+
TINY = 2
|
6
|
+
STRING = [MAJOR, MINOR, TINY].join('.')
|
7
|
+
|
8
|
+
def VERSION.require_version(major, minor=0, tiny=0)
|
9
|
+
unless ([MAJOR, MINOR, TINY] <=> [major, minor, tiny]) >= 0
|
10
|
+
raise Capistrano::Error, "capistrano-offroad version #{MAJOR}.#{MINOR}.#{TINY} is below required #{major}.#{minor}.#{tiny}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: threetee-capistrano-offroad
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 31
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Maciej Pasternacki
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-11-02 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: capistrano
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 11
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 5
|
33
|
+
- 8
|
34
|
+
version: 2.5.8
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
description: |
|
38
|
+
Capistrano-offroad is a support package for using Capistrano with
|
39
|
+
non-rails projects. It contains basic reset of Rails-specific tasks,
|
40
|
+
a handful of utility functions, and modules with recipes.
|
41
|
+
|
42
|
+
email: maciej@pasternacki.net
|
43
|
+
executables: []
|
44
|
+
|
45
|
+
extensions: []
|
46
|
+
|
47
|
+
extra_rdoc_files: []
|
48
|
+
|
49
|
+
files:
|
50
|
+
- lib/capistrano-offroad/modules/daemontools.rb
|
51
|
+
- lib/capistrano-offroad/modules/defaults.rb
|
52
|
+
- lib/capistrano-offroad/modules/django.rb
|
53
|
+
- lib/capistrano-offroad/modules/monit.rb
|
54
|
+
- lib/capistrano-offroad/modules/supervisord.rb
|
55
|
+
- lib/capistrano-offroad/reset.rb
|
56
|
+
- lib/capistrano-offroad/utils.rb
|
57
|
+
- lib/capistrano-offroad/version.rb
|
58
|
+
- lib/capistrano-offroad.rb
|
59
|
+
- README
|
60
|
+
- LICENSE
|
61
|
+
has_rdoc: true
|
62
|
+
homepage: http://github.com/mpasternacki/capistrano-offroad
|
63
|
+
licenses:
|
64
|
+
- BSD
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 3
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
hash: 23
|
85
|
+
segments:
|
86
|
+
- 1
|
87
|
+
- 3
|
88
|
+
- 6
|
89
|
+
version: 1.3.6
|
90
|
+
requirements: []
|
91
|
+
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 1.3.7
|
94
|
+
signing_key:
|
95
|
+
specification_version: 3
|
96
|
+
summary: Capistrano add-ons and recipes for non-rails projects
|
97
|
+
test_files: []
|
98
|
+
|