landrush 1.2.0 → 1.3.0

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