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 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,7 @@
1
+ #!/usr/bin/env ruby
2
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/multiserver_whenever.rb')
3
+
4
+ env = ARGV.shift || 'production'
5
+ whenever = MultiserverWhenever.new(:environment => env)
6
+ whenever.clear!
7
+ whenever.write!
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/multiserver_wheneverizer.rb')
3
+
4
+ w = MultiserverWheneverizer.new
5
+ w.run!
@@ -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
@@ -0,0 +1,3 @@
1
+ ---
2
+ <%= hostname %>:
3
+ - example
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
+