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.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.rubocop.yml +14 -1
- data/.travis.yml +2 -6
- data/Gemfile +30 -2
- data/Gemfile.lock +156 -0
- data/README.md +7 -2
- data/Rakefile +4 -3
- data/bin/phut +35 -83
- data/bin/vhost +28 -26
- data/features/{dsl.feature → dsl/error.feature} +8 -6
- data/features/{dsl_link.feature → dsl/link.feature} +11 -14
- data/features/dsl/netns.feature +115 -0
- data/features/dsl/vhost.feature +37 -0
- data/features/{dsl_vswitch.feature → dsl/vswitch.feature} +12 -12
- data/features/phut_run.feature +15 -0
- data/features/shell/vswitch#destroy.feature +10 -0
- data/features/shell/vswitch#ports.feature +36 -0
- data/features/shell/vswitch.all.feature +26 -0
- data/features/shell/vswitch.create.feature +30 -0
- data/features/shell/vswitch.destroy.feature +19 -0
- data/features/shell/vswitch.destroy_all.feature +18 -0
- data/features/step_definitions/link_steps.rb +5 -0
- data/features/step_definitions/netns_steps.rb +31 -0
- data/features/step_definitions/phut_steps.rb +5 -34
- data/features/step_definitions/vhost_steps.rb +5 -0
- data/features/step_definitions/vswitch_steps.rb +17 -0
- data/features/support/env.rb +3 -3
- data/features/support/hooks.rb +23 -15
- data/lib/phut.rb +3 -0
- data/lib/phut/finder.rb +19 -0
- data/lib/phut/link.rb +84 -0
- data/lib/phut/netns.rb +111 -22
- data/lib/phut/open_vswitch.rb +98 -96
- data/lib/phut/parser.rb +39 -8
- data/lib/phut/raw_socket.rb +4 -0
- data/lib/phut/route.rb +34 -0
- data/lib/phut/setting.rb +21 -4
- data/lib/phut/shell_runner.rb +13 -2
- data/lib/phut/syntax.rb +31 -14
- data/lib/phut/syntax/directive.rb +9 -1
- data/lib/phut/syntax/netns_directive.rb +13 -2
- data/lib/phut/syntax/vhost_directive.rb +2 -0
- data/lib/phut/syntax/vswitch_directive.rb +3 -1
- data/lib/phut/version.rb +3 -1
- data/lib/phut/veth.rb +68 -0
- data/lib/phut/vhost.rb +99 -58
- data/lib/phut/vhost_daemon.rb +53 -11
- data/lib/phut/vsctl.rb +125 -0
- data/lib/phut/vswitch.rb +10 -0
- data/phut.gemspec +9 -31
- data/tasks/cucumber.rake +5 -1
- data/tasks/flay.rake +2 -0
- data/tasks/flog.rake +3 -1
- data/tasks/gem.rake +2 -0
- data/tasks/minitest.rake +7 -0
- data/tasks/reek.rake +2 -0
- data/tasks/rubocop.rake +2 -0
- data/tasks/yard.rake +2 -0
- data/test/phut/link_test.rb +85 -0
- data/test/phut/netns_test.rb +58 -0
- data/test/phut/open_vswitch_test.rb +125 -0
- data/test/phut/veth_test.rb +48 -0
- data/test/phut/vhost_test.rb +56 -0
- metadata +41 -287
- data/.rspec +0 -3
- data/Guardfile +0 -29
- data/features/dsl_vhost.feature +0 -37
- data/features/phut_kill.feature +0 -27
- data/features/shell.feature +0 -39
- data/lib/phut/configuration.rb +0 -92
- data/lib/phut/null_logger.rb +0 -14
- data/lib/phut/virtual_link.rb +0 -109
- data/spec/phut/parser_spec.rb +0 -66
- data/spec/phut_spec.rb +0 -45
- data/spec/spec_helper.rb +0 -14
- data/tasks/LICENSE +0 -675
- data/tasks/relish.rake +0 -8
- data/tasks/rspec.rake +0 -8
data/.rspec
DELETED
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
|
data/features/dsl_vhost.feature
DELETED
@@ -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
|
-
|
data/features/phut_kill.feature
DELETED
@@ -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 |
|
data/features/shell.feature
DELETED
@@ -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!"
|
data/lib/phut/configuration.rb
DELETED
@@ -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
|
data/lib/phut/null_logger.rb
DELETED
data/lib/phut/virtual_link.rb
DELETED
@@ -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
|
data/spec/phut/parser_spec.rb
DELETED
@@ -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
|
data/spec/phut_spec.rb
DELETED
@@ -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
|