proctor 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Proctorfile +4 -0
- data/README.md +97 -2
- data/Rakefile +15 -1
- data/bin/proctor +92 -88
- data/lib/proctor/app_config.rb +23 -0
- data/lib/proctor/app_file.rb +40 -1
- data/lib/proctor/cmd_state.rb +39 -0
- data/lib/proctor/manager.rb +8 -2
- data/lib/proctor/presenter/list.rb +67 -0
- data/lib/proctor/presenter/render.rb +39 -0
- data/lib/proctor/presenter/show.rb +71 -0
- data/lib/proctor/service.rb +8 -0
- data/lib/proctor/template_config.rb +22 -0
- data/lib/proctor/template_file.rb +44 -0
- data/lib/proctor/version.rb +1 -1
- data/lib/proctor.rb +1 -1
- data/proctor/Proctorfile +44 -20
- data/proctor/templates/foreman_default_n.erb +9 -0
- data/proctor/templates/monit_default_s.erb +6 -0
- data/proctor/templates/monit_faye_s.erb +7 -0
- data/{lib/proctor/app_global.rb → proctor/templates/monit_web_s.erb} +0 -0
- data/{lib/proctor/config_global.rb → proctor/templates/upstart_default_n.erb} +0 -0
- data/proctor/templates/upstart_default_s.erb +7 -0
- data/proctor/templates/upstart_faye_s.erb +9 -0
- data/proctor/{managers/MonitDefault.rb → templates/upstart_passenger_s.erb} +0 -0
- data/proctor.gemspec +2 -0
- data/spec/acceptance/help_spec.rb +17 -1
- data/spec/acceptance/list_spec.rb +17 -0
- data/spec/spec_helper.rb +7 -4
- data/spec/support/aruba.rb +2 -2
- data/spec/unit/app_config_spec.rb +30 -0
- data/spec/unit/app_file_spec.rb +36 -5
- data/spec/unit/manager_spec.rb +16 -7
- data/spec/unit/service_spec.rb +20 -0
- data/spec/unit/template_config_spec.rb +12 -0
- data/spec/unit/template_file_spec.rb +16 -0
- data/spec/unit/template_spec.rb +3 -2
- metadata +61 -25
- data/lib/proctor/config_file.rb +0 -5
- data/lib/proctor/export.rb +0 -5
- data/lib/proctor/job.rb +0 -4
- data/proctor/managers/MonitFaye.rb +0 -0
- data/proctor/managers/MonitWeb.rb +0 -0
- data/proctor/managers/UpstartDefault.rb +0 -0
- data/proctor/managers/UpstartFaye.rb +0 -0
- data/proctor/managers/UpstartWeb.rb +0 -0
- data/proctor/templates/monit_default.erb +0 -0
- data/proctor/templates/monit_faye.erb +0 -0
- data/proctor/templates/monit_web.erb +0 -0
- data/proctor/templates/upstart_default.erb +0 -0
- data/proctor/templates/upstart_faye.erb +0 -0
- data/proctor/templates/upstart_web.erb +0 -0
- data/spec/unit/config_file_spec.rb +0 -9
- data/spec/unit/export_spec.rb +0 -9
- data/spec/unit/job_spec.rb +0 -9
@@ -0,0 +1,71 @@
|
|
1
|
+
module Proctor
|
2
|
+
module Presenter
|
3
|
+
class Show
|
4
|
+
|
5
|
+
def initialize(global, options, args)
|
6
|
+
@global = global
|
7
|
+
@options = options
|
8
|
+
@args = args
|
9
|
+
validate_handle(args[0])
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate_handle(handle)
|
13
|
+
if handle.length != 3
|
14
|
+
raise "invalid handle (#{handle}) see 'proctor list for a valid handle'"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def xhandle(string)
|
19
|
+
Digest::MD5.hexdigest(string)[0..2]
|
20
|
+
end
|
21
|
+
|
22
|
+
def find_asset(handle)
|
23
|
+
|
24
|
+
result = @options[:templates].values.find {|x| xhandle(x) == handle}
|
25
|
+
return ['template', result] unless result.nil?
|
26
|
+
|
27
|
+
result = AppConfig.app_files(@global).find {|x| xhandle(x) == handle}
|
28
|
+
return ['appfile', result] unless result.nil?
|
29
|
+
|
30
|
+
result = @options[:app_config]['managers'].keys.find {|x| xhandle(x) == handle}
|
31
|
+
return ['manager', result] unless result.nil?
|
32
|
+
|
33
|
+
result = @options[:app_config]['services'].keys.find {|x| xhandle(x) == handle}
|
34
|
+
return ['service', result] unless result.nil?
|
35
|
+
|
36
|
+
raise "unknown handle (#{handle}) see 'proctor list' for a valid handle"
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
def show
|
41
|
+
type, asset = find_asset(@args[0])
|
42
|
+
|
43
|
+
case type
|
44
|
+
when "template" then show_template(asset)
|
45
|
+
when "appfile" then show_appfile(asset)
|
46
|
+
when "manager" then show_manager(asset)
|
47
|
+
when "service" then show_service(asset)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def show_template(asset)
|
52
|
+
puts "# Template #{asset}"
|
53
|
+
puts File.read(asset)
|
54
|
+
end
|
55
|
+
|
56
|
+
def show_appfile(asset)
|
57
|
+
puts "# AppFile #{asset}"
|
58
|
+
puts File.read(asset)
|
59
|
+
end
|
60
|
+
|
61
|
+
def show_manager(asset)
|
62
|
+
puts "# Manager #{asset}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def show_service(asset)
|
66
|
+
puts "# Service #{asset}"
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Proctor
|
2
|
+
class TemplateConfig
|
3
|
+
|
4
|
+
def self.load(global_options = {})
|
5
|
+
template_files = self.files(global_options)
|
6
|
+
template_files.reduce({}) do |a, v|
|
7
|
+
a.merge({File.basename(v) => v})
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def self.files(global_options)
|
14
|
+
Dir.glob('proctor/templates/*').map {|f| File.expand_path(f)}
|
15
|
+
end
|
16
|
+
|
17
|
+
#def self.base_dir
|
18
|
+
# File.expand_path(File.dirname(File.expand_path(__FILE__)) + '/../..')
|
19
|
+
#end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Proctor
|
4
|
+
class TemplateFile
|
5
|
+
attr_reader :config_data
|
6
|
+
|
7
|
+
def initialize(filename)
|
8
|
+
check_file_existence(filename)
|
9
|
+
@config_data = load_data(filename)
|
10
|
+
check_data_format(filename)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def load_data(file)
|
16
|
+
begin
|
17
|
+
@config_data = YAML.load_file(file)
|
18
|
+
rescue Psych::SyntaxError
|
19
|
+
error_msg = "invalid file format (expecting YAML - #{file})"
|
20
|
+
raise InvalidYamlException.new, error_msg
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def check_data_format(file)
|
25
|
+
raise InvalidDataType, "expecting hash data (#{file})" unless @config_data.is_a?(Hash)
|
26
|
+
end
|
27
|
+
|
28
|
+
def check_file_existence(file)
|
29
|
+
error_msg = "missing app file (#{file})"
|
30
|
+
raise MissingFileException, error_msg unless File.exist?(file)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
class MissingFileException < RuntimeError
|
36
|
+
end
|
37
|
+
|
38
|
+
class InvalidYamlException < RuntimeError
|
39
|
+
end
|
40
|
+
|
41
|
+
class InvalidDataType < RuntimeError
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/lib/proctor/version.rb
CHANGED
data/lib/proctor.rb
CHANGED
data/proctor/Proctorfile
CHANGED
@@ -1,28 +1,52 @@
|
|
1
1
|
# vim: set ft=yaml:
|
2
2
|
---
|
3
|
-
# exports:
|
4
|
-
# upstart:
|
5
|
-
# start_command: "asdf"
|
6
|
-
# stop_command: "asdf"
|
7
|
-
# monit:
|
8
|
-
# reload_command: "asdf"
|
9
|
-
# procs:
|
10
|
-
# web:
|
11
|
-
# start_command: "asdf"
|
12
|
-
# stop_command: "asdf"
|
13
|
-
# faye:
|
14
|
-
# start_command: "asdf"
|
15
3
|
|
16
|
-
|
4
|
+
managers:
|
5
|
+
init:
|
6
|
+
export_directory: "/etc/init.d"
|
17
7
|
upstart:
|
18
|
-
|
19
|
-
|
8
|
+
export_directory: "/etc/init"
|
9
|
+
start_command: "/sbin/init start <%= app_name %>"
|
10
|
+
stop_command: "/sbin/init stop <%= app_name %>"
|
11
|
+
status_command: "/sbin/init status <%= app_name %>"
|
20
12
|
monit:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
start_command:
|
25
|
-
|
13
|
+
export_directory: "/etc/monit/conf.d"
|
14
|
+
reload_command: "monit reload"
|
15
|
+
stop_command: "monit quit"
|
16
|
+
start_command: "monit"
|
17
|
+
status_command: "monit summary"
|
18
|
+
pidfile: "/a/b/c"
|
19
|
+
foreman:
|
20
|
+
start_command: "foreman start"
|
21
|
+
use_master_template: true
|
22
|
+
use_worker_template: false
|
23
|
+
|
24
|
+
services:
|
25
|
+
unicorn:
|
26
|
+
start_command: "bin/unicorn --log_file shared/log/<%= name %>.log"
|
27
|
+
stop_command: "qwer"
|
28
|
+
passenger:
|
29
|
+
start_command: "bin/passenger --log_file shared/log/<%= name %>.log"
|
30
|
+
stop_command: "qwer"
|
26
31
|
faye:
|
27
32
|
start_command: "qwer"
|
33
|
+
export.monit.memory_limit: "<%= ForemanEnv.production? ? '20MB' : '10MB' %>"
|
34
|
+
exports_to: ['monit', 'upstart']
|
35
|
+
start_command: "script/faye_script.sh"
|
36
|
+
port: 2343
|
37
|
+
|
38
|
+
nodes:
|
39
|
+
dev:
|
40
|
+
- passenger
|
41
|
+
- faye
|
42
|
+
- postgres-standalone
|
43
|
+
- jobq
|
44
|
+
- renderpro
|
45
|
+
- redis
|
46
|
+
production:
|
47
|
+
- unicorn
|
48
|
+
- faye
|
49
|
+
- postgres-shared
|
50
|
+
backup:
|
51
|
+
- postgres
|
28
52
|
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Generated by Proctor at <%= Time.now %>
|
2
|
+
|
3
|
+
check process <%= app_name %> with pidfile <%= pidfile %>
|
4
|
+
start program "/etc/init.d/<%= app_name %> start"
|
5
|
+
stop program "/etc/init.d/<%= app_name %> stop"
|
6
|
+
if failed port <%= port %> then restart
|
7
|
+
if 5 restarts within 5 cycles then timeout
|
File without changes
|
File without changes
|
File without changes
|
data/proctor.gemspec
CHANGED
@@ -18,10 +18,12 @@ Gem::Specification.new do |gem|
|
|
18
18
|
|
19
19
|
gem.add_dependency('gli')
|
20
20
|
gem.add_dependency('foreman')
|
21
|
+
gem.add_dependency('hash-deep-merge')
|
21
22
|
|
22
23
|
gem.add_development_dependency('rake')
|
23
24
|
gem.add_development_dependency('rdoc')
|
24
25
|
gem.add_development_dependency('rspec')
|
25
26
|
gem.add_development_dependency('aruba')
|
27
|
+
gem.add_development_dependency('debugger')
|
26
28
|
|
27
29
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe 'start/help' do
|
3
|
+
describe 'start/help', :acceptance do
|
4
4
|
|
5
5
|
it 'returns text' do
|
6
6
|
start_simple
|
@@ -9,6 +9,7 @@ describe 'start/help' do
|
|
9
9
|
|
10
10
|
it 'does not have an error' do
|
11
11
|
start_simple
|
12
|
+
last_exit_status.should == 0
|
12
13
|
all_output.should_not include('Error')
|
13
14
|
end
|
14
15
|
|
@@ -17,4 +18,19 @@ describe 'start/help' do
|
|
17
18
|
all_output.should include('start')
|
18
19
|
end
|
19
20
|
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "checking existence of App file" do
|
24
|
+
it "returns an error w/o the app file" do
|
25
|
+
clear_app_file do
|
26
|
+
start_simple "list", false
|
27
|
+
last_exit_status.should_not == 0
|
28
|
+
all_output.should include('error: missing app file')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
it "returns an error when specifying an alternative proctorfile" do
|
32
|
+
start_simple "list -f Nofile", false
|
33
|
+
last_exit_status.should_not == 0
|
34
|
+
all_output.should include('error: missing app file')
|
35
|
+
end
|
20
36
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'list', :acceptance do
|
4
|
+
|
5
|
+
it 'returns help text' do
|
6
|
+
start_simple "help list"
|
7
|
+
all_output.should include('list')
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'raises an error with an unknown type' do
|
11
|
+
start_simple "list -t whatexxver", false
|
12
|
+
last_exit_status.should_not == 0
|
13
|
+
all_output.should include('error')
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -13,12 +13,15 @@ RSpec.configure do |config|
|
|
13
13
|
config.color_enabled = true
|
14
14
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
15
15
|
config.run_all_when_everything_filtered = true
|
16
|
-
config.filter_run :focus
|
17
16
|
config.include Aruba::Api, :example_group => {
|
18
17
|
:file_path => /spec\/acceptance/
|
19
18
|
}
|
20
|
-
config.before(:suite, :example_group => {
|
21
|
-
:file_path => /spec\/unit/
|
22
|
-
}) { $in_unit_spec_suite = true }
|
23
19
|
|
24
20
|
end
|
21
|
+
|
22
|
+
def clear_app_file(&block)
|
23
|
+
system "mv Proctorfile /tmp/Proctorfile.#{$$}" if File.exist?("Proctorfile")
|
24
|
+
yield
|
25
|
+
system "rm -f Proctorfile"
|
26
|
+
system "mv /tmp/Proctorfile.#{$$} Proctorfile" if File.exist?("/tmp/Proctorfile.#{$$}")
|
27
|
+
end
|
data/spec/support/aruba.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative "../../lib/proctor/app_config"
|
3
|
+
|
4
|
+
include Proctor
|
5
|
+
|
6
|
+
describe AppConfig do
|
7
|
+
it "loads data and generates a hash" do
|
8
|
+
result = AppConfig.load
|
9
|
+
result.should_not be_nil
|
10
|
+
result.should be_a(Hash)
|
11
|
+
end
|
12
|
+
it "has default values" do
|
13
|
+
app_data = "---\nmanagers:\n newstart:\n export_directory: '/tmp/test'"
|
14
|
+
clear_app_file do
|
15
|
+
File.open("Proctorfile", 'w') {|f| f.puts "#{app_data}"}
|
16
|
+
result = AppConfig.load
|
17
|
+
tst_value = result["managers"]["upstart"]["export_directory"]
|
18
|
+
tst_value.should == "/etc/init"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
it "overwrites default values with local values" do
|
22
|
+
app_data = "---\nmanagers:\n upstart:\n export_directory: '/tmp/test'"
|
23
|
+
clear_app_file do
|
24
|
+
File.open("Proctorfile", 'w') {|f| f.puts "#{app_data}"}
|
25
|
+
result = AppConfig.load
|
26
|
+
tst_value = result["managers"]["upstart"]["export_directory"]
|
27
|
+
tst_value.should == "/tmp/test"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/spec/unit/app_file_spec.rb
CHANGED
@@ -1,9 +1,40 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require_relative "../../lib/proctor/app_file"
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
include Proctor
|
5
|
+
|
6
|
+
describe AppFile do
|
7
|
+
|
8
|
+
describe "#new" do
|
9
|
+
it "reports an error if the app file is missing" do
|
10
|
+
lambda { AppFile.new("Unknown") }.should raise_error(MissingFileException)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "reports an error if the app file YAML has a parser error" do
|
14
|
+
file = "/tmp/test.#{$$}"
|
15
|
+
system "echo '\007\012\043' > #{file}"
|
16
|
+
lambda { AppFile.new(file) }.should raise_error(InvalidYamlException)
|
17
|
+
system "rm #{file}"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "reports an error if the data isn't a hash" do
|
21
|
+
file = "/tmp/test.#{$$}"
|
22
|
+
system "echo 'hello world' > #{file}"
|
23
|
+
lambda { AppFile.new(file) }.should raise_error(InvalidDataType)
|
24
|
+
system "rm #{file}"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "works ok if the file has valid data" do
|
28
|
+
file = "/tmp/test.#{$$}"
|
29
|
+
system "echo '---\na:\n b: 1' > #{file}"
|
30
|
+
lambda { AppFile.new(file) }.should_not raise_error
|
31
|
+
system "rm #{file}"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
#it "should have a list of valid object types"
|
37
|
+
#it "should raise warnings for invalid objects"
|
38
|
+
#it "should handle embedded ERB tags"
|
39
|
+
#it "reports if there is an ERB rendering error"
|
9
40
|
end
|
data/spec/unit/manager_spec.rb
CHANGED
@@ -1,11 +1,20 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require_relative "../../lib/proctor/manager"
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
include Proctor
|
5
|
+
|
6
|
+
describe Manager do
|
7
|
+
before(:each) do
|
8
|
+
@obj = Manager.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "exists" do
|
12
|
+
@obj.should_not be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has an input hash" do
|
16
|
+
@obj.should respond_to(:input_hash)
|
17
|
+
@obj.input_hash.should be_a(Hash)
|
18
|
+
end
|
19
|
+
|
11
20
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative "../../lib/proctor/service"
|
3
|
+
|
4
|
+
include Proctor
|
5
|
+
|
6
|
+
describe Service do
|
7
|
+
before(:each) do
|
8
|
+
@obj = Service.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should exist" do
|
12
|
+
@obj.should_not be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have an input hash" do
|
16
|
+
@obj.should respond_to(:input_hash)
|
17
|
+
@obj.input_hash.should be_a(Hash)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative "../../lib/proctor/template_config"
|
3
|
+
|
4
|
+
include Proctor
|
5
|
+
|
6
|
+
describe TemplateConfig do
|
7
|
+
it "loads data and generates a hash" do
|
8
|
+
result = TemplateConfig.load
|
9
|
+
result.should_not be_nil
|
10
|
+
result.should be_a(Hash)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative "../../lib/proctor/template_file"
|
3
|
+
|
4
|
+
include Proctor
|
5
|
+
|
6
|
+
describe TemplateFile do
|
7
|
+
|
8
|
+
describe "#new" do
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
#it "should have a list of valid object types"
|
13
|
+
#it "should raise warnings for invalid objects"
|
14
|
+
#it "should handle embedded ERB tags"
|
15
|
+
#it "reports if there is an ERB rendering error"
|
16
|
+
end
|
data/spec/unit/template_spec.rb
CHANGED
@@ -2,6 +2,7 @@ require 'spec_helper'
|
|
2
2
|
require_relative "../../lib/proctor/template"
|
3
3
|
|
4
4
|
describe Proctor::Template do
|
5
|
-
it "should support template lookup"
|
6
|
-
it "should return an error if the template isn't found"
|
5
|
+
#it "should support template lookup"
|
6
|
+
#it "should return an error if the template isn't found"
|
7
|
+
#it "should report if there is a template rendering error"
|
7
8
|
end
|