landrush 1.1.2 → 1.2.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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +12 -178
  3. data/.travis.yml +6 -1
  4. data/CHANGELOG.md +18 -1
  5. data/CONTRIBUTING.adoc +112 -0
  6. data/Gemfile +6 -9
  7. data/Guardfile +10 -0
  8. data/README.adoc +100 -0
  9. data/Rakefile +14 -2
  10. data/appveyor.yml +20 -0
  11. data/doc/Development.adoc +112 -0
  12. data/doc/ProxyMobile.adoc +66 -0
  13. data/doc/Troubleshooting.adoc +42 -0
  14. data/doc/Usage.adoc +271 -0
  15. data/features/commands.feature +35 -0
  16. data/features/dns_resolution.feature +6 -5
  17. data/features/{landrush-ip.feature → landrush_ip.feature} +0 -0
  18. data/features/step_definitions/landrush_custom_steps.rb +48 -0
  19. data/features/support/env.rb +25 -1
  20. data/landrush.gemspec +3 -3
  21. data/lib/landrush/action/common.rb +3 -11
  22. data/lib/landrush/action/install_prerequisites.rb +2 -3
  23. data/lib/landrush/action/redirect_dns.rb +1 -1
  24. data/lib/landrush/action/setup.rb +25 -30
  25. data/lib/landrush/action/teardown.rb +8 -11
  26. data/lib/landrush/cap/guest/all/read_host_visible_ip_address.rb +28 -4
  27. data/lib/landrush/cap/guest/linux/add_iptables_rule.rb +1 -1
  28. data/lib/landrush/cap/guest/linux/redirect_dns.rb +2 -2
  29. data/lib/landrush/cap/guest/suse/add_iptables_rule.rb +20 -0
  30. data/lib/landrush/cap/guest/suse/install_iptables.rb +14 -0
  31. data/lib/landrush/cap/guest/suse/iptables_installed.rb +11 -0
  32. data/lib/landrush/cap/host/suse/dnsmasq_installed.rb +11 -0
  33. data/lib/landrush/cap/host/suse/install_dnsmasq.rb +14 -0
  34. data/lib/landrush/cap/host/suse/restart_dnsmasq.rb +21 -0
  35. data/lib/landrush/cap/host/windows/configure_visibility_on_host.rb +1 -1
  36. data/lib/landrush/command.rb +42 -17
  37. data/lib/landrush/config.rb +29 -14
  38. data/lib/landrush/plugin.rb +30 -0
  39. data/lib/landrush/server.rb +96 -138
  40. data/lib/landrush/start_server.rb +11 -0
  41. data/lib/landrush/store.rb +6 -2
  42. data/lib/landrush/util/path.rb +32 -0
  43. data/lib/landrush/util/process_helper.rb +46 -0
  44. data/lib/landrush/util/retry.rb +2 -2
  45. data/lib/landrush/version.rb +1 -1
  46. data/test/landrush/action/setup_test.rb +19 -25
  47. data/test/landrush/action/teardown_test.rb +18 -15
  48. data/test/landrush/cap/guest/all/read_host_visible_ip_address_test.rb +35 -1
  49. data/test/landrush/cap/guest/linux/configured_dns_servers_test.rb +8 -8
  50. data/test/landrush/cap/guest/linux/redirect_dns_test.rb +4 -4
  51. data/test/landrush/config_test.rb +23 -2
  52. data/test/landrush/dependent_vms_test.rb +5 -5
  53. data/test/landrush/issues/255.rb +115 -0
  54. data/test/landrush/server_test.rb +22 -4
  55. data/test/landrush/store_test.rb +28 -13
  56. data/test/support/test_server_daemon.rb +2 -4
  57. data/test/test_helper.rb +37 -14
  58. metadata +30 -15
  59. data/CONTRIBUTING.md +0 -103
  60. data/NOTES.md +0 -28
  61. data/README.md +0 -406
  62. data/doc/proxy-mobile/README.md +0 -50
  63. data/features/step_definitions/dns.rb +0 -19
  64. data/features/step_definitions/ip.rb +0 -13
@@ -0,0 +1,11 @@
1
+ # This file gets execute outside the Vagrant (bundled) environment.
2
+ # For that reason we have to put the gems we need ourself onto the LOADPATH.
3
+ # The caller of this file will pass the Vagrant gem dir as first argument which
4
+ # we use as base to find the required gems
5
+
6
+ gem_path = ARGV[2]
7
+ Dir.entries(gem_path).each { |gem_dir| $LOAD_PATH.unshift "#{File.join(ARGV[2], gem_dir)}/lib" }
8
+
9
+ require_relative 'server'
10
+
11
+ Landrush::Server.run(ARGV[0], ARGV[1]) if __FILE__ == $PROGRAM_NAME
@@ -43,7 +43,11 @@ module Landrush
43
43
  end
44
44
 
45
45
  def find(search)
46
- search = IPAddr.new(search).reverse if (IPAddr.new(search) rescue nil)
46
+ search = IPAddr.new(search).reverse if begin
47
+ IPAddr.new(search)
48
+ rescue
49
+ nil
50
+ end
47
51
  current_config.keys.detect do |key|
48
52
  key.casecmp(search) == 0 ||
49
53
  search =~ /#{key}$/i ||
@@ -74,7 +78,7 @@ module Landrush
74
78
  end
75
79
 
76
80
  def write(config)
77
- File.open(backing_file, "w") do |f|
81
+ File.open(backing_file, 'w') do |f|
78
82
  f.write(JSON.pretty_generate(config))
79
83
  end
80
84
  end
@@ -0,0 +1,32 @@
1
+ module Landrush
2
+ module Util
3
+ class Path
4
+ def self.embedded_vagrant_ruby
5
+ bin_dir = embedded_vagrant_bin_dir
6
+ ruby_bin = bin_dir + separator + 'ruby'
7
+ ruby_bin if File.exist?(ruby_bin)
8
+ end
9
+
10
+ def self.ensure_ruby_on_path
11
+ bin_dir = embedded_vagrant_bin_dir
12
+ ENV['PATH'] = bin_dir + File::PATH_SEPARATOR + ENV['PATH'] if File.exist?(bin_dir)
13
+ end
14
+
15
+ def self.embedded_vagrant_bin_dir
16
+ vagrant_binary = Vagrant::Util::Which.which('vagrant')
17
+ vagrant_binary = File.realpath(vagrant_binary) if File.symlink?(vagrant_binary)
18
+ # in a Vagrant installation the Ruby executable is in ../embedded/bin relative to the vagrant executable
19
+ File.dirname(File.dirname(vagrant_binary)) + separator + 'embedded' + separator + 'bin'
20
+ end
21
+
22
+ def self.separator
23
+ # we don't use File.join here, since even on Cygwin we want a Windows path - see https://github.com/vagrant-landrush/landrush/issues/237
24
+ if Vagrant::Util::Platform.windows?
25
+ '\\'
26
+ else
27
+ '/'
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,46 @@
1
+ module Landrush
2
+ module Util
3
+ # A module containing helper classes for dealing with pid files
4
+ module ProcessHelper
5
+ def write_pid(pid, pid_file)
6
+ ensure_path_exits(pid_file)
7
+ File.open(pid_file, 'w') { |f| f << pid.to_s }
8
+ end
9
+
10
+ def read_pid(pid_file)
11
+ IO.read(pid_file).to_i
12
+ rescue
13
+ nil
14
+ end
15
+
16
+ def delete_pid_file(pid_file)
17
+ FileUtils.rm(pid_file) if File.exist? pid_file
18
+ end
19
+
20
+ def process_status(pid_file)
21
+ return running? ? :running : :unknown if File.exist? pid_file
22
+ :stopped
23
+ end
24
+
25
+ def ensure_path_exits(file_name)
26
+ dirname = File.dirname(file_name)
27
+ FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
28
+ end
29
+
30
+ def terminate_process(pid)
31
+ # Kill/Term loop - if the daemon didn't die easily, shoot
32
+ # it a few more times.
33
+ attempts = 5
34
+ while running? && attempts > 0
35
+ sig = (attempts >= 2) ? 'KILL' : 'TERM'
36
+
37
+ puts "Sending #{sig} to process #{pid}..."
38
+ Process.kill(sig, pid)
39
+
40
+ attempts -= 1
41
+ sleep 1
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,8 +1,8 @@
1
1
  module Landrush
2
2
  module Util
3
3
  class Retry
4
- def self.retry(opts=nil)
5
- opts = {tries: 1}.merge(opts || {})
4
+ def self.retry(opts = nil)
5
+ opts = { tries: 1 }.merge(opts || {})
6
6
  n = 0
7
7
  while n < opts[:tries]
8
8
  return true if yield
@@ -1,3 +1,3 @@
1
1
  module Landrush
2
- VERSION = '1.1.2'.freeze
2
+ VERSION = '1.2.0'.freeze
3
3
  end
@@ -7,29 +7,30 @@ module Landrush
7
7
  describe Setup do
8
8
  let(:env) { fake_environment }
9
9
  let(:app) { proc {} }
10
+
10
11
  before do
11
12
  env[:machine].config.landrush.host_redirect_dns = false
12
13
  end
13
14
 
14
- it "calls the next app in the chain" do
15
+ it 'calls the next app in the chain' do
15
16
  app = -> (e) { e[:called] = true }
16
- setup = Setup.new(app, nil)
17
+ setup = Landrush::Action::Setup.new(app, env)
17
18
 
18
19
  setup.call(env)
19
20
 
20
21
  env[:called].must_equal true
21
22
  end
22
23
 
23
- it "records the booting host as a dependent VM" do
24
- setup = Setup.new(app, nil)
24
+ it 'records the booting host as a dependent VM' do
25
+ setup = Landrush::Action::Setup.new(app, env)
25
26
 
26
27
  setup.call(env)
27
28
 
28
- DependentVMs.list.must_equal %w[somehost.vagrant.test]
29
+ DependentVMs.list.must_equal %w(somehost.vagrant.test)
29
30
  end
30
31
 
31
32
  it "starts the landrush server if it's not already started" do
32
- setup = Setup.new(app, nil)
33
+ setup = Landrush::Action::Setup.new(app, env)
33
34
 
34
35
  setup.call(env)
35
36
 
@@ -37,8 +38,10 @@ module Landrush
37
38
  end
38
39
 
39
40
  it "does not attempt to start the server if it's already up" do
40
- setup = Setup.new(app, nil)
41
+ setup = Landrush::Action::Setup.new(app, env)
41
42
 
43
+ Server.working_dir = File.join(env[:home_path], 'data', 'landrush')
44
+ Server.gems_dir = env[:gems_path].to_s + '/gems'
42
45
  Server.start
43
46
  original_pid = Server.pid
44
47
 
@@ -48,8 +51,8 @@ module Landrush
48
51
  Server.pid.must_equal original_pid
49
52
  end
50
53
 
51
- it "does nothing if it is not enabled via config" do
52
- setup = Setup.new(app, nil)
54
+ it 'does nothing if it is not enabled via config' do
55
+ setup = Landrush::Action::Setup.new(app, env)
53
56
 
54
57
  env[:machine].config.landrush.disable
55
58
  setup.call(env)
@@ -57,16 +60,8 @@ module Landrush
57
60
  DependentVMs.list.must_equal []
58
61
  end
59
62
 
60
- it "for single private network IP host visible IP can be retrieved w/o starting the VM" do
61
- setup = Setup.new(app, nil)
62
- env[:machine].config.vm.network :private_network, ip: '42.42.42.42'
63
-
64
- setup.call(env)
65
- Store.hosts.get('somehost.vagrant.test').must_equal '42.42.42.42'
66
- end
67
-
68
- it "for multiple private network IPs host visible IP cant be retrieved if host_ip_address is set" do
69
- setup = Setup.new(app, nil)
63
+ it 'for multiple private network IPs host visible IP cant be retrieved if host_ip_address is set' do
64
+ setup = Landrush::Action::Setup.new(app, env)
70
65
 
71
66
  env[:machine].config.vm.network :private_network, ip: '42.42.42.41'
72
67
  env[:machine].config.vm.network :private_network, ip: '42.42.42.42'
@@ -75,8 +70,8 @@ module Landrush
75
70
  Store.hosts.get('somehost.vagrant.test').must_equal '42.42.42.42'
76
71
  end
77
72
 
78
- it "is possible to add cnames via the config.landrush.host configuration option" do
79
- setup = Setup.new(app, nil)
73
+ it 'is possible to add cnames via the config.landrush.host configuration option' do
74
+ setup = Landrush::Action::Setup.new(app, env)
80
75
 
81
76
  env[:machine].config.landrush.host 'foo', 'bar'
82
77
  setup.call(env)
@@ -86,17 +81,16 @@ module Landrush
86
81
 
87
82
  describe 'after boot' do
88
83
  it "stores the machine's hostname => ip address" do
89
- setup = Setup.new(app, nil)
84
+ setup = Landrush::Action::Setup.new(app, env)
90
85
 
91
86
  setup.call(env)
92
87
 
93
88
  Store.hosts.get('somehost.vagrant.test').must_equal '1.2.3.4'
94
89
  end
95
90
 
96
- it "does nothing if it is not enabled via config" do
97
- setup = Setup.new(app, nil)
98
-
91
+ it 'does nothing if it is not enabled via config' do
99
92
  env = fake_environment(enabled: false)
93
+ setup = Landrush::Action::Setup.new(app, env)
100
94
  setup.call(env)
101
95
 
102
96
  Store.hosts.get('somehost.vagrant.test').must_equal nil
@@ -5,10 +5,10 @@ require 'landrush/action/teardown'
5
5
  module Landrush
6
6
  module Action
7
7
  describe Teardown do
8
- it "calls the next app in the chain" do
8
+ it 'calls the next app in the chain' do
9
9
  env = fake_environment
10
10
  app = -> (e) { e[:called] = true }
11
- teardown = Teardown.new(app, nil)
11
+ teardown = Teardown.new(app, env)
12
12
 
13
13
  teardown.call(env)
14
14
 
@@ -17,8 +17,8 @@ module Landrush
17
17
 
18
18
  it "clears the machine's hostname => ip address" do
19
19
  app = proc {}
20
- teardown = Teardown.new(app, nil)
21
20
  env = fake_environment
21
+ teardown = Teardown.new(app, env)
22
22
 
23
23
  Store.hosts.set('somehost.vagrant.test', '1.2.3.4')
24
24
  teardown.call(env)
@@ -26,10 +26,10 @@ module Landrush
26
26
  Store.hosts.get('somehost.vagrant.test').must_equal nil
27
27
  end
28
28
 
29
- it "removes the machine as a dependent VM" do
29
+ it 'removes the machine as a dependent VM' do
30
30
  app = proc {}
31
- teardown = Teardown.new(app, nil)
32
31
  env = fake_environment
32
+ teardown = Teardown.new(app, env)
33
33
 
34
34
  DependentVMs.add('somehost.vagrant.test')
35
35
  teardown.call(env)
@@ -37,10 +37,10 @@ module Landrush
37
37
  DependentVMs.list.must_equal []
38
38
  end
39
39
 
40
- it "stops the landrush server when there are no dependent machines left" do
40
+ it 'stops the landrush server when there are no dependent machines left' do
41
41
  app = proc {}
42
- teardown = Teardown.new(app, nil)
43
42
  env = fake_environment
43
+ teardown = Teardown.new(app, env)
44
44
 
45
45
  Server.start
46
46
  teardown.call(env)
@@ -48,22 +48,26 @@ module Landrush
48
48
  Server.running?.must_equal false
49
49
  end
50
50
 
51
- it "leaves the landrush server when other dependent vms exist" do
51
+ it 'leaves the landrush server when other dependent vms exist' do
52
52
  app = proc {}
53
- teardown = Teardown.new(app, nil)
54
53
  env = fake_environment
54
+ teardown = Teardown.new(app, env)
55
+
55
56
  DependentVMs.add('otherhost.vagrant.test')
56
57
 
58
+ Server.working_dir = File.join(env[:home_path], 'data', 'landrush')
59
+ Server.gems_dir = env[:gems_path].to_s + '/gems'
57
60
  Server.start
58
61
  teardown.call(env)
59
62
 
60
63
  Server.running?.must_equal true
61
64
  end
62
65
 
63
- it "leaves static entries when other dependent vms exist" do
66
+ it 'leaves static entries when other dependent vms exist' do
64
67
  app = proc {}
65
- teardown = Teardown.new(app, nil)
66
68
  env = fake_environment
69
+ teardown = Teardown.new(app, env)
70
+
67
71
  DependentVMs.add('otherhost.vagrant.test')
68
72
 
69
73
  fake_static_entry(env, 'static.vagrant.test', '3.4.5.6')
@@ -75,23 +79,22 @@ module Landrush
75
79
 
76
80
  it "leaves the server alone if it's not running" do
77
81
  app = proc {}
78
- teardown = Teardown.new(app, nil)
79
82
  env = fake_environment
83
+ teardown = Teardown.new(app, env)
80
84
 
81
85
  teardown.call(env)
82
86
 
83
87
  Server.running?.must_equal false
84
88
  end
85
89
 
86
- it "does nothing when landrush is disabled" do
90
+ it 'does nothing when landrush is disabled' do
87
91
  # somewhat unrealistic since this entry shouldn't be there if it was
88
92
  # disabled in the first place, but oh well
89
93
  Store.hosts.set('somehost.vagrant.test', '1.2.3.4')
90
94
 
91
95
  app = proc {}
92
- teardown = Teardown.new(app, nil)
93
-
94
96
  env = fake_environment
97
+ teardown = Teardown.new(app, env)
95
98
  env[:machine].config.landrush.disable
96
99
 
97
100
  teardown.call(env)
@@ -35,7 +35,6 @@ module Landrush
35
35
 
36
36
  expected = addresses.last['ipv4']
37
37
 
38
- # call_cap(machine).must_equal expected
39
38
  call_cap(machine).must_equal expected
40
39
  end
41
40
 
@@ -81,6 +80,41 @@ module Landrush
81
80
 
82
81
  call_cap(machine).must_equal expected
83
82
  end
83
+
84
+ # Now, let's explicitly test the IPv4/IPv6 selection support, starting with the default (IPv4)
85
+ it 'should return the last non-empty IPv4 address' do
86
+ machine.config.landrush.host_interface = nil
87
+ machine.config.landrush.host_interface_excludes = [/exclude[0-9]+/, /include[0-9]+/]
88
+
89
+ expected = addresses.detect { |a| a['name'] == 'ipv6empty2' }
90
+ expected = expected['ipv4']
91
+
92
+ call_cap(machine).must_equal expected
93
+ end
94
+
95
+ # Test IPv6 selection
96
+ it 'should return the last non-empty IPv6 address' do
97
+ machine.config.landrush.host_interface = nil
98
+ machine.config.landrush.host_interface_class = :ipv6
99
+ machine.config.landrush.host_interface_excludes = [/exclude[0-9]+/, /include[0-9]+/]
100
+
101
+ expected = addresses.detect { |a| a['name'] == 'ipv4empty2' }
102
+ expected = expected['ipv6']
103
+
104
+ call_cap(machine).must_equal expected
105
+ end
106
+
107
+ # Test ANY selection
108
+ it 'should return the last non-empty address of either class' do
109
+ machine.config.landrush.host_interface = nil
110
+ machine.config.landrush.host_interface_class = :any
111
+ machine.config.landrush.host_interface_excludes = [/exclude[0-9]+/, /include[0-9]+/]
112
+
113
+ expected = addresses.detect { |a| a['name'] == 'ipv4empty2' }
114
+ expected = expected['ipv6']
115
+
116
+ call_cap(machine).must_equal expected
117
+ end
84
118
  end
85
119
  end
86
120
  end
@@ -4,30 +4,30 @@ describe Landrush::Cap::Linux::ConfiguredDnsServers do
4
4
  let(:machine) { fake_machine }
5
5
 
6
6
  before do
7
- Landrush::Cap::Linux::ConfiguredDnsServers.instance_variable_set("@dns_servers", nil)
7
+ Landrush::Cap::Linux::ConfiguredDnsServers.instance_variable_set('@dns_servers', nil)
8
8
  end
9
9
 
10
10
  describe 'configured_dns_servers' do
11
11
  it 'parses out a single resolv.conf dns server' do
12
- machine.communicate.stubs(:sudo).yields(:stdout, "nameserver 12.23.34.45")
12
+ machine.communicate.stubs(:sudo).yields(:stdout, 'nameserver 12.23.34.45')
13
13
 
14
14
  dns_servers = Landrush::Cap::Linux::ConfiguredDnsServers.configured_dns_servers(machine)
15
15
 
16
- dns_servers.must_equal(["12.23.34.45"])
16
+ dns_servers.must_equal(['12.23.34.45'])
17
17
  end
18
18
 
19
19
  it 'parses out multiple the resolv.conf dns servers' do
20
20
  machine.communicate.stubs(:sudo).yields(:stdout, [
21
- "nameserver 12.23.34.45",
22
- "nameserver 45.34.23.12"
21
+ 'nameserver 12.23.34.45',
22
+ 'nameserver 45.34.23.12'
23
23
  ].join("\n"))
24
24
 
25
25
  dns_servers = Landrush::Cap::Linux::ConfiguredDnsServers.configured_dns_servers(machine)
26
26
 
27
27
  dns_servers.must_equal([
28
- "12.23.34.45",
29
- "45.34.23.12"
30
- ])
28
+ '12.23.34.45',
29
+ '45.34.23.12'
30
+ ])
31
31
  end
32
32
  end
33
33
  end
@@ -7,10 +7,10 @@ describe Landrush::Cap::Linux::RedirectDns do
7
7
  it 'fetches the dns servers from the machine, and adds one iptables rule per server' do
8
8
  machine.guest.stubs(:capability).with(:configured_dns_servers).returns(%w(1.2.3.4 4.5.6.7))
9
9
 
10
- machine.guest.expects(:capability).with(:add_iptables_rule, "OUTPUT -t nat -p tcp -d 1.2.3.4 --dport 53 -j DNAT --to-destination 2.3.4.5:4321").once
11
- machine.guest.expects(:capability).with(:add_iptables_rule, "OUTPUT -t nat -p udp -d 1.2.3.4 --dport 53 -j DNAT --to-destination 2.3.4.5:4321").once
12
- machine.guest.expects(:capability).with(:add_iptables_rule, "OUTPUT -t nat -p tcp -d 4.5.6.7 --dport 53 -j DNAT --to-destination 2.3.4.5:4321").once
13
- machine.guest.expects(:capability).with(:add_iptables_rule, "OUTPUT -t nat -p udp -d 4.5.6.7 --dport 53 -j DNAT --to-destination 2.3.4.5:4321").once
10
+ machine.guest.expects(:capability).with(:add_iptables_rule, 'OUTPUT -t nat -p tcp -d 1.2.3.4 --dport 53 -j DNAT --to-destination 2.3.4.5:4321').once
11
+ machine.guest.expects(:capability).with(:add_iptables_rule, 'OUTPUT -t nat -p udp -d 1.2.3.4 --dport 53 -j DNAT --to-destination 2.3.4.5:4321').once
12
+ machine.guest.expects(:capability).with(:add_iptables_rule, 'OUTPUT -t nat -p tcp -d 4.5.6.7 --dport 53 -j DNAT --to-destination 2.3.4.5:4321').once
13
+ machine.guest.expects(:capability).with(:add_iptables_rule, 'OUTPUT -t nat -p udp -d 4.5.6.7 --dport 53 -j DNAT --to-destination 2.3.4.5:4321').once
14
14
 
15
15
  Landrush::Cap::Linux::RedirectDns.redirect_dns(
16
16
  machine,