itrg-invoker 1.6.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.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/bin/invoker +7 -0
  3. data/lib/invoker/cli/pinger.rb +23 -0
  4. data/lib/invoker/cli/question.rb +15 -0
  5. data/lib/invoker/cli/tail.rb +34 -0
  6. data/lib/invoker/cli/tail_watcher.rb +34 -0
  7. data/lib/invoker/cli.rb +197 -0
  8. data/lib/invoker/command_worker.rb +64 -0
  9. data/lib/invoker/commander.rb +101 -0
  10. data/lib/invoker/daemon.rb +126 -0
  11. data/lib/invoker/dns_cache.rb +23 -0
  12. data/lib/invoker/errors.rb +17 -0
  13. data/lib/invoker/event/manager.rb +79 -0
  14. data/lib/invoker/ipc/add_command.rb +12 -0
  15. data/lib/invoker/ipc/add_http_command.rb +10 -0
  16. data/lib/invoker/ipc/base_command.rb +24 -0
  17. data/lib/invoker/ipc/client_handler.rb +26 -0
  18. data/lib/invoker/ipc/dns_check_command.rb +17 -0
  19. data/lib/invoker/ipc/list_command.rb +11 -0
  20. data/lib/invoker/ipc/message/list_response.rb +35 -0
  21. data/lib/invoker/ipc/message/tail_response.rb +10 -0
  22. data/lib/invoker/ipc/message.rb +170 -0
  23. data/lib/invoker/ipc/ping_command.rb +10 -0
  24. data/lib/invoker/ipc/reload_command.rb +12 -0
  25. data/lib/invoker/ipc/remove_command.rb +12 -0
  26. data/lib/invoker/ipc/server.rb +26 -0
  27. data/lib/invoker/ipc/tail_command.rb +11 -0
  28. data/lib/invoker/ipc/unix_client.rb +60 -0
  29. data/lib/invoker/ipc.rb +45 -0
  30. data/lib/invoker/logger.rb +13 -0
  31. data/lib/invoker/parsers/config.rb +184 -0
  32. data/lib/invoker/parsers/procfile.rb +86 -0
  33. data/lib/invoker/power/balancer.rb +133 -0
  34. data/lib/invoker/power/config.rb +77 -0
  35. data/lib/invoker/power/dns.rb +38 -0
  36. data/lib/invoker/power/http_parser.rb +68 -0
  37. data/lib/invoker/power/http_response.rb +81 -0
  38. data/lib/invoker/power/port_finder.rb +49 -0
  39. data/lib/invoker/power/power.rb +3 -0
  40. data/lib/invoker/power/powerup.rb +29 -0
  41. data/lib/invoker/power/setup/distro/arch.rb +15 -0
  42. data/lib/invoker/power/setup/distro/base.rb +80 -0
  43. data/lib/invoker/power/setup/distro/debian.rb +11 -0
  44. data/lib/invoker/power/setup/distro/opensuse.rb +11 -0
  45. data/lib/invoker/power/setup/distro/redhat.rb +11 -0
  46. data/lib/invoker/power/setup/distro/ubuntu.rb +46 -0
  47. data/lib/invoker/power/setup/files/invoker_forwarder.sh.erb +17 -0
  48. data/lib/invoker/power/setup/files/socat_invoker.service +12 -0
  49. data/lib/invoker/power/setup/linux_setup.rb +97 -0
  50. data/lib/invoker/power/setup/osx_setup.rb +137 -0
  51. data/lib/invoker/power/setup.rb +93 -0
  52. data/lib/invoker/power/templates/400.html +40 -0
  53. data/lib/invoker/power/templates/404.html +40 -0
  54. data/lib/invoker/power/templates/503.html +40 -0
  55. data/lib/invoker/power/url_rewriter.rb +40 -0
  56. data/lib/invoker/process_manager.rb +201 -0
  57. data/lib/invoker/process_printer.rb +59 -0
  58. data/lib/invoker/reactor/reader.rb +65 -0
  59. data/lib/invoker/reactor.rb +37 -0
  60. data/lib/invoker/version.rb +47 -0
  61. data/lib/invoker.rb +151 -0
  62. data/spec/invoker/cli/pinger_spec.rb +22 -0
  63. data/spec/invoker/cli/tail_watcher_spec.rb +39 -0
  64. data/spec/invoker/cli_spec.rb +27 -0
  65. data/spec/invoker/command_worker_spec.rb +45 -0
  66. data/spec/invoker/commander_spec.rb +152 -0
  67. data/spec/invoker/config_spec.rb +361 -0
  68. data/spec/invoker/daemon_spec.rb +34 -0
  69. data/spec/invoker/event/manager_spec.rb +67 -0
  70. data/spec/invoker/invoker_spec.rb +71 -0
  71. data/spec/invoker/ipc/client_handler_spec.rb +54 -0
  72. data/spec/invoker/ipc/dns_check_command_spec.rb +32 -0
  73. data/spec/invoker/ipc/message/list_response_spec.rb +24 -0
  74. data/spec/invoker/ipc/message_spec.rb +49 -0
  75. data/spec/invoker/ipc/unix_client_spec.rb +29 -0
  76. data/spec/invoker/power/balancer_spec.rb +53 -0
  77. data/spec/invoker/power/config_spec.rb +18 -0
  78. data/spec/invoker/power/http_parser_spec.rb +32 -0
  79. data/spec/invoker/power/http_response_spec.rb +34 -0
  80. data/spec/invoker/power/port_finder_spec.rb +16 -0
  81. data/spec/invoker/power/setup/linux_setup_spec.rb +166 -0
  82. data/spec/invoker/power/setup/osx_setup_spec.rb +105 -0
  83. data/spec/invoker/power/setup_spec.rb +4 -0
  84. data/spec/invoker/power/url_rewriter_spec.rb +69 -0
  85. data/spec/invoker/power/web_sockets_spec.rb +61 -0
  86. data/spec/invoker/process_manager_spec.rb +130 -0
  87. data/spec/invoker/reactor_spec.rb +6 -0
  88. data/spec/spec_helper.rb +43 -0
  89. metadata +376 -0
@@ -0,0 +1,49 @@
1
+ module Invoker
2
+ module Power
3
+ class PortFinder
4
+ STARTING_PORT = 23400
5
+ attr_accessor :dns_port, :http_port, :starting_port, :https_port
6
+ def initialize
7
+ @starting_port = STARTING_PORT
8
+ @ports = []
9
+ @dns_port = nil
10
+ @http_port = nil
11
+ end
12
+
13
+ def find_ports
14
+ STARTING_PORT.upto(STARTING_PORT + 100) do |port|
15
+ break if @ports.size > 3
16
+ if check_if_port_is_open(port)
17
+ @ports << port
18
+ else
19
+ next
20
+ end
21
+ end
22
+ @dns_port = @ports[0]
23
+ @http_port = @ports[1]
24
+ @https_port = @ports[2]
25
+ end
26
+
27
+ private
28
+
29
+ def check_if_port_is_open(port)
30
+ socket_flag = true
31
+ sockets = nil
32
+ begin
33
+ sockets = Socket.tcp_server_sockets(port)
34
+ socket_flag = false if sockets.size <= 1
35
+ rescue Errno::EADDRINUSE
36
+ socket_flag = false
37
+ end
38
+ sockets && close_socket_pairs(sockets)
39
+ socket_flag
40
+ end
41
+
42
+ def close_socket_pairs(sockets)
43
+ sockets.each { |s| s.close }
44
+ rescue
45
+ nil
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ require "invoker/power/http_response"
2
+ require "invoker/power/dns"
3
+ require "invoker/power/balancer"
@@ -0,0 +1,29 @@
1
+ module Invoker
2
+ # power is really a stupid pun on pow.
3
+ module Power
4
+ class Powerup
5
+ def self.fork_and_start
6
+ powerup = new()
7
+ fork { powerup.run }
8
+ end
9
+
10
+ def run
11
+ require "invoker/power/power"
12
+ EM.epoll
13
+ EM.run {
14
+ trap("TERM") { stop }
15
+ trap("INT") { stop }
16
+ if Invoker.darwin?
17
+ DNS.new.run(listen: DNS.server_ports)
18
+ end
19
+ Balancer.run
20
+ }
21
+ end
22
+
23
+ def stop
24
+ Invoker::Logger.puts "Terminating Proxy/Server"
25
+ EventMachine.stop
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ module Invoker
2
+ module Power
3
+ module Distro
4
+ class Arch < Base
5
+ def install_required_software
6
+ system("pacman -S --needed --noconfirm dnsmasq socat")
7
+ system("mkdir -p /etc/dnsmasq.d")
8
+ unless File.open("/etc/dnsmasq.conf").each_line.any? { |line| line.chomp == "conf-dir=/etc/dnsmasq.d" }
9
+ File.open("/etc/dnsmasq.conf", "a") {|f| f.write("conf-dir=/etc/dnsmasq.d") }
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,80 @@
1
+ module Invoker
2
+ module Power
3
+ module Distro
4
+ class Base
5
+ SOCAT_SHELLSCRIPT = "/usr/bin/invoker_forwarder.sh"
6
+ SOCAT_SYSTEMD = "/etc/systemd/system/socat_invoker.service"
7
+ RESOLVER_DIR = "/etc/dnsmasq.d"
8
+ attr_accessor :tld
9
+
10
+ def resolver_file
11
+ File.join(RESOLVER_DIR, "#{tld}-tld")
12
+ end
13
+
14
+ def self.distro_installer(tld)
15
+ if distro.start_with? "Arch Linux", "Manjaro Linux"
16
+ require "invoker/power/setup/distro/arch"
17
+ Arch.new(tld)
18
+ elsif distro.start_with? "Debian"
19
+ require "invoker/power/setup/distro/debian"
20
+ Debian.new(tld)
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"
28
+ require "invoker/power/setup/distro/opensuse"
29
+ Opensuse.new(tld)
30
+ else
31
+ raise "Your selected distro is not supported by Invoker"
32
+ end
33
+ end
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
+
46
+ def initialize(tld)
47
+ self.tld = tld
48
+ end
49
+
50
+ # Install required software
51
+ def install_required_software
52
+ raise "Unimplemented"
53
+ end
54
+
55
+ def restart_services
56
+ system("systemctl enable socat_invoker.service")
57
+ system("systemctl enable dnsmasq")
58
+ system("systemctl start socat_invoker.service")
59
+ system("systemctl restart dnsmasq")
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
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,11 @@
1
+ module Invoker
2
+ module Power
3
+ module Distro
4
+ class Debian < Base
5
+ def install_required_software
6
+ system("apt-get --assume-yes install dnsmasq socat")
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Invoker
2
+ module Power
3
+ module Distro
4
+ class Opensuse < Base
5
+ def install_required_software
6
+ system("zypper install -l dnsmasq socat")
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Invoker
2
+ module Power
3
+ module Distro
4
+ class Redhat < Base
5
+ def install_required_software
6
+ system("yum --assumeyes install dnsmasq socat")
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,46 @@
1
+ require "invoker/power/setup/distro/debian"
2
+
3
+ module Invoker
4
+ module Power
5
+ module Distro
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
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+ set -e
3
+ KillJobs() {
4
+ for job in $(jobs -p); do
5
+ kill -s SIGTERM $job > /dev/null 2>&1 || (sleep 10 && kill -9 $job > /dev/null 2>&1 &)
6
+ done
7
+ }
8
+
9
+ # Whatever you need to clean here
10
+ trap KillJobs SIGINT SIGTERM EXIT
11
+
12
+ /usr/bin/socat TCP-LISTEN:80,reuseaddr,fork TCP:0.0.0.0:<%= http_port %>&
13
+ pid1=$!
14
+ /usr/bin/socat TCP-LISTEN:443,reuseaddr,fork TCP:0.0.0.0:<%= https_port %>&
15
+ pid2=$!
16
+ wait $pid1 $pid2
17
+ wait $pid1 $pid2
@@ -0,0 +1,12 @@
1
+ [Unit]
2
+ Description=Socat port forwarding service
3
+ After=network.target
4
+ Documentation=man:socat(1)
5
+
6
+ [Service]
7
+ ExecStart=/usr/bin/invoker_forwarder.sh
8
+ Restart=on-success
9
+
10
+
11
+ [Install]
12
+ WantedBy=multi-user.target
@@ -0,0 +1,97 @@
1
+ require "invoker/power/setup/distro/base"
2
+ require 'erb'
3
+ require 'fileutils'
4
+
5
+ module Invoker
6
+ module Power
7
+ class LinuxSetup < Setup
8
+ attr_accessor :distro_installer
9
+
10
+ def setup_invoker
11
+ initialize_distro_installer
12
+ if distro_installer.get_user_confirmation?
13
+ find_open_ports
14
+ distro_installer.install_required_software
15
+ install_resolver
16
+ install_port_forwarder
17
+ distro_installer.restart_services
18
+ drop_to_normal_user
19
+ create_config_file
20
+ else
21
+ Invoker::Logger.puts("Invoker is not configured to serve from subdomains".colorize(:red))
22
+ end
23
+ self
24
+ end
25
+
26
+ def uninstall_invoker
27
+ system("systemctl disable socat_invoker.service")
28
+ system("systemctl stop socat_invoker.service")
29
+ system("rm #{Invoker::Power::Distro::Base::SOCAT_SYSTEMD}")
30
+ system("rm #{Invoker::Power::Distro::Base::SOCAT_SHELLSCRIPT}")
31
+ initialize_distro_installer
32
+ remove_resolver_file
33
+ drop_to_normal_user
34
+ Invoker::Power::Config.delete
35
+ end
36
+
37
+ def build_power_config
38
+ config = super
39
+ config[:tld] = distro_installer.tld
40
+ config
41
+ end
42
+
43
+ def resolver_file
44
+ distro_installer.resolver_file
45
+ end
46
+
47
+ def forwarder_script
48
+ File.join(File.dirname(__FILE__), "files/invoker_forwarder.sh.erb")
49
+ end
50
+
51
+ def socat_unit
52
+ File.join(File.dirname(__FILE__), "files/socat_invoker.service")
53
+ end
54
+
55
+ private
56
+
57
+ def initialize_distro_installer
58
+ @distro_installer ||= Invoker::Power::Distro::Base.distro_installer(tld)
59
+ end
60
+
61
+ def install_resolver
62
+ return if resolver_file.nil?
63
+ File.open(resolver_file, "w") do |fl|
64
+ fl.write(resolver_file_content)
65
+ end
66
+ end
67
+
68
+ def install_port_forwarder
69
+ install_forwarder_script(port_finder.http_port, port_finder.https_port)
70
+ install_systemd_unit
71
+ end
72
+
73
+ def resolver_file_content
74
+ content =<<-EOD
75
+ local=/#{tld}/
76
+ address=/#{tld}/127.0.0.1
77
+ EOD
78
+ content
79
+ end
80
+
81
+ def install_forwarder_script(http_port, https_port)
82
+ script_template = File.read(forwarder_script)
83
+ renderer = ERB.new(script_template)
84
+ script_output = renderer.result(binding)
85
+ File.open(Invoker::Power::Distro::Base::SOCAT_SHELLSCRIPT, "w") do |fl|
86
+ fl.write(script_output)
87
+ end
88
+ system("chmod +x #{Invoker::Power::Distro::Base::SOCAT_SHELLSCRIPT}")
89
+ end
90
+
91
+ def install_systemd_unit
92
+ FileUtils.cp(socat_unit, Invoker::Power::Distro::Base::SOCAT_SYSTEMD)
93
+ system("chmod 644 #{Invoker::Power::Distro::Base::SOCAT_SYSTEMD}")
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,137 @@
1
+ module Invoker
2
+ module Power
3
+ class OsxSetup < Setup
4
+ FIREWALL_PLIST_FILE = "/Library/LaunchDaemons/com.codemancers.invoker.firewall.plist"
5
+ RESOLVER_DIR = "/etc/resolver"
6
+
7
+ def resolver_file
8
+ File.join(RESOLVER_DIR, tld)
9
+ end
10
+
11
+ def setup_invoker
12
+ if setup_resolver_file
13
+ find_open_ports
14
+ install_resolver(port_finder.dns_port)
15
+ install_firewall(port_finder.http_port, port_finder.https_port)
16
+ # Before writing the config file, drop down to a normal user
17
+ drop_to_normal_user
18
+ create_config_file
19
+ else
20
+ Invoker::Logger.puts("Invoker is not configured to serve from subdomains".colorize(:red))
21
+ end
22
+ self
23
+ end
24
+
25
+ def uninstall_invoker
26
+ uninstall_invoker_flag = Invoker::CLI::Question.agree("Are you sure you want to uninstall firewall rules created by setup (y/n) : ")
27
+
28
+ if uninstall_invoker_flag
29
+ remove_resolver_file
30
+ unload_firewall_rule(true)
31
+ Invoker::Power::Config.delete
32
+ Invoker::Logger.puts("Firewall rules were removed")
33
+ end
34
+ end
35
+
36
+ def build_power_config
37
+ config = super
38
+ config[:dns_port] = port_finder.dns_port
39
+ config
40
+ end
41
+
42
+ def install_resolver(dns_port)
43
+ open_resolver_for_write { |fl| fl.write(resolve_string(dns_port)) }
44
+ rescue Errno::EACCES
45
+ Invoker::Logger.puts("Running setup requires root access, please rerun it with sudo".colorize(:red))
46
+ raise
47
+ end
48
+
49
+ def install_firewall(http_port, https_port)
50
+ File.open(FIREWALL_PLIST_FILE, "w") { |fl|
51
+ fl.write(plist_string(http_port, https_port))
52
+ }
53
+ unload_firewall_rule
54
+ load_firewall_rule
55
+ end
56
+
57
+ def load_firewall_rule
58
+ system("launchctl load -Fw #{FIREWALL_PLIST_FILE} 2>/dev/null")
59
+ end
60
+
61
+ def unload_firewall_rule(remove = false)
62
+ system("pfctl -a com.apple/250.InvokerFirewall -F nat 2>/dev/null")
63
+ system("launchctl unload -w #{FIREWALL_PLIST_FILE} 2>/dev/null")
64
+ system("rm -rf #{FIREWALL_PLIST_FILE}") if remove
65
+ end
66
+
67
+ # Ripped from POW code
68
+ def plist_string(http_port, https_port)
69
+ plist =<<-EOD
70
+ <?xml version="1.0" encoding="UTF-8"?>
71
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
72
+ <plist version="1.0">
73
+ <dict>
74
+ <key>Label</key>
75
+ <string>com.codemancers.invoker</string>
76
+ <key>ProgramArguments</key>
77
+ <array>
78
+ <string>sh</string>
79
+ <string>-c</string>
80
+ <string>#{firewall_command(http_port, https_port)}</string>
81
+ </array>
82
+ <key>RunAtLoad</key>
83
+ <true/>
84
+ <key>UserName</key>
85
+ <string>root</string>
86
+ </dict>
87
+ </plist>
88
+ EOD
89
+ plist
90
+ end
91
+
92
+ def resolve_string(dns_port)
93
+ string =<<-EOD
94
+ nameserver 127.0.0.1
95
+ port #{dns_port}
96
+ EOD
97
+ string
98
+ end
99
+
100
+ # Ripped from Pow code
101
+ def firewall_command(http_port, https_port)
102
+ rules = [
103
+ "rdr pass on lo0 inet proto tcp from any to any port 80 -> 127.0.0.1 port #{http_port}",
104
+ "rdr pass on lo0 inet proto tcp from any to any port 443 -> 127.0.0.1 port #{https_port}"
105
+ ].join("\n")
106
+ "echo \"#{rules}\" | pfctl -a 'com.apple/250.InvokerFirewall' -f - -E"
107
+ end
108
+
109
+ def setup_resolver_file
110
+ return true unless File.exist?(resolver_file)
111
+
112
+ Invoker::Logger.puts "Invoker has detected an existing Pow installation. We recommend "\
113
+ "that you uninstall pow and rerun this setup.".colorize(:red)
114
+ Invoker::Logger.puts "If you have already uninstalled Pow, proceed with installation"\
115
+ " by pressing y/n."
116
+ replace_resolver_flag = Invoker::CLI::Question.agree("Replace Pow configuration (y/n) : ")
117
+
118
+ if replace_resolver_flag
119
+ Invoker::Logger.puts "Invoker has overwritten one or more files created by Pow. "\
120
+ "If .#{tld} domains still don't resolve locally, try turning off the wi-fi"\
121
+ " and turning it on. It'll force OS X to reload network configuration".colorize(:green)
122
+ end
123
+ replace_resolver_flag
124
+ end
125
+
126
+ private
127
+
128
+ def open_resolver_for_write
129
+ FileUtils.mkdir(RESOLVER_DIR) unless Dir.exist?(RESOLVER_DIR)
130
+ fl = File.open(resolver_file, "w")
131
+ yield fl
132
+ ensure
133
+ fl && fl.close
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,93 @@
1
+ require "eventmachine"
2
+
3
+ module Invoker
4
+ module Power
5
+ class Setup
6
+ attr_accessor :port_finder, :tld
7
+
8
+ def self.install(tld)
9
+ selected_installer_klass = installer_klass
10
+ selected_installer_klass.new(tld).install
11
+ end
12
+
13
+ def self.uninstall
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
19
+ end
20
+
21
+ def self.installer_klass
22
+ if Invoker.darwin?
23
+ Invoker::Power::OsxSetup
24
+ else
25
+ Invoker::Power::LinuxSetup
26
+ end
27
+ end
28
+
29
+ def initialize(tld)
30
+ if tld !~ /^[a-z]+$/
31
+ Invoker::Logger.puts("Please specify valid tld".colorize(:red))
32
+ exit(1)
33
+ end
34
+ self.tld = tld
35
+ end
36
+
37
+ def install
38
+ if check_if_setup_can_run?
39
+ setup_invoker
40
+ else
41
+ Invoker::Logger.puts("The setup has been already run.".colorize(:red))
42
+ end
43
+ self
44
+ end
45
+
46
+ def drop_to_normal_user
47
+ EventMachine.set_effective_user(ENV["SUDO_USER"])
48
+ end
49
+
50
+ def find_open_ports
51
+ port_finder.find_ports()
52
+ end
53
+
54
+ def port_finder
55
+ @port_finder ||= Invoker::Power::PortFinder.new()
56
+ end
57
+
58
+ def check_if_setup_can_run?
59
+ !File.exist?(Invoker::Power::Config.config_file)
60
+ end
61
+
62
+ def create_config_file
63
+ Invoker.setup_config_location
64
+ config = build_power_config
65
+ Invoker::Power::Config.create(config)
66
+ end
67
+
68
+ # Builds and returns power config hash. Override this method in subclasses if necessary.
69
+ def build_power_config
70
+ config = {
71
+ http_port: port_finder.http_port,
72
+ https_port: port_finder.https_port,
73
+ tld: tld
74
+ }
75
+ config
76
+ end
77
+
78
+ def remove_resolver_file
79
+ return if resolver_file.nil?
80
+ begin
81
+ safe_remove_file(resolver_file)
82
+ rescue Errno::EACCES
83
+ Invoker::Logger.puts("Running uninstall requires root access, please rerun it with sudo".colorize(:red))
84
+ raise
85
+ end
86
+ end
87
+
88
+ def safe_remove_file(file)
89
+ File.delete(file) if File.exist?(file)
90
+ end
91
+ end
92
+ end
93
+ 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>