procodile 1.0.12 → 1.0.13
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.
- checksums.yaml +4 -4
- data/bin/procodile +37 -79
- data/lib/procodile/app_determination.rb +150 -0
- data/lib/procodile/instance.rb +11 -0
- data/lib/procodile/supervisor.rb +1 -1
- data/lib/procodile/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7feabe360a0d490ac91076744fd7f782d39eebd0
|
|
4
|
+
data.tar.gz: 71e2007d58331378e50d47263f12dee80b35d103
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ee34c71d613246a255baaa0c9d2a6bf43be1ed845bd0001413c3e1cf45bc4b43eb7fb39563c79483ced396a277158a11f65348e82791340db699cf4f7e847089
|
|
7
|
+
data.tar.gz: d6f501fbb6997231185507fcddd508446399a75b74eb53fa519f922c54d5eaecfb7e1c12f909407b056d1122b80baa9e3dfb1f2d279abffd3093e19667632f16
|
data/bin/procodile
CHANGED
|
@@ -46,100 +46,58 @@ rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
|
|
|
46
46
|
exit 1
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if
|
|
53
|
-
|
|
54
|
-
root = options[:root]
|
|
55
|
-
procfile = options[:procfile]
|
|
56
|
-
elsif options[:root] && options[:procfile].nil?
|
|
57
|
-
# root provided on the command line but no procfile
|
|
58
|
-
root = options[:root]
|
|
59
|
-
procfile = nil
|
|
60
|
-
elsif options[:root].nil? && options[:procfile]
|
|
61
|
-
# no root provided but a procfile is provided
|
|
62
|
-
procfile = File.expand_path(options[:procfile])
|
|
63
|
-
root = File.dirname(procfile)
|
|
49
|
+
|
|
50
|
+
# Get the global configuration file data
|
|
51
|
+
global_config_path = ENV['PROCODILE_CONFIG'] || "/etc/procodile"
|
|
52
|
+
if File.file?(global_config_path)
|
|
53
|
+
global_config = YAML.load_file(global_config_path)
|
|
64
54
|
else
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
global_config_path = ENV['PROCODILE_CONFIG'] || "/etc/procodile"
|
|
68
|
-
if File.exist?(global_config_path)
|
|
69
|
-
global_config = YAML.load_file(global_config_path)
|
|
70
|
-
if global_config.is_a?(Array)
|
|
71
|
-
if ENV['PROCODILE_APP_ID']
|
|
72
|
-
app_id = ENV['PROCODILE_APP_ID'].to_i
|
|
73
|
-
preselect = true
|
|
74
|
-
else
|
|
75
|
-
puts "There are multiple applications configured in #{global_config_path}"
|
|
76
|
-
if File.file?("Procfile")
|
|
77
|
-
puts "\e[45;37mChoose an appplication or press ENTER to use the current directory:\e[0m"
|
|
78
|
-
else
|
|
79
|
-
puts "\e[45;37mChoose an application:\e[0m"
|
|
80
|
-
end
|
|
81
|
-
global_config.each_with_index do |app, i|
|
|
82
|
-
col = i % 3
|
|
83
|
-
print "#{(i+1)}) #{app['name']}"[0,28].ljust(col != 2 ? 30 : 0, ' ')
|
|
84
|
-
if col == 2 || i == global_config.size - 1
|
|
85
|
-
puts
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
app_id = STDIN.gets.to_i
|
|
89
|
-
ENV['PROCODILE_APP_ID'] = app_id.to_s
|
|
90
|
-
preselect = false
|
|
91
|
-
end
|
|
55
|
+
global_config = {}
|
|
56
|
+
end
|
|
92
57
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
58
|
+
# Create a determination to work out where we want to load our app from
|
|
59
|
+
require 'procodile/app_determination'
|
|
60
|
+
ap = Procodile::AppDetermination.new(FileUtils.pwd, options[:root], options[:procfile], options[:environment], global_config)
|
|
61
|
+
if ap.ambiguous?
|
|
62
|
+
if ENV['PROCODILE_APP_ID']
|
|
63
|
+
ap.set_app(ENV['PROCODILE_APP_ID'].to_i)
|
|
64
|
+
elsif ap.app_options.empty?
|
|
65
|
+
$stderr.puts "Error: Could not find procodile in #{FileUtils.pwd}/Procfile".color(31)
|
|
66
|
+
exit 1
|
|
67
|
+
else
|
|
68
|
+
puts "There are multiple applications configured in #{global_config_path}"
|
|
69
|
+
puts "\e[45;37mChoose an application:\e[0m"
|
|
70
|
+
ap.app_options.each do |i, app|
|
|
71
|
+
col = i % 3
|
|
72
|
+
print "#{(i+1)}) #{app}"[0,28].ljust(col != 2 ? 30 : 0, ' ')
|
|
73
|
+
if col == 2 || i == ap.app_options.size - 1
|
|
74
|
+
puts
|
|
110
75
|
end
|
|
111
76
|
end
|
|
77
|
+
|
|
78
|
+
app_id = STDIN.gets.strip.to_i - 1
|
|
79
|
+
if ap.app_options[app_id]
|
|
80
|
+
ap.set_app(app_id)
|
|
81
|
+
else
|
|
82
|
+
puts "Invalid app number: #{app_id + 1}"
|
|
83
|
+
exit 1
|
|
84
|
+
end
|
|
112
85
|
end
|
|
113
86
|
end
|
|
114
87
|
|
|
115
|
-
if
|
|
88
|
+
if ap.user && ENV['USER'] != ap.user
|
|
116
89
|
if global_config['user_reexec']
|
|
117
|
-
$stderr.puts "\e[31mProcodile must be run as #{
|
|
118
|
-
exec("sudo -E -u #{
|
|
90
|
+
$stderr.puts "\e[31mProcodile must be run as #{ap.user}. Re-executing as #{ap.user}...\e[0m"
|
|
91
|
+
exec("sudo -E -u #{ap.user} -- #{$0} #{ORIGINAL_ARGV}")
|
|
119
92
|
else
|
|
120
|
-
$stderr.puts "\e[31mError: Procodile must be run as #{
|
|
93
|
+
$stderr.puts "\e[31mError: Procodile must be run as #{ap.user}\e[0m"
|
|
121
94
|
exit 1
|
|
122
95
|
end
|
|
123
96
|
end
|
|
124
97
|
|
|
125
|
-
if global_config['root'] && global_config['procfile']
|
|
126
|
-
# the global config specifies a root and a procfile
|
|
127
|
-
root = global_config['root']
|
|
128
|
-
procfile = File.expand_path(global_config['procfile'], root)
|
|
129
|
-
elsif global_config['root'] && global_config['procfile'].nil?
|
|
130
|
-
root = global_config['root']
|
|
131
|
-
procfile = nil # assume from the root
|
|
132
|
-
elsif global_config['root'].nil? && global_config['procfile']
|
|
133
|
-
procfile = global_config['procfile']
|
|
134
|
-
root = File.dirname(procfile)
|
|
135
|
-
else
|
|
136
|
-
root ||= FileUtils.pwd
|
|
137
|
-
procfile ||= nil
|
|
138
|
-
end
|
|
139
|
-
|
|
140
98
|
begin
|
|
141
99
|
if command != 'help'
|
|
142
|
-
cli.config = Procodile::Config.new(root,
|
|
100
|
+
cli.config = Procodile::Config.new(ap.root, ap.environment, ap.procfile)
|
|
143
101
|
end
|
|
144
102
|
cli.dispatch(command)
|
|
145
103
|
rescue Procodile::Error => e
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
module Procodile
|
|
2
|
+
#
|
|
3
|
+
# This class is responsible for determining which application should be
|
|
4
|
+
# sued
|
|
5
|
+
#
|
|
6
|
+
class AppDetermination
|
|
7
|
+
|
|
8
|
+
# Start by creating an determination ased on the root and procfile that has been provided
|
|
9
|
+
# to us by the user (from --root and/or --procfile)
|
|
10
|
+
def initialize(pwd, given_root, given_procfile, given_environment, global_options = {})
|
|
11
|
+
@pwd = pwd
|
|
12
|
+
@given_root = given_root
|
|
13
|
+
@given_procfile = given_procfile
|
|
14
|
+
@given_environment = given_environment
|
|
15
|
+
@global_options = global_options
|
|
16
|
+
calculate
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Return the environment
|
|
20
|
+
def environment
|
|
21
|
+
@given_environment || @environment || 'production'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Return the root directory
|
|
25
|
+
def root
|
|
26
|
+
@root
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Return the procfile
|
|
30
|
+
def procfile
|
|
31
|
+
@procfile
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Return the user that we must be executing as if not current user
|
|
35
|
+
def user
|
|
36
|
+
@user
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Should this be reexeced
|
|
40
|
+
def reexec?
|
|
41
|
+
@reexec == true
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Are we in an app's directory?
|
|
45
|
+
def in_app_directory?
|
|
46
|
+
@in_app_directory == true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# If we have a root and procfile, we're all good
|
|
50
|
+
def unambiguous?
|
|
51
|
+
!!(@root && @procfile)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def ambiguous?
|
|
55
|
+
!unambiguous?
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Choose which of the ambiguous options we want to choose
|
|
59
|
+
def set_app(id)
|
|
60
|
+
@app_id = id
|
|
61
|
+
find_root_and_procfile_from_options(@global_options)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Return an hash of possible options to settle the ambiguity
|
|
65
|
+
def app_options
|
|
66
|
+
if ambiguous?
|
|
67
|
+
hash = {}
|
|
68
|
+
@global_options.each_with_index { |option, i| hash[i] = option['name'] || option['root'] }
|
|
69
|
+
hash
|
|
70
|
+
else
|
|
71
|
+
{}
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def calculate
|
|
78
|
+
# Try and find something using the information that has been given to us by the user
|
|
79
|
+
find_root_and_procfile(@pwd, @given_root, @given_procfile)
|
|
80
|
+
if ambiguous?
|
|
81
|
+
# Otherwise, try and use the global config we have been given
|
|
82
|
+
find_root_and_procfile_from_options(@global_options)
|
|
83
|
+
else
|
|
84
|
+
# Try to load additional global details on to the existing app
|
|
85
|
+
if @root && options = global_options_for_path(@root)
|
|
86
|
+
add_global_options(options)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def find_root_and_procfile(pwd, root, procfile)
|
|
92
|
+
if root && procfile
|
|
93
|
+
# The user has provided both the root and procfile, we can use these
|
|
94
|
+
@root = File.expand_path(root)
|
|
95
|
+
@procfile = File.expand_path(procfile, @root)
|
|
96
|
+
elsif root && procfile.nil?
|
|
97
|
+
# The user has given us a root, we can assume they want to use the procfile
|
|
98
|
+
# from the root
|
|
99
|
+
@root = File.expand_path(root)
|
|
100
|
+
@procfile = File.join(@root, 'Procfile')
|
|
101
|
+
elsif root.nil? && procfile
|
|
102
|
+
# The user has given us a procfile but no root. We will assume the procfile
|
|
103
|
+
# is in the root of the directory
|
|
104
|
+
@procfile = File.expand_path(procfile)
|
|
105
|
+
@root = File.dirname(@procfile)
|
|
106
|
+
else
|
|
107
|
+
# The user has given us nothing. We will check to see if there's a Procfile
|
|
108
|
+
# in the root of our current pwd
|
|
109
|
+
if File.file?(File.join(pwd, 'Procfile'))
|
|
110
|
+
# If there's a procfile in our current pwd, we'll look at using that.
|
|
111
|
+
@procfile = File.join(pwd, 'Procfile')
|
|
112
|
+
@root = File.dirname(@procfile)
|
|
113
|
+
@in_app_directory = true
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def find_root_and_procfile_from_options(options)
|
|
119
|
+
if options.is_a?(Hash)
|
|
120
|
+
# Use the current hash
|
|
121
|
+
find_root_and_procfile(@pwd, options['root'], options['procfile'])
|
|
122
|
+
add_global_options(options)
|
|
123
|
+
elsif options.is_a?(Array)
|
|
124
|
+
# Global options is provides a list of apps. We need to know which one of
|
|
125
|
+
# these we should be looking at.
|
|
126
|
+
if @app_id
|
|
127
|
+
find_root_and_procfile_from_options(options[@app_id])
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def global_options_for_path(root)
|
|
133
|
+
root = File.expand_path(root)
|
|
134
|
+
if @global_options.is_a?(Hash) && @global_options['root'] && File.expand_path(@global_options['root']) == root
|
|
135
|
+
@global_options
|
|
136
|
+
elsif @global_options.is_a?(Array) && option = @global_options.select { |o| o['root'] && File.expand_path(o['root']) == root }.first
|
|
137
|
+
option
|
|
138
|
+
else
|
|
139
|
+
nil
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def add_global_options(options)
|
|
144
|
+
@user = options['user'] if options['user']
|
|
145
|
+
@reexec = options['user_reexec'] if options['user_reexec']
|
|
146
|
+
@environment = options['environment'] if options['environment']
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
end
|
|
150
|
+
end
|
data/lib/procodile/instance.rb
CHANGED
|
@@ -41,6 +41,17 @@ module Procodile
|
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
#
|
|
45
|
+
# Should this process be running?
|
|
46
|
+
#
|
|
47
|
+
def should_be_running?
|
|
48
|
+
if stopped? || stopping?
|
|
49
|
+
false
|
|
50
|
+
else
|
|
51
|
+
true
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
44
55
|
#
|
|
45
56
|
# Return an array of environment variables that should be set
|
|
46
57
|
#
|
data/lib/procodile/supervisor.rb
CHANGED
|
@@ -184,7 +184,7 @@ module Procodile
|
|
|
184
184
|
messages << {:type => :incorrect_quantity, :process => process.name, :current => process_instances.size, :desired => process.quantity}
|
|
185
185
|
end
|
|
186
186
|
for instance in process_instances
|
|
187
|
-
if instance.status != 'Running'
|
|
187
|
+
if instance.should_be_running? && instance.status != 'Running'
|
|
188
188
|
messages << {:type => :not_running, :instance => instance.description, :status => instance.status}
|
|
189
189
|
end
|
|
190
190
|
end
|
data/lib/procodile/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: procodile
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.13
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Adam Cooke
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-03-
|
|
11
|
+
date: 2017-03-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: json
|
|
@@ -34,6 +34,7 @@ extra_rdoc_files: []
|
|
|
34
34
|
files:
|
|
35
35
|
- bin/procodile
|
|
36
36
|
- lib/procodile.rb
|
|
37
|
+
- lib/procodile/app_determination.rb
|
|
37
38
|
- lib/procodile/cli.rb
|
|
38
39
|
- lib/procodile/config.rb
|
|
39
40
|
- lib/procodile/control_client.rb
|
|
@@ -75,3 +76,4 @@ specification_version: 4
|
|
|
75
76
|
summary: This gem will help you run Ruby processes from a Procfile on Linux servers
|
|
76
77
|
in the background.
|
|
77
78
|
test_files: []
|
|
79
|
+
has_rdoc:
|