warehouse_supervisor 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ *.swp
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ log/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in warehouse_supervisor.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Diego Guerra
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # Warehouse Supervisor
2
+
3
+ Easily create [supervisor](http://supervisord.org/) configuration files and run them in dev mode.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'warehouse_supervisor'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install warehouse_supervisor
18
+
19
+ ## Usage
20
+
21
+ There are 2 basic commands:
22
+
23
+ ### print
24
+
25
+ warehouse_supervisor print -g production -c config.yml processes.conf.erb
26
+
27
+ This will print your config file according to config.yml and processes.conf.erb
28
+
29
+ ### start
30
+
31
+ warehouse_supervisor start -g production -c config.yml processes.conf.erb
32
+
33
+ This will start a supervisor instance running in the foreground with the config you specified
34
+
35
+ Both these commands take the following options:
36
+
37
+ * --group | -g: Group to use
38
+ * --config | -c: Definition file
39
+ * --log-dir | -q (only in `start`): Log directory
40
+
41
+ ## Files
42
+
43
+ Warehouse Supervisor needs 2 files to work:
44
+
45
+ - Templates file
46
+ - Definitions file
47
+
48
+ ### Templates file
49
+
50
+ This is an erb file where you'll define the different *program templates* that your app uses, for example:
51
+
52
+ <% template :resque_web do %>
53
+ user = <%= user || ENV["USER"] %>
54
+ directory = <%=dir || ENV["RAILS_ROOT"]%>
55
+ command = bundle exec resque-web -F -L -p 5678 config/resque_config.rb
56
+ environment = HOME='<%=home || ENV["HOME"]%>',USER=<%=user || ENV["USER"]%>
57
+ <% end %>
58
+
59
+ Each program template that you need will be define in a `template` block.
60
+
61
+ ### Definitions file
62
+
63
+ This is a yml file where you can define the *programs* that supervisor will run. For example:
64
+
65
+ development:
66
+ resque_web:
67
+ template: resque_web
68
+ dir: "/my/dir"
69
+
70
+ It defines groups of programs and for each one defines the template to be used and the variables
71
+ that each program requires.
72
+
73
+ For each program Warehouse Supervisor will compile its template with the provided variables, and it'll add this to
74
+ the output. This way you may use generic templates to define similar programs.
75
+
76
+ For a full example of both files check the examples dir.
77
+
78
+
79
+ ## Contributing
80
+
81
+ 1. Fork it
82
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
83
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
84
+ 4. Push to the branch (`git push origin my-new-feature`)
85
+ 5. Create new Pull Request
86
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,5 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'lib/warehouse_supervisor/warehouse_supervisor_cli'
4
+
5
+ WarehouseSupervisor::WarehouseSupervisorCli.start(ARGV)
@@ -0,0 +1,25 @@
1
+ <% template :worker do %>
2
+ user = <%= user || ENV["USER"] %>
3
+ command = bundle exec rake environment resque:work
4
+ environment = QUEUE='<%=queues.join(",")%>',HOME='<%=home || ENV["HOME"]%>',USER=<%=user || ENV["USER"]%>, RAILS_ENV=<%=rails_env || ENV["RAILS_ENV"]%>, VERBOSE=1
5
+ directory = <%=dir || ENV["RAILS_ROOT"]%>
6
+ numprocs = <%=num_procs || 1%>
7
+ process_name = %(program_name)s_%(process_num)d
8
+ redirect_stderr = true
9
+ stdout_logfile = log/%(program_name)s_%(process_num)d
10
+ <% end %>
11
+
12
+ <% template :scheduler do %>
13
+ user = <%= user || ENV["USER"] %>
14
+ command = bundle exec rake resque:scheduler
15
+ directory = <%=dir || ENV["RAILS_ROOT"]%>
16
+ environment = HOME='<%=home || ENV["HOME"]%>',USER=<%=user || ENV["USER"]%>, RAILS_ENV=<%=rails_env || ENV["RAILS_ENV"]%>, VERBOSE=1
17
+ <% end %>
18
+
19
+ <% template :resque_web do %>
20
+ user = <%= user || ENV["USER"] %>
21
+ directory = <%=dir || ENV["RAILS_ROOT"]%>
22
+ command = bundle exec resque-web -F -L -p 5678 config/resque_config.rb
23
+ environment = HOME='<%=home || ENV["HOME"]%>',USER=<%=user || ENV["USER"]%>, RAILS_ENV=<%=rails_env || ENV["RAILS_ENV"]%>, VERBOSE=1
24
+ <% end %>
25
+
@@ -0,0 +1,32 @@
1
+ development:
2
+ resque_workers:
3
+ template: worker
4
+ queues:
5
+ - high
6
+ - medium
7
+ - low
8
+ num_procs: 1
9
+ resque_scheduler:
10
+ template: scheduler
11
+ resque_web:
12
+ template: resque_web
13
+ dir: awesome
14
+
15
+ production:
16
+ high_resque_workers:
17
+ template: worker
18
+ queues:
19
+ - high
20
+ num_procs: 2
21
+ all_resque_workers:
22
+ template: worker
23
+ queues:
24
+ - high
25
+ - medium
26
+ - low
27
+ resque_scheduler:
28
+ template: scheduler
29
+ resque_web:
30
+ template: resque_web
31
+
32
+
@@ -0,0 +1,5 @@
1
+ require "warehouse_supervisor/version"
2
+
3
+ module WarehouseSupervisor
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,18 @@
1
+ require 'erb'
2
+ require 'warehouse_supervisor/template_binding'
3
+
4
+ module WarehouseSupervisor
5
+ class ProgramRenderer
6
+
7
+ def initialize(definitions, erb_content)
8
+ @definitions = definitions
9
+ @erb_content = erb_content
10
+ end
11
+
12
+ def render(program_name)
13
+ program_definition = TemplateBinding.new(program_name, @definitions[program_name])
14
+ ERB.new(@erb_content, nil, nil, "@output").result(program_definition.get_binding).gsub(/^$\n/, "").gsub(/^[\s]+/, "")
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,16 @@
1
+ require 'warehouse_supervisor/program_renderer'
2
+
3
+ module WarehouseSupervisor
4
+ class Renderer
5
+ def initialize(definitions, erb_content)
6
+ @definitions = definitions
7
+ @erb_content = erb_content
8
+ end
9
+
10
+ def render
11
+ r = ProgramRenderer.new(@definitions, @erb_content)
12
+ @definitions.keys.map { |program_name| r.render(program_name) }.join("\n")
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ module WarehouseSupervisor
2
+
3
+ class TemplateBinding
4
+ def initialize(program_name, hash)
5
+ @program_name = program_name
6
+ @template = hash["template"]
7
+ singleton = class << self; self end
8
+ hash.each do |method_name, value|
9
+ singleton.send(:define_method, method_name) {value} unless method_name == "template"
10
+ end
11
+ end
12
+
13
+ def template(t)
14
+ if @template == t.to_s
15
+ @output << "[program:#{@program_name}]"
16
+ yield
17
+ end
18
+ end
19
+
20
+ def method_missing(*args)
21
+ nil
22
+ end
23
+
24
+ def get_binding
25
+ binding
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ module WarehouseSupervisor
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,47 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'yaml'
4
+ require 'tempfile'
5
+ require 'fileutils'
6
+ require 'thor'
7
+ require 'warehouse_supervisor/renderer'
8
+
9
+ module WarehouseSupervisor
10
+ class WarehouseSupervisorCli < Thor
11
+ class_option :group, :aliases => :g, :default => "development"
12
+ class_option :config, :aliases => :c, :required => true
13
+
14
+ desc "print file", "output the file acording to the config"
15
+ def print(erb_file)
16
+ puts generate_contents(options[:group], options[:config], erb_file)
17
+ end
18
+
19
+ desc "start file", "start an undemonized supervisor with file"
20
+ option :log_dir, :aliases => :q, :default => "log"
21
+ def start(erb_file)
22
+ Tempfile.open("supervisord.conf") do |f|
23
+ log_dir = options[:log_dir]
24
+ f.puts "[supervisord]"
25
+ f.puts "logfile = #{File.join(log_dir, "supervisord.log")}"
26
+ f.puts "childlogdir = #{log_dir}"
27
+ f.puts "nodaemon = true"
28
+ f.puts
29
+ f.write generate_contents(options[:group], options[:config], erb_file)
30
+ f.flush
31
+ FileUtils.mkdir_p options[:log_dir]
32
+ command = "supervisord -c '#{f.path}'"
33
+ puts command
34
+ exec command
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def generate_contents(group, definitions_file, erb_file)
41
+ definitions = YAML.load(File.read(definitions_file))[group.to_s]
42
+ erb_content = File.read(erb_file)
43
+ Renderer.new(definitions, erb_content).render
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,37 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'yaml'
4
+ require 'warehouse_supervisor/program_renderer'
5
+
6
+ include WarehouseSupervisor
7
+
8
+ describe ProgramRenderer do
9
+
10
+ let(:erb_content) {File.read "example/processes.conf.erb"}
11
+ let(:definitions) {YAML.load(File.read "example/warehouse_supervisor.yml")}
12
+
13
+ it "should render the title once" do
14
+ pr = ProgramRenderer.new(definitions["development"], erb_content).render("resque_web")
15
+ pr.scan(/\[program:resque_web\]/).should have(1).element
16
+ end
17
+
18
+ it "should not render other templates" do
19
+ pr = ProgramRenderer.new(definitions["development"], erb_content).render("resque_web")
20
+ pr.should_not =~ /worker/
21
+ end
22
+
23
+ it "should render the variables" do
24
+ pr = ProgramRenderer.new(definitions["development"], erb_content).render("resque_web")
25
+ pr.should =~ /directory = awesome/
26
+ end
27
+
28
+ it "should have a pretty output" do
29
+ pr = ProgramRenderer.new(definitions["development"], erb_content).render("resque_web")
30
+ pr.should_not include "\n\n"
31
+ end
32
+
33
+ it "should remove starting spaces" do
34
+ pr = ProgramRenderer.new(definitions["development"], erb_content).render("resque_web")
35
+ pr.should_not include "^\s+"
36
+ end
37
+ end
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'yaml'
4
+ require 'warehouse_supervisor/renderer'
5
+
6
+ include WarehouseSupervisor
7
+
8
+ describe Renderer do
9
+ let(:erb_content) {File.read "example/processes.conf.erb"}
10
+ let(:definitions) {YAML.load(File.read "example/warehouse_supervisor.yml")}
11
+
12
+ it "should render the full file" do
13
+ c = Renderer.new(definitions["development"], erb_content).render
14
+ c.scan(/\[program:resque_web\]/).should have(1).element
15
+ c.scan(/\[program:resque_workers\]/).should have(1).element
16
+ c.scan(/\[program:resque_scheduler\]/).should have(1).element
17
+ end
18
+
19
+
20
+ end
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'yaml'
4
+ require 'warehouse_supervisor/template_binding'
5
+
6
+ include WarehouseSupervisor
7
+
8
+ describe TemplateBinding do
9
+
10
+ it "should define methods" do
11
+ t = TemplateBinding.new("tal", "cosa" => "otra")
12
+ t.cosa.should eql "otra"
13
+ end
14
+
15
+ it "should not redefine template" do
16
+ t = TemplateBinding.new("tal", "cosa" => "otra", "template" => "tala")
17
+ expect {t.template}.to raise_error
18
+ end
19
+
20
+ it "should not break on non-existing methods" do
21
+ t = TemplateBinding.new("tal", "cosa" => "otra", "template" => "tala")
22
+ t.otrassss.should be_nil
23
+ end
24
+
25
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'warehouse_supervisor/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "warehouse_supervisor"
8
+ gem.version = WarehouseSupervisor::VERSION
9
+ gem.authors = ["Diego Guerra"]
10
+ gem.email = ["diego.guerra.suarez@gmail.com"]
11
+ gem.description = %q{Easily create and run supervisord configuration files}
12
+ gem.summary = gem.description
13
+ gem.homepage = "https://github.com/dgsuarez/warehouse_supervisor"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'rake'
21
+ gem.add_dependency 'thor'
22
+ gem.add_development_dependency 'rspec'
23
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: warehouse_supervisor
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Diego Guerra
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-04-28 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rake
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: thor
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ type: :development
61
+ version_requirements: *id003
62
+ description: Easily create and run supervisord configuration files
63
+ email:
64
+ - diego.guerra.suarez@gmail.com
65
+ executables:
66
+ - warehouse_supervisor
67
+ extensions: []
68
+
69
+ extra_rdoc_files: []
70
+
71
+ files:
72
+ - .gitignore
73
+ - Gemfile
74
+ - LICENSE.txt
75
+ - README.md
76
+ - Rakefile
77
+ - bin/warehouse_supervisor
78
+ - example/processes.conf.erb
79
+ - example/warehouse_supervisor.yml
80
+ - lib/warehouse_supervisor.rb
81
+ - lib/warehouse_supervisor/program_renderer.rb
82
+ - lib/warehouse_supervisor/renderer.rb
83
+ - lib/warehouse_supervisor/template_binding.rb
84
+ - lib/warehouse_supervisor/version.rb
85
+ - lib/warehouse_supervisor/warehouse_supervisor_cli.rb
86
+ - spec/warehouse_supervisor/program_renderer_spec.rb
87
+ - spec/warehouse_supervisor/renderer_spec.rb
88
+ - spec/warehouse_supervisor/template_binding_spec.rb
89
+ - warehouse_supervisor.gemspec
90
+ homepage: https://github.com/dgsuarez/warehouse_supervisor
91
+ licenses: []
92
+
93
+ post_install_message:
94
+ rdoc_options: []
95
+
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ hash: 3
104
+ segments:
105
+ - 0
106
+ version: "0"
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ hash: 3
113
+ segments:
114
+ - 0
115
+ version: "0"
116
+ requirements: []
117
+
118
+ rubyforge_project:
119
+ rubygems_version: 1.8.21
120
+ signing_key:
121
+ specification_version: 3
122
+ summary: Easily create and run supervisord configuration files
123
+ test_files:
124
+ - spec/warehouse_supervisor/program_renderer_spec.rb
125
+ - spec/warehouse_supervisor/renderer_spec.rb
126
+ - spec/warehouse_supervisor/template_binding_spec.rb