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
data/Proctorfile
ADDED
data/README.md
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
# Proctor
|
2
2
|
|
3
|
-
|
3
|
+
Proctor is a configurable process manager that supports:
|
4
|
+
* customized upstart/init scripts
|
5
|
+
* separate start/stop/restart commands
|
6
|
+
* multiple managent tools like monit & upstart
|
7
|
+
* lightweight process monitoring
|
8
|
+
* config file cleanup
|
9
|
+
|
10
|
+
Proctor was inspired by the excellent Foreman gem. Proctor
|
11
|
+
seeks to retain the clean and simple design of Foreman,
|
12
|
+
while adding a bit more configurability.
|
4
13
|
|
5
14
|
## Installation
|
6
15
|
|
@@ -18,7 +27,93 @@ Or install it yourself as:
|
|
18
27
|
|
19
28
|
## Usage
|
20
29
|
|
21
|
-
|
30
|
+
Start by running 'proctor help'.
|
31
|
+
|
32
|
+
Proctor is useful when an application requires a suite of
|
33
|
+
independent processes which need to be managed and monitored.
|
34
|
+
|
35
|
+
For development, Proctor brings up all your processes in a
|
36
|
+
single screen, just like Foreman.
|
37
|
+
|
38
|
+
For production, Proctor is designed to work in concert with
|
39
|
+
config tools like Puppet/Chef, and with deploy tools like
|
40
|
+
Capistrano. Proctor can create tailored application
|
41
|
+
manifests for single or multi-server deployments.
|
42
|
+
|
43
|
+
## Background
|
44
|
+
|
45
|
+
With Proctor, all of your application processes are described in
|
46
|
+
a single YAML file, called a Proctorfile.
|
47
|
+
|
48
|
+
In the Proctorfile, you can designate one or more Nodes. Example
|
49
|
+
Nodes include `web`, `db`, `backup`. Each node has a list of
|
50
|
+
Services.
|
51
|
+
|
52
|
+
nodes:
|
53
|
+
web:
|
54
|
+
- passenger
|
55
|
+
- faye
|
56
|
+
- jobq
|
57
|
+
- renderpro
|
58
|
+
- redis
|
59
|
+
db:
|
60
|
+
- postgres-shared
|
61
|
+
backup:
|
62
|
+
- postgres
|
63
|
+
|
64
|
+
Services are defined independently. Example Services include
|
65
|
+
`unicorn`, `faye`, `postgres` and `redis`.
|
66
|
+
|
67
|
+
services:
|
68
|
+
unicorn:
|
69
|
+
start_command: "bin/unicorn --log_file shared/log/<%= name %>.log"
|
70
|
+
stop_command: "qwer"
|
71
|
+
passenger:
|
72
|
+
start_command: "bin/passenger --log_file shared/log/<%= name %>.log"
|
73
|
+
stop_command: "qwer"
|
74
|
+
faye:
|
75
|
+
start_command: "qwer"
|
76
|
+
export.monit.memory_limit: "<%= ForemanEnv.production? ? '20MB' : '10MB' %>"
|
77
|
+
exports_to: ['monit', 'upstart']
|
78
|
+
start_command: "script/faye_script.sh"
|
79
|
+
port: 2343
|
80
|
+
|
81
|
+
Services are controlled and monitored by Managers. Example
|
82
|
+
Managers include `upstart`, `monit`, and `foreman`.
|
83
|
+
|
84
|
+
managers:
|
85
|
+
upstart:
|
86
|
+
export_directory: "/etc/init"
|
87
|
+
start_command: "/sbin/init start <%= app_name %>"
|
88
|
+
stop_command: "/sbin/init stop <%= app_name %>"
|
89
|
+
status_command: "/sbin/init status <%= app_name %>"
|
90
|
+
monit:
|
91
|
+
export_directory: "/etc/monit/conf.d"
|
92
|
+
reload_command: "monit reload"
|
93
|
+
stop_command: "monit quit"
|
94
|
+
start_command: "monit"
|
95
|
+
status_command: "monit summary"
|
96
|
+
pidfile: "/a/b/c"
|
97
|
+
foreman:
|
98
|
+
start_command: "foreman start"
|
99
|
+
use_master_template: true
|
100
|
+
use_worker_template: false
|
101
|
+
|
102
|
+
In a Proctor run, ERB templates are used to create config
|
103
|
+
files that are exported to managers. Different Templates
|
104
|
+
can be established for each type of Service and Manager.
|
105
|
+
|
106
|
+
# Monit config file (template: <%= original_template_file %>)
|
107
|
+
# Generated by Proctor at <%= Time.now %>
|
108
|
+
# Hostname: <%= ENV['host'] %>
|
109
|
+
# Target Directory: <%= export_directory %>
|
110
|
+
|
111
|
+
check process <%= role_name %> with pidfile <%= pidfile %>
|
112
|
+
start program = "<%= start_command %>"
|
113
|
+
stop program = "<%= stop_command %>"
|
114
|
+
|
115
|
+
In a Proctor run, multiple Proctorfiles can be referenced, and
|
116
|
+
their values will be merged together.
|
22
117
|
|
23
118
|
## Contributing
|
24
119
|
|
data/Rakefile
CHANGED
@@ -3,7 +3,21 @@ require "bundler/gem_tasks"
|
|
3
3
|
|
4
4
|
desc "Run all specs"
|
5
5
|
task :rspec do
|
6
|
-
system "rspec"
|
6
|
+
system "rspec -d"
|
7
|
+
end
|
8
|
+
|
9
|
+
namespace :rspec do
|
10
|
+
|
11
|
+
desc "Run unit specs"
|
12
|
+
task :unit do
|
13
|
+
system "rspec -d spec/unit"
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Run acceptance specs"
|
17
|
+
task :acceptance do
|
18
|
+
system "rspec -d spec/acceptance"
|
19
|
+
end
|
20
|
+
|
7
21
|
end
|
8
22
|
|
9
23
|
task :default => :rspec
|
data/bin/proctor
CHANGED
@@ -3,26 +3,20 @@
|
|
3
3
|
$: << File.expand_path(File.dirname(File.realpath(__FILE__)) + '/../lib')
|
4
4
|
|
5
5
|
require 'rubygems'
|
6
|
+
require 'debugger'
|
6
7
|
require 'gli'
|
7
8
|
require 'proctor'
|
8
9
|
|
9
10
|
include GLI
|
11
|
+
include Proctor
|
12
|
+
|
13
|
+
APP_CONFIG=
|
10
14
|
|
11
15
|
# ---- global options ----------------------------------------------------
|
12
16
|
|
13
17
|
version Proctor::VERSION
|
14
18
|
program_desc 'proctor - an application process manager'
|
15
19
|
|
16
|
-
desc 'Root Directory'
|
17
|
-
default_value Dir.pwd
|
18
|
-
arg_name 'APP_ROOT'
|
19
|
-
flag [:d,'app-root']
|
20
|
-
|
21
|
-
desc 'Application Environment'
|
22
|
-
default_value "production"
|
23
|
-
arg_name 'ENV'
|
24
|
-
flag [:e,:environment]
|
25
|
-
|
26
20
|
desc 'Select Proctorfile'
|
27
21
|
default_value 'Proctorfile'
|
28
22
|
arg_name 'PROCTORFILE'
|
@@ -32,93 +26,106 @@ flag [:f,:proctorfile]
|
|
32
26
|
|
33
27
|
desc 'Validates your application Proctorfile'
|
34
28
|
command :check do |c|
|
35
|
-
c.action do |
|
36
|
-
puts "
|
37
|
-
# If you have any errors, just raise them
|
38
|
-
# raise "that command made no sense"
|
29
|
+
c.action do |global,options,args|
|
30
|
+
puts "OK"
|
39
31
|
end
|
40
32
|
end
|
41
33
|
|
42
|
-
desc '
|
34
|
+
desc 'Removes exported proctor assets'
|
35
|
+
long_desc <<-EOF
|
36
|
+
Requires a NODE and a MANAGER name. To see
|
37
|
+
all NODEs and MANAGERs, use 'proctor list'.
|
38
|
+
EOF
|
39
|
+
arg_name "NODE MANAGER"
|
43
40
|
command :cleanup do |c|
|
44
|
-
c.action do |
|
45
|
-
puts "
|
46
|
-
# If you have any errors, just raise them
|
47
|
-
# raise "that command made no sense"
|
41
|
+
c.action do |global,options,args|
|
42
|
+
puts "CLEANUP"
|
48
43
|
end
|
49
44
|
end
|
50
45
|
|
51
|
-
desc 'Exports
|
52
|
-
|
46
|
+
desc 'Exports assets to a management tool'
|
47
|
+
long_desc <<-EOF
|
48
|
+
Requires a NODE and a MANAGER name. To see
|
49
|
+
all NODEs and MANAGERs, use 'proctor list'.
|
50
|
+
EOF
|
51
|
+
arg_name "NODE MANAGER"
|
53
52
|
command :export do |c|
|
54
|
-
|
55
|
-
|
56
|
-
c.default_value 'upstart'
|
57
|
-
c.arg_name 'FORMAT'
|
58
|
-
c.flag [:f, :format]
|
59
|
-
|
60
|
-
c.desc 'Location'
|
61
|
-
c.default_value Dir.pwd
|
62
|
-
c.arg_name 'DIRECTORY'
|
63
|
-
c.flag [:d, :directory]
|
64
|
-
|
65
|
-
c.action do |global_options,options,args|
|
66
|
-
puts "I AM IN EXPORT"
|
53
|
+
c.action do |global,options,args|
|
54
|
+
puts "EXPORT"
|
67
55
|
end
|
68
|
-
|
69
56
|
end
|
70
57
|
|
71
|
-
desc '
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
77
|
-
end
|
58
|
+
desc 'Lists handles, names and paths for proctor assets'
|
59
|
+
long_desc <<-EOF
|
60
|
+
Lists the name or path of each Proctor asset. Asset types include Templates,
|
61
|
+
AppFiles, Managers, Services, and Nodes. Managers, Services and Nodes are
|
62
|
+
defined within an AppFile.
|
78
63
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
64
|
+
AppFile values from multiple files are merged together. When there is a conflict,
|
65
|
+
the last value take precedence.
|
66
|
+
EOF
|
67
|
+
command :list do |c|
|
68
|
+
opt_arr = %w(templates appfiles managers services manifest all)
|
69
|
+
opt_str = opt_arr.join('|')
|
70
|
+
c.desc "One of: [#{opt_str}]"
|
71
|
+
c.default_value 'all'
|
72
|
+
c.arg_name 'ASSET_TYPE'
|
73
|
+
c.flag [:t, :type]
|
74
|
+
c.action do |global,options,args|
|
75
|
+
unless opt_arr.include?(options[:type])
|
76
|
+
raise "unrecognized type (#{options[:type]}) must be one of [#{opt_str}]"
|
77
|
+
end
|
78
|
+
Presenter::List.new(global, options, args).render
|
84
79
|
end
|
85
80
|
end
|
86
81
|
|
87
|
-
desc '
|
88
|
-
arg_name '
|
89
|
-
|
90
|
-
|
91
|
-
|
82
|
+
desc 'Renders an ERB template to the console'
|
83
|
+
arg_name 'MANAGER SERVICE'
|
84
|
+
long_desc <<-EOF
|
85
|
+
Requires a MANAGER and a SERVICE. To see all
|
86
|
+
MANAGERs and SERVICEs, use 'proctor list'.
|
87
|
+
EOF
|
88
|
+
command :render do |c|
|
89
|
+
c.action do |global,options,args|
|
90
|
+
raise "usage 'render ROLE MANAGER'" unless args.length == 2
|
91
|
+
|
92
|
+
Presenter::Render.new(global, options, args).render
|
92
93
|
end
|
93
94
|
end
|
94
95
|
|
95
|
-
desc '
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
96
|
+
desc 'Shows content of a proctor asset'
|
97
|
+
long_desc <<-EOF
|
98
|
+
Displays a raw asset (Template, AppFile, Manager, Service, Node)
|
99
|
+
to the console. View asset handles using 'proctor list'. (asset
|
100
|
+
handles are three character strings at the start of each line)
|
101
|
+
EOF
|
102
|
+
arg_name 'HANDLE'
|
103
|
+
command :show do |c|
|
104
|
+
c.action do |global,options,args|
|
105
|
+
raise "need a handle!" if args.length != 1
|
106
|
+
Presenter::Show.new(global, options, args).show
|
100
107
|
end
|
101
108
|
end
|
102
109
|
|
103
|
-
desc '
|
104
|
-
arg_name
|
110
|
+
desc 'Starts the application'
|
111
|
+
arg_name "NODE MANAGER"
|
112
|
+
long_desc <<-EOF
|
113
|
+
Requires a NODE and a MANAGER name. To see
|
114
|
+
all NODEs and MANAGERs, use 'proctor list'.
|
115
|
+
EOF
|
105
116
|
command :start do |c|
|
106
|
-
c.desc 'Describe a switch to start'
|
107
|
-
c.switch :s
|
108
117
|
|
109
|
-
c.desc 'Describe a flag to start'
|
110
|
-
c.default_value 'default'
|
111
|
-
c.flag :f
|
112
118
|
c.action do |global_options,options,args|
|
113
|
-
puts "
|
114
|
-
|
115
|
-
# If you have any errors, just raise them
|
116
|
-
# raise "that command made no sense"
|
119
|
+
puts "START"
|
117
120
|
end
|
118
121
|
end
|
119
122
|
|
120
|
-
desc 'Stops the application
|
121
|
-
arg_name
|
123
|
+
desc 'Stops the application'
|
124
|
+
arg_name "NODE MANAGER"
|
125
|
+
long_desc <<-EOF
|
126
|
+
Requires a NODE and a MANAGER name. To see
|
127
|
+
all NODEs and MANAGERs, use 'proctor list'.
|
128
|
+
EOF
|
122
129
|
command :stop do |c|
|
123
130
|
c.desc 'Describe a switch to start'
|
124
131
|
c.switch :s
|
@@ -127,15 +134,17 @@ command :stop do |c|
|
|
127
134
|
c.default_value 'default'
|
128
135
|
c.flag :f
|
129
136
|
c.action do |global_options,options,args|
|
130
|
-
puts "I AM IN
|
131
|
-
|
132
|
-
# If you have any errors, just raise them
|
137
|
+
puts "I AM IN STOP"
|
133
138
|
# raise "that command made no sense"
|
134
139
|
end
|
135
140
|
end
|
136
141
|
|
137
|
-
desc '
|
138
|
-
arg_name
|
142
|
+
desc 'Displays the application status'
|
143
|
+
arg_name "NODE MANAGER"
|
144
|
+
long_desc <<-EOF
|
145
|
+
Requires a NODE and a MANAGER name. To see
|
146
|
+
all NODEs and MANAGERs, use 'proctor list'.
|
147
|
+
EOF
|
139
148
|
command :status do |c|
|
140
149
|
c.desc 'Describe a switch to start'
|
141
150
|
c.switch :s
|
@@ -143,11 +152,8 @@ command :status do |c|
|
|
143
152
|
c.desc 'Describe a flag to start'
|
144
153
|
c.default_value 'default'
|
145
154
|
c.flag :f
|
146
|
-
c.action do |
|
147
|
-
puts "I AM IN
|
148
|
-
|
149
|
-
# If you have any errors, just raise them
|
150
|
-
# raise "that command made no sense"
|
155
|
+
c.action do |global,options,args|
|
156
|
+
puts "I AM IN STATUS"
|
151
157
|
end
|
152
158
|
end
|
153
159
|
|
@@ -155,18 +161,16 @@ end
|
|
155
161
|
# ----- pre/post --------------------------------------------------------------
|
156
162
|
|
157
163
|
pre do |global,command,options,args|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
#
|
162
|
-
# on that command only
|
164
|
+
options[:app_config] = AppConfig.load(global) unless command.nil? || command.name == :help
|
165
|
+
options[:templates] = TemplateConfig.load(global) unless command.nil? || command.name == :help
|
166
|
+
|
167
|
+
# Return true to proceed; false to abort and not call the chosen command
|
168
|
+
# Use skips_pre before a command to skip this block on that command only
|
163
169
|
true
|
164
170
|
end
|
165
171
|
|
166
172
|
post do |global,command,options,args|
|
167
|
-
#
|
168
|
-
# Use skips_post before a command to skip this
|
169
|
-
# block on that command only
|
173
|
+
# Use skips_post before a command to skip this block on that command only
|
170
174
|
end
|
171
175
|
|
172
176
|
on_error do |exception|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'hash_deep_merge'
|
2
|
+
|
3
|
+
module Proctor
|
4
|
+
class AppConfig
|
5
|
+
|
6
|
+
def self.load(global_options = {:f => "Proctorfile"})
|
7
|
+
app_files = self.app_files(global_options).map {|f| AppFile.new(f)}
|
8
|
+
app_files.reduce({}) { |a,v| a.deep_merge(v.config_data) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.app_files(global_options)
|
12
|
+
proctorfile = global_options[:f]
|
13
|
+
["#{base_dir}/proctor/Proctorfile", "#{Dir.pwd}/#{proctorfile}", ]
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def self.base_dir
|
19
|
+
File.expand_path(File.dirname(File.expand_path(__FILE__)) + '/../..')
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/lib/proctor/app_file.rb
CHANGED
@@ -1,5 +1,44 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
1
3
|
module Proctor
|
2
|
-
|
4
|
+
class AppFile
|
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
|
3
40
|
|
41
|
+
class InvalidDataType < RuntimeError
|
4
42
|
end
|
43
|
+
|
5
44
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Proctor
|
2
|
+
|
3
|
+
class CmdState
|
4
|
+
|
5
|
+
def self.app_files(global, options, args)
|
6
|
+
AppConfig.app_files(global)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.templates(global, options, args)
|
10
|
+
options[:templates].values.sort
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.nodes(global, options, args)
|
14
|
+
options[:app_config]['nodes']
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.node_names(global, options, args)
|
18
|
+
options[:app_config]['nodes'].keys
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.services(global, options, args)
|
22
|
+
options[:app_config]['services']
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.service_names(global, options, args)
|
26
|
+
options[:app_config]['services'].keys
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.managers(global, options, args)
|
30
|
+
options[:app_config]['managers']
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.manager_names(global, options, args)
|
34
|
+
options[:app_config]['managers'].keys
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/lib/proctor/manager.rb
CHANGED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module Proctor
|
4
|
+
module Presenter
|
5
|
+
class List
|
6
|
+
|
7
|
+
def initialize(global, options, args)
|
8
|
+
@global = global
|
9
|
+
@options = options
|
10
|
+
@args = args
|
11
|
+
end
|
12
|
+
|
13
|
+
def render
|
14
|
+
case @options[:type]
|
15
|
+
when "appfiles" then render_appfiles
|
16
|
+
when "managers" then render_managers
|
17
|
+
when "services" then render_services
|
18
|
+
when "templates" then render_templates
|
19
|
+
when "node" then render_node
|
20
|
+
when "all" then render_all
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def handle(string)
|
25
|
+
Digest::MD5.hexdigest(string)[0..2]
|
26
|
+
end
|
27
|
+
|
28
|
+
def puts_handle(string)
|
29
|
+
puts "#{handle(string)}: #{string}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def render_templates
|
33
|
+
puts "[Templates]"
|
34
|
+
CmdState.templates(@global, @options, @args).each {|v| puts_handle(v)}
|
35
|
+
end
|
36
|
+
|
37
|
+
def render_appfiles
|
38
|
+
puts "[AppFiles]"
|
39
|
+
CmdState.app_files(@global, @options, @args).each { |f| puts "#{handle(f)}: #{f}" }
|
40
|
+
end
|
41
|
+
|
42
|
+
def render_managers
|
43
|
+
puts "[Managers]"
|
44
|
+
CmdState.managers(@global, @options, @args).keys.each {|k| puts_handle(k)}
|
45
|
+
end
|
46
|
+
|
47
|
+
def render_services
|
48
|
+
puts "[Services]"
|
49
|
+
CmdState.services(@global, @options, @args).keys.each {|k| puts_handle(k)}
|
50
|
+
end
|
51
|
+
|
52
|
+
def render_node
|
53
|
+
puts "[Nodes]"
|
54
|
+
CmdState.nodes(@global, @options, @args).keys.each {|k| puts_handle(k)}
|
55
|
+
end
|
56
|
+
|
57
|
+
def render_all
|
58
|
+
render_templates
|
59
|
+
render_appfiles
|
60
|
+
render_managers
|
61
|
+
render_services
|
62
|
+
render_node
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Proctor
|
2
|
+
module Presenter
|
3
|
+
class Render
|
4
|
+
|
5
|
+
def initialize(global, options, args)
|
6
|
+
@global = global
|
7
|
+
@options = options
|
8
|
+
@args = args
|
9
|
+
@role = args[0]
|
10
|
+
@manager = args[1]
|
11
|
+
check_for_valid_role(@role)
|
12
|
+
check_for_valid_manager(@manager)
|
13
|
+
end
|
14
|
+
|
15
|
+
def check_for_valid_role(role)
|
16
|
+
roles = CmdState.roles(@global, @options, @args) + ["manifest"]
|
17
|
+
unless roles.include? role
|
18
|
+
raise "Invalid ROLE (#{role}) - use one of [#{roles.join('|')}]"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def check_for_valid_manager(manager)
|
23
|
+
managers = CmdState.manager_names(@global, @options, @args)
|
24
|
+
unless managers.include? manager
|
25
|
+
raise "Invalid MANAGER (#{manager}) - use one of [#{managers.join('|')}]"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def render_template
|
30
|
+
puts "# Template #{@role} #{@manager}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def render
|
34
|
+
render_template
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|