invoker 1.4.1 → 1.5.1
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 +0 -1
- data/.rubocop.yml +0 -1
- data/.travis.yml +4 -2
- data/Dockerfile +7 -0
- data/Gemfile +3 -0
- data/Rakefile +8 -0
- data/examples/hello_sinatra.rb +26 -0
- data/examples/sample.ini +3 -0
- data/invoker.gemspec +2 -1
- data/lib/invoker.rb +20 -3
- data/lib/invoker/cli.rb +32 -6
- data/lib/invoker/dns_cache.rb +2 -2
- data/lib/invoker/ipc/add_http_command.rb +1 -1
- data/lib/invoker/ipc/dns_check_command.rb +2 -1
- data/lib/invoker/ipc/message.rb +2 -2
- data/lib/invoker/parsers/config.rb +4 -1
- data/lib/invoker/power/balancer.rb +16 -4
- data/lib/invoker/power/config.rb +3 -2
- data/lib/invoker/power/dns.rb +1 -1
- data/lib/invoker/power/pf_migrate.rb +1 -1
- data/lib/invoker/power/setup.rb +43 -4
- data/lib/invoker/power/setup/distro/arch.rb +1 -4
- data/lib/invoker/power/setup/distro/base.rb +23 -21
- data/lib/invoker/power/setup/distro/debian.rb +1 -1
- data/lib/invoker/power/setup/distro/opensuse.rb +11 -0
- data/lib/invoker/power/setup/distro/redhat.rb +1 -7
- data/lib/invoker/power/setup/files/invoker_forwarder.sh.erb +17 -0
- data/lib/invoker/power/setup/files/socat_invoker.service +12 -0
- data/lib/invoker/power/setup/linux_setup.rb +46 -29
- data/lib/invoker/power/setup/osx_setup.rb +16 -28
- data/lib/invoker/power/url_rewriter.rb +6 -3
- data/lib/invoker/process_manager.rb +13 -7
- data/lib/invoker/version.rb +1 -1
- data/readme.md +4 -4
- data/spec/invoker/commander_spec.rb +19 -8
- data/spec/invoker/config_spec.rb +22 -27
- data/spec/invoker/invoker_spec.rb +2 -1
- data/spec/invoker/ipc/client_handler_spec.rb +11 -1
- data/spec/invoker/power/config_spec.rb +2 -1
- data/spec/invoker/power/pf_migrate_spec.rb +7 -0
- data/spec/invoker/power/setup/linux_setup_spec.rb +57 -9
- data/spec/invoker/power/setup/osx_setup_spec.rb +22 -8
- data/spec/invoker/power/url_rewriter_spec.rb +33 -1
- data/spec/invoker/power/web_sockets_spec.rb +61 -0
- data/spec/invoker/process_manager_spec.rb +34 -2
- data/spec/spec_helper.rb +12 -16
- metadata +27 -35
- data/spec/support/mock_setup_file.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 35e208abbd4ff8979f1d1ecc0c5896ef3b460799
|
4
|
+
data.tar.gz: 6e2e65d581a9705f5358bf8076654a9b34185683
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44eecb467482053d584410fbc279c192e1dc25b7c97f245bf058f20e7bac0a12d9c0c73487d0ab0652d632030ef3f39741449dd5d30391104ef4ec9cc165091f
|
7
|
+
data.tar.gz: a4108aab6742c8b02886423a341c2d59c47deba5645d73b671686aff4cac4f7af668677645bb5444b8d37fe260afa8e05631ca249ba9d41f6bc9396426534a30
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/Dockerfile
ADDED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -5,3 +5,11 @@ RSpec::Core::RakeTask.new
|
|
5
5
|
|
6
6
|
task :default => :spec
|
7
7
|
task :test => :spec
|
8
|
+
|
9
|
+
current_directory = File.expand_path(File.dirname(__FILE__))
|
10
|
+
|
11
|
+
desc "run specs inside docker"
|
12
|
+
task :docker_spec do
|
13
|
+
system("docker build -t invoker-ruby . ")
|
14
|
+
system("docker run --name invoker-rspec --rm -v #{current_directory}:/invoker -t invoker-ruby")
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# myapp.rb
|
2
|
+
require 'sinatra'
|
3
|
+
|
4
|
+
get '/' do
|
5
|
+
'Hello world!'
|
6
|
+
end
|
7
|
+
|
8
|
+
get "/emacs" do
|
9
|
+
redirect to("/vim")
|
10
|
+
end
|
11
|
+
|
12
|
+
get "/vim" do
|
13
|
+
"vim rules"
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
post '/foo' do
|
18
|
+
puts request.env
|
19
|
+
"done"
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
post "/api/v1/datapoints" do
|
24
|
+
puts request.env
|
25
|
+
"done"
|
26
|
+
end
|
data/examples/sample.ini
ADDED
data/invoker.gemspec
CHANGED
@@ -35,8 +35,9 @@ Gem::Specification.new do |s|
|
|
35
35
|
s.add_dependency("uuid", "~> 2.3")
|
36
36
|
s.add_dependency("facter", "~> 2.2")
|
37
37
|
s.add_dependency("http-parser-lite", "~> 0.6")
|
38
|
-
s.add_dependency("dotenv", "~>
|
38
|
+
s.add_dependency("dotenv", "~> 2.0")
|
39
39
|
s.add_development_dependency("rspec", "~> 3.0")
|
40
40
|
s.add_development_dependency("mocha")
|
41
41
|
s.add_development_dependency("rake")
|
42
|
+
s.add_development_dependency('fakefs')
|
42
43
|
end
|
data/lib/invoker.rb
CHANGED
@@ -44,6 +44,10 @@ module Invoker
|
|
44
44
|
ruby_platform.downcase.include?("darwin")
|
45
45
|
end
|
46
46
|
|
47
|
+
def linux?
|
48
|
+
ruby_platform.downcase.include?("linux")
|
49
|
+
end
|
50
|
+
|
47
51
|
def ruby_platform
|
48
52
|
RUBY_PLATFORM
|
49
53
|
end
|
@@ -100,18 +104,27 @@ module Invoker
|
|
100
104
|
end
|
101
105
|
|
102
106
|
def notify_user(message)
|
103
|
-
|
107
|
+
if Invoker.darwin?
|
108
|
+
run_without_bundler { check_and_notify_with_terminal_notifier(message) }
|
109
|
+
elsif Invoker.linux?
|
110
|
+
notify_with_libnotify(message)
|
111
|
+
end
|
104
112
|
end
|
105
113
|
|
106
114
|
def check_and_notify_with_terminal_notifier(message)
|
107
|
-
return unless Invoker.darwin?
|
108
|
-
|
109
115
|
command_path = `which terminal-notifier`
|
110
116
|
if command_path && !command_path.empty?
|
111
117
|
system("terminal-notifier -message '#{message}' -title Invoker")
|
112
118
|
end
|
113
119
|
end
|
114
120
|
|
121
|
+
def notify_with_libnotify(message)
|
122
|
+
begin
|
123
|
+
require "libnotify"
|
124
|
+
Libnotify.show(body: message, summary: "Invoker", timeout: 2.5)
|
125
|
+
rescue LoadError; end
|
126
|
+
end
|
127
|
+
|
115
128
|
def migrate_old_config(old_config, config_location)
|
116
129
|
new_config = File.join(config_location, 'config')
|
117
130
|
File.open(new_config, 'w') do |file|
|
@@ -131,5 +144,9 @@ module Invoker
|
|
131
144
|
Etc.getpwuid(Process.uid).dir
|
132
145
|
end
|
133
146
|
end
|
147
|
+
|
148
|
+
def default_tld
|
149
|
+
'dev'
|
150
|
+
end
|
134
151
|
end
|
135
152
|
end
|
data/lib/invoker/cli.rb
CHANGED
@@ -13,8 +13,11 @@ module Invoker
|
|
13
13
|
end
|
14
14
|
|
15
15
|
desc "setup", "Run Invoker setup"
|
16
|
+
option :tld,
|
17
|
+
type: :string,
|
18
|
+
banner: 'Configure invoker to use a different top level domain'
|
16
19
|
def setup
|
17
|
-
Invoker::Power::Setup.install
|
20
|
+
Invoker::Power::Setup.install(get_tld(options))
|
18
21
|
end
|
19
22
|
|
20
23
|
desc "version", "Print Invoker version"
|
@@ -39,7 +42,7 @@ module Invoker
|
|
39
42
|
port = options[:port] || 9000
|
40
43
|
Invoker.daemonize = options[:daemon]
|
41
44
|
Invoker.load_invoker_config(file, port)
|
42
|
-
|
45
|
+
warn_about_notification
|
43
46
|
warn_about_old_configuration
|
44
47
|
pinger = Invoker::CLI::Pinger.new(unix_socket)
|
45
48
|
abort("Invoker is already running".color(:red)) if pinger.invoker_running?
|
@@ -51,9 +54,9 @@ module Invoker
|
|
51
54
|
unix_socket.send_command('add', process_name: name)
|
52
55
|
end
|
53
56
|
|
54
|
-
desc "add_http process_name port", "Add an external http process to Invoker DNS server"
|
55
|
-
def add_http(name, port)
|
56
|
-
unix_socket.send_command('add_http', process_name: name, port: port)
|
57
|
+
desc "add_http process_name port [IP]", "Add an external http process to Invoker DNS server"
|
58
|
+
def add_http(name, port, ip = nil)
|
59
|
+
unix_socket.send_command('add_http', process_name: name, port: port, ip: ip)
|
57
60
|
end
|
58
61
|
|
59
62
|
desc "tail process1 process2", "Tail a particular process"
|
@@ -105,12 +108,35 @@ module Invoker
|
|
105
108
|
tasks.keys + ["help"]
|
106
109
|
end
|
107
110
|
|
111
|
+
def get_tld(options)
|
112
|
+
if options[:tld] && !options[:tld].empty?
|
113
|
+
options[:tld]
|
114
|
+
else
|
115
|
+
'dev'
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
108
119
|
def unix_socket
|
109
120
|
Invoker::IPC::UnixClient.new
|
110
121
|
end
|
111
122
|
|
123
|
+
def warn_about_notification
|
124
|
+
if Invoker.darwin?
|
125
|
+
warn_about_terminal_notifier
|
126
|
+
else
|
127
|
+
warn_about_libnotify
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def warn_about_libnotify
|
132
|
+
require "libnotify"
|
133
|
+
rescue LoadError
|
134
|
+
Invoker::Logger.puts "You can install libnotify gem for Invoker notifications "\
|
135
|
+
"via system tray".color(:red)
|
136
|
+
end
|
137
|
+
|
112
138
|
def warn_about_terminal_notifier
|
113
|
-
if
|
139
|
+
if Invoker.darwin?
|
114
140
|
command_path = `which terminal-notifier`
|
115
141
|
if !command_path || command_path.empty?
|
116
142
|
Invoker::Logger.puts "You can enable OSX notification for processes "\
|
data/lib/invoker/dns_cache.rb
CHANGED
@@ -16,8 +16,8 @@ module Invoker
|
|
16
16
|
@dns_mutex.synchronize { dns_data[process_name] }
|
17
17
|
end
|
18
18
|
|
19
|
-
def add(name, port)
|
20
|
-
@dns_mutex.synchronize { dns_data[name] = { 'port' => port } }
|
19
|
+
def add(name, port, ip = nil)
|
20
|
+
@dns_mutex.synchronize { dns_data[name] = { 'port' => port, 'ip' => ip } }
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -2,7 +2,7 @@ module Invoker
|
|
2
2
|
module IPC
|
3
3
|
class AddHttpCommand < BaseCommand
|
4
4
|
def run_command(message_object)
|
5
|
-
Invoker.dns_cache.add(message_object.process_name, message_object.port)
|
5
|
+
Invoker.dns_cache.add(message_object.process_name, message_object.port, message_object.ip)
|
6
6
|
true
|
7
7
|
end
|
8
8
|
end
|
@@ -6,7 +6,8 @@ module Invoker
|
|
6
6
|
|
7
7
|
dns_check_response = Invoker::IPC::Message::DnsCheckResponse.new(
|
8
8
|
process_name: message_object.process_name,
|
9
|
-
port: process_detail ? process_detail['port'] : nil
|
9
|
+
port: process_detail ? process_detail['port'] : nil,
|
10
|
+
ip: process_detail && process_detail['ip'] ? process_detail['ip'] : '0.0.0.0'
|
10
11
|
)
|
11
12
|
send_data(dns_check_response)
|
12
13
|
true
|
data/lib/invoker/ipc/message.rb
CHANGED
@@ -118,7 +118,7 @@ module Invoker
|
|
118
118
|
|
119
119
|
class AddHttp < Base
|
120
120
|
include Serialization
|
121
|
-
message_attributes :process_name, :port
|
121
|
+
message_attributes :process_name, :port, :ip
|
122
122
|
end
|
123
123
|
|
124
124
|
class Reload < Base
|
@@ -151,7 +151,7 @@ module Invoker
|
|
151
151
|
|
152
152
|
class DnsCheckResponse < Base
|
153
153
|
include Serialization
|
154
|
-
message_attributes :process_name, :port
|
154
|
+
message_attributes :process_name, :port, :ip
|
155
155
|
end
|
156
156
|
|
157
157
|
class Ping < Base
|
@@ -16,7 +16,6 @@ module Invoker
|
|
16
16
|
# value by 1, that way generating different ports for different commands.
|
17
17
|
def initialize(filename, port)
|
18
18
|
@filename = filename || autodetect_config_file
|
19
|
-
|
20
19
|
print_message_and_abort if invalid_config_file?
|
21
20
|
|
22
21
|
@port = port - 1
|
@@ -38,6 +37,10 @@ module Invoker
|
|
38
37
|
power_config && power_config.https_port
|
39
38
|
end
|
40
39
|
|
40
|
+
def tld
|
41
|
+
power_config && power_config.tld
|
42
|
+
end
|
43
|
+
|
41
44
|
def autorunnable_processes
|
42
45
|
processes.reject(&:disable_autorun)
|
43
46
|
end
|
@@ -22,7 +22,7 @@ module Invoker
|
|
22
22
|
end
|
23
23
|
|
24
24
|
class Balancer
|
25
|
-
attr_accessor :connection, :http_parser, :session, :protocol
|
25
|
+
attr_accessor :connection, :http_parser, :session, :protocol, :upgraded_to
|
26
26
|
|
27
27
|
def self.run(options = {})
|
28
28
|
start_http_proxy(InvokerHttpProxy, 'http', options)
|
@@ -43,6 +43,7 @@ module Invoker
|
|
43
43
|
@protocol = protocol
|
44
44
|
@http_parser = HttpParser.new(protocol)
|
45
45
|
@session = nil
|
46
|
+
@upgraded_to = nil
|
46
47
|
@buffer = []
|
47
48
|
end
|
48
49
|
|
@@ -71,7 +72,7 @@ module Invoker
|
|
71
72
|
|
72
73
|
dns_check_response = UrlRewriter.new.select_backend_config(headers['Host'])
|
73
74
|
if dns_check_response && dns_check_response.port
|
74
|
-
connection.server(session, host:
|
75
|
+
connection.server(session, host: dns_check_response.ip, port: dns_check_response.port)
|
75
76
|
else
|
76
77
|
return_error_page(404)
|
77
78
|
http_parser.reset
|
@@ -80,8 +81,12 @@ module Invoker
|
|
80
81
|
end
|
81
82
|
|
82
83
|
def upstream_data(data)
|
83
|
-
|
84
|
-
|
84
|
+
if upgraded_to == "websocket"
|
85
|
+
data
|
86
|
+
else
|
87
|
+
append_for_http_parsing(data)
|
88
|
+
nil
|
89
|
+
end
|
85
90
|
end
|
86
91
|
|
87
92
|
def append_for_http_parsing(data)
|
@@ -93,6 +98,13 @@ module Invoker
|
|
93
98
|
|
94
99
|
def backend_data(backend, data)
|
95
100
|
@backend_data = true
|
101
|
+
|
102
|
+
# check backend data for websockets connection. check for upgrade headers
|
103
|
+
# - Upgarde: websocket\r\n
|
104
|
+
if data =~ /Upgrade: websocket/
|
105
|
+
@upgraded_to = "websocket"
|
106
|
+
end
|
107
|
+
|
96
108
|
data
|
97
109
|
end
|
98
110
|
|
data/lib/invoker/power/config.rb
CHANGED
@@ -60,9 +60,10 @@ module Invoker
|
|
60
60
|
def dns_port; @config[:dns_port]; end
|
61
61
|
def http_port; @config[:http_port]; end
|
62
62
|
def ipfw_rule_number; @config[:ipfw_rule_number]; end
|
63
|
+
def https_port; @config[:https_port]; end
|
63
64
|
|
64
|
-
def
|
65
|
-
@config[:
|
65
|
+
def tld
|
66
|
+
@config[:tld] || Invoker.default_tld
|
66
67
|
end
|
67
68
|
|
68
69
|
def save
|
data/lib/invoker/power/dns.rb
CHANGED
@@ -13,7 +13,7 @@ module Invoker
|
|
13
13
|
def migrate
|
14
14
|
if firewall_config_requires_migration? && ask_user_for_migration
|
15
15
|
sudome
|
16
|
-
osx_setup = Invoker::Power::OsxSetup.new()
|
16
|
+
osx_setup = Invoker::Power::OsxSetup.new(Invoker.config.tld)
|
17
17
|
osx_setup.install_firewall(Invoker.config.http_port, Invoker.config.https_port)
|
18
18
|
drop_to_normal_user
|
19
19
|
Invoker::Logger.puts "Invoker has updated its configuration for yosemite."\
|
data/lib/invoker/power/setup.rb
CHANGED
@@ -3,15 +3,17 @@ require "eventmachine"
|
|
3
3
|
module Invoker
|
4
4
|
module Power
|
5
5
|
class Setup
|
6
|
-
attr_accessor :port_finder
|
7
|
-
|
6
|
+
attr_accessor :port_finder, :tld
|
7
|
+
|
8
|
+
def self.install(tld)
|
8
9
|
selected_installer_klass = installer_klass
|
9
|
-
selected_installer_klass.new.install
|
10
|
+
selected_installer_klass.new(tld).install
|
10
11
|
end
|
11
12
|
|
12
13
|
def self.uninstall
|
14
|
+
power_config = Invoker::Power::Config.load_config
|
13
15
|
selected_installer_klass = installer_klass
|
14
|
-
selected_installer_klass.new.uninstall_invoker
|
16
|
+
selected_installer_klass.new(power_config.tld).uninstall_invoker
|
15
17
|
end
|
16
18
|
|
17
19
|
def self.installer_klass
|
@@ -22,6 +24,14 @@ module Invoker
|
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
27
|
+
def initialize(tld)
|
28
|
+
if tld !~ /^[a-z]+$/
|
29
|
+
Invoker::Logger.puts("Please specify valid tld".color(:red))
|
30
|
+
exit(1)
|
31
|
+
end
|
32
|
+
self.tld = tld
|
33
|
+
end
|
34
|
+
|
25
35
|
def install
|
26
36
|
if check_if_setup_can_run?
|
27
37
|
setup_invoker
|
@@ -46,6 +56,35 @@ module Invoker
|
|
46
56
|
def check_if_setup_can_run?
|
47
57
|
!File.exists?(Invoker::Power::Config.config_file)
|
48
58
|
end
|
59
|
+
|
60
|
+
def create_config_file
|
61
|
+
Invoker.setup_config_location
|
62
|
+
config = build_power_config
|
63
|
+
Invoker::Power::Config.create(config)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Builds and returns power config hash. Override this method in subclasses if necessary.
|
67
|
+
def build_power_config
|
68
|
+
config = {
|
69
|
+
http_port: port_finder.http_port,
|
70
|
+
https_port: port_finder.https_port,
|
71
|
+
tld: tld
|
72
|
+
}
|
73
|
+
config
|
74
|
+
end
|
75
|
+
|
76
|
+
def remove_resolver_file
|
77
|
+
begin
|
78
|
+
safe_remove_file(resolver_file)
|
79
|
+
rescue Errno::EACCES
|
80
|
+
Invoker::Logger.puts("Running uninstall requires root access, please rerun it with sudo".color(:red))
|
81
|
+
raise
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def safe_remove_file(file)
|
86
|
+
File.delete(file) if File.exists?(file)
|
87
|
+
end
|
49
88
|
end
|
50
89
|
end
|
51
90
|
end
|