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/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
+ """