landrush 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +2 -0
- data/.rubocop_todo.yml +100 -12
- data/.travis.yml +1 -2
- data/CHANGELOG.md +11 -0
- data/Gemfile +11 -11
- data/README.adoc +8 -1
- data/Rakefile +3 -3
- data/appveyor.yml +3 -1
- data/doc/Development.adoc +24 -19
- data/doc/Usage.adoc +17 -6
- data/features/dns_resolution.feature +3 -0
- data/features/docker_provider.feature +32 -0
- data/features/support/env.rb +2 -2
- data/landrush.gemspec +3 -3
- data/lib/landrush.rb +1 -0
- data/lib/landrush/action/common.rb +7 -2
- data/lib/landrush/action/redirect_dns.rb +3 -0
- data/lib/landrush/action/setup.rb +16 -12
- data/lib/landrush/action/teardown.rb +2 -0
- data/lib/landrush/cap/guest/all/read_host_visible_ip_address.rb +2 -2
- data/lib/landrush/cap/guest/linux/add_iptables_rule.rb +2 -2
- data/lib/landrush/cap/guest/linux/configured_dns_servers.rb +1 -0
- data/lib/landrush/cap/guest/linux/redirect_dns.rb +1 -1
- data/lib/landrush/cap/guest/suse/add_iptables_rule.rb +2 -2
- data/lib/landrush/cap/host/arch/dnsmasq_installed.rb +11 -0
- data/lib/landrush/cap/host/arch/install_dnsmasq.rb +16 -0
- data/lib/landrush/cap/host/arch/restart_dnsmasq.rb +21 -0
- data/lib/landrush/cap/host/darwin/configure_visibility_on_host.rb +21 -18
- data/lib/landrush/cap/host/debian/host.rb +1 -0
- data/lib/landrush/cap/host/linux/configure_visibility_on_host.rb +5 -3
- data/lib/landrush/cap/host/linux/create_dnsmasq_config.rb +3 -0
- data/lib/landrush/cap/host/redhat/restart_dnsmasq.rb +8 -2
- data/lib/landrush/cap/host/ubuntu/host.rb +1 -0
- data/lib/landrush/cap/host/windows/configure_visibility_on_host.rb +14 -6
- data/lib/landrush/command.rb +18 -3
- data/lib/landrush/config.rb +6 -2
- data/lib/landrush/dns_server.rb +82 -0
- data/lib/landrush/plugin.rb +18 -0
- data/lib/landrush/server.rb +147 -205
- data/lib/landrush/start_server.rb +1 -1
- data/lib/landrush/store.rb +53 -24
- data/lib/landrush/util/dnsmasq.rb +10 -0
- data/lib/landrush/util/process_helper.rb +16 -16
- data/lib/landrush/util/retry.rb +1 -0
- data/lib/landrush/version.rb +1 -1
- data/test/landrush/action/setup_test.rb +8 -7
- data/test/landrush/action/teardown_test.rb +5 -5
- data/test/landrush/cap/guest/linux/redirect_dns_test.rb +1 -1
- data/test/landrush/cap/host/darwin/configure_visibility_on_host_test.rb +10 -6
- data/test/landrush/cap/host/linux/configure_visibility_on_host_test.rb +1 -1
- data/test/landrush/cap/host/windows/configure_visibility_on_host_test.rb +35 -4
- data/test/landrush/issues/255.rb +55 -55
- data/test/landrush/parallel_store_use_test.rb +50 -0
- data/test/landrush/server_test.rb +6 -17
- data/test/landrush/store_test.rb +8 -8
- data/test/landrush/util/dnsmasq_test.rb +42 -0
- data/test/support/create_fake_working_dir.rb +3 -2
- data/test/support/delete_fake_working_dir.rb +1 -1
- data/test/support/test_server_daemon.rb +1 -1
- data/test/test_helper.rb +6 -8
- metadata +42 -17
data/lib/landrush/command.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Landrush
|
2
2
|
class Command < Vagrant.plugin('2', :command)
|
3
|
-
DAEMON_COMMANDS = %w
|
3
|
+
DAEMON_COMMANDS = %w[start stop restart].freeze
|
4
4
|
|
5
5
|
def self.synopsis
|
6
6
|
'manages DNS for both guest and host'
|
@@ -16,6 +16,8 @@ module Landrush
|
|
16
16
|
command = ARGV.first || 'help'
|
17
17
|
if DAEMON_COMMANDS.include?(command)
|
18
18
|
Server.send(command)
|
19
|
+
elsif command == 'status'
|
20
|
+
status
|
19
21
|
elsif command == 'dependentvms' || command == 'vms'
|
20
22
|
dependent_vms
|
21
23
|
elsif command == 'ls' || command == 'list'
|
@@ -37,14 +39,16 @@ module Landrush
|
|
37
39
|
raise Vagrant::Errors::CLIInvalidOptions, help: usage(msg)
|
38
40
|
end
|
39
41
|
|
40
|
-
def usage(msg)
|
42
|
+
def usage(msg)
|
43
|
+
<<-EOS.gsub(/^ /, '')
|
41
44
|
ERROR: #{msg}
|
42
45
|
|
43
46
|
#{help}
|
44
47
|
EOS
|
45
48
|
end
|
46
49
|
|
47
|
-
def help
|
50
|
+
def help
|
51
|
+
<<-EOS.gsub(/^ /, '')
|
48
52
|
vagrant landrush <command>
|
49
53
|
|
50
54
|
commands:
|
@@ -67,6 +71,17 @@ module Landrush
|
|
67
71
|
|
68
72
|
private
|
69
73
|
|
74
|
+
def status
|
75
|
+
case Landrush::Server.status
|
76
|
+
when :running
|
77
|
+
puts "Daemon status: running pid=#{Landrush::Server.pid}"
|
78
|
+
when :stopped
|
79
|
+
puts 'Daemon status: stopped'
|
80
|
+
else
|
81
|
+
puts 'Daemon status: unknown'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
70
85
|
def dependent_vms
|
71
86
|
if DependentVMs.any?
|
72
87
|
@env.ui.info(DependentVMs.list.map { |dvm| " - #{dvm}" }.join("\n"))
|
data/lib/landrush/config.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module Landrush
|
2
2
|
class Config < Vagrant.plugin('2', :config)
|
3
3
|
attr_accessor :hosts
|
4
|
-
attr_accessor :enabled
|
5
4
|
attr_accessor :tld
|
5
|
+
attr_accessor :enabled
|
6
6
|
attr_accessor :upstream_servers
|
7
7
|
attr_accessor :host_ip_address
|
8
8
|
attr_accessor :guest_redirect_dns
|
@@ -11,7 +11,7 @@ module Landrush
|
|
11
11
|
attr_accessor :host_interface_excludes
|
12
12
|
attr_accessor :host_redirect_dns
|
13
13
|
|
14
|
-
INTERFACE_CLASSES = [
|
14
|
+
INTERFACE_CLASSES = %i[any ipv4 ipv6].freeze
|
15
15
|
INTERFACE_CLASS_INVALID = "Invalid interface class, should be one of: #{INTERFACE_CLASSES.join(', ')}".freeze
|
16
16
|
|
17
17
|
DEFAULTS = {
|
@@ -63,6 +63,10 @@ module Landrush
|
|
63
63
|
@hosts[hostname] = ip_address
|
64
64
|
end
|
65
65
|
|
66
|
+
def tld_as_array
|
67
|
+
Array(@tld)
|
68
|
+
end
|
69
|
+
|
66
70
|
def upstream(ip, port = 53, protocol = nil)
|
67
71
|
@upstream_servers = [] if @upstream_servers == UNSET_VALUE
|
68
72
|
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'rubydns'
|
2
|
+
require 'ipaddr'
|
3
|
+
require_relative 'store'
|
4
|
+
|
5
|
+
module Landrush
|
6
|
+
module DnsServer
|
7
|
+
Name = Resolv::DNS::Name
|
8
|
+
IN = Resolv::DNS::Resource::IN
|
9
|
+
|
10
|
+
def self.interfaces
|
11
|
+
[[:udp, '0.0.0.0', Server.port], [:tcp, '0.0.0.0', Server.port]]
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.upstream_servers
|
15
|
+
# Doing collect to cast protocol to symbol because JSON store doesn't know about symbols
|
16
|
+
@upstream_servers ||= Store.config.get('upstream').collect { |i| [i[0].to_sym, i[1], i[2]] }
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.upstream
|
20
|
+
@upstream ||= RubyDNS::Resolver.new(upstream_servers, logger: @logger)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.start_dns_server(logger)
|
24
|
+
@logger = logger
|
25
|
+
run_dns_server(listen: interfaces, logger: logger) do
|
26
|
+
match(/.*/, IN::A) do |transaction|
|
27
|
+
host = Store.hosts.find(transaction.name)
|
28
|
+
if host
|
29
|
+
DnsServer.check_a_record(host, transaction)
|
30
|
+
else
|
31
|
+
transaction.passthrough!(DnsServer.upstream)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
match(/.*/, IN::PTR) do |transaction|
|
36
|
+
host = Store.hosts.find(transaction.name)
|
37
|
+
if host
|
38
|
+
transaction.respond!(Name.create(Store.hosts.get(host)))
|
39
|
+
else
|
40
|
+
transaction.passthrough!(DnsServer.upstream)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Default DNS handler
|
45
|
+
otherwise do |transaction|
|
46
|
+
transaction.passthrough!(DnsServer.upstream)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.run_dns_server(options = {}, &block)
|
52
|
+
server = RubyDNS::RuleBasedServer.new(options, &block)
|
53
|
+
|
54
|
+
EventMachine.run do
|
55
|
+
trap('INT') do
|
56
|
+
EventMachine.stop
|
57
|
+
end
|
58
|
+
|
59
|
+
server.run(options)
|
60
|
+
end
|
61
|
+
|
62
|
+
server.fire(:stop)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.check_a_record(host, transaction)
|
66
|
+
value = Store.hosts.get(host)
|
67
|
+
return if value.nil?
|
68
|
+
|
69
|
+
if begin
|
70
|
+
IPAddr.new(value)
|
71
|
+
rescue StandardError
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
name = transaction.name =~ /#{host}/ ? transaction.name : host
|
75
|
+
transaction.respond!(value, ttl: 0, name: name)
|
76
|
+
else
|
77
|
+
transaction.respond!(Name.create(value), resource_class: IN::CNAME, ttl: 0)
|
78
|
+
DnsServer.check_a_record(value, transaction)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/landrush/plugin.rb
CHANGED
@@ -23,6 +23,9 @@ module Landrush
|
|
23
23
|
hook.before(VagrantPlugins::HyperV::Action::WaitForIPAddress, pre_boot_actions)
|
24
24
|
hook.after(Vagrant::Action::Builtin::WaitForCommunicator, post_boot_actions)
|
25
25
|
|
26
|
+
# Hooks for Docker provider
|
27
|
+
hook.after(VagrantPlugins::DockerProvider::Action::Start, pre_boot_actions)
|
28
|
+
|
26
29
|
# Hooks for Libvirt provider
|
27
30
|
if defined?(VagrantPlugins::ProviderLibvirt)
|
28
31
|
hook.after(VagrantPlugins::ProviderLibvirt::Action::CreateNetworks, pre_boot_actions)
|
@@ -196,5 +199,20 @@ module Landrush
|
|
196
199
|
require_relative 'cap/host/suse/restart_dnsmasq'
|
197
200
|
Cap::Suse::RestartDnsmasq
|
198
201
|
end
|
202
|
+
|
203
|
+
host_capability('arch', 'dnsmasq_installed') do
|
204
|
+
require_relative 'cap/host/arch/dnsmasq_installed'
|
205
|
+
Cap::Arch::DnsmasqInstalled
|
206
|
+
end
|
207
|
+
|
208
|
+
host_capability('arch', 'install_dnsmasq') do
|
209
|
+
require_relative 'cap/host/arch/install_dnsmasq'
|
210
|
+
Cap::Arch::InstallDnsmasq
|
211
|
+
end
|
212
|
+
|
213
|
+
host_capability('arch', 'restart_dnsmasq') do
|
214
|
+
require_relative 'cap/host/arch/restart_dnsmasq'
|
215
|
+
Cap::Arch::RestartDnsmasq
|
216
|
+
end
|
199
217
|
end
|
200
218
|
end
|
data/lib/landrush/server.rb
CHANGED
@@ -1,46 +1,51 @@
|
|
1
|
-
require '
|
2
|
-
require 'ipaddr'
|
1
|
+
require 'filelock'
|
3
2
|
require 'win32/process' unless (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM).nil? # only require on Windows
|
4
3
|
require_relative 'store'
|
5
4
|
require_relative 'util/path'
|
6
5
|
require_relative 'util/process_helper'
|
6
|
+
require_relative 'dns_server'
|
7
7
|
|
8
8
|
module Landrush
|
9
9
|
class Server
|
10
10
|
extend Landrush::Util::ProcessHelper
|
11
|
-
|
12
|
-
Name = Resolv::DNS::Name
|
13
|
-
IN = Resolv::DNS::Resource::IN
|
11
|
+
extend Landrush::DnsServer
|
14
12
|
|
15
13
|
class << self
|
16
14
|
attr_reader :gems_dir
|
15
|
+
attr_reader :ui
|
16
|
+
attr_writer :ui
|
17
|
+
attr_writer :port
|
17
18
|
|
18
19
|
def gems_dir=(gems_dir)
|
19
20
|
@gems_dir = Pathname(gems_dir)
|
20
21
|
end
|
21
22
|
|
22
|
-
attr_reader :ui
|
23
|
-
attr_writer :ui
|
24
|
-
|
25
23
|
def working_dir
|
26
24
|
# TODO, https://github.com/vagrant-landrush/landrush/issues/178
|
27
25
|
# Due to the fact that the whole server is just a bunch of static methods,
|
28
|
-
# there is no
|
26
|
+
# there is no initialize method to ensure that the working directory is
|
29
27
|
# set prior to making calls to this method. Things work, since at the appropriate
|
30
28
|
# Vagrant plugin integration points (e.g. setup.rb) we set the working dir based
|
31
|
-
# on the
|
29
|
+
# on the environment passed to us.
|
32
30
|
if @working_dir.nil?
|
33
31
|
raise 'The Server\s working directory needs to be explicitly set prior to calling this method'
|
34
32
|
end
|
33
|
+
|
35
34
|
@working_dir
|
36
35
|
end
|
37
36
|
|
38
37
|
def working_dir=(working_dir)
|
39
38
|
@working_dir = Pathname(working_dir).tap(&:mkpath)
|
39
|
+
@log_file = File.join(working_dir, 'log', 'landrush.log')
|
40
|
+
ensure_path_exits(@log_file)
|
41
|
+
@logger = setup_logging
|
42
|
+
@pid_file = File.join(working_dir, 'run', 'landrush.pid')
|
43
|
+
ensure_path_exits(@pid_file)
|
40
44
|
end
|
41
45
|
|
42
46
|
def port
|
43
|
-
@port unless @port.nil?
|
47
|
+
return @port unless @port.nil?
|
48
|
+
|
44
49
|
if (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM).nil?
|
45
50
|
# Default Landrush port for non Windows OS
|
46
51
|
100_53
|
@@ -50,229 +55,166 @@ module Landrush
|
|
50
55
|
end
|
51
56
|
end
|
52
57
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
File.join(log_directory, 'landrush.log')
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.upstream_servers
|
65
|
-
# Doing collect to cast protocol to symbol because JSON store doesn't know about symbols
|
66
|
-
@upstream_servers ||= Store.config.get('upstream').collect { |i| [i[0].to_sym, i[1], i[2]] }
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.interfaces
|
70
|
-
[
|
71
|
-
[:udp, '0.0.0.0', port],
|
72
|
-
[:tcp, '0.0.0.0', port]
|
73
|
-
]
|
74
|
-
end
|
75
|
-
|
76
|
-
def self.upstream
|
77
|
-
@upstream ||= RubyDNS::Resolver.new(upstream_servers)
|
78
|
-
end
|
58
|
+
# Used to start the Landrush DNS server as a child process using ChildProcess gem
|
59
|
+
def start
|
60
|
+
with_pid_lock do |file|
|
61
|
+
# Check if the daemon is already started...
|
62
|
+
if running?(file)
|
63
|
+
@ui.info "[landrush] DNS server already running with pid #{read_pid(file)}" unless @ui.nil?
|
64
|
+
return
|
65
|
+
end
|
79
66
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
67
|
+
# On a machine with just Vagrant installed there might be no other Ruby except the
|
68
|
+
# one bundled with Vagrant. Let's make sure the embedded bin directory containing
|
69
|
+
# the Ruby executable is added to the PATH.
|
70
|
+
Landrush::Util::Path.ensure_ruby_on_path
|
71
|
+
|
72
|
+
ruby_bin = Landrush::Util::Path.embedded_vagrant_ruby.nil? ? 'ruby' : Landrush::Util::Path.embedded_vagrant_ruby
|
73
|
+
start_server_script = Pathname(__dir__).join('start_server.rb').to_s
|
74
|
+
@ui.detail("[landrush] starting DNS server: '#{ruby_bin} #{start_server_script} #{port} #{working_dir} #{gems_dir}'") unless @ui.nil?
|
75
|
+
if Vagrant::Util::Platform.windows?
|
76
|
+
# Need to handle Windows differently. Kernel.spawn fails to work, if
|
77
|
+
# the shell creating the process is closed.
|
78
|
+
# See https://github.com/vagrant-landrush/landrush/issues/199
|
79
|
+
#
|
80
|
+
# Note to the Future: Windows does not have a
|
81
|
+
# file handle inheritance issue like Linux and Mac (see:
|
82
|
+
# https://github.com/vagrant-landrush/landrush/issues/249)
|
83
|
+
#
|
84
|
+
# On windows, if no filehandle is passed then no files get
|
85
|
+
# inherited by default, but if any filehandle is passed to
|
86
|
+
# a spawned process then all files that are
|
87
|
+
# set as inheritable will get inherited. In another project this
|
88
|
+
# created a problem (see: https://github.com/dustymabe/vagrant-sshfs/issues/41).
|
89
|
+
#
|
90
|
+
# Today we don't pass any filehandles, so it isn't a problem.
|
91
|
+
# Future self, make sure this doesn't become a problem.
|
92
|
+
info = Process.create(command_line: "#{ruby_bin} #{start_server_script} #{port} #{working_dir} #{gems_dir}",
|
93
|
+
creation_flags: Process::DETACHED_PROCESS,
|
94
|
+
process_inherit: false,
|
95
|
+
thread_inherit: true,
|
96
|
+
cwd: working_dir.to_path)
|
97
|
+
pid = info.process_id
|
98
|
+
else
|
99
|
+
# Fix https://github.com/vagrant-landrush/landrush/issues/249)
|
100
|
+
# by turning of filehandle inheritance with :close_others => true
|
101
|
+
# and by explicitly closing STDIN, STDOUT, and STDERR
|
102
|
+
pid = spawn(ruby_bin, start_server_script, port.to_s, working_dir.to_s, gems_dir.to_s,
|
103
|
+
in: :close,
|
104
|
+
out: :close,
|
105
|
+
err: :close,
|
106
|
+
close_others: true,
|
107
|
+
chdir: working_dir.to_path,
|
108
|
+
pgroup: true)
|
109
|
+
Process.detach pid
|
110
|
+
end
|
86
111
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
# Need to handle Windows differently. Kernel.spawn fails to work, if
|
92
|
-
# the shell creating the process is closed.
|
93
|
-
# See https://github.com/vagrant-landrush/landrush/issues/199
|
94
|
-
#
|
95
|
-
# Note to the Future: Windows does not have a
|
96
|
-
# file handle inheritance issue like Linux and Mac (see:
|
97
|
-
# https://github.com/vagrant-landrush/landrush/issues/249)
|
98
|
-
#
|
99
|
-
# On windows, if no filehandle is passed then no files get
|
100
|
-
# inherited by default, but if any filehandle is passed to
|
101
|
-
# a spawned process then all files that are
|
102
|
-
# set as inheritable will get inherited. In another project this
|
103
|
-
# created a problem (see: https://github.com/dustymabe/vagrant-sshfs/issues/41).
|
104
|
-
#
|
105
|
-
# Today we don't pass any filehandles, so it isn't a problem.
|
106
|
-
# Future self, make sure this doesn't become a problem.
|
107
|
-
info = Process.create(command_line: "#{ruby_bin} #{start_server_script} #{port} #{working_dir} #{gems_dir}",
|
108
|
-
creation_flags: Process::DETACHED_PROCESS,
|
109
|
-
process_inherit: false,
|
110
|
-
thread_inherit: true,
|
111
|
-
cwd: working_dir.to_path)
|
112
|
-
pid = info.process_id
|
113
|
-
else
|
114
|
-
# Fix https://github.com/vagrant-landrush/landrush/issues/249)
|
115
|
-
# by turning of filehandle inheritance with :close_others => true
|
116
|
-
# and by explicitly closing STDIN, STDOUT, and STDERR
|
117
|
-
pid = spawn(ruby_bin, start_server_script, port.to_s, working_dir.to_s, gems_dir.to_s,
|
118
|
-
in: :close,
|
119
|
-
out: :close,
|
120
|
-
err: :close,
|
121
|
-
close_others: true,
|
122
|
-
chdir: working_dir.to_path,
|
123
|
-
pgroup: true)
|
124
|
-
Process.detach pid
|
112
|
+
write_pid(pid, file)
|
113
|
+
# As of Vagrant 1.8.6 this additional sleep is needed, otherwise the child process dies!?
|
114
|
+
sleep 1
|
115
|
+
end
|
125
116
|
end
|
126
117
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
end
|
118
|
+
def stop
|
119
|
+
with_pid_lock do |file|
|
120
|
+
puts 'Stopping daemon...'
|
131
121
|
|
132
|
-
|
133
|
-
|
122
|
+
# Check if the daemon is already stopped...
|
123
|
+
unless running?(file)
|
124
|
+
return
|
125
|
+
end
|
134
126
|
|
135
|
-
|
136
|
-
unless File.file?(pid_file)
|
137
|
-
puts "Pid file #{pid_file} not found. Is the daemon running?"
|
138
|
-
return
|
139
|
-
end
|
127
|
+
terminate_process(file)
|
140
128
|
|
141
|
-
|
129
|
+
# If after doing our best the daemon is still running (pretty odd)...
|
130
|
+
if running?(file)
|
131
|
+
puts 'Daemon appears to be still running!'
|
132
|
+
return
|
133
|
+
end
|
142
134
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
return
|
135
|
+
# Otherwise the daemon has been stopped.
|
136
|
+
write_pid('', file)
|
137
|
+
end
|
147
138
|
end
|
148
139
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
if running?
|
153
|
-
puts 'Daemon appears to be still running!'
|
154
|
-
return
|
140
|
+
def restart
|
141
|
+
stop
|
142
|
+
start
|
155
143
|
end
|
156
144
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
def self.restart
|
162
|
-
stop
|
163
|
-
start
|
164
|
-
end
|
165
|
-
|
166
|
-
def self.pid
|
167
|
-
IO.read(pid_file).to_i
|
168
|
-
rescue
|
169
|
-
nil
|
170
|
-
end
|
171
|
-
|
172
|
-
def self.running?
|
173
|
-
pid = read_pid(pid_file)
|
174
|
-
return false if pid.nil?
|
175
|
-
if Vagrant::Util::Platform.windows?
|
176
|
-
begin
|
177
|
-
Process.get_exitcode(pid).nil?
|
178
|
-
# Need to handle this explicitly since this error gets thrown in case we call get_exitcode with a stale pid
|
179
|
-
rescue SystemCallError => e
|
180
|
-
raise e unless e.class.name.start_with?('Errno::ENXIO')
|
145
|
+
def status
|
146
|
+
with_pid_lock do |file|
|
147
|
+
process_status(file)
|
181
148
|
end
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
149
|
+
end
|
150
|
+
|
151
|
+
def pid
|
152
|
+
with_pid_lock do |file|
|
153
|
+
read_pid(file)
|
187
154
|
end
|
188
155
|
end
|
189
|
-
end
|
190
156
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
else
|
198
|
-
puts 'Daemon status: unknown'
|
199
|
-
puts "#{pid_file} exists, but process is not running"
|
200
|
-
puts "Check log file: #{log_file_path}"
|
157
|
+
def run(port, working_dir)
|
158
|
+
server = self
|
159
|
+
server.port = port
|
160
|
+
server.working_dir = working_dir
|
161
|
+
|
162
|
+
DnsServer.start_dns_server(@logger)
|
201
163
|
end
|
202
|
-
end
|
203
164
|
|
204
|
-
|
205
|
-
server = self
|
206
|
-
server.port = port
|
207
|
-
server.working_dir = working_dir
|
165
|
+
private
|
208
166
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
@logger = Logger.new(log_file)
|
213
|
-
@logger.level = Logger::INFO
|
167
|
+
def running?(file)
|
168
|
+
pid = read_pid(file)
|
169
|
+
return false if pid.nil? || pid.zero?
|
214
170
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
else
|
222
|
-
transaction.passthrough!(server.upstream)
|
171
|
+
if Vagrant::Util::Platform.windows?
|
172
|
+
begin
|
173
|
+
Process.get_exitcode(pid).nil?
|
174
|
+
rescue SystemCallError => e
|
175
|
+
# Need to handle this explicitly since this error gets thrown in case we call get_exitcode with a stale pid
|
176
|
+
raise e unless e.class.name.start_with?('Errno::ENXIO')
|
223
177
|
end
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
transaction.respond!(Name.create(Store.hosts.get(host)))
|
230
|
-
else
|
231
|
-
transaction.passthrough!(server.upstream)
|
178
|
+
else
|
179
|
+
begin
|
180
|
+
!!Process.kill(0, pid)
|
181
|
+
rescue StandardError
|
182
|
+
false
|
232
183
|
end
|
233
184
|
end
|
234
|
-
|
235
|
-
# Default DNS handler
|
236
|
-
otherwise do |transaction|
|
237
|
-
# @logger.info "Passing on to upstream: #{transaction.to_s}"
|
238
|
-
transaction.passthrough!(server.upstream)
|
239
|
-
end
|
240
185
|
end
|
241
|
-
end
|
242
|
-
|
243
|
-
def self.run_dns_server(options = {}, &block)
|
244
|
-
server = RubyDNS::RuleBasedServer.new(options, &block)
|
245
186
|
|
246
|
-
|
247
|
-
|
248
|
-
|
187
|
+
def setup_logging
|
188
|
+
log_file = File.open(@log_file, 'w')
|
189
|
+
log_file.sync = true
|
190
|
+
logger = Logger.new(log_file)
|
191
|
+
|
192
|
+
case ENV.fetch(:LANDRUSH_LOG.to_s) { 'info' }
|
193
|
+
when 'debug'
|
194
|
+
logger.level = Logger::DEBUG
|
195
|
+
when 'info'
|
196
|
+
logger.level = Logger::INFO
|
197
|
+
when 'warn'
|
198
|
+
logger.level = Logger::WARN
|
199
|
+
when 'error'
|
200
|
+
logger.level = Logger::ERROR
|
201
|
+
when 'fatal'
|
202
|
+
logger.level = Logger::FATAL
|
203
|
+
when 'unknown'
|
204
|
+
logger.level = Logger::UNKNOWN
|
205
|
+
else
|
206
|
+
raise ArgumentError, "invalid log level: #{severity}"
|
249
207
|
end
|
250
|
-
|
251
|
-
server.run(options)
|
208
|
+
logger
|
252
209
|
end
|
253
210
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
if begin
|
262
|
-
IPAddr.new(value)
|
263
|
-
rescue
|
264
|
-
nil
|
265
|
-
end
|
266
|
-
name = transaction.name =~ /#{host}/ ? transaction.name : host
|
267
|
-
transaction.respond!(value, ttl: 0, name: name)
|
268
|
-
else
|
269
|
-
transaction.respond!(Name.create(value), resource_class: IN::CNAME, ttl: 0)
|
270
|
-
check_a_record(value, transaction)
|
211
|
+
def with_pid_lock
|
212
|
+
Filelock @pid_file, wait: 60 do |file|
|
213
|
+
yield file
|
214
|
+
end
|
215
|
+
rescue Filelock::WaitTimeout
|
216
|
+
raise ConfigLockError, 'Unable to lock pid file.'
|
271
217
|
end
|
272
218
|
end
|
273
|
-
|
274
|
-
def self.pid_file
|
275
|
-
File.join(working_dir, 'run', 'landrush.pid')
|
276
|
-
end
|
277
219
|
end
|
278
220
|
end
|