phut 0.7.4 → 0.7.5
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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/bin/phut +19 -14
- data/bin/vhost +0 -1
- data/features/dsl.feature +14 -14
- data/features/shell.feature +6 -6
- data/features/step_definitions/phut_steps.rb +8 -4
- data/features/support/hooks.rb +7 -5
- data/lib/phut/configuration.rb +23 -57
- data/lib/phut/netns.rb +13 -2
- data/lib/phut/open_vswitch.rb +46 -9
- data/lib/phut/parser.rb +3 -3
- data/lib/phut/syntax.rb +10 -102
- data/lib/phut/syntax/directive.rb +16 -0
- data/lib/phut/syntax/netns_directive.rb +25 -0
- data/lib/phut/syntax/vhost_directive.rb +42 -0
- data/lib/phut/syntax/vswitch_directive.rb +26 -0
- data/lib/phut/version.rb +1 -1
- data/lib/phut/vhost.rb +30 -8
- data/lib/phut/virtual_link.rb +24 -6
- data/phut.gemspec +8 -8
- data/spec/phut/parser_spec.rb +0 -5
- data/spec/spec_helper.rb +1 -1
- metadata +40 -32
- data/.ruby-version +0 -1
- data/spec/phut/open_vswitch_spec.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c3b681d2cbe588388b838a3b6d9d888242a319a
|
4
|
+
data.tar.gz: 2b8602c3b6d63299c5f648256cffa40c201684c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f5bca013e25718e9e209dd90e9597ea62373e914af63c5a81bd286f8aa917e7f2de6dd8cd755664cc3593545c47fd532d1e8fc844f06ad641cd97167702d8e6
|
7
|
+
data.tar.gz: 3b31460f0b73ca4ee302b4664504e78c359549213bc92900dc887e2c93766c73849faa2cccf80e14137cb467fb955191f1f6ed929754fda7faae19b7c48f40dc
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/bin/phut
CHANGED
@@ -41,13 +41,17 @@ module Phut
|
|
41
41
|
Phut.socket_dir = dir
|
42
42
|
end
|
43
43
|
Pry::Commands.block_command 'vswitch' do |dpid|
|
44
|
-
Phut::OpenVswitch.
|
44
|
+
if Phut::OpenVswitch.find_by(name: dpid)
|
45
|
+
fail(Phut::OpenVswitch::AlreadyRunning,
|
46
|
+
"Open vSwitch (dpid = #{dpid}) is already running!")
|
47
|
+
end
|
48
|
+
Phut::OpenVswitch.create(dpid).run
|
45
49
|
end
|
46
50
|
Pry::Commands.block_command 'dump_flows' do |dpid|
|
47
|
-
puts Phut::OpenVswitch.
|
51
|
+
puts Phut::OpenVswitch.dump_flows(dpid)
|
48
52
|
end
|
49
53
|
Pry::Commands.block_command 'kill' do |dpid|
|
50
|
-
Phut::OpenVswitch.
|
54
|
+
Phut::OpenVswitch.shutdown(dpid)
|
51
55
|
end
|
52
56
|
pry
|
53
57
|
end
|
@@ -57,11 +61,11 @@ module Phut
|
|
57
61
|
arg_name 'FILE'
|
58
62
|
command :run do |c|
|
59
63
|
c.desc 'Location to put pid files'
|
60
|
-
c.flag [:
|
64
|
+
c.flag [:P, :pid_dir], default_value: Phut.pid_dir
|
61
65
|
c.desc 'Location to put log files'
|
62
|
-
c.flag [:
|
66
|
+
c.flag [:L, :log_dir], default_value: Phut.log_dir
|
63
67
|
c.desc 'Location to put socket files'
|
64
|
-
c.flag [:
|
68
|
+
c.flag [:S, :socket_dir], default_value: Phut.socket_dir
|
65
69
|
|
66
70
|
c.action do |global_options, options, args|
|
67
71
|
stdout_logger = Logger.new($stderr).tap do |logger|
|
@@ -87,19 +91,20 @@ module Phut
|
|
87
91
|
arg_name 'FILE'
|
88
92
|
command :stop do |c|
|
89
93
|
c.desc 'Location to put pid files'
|
90
|
-
c.flag [:
|
91
|
-
|
94
|
+
c.flag [:P, :pid_dir], default_value: Phut.pid_dir
|
92
95
|
c.desc 'Location to put log files'
|
93
|
-
c.flag [:
|
94
|
-
|
96
|
+
c.flag [:L, :log_dir], default_value: Phut.log_dir
|
95
97
|
c.desc 'Location to put socket files'
|
96
|
-
c.flag [:
|
98
|
+
c.flag [:S, :socket_dir], default_value: Phut.socket_dir
|
97
99
|
|
98
|
-
c.action do |global_options,
|
100
|
+
c.action do |global_options, options, args|
|
99
101
|
stdout_logger = Logger.new($stderr).tap do |logger|
|
100
102
|
logger.formatter = proc { |_sev, _dtm, _name, msg| msg + "\n" }
|
101
103
|
logger.level = global_options[:verbose] ? Logger::DEBUG : Logger::INFO
|
102
104
|
end
|
105
|
+
Phut.pid_dir = options.fetch(:pid_dir)
|
106
|
+
Phut.log_dir = options.fetch(:log_dir)
|
107
|
+
Phut.socket_dir = options.fetch(:socket_dir)
|
103
108
|
Phut::Parser.new(stdout_logger).parse(args[0]).stop
|
104
109
|
end
|
105
110
|
end
|
@@ -108,14 +113,14 @@ module Phut
|
|
108
113
|
arg_name 'NAME'
|
109
114
|
command :kill do |c|
|
110
115
|
c.desc 'Location to find socket files'
|
111
|
-
c.flag [:
|
116
|
+
c.flag [:S, :socket_dir], default_value: Phut.socket_dir
|
112
117
|
|
113
118
|
c.action do |_global_options, options, args|
|
114
119
|
help_now! if args.size != 1
|
115
120
|
begin
|
116
121
|
Phut::VhostDaemon.process(args[0], options[:socket_dir]).stop
|
117
122
|
rescue
|
118
|
-
Phut::OpenVswitch.
|
123
|
+
Phut::OpenVswitch.shutdown(args[0])
|
119
124
|
end
|
120
125
|
end
|
121
126
|
end
|
data/bin/vhost
CHANGED
data/features/dsl.feature
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
Feature: DSL parser
|
2
2
|
Scenario: name conflict (vsiwtch and vswitch)
|
3
3
|
Given a file named "network.conf" with:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
"""ruby
|
5
|
+
vswitch { dpid 0xabc }
|
6
|
+
vswitch { dpid 0xabc }
|
7
|
+
"""
|
8
8
|
When I do phut run "network.conf"
|
9
9
|
Then the exit status should not be 0
|
10
10
|
And the stderr should contain:
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
"""
|
12
|
+
The name 0xabc conflicts with vswitch (name = 0xabc, dpid = 0xabc).
|
13
|
+
"""
|
14
14
|
|
15
15
|
Scenario: name conflict (vhost and vhost)
|
16
16
|
Given a file named "network.conf" with:
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
"""ruby
|
18
|
+
vhost { ip '192.168.0.1' }
|
19
|
+
vhost { ip '192.168.0.1' }
|
20
|
+
"""
|
21
21
|
When I do phut run "network.conf"
|
22
22
|
Then the exit status should not be 0
|
23
23
|
And the stderr should contain:
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
"""
|
25
|
+
The name 192.168.0.1 conflicts with vhost (name = 192.168.0.1, IP address = 192.168.0.1).
|
26
|
+
"""
|
data/features/shell.feature
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
Feature: Shell
|
2
2
|
Background:
|
3
|
-
Given I
|
4
|
-
And I
|
3
|
+
Given I wait 5 seconds for a command to start up
|
4
|
+
And I run `phut -v` interactively
|
5
5
|
|
6
6
|
@shell
|
7
7
|
Scenario: vswitch NUMBER
|
8
8
|
When I type "vswitch 0xabc"
|
9
9
|
And I type "quit"
|
10
|
-
And
|
10
|
+
And sleep 1
|
11
11
|
Then a vswitch named "0xabc" should be running
|
12
12
|
|
13
13
|
@shell
|
14
14
|
Scenario: vswitch STRING
|
15
15
|
When I type "vswitch '0xabc'"
|
16
16
|
And I type "quit"
|
17
|
-
And
|
17
|
+
And sleep 1
|
18
18
|
Then a vswitch named "0xabc" should be running
|
19
19
|
|
20
20
|
@shell
|
@@ -22,7 +22,7 @@ Feature: Shell
|
|
22
22
|
Given I type "vswitch '0xabc'"
|
23
23
|
When I type "dump_flows 0xabc"
|
24
24
|
And I type "quit"
|
25
|
-
And
|
25
|
+
And sleep 1
|
26
26
|
Then the output should contain "NXST_FLOW reply"
|
27
27
|
|
28
28
|
@shell
|
@@ -37,7 +37,7 @@ Feature: Shell
|
|
37
37
|
And I type "vswitch 0xabc"
|
38
38
|
When I type "kill 0xabc"
|
39
39
|
And I type "quit"
|
40
|
-
And
|
40
|
+
And sleep 1
|
41
41
|
Then a vswitch named "0xabc" should not be running
|
42
42
|
|
43
43
|
@shell
|
@@ -1,18 +1,22 @@
|
|
1
1
|
require 'phut'
|
2
2
|
|
3
|
-
When(/^I do phut run "(.*?)"$/) do |
|
4
|
-
@config_file =
|
3
|
+
When(/^I do phut run "(.*?)"$/) do |config_file|
|
4
|
+
@config_file = config_file
|
5
5
|
cd('.') do
|
6
|
-
run_opts = "-
|
6
|
+
run_opts = "-P #{@pid_dir} -L #{@log_dir} -S #{@socket_dir}"
|
7
7
|
step %(I run `phut -v run #{run_opts} #{@config_file}`)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
11
|
When(/^I do phut kill "(.*?)"$/) do |name|
|
12
|
-
run_opts = "-
|
12
|
+
run_opts = "-S #{@socket_dir}"
|
13
13
|
step %(I successfully run `phut -v kill #{run_opts} #{name}`)
|
14
14
|
end
|
15
15
|
|
16
|
+
When(/^sleep (\d+)$/) do |time|
|
17
|
+
sleep time.to_i
|
18
|
+
end
|
19
|
+
|
16
20
|
Then(/^a vswitch named "(.*?)" should be running$/) do |name|
|
17
21
|
expect(system("sudo ovs-vsctl br-exists br#{name}")).to be_truthy
|
18
22
|
end
|
data/features/support/hooks.rb
CHANGED
@@ -12,11 +12,13 @@ Before('@sudo') do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
After('@sudo') do
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
Aruba.configure do |config|
|
16
|
+
Dir.chdir(config.working_directory) do
|
17
|
+
Phut.pid_dir = @pid_dir
|
18
|
+
Phut.log_dir = @log_dir
|
19
|
+
Phut.socket_dir = @socket_dir
|
20
|
+
Phut::Parser.new.parse(@config_file).stop
|
21
|
+
end
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
data/lib/phut/configuration.rb
CHANGED
@@ -4,19 +4,25 @@ require 'phut/open_vswitch'
|
|
4
4
|
module Phut
|
5
5
|
# Parsed DSL data.
|
6
6
|
class Configuration
|
7
|
-
def initialize(
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
def initialize(&block)
|
8
|
+
OpenVswitch.all.clear
|
9
|
+
Vhost.all.clear
|
10
|
+
Netns.all.clear
|
11
|
+
VirtualLink.all.clear
|
12
|
+
block.call self
|
11
13
|
end
|
12
14
|
|
13
15
|
# rubocop:disable MethodLength
|
14
16
|
def fetch(key)
|
15
17
|
case key
|
16
18
|
when String
|
17
|
-
|
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}"
|
18
24
|
when Array
|
19
|
-
|
25
|
+
VirtualLink.each do |each|
|
20
26
|
return each if [each.name_a, each.name_b].sort == key.sort
|
21
27
|
end
|
22
28
|
fail "link #{key.join ' '} not found."
|
@@ -33,62 +39,22 @@ module Phut
|
|
33
39
|
self
|
34
40
|
end
|
35
41
|
|
36
|
-
def vswitches
|
37
|
-
@all.values.select { |each| each.is_a? OpenVswitch }
|
38
|
-
end
|
39
|
-
|
40
|
-
def vhosts
|
41
|
-
@all.values.select { |each| each.is_a? Vhost }
|
42
|
-
end
|
43
|
-
|
44
|
-
def netnss
|
45
|
-
@all.values.select { |each| each.is_a? Netns }
|
46
|
-
end
|
47
|
-
|
48
42
|
def run
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
vswitches.each(&:run)
|
43
|
+
[VirtualLink, Vhost, Netns, OpenVswitch].each do |klass|
|
44
|
+
klass.each(&:run)
|
45
|
+
end
|
53
46
|
end
|
54
47
|
|
55
48
|
def stop
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
@links.each(&:maybe_stop)
|
60
|
-
end
|
61
|
-
|
62
|
-
def add_vswitch(name, attrs)
|
63
|
-
check_name_conflict name
|
64
|
-
@all[name] =
|
65
|
-
OpenVswitch.new(attrs[:dpid], attrs[:port_number], name, @logger)
|
66
|
-
end
|
67
|
-
|
68
|
-
def add_vhost(name, attrs)
|
69
|
-
check_name_conflict name
|
70
|
-
@all[name] =
|
71
|
-
Vhost.new(attrs[:ip], attrs[:mac], attrs[:promisc], name, @logger)
|
72
|
-
end
|
73
|
-
|
74
|
-
def add_netns(name, attrs)
|
75
|
-
check_name_conflict name
|
76
|
-
@all[name] = Netns.new(attrs, name, @logger)
|
77
|
-
end
|
78
|
-
|
79
|
-
def add_link(name_a, name_b)
|
80
|
-
@links << VirtualLink.new(name_a, name_b, @logger)
|
49
|
+
[OpenVswitch, Vhost, Netns, VirtualLink].each do |klass|
|
50
|
+
klass.each(&:stop)
|
51
|
+
end
|
81
52
|
end
|
82
53
|
|
83
54
|
private
|
84
55
|
|
85
|
-
def check_name_conflict(name)
|
86
|
-
conflict = @all[name]
|
87
|
-
fail "The name #{name} conflicts with #{conflict}." if conflict
|
88
|
-
end
|
89
|
-
|
90
56
|
def update_vswitch_ports
|
91
|
-
|
57
|
+
VirtualLink.each do |each|
|
92
58
|
maybe_connect_link_to_vswitch each
|
93
59
|
end
|
94
60
|
end
|
@@ -100,23 +66,23 @@ module Phut
|
|
100
66
|
end
|
101
67
|
|
102
68
|
def vswitches_connected_to(link)
|
103
|
-
|
69
|
+
OpenVswitch.select { |each| link.connect_to?(each) }
|
104
70
|
end
|
105
71
|
|
106
72
|
def update_vhost_interfaces
|
107
|
-
|
73
|
+
Vhost.each do |each|
|
108
74
|
each.network_device = find_network_device(each)
|
109
75
|
end
|
110
76
|
end
|
111
77
|
|
112
78
|
def update_netns_interfaces
|
113
|
-
|
79
|
+
Netns.each do |each|
|
114
80
|
each.network_device = find_network_device(each)
|
115
81
|
end
|
116
82
|
end
|
117
83
|
|
118
84
|
def find_network_device(vhost)
|
119
|
-
|
85
|
+
VirtualLink.each do |each|
|
120
86
|
device = each.find_network_device(vhost)
|
121
87
|
return device if device
|
122
88
|
end
|
data/lib/phut/netns.rb
CHANGED
@@ -1,15 +1,26 @@
|
|
1
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
1
2
|
require 'phut/null_logger'
|
2
3
|
require 'phut/shell_runner'
|
3
4
|
|
4
5
|
module Phut
|
5
6
|
# `ip netns ...` command runner
|
6
7
|
class Netns
|
8
|
+
cattr_accessor(:all, instance_reader: false) { [] }
|
9
|
+
|
10
|
+
def self.create(options, name, logger = NullLogger.new)
|
11
|
+
new(options, name, logger).tap { |netns| all << netns }
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.each(&block)
|
15
|
+
all.each(&block)
|
16
|
+
end
|
17
|
+
|
7
18
|
include ShellRunner
|
8
19
|
|
9
20
|
attr_reader :name
|
10
21
|
attr_accessor :network_device
|
11
22
|
|
12
|
-
def initialize(options, name, logger
|
23
|
+
def initialize(options, name, logger)
|
13
24
|
@name = name
|
14
25
|
@options = options
|
15
26
|
@logger = logger
|
@@ -26,7 +37,7 @@ module Phut
|
|
26
37
|
end
|
27
38
|
# rubocop:enable AbcSize
|
28
39
|
|
29
|
-
def
|
40
|
+
def stop
|
30
41
|
sh "sudo ip netns delete #{name}"
|
31
42
|
end
|
32
43
|
|
data/lib/phut/open_vswitch.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
1
2
|
require 'pio'
|
2
3
|
require 'phut/null_logger'
|
3
4
|
require 'phut/setting'
|
@@ -5,7 +6,43 @@ require 'phut/shell_runner'
|
|
5
6
|
|
6
7
|
module Phut
|
7
8
|
# Open vSwitch controller.
|
9
|
+
# rubocop:disable ClassLength
|
8
10
|
class OpenVswitch
|
11
|
+
cattr_accessor(:all, instance_reader: false) { [] }
|
12
|
+
|
13
|
+
def self.create(dpid, port_number = 6653, name = nil,
|
14
|
+
logger = NullLogger.new)
|
15
|
+
new(dpid, port_number, name, logger).tap do |vswitch|
|
16
|
+
conflict = find_by(name: vswitch.name)
|
17
|
+
fail "The name #{vswitch.name} conflicts with #{conflict}." if conflict
|
18
|
+
all << vswitch
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.dump_flows(dpid, port_number = 6653, name = nil,
|
23
|
+
logger = NullLogger.new)
|
24
|
+
OpenVswitch.new(dpid, port_number, name, logger).dump_flows
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.shutdown(dpid, port_number = 6653, name = nil,
|
28
|
+
logger = NullLogger.new)
|
29
|
+
OpenVswitch.new(dpid, port_number, name, logger).stop!
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.find_by(queries)
|
33
|
+
queries.inject(all) do |memo, (attr, value)|
|
34
|
+
memo.find_all { |vswitch| vswitch.__send__(attr) == value }
|
35
|
+
end.first
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.each(&block)
|
39
|
+
all.each(&block)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.select(&block)
|
43
|
+
all.select(&block)
|
44
|
+
end
|
45
|
+
|
9
46
|
class AlreadyRunning < StandardError; end
|
10
47
|
|
11
48
|
include ShellRunner
|
@@ -14,8 +51,7 @@ module Phut
|
|
14
51
|
alias_method :datapath_id, :dpid
|
15
52
|
attr_reader :network_devices
|
16
53
|
|
17
|
-
def initialize(dpid, port_number
|
18
|
-
name = nil, logger = NullLogger.new)
|
54
|
+
def initialize(dpid, port_number, name, logger)
|
19
55
|
@dpid = dpid
|
20
56
|
@port_number = port_number
|
21
57
|
@name = name
|
@@ -54,15 +90,15 @@ module Phut
|
|
54
90
|
# rubocop:enable AbcSize
|
55
91
|
|
56
92
|
def stop
|
57
|
-
|
58
|
-
|
93
|
+
return unless running?
|
94
|
+
stop!
|
59
95
|
end
|
60
|
-
alias_method :shutdown, :stop
|
61
96
|
|
62
|
-
def
|
63
|
-
|
64
|
-
|
97
|
+
def stop!
|
98
|
+
fail "Open vSwitch (dpid = #{@dpid}) is not running!" unless running?
|
99
|
+
sh "sudo ovs-vsctl del-br #{bridge_name}"
|
65
100
|
end
|
101
|
+
alias_method :shutdown, :stop!
|
66
102
|
|
67
103
|
def bring_port_up(port_number)
|
68
104
|
sh "sudo ovs-ofctl mod-port #{bridge_name} #{port_number} up"
|
@@ -73,7 +109,7 @@ module Phut
|
|
73
109
|
end
|
74
110
|
|
75
111
|
def dump_flows
|
76
|
-
`sudo ovs-ofctl dump-flows #{bridge_name}`
|
112
|
+
`sudo ovs-ofctl dump-flows #{bridge_name} -O #{Pio::OpenFlow.version}`
|
77
113
|
end
|
78
114
|
|
79
115
|
def running?
|
@@ -105,4 +141,5 @@ module Phut
|
|
105
141
|
'0' * (16 - hex.length) + hex
|
106
142
|
end
|
107
143
|
end
|
144
|
+
# rubocop:enable ClassLength
|
108
145
|
end
|
data/lib/phut/parser.rb
CHANGED
@@ -10,9 +10,9 @@ module Phut
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def parse(file)
|
13
|
-
Configuration.new
|
14
|
-
Syntax.new(
|
15
|
-
|
13
|
+
Configuration.new do |config|
|
14
|
+
Syntax.new(config, @logger).instance_eval IO.read(file), file
|
15
|
+
config.update_connections
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
data/lib/phut/syntax.rb
CHANGED
@@ -1,128 +1,36 @@
|
|
1
1
|
require 'phut/netns'
|
2
|
+
require 'phut/syntax/netns_directive'
|
3
|
+
require 'phut/syntax/vhost_directive'
|
4
|
+
require 'phut/syntax/vswitch_directive'
|
2
5
|
require 'phut/vhost'
|
3
6
|
require 'phut/virtual_link'
|
4
7
|
|
5
8
|
module Phut
|
6
9
|
# DSL syntax definitions.
|
7
10
|
class Syntax
|
8
|
-
|
9
|
-
class VswitchDirective
|
10
|
-
def initialize(alias_name, &block)
|
11
|
-
@attributes = { name: alias_name, port_number: 6653 }
|
12
|
-
instance_eval(&block)
|
13
|
-
end
|
14
|
-
|
15
|
-
def dpid(value)
|
16
|
-
dpid = if value.is_a?(String) && /^0x/=~ value
|
17
|
-
value.hex
|
18
|
-
else
|
19
|
-
value.to_i
|
20
|
-
end
|
21
|
-
@attributes[:dpid] = dpid
|
22
|
-
@attributes[:name] ||= format('%#x', @attributes[:dpid])
|
23
|
-
end
|
24
|
-
alias_method :datapath_id, :dpid
|
25
|
-
|
26
|
-
def port(port_no)
|
27
|
-
@attributes[:port_number] = port_no
|
28
|
-
end
|
29
|
-
|
30
|
-
def [](key)
|
31
|
-
@attributes[key]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# The 'vhost(name) { ...attributes... }' directive.
|
36
|
-
class VhostDirective
|
37
|
-
# Generates an unused IP address
|
38
|
-
class UnusedIpAddress
|
39
|
-
def initialize
|
40
|
-
@index = 0
|
41
|
-
end
|
42
|
-
|
43
|
-
def generate
|
44
|
-
@index += 1
|
45
|
-
"192.168.0.#{@index}"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
UnusedIpAddressSingleton = UnusedIpAddress.new
|
50
|
-
|
51
|
-
def initialize(alias_name, &block)
|
52
|
-
@attributes =
|
53
|
-
{ name: alias_name, mac: Pio::Mac.new(rand(0xffffffffffff + 1)) }
|
54
|
-
if block
|
55
|
-
instance_eval(&block) if block
|
56
|
-
else
|
57
|
-
@attributes[:ip] = UnusedIpAddressSingleton.generate
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def ip(value)
|
62
|
-
@attributes[:ip] = value
|
63
|
-
@attributes[:name] ||= value
|
64
|
-
end
|
65
|
-
|
66
|
-
def mac(value)
|
67
|
-
@attributes[:mac] = value
|
68
|
-
end
|
69
|
-
|
70
|
-
def promisc(on_off)
|
71
|
-
@attributes[:promisc] = on_off
|
72
|
-
end
|
73
|
-
|
74
|
-
def [](key)
|
75
|
-
@attributes[key]
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
# The 'netns(name) { ...attributes... }' directive.
|
80
|
-
class NetnsDirective
|
81
|
-
def initialize(alias_name, &block)
|
82
|
-
@attributes = { name: alias_name }
|
83
|
-
instance_eval(&block)
|
84
|
-
end
|
85
|
-
|
86
|
-
def ip(value)
|
87
|
-
@attributes[:ip] = value
|
88
|
-
@attributes[:name] ||= value
|
89
|
-
end
|
90
|
-
|
91
|
-
def netmask(value)
|
92
|
-
@attributes[:netmask] = value
|
93
|
-
end
|
94
|
-
|
95
|
-
def route(options)
|
96
|
-
@attributes[:net] = options.fetch(:net)
|
97
|
-
@attributes[:gateway] = options.fetch(:gateway)
|
98
|
-
end
|
99
|
-
|
100
|
-
def [](key)
|
101
|
-
@attributes[key]
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def initialize(config)
|
11
|
+
def initialize(config, logger)
|
106
12
|
@config = config
|
13
|
+
@logger = logger
|
107
14
|
end
|
108
15
|
|
109
16
|
def vswitch(alias_name = nil, &block)
|
110
17
|
attrs = VswitchDirective.new(alias_name, &block)
|
111
|
-
|
18
|
+
OpenVswitch.create(attrs[:dpid], attrs[:port], attrs[:name], @logger)
|
112
19
|
end
|
113
20
|
|
114
21
|
def vhost(alias_name = nil, &block)
|
115
22
|
attrs = VhostDirective.new(alias_name, &block)
|
116
|
-
|
23
|
+
Vhost.create(attrs[:ip], attrs[:mac], attrs[:promisc], attrs[:name],
|
24
|
+
@logger)
|
117
25
|
end
|
118
26
|
|
119
27
|
def netns(name, &block)
|
120
28
|
attrs = NetnsDirective.new(name, &block)
|
121
|
-
|
29
|
+
Netns.create(attrs, attrs[:name], @logger)
|
122
30
|
end
|
123
31
|
|
124
32
|
def link(name_a, name_b)
|
125
|
-
|
33
|
+
VirtualLink.create(name_a, name_b, @logger)
|
126
34
|
end
|
127
35
|
end
|
128
36
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'phut/syntax/directive'
|
2
|
+
|
3
|
+
module Phut
|
4
|
+
class Syntax
|
5
|
+
# The 'netns(name) { ...attributes... }' directive.
|
6
|
+
class NetnsDirective < Directive
|
7
|
+
attribute :netmask
|
8
|
+
|
9
|
+
def initialize(alias_name, &block)
|
10
|
+
@attributes = { name: alias_name }
|
11
|
+
instance_eval(&block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def ip(value)
|
15
|
+
@attributes[:ip] = value
|
16
|
+
@attributes[:name] ||= value
|
17
|
+
end
|
18
|
+
|
19
|
+
def route(options)
|
20
|
+
@attributes[:net] = options.fetch(:net)
|
21
|
+
@attributes[:gateway] = options.fetch(:gateway)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'phut/syntax/directive'
|
2
|
+
|
3
|
+
module Phut
|
4
|
+
class Syntax
|
5
|
+
# The 'vhost(name) { ...attributes... }' directive.
|
6
|
+
class VhostDirective < Directive
|
7
|
+
# Generates an unused IP address
|
8
|
+
class UnusedIpAddress
|
9
|
+
def initialize
|
10
|
+
@index = 0
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate
|
14
|
+
@index += 1
|
15
|
+
"192.168.0.#{@index}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
UnusedIpAddressSingleton = UnusedIpAddress.new
|
20
|
+
|
21
|
+
attribute :mac
|
22
|
+
attribute :promisc
|
23
|
+
|
24
|
+
def initialize(alias_name, &block)
|
25
|
+
@attributes =
|
26
|
+
{ name: alias_name,
|
27
|
+
mac: Pio::Mac.new(rand(0xffffffffffff + 1)),
|
28
|
+
promisc: false }
|
29
|
+
if block
|
30
|
+
instance_eval(&block)
|
31
|
+
else
|
32
|
+
@attributes[:ip] = UnusedIpAddressSingleton.generate
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def ip(value)
|
37
|
+
@attributes[:ip] = value
|
38
|
+
@attributes[:name] ||= value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'phut/syntax/directive'
|
2
|
+
|
3
|
+
module Phut
|
4
|
+
class Syntax
|
5
|
+
# The 'vswitch(name) { ...attributes... }' directive.
|
6
|
+
class VswitchDirective < Directive
|
7
|
+
attribute :port
|
8
|
+
|
9
|
+
def initialize(alias_name, &block)
|
10
|
+
@attributes = { name: alias_name, port: 6653 }
|
11
|
+
instance_eval(&block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def dpid(value)
|
15
|
+
dpid = if value.is_a?(String) && /^0x/=~ value
|
16
|
+
value.hex
|
17
|
+
else
|
18
|
+
value.to_i
|
19
|
+
end
|
20
|
+
@attributes[:dpid] = dpid
|
21
|
+
@attributes[:name] ||= format('%#x', @attributes[:dpid])
|
22
|
+
end
|
23
|
+
alias_method :datapath_id, :dpid
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/phut/version.rb
CHANGED
data/lib/phut/vhost.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
1
2
|
require 'phut/null_logger'
|
2
3
|
require 'phut/setting'
|
3
4
|
require 'phut/shell_runner'
|
@@ -6,14 +7,35 @@ require 'pio/mac'
|
|
6
7
|
module Phut
|
7
8
|
# An interface class to vhost emulation utility program.
|
8
9
|
class Vhost
|
10
|
+
cattr_accessor(:all, instance_reader: false) { [] }
|
11
|
+
|
12
|
+
def self.create(ip_address, mac_address, promisc, name = nil,
|
13
|
+
logger = NullLogger.new)
|
14
|
+
new(ip_address, mac_address, promisc, name, logger).tap do |vhost|
|
15
|
+
conflict = find_by(name: vhost.name)
|
16
|
+
fail "The name #{vhost.name} conflicts with #{conflict}." if conflict
|
17
|
+
all << vhost
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# This method smells of :reek:NestedIterators but ignores them
|
22
|
+
def self.find_by(queries)
|
23
|
+
queries.inject(all) do |memo, (attr, value)|
|
24
|
+
memo.find_all { |vhost| vhost.__send__(attr) == value }
|
25
|
+
end.first
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.each(&block)
|
29
|
+
all.each(&block)
|
30
|
+
end
|
31
|
+
|
9
32
|
include ShellRunner
|
10
33
|
|
11
34
|
attr_reader :ip_address
|
12
35
|
attr_reader :mac_address
|
13
36
|
attr_accessor :network_device
|
14
37
|
|
15
|
-
def initialize(ip_address, mac_address, promisc,
|
16
|
-
name = nil, logger = NullLogger.new)
|
38
|
+
def initialize(ip_address, mac_address, promisc, name, logger)
|
17
39
|
@ip_address = ip_address
|
18
40
|
@promisc = promisc
|
19
41
|
@name = name
|
@@ -29,7 +51,7 @@ module Phut
|
|
29
51
|
"vhost (name = #{name}, IP address = #{@ip_address})"
|
30
52
|
end
|
31
53
|
|
32
|
-
def run(all_hosts =
|
54
|
+
def run(all_hosts = Vhost.all)
|
33
55
|
@all_hosts ||= all_hosts
|
34
56
|
if ENV['rvm_path']
|
35
57
|
sh "rvmsudo vhost run #{run_options}"
|
@@ -40,13 +62,13 @@ module Phut
|
|
40
62
|
end
|
41
63
|
|
42
64
|
def stop
|
43
|
-
|
44
|
-
|
65
|
+
return unless running?
|
66
|
+
stop!
|
45
67
|
end
|
46
68
|
|
47
|
-
def
|
48
|
-
|
49
|
-
stop
|
69
|
+
def stop!
|
70
|
+
fail "vhost (name = #{name}) is not running!" unless running?
|
71
|
+
sh "vhost stop -n #{name} -S #{Phut.socket_dir}"
|
50
72
|
end
|
51
73
|
|
52
74
|
def running?
|
data/lib/phut/virtual_link.rb
CHANGED
@@ -1,9 +1,20 @@
|
|
1
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
1
2
|
require 'phut/null_logger'
|
2
3
|
require 'phut/shell_runner'
|
3
4
|
|
4
5
|
module Phut
|
5
6
|
# Network virtual link.
|
6
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
|
+
|
7
18
|
# Creates a valid network device name.
|
8
19
|
class NetworkDeviceName
|
9
20
|
attr_reader :name
|
@@ -35,7 +46,7 @@ module Phut
|
|
35
46
|
attr_reader :device_a
|
36
47
|
attr_reader :device_b
|
37
48
|
|
38
|
-
def initialize(name_a, name_b, logger
|
49
|
+
def initialize(name_a, name_b, logger)
|
39
50
|
fail if name_a == name_b
|
40
51
|
@name_a = name_a
|
41
52
|
@name_b = name_b
|
@@ -44,6 +55,13 @@ module Phut
|
|
44
55
|
@logger = logger
|
45
56
|
end
|
46
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
|
+
|
47
65
|
def run
|
48
66
|
stop if up?
|
49
67
|
add
|
@@ -51,16 +69,16 @@ module Phut
|
|
51
69
|
end
|
52
70
|
|
53
71
|
def stop
|
72
|
+
return unless up?
|
73
|
+
stop!
|
74
|
+
end
|
75
|
+
|
76
|
+
def stop!
|
54
77
|
sh "sudo ip link delete #{@device_a}"
|
55
78
|
rescue
|
56
79
|
raise "link #{@name_a} #{@name_b} does not exist!"
|
57
80
|
end
|
58
81
|
|
59
|
-
def maybe_stop
|
60
|
-
return unless up?
|
61
|
-
stop
|
62
|
-
end
|
63
|
-
|
64
82
|
def up?
|
65
83
|
/^#{@device_a}\s+Link encap:Ethernet/ =~ `LANG=C ifconfig -a` || false
|
66
84
|
end
|
data/phut.gemspec
CHANGED
@@ -23,7 +23,8 @@ Gem::Specification.new do |gem|
|
|
23
23
|
|
24
24
|
gem.required_ruby_version = '>= 2.0.0'
|
25
25
|
|
26
|
-
gem.add_dependency '
|
26
|
+
gem.add_dependency 'activesupport', '~> 4.2', '>= 4.2.5'
|
27
|
+
gem.add_dependency 'gli', '~> 2.13.4'
|
27
28
|
gem.add_dependency 'pio', '~> 0.30.0'
|
28
29
|
gem.add_dependency 'pry', '~> 0.10.3'
|
29
30
|
|
@@ -32,23 +33,22 @@ Gem::Specification.new do |gem|
|
|
32
33
|
gem.add_development_dependency 'yard', '~> 0.8.7.6'
|
33
34
|
|
34
35
|
# Development
|
35
|
-
gem.add_development_dependency 'byebug', '~> 7.0.0'
|
36
36
|
gem.add_development_dependency 'guard', '~> 2.13.0'
|
37
37
|
gem.add_development_dependency 'guard-bundler', '~> 2.1.0'
|
38
|
-
gem.add_development_dependency 'guard-cucumber', '~>
|
38
|
+
gem.add_development_dependency 'guard-cucumber', '~> 2.0.0'
|
39
39
|
gem.add_development_dependency 'guard-rspec', '~> 4.6.4'
|
40
40
|
gem.add_development_dependency 'guard-rubocop', '~> 1.2.0'
|
41
41
|
|
42
42
|
# Test
|
43
|
-
gem.add_development_dependency 'aruba', '~> 0.
|
43
|
+
gem.add_development_dependency 'aruba', '~> 0.11.2'
|
44
44
|
gem.add_development_dependency 'codeclimate-test-reporter'
|
45
|
-
gem.add_development_dependency 'coveralls', '~> 0.8.
|
45
|
+
gem.add_development_dependency 'coveralls', '~> 0.8.10'
|
46
46
|
gem.add_development_dependency 'cucumber', '~> 2.1.0'
|
47
47
|
gem.add_development_dependency 'flay', '~> 2.6.1'
|
48
48
|
gem.add_development_dependency 'flog', '~> 4.3.2'
|
49
49
|
gem.add_development_dependency 'rake'
|
50
|
-
gem.add_development_dependency 'reek', '~> 3.
|
51
|
-
gem.add_development_dependency 'rspec', '~> 3.
|
50
|
+
gem.add_development_dependency 'reek', '~> 3.7.1'
|
51
|
+
gem.add_development_dependency 'rspec', '~> 3.4.0'
|
52
52
|
gem.add_development_dependency 'rspec-given', '~> 3.7.1'
|
53
|
-
gem.add_development_dependency 'rubocop', '~> 0.
|
53
|
+
gem.add_development_dependency 'rubocop', '~> 0.35.1'
|
54
54
|
end
|
data/spec/phut/parser_spec.rb
CHANGED
@@ -12,7 +12,6 @@ describe Phut::Parser do
|
|
12
12
|
When(:string) { "vswitch { dpid '0xabc' }" }
|
13
13
|
|
14
14
|
describe '#vswitch' do
|
15
|
-
Then { configuration.vswitches.size == 1 }
|
16
15
|
Then { configuration.fetch('0xabc').datapath_id == 0xabc }
|
17
16
|
Then { configuration.fetch('0xabc').dpid == 0xabc }
|
18
17
|
end
|
@@ -22,7 +21,6 @@ describe Phut::Parser do
|
|
22
21
|
When(:string) { "vswitch { datapath_id '0xabc' }" }
|
23
22
|
|
24
23
|
describe '#vswitch' do
|
25
|
-
Then { configuration.vswitches.size == 1 }
|
26
24
|
Then { configuration.fetch('0xabc').dpid == 0xabc }
|
27
25
|
Then { configuration.fetch('0xabc').datapath_id == 0xabc }
|
28
26
|
end
|
@@ -32,7 +30,6 @@ describe Phut::Parser do
|
|
32
30
|
When(:string) { "vswitch('my_controller') { dpid '0xabc' }" }
|
33
31
|
|
34
32
|
describe '#vswitch' do
|
35
|
-
Then { configuration.vswitches.size == 1 }
|
36
33
|
Then { configuration.fetch('my_controller').dpid == 0xabc }
|
37
34
|
Then { configuration.fetch('my_controller').datapath_id == 0xabc }
|
38
35
|
end
|
@@ -48,7 +45,6 @@ CONFIGURATION
|
|
48
45
|
end
|
49
46
|
|
50
47
|
describe '#vhost' do
|
51
|
-
Then { configuration.vhosts.size == 2 }
|
52
48
|
Then { configuration.fetch('192.168.0.1').ip_address == '192.168.0.1' }
|
53
49
|
end
|
54
50
|
end
|
@@ -63,7 +59,6 @@ CONFIGURATION
|
|
63
59
|
end
|
64
60
|
|
65
61
|
describe '#vhost' do
|
66
|
-
Then { configuration.vhosts.size == 2 }
|
67
62
|
Then { configuration.fetch('host1').ip_address == '192.168.0.1' }
|
68
63
|
end
|
69
64
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -8,7 +8,7 @@ if ENV['CODECLIMATE_REPO_TOKEN']
|
|
8
8
|
formatters << CodeClimate::TestReporter::Formatter
|
9
9
|
end
|
10
10
|
|
11
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter
|
11
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(formatters)
|
12
12
|
SimpleCov.start { add_filter '/vendor/' }
|
13
13
|
|
14
14
|
require 'rspec/given'
|
metadata
CHANGED
@@ -1,29 +1,49 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phut
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yasuhito Takamiya
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.2'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 4.2.5
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.2'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 4.2.5
|
13
33
|
- !ruby/object:Gem::Dependency
|
14
34
|
name: gli
|
15
35
|
requirement: !ruby/object:Gem::Requirement
|
16
36
|
requirements:
|
17
37
|
- - "~>"
|
18
38
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.13.
|
39
|
+
version: 2.13.4
|
20
40
|
type: :runtime
|
21
41
|
prerelease: false
|
22
42
|
version_requirements: !ruby/object:Gem::Requirement
|
23
43
|
requirements:
|
24
44
|
- - "~>"
|
25
45
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.13.
|
46
|
+
version: 2.13.4
|
27
47
|
- !ruby/object:Gem::Dependency
|
28
48
|
name: pio
|
29
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,20 +100,6 @@ dependencies:
|
|
80
100
|
- - "~>"
|
81
101
|
- !ruby/object:Gem::Version
|
82
102
|
version: 0.8.7.6
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: byebug
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 7.0.0
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 7.0.0
|
97
103
|
- !ruby/object:Gem::Dependency
|
98
104
|
name: guard
|
99
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,14 +134,14 @@ dependencies:
|
|
128
134
|
requirements:
|
129
135
|
- - "~>"
|
130
136
|
- !ruby/object:Gem::Version
|
131
|
-
version:
|
137
|
+
version: 2.0.0
|
132
138
|
type: :development
|
133
139
|
prerelease: false
|
134
140
|
version_requirements: !ruby/object:Gem::Requirement
|
135
141
|
requirements:
|
136
142
|
- - "~>"
|
137
143
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
144
|
+
version: 2.0.0
|
139
145
|
- !ruby/object:Gem::Dependency
|
140
146
|
name: guard-rspec
|
141
147
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,14 +176,14 @@ dependencies:
|
|
170
176
|
requirements:
|
171
177
|
- - "~>"
|
172
178
|
- !ruby/object:Gem::Version
|
173
|
-
version: 0.
|
179
|
+
version: 0.11.2
|
174
180
|
type: :development
|
175
181
|
prerelease: false
|
176
182
|
version_requirements: !ruby/object:Gem::Requirement
|
177
183
|
requirements:
|
178
184
|
- - "~>"
|
179
185
|
- !ruby/object:Gem::Version
|
180
|
-
version: 0.
|
186
|
+
version: 0.11.2
|
181
187
|
- !ruby/object:Gem::Dependency
|
182
188
|
name: codeclimate-test-reporter
|
183
189
|
requirement: !ruby/object:Gem::Requirement
|
@@ -198,14 +204,14 @@ dependencies:
|
|
198
204
|
requirements:
|
199
205
|
- - "~>"
|
200
206
|
- !ruby/object:Gem::Version
|
201
|
-
version: 0.8.
|
207
|
+
version: 0.8.10
|
202
208
|
type: :development
|
203
209
|
prerelease: false
|
204
210
|
version_requirements: !ruby/object:Gem::Requirement
|
205
211
|
requirements:
|
206
212
|
- - "~>"
|
207
213
|
- !ruby/object:Gem::Version
|
208
|
-
version: 0.8.
|
214
|
+
version: 0.8.10
|
209
215
|
- !ruby/object:Gem::Dependency
|
210
216
|
name: cucumber
|
211
217
|
requirement: !ruby/object:Gem::Requirement
|
@@ -268,28 +274,28 @@ dependencies:
|
|
268
274
|
requirements:
|
269
275
|
- - "~>"
|
270
276
|
- !ruby/object:Gem::Version
|
271
|
-
version: 3.
|
277
|
+
version: 3.7.1
|
272
278
|
type: :development
|
273
279
|
prerelease: false
|
274
280
|
version_requirements: !ruby/object:Gem::Requirement
|
275
281
|
requirements:
|
276
282
|
- - "~>"
|
277
283
|
- !ruby/object:Gem::Version
|
278
|
-
version: 3.
|
284
|
+
version: 3.7.1
|
279
285
|
- !ruby/object:Gem::Dependency
|
280
286
|
name: rspec
|
281
287
|
requirement: !ruby/object:Gem::Requirement
|
282
288
|
requirements:
|
283
289
|
- - "~>"
|
284
290
|
- !ruby/object:Gem::Version
|
285
|
-
version: 3.
|
291
|
+
version: 3.4.0
|
286
292
|
type: :development
|
287
293
|
prerelease: false
|
288
294
|
version_requirements: !ruby/object:Gem::Requirement
|
289
295
|
requirements:
|
290
296
|
- - "~>"
|
291
297
|
- !ruby/object:Gem::Version
|
292
|
-
version: 3.
|
298
|
+
version: 3.4.0
|
293
299
|
- !ruby/object:Gem::Dependency
|
294
300
|
name: rspec-given
|
295
301
|
requirement: !ruby/object:Gem::Requirement
|
@@ -310,14 +316,14 @@ dependencies:
|
|
310
316
|
requirements:
|
311
317
|
- - "~>"
|
312
318
|
- !ruby/object:Gem::Version
|
313
|
-
version: 0.
|
319
|
+
version: 0.35.1
|
314
320
|
type: :development
|
315
321
|
prerelease: false
|
316
322
|
version_requirements: !ruby/object:Gem::Requirement
|
317
323
|
requirements:
|
318
324
|
- - "~>"
|
319
325
|
- !ruby/object:Gem::Version
|
320
|
-
version: 0.
|
326
|
+
version: 0.35.1
|
321
327
|
description: A simple network emulator with capabilities similar to mininet.
|
322
328
|
email:
|
323
329
|
- yasuhito@gmail.com
|
@@ -332,7 +338,6 @@ files:
|
|
332
338
|
- ".hound.yml"
|
333
339
|
- ".rspec"
|
334
340
|
- ".rubocop.yml"
|
335
|
-
- ".ruby-version"
|
336
341
|
- ".travis.yml"
|
337
342
|
- CHANGELOG.md
|
338
343
|
- CONTRIBUTING.md
|
@@ -363,12 +368,15 @@ files:
|
|
363
368
|
- lib/phut/setting.rb
|
364
369
|
- lib/phut/shell_runner.rb
|
365
370
|
- lib/phut/syntax.rb
|
371
|
+
- lib/phut/syntax/directive.rb
|
372
|
+
- lib/phut/syntax/netns_directive.rb
|
373
|
+
- lib/phut/syntax/vhost_directive.rb
|
374
|
+
- lib/phut/syntax/vswitch_directive.rb
|
366
375
|
- lib/phut/version.rb
|
367
376
|
- lib/phut/vhost.rb
|
368
377
|
- lib/phut/vhost_daemon.rb
|
369
378
|
- lib/phut/virtual_link.rb
|
370
379
|
- phut.gemspec
|
371
|
-
- spec/phut/open_vswitch_spec.rb
|
372
380
|
- spec/phut/parser_spec.rb
|
373
381
|
- spec/phut_spec.rb
|
374
382
|
- spec/spec_helper.rb
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.0.0
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'phut/open_vswitch'
|
2
|
-
|
3
|
-
describe Phut::OpenVswitch do
|
4
|
-
describe '.new' do
|
5
|
-
context 'with 0xabc' do
|
6
|
-
Given(:vswitch) do
|
7
|
-
Phut::OpenVswitch.new(0xabc).tap do |vswitch|
|
8
|
-
allow(vswitch).to receive(:running?).and_return(false, true)
|
9
|
-
allow(vswitch).to receive(:sh)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
describe '#run' do
|
14
|
-
When { vswitch.run }
|
15
|
-
Then do
|
16
|
-
expect(vswitch).to(have_received(:sh).
|
17
|
-
with('sudo ovs-vsctl add-br br0xabc'))
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|