multiserver_whenever 0.1.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/LICENSE +20 -0
- data/README.rdoc +94 -0
- data/bin/multiserver_whenever +7 -0
- data/bin/multiserver_wheneverize +5 -0
- data/lib/multiserver_whenever.rb +89 -0
- data/lib/multiserver_wheneverizer.rb +35 -0
- data/templates/config/whenever/do_not_remove.rb +24 -0
- data/templates/config/whenever/example.rb +20 -0
- data/templates/config/whenever.yml +3 -0
- metadata +91 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Chris Powers
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
= Multiserver Whenever
|
2
|
+
|
3
|
+
<em>Created by Chris Powers 12/7/2010</em>
|
4
|
+
|
5
|
+
Provides the <tt>multiserver_whenever</tt> command for generating host-specific
|
6
|
+
crontabs with role-based whenever files. This is very handy for when you need
|
7
|
+
to deploy different crontabs to different staging/production servers, but still
|
8
|
+
want to leverage the <tt>whenever</tt> gem's DSL and build tools.
|
9
|
+
|
10
|
+
Learn all about the original <tt>whenever</tt> gem at https://github.com/javan/whenever.
|
11
|
+
|
12
|
+
|
13
|
+
== Installation
|
14
|
+
|
15
|
+
Just install the <tt>multiserver_whenever</tt> gem per usual:
|
16
|
+
|
17
|
+
gem install multiserver_whenever
|
18
|
+
|
19
|
+
|
20
|
+
== Generating Document Structure with MultiserverWheneverize
|
21
|
+
|
22
|
+
Taking off of the <tt>whenever</tt> gem's <tt>wheneverize</tt>, this gem provides
|
23
|
+
the <tt>multiserver_wheneverize</tt> command to generate the initial file structure:
|
24
|
+
|
25
|
+
cd /path/to/your_app
|
26
|
+
multiserver_wheneverize
|
27
|
+
|
28
|
+
The generated file structure looks like:
|
29
|
+
|
30
|
+
- your_app/
|
31
|
+
- config/
|
32
|
+
- whenever.yml
|
33
|
+
- whenever/
|
34
|
+
- do_not_remove.rb
|
35
|
+
- example.rb
|
36
|
+
|
37
|
+
|
38
|
+
== Configuration
|
39
|
+
|
40
|
+
The <tt>config/whenever.yml</tt> file is a hash where the keys are server hostnames and
|
41
|
+
the values are arrays of "roles".
|
42
|
+
|
43
|
+
Let's say that I have two servers with hostnames <tt>app_server</tt> and <tt>db_server</tt>.
|
44
|
+
I need to set app-related crontabs on <tt>app_server</tt>, db-related crontabs on
|
45
|
+
<tt>db_server</tt> and some shared crontabs on both. To do this, I will first create three
|
46
|
+
whenever files in <tt>config/whenever</tt>:
|
47
|
+
|
48
|
+
- your_app/
|
49
|
+
- config/
|
50
|
+
- whenever.yml
|
51
|
+
- whenever/
|
52
|
+
- app.rb
|
53
|
+
- db.rb
|
54
|
+
- do_not_remove.rb
|
55
|
+
- shared.rb
|
56
|
+
|
57
|
+
The contents of each of these files is regular <tt>whenever</tt> code (see https://github.com/javan/whenever).
|
58
|
+
|
59
|
+
Then in our <tt>config/whenever.yml</tt> file we map our hostnames to the cron roles:
|
60
|
+
|
61
|
+
---
|
62
|
+
app_server:
|
63
|
+
- app
|
64
|
+
- shared
|
65
|
+
db_server:
|
66
|
+
- db
|
67
|
+
- shared
|
68
|
+
|
69
|
+
Now when you run the <tt>multiserver_whenever</tt> command on one of your servers, it will
|
70
|
+
only apply the <tt>whenever</tt> files that are specified in your <tt>config/whenever.yml</tt>
|
71
|
+
file.
|
72
|
+
|
73
|
+
|
74
|
+
== Running <tt>multiserver_whenever</tt>
|
75
|
+
|
76
|
+
If you are using the whenever <tt>rake</tt> and <tt>runner</tt> commands, you may need to
|
77
|
+
specify a Rails environment. It defaults to using <tt>production</tt>, but you can simply
|
78
|
+
pass a different environment to the <tt>multiserver_whenever</tt> command instead:
|
79
|
+
|
80
|
+
multiserver_whenever staging
|
81
|
+
|
82
|
+
|
83
|
+
== Deployment with Capistrano
|
84
|
+
|
85
|
+
In your Capistrano deployment code, you should be able to add something like this to run
|
86
|
+
<tt>multiserver_whenever</tt> on deployment:
|
87
|
+
|
88
|
+
namespace :whenever do
|
89
|
+
desc "Update your whenever-generated crontabs"
|
90
|
+
task :update do
|
91
|
+
run "cd #{release_path}; multiserver_whenever #{rails_env}"
|
92
|
+
end
|
93
|
+
after "deploy:update", "whenever:update"
|
94
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class MultiserverWhenever
|
4
|
+
def initialize(set_vars = {})
|
5
|
+
defaults = {:environment => 'production'}
|
6
|
+
@set_vars = defaults.merge(set_vars)
|
7
|
+
end
|
8
|
+
|
9
|
+
def clear!
|
10
|
+
current_whenever_identifiers.each do |identifier|
|
11
|
+
whenever_with_vars "--load-file #{dummy_whenever_path} --clear-crontab #{identifier}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def write!
|
16
|
+
roles.each do |role|
|
17
|
+
relative_path = "config/whenever/#{role}.rb"
|
18
|
+
absolute_path = File.expand_path(relative_path)
|
19
|
+
whenever_with_vars "--load-file #{relative_path} --update-crontab #{absolute_path}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def current_whenever_identifiers
|
24
|
+
@identifiers ||= parse_identifiers
|
25
|
+
end
|
26
|
+
|
27
|
+
def read_cron
|
28
|
+
command("crontab -l")
|
29
|
+
end
|
30
|
+
|
31
|
+
def roles
|
32
|
+
[config[hostname]].flatten.compact
|
33
|
+
end
|
34
|
+
|
35
|
+
def config
|
36
|
+
@config ||= YAML.load(read_config)
|
37
|
+
end
|
38
|
+
|
39
|
+
def read_config
|
40
|
+
File.read("config/whenever.yml")
|
41
|
+
end
|
42
|
+
|
43
|
+
def hostname
|
44
|
+
command('hostname')
|
45
|
+
end
|
46
|
+
|
47
|
+
# So for some reason, the whenever command requires that the
|
48
|
+
# --load-file argument be passed, even if you are using the
|
49
|
+
# --clear-crontab argument to clear out outdated crontabs.
|
50
|
+
#
|
51
|
+
# The problem is that you may need to clear out old crontab
|
52
|
+
# data from cron that was generated by a whenever file that
|
53
|
+
# no longer exists, so you can't use it for the --load-file
|
54
|
+
# argument. As it's unnecessary anyways, I'm just going to use
|
55
|
+
# the config/whenever/do_not_remove.rb file anytime we're
|
56
|
+
# clearing crontabs out. It's an "empty" file, but we need
|
57
|
+
# to keep it around.
|
58
|
+
#
|
59
|
+
def dummy_whenever_path
|
60
|
+
"config/whenever/do_not_remove.rb"
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse_identifiers
|
64
|
+
lines = read_cron.split("\n")
|
65
|
+
lines = lines.select {|line| line =~ /^# Begin Whenever/ }
|
66
|
+
lines.map {|line| line.gsub("# Begin Whenever generated tasks for: ", '') }
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def whenever_with_vars(opts)
|
72
|
+
unless @set_vars.empty?
|
73
|
+
query_string = @set_vars.inject([]) {|arr, tuple| arr << "#{tuple.first}=#{tuple.last}"}.join("&")
|
74
|
+
opts << " --set #{query_string}"
|
75
|
+
end
|
76
|
+
whenever(opts)
|
77
|
+
end
|
78
|
+
|
79
|
+
def whenever(opts)
|
80
|
+
cmd = "whenever #{opts}"
|
81
|
+
puts cmd
|
82
|
+
%x{#{cmd}}
|
83
|
+
end
|
84
|
+
|
85
|
+
def command(cmd)
|
86
|
+
%x{#{cmd}}.strip
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
class MultiserverWheneverizer
|
5
|
+
def run!
|
6
|
+
write_config!
|
7
|
+
copy_whenever_files!
|
8
|
+
end
|
9
|
+
|
10
|
+
def write_config!
|
11
|
+
FileUtils.mkdir_p("config")
|
12
|
+
File.open("config/whenever.yml", 'w') { |f| f.puts custom_config }
|
13
|
+
end
|
14
|
+
|
15
|
+
def copy_whenever_files!
|
16
|
+
FileUtils.mkdir_p("config/whenever")
|
17
|
+
FileUtils.cp_r("#{gem_root}/templates/config/whenever/.", "config/whenever")
|
18
|
+
end
|
19
|
+
|
20
|
+
def custom_config
|
21
|
+
ERB.new(File.read("#{gem_root}/templates/config/whenever.yml")).result(binding)
|
22
|
+
end
|
23
|
+
|
24
|
+
def hostname
|
25
|
+
`hostname`.strip
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def gem_root
|
31
|
+
@gem_root ||= File.expand_path File.dirname(File.dirname(__FILE__))
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# HERE BE DRAGONS!
|
2
|
+
#
|
3
|
+
# ___====-_ _-====___
|
4
|
+
# __--^^^ // \\ ^^^--_
|
5
|
+
# _-^ // ( ) \\ ^-_
|
6
|
+
# - // |\^^/| \\ -
|
7
|
+
# _/ // (0::0) \\ \_
|
8
|
+
# / (( \\// )) \
|
9
|
+
# - \\ (oo) // -
|
10
|
+
# - \\ / \/ \ // -
|
11
|
+
# - \\/ \// -
|
12
|
+
# / /| /\ ( ) /\ |\ \
|
13
|
+
# |/ | /\_/\_/\_/ \_/\ ( /\ ) /\_/ \_/\_/\_/\ | \|
|
14
|
+
# ` |/ V V ` V \_(| | | |)_/ V ' V V \| '
|
15
|
+
# ` ` ` ` / | | | | \ ' ' ' '
|
16
|
+
# <( | | | | )>
|
17
|
+
# <__\_| | | |_\__>
|
18
|
+
# ^^^^ ^^^ ^^^ ^^^^^
|
19
|
+
#
|
20
|
+
# Seriously, though, please don't delete this file. It is required
|
21
|
+
# for MultiserverWhenever.clear! to work correctly. See the file
|
22
|
+
# lib/multiserver_whenever.rb for more information.
|
23
|
+
#
|
24
|
+
# Or just stay here and admire the dragon.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Use this file to easily define all of your cron jobs.
|
2
|
+
#
|
3
|
+
# It's helpful, but not entirely necessary to understand cron before proceeding.
|
4
|
+
# http://en.wikipedia.org/wiki/Cron
|
5
|
+
|
6
|
+
# Example:
|
7
|
+
#
|
8
|
+
# set :output, "/path/to/my/cron_log.log"
|
9
|
+
#
|
10
|
+
# every 2.hours do
|
11
|
+
# command "/usr/bin/some_great_command"
|
12
|
+
# runner "MyModel.some_method"
|
13
|
+
# rake "some:great:rake:task"
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# every 4.days do
|
17
|
+
# runner "AnotherModel.prune_old_records"
|
18
|
+
# end
|
19
|
+
|
20
|
+
# Learn more: http://github.com/javan/whenever
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: multiserver_whenever
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Chris Powers
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-12-07 00:00:00 -06:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: whenever
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 6
|
33
|
+
- 2
|
34
|
+
version: 0.6.2
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
description: Provides the multiserver_whenever command for generating host-specific crontabs with role-based whenever files.
|
38
|
+
email: chrisjpowers@gmail.com
|
39
|
+
executables:
|
40
|
+
- multiserver_whenever
|
41
|
+
- multiserver_wheneverize
|
42
|
+
extensions: []
|
43
|
+
|
44
|
+
extra_rdoc_files: []
|
45
|
+
|
46
|
+
files:
|
47
|
+
- README.rdoc
|
48
|
+
- LICENSE
|
49
|
+
- lib/multiserver_whenever.rb
|
50
|
+
- lib/multiserver_wheneverizer.rb
|
51
|
+
- templates/config/whenever.yml
|
52
|
+
- templates/config/whenever/do_not_remove.rb
|
53
|
+
- templates/config/whenever/example.rb
|
54
|
+
- bin/multiserver_whenever
|
55
|
+
- bin/multiserver_wheneverize
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://github.com/chrisjpowers/multiserver_whenever
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 3
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
hash: 3
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.3.7
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Provides the multiserver_whenever command for generating host-specific crontabs with role-based whenever files.
|
90
|
+
test_files: []
|
91
|
+
|