landrush 1.2.0 → 1.3.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 (62) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +2 -0
  3. data/.rubocop_todo.yml +100 -12
  4. data/.travis.yml +1 -2
  5. data/CHANGELOG.md +11 -0
  6. data/Gemfile +11 -11
  7. data/README.adoc +8 -1
  8. data/Rakefile +3 -3
  9. data/appveyor.yml +3 -1
  10. data/doc/Development.adoc +24 -19
  11. data/doc/Usage.adoc +17 -6
  12. data/features/dns_resolution.feature +3 -0
  13. data/features/docker_provider.feature +32 -0
  14. data/features/support/env.rb +2 -2
  15. data/landrush.gemspec +3 -3
  16. data/lib/landrush.rb +1 -0
  17. data/lib/landrush/action/common.rb +7 -2
  18. data/lib/landrush/action/redirect_dns.rb +3 -0
  19. data/lib/landrush/action/setup.rb +16 -12
  20. data/lib/landrush/action/teardown.rb +2 -0
  21. data/lib/landrush/cap/guest/all/read_host_visible_ip_address.rb +2 -2
  22. data/lib/landrush/cap/guest/linux/add_iptables_rule.rb +2 -2
  23. data/lib/landrush/cap/guest/linux/configured_dns_servers.rb +1 -0
  24. data/lib/landrush/cap/guest/linux/redirect_dns.rb +1 -1
  25. data/lib/landrush/cap/guest/suse/add_iptables_rule.rb +2 -2
  26. data/lib/landrush/cap/host/arch/dnsmasq_installed.rb +11 -0
  27. data/lib/landrush/cap/host/arch/install_dnsmasq.rb +16 -0
  28. data/lib/landrush/cap/host/arch/restart_dnsmasq.rb +21 -0
  29. data/lib/landrush/cap/host/darwin/configure_visibility_on_host.rb +21 -18
  30. data/lib/landrush/cap/host/debian/host.rb +1 -0
  31. data/lib/landrush/cap/host/linux/configure_visibility_on_host.rb +5 -3
  32. data/lib/landrush/cap/host/linux/create_dnsmasq_config.rb +3 -0
  33. data/lib/landrush/cap/host/redhat/restart_dnsmasq.rb +8 -2
  34. data/lib/landrush/cap/host/ubuntu/host.rb +1 -0
  35. data/lib/landrush/cap/host/windows/configure_visibility_on_host.rb +14 -6
  36. data/lib/landrush/command.rb +18 -3
  37. data/lib/landrush/config.rb +6 -2
  38. data/lib/landrush/dns_server.rb +82 -0
  39. data/lib/landrush/plugin.rb +18 -0
  40. data/lib/landrush/server.rb +147 -205
  41. data/lib/landrush/start_server.rb +1 -1
  42. data/lib/landrush/store.rb +53 -24
  43. data/lib/landrush/util/dnsmasq.rb +10 -0
  44. data/lib/landrush/util/process_helper.rb +16 -16
  45. data/lib/landrush/util/retry.rb +1 -0
  46. data/lib/landrush/version.rb +1 -1
  47. data/test/landrush/action/setup_test.rb +8 -7
  48. data/test/landrush/action/teardown_test.rb +5 -5
  49. data/test/landrush/cap/guest/linux/redirect_dns_test.rb +1 -1
  50. data/test/landrush/cap/host/darwin/configure_visibility_on_host_test.rb +10 -6
  51. data/test/landrush/cap/host/linux/configure_visibility_on_host_test.rb +1 -1
  52. data/test/landrush/cap/host/windows/configure_visibility_on_host_test.rb +35 -4
  53. data/test/landrush/issues/255.rb +55 -55
  54. data/test/landrush/parallel_store_use_test.rb +50 -0
  55. data/test/landrush/server_test.rb +6 -17
  56. data/test/landrush/store_test.rb +8 -8
  57. data/test/landrush/util/dnsmasq_test.rb +42 -0
  58. data/test/support/create_fake_working_dir.rb +3 -2
  59. data/test/support/delete_fake_working_dir.rb +1 -1
  60. data/test/support/test_server_daemon.rb +1 -1
  61. data/test/test_helper.rb +6 -8
  62. metadata +42 -17
@@ -1,6 +1,6 @@
1
1
  module Landrush
2
2
  class Command < Vagrant.plugin('2', :command)
3
- DAEMON_COMMANDS = %w(start stop restart status).freeze
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); <<-EOS.gsub(/^ /, '')
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; <<-EOS.gsub(/^ /, '')
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"))
@@ -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 = [:any, :ipv4, :ipv6].freeze
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
@@ -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
@@ -1,46 +1,51 @@
1
- require 'rubydns'
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 initalize method to ensure that the working directory is
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 enviroment passed to us.
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
- attr_writer :port
54
- end
55
-
56
- def self.log_directory
57
- File.join(working_dir, 'log')
58
- end
59
-
60
- def self.log_file_path
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
- # Used to start the Landrush DNS server as a child process using ChildProcess gem
81
- def self.start
82
- # On a machine with just Vagrant installed there might be no other Ruby except the
83
- # one bundled with Vagrant. Let's make sure the embedded bin directory containing
84
- # the Ruby executable is added to the PATH.
85
- Landrush::Util::Path.ensure_ruby_on_path
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
- ruby_bin = Landrush::Util::Path.embedded_vagrant_ruby.nil? ? 'ruby' : Landrush::Util::Path.embedded_vagrant_ruby
88
- start_server_script = Pathname(__dir__).join('start_server.rb').to_s
89
- @ui.detail("[landrush] '#{ruby_bin} #{start_server_script} #{port} #{working_dir} #{gems_dir}'") unless @ui.nil?
90
- if Vagrant::Util::Platform.windows?
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
- write_pid(pid, pid_file)
128
- # As of Vagrant 1.8.6 this additonal sleep is needed, otherwise the child process dies!?
129
- sleep 1
130
- end
118
+ def stop
119
+ with_pid_lock do |file|
120
+ puts 'Stopping daemon...'
131
121
 
132
- def self.stop
133
- puts 'Stopping daemon...'
122
+ # Check if the daemon is already stopped...
123
+ unless running?(file)
124
+ return
125
+ end
134
126
 
135
- # Check if the pid file exists...
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
- pid = read_pid(pid_file)
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
- # Check if the daemon is already stopped...
144
- unless running?
145
- puts "Pid #{pid} is not running. Has daemon crashed?"
146
- return
135
+ # Otherwise the daemon has been stopped.
136
+ write_pid('', file)
137
+ end
147
138
  end
148
139
 
149
- terminate_process pid
150
-
151
- # If after doing our best the daemon is still running (pretty odd)...
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
- # Otherwise the daemon has been stopped.
158
- delete_pid_file(pid_file)
159
- end
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
- else
183
- begin
184
- !!Process.kill(0, pid)
185
- rescue
186
- false
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
- def self.status
192
- case process_status(pid_file)
193
- when :running
194
- puts "Daemon status: running pid=#{read_pid(pid_file)}"
195
- when :stopped
196
- puts 'Daemon status: stopped'
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
- def self.run(port, working_dir)
205
- server = self
206
- server.port = port
207
- server.working_dir = working_dir
165
+ private
208
166
 
209
- ensure_path_exits(log_file_path)
210
- log_file = File.open(log_file_path, 'w')
211
- log_file.sync = true
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
- # Start the DNS server
216
- run_dns_server(listen: interfaces, logger: @logger) do
217
- match(/.*/, IN::A) do |transaction|
218
- host = Store.hosts.find(transaction.name)
219
- if host
220
- server.check_a_record(host, transaction)
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
- end
225
-
226
- match(/.*/, IN::PTR) do |transaction|
227
- host = Store.hosts.find(transaction.name)
228
- if host
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
- EventMachine.run do
247
- trap('INT') do
248
- EventMachine.stop
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
- server.fire(:stop)
255
- end
256
-
257
- def self.check_a_record(host, transaction)
258
- value = Store.hosts.get(host)
259
- return if value.nil?
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