invoker 1.5.3 → 1.5.8
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 +5 -5
- data/lib/invoker.rb +5 -6
- data/lib/invoker/cli.rb +47 -14
- data/lib/invoker/command_worker.rb +6 -2
- data/lib/invoker/commander.rb +8 -2
- data/lib/invoker/ipc/unix_client.rb +2 -2
- data/lib/invoker/parsers/config.rb +3 -3
- data/lib/invoker/power/balancer.rb +6 -4
- data/lib/invoker/power/setup.rb +9 -6
- data/lib/invoker/power/setup/distro/base.rb +36 -13
- data/lib/invoker/power/setup/distro/ubuntu.rb +36 -0
- data/lib/invoker/power/setup/linux_setup.rb +11 -19
- data/lib/invoker/power/setup/osx_setup.rb +4 -4
- data/lib/invoker/process_manager.rb +7 -4
- data/lib/invoker/process_printer.rb +16 -0
- data/lib/invoker/reactor/reader.rb +17 -6
- data/lib/invoker/version.rb +1 -1
- data/spec/invoker/config_spec.rb +4 -4
- data/spec/invoker/power/balancer_spec.rb +31 -0
- data/spec/invoker/power/setup/linux_setup_spec.rb +97 -34
- data/spec/invoker/power/url_rewriter_spec.rb +24 -25
- data/spec/spec_helper.rb +3 -3
- metadata +56 -69
- data/.coveralls.yml +0 -1
- data/.gitignore +0 -16
- data/.rspec +0 -2
- data/.rubocop.yml +0 -29
- data/.travis.yml +0 -10
- data/Dockerfile +0 -7
- data/Gemfile +0 -13
- data/MIT-LICENSE +0 -20
- data/Rakefile +0 -15
- data/TODO +0 -5
- data/contrib/completion/invoker-completion.bash +0 -70
- data/contrib/completion/invoker-completion.zsh +0 -62
- data/examples/hello_sinatra.rb +0 -26
- data/examples/sample.ini +0 -3
- data/invoker.gemspec +0 -43
- data/lib/invoker/power/pf_migrate.rb +0 -64
- data/lib/invoker/power/setup/distro/mint.rb +0 -10
- data/readme.md +0 -25
- data/spec/invoker/power/pf_migrate_spec.rb +0 -87
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b853190df0eac206efeac859446934d0e1b6df0fa93ad88d1ef950c2b9e30143
|
4
|
+
data.tar.gz: 127d6df5d280e555ed05b8b3449bfcc100ae6d9efb5bb447e01eaeedef16bef9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75ce1dd71098a4f5306797a8bc7ef82b7dafdbf21160a8633526fa697a4925b420d6f7ba8a3fcb230009fafa3d95e269bc384bffaa3dc7313996b689f2d00383
|
7
|
+
data.tar.gz: 3328f736e84fd2e681c59338c416b111c77199f0cdc01d06e2297ec5b82b3b9cc7b63d94bcaf77f6b68dd7c1be315936786e66014f135ad1be77fa68ef8631dd
|
data/lib/invoker.rb
CHANGED
@@ -6,8 +6,7 @@ require "formatador"
|
|
6
6
|
require "ostruct"
|
7
7
|
require "uuid"
|
8
8
|
require "json"
|
9
|
-
require "
|
10
|
-
require "rainbow/ext/string"
|
9
|
+
require "colorize"
|
11
10
|
require "etc"
|
12
11
|
|
13
12
|
require "invoker/version"
|
@@ -22,7 +21,6 @@ require "invoker/power/setup"
|
|
22
21
|
require "invoker/power/setup/linux_setup"
|
23
22
|
require "invoker/power/setup/osx_setup"
|
24
23
|
require "invoker/power/powerup"
|
25
|
-
require "invoker/power/pf_migrate"
|
26
24
|
require "invoker/errors"
|
27
25
|
require "invoker/parsers/procfile"
|
28
26
|
require "invoker/parsers/config"
|
@@ -36,9 +34,10 @@ require "invoker/process_printer"
|
|
36
34
|
module Invoker
|
37
35
|
class << self
|
38
36
|
attr_accessor :config, :tail_watchers, :commander
|
39
|
-
attr_accessor :dns_cache, :daemonize
|
37
|
+
attr_accessor :dns_cache, :daemonize, :nocolors, :certificate, :private_key
|
40
38
|
|
41
39
|
alias_method :daemonize?, :daemonize
|
40
|
+
alias_method :nocolors?, :nocolors
|
42
41
|
|
43
42
|
def darwin?
|
44
43
|
ruby_platform.downcase.include?("darwin")
|
@@ -73,7 +72,7 @@ module Invoker
|
|
73
72
|
return true if File.exist?(Invoker::Power::Config.config_file)
|
74
73
|
|
75
74
|
if throw_warning
|
76
|
-
Invoker::Logger.puts("Invoker has detected setup has not been run. Domain feature will not work without running setup command.".
|
75
|
+
Invoker::Logger.puts("Invoker has detected setup has not been run. Domain feature will not work without running setup command.".colorize(:red))
|
77
76
|
end
|
78
77
|
false
|
79
78
|
end
|
@@ -146,7 +145,7 @@ module Invoker
|
|
146
145
|
end
|
147
146
|
|
148
147
|
def default_tld
|
149
|
-
'
|
148
|
+
'test'
|
150
149
|
end
|
151
150
|
end
|
152
151
|
end
|
data/lib/invoker/cli.rb
CHANGED
@@ -19,6 +19,7 @@ module Invoker
|
|
19
19
|
def setup
|
20
20
|
Invoker::Power::Setup.install(get_tld(options))
|
21
21
|
end
|
22
|
+
map install: :setup
|
22
23
|
|
23
24
|
desc "version", "Print Invoker version"
|
24
25
|
def version
|
@@ -37,15 +38,27 @@ module Invoker
|
|
37
38
|
type: :boolean,
|
38
39
|
banner: "Daemonize the server into the background",
|
39
40
|
aliases: [:d]
|
41
|
+
option :nocolors,
|
42
|
+
type: :boolean,
|
43
|
+
banner: "Disable color in output",
|
44
|
+
aliases: [:nc]
|
45
|
+
option :certificate,
|
46
|
+
type: :string,
|
47
|
+
banner: "Path to certificate"
|
48
|
+
option :private_key,
|
49
|
+
type: :string,
|
50
|
+
banner: "Path to private key"
|
40
51
|
def start(file = nil)
|
41
52
|
Invoker.setup_config_location
|
42
53
|
port = options[:port] || 9000
|
43
54
|
Invoker.daemonize = options[:daemon]
|
55
|
+
Invoker.nocolors = options[:nocolors]
|
56
|
+
Invoker.certificate = options[:certificate]
|
57
|
+
Invoker.private_key = options[:private_key]
|
44
58
|
Invoker.load_invoker_config(file, port)
|
45
59
|
warn_about_notification
|
46
|
-
warn_about_old_configuration
|
47
60
|
pinger = Invoker::CLI::Pinger.new(unix_socket)
|
48
|
-
abort("Invoker is already running".
|
61
|
+
abort("Invoker is already running".colorize(:red)) if pinger.invoker_running?
|
49
62
|
Invoker.commander.start_manager
|
50
63
|
end
|
51
64
|
|
@@ -78,11 +91,35 @@ module Invoker
|
|
78
91
|
signal = options[:signal] || 'INT'
|
79
92
|
unix_socket.send_command('reload', process_name: name, signal: signal)
|
80
93
|
end
|
94
|
+
map restart: :reload
|
81
95
|
|
82
96
|
desc "list", "List all running processes"
|
97
|
+
option :raw,
|
98
|
+
type: :boolean,
|
99
|
+
banner: "Print process list in raw text format",
|
100
|
+
aliases: [:r]
|
101
|
+
option :wait,
|
102
|
+
type: :boolean,
|
103
|
+
banner: "wait for update",
|
104
|
+
aliases: [:w]
|
83
105
|
def list
|
84
|
-
|
85
|
-
|
106
|
+
if options[:wait]
|
107
|
+
Signal.trap("INT") { exit(0) }
|
108
|
+
loop do
|
109
|
+
puts "\e[H\e[2J"
|
110
|
+
unix_socket.send_command('list') do |response_object|
|
111
|
+
Invoker::ProcessPrinter.new(response_object).tap { |printer| printer.print_table }
|
112
|
+
end
|
113
|
+
sleep(5)
|
114
|
+
end
|
115
|
+
else
|
116
|
+
unix_socket.send_command('list') do |response_object|
|
117
|
+
if options[:raw]
|
118
|
+
Invoker::ProcessPrinter.new(response_object).tap { |printer| printer.print_raw_text }
|
119
|
+
else
|
120
|
+
Invoker::ProcessPrinter.new(response_object).tap { |printer| printer.print_table }
|
121
|
+
end
|
122
|
+
end
|
86
123
|
end
|
87
124
|
end
|
88
125
|
|
@@ -110,14 +147,16 @@ module Invoker
|
|
110
147
|
end
|
111
148
|
|
112
149
|
def self.valid_tasks
|
113
|
-
tasks.keys +
|
150
|
+
tasks.keys + %w(help install restart)
|
114
151
|
end
|
115
152
|
|
153
|
+
# TODO(kgrz): the default TLD option is duplicated in both this file and
|
154
|
+
# lib/invoker.rb May be assign this to a constant?
|
116
155
|
def get_tld(options)
|
117
156
|
if options[:tld] && !options[:tld].empty?
|
118
157
|
options[:tld]
|
119
158
|
else
|
120
|
-
'
|
159
|
+
'test'
|
121
160
|
end
|
122
161
|
end
|
123
162
|
|
@@ -137,7 +176,7 @@ module Invoker
|
|
137
176
|
require "libnotify"
|
138
177
|
rescue LoadError
|
139
178
|
Invoker::Logger.puts "You can install libnotify gem for Invoker notifications "\
|
140
|
-
"via system tray".
|
179
|
+
"via system tray".colorize(:red)
|
141
180
|
end
|
142
181
|
|
143
182
|
def warn_about_terminal_notifier
|
@@ -145,16 +184,10 @@ module Invoker
|
|
145
184
|
command_path = `which terminal-notifier`
|
146
185
|
if !command_path || command_path.empty?
|
147
186
|
Invoker::Logger.puts "You can enable OSX notification for processes "\
|
148
|
-
"by installing terminal-notifier gem".
|
187
|
+
"by installing terminal-notifier gem".colorize(:red)
|
149
188
|
end
|
150
189
|
end
|
151
190
|
end
|
152
|
-
|
153
|
-
def warn_about_old_configuration
|
154
|
-
Invoker::Power::PfMigrate.new.tap do |pf_migrator|
|
155
|
-
pf_migrator.migrate
|
156
|
-
end
|
157
|
-
end
|
158
191
|
end
|
159
192
|
end
|
160
193
|
|
@@ -25,9 +25,13 @@ module Invoker
|
|
25
25
|
# Print the lines received over the network
|
26
26
|
def receive_line(line)
|
27
27
|
tail_watchers = Invoker.tail_watchers[@command_label]
|
28
|
-
color_line = "#{@command_label.
|
28
|
+
color_line = "#{@command_label.colorize(color)} : #{line}"
|
29
29
|
plain_line = "#{@command_label} : #{line}"
|
30
|
-
Invoker
|
30
|
+
if Invoker.nocolors?
|
31
|
+
Invoker::Logger.puts plain_line
|
32
|
+
else
|
33
|
+
Invoker::Logger.puts color_line
|
34
|
+
end
|
31
35
|
if tail_watchers && !tail_watchers.empty?
|
32
36
|
json_encoded_tail_response = tail_response(color_line)
|
33
37
|
if json_encoded_tail_response
|
data/lib/invoker/commander.rb
CHANGED
@@ -82,10 +82,16 @@ module Invoker
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def install_interrupt_handler
|
85
|
-
Signal.trap("INT")
|
85
|
+
Signal.trap("INT") {
|
86
|
+
Invoker::Logger.puts("Stopping invoker")
|
86
87
|
process_manager.kill_workers
|
87
88
|
exit(0)
|
88
|
-
|
89
|
+
}
|
90
|
+
Signal.trap("TERM") {
|
91
|
+
Invoker::Logger.puts("Stopping invoker")
|
92
|
+
process_manager.kill_workers
|
93
|
+
exit(0)
|
94
|
+
}
|
89
95
|
end
|
90
96
|
|
91
97
|
def daemonize_app
|
@@ -28,7 +28,7 @@ module Invoker
|
|
28
28
|
begin
|
29
29
|
socket = Socket.unix(Invoker::IPC::Server::SOCKET_PATH)
|
30
30
|
rescue
|
31
|
-
abort("Invoker does not seem to be running".
|
31
|
+
abort("Invoker does not seem to be running".colorize(:red))
|
32
32
|
end
|
33
33
|
message_object = get_message_object(command, message)
|
34
34
|
send_json_message(socket, message_object)
|
@@ -49,7 +49,7 @@ module Invoker
|
|
49
49
|
def open_client_socket(abort_if_not_running = true)
|
50
50
|
Socket.unix(Invoker::IPC::Server::SOCKET_PATH) { |socket| yield socket }
|
51
51
|
rescue
|
52
|
-
abort_if_not_running && abort("Invoker does not seem to be running".
|
52
|
+
abort_if_not_running && abort("Invoker does not seem to be running".colorize(:red))
|
53
53
|
end
|
54
54
|
|
55
55
|
def send_json_message(socket, message_object)
|
@@ -90,7 +90,7 @@ module Invoker
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def print_message_and_abort
|
93
|
-
Invoker::Logger.puts("\n Invalid config file. Invoker requires an ini or a Procfile.".
|
93
|
+
Invoker::Logger.puts("\n Invalid config file. Invoker requires an ini or a Procfile.".colorize(:red))
|
94
94
|
abort
|
95
95
|
end
|
96
96
|
|
@@ -133,10 +133,10 @@ module Invoker
|
|
133
133
|
end
|
134
134
|
|
135
135
|
sleep_duration = section['sleep'].to_i
|
136
|
-
if sleep_duration
|
136
|
+
if sleep_duration >= 0
|
137
137
|
pconfig['sleep_duration'] = sleep_duration
|
138
138
|
else
|
139
|
-
pconfig['sleep_duration'] =
|
139
|
+
pconfig['sleep_duration'] = 0
|
140
140
|
end
|
141
141
|
|
142
142
|
OpenStruct.new(pconfig)
|
@@ -17,7 +17,7 @@ module Invoker
|
|
17
17
|
class InvokerHttpsProxy < InvokerHttpProxy
|
18
18
|
def post_init
|
19
19
|
super
|
20
|
-
start_tls
|
20
|
+
start_tls(private_key_file: Invoker.private_key, cert_chain_file: Invoker.certificate)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -65,12 +65,14 @@ module Invoker
|
|
65
65
|
return
|
66
66
|
end
|
67
67
|
@session = UUID.generate()
|
68
|
-
|
68
|
+
headers = headers.transform_keys(&:downcase)
|
69
|
+
|
70
|
+
if !headers['host'] || headers['host'].empty?
|
69
71
|
return_error_page(400)
|
70
72
|
return
|
71
73
|
end
|
72
74
|
|
73
|
-
dns_check_response = UrlRewriter.new.select_backend_config(headers['
|
75
|
+
dns_check_response = UrlRewriter.new.select_backend_config(headers['host'])
|
74
76
|
if dns_check_response && dns_check_response.port
|
75
77
|
connection.server(session, host: dns_check_response.ip, port: dns_check_response.port)
|
76
78
|
else
|
@@ -100,7 +102,7 @@ module Invoker
|
|
100
102
|
@backend_data = true
|
101
103
|
|
102
104
|
# check backend data for websockets connection. check for upgrade headers
|
103
|
-
# -
|
105
|
+
# - Upgrade: websocket\r\n
|
104
106
|
if data =~ /Upgrade: websocket/
|
105
107
|
@upgraded_to = "websocket"
|
106
108
|
end
|
data/lib/invoker/power/setup.rb
CHANGED
@@ -11,9 +11,11 @@ module Invoker
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.uninstall
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
if Invoker::Power::Config.has_config?
|
15
|
+
power_config = Invoker::Power::Config.load_config
|
16
|
+
selected_installer_klass = installer_klass
|
17
|
+
selected_installer_klass.new(power_config.tld).uninstall_invoker
|
18
|
+
end
|
17
19
|
end
|
18
20
|
|
19
21
|
def self.installer_klass
|
@@ -26,7 +28,7 @@ module Invoker
|
|
26
28
|
|
27
29
|
def initialize(tld)
|
28
30
|
if tld !~ /^[a-z]+$/
|
29
|
-
Invoker::Logger.puts("Please specify valid tld".
|
31
|
+
Invoker::Logger.puts("Please specify valid tld".colorize(:red))
|
30
32
|
exit(1)
|
31
33
|
end
|
32
34
|
self.tld = tld
|
@@ -36,7 +38,7 @@ module Invoker
|
|
36
38
|
if check_if_setup_can_run?
|
37
39
|
setup_invoker
|
38
40
|
else
|
39
|
-
Invoker::Logger.puts("The setup has been already run.".
|
41
|
+
Invoker::Logger.puts("The setup has been already run.".colorize(:red))
|
40
42
|
end
|
41
43
|
self
|
42
44
|
end
|
@@ -74,10 +76,11 @@ module Invoker
|
|
74
76
|
end
|
75
77
|
|
76
78
|
def remove_resolver_file
|
79
|
+
return if resolver_file.nil?
|
77
80
|
begin
|
78
81
|
safe_remove_file(resolver_file)
|
79
82
|
rescue Errno::EACCES
|
80
|
-
Invoker::Logger.puts("Running uninstall requires root access, please rerun it with sudo".
|
83
|
+
Invoker::Logger.puts("Running uninstall requires root access, please rerun it with sudo".colorize(:red))
|
81
84
|
raise
|
82
85
|
end
|
83
86
|
end
|
@@ -12,23 +12,19 @@ module Invoker
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.distro_installer(tld)
|
15
|
-
|
16
|
-
when "Ubuntu"
|
17
|
-
require "invoker/power/setup/distro/ubuntu"
|
18
|
-
Ubuntu.new(tld)
|
19
|
-
when "Fedora"
|
20
|
-
require "invoker/power/setup/distro/redhat"
|
21
|
-
Redhat.new(tld)
|
22
|
-
when "Archlinux"
|
15
|
+
if distro.start_with? "Arch Linux", "Manjaro Linux"
|
23
16
|
require "invoker/power/setup/distro/arch"
|
24
17
|
Arch.new(tld)
|
25
|
-
|
18
|
+
elsif distro.start_with? "Debian"
|
26
19
|
require "invoker/power/setup/distro/debian"
|
27
20
|
Debian.new(tld)
|
28
|
-
|
29
|
-
require "invoker/power/setup/distro/
|
30
|
-
|
31
|
-
|
21
|
+
elsif distro.start_with? "Fedora"
|
22
|
+
require "invoker/power/setup/distro/redhat"
|
23
|
+
Redhat.new(tld)
|
24
|
+
elsif distro.start_with? "Linux Mint", "Ubuntu"
|
25
|
+
require "invoker/power/setup/distro/ubuntu"
|
26
|
+
Ubuntu.new(tld)
|
27
|
+
elsif distro.start_with? "openSUSE"
|
32
28
|
require "invoker/power/setup/distro/opensuse"
|
33
29
|
Opensuse.new(tld)
|
34
30
|
else
|
@@ -36,6 +32,17 @@ module Invoker
|
|
36
32
|
end
|
37
33
|
end
|
38
34
|
|
35
|
+
def self.distro
|
36
|
+
@distro ||= if File.exist?('/etc/os-release')
|
37
|
+
File.read('/etc/os-release').each_line do |line|
|
38
|
+
parsed_line = line.chomp.tr('"', '').split('=')
|
39
|
+
break parsed_line[1] if parsed_line[0] == 'NAME'
|
40
|
+
end
|
41
|
+
else
|
42
|
+
raise "File /etc/os-release doesn't exist or not Linux"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
39
46
|
def initialize(tld)
|
40
47
|
self.tld = tld
|
41
48
|
end
|
@@ -51,6 +58,22 @@ module Invoker
|
|
51
58
|
system("systemctl start socat_invoker.service")
|
52
59
|
system("systemctl restart dnsmasq")
|
53
60
|
end
|
61
|
+
|
62
|
+
def install_packages
|
63
|
+
"dnsmasq and socat"
|
64
|
+
end
|
65
|
+
|
66
|
+
def install_other
|
67
|
+
" a local resolver for .#{tld} domain and"
|
68
|
+
end
|
69
|
+
|
70
|
+
def get_user_confirmation?
|
71
|
+
Invoker::Logger.puts("Invoker is going to install #{install_packages} on this machine."\
|
72
|
+
" It is also going to install#{install_other} a socat service"\
|
73
|
+
" which will forward all local requests on port 80 and 443 to another port")
|
74
|
+
Invoker::Logger.puts("If you still want to proceed with installation, press y.")
|
75
|
+
Invoker::CLI::Question.agree("Proceed with installation (y/n) : ")
|
76
|
+
end
|
54
77
|
end
|
55
78
|
end
|
56
79
|
end
|
@@ -4,6 +4,42 @@ module Invoker
|
|
4
4
|
module Power
|
5
5
|
module Distro
|
6
6
|
class Ubuntu < Debian
|
7
|
+
def using_systemd_resolved?
|
8
|
+
return @_using_systemd_resolved if defined?(@_using_systemd_resolved)
|
9
|
+
@_using_systemd_resolved = system("systemctl is-active --quiet systemd-resolved")
|
10
|
+
end
|
11
|
+
|
12
|
+
def install_required_software
|
13
|
+
if using_systemd_resolved?
|
14
|
+
# Don't install dnsmasq if Ubuntu version uses systemd-resolved for DNS because they conflict
|
15
|
+
system("apt-get --assume-yes install socat")
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def install_packages
|
22
|
+
using_systemd_resolved? ? "socat" : super
|
23
|
+
end
|
24
|
+
|
25
|
+
def install_other
|
26
|
+
using_systemd_resolved? ? nil : super
|
27
|
+
end
|
28
|
+
|
29
|
+
def resolver_file
|
30
|
+
using_systemd_resolved? ? nil : super
|
31
|
+
end
|
32
|
+
|
33
|
+
def tld
|
34
|
+
using_systemd_resolved? ? 'localhost' : @tld
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_user_confirmation?
|
38
|
+
if using_systemd_resolved? && tld != 'localhost'
|
39
|
+
Invoker::Logger.puts("Ubuntu installations using systemd-resolved (typically Ubuntu 17+) only support the .localhost domain, so your tld setting (or the default) will be ignored.".colorize(:yellow))
|
40
|
+
end
|
41
|
+
super
|
42
|
+
end
|
7
43
|
end
|
8
44
|
end
|
9
45
|
end
|