phut 0.7.7 → 0.7.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.rubocop.yml +14 -1
  4. data/.travis.yml +2 -6
  5. data/Gemfile +30 -2
  6. data/Gemfile.lock +156 -0
  7. data/README.md +7 -2
  8. data/Rakefile +4 -3
  9. data/bin/phut +35 -83
  10. data/bin/vhost +28 -26
  11. data/features/{dsl.feature → dsl/error.feature} +8 -6
  12. data/features/{dsl_link.feature → dsl/link.feature} +11 -14
  13. data/features/dsl/netns.feature +115 -0
  14. data/features/dsl/vhost.feature +37 -0
  15. data/features/{dsl_vswitch.feature → dsl/vswitch.feature} +12 -12
  16. data/features/phut_run.feature +15 -0
  17. data/features/shell/vswitch#destroy.feature +10 -0
  18. data/features/shell/vswitch#ports.feature +36 -0
  19. data/features/shell/vswitch.all.feature +26 -0
  20. data/features/shell/vswitch.create.feature +30 -0
  21. data/features/shell/vswitch.destroy.feature +19 -0
  22. data/features/shell/vswitch.destroy_all.feature +18 -0
  23. data/features/step_definitions/link_steps.rb +5 -0
  24. data/features/step_definitions/netns_steps.rb +31 -0
  25. data/features/step_definitions/phut_steps.rb +5 -34
  26. data/features/step_definitions/vhost_steps.rb +5 -0
  27. data/features/step_definitions/vswitch_steps.rb +17 -0
  28. data/features/support/env.rb +3 -3
  29. data/features/support/hooks.rb +23 -15
  30. data/lib/phut.rb +3 -0
  31. data/lib/phut/finder.rb +19 -0
  32. data/lib/phut/link.rb +84 -0
  33. data/lib/phut/netns.rb +111 -22
  34. data/lib/phut/open_vswitch.rb +98 -96
  35. data/lib/phut/parser.rb +39 -8
  36. data/lib/phut/raw_socket.rb +4 -0
  37. data/lib/phut/route.rb +34 -0
  38. data/lib/phut/setting.rb +21 -4
  39. data/lib/phut/shell_runner.rb +13 -2
  40. data/lib/phut/syntax.rb +31 -14
  41. data/lib/phut/syntax/directive.rb +9 -1
  42. data/lib/phut/syntax/netns_directive.rb +13 -2
  43. data/lib/phut/syntax/vhost_directive.rb +2 -0
  44. data/lib/phut/syntax/vswitch_directive.rb +3 -1
  45. data/lib/phut/version.rb +3 -1
  46. data/lib/phut/veth.rb +68 -0
  47. data/lib/phut/vhost.rb +99 -58
  48. data/lib/phut/vhost_daemon.rb +53 -11
  49. data/lib/phut/vsctl.rb +125 -0
  50. data/lib/phut/vswitch.rb +10 -0
  51. data/phut.gemspec +9 -31
  52. data/tasks/cucumber.rake +5 -1
  53. data/tasks/flay.rake +2 -0
  54. data/tasks/flog.rake +3 -1
  55. data/tasks/gem.rake +2 -0
  56. data/tasks/minitest.rake +7 -0
  57. data/tasks/reek.rake +2 -0
  58. data/tasks/rubocop.rake +2 -0
  59. data/tasks/yard.rake +2 -0
  60. data/test/phut/link_test.rb +85 -0
  61. data/test/phut/netns_test.rb +58 -0
  62. data/test/phut/open_vswitch_test.rb +125 -0
  63. data/test/phut/veth_test.rb +48 -0
  64. data/test/phut/vhost_test.rb +56 -0
  65. metadata +41 -287
  66. data/.rspec +0 -3
  67. data/Guardfile +0 -29
  68. data/features/dsl_vhost.feature +0 -37
  69. data/features/phut_kill.feature +0 -27
  70. data/features/shell.feature +0 -39
  71. data/lib/phut/configuration.rb +0 -92
  72. data/lib/phut/null_logger.rb +0 -14
  73. data/lib/phut/virtual_link.rb +0 -109
  74. data/spec/phut/parser_spec.rb +0 -66
  75. data/spec/phut_spec.rb +0 -45
  76. data/spec/spec_helper.rb +0 -14
  77. data/tasks/LICENSE +0 -675
  78. data/tasks/relish.rake +0 -8
  79. data/tasks/rspec.rake +0 -8
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --require spec_helper
2
- --order random
3
- --color
data/Guardfile DELETED
@@ -1,29 +0,0 @@
1
- guard :rspec, cmd: 'bundle exec rspec' do
2
- watch(%r{^spec/phut/.+_spec\.rb$})
3
- watch(%r{^lib/phut/(.+)\.rb$}) { |m| "spec/phut/#{m[1]}_spec.rb" }
4
- watch('spec/spec_helper.rb') { 'spec' }
5
- end
6
-
7
- guard :bundler do
8
- watch('Gemfile')
9
- watch(/^.+\.gemspec/)
10
- end
11
-
12
- guard :rubocop, all_on_start: false do
13
- watch('Gemfile')
14
- watch('Guardfile')
15
- watch('Rakefile')
16
- watch('bin/phut')
17
- watch(/.+\.rake$/)
18
- watch(/.+\.rb$/)
19
- watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
20
- end
21
-
22
- guard 'cucumber', cli: '--tags ~@sudo --tags ~@shell' do
23
- watch('bin/phut') { 'features' }
24
- watch(%r{^features/.+\.feature$})
25
- watch(%r{^features/support/.+$}) { 'features' }
26
- watch(%r{^features/step_definitions/(.+)_steps\.rb$}) do |m|
27
- Dir[File.join("**/#{m[1]}.feature")][0] || 'features'
28
- end
29
- end
@@ -1,37 +0,0 @@
1
- Feature: The vhost DSL directive.
2
- @sudo
3
- Scenario: phut run with "vhost { ip ... }"
4
- Given a file named "network.conf" with:
5
- """
6
- vhost { ip '192.168.0.1' }
7
- vhost { ip '192.168.0.2' }
8
- link '192.168.0.1', '192.168.0.2'
9
- """
10
- When I do phut run "network.conf"
11
- Then a vhost named "192.168.0.1" launches
12
- And a vhost named "192.168.0.2" launches
13
-
14
- @sudo
15
- Scenario: phut run with "vhost(alias) { ... }"
16
- Given a file named "network.conf" with:
17
- """
18
- vhost('host1') { ip '192.168.0.1' }
19
- vhost('host2') { ip '192.168.0.2' }
20
- link 'host1', 'host2'
21
- """
22
- When I do phut run "network.conf"
23
- Then a vhost named "host1" launches
24
- And a vhost named "host2" launches
25
-
26
- @sudo
27
- Scenario: phut run with "vhost(alias)"
28
- Given a file named "network.conf" with:
29
- """
30
- vhost('host1')
31
- vhost('host2')
32
- link 'host1', 'host2'
33
- """
34
- When I do phut run "network.conf"
35
- Then a vhost named "host1" launches
36
- And a vhost named "host2" launches
37
-
@@ -1,27 +0,0 @@
1
- Feature: phut kill command
2
- Background:
3
- Given a file named "network.conf" with:
4
- """
5
- vswitch { datapath_id 0xabc }
6
-
7
- vhost('host1') { ip '192.168.0.1' }
8
- vhost('host2') { ip '192.168.0.2' }
9
-
10
- link '0xabc', 'host1'
11
- link '0xabc', 'host2'
12
- """
13
- And I do phut run "network.conf"
14
-
15
- @sudo
16
- Scenario: phut kill vswitch_name
17
- When I do phut kill "0xabc"
18
- And I run `sudo ovs-vsctl list-br`
19
- Then the output from "sudo ovs-vsctl list-br" should not contain "br0xabc"
20
-
21
- @sudo
22
- Scenario: phut kill vhost_name
23
- When I do phut kill "host1"
24
- And I successfully run `sleep 5`
25
- Then the following files should not exist:
26
- | vhost.host1.pid |
27
- | vhost.host1.ctl |
@@ -1,39 +0,0 @@
1
- Feature: Shell
2
- Background:
3
- Given I wait 5 seconds for a command to start up
4
- And I run `phut -v` interactively
5
-
6
- @shell
7
- Scenario: vswitch NUMBER
8
- When I type "vswitch 0xabc"
9
- And I type "quit"
10
- And sleep 1
11
- Then a vswitch named "0xabc" should be running
12
-
13
- @shell
14
- Scenario: vswitch STRING
15
- When I type "vswitch '0xabc'"
16
- And I type "quit"
17
- And sleep 1
18
- Then a vswitch named "0xabc" should be running
19
-
20
- @shell
21
- Scenario: vswitch twice and fail
22
- And I type "vswitch 0xabc"
23
- When I type "vswitch 0xabc"
24
- And I type "quit"
25
- Then the output should contain "Open vSwitch (dpid = 0xabc) is already running!"
26
-
27
- @shell
28
- Scenario: Kill and .pid is deleted
29
- And I type "vswitch 0xabc"
30
- When I type "kill 0xabc"
31
- And I type "quit"
32
- And sleep 1
33
- Then a vswitch named "0xabc" should not be running
34
-
35
- @shell
36
- Scenario: Kill without run and fail
37
- When I type "kill 0xabc"
38
- And I type "quit"
39
- Then the output should contain "Open vSwitch (dpid = 0xabc) is not running!"
@@ -1,92 +0,0 @@
1
- require 'phut/null_logger'
2
- require 'phut/open_vswitch'
3
-
4
- module Phut
5
- # Parsed DSL data.
6
- class Configuration
7
- def initialize(&block)
8
- OpenVswitch.all.clear
9
- Vhost.all.clear
10
- Netns.all.clear
11
- VirtualLink.all.clear
12
- block.call self
13
- end
14
-
15
- # rubocop:disable MethodLength
16
- def fetch(key)
17
- case key
18
- when String
19
- [OpenVswitch, Vhost, Netns].each do |each|
20
- found = each.find_by(name: key)
21
- return found if found
22
- end
23
- fail "Invalid key: #{key.inspect}"
24
- when Array
25
- VirtualLink.each do |each|
26
- return each if [each.name_a, each.name_b].sort == key.sort
27
- end
28
- fail "link #{key.join ' '} not found."
29
- else
30
- fail "Invalid key: #{key.inspect}"
31
- end
32
- end
33
- # rubocop:enable MethodLength
34
-
35
- def update_connections
36
- update_vswitch_ports
37
- update_vhost_interfaces
38
- update_netns_interfaces
39
- self
40
- end
41
-
42
- def run
43
- [VirtualLink, Vhost, Netns, OpenVswitch].each do |klass|
44
- klass.each(&:run)
45
- end
46
- end
47
-
48
- def stop
49
- [OpenVswitch, Vhost, Netns, VirtualLink].each do |klass|
50
- klass.each(&:stop)
51
- end
52
- end
53
-
54
- private
55
-
56
- def update_vswitch_ports
57
- VirtualLink.each do |each|
58
- maybe_connect_link_to_vswitch each
59
- end
60
- end
61
-
62
- def maybe_connect_link_to_vswitch(link)
63
- vswitches_connected_to(link).each do |each|
64
- each.add_network_device link.find_network_device(each)
65
- end
66
- end
67
-
68
- def vswitches_connected_to(link)
69
- OpenVswitch.select { |each| link.connect_to?(each) }
70
- end
71
-
72
- def update_vhost_interfaces
73
- Vhost.each do |each|
74
- each.network_device = find_network_device(each)
75
- end
76
- end
77
-
78
- def update_netns_interfaces
79
- Netns.each do |each|
80
- each.network_device = find_network_device(each)
81
- end
82
- end
83
-
84
- def find_network_device(vhost)
85
- VirtualLink.each do |each|
86
- device = each.find_network_device(vhost)
87
- return device if device
88
- end
89
- fail "No network device found for #{vhost}."
90
- end
91
- end
92
- end
@@ -1,14 +0,0 @@
1
- require 'logger'
2
-
3
- module Phut
4
- # Null logger
5
- class NullLogger < Logger
6
- def initialize(*_args)
7
- # noop
8
- end
9
-
10
- def add(*_args, &_block)
11
- # noop
12
- end
13
- end
14
- end
@@ -1,109 +0,0 @@
1
- require 'active_support/core_ext/class/attribute_accessors'
2
- require 'phut/null_logger'
3
- require 'phut/shell_runner'
4
-
5
- module Phut
6
- # Network virtual link.
7
- class VirtualLink
8
- cattr_accessor(:all, instance_reader: false) { [] }
9
-
10
- def self.create(name_a, name_b, logger = NullLogger.new)
11
- new(name_a, name_b, logger).tap { |vlink| all << vlink }
12
- end
13
-
14
- def self.each(&block)
15
- all.each(&block)
16
- end
17
-
18
- # Creates a valid network device name.
19
- class NetworkDeviceName
20
- attr_reader :name
21
- attr_writer :port_number
22
-
23
- def initialize(name)
24
- @name = name
25
- end
26
-
27
- def to_s
28
- @name.tr('.', '_') + port_number_string
29
- end
30
-
31
- def inspect
32
- to_s
33
- end
34
-
35
- private
36
-
37
- def port_number_string
38
- @port_number ? '_' + @port_number.to_s : ''
39
- end
40
- end
41
-
42
- include ShellRunner
43
-
44
- attr_reader :name_a
45
- attr_reader :name_b
46
- attr_reader :device_a
47
- attr_reader :device_b
48
-
49
- def initialize(name_a, name_b, logger)
50
- fail if name_a == name_b
51
- @name_a = name_a
52
- @name_b = name_b
53
- @device_a = NetworkDeviceName.new(name_a)
54
- @device_b = NetworkDeviceName.new(name_b)
55
- @logger = logger
56
- end
57
-
58
- def ==(other)
59
- @name_a == other.name_a &&
60
- @name_b == other.name_b &&
61
- @device_a == other.device_a &&
62
- @device_b == other.device_b
63
- end
64
-
65
- def run
66
- stop if up?
67
- add
68
- up
69
- end
70
-
71
- def stop
72
- return unless up?
73
- stop!
74
- end
75
-
76
- def stop!
77
- sh "sudo ip link delete #{@device_a}"
78
- rescue
79
- raise "link #{@name_a} #{@name_b} does not exist!"
80
- end
81
-
82
- def up?
83
- /^#{@device_a}\s+Link encap:Ethernet/ =~ `LANG=C ifconfig -a` || false
84
- end
85
-
86
- def connect_to?(vswitch)
87
- find_network_device(vswitch) || false
88
- end
89
-
90
- def find_network_device(vswitch_or_vhost)
91
- [@device_a, @device_b].detect do |each|
92
- each.name == vswitch_or_vhost.name
93
- end
94
- end
95
-
96
- private
97
-
98
- def add
99
- sh "sudo ip link add name #{@device_a} type veth peer name #{@device_b}"
100
- sh "sudo /sbin/sysctl -q -w net.ipv6.conf.#{@device_a}.disable_ipv6=1"
101
- sh "sudo /sbin/sysctl -q -w net.ipv6.conf.#{@device_b}.disable_ipv6=1"
102
- end
103
-
104
- def up
105
- sh "sudo /sbin/ifconfig #{@device_a} up"
106
- sh "sudo /sbin/ifconfig #{@device_b} up"
107
- end
108
- end
109
- end
@@ -1,66 +0,0 @@
1
- require 'phut'
2
- require 'stringio'
3
-
4
- describe Phut::Parser do
5
- describe '#parse' do
6
- Given do
7
- allow(IO).to receive(:read).with('CONFIGURATION_FILE').and_return(string)
8
- end
9
- Given(:configuration) { Phut::Parser.new.parse 'CONFIGURATION_FILE' }
10
-
11
- context "with 'vswitch { dpid '0xabc' }'" do
12
- When(:string) { "vswitch { dpid '0xabc' }" }
13
-
14
- describe '#vswitch' do
15
- Then { configuration.fetch('0xabc').datapath_id == 0xabc }
16
- Then { configuration.fetch('0xabc').dpid == 0xabc }
17
- end
18
- end
19
-
20
- context "with 'vswitch { datapath_id '0xabc' }" do
21
- When(:string) { "vswitch { datapath_id '0xabc' }" }
22
-
23
- describe '#vswitch' do
24
- Then { configuration.fetch('0xabc').dpid == 0xabc }
25
- Then { configuration.fetch('0xabc').datapath_id == 0xabc }
26
- end
27
- end
28
-
29
- context "with 'vswitch('my_controller') { dpid '0xabc' }'" do
30
- When(:string) { "vswitch('my_controller') { dpid '0xabc' }" }
31
-
32
- describe '#vswitch' do
33
- Then { configuration.fetch('my_controller').dpid == 0xabc }
34
- Then { configuration.fetch('my_controller').datapath_id == 0xabc }
35
- end
36
- end
37
-
38
- context "with 'vhost { ip '192.168.0.1' }' ..." do
39
- When(:string) do
40
- <<-CONFIGURATION
41
- vhost { ip '192.168.0.1' }
42
- vhost { ip '192.168.0.2' }
43
- link '192.168.0.1', '192.168.0.2'
44
- CONFIGURATION
45
- end
46
-
47
- describe '#vhost' do
48
- Then { configuration.fetch('192.168.0.1').ip_address == '192.168.0.1' }
49
- end
50
- end
51
-
52
- context "with 'vhost('host1') { ip '192.168.0.1' }' ..." do
53
- When(:string) do
54
- <<-CONFIGURATION
55
- vhost('host1') { ip '192.168.0.1' }
56
- vhost('host2') { ip '192.168.0.2' }
57
- link 'host1', 'host2'
58
- CONFIGURATION
59
- end
60
-
61
- describe '#vhost' do
62
- Then { configuration.fetch('host1').ip_address == '192.168.0.1' }
63
- end
64
- end
65
- end
66
- end
@@ -1,45 +0,0 @@
1
- require 'phut/setting'
2
-
3
- describe Phut do
4
- Given { allow(FileTest).to receive(:directory?).and_return(true) }
5
-
6
- describe '.pid_dir' do
7
- Given(:result) { Phut.pid_dir }
8
- Then { result == Dir.tmpdir }
9
-
10
- context "pid_dir = '/tmp/pid'" do
11
- Given { Phut.pid_dir = '/tmp/pid' }
12
- Then { result == '/tmp/pid' }
13
- end
14
-
15
- context "pid_dir = '.'" do
16
- Given { Phut.pid_dir = '.' }
17
- Then { result == File.expand_path('.') }
18
- end
19
- end
20
-
21
- describe '.log_dir' do
22
- Given(:result) { Phut.log_dir }
23
- Then { result == Dir.tmpdir }
24
-
25
- context "log_dir = '/tmp/log'" do
26
- Given { Phut.log_dir = '/tmp/log' }
27
- Then { result == '/tmp/log' }
28
- end
29
-
30
- context "log_dir = '.'" do
31
- Given { Phut.log_dir = '.' }
32
- Then { result == File.expand_path('.') }
33
- end
34
- end
35
-
36
- describe '.socket_dir' do
37
- Given(:result) { Phut.socket_dir }
38
- Then { result == Dir.tmpdir }
39
-
40
- context "socket_dir = '/tmp/socket'" do
41
- Given { Phut.socket_dir = '/tmp/socket' }
42
- Then { result == '/tmp/socket' }
43
- end
44
- end
45
- end