invoker 1.3.2 → 1.4.0
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/.gitignore +1 -0
- data/contrib/completion/invoker-completion.bash +70 -0
- data/lib/invoker/cli.rb +2 -2
- data/lib/invoker/ipc/message.rb +1 -1
- data/lib/invoker/ipc/message/list_response.rb +4 -2
- data/lib/invoker/parsers/config.rb +38 -5
- data/lib/invoker/power/balancer.rb +7 -23
- data/lib/invoker/power/setup/distro/base.rb +6 -0
- data/lib/invoker/power/setup/distro/debian.rb +11 -0
- data/lib/invoker/power/setup/distro/mint.rb +10 -0
- data/lib/invoker/power/setup/distro/ubuntu.rb +3 -4
- data/lib/invoker/power/templates/400.html +40 -0
- data/lib/invoker/power/url_rewriter.rb +37 -0
- data/lib/invoker/process_printer.rb +1 -0
- data/lib/invoker/version.rb +1 -1
- data/spec/invoker/config_spec.rb +103 -8
- data/spec/invoker/ipc/message/list_response_spec.rb +4 -2
- data/spec/invoker/ipc/message_spec.rb +8 -4
- data/spec/invoker/power/balancer_spec.rb +11 -64
- data/spec/invoker/power/url_rewriter_spec.rb +38 -0
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d51eb067dec10fd3eefb72b5ddc023b147017a51
|
4
|
+
data.tar.gz: ff4b7b25c9558f5e718bf44b29b3e0aa42990579
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92c403e1bba997b4568dd7071c6649a7bce887e5a87d74c60158abb4c73c773362ed8310b6a73a695baf8d459758072b8f63662c3a96b3ec00d9486a5f5fa878
|
7
|
+
data.tar.gz: f6ae56c5bcba81cdb85528faa8e8f843fa324c9c08b82b61d14ba4151e9dd88eea2dfab6304925ff1398361e1dc9bef98cdf8453082c8e6d1aa64349626a15fd
|
data/.gitignore
CHANGED
@@ -0,0 +1,70 @@
|
|
1
|
+
# BASH completion function for Invoker
|
2
|
+
|
3
|
+
# source it from bashrc
|
4
|
+
# dependencies:
|
5
|
+
# 1) netcat
|
6
|
+
# 2) find
|
7
|
+
|
8
|
+
check_open_port()
|
9
|
+
{
|
10
|
+
local port=$1
|
11
|
+
if [[ $(which nc) ]]; then
|
12
|
+
local open=$(nc -z -w2 localhost $port > /dev/null; echo $?)
|
13
|
+
if [[ "$open" == "1" ]]; then
|
14
|
+
COMPREPLY=( $(compgen -W "${port}" -- ${cur}) )
|
15
|
+
else
|
16
|
+
check_open_port $(($port+1))
|
17
|
+
fi
|
18
|
+
fi
|
19
|
+
}
|
20
|
+
_invoker()
|
21
|
+
{
|
22
|
+
local cur prev opts
|
23
|
+
COMPREPLY=()
|
24
|
+
cur="${COMP_WORDS[COMP_CWORD]}"
|
25
|
+
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
26
|
+
opts="add add_http help list reload remove setup"
|
27
|
+
opts="$opts start stop tail uninstall version"
|
28
|
+
|
29
|
+
case "${prev}" in
|
30
|
+
add | add_http | list | reload | remove | setup | stop | tail \
|
31
|
+
| uninstall | version)
|
32
|
+
COMPREPLY=()
|
33
|
+
;;
|
34
|
+
-d | --daemon | --no-daemon)
|
35
|
+
local extra_opts=("--port")
|
36
|
+
COMPREPLY=( $(compgen -W "${extra_opts}" -- ${cur}) )
|
37
|
+
;;
|
38
|
+
--port)
|
39
|
+
# auto-suggest port
|
40
|
+
check_open_port 9000
|
41
|
+
;;
|
42
|
+
help)
|
43
|
+
# Show opts again, but only once; don't infinitely recurse
|
44
|
+
local prev2="${COMP_WORDS[COMP_CWORD-2]}"
|
45
|
+
if [ "$prev2" == "help" ]; then
|
46
|
+
COMPREPLY=()
|
47
|
+
else
|
48
|
+
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
49
|
+
fi
|
50
|
+
;;
|
51
|
+
start)
|
52
|
+
local filename=$(find . -type f -name "*.ini")
|
53
|
+
if [[ $filename ]]; then
|
54
|
+
COMPREPLY=( $(compgen -W "${filename}" -- ${cur}) )
|
55
|
+
else
|
56
|
+
COMPREPLY=()
|
57
|
+
fi
|
58
|
+
;;
|
59
|
+
*.ini)
|
60
|
+
local start_opts="-d --daemon --no-daemon --port"
|
61
|
+
COMPREPLY=( $(compgen -W "${start_opts}" -- ${cur}) )
|
62
|
+
;;
|
63
|
+
invoker)
|
64
|
+
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
65
|
+
;;
|
66
|
+
esac
|
67
|
+
|
68
|
+
return 0
|
69
|
+
}
|
70
|
+
complete -F _invoker invoker
|
data/lib/invoker/cli.rb
CHANGED
@@ -28,13 +28,13 @@ module Invoker
|
|
28
28
|
Invoker::Power::Setup.uninstall
|
29
29
|
end
|
30
30
|
|
31
|
-
desc "start CONFIG_FILE", "Start Invoker Server"
|
31
|
+
desc "start [CONFIG_FILE]", "Start Invoker Server"
|
32
32
|
option :port, type: :numeric, banner: "Port series to be used for starting rack servers"
|
33
33
|
option :daemon,
|
34
34
|
type: :boolean,
|
35
35
|
banner: "Daemonize the server into the background",
|
36
36
|
aliases: [:d]
|
37
|
-
def start(file)
|
37
|
+
def start(file = nil)
|
38
38
|
Invoker.setup_config_location
|
39
39
|
port = options[:port] || 9000
|
40
40
|
Invoker.daemonize = options[:daemon]
|
data/lib/invoker/ipc/message.rb
CHANGED
@@ -16,8 +16,10 @@ module Invoker
|
|
16
16
|
process_array = []
|
17
17
|
Invoker.config.processes.each do |process|
|
18
18
|
worker_attrs = {
|
19
|
-
:
|
20
|
-
:
|
19
|
+
shell_command: process.cmd,
|
20
|
+
process_name: process.label,
|
21
|
+
dir: process.dir,
|
22
|
+
port: process.port
|
21
23
|
}
|
22
24
|
if worker = workers[process.label]
|
23
25
|
worker_attrs.update(pid: worker.pid)
|
@@ -4,11 +4,22 @@ module Invoker
|
|
4
4
|
module Parsers
|
5
5
|
class Config
|
6
6
|
PORT_REGEX = /\$PORT/
|
7
|
-
attr_accessor :processes, :power_config
|
8
7
|
|
8
|
+
attr_accessor :processes, :power_config
|
9
|
+
attr_reader :filename
|
10
|
+
|
11
|
+
# initialize takes a port form cli and decrements it by 1 and sets the
|
12
|
+
# instance variable @port. This port value is used as the environment
|
13
|
+
# variable $PORT mentioned inside invoker.ini. When method pick_port gets
|
14
|
+
# fired it increments the value of port by 1, subsequently when pick_port
|
15
|
+
# again gets fired, for another command, it will again increment port
|
16
|
+
# value by 1, that way generating different ports for different commands.
|
9
17
|
def initialize(filename, port)
|
10
|
-
@filename = filename
|
11
|
-
|
18
|
+
@filename = filename || autodetect_config_file
|
19
|
+
|
20
|
+
print_message_and_abort if invalid_config_file?
|
21
|
+
|
22
|
+
@port = port - 1
|
12
23
|
@processes = load_config
|
13
24
|
if Invoker.can_run_balancer?
|
14
25
|
@power_config = Invoker::Power::Config.load_config()
|
@@ -37,14 +48,23 @@ module Invoker
|
|
37
48
|
|
38
49
|
private
|
39
50
|
|
51
|
+
def autodetect_config_file
|
52
|
+
Dir.glob("{invoker.ini,Procfile}").first
|
53
|
+
end
|
54
|
+
|
55
|
+
def invalid_config_file?
|
56
|
+
@filename.nil?
|
57
|
+
end
|
58
|
+
|
40
59
|
def load_config
|
60
|
+
@filename = to_global_file if is_global?
|
61
|
+
|
41
62
|
if is_ini?
|
42
63
|
process_ini
|
43
64
|
elsif is_procfile?
|
44
65
|
process_procfile
|
45
66
|
else
|
46
|
-
|
47
|
-
abort
|
67
|
+
print_message_and_abort
|
48
68
|
end
|
49
69
|
end
|
50
70
|
|
@@ -65,6 +85,11 @@ module Invoker
|
|
65
85
|
end
|
66
86
|
end
|
67
87
|
|
88
|
+
def print_message_and_abort
|
89
|
+
Invoker::Logger.puts("\n Invalid config file. Invoker requires an ini or a Procfile.".color(:red))
|
90
|
+
abort
|
91
|
+
end
|
92
|
+
|
68
93
|
def process_command_from_section(section)
|
69
94
|
if supports_subdomain?(section)
|
70
95
|
port = pick_port(section)
|
@@ -128,6 +153,14 @@ module Invoker
|
|
128
153
|
def is_procfile?
|
129
154
|
@filename =~ /Procfile/
|
130
155
|
end
|
156
|
+
|
157
|
+
def to_global_file
|
158
|
+
File.join(Invoker::Power::Config.config_dir, "#{@filename}.ini")
|
159
|
+
end
|
160
|
+
|
161
|
+
def is_global?
|
162
|
+
@filename =~ /^\w+$/ && File.exist?(to_global_file)
|
163
|
+
end
|
131
164
|
end
|
132
165
|
end
|
133
166
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'em-proxy'
|
2
2
|
require 'http-parser'
|
3
3
|
require "invoker/power/http_parser"
|
4
|
+
require "invoker/power/url_rewriter"
|
4
5
|
|
5
6
|
module Invoker
|
6
7
|
module Power
|
@@ -22,8 +23,6 @@ module Invoker
|
|
22
23
|
|
23
24
|
class Balancer
|
24
25
|
attr_accessor :connection, :http_parser, :session, :protocol
|
25
|
-
DEV_MATCH_REGEX = /([\w-]+)\.dev(\:\d+)?$/
|
26
|
-
XIP_IO_MATCH_REGEX = /([\w-]+)\.\d+\.\d+\.\d+\.\d+\.xip\.io(\:\d+)?$/
|
27
26
|
|
28
27
|
def self.run(options = {})
|
29
28
|
start_http_proxy(InvokerHttpProxy, 'http', options)
|
@@ -65,7 +64,12 @@ module Invoker
|
|
65
64
|
return
|
66
65
|
end
|
67
66
|
@session = UUID.generate()
|
68
|
-
|
67
|
+
if !headers['Host'] || headers['Host'].empty?
|
68
|
+
return_error_page(400)
|
69
|
+
return
|
70
|
+
end
|
71
|
+
|
72
|
+
dns_check_response = UrlRewriter.new.select_backend_config(headers['Host'])
|
69
73
|
if dns_check_response && dns_check_response.port
|
70
74
|
connection.server(session, host: '0.0.0.0', port: dns_check_response.port)
|
71
75
|
else
|
@@ -101,28 +105,8 @@ module Invoker
|
|
101
105
|
connection.close_connection_after_writing if backend == session
|
102
106
|
end
|
103
107
|
|
104
|
-
def extract_host_from_domain(host)
|
105
|
-
host.match(DEV_MATCH_REGEX) || host.match(XIP_IO_MATCH_REGEX)
|
106
|
-
end
|
107
|
-
|
108
108
|
private
|
109
109
|
|
110
|
-
def select_backend_config(host)
|
111
|
-
matching_string = extract_host_from_domain(host)
|
112
|
-
return nil unless matching_string
|
113
|
-
if selected_app = matching_string[1]
|
114
|
-
dns_check(process_name: selected_app)
|
115
|
-
else
|
116
|
-
nil
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
def dns_check(dns_args)
|
121
|
-
Invoker::IPC::UnixClient.send_command("dns_check", dns_args) do |dns_response|
|
122
|
-
dns_response
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
110
|
def return_error_page(status)
|
127
111
|
http_response = Invoker::Power::HttpResponse.new()
|
128
112
|
http_response.status = status
|
@@ -16,6 +16,12 @@ module Invoker
|
|
16
16
|
when "Archlinux"
|
17
17
|
require "invoker/power/setup/distro/arch"
|
18
18
|
Arch.new
|
19
|
+
when "Debian"
|
20
|
+
require "invoker/power/setup/distro/debian"
|
21
|
+
Debian.new
|
22
|
+
when "LinuxMint"
|
23
|
+
require "invoker/power/setup/distro/mint"
|
24
|
+
Mint.new
|
19
25
|
else
|
20
26
|
raise "Your selected distro is not supported by Invoker"
|
21
27
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<title>Invoker</title>
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
margin: 0;
|
9
|
+
padding: 0;
|
10
|
+
background: #fff;
|
11
|
+
line-height: 18px;
|
12
|
+
}
|
13
|
+
div.page {
|
14
|
+
padding: 36px 90px;
|
15
|
+
}
|
16
|
+
h1, h2, p, li {
|
17
|
+
font-family: Helvetica, sans-serif;
|
18
|
+
font-size: 13px;
|
19
|
+
}
|
20
|
+
h1 {
|
21
|
+
line-height: 45px;
|
22
|
+
font-size: 36px;
|
23
|
+
margin: 0;
|
24
|
+
}
|
25
|
+
h2 {
|
26
|
+
line-height: 27px;
|
27
|
+
font-size: 18px;
|
28
|
+
font-weight: normal;
|
29
|
+
margin: 0;
|
30
|
+
}
|
31
|
+
</style>
|
32
|
+
</head>
|
33
|
+
<body class="">
|
34
|
+
<div class="page">
|
35
|
+
<h1>Bad request</h1>
|
36
|
+
<hr>
|
37
|
+
<h2>Invoker couldn't understand the request</h2>
|
38
|
+
</div>
|
39
|
+
</body>
|
40
|
+
</html>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Invoker
|
2
|
+
module Power
|
3
|
+
class UrlRewriter
|
4
|
+
DEV_MATCH_REGEX = [/([\w.-]+)\.dev(\:\d+)?$/, /([\w-]+)\.dev(\:\d+)?$/]
|
5
|
+
|
6
|
+
def select_backend_config(complete_path)
|
7
|
+
possible_matches = extract_host_from_domain(complete_path)
|
8
|
+
exact_match = nil
|
9
|
+
possible_matches.each do |match|
|
10
|
+
if match
|
11
|
+
exact_match = dns_check(process_name: match)
|
12
|
+
break if exact_match.port
|
13
|
+
end
|
14
|
+
end
|
15
|
+
exact_match
|
16
|
+
end
|
17
|
+
|
18
|
+
def extract_host_from_domain(complete_path)
|
19
|
+
matching_strings = []
|
20
|
+
DEV_MATCH_REGEX.map do |regexp|
|
21
|
+
if (match_result = complete_path.match(regexp))
|
22
|
+
matching_strings << match_result[1]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
matching_strings.uniq
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def dns_check(dns_args)
|
31
|
+
Invoker::IPC::UnixClient.send_command("dns_check", dns_args) do |dns_response|
|
32
|
+
dns_response
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -26,6 +26,7 @@ module Invoker
|
|
26
26
|
|
27
27
|
hash_with_colors['dir'] = colored_string(process.dir, color)
|
28
28
|
hash_with_colors['pid'] = colored_string(process.pid || 'Not Running', color)
|
29
|
+
hash_with_colors['port'] = colored_string(process.port, color)
|
29
30
|
hash_with_colors['shell_command'] = colored_string(process.shell_command, color)
|
30
31
|
hash_with_colors['process_name'] = colored_string(process.process_name, color)
|
31
32
|
hash_with_colors
|
data/lib/invoker/version.rb
CHANGED
data/spec/invoker/config_spec.rb
CHANGED
@@ -79,13 +79,13 @@ command = ls
|
|
79
79
|
config = Invoker::Parsers::Config.new(file.path, 9000)
|
80
80
|
command1 = config.processes.first
|
81
81
|
|
82
|
-
expect(command1.port).to eq(
|
83
|
-
expect(command1.cmd).to match(/
|
82
|
+
expect(command1.port).to eq(9000)
|
83
|
+
expect(command1.cmd).to match(/9000/)
|
84
84
|
|
85
85
|
command2 = config.processes[1]
|
86
86
|
|
87
|
-
expect(command2.port).to eq(
|
88
|
-
expect(command2.cmd).to match(/
|
87
|
+
expect(command2.port).to eq(9001)
|
88
|
+
expect(command2.cmd).to match(/9001/)
|
89
89
|
|
90
90
|
command2 = config.processes[2]
|
91
91
|
|
@@ -118,8 +118,8 @@ command = ls
|
|
118
118
|
config = Invoker::Parsers::Config.new(file.path, 9000)
|
119
119
|
command1 = config.processes.first
|
120
120
|
|
121
|
-
expect(command1.port).to eq(
|
122
|
-
expect(command1.cmd).to match(/
|
121
|
+
expect(command1.port).to eq(9000)
|
122
|
+
expect(command1.cmd).to match(/9000/)
|
123
123
|
|
124
124
|
command2 = config.processes[1]
|
125
125
|
|
@@ -162,7 +162,7 @@ web: bundle exec rails s -p $PORT
|
|
162
162
|
config = Invoker::Parsers::Config.new("/tmp/Procfile", 9000)
|
163
163
|
command1 = config.processes.first
|
164
164
|
|
165
|
-
expect(command1.port).to eq(
|
165
|
+
expect(command1.port).to eq(9000)
|
166
166
|
expect(command1.cmd).to match(/bundle exec rails/)
|
167
167
|
ensure
|
168
168
|
File.delete("/tmp/Procfile")
|
@@ -183,7 +183,7 @@ web: bundle exec rails s -p $PORT
|
|
183
183
|
|
184
184
|
expect(dns_cache.dns_data).to_not be_empty
|
185
185
|
expect(dns_cache.dns_data['web']).to_not be_empty
|
186
|
-
expect(dns_cache.dns_data['web']['port']).to eql
|
186
|
+
expect(dns_cache.dns_data['web']['port']).to eql 9000
|
187
187
|
ensure
|
188
188
|
File.delete("/tmp/Procfile")
|
189
189
|
end
|
@@ -223,4 +223,99 @@ command = bundle exec rails s -p $PORT
|
|
223
223
|
end
|
224
224
|
end
|
225
225
|
end
|
226
|
+
|
227
|
+
describe "global config file" do
|
228
|
+
it "should use global config file if available" do
|
229
|
+
begin
|
230
|
+
filename = "#{Invoker::Power::Config.config_dir}/foo.ini"
|
231
|
+
file = File.open(filename, "w")
|
232
|
+
config_data =<<-EOD
|
233
|
+
[try_sleep]
|
234
|
+
directory = /tmp
|
235
|
+
command = ruby try_sleep.rb
|
236
|
+
EOD
|
237
|
+
file.write(config_data)
|
238
|
+
file.close
|
239
|
+
config = Invoker::Parsers::Config.new("foo", 9000)
|
240
|
+
expect(config.filename).to eql(filename)
|
241
|
+
ensure
|
242
|
+
File.unlink(filename)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
describe "config file autodetection" do
|
248
|
+
context "no config file given" do
|
249
|
+
|
250
|
+
def create_invoker_ini
|
251
|
+
file = File.open("invoker.ini", "w")
|
252
|
+
config_data =<<-EOD
|
253
|
+
[some_process]
|
254
|
+
command = some_command
|
255
|
+
EOD
|
256
|
+
file.write(config_data)
|
257
|
+
file.close
|
258
|
+
|
259
|
+
file
|
260
|
+
end
|
261
|
+
|
262
|
+
def create_procfile
|
263
|
+
file = File.open("Procfile", "w")
|
264
|
+
config_data =<<-EOD
|
265
|
+
some_other_process: some_other_command
|
266
|
+
EOD
|
267
|
+
file.write(config_data)
|
268
|
+
file.close
|
269
|
+
|
270
|
+
file
|
271
|
+
end
|
272
|
+
|
273
|
+
context "directory has invoker.ini" do
|
274
|
+
it "autodetects invoker.ini" do
|
275
|
+
begin
|
276
|
+
file = create_invoker_ini
|
277
|
+
|
278
|
+
config = Invoker::Parsers::Config.new(nil, 9000)
|
279
|
+
expect(config.process("some_process").cmd).to eq("some_command")
|
280
|
+
ensure
|
281
|
+
File.delete(file)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
context "directory has Procfile" do
|
287
|
+
it "autodetects Procfile" do
|
288
|
+
begin
|
289
|
+
file = create_procfile
|
290
|
+
|
291
|
+
config = Invoker::Parsers::Config.new(nil, 9000)
|
292
|
+
expect(config.process("some_other_process").cmd).to eq("some_other_command")
|
293
|
+
ensure
|
294
|
+
File.delete(file)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
context "directory has both invoker.ini and Procfile" do
|
300
|
+
it "prioritizes invoker.ini" do
|
301
|
+
begin
|
302
|
+
invoker_ini = create_invoker_ini
|
303
|
+
procfile = create_procfile
|
304
|
+
|
305
|
+
config = Invoker::Parsers::Config.new(nil, 9000)
|
306
|
+
expect(config.process("some_process").cmd).to eq("some_command")
|
307
|
+
ensure
|
308
|
+
File.delete(invoker_ini)
|
309
|
+
File.delete(procfile)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
context "directory doesn't have invoker.ini or Procfile" do
|
315
|
+
it "aborts" do
|
316
|
+
expect { Invoker::Parsers::Config.new(nil, 9000) }.to raise_error(SystemExit)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
226
321
|
end
|
@@ -4,8 +4,10 @@ describe MM::ListResponse do
|
|
4
4
|
context "serializing a response" do
|
5
5
|
let(:process_array) do
|
6
6
|
[
|
7
|
-
{ shell_command: 'foo', process_name: 'foo', dir: '/tmp', pid: 100
|
8
|
-
|
7
|
+
{ shell_command: 'foo', process_name: 'foo', dir: '/tmp', pid: 100,
|
8
|
+
port: 9000 },
|
9
|
+
{ shell_command: 'bar', process_name: 'bar', dir: '/tmp', pid: 200,
|
10
|
+
port: 9001 }
|
9
11
|
]
|
10
12
|
end
|
11
13
|
|
@@ -19,8 +19,10 @@ describe Invoker::IPC::Message do
|
|
19
19
|
context "for nested messages" do
|
20
20
|
let(:process_array) do
|
21
21
|
[
|
22
|
-
{ shell_command: 'foo', process_name: 'foo', dir: '/tmp', pid: 100
|
23
|
-
|
22
|
+
{ shell_command: 'foo', process_name: 'foo', dir: '/tmp', pid: 100,
|
23
|
+
port: 9000 },
|
24
|
+
{ shell_command: 'bar', process_name: 'bar', dir: '/tmp', pid: 200,
|
25
|
+
port: 9001 }
|
24
26
|
]
|
25
27
|
end
|
26
28
|
|
@@ -33,8 +35,10 @@ describe Invoker::IPC::Message do
|
|
33
35
|
|
34
36
|
it "should report not equal for different objects" do
|
35
37
|
another_process_array = [
|
36
|
-
{ shell_command: 'baz', process_name: 'foo', dir: '/tmp', pid: 100
|
37
|
-
|
38
|
+
{ shell_command: 'baz', process_name: 'foo', dir: '/tmp', pid: 100,
|
39
|
+
port: 9000 },
|
40
|
+
{ shell_command: 'bar', process_name: 'bar', dir: '/tmp', pid: 200,
|
41
|
+
port: 9001 }
|
38
42
|
]
|
39
43
|
|
40
44
|
m2 = MM::ListResponse.new(processes: another_process_array)
|
@@ -2,74 +2,21 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Invoker::Power::Balancer do
|
4
4
|
before do
|
5
|
-
@
|
5
|
+
@http_connection = mock("connection")
|
6
|
+
@balancer = Invoker::Power::Balancer.new(@http_connection, "http")
|
6
7
|
end
|
7
8
|
|
8
|
-
context "
|
9
|
-
it "should
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
matching_string = match[1]
|
14
|
-
expect(matching_string).to eq("foo")
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should match foo.dev:1080" do
|
18
|
-
match = @balancer.extract_host_from_domain("foo.dev:1080")
|
19
|
-
expect(match).to_not be_nil
|
20
|
-
|
21
|
-
matching_string = match[1]
|
22
|
-
expect(matching_string).to eq("foo")
|
9
|
+
context "when Host field is missing in the request" do
|
10
|
+
it "should return 400 as response when Host is missing" do
|
11
|
+
headers = {}
|
12
|
+
@http_connection.expects(:send_data).with() { |value| value =~ /400 Bad Request/i }
|
13
|
+
@balancer.headers_received(headers)
|
23
14
|
end
|
24
15
|
|
25
|
-
it "should
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
matching_string = match[1]
|
30
|
-
expect(matching_string).to eq("bar")
|
31
|
-
end
|
32
|
-
|
33
|
-
it "should match hello-world.dev" do
|
34
|
-
match = @balancer.extract_host_from_domain("hello-world.dev")
|
35
|
-
expect(match).to_not be_nil
|
36
|
-
|
37
|
-
matching_string = match[1]
|
38
|
-
expect(matching_string).to eq("hello-world")
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
context "matching domain part of incoming request using xip.io" do
|
43
|
-
it "should do foo.10.0.0.1.xip.io match" do
|
44
|
-
match = @balancer.extract_host_from_domain("foo.10.0.0.1.xip.io")
|
45
|
-
expect(match).to_not be_nil
|
46
|
-
|
47
|
-
matching_string = match[1]
|
48
|
-
expect(matching_string).to eq("foo")
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should match foo.10.0.0.1.xip.io:1080" do
|
52
|
-
match = @balancer.extract_host_from_domain("foo.10.0.0.1.xip.io:1080")
|
53
|
-
expect(match).to_not be_nil
|
54
|
-
|
55
|
-
matching_string = match[1]
|
56
|
-
expect(matching_string).to eq("foo")
|
57
|
-
end
|
58
|
-
|
59
|
-
it "should match emacs.bar.10.0.0.1.xip.io" do
|
60
|
-
match = @balancer.extract_host_from_domain("emacs.bar.10.0.0.1.xip.io")
|
61
|
-
expect(match).to_not be_nil
|
62
|
-
|
63
|
-
matching_string = match[1]
|
64
|
-
expect(matching_string).to eq("bar")
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should match hello-world.10.0.0.1.xip.io" do
|
68
|
-
match = @balancer.extract_host_from_domain("hello-world.10.0.0.1.xip.io")
|
69
|
-
expect(match).to_not be_nil
|
70
|
-
|
71
|
-
matching_string = match[1]
|
72
|
-
expect(matching_string).to eq("hello-world")
|
16
|
+
it "should return 400 as response when Host is empty" do
|
17
|
+
headers = { 'Host' => '' }
|
18
|
+
@http_connection.expects(:send_data).with() { |value| value =~ /400 Bad Request/i }
|
19
|
+
@balancer.headers_received(headers)
|
73
20
|
end
|
74
21
|
end
|
75
22
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Invoker::Power::UrlRewriter do
|
4
|
+
let(:rewriter) { Invoker::Power::UrlRewriter.new }
|
5
|
+
|
6
|
+
context "matching domain part of incoming request" do
|
7
|
+
it "should do foo.dev match" do
|
8
|
+
match = rewriter.extract_host_from_domain("foo.dev")
|
9
|
+
expect(match).to_not be_empty
|
10
|
+
|
11
|
+
matching_string = match[0]
|
12
|
+
expect(matching_string).to eq("foo")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should match foo.dev:1080" do
|
16
|
+
match = rewriter.extract_host_from_domain("foo.dev:1080")
|
17
|
+
expect(match).to_not be_empty
|
18
|
+
|
19
|
+
matching_string = match[0]
|
20
|
+
expect(matching_string).to eq("foo")
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should match emacs.bar.dev" do
|
24
|
+
match = rewriter.extract_host_from_domain("emacs.bar.dev")
|
25
|
+
expect(match).to_not be_empty
|
26
|
+
|
27
|
+
expect(match[0]).to eq("emacs.bar")
|
28
|
+
expect(match[1]).to eq("bar")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should match hello-world.dev" do
|
32
|
+
match = rewriter.extract_host_from_domain("hello-world.dev")
|
33
|
+
expect(match).to_not be_nil
|
34
|
+
|
35
|
+
expect(match[0]).to eq("hello-world")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: invoker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hemant Kumar
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-11-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thor
|
@@ -224,6 +224,7 @@ files:
|
|
224
224
|
- Rakefile
|
225
225
|
- TODO
|
226
226
|
- bin/invoker
|
227
|
+
- contrib/completion/invoker-completion.bash
|
227
228
|
- contrib/completion/invoker-completion.zsh
|
228
229
|
- invoker.gemspec
|
229
230
|
- lib/invoker.rb
|
@@ -269,12 +270,16 @@ files:
|
|
269
270
|
- lib/invoker/power/setup.rb
|
270
271
|
- lib/invoker/power/setup/distro/arch.rb
|
271
272
|
- lib/invoker/power/setup/distro/base.rb
|
273
|
+
- lib/invoker/power/setup/distro/debian.rb
|
274
|
+
- lib/invoker/power/setup/distro/mint.rb
|
272
275
|
- lib/invoker/power/setup/distro/redhat.rb
|
273
276
|
- lib/invoker/power/setup/distro/ubuntu.rb
|
274
277
|
- lib/invoker/power/setup/linux_setup.rb
|
275
278
|
- lib/invoker/power/setup/osx_setup.rb
|
279
|
+
- lib/invoker/power/templates/400.html
|
276
280
|
- lib/invoker/power/templates/404.html
|
277
281
|
- lib/invoker/power/templates/503.html
|
282
|
+
- lib/invoker/power/url_rewriter.rb
|
278
283
|
- lib/invoker/process_manager.rb
|
279
284
|
- lib/invoker/process_printer.rb
|
280
285
|
- lib/invoker/reactor.rb
|
@@ -304,6 +309,7 @@ files:
|
|
304
309
|
- spec/invoker/power/setup/linux_setup_spec.rb
|
305
310
|
- spec/invoker/power/setup/osx_setup_spec.rb
|
306
311
|
- spec/invoker/power/setup_spec.rb
|
312
|
+
- spec/invoker/power/url_rewriter_spec.rb
|
307
313
|
- spec/invoker/process_manager_spec.rb
|
308
314
|
- spec/invoker/reactor_spec.rb
|
309
315
|
- spec/spec_helper.rb
|
@@ -328,7 +334,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
328
334
|
version: '0'
|
329
335
|
requirements: []
|
330
336
|
rubyforge_project:
|
331
|
-
rubygems_version: 2.
|
337
|
+
rubygems_version: 2.4.5.1
|
332
338
|
signing_key:
|
333
339
|
specification_version: 4
|
334
340
|
summary: Something small for Process management
|
@@ -356,8 +362,8 @@ test_files:
|
|
356
362
|
- spec/invoker/power/setup/linux_setup_spec.rb
|
357
363
|
- spec/invoker/power/setup/osx_setup_spec.rb
|
358
364
|
- spec/invoker/power/setup_spec.rb
|
365
|
+
- spec/invoker/power/url_rewriter_spec.rb
|
359
366
|
- spec/invoker/process_manager_spec.rb
|
360
367
|
- spec/invoker/reactor_spec.rb
|
361
368
|
- spec/spec_helper.rb
|
362
369
|
- spec/support/mock_setup_file.rb
|
363
|
-
has_rdoc:
|