phut 0.7.7 → 0.7.8

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 (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/bin/vhost CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'rubygems'
4
5
  require 'bundler'
@@ -10,6 +11,7 @@ require 'phut'
10
11
  module Phut
11
12
  class VhostDaemon
12
13
  # /bin/vhost command
14
+ # rubocop:disable BlockLength
13
15
  module App
14
16
  extend GLI::App
15
17
 
@@ -18,51 +20,50 @@ module Phut
18
20
  desc 'Runs a vhost process'
19
21
  command :run do |c|
20
22
  desc 'Host name'
21
- c.flag [:n, :name]
23
+ c.flag %i[n name]
22
24
  desc 'Network interface'
23
- c.flag [:I, :interface]
25
+ c.flag %i[I interface]
24
26
  desc 'IP address'
25
- c.flag [:i, :ip_address]
27
+ c.flag %i[i ip_address]
26
28
  desc 'MAC address'
27
- c.flag [:m, :mac_address]
29
+ c.flag %i[m mac_address]
28
30
  c.desc 'ARP entries'
29
- c.flag [:a, :arp_entries], negatable: false
31
+ c.flag %i[a arp_entries], negatable: false
30
32
  c.desc 'Promisc mode'
31
- c.switch [:p, :promisc], negatable: false
33
+ c.switch %i[p promisc], negatable: false
32
34
 
33
35
  c.desc 'Location to put pid files'
34
- c.flag [:P, :pid_dir], default_value: Phut.pid_dir
36
+ c.flag %i[P pid_dir], default_value: Phut.pid_dir
35
37
  c.desc 'Location to put log files'
36
- c.flag [:L, :log_dir], default_value: Phut.log_dir
38
+ c.flag %i[L log_dir], default_value: Phut.log_dir
37
39
  c.desc 'Location to put socket files'
38
- c.flag [:S, :socket_dir], default_value: Phut.socket_dir
40
+ c.flag %i[S socket_dir], default_value: Phut.socket_dir
39
41
 
40
- c.action do |_global_options, options, _args|
41
- fail '--name option is mandatory' if options[:name].nil?
42
- fail '--interface option is mandatory' if options[:interface].nil?
43
- fail '--ip_address option is mandatory' if options[:ip_address].nil?
44
- fail '--mac_address option is mandatory' if options[:mac_address].nil?
45
- options[:arp_table] =
46
- options[:arp_entries].split(',').
42
+ c.action do |_global_opts, opts, _args|
43
+ raise '--name option is mandatory' if opts[:name].nil?
44
+ raise '--ip_address option is mandatory' if opts[:ip_address].nil?
45
+ raise '--mac_address option is mandatory' if opts[:mac_address].nil?
46
+ opts[:arp_table] =
47
+ (opts[:arp_entries] || '').split(',').
47
48
  each_with_object({}) do |each, table|
48
49
  ip_address, mac_address = each.split('/')
49
50
  table[ip_address] = mac_address
50
51
  end
51
- VhostDaemon.new(options).run
52
+ VhostDaemon.new(opts).run
52
53
  end
53
54
  end
54
55
 
55
56
  desc 'Terminates a vhost process'
56
57
  command :stop do |c|
57
58
  desc 'Host name'
58
- c.flag [:n, :name]
59
+ c.flag %i[n name]
59
60
  c.desc 'Location to put socket files'
60
- c.flag [:S, :socket_dir], default_value: Phut.socket_dir
61
+ c.flag %i[S socket_dir], default_value: Phut.socket_dir
61
62
 
62
- c.action do |_global_options, options, _args|
63
- fail '--name option is mandatory' if options[:name].nil?
63
+ c.action do |_global_opts, opts, _args|
64
+ raise '--name option is mandatory' if opts[:name].nil?
64
65
  begin
65
- VhostDaemon.process(options[:name], options[:socket_dir]).stop
66
+ VhostDaemon.process(opts[:name], opts[:socket_dir]).kill
66
67
  rescue DRb::DRbConnError
67
68
  true # OK
68
69
  end
@@ -72,11 +73,11 @@ module Phut
72
73
  desc 'Sends UDP packets to destination host'
73
74
  command :send_packets do |c|
74
75
  desc 'Source host name'
75
- c.flag [:s, :source]
76
+ c.flag %i[s source]
76
77
 
77
- c.action do |_global_options, options, _args|
78
- fail '--source option is mandatory' if options[:source].nil?
79
- VhostDaemon.process(options[:source], options[:socket_dir]).
78
+ c.action do |_global_opts, opts, _args|
79
+ raise '--source option is mandatory' if opts[:source].nil?
80
+ VhostDaemon.process(opts[:source], opts[:socket_dir]).
80
81
  send_packets
81
82
  end
82
83
  end
@@ -85,5 +86,6 @@ module Phut
85
86
 
86
87
  exit run(ARGV)
87
88
  end
89
+ # rubocop:enable BlockLength
88
90
  end
89
91
  end
@@ -1,26 +1,28 @@
1
1
  Feature: DSL parser
2
+ @sudo
2
3
  Scenario: name conflict (vsiwtch and vswitch)
3
- Given a file named "network.conf" with:
4
+ Given a file named "phut.conf" with:
4
5
  """ruby
5
6
  vswitch { dpid 0xabc }
6
7
  vswitch { dpid 0xabc }
7
8
  """
8
- When I do phut run "network.conf"
9
+ When I do phut run "phut.conf"
9
10
  Then the exit status should not be 0
10
11
  And the stderr should contain:
11
12
  """
12
- The name 0xabc conflicts with vswitch (name = 0xabc, dpid = 0xabc).
13
+ a Vswitch #<Vswitch name: "0xabc", dpid: 0xabc, openflow_version: 1.0, tcp_port: 6653> already exists
13
14
  """
14
15
 
16
+ @sudo
15
17
  Scenario: name conflict (vhost and vhost)
16
- Given a file named "network.conf" with:
18
+ Given a file named "phut.conf" with:
17
19
  """ruby
18
20
  vhost { ip '192.168.0.1' }
19
21
  vhost { ip '192.168.0.1' }
20
22
  """
21
- When I do phut run "network.conf"
23
+ When I do phut run "phut.conf"
22
24
  Then the exit status should not be 0
23
25
  And the stderr should contain:
24
26
  """
25
- The name 192.168.0.1 conflicts with vhost (name = 192.168.0.1, IP address = 192.168.0.1).
27
+ error: 192.168.0.1 is already running
26
28
  """
@@ -1,29 +1,29 @@
1
1
  Feature: The link directive of phut DSL
2
2
  @sudo
3
3
  Scenario: link name_a, name_b
4
- Given a file named "network.conf" with:
4
+ Given a file named "phut.conf" with:
5
5
  """
6
6
  vswitch { dpid 0xabc }
7
7
  vhost { ip '192.168.0.1' }
8
8
  link '0xabc', '192.168.0.1'
9
9
  """
10
- When I do phut run "network.conf"
11
- Then a link is created between "0xabc" and "192.168.0.1"
10
+ When I do phut run "phut.conf"
11
+ Then a link between "0xabc" and "192.168.0.1" should be created
12
12
 
13
13
  @sudo
14
14
  Scenario: link alias_a, alias_b
15
- Given a file named "network.conf" with:
15
+ Given a file named "phut.conf" with:
16
16
  """
17
17
  vswitch('my_switch') { dpid 0xabc }
18
18
  vhost('host1') { ip '192.168.0.1' }
19
19
  link 'my_switch', 'host1'
20
20
  """
21
- When I do phut run "network.conf"
22
- Then a link is created between "my_switch" and "host1"
21
+ When I do phut run "phut.conf"
22
+ Then a link between "my_switch" and "host1" should be created
23
23
 
24
24
  @sudo
25
25
  Scenario: connect multiple links to a switch
26
- Given a file named "network.conf" with:
26
+ Given a file named "phut.conf" with:
27
27
  """
28
28
  vswitch { datapath_id 0xabc }
29
29
 
@@ -41,11 +41,8 @@ Feature: The link directive of phut DSL
41
41
  link '0xabc', 'host2'
42
42
  link '0xabc', 'host3'
43
43
  """
44
- When I do phut run "network.conf"
44
+ When I do phut run "phut.conf"
45
45
  And I run `phut show 0xabc`
46
- Then a link is created between "0xabc" and "host1"
47
- And a link is created between "0xabc" and "host2"
48
- And a link is created between "0xabc" and "host3"
49
- And the output from "phut show 0xabc" should contain "1(0xabc_1)"
50
- And the output from "phut show 0xabc" should contain "2(0xabc_2)"
51
- And the output from "phut show 0xabc" should contain "3(0xabc_3)"
46
+ Then a link between "0xabc" and "host1" should be created
47
+ And a link between "0xabc" and "host2" should be created
48
+ And a link between "0xabc" and "host3" should be created
@@ -0,0 +1,115 @@
1
+ Feature: The netns DSL directive.
2
+ @sudo
3
+ Scenario: phut run with "netns(name)"
4
+ Given a file named "phut.conf" with:
5
+ """
6
+ netns('host1')
7
+ """
8
+ When I do phut run "phut.conf"
9
+ Then a netns named "host1" should be started
10
+
11
+ @sudo
12
+ Scenario: ip option (no device)
13
+ Given a file named "phut.conf" with:
14
+ """
15
+ netns('host1') {
16
+ ip '192.168.0.1'
17
+ }
18
+ """
19
+ When I do phut run "phut.conf"
20
+ Then a netns named "host1" should be started
21
+ And the IP address of the netns "host1" should not be set
22
+
23
+ @sudo
24
+ Scenario: ip option
25
+ Given a file named "phut.conf" with:
26
+ """
27
+ netns('host1') {
28
+ ip '192.168.0.1'
29
+ }
30
+ netns('host2') {
31
+ ip '192.168.0.2'
32
+ }
33
+ link 'host1', 'host2'
34
+ """
35
+ When I do phut run "phut.conf"
36
+ Then the IP address of the netns "host1" should be "192.168.0.1"
37
+ And the IP address of the netns "host2" should be "192.168.0.2"
38
+
39
+ @sudo
40
+ Scenario: netmask option
41
+ Given a file named "phut.conf" with:
42
+ """
43
+ netns('host1') {
44
+ ip '192.168.0.1'
45
+ netmask '255.255.255.0'
46
+ }
47
+ netns('host2') {
48
+ ip '192.168.0.2'
49
+ netmask '255.255.255.128'
50
+ }
51
+ link 'host1', 'host2'
52
+ """
53
+ When I do phut run "phut.conf"
54
+ Then the netmask of the netns "host1" should be "255.255.255.0"
55
+ And the netmask of the netns "host2" should be "255.255.255.128"
56
+
57
+ @sudo
58
+ Scenario: mac option
59
+ Given a file named "phut.conf" with:
60
+ """
61
+ netns('host1') {
62
+ ip '192.168.0.1'
63
+ mac '00:00:ba:dc:ab:1e'
64
+ }
65
+ netns('host2') {
66
+ ip '192.168.0.2'
67
+ mac '00:ac:ce:55:1b:1e'
68
+ }
69
+ link 'host1', 'host2'
70
+ """
71
+ When I do phut run "phut.conf"
72
+ Then the MAC address of the netns "host1" should be "00:00:ba:dc:ab:1e"
73
+ And the MAC address of the netns "host2" should be "00:ac:ce:55:1b:1e"
74
+
75
+ @sudo
76
+ Scenario: route option
77
+ Given a file named "phut.conf" with:
78
+ """
79
+ netns('host1') {
80
+ ip '192.168.0.1'
81
+ netmask '255.255.255.0'
82
+ route net: '0.0.0.0', gateway: '192.168.0.254'
83
+ }
84
+ netns('host2') {
85
+ ip '192.168.1.2'
86
+ netmask '255.255.255.0'
87
+ route net: '0.0.0.0', gateway: '192.168.1.254'
88
+ }
89
+ link 'host1', 'host2'
90
+ """
91
+ When I do phut run "phut.conf"
92
+ Then the netns "host1" have the following route:
93
+ | net | gateway |
94
+ | 0.0.0.0 | 192.168.0.254 |
95
+ And the netns "host2" have the following route:
96
+ | net | gateway |
97
+ | 0.0.0.0 | 192.168.1.254 |
98
+
99
+ @sudo
100
+ Scenario: vlan option
101
+ Given a file named "phut.conf" with:
102
+ """
103
+ netns('host1') {
104
+ ip '192.168.0.1'
105
+ vlan 10
106
+ }
107
+ netns('host2') {
108
+ ip '192.168.1.2'
109
+ vlan 20
110
+ }
111
+ link 'host1', 'host2'
112
+ """
113
+ When I do phut run "phut.conf"
114
+ Then the VLAN of the netns "host1" should be "10"
115
+ And the VLAN of the netns "host2" should be "20"
@@ -0,0 +1,37 @@
1
+ Feature: The vhost DSL directive.
2
+ @sudo
3
+ Scenario: phut run with "vhost { ip ... }"
4
+ Given a file named "phut.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 "phut.conf"
11
+ Then a vhost named "192.168.0.1" should be running
12
+ And a vhost named "192.168.0.2" should be running
13
+
14
+ @sudo
15
+ Scenario: phut run with "vhost(alias) { ... }"
16
+ Given a file named "phut.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 "phut.conf"
23
+ Then a vhost named "host1" should be running
24
+ And a vhost named "host2" should be running
25
+
26
+ @sudo
27
+ Scenario: phut run with "vhost(alias)"
28
+ Given a file named "phut.conf" with:
29
+ """
30
+ vhost('host1')
31
+ vhost('host2')
32
+ link 'host1', 'host2'
33
+ """
34
+ When I do phut run "phut.conf"
35
+ Then a vhost named "host1" should be running
36
+ And a vhost named "host2" should be running
37
+
@@ -1,52 +1,52 @@
1
1
  @sudo
2
2
  Feature: The vswitch DSL directive.
3
3
  Scenario: vswitch { dpid STRING }
4
- Given a file named "network.conf" with:
4
+ Given a file named "phut.conf" with:
5
5
  """
6
6
  vswitch { dpid '0xabc' }
7
7
  """
8
- When I do phut run "network.conf"
8
+ When I do phut run "phut.conf"
9
9
  Then a vswitch named "0xabc" (controller port = 6653) should be running
10
10
 
11
11
  Scenario: vswitch { dpid NUMBER }
12
- Given a file named "network.conf" with:
12
+ Given a file named "phut.conf" with:
13
13
  """
14
14
  vswitch { dpid 0xabc }
15
15
  """
16
- When I do phut run "network.conf"
16
+ When I do phut run "phut.conf"
17
17
  Then a vswitch named "0xabc" (controller port = 6653) should be running
18
18
 
19
19
  Scenario: vswitch { datapath_id STRING }
20
- Given a file named "network.conf" with:
20
+ Given a file named "phut.conf" with:
21
21
  """
22
22
  vswitch { datapath_id '0xabc' }
23
23
  """
24
- When I do phut run "network.conf"
24
+ When I do phut run "phut.conf"
25
25
  Then a vswitch named "0xabc" (controller port = 6653) should be running
26
26
 
27
27
  Scenario: vswitch { datapath_id NUMBER }
28
- Given a file named "network.conf" with:
28
+ Given a file named "phut.conf" with:
29
29
  """
30
30
  vswitch { datapath_id 0xabc }
31
31
  """
32
- When I do phut run "network.conf"
32
+ When I do phut run "phut.conf"
33
33
  Then a vswitch named "0xabc" (controller port = 6653) should be running
34
34
 
35
35
  Scenario: vswitch { dpid ...; port NUMBER }
36
- Given a file named "network.conf" with:
36
+ Given a file named "phut.conf" with:
37
37
  """
38
38
  vswitch {
39
39
  datapath_id 0xabc
40
40
  port 1234
41
41
  }
42
42
  """
43
- When I do phut run "network.conf"
43
+ When I do phut run "phut.conf"
44
44
  Then a vswitch named "0xabc" (controller port = 1234) should be running
45
45
 
46
46
  Scenario: vswitch(alias) { ... }
47
- Given a file named "network.conf" with:
47
+ Given a file named "phut.conf" with:
48
48
  """
49
49
  vswitch('my_switch') { datapath_id '0xabc' }
50
50
  """
51
- When I do phut run "network.conf"
51
+ When I do phut run "phut.conf"
52
52
  Then a vswitch named "my_switch" (controller port = 6653) should be running
@@ -0,0 +1,15 @@
1
+ Feature: phut run command
2
+ Scenario: pid_dir doesn't exist error
3
+ When I run `phut run --pid_dir foo phut.conf`
4
+ Then the exit status should not be 0
5
+ And the output should contain "error: No such directory: foo"
6
+
7
+ Scenario: log_dir doesn't exist error
8
+ When I run `phut run --log_dir foo phut.conf`
9
+ Then the exit status should not be 0
10
+ And the output should contain "error: No such directory: foo"
11
+
12
+ Scenario: socket_dir doesn't exist error
13
+ When I run `phut run --socket_dir foo phut.conf`
14
+ Then the exit status should not be 0
15
+ And the output should contain "error: No such directory: foo"
@@ -0,0 +1,10 @@
1
+ Feature: Vswitch#destroy
2
+ Background:
3
+ Given I run `phut -v` interactively
4
+
5
+ @sudo
6
+ Scenario: Vswitch#stop
7
+ Given I type "vswitch = Vswitch.create(dpid: 0xabc)"
8
+ When I type "vswitch.destroy"
9
+ And sleep 5
10
+ Then a vswitch named "0xabc" should not be running
@@ -0,0 +1,36 @@
1
+ Feature: Vswitch#ports
2
+
3
+ TODO: Vswitch#ports should return an array of Port object
4
+ that contains its port number
5
+
6
+ Background:
7
+ Given I run `phut -v` interactively
8
+ And I type "vswitch = Vswitch.create(dpid: 0xabc)"
9
+
10
+ @sudo
11
+ Scenario: Vswitch#ports #=> []
12
+ When I type "vswitch.ports"
13
+ And sleep 5
14
+ Then the output should contain "[]"
15
+
16
+ @sudo
17
+ Scenario: Vswitch#ports
18
+ Given I type "link = Link.create('a', 'b')"
19
+ And I type "vswitch.add_port link.device('a')"
20
+ When I type "vswitch.ports"
21
+ And sleep 5
22
+ Then the output should contain:
23
+ """
24
+ ["L0_a"]
25
+ """
26
+
27
+ @sudo
28
+ Scenario: Vswitch#ports
29
+ Given I type "link = Link.create('a', 'b')"
30
+ And I type "vswitch.add_numbered_port 2, link.device('a')"
31
+ When I type "vswitch.ports"
32
+ And sleep 5
33
+ Then the output should contain:
34
+ """
35
+ ["L0_a"]
36
+ """