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