invoker_ruby34 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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 +374 -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>