proctor 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/TODO +28 -0
- data/bin/proctor +55 -85
- data/bin/showlog +5 -0
- data/bin/showtime +5 -0
- data/lib/proctor/command/asset_list_cmd.rb +56 -0
- data/lib/proctor/{presenter/show.rb → command/asset_show_cmd.rb} +7 -2
- data/lib/proctor/command/file_cleanup_cmd.rb +81 -0
- data/lib/proctor/command/file_export_cmd.rb +79 -0
- data/lib/proctor/command/helpers/command.rb +27 -0
- data/lib/proctor/command/render_group_cmd.rb +39 -0
- data/lib/proctor/command/render_service_cmd.rb +34 -0
- data/lib/proctor/command/start_cmd.rb +70 -0
- data/lib/proctor/config/app_file.rb +54 -0
- data/lib/proctor/config/app_files.rb +50 -0
- data/lib/proctor/config/env.rb +35 -0
- data/lib/proctor/config/template_file.rb +41 -0
- data/lib/proctor/config/template_files.rb +39 -0
- data/lib/proctor/manager.rb +36 -3
- data/lib/proctor/managers.rb +38 -0
- data/lib/proctor/node.rb +26 -0
- data/lib/proctor/nodes.rb +38 -0
- data/lib/proctor/resource/erb.rb +95 -0
- data/lib/proctor/resource/lookup.rb +82 -0
- data/lib/proctor/service.rb +28 -3
- data/lib/proctor/services.rb +38 -0
- data/lib/proctor/util/helpers.rb +13 -0
- data/lib/proctor/util/version.rb +3 -0
- data/proctor.gemspec +2 -1
- data/proctor/Proctorfile +35 -34
- data/proctor/templates/foreman_default_g.erb +3 -0
- data/proctor/templates/monit_default_s.erb +3 -6
- data/proctor/templates/monit_faye_s.erb +3 -3
- data/proctor/templates/upstart_default_g.erb +1 -0
- data/proctor/templates/upstart_default_s.erb +1 -3
- data/proctor/templates/upstart_passenger_s.erb +3 -0
- data/spec/acceptance/asset_list_spec.rb +16 -0
- data/spec/acceptance/asset_show_spec.rb +16 -0
- data/spec/acceptance/file_cleanup_spec.rb +16 -0
- data/spec/acceptance/file_export_spec.rb +16 -0
- data/spec/acceptance/render_group_spec.rb +15 -0
- data/spec/acceptance/render_service_spec.rb +16 -0
- data/spec/acceptance/start_spec.rb +16 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/unit/command/file_export_cmd_spec.rb +46 -0
- data/spec/unit/command/file_list_cmd_spec.rb +30 -0
- data/spec/unit/command/render_group_cmd_spec.rb +44 -0
- data/spec/unit/command/render_service_cmd_spec.rb +42 -0
- data/spec/unit/{app_file_spec.rb → config/app_file_spec.rb} +27 -7
- data/spec/unit/config/app_files_spec.rb +55 -0
- data/spec/unit/config/env_spec.rb +37 -0
- data/spec/unit/config/template_file_spec.rb +55 -0
- data/spec/unit/config/template_files_spec.rb +32 -0
- data/spec/unit/manager_spec.rb +30 -10
- data/spec/unit/managers_spec.rb +40 -0
- data/spec/unit/node_spec.rb +34 -0
- data/spec/unit/nodes_spec.rb +36 -0
- data/spec/unit/service_spec.rb +31 -10
- data/spec/unit/services_spec.rb +34 -0
- metadata +86 -31
- data/Proctorfile +0 -4
- data/lib/proctor/app_config.rb +0 -23
- data/lib/proctor/app_file.rb +0 -44
- data/lib/proctor/cmd_state.rb +0 -39
- data/lib/proctor/presenter/list.rb +0 -67
- data/lib/proctor/presenter/render.rb +0 -39
- data/lib/proctor/template.rb +0 -5
- data/lib/proctor/template_config.rb +0 -22
- data/lib/proctor/template_file.rb +0 -44
- data/lib/proctor/util.rb +0 -12
- data/lib/proctor/version.rb +0 -3
- data/proctor/templates/foreman_default_n.erb +0 -9
- data/proctor/templates/monit_web_s.erb +0 -0
- data/proctor/templates/upstart_default_n.erb +0 -0
- data/spec/acceptance/help_spec.rb +0 -36
- data/spec/acceptance/list_spec.rb +0 -17
- data/spec/unit/app_config_spec.rb +0 -30
- data/spec/unit/template_config_spec.rb +0 -12
- data/spec/unit/template_file_spec.rb +0 -16
- data/spec/unit/template_spec.rb +0 -8
@@ -0,0 +1,27 @@
|
|
1
|
+
module Proctor
|
2
|
+
module Command
|
3
|
+
module Helpers
|
4
|
+
|
5
|
+
module Command
|
6
|
+
|
7
|
+
def check_number_of_args(args, target_number, message, opts = {})
|
8
|
+
opts_txt = options_msg(opts)
|
9
|
+
if args.length != target_number
|
10
|
+
raise InvalidNumberOfArgs, "Usage '#{message}' #{opts_txt}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def options_msg(hash)
|
15
|
+
hash.to_a.map do |i|
|
16
|
+
"\n #{i[0]} [#{i[1].join('|')}]"
|
17
|
+
end.join
|
18
|
+
end
|
19
|
+
|
20
|
+
class InvalidNumberOfArgs < RuntimeError
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative "./helpers/command"
|
2
|
+
require_relative "../resource/erb"
|
3
|
+
require_relative "../resource/lookup"
|
4
|
+
|
5
|
+
module Proctor
|
6
|
+
module Command
|
7
|
+
class RenderGroupCmd
|
8
|
+
|
9
|
+
include Helpers::Command
|
10
|
+
include Proctor::Resource::Erb
|
11
|
+
include Proctor::Resource::Lookup
|
12
|
+
|
13
|
+
def initialize(global, options, args)
|
14
|
+
@manager = args[0]
|
15
|
+
@node = args[1]
|
16
|
+
@env = options['env']
|
17
|
+
opts = {'MANAGERS' => @env.managers.names, 'NODES' => @env.nodes.names}
|
18
|
+
check_number_of_args(args, 2, 'render_group MANAGER NODE', opts)
|
19
|
+
end
|
20
|
+
|
21
|
+
def render_string
|
22
|
+
manager = lookup_valid_manager(@manager, @env)
|
23
|
+
node = lookup_valid_node(@node, @env)
|
24
|
+
template = lookup_valid_group_template(@manager, @node, @env)
|
25
|
+
services = lookup_valid_services_hash(@node, @env)
|
26
|
+
render_group_template(manager, node, services, template, @env)
|
27
|
+
end
|
28
|
+
|
29
|
+
def group
|
30
|
+
puts render_string
|
31
|
+
end
|
32
|
+
|
33
|
+
def render
|
34
|
+
puts render_string
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative "./helpers/command"
|
2
|
+
require_relative "../resource/erb"
|
3
|
+
require_relative "../resource/lookup"
|
4
|
+
|
5
|
+
module Proctor
|
6
|
+
module Command
|
7
|
+
class RenderServiceCmd
|
8
|
+
|
9
|
+
include Helpers::Command
|
10
|
+
include Proctor::Resource::Erb
|
11
|
+
include Proctor::Resource::Lookup
|
12
|
+
|
13
|
+
def initialize(global, options, args)
|
14
|
+
@manager = args[0]
|
15
|
+
@service = args[1]
|
16
|
+
@env = options['env']
|
17
|
+
opts = {'MANAGERS' => @env.managers.names, 'SERVICES' => @env.services.names}
|
18
|
+
check_number_of_args(args, 2, 'render_service MANAGER SERVICE', opts)
|
19
|
+
end
|
20
|
+
|
21
|
+
def render
|
22
|
+
puts render_string
|
23
|
+
end
|
24
|
+
|
25
|
+
def render_string
|
26
|
+
manager = lookup_valid_manager(@manager, @env)
|
27
|
+
service = lookup_valid_service(@service, @env)
|
28
|
+
template = lookup_valid_service_template(@manager, @service, @env)
|
29
|
+
render_service_template(manager, service, template, @env)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require_relative "./helpers/command"
|
2
|
+
require_relative "../resource/erb"
|
3
|
+
require_relative "../resource/lookup"
|
4
|
+
|
5
|
+
module Proctor
|
6
|
+
module Command
|
7
|
+
class StartCmd
|
8
|
+
|
9
|
+
include Helpers::Command
|
10
|
+
include Proctor::Resource::Erb
|
11
|
+
include Proctor::Resource::Lookup
|
12
|
+
|
13
|
+
def initialize(global, options, args)
|
14
|
+
@env = options['env']
|
15
|
+
@manager = args[0]
|
16
|
+
@node = args[1]
|
17
|
+
opts = {'MANAGERS' => @env.managers.names, 'NODES' => @env.nodes.names}
|
18
|
+
check_number_of_args(args, 2, 'start MANAGER NODE', opts)
|
19
|
+
end
|
20
|
+
|
21
|
+
def start
|
22
|
+
env = @env
|
23
|
+
_manager = lookup_valid_manager(@manager, @env)
|
24
|
+
#update_manager_with_cl_options(manager)
|
25
|
+
manager = erb_ify(_manager, {}, env)
|
26
|
+
node = lookup_valid_node(@node, @env)
|
27
|
+
if manager.data["group_data"]
|
28
|
+
start_group(manager)
|
29
|
+
end
|
30
|
+
if manager.data["service_data"]
|
31
|
+
node.services.each do |service_name|
|
32
|
+
service = lookup_valid_service(service_name, @env)
|
33
|
+
start_service(manager, service, @env)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def start_group(manager)
|
41
|
+
export_directory = manager.data["export_directory"]
|
42
|
+
start_command = manager.data["group_data"]["start_command"]
|
43
|
+
begin
|
44
|
+
cmd = "cd #{export_directory} ; #{start_command}"
|
45
|
+
system cmd
|
46
|
+
rescue
|
47
|
+
msg = "start problem"
|
48
|
+
raise StartError, msg
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def start_service(manager, service, env)
|
53
|
+
export_directory = manager.data["export_directory"]
|
54
|
+
start_command = manager.data["service_data"]["start_command"]
|
55
|
+
begin
|
56
|
+
cmd = "cd #{export_directory} ; #{start_command}"
|
57
|
+
system cmd
|
58
|
+
rescue
|
59
|
+
msg = "start problem"
|
60
|
+
raise StartError, msg
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class StartError < RuntimeError
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require_relative '../util/helpers'
|
3
|
+
|
4
|
+
module Proctor
|
5
|
+
module Config
|
6
|
+
class AppFile
|
7
|
+
|
8
|
+
include Proctor::Config
|
9
|
+
include Util::Helpers
|
10
|
+
|
11
|
+
attr_reader :data, :handle, :name
|
12
|
+
|
13
|
+
def initialize(file_path)
|
14
|
+
validate_file_existence(file_path)
|
15
|
+
@name = file_path
|
16
|
+
@data = load_data(file_path)
|
17
|
+
@handle = md5_handle(file_path)
|
18
|
+
validate_data_format(file_path)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def load_data(file)
|
24
|
+
begin
|
25
|
+
@data = YAML.load_file(file)
|
26
|
+
rescue Psych::SyntaxError
|
27
|
+
error_msg = "invalid file format (expecting YAML - #{file})"
|
28
|
+
raise InvalidYamlException.new, error_msg
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def validate_data_format(file)
|
33
|
+
raise InvalidDataType, "expecting hash data (#{file})" unless @data.is_a?(Hash)
|
34
|
+
end
|
35
|
+
|
36
|
+
def validate_file_existence(file)
|
37
|
+
error_msg = "missing app file (#{file})"
|
38
|
+
raise MissingAppFileException, error_msg unless File.exist?(file)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
class MissingAppFileException < RuntimeError
|
44
|
+
end
|
45
|
+
|
46
|
+
class InvalidYamlException < RuntimeError
|
47
|
+
end
|
48
|
+
|
49
|
+
class InvalidDataType < RuntimeError
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'hash_deep_merge'
|
2
|
+
require_relative './app_file'
|
3
|
+
|
4
|
+
module Proctor
|
5
|
+
module Config
|
6
|
+
class AppFiles
|
7
|
+
|
8
|
+
def initialize(params)
|
9
|
+
@all = path_list(params).map {|f| AppFile.new(f)}
|
10
|
+
end
|
11
|
+
|
12
|
+
def all
|
13
|
+
@all.sort {|a,b| a.name <=> b.name}
|
14
|
+
end
|
15
|
+
|
16
|
+
def merged_data
|
17
|
+
@all.reduce({}) { |a,v| a.deep_merge(v.data) }
|
18
|
+
end
|
19
|
+
|
20
|
+
def path_list(params)
|
21
|
+
gem_app_path + cwd_app_path + commandline_app_path(params)
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_by_handle(handle)
|
25
|
+
@all.find {|app_file| app_file.handle == handle}
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def commandline_app_path(params)
|
31
|
+
cl_name = params[0][:f]
|
32
|
+
cl_name.nil? ? [] : [cl_name]
|
33
|
+
end
|
34
|
+
|
35
|
+
def cwd_app_path
|
36
|
+
tgt_file = "#{Dir.pwd}/Proctorfile"
|
37
|
+
File.exist?(tgt_file) ? [tgt_file] : []
|
38
|
+
end
|
39
|
+
|
40
|
+
def gem_app_path
|
41
|
+
["#{gem_base_dir}/proctor/Proctorfile"]
|
42
|
+
end
|
43
|
+
|
44
|
+
def gem_base_dir
|
45
|
+
File.expand_path('../../../', File.dirname(__FILE__))
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
f1 = %w(./template_files ./app_files)
|
2
|
+
f2 = %w(../managers ../services ../nodes)
|
3
|
+
|
4
|
+
(f1 + f2).each {|f| require_relative f}
|
5
|
+
|
6
|
+
module Proctor
|
7
|
+
|
8
|
+
module Config
|
9
|
+
|
10
|
+
class Env
|
11
|
+
|
12
|
+
attr_reader :template_files
|
13
|
+
attr_reader :app_files, :managers, :services, :nodes
|
14
|
+
attr_reader :app
|
15
|
+
|
16
|
+
def initialize(params)
|
17
|
+
@template_files = TemplateFiles.new(params)
|
18
|
+
@app_files = AppFiles.new(params)
|
19
|
+
@managers = Managers.new(@app_files, params)
|
20
|
+
@services = Services.new(@app_files, params)
|
21
|
+
@nodes = Nodes.new(@app_files, params)
|
22
|
+
@app = {}
|
23
|
+
set_app_metadata
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_app_metadata
|
27
|
+
@app['name'] = Dir.pwd.split('/').last
|
28
|
+
@app['gemdir'] = File.expand_path('../../../', File.dirname(__FILE__))
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require_relative '../util/helpers'
|
3
|
+
|
4
|
+
module Proctor
|
5
|
+
module Config
|
6
|
+
class TemplateFile
|
7
|
+
|
8
|
+
include Proctor::Config
|
9
|
+
include Util::Helpers
|
10
|
+
|
11
|
+
attr_reader :name, :path, :handle
|
12
|
+
|
13
|
+
def initialize(file_path)
|
14
|
+
validate_file_existence(file_path)
|
15
|
+
@name = file_name(file_path)
|
16
|
+
@path = file_path
|
17
|
+
@handle = md5_handle(file_path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def text
|
21
|
+
File.read(@path)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def file_name(file_path)
|
27
|
+
File.basename(file_path, '.erb')
|
28
|
+
end
|
29
|
+
|
30
|
+
def validate_file_existence(file)
|
31
|
+
error_msg = "missing template file (#{file})"
|
32
|
+
raise MissingTemplateFileException, error_msg unless File.exist?(file)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
class MissingTemplateFileException < RuntimeError
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative './template_file'
|
2
|
+
|
3
|
+
module Proctor
|
4
|
+
module Config
|
5
|
+
class TemplateFiles
|
6
|
+
|
7
|
+
def initialize (params)
|
8
|
+
@all = path_list(params).map {|f| TemplateFile.new(f)}
|
9
|
+
end
|
10
|
+
|
11
|
+
def all
|
12
|
+
@all.sort {|a,b| a.name <=> b.name}
|
13
|
+
end
|
14
|
+
|
15
|
+
def find_by_name(file_name)
|
16
|
+
@all.find {|template_file| template_file.name == file_name}
|
17
|
+
end
|
18
|
+
|
19
|
+
def find_by_handle(handle)
|
20
|
+
@all.find {|template_file| template_file.handle == handle}
|
21
|
+
end
|
22
|
+
|
23
|
+
def names
|
24
|
+
@all.map {|template| template.name}
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def path_list(params)
|
30
|
+
Dir.glob("#{gem_base_dir}/proctor/templates/*").map {|f| File.expand_path(f)}
|
31
|
+
end
|
32
|
+
|
33
|
+
def gem_base_dir
|
34
|
+
File.dirname(File.expand_path('../../../', __FILE__))
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/proctor/manager.rb
CHANGED
@@ -1,11 +1,44 @@
|
|
1
|
+
require_relative './util/helpers'
|
2
|
+
|
1
3
|
module Proctor
|
2
4
|
class Manager
|
3
|
-
attr_reader :input_hash, :opts
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
include Proctor::Util::Helpers
|
7
|
+
|
8
|
+
attr_reader :name, :data, :handle
|
9
|
+
|
10
|
+
def initialize(name, data)
|
11
|
+
@name = name
|
12
|
+
@data = data
|
13
|
+
@handle = md5_handle(name)
|
14
|
+
validate_required_manager_fields(data)
|
7
15
|
end
|
8
16
|
|
17
|
+
private
|
18
|
+
|
19
|
+
def validate_required_manager_fields(manager_hash)
|
20
|
+
required_fields = %w(export_directory)
|
21
|
+
required_fields.each do |field|
|
22
|
+
if manager_hash[field].nil?
|
23
|
+
raise MissingManagerField, "missing required service field (#{field})"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate_export_directory(manager_hash)
|
29
|
+
dir = manager_hash['export_directory']
|
30
|
+
unless Dir.exist?(dir)
|
31
|
+
raise MissingExportDirectory, "missing export directory (#{dir})"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
class MissingManagerField < RuntimeError
|
9
38
|
end
|
39
|
+
|
40
|
+
class MissingExportDirectory < RuntimeError
|
41
|
+
end
|
42
|
+
|
10
43
|
end
|
11
44
|
|