vagrant-tun 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ .coverage/
2
+ Gemfile.lock
3
+ coverage/
4
+ pkg/
5
+
6
+ *.swp
7
+ *.swo
8
+ *.swn
9
+ *.swo
10
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vagrant-tun.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Rick van de Loo
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Makefile ADDED
@@ -0,0 +1,16 @@
1
+ .PHONY: all clean
2
+
3
+ NAME := vagrant-tun
4
+ VERSION := 0.1
5
+ MAINTAINER := Rick van de Loo <rickvandeloo@gmail.com>
6
+ DESCRIPTION := Make sure the tun module is loaded into the kernel
7
+
8
+ all:
9
+ rake build
10
+ test:
11
+ bundle exec rspec spec/
12
+ install:
13
+ find pkg/ -name '*.gem' | head -n 1 | xargs vagrant plugin install
14
+ clean:
15
+ git clean -xfd
16
+
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # vagrant-tun
2
+
3
+ ## Purpose
4
+
5
+ This Vagrant plugin makes sure that there is a TUN/TAP device in a usable state.
6
+
7
+ There are a couple of reasons why `/dev/net/tun` could be unavailable after provisioning. One of them is that it could be that the base image you are using does not have the `tun` module loaded by default. Another is that updating and upgrading the machine during the provisioning stage has installed a new kernel and requires a reboot for the `tun` module to be successfully loaded. This plugin tries to automate all of that.
8
+
9
+ 1. Check if the TUN adapter exists and is in a usable state
10
+
11
+ 2. If not, create it with ```mkdir -p /dev/net && mknod /dev/net/tun c 10 200 && chmod 0666 /dev/net/tun```
12
+
13
+ 3. If it still is not in a usable state, try to load the `tun` module into the kernel and check again
14
+
15
+ 4. If it is still not in a usable state, reboot the machine and check again
16
+
17
+
18
+ ## Usage
19
+
20
+ ### Install the plugin
21
+
22
+ ```
23
+ $ vagrant plugin install vagrant-tun
24
+ ```
25
+
26
+ Enable the plugin in your Vagrantfile
27
+ ```
28
+ Vagrant.configure('2') do |config|
29
+ config.tun.enabled = true
30
+ ```
31
+
32
+ ## Development
33
+
34
+ ### Install the build deps
35
+
36
+ ```
37
+ sudo gem install bundler rake rspec simplecov
38
+ ```
39
+
40
+ ### Run the tests
41
+ ```
42
+ $ make test
43
+ ```
44
+
45
+ ### Create the gemfile (package)
46
+
47
+ ```
48
+ $ make
49
+ rake build
50
+ vagrant-tun 0.0.1 built to pkg/vagrant-tun-0.0.1.gem.
51
+ ```
52
+
53
+ ### Install the built gemfile
54
+ ```
55
+ $ make install
56
+ find pkg/ -name '*.gem' | head -n 1 | xargs vagrant plugin install
57
+ Installing the 'pkg/vagrant-tun-0.0.1.gem' plugin. This can take a few minutes...
58
+ Installed the plugin 'vagrant-tun (0.0.1)'!
59
+ ```
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,10 @@
1
+ Vagrant.configure('2') do |config|
2
+ config.vm.box = "archlinux_x86_64"
3
+ config.vm.box_url = "http://cloud.terry.im/vagrant/archlinux-x86_64.box"
4
+
5
+ config.tun.enabled = true
6
+
7
+ config.vm.provision "shell", inline: "pacman -Rsc virtualbox-guest-dkms --noconfirm"
8
+ config.vm.provision "shell", inline: "pacman -Syyu --noconfirm"
9
+ end
10
+
@@ -0,0 +1,90 @@
1
+ module VagrantTun
2
+ class Command
3
+
4
+ def initialize(app, env)
5
+ @app = app
6
+ @env = env
7
+ end
8
+
9
+ def call(env)
10
+ if env[:machine].config.tun.enabled
11
+ ensure_tun_available(env)
12
+ end
13
+ @app.call(env)
14
+ end
15
+
16
+ def try_load_tun_kernel_module(env)
17
+ load_tun_module_command = "modprobe tun"
18
+ env[:machine].communicate.sudo(load_tun_module_command, {:error_check => false}) do |type, data|
19
+ return verify_adapter(env, false)
20
+ end
21
+ end
22
+
23
+ def try_create_adapter(env)
24
+ env[:ui].info("Trying to create TUN adapter")
25
+ result = false
26
+ create_adapter_command = '(mkdir -p /dev/net && '
27
+ create_adapter_command << 'mknod /dev/net/tun c 10 200 && '
28
+ create_adapter_command << 'chmod 0666 /dev/net/tun) 2>/dev/null'
29
+ env[:machine].communicate.sudo(create_adapter_command, {:error_check => false}) do |type, data|
30
+ result = verify_adapter(env, false)
31
+ if ! result
32
+ result = try_load_tun_kernel_module(env)
33
+ end
34
+ end
35
+ return result
36
+ end
37
+
38
+ def verify_adapter(env, try_create)
39
+ env[:ui].info("Verifying TUN adapter..")
40
+ result = false
41
+ env[:machine].communicate.sudo('cat /dev/net/tun', {:error_check => false}) do |type, data|
42
+ adapter_state = data.to_s.strip
43
+ case adapter_state
44
+ when /\bFile descriptor in bad state\b/
45
+ env[:ui].info("TUN adapter OK!")
46
+ result = true
47
+ when /\bNo such file or directory\b/
48
+ if try_create
49
+ env[:ui].info("TUN adapter not OK :(")
50
+ result = try_create_adapter(env)
51
+ else
52
+ result = false
53
+ end
54
+ end
55
+ end
56
+ return result
57
+ end
58
+
59
+ # Try all strategies to get the TUN adapter in an available state
60
+ def iter_verify_adapter(env)
61
+ success = verify_adapter(env, true)
62
+ if ! success
63
+ reboot(env)
64
+ success = verify_adapter(env, true)
65
+ end
66
+ return success
67
+ end
68
+
69
+ def log_success_or_fail_message(env, success)
70
+ if success
71
+ env[:ui].info("Ensured the TUN module is loaded into the kernel.")
72
+ else
73
+ env[:ui].error("Failed to load the TUN/TAP adapter. If you are running a custom kernel make sure you have the tun module enabled.")
74
+ end
75
+ end
76
+
77
+ def ensure_tun_available(env)
78
+ success = iter_verify_adapter(env)
79
+ log_success_or_fail_message(env, success)
80
+ end
81
+
82
+ def reboot(env)
83
+ env[:ui].info("Rebooting because we couldn't load the tun module. Maybe the kernel was updated?")
84
+ env[:machine].action(:reload)
85
+ begin
86
+ sleep 1
87
+ end until env[:machine].communicate.ready?
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,18 @@
1
+ require 'vagrant'
2
+
3
+ module VagrantTun
4
+ class Config < Vagrant.plugin("2", :config)
5
+ attr_accessor :enabled
6
+
7
+ def initialize
8
+ super
9
+ # UNSET_VALUE so that Vagrant can properly automatically merge multiple configurations.
10
+ # https://www.vagrantup.com/docs/plugins/configuration.html
11
+ @enabled = UNSET_VALUE
12
+ end
13
+
14
+ def finalize!
15
+ @enabled = (@enabled != UNSET_VALUE) && (@enabled != false)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ module Vagrant
2
+ module Tun
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,20 @@
1
+ require "vagrant"
2
+ require "vagrant-tun/command"
3
+
4
+ module VagrantTun
5
+ class Plugin < Vagrant.plugin("2")
6
+ name "tun"
7
+ description <<-DESC
8
+ Make sure the tun module is loaded into the kernel
9
+ DESC
10
+
11
+ config 'tun' do
12
+ require File.expand_path("../vagrant-tun/config", __FILE__)
13
+ Config
14
+ end
15
+
16
+ action_hook(:VagrantTun, :machine_action_up) do |hook|
17
+ hook.append(VagrantTun::Command)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1 @@
1
+ require 'simplecov'
@@ -0,0 +1,71 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # vim: set fileencoding=utf-8
3
+
4
+ require 'spec_helper'
5
+ require "vagrant-tun/command"
6
+
7
+ describe VagrantTun::Command do
8
+ # create a fake app and env to pass into the VagrantTun::Command constructor
9
+ let(:app) { lambda { |env| } }
10
+ let(:env) { { :machine => machine, :ui => ui } }
11
+
12
+ # pretend env contains the Vagrant ui element
13
+ let(:ui) do
14
+ double('ui').tap do |ui|
15
+ allow(ui).to receive(:info) { nil }
16
+ end
17
+ end
18
+
19
+ # pretend env[:machine].config.tun.enabled is false
20
+ let(:machine) do
21
+ double('machine').tap do |machine|
22
+ allow(machine).to receive(:config) { config }
23
+ end
24
+ end
25
+ let(:config) do
26
+ double('config').tap do |config|
27
+ allow(config).to receive(:tun) { tun }
28
+ end
29
+ end
30
+ let(:tun) do
31
+ double('tun').tap do |config|
32
+ allow(config).to receive(:enabled) { enabled }
33
+ end
34
+ end
35
+ let(:enabled) { false }
36
+
37
+
38
+ # Call the method under test after every 'it'. Similar to setUp in Python TestCase
39
+ after do
40
+ subject.call(env)
41
+ end
42
+
43
+ # instantiate class of which a method is to be tested
44
+ subject { described_class.new(app, env) }
45
+
46
+ # the method that we are going to test
47
+ describe "#call" do
48
+
49
+ context "when config tun disabled (default)" do
50
+ it "does nothing but call the super" do
51
+ # check ensure_tun_available is not called when plugin is disabled
52
+ expect(subject).to receive(:ensure_tun_available).never
53
+ # check super is still called when plugin is disabled
54
+ expect(app).to receive(:call).with(env)
55
+ end
56
+ end
57
+
58
+ context "when config tun enabled" do
59
+ # pretend env[:machine].config.tun.enabled is true
60
+ let(:enabled) { true }
61
+
62
+ it "ensures the tun adapter is available" do
63
+ # check ensure_tun_available is called when plugin is enabled
64
+ expect(subject).to receive(:ensure_tun_available).with(env)
65
+ # check super is also called when plugin is enabled
66
+ expect(app).to receive(:call).with(env)
67
+ end
68
+ end
69
+ end
70
+ end
71
+
@@ -0,0 +1,40 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # vim: set fileencoding=utf-8
3
+
4
+ require 'spec_helper'
5
+ require "vagrant-tun/command"
6
+
7
+ describe VagrantTun::Command do
8
+ # create a fake app and env to pass into the VagrantTun::Command constructor
9
+ let(:app) { lambda { |env| } }
10
+ let(:env) { { } }
11
+
12
+ # Call the method under test after every 'it'. Similar to setUp in Python TestCase
13
+ after do
14
+ subject.ensure_tun_available(env)
15
+ end
16
+
17
+ # instantiate class of which a method is to be tested
18
+ subject { described_class.new(app, env) }
19
+
20
+ # the method that we are going to test
21
+ describe "#ensure_tun_available" do
22
+
23
+ context "when ensuring tun available" do
24
+ it "tries all the strategies to get the TUN adapter in an available state and can fail" do
25
+ # check if iter_verify_adapter is called and pretend it returned false
26
+ expect(subject).to receive(:iter_verify_adapter).with(env).and_return(false)
27
+ # check log_success_or_fail_message is called
28
+ expect(subject).to receive(:log_success_or_fail_message).with(env, false)
29
+ end
30
+
31
+ it "tries all the strategies to get the TUN adapter in an available state and can succeed" do
32
+ # check if iter_verify_adapter is called and pretend it returned true
33
+ expect(subject).to receive(:iter_verify_adapter).with(env).and_return(true)
34
+ # check log_success_or_fail_message is called
35
+ expect(subject).to receive(:log_success_or_fail_message).with(env, true)
36
+ end
37
+ end
38
+ end
39
+ end
40
+
@@ -0,0 +1,47 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # vim: set fileencoding=utf-8
3
+
4
+ require 'spec_helper'
5
+ require "vagrant-tun/command"
6
+
7
+ describe VagrantTun::Command do
8
+ # create a fake app and env to pass into the VagrantTun::Command constructor
9
+ let(:app) { lambda { |env| } }
10
+ let(:env) { { } }
11
+
12
+ # instantiate class of which a method is to be tested
13
+ subject { described_class.new(app, env) }
14
+
15
+ # the method that we are going to test
16
+ describe "#iter_verify_adapter" do
17
+
18
+ context "iterating over all strategies" do
19
+ it "verifies the adapter with try create and succeeds" do
20
+ # check if verify_adapter is called once and pretend it returned true
21
+ expect(subject).to receive(:verify_adapter).once.with(env, true).and_return(true)
22
+ # check that the machine is not rebooted
23
+ expect(subject).to receive(:reboot).never
24
+ # check if iter_verify_adapter returned true
25
+ expect( subject.iter_verify_adapter(env) ).to eq(true)
26
+ end
27
+
28
+ it "verifies the adapter with try create and fails the first time" do
29
+ # check if verify_adapter is called twice and pretend it returned true
30
+ expect(subject).to receive(:verify_adapter).twice.with(env, true).and_return(false, true)
31
+ # check that the machine is rebooted
32
+ expect(subject).to receive(:reboot).once.with(env)
33
+ # check if iter_verify_adapter returned true
34
+ expect( subject.iter_verify_adapter(env) ).to eq(true)
35
+ end
36
+
37
+ it "verifies the adapter with try create and fails both times" do
38
+ # check if verify_adapter is called twice and pretend it returned true
39
+ expect(subject).to receive(:verify_adapter).twice.with(env, true).and_return(false, false)
40
+ # check that the machine is rebooted
41
+ expect(subject).to receive(:reboot).once.with(env)
42
+ # check if iter_verify_adapter returned false
43
+ expect( subject.iter_verify_adapter(env) ).to eq(false)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path('../lib/vagrant-tun/version', __FILE__)
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "vagrant-tun"
5
+ spec.version = Vagrant::Tun::VERSION
6
+ spec.authors = ["Rick van de Loo"]
7
+ spec.email = ["rickvandeloo@gmail.com"]
8
+ spec.description = %q{Make sure the TUN module is loaded into the kernel}
9
+ spec.summary = %q{Make sure the TUN module is loaded into the kernel}
10
+ spec.homepage = "https://github.com/vdloo/vagrant-tun"
11
+ spec.license = "MIT"
12
+
13
+ spec.files = `git ls-files`.split("\n")
14
+ spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ spec.require_paths = ["lib"]
17
+
18
+ spec.add_development_dependency "bundler"
19
+ spec.add_development_dependency "rake"
20
+ spec.add_development_dependency "rspec"
21
+ spec.add_development_dependency "simplecov"
22
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-tun
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Rick van de Loo
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-08-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: simplecov
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Make sure the TUN module is loaded into the kernel
79
+ email:
80
+ - rickvandeloo@gmail.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - Gemfile
87
+ - LICENSE.txt
88
+ - Makefile
89
+ - README.md
90
+ - Rakefile
91
+ - example/Vagrantfile
92
+ - lib/vagrant-tun.rb
93
+ - lib/vagrant-tun/command.rb
94
+ - lib/vagrant-tun/config.rb
95
+ - lib/vagrant-tun/version.rb
96
+ - spec/spec_helper.rb
97
+ - spec/unit/command/call_spec.rb
98
+ - spec/unit/command/ensure_tun_available_spec.rb
99
+ - spec/unit/command/iter_verify_adapter_spec.rb
100
+ - vagrant-tun.gemspec
101
+ homepage: https://github.com/vdloo/vagrant-tun
102
+ licenses:
103
+ - MIT
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 1.8.23
123
+ signing_key:
124
+ specification_version: 3
125
+ summary: Make sure the TUN module is loaded into the kernel
126
+ test_files: []