proctor 0.0.2 → 0.0.3
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/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
|